#!/usr/bin/env python3 import sys; assert sys.version_info[0] >= 3, "Python 3 required." from chacha20poly1305 import ChaCha20Poly1305 import os from pyblake2 import blake2b import struct from sapling_generators import VALUE_COMMITMENT_VALUE_BASE, VALUE_COMMITMENT_RANDOMNESS_BASE from sapling_jubjub import Fr, JUBJUB_COFACTOR from sapling_key_components import SpendingKey, diversify_hash from sapling_notes import note_commit from utils import leos2bsp, leos2ip from tv_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('