def __init__(self, ask, nsk, ovk, dk, c, depth=0, parent_tag=i2leosp(32, 0), i=0): self._ask = ask self._nsk = nsk self._ovk = ovk self._dk = dk self._c = c self._depth = depth self._parent_tag = parent_tag self._i = i
def child(self, i): if i >= 1 << 31: # child is a hardened key prefix = b'\x11' + encode_xsk_parts(self.ask(), self.nsk(), self.ovk(), self.dk()) else: prefix = b'\x12' + encode_xfvk_parts(self.ak(), self.nk(), self.ovk(), self.dk()) I = prf_expand(self.c(), prefix + i2leosp(32, i)) I_L = I[:32] I_R = I[32:] I_ask = to_scalar(prf_expand(I_L, b'\x13')) I_nsk = to_scalar(prf_expand(I_L, b'\x14')) ask_i = I_ask + self.ask() nsk_i = I_nsk + self.nsk() ovk_i = prf_expand(I_L, b'\x15' + self.ovk())[:32] dk_i = prf_expand(I_L, b'\x16' + self.dk())[:32] c_i = I_R return self.__class__(ask_i, nsk_i, ovk_i, dk_i, c_i, self.depth() + 1, self.tag(), i)
def child(self, i): if i >= 1 << 31: raise ValueError( "can't derive a child hardened key from an extended full viewing key" ) else: prefix = b'\x12' + encode_xfvk_parts(self.ak(), self.nk(), self.ovk(), self.dk()) I = prf_expand(self.c(), prefix + i2leosp(32, i)) I_L = I[:32] I_R = I[32:] I_ask = to_scalar(prf_expand(I_L, b'\x13')) I_nsk = to_scalar(prf_expand(I_L, b'\x14')) ak_i = SPENDING_KEY_BASE * I_ask + self.ak() nk_i = PROVING_KEY_BASE * I_nsk + self.nk() ovk_i = prf_expand(I_L, b'\x15' + self.ovk())[:32] dk_i = prf_expand(I_L, b'\x16' + self.dk())[:32] c_i = I_R return self.__class__(ak_i, nk_i, ovk_i, dk_i, c_i, self.depth() + 1, self.tag(), i)
def __bytes__(self): return i2leosp(256, self.s)
# # Sapling generators # SPENDING_KEY_BASE = find_group_hash(b'Zcash_G_', b'') PROVING_KEY_BASE = find_group_hash(b'Zcash_H_', b'') NOTE_POSITION_BASE = find_group_hash(b'Zcash_J_', b'') WINDOWED_PEDERSEN_RANDOMNESS_BASE = find_group_hash(b'Zcash_PH', b'r') VALUE_COMMITMENT_VALUE_BASE = find_group_hash(b'Zcash_cv', b'v') VALUE_COMMITMENT_RANDOMNESS_BASE = find_group_hash(b'Zcash_cv', b'r') required_bases = 4 PEDERSEN_BASES = [ find_group_hash(b'Zcash_PH', i2leosp(32, iminus1)) for iminus1 in range(0, required_bases) ] def main(): render_tv( render_args(), 'sapling_generators', ( ('skb', '[u8; 32]'), ('pkb', '[u8; 32]'), ('npb', '[u8; 32]'), ('wprb', '[u8; 32]'), ('vcvb', '[u8; 32]'), ('vcrb', '[u8; 32]'),
def __bytes__(self): return ( i2leosp(8, self.depth()) + self.parent_tag() + i2leosp(32, self.i()) + self.c() + encode_xsk_parts(self.ask(), self.nsk(), self.ovk(), self.dk()))
def I_D_i(D, i): return find_group_hash(D, i2leosp(32, i - 1))
def __bytes__(self): # TODO: Check length return i2leosp(256, self.s)