102 lines
2.4 KiB
Python
Executable File
102 lines
2.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import sys; assert sys.version_info[0] >= 3, "Python 3 required."
|
|
|
|
from hashlib import blake2b
|
|
|
|
from .key_components import FullViewingKey, ExtendedSpendingKey
|
|
|
|
from ..hd_common import hardened
|
|
from ..utils import i2leosp
|
|
from ..output import render_args, render_tv
|
|
|
|
|
|
class DerivedSpendingKey(object):
|
|
def __init__(self, extsk, depth=0, parent_tag=i2leosp(32, 0), i=0):
|
|
self._extsk = extsk
|
|
self._depth = depth
|
|
self._parent_tag = parent_tag
|
|
self._i = i
|
|
|
|
def __eq__(self, other):
|
|
return (self._extsk == other._extsk and
|
|
self._depth == other._depth and
|
|
self._parent_tag == other._parent_tag and
|
|
self._i == other._i)
|
|
|
|
@classmethod
|
|
def master(cls, S):
|
|
return cls(ExtendedSpendingKey.master(S))
|
|
|
|
def sk(self):
|
|
return self._extsk.data
|
|
|
|
def c(self):
|
|
return self._extsk.chaincode
|
|
|
|
def depth(self):
|
|
return self._depth
|
|
|
|
def parent_tag(self):
|
|
return self._parent_tag
|
|
|
|
def i(self):
|
|
return self._i
|
|
|
|
def fingerprint(self):
|
|
fvk = FullViewingKey.from_spending_key(self._extsk)
|
|
digest = blake2b(person=b'ZcashOrchardFVFP', digest_size=32)
|
|
digest.update(bytes(fvk.ak) + bytes(fvk.nk) + bytes(fvk.rivk))
|
|
return digest.digest()
|
|
|
|
def tag(self):
|
|
return self.fingerprint()[:4]
|
|
|
|
def __bytes__(self):
|
|
return (i2leosp(8, self.depth()) +
|
|
self.parent_tag() +
|
|
i2leosp(32, self.i()) +
|
|
self.c() +
|
|
self.sk())
|
|
|
|
def child(self, i):
|
|
return self.__class__(self._extsk.child(i), self.depth()+1, self.tag(), i)
|
|
|
|
|
|
def main():
|
|
args = render_args()
|
|
|
|
seed = bytes(range(32))
|
|
m = DerivedSpendingKey.master(seed)
|
|
m_1h = m.child(hardened(1))
|
|
m_1h_2h = m_1h.child(hardened(2))
|
|
m_1h_2h_3h = m_1h_2h.child(hardened(3))
|
|
|
|
keys = [m, m_1h, m_1h_2h, m_1h_2h_3h]
|
|
|
|
render_tvs(args, keys)
|
|
|
|
def render_tvs(args, keys):
|
|
test_vectors = [
|
|
{'sk' : k.sk(),
|
|
'c' : k.c(),
|
|
'xsk' : bytes(k),
|
|
'fp' : k.fingerprint(),
|
|
}
|
|
for k in keys
|
|
]
|
|
|
|
render_tv(
|
|
args,
|
|
'orchard_zip32',
|
|
(
|
|
('sk', '[u8; 32]'),
|
|
('c', '[u8; 32]'),
|
|
('xsk', '[u8; 73]'),
|
|
('fp', '[u8; 32]'),
|
|
),
|
|
test_vectors,
|
|
)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|