Extract ZIP 32 hardened-only key derivation from Orchard

This commit is contained in:
Jack Grigg 2024-11-02 04:57:07 +00:00
parent 5b76d4bba0
commit ff8eb510c7
2 changed files with 40 additions and 14 deletions

View File

@ -1,10 +1,9 @@
#!/usr/bin/env python3
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
from hashlib import blake2b
from ..ff1 import ff1_aes256_encrypt
from ..sapling.key_components import prf_expand
from ..zip_0032 import CKDh, HardenedOnlyContext, MKGh
from .generators import NULLIFIER_K_BASE, SPENDING_KEY_BASE, group_hash
from .pallas import Fp, Scalar, Point
@ -55,26 +54,20 @@ class SpendingKey(object):
class ExtendedSpendingKey(SpendingKey):
Orchard = HardenedOnlyContext(b'ZcashIP32Orchard', b'\x81')
def __init__(self, chaincode, data):
SpendingKey.__init__(self, data)
self.chaincode = chaincode
@classmethod
def master(cls, S):
digest = blake2b(person=b'ZcashIP32Orchard')
digest.update(S)
I = digest.digest()
I_L = I[:32]
I_R = I[32:]
return cls(I_R, I_L)
(sk, chaincode) = MKGh(cls.Orchard, S)
return cls(chaincode, sk)
def child(self, i):
assert 0x80000000 <= i and i <= 0xFFFFFFFF
I = prf_expand(self.chaincode, b'\x81' + self.data + i2leosp(32, i))
I_L = I[:32]
I_R = I[32:]
return self.__class__(I_R, I_L)
(sk_i, c_i) = CKDh(self.Orchard, self.data, self.chaincode, i)
return self.__class__(c_i, sk_i)
class FullViewingKey(object):

View File

@ -0,0 +1,33 @@
from hashlib import blake2b
from .sapling.key_components import prf_expand
from .utils import i2leosp
class HardenedOnlyContext(object):
def __init__(self, MKGDomain, CKDDomain):
assert type(MKGDomain) == bytes
assert len(MKGDomain) == 16
assert type(CKDDomain) == bytes
assert len(CKDDomain) == 1
self.MKGDomain = MKGDomain
self.CKDDomain = CKDDomain
def MKGh(Context, IKM):
assert type(Context) == HardenedOnlyContext
digest = blake2b(person=Context.MKGDomain)
digest.update(IKM)
I = digest.digest()
I_L = I[:32]
I_R = I[32:]
return (I_L, I_R)
def CKDh(Context, sk_par, c_par, i):
assert type(Context) == HardenedOnlyContext
assert 0x80000000 <= i and i <= 0xFFFFFFFF
I = prf_expand(c_par, Context.CKDDomain + sk_par + i2leosp(32, i))
I_L = I[:32]
I_R = I[32:]
return (I_L, I_R)