Exemplo n.º 1
0
 def __init__(
         self,
         nested_snark_name: str,
         wrapper_snark_name: str,
         nested_pairing_parameters: PairingParameters,
         wrapper_pairing_parameters: PairingParameters):
     self.nested_snark_name = nested_snark_name
     self.wrapper_snark_name = wrapper_snark_name
     self.nested_snark = get_zksnark_provider(nested_snark_name)
     self.wrapper_snark = get_zksnark_provider(wrapper_snark_name)
     self.nested_pairing_parameters = nested_pairing_parameters
     self.wrapper_pairing_parameters = wrapper_pairing_parameters
Exemplo n.º 2
0
    def create_mix_parameters_from_proof(
            self, mix_call_desc: MixCallDescription,
            prover_inputs: ProofInputs,
            signing_keypair: signing.SigningKeyPair, ext_proof: ExtendedProof,
            sender_eth_address: str) -> MixParameters:

        # Encrypt the notes
        outputs_and_notes = zip(mix_call_desc.outputs, prover_inputs.js_outputs) \
            # pylint: disable=no-member

        output_notes_with_k_pk: List[Tuple[ZethNote, EncryptionPublicKey]] = \
            [(note, zeth_addr.k_pk)
             for ((zeth_addr, _), note) in outputs_and_notes]
        ciphertexts = encrypt_notes(output_notes_with_k_pk)

        # Sign
        zksnark = get_zksnark_provider(self.prover_config.zksnark_name)
        signature = joinsplit_sign(zksnark,
                                   self.prover_config.pairing_parameters,
                                   signing_keypair, sender_eth_address,
                                   ciphertexts, ext_proof)

        mix_params = MixParameters(ext_proof, signing_keypair.vk, signature,
                                   ciphertexts)
        return mix_params
Exemplo n.º 3
0
    def create_mix_parameters_and_signing_key(
        self,
        prover_client: ProverClient,
        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[MixParameters, JoinsplitSigKeyPair]:
        """
        Convenience function around creation of MixCallDescription, ProofInputs,
        Proof and MixParameters.
        """
        # Generate prover inputs and signing key
        mix_call_desc = MixCallDescription(mk_tree, sender_ownership_keypair,
                                           inputs, outputs, v_in, v_out,
                                           compute_h_sig_cb)
        prover_inputs, signing_keypair = MixerClient.create_prover_inputs(
            mix_call_desc)

        zksnark = get_zksnark_provider(self.prover_config.zksnark_name)

        # Query the prover_server for the related proof
        ext_proof_proto = prover_client.get_proof(prover_inputs)
        ext_proof = zksnark.extended_proof_from_proto(ext_proof_proto)

        # Create the final MixParameters object
        mix_params = self.create_mix_parameters_from_proof(
            mix_call_desc, prover_inputs, signing_keypair, ext_proof,
            sender_eth_address)

        return mix_params, signing_keypair
Exemplo n.º 4
0
 def open(web3: Any, prover_server_endpoint: str,
          mixer_instance: Any) -> MixerClient:
     """
     Create a client for an existing Zeth deployment.
     """
     return MixerClient(web3, ProverClient(prover_server_endpoint),
                        mixer_instance,
                        get_zksnark_provider(constants.ZKSNARK_DEFAULT))
Exemplo n.º 5
0
 def _create_mix_call(self, mix_parameters: MixParameters) -> Any:
     """
     Given a MixParameters object and other transaction properties, create a
     web3 call object, which can be used to create a transaction or a query.
     """
     zksnark = get_zksnark_provider(self.prover_config.zksnark_name)
     pp = self.prover_config.pairing_parameters
     mix_params_eth = mix_parameters_to_contract_arguments(
         zksnark, pp, mix_parameters)
     return self.mixer_instance.functions.mix(*mix_params_eth)
Exemplo n.º 6
0
    def deploy(
        web3: Any,
        prover_client: ProverClient,
        deployer_eth_address: str,
        deployer_eth_private_key: Optional[bytes],
        token_address: Optional[str] = None,
        permitted_dispatcher: Optional[str] = None,
        vk_hash: Optional[str] = None,
        deploy_gas: Optional[int] = None
    ) -> Tuple[MixerClient, contracts.InstanceDescription]:
        """
        Deploy Zeth contracts.
        """
        prover_config = prover_client.get_configuration()
        vk = prover_client.get_verification_key()

        contracts_dir = get_contracts_dir()
        zksnark = get_zksnark_provider(prover_config.zksnark_name)
        pp = prover_config.pairing_parameters
        mixer_name = zksnark.get_contract_name(pp)
        mixer_src = os.path.join(contracts_dir, mixer_name + ".sol")
        vk_hash_evm = list(hex_to_uint256_list(vk_hash)) if vk_hash else [0, 0]
        assert len(vk_hash_evm) == 2

        # Constructor parameters have the form:
        #   uint256 mk_depth
        #   address token
        #   ... snark-specific key data ...
        constructor_parameters: List[Any] = [
            constants.ZETH_MERKLE_TREE_DEPTH,  # mk_depth
            token_address or ZERO_ADDRESS,  # token
            zksnark.verification_key_to_contract_parameters(vk, pp),  # vk
            permitted_dispatcher or ZERO_ADDRESS,  # permitted_dispatcher
            vk_hash_evm  # vk_hash
        ]
        mixer_description = contracts.InstanceDescription.deploy(
            web3,
            mixer_src,
            mixer_name,
            deployer_eth_address,
            deployer_eth_private_key,
            deploy_gas,
            compiler_flags={},
            args=constructor_parameters)
        mixer_instance = mixer_description.instantiate(web3)
        client = MixerClient(web3, prover_config, mixer_instance)
        return client, mixer_description
Exemplo n.º 7
0
    def zklay_deposit(self,
                      deposit_params: DepositParameters,
                      sender_eth_address: str,
                      sender_eth_private_key: Optional[bytes],
                      tx_value: EtherValue,
                      call_gas: int = constants.DEFAULT_MIX_GAS_WEI) -> str:
        zksnark = get_zksnark_provider(self.prover_config.zksnark_name)
        pp = self.prover_config.pairing_parameters
        mix_params_eth = deposit_parameters_to_contract_arguments(
            zksnark, pp, deposit_params)

        deposit_call = self.mixer_instance.functions.deposit(
            *deposit_params_eth)
        tx_hash = contracts.send_contract_call(self.web3, deposit_call,
                                               sender_eth_address,
                                               sender_eth_private_key,
                                               tx_value,
                                               constants.DEFAULT_MIX_GAS_WEI)
        return tx_hash.hex()
Exemplo n.º 8
0
    def deploy(
        web3: Any,
        prover_client: ProverClient,
        deployer_eth_address: str,
        deployer_eth_private_key: Optional[bytes],
        token_address: Optional[str] = None,
        deploy_gas: Optional[int] = None
    ) -> Tuple[MixerClient, contracts.InstanceDescription]:
        """
        Deploy Zeth contracts.
        """
        prover_config = prover_client.get_configuration()
        zksnark = get_zksnark_provider(prover_config.zksnark_name)
        vk_proto = prover_client.get_verification_key()
        pp = prover_config.pairing_parameters
        vk = zksnark.verification_key_from_proto(vk_proto)
        deploy_gas = deploy_gas or constants.DEPLOYMENT_GAS_WEI

        contracts_dir = get_contracts_dir()
        mixer_name = zksnark.get_contract_name(pp)
        mixer_src = os.path.join(contracts_dir, mixer_name + ".sol")

        # Constructor parameters have the form:
        #   uint256 mk_depth
        #   address token
        #   ... snark-specific key data ...
        constructor_parameters: List[Any] = [
            constants.ZETH_MERKLE_TREE_DEPTH,  # mk_depth
            token_address or ZERO_ADDRESS,  # token
            zksnark.verification_key_to_contract_parameters(vk, pp),  # vk
        ]
        mixer_description = contracts.InstanceDescription.deploy(
            web3,
            mixer_src,
            mixer_name,
            deployer_eth_address,
            deployer_eth_private_key,
            deploy_gas,
            compiler_flags={},
            args=constructor_parameters)
        mixer_instance = mixer_description.instantiate(web3)
        client = MixerClient(web3, prover_config, mixer_instance)
        return client, mixer_description
Exemplo n.º 9
0
    def deploy(
            web3: Any,
            prover_server_endpoint: str,
            deployer_eth_address: str,
            deployer_eth_private_key: Optional[bytes],
            token_address: Optional[str] = None,
            deploy_gas: Optional[int] = None,
            zksnark: Optional[IZKSnarkProvider] = None) \
            -> Tuple[MixerClient, contracts.InstanceDescription]:
        """
        Deploy Zeth contracts.
        """
        print("[INFO] 1. Fetching verification key from the proving server")
        zksnark = zksnark or get_zksnark_provider(constants.ZKSNARK_DEFAULT)
        prover_client = ProverClient(prover_server_endpoint)
        vk_proto = prover_client.get_verification_key()
        vk = zksnark.verification_key_from_proto(vk_proto)
        deploy_gas = deploy_gas or constants.DEPLOYMENT_GAS_WEI

        print("[INFO] 2. Received VK, writing verification key...")
        write_verification_key(vk, "vk.json")

        print("[INFO] 3. VK written, deploying smart contracts...")
        contracts_dir = get_contracts_dir()
        mixer_name = zksnark.get_contract_name()
        mixer_src = os.path.join(contracts_dir, mixer_name + ".sol")

        verification_key_params = zksnark.verification_key_parameters(vk)
        mixer_description = contracts.InstanceDescription.deploy(
            web3,
            mixer_src,
            mixer_name,
            deployer_eth_address,
            deployer_eth_private_key,
            deploy_gas, {},
            mk_depth=constants.ZETH_MERKLE_TREE_DEPTH,
            token=token_address
            or "0x0000000000000000000000000000000000000000",
            **verification_key_params)
        mixer_instance = mixer_description.instantiate(web3)
        client = MixerClient(web3, prover_client, mixer_instance, zksnark)
        return client, mixer_description
Exemplo n.º 10
0
def create_nested_tx(zeth_tx_file: str, prover_config_file: str,
                     output_file: str) -> None:
    """
    Create a Zecale nested transaction from a zeth MixParameters object
    """

    # Load prover config (which is assumed to already exist)
    with open(prover_config_file, "r") as prover_config_f:
        prover_config = \
            ProverConfiguration.from_json_dict(json.load(prover_config_f))
    zksnark = zksnark = get_zksnark_provider(prover_config.zksnark_name)

    # Read the MixParameters
    with open(zeth_tx_file, "r") as zeth_tx_f:
        zeth_mix_params = \
            MixParameters.from_json_dict(zksnark, json.load(zeth_tx_f))

    # Convert to a nested transaction, and write to output file
    nested_tx = _create_zeth_nested_tx(zeth_mix_params, 0)
    with open(output_file, "w") as output_f:
        json.dump(nested_tx.to_json_dict(), output_f)
Exemplo n.º 11
0
    def create_mix_parameters_from_proof(
            self,
            mix_call_desc: MixCallDescription,
            prover_inputs: api.ProofInputs,
            signing_keypair: signing.SigningKeyPair,
            ext_proof: ExtendedProof,
            public_data: List[int],
            sender_eth_address: str,
            for_dispatch_call: bool = False) -> MixParameters:
        """
        Create the MixParameters from MixCallDescription, signing keypair, sender
        address and derived data (prover inputs and proof). This includes
        creating and encrypting the plaintext messages, and generating the
        one-time signature.

        If for_dispatch_call is set, the parameters are to be passed to the
        Mixer's `dispatch` call in a later operation (in which proof data is
        not available), hence proof is ommitted from the signature.
        """

        # Encrypt the notes
        outputs_and_notes = zip(mix_call_desc.outputs, prover_inputs.js_outputs) \
            # pylint: disable=no-member

        output_notes_with_k_pk: List[Tuple[api.ZethNote, EncryptionPublicKey]] = \
            [(note, zeth_addr.k_pk)
             for ((zeth_addr, _), note) in outputs_and_notes]
        ciphertexts = encrypt_notes(output_notes_with_k_pk)

        # Sign
        zksnark = get_zksnark_provider(self.prover_config.zksnark_name)
        signature = joinsplit_sign(zksnark,
                                   self.prover_config.pairing_parameters,
                                   signing_keypair, sender_eth_address,
                                   ciphertexts, ext_proof, public_data,
                                   for_dispatch_call)

        mix_params = MixParameters(ext_proof, public_data, signing_keypair.vk,
                                   signature, ciphertexts)
        return mix_params
Exemplo n.º 12
0
 def get_zksnark_provider(self) -> IZKSnarkProvider:
     """
     Get the appropriate zksnark provider, based on the server configuration.
     """
     config = self.get_configuration()
     return get_zksnark_provider(config.zksnark_name)