def master(cls, S): I = blake2b(person=b'ZcashIP32Sapling', data=S).digest() I_L = I[:32] I_R = I[32:] sk_m = I_L ask_m = to_scalar(prf_expand(sk_m, b'\x00')) nsk_m = to_scalar(prf_expand(sk_m, b'\x01')) ovk_m = prf_expand(sk_m, b'\x02')[:32] dk_m = prf_expand(sk_m, b'\x10')[:32] c_m = I_R return cls(ask_m, nsk_m, ovk_m, dk_m, c_m)
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 gen_private(self): return to_scalar(self._random(64))