Implement Pedersen hashes and commitments
This commit is contained in:
parent
146c821fc9
commit
929b36ccfd
|
@ -1,4 +1,5 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
from sapling_utils import i2lebsp
|
||||||
|
|
||||||
ENDIANNESS = 'little'
|
ENDIANNESS = 'little'
|
||||||
|
|
||||||
|
@ -44,6 +45,9 @@ class FieldElement(object):
|
||||||
def inv(self):
|
def inv(self):
|
||||||
return self.exp(self.m - 2)
|
return self.exp(self.m - 2)
|
||||||
|
|
||||||
|
def bits(self, l):
|
||||||
|
return i2lebsp(l, self.s)
|
||||||
|
|
||||||
def __bytes__(self):
|
def __bytes__(self):
|
||||||
return self.s.to_bytes(32, byteorder=ENDIANNESS)
|
return self.s.to_bytes(32, byteorder=ENDIANNESS)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
from sapling_generators import find_group_hash, NOTE_POSITION_BASE, WINDOWED_PEDERSEN_RANDOMNESS_BASE
|
||||||
|
from sapling_jubjub import ENDIANNESS, Fr
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Pedersen hashes
|
||||||
|
#
|
||||||
|
|
||||||
|
def I_D_i(D, i):
|
||||||
|
return find_group_hash(D, (i - 1).to_bytes(4, byteorder=ENDIANNESS))
|
||||||
|
|
||||||
|
def encode_chunk(mj):
|
||||||
|
(s0, s1, s2) = mj
|
||||||
|
return (1 - 2*s2) * (1 + s0 + 2*s1)
|
||||||
|
|
||||||
|
def encode_segment(Mi):
|
||||||
|
ki = len(Mi) / 3
|
||||||
|
Michunks = [Mi[i:i+3] for i in range(0, len(Mi), 3)]
|
||||||
|
assert(len(Michunks) == ki)
|
||||||
|
return Fr(sum([encode_chunk(Michunks[j-1]) * 2**(4*(j-1)) for j in range(1, ki + 1)]))
|
||||||
|
|
||||||
|
def cldiv(n, divisor):
|
||||||
|
return (n + (divisor - 1)) // divisor
|
||||||
|
|
||||||
|
c = 63
|
||||||
|
|
||||||
|
def pedersen_hash_to_point(D, M):
|
||||||
|
# Pad M to a multiple of 3 bits
|
||||||
|
Mdash = M + [0] * ((-len(M)) % 3)
|
||||||
|
n = cldiv(len(Mdash), 3 * c)
|
||||||
|
Msegs = [Mdash[i:i+(3*c)] for i in range(0, len(Mdash), 3*c)]
|
||||||
|
assert(len(Msegs) == n)
|
||||||
|
return sum([I_D_i(D, i) * encode_segment(Msegs[i-1]) for i in range(1, n + 1)])
|
||||||
|
|
||||||
|
def pedersen_hash(D, M):
|
||||||
|
return pedersen_hash_to_point(D, M).u.bits(255)
|
||||||
|
|
||||||
|
def mixing_pedersen_hash(P, x):
|
||||||
|
return P + NOTE_POSITION_BASE * x
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Pedersen commitments
|
||||||
|
#
|
||||||
|
|
||||||
|
def windowed_pedersen_commitment(r, s):
|
||||||
|
return pedersen_hash_to_point(b'Zcash_PH', s) + WINDOWED_PEDERSEN_RANDOMNESS_BASE * r
|
||||||
|
|
||||||
|
def homomorphic_pedersen_commitment(rcv, D, v):
|
||||||
|
return find_group_hash(D, b'v') * v + find_group_hash(D, b'r') * rcv
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
def i2lebsp(l, x):
|
||||||
|
return [int(c) for c in format(x, '0%sb' % l)[::-1]]
|
Loading…
Reference in New Issue