def load_zeth_address_public(ctx: ClientConfig) -> ZethAddressPub: """ Load a ZethAddressPub from a key file. """ secret_key_file = get_zeth_address_file(ctx) pub_addr_file = pub_address_file(secret_key_file) with open(pub_addr_file, "r") as pub_addr_f: return ZethAddressPub.parse(pub_addr_f.read())
def parse_output(output_str: str) -> Tuple[ZethAddressPub, EtherValue]: """ Parse a string of the form "<receiver_pub_address>,<value>" to an output specification. <receiver_pub_address> can be a file name containing the address. "<value>" is interpretted as the <default-address-file>,<value>. """ parts = output_str.split(",") if len(parts) == 1: addr = ZETH_PUBLIC_ADDRESS_FILE_DEFAULT value = parts[0] elif len(parts) == 2: addr = parts[0] value = parts[1] else: raise ClickException(f"invalid output spec: {output_str}") if exists(addr): with open(addr, "r") as addr_f: addr = addr_f.read() return (ZethAddressPub.parse(addr), EtherValue(value))
def __init__(self, mk_tree: MerkleTree, sender_ownership_keypair: OwnershipKeyPair, inputs: List[Tuple[int, api.ZethNote]], outputs: List[Tuple[ZethAddressPub, EtherValue]], v_in: EtherValue, v_out: EtherValue, compute_h_sig_cb: Optional[ComputeHSigCB] = None): assert len(inputs) <= constants.JS_INPUTS assert len(outputs) <= constants.JS_OUTPUTS self.mk_tree = mk_tree self.sender_ownership_keypair = sender_ownership_keypair self.v_in = v_in self.v_out = v_out self.compute_h_sig_cb = compute_h_sig_cb # Perform some cleaning and minimal pre-processing of the data. Compute # and store data that is not derivable from the ProverInput or Proof # structs (such as the encryption keys for receivers), making it # available to MixerClient calls. # Expand inputs with dummy entries and compute merkle paths. sender_a_pk = sender_ownership_keypair.a_pk self.inputs = \ inputs + \ [get_dummy_input_and_address(sender_a_pk) for _ in range(constants.JS_INPUTS - len(inputs))] # Pad the list of outputs if necessary if len(outputs) < constants.JS_OUTPUTS: dummy_k_pk = generate_encryption_keypair().k_pk dummy_addr_pk = ZethAddressPub(sender_a_pk, dummy_k_pk) self.outputs = \ outputs + \ [(dummy_addr_pk, EtherValue(0)) for _ in range(constants.JS_OUTPUTS - len(outputs))] else: self.outputs = outputs
def create_mix_parameters_keep_signing_key( self, mk_tree: MerkleTree, sender_ownership_keypair: OwnershipKeyPair, sender_eth_address: str, inputs: List[Tuple[int, ZethNote]], outputs: List[Tuple[ZethAddressPub, EtherValue]], v_in: EtherValue, v_out: EtherValue, compute_h_sig_cb: Optional[ComputeHSigCB] = None ) -> Tuple[contracts.MixParameters, JoinsplitSigKeyPair]: assert len(inputs) <= constants.JS_INPUTS assert len(outputs) <= constants.JS_OUTPUTS sender_a_sk = sender_ownership_keypair.a_sk sender_a_pk = sender_ownership_keypair.a_pk inputs = \ inputs + \ [get_dummy_input_and_address(sender_a_pk) for _ in range(constants.JS_INPUTS - len(inputs))] mk_root = mk_tree.get_root() mk_paths = [compute_merkle_path(addr, mk_tree) for addr, _ in inputs] # Generate output notes and proof. Dummy outputs are constructed with # value 0 to an invalid ZethAddressPub, formed from the senders # a_pk, and an ephemeral k_pk. dummy_k_pk = generate_encryption_keypair().k_pk dummy_addr_pk = ZethAddressPub(sender_a_pk, dummy_k_pk) outputs = \ outputs + \ [(dummy_addr_pk, EtherValue(0)) for _ in range(constants.JS_OUTPUTS - len(outputs))] outputs_with_a_pk = \ [(zeth_addr.a_pk, to_zeth_units(value)) for (zeth_addr, value) in outputs] # Timer used to time proof-generation round trip time. timer = Timer.started() (output_note1, output_note2, extproof, signing_keypair) = \ self.get_proof_joinsplit_2_by_2( mk_root, inputs[0], mk_paths[0], inputs[1], mk_paths[1], sender_a_sk, outputs_with_a_pk[0], outputs_with_a_pk[1], to_zeth_units(v_in), to_zeth_units(v_out), compute_h_sig_cb) proof_gen_time_s = timer.elapsed_seconds() print(f"PROOF GEN ROUND TRIP: {proof_gen_time_s} seconds") # Encrypt the notes outputs_and_notes = zip(outputs, [output_note1, output_note2]) output_notes_with_k_pk = \ [(note, zeth_addr.k_pk) for ((zeth_addr, _), note) in outputs_and_notes] ciphertexts = encrypt_notes(output_notes_with_k_pk) # Sign signature = joinsplit_sign(signing_keypair, sender_eth_address, ciphertexts, extproof) mix_params = contracts.MixParameters(extproof, signing_keypair.vk, signature, ciphertexts) return mix_params, signing_keypair