#!/usr/bin/env python3 import sys; assert sys.version_info[0] >= 3, "Python 3 required." from chacha20poly1305 import ChaCha20Poly1305 from hashlib import blake2b import os import struct from .generators import VALUE_COMMITMENT_VALUE_BASE, VALUE_COMMITMENT_RANDOMNESS_BASE from .jubjub import Fr, JUBJUB_COFACTOR from .key_components import SpendingKey, diversify_hash from .notes import note_commit from ..utils import leos2bsp, leos2ip from ..output import render_args, render_tv def kdf_sapling(shared_secret, epk): digest = blake2b(digest_size=32, person=b'Zcash_SaplingKDF') digest.update(bytes(shared_secret)) digest.update(bytes(epk)) return digest.digest() def prf_ock(ovk, cv, cmu, ephemeral_key): digest = blake2b(digest_size=32, person=b'Zcash_Derive_ock') digest.update(ovk) digest.update(cv) digest.update(cmu) digest.update(ephemeral_key) return digest.digest() class SaplingKeyAgreement(object): @staticmethod def private(random): return Fr(leos2ip(random(32))) @staticmethod def derive_public(esk, g_d): return g_d * esk @staticmethod def agree(esk, pk_d): return pk_d * esk * JUBJUB_COFACTOR class SaplingSym(object): @staticmethod def k(random): return random(32) @staticmethod def encrypt(key, plaintext): cip = ChaCha20Poly1305(key) return bytes(cip.encrypt(b'\x00' * 12, plaintext)) class SaplingNotePlaintext(object): def __init__(self, d, v, rcm, memo): self.d = d self.v = v self.rcm = rcm self.memo = memo def __bytes__(self): return ( b'\x01' + self.d + struct.pack('