From dd0773dbb344d2aa57b31dbea3e27c6cee5e099d Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Fri, 1 Jan 2021 11:28:40 +0000 Subject: [PATCH 001/137] Updated copyright headers to 2021 --- client/py.typed | 2 +- client/setup.py | 2 +- client/test_commands/__init__.py | 2 +- client/test_commands/deploy_test_token.py | 2 +- client/test_commands/mock.py | 2 +- client/test_commands/scenario.py | 2 +- client/test_commands/test_altbn128_mixer_base.py | 2 +- client/test_commands/test_bls12_377_contract.py | 2 +- client/test_commands/test_bw6_761_contract.py | 2 +- client/test_commands/test_erc_token_mixing.py | 2 +- client/test_commands/test_ether_mixing.py | 2 +- client/test_commands/test_groth16_bls12_377_contract.py | 2 +- client/test_commands/test_merkle_tree_contract.py | 2 +- client/test_commands/test_mimc_contract.py | 2 +- client/tests/__init__.py | 2 +- client/tests/test_contracts.py | 2 +- client/tests/test_encryption.py | 2 +- client/tests/test_ethervalue.py | 2 +- client/tests/test_joinsplit.py | 2 +- client/tests/test_merkle_tree.py | 2 +- client/tests/test_mimc.py | 2 +- client/tests/test_mixer_client.py | 2 +- client/tests/test_pairing.py | 2 +- client/tests/test_signing.py | 2 +- client/tests/test_zksnark.py | 2 +- client/zeth/__init__.py | 2 +- client/zeth/api/__init__.py | 2 +- client/zeth/api/py.typed | 2 +- client/zeth/cli/__init__.py | 2 +- client/zeth/cli/constants.py | 2 +- client/zeth/cli/py.typed | 2 +- client/zeth/cli/utils.py | 2 +- client/zeth/cli/zeth | 2 +- client/zeth/cli/zeth_deploy.py | 2 +- client/zeth/cli/zeth_gen_address.py | 2 +- client/zeth/cli/zeth_ls_commits.py | 2 +- client/zeth/cli/zeth_ls_notes.py | 2 +- client/zeth/cli/zeth_mix.py | 2 +- client/zeth/cli/zeth_sync.py | 2 +- client/zeth/core/__init__.py | 2 +- client/zeth/core/constants.py | 2 +- client/zeth/core/contracts.py | 2 +- client/zeth/core/encryption.py | 2 +- client/zeth/core/errors.py | 2 +- client/zeth/core/merkle_tree.py | 2 +- client/zeth/core/mimc.py | 2 +- client/zeth/core/mixer_client.py | 2 +- client/zeth/core/ownership.py | 2 +- client/zeth/core/pairing.py | 2 +- client/zeth/core/proto_utils.py | 2 +- client/zeth/core/prover_client.py | 2 +- client/zeth/core/py.typed | 2 +- client/zeth/core/signing.py | 2 +- client/zeth/core/timer.py | 2 +- client/zeth/core/utils.py | 2 +- client/zeth/core/wallet.py | 2 +- client/zeth/core/zeth_address.py | 2 +- client/zeth/core/zksnark.py | 2 +- client/zeth/helper/__init__.py | 2 +- client/zeth/helper/eth_fund.py | 2 +- client/zeth/helper/eth_gen_address.py | 2 +- client/zeth/helper/eth_gen_network_config.py | 2 +- client/zeth/helper/eth_get_balance.py | 2 +- client/zeth/helper/eth_send.py | 2 +- client/zeth/helper/token_approve.py | 2 +- client/zeth/helper/zeth_helper | 2 +- debug/analyzer/__init__.py | 2 +- debug/analyzer/parse_r1cs.py | 2 +- libzeth/circuits/binary_operation.hpp | 2 +- libzeth/circuits/binary_operation.tcc | 2 +- libzeth/circuits/blake2s/blake2s.hpp | 2 +- libzeth/circuits/blake2s/blake2s.tcc | 2 +- libzeth/circuits/blake2s/blake2s_comp.hpp | 2 +- libzeth/circuits/blake2s/blake2s_comp.tcc | 2 +- libzeth/circuits/blake2s/blake2s_comp_setup.tcc | 2 +- libzeth/circuits/blake2s/g_primitive.hpp | 2 +- libzeth/circuits/blake2s/g_primitive.tcc | 2 +- libzeth/circuits/circuit_types.hpp | 2 +- libzeth/circuits/circuit_utils.hpp | 2 +- libzeth/circuits/circuit_utils.tcc | 2 +- libzeth/circuits/circuit_wrapper.hpp | 2 +- libzeth/circuits/circuit_wrapper.tcc | 2 +- libzeth/circuits/joinsplit.tcc | 2 +- libzeth/circuits/mimc/mimc_round.hpp | 2 +- libzeth/circuits/mimc/mimc_round.tcc | 2 +- libzeth/circuits/prfs/prf.hpp | 2 +- libzeth/circuits/prfs/prf.tcc | 2 +- libzeth/circuits/safe_arithmetic.cpp | 2 +- libzeth/circuits/safe_arithmetic.hpp | 2 +- libzeth/core/bits.cpp | 2 +- libzeth/core/bits.hpp | 2 +- libzeth/core/bits.tcc | 2 +- libzeth/core/chacha_rng.cpp | 2 +- libzeth/core/chacha_rng.hpp | 2 +- libzeth/core/evaluator_from_lagrange.hpp | 2 +- libzeth/core/evaluator_from_lagrange.tcc | 2 +- libzeth/core/extended_proof.hpp | 2 +- libzeth/core/extended_proof.tcc | 2 +- libzeth/core/field_element_utils.hpp | 2 +- libzeth/core/field_element_utils.tcc | 2 +- libzeth/core/group_element_utils.hpp | 2 +- libzeth/core/group_element_utils.tcc | 2 +- libzeth/core/hash_stream.hpp | 2 +- libzeth/core/hash_stream.tcc | 2 +- libzeth/core/include_libff.hpp | 2 +- libzeth/core/include_libsnark.hpp | 2 +- libzeth/core/joinsplit_input.hpp | 2 +- libzeth/core/multi_exp.hpp | 2 +- libzeth/core/multi_exp.tcc | 2 +- libzeth/core/note.hpp | 2 +- libzeth/core/utils.cpp | 2 +- libzeth/core/utils.hpp | 2 +- libzeth/core/utils.tcc | 2 +- libzeth/mpc/groth16/mpc_hash.cpp | 2 +- libzeth/mpc/groth16/mpc_hash.hpp | 2 +- libzeth/mpc/groth16/mpc_utils.hpp | 2 +- libzeth/mpc/groth16/mpc_utils.tcc | 2 +- libzeth/mpc/groth16/phase2.hpp | 2 +- libzeth/mpc/groth16/phase2.tcc | 2 +- libzeth/mpc/groth16/powersoftau_utils.cpp | 2 +- libzeth/mpc/groth16/powersoftau_utils.hpp | 2 +- libzeth/mpc/groth16/powersoftau_utils.tcc | 2 +- libzeth/serialization/filesystem_util.cpp | 2 +- libzeth/serialization/filesystem_util.hpp | 2 +- libzeth/serialization/proto_utils.cpp | 2 +- libzeth/serialization/proto_utils.hpp | 2 +- libzeth/serialization/proto_utils.tcc | 2 +- libzeth/serialization/r1cs_serialization.hpp | 2 +- libzeth/serialization/r1cs_serialization.tcc | 2 +- libzeth/snarks/groth16/groth16_api_handler.hpp | 2 +- libzeth/snarks/groth16/groth16_api_handler.tcc | 2 +- libzeth/snarks/groth16/groth16_snark.hpp | 2 +- libzeth/snarks/groth16/groth16_snark.tcc | 2 +- libzeth/snarks/pghr13/pghr13_api_handler.hpp | 2 +- libzeth/snarks/pghr13/pghr13_api_handler.tcc | 2 +- libzeth/snarks/pghr13/pghr13_snark.hpp | 2 +- libzeth/snarks/pghr13/pghr13_snark.tcc | 2 +- libzeth/tests/circuits/binary_operation_test.cpp | 2 +- libzeth/tests/circuits/blake2s_test.cpp | 2 +- libzeth/tests/circuits/commitments_test.cpp | 2 +- libzeth/tests/circuits/merkle_tree_test.cpp | 2 +- libzeth/tests/circuits/mimc_mp_test.cpp | 2 +- libzeth/tests/circuits/note_test.cpp | 2 +- libzeth/tests/circuits/packed_addition_test.cpp | 2 +- libzeth/tests/circuits/prfs_test.cpp | 2 +- libzeth/tests/circuits/sha256_test.cpp | 2 +- libzeth/tests/circuits/simple_test.cpp | 2 +- libzeth/tests/circuits/simple_test.hpp | 2 +- libzeth/tests/circuits/simple_test.tcc | 2 +- libzeth/tests/core/bits_test.cpp | 2 +- libzeth/tests/core/chacha_test.cpp | 2 +- libzeth/tests/core/ec_operation_data_test.cpp | 2 +- libzeth/tests/core/evaluator_from_lagrange_test.cpp | 2 +- libzeth/tests/core/field_element_utils_test.cpp | 2 +- libzeth/tests/core/group_element_utils_test.cpp | 2 +- libzeth/tests/core/utils_test.cpp | 2 +- libzeth/tests/mpc/groth16/mpc_hash_test.cpp | 2 +- libzeth/tests/mpc/groth16/mpc_test.cpp | 2 +- libzeth/tests/mpc/groth16/powersoftau_test.cpp | 2 +- libzeth/tests/prover/prover_test.cpp | 2 +- libzeth/tests/serialization/proto_utils_test.cpp | 2 +- libzeth/tests/serialization/r1cs_serialization_test.cpp | 2 +- libzeth/tests/snarks/common_api_tests.tcc | 2 +- libzeth/tests/snarks/groth16/groth16_api_handler_test.cpp | 2 +- libzeth/tests/snarks/pghr13/pghr13_api_handler_test.cpp | 2 +- libzeth/zeth_constants.hpp | 2 +- mpc/commands/__init__.py | 2 +- mpc/commands/constants.py | 2 +- mpc/commands/contributors_from_csv | 2 +- mpc/commands/create_keypair | 2 +- mpc/commands/generate_key | 2 +- mpc/commands/get_challenge | 2 +- mpc/commands/phase1_contribute | 2 +- mpc/commands/phase1_server | 2 +- mpc/commands/phase2_contribute | 2 +- mpc/commands/phase2_prepare | 2 +- mpc/commands/phase2_server | 2 +- mpc/commands/public_key | 2 +- mpc/commands/public_key_operations.py | 2 +- mpc/commands/sign_contribution | 2 +- mpc/commands/upload_contribution | 2 +- mpc/coordinator/__init__.py | 2 +- mpc/coordinator/client.py | 2 +- mpc/coordinator/contribute.py | 2 +- mpc/coordinator/contributor_list.py | 2 +- mpc/coordinator/crypto.py | 2 +- mpc/coordinator/icontributionhandler.py | 2 +- mpc/coordinator/interval.py | 2 +- mpc/coordinator/mpc_command.py | 2 +- mpc/coordinator/null_contribution_handler.py | 2 +- mpc/coordinator/phase1_contribution_handler.py | 2 +- mpc/coordinator/phase2_contribution_handler.py | 2 +- mpc/coordinator/powersoftau_command.py | 2 +- mpc/coordinator/powersoftau_process_command.py | 2 +- mpc/coordinator/server.py | 2 +- mpc/coordinator/server_configuration.py | 2 +- mpc/coordinator/server_state.py | 2 +- mpc/coordinator/upload_utils.py | 2 +- mpc/setup.py | 2 +- mpc/test/__init__.py | 2 +- mpc/test/test_crypto.py | 2 +- mpc/test/test_server_state.py | 2 +- mpc_tools/mpc_phase2/cli/mpc_common.cpp | 2 +- mpc_tools/mpc_phase2/cli/mpc_common.hpp | 2 +- mpc_tools/mpc_phase2/cli/mpc_create_keypair.cpp | 2 +- mpc_tools/mpc_phase2/cli/mpc_dummy_phase2.cpp | 2 +- mpc_tools/mpc_phase2/cli/mpc_linear_combination.cpp | 2 +- mpc_tools/mpc_phase2/cli/mpc_phase2_begin.cpp | 2 +- mpc_tools/mpc_phase2/cli/mpc_phase2_contribute.cpp | 2 +- mpc_tools/mpc_phase2/cli/mpc_phase2_verify_contribution.cpp | 2 +- mpc_tools/mpc_phase2/cli/mpc_phase2_verify_transcript.cpp | 2 +- mpc_tools/mpc_phase2/mpc_client.cpp | 2 +- mpc_tools/mpc_phase2/mpc_coord.cpp | 2 +- mpc_tools/mpc_phase2/test/mpc_test_cli.cpp | 2 +- mpc_tools/pot_process/pot_process.cpp | 2 +- prover_server/prover_server.cpp | 4 ++-- scripts/mimc_round_constants_generation.py | 2 +- zeth_config.h.in | 2 +- zeth_contracts/contracts/AltBN128MixerBase.sol | 2 +- zeth_contracts/contracts/AltBN128MixerBase_test.sol | 2 +- zeth_contracts/contracts/BLS12_377MixerBase.sol | 2 +- zeth_contracts/contracts/BLS12_377_test.sol | 2 +- zeth_contracts/contracts/BW6_761_test.sol | 2 +- zeth_contracts/contracts/BaseMerkleTree.sol | 2 +- zeth_contracts/contracts/Groth16AltBN128.sol | 2 +- zeth_contracts/contracts/Groth16AltBN128Mixer.sol | 2 +- zeth_contracts/contracts/Groth16BLS12_377.sol | 2 +- zeth_contracts/contracts/Groth16BLS12_377Mixer.sol | 2 +- zeth_contracts/contracts/Groth16BLS12_377_test.sol | 2 +- zeth_contracts/contracts/MerkleTreeMiMC7_test.sol | 2 +- zeth_contracts/contracts/MerkleTreeSha256.sol | 2 +- zeth_contracts/contracts/MiMC31.sol | 2 +- zeth_contracts/contracts/MiMC7.sol | 2 +- zeth_contracts/contracts/MiMC_test.sol | 2 +- zeth_contracts/contracts/Migrations.sol | 2 +- zeth_contracts/contracts/MixerBase.sol | 2 +- zeth_contracts/contracts/OTSchnorrVerifier.sol | 2 +- zeth_contracts/contracts/Pairing.sol | 2 +- zeth_contracts/contracts/Pghr13AltBN128Mixer.sol | 2 +- zeth_contracts/contracts/Tokens.sol | 2 +- 240 files changed, 241 insertions(+), 241 deletions(-) diff --git a/client/py.typed b/client/py.typed index a0c5d77b1..58db294ed 100644 --- a/client/py.typed +++ b/client/py.typed @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/setup.py b/client/setup.py index 6449ec5f6..2c7b8ed0b 100644 --- a/client/setup.py +++ b/client/setup.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/test_commands/__init__.py b/client/test_commands/__init__.py index 6fb9229d2..f50145434 100644 --- a/client/test_commands/__init__.py +++ b/client/test_commands/__init__.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/test_commands/deploy_test_token.py b/client/test_commands/deploy_test_token.py index 1cabf79a7..56973230d 100644 --- a/client/test_commands/deploy_test_token.py +++ b/client/test_commands/deploy_test_token.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/test_commands/mock.py b/client/test_commands/mock.py index 7163028f4..f683d22ad 100644 --- a/client/test_commands/mock.py +++ b/client/test_commands/mock.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/test_commands/scenario.py b/client/test_commands/scenario.py index 1029b4e1e..635a76aa0 100644 --- a/client/test_commands/scenario.py +++ b/client/test_commands/scenario.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/test_commands/test_altbn128_mixer_base.py b/client/test_commands/test_altbn128_mixer_base.py index dcc6b6253..3cb4d0cbe 100644 --- a/client/test_commands/test_altbn128_mixer_base.py +++ b/client/test_commands/test_altbn128_mixer_base.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/test_commands/test_bls12_377_contract.py b/client/test_commands/test_bls12_377_contract.py index 453695fbf..c75bd7703 100644 --- a/client/test_commands/test_bls12_377_contract.py +++ b/client/test_commands/test_bls12_377_contract.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/test_commands/test_bw6_761_contract.py b/client/test_commands/test_bw6_761_contract.py index f6bd6483b..fcbf1045d 100644 --- a/client/test_commands/test_bw6_761_contract.py +++ b/client/test_commands/test_bw6_761_contract.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/test_commands/test_erc_token_mixing.py b/client/test_commands/test_erc_token_mixing.py index 0ffea8e63..912ac2cd1 100644 --- a/client/test_commands/test_erc_token_mixing.py +++ b/client/test_commands/test_erc_token_mixing.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/test_commands/test_ether_mixing.py b/client/test_commands/test_ether_mixing.py index 7306dca54..8d5db1803 100644 --- a/client/test_commands/test_ether_mixing.py +++ b/client/test_commands/test_ether_mixing.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/test_commands/test_groth16_bls12_377_contract.py b/client/test_commands/test_groth16_bls12_377_contract.py index dffa5fe39..acb6caa02 100644 --- a/client/test_commands/test_groth16_bls12_377_contract.py +++ b/client/test_commands/test_groth16_bls12_377_contract.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/test_commands/test_merkle_tree_contract.py b/client/test_commands/test_merkle_tree_contract.py index 586ba04d9..7e6523aa6 100644 --- a/client/test_commands/test_merkle_tree_contract.py +++ b/client/test_commands/test_merkle_tree_contract.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/test_commands/test_mimc_contract.py b/client/test_commands/test_mimc_contract.py index dc965844f..1c986c14d 100644 --- a/client/test_commands/test_mimc_contract.py +++ b/client/test_commands/test_mimc_contract.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/tests/__init__.py b/client/tests/__init__.py index 6fb9229d2..f50145434 100644 --- a/client/tests/__init__.py +++ b/client/tests/__init__.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/tests/test_contracts.py b/client/tests/test_contracts.py index 275fbdc53..0fa9a386c 100644 --- a/client/tests/test_contracts.py +++ b/client/tests/test_contracts.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/tests/test_encryption.py b/client/tests/test_encryption.py index d9750e328..2ff86b710 100644 --- a/client/tests/test_encryption.py +++ b/client/tests/test_encryption.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/tests/test_ethervalue.py b/client/tests/test_ethervalue.py index ef0be2701..e26d9be16 100644 --- a/client/tests/test_ethervalue.py +++ b/client/tests/test_ethervalue.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/tests/test_joinsplit.py b/client/tests/test_joinsplit.py index f137ff3ab..7722c5bc9 100644 --- a/client/tests/test_joinsplit.py +++ b/client/tests/test_joinsplit.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/tests/test_merkle_tree.py b/client/tests/test_merkle_tree.py index 45e511407..85a0937e1 100644 --- a/client/tests/test_merkle_tree.py +++ b/client/tests/test_merkle_tree.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/tests/test_mimc.py b/client/tests/test_mimc.py index a6d3e8994..d1a1ff8da 100644 --- a/client/tests/test_mimc.py +++ b/client/tests/test_mimc.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/tests/test_mixer_client.py b/client/tests/test_mixer_client.py index 3115d7304..977b8e6bd 100644 --- a/client/tests/test_mixer_client.py +++ b/client/tests/test_mixer_client.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/tests/test_pairing.py b/client/tests/test_pairing.py index e2b4821d6..12e40a159 100644 --- a/client/tests/test_pairing.py +++ b/client/tests/test_pairing.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/tests/test_signing.py b/client/tests/test_signing.py index 9d43df6eb..b88071405 100644 --- a/client/tests/test_signing.py +++ b/client/tests/test_signing.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/tests/test_zksnark.py b/client/tests/test_zksnark.py index 8afe5f494..73fe37c28 100644 --- a/client/tests/test_zksnark.py +++ b/client/tests/test_zksnark.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/__init__.py b/client/zeth/__init__.py index b6e016d34..fca72ddb7 100644 --- a/client/zeth/__init__.py +++ b/client/zeth/__init__.py @@ -1,3 +1,3 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/api/__init__.py b/client/zeth/api/__init__.py index b6e016d34..fca72ddb7 100644 --- a/client/zeth/api/__init__.py +++ b/client/zeth/api/__init__.py @@ -1,3 +1,3 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/api/py.typed b/client/zeth/api/py.typed index a0c5d77b1..58db294ed 100644 --- a/client/zeth/api/py.typed +++ b/client/zeth/api/py.typed @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/cli/__init__.py b/client/zeth/cli/__init__.py index b6e016d34..fca72ddb7 100644 --- a/client/zeth/cli/__init__.py +++ b/client/zeth/cli/__init__.py @@ -1,3 +1,3 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/cli/constants.py b/client/zeth/cli/constants.py index b7df75cdc..598dd677e 100644 --- a/client/zeth/cli/constants.py +++ b/client/zeth/cli/constants.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/cli/py.typed b/client/zeth/cli/py.typed index a0c5d77b1..58db294ed 100644 --- a/client/zeth/cli/py.typed +++ b/client/zeth/cli/py.typed @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/cli/utils.py b/client/zeth/cli/utils.py index 78fddac44..081976611 100644 --- a/client/zeth/cli/utils.py +++ b/client/zeth/cli/utils.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/cli/zeth b/client/zeth/cli/zeth index ba248de18..cf4b8d7e6 100644 --- a/client/zeth/cli/zeth +++ b/client/zeth/cli/zeth @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/cli/zeth_deploy.py b/client/zeth/cli/zeth_deploy.py index 49dbeb162..cfc4f3767 100644 --- a/client/zeth/cli/zeth_deploy.py +++ b/client/zeth/cli/zeth_deploy.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/cli/zeth_gen_address.py b/client/zeth/cli/zeth_gen_address.py index 28702210f..75783fd03 100644 --- a/client/zeth/cli/zeth_gen_address.py +++ b/client/zeth/cli/zeth_gen_address.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/cli/zeth_ls_commits.py b/client/zeth/cli/zeth_ls_commits.py index f0d835bf4..e658597d3 100644 --- a/client/zeth/cli/zeth_ls_commits.py +++ b/client/zeth/cli/zeth_ls_commits.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/cli/zeth_ls_notes.py b/client/zeth/cli/zeth_ls_notes.py index 961707395..b7d63509a 100644 --- a/client/zeth/cli/zeth_ls_notes.py +++ b/client/zeth/cli/zeth_ls_notes.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/cli/zeth_mix.py b/client/zeth/cli/zeth_mix.py index e35c8deb0..af3c08a5c 100644 --- a/client/zeth/cli/zeth_mix.py +++ b/client/zeth/cli/zeth_mix.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/cli/zeth_sync.py b/client/zeth/cli/zeth_sync.py index 2954806ff..929f5ff93 100644 --- a/client/zeth/cli/zeth_sync.py +++ b/client/zeth/cli/zeth_sync.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/__init__.py b/client/zeth/core/__init__.py index 6fb9229d2..f50145434 100644 --- a/client/zeth/core/__init__.py +++ b/client/zeth/core/__init__.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/constants.py b/client/zeth/core/constants.py index a90a804c6..050b19b10 100644 --- a/client/zeth/core/constants.py +++ b/client/zeth/core/constants.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/contracts.py b/client/zeth/core/contracts.py index b86292b69..139ab4498 100644 --- a/client/zeth/core/contracts.py +++ b/client/zeth/core/contracts.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/encryption.py b/client/zeth/core/encryption.py index 7bd636ad2..0d3367fc5 100644 --- a/client/zeth/core/encryption.py +++ b/client/zeth/core/encryption.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/errors.py b/client/zeth/core/errors.py index a9fdb2896..7906354de 100644 --- a/client/zeth/core/errors.py +++ b/client/zeth/core/errors.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/merkle_tree.py b/client/zeth/core/merkle_tree.py index beecf66ba..db97af6c4 100644 --- a/client/zeth/core/merkle_tree.py +++ b/client/zeth/core/merkle_tree.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/mimc.py b/client/zeth/core/mimc.py index 23993fd08..d94bc81c2 100644 --- a/client/zeth/core/mimc.py +++ b/client/zeth/core/mimc.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/mixer_client.py b/client/zeth/core/mixer_client.py index 04ba7d20e..a3d810a25 100644 --- a/client/zeth/core/mixer_client.py +++ b/client/zeth/core/mixer_client.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/ownership.py b/client/zeth/core/ownership.py index a684067f1..601dd4d70 100644 --- a/client/zeth/core/ownership.py +++ b/client/zeth/core/ownership.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/pairing.py b/client/zeth/core/pairing.py index d6d26b389..7ba927422 100644 --- a/client/zeth/core/pairing.py +++ b/client/zeth/core/pairing.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/proto_utils.py b/client/zeth/core/proto_utils.py index ea4db3484..a8f9def23 100644 --- a/client/zeth/core/proto_utils.py +++ b/client/zeth/core/proto_utils.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/prover_client.py b/client/zeth/core/prover_client.py index 775d8b9bc..8b6095007 100644 --- a/client/zeth/core/prover_client.py +++ b/client/zeth/core/prover_client.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/py.typed b/client/zeth/core/py.typed index a0c5d77b1..58db294ed 100644 --- a/client/zeth/core/py.typed +++ b/client/zeth/core/py.typed @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/signing.py b/client/zeth/core/signing.py index f725647c8..58d0261f5 100644 --- a/client/zeth/core/signing.py +++ b/client/zeth/core/signing.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/timer.py b/client/zeth/core/timer.py index c56eadda1..94c3632cc 100644 --- a/client/zeth/core/timer.py +++ b/client/zeth/core/timer.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/utils.py b/client/zeth/core/utils.py index f97fc0cdd..9e0587fbd 100644 --- a/client/zeth/core/utils.py +++ b/client/zeth/core/utils.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/wallet.py b/client/zeth/core/wallet.py index 029688937..2ae054ca1 100644 --- a/client/zeth/core/wallet.py +++ b/client/zeth/core/wallet.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/zeth_address.py b/client/zeth/core/zeth_address.py index 30d692114..0479920ce 100644 --- a/client/zeth/core/zeth_address.py +++ b/client/zeth/core/zeth_address.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/core/zksnark.py b/client/zeth/core/zksnark.py index d795c43e1..f78eaf400 100644 --- a/client/zeth/core/zksnark.py +++ b/client/zeth/core/zksnark.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/helper/__init__.py b/client/zeth/helper/__init__.py index b6e016d34..fca72ddb7 100644 --- a/client/zeth/helper/__init__.py +++ b/client/zeth/helper/__init__.py @@ -1,3 +1,3 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/helper/eth_fund.py b/client/zeth/helper/eth_fund.py index 634f1f3ed..3e02fac6f 100644 --- a/client/zeth/helper/eth_fund.py +++ b/client/zeth/helper/eth_fund.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/helper/eth_gen_address.py b/client/zeth/helper/eth_gen_address.py index 1a30e71c7..8b2ba0520 100644 --- a/client/zeth/helper/eth_gen_address.py +++ b/client/zeth/helper/eth_gen_address.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/helper/eth_gen_network_config.py b/client/zeth/helper/eth_gen_network_config.py index bad321885..b1b907a4b 100644 --- a/client/zeth/helper/eth_gen_network_config.py +++ b/client/zeth/helper/eth_gen_network_config.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/helper/eth_get_balance.py b/client/zeth/helper/eth_get_balance.py index c3ebeb948..4aa5e662a 100644 --- a/client/zeth/helper/eth_get_balance.py +++ b/client/zeth/helper/eth_get_balance.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/helper/eth_send.py b/client/zeth/helper/eth_send.py index 6c4caf542..c1906e282 100644 --- a/client/zeth/helper/eth_send.py +++ b/client/zeth/helper/eth_send.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/helper/token_approve.py b/client/zeth/helper/token_approve.py index 54904bc21..350400efc 100644 --- a/client/zeth/helper/token_approve.py +++ b/client/zeth/helper/token_approve.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/zeth/helper/zeth_helper b/client/zeth/helper/zeth_helper index 2264e1204..0bdbf5a6b 100644 --- a/client/zeth/helper/zeth_helper +++ b/client/zeth/helper/zeth_helper @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/debug/analyzer/__init__.py b/debug/analyzer/__init__.py index 2bb908d40..830ea092f 100644 --- a/debug/analyzer/__init__.py +++ b/debug/analyzer/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/debug/analyzer/parse_r1cs.py b/debug/analyzer/parse_r1cs.py index 75c2ebb2a..8e9836f21 100644 --- a/debug/analyzer/parse_r1cs.py +++ b/debug/analyzer/parse_r1cs.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/binary_operation.hpp b/libzeth/circuits/binary_operation.hpp index 159d4d872..543eb6846 100644 --- a/libzeth/circuits/binary_operation.hpp +++ b/libzeth/circuits/binary_operation.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/binary_operation.tcc b/libzeth/circuits/binary_operation.tcc index f65cd766a..1f812f9be 100644 --- a/libzeth/circuits/binary_operation.tcc +++ b/libzeth/circuits/binary_operation.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/blake2s/blake2s.hpp b/libzeth/circuits/blake2s/blake2s.hpp index c7d593ebc..707ede6b5 100644 --- a/libzeth/circuits/blake2s/blake2s.hpp +++ b/libzeth/circuits/blake2s/blake2s.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/blake2s/blake2s.tcc b/libzeth/circuits/blake2s/blake2s.tcc index 6060e7c63..2191d666b 100644 --- a/libzeth/circuits/blake2s/blake2s.tcc +++ b/libzeth/circuits/blake2s/blake2s.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/blake2s/blake2s_comp.hpp b/libzeth/circuits/blake2s/blake2s_comp.hpp index 3ada4f95d..55b635996 100644 --- a/libzeth/circuits/blake2s/blake2s_comp.hpp +++ b/libzeth/circuits/blake2s/blake2s_comp.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/blake2s/blake2s_comp.tcc b/libzeth/circuits/blake2s/blake2s_comp.tcc index 5a0aef193..e09ea6626 100644 --- a/libzeth/circuits/blake2s/blake2s_comp.tcc +++ b/libzeth/circuits/blake2s/blake2s_comp.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/blake2s/blake2s_comp_setup.tcc b/libzeth/circuits/blake2s/blake2s_comp_setup.tcc index bebf05148..8612af1c7 100644 --- a/libzeth/circuits/blake2s/blake2s_comp_setup.tcc +++ b/libzeth/circuits/blake2s/blake2s_comp_setup.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/blake2s/g_primitive.hpp b/libzeth/circuits/blake2s/g_primitive.hpp index dc5c08df0..70c07a31c 100644 --- a/libzeth/circuits/blake2s/g_primitive.hpp +++ b/libzeth/circuits/blake2s/g_primitive.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/blake2s/g_primitive.tcc b/libzeth/circuits/blake2s/g_primitive.tcc index b05ad3dea..8cd6b8bb6 100644 --- a/libzeth/circuits/blake2s/g_primitive.tcc +++ b/libzeth/circuits/blake2s/g_primitive.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/circuit_types.hpp b/libzeth/circuits/circuit_types.hpp index 83305eefd..fe2817fe4 100644 --- a/libzeth/circuits/circuit_types.hpp +++ b/libzeth/circuits/circuit_types.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/circuit_utils.hpp b/libzeth/circuits/circuit_utils.hpp index e97616116..43f029c52 100644 --- a/libzeth/circuits/circuit_utils.hpp +++ b/libzeth/circuits/circuit_utils.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/circuit_utils.tcc b/libzeth/circuits/circuit_utils.tcc index 4ac2b7a2c..197ea9e6e 100644 --- a/libzeth/circuits/circuit_utils.tcc +++ b/libzeth/circuits/circuit_utils.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/circuit_wrapper.hpp b/libzeth/circuits/circuit_wrapper.hpp index cbc885be8..a9a6240ac 100644 --- a/libzeth/circuits/circuit_wrapper.hpp +++ b/libzeth/circuits/circuit_wrapper.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/circuit_wrapper.tcc b/libzeth/circuits/circuit_wrapper.tcc index cc0ec0792..77adbb937 100644 --- a/libzeth/circuits/circuit_wrapper.tcc +++ b/libzeth/circuits/circuit_wrapper.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/joinsplit.tcc b/libzeth/circuits/joinsplit.tcc index d04341df0..edbd35ed4 100644 --- a/libzeth/circuits/joinsplit.tcc +++ b/libzeth/circuits/joinsplit.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/mimc/mimc_round.hpp b/libzeth/circuits/mimc/mimc_round.hpp index 508bf0fbb..be80016bd 100644 --- a/libzeth/circuits/mimc/mimc_round.hpp +++ b/libzeth/circuits/mimc/mimc_round.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/mimc/mimc_round.tcc b/libzeth/circuits/mimc/mimc_round.tcc index 7185104de..33051b903 100644 --- a/libzeth/circuits/mimc/mimc_round.tcc +++ b/libzeth/circuits/mimc/mimc_round.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/prfs/prf.hpp b/libzeth/circuits/prfs/prf.hpp index 20fa67e95..d0b12090b 100644 --- a/libzeth/circuits/prfs/prf.hpp +++ b/libzeth/circuits/prfs/prf.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/prfs/prf.tcc b/libzeth/circuits/prfs/prf.tcc index b74c2f883..644975507 100644 --- a/libzeth/circuits/prfs/prf.tcc +++ b/libzeth/circuits/prfs/prf.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/safe_arithmetic.cpp b/libzeth/circuits/safe_arithmetic.cpp index 978fe6cb3..29b4640f6 100644 --- a/libzeth/circuits/safe_arithmetic.cpp +++ b/libzeth/circuits/safe_arithmetic.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/circuits/safe_arithmetic.hpp b/libzeth/circuits/safe_arithmetic.hpp index 4ba0c87f6..48e1aa2c4 100644 --- a/libzeth/circuits/safe_arithmetic.hpp +++ b/libzeth/circuits/safe_arithmetic.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/bits.cpp b/libzeth/core/bits.cpp index 557a56fec..28dbe8f2e 100644 --- a/libzeth/core/bits.cpp +++ b/libzeth/core/bits.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/bits.hpp b/libzeth/core/bits.hpp index ba8c6ee96..e717796dc 100644 --- a/libzeth/core/bits.hpp +++ b/libzeth/core/bits.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/bits.tcc b/libzeth/core/bits.tcc index e12453f1b..8c0bb87a9 100644 --- a/libzeth/core/bits.tcc +++ b/libzeth/core/bits.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/chacha_rng.cpp b/libzeth/core/chacha_rng.cpp index 13c04ed32..2e062b850 100644 --- a/libzeth/core/chacha_rng.cpp +++ b/libzeth/core/chacha_rng.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/chacha_rng.hpp b/libzeth/core/chacha_rng.hpp index 6aec3801a..4425f34c8 100644 --- a/libzeth/core/chacha_rng.hpp +++ b/libzeth/core/chacha_rng.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/evaluator_from_lagrange.hpp b/libzeth/core/evaluator_from_lagrange.hpp index 4c641b63c..c72a0231b 100644 --- a/libzeth/core/evaluator_from_lagrange.hpp +++ b/libzeth/core/evaluator_from_lagrange.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/evaluator_from_lagrange.tcc b/libzeth/core/evaluator_from_lagrange.tcc index f21ffd59d..331510e4c 100644 --- a/libzeth/core/evaluator_from_lagrange.tcc +++ b/libzeth/core/evaluator_from_lagrange.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/extended_proof.hpp b/libzeth/core/extended_proof.hpp index 01462aca2..c793fcb5d 100644 --- a/libzeth/core/extended_proof.hpp +++ b/libzeth/core/extended_proof.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/extended_proof.tcc b/libzeth/core/extended_proof.tcc index 4886330ec..de99118ac 100644 --- a/libzeth/core/extended_proof.tcc +++ b/libzeth/core/extended_proof.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/field_element_utils.hpp b/libzeth/core/field_element_utils.hpp index eb0fbb1c6..891d942b5 100644 --- a/libzeth/core/field_element_utils.hpp +++ b/libzeth/core/field_element_utils.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/field_element_utils.tcc b/libzeth/core/field_element_utils.tcc index 07ec8046a..709128aa3 100644 --- a/libzeth/core/field_element_utils.tcc +++ b/libzeth/core/field_element_utils.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/group_element_utils.hpp b/libzeth/core/group_element_utils.hpp index 306254853..6c3577e91 100644 --- a/libzeth/core/group_element_utils.hpp +++ b/libzeth/core/group_element_utils.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/group_element_utils.tcc b/libzeth/core/group_element_utils.tcc index 28ef5ec74..e3f65327c 100644 --- a/libzeth/core/group_element_utils.tcc +++ b/libzeth/core/group_element_utils.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/hash_stream.hpp b/libzeth/core/hash_stream.hpp index b5e03004e..5210797a5 100644 --- a/libzeth/core/hash_stream.hpp +++ b/libzeth/core/hash_stream.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/hash_stream.tcc b/libzeth/core/hash_stream.tcc index 82091fa4a..09a9a6439 100644 --- a/libzeth/core/hash_stream.tcc +++ b/libzeth/core/hash_stream.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/include_libff.hpp b/libzeth/core/include_libff.hpp index 5ece1eda2..77fb90edf 100644 --- a/libzeth/core/include_libff.hpp +++ b/libzeth/core/include_libff.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/include_libsnark.hpp b/libzeth/core/include_libsnark.hpp index ceccc7d5e..65cb132d8 100644 --- a/libzeth/core/include_libsnark.hpp +++ b/libzeth/core/include_libsnark.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/joinsplit_input.hpp b/libzeth/core/joinsplit_input.hpp index 84001110b..1cf4bd36b 100644 --- a/libzeth/core/joinsplit_input.hpp +++ b/libzeth/core/joinsplit_input.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/multi_exp.hpp b/libzeth/core/multi_exp.hpp index 6a4032e39..5ef1ce866 100644 --- a/libzeth/core/multi_exp.hpp +++ b/libzeth/core/multi_exp.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/multi_exp.tcc b/libzeth/core/multi_exp.tcc index 209a2ded8..daf71016d 100644 --- a/libzeth/core/multi_exp.tcc +++ b/libzeth/core/multi_exp.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/note.hpp b/libzeth/core/note.hpp index 609c36ec6..0e00a5987 100644 --- a/libzeth/core/note.hpp +++ b/libzeth/core/note.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/utils.cpp b/libzeth/core/utils.cpp index 350380014..3c479ada0 100644 --- a/libzeth/core/utils.cpp +++ b/libzeth/core/utils.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/utils.hpp b/libzeth/core/utils.hpp index becd8e54d..7bc2685c9 100644 --- a/libzeth/core/utils.hpp +++ b/libzeth/core/utils.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/core/utils.tcc b/libzeth/core/utils.tcc index a05bd665c..14f791ce6 100644 --- a/libzeth/core/utils.tcc +++ b/libzeth/core/utils.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/mpc/groth16/mpc_hash.cpp b/libzeth/mpc/groth16/mpc_hash.cpp index d5931e5c5..253020e9c 100644 --- a/libzeth/mpc/groth16/mpc_hash.cpp +++ b/libzeth/mpc/groth16/mpc_hash.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/mpc/groth16/mpc_hash.hpp b/libzeth/mpc/groth16/mpc_hash.hpp index 2bd2c3aab..660b8fc7a 100644 --- a/libzeth/mpc/groth16/mpc_hash.hpp +++ b/libzeth/mpc/groth16/mpc_hash.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/mpc/groth16/mpc_utils.hpp b/libzeth/mpc/groth16/mpc_utils.hpp index ce1d190b8..84c043236 100644 --- a/libzeth/mpc/groth16/mpc_utils.hpp +++ b/libzeth/mpc/groth16/mpc_utils.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/mpc/groth16/mpc_utils.tcc b/libzeth/mpc/groth16/mpc_utils.tcc index ea609a294..a51004834 100644 --- a/libzeth/mpc/groth16/mpc_utils.tcc +++ b/libzeth/mpc/groth16/mpc_utils.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/mpc/groth16/phase2.hpp b/libzeth/mpc/groth16/phase2.hpp index 552a4cddd..c89021d1e 100644 --- a/libzeth/mpc/groth16/phase2.hpp +++ b/libzeth/mpc/groth16/phase2.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/mpc/groth16/phase2.tcc b/libzeth/mpc/groth16/phase2.tcc index 7aa8b7ee7..2806e7241 100644 --- a/libzeth/mpc/groth16/phase2.tcc +++ b/libzeth/mpc/groth16/phase2.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/mpc/groth16/powersoftau_utils.cpp b/libzeth/mpc/groth16/powersoftau_utils.cpp index c29ba2915..49c8628f0 100644 --- a/libzeth/mpc/groth16/powersoftau_utils.cpp +++ b/libzeth/mpc/groth16/powersoftau_utils.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/mpc/groth16/powersoftau_utils.hpp b/libzeth/mpc/groth16/powersoftau_utils.hpp index 0415387ea..0b48a3954 100644 --- a/libzeth/mpc/groth16/powersoftau_utils.hpp +++ b/libzeth/mpc/groth16/powersoftau_utils.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/mpc/groth16/powersoftau_utils.tcc b/libzeth/mpc/groth16/powersoftau_utils.tcc index e5b350ac9..945b5e63f 100644 --- a/libzeth/mpc/groth16/powersoftau_utils.tcc +++ b/libzeth/mpc/groth16/powersoftau_utils.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/serialization/filesystem_util.cpp b/libzeth/serialization/filesystem_util.cpp index 387f5fa3f..fd8de20bc 100644 --- a/libzeth/serialization/filesystem_util.cpp +++ b/libzeth/serialization/filesystem_util.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/serialization/filesystem_util.hpp b/libzeth/serialization/filesystem_util.hpp index c9bf1509b..d9e2ab63c 100644 --- a/libzeth/serialization/filesystem_util.hpp +++ b/libzeth/serialization/filesystem_util.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/serialization/proto_utils.cpp b/libzeth/serialization/proto_utils.cpp index 9dfe5dfce..1717d6dd3 100644 --- a/libzeth/serialization/proto_utils.cpp +++ b/libzeth/serialization/proto_utils.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/serialization/proto_utils.hpp b/libzeth/serialization/proto_utils.hpp index 23822fd67..260e7405f 100644 --- a/libzeth/serialization/proto_utils.hpp +++ b/libzeth/serialization/proto_utils.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/serialization/proto_utils.tcc b/libzeth/serialization/proto_utils.tcc index afed1e955..00b7859c9 100644 --- a/libzeth/serialization/proto_utils.tcc +++ b/libzeth/serialization/proto_utils.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/serialization/r1cs_serialization.hpp b/libzeth/serialization/r1cs_serialization.hpp index 56b4949ca..9fd3ead52 100644 --- a/libzeth/serialization/r1cs_serialization.hpp +++ b/libzeth/serialization/r1cs_serialization.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/serialization/r1cs_serialization.tcc b/libzeth/serialization/r1cs_serialization.tcc index 29998c9fa..52b4f6353 100644 --- a/libzeth/serialization/r1cs_serialization.tcc +++ b/libzeth/serialization/r1cs_serialization.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/snarks/groth16/groth16_api_handler.hpp b/libzeth/snarks/groth16/groth16_api_handler.hpp index 334b17f35..311b85ada 100644 --- a/libzeth/snarks/groth16/groth16_api_handler.hpp +++ b/libzeth/snarks/groth16/groth16_api_handler.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/snarks/groth16/groth16_api_handler.tcc b/libzeth/snarks/groth16/groth16_api_handler.tcc index 062788f09..80166f8f9 100644 --- a/libzeth/snarks/groth16/groth16_api_handler.tcc +++ b/libzeth/snarks/groth16/groth16_api_handler.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/snarks/groth16/groth16_snark.hpp b/libzeth/snarks/groth16/groth16_snark.hpp index 94b3ac141..c393cebfe 100644 --- a/libzeth/snarks/groth16/groth16_snark.hpp +++ b/libzeth/snarks/groth16/groth16_snark.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/snarks/groth16/groth16_snark.tcc b/libzeth/snarks/groth16/groth16_snark.tcc index 5d43de065..7482810be 100644 --- a/libzeth/snarks/groth16/groth16_snark.tcc +++ b/libzeth/snarks/groth16/groth16_snark.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/snarks/pghr13/pghr13_api_handler.hpp b/libzeth/snarks/pghr13/pghr13_api_handler.hpp index 728628712..d87182f94 100644 --- a/libzeth/snarks/pghr13/pghr13_api_handler.hpp +++ b/libzeth/snarks/pghr13/pghr13_api_handler.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/snarks/pghr13/pghr13_api_handler.tcc b/libzeth/snarks/pghr13/pghr13_api_handler.tcc index 448c89a50..17190b8a8 100644 --- a/libzeth/snarks/pghr13/pghr13_api_handler.tcc +++ b/libzeth/snarks/pghr13/pghr13_api_handler.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/snarks/pghr13/pghr13_snark.hpp b/libzeth/snarks/pghr13/pghr13_snark.hpp index 9dde87a32..48c83a934 100644 --- a/libzeth/snarks/pghr13/pghr13_snark.hpp +++ b/libzeth/snarks/pghr13/pghr13_snark.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/snarks/pghr13/pghr13_snark.tcc b/libzeth/snarks/pghr13/pghr13_snark.tcc index be5977428..878dd8038 100644 --- a/libzeth/snarks/pghr13/pghr13_snark.tcc +++ b/libzeth/snarks/pghr13/pghr13_snark.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/circuits/binary_operation_test.cpp b/libzeth/tests/circuits/binary_operation_test.cpp index 23c463c13..5a6911b27 100644 --- a/libzeth/tests/circuits/binary_operation_test.cpp +++ b/libzeth/tests/circuits/binary_operation_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/circuits/blake2s_test.cpp b/libzeth/tests/circuits/blake2s_test.cpp index cdb756ba7..f96b561de 100644 --- a/libzeth/tests/circuits/blake2s_test.cpp +++ b/libzeth/tests/circuits/blake2s_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/circuits/commitments_test.cpp b/libzeth/tests/circuits/commitments_test.cpp index 28f113989..49e2d33f4 100644 --- a/libzeth/tests/circuits/commitments_test.cpp +++ b/libzeth/tests/circuits/commitments_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/circuits/merkle_tree_test.cpp b/libzeth/tests/circuits/merkle_tree_test.cpp index 728582315..5e5172f63 100644 --- a/libzeth/tests/circuits/merkle_tree_test.cpp +++ b/libzeth/tests/circuits/merkle_tree_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/circuits/mimc_mp_test.cpp b/libzeth/tests/circuits/mimc_mp_test.cpp index 7563b9553..e7e82e7fa 100644 --- a/libzeth/tests/circuits/mimc_mp_test.cpp +++ b/libzeth/tests/circuits/mimc_mp_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/circuits/note_test.cpp b/libzeth/tests/circuits/note_test.cpp index be8d6bf21..2c706ed61 100644 --- a/libzeth/tests/circuits/note_test.cpp +++ b/libzeth/tests/circuits/note_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/circuits/packed_addition_test.cpp b/libzeth/tests/circuits/packed_addition_test.cpp index 8daf05c79..067773056 100644 --- a/libzeth/tests/circuits/packed_addition_test.cpp +++ b/libzeth/tests/circuits/packed_addition_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/circuits/prfs_test.cpp b/libzeth/tests/circuits/prfs_test.cpp index dbd4c8223..670b5527a 100644 --- a/libzeth/tests/circuits/prfs_test.cpp +++ b/libzeth/tests/circuits/prfs_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/circuits/sha256_test.cpp b/libzeth/tests/circuits/sha256_test.cpp index c4b52ccea..9458188e9 100644 --- a/libzeth/tests/circuits/sha256_test.cpp +++ b/libzeth/tests/circuits/sha256_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/circuits/simple_test.cpp b/libzeth/tests/circuits/simple_test.cpp index 2f65f85d9..5a2a2b048 100644 --- a/libzeth/tests/circuits/simple_test.cpp +++ b/libzeth/tests/circuits/simple_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/circuits/simple_test.hpp b/libzeth/tests/circuits/simple_test.hpp index 915b08455..e613bc6ee 100644 --- a/libzeth/tests/circuits/simple_test.hpp +++ b/libzeth/tests/circuits/simple_test.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/circuits/simple_test.tcc b/libzeth/tests/circuits/simple_test.tcc index 84f5a4728..a6d1f8b1f 100644 --- a/libzeth/tests/circuits/simple_test.tcc +++ b/libzeth/tests/circuits/simple_test.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/core/bits_test.cpp b/libzeth/tests/core/bits_test.cpp index f2f6e93dd..2c2832526 100644 --- a/libzeth/tests/core/bits_test.cpp +++ b/libzeth/tests/core/bits_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/core/chacha_test.cpp b/libzeth/tests/core/chacha_test.cpp index 68a817eb9..856d9ee29 100644 --- a/libzeth/tests/core/chacha_test.cpp +++ b/libzeth/tests/core/chacha_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/core/ec_operation_data_test.cpp b/libzeth/tests/core/ec_operation_data_test.cpp index c297e952a..9cc79a4eb 100644 --- a/libzeth/tests/core/ec_operation_data_test.cpp +++ b/libzeth/tests/core/ec_operation_data_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/core/evaluator_from_lagrange_test.cpp b/libzeth/tests/core/evaluator_from_lagrange_test.cpp index 18b1caa10..b8986b8b3 100644 --- a/libzeth/tests/core/evaluator_from_lagrange_test.cpp +++ b/libzeth/tests/core/evaluator_from_lagrange_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/core/field_element_utils_test.cpp b/libzeth/tests/core/field_element_utils_test.cpp index 4db8c25ee..f678cc94e 100644 --- a/libzeth/tests/core/field_element_utils_test.cpp +++ b/libzeth/tests/core/field_element_utils_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/core/group_element_utils_test.cpp b/libzeth/tests/core/group_element_utils_test.cpp index 5454e0f3e..daba16dd8 100644 --- a/libzeth/tests/core/group_element_utils_test.cpp +++ b/libzeth/tests/core/group_element_utils_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/core/utils_test.cpp b/libzeth/tests/core/utils_test.cpp index 381a9853b..f3de08eac 100644 --- a/libzeth/tests/core/utils_test.cpp +++ b/libzeth/tests/core/utils_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/mpc/groth16/mpc_hash_test.cpp b/libzeth/tests/mpc/groth16/mpc_hash_test.cpp index 4b9725167..d51ed6e9a 100644 --- a/libzeth/tests/mpc/groth16/mpc_hash_test.cpp +++ b/libzeth/tests/mpc/groth16/mpc_hash_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/mpc/groth16/mpc_test.cpp b/libzeth/tests/mpc/groth16/mpc_test.cpp index a37f28ea4..5661633db 100644 --- a/libzeth/tests/mpc/groth16/mpc_test.cpp +++ b/libzeth/tests/mpc/groth16/mpc_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/mpc/groth16/powersoftau_test.cpp b/libzeth/tests/mpc/groth16/powersoftau_test.cpp index ad17032bb..5bac0feff 100644 --- a/libzeth/tests/mpc/groth16/powersoftau_test.cpp +++ b/libzeth/tests/mpc/groth16/powersoftau_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/prover/prover_test.cpp b/libzeth/tests/prover/prover_test.cpp index 6f9991d74..87aae2dbd 100644 --- a/libzeth/tests/prover/prover_test.cpp +++ b/libzeth/tests/prover/prover_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/serialization/proto_utils_test.cpp b/libzeth/tests/serialization/proto_utils_test.cpp index 02fbebeac..d6564d82b 100644 --- a/libzeth/tests/serialization/proto_utils_test.cpp +++ b/libzeth/tests/serialization/proto_utils_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/serialization/r1cs_serialization_test.cpp b/libzeth/tests/serialization/r1cs_serialization_test.cpp index 54f03eab2..f3d686775 100644 --- a/libzeth/tests/serialization/r1cs_serialization_test.cpp +++ b/libzeth/tests/serialization/r1cs_serialization_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/snarks/common_api_tests.tcc b/libzeth/tests/snarks/common_api_tests.tcc index 53be8dcb7..623e7f511 100644 --- a/libzeth/tests/snarks/common_api_tests.tcc +++ b/libzeth/tests/snarks/common_api_tests.tcc @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/snarks/groth16/groth16_api_handler_test.cpp b/libzeth/tests/snarks/groth16/groth16_api_handler_test.cpp index dbec8cfba..c478b8a93 100644 --- a/libzeth/tests/snarks/groth16/groth16_api_handler_test.cpp +++ b/libzeth/tests/snarks/groth16/groth16_api_handler_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/tests/snarks/pghr13/pghr13_api_handler_test.cpp b/libzeth/tests/snarks/pghr13/pghr13_api_handler_test.cpp index fbf9adfbc..f368a09fa 100644 --- a/libzeth/tests/snarks/pghr13/pghr13_api_handler_test.cpp +++ b/libzeth/tests/snarks/pghr13/pghr13_api_handler_test.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/libzeth/zeth_constants.hpp b/libzeth/zeth_constants.hpp index 2490d5323..aca0c04f4 100644 --- a/libzeth/zeth_constants.hpp +++ b/libzeth/zeth_constants.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/commands/__init__.py b/mpc/commands/__init__.py index 6fb9229d2..f50145434 100644 --- a/mpc/commands/__init__.py +++ b/mpc/commands/__init__.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/commands/constants.py b/mpc/commands/constants.py index e173ecd55..198900695 100644 --- a/mpc/commands/constants.py +++ b/mpc/commands/constants.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/commands/contributors_from_csv b/mpc/commands/contributors_from_csv index abe1696e5..667e461de 100644 --- a/mpc/commands/contributors_from_csv +++ b/mpc/commands/contributors_from_csv @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/commands/create_keypair b/mpc/commands/create_keypair index 4cbfc850d..55293be15 100644 --- a/mpc/commands/create_keypair +++ b/mpc/commands/create_keypair @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/commands/generate_key b/mpc/commands/generate_key index c8a85ff32..ebbf3df6a 100644 --- a/mpc/commands/generate_key +++ b/mpc/commands/generate_key @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/commands/get_challenge b/mpc/commands/get_challenge index 285f5756a..fbde531ca 100644 --- a/mpc/commands/get_challenge +++ b/mpc/commands/get_challenge @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/commands/phase1_contribute b/mpc/commands/phase1_contribute index bb4482303..ae1f22d46 100644 --- a/mpc/commands/phase1_contribute +++ b/mpc/commands/phase1_contribute @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/commands/phase1_server b/mpc/commands/phase1_server index dd3d011fa..85476a785 100644 --- a/mpc/commands/phase1_server +++ b/mpc/commands/phase1_server @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/commands/phase2_contribute b/mpc/commands/phase2_contribute index b048c8e29..9a785ee3b 100644 --- a/mpc/commands/phase2_contribute +++ b/mpc/commands/phase2_contribute @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/commands/phase2_prepare b/mpc/commands/phase2_prepare index 77808de15..975d051c2 100644 --- a/mpc/commands/phase2_prepare +++ b/mpc/commands/phase2_prepare @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/commands/phase2_server b/mpc/commands/phase2_server index e40b8b402..dc6159b37 100644 --- a/mpc/commands/phase2_server +++ b/mpc/commands/phase2_server @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/commands/public_key b/mpc/commands/public_key index 7b1dfacac..26cbd50a6 100755 --- a/mpc/commands/public_key +++ b/mpc/commands/public_key @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/commands/public_key_operations.py b/mpc/commands/public_key_operations.py index ade721106..9f6c3f015 100644 --- a/mpc/commands/public_key_operations.py +++ b/mpc/commands/public_key_operations.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/commands/sign_contribution b/mpc/commands/sign_contribution index a402fc0e4..d91425cd2 100644 --- a/mpc/commands/sign_contribution +++ b/mpc/commands/sign_contribution @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/commands/upload_contribution b/mpc/commands/upload_contribution index 732ba7d10..87ece8d29 100644 --- a/mpc/commands/upload_contribution +++ b/mpc/commands/upload_contribution @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/__init__.py b/mpc/coordinator/__init__.py index 6fb9229d2..f50145434 100644 --- a/mpc/coordinator/__init__.py +++ b/mpc/coordinator/__init__.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/client.py b/mpc/coordinator/client.py index e2c264944..b7bedc4de 100644 --- a/mpc/coordinator/client.py +++ b/mpc/coordinator/client.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/contribute.py b/mpc/coordinator/contribute.py index 2e3b83315..3ccd35e45 100644 --- a/mpc/coordinator/contribute.py +++ b/mpc/coordinator/contribute.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/contributor_list.py b/mpc/coordinator/contributor_list.py index 6fdd75103..6a66ea008 100644 --- a/mpc/coordinator/contributor_list.py +++ b/mpc/coordinator/contributor_list.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/crypto.py b/mpc/coordinator/crypto.py index b5eeeb19c..74e6f0034 100644 --- a/mpc/coordinator/crypto.py +++ b/mpc/coordinator/crypto.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/icontributionhandler.py b/mpc/coordinator/icontributionhandler.py index 43656f7f2..8c5d18f17 100644 --- a/mpc/coordinator/icontributionhandler.py +++ b/mpc/coordinator/icontributionhandler.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/interval.py b/mpc/coordinator/interval.py index 57a85a650..1bdbd9ffa 100644 --- a/mpc/coordinator/interval.py +++ b/mpc/coordinator/interval.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/mpc_command.py b/mpc/coordinator/mpc_command.py index 86161d0ef..89f319da5 100644 --- a/mpc/coordinator/mpc_command.py +++ b/mpc/coordinator/mpc_command.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/null_contribution_handler.py b/mpc/coordinator/null_contribution_handler.py index 38303abf9..2e4312fb4 100644 --- a/mpc/coordinator/null_contribution_handler.py +++ b/mpc/coordinator/null_contribution_handler.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/phase1_contribution_handler.py b/mpc/coordinator/phase1_contribution_handler.py index e3e6ca56b..c61fcc405 100644 --- a/mpc/coordinator/phase1_contribution_handler.py +++ b/mpc/coordinator/phase1_contribution_handler.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/phase2_contribution_handler.py b/mpc/coordinator/phase2_contribution_handler.py index 1cc3c0e9d..9727800bb 100644 --- a/mpc/coordinator/phase2_contribution_handler.py +++ b/mpc/coordinator/phase2_contribution_handler.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/powersoftau_command.py b/mpc/coordinator/powersoftau_command.py index b9be08ad9..e9408a353 100644 --- a/mpc/coordinator/powersoftau_command.py +++ b/mpc/coordinator/powersoftau_command.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/powersoftau_process_command.py b/mpc/coordinator/powersoftau_process_command.py index 0d9a98f1f..fc7f514c1 100644 --- a/mpc/coordinator/powersoftau_process_command.py +++ b/mpc/coordinator/powersoftau_process_command.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/server.py b/mpc/coordinator/server.py index 42d56d93d..41d607bf3 100644 --- a/mpc/coordinator/server.py +++ b/mpc/coordinator/server.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/server_configuration.py b/mpc/coordinator/server_configuration.py index e97c7b46b..735ddd237 100644 --- a/mpc/coordinator/server_configuration.py +++ b/mpc/coordinator/server_configuration.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/server_state.py b/mpc/coordinator/server_state.py index 67b404952..4474817a0 100644 --- a/mpc/coordinator/server_state.py +++ b/mpc/coordinator/server_state.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/coordinator/upload_utils.py b/mpc/coordinator/upload_utils.py index f2404f03d..59f5d17dc 100644 --- a/mpc/coordinator/upload_utils.py +++ b/mpc/coordinator/upload_utils.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/setup.py b/mpc/setup.py index c76072d7a..35d6bbe81 100644 --- a/mpc/setup.py +++ b/mpc/setup.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/test/__init__.py b/mpc/test/__init__.py index 6fb9229d2..f50145434 100644 --- a/mpc/test/__init__.py +++ b/mpc/test/__init__.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/test/test_crypto.py b/mpc/test/test_crypto.py index 6842916d7..1c83a7383 100644 --- a/mpc/test/test_crypto.py +++ b/mpc/test/test_crypto.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc/test/test_server_state.py b/mpc/test/test_server_state.py index c77befe1e..69b2f10d1 100644 --- a/mpc/test/test_server_state.py +++ b/mpc/test/test_server_state.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc_tools/mpc_phase2/cli/mpc_common.cpp b/mpc_tools/mpc_phase2/cli/mpc_common.cpp index 2c2f6c5a4..bfbcf4709 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_common.cpp +++ b/mpc_tools/mpc_phase2/cli/mpc_common.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc_tools/mpc_phase2/cli/mpc_common.hpp b/mpc_tools/mpc_phase2/cli/mpc_common.hpp index f02e5920f..0e2f4c427 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_common.hpp +++ b/mpc_tools/mpc_phase2/cli/mpc_common.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc_tools/mpc_phase2/cli/mpc_create_keypair.cpp b/mpc_tools/mpc_phase2/cli/mpc_create_keypair.cpp index af39fee6d..bffdb648e 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_create_keypair.cpp +++ b/mpc_tools/mpc_phase2/cli/mpc_create_keypair.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc_tools/mpc_phase2/cli/mpc_dummy_phase2.cpp b/mpc_tools/mpc_phase2/cli/mpc_dummy_phase2.cpp index 83b088c09..296f6bf81 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_dummy_phase2.cpp +++ b/mpc_tools/mpc_phase2/cli/mpc_dummy_phase2.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc_tools/mpc_phase2/cli/mpc_linear_combination.cpp b/mpc_tools/mpc_phase2/cli/mpc_linear_combination.cpp index 37ec882cb..4dbc12d76 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_linear_combination.cpp +++ b/mpc_tools/mpc_phase2/cli/mpc_linear_combination.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc_tools/mpc_phase2/cli/mpc_phase2_begin.cpp b/mpc_tools/mpc_phase2/cli/mpc_phase2_begin.cpp index 75e3b5ab2..69c2d84bb 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_phase2_begin.cpp +++ b/mpc_tools/mpc_phase2/cli/mpc_phase2_begin.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc_tools/mpc_phase2/cli/mpc_phase2_contribute.cpp b/mpc_tools/mpc_phase2/cli/mpc_phase2_contribute.cpp index 4aae701ef..a802fda7a 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_phase2_contribute.cpp +++ b/mpc_tools/mpc_phase2/cli/mpc_phase2_contribute.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_contribution.cpp b/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_contribution.cpp index 9f112c26e..7e9739fc2 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_contribution.cpp +++ b/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_contribution.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_transcript.cpp b/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_transcript.cpp index 6ab8ba1f3..3bc7dd6fb 100644 --- a/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_transcript.cpp +++ b/mpc_tools/mpc_phase2/cli/mpc_phase2_verify_transcript.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc_tools/mpc_phase2/mpc_client.cpp b/mpc_tools/mpc_phase2/mpc_client.cpp index b3e186965..4c6a3961c 100644 --- a/mpc_tools/mpc_phase2/mpc_client.cpp +++ b/mpc_tools/mpc_phase2/mpc_client.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc_tools/mpc_phase2/mpc_coord.cpp b/mpc_tools/mpc_phase2/mpc_coord.cpp index 34e2a1fd8..a78d17c8e 100644 --- a/mpc_tools/mpc_phase2/mpc_coord.cpp +++ b/mpc_tools/mpc_phase2/mpc_coord.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc_tools/mpc_phase2/test/mpc_test_cli.cpp b/mpc_tools/mpc_phase2/test/mpc_test_cli.cpp index 9cef02b72..fdb0caafd 100644 --- a/mpc_tools/mpc_phase2/test/mpc_test_cli.cpp +++ b/mpc_tools/mpc_phase2/test/mpc_test_cli.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/mpc_tools/pot_process/pot_process.cpp b/mpc_tools/pot_process/pot_process.cpp index a64ad5a3a..61b32c119 100644 --- a/mpc_tools/pot_process/pot_process.cpp +++ b/mpc_tools/pot_process/pot_process.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/prover_server/prover_server.cpp b/prover_server/prover_server.cpp index e804e8e3d..b4234dd64 100644 --- a/prover_server/prover_server.cpp +++ b/prover_server/prover_server.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ @@ -257,7 +257,7 @@ std::string get_server_version() void display_server_start_message() { std::string copyright = - "Copyright (c) 2015-2020 Clearmatics Technologies Ltd"; + "Copyright (c) 2015-2021 Clearmatics Technologies Ltd"; std::string license = "SPDX-License-Identifier: LGPL-3.0+"; std::string project = "R&D Department: PoC for Zerocash on Ethereum/Autonity"; diff --git a/scripts/mimc_round_constants_generation.py b/scripts/mimc_round_constants_generation.py index aacb70f5f..02ddbbe23 100644 --- a/scripts/mimc_round_constants_generation.py +++ b/scripts/mimc_round_constants_generation.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -# Copyright (c) 2015-2020 Clearmatics Technologies Ltd +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd # # SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_config.h.in b/zeth_config.h.in index d453ba895..7852b46af 100644 --- a/zeth_config.h.in +++ b/zeth_config.h.in @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/AltBN128MixerBase.sol b/zeth_contracts/contracts/AltBN128MixerBase.sol index b8f80a49e..6d8c06fa2 100644 --- a/zeth_contracts/contracts/AltBN128MixerBase.sol +++ b/zeth_contracts/contracts/AltBN128MixerBase.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/AltBN128MixerBase_test.sol b/zeth_contracts/contracts/AltBN128MixerBase_test.sol index 478ac18d0..d63bf2c6a 100644 --- a/zeth_contracts/contracts/AltBN128MixerBase_test.sol +++ b/zeth_contracts/contracts/AltBN128MixerBase_test.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/BLS12_377MixerBase.sol b/zeth_contracts/contracts/BLS12_377MixerBase.sol index 195d0098e..53cd845e6 100644 --- a/zeth_contracts/contracts/BLS12_377MixerBase.sol +++ b/zeth_contracts/contracts/BLS12_377MixerBase.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/BLS12_377_test.sol b/zeth_contracts/contracts/BLS12_377_test.sol index dce118d47..623082947 100644 --- a/zeth_contracts/contracts/BLS12_377_test.sol +++ b/zeth_contracts/contracts/BLS12_377_test.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/BW6_761_test.sol b/zeth_contracts/contracts/BW6_761_test.sol index cad27fdd5..d2d12baa8 100644 --- a/zeth_contracts/contracts/BW6_761_test.sol +++ b/zeth_contracts/contracts/BW6_761_test.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/BaseMerkleTree.sol b/zeth_contracts/contracts/BaseMerkleTree.sol index 2d88a38bc..98363f151 100644 --- a/zeth_contracts/contracts/BaseMerkleTree.sol +++ b/zeth_contracts/contracts/BaseMerkleTree.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/Groth16AltBN128.sol b/zeth_contracts/contracts/Groth16AltBN128.sol index 40224cd4f..ff9e5f316 100644 --- a/zeth_contracts/contracts/Groth16AltBN128.sol +++ b/zeth_contracts/contracts/Groth16AltBN128.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol b/zeth_contracts/contracts/Groth16AltBN128Mixer.sol index 6912cbb83..9949460ce 100644 --- a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Groth16AltBN128Mixer.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/Groth16BLS12_377.sol b/zeth_contracts/contracts/Groth16BLS12_377.sol index 056977d34..8e8ca1289 100644 --- a/zeth_contracts/contracts/Groth16BLS12_377.sol +++ b/zeth_contracts/contracts/Groth16BLS12_377.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol b/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol index cfa0aec2f..d00cf3258 100644 --- a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol +++ b/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/Groth16BLS12_377_test.sol b/zeth_contracts/contracts/Groth16BLS12_377_test.sol index f6888a853..fd95b7d91 100644 --- a/zeth_contracts/contracts/Groth16BLS12_377_test.sol +++ b/zeth_contracts/contracts/Groth16BLS12_377_test.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol b/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol index 39713c7b2..a09deda42 100644 --- a/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol +++ b/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/MerkleTreeSha256.sol b/zeth_contracts/contracts/MerkleTreeSha256.sol index 5cf067e4b..554e0e657 100644 --- a/zeth_contracts/contracts/MerkleTreeSha256.sol +++ b/zeth_contracts/contracts/MerkleTreeSha256.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/MiMC31.sol b/zeth_contracts/contracts/MiMC31.sol index 7f04f2dc7..f3c7f7b50 100644 --- a/zeth_contracts/contracts/MiMC31.sol +++ b/zeth_contracts/contracts/MiMC31.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/MiMC7.sol b/zeth_contracts/contracts/MiMC7.sol index 73bebdf0a..747ddcdd1 100644 --- a/zeth_contracts/contracts/MiMC7.sol +++ b/zeth_contracts/contracts/MiMC7.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/MiMC_test.sol b/zeth_contracts/contracts/MiMC_test.sol index e536c0bad..786d858b7 100644 --- a/zeth_contracts/contracts/MiMC_test.sol +++ b/zeth_contracts/contracts/MiMC_test.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/Migrations.sol b/zeth_contracts/contracts/Migrations.sol index fd29c98bc..776c0250e 100644 --- a/zeth_contracts/contracts/Migrations.sol +++ b/zeth_contracts/contracts/Migrations.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/MixerBase.sol b/zeth_contracts/contracts/MixerBase.sol index 5cbe29078..2905aa97a 100644 --- a/zeth_contracts/contracts/MixerBase.sol +++ b/zeth_contracts/contracts/MixerBase.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/OTSchnorrVerifier.sol b/zeth_contracts/contracts/OTSchnorrVerifier.sol index 5a557345d..dbaa35777 100644 --- a/zeth_contracts/contracts/OTSchnorrVerifier.sol +++ b/zeth_contracts/contracts/OTSchnorrVerifier.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/Pairing.sol b/zeth_contracts/contracts/Pairing.sol index 54fcbde94..4202dc3a8 100644 --- a/zeth_contracts/contracts/Pairing.sol +++ b/zeth_contracts/contracts/Pairing.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol index 69a3170e0..01123fb11 100644 --- a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ diff --git a/zeth_contracts/contracts/Tokens.sol b/zeth_contracts/contracts/Tokens.sol index 8e5aec79a..9a77c9e11 100644 --- a/zeth_contracts/contracts/Tokens.sol +++ b/zeth_contracts/contracts/Tokens.sol @@ -1,4 +1,4 @@ -// Copyright (c) 2015-2020 Clearmatics Technologies Ltd +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd // // SPDX-License-Identifier: LGPL-3.0+ From 880137b6a9f1d846e19deee78cc16a22e822fd06 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 22 Dec 2020 10:17:36 +0000 Subject: [PATCH 002/137] ci: enable contract tests --- client/Makefile | 8 ++++-- scripts/ci | 74 ++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 76 insertions(+), 6 deletions(-) diff --git a/client/Makefile b/client/Makefile index 8be9862d9..569ba9a62 100644 --- a/client/Makefile +++ b/client/Makefile @@ -39,5 +39,9 @@ test: ${PROTOBUF_OUTPUT} python -m unittest test_contracts: ${PROTOBUF_OUTPUT} - python test_commands/test_contract_base_mixer.py - python test_commands/test_merkle_tree_contract.py + python -m test_commands.test_altbn128_mixer_base + python -m test_commands.test_bls12_377_contract + python -m test_commands.test_bw6_761_contract + python -m test_commands.test_groth16_bls12_377_contract + python -m test_commands.test_merkle_tree_contract + python -m test_commands.test_mimc_contract diff --git a/scripts/ci b/scripts/ci index a7419a899..e64d0bacd 100755 --- a/scripts/ci +++ b/scripts/ci @@ -7,6 +7,59 @@ echo "running against commit: "`git log --oneline --no-decorate -n 1` set -x set -e +function _setup_client() { + pushd client + python3 -m venv env + . env/bin/activate + pip install --upgrade pip --progress-bar off + pip install --upgrade setuptools wheel + make setup + + deactivate + popd +} + +function _ganache_is_active() { + curl -sf \ + -H "Content-Type: application/json" \ + -X POST \ + --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[]}' \ + http://localhost:8545 +} + +function _start_ganache() { + pushd zeth_contracts + + npm run testrpc > ganache.stdout & + echo $! > ganache.pid + + # Wait for ganache to be active + while ! _ganache_is_active ; do + echo "_start_ganache: waiting for ganache ..." + sleep 1 + done + echo "_start_ganache: ganache is active" + + popd +} + +function _stop_ganache() { + pushd zeth_contracts + if ! [ -e ganache.pid ] ; then + echo "_stop_ganache: no PID file" + return 1 + fi + + pid=`cat ganache.pid` + while (kill "${pid}") ; do + sleep 0.5 + done + rm ganache.pid + echo "_stop_ganache: ganache stopped" + + popd +} + function check_format() { scripts/format git diff --no-ext-diff | head -n 20 > format_errors @@ -27,15 +80,28 @@ function check_contracts() { npm install --unsafe-perm npm run check popd + + # Run contract tests (in python) + _setup_client + + _start_ganache + + pushd client + . env/bin/activate + make test_contracts + deactivate + popd + + _stop_ganache + } function check_client() { + _setup_client + pushd client - python3 -m venv env . env/bin/activate - pip install --upgrade pip --progress-bar off - pip install --upgrade setuptools wheel - make setup + make check deactivate From 93f0bed209345e4784ca535c283e1fb60c81054d Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 22 Dec 2020 11:47:44 +0000 Subject: [PATCH 003/137] client: separate contract tests and use unittest framework --- client/Makefile | 10 +- client/test_commands/test_mimc_contract.py | 60 ----------- client/test_contracts/__init__.py | 5 + .../test_altbn128_mixer_base.py | 99 +++++++++---------- .../test_bls12_377_contract.py | 95 +++++++++--------- .../test_bw6_761_contract.py | 96 +++++++++--------- .../test_groth16_bls12_377_contract.py | 89 ++++++++--------- .../test_merkle_tree_contract.py | 81 +++++++-------- client/test_contracts/test_mimc_contract.py | 51 ++++++++++ 9 files changed, 269 insertions(+), 317 deletions(-) delete mode 100644 client/test_commands/test_mimc_contract.py create mode 100644 client/test_contracts/__init__.py rename client/{test_commands => test_contracts}/test_altbn128_mixer_base.py (65%) rename client/{test_commands => test_contracts}/test_bls12_377_contract.py (68%) rename client/{test_commands => test_contracts}/test_bw6_761_contract.py (72%) rename client/{test_commands => test_contracts}/test_groth16_bls12_377_contract.py (67%) rename client/{test_commands => test_contracts}/test_merkle_tree_contract.py (53%) create mode 100644 client/test_contracts/test_mimc_contract.py diff --git a/client/Makefile b/client/Makefile index 569ba9a62..9cc596444 100644 --- a/client/Makefile +++ b/client/Makefile @@ -33,15 +33,11 @@ syntax: ${PROTOBUF_OUTPUT} mypy zeth/cli/zeth zeth/helper/zeth_helper mypy -p tests mypy -p test_commands + mypy -p test_contracts pylint zeth.core zeth.cli zeth.helper tests test_commands test: ${PROTOBUF_OUTPUT} - python -m unittest + python -m unittest discover tests test_contracts: ${PROTOBUF_OUTPUT} - python -m test_commands.test_altbn128_mixer_base - python -m test_commands.test_bls12_377_contract - python -m test_commands.test_bw6_761_contract - python -m test_commands.test_groth16_bls12_377_contract - python -m test_commands.test_merkle_tree_contract - python -m test_commands.test_mimc_contract + python -m unittest discover test_contracts diff --git a/client/test_commands/test_mimc_contract.py b/client/test_commands/test_mimc_contract.py deleted file mode 100644 index 1c986c14d..000000000 --- a/client/test_commands/test_mimc_contract.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright (c) 2015-2021 Clearmatics Technologies Ltd -# -# SPDX-License-Identifier: LGPL-3.0+ - -from zeth.core.utils import get_contracts_dir -from zeth.core.contracts import InstanceDescription -from zeth.core.mimc import MiMC7, MiMC31 -from zeth.cli.utils import get_eth_network, open_web3_from_network -from os.path import join -import sys -from typing import Any - - -def test_mimc7(instance: Any) -> None: - # pylint: disable=line-too-long - x = int(28948022309329048855892746252171976963317496166410141009864396001978282409983).to_bytes(32, 'big') # noqa - y = int(14220067918847996031108144435763672811050758065945364308986253046354060608451).to_bytes(32, 'big') # noqa - # pylint: enable=line-too-long - h = MiMC7().hash(x, y) - - result = instance.functions.test_mimc7(x, y).call() - assert result == h - - -def test_mimc31(instance: Any) -> None: - # pylint: disable=line-too-long - x = int(28948022309329048855892746252171976963317496166410141009864396001978282409983).to_bytes(32, 'big') # noqa - y = int(14220067918847996031108144435763672811050758065945364308986253046354060608451).to_bytes(32, 'big') # noqa - # pylint: enable=line-too-long - h = MiMC31().hash(x, y) - - result = instance.functions.test_mimc31(x, y).call() - - assert result == h - - -def main() -> int: - web3: Any = open_web3_from_network(get_eth_network(None)) - contracts_dir = get_contracts_dir() - contract_instance_desc = InstanceDescription.deploy( - web3, - join(contracts_dir, "MiMC_test.sol"), - "MiMC_test", - web3.eth.accounts[0], # pylint: disable=no-member - None, - 500000, - {"allow_paths": contracts_dir}) - contract_instance = contract_instance_desc.instantiate(web3) - - test_mimc7(contract_instance) - test_mimc31(contract_instance) - - print("========================================") - print("== PASSED ==") - print("========================================") - return 0 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/client/test_contracts/__init__.py b/client/test_contracts/__init__.py new file mode 100644 index 000000000..f50145434 --- /dev/null +++ b/client/test_contracts/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd +# +# SPDX-License-Identifier: LGPL-3.0+ diff --git a/client/test_commands/test_altbn128_mixer_base.py b/client/test_contracts/test_altbn128_mixer_base.py similarity index 65% rename from client/test_commands/test_altbn128_mixer_base.py rename to client/test_contracts/test_altbn128_mixer_base.py index 3cb4d0cbe..267d3175c 100644 --- a/client/test_commands/test_altbn128_mixer_base.py +++ b/client/test_contracts/test_altbn128_mixer_base.py @@ -7,6 +7,7 @@ from zeth.core.constants import \ JS_INPUTS, ZETH_PUBLIC_UNIT_VALUE, ZETH_MERKLE_TREE_DEPTH import test_commands.mock as mock +from unittest import TestCase from typing import Any # pylint: disable=line-too-long @@ -91,58 +92,46 @@ PACKED_PRIMARY_INPUTS = \ [ROOT] + COMMITMENTS + NULLIFIERS + [HSIG] + HTAGS + [RESIDUAL_BITS] - -def test_assemble_nullifiers(mixer_instance: Any) -> None: - # Test retrieving nullifiers - print("--- test_assemble_nullifiers") - for i in range(JS_INPUTS): - res = mixer_instance.functions.\ - assemble_nullifier_test(i, PACKED_PRIMARY_INPUTS).call() - val = int.from_bytes(res, byteorder="big") - assert val == NULLIFIERS[i], f"expected: {NULLIFIERS[i]}, got: {val}" - - -def test_assemble_hsig(mixer_instance: Any) -> None: - # Test retrieving hsig - print("--- test_assemble_hsig") - res = mixer_instance.functions.\ - assemble_hsig_test(PACKED_PRIMARY_INPUTS).call() - hsig = int.from_bytes(res, byteorder="big") - assert hsig == HSIG, f"expected: {HSIG}, got {hsig}" - - -def test_assemble_vpub(mixer_instance: Any) -> None: - # Test retrieving public values - print("--- test_assemble_vpub") - v_in, v_out = mixer_instance.functions.assemble_public_values_test( - PACKED_PRIMARY_INPUTS[-1]).call() - v_in_expect = VPUB[0] * ZETH_PUBLIC_UNIT_VALUE - v_out_expect = VPUB[1] * ZETH_PUBLIC_UNIT_VALUE - assert v_in == v_in_expect, f"expected: {v_in_expect}, got: {v_in}" - assert v_out == v_out_expect, f"expected: {v_out_expect}, got: {v_out}" - - -def main() -> None: - print("Deploying AltBN128MixerBase_test.sol") - _web3, eth = mock.open_test_web3() - deployer_eth_address = eth.accounts[0] - _mixer_interface, mixer_instance = mock.deploy_contract( - eth, - deployer_eth_address, - "AltBN128MixerBase_test", - { - 'mk_depth': ZETH_MERKLE_TREE_DEPTH, - }) - - print("Testing ...") - test_assemble_nullifiers(mixer_instance) - test_assemble_vpub(mixer_instance) - test_assemble_hsig(mixer_instance) - - print("========================================") - print("== PASSED ==") - print("========================================") - - -if __name__ == '__main__': - main() +MIXER_INSTANCE: Any = None + + +class TestAltBN128MixerBaseContract(TestCase): + + @staticmethod + def setUpClass() -> None: + print("Deploying AltBN128MixerBase_test.sol") + _web3, eth = mock.open_test_web3() + deployer_eth_address = eth.accounts[0] + _mixer_interface, mixer_instance = mock.deploy_contract( + eth, + deployer_eth_address, + "AltBN128MixerBase_test", + { + 'mk_depth': ZETH_MERKLE_TREE_DEPTH, + }) + global MIXER_INSTANCE # pylint: disable=global-statement + MIXER_INSTANCE = mixer_instance + + def test_assemble_nullifiers(self) -> None: + # Test retrieving nullifiers + for i in range(JS_INPUTS): + res = MIXER_INSTANCE.functions.\ + assemble_nullifier_test(i, PACKED_PRIMARY_INPUTS).call() + val = int.from_bytes(res, byteorder="big") + self.assertEqual(NULLIFIERS[i], val) + + def test_assemble_hsig(self) -> None: + # Test retrieving hsig + res = MIXER_INSTANCE.functions.\ + assemble_hsig_test(PACKED_PRIMARY_INPUTS).call() + hsig = int.from_bytes(res, byteorder="big") + self.assertEqual(HSIG, hsig) + + def test_assemble_vpub(self) -> None: + # Test retrieving public values + v_in, v_out = MIXER_INSTANCE.functions.assemble_public_values_test( + PACKED_PRIMARY_INPUTS[-1]).call() + v_in_expect = VPUB[0] * ZETH_PUBLIC_UNIT_VALUE + v_out_expect = VPUB[1] * ZETH_PUBLIC_UNIT_VALUE + self.assertEqual(v_in_expect, v_in) + self.assertEqual(v_out_expect, v_out) diff --git a/client/test_commands/test_bls12_377_contract.py b/client/test_contracts/test_bls12_377_contract.py similarity index 68% rename from client/test_commands/test_bls12_377_contract.py rename to client/test_contracts/test_bls12_377_contract.py index c75bd7703..77e333c29 100644 --- a/client/test_commands/test_bls12_377_contract.py +++ b/client/test_contracts/test_bls12_377_contract.py @@ -3,6 +3,7 @@ # SPDX-License-Identifier: LGPL-3.0+ from test_commands import mock +from unittest import TestCase from typing import Any # Data generated by libzeth/tests/core/ec_operation_data_test. Statements to be @@ -74,53 +75,47 @@ def _b32(hex_value: str) -> bytes: ] -def test_bls12_ecadd(bls12_instance: Any) -> None: - """ - Check that [6] == [2] + [4] - """ - result = bls12_instance.functions.testECAdd(G1_2 + G1_4).call() - assert result == G1_6 - - -def test_bls12_ecmul(bls12_instance: Any) -> None: - """ - Check that [-8] == -2 * [4] - """ - result = bls12_instance.functions.testECMul(G1_4 + FR_MINUS_2).call() - assert result == G1_MINUS_8 - - -def test_bls12_ecpairing(bls12_instance: Any) -> None: - """ - Check that e([6], [4]) * e([3],[8]) * e([4],[4]) * e([-8], [8]) == 1 - """ - # Note, return result here is uint256(1) or uint256(0) depending on the - # pairing check result. - points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_8 - result = bls12_instance.functions.testECPairing(points).call() - assert result == 1 - - points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_4 - result = bls12_instance.functions.testECPairing(points).call() - assert result == 0 - - -def main() -> None: - _web3, eth = mock.open_test_web3() - _bls12_interface, bls12_instance = mock.deploy_contract( - eth, - eth.accounts[0], - "BLS12_377_test", - {}) - - test_bls12_ecadd(bls12_instance) - test_bls12_ecmul(bls12_instance) - test_bls12_ecpairing(bls12_instance) - - print("========================================") - print("== PASSED ==") - print("========================================") - - -if __name__ == "__main__": - main() +BLS12_INSTANCE: Any = None + + +class TestBLS12_377Contract(TestCase): + + @staticmethod + def setUpClass() -> None: + print("Deploying BLS12_377_test.sol") + _web3, eth = mock.open_test_web3() + _bls12_interface, bls12_instance = mock.deploy_contract( + eth, + eth.accounts[0], + "BLS12_377_test", + {}) + global BLS12_INSTANCE # pylint: disable=global-statement + BLS12_INSTANCE = bls12_instance + + def test_bls12_ecadd(self) -> None: + """ + Check that [6] == [2] + [4] + """ + result = BLS12_INSTANCE.functions.testECAdd(G1_2 + G1_4).call() + self.assertEqual(G1_6, result) + + def test_bls12_ecmul(self) -> None: + """ + Check that [-8] == -2 * [4] + """ + result = BLS12_INSTANCE.functions.testECMul(G1_4 + FR_MINUS_2).call() + self.assertEqual(G1_MINUS_8, result) + + def test_bls12_ecpairing(self) -> None: + """ + Check that e([6], [4]) * e([3],[8]) * e([4],[4]) * e([-8], [8]) == 1 + """ + # Note, return result here is uint256(1) or uint256(0) depending on the + # pairing check result. + points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_8 + result = BLS12_INSTANCE.functions.testECPairing(points).call() + self.assertEqual(1, result) + + points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_4 + result = BLS12_INSTANCE.functions.testECPairing(points).call() + self.assertEqual(0, result) diff --git a/client/test_commands/test_bw6_761_contract.py b/client/test_contracts/test_bw6_761_contract.py similarity index 72% rename from client/test_commands/test_bw6_761_contract.py rename to client/test_contracts/test_bw6_761_contract.py index fcbf1045d..ba35a6d16 100644 --- a/client/test_commands/test_bw6_761_contract.py +++ b/client/test_contracts/test_bw6_761_contract.py @@ -3,6 +3,7 @@ # SPDX-License-Identifier: LGPL-3.0+ from test_commands import mock +from unittest import TestCase from typing import Any # Data generated by libzeth/tests/core/ec_operation_data_test. Statements to be @@ -80,54 +81,47 @@ def _b32(hex_value: str) -> bytes: _b32("ed5512a98239b73fdff458e7c0e09b9d246e3f5681429affc2b1f7e2fcbd1141"), ] - -def test_bw6_ecadd(bw6_instance: Any) -> None: - """ - Check that [6] == [2] + [4] - """ - result = bw6_instance.functions.testECAdd(G1_2 + G1_4).call() - assert result == G1_6 - - -def test_bw6_ecmul(bw6_instance: Any) -> None: - """ - Check that [-8] == -2 * [4] - """ - result = bw6_instance.functions.testECMul(G1_4 + FR_MINUS_2).call() - assert result == G1_MINUS_8 - - -def test_bw6_ecpairing(bw6_instance: Any) -> None: - """ - Check that e([6], [4]) * e([3],[8]) * e([4],[4]) * e([-8], [8]) == 1 - """ - # Note, return result here is uint256(1) or uint256(0) depending on the - # pairing check result. - points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_8 - result = bw6_instance.functions.testECPairing(points).call() - assert result == 1 - - points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_4 - result = bw6_instance.functions.testECPairing(points).call() - assert result == 0 - - -def main() -> None: - _web3, eth = mock.open_test_web3() - _bw6_interface, bw6_instance = mock.deploy_contract( - eth, - eth.accounts[0], - "BW6_761_test", - {}) - - test_bw6_ecadd(bw6_instance) - test_bw6_ecmul(bw6_instance) - test_bw6_ecpairing(bw6_instance) - - print("========================================") - print("== PASSED ==") - print("========================================") - - -if __name__ == "__main__": - main() +BW6_INSTANCE: Any = None + + +class TestBW6_761Contract(TestCase): + + @staticmethod + def setUpClass() -> None: + print("Deploying BW6_761_test.sol") + _web3, eth = mock.open_test_web3() + _bw6_interface, bw6_instance = mock.deploy_contract( + eth, + eth.accounts[0], + "BW6_761_test", + {}) + global BW6_INSTANCE # pylint: disable=global-statement + BW6_INSTANCE = bw6_instance + + def test_bw6_ecadd(self) -> None: + """ + Check that [6] == [2] + [4] + """ + result = BW6_INSTANCE.functions.testECAdd(G1_2 + G1_4).call() + self.assertEqual(G1_6, result) + + def test_bw6_ecmul(self) -> None: + """ + Check that [-8] == -2 * [4] + """ + result = BW6_INSTANCE.functions.testECMul(G1_4 + FR_MINUS_2).call() + self.assertEqual(G1_MINUS_8, result) + + def test_bw6_ecpairing(self) -> None: + """ + Check that e([6], [4]) * e([3],[8]) * e([4],[4]) * e([-8], [8]) == 1 + """ + # Note, return result here is uint256(1) or uint256(0) depending on the + # pairing check result. + points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_8 + result = BW6_INSTANCE.functions.testECPairing(points).call() + self.assertEqual(1, result) + + points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_4 + result = BW6_INSTANCE.functions.testECPairing(points).call() + self.assertEqual(0, result) diff --git a/client/test_commands/test_groth16_bls12_377_contract.py b/client/test_contracts/test_groth16_bls12_377_contract.py similarity index 67% rename from client/test_commands/test_groth16_bls12_377_contract.py rename to client/test_contracts/test_groth16_bls12_377_contract.py index acb6caa02..6f0ab4d74 100644 --- a/client/test_commands/test_groth16_bls12_377_contract.py +++ b/client/test_contracts/test_groth16_bls12_377_contract.py @@ -8,7 +8,7 @@ from zeth.cli.utils import get_eth_network, open_web3_from_network from tests.test_pairing import BLS12_377_PAIRING from os.path import join -import sys +from unittest import TestCase from typing import List, Any # pylint: disable=line-too-long @@ -63,51 +63,42 @@ ] # pylint: enable=line-too-long - -def _invoke_groth16_bls12_377_verify( - contract_instance: Any, - vk: Groth16.VerificationKey, - proof: Groth16.Proof, - inputs: List[str]) -> bool: - vk_evm = Groth16.verification_key_to_contract_parameters( - vk, BLS12_377_PAIRING) - proof_evm = Groth16.proof_to_contract_parameters(proof, BLS12_377_PAIRING) - inputs_evm = hex_list_to_uint256_list(inputs) - return contract_instance.functions.test_verify( - vk_evm, proof_evm, inputs_evm).call() - - -def test_groth16_bls12_377_valid(contract_instance: Any) -> None: - assert _invoke_groth16_bls12_377_verify( - contract_instance, VERIFICATION_KEY, PROOF, INPUTS_VALID) - - -def test_groth16_bls12_377_invalid(contract_instance: Any) -> None: - assert not _invoke_groth16_bls12_377_verify( - contract_instance, VERIFICATION_KEY, PROOF, INPUTS_INVALID) - - -def main() -> int: - web3: Any = open_web3_from_network(get_eth_network(None)) - contracts_dir = get_contracts_dir() - contract_instance_desc = InstanceDescription.deploy( - web3, - join(contracts_dir, "Groth16BLS12_377_test.sol"), - "Groth16BLS12_377_test", - web3.eth.accounts[0], # pylint: disable=no-member - None, - 500000, - {"allow_paths": contracts_dir}) - contract_instance = contract_instance_desc.instantiate(web3) - - test_groth16_bls12_377_valid(contract_instance) - test_groth16_bls12_377_invalid(contract_instance) - - print("========================================") - print("== PASSED ==") - print("========================================") - return 0 - - -if __name__ == "__main__": - sys.exit(main()) +CONTRACT_INSTANCE: Any = None + + +class TestGroth16BLS12_377Contract(TestCase): + + @staticmethod + def setUpClass() -> None: + web3: Any = open_web3_from_network(get_eth_network(None)) + contracts_dir = get_contracts_dir() + contract_instance_desc = InstanceDescription.deploy( + web3, + join(contracts_dir, "Groth16BLS12_377_test.sol"), + "Groth16BLS12_377_test", + web3.eth.accounts[0], # pylint: disable=no-member + None, + 500000, + {"allow_paths": contracts_dir}) + global CONTRACT_INSTANCE # pylint: disable=global-statement + CONTRACT_INSTANCE = contract_instance_desc.instantiate(web3) + + @staticmethod + def _invoke_groth16_bls12_377_verify( + vk: Groth16.VerificationKey, + proof: Groth16.Proof, + inputs: List[str]) -> bool: + vk_evm = Groth16.verification_key_to_contract_parameters( + vk, BLS12_377_PAIRING) + proof_evm = Groth16.proof_to_contract_parameters(proof, BLS12_377_PAIRING) + inputs_evm = hex_list_to_uint256_list(inputs) + return CONTRACT_INSTANCE.functions.test_verify( + vk_evm, proof_evm, inputs_evm).call() + + def test_groth16_bls12_377_valid(self) -> None: + self.assertTrue(self._invoke_groth16_bls12_377_verify( + VERIFICATION_KEY, PROOF, INPUTS_VALID)) + + def test_groth16_bls12_377_invalid(self) -> None: + self.assertFalse(self._invoke_groth16_bls12_377_verify( + VERIFICATION_KEY, PROOF, INPUTS_INVALID)) diff --git a/client/test_commands/test_merkle_tree_contract.py b/client/test_contracts/test_merkle_tree_contract.py similarity index 53% rename from client/test_commands/test_merkle_tree_contract.py rename to client/test_contracts/test_merkle_tree_contract.py index 7e6523aa6..98592ff87 100644 --- a/client/test_commands/test_merkle_tree_contract.py +++ b/client/test_contracts/test_merkle_tree_contract.py @@ -9,8 +9,10 @@ from zeth.core.utils import extend_32bytes from zeth.core.mimc import MiMC7 from typing import Any +from unittest import TestCase import test_commands.mock as mock + TEST_VALUES = [ extend_32bytes(bytes.fromhex("f0")), extend_32bytes(bytes.fromhex("f1")), @@ -30,30 +32,30 @@ extend_32bytes(bytes.fromhex("ff")), ] - -def assert_root(expected_root: bytes, actual_root: bytes, msg: str) -> None: - if actual_root != expected_root: - print(f"FAILED: {msg}") - print(f"Expected: {expected_root.hex()}") - print(f"Actual: {actual_root.hex()}") - raise Exception("failed") +MKTREE_INSTANCE: Any = None -def test_tree_empty(contract: Any) -> None: - mktree = MerkleTree.empty_with_depth(ZETH_MERKLE_TREE_DEPTH, MiMC7()) - expected_root = mktree.recompute_root() - root = contract.functions.testAddLeaves([], []).call() - assert_root(expected_root, root, "test_tree_empty") +class TestMerkleTreeContract(TestCase): + @staticmethod + def setUpClass() -> None: + _web3, eth = mock.open_test_web3() + deployer_eth_address = eth.accounts[0] + _mktree_interface, mktree_instance = mock.deploy_contract( + eth, + deployer_eth_address, + "MerkleTreeMiMC7_test", + {'treeDepth': ZETH_MERKLE_TREE_DEPTH}) + global MKTREE_INSTANCE # pylint: disable=global-statement + MKTREE_INSTANCE = mktree_instance -def test_tree_partial(contract: Any) -> None: - """ - Send a series of different arrays of leaves to the contract and check that - the root is as expected. Send as 2 batches, to test updating the tree, from - various states. - """ + def test_tree_empty(self) -> None: + mktree = MerkleTree.empty_with_depth(ZETH_MERKLE_TREE_DEPTH, MiMC7()) + expected_root = mktree.recompute_root() + root = MKTREE_INSTANCE.functions.testAddLeaves([], []).call() + self.assertEqual(expected_root, root, "test_tree_empty") - def _test_partial(num_entries: int, step: int = 1) -> None: + def _test_partial(self, num_entries: int, step: int = 1) -> None: """ Take the first 'num_entries' from TEST_VALUES. Cut them at each possible place and submit them as two halves to the contract, receiving back the @@ -70,33 +72,22 @@ def _test_partial(num_entries: int, step: int = 1) -> None: print(f"_test_partial: num_entries={num_entries}, cut={cut}") first = leaves[:cut] second = leaves[cut:] - root = contract.functions.testAddLeaves(first, second).call() - assert_root( + root = MKTREE_INSTANCE.functions.testAddLeaves(first, second).call() + self.assertEqual( expected_root, root, f"num_entries: {num_entries}, cut: {cut}: ") - # Perform the filling tests using arrays of these sizes - _test_partial(1) - _test_partial(7) - _test_partial(8) - _test_partial(9) - _test_partial(15, 3) - _test_partial(16, 3) - - -def main() -> None: - _web3, eth = mock.open_test_web3() - deployer_eth_address = eth.accounts[0] - _mktree_interface, mktree_instance = mock.deploy_contract( - eth, - deployer_eth_address, - "MerkleTreeMiMC7_test", - {'treeDepth': ZETH_MERKLE_TREE_DEPTH}) - - test_tree_empty(mktree_instance) - test_tree_partial(mktree_instance) - - -if __name__ == '__main__': - main() + def test_tree_partial(self) -> None: + """ + Send a series of different arrays of leaves to the contract and check that + the root is as expected. Send as 2 batches, to test updating the tree, + from various states. + """ + # Perform the filling tests using arrays of these sizes + self._test_partial(1) + self._test_partial(7) + self._test_partial(8) + self._test_partial(9) + self._test_partial(15, 3) + self._test_partial(16, 3) diff --git a/client/test_contracts/test_mimc_contract.py b/client/test_contracts/test_mimc_contract.py new file mode 100644 index 000000000..056988c6e --- /dev/null +++ b/client/test_contracts/test_mimc_contract.py @@ -0,0 +1,51 @@ +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd +# +# SPDX-License-Identifier: LGPL-3.0+ + +from zeth.core.utils import get_contracts_dir +from zeth.core.contracts import InstanceDescription +from zeth.core.mimc import MiMC7, MiMC31 +from zeth.cli.utils import get_eth_network, open_web3_from_network +from os.path import join +from unittest import TestCase +from typing import Any + +CONTRACT_INSTANCE: Any = None + + +class TestMiMCContract(TestCase): + + @staticmethod + def setUpClass() -> None: + web3: Any = open_web3_from_network(get_eth_network(None)) + contracts_dir = get_contracts_dir() + contract_instance_desc = InstanceDescription.deploy( + web3, + join(contracts_dir, "MiMC_test.sol"), + "MiMC_test", + web3.eth.accounts[0], # pylint: disable=no-member + None, + 500000, + {"allow_paths": contracts_dir}) + global CONTRACT_INSTANCE # pylint: disable=global-statement + CONTRACT_INSTANCE = contract_instance_desc.instantiate(web3) + + def test_mimc7(self) -> None: + # pylint: disable=line-too-long + x = int(28948022309329048855892746252171976963317496166410141009864396001978282409983).to_bytes(32, 'big') # noqa + y = int(14220067918847996031108144435763672811050758065945364308986253046354060608451).to_bytes(32, 'big') # noqa + # pylint: enable=line-too-long + h = MiMC7().hash(x, y) + + result = CONTRACT_INSTANCE.functions.test_mimc7(x, y).call() + self.assertEqual(h, result) + + def test_mimc31(self) -> None: + # pylint: disable=line-too-long + x = int(28948022309329048855892746252171976963317496166410141009864396001978282409983).to_bytes(32, 'big') # noqa + y = int(14220067918847996031108144435763672811050758065945364308986253046354060608451).to_bytes(32, 'big') # noqa + # pylint: enable=line-too-long + h = MiMC31().hash(x, y) + + result = CONTRACT_INSTANCE.functions.test_mimc31(x, y).call() + self.assertEqual(h, result) From b8e15abcfe2dfca3d09972f5174e6183f46420e1 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 22 Dec 2020 11:48:13 +0000 Subject: [PATCH 004/137] ci: cache npm and pip in contract and client checks --- .github/workflows/onpush-checks.yml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/.github/workflows/onpush-checks.yml b/.github/workflows/onpush-checks.yml index c93f1861e..4955c285c 100644 --- a/.github/workflows/onpush-checks.yml +++ b/.github/workflows/onpush-checks.yml @@ -15,6 +15,22 @@ jobs: - uses: actions/setup-node@v1 with: node-version: 10 + - name: Cache npm + uses: actions/cache@v1 + with: + path: ~/.npm + key: check-contracts-npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} + # Cache ganache-cli/node_modules to avoid recompiling native code + - name: Cache depends/ganache-cli/node_modules + uses: actions/cache@v1 + with: + path: depends/ganache-cli/node_modules + key: check-contracts-ganache-node-modules-${{ runner.os }}-${{ hashFiles('depends/ganache-cli/package-lock.json') }} + - name: Cache pip + uses: actions/cache@v2 + with: + path: ~/.cache/pip + key: check-contracts-pip-${{ runner.os }}-${{ hashFiles('client/setup.py') }} - name: Check Contracts run: scripts/ci check_contracts @@ -24,7 +40,12 @@ jobs: - uses: actions/checkout@v1 with: submodules: recursive - - name: Execute + - name: Cache pip + uses: actions/cache@v2 + with: + path: ~/.cache/pip + key: check-client-pip-${{ runner.os }}-${{ hashFiles('client/setup.py') }} + - name: Check Client run: scripts/ci check_client check-cpp-linux: From 8d64aa8363bb446d2eaee56a9f19569081e832ef Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 4 Jan 2021 12:20:29 +0000 Subject: [PATCH 005/137] client: expose further json methods on MixParameters --- client/zeth/core/mixer_client.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/zeth/core/mixer_client.py b/client/zeth/core/mixer_client.py index a3d810a25..57546e476 100644 --- a/client/zeth/core/mixer_client.py +++ b/client/zeth/core/mixer_client.py @@ -112,12 +112,12 @@ def __init__( @staticmethod def from_json(zksnark: IZKSnarkProvider, params_json: str) -> MixParameters: - return MixParameters._from_json_dict(zksnark, json.loads(params_json)) + return MixParameters.from_json_dict(zksnark, json.loads(params_json)) def to_json(self) -> str: - return json.dumps(self._to_json_dict()) + return json.dumps(self.to_json_dict()) - def _to_json_dict(self) -> Dict[str, Any]: + def to_json_dict(self) -> Dict[str, Any]: ext_proof_json = self.extended_proof.to_json_dict() signature_vk_json = [ str(x) for x in @@ -132,7 +132,7 @@ def _to_json_dict(self) -> Dict[str, Any]: } @staticmethod - def _from_json_dict( + def from_json_dict( zksnark: IZKSnarkProvider, json_dict: Dict[str, Any]) -> MixParameters: ext_proof = ExtendedProof.from_json_dict( From dd0f64f35ff85f1da78057a67e8079c5c81d3cca Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 5 Jan 2021 18:39:01 +0000 Subject: [PATCH 006/137] add dispatch call to mixer contract --- client/zeth/cli/zeth_deploy.py | 12 ++- client/zeth/core/mixer_client.py | 20 ++++ .../contracts/AltBN128MixerBase.sol | 6 +- .../contracts/AltBN128MixerBase_test.sol | 3 +- .../contracts/BLS12_377MixerBase.sol | 6 +- .../contracts/Groth16AltBN128Mixer.sol | 6 +- .../contracts/Groth16BLS12_377Mixer.sol | 6 +- zeth_contracts/contracts/MixerBase.sol | 91 ++++++++++++++++++- .../contracts/Pghr13AltBN128Mixer.sol | 10 +- 9 files changed, 144 insertions(+), 16 deletions(-) diff --git a/client/zeth/cli/zeth_deploy.py b/client/zeth/cli/zeth_deploy.py index cfc4f3767..8c0a550d7 100644 --- a/client/zeth/cli/zeth_deploy.py +++ b/client/zeth/cli/zeth_deploy.py @@ -20,6 +20,10 @@ default=INSTANCE_FILE_DEFAULT, help=f"File to write deployment address to (default={INSTANCE_FILE_DEFAULT})") @option("--token-address", help="Address of token contract (if used)") +@option( + "--permitted-dispatcher", + help="Address of contract permitted to call dispatch method") +@option("--vk-hash", type=str, help="verification key hash for dispatch calls") @option("--deploy-gas", type=int, help="Maximum gas, in Wei") @pass_context def deploy( @@ -27,7 +31,9 @@ def deploy( eth_addr: Optional[str], eth_private_key: Optional[str], instance_out: str, - token_address: str, + token_address: Optional[str], + permitted_dispatcher: Optional[str], + vk_hash: Optional[str], deploy_gas: Optional[int]) -> None: """ Deploy the zeth contracts and record the instantiation details. @@ -51,7 +57,9 @@ def deploy( eth_address, eth_private_key_data, token_address, - deploy_gas) + permitted_dispatcher=permitted_dispatcher, + vk_hash=vk_hash, + deploy_gas=deploy_gas) mixer_desc = MixerDescription(mixer_instance_desc, token_instance_desc) write_mixer_description(instance_out, mixer_desc) diff --git a/client/zeth/core/mixer_client.py b/client/zeth/core/mixer_client.py index 57546e476..7f353be9a 100644 --- a/client/zeth/core/mixer_client.py +++ b/client/zeth/core/mixer_client.py @@ -30,6 +30,7 @@ from Crypto import Random from hashlib import blake2s, sha256 import traceback +import eth_abi from typing import Tuple, Dict, List, Iterator, Callable, Optional, Any @@ -166,6 +167,21 @@ def mix_parameters_to_contract_arguments( ] +def mix_parameters_to_dispatch_parameters(mix_parameters: MixParameters) -> bytes: + """ + Encode parameters from mix_parameters into an array of uint256 values, + compatible with the `dispatch` method on Mixer. This conforms to the + `IZecaleApplicationan` solidity interface of Zecale + (https://github.com/clearmatics/zecale) + """ + vk_param = signing.verification_key_as_mix_parameter( + mix_parameters.signature_vk) + sigma_param = signing.signature_as_mix_parameter(mix_parameters.signature) + return eth_abi.encode_abi( + ['uint256[4]', 'uint256', 'bytes[]'], + [vk_param, sigma_param, mix_parameters.ciphertexts]) # type: ignore + + class MixOutputEvents: """ Event data for a single joinsplit output. Holds address (in merkle tree), @@ -252,6 +268,8 @@ def deploy( 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]: """ @@ -276,6 +294,8 @@ def deploy( 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 + int(vk_hash, 16) if vk_hash else 0, # vk_hash ] mixer_description = contracts.InstanceDescription.deploy( web3, diff --git a/zeth_contracts/contracts/AltBN128MixerBase.sol b/zeth_contracts/contracts/AltBN128MixerBase.sol index 6d8c06fa2..8df0c7cc2 100644 --- a/zeth_contracts/contracts/AltBN128MixerBase.sol +++ b/zeth_contracts/contracts/AltBN128MixerBase.sol @@ -38,10 +38,12 @@ contract AltBN128MixerBase is MixerBase constructor( uint256 mk_depth, address token, - uint256[] memory vk + uint256[] memory vk, + address permitted_dispatcher, + uint256 vk_hash ) public - MixerBase(mk_depth, token, vk) + MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) { } diff --git a/zeth_contracts/contracts/AltBN128MixerBase_test.sol b/zeth_contracts/contracts/AltBN128MixerBase_test.sol index d63bf2c6a..c3f767986 100644 --- a/zeth_contracts/contracts/AltBN128MixerBase_test.sol +++ b/zeth_contracts/contracts/AltBN128MixerBase_test.sol @@ -14,7 +14,8 @@ contract AltBN128MixerBase_test is AltBN128MixerBase { constructor(uint256 mk_depth) public - AltBN128MixerBase(mk_depth, address(0), new uint256[](0)) + AltBN128MixerBase( + mk_depth, address(0), new uint256[](0), address(0), 0) { } diff --git a/zeth_contracts/contracts/BLS12_377MixerBase.sol b/zeth_contracts/contracts/BLS12_377MixerBase.sol index 53cd845e6..b4625548b 100644 --- a/zeth_contracts/contracts/BLS12_377MixerBase.sol +++ b/zeth_contracts/contracts/BLS12_377MixerBase.sol @@ -45,10 +45,12 @@ contract BLS12_377MixerBase is MixerBase constructor( uint256 mk_depth, address token, - uint256[] memory vk + uint256[] memory vk, + address permitted_dispatcher, + uint256 vk_hash ) public - MixerBase(mk_depth, token, vk) + MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) { } diff --git a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol b/zeth_contracts/contracts/Groth16AltBN128Mixer.sol index 9949460ce..bd2fe6ccf 100644 --- a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Groth16AltBN128Mixer.sol @@ -15,10 +15,12 @@ contract Groth16AltBN128Mixer is AltBN128MixerBase constructor( uint256 mk_depth, address token, - uint256[] memory vk + uint256[] memory vk, + address permitted_dispatcher, + uint256 vk_hash ) public - AltBN128MixerBase(mk_depth, token, vk) + AltBN128MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) { } diff --git a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol b/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol index d00cf3258..0aa2c3ed4 100644 --- a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol +++ b/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol @@ -15,10 +15,12 @@ contract Groth16BLS12_377Mixer is BLS12_377MixerBase constructor( uint256 mk_depth, address token, - uint256[] memory vk + uint256[] memory vk, + address permitted_dispatcher, + uint256 vk_hash ) public - BLS12_377MixerBase(mk_depth, token, vk) + BLS12_377MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) { } diff --git a/zeth_contracts/contracts/MixerBase.sol b/zeth_contracts/contracts/MixerBase.sol index 2905aa97a..aae0bc147 100644 --- a/zeth_contracts/contracts/MixerBase.sol +++ b/zeth_contracts/contracts/MixerBase.sol @@ -27,6 +27,14 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // If token = address(0) then the mixer works with ether address private _token; + // Contract that is allowed to call the `dispatch` method, passing in the + // correct _vk_hash. (Disable the dispatch method by setting + // _permitted_dispatcher = 0, in which case _vk_hash is unused.) + address private _permitted_dispatcher; + + // The acceptable value of _vk_hash, passed in by a trusted dispatcher. + uint256 private _vk_hash; + // JoinSplit description, gives the number of inputs (nullifiers) and // outputs (commitments/ciphertexts) to receive and process. // @@ -84,7 +92,13 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract event LogDebug(string message); /// Constructor - constructor(uint256 depth, address token_address, uint256[] memory vk) + constructor( + uint256 depth, + address token_address, + uint256[] memory vk, + address permitted_dispatcher, + uint256 vk_hash + ) public BaseMerkleTree(depth) { @@ -92,6 +106,8 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract _roots[initialRoot] = true; _vk = vk; _token = token_address; + _permitted_dispatcher = permitted_dispatcher; + _vk_hash = vk_hash; } /// Function allowing external users of the contract to retrieve some of @@ -116,6 +132,68 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract num_inputs_out = NUM_INPUTS; } + /// Permitted dispatchers may call this entry point if they have verified + /// the associated proof. This is technically part of the + /// IZecaleApplication interface, see + /// https://github.com/clearmatics/zecale + function dispatch( + uint256 nested_vk_hash, + uint256[] memory nested_inputs, + bytes memory nested_parameters + ) + public + payable + { + // Sanity / permission checkcheck + require( + msg.sender == _permitted_dispatcher, "dispatcher not permitted"); + require(nested_vk_hash == _vk_hash, "invalid nested_vk_hash"); + require(nested_inputs.length == NUM_INPUTS); + + // Decode the nested parameters + // TODO: convert ciphertext array without copying + (uint256[4] memory vk, + uint256 sigma, + bytes[] memory decoded_ciphertexts) = abi.decode( + nested_parameters, (uint256[4], uint256, bytes[])); + bytes[JSOUT] memory ciphertexts; + for (uint256 i = 0 ; i < JSOUT ; ++i) { + ciphertexts[i] = decoded_ciphertexts[i]; + } + + // Copy the public inputs into a fixed-size array. + // TODO: convert without copying. + uint256[NUM_INPUTS] memory inputs; + for (uint256 i = 0 ; i < NUM_INPUTS ; ++i) { + inputs[i] = nested_inputs[i]; + } + + // 1. Check the root and the nullifiers + bytes32[JSIN] memory nullifiers; + check_mkroot_nullifiers_hsig_append_nullifiers_state( + vk, inputs, nullifiers); + + // 2.a Verify the signature on the hash of data_to_be_signed. + // hash_to_be_signed is expected to have been created without the proof + // data. + bytes32 hash_to_be_signed = sha256( + abi.encodePacked( + uint256(msg.sender), + ciphertexts[0], + ciphertexts[1], + inputs + ) + ); + require( + OTSchnorrVerifier.verify( + vk[0], vk[1], vk[2], vk[3], sigma, hash_to_be_signed), + "Invalid signature: Unable to verify the signature correctly" + ); + + mix_append_commitments_emit_and_handle_public_values( + inputs, ciphertexts, nullifiers); + } + /// This function is used to execute payments in zero knowledge. /// The format of `proof` is internal to the zk-snark library. /// The `inputs` array is the set of scalar inputs to the proof. @@ -160,6 +238,17 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract "Invalid proof: Unable to verify the proof correctly" ); + mix_append_commitments_emit_and_handle_public_values( + inputs, ciphertexts, nullifiers); + } + + function mix_append_commitments_emit_and_handle_public_values( + uint256[NUM_INPUTS] memory inputs, + bytes[JSOUT] memory ciphertexts, + bytes32[JSIN] memory nullifiers + ) + internal + { // 3. Append the commitments to the tree bytes32[JSOUT] memory commitments; assemble_commitments_and_append_to_state(inputs, commitments); diff --git a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol index 01123fb11..750a8c6ed 100644 --- a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol @@ -35,17 +35,19 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase constructor( uint256 mk_depth, address token, - uint256[] memory vk + uint256[] memory vk, + address permitted_dispatcher, + uint256 vk_hash ) public - AltBN128MixerBase(mk_depth, token, vk) + AltBN128MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) { uint256 vk_words = vk.length; require(vk_words >= 26, "invalid vk length"); } function verify( - uint256[num_inputs] memory input, + uint256[NUM_INPUTS] memory input, Proof memory proof ) internal @@ -148,7 +150,7 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase function verify_zk_proof( uint256[] memory proof_data, - uint256[num_inputs] memory inputs + uint256[NUM_INPUTS] memory inputs ) internal returns (bool) From 14f8c01f2fb01485ff0a9a10a906ccd702f0e988 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 6 Jan 2021 10:41:21 +0000 Subject: [PATCH 007/137] client: record permitted dispatcher and support dumping MixParameters --- client/zeth/cli/utils.py | 36 ++++++++++++++++++++++------------ client/zeth/cli/zeth_deploy.py | 6 +++++- client/zeth/cli/zeth_mix.py | 20 +++++++++++++++---- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/client/zeth/cli/utils.py b/client/zeth/cli/utils.py index 081976611..fc8127fb3 100644 --- a/client/zeth/cli/utils.py +++ b/client/zeth/cli/utils.py @@ -21,7 +21,7 @@ import json from os.path import exists, join, splitext from web3 import Web3 # type: ignore -from typing import Dict, Tuple, Optional, Callable, Any +from typing import Dict, Tuple, Optional, Callable, Any, cast class NetworkConfig: @@ -131,26 +131,36 @@ class MixerDescription: def __init__( self, mixer: InstanceDescription, - token: Optional[InstanceDescription]): + token: Optional[InstanceDescription], + permitted_dispatcher: Optional[str], + vk_hash: Optional[str]): self.mixer = mixer self.token = token + self.permitted_dispatcher = permitted_dispatcher + self.vk_hash = vk_hash - def to_json(self) -> str: - json_dict = { + def to_json_dict(self) -> Dict[str, Any]: + json_dict: Dict[str, Any] = { "mixer": self.mixer.to_json_dict() } if self.token: json_dict["token"] = self.token.to_json_dict() - return json.dumps(json_dict) + if self.permitted_dispatcher: + json_dict["permitted_dispatcher"] = self.permitted_dispatcher + if self.vk_hash: + json_dict["vk_hash"] = self.vk_hash + return json_dict @staticmethod - def from_json(json_str: str) -> MixerDescription: - json_dict = json.loads(json_str) + def from_json_dict(json_dict: Dict[str, Any]) -> MixerDescription: mixer = InstanceDescription.from_json_dict(json_dict["mixer"]) - token_dict = json_dict.get("token", None) + token_dict = cast(Optional[Dict[str, Any]], json_dict.get("token", None)) token = InstanceDescription.from_json_dict(token_dict) \ if token_dict else None - return MixerDescription(mixer, token) + permitted_dispatcher = \ + cast(Optional[str], json_dict.get("permitted_dispatcher", None)) + vk_hash = cast(Optional[str], json_dict.get("vk_hash", None)) + return MixerDescription(mixer, token, permitted_dispatcher, vk_hash) def get_erc20_abi() -> Dict[str, Any]: @@ -175,15 +185,15 @@ def write_mixer_description( Write the mixer (and token) instance information """ with open(mixer_desc_file, "w") as instance_f: - instance_f.write(mixer_desc.to_json()) + json.dump(mixer_desc.to_json_dict(), instance_f) -def load_mixer_description(mixer_description_file: str) -> MixerDescription: +def load_mixer_description(mixer_desc_file: str) -> MixerDescription: """ Return mixer and token (if present) contract instances """ - with open(mixer_description_file, "r") as desc_f: - return MixerDescription.from_json(desc_f.read()) + with open(mixer_desc_file, "r") as desc_f: + return MixerDescription.from_json_dict(json.load(desc_f)) def load_mixer_description_from_ctx(ctx: ClientConfig) -> MixerDescription: diff --git a/client/zeth/cli/zeth_deploy.py b/client/zeth/cli/zeth_deploy.py index 8c0a550d7..d731cf4c8 100644 --- a/client/zeth/cli/zeth_deploy.py +++ b/client/zeth/cli/zeth_deploy.py @@ -61,5 +61,9 @@ def deploy( vk_hash=vk_hash, deploy_gas=deploy_gas) - mixer_desc = MixerDescription(mixer_instance_desc, token_instance_desc) + mixer_desc = MixerDescription( + mixer=mixer_instance_desc, + token=token_instance_desc, + permitted_dispatcher=permitted_dispatcher, + vk_hash=vk_hash) write_mixer_description(instance_out, mixer_desc) diff --git a/client/zeth/cli/zeth_mix.py b/client/zeth/cli/zeth_mix.py index af3c08a5c..e9a596b18 100644 --- a/client/zeth/cli/zeth_mix.py +++ b/client/zeth/cli/zeth_mix.py @@ -11,6 +11,7 @@ from zeth.api.zeth_messages_pb2 import ZethNote from click import command, option, pass_context, ClickException, Context from typing import List, Tuple, Optional +import json @command() @@ -26,7 +27,8 @@ @option("--eth-addr", help="Sender's eth address or address filename") @option("--eth-private-key", help="Sender's eth private key file") @option("--wait", is_flag=True, help="Wait for transaction to be mined") -@option("--show-parameters", is_flag=True, help="Show the mixer parameters") +@option("--dump-parameters", help="Write mix parameters to file ('-' for stdout)") +@option("--dry-run", "-n", is_flag=True, help="Do not send the mix transaction") @pass_context def mix( ctx: Context, @@ -37,7 +39,8 @@ def mix( eth_addr: Optional[str], eth_private_key: Optional[str], wait: bool, - show_parameters: bool) -> None: + dump_parameters: Optional[str], + dry_run: bool) -> None: """ Generic mix function """ @@ -91,8 +94,17 @@ def mix( vin_pub, vout_pub) - if show_parameters: - print(f"mix_params={mix_params.to_json()}") + # Dump parameters if requested + if dump_parameters: + if dump_parameters == '-': + print(f"mix_params={mix_params.to_json()}") + else: + with open(dump_parameters, "w") as mix_params_f: + json.dump(mix_params.to_json_dict(), mix_params_f) + + # Early-out if dry_run flag is set + if dry_run: + return tx_hash = zeth_client.mix( mix_params=mix_params, From ea3db05ab311305f370783dea45294722c1e681b Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 6 Jan 2021 11:52:14 +0000 Subject: [PATCH 008/137] client: --for-dispatch-call flag to create parameters for dispatch calls --- client/zeth/cli/zeth_mix.py | 10 ++++-- client/zeth/core/mixer_client.py | 54 +++++++++++++++++++++++--------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/client/zeth/cli/zeth_mix.py b/client/zeth/cli/zeth_mix.py index e9a596b18..3b4ff32fd 100644 --- a/client/zeth/cli/zeth_mix.py +++ b/client/zeth/cli/zeth_mix.py @@ -27,6 +27,10 @@ @option("--eth-addr", help="Sender's eth address or address filename") @option("--eth-private-key", help="Sender's eth private key file") @option("--wait", is_flag=True, help="Wait for transaction to be mined") +@option( + "--for-dispatch-call", + is_flag=True, + help="Generate signature for later call to dispatch (implies --dry-run)") @option("--dump-parameters", help="Write mix parameters to file ('-' for stdout)") @option("--dry-run", "-n", is_flag=True, help="Do not send the mix transaction") @pass_context @@ -39,6 +43,7 @@ def mix( eth_addr: Optional[str], eth_private_key: Optional[str], wait: bool, + for_dispatch_call: bool, dump_parameters: Optional[str], dry_run: bool) -> None: """ @@ -92,7 +97,8 @@ def mix( inputs, outputs, vin_pub, - vout_pub) + vout_pub, + for_dispatch_call=for_dispatch_call) # Dump parameters if requested if dump_parameters: @@ -103,7 +109,7 @@ def mix( json.dump(mix_params.to_json_dict(), mix_params_f) # Early-out if dry_run flag is set - if dry_run: + if for_dispatch_call or dry_run: return tx_hash = zeth_client.mix( diff --git a/client/zeth/core/mixer_client.py b/client/zeth/core/mixer_client.py index 7f353be9a..8387c9eb3 100644 --- a/client/zeth/core/mixer_client.py +++ b/client/zeth/core/mixer_client.py @@ -512,8 +512,19 @@ def create_mix_parameters_from_proof( prover_inputs: ProofInputs, signing_keypair: signing.SigningKeyPair, ext_proof: ExtendedProof, - sender_eth_address: str + 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) \ @@ -531,7 +542,8 @@ def create_mix_parameters_from_proof( signing_keypair, sender_eth_address, ciphertexts, - ext_proof) + ext_proof, + for_dispatch_call) mix_params = MixParameters( ext_proof, signing_keypair.vk, signature, ciphertexts) @@ -547,11 +559,15 @@ def create_mix_parameters_and_signing_key( outputs: List[Tuple[ZethAddressPub, EtherValue]], v_in: EtherValue, v_out: EtherValue, - compute_h_sig_cb: Optional[ComputeHSigCB] = None + compute_h_sig_cb: Optional[ComputeHSigCB] = None, + for_dispatch_call: bool = False ) -> Tuple[MixParameters, JoinsplitSigKeyPair]: """ Convenience function around creation of MixCallDescription, ProofInputs, - Proof and MixParameters. + Proof and MixParameters. 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. """ # Generate prover inputs and signing key mix_call_desc = MixCallDescription( @@ -577,7 +593,8 @@ def create_mix_parameters_and_signing_key( prover_inputs, signing_keypair, ext_proof, - sender_eth_address) + sender_eth_address, + for_dispatch_call) return mix_params, signing_keypair @@ -655,20 +672,24 @@ def joinsplit_sign( signing_keypair: JoinsplitSigKeyPair, sender_eth_address: str, ciphertexts: List[bytes], - extproof: ExtendedProof) -> int: - """ - Generate a signature on the hash of the ciphertexts, proofs and - primary inputs. This is used to solve transaction malleability. We chose - to sign the hash and not the values themselves for modularity (to use the - same code regardless of whether GROTH16 or PGHR13 proof system is chosen), - and sign the hash of the ciphers and inputs for consistency. + extproof: ExtendedProof, + for_dispatch_call: bool = False) -> int: + """ + Generate a signature on the hash of the ciphertexts, proofs and primary + inputs. This is used to solve transaction malleability. We chose to sign + the hash and not the values themselves for modularity (to use the same code + regardless of whether GROTH16 or PGHR13 proof system is chosen), and sign + the hash of the ciphers and inputs for consistency. 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. """ assert len(ciphertexts) == constants.JS_INPUTS # The message to sign consists of (in order): # - senders Ethereum address # - ciphertexts - # - proof elements + # - proof elements (if for_dispatch_call is False) # - public input elements h = sha256() h.update(eth_address_to_bytes32(sender_eth_address)) @@ -677,7 +698,12 @@ def joinsplit_sign( proof_bytes, pub_inputs_bytes = _proof_and_inputs_to_bytes( zksnark, pp, extproof) - h.update(proof_bytes) + + # If for_dispatch_call is set, omit proof from the signature. See + # MixerBase.sol. + if not for_dispatch_call: + h.update(proof_bytes) + h.update(pub_inputs_bytes) message_digest = h.digest() return signing.sign(signing_keypair.sk, message_digest) From 9ada7be0ef01ca50a4161073086469972481c8d8 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 6 Jan 2021 15:49:00 +0000 Subject: [PATCH 009/137] client: fix spacing in core.contracts --- client/zeth/core/contracts.py | 1 - 1 file changed, 1 deletion(-) diff --git a/client/zeth/core/contracts.py b/client/zeth/core/contracts.py index 139ab4498..ede59a694 100644 --- a/client/zeth/core/contracts.py +++ b/client/zeth/core/contracts.py @@ -140,7 +140,6 @@ def send_contract_call( between hosted keys (sender_eth_private_key is None) and local keys (sender_eth_private_key is not None). Returns the hash of the broadcast transaction. - """ tx_desc: Dict[str, Union[str, int]] = {'from': sender_eth_addr} if value: From 7483f83f453165311c597028e914b799b601fe72 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 6 Jan 2021 15:49:31 +0000 Subject: [PATCH 010/137] client: fix comments in core.mixer_client --- client/zeth/core/mixer_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/zeth/core/mixer_client.py b/client/zeth/core/mixer_client.py index 8387c9eb3..a1be888fc 100644 --- a/client/zeth/core/mixer_client.py +++ b/client/zeth/core/mixer_client.py @@ -171,7 +171,7 @@ def mix_parameters_to_dispatch_parameters(mix_parameters: MixParameters) -> byte """ Encode parameters from mix_parameters into an array of uint256 values, compatible with the `dispatch` method on Mixer. This conforms to the - `IZecaleApplicationan` solidity interface of Zecale + `IZecaleApplication` solidity interface of Zecale (https://github.com/clearmatics/zecale) """ vk_param = signing.verification_key_as_mix_parameter( From 44f0e1c061b01a5d0e239c30f9792c3d3f4954d5 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 6 Jan 2021 16:12:46 +0000 Subject: [PATCH 011/137] client: clean up some OT-sig interfaces and support json encode/decode of key data --- client/tests/test_contracts.py | 6 +- client/tests/test_mixer_client.py | 6 +- client/tests/test_signing.py | 13 +++- client/zeth/core/mixer_client.py | 2 +- client/zeth/core/signing.py | 106 +++++++++++++++++++++++------- 5 files changed, 102 insertions(+), 31 deletions(-) diff --git a/client/tests/test_contracts.py b/client/tests/test_contracts.py index 0fa9a386c..6419d3fdb 100644 --- a/client/tests/test_contracts.py +++ b/client/tests/test_contracts.py @@ -9,7 +9,7 @@ from zeth.core.zksnark import ExtendedProof, Groth16 from zeth.core.mixer_client import MixParameters from zeth.core.encryption import generate_encryption_keypair, encrypt -from zeth.core.signing import gen_signing_keypair, sign, encode_vk_to_bytes +from zeth.core.signing import gen_signing_keypair, sign from zeth.core.constants import NOTE_LENGTH_BYTES from unittest import TestCase from secrets import token_bytes @@ -50,7 +50,7 @@ def test_mix_parameters(self) -> None: mix_params.extended_proof.to_json_dict(), mix_params_2.extended_proof.to_json_dict()) self.assertEqual( - encode_vk_to_bytes(mix_params.signature_vk), - encode_vk_to_bytes(mix_params_2.signature_vk)) + mix_params.signature_vk.to_bytes(), + mix_params_2.signature_vk.to_bytes()) self.assertEqual(mix_params.signature, mix_params_2.signature) self.assertEqual(mix_params.ciphertexts, mix_params_2.ciphertexts) diff --git a/client/tests/test_mixer_client.py b/client/tests/test_mixer_client.py index 977b8e6bd..03bc7edc2 100644 --- a/client/tests/test_mixer_client.py +++ b/client/tests/test_mixer_client.py @@ -5,7 +5,7 @@ from zeth.core.zksnark import ExtendedProof, Groth16 from zeth.core.mixer_client import MixParameters from zeth.core.encryption import generate_encryption_keypair, encrypt -from zeth.core.signing import gen_signing_keypair, sign, encode_vk_to_bytes +from zeth.core.signing import gen_signing_keypair, sign from zeth.core.constants import NOTE_LENGTH_BYTES from unittest import TestCase from secrets import token_bytes @@ -46,7 +46,7 @@ def test_mix_parameters(self) -> None: mix_params.extended_proof.to_json_dict(), mix_params_2.extended_proof.to_json_dict()) self.assertEqual( - encode_vk_to_bytes(mix_params.signature_vk), - encode_vk_to_bytes(mix_params_2.signature_vk)) + mix_params.signature_vk.to_bytes(), + mix_params_2.signature_vk.to_bytes()) self.assertEqual(mix_params.signature, mix_params_2.signature) self.assertEqual(mix_params.ciphertexts, mix_params_2.ciphertexts) diff --git a/client/tests/test_signing.py b/client/tests/test_signing.py index b88071405..25a3a4f76 100644 --- a/client/tests/test_signing.py +++ b/client/tests/test_signing.py @@ -44,6 +44,15 @@ def test_signature_encoding(self) -> None: """ m = sha256("clearmatics".encode()).digest() sig = signing.sign(self.keypair.sk, m) - sig_encoded = signing.encode_signature_to_bytes(sig) - sig_decoded = signing.decode_signature_from_bytes(sig_encoded) + sig_encoded = signing.signature_to_bytes(sig) + sig_decoded = signing.signature_from_bytes(sig_encoded) self.assertEqual(sig, sig_decoded) + + def test_keypair_encode_decode(self) -> None: + """ + Test encoding and decoding of key pair + """ + keypair = signing.gen_signing_keypair() + keypair_json = keypair.to_json_dict() + keypair2 = signing.SigningKeyPair.from_json_dict(keypair_json) + self.assertEqual(keypair_json, keypair2.to_json_dict()) diff --git a/client/zeth/core/mixer_client.py b/client/zeth/core/mixer_client.py index a1be888fc..07b18d057 100644 --- a/client/zeth/core/mixer_client.py +++ b/client/zeth/core/mixer_client.py @@ -753,7 +753,7 @@ def compute_h_sig( h = sha256() h.update(nf0) h.update(nf1) - h.update(signing.encode_vk_to_bytes(sign_vk)) + h.update(sign_vk.to_bytes()) return h.digest() diff --git a/client/zeth/core/signing.py b/client/zeth/core/signing.py index 58d0261f5..3dc02716b 100644 --- a/client/zeth/core/signing.py +++ b/client/zeth/core/signing.py @@ -11,11 +11,12 @@ BN128 """ +from __future__ import annotations from math import ceil from os import urandom from hashlib import sha256 from py_ecc import bn128 as ec -from typing import List, Tuple +from typing import Dict, List, Tuple, Any FQ = ec.FQ G1 = Tuple[ec.FQ, ec.FQ] @@ -31,9 +32,24 @@ class SigningVerificationKey: """ An OT-Schnorr verification key. """ - def __init__(self, x_g1: G1, y_g1: G1): - self.ppk = x_g1 - self.spk = y_g1 + def __init__(self, ppk: G1, spk: G1): + self.ppk = ppk + self.spk = spk + + def to_bytes(self) -> bytes: + return g1_to_bytes(self.ppk) + g1_to_bytes(self.spk) + + def to_json_dict(self) -> Dict[str, Any]: + return { + "ppk": g1_to_json_dict(self.ppk), + "spk": g1_to_json_dict(self.spk), + } + + @staticmethod + def from_json_dict(json_dict: Dict[str, Any]) -> SigningVerificationKey: + return SigningVerificationKey( + ppk=g1_from_json_dict(json_dict["ppk"]), + spk=g1_from_json_dict(json_dict["spk"])) class SigningSecretKey: @@ -44,18 +60,40 @@ def __init__(self, x: FQ, y: FQ, y_g1: G1): self.psk = x self.ssk = (y, y_g1) + def to_json_dict(self) -> Dict[str, Any]: + return { + "psk": fq_to_hex(self.psk), + "ssk_y": fq_to_hex(self.ssk[0]), + "ssk_y_g1": g1_to_json_dict(self.ssk[1]), + } + + @staticmethod + def from_json_dict(json_dict: Dict[str, Any]) -> SigningSecretKey: + return SigningSecretKey( + x=fq_from_hex(json_dict["psk"]), + y=fq_from_hex(json_dict["ssk_y"]), + y_g1=g1_from_json_dict(json_dict["ssk_y_g1"])) + class SigningKeyPair: """ An OT-Schnorr signing and verification keypair. """ - def __init__(self, x: FQ, y: FQ, x_g1: G1, y_g1: G1): - # We include y_g1 in the signing key - self.sk = SigningSecretKey(x, y, y_g1) - self.vk = SigningVerificationKey(x_g1, y_g1) + def __init__(self, sk: SigningSecretKey, vk: SigningVerificationKey): + self.sk = sk + self.vk = vk + def to_json_dict(self) -> Dict[str, Any]: + return { + "sk": self.sk.to_json_dict(), + "vk": self.vk.to_json_dict(), + } -Signature = int + @staticmethod + def from_json_dict(json_dict: Dict[str, Any]) -> SigningKeyPair: + return SigningKeyPair( + SigningSecretKey.from_json_dict(json_dict["sk"]), + SigningVerificationKey.from_json_dict(json_dict["vk"])) def gen_signing_keypair() -> SigningKeyPair: @@ -70,25 +108,21 @@ def gen_signing_keypair() -> SigningKeyPair: int(bytes(urandom(key_size_byte)).hex(), 16) % SIGNATURE_PRIME) X = ec.multiply(ec.G1, x.n) Y = ec.multiply(ec.G1, y.n) - return SigningKeyPair(x, y, X, Y) + # We include y_g1 in the signing key + sk = SigningSecretKey(x, y, Y) + vk = SigningVerificationKey(X, Y) + return SigningKeyPair(sk, vk) -def encode_vk_to_bytes(vk: SigningVerificationKey) -> bytes: - """ - Encode a verification key as a byte string - We assume here the group prime $p$ is written in less than 256 bits - to conform with Ethereum bytes32 type - """ - vk_byte = g1_to_bytes(vk.ppk) - vk_byte += g1_to_bytes(vk.spk) - return vk_byte + +Signature = int -def encode_signature_to_bytes(signature: Signature) -> bytes: +def signature_to_bytes(signature: Signature) -> bytes: return signature.to_bytes(32, byteorder='big') -def decode_signature_from_bytes(sig_bytes: bytes) -> Signature: +def signature_from_bytes(sig_bytes: bytes) -> Signature: return int.from_bytes(sig_bytes, byteorder='big') @@ -111,7 +145,6 @@ def sign( # Compute the signature sigma sigma = (sk.ssk[0].n + challenge * sk.psk.n) % SIGNATURE_PRIME - return sigma @@ -168,6 +201,24 @@ def signature_from_mix_parameter(param: int) -> Signature: """ return param +# Low level encoding / decoding functions + + +def fq_to_bytes(fq_element: FQ) -> bytes: + return int(fq_element.n).to_bytes(32, byteorder='big') + + +def fq_from_bytes(fq_bytes: bytes) -> FQ: + return FQ(int.from_bytes(fq_bytes, byteorder='big')) + + +def fq_to_hex(fq_element: FQ) -> str: + return fq_to_bytes(fq_element).hex() + + +def fq_from_hex(fq_hex: str) -> FQ: + return fq_from_bytes(bytes.fromhex(fq_hex)) + def g1_to_bytes(group_el: G1) -> bytes: """ @@ -178,3 +229,14 @@ def g1_to_bytes(group_el: G1) -> bytes: return \ int(group_el[0]).to_bytes(32, byteorder='big') + \ int(group_el[1]).to_bytes(32, byteorder='big') + + +def g1_to_json_dict(group_el: G1) -> Dict[str, Any]: + return { + "x": fq_to_hex(group_el[0]), + "y": fq_to_hex(group_el[1]), + } + + +def g1_from_json_dict(json_dict: Dict[str, Any]) -> G1: + return (fq_from_hex(json_dict["x"]), fq_from_hex(json_dict["y"])) From 0b4ee1e2757a093a1b30d42b3eb49db509f42f7b Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 6 Jan 2021 16:14:23 +0000 Subject: [PATCH 012/137] client: removed duplicated test code --- client/tests/test_contracts.py | 56 ---------------------------------- 1 file changed, 56 deletions(-) delete mode 100644 client/tests/test_contracts.py diff --git a/client/tests/test_contracts.py b/client/tests/test_contracts.py deleted file mode 100644 index 6419d3fdb..000000000 --- a/client/tests/test_contracts.py +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright (c) 2015-2021 Clearmatics Technologies Ltd -# -# SPDX-License-Identifier: LGPL-3.0+ - -""" -Tests for zeth.core.contracts module -""" - -from zeth.core.zksnark import ExtendedProof, Groth16 -from zeth.core.mixer_client import MixParameters -from zeth.core.encryption import generate_encryption_keypair, encrypt -from zeth.core.signing import gen_signing_keypair, sign -from zeth.core.constants import NOTE_LENGTH_BYTES -from unittest import TestCase -from secrets import token_bytes - - -class TestContracts(TestCase): - - def test_mix_parameters(self) -> None: - zksnark = Groth16() - - ext_proof = ExtendedProof( - proof=Groth16.proof_from_json_dict({ - "a": ["1234", "2345"], - "b": [["3456", "4567"], ["5678", "6789"]], - "c": ["789a", "89ab"], - }), - inputs=[ - "9abc", - "abcd", - "bcde", - "cdef", - ]) - sig_keypair = gen_signing_keypair() - sig_vk = sig_keypair.vk - sig = sign(sig_keypair.sk, bytes.fromhex("00112233")) - receiver_enc_keypair = generate_encryption_keypair() - ciphertexts = [ - encrypt(token_bytes(NOTE_LENGTH_BYTES), receiver_enc_keypair.k_pk), - encrypt(token_bytes(NOTE_LENGTH_BYTES), receiver_enc_keypair.k_pk), - ] - - mix_params = MixParameters(ext_proof, sig_vk, sig, ciphertexts) - - mix_params_json = mix_params.to_json() - mix_params_2 = MixParameters.from_json(zksnark, mix_params_json) - - self.assertEqual( - mix_params.extended_proof.to_json_dict(), - mix_params_2.extended_proof.to_json_dict()) - self.assertEqual( - mix_params.signature_vk.to_bytes(), - mix_params_2.signature_vk.to_bytes()) - self.assertEqual(mix_params.signature, mix_params_2.signature) - self.assertEqual(mix_params.ciphertexts, mix_params_2.ciphertexts) From 5d1867499ae9dd85a56d024099d3a671e3740e63 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 6 Jan 2021 16:23:50 +0000 Subject: [PATCH 013/137] client: flag to dump signing key used to create MixParameters --- client/zeth/cli/zeth_mix.py | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/client/zeth/cli/zeth_mix.py b/client/zeth/cli/zeth_mix.py index 3b4ff32fd..5b44d7a78 100644 --- a/client/zeth/cli/zeth_mix.py +++ b/client/zeth/cli/zeth_mix.py @@ -32,6 +32,10 @@ is_flag=True, help="Generate signature for later call to dispatch (implies --dry-run)") @option("--dump-parameters", help="Write mix parameters to file ('-' for stdout)") +@option( + "--dump-signing-keypair", + help="Write signing keypair to file ('-' for stdout). " + "USE ONLY FOR DEBUGGING.") @option("--dry-run", "-n", is_flag=True, help="Do not send the mix transaction") @pass_context def mix( @@ -45,6 +49,7 @@ def mix( wait: bool, for_dispatch_call: bool, dump_parameters: Optional[str], + dump_signing_keypair: Optional[str], dry_run: bool) -> None: """ Generic mix function @@ -89,16 +94,17 @@ def mix( # Create the MixParameters object manually so they can be displayed. # TODO: support saving the generated MixParameters to be sent later. - mix_params, _ = zeth_client.create_mix_parameters_and_signing_key( - prover_client, - wallet.merkle_tree, - zeth_address.ownership_keypair(), - eth_address, - inputs, - outputs, - vin_pub, - vout_pub, - for_dispatch_call=for_dispatch_call) + mix_params, signing_keypair = \ + zeth_client.create_mix_parameters_and_signing_key( + prover_client, + wallet.merkle_tree, + zeth_address.ownership_keypair(), + eth_address, + inputs, + outputs, + vin_pub, + vout_pub, + for_dispatch_call=for_dispatch_call) # Dump parameters if requested if dump_parameters: @@ -108,6 +114,14 @@ def mix( with open(dump_parameters, "w") as mix_params_f: json.dump(mix_params.to_json_dict(), mix_params_f) + # Dump one-time signature keypair if requested + if dump_signing_keypair: + if dump_signing_keypair == '-': + print(f"signing_key={signing_keypair.to_json_dict()}") + else: + with open(dump_signing_keypair, "w") as signing_keypair_f: + json.dump(signing_keypair.to_json_dict(), signing_keypair_f) + # Early-out if dry_run flag is set if for_dispatch_call or dry_run: return From 452e8ec18841ddd5bbe0aaa39b1b9a2359a592a2 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 6 Jan 2021 17:25:22 +0000 Subject: [PATCH 014/137] client: contract test for mixer dispatch method and parameter creation --- .../test_altbn128_mixer_base.py | 126 +++++++++++++++++- scripts/test_zeth_cli | 5 + .../contracts/AltBN128MixerBase_test.sol | 12 +- 3 files changed, 138 insertions(+), 5 deletions(-) diff --git a/client/test_contracts/test_altbn128_mixer_base.py b/client/test_contracts/test_altbn128_mixer_base.py index 267d3175c..4c3ecec79 100644 --- a/client/test_contracts/test_altbn128_mixer_base.py +++ b/client/test_contracts/test_altbn128_mixer_base.py @@ -6,9 +6,17 @@ from zeth.core.constants import \ JS_INPUTS, ZETH_PUBLIC_UNIT_VALUE, ZETH_MERKLE_TREE_DEPTH +from zeth.core.prover_client import ProverConfiguration +from zeth.core.zksnark import get_zksnark_provider +from zeth.core.utils import EtherValue, hex_list_to_uint256_list +from zeth.core.signing import SigningKeyPair +from zeth.core.mixer_client import MixParameters, MixerClient, joinsplit_sign, \ + mix_parameters_to_dispatch_parameters +import zeth.core.contracts as contracts +import tests.test_pairing as test_pairing import test_commands.mock as mock from unittest import TestCase -from typing import Any +from typing import Dict, Optional, Any # pylint: disable=line-too-long @@ -92,15 +100,85 @@ PACKED_PRIMARY_INPUTS = \ [ROOT] + COMMITMENTS + NULLIFIERS + [HSIG] + HTAGS + [RESIDUAL_BITS] +PROVER_CONFIG = ProverConfiguration( + zksnark_name="GROTH16", + pairing_parameters=test_pairing.ALT_BN128_PAIRING) + +VK_HASH = 1 + +MIX_PARAMETERS_VIN = EtherValue(200) + +# Signing key and mix parameters obtained from the test_zeth_cli scripts. See +# scripts/test_zeth_cli. + +MIX_PARAMETERS_SIGNING_KEYPAIR = SigningKeyPair.from_json_dict({ + "sk": { + "psk": "19cca1b1f0a3389880a51c5dad6da41885f1aa2a85d3895a7ee57cd93b91d92d", + "ssk_y": "091f01468410d87af0308ca0e27580de7ce59b5771dbadf47c1831dcbd8d2ec2", # noqa + "ssk_y_g1": { + "x": "0f9a984abbea6e4f61a927d7fc7aa1ac997fd98edc7c57f43888ec025ba58de9", # noqa + "y": "08c7c8dcea11753d8ce4c77b70f3da5f497f3ecd6745e108d5080fae9936e66f", # noqa + }, + }, + "vk": { + "ppk": { + "x": "2142d7e3c856f37296366fbde935161d62f3e51685d91e541b2c44df830e9fd7", # noqa + "y": "2da8644fa7c59b29d23d6a16591838dbfee30d281e0837dcdbf18fcca9eea54a", # noqa + }, + "spk": { + "x": "0f9a984abbea6e4f61a927d7fc7aa1ac997fd98edc7c57f43888ec025ba58de9", # noqa + "y": "08c7c8dcea11753d8ce4c77b70f3da5f497f3ecd6745e108d5080fae9936e66f", # noqa + } + } +}) + +MIX_PARAMETERS_DICT: Dict[str, Any] = { + "extended_proof": { + "proof": { + "a": ["0x022fc050ed6c153dcbfb1f18fdffd86e99e76bf9f9ceeb74b921be467df44d4f", "0x0473a961d1990f60799eff2bc2b8cb33cbeb4644fb87c3a2b5fa16b3cb662c80"], # noqa + "b": [["0x14f5918361b5f09955f822b378d4cb363265cdbf43ac3eae9594f93b25c740a5", "0x1caab696a800e657558485215194cfb5915ddea3fc9001537d1811fba04068b3"], ["0x1e2552d77e7af276b2d92a3a61e4fdeab0487af08c63f65902de91a7d5a21824", "0x0f1380685f4aba028770692dd3ccdbdc3ba4758482344784e34cee54f9f8b4a1"]], # noqa + "c": ["0x2bc2e2bfe646a10d5f220b21b5149bf724a8d34fd5f713775095b65f108ce90e", "0x1dc8f1acf805daf143686385f17ad06f4768e600555abbd1b21b65393ff196e8"], # noqa + }, + "inputs": [ + "0x01e202cf4ac3721b9bfd398ec65969c811f32cb1e46df020337e9fc2fda0f014", + "0x19917fa2eea86a9082ef7766c7e7737c4153a499796baf01f68787d267b278cc", + "0x15e8587966977c5c5430cb9e84e686ee5f327ec2651a86c978ed7973ee8cd4b9", + "0x10c16790b950db6a0fd94ee66015d37e506e7a970cbbc962325839188ddd4875", + "0x029eae0aed749a8e05565a5228b825ac6e9a8ad034dbc7b674786783bae64be2", + "0x0945c9391ddd49eb41234a2249c78203040bf337ab27e1dd7a3c112010bc160d", + "0x03fb8ae204697d92aa1cb161a8fd533d62c9d4113db1de78547aa330f8148510", + "0x03dc42c147cc05ef3e5c3aae875a860dd73e7be3bc9578499a171f52cc5949e7", + "0x00000000000000000000000000001663000000000bebc2000000000000000000", + ], + }, + "signature_vk": [ + "15044425925993845483393126099570793906913594542449620874334342139863918092247", # noqa + "20651600815268664951459086661967759114548020657233676039273591752689993033034", # noqa + "7057838256995470367292750127543080978509804434882431937449883270040531602921", # noqa + "3971491659664912517391994943672743161518296354269326311016522861877057218159", # noqa + ], + "signature": "10654946530806799981365073476369904106395106992608919376340445285630856100688", # noqa + "ciphertexts": [ + "f976f9b61cb10cb3275c7dc5941c314e8a6f894e312426f005322fdc7cc7ec3ba895de2033c09e19e35720f416ac8cbfd131048e38e244a56bf0ade2a9367c5fbf8a7976f59d270f590f6eb5ab9fbf35afa4550866837a29553bb6610cd0a5f57ca5b9ae6cf1d536ace98f1a58b7fde2030d013a6c4869875c3689ffbe535dbe2dcaad2b7f396eb2124d2d328a88e54c4ff524e417f1b57b", # noqa + "31424a6831ff6b7b5948ba5d7472030cf3427eeb730e974475d756995e48a1266b4ba550b6e28eb8b6b6367b3e7b7308ff2c1d641adcebaa818d3f325869bc66889c5e269673acbdfaa481feb5c57ef0ecccdcb58a8293dd347cf9a8423717dbea48119ebdc5b660f94a9ad1f43848299e02bcf07c59d3c594d65a486aa850c7adb7793673b965dfe27309631de9cad66638669afc16abea", # noqa + ], +} + +WEB3: Optional[Any] = None + +ETH: Optional[Any] = None + MIXER_INSTANCE: Any = None +MIXER_CLIENT: Optional[MixerClient] = None + class TestAltBN128MixerBaseContract(TestCase): @staticmethod def setUpClass() -> None: print("Deploying AltBN128MixerBase_test.sol") - _web3, eth = mock.open_test_web3() + web3, eth = mock.open_test_web3() deployer_eth_address = eth.accounts[0] _mixer_interface, mixer_instance = mock.deploy_contract( eth, @@ -108,9 +186,18 @@ def setUpClass() -> None: "AltBN128MixerBase_test", { 'mk_depth': ZETH_MERKLE_TREE_DEPTH, + 'permitted_dispatcher': deployer_eth_address, + 'vk_hash': VK_HASH, }) - global MIXER_INSTANCE # pylint: disable=global-statement + + global WEB3 # pylint: disable=global-statement + WEB3 = web3 + global ETH # pylint: disable=global-statement + ETH = eth + global MIXER_INSTANCE # pylint: disable=global-statement MIXER_INSTANCE = mixer_instance + global MIXER_CLIENT # pylint: disable=global-statement + MIXER_CLIENT = MixerClient(web3, PROVER_CONFIG, MIXER_INSTANCE) def test_assemble_nullifiers(self) -> None: # Test retrieving nullifiers @@ -135,3 +222,36 @@ def test_assemble_vpub(self) -> None: v_out_expect = VPUB[1] * ZETH_PUBLIC_UNIT_VALUE self.assertEqual(v_in_expect, v_in) self.assertEqual(v_out_expect, v_out) + + def test_dispatch_call(self) -> None: + # Test calling dispatch. Use the "dummy" MixParameters and signing key, + # recreating the signature for the sender. + + zksnark = get_zksnark_provider(PROVER_CONFIG.zksnark_name) + sender_eth_address = ETH.accounts[0] # type: ignore + mix_params = MixParameters.from_json_dict(zksnark, MIX_PARAMETERS_DICT) + new_signature = joinsplit_sign( + zksnark=get_zksnark_provider(PROVER_CONFIG.zksnark_name), + pp=PROVER_CONFIG.pairing_parameters, + signing_keypair=MIX_PARAMETERS_SIGNING_KEYPAIR, + sender_eth_address=sender_eth_address, + ciphertexts=mix_params.ciphertexts, + extproof=mix_params.extended_proof, + for_dispatch_call=True) + mix_params.signature = new_signature + + nested_inputs = hex_list_to_uint256_list(mix_params.extended_proof.inputs) + nested_parameters = mix_parameters_to_dispatch_parameters(mix_params) + mixer_call = MIXER_INSTANCE.functions.dispatch( + VK_HASH, nested_inputs, nested_parameters) + + # Broadcast transaction and wait for the result. + tx_id = contracts.send_contract_call( + web3=WEB3, + call=mixer_call, + sender_eth_addr=sender_eth_address, + sender_eth_private_key=None, + value=MIX_PARAMETERS_VIN) + tx_receipt = ETH.waitForTransactionReceipt(tx_id, 10000) # type: ignore + status = tx_receipt.status + self.assertEqual(True, status) diff --git a/scripts/test_zeth_cli b/scripts/test_zeth_cli index 667d023eb..27bc5afb7 100755 --- a/scripts/test_zeth_cli +++ b/scripts/test_zeth_cli @@ -40,6 +40,11 @@ copy_deployment_info deployer charlie pushd alice alice_pk=`cat zeth-address.pub` if ! [ -e notes/state_zeth ] ; then + # Uncomment the following command to create dispatch call data for this transaction + # zeth mix --wait --vin 200 --out ${alice_pk},200 \ + # --for-dispatch-call \ + # --dump-signing-keypair deposit_otsig_keypair.json \ + # --dump-parameters deposit_mixparams.json zeth mix --wait --vin 200 --out ${alice_pk},200 fi note_id=`zeth ls-notes | tail -n 1 | grep -oe '^[A-Za-z0-9]\+'` diff --git a/zeth_contracts/contracts/AltBN128MixerBase_test.sol b/zeth_contracts/contracts/AltBN128MixerBase_test.sol index c3f767986..7757413e8 100644 --- a/zeth_contracts/contracts/AltBN128MixerBase_test.sol +++ b/zeth_contracts/contracts/AltBN128MixerBase_test.sol @@ -12,10 +12,18 @@ import "./AltBN128MixerBase.sol"; // specific methods. contract AltBN128MixerBase_test is AltBN128MixerBase { - constructor(uint256 mk_depth) + constructor( + uint256 mk_depth, + address permitted_dispatcher, + uint256 vk_hash + ) public AltBN128MixerBase( - mk_depth, address(0), new uint256[](0), address(0), 0) + mk_depth, + address(0), + new uint256[](0), + permitted_dispatcher, + vk_hash) { } From 137c8499d0f8f1cec88195c403ad5b7d0762ad88 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 7 Jan 2021 16:18:42 +0000 Subject: [PATCH 015/137] client: get-verification-key command --- client/zeth/cli/zeth | 2 ++ client/zeth/cli/zeth_get_verification_key.py | 37 ++++++++++++++++++++ scripts/test_zeth_cli | 3 ++ 3 files changed, 42 insertions(+) create mode 100644 client/zeth/cli/zeth_get_verification_key.py diff --git a/client/zeth/cli/zeth b/client/zeth/cli/zeth index cf4b8d7e6..6bbde787e 100644 --- a/client/zeth/cli/zeth +++ b/client/zeth/cli/zeth @@ -9,6 +9,7 @@ from zeth.cli.constants import \ INSTANCE_FILE_DEFAULT, ZETH_SECRET_ADDRESS_FILE_DEFAULT, WALLET_DIR_DEFAULT, \ ETH_NETWORK_FILE_DEFAULT, ETH_NETWORK_DEFAULT from zeth.cli.utils import ClientConfig +from zeth.cli.zeth_get_verification_key import get_verification_key from zeth.cli.zeth_deploy import deploy from zeth.cli.zeth_gen_address import gen_address from zeth.cli.zeth_sync import sync @@ -80,6 +81,7 @@ def zeth( wallet_dir=wallet_dir) +zeth.add_command(get_verification_key) zeth.add_command(deploy) zeth.add_command(gen_address) zeth.add_command(sync) diff --git a/client/zeth/cli/zeth_get_verification_key.py b/client/zeth/cli/zeth_get_verification_key.py new file mode 100644 index 000000000..31a750adb --- /dev/null +++ b/client/zeth/cli/zeth_get_verification_key.py @@ -0,0 +1,37 @@ +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd +# +# SPDX-License-Identifier: LGPL-3.0+ + +from click import command, option, Context, pass_context + +from zeth.core.zksnark import get_zksnark_provider +from zeth.cli.utils import create_prover_client +import json +from typing import Optional + + +@command() +@option("--vk-out", "-o", help="Output file") +@pass_context +def get_verification_key(ctx: Context, vk_out: Optional[str]) -> None: + """ + Command help text. + """ + + # Get the VK (proto object) + client_ctx = ctx.obj + prover_client = create_prover_client(client_ctx) + vk_proto = prover_client.get_verification_key() + + # Get a zksnark provider and convert the VK to json + zksnark_name = prover_client.get_configuration().zksnark_name + zksnark = get_zksnark_provider(zksnark_name) + vk = zksnark.verification_key_from_proto(vk_proto) + vk_json = vk.to_json_dict() + + # Write the json to stdout or a file + if vk_out: + with open(vk_out, "w") as vk_f: + json.dump(vk_json, vk_f) + else: + print(json.dumps(vk_json)) diff --git a/scripts/test_zeth_cli b/scripts/test_zeth_cli index 27bc5afb7..439e88d9f 100755 --- a/scripts/test_zeth_cli +++ b/scripts/test_zeth_cli @@ -38,6 +38,9 @@ copy_deployment_info deployer charlie # Alice deposits 200 and sends 100 to Bob pushd alice +# Test getting vk from prover server +[ -e vk.json ] || zeth get-verification-key --vk-out vk.json + alice_pk=`cat zeth-address.pub` if ! [ -e notes/state_zeth ] ; then # Uncomment the following command to create dispatch call data for this transaction From dda1ed185c2fef5cd33ddfca4d62fc957ba7584a Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 7 Jan 2021 21:56:00 +0000 Subject: [PATCH 016/137] cient: util function to parse contract address --- client/zeth/cli/utils.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/client/zeth/cli/utils.py b/client/zeth/cli/utils.py index fc8127fb3..361e909cf 100644 --- a/client/zeth/cli/utils.py +++ b/client/zeth/cli/utils.py @@ -118,6 +118,20 @@ def open_web3_from_network(eth_net: NetworkConfig) -> Any: insecure=eth_net.insecure) +def load_contract_address(contract_addr: str) -> str: + """ + Parse a string as either an eth address, or a contract instance file. + """ + if contract_addr.startswith("0x"): + return Web3.toChecksumAddress(contract_addr) + if exists(contract_addr): + with open(contract_addr, "r") as instance_f: + instance = InstanceDescription.from_json_dict(json.load(instance_f)) + return Web3.toChecksumAddress(instance.address) + raise ClickException( + f"failed to parse as address or instance file: {contract_addr}") + + def open_web3_from_ctx(ctx: ClientConfig) -> Any: eth_net = get_eth_network(ctx.eth_network) return open_web3_from_network(eth_net) From 97f3373c8ef85621fc7824a80ae705f03b9fdcfe Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 7 Jan 2021 21:58:05 +0000 Subject: [PATCH 017/137] client: make zeth mixer description compatible with regular contract instance description --- client/zeth/cli/utils.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/client/zeth/cli/utils.py b/client/zeth/cli/utils.py index 361e909cf..827db4162 100644 --- a/client/zeth/cli/utils.py +++ b/client/zeth/cli/utils.py @@ -140,7 +140,9 @@ def open_web3_from_ctx(ctx: ClientConfig) -> Any: class MixerDescription: """ Holds an InstanceDescription for the mixer contract, and optionally an - InstanceDescription for the token contract. + InstanceDescription for the token contract. When serialized to json, the + InstanceDescription for the mixer is held in the top-level object, so that + MixerDescription is compatible with a regular contract instance. """ def __init__( self, @@ -154,26 +156,31 @@ def __init__( self.vk_hash = vk_hash def to_json_dict(self) -> Dict[str, Any]: - json_dict: Dict[str, Any] = { - "mixer": self.mixer.to_json_dict() - } + # Create an InstanceDescription JSON object, adding a "zeth_mixer" + # attribute for the extra data. + json_dict = self.mixer.to_json_dict() + + zeth_mixer: Dict[str, Any] = {} if self.token: - json_dict["token"] = self.token.to_json_dict() + zeth_mixer["token"] = self.token.to_json_dict() if self.permitted_dispatcher: - json_dict["permitted_dispatcher"] = self.permitted_dispatcher + zeth_mixer["permitted_dispatcher"] = self.permitted_dispatcher if self.vk_hash: - json_dict["vk_hash"] = self.vk_hash + zeth_mixer["vk_hash"] = self.vk_hash + json_dict["zeth_mixer"] = zeth_mixer return json_dict @staticmethod def from_json_dict(json_dict: Dict[str, Any]) -> MixerDescription: - mixer = InstanceDescription.from_json_dict(json_dict["mixer"]) - token_dict = cast(Optional[Dict[str, Any]], json_dict.get("token", None)) + zeth_mixer = json_dict["zeth_mixer"] + + mixer = InstanceDescription.from_json_dict(json_dict) + token_dict = cast(Optional[Dict[str, Any]], zeth_mixer.get("token", None)) token = InstanceDescription.from_json_dict(token_dict) \ if token_dict else None permitted_dispatcher = \ - cast(Optional[str], json_dict.get("permitted_dispatcher", None)) - vk_hash = cast(Optional[str], json_dict.get("vk_hash", None)) + cast(Optional[str], zeth_mixer.get("permitted_dispatcher", None)) + vk_hash = cast(Optional[str], zeth_mixer.get("vk_hash", None)) return MixerDescription(mixer, token, permitted_dispatcher, vk_hash) From 7d20964ddb988144bf7ca9283eccb1f12caa7766 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 7 Jan 2021 21:58:56 +0000 Subject: [PATCH 018/137] client: improve support for permitted_dispatcher and vk_hash in deploy command --- client/zeth/cli/zeth_deploy.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/client/zeth/cli/zeth_deploy.py b/client/zeth/cli/zeth_deploy.py index d731cf4c8..729f003a3 100644 --- a/client/zeth/cli/zeth_deploy.py +++ b/client/zeth/cli/zeth_deploy.py @@ -6,9 +6,9 @@ from zeth.cli.utils import \ open_web3_from_ctx, get_erc20_instance_description, load_eth_address, \ load_eth_private_key, write_mixer_description, MixerDescription, \ - create_prover_client + create_prover_client, load_contract_address from zeth.core.mixer_client import MixerClient -from click import Context, command, option, pass_context +from click import Context, command, option, pass_context, ClickException from typing import Optional @@ -22,7 +22,7 @@ @option("--token-address", help="Address of token contract (if used)") @option( "--permitted-dispatcher", - help="Address of contract permitted to call dispatch method") + help="Instance file or address of contract permitted to call dispatch method") @option("--vk-hash", type=str, help="verification key hash for dispatch calls") @option("--deploy-gas", type=int, help="Maximum gas, in Wei") @pass_context @@ -43,10 +43,19 @@ def deploy( client_ctx = ctx.obj web3 = open_web3_from_ctx(client_ctx) + if bool(permitted_dispatcher) != bool(vk_hash): + raise ClickException( + "Must supply BOTH --permitted-dispatch AND --vk-hash, or NEITHER") + print(f"deploy: eth_address={eth_address}") print(f"deploy: instance_out={instance_out}") print(f"deploy: token_address={token_address}") + if permitted_dispatcher: + permitted_dispatcher = load_contract_address(permitted_dispatcher) + print(f"deploy: permitted_dispatcher={permitted_dispatcher}") + print(f"deploy: vk_hash={vk_hash}") + token_instance_desc = get_erc20_instance_description(token_address) \ if token_address else None From c860cd1f047ebc0e3845bed399205fedededb58d Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 7 Jan 2021 22:00:04 +0000 Subject: [PATCH 019/137] client: remove some legacy output from prover_client --- client/zeth/core/prover_client.py | 1 - 1 file changed, 1 deletion(-) diff --git a/client/zeth/core/prover_client.py b/client/zeth/core/prover_client.py index 8b6095007..eb7126114 100644 --- a/client/zeth/core/prover_client.py +++ b/client/zeth/core/prover_client.py @@ -99,7 +99,6 @@ def get_verification_key(self) -> VerificationKey: """ with grpc.insecure_channel(self.endpoint) as channel: stub = prover_pb2_grpc.ProverStub(channel) # type: ignore - print("-------------- Get the verification key --------------") verificationkey = stub.GetVerificationKey(_make_empty_message()) return verificationkey From 75388dbf855174dc0ef131dc2181c4470e9788f5 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Fri, 8 Jan 2021 14:54:10 +0000 Subject: [PATCH 020/137] Fix up DebugLog on mixer contract and improve client support for event parsing. --- client/zeth/core/contracts.py | 35 +++++++++++++++++++++++++- zeth_contracts/contracts/MixerBase.sol | 5 ++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/client/zeth/core/contracts.py b/client/zeth/core/contracts.py index ede59a694..85201c57e 100644 --- a/client/zeth/core/contracts.py +++ b/client/zeth/core/contracts.py @@ -9,6 +9,7 @@ from zeth.core.constants import SOL_COMPILER_VERSION from web3.utils.contracts import find_matching_event_abi # type: ignore from web3.utils.events import get_event_data # type: ignore +from eth_utils import event_abi_to_log_topic # type: ignore import solcx from typing import Dict, List, Iterator, Optional, Union, Iterable, Any @@ -187,8 +188,21 @@ def get_event_logs( instance, with the given name. Yields an iterator of event-specific objects to be decoded by the caller. """ + + # It is possible to achieve this via the contract interface, with code of + # the form: + # + # event = instance.events[event_name] + # filter = event.createFilter(fromBlock=start_block, toBlock=to_block) + # logs = web3.eth.getFilterLogs(filter) + # + # However, this creates filters on the host node, which may not be + # permitted in all configurations. Hence, the code here iterates manually, + # skpping events with other topics, from the same contract. + contract_address = instance.address event_abi = find_matching_event_abi(instance.abi, event_name=event_name) + log_topic = event_abi_to_log_topic(event_abi) batch_size = batch_size or SYNC_BLOCKS_PER_BATCH while start_block <= end_block: @@ -202,5 +216,24 @@ def get_event_logs( } logs = web3.eth.getLogs(filter_params) for log in logs: - yield get_event_data(event_abi, log) + if log_topic == log['topics'][0]: + yield get_event_data(event_abi, log) start_block = to_block + 1 + + +def get_event_logs_from_tx_receipt( + instance_desc: InstanceDescription, + event_name: str, + tx_receipt: Any) -> Iterator[Any]: + """ + Query a transaction receipt for all events emitted by the given contract + instance with a given event name. Yields an iterator of event-specific + objects to be decoded by the caller. This function intentionally avoids + connecting to a node, or creating host-side filters. + """ + contract_address = instance_desc.address + event_abi = find_matching_event_abi(instance_desc.abi, event_name=event_name) + log_topic = event_abi_to_log_topic(event_abi) + for log in tx_receipt.logs: + if log.address == contract_address and log_topic == log['topics'][0]: + yield get_event_data(event_abi, log) diff --git a/zeth_contracts/contracts/MixerBase.sol b/zeth_contracts/contracts/MixerBase.sol index aae0bc147..ab3970706 100644 --- a/zeth_contracts/contracts/MixerBase.sol +++ b/zeth_contracts/contracts/MixerBase.sol @@ -89,7 +89,7 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract ); /// Debug only - event LogDebug(string message); + event LogDebug(string message, uint256 value); /// Constructor constructor( @@ -184,10 +184,11 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract inputs ) ); + require( OTSchnorrVerifier.verify( vk[0], vk[1], vk[2], vk[3], sigma, hash_to_be_signed), - "Invalid signature: Unable to verify the signature correctly" + "Invalid signature in dispatch" ); mix_append_commitments_emit_and_handle_public_values( From e94d07ad5bd5968c155fb2195320780462246361 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Fri, 8 Jan 2021 14:54:29 +0000 Subject: [PATCH 021/137] client: wait command to dump all event data from mixer tx --- client/zeth/cli/zeth | 2 ++ client/zeth/cli/zeth_wait.py | 37 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 client/zeth/cli/zeth_wait.py diff --git a/client/zeth/cli/zeth b/client/zeth/cli/zeth index 6bbde787e..aaa1a8ddd 100644 --- a/client/zeth/cli/zeth +++ b/client/zeth/cli/zeth @@ -14,6 +14,7 @@ from zeth.cli.zeth_deploy import deploy from zeth.cli.zeth_gen_address import gen_address from zeth.cli.zeth_sync import sync from zeth.cli.zeth_mix import mix +from zeth.cli.zeth_wait import wait from zeth.cli.zeth_ls_notes import ls_notes from zeth.cli.zeth_ls_commits import ls_commits from click import group, command, option, pass_context, ClickException, Context @@ -86,6 +87,7 @@ zeth.add_command(deploy) zeth.add_command(gen_address) zeth.add_command(sync) zeth.add_command(mix) +zeth.add_command(wait) zeth.add_command(ls_notes) zeth.add_command(ls_commits) zeth.add_command(help) diff --git a/client/zeth/cli/zeth_wait.py b/client/zeth/cli/zeth_wait.py new file mode 100644 index 000000000..066cd841d --- /dev/null +++ b/client/zeth/cli/zeth_wait.py @@ -0,0 +1,37 @@ +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd +# +# SPDX-License-Identifier: LGPL-3.0+ + +from zeth.cli.utils import load_mixer_description_from_ctx, open_web3_from_ctx +from zeth.core.contracts import get_event_logs_from_tx_receipt +from click import command, pass_context, Context, argument + + +@command() +@argument("transaction-id") +@pass_context +def wait(ctx: Context, transaction_id: str) -> None: + """ + Wait for a mix transaction and dump all log data. Does not update the + wallet. Use sync to scan the chain for new notes. + """ + client_ctx = ctx.obj + mixer_desc = load_mixer_description_from_ctx(client_ctx) + instance_desc = mixer_desc.mixer + + # Retrieve the tx receipt and dump logs + web3 = open_web3_from_ctx(client_ctx) # type: ignore + tx_receipt = web3.eth.waitForTransactionReceipt(transaction_id, 10000) \ + # pylint: disable=no-member + + print("LogDebug events:") + logs = get_event_logs_from_tx_receipt(instance_desc, "LogDebug", tx_receipt) + for log in logs: + print( + f" {log.args['message']}: {log.args['value']} " + f"({hex(log.args['value'])})") + + print("LogMix events:") + logs = get_event_logs_from_tx_receipt(instance_desc, "LogMix", tx_receipt) + for log in logs: + print(f" {log}") From 20fe15d09dcdad2f887ae1bf480073ee2726affd Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 11 Jan 2021 10:46:32 +0000 Subject: [PATCH 022/137] client: util function to extract address from contract instance description --- client/zeth/helper/eth_get_contract_address.py | 15 +++++++++++++++ client/zeth/helper/zeth_helper | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 client/zeth/helper/eth_get_contract_address.py diff --git a/client/zeth/helper/eth_get_contract_address.py b/client/zeth/helper/eth_get_contract_address.py new file mode 100644 index 000000000..bb454ec82 --- /dev/null +++ b/client/zeth/helper/eth_get_contract_address.py @@ -0,0 +1,15 @@ +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd +# +# SPDX-License-Identifier: LGPL-3.0+ + +from zeth.cli.utils import load_contract_address +from click import command, argument + + +@command() +@argument("instance-file") +def eth_get_contract_address(instance_file: str) -> None: + """ + Extract the address from a contract instance description file. + """ + print(load_contract_address(instance_file)) diff --git a/client/zeth/helper/zeth_helper b/client/zeth/helper/zeth_helper index 0bdbf5a6b..f0d1a3964 100644 --- a/client/zeth/helper/zeth_helper +++ b/client/zeth/helper/zeth_helper @@ -4,12 +4,12 @@ # # SPDX-License-Identifier: LGPL-3.0+ - from zeth.helper.eth_gen_network_config import eth_gen_network_config from zeth.helper.eth_gen_address import eth_gen_address from zeth.helper.eth_get_balance import eth_get_balance from zeth.helper.eth_fund import eth_fund from zeth.helper.eth_send import eth_send +from zeth.helper.eth_get_contract_address import eth_get_contract_address from zeth.helper.token_approve import token_approve from zeth.cli.constants import ETH_NETWORK_FILE_DEFAULT, ETH_NETWORK_DEFAULT from click import group, command, option, pass_context, ClickException, Context @@ -50,6 +50,7 @@ zeth_helper.add_command(eth_gen_address) zeth_helper.add_command(eth_get_balance) zeth_helper.add_command(eth_fund) zeth_helper.add_command(eth_send) +zeth_helper.add_command(eth_get_contract_address) zeth_helper.add_command(token_approve) zeth_helper.add_command(help) From 8caa24be246193cca16b0bb0d8f92db795e467f1 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 11 Jan 2021 10:50:51 +0000 Subject: [PATCH 023/137] client: skip loading unused data in dispatch mode --- client/zeth/cli/zeth_mix.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/zeth/cli/zeth_mix.py b/client/zeth/cli/zeth_mix.py index 5b44d7a78..7025f62dc 100644 --- a/client/zeth/cli/zeth_mix.py +++ b/client/zeth/cli/zeth_mix.py @@ -86,7 +86,6 @@ def mix( raise ClickException("input and output value mismatch") eth_address = load_eth_address(eth_addr) - eth_private_key_data = load_eth_private_key(eth_private_key) # If instance uses an ERC20 token, tx_value can be 0. Otherwise it should # match vin_pub. @@ -126,6 +125,7 @@ def mix( if for_dispatch_call or dry_run: return + eth_private_key_data = load_eth_private_key(eth_private_key) tx_hash = zeth_client.mix( mix_params=mix_params, sender_eth_address=eth_address, From 91f81cf03d6fa388f6130ca6f0e7acdbc7fd9a49 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 11 Jan 2021 10:51:55 +0000 Subject: [PATCH 024/137] contracts: remove unused event --- zeth_contracts/contracts/BaseMerkleTree.sol | 3 --- 1 file changed, 3 deletions(-) diff --git a/zeth_contracts/contracts/BaseMerkleTree.sol b/zeth_contracts/contracts/BaseMerkleTree.sol index 98363f151..1b30c9694 100644 --- a/zeth_contracts/contracts/BaseMerkleTree.sol +++ b/zeth_contracts/contracts/BaseMerkleTree.sol @@ -36,9 +36,6 @@ contract BaseMerkleTree // Number of leaves populated in `nodes`. uint256 internal num_leaves; - // Debug only - event LogDebug(bytes32 message); - /// Constructor constructor(uint256 treeDepth) public { require ( From b9cad58508e5c706980a6691acd3960696f621ea Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 14 Jan 2021 13:55:13 +0000 Subject: [PATCH 025/137] client: replace old SIGNATURE_PRIME constant with ec.curve_order --- client/zeth/core/signing.py | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/client/zeth/core/signing.py b/client/zeth/core/signing.py index 3dc02716b..777f96e2f 100644 --- a/client/zeth/core/signing.py +++ b/client/zeth/core/signing.py @@ -21,12 +21,6 @@ FQ = ec.FQ G1 = Tuple[ec.FQ, ec.FQ] -# pylint: disable=line-too-long -# Characteristic of the scalar field of BN128 (see comment and reference above). -SIGNATURE_PRIME = \ - 21888242871839275222246405745257275088548364400416034343698204186575808495617 # noqa -# pylint: enable=line-too-long - class SigningVerificationKey: """ @@ -101,11 +95,11 @@ def gen_signing_keypair() -> SigningKeyPair: Return a one-time signature key-pair composed of elements of F_q and G1. """ - key_size_byte = ceil(len("{0:b}".format(SIGNATURE_PRIME)) / 8) + key_size_byte = ceil(len("{0:b}".format(ec.curve_order)) / 8) x = FQ( - int(bytes(urandom(key_size_byte)).hex(), 16) % SIGNATURE_PRIME) + int(bytes(urandom(key_size_byte)).hex(), 16) % ec.curve_order) y = FQ( - int(bytes(urandom(key_size_byte)).hex(), 16) % SIGNATURE_PRIME) + int(bytes(urandom(key_size_byte)).hex(), 16) % ec.curve_order) X = ec.multiply(ec.G1, x.n) Y = ec.multiply(ec.G1, y.n) @@ -141,10 +135,10 @@ def sign( # Convert the hex digest into a field element challenge = int(sha256(challenge_to_hash).hexdigest(), 16) - challenge = challenge % SIGNATURE_PRIME + challenge = challenge % ec.curve_order # Compute the signature sigma - sigma = (sk.ssk[0].n + challenge * sk.psk.n) % SIGNATURE_PRIME + sigma = (sk.ssk[0].n + challenge * sk.psk.n) % ec.curve_order return sigma @@ -161,7 +155,7 @@ def verify( challenge_to_hash = g1_to_bytes(vk.spk) + m challenge = int(sha256(challenge_to_hash).hexdigest(), 16) - challenge = challenge % SIGNATURE_PRIME + challenge = challenge % ec.curve_order left_part = ec.multiply(ec.G1, FQ(sigma).n) right_part = ec.add(vk.spk, ec.multiply(vk.ppk, FQ(challenge).n)) From 6c00b2dbd09ec5b77232cb983b08fe961c1b02ed Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 11 Jan 2021 17:43:23 +0000 Subject: [PATCH 026/137] client: mimc-based client-side hashing of field elements --- client/tests/test_input_hasher.py | 44 +++++++++++++++++++++++++++++++ client/zeth/core/input_hasher.py | 35 ++++++++++++++++++++++++ client/zeth/core/mimc.py | 11 ++++++-- 3 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 client/tests/test_input_hasher.py create mode 100644 client/zeth/core/input_hasher.py diff --git a/client/tests/test_input_hasher.py b/client/tests/test_input_hasher.py new file mode 100644 index 000000000..10043937e --- /dev/null +++ b/client/tests/test_input_hasher.py @@ -0,0 +1,44 @@ +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd +# +# SPDX-License-Identifier: LGPL-3.0+ + +from zeth.core.mimc import MiMC7, MiMC31 +from zeth.core.input_hasher import InputHasher +from unittest import TestCase + +DUMMY_INPUT_VALUES = [-1, 0, 1] + + +class TestInputHasher(TestCase): + + def test_input_hasher_simple(self) -> None: + # Some very simple cases + mimc = MiMC7() + input_hasher = InputHasher(mimc, 7) + self.assertEqual(mimc.hash_int(7, 0), input_hasher.hash([])) + self.assertEqual( + mimc.hash_int(mimc.hash_int(7, 1), 1), input_hasher.hash([1])) + self.assertEqual( + mimc.hash_int( + mimc.hash_int( + mimc.hash_int(7, 1), 2), + 2), + input_hasher.hash([1, 2])) + + def test_input_hasher_mimc7(self) -> None: + mimc = MiMC7() + input_hasher = InputHasher(mimc) + values = [x % mimc.prime for x in DUMMY_INPUT_VALUES] + # pylint:disable=line-too-long + expect = 5568471640435576440988459485125198359192118312228711462978763973844457667180 # noqa + # pylint:enable=line-too-long + self.assertEqual(expect, input_hasher.hash(values)) + + def test_input_hasher_mimc31(self) -> None: + mimc = MiMC31() + input_hasher = InputHasher(mimc) + values = [x % mimc.prime for x in DUMMY_INPUT_VALUES] + # pylint: disable=line-too-long + expect = 1029772481427643815119825324071277815354972734622711297984795198139876181749 # noqa + # pylint: enable=line-too-long + self.assertEqual(expect, input_hasher.hash(values)) diff --git a/client/zeth/core/input_hasher.py b/client/zeth/core/input_hasher.py new file mode 100644 index 000000000..87dd395c6 --- /dev/null +++ b/client/zeth/core/input_hasher.py @@ -0,0 +1,35 @@ +# Copyright (c) 2015-2021 Clearmatics Technologies Ltd +# +# SPDX-License-Identifier: LGPL-3.0+ + +from zeth.core.mimc import MiMCBase +from typing import List + + +# Default seed, generated as: +# zeth.core.mimc._keccak_256( +# zeth.core.mimc._str_to_bytes("clearmatics_hash_seed")) +DEFAULT_IV_UINT256 = \ + 13196537064117388418196223856311987714388543839552400408340921397545324034315 + + +class InputHasher: + """ + Hash a series of field elements via the Merkle-Damgard construction on a + MiMC compression function. Note that since this function only accepts whole + numbers of scalar field elements, there is no ambiguity w.r.t to padding + and we could technically omit the finalization step. It has been kept for + now, to allow time for further consideration, and in case the form of the + hasher changes (e.g. in case we want to be able to hash arbitrary bit + strings in the future). + """ + def __init__(self, compression_fn: MiMCBase, iv: int = DEFAULT_IV_UINT256): + assert compression_fn.prime < (2 << 256) + self._compression_fn = compression_fn + self._iv = iv % compression_fn.prime + + def hash(self, values: List[int]) -> int: + current = self._iv + for m in values: + current = self._compression_fn.hash_int(current, m) + return self._compression_fn.hash_int(current, len(values)) diff --git a/client/zeth/core/mimc.py b/client/zeth/core/mimc.py index d94bc81c2..b05dc2648 100644 --- a/client/zeth/core/mimc.py +++ b/client/zeth/core/mimc.py @@ -61,8 +61,15 @@ def hash(self, left: bytes, right: bytes) -> bytes: """ x = int.from_bytes(left, byteorder='big') % self.prime y = int.from_bytes(right, byteorder='big') % self.prime - result = (self.encrypt(x, y) + x + y) % self.prime - return result.to_bytes(32, byteorder='big') + return self.hash_int(x, y).to_bytes(32, byteorder='big') + + def hash_int(self, x: int, y: int) -> int: + """ + Similar to hash, but use field elements directly. + """ + assert x < self.prime + assert y < self.prime + return (self.encrypt(x, y) + x + y) % self.prime @abstractmethod def mimc_round(self, message: int, key: int, rc: int) -> int: From 9ad8aeaafb916dfc544cd7bc1e28477dd04703cd Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 11 Jan 2021 18:31:43 +0000 Subject: [PATCH 027/137] libzeth: pb_linear_combinations instead of pb_variables in mimc round gadget --- libzeth/circuits/mimc/mimc_round.hpp | 8 ++++---- libzeth/circuits/mimc/mimc_round.tcc | 11 +++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/libzeth/circuits/mimc/mimc_round.hpp b/libzeth/circuits/mimc/mimc_round.hpp index be80016bd..87c7ad757 100644 --- a/libzeth/circuits/mimc/mimc_round.hpp +++ b/libzeth/circuits/mimc/mimc_round.hpp @@ -25,10 +25,10 @@ class MiMC_round_gadget : public libsnark::gadget bit_utils::hamming_weight() - 2; // Message of the current round - const libsnark::pb_variable msg; + const libsnark::pb_linear_combination msg; // Key of the current round - const libsnark::pb_variable key; + const libsnark::pb_linear_combination key; // Round constant of the current round const FieldT round_const; @@ -45,8 +45,8 @@ class MiMC_round_gadget : public libsnark::gadget public: MiMC_round_gadget( libsnark::protoboard &pb, - const libsnark::pb_variable &msg, - const libsnark::pb_variable &key, + const libsnark::pb_linear_combination &msg, + const libsnark::pb_linear_combination &key, const FieldT &round_const, libsnark::pb_variable &result, const bool add_k_to_result, diff --git a/libzeth/circuits/mimc/mimc_round.tcc b/libzeth/circuits/mimc/mimc_round.tcc index 33051b903..02186624d 100644 --- a/libzeth/circuits/mimc/mimc_round.tcc +++ b/libzeth/circuits/mimc/mimc_round.tcc @@ -13,8 +13,8 @@ namespace libzeth template MiMC_round_gadget::MiMC_round_gadget( libsnark::protoboard &pb, - const libsnark::pb_variable &msg, - const libsnark::pb_variable &key, + const libsnark::pb_linear_combination &msg, + const libsnark::pb_linear_combination &key, const FieldT &round_const, libsnark::pb_variable &result, const bool add_key_to_result, @@ -100,9 +100,12 @@ void MiMC_round_gadget::generate_r1cs_constraints() template void MiMC_round_gadget::generate_r1cs_witness() const { + key.evaluate(this->pb); + msg.evaluate(this->pb); + constexpr size_t mask = 1 << (EXPONENT_NUM_BITS - 1); - const FieldT k_val = this->pb.val(key); - const FieldT t = this->pb.val(msg) + k_val + round_const; + const FieldT k_val = this->pb.lc_val(key); + const FieldT t = this->pb.lc_val(msg) + k_val + round_const; // First intermediate variable has value t^2 size_t exp = Exponent << 1; From 394e394b3bdacea0f1c9c2c4186142480c6c4d9d Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Mon, 18 Jan 2021 10:52:26 +0000 Subject: [PATCH 028/137] Added missing scalar field characteristic to R1CS json serialization --- libzeth/serialization/r1cs_serialization.tcc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libzeth/serialization/r1cs_serialization.tcc b/libzeth/serialization/r1cs_serialization.tcc index 52b4f6353..d6c575b02 100644 --- a/libzeth/serialization/r1cs_serialization.tcc +++ b/libzeth/serialization/r1cs_serialization.tcc @@ -153,8 +153,9 @@ std::ostream &r1cs_write_json( out_s << "{\n"; out_s << "\"scalar_field_characteristic\":" - << "\"Not yet supported. Should be bigint in hexadecimal\"" - << ",\n"; + << "\"0x" + + bigint_to_hex>(libff::Fr::field_char()) + << "\",\n"; out_s << "\"num_variables\":" << pb.num_variables() << ",\n"; out_s << "\"num_constraints\":" << pb.num_constraints() << ",\n"; out_s << "\"num_inputs\": " << pb.num_inputs() << ",\n"; From fbce4273ab8087d3d83f22d4e714b8e4ef7ebaa9 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Mon, 18 Jan 2021 10:57:08 +0000 Subject: [PATCH 029/137] Updated analyzer README --- debug/analyzer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debug/analyzer/README.md b/debug/analyzer/README.md index cdc24c594..9b1685d1e 100644 --- a/debug/analyzer/README.md +++ b/debug/analyzer/README.md @@ -6,7 +6,7 @@ Basic set of functionalities to parse and run basic queries on the r1cs exported ```json { - "scalar_field_characteristic": "Not yet supported. Should be bigint in hexadecimal", + "scalar_field_characteristic": "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001", "num_variables": 549746, # Number of wires "num_constraints": 433391, # Number of gates "num_inputs": 17, # Number of primary inputs From 46accdb123162bb5f6625035cd3aa34c98b6e769 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 12 Jan 2021 10:39:16 +0000 Subject: [PATCH 030/137] libzeth: clean up mimc gadgets and make interface consistent --- .../merkle_tree/merkle_path_compute.hpp | 4 +- .../merkle_tree/merkle_path_compute.tcc | 9 ++-- libzeth/circuits/mimc/mimc.hpp | 8 +-- libzeth/circuits/mimc/mimc.tcc | 49 ++++++++++------- libzeth/circuits/mimc/mimc_mp.hpp | 16 +++--- libzeth/circuits/mimc/mimc_mp.tcc | 54 +++++++++---------- libzeth/tests/circuits/mimc_mp_test.cpp | 34 ++++++++---- 7 files changed, 101 insertions(+), 73 deletions(-) diff --git a/libzeth/circuits/merkle_tree/merkle_path_compute.hpp b/libzeth/circuits/merkle_tree/merkle_path_compute.hpp index abec3e2a0..32ab1f5b7 100644 --- a/libzeth/circuits/merkle_tree/merkle_path_compute.hpp +++ b/libzeth/circuits/merkle_tree/merkle_path_compute.hpp @@ -23,10 +23,12 @@ class merkle_path_compute : public libsnark::gadget // Merkle Authentication path const libsnark::pb_variable_array path; + // Digests + libsnark::pb_variable_array digests; // Gadget informing the position in the three of the computed // hash and authentication node std::vector> selectors; - // Vector of hash gadgets to compute the intermediary hashes + // Vector of hash gadgets to compute the intermediary digests std::vector hashers; merkle_path_compute( diff --git a/libzeth/circuits/merkle_tree/merkle_path_compute.tcc b/libzeth/circuits/merkle_tree/merkle_path_compute.tcc index e6cdf6dab..1f9f5dbde 100644 --- a/libzeth/circuits/merkle_tree/merkle_path_compute.tcc +++ b/libzeth/circuits/merkle_tree/merkle_path_compute.tcc @@ -29,7 +29,9 @@ merkle_path_compute::merkle_path_compute( assert(address_bits.size() == depth); // For each layer of the tree + digests.allocate(pb, depth, FMT(annotation_prefix, " digests")); for (size_t i = 0; i < depth; i++) { + // We first initialize the gadget to order the computed hash and the // authentication node to know which one is the first to be hashed and // which one is the second (as in mimc_hash(left, right)) We also append @@ -44,7 +46,7 @@ merkle_path_compute::merkle_path_compute( } else { selectors.push_back(merkle_path_selector( pb, - hashers[i - 1].result(), + digests[i - 1], path[i], address_bits[i], FMT(this->annotation_prefix, " selector[%zu]", i))); @@ -56,6 +58,7 @@ merkle_path_compute::merkle_path_compute( pb, {selectors[i].get_left()}, selectors[i].get_right(), + digests[i], FMT(this->annotation_prefix, " hasher[%zu]", i)); // We append the initialized hasher in the vector of hashers @@ -91,11 +94,11 @@ const libsnark::pb_variable merkle_path_compute:: result() { // We first check that we are not working with an empty tree - assert(hashers.size() > 0); + assert(digests.size() > 0); // We return the last hasher result, that is to say the computed root, // generated out of leaf, leaf address and merkle authentication path - return hashers.back().result(); + return digests[digests.size() - 1]; }; } // namespace libzeth diff --git a/libzeth/circuits/mimc/mimc.hpp b/libzeth/circuits/mimc/mimc.hpp index 9948d019f..aad68e26b 100644 --- a/libzeth/circuits/mimc/mimc.hpp +++ b/libzeth/circuits/mimc/mimc.hpp @@ -28,21 +28,21 @@ class MiMC_permutation_gadget : public libsnark::gadget // Vector of intermediate result values std::array, NumRounds> round_results; + // Vector of MiMC round_gadgets std::vector round_gadgets; public: MiMC_permutation_gadget( libsnark::protoboard &pb, - const libsnark::pb_variable &msg, - const libsnark::pb_variable &key, + const libsnark::pb_linear_combination &msg, + const libsnark::pb_linear_combination &key, + const libsnark::pb_variable &result, const std::string &annotation_prefix = "MiMCe7_permutation_gadget"); void generate_r1cs_constraints(); void generate_r1cs_witness() const; - const libsnark::pb_variable &result() const; - // Constants vector initialization void setup_sha3_constants(); }; diff --git a/libzeth/circuits/mimc/mimc.tcc b/libzeth/circuits/mimc/mimc.tcc index 6f6487646..ce18bad95 100644 --- a/libzeth/circuits/mimc/mimc.tcc +++ b/libzeth/circuits/mimc/mimc.tcc @@ -21,8 +21,9 @@ bool MiMC_permutation_gadget:: template MiMC_permutation_gadget::MiMC_permutation_gadget( libsnark::protoboard &pb, - const libsnark::pb_variable &msg, - const libsnark::pb_variable &key, + const libsnark::pb_linear_combination &msg, + const libsnark::pb_linear_combination &key, + const libsnark::pb_variable &result, const std::string &annotation_prefix) : libsnark::gadget(pb, annotation_prefix) { @@ -31,27 +32,45 @@ MiMC_permutation_gadget::MiMC_permutation_gadget( // Initialize the round gadgets round_gadgets.reserve(NumRounds); - const libsnark::pb_variable *round_msg = &msg; - for (size_t i = 0; i < NumRounds; i++) { - // Set the input of the next round with the output variable of the - // previous round (except for round 0) - round_results[i].allocate( - this->pb, FMT(this->annotation_prefix, " round_result[%zu]", i)); + // First round uses round_msg as an input. + round_results[0].allocate( + this->pb, FMT(this->annotation_prefix, " round_result[0]")); + round_gadgets.emplace_back( + this->pb, + msg, + key, + round_constants[0], + round_results[0], + false, + FMT(this->annotation_prefix, " round[0]")); + + // All other rounds use the output of the previous round and output to an + // intermediate variable, except the last round, which outputs to the + // result parameter. + for (size_t i = 1; i < NumRounds; i++) { const bool is_last = (i == (NumRounds - 1)); + // Allocate output variable (except for last round, which outputs to + // the result variable). + if (is_last) { + round_results[i] = result; + } else { + round_results[i].allocate( + this->pb, + FMT(this->annotation_prefix, " round_result[%zu]", i)); + } + // Initialize and add the current round gadget into the rounds gadget // vector, picking the relative constant round_gadgets.emplace_back( this->pb, - *round_msg, + round_results[i - 1], key, round_constants[i], round_results[i], is_last, FMT(this->annotation_prefix, " round[%zu]", i)); - - round_msg = &round_results[i]; } } @@ -76,14 +95,6 @@ void MiMC_permutation_gadget:: } } -template -const libsnark::pb_variable - &MiMC_permutation_gadget::result() const -{ - // Returns the result of the last encryption/permutation - return round_results.back(); -} - // The following constants correspond to the iterative computation of sha3_256 // hash function over the initial seed "clearmatics_mt_seed". See: // client/zethCodeConstantsGeneration.py for more details diff --git a/libzeth/circuits/mimc/mimc_mp.hpp b/libzeth/circuits/mimc/mimc_mp.hpp index 757ae5d22..c7ab684b3 100644 --- a/libzeth/circuits/mimc/mimc_mp.hpp +++ b/libzeth/circuits/mimc/mimc_mp.hpp @@ -24,24 +24,24 @@ class MiMC_mp_gadget : public libsnark::gadget libsnark::pb_variable x; // Second input libsnark::pb_variable y; - // Permutation gadget - PermutationT permutation_gadget; // Output variable - libsnark::pb_variable output; + libsnark::pb_variable result; + // Permutation output + libsnark::pb_variable perm_output; + // Permutation gadget + std::shared_ptr permutation_gadget; public: MiMC_mp_gadget( libsnark::protoboard &pb, - const libsnark::pb_variable x, - const libsnark::pb_variable y, + const libsnark::pb_variable &x, + const libsnark::pb_variable &y, + const libsnark::pb_variable &result, const std::string &annotation_prefix = "MiMC_mp_gadget"); void generate_r1cs_constraints(); void generate_r1cs_witness() const; - // Returns the hash computed - const libsnark::pb_variable &result() const; - // Returns the hash (field element) static FieldT get_hash(const FieldT x, FieldT y); }; diff --git a/libzeth/circuits/mimc/mimc_mp.tcc b/libzeth/circuits/mimc/mimc_mp.tcc index bb86ef0ec..f92dd042c 100644 --- a/libzeth/circuits/mimc/mimc_mp.tcc +++ b/libzeth/circuits/mimc/mimc_mp.tcc @@ -5,38 +5,41 @@ #ifndef __ZETH_CIRCUITS_MIMC_MP_TCC__ #define __ZETH_CIRCUITS_MIMC_MP_TCC__ +#include "mimc_mp.hpp" + namespace libzeth { template MiMC_mp_gadget::MiMC_mp_gadget( libsnark::protoboard &pb, - const libsnark::pb_variable x, - const libsnark::pb_variable y, + const libsnark::pb_variable &x, + const libsnark::pb_variable &y, + const libsnark::pb_variable &result, const std::string &annotation_prefix) : libsnark::gadget(pb, annotation_prefix) , x(x) , y(y) - , permutation_gadget( - pb, x, y, FMT(this->annotation_prefix, " permutation_gadget")) + , result(result) { - // Allocates output variable - output.allocate(pb, FMT(this->annotation_prefix, " output")); + perm_output.allocate(this->pb, FMT(annotation_prefix, " perm_output")); + permutation_gadget.reset(new PermutationT( + pb, + x, + y, + perm_output, + FMT(this->annotation_prefix, " permutation_gadget"))); } template void MiMC_mp_gadget::generate_r1cs_constraints() { // Setting constraints for the permutation gadget - permutation_gadget.generate_r1cs_constraints(); - - const libsnark::pb_variable &m = x; - const libsnark::pb_variable &key = y; + permutation_gadget->generate_r1cs_constraints(); // Adding constraint for the Miyaguchi-Preneel equation this->pb.add_r1cs_constraint( - libsnark::r1cs_constraint( - permutation_gadget.result() + m + key, 1, output), + libsnark::r1cs_constraint(perm_output + x + y, 1, result), FMT(this->annotation_prefix, " out=k+E_k(m_i)+m_i")); } @@ -44,20 +47,11 @@ template void MiMC_mp_gadget::generate_r1cs_witness() const { // Generating witness for the gadget - permutation_gadget.generate_r1cs_witness(); + permutation_gadget->generate_r1cs_witness(); // Filling output variables for Miyaguchi-Preenel equation - this->pb.val(output) = this->pb.val(y) + - this->pb.val(permutation_gadget.result()) + - this->pb.val(x); -} - -template -const libsnark::pb_variable - &MiMC_mp_gadget::result() const -{ - // Returns the output - return output; + this->pb.val(result) = + this->pb.val(y) + this->pb.val(perm_output) + this->pb.val(x); } // Returns the hash of two elements @@ -68,23 +62,27 @@ FieldT MiMC_mp_gadget::get_hash(const FieldT x, FieldT y) libsnark::pb_variable pb_x; libsnark::pb_variable pb_y; + libsnark::pb_variable result; // Allocates and fill with the x and y - pb_x.allocate(pb, " x"); + pb_x.allocate(pb, "x"); pb.val(pb_x) = x; - pb_y.allocate(pb, " y"); + pb_y.allocate(pb, "y"); pb.val(pb_y) = y; + result.allocate(pb, "result"); + // Initialize the Hash MiMC_mp_gadget mimc_hasher( - pb, pb_x, pb_y, " mimc_hash"); + pb, pb_x, pb_y, result, " mimc_hash"); // Computes the hash + mimc_hasher.generate_r1cs_constraints(); mimc_hasher.generate_r1cs_witness(); // Returns the hash - return pb.val(mimc_hasher.result()); + return pb.val(result); } } // namespace libzeth diff --git a/libzeth/tests/circuits/mimc_mp_test.cpp b/libzeth/tests/circuits/mimc_mp_test.cpp index e7e82e7fa..ca081c8e4 100644 --- a/libzeth/tests/circuits/mimc_mp_test.cpp +++ b/libzeth/tests/circuits/mimc_mp_test.cpp @@ -132,8 +132,10 @@ TEST(TestMiMC, MiMC7PermTrue) libsnark::pb_variable in_x; libsnark::pb_variable in_k; + libsnark::pb_variable result; in_x.allocate(pb, "x"); in_k.allocate(pb, "k"); + result.allocate(pb, "result"); pb.val(in_x) = Field("3703141493535563179657531719960160174296085208671919" "316200479060314459804651"); @@ -141,14 +143,14 @@ TEST(TestMiMC, MiMC7PermTrue) "2890706581988986633412003"); MiMC_permutation_gadget mimc_gadget( - pb, in_x, in_k, "mimc_gadget"); + pb, in_x, in_k, result, "mimc_gadget"); mimc_gadget.generate_r1cs_constraints(); mimc_gadget.generate_r1cs_witness(); Field expected_out = Field("192990723315478049773124691205698348115617480" "95378968014959488920239255590840"); ASSERT_TRUE(pb.is_satisfied()); - ASSERT_TRUE(expected_out == pb.val(mimc_gadget.result())); + ASSERT_TRUE(expected_out == pb.val(result)); } TEST(TestMiMC, MiMC7PermFalse) @@ -157,21 +159,24 @@ TEST(TestMiMC, MiMC7PermFalse) libsnark::pb_variable in_x; libsnark::pb_variable in_k; + libsnark::pb_variable result; in_x.allocate(pb, "x"); in_k.allocate(pb, "k"); + result.allocate(pb, "result"); pb.val(in_x) = Field("3703141493535563179657531719960160174296085208671919" "316200479060314459804651"); pb.val(in_k) = Field("13455131405143248756924738814405142"); - MiMCe7_permutation_gadget mimc_gadget(pb, in_x, in_k, "mimc_gadget"); + MiMCe7_permutation_gadget mimc_gadget( + pb, in_x, in_k, result, "mimc_gadget"); mimc_gadget.generate_r1cs_constraints(); mimc_gadget.generate_r1cs_witness(); Field unexpected_out = Field("1929907233154780497731246912056983481156174" "8095378968014959488920239255590840"); ASSERT_TRUE(pb.is_satisfied()); - ASSERT_FALSE(unexpected_out == pb.val(mimc_gadget.result())); + ASSERT_FALSE(unexpected_out == pb.val(result)); } TEST(TestMiMC, MiMC7MpTrue) @@ -193,15 +198,18 @@ TEST(TestMiMC, MiMC7MpTrue) pb.val(x) = Field("3703141493535563179657531719960160174296085208671919316" "200479060314459804651"); + libsnark::pb_variable result; + result.allocate(pb, "result"); + MiMC_mp_gadget> mimc_mp_gadget( - pb, x, y, "gadget"); + pb, x, y, result, "gadget"); mimc_mp_gadget.generate_r1cs_constraints(); mimc_mp_gadget.generate_r1cs_witness(); Field expected_out = Field("167979224495559946840631042142333962005996937" "15764605878168345782964540311877"); ASSERT_TRUE(pb.is_satisfied()); - ASSERT_TRUE(expected_out == pb.val(mimc_mp_gadget.result())); + ASSERT_TRUE(expected_out == pb.val(result)); } TEST(TestMiMC, MiMC7MpFalse) @@ -221,15 +229,18 @@ TEST(TestMiMC, MiMC7MpFalse) pb.val(x) = Field("3703141493535563179657531719960160174296085208671919316" "200479060314459804651"); + libsnark::pb_variable result; + result.allocate(pb, "result"); + MiMC_mp_gadget> mimc_mp_gadget( - pb, x, y, "gadget"); + pb, x, y, result, "gadget"); mimc_mp_gadget.generate_r1cs_constraints(); mimc_mp_gadget.generate_r1cs_witness(); Field unexpected_out = Field("1679792244955599468406310421423339620059969" "3715764605878168345782964540311877"); ASSERT_TRUE(pb.is_satisfied()); - ASSERT_FALSE(unexpected_out == pb.val(mimc_mp_gadget.result())); + ASSERT_FALSE(unexpected_out == pb.val(result)); } TEST(TestMiMC, TestMiMC31) @@ -260,15 +271,18 @@ TEST(TestMiMC, TestMiMC31) m.allocate(pb, "m"); pb.val(m) = m_val; + libsnark::pb_variable h; + h.allocate(pb, "h"); + MiMC_mp_gadget> mimc_mp_gadget( - pb, m, k, "mimc_mp"); + pb, m, k, h, "mimc_mp"); mimc_mp_gadget.generate_r1cs_constraints(); mimc_mp_gadget.generate_r1cs_witness(); // Check that the circuit is satisfied, and that the expected result is // generated. ASSERT_TRUE(pb.is_satisfied()); - ASSERT_EQ(h_val, pb.val(mimc_mp_gadget.result())); + ASSERT_EQ(h_val, pb.val(h)); } } // namespace From df2ba6df4fa78917b551ce247240bf0e5cdfeb1a Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 12 Jan 2021 10:48:35 +0000 Subject: [PATCH 031/137] libzeth: support pb_linear_combination as input to mimc_mp --- libzeth/circuits/mimc/mimc_mp.hpp | 8 ++++---- libzeth/circuits/mimc/mimc_mp.tcc | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libzeth/circuits/mimc/mimc_mp.hpp b/libzeth/circuits/mimc/mimc_mp.hpp index c7ab684b3..64747624e 100644 --- a/libzeth/circuits/mimc/mimc_mp.hpp +++ b/libzeth/circuits/mimc/mimc_mp.hpp @@ -21,9 +21,9 @@ class MiMC_mp_gadget : public libsnark::gadget { private: // First input - libsnark::pb_variable x; + libsnark::pb_linear_combination x; // Second input - libsnark::pb_variable y; + libsnark::pb_linear_combination y; // Output variable libsnark::pb_variable result; // Permutation output @@ -34,8 +34,8 @@ class MiMC_mp_gadget : public libsnark::gadget public: MiMC_mp_gadget( libsnark::protoboard &pb, - const libsnark::pb_variable &x, - const libsnark::pb_variable &y, + const libsnark::pb_linear_combination &x, + const libsnark::pb_linear_combination &y, const libsnark::pb_variable &result, const std::string &annotation_prefix = "MiMC_mp_gadget"); diff --git a/libzeth/circuits/mimc/mimc_mp.tcc b/libzeth/circuits/mimc/mimc_mp.tcc index f92dd042c..ff66204f2 100644 --- a/libzeth/circuits/mimc/mimc_mp.tcc +++ b/libzeth/circuits/mimc/mimc_mp.tcc @@ -13,8 +13,8 @@ namespace libzeth template MiMC_mp_gadget::MiMC_mp_gadget( libsnark::protoboard &pb, - const libsnark::pb_variable &x, - const libsnark::pb_variable &y, + const libsnark::pb_linear_combination &x, + const libsnark::pb_linear_combination &y, const libsnark::pb_variable &result, const std::string &annotation_prefix) : libsnark::gadget(pb, annotation_prefix) @@ -51,7 +51,7 @@ void MiMC_mp_gadget::generate_r1cs_witness() const // Filling output variables for Miyaguchi-Preenel equation this->pb.val(result) = - this->pb.val(y) + this->pb.val(perm_output) + this->pb.val(x); + this->pb.lc_val(y) + this->pb.val(perm_output) + this->pb.lc_val(x); } // Returns the hash of two elements From 23effc340976894b846d6f8c222398c7d0b41b0f Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 12 Jan 2021 15:57:13 +0000 Subject: [PATCH 032/137] libzeth: input hasher gadget and test --- libzeth/circuits/mimc/mimc_input_hasher.hpp | 43 ++++++++ libzeth/circuits/mimc/mimc_input_hasher.tcc | 97 +++++++++++++++++++ .../tests/circuits/mimc_input_hasher_test.cpp | 71 ++++++++++++++ 3 files changed, 211 insertions(+) create mode 100644 libzeth/circuits/mimc/mimc_input_hasher.hpp create mode 100644 libzeth/circuits/mimc/mimc_input_hasher.tcc create mode 100644 libzeth/tests/circuits/mimc_input_hasher_test.cpp diff --git a/libzeth/circuits/mimc/mimc_input_hasher.hpp b/libzeth/circuits/mimc/mimc_input_hasher.hpp new file mode 100644 index 000000000..f0b328ba9 --- /dev/null +++ b/libzeth/circuits/mimc/mimc_input_hasher.hpp @@ -0,0 +1,43 @@ +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_CIRCUITS_MIMC_MIMC_INPUT_HASHER_HPP__ +#define __ZETH_CIRCUITS_MIMC_MIMC_INPUT_HASHER_HPP__ + +#include + +namespace libzeth +{ + +/// Given a list of variables, hash the variables to a value which can be used +/// as a public input bound to the original variables. +template +class mimc_input_hasher : public libsnark::gadget +{ +private: + // Output variable + libsnark::pb_variable _result; + + // Compression function constraints + std::vector> _compression_functions; + + // Intermediate values + libsnark::pb_variable_array _intermediate_values; + +public: + mimc_input_hasher( + libsnark::protoboard &pb, + const libsnark::pb_linear_combination_array &inputs, + const libsnark::pb_variable hash_output, + const std::string &annotation_prefix); + + void generate_r1cs_constraints(); + void generate_r1cs_witness() const; +}; + +} // namespace libzeth + +#include "mimc_input_hasher.tcc" + +#endif // __ZETH_CIRCUITS_MIMC_MIMC_INPUT_HASHER_HPP__ diff --git a/libzeth/circuits/mimc/mimc_input_hasher.tcc b/libzeth/circuits/mimc/mimc_input_hasher.tcc new file mode 100644 index 000000000..adea1f359 --- /dev/null +++ b/libzeth/circuits/mimc/mimc_input_hasher.tcc @@ -0,0 +1,97 @@ +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_CIRCUITS_MIMC_MIMC_INPUT_HASHER_TCC__ +#define __ZETH_CIRCUITS_MIMC_MIMC_INPUT_HASHER_TCC__ + +#include "mimc_input_hasher.hpp" + +namespace libzeth +{ + +template +mimc_input_hasher::mimc_input_hasher( + libsnark::protoboard &pb, + const libsnark::pb_linear_combination_array &inputs, + const libsnark::pb_variable result, + const std::string &annotation_prefix) + : libsnark::gadget(pb, annotation_prefix), _result(result) +{ + const size_t num_inputs = inputs.size(); + if (num_inputs < 2) { + // Although it would be superfluous, we could support 1 entry. However + // it would add some complexity to the code below. For now, assume + // strictly more than 1 entry. + throw std::invalid_argument( + "inputs array must have at least 2 entries"); + } + + // Require one compression function invocation per element in the array, + // followed by the finalization step. Each invocation except the last + // requires an intermediate output variable. + _compression_functions.reserve(num_inputs + 1); + _intermediate_values.allocate( + pb, num_inputs, FMT(annotation_prefix, "intermediate_values")); + + // IV generated as: + // zeth.core.mimc._keccak_256( + // zeth.core.mimc._str_to_bytes("clearmatics_hash_seed")) + // See: client/zeth/core/mimc.py + const FieldT iv_val( + "1319653706411738841819622385631198771438854383955240040834092139" + "7545324034315"); + libsnark::pb_linear_combination iv; + iv.assign(pb, iv_val); + + // First step: hash_output[0] <- mimc_mp(iv, i[0]) + + _compression_functions.emplace_back(new comp_fnT( + pb, + iv, + inputs[0], + _intermediate_values[0], + FMT(annotation_prefix, " compression_functions[0]"))); + + // Intermediate invocations of the compression fucntion. + for (size_t i = 1; i < num_inputs; ++i) { + _compression_functions.emplace_back(new comp_fnT( + pb, + _intermediate_values[i - 1], + inputs[i], + _intermediate_values[i], + FMT(annotation_prefix, " compression_functions[%zu]", i))); + } + + // Last invocation of compression function to finalize. + libsnark::pb_linear_combination num_inputs_lc; + num_inputs_lc.assign(pb, FieldT(num_inputs)); + _compression_functions.emplace_back(new comp_fnT( + pb, + _intermediate_values[num_inputs - 1], + num_inputs_lc, + result, + FMT(annotation_prefix, " compression_functions[%zu]", num_inputs))); + + assert(_compression_functions.size() == num_inputs + 1); +} + +template +void mimc_input_hasher::generate_r1cs_constraints() +{ + for (const std::shared_ptr &cf : _compression_functions) { + cf->generate_r1cs_constraints(); + } +} + +template +void mimc_input_hasher::generate_r1cs_witness() const +{ + for (const std::shared_ptr &cf : _compression_functions) { + cf->generate_r1cs_witness(); + } +} + +} // namespace libzeth + +#endif // __ZETH_CIRCUITS_MIMC_MIMC_INPUT_HASHER_TCC__ diff --git a/libzeth/tests/circuits/mimc_input_hasher_test.cpp b/libzeth/tests/circuits/mimc_input_hasher_test.cpp new file mode 100644 index 000000000..bef917e50 --- /dev/null +++ b/libzeth/tests/circuits/mimc_input_hasher_test.cpp @@ -0,0 +1,71 @@ +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#include "libzeth/circuits/circuit_types.hpp" +#include "libzeth/circuits/mimc/mimc_input_hasher.hpp" +#include "libzeth/circuits/mimc/mimc_mp.hpp" + +#include +#include + +namespace +{ + +using pp = libff::bls12_377_pp; +using Field = libff::Fr; +using comp_fn = libzeth::tree_hash_selector::tree_hash; +using input_hasher = libzeth::mimc_input_hasher; + +TEST(MiMCInputHasherTest, SimpleInputValues) +{ + // Test data generated as follows: + // $ python + // >>> from zeth.core.mimc import MiMC31 + // >>> from zeth.core.input_hasher import InputHasher + // >>> InputHasher(MiMC31()).hash([0,1,-1,2,-2]) + const std::vector simple_values{{ + Field::zero(), + Field::one(), + -Field::one(), + Field("2"), + -Field("2"), + }}; + const Field expect_hash("47690627216444699952391427631776755329098419241452" + "8676152606007181154538262"); + + libsnark::protoboard pb; + + // Public input: hash of multiple values + libsnark::pb_variable hashed_inputs; + hashed_inputs.allocate(pb, "hashed_inputs"); + pb.set_input_sizes(1); + + // Values to hash + libsnark::pb_variable_array orig_inputs; + orig_inputs.allocate(pb, simple_values.size(), "orig_inputs"); + + // Input hasher + input_hasher hasher(pb, orig_inputs, hashed_inputs, "hasher"); + + // Constraints + hasher.generate_r1cs_constraints(); + + // Witness + for (size_t i = 0; i < simple_values.size(); ++i) { + pb.val(orig_inputs[i]) = simple_values[i]; + } + hasher.generate_r1cs_witness(); + + ASSERT_EQ(expect_hash, pb.val(hashed_inputs)); + ASSERT_TRUE(pb.is_satisfied()); +} + +} // namespace + +int main(int argc, char **argv) +{ + pp::init_public_params(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From 7e9db5e916beca2588e8f0cfcef75a0b52d7e546 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 13 Jan 2021 10:33:36 +0000 Subject: [PATCH 033/137] libzeth: immediate version of input hashing function --- libzeth/circuits/mimc/mimc_input_hasher.hpp | 3 ++ libzeth/circuits/mimc/mimc_input_hasher.tcc | 32 ++++++++++++++----- .../tests/circuits/mimc_input_hasher_test.cpp | 1 + 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/libzeth/circuits/mimc/mimc_input_hasher.hpp b/libzeth/circuits/mimc/mimc_input_hasher.hpp index f0b328ba9..b8fffda08 100644 --- a/libzeth/circuits/mimc/mimc_input_hasher.hpp +++ b/libzeth/circuits/mimc/mimc_input_hasher.hpp @@ -34,6 +34,9 @@ class mimc_input_hasher : public libsnark::gadget void generate_r1cs_constraints(); void generate_r1cs_witness() const; + + static FieldT get_iv(); + static FieldT compute_hash(const std::vector &values); }; } // namespace libzeth diff --git a/libzeth/circuits/mimc/mimc_input_hasher.tcc b/libzeth/circuits/mimc/mimc_input_hasher.tcc index adea1f359..792644b22 100644 --- a/libzeth/circuits/mimc/mimc_input_hasher.tcc +++ b/libzeth/circuits/mimc/mimc_input_hasher.tcc @@ -34,15 +34,8 @@ mimc_input_hasher::mimc_input_hasher( _intermediate_values.allocate( pb, num_inputs, FMT(annotation_prefix, "intermediate_values")); - // IV generated as: - // zeth.core.mimc._keccak_256( - // zeth.core.mimc._str_to_bytes("clearmatics_hash_seed")) - // See: client/zeth/core/mimc.py - const FieldT iv_val( - "1319653706411738841819622385631198771438854383955240040834092139" - "7545324034315"); libsnark::pb_linear_combination iv; - iv.assign(pb, iv_val); + iv.assign(pb, get_iv()); // First step: hash_output[0] <- mimc_mp(iv, i[0]) @@ -92,6 +85,29 @@ void mimc_input_hasher::generate_r1cs_witness() const } } +template +FieldT mimc_input_hasher::get_iv() +{ + // IV generated as: + // zeth.core.mimc._keccak_256( + // zeth.core.mimc._str_to_bytes("clearmatics_hash_seed")) + // See: client/zeth/core/mimc.py + return FieldT( + "1319653706411738841819622385631198771438854383955240040834092139" + "7545324034315"); +} + +template +FieldT mimc_input_hasher::compute_hash( + const std::vector &values) +{ + FieldT h = get_iv(); + for (const FieldT &v : values) { + h = comp_fnT::get_hash(h, v); + } + return comp_fnT::get_hash(h, FieldT(values.size())); +} + } // namespace libzeth #endif // __ZETH_CIRCUITS_MIMC_MIMC_INPUT_HASHER_TCC__ diff --git a/libzeth/tests/circuits/mimc_input_hasher_test.cpp b/libzeth/tests/circuits/mimc_input_hasher_test.cpp index bef917e50..0c8e706f4 100644 --- a/libzeth/tests/circuits/mimc_input_hasher_test.cpp +++ b/libzeth/tests/circuits/mimc_input_hasher_test.cpp @@ -58,6 +58,7 @@ TEST(MiMCInputHasherTest, SimpleInputValues) hasher.generate_r1cs_witness(); ASSERT_EQ(expect_hash, pb.val(hashed_inputs)); + ASSERT_EQ(expect_hash, input_hasher::compute_hash(simple_values)); ASSERT_TRUE(pb.is_satisfied()); } From 2d60a5003e977903e59bb580714c6442f5f24ec3 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 13 Jan 2021 16:35:47 +0000 Subject: [PATCH 034/137] client: abstract proto types behind prover_client interface --- client/test_commands/scenario.py | 6 +---- client/zeth/cli/zeth_get_verification_key.py | 8 +------ client/zeth/core/mixer_client.py | 12 ++++------ client/zeth/core/prover_client.py | 24 ++++++++++++++------ 4 files changed, 23 insertions(+), 27 deletions(-) diff --git a/client/test_commands/scenario.py b/client/test_commands/scenario.py index 635a76aa0..463eee7b2 100644 --- a/client/test_commands/scenario.py +++ b/client/test_commands/scenario.py @@ -56,7 +56,6 @@ def wait_for_tx_update_mk_tree( def get_mix_parameters_components( zeth_client: MixerClient, prover_client: ProverClient, - zksnark: IZKSnarkProvider, mk_tree: MerkleTree, sender_ownership_keypair: OwnershipKeyPair, inputs: List[Tuple[int, ZethNote]], @@ -79,8 +78,7 @@ def get_mix_parameters_components( compute_h_sig_cb) prover_inputs, signing_keypair = zeth_client.create_prover_inputs( mix_call_desc) - ext_proof_proto = prover_client.get_proof(prover_inputs) - ext_proof = zksnark.extended_proof_from_proto(ext_proof_proto) + ext_proof = prover_client.get_proof(prover_inputs) return ( prover_inputs.js_outputs[0], prover_inputs.js_outputs[1], @@ -262,7 +260,6 @@ def compute_h_sig_attack_nf( get_mix_parameters_components( zeth_client, prover_client, - zksnark, mk_tree, keystore["Charlie"].ownership_keypair(), # sender [input1, input2], @@ -370,7 +367,6 @@ def charlie_corrupt_bob_deposit( get_mix_parameters_components( zeth_client, prover_client, - zksnark, mk_tree, keystore["Bob"].ownership_keypair(), [input1, input2], diff --git a/client/zeth/cli/zeth_get_verification_key.py b/client/zeth/cli/zeth_get_verification_key.py index 31a750adb..662728163 100644 --- a/client/zeth/cli/zeth_get_verification_key.py +++ b/client/zeth/cli/zeth_get_verification_key.py @@ -4,7 +4,6 @@ from click import command, option, Context, pass_context -from zeth.core.zksnark import get_zksnark_provider from zeth.cli.utils import create_prover_client import json from typing import Optional @@ -21,12 +20,7 @@ def get_verification_key(ctx: Context, vk_out: Optional[str]) -> None: # Get the VK (proto object) client_ctx = ctx.obj prover_client = create_prover_client(client_ctx) - vk_proto = prover_client.get_verification_key() - - # Get a zksnark provider and convert the VK to json - zksnark_name = prover_client.get_configuration().zksnark_name - zksnark = get_zksnark_provider(zksnark_name) - vk = zksnark.verification_key_from_proto(vk_proto) + vk = prover_client.get_verification_key() vk_json = vk.to_json_dict() # Write the json to stdout or a file diff --git a/client/zeth/core/mixer_client.py b/client/zeth/core/mixer_client.py index 07b18d057..0b7cbda5d 100644 --- a/client/zeth/core/mixer_client.py +++ b/client/zeth/core/mixer_client.py @@ -276,13 +276,12 @@ def deploy( 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) + vk = prover_client.get_verification_key() deploy_gas = deploy_gas or constants.DEPLOYMENT_GAS_WEI 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") @@ -581,11 +580,8 @@ def create_mix_parameters_and_signing_key( 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) + ext_proof = prover_client.get_proof(prover_inputs) # Create the final MixParameters object mix_params = self.create_mix_parameters_from_proof( diff --git a/client/zeth/core/prover_client.py b/client/zeth/core/prover_client.py index eb7126114..a9e387dea 100644 --- a/client/zeth/core/prover_client.py +++ b/client/zeth/core/prover_client.py @@ -5,9 +5,10 @@ # SPDX-License-Identifier: LGPL-3.0+ from __future__ import annotations -from .pairing import PairingParameters, pairing_parameters_from_proto +from zeth.core.zksnark import IZKSnarkProvider, get_zksnark_provider, \ + IVerificationKey, ExtendedProof +from zeth.core.pairing import PairingParameters, pairing_parameters_from_proto from zeth.api.zeth_messages_pb2 import ProofInputs -from zeth.api.snark_messages_pb2 import VerificationKey, ExtendedProof from zeth.api import prover_pb2 # type: ignore from zeth.api import prover_pb2_grpc # type: ignore import grpc # type: ignore @@ -93,14 +94,22 @@ def get_configuration(self) -> ProverConfiguration: return self.prover_config - def get_verification_key(self) -> VerificationKey: + 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) + + def get_verification_key(self) -> IVerificationKey: """ Fetch the verification key from the proving service """ with grpc.insecure_channel(self.endpoint) as channel: stub = prover_pb2_grpc.ProverStub(channel) # type: ignore - verificationkey = stub.GetVerificationKey(_make_empty_message()) - return verificationkey + vk_proto = stub.GetVerificationKey(_make_empty_message()) + zksnark = self.get_zksnark_provider() + return zksnark.verification_key_from_proto(vk_proto) def get_proof( self, @@ -111,8 +120,9 @@ def get_proof( with grpc.insecure_channel(self.endpoint) as channel: stub = prover_pb2_grpc.ProverStub(channel) # type: ignore print("-------------- Get the proof --------------") - proof = stub.Prove(proof_inputs) - return proof + extproof_proto = stub.Prove(proof_inputs) + zksnark = self.get_zksnark_provider() + return zksnark.extended_proof_from_proto(extproof_proto) def _make_empty_message() -> empty_pb2.Empty: From 66f53f1e8f72507467b106f85d183458492dbfef Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 14 Jan 2021 16:13:47 +0000 Subject: [PATCH 035/137] prover_server: fix memory error --- prover_server/prover_server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prover_server/prover_server.cpp b/prover_server/prover_server.cpp index b4234dd64..8e9fda11c 100644 --- a/prover_server/prover_server.cpp +++ b/prover_server/prover_server.cpp @@ -88,7 +88,7 @@ static void write_ext_proof_to_file( class prover_server final : public zeth_proto::Prover::Service { private: - circuit_wrapper prover; + circuit_wrapper &prover; // The keypair is the result of the setup. Store a copy internally. snark::keypair keypair; From 8fec66aeb0a3dc8fb7d7d1da65a61893b7663e7f Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 14 Jan 2021 16:14:49 +0000 Subject: [PATCH 036/137] libzecale: clean up circuit_wrapper and avoid recreating the full circuit for each invocation --- libzeth/circuits/circuit_wrapper.hpp | 23 ++++++++++++++--------- libzeth/circuits/circuit_wrapper.tcc | 23 +++++++---------------- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/libzeth/circuits/circuit_wrapper.hpp b/libzeth/circuits/circuit_wrapper.hpp index a9a6240ac..0094c1c39 100644 --- a/libzeth/circuits/circuit_wrapper.hpp +++ b/libzeth/circuits/circuit_wrapper.hpp @@ -25,26 +25,27 @@ template< size_t TreeDepth> class circuit_wrapper { -private: - std::shared_ptr, +public: + using Field = libff::Fr; + // Both `joinsplit` and `joinsplit_gadget` are already used in the + // namespace. + using joinsplit_type = joinsplit_gadget< + Field, HashT, HashTreeT, NumInputs, NumOutputs, - TreeDepth>> - joinsplit_g; - -public: - using Field = libff::Fr; + TreeDepth>; circuit_wrapper(); + circuit_wrapper(const circuit_wrapper &) = delete; + circuit_wrapper &operator=(const circuit_wrapper &) = delete; // Generate the trusted setup typename snarkT::keypair generate_trusted_setup() const; // Retrieve the constraint system (intended for debugging purposes). - libsnark::protoboard get_constraint_system() const; + const libsnark::protoboard &get_constraint_system() const; // Generate a proof and returns an extended proof extended_proof prove( @@ -56,6 +57,10 @@ class circuit_wrapper const bits256 &h_sig_in, const bits256 &phi_in, const typename snarkT::proving_key &proving_key) const; + +private: + libsnark::protoboard pb; + std::shared_ptr joinsplit; }; } // namespace libzeth diff --git a/libzeth/circuits/circuit_wrapper.tcc b/libzeth/circuits/circuit_wrapper.tcc index 77adbb937..5d6379894 100644 --- a/libzeth/circuits/circuit_wrapper.tcc +++ b/libzeth/circuits/circuit_wrapper.tcc @@ -27,6 +27,11 @@ circuit_wrapper< NumOutputs, TreeDepth>::circuit_wrapper() { + // TODO: joinsplit_gadget should be refactored to be properly composable. + joinsplit = std::make_shared(pb); + + // Generate constraints + joinsplit->generate_r1cs_constraints(); } template< @@ -46,11 +51,6 @@ typename snarkT::keypair circuit_wrapper< NumOutputs, TreeDepth>::generate_trusted_setup() const { - libsnark::protoboard pb; - joinsplit_gadget - g(pb); - g.generate_r1cs_constraints(); - // Generate a verification and proving key (trusted setup) and write them // in a file return snarkT::generate_setup(pb); @@ -64,7 +64,7 @@ template< size_t NumInputs, size_t NumOutputs, size_t TreeDepth> -libsnark::protoboard> circuit_wrapper< +const libsnark::protoboard> &circuit_wrapper< HashT, HashTreeT, ppT, @@ -73,10 +73,6 @@ libsnark::protoboard> circuit_wrapper< NumOutputs, TreeDepth>::get_constraint_system() const { - libsnark::protoboard pb; - joinsplit_gadget - g(pb); - g.generate_r1cs_constraints(); return pb; } @@ -128,12 +124,7 @@ extended_proof circuit_wrapper< throw std::invalid_argument("invalid joinsplit balance"); } - libsnark::protoboard pb; - - joinsplit_gadget - g(pb); - g.generate_r1cs_constraints(); - g.generate_r1cs_witness( + joinsplit->generate_r1cs_witness( root, inputs, outputs, vpub_in, vpub_out, h_sig_in, phi_in); bool is_valid_witness = pb.is_satisfied(); From 896685e6cdab59194978c70e85f840686acc7419 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 14 Jan 2021 17:25:04 +0000 Subject: [PATCH 037/137] submodule: update libsnark to get some better memory protection --- depends/libsnark | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/libsnark b/depends/libsnark index 39bb0b9f1..fa306c6fc 160000 --- a/depends/libsnark +++ b/depends/libsnark @@ -1 +1 @@ -Subproject commit 39bb0b9f193511a22a94d35bb3829afc9671b55d +Subproject commit fa306c6fc981c5459adcb368f3e42cb0122681fb From 026a12e5054458f6c03d1addee9a2320e30f4488 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 14 Jan 2021 17:50:56 +0000 Subject: [PATCH 038/137] libzeth: make joinsplit a bit more composable --- libzeth/circuits/circuit_wrapper.tcc | 3 +++ libzeth/circuits/joinsplit.tcc | 15 ++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/libzeth/circuits/circuit_wrapper.tcc b/libzeth/circuits/circuit_wrapper.tcc index 5d6379894..d30a93c8c 100644 --- a/libzeth/circuits/circuit_wrapper.tcc +++ b/libzeth/circuits/circuit_wrapper.tcc @@ -27,8 +27,11 @@ circuit_wrapper< NumOutputs, TreeDepth>::circuit_wrapper() { + // Joinsplit gadget internally allocates its public data first. // TODO: joinsplit_gadget should be refactored to be properly composable. joinsplit = std::make_shared(pb); + const size_t num_public_elements = joinsplit->get_num_public_elements(); + pb.set_input_sizes(num_public_elements); // Generate constraints joinsplit->generate_r1cs_constraints(); diff --git a/libzeth/circuits/joinsplit.tcc b/libzeth/circuits/joinsplit.tcc index edbd35ed4..b4c41f3fb 100644 --- a/libzeth/circuits/joinsplit.tcc +++ b/libzeth/circuits/joinsplit.tcc @@ -192,10 +192,10 @@ public: // represented. The aggregation of these bits plus of value_pub_in, // and value_pub_out take `nb_field_residual` field element(s) to be // represented - const size_t nb_packed_inputs = + const size_t num_packed_public_elements = 2 * NumInputs + 1 + nb_field_residual; - const size_t nb_inputs = 1 + NumOutputs + nb_packed_inputs; - pb.set_input_sizes(nb_inputs); + const size_t num_public_elements = + 1 + NumOutputs + num_packed_public_elements; // --------------------------------------------------------------- ZERO.allocate(pb, FMT(this->annotation_prefix, " ZERO")); @@ -277,14 +277,15 @@ public: // since we are packing all the inputs nullifiers + the h_is + // + the h_sig + the residual bits assert(packed_inputs.size() == NumInputs + 1 + NumInputs + 1); - assert(nb_packed_inputs == [this]() { + assert(num_packed_public_elements == [this]() { size_t sum = 0; for (const auto &i : packed_inputs) { sum = sum + i.size(); } return sum; }()); - assert(nb_inputs == get_inputs_field_element_size()); + assert(num_public_elements == get_num_public_elements()); + (void)num_public_elements; // [SANITY CHECK] Total size of unpacked inputs size_t total_size_unpacked_inputs = 0; @@ -599,8 +600,8 @@ public: return get_inputs_bit_size() - (1 + NumOutputs) * FieldT::capacity(); } - // Computes the number of field elements in the primary inputs - static size_t get_inputs_field_element_size() + // Computes the number of field elements in the public data + static size_t get_num_public_elements() { size_t nb_elements = 0; From 7090f4817d8472ffd2de17fa590445c16781d167 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 20 Jan 2021 11:05:52 +0000 Subject: [PATCH 039/137] libzeth: comment about "experimental" code (review) --- client/zeth/core/input_hasher.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/client/zeth/core/input_hasher.py b/client/zeth/core/input_hasher.py index 87dd395c6..09119064f 100644 --- a/client/zeth/core/input_hasher.py +++ b/client/zeth/core/input_hasher.py @@ -15,13 +15,14 @@ class InputHasher: """ - Hash a series of field elements via the Merkle-Damgard construction on a - MiMC compression function. Note that since this function only accepts whole - numbers of scalar field elements, there is no ambiguity w.r.t to padding - and we could technically omit the finalization step. It has been kept for - now, to allow time for further consideration, and in case the form of the - hasher changes (e.g. in case we want to be able to hash arbitrary bit - strings in the future). + Note that this is currently experimental code. Hash a series of field + elements via the Merkle-Damgard construction on a MiMC compression + function. Note that since this function only accepts whole numbers of + scalar field elements, there is no ambiguity w.r.t to padding and we could + technically omit the finalization step. It has been kept for now, to allow + time for further consideration, and in case the form of the hasher changes + (e.g. in case we want to be able to hash arbitrary bit strings in the + future). """ def __init__(self, compression_fn: MiMCBase, iv: int = DEFAULT_IV_UINT256): assert compression_fn.prime < (2 << 256) From b38aa679d70377fc967013bb2a7499aa3812e084 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 20 Jan 2021 11:29:18 +0000 Subject: [PATCH 040/137] libzeth: rename type parameter (review) --- libzeth/circuits/mimc/mimc_input_hasher.hpp | 4 +-- libzeth/circuits/mimc/mimc_input_hasher.tcc | 36 ++++++++++----------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/libzeth/circuits/mimc/mimc_input_hasher.hpp b/libzeth/circuits/mimc/mimc_input_hasher.hpp index b8fffda08..a6395593a 100644 --- a/libzeth/circuits/mimc/mimc_input_hasher.hpp +++ b/libzeth/circuits/mimc/mimc_input_hasher.hpp @@ -12,7 +12,7 @@ namespace libzeth /// Given a list of variables, hash the variables to a value which can be used /// as a public input bound to the original variables. -template +template class mimc_input_hasher : public libsnark::gadget { private: @@ -20,7 +20,7 @@ class mimc_input_hasher : public libsnark::gadget libsnark::pb_variable _result; // Compression function constraints - std::vector> _compression_functions; + std::vector> _compression_functions; // Intermediate values libsnark::pb_variable_array _intermediate_values; diff --git a/libzeth/circuits/mimc/mimc_input_hasher.tcc b/libzeth/circuits/mimc/mimc_input_hasher.tcc index 792644b22..f00c0de8f 100644 --- a/libzeth/circuits/mimc/mimc_input_hasher.tcc +++ b/libzeth/circuits/mimc/mimc_input_hasher.tcc @@ -10,8 +10,8 @@ namespace libzeth { -template -mimc_input_hasher::mimc_input_hasher( +template +mimc_input_hasher::mimc_input_hasher( libsnark::protoboard &pb, const libsnark::pb_linear_combination_array &inputs, const libsnark::pb_variable result, @@ -39,16 +39,16 @@ mimc_input_hasher::mimc_input_hasher( // First step: hash_output[0] <- mimc_mp(iv, i[0]) - _compression_functions.emplace_back(new comp_fnT( + _compression_functions.emplace_back(new compFnT( pb, iv, inputs[0], _intermediate_values[0], FMT(annotation_prefix, " compression_functions[0]"))); - // Intermediate invocations of the compression fucntion. + // Intermediate invocations of the compression function. for (size_t i = 1; i < num_inputs; ++i) { - _compression_functions.emplace_back(new comp_fnT( + _compression_functions.emplace_back(new compFnT( pb, _intermediate_values[i - 1], inputs[i], @@ -59,7 +59,7 @@ mimc_input_hasher::mimc_input_hasher( // Last invocation of compression function to finalize. libsnark::pb_linear_combination num_inputs_lc; num_inputs_lc.assign(pb, FieldT(num_inputs)); - _compression_functions.emplace_back(new comp_fnT( + _compression_functions.emplace_back(new compFnT( pb, _intermediate_values[num_inputs - 1], num_inputs_lc, @@ -69,24 +69,24 @@ mimc_input_hasher::mimc_input_hasher( assert(_compression_functions.size() == num_inputs + 1); } -template -void mimc_input_hasher::generate_r1cs_constraints() +template +void mimc_input_hasher::generate_r1cs_constraints() { - for (const std::shared_ptr &cf : _compression_functions) { + for (const std::shared_ptr &cf : _compression_functions) { cf->generate_r1cs_constraints(); } } -template -void mimc_input_hasher::generate_r1cs_witness() const +template +void mimc_input_hasher::generate_r1cs_witness() const { - for (const std::shared_ptr &cf : _compression_functions) { + for (const std::shared_ptr &cf : _compression_functions) { cf->generate_r1cs_witness(); } } -template -FieldT mimc_input_hasher::get_iv() +template +FieldT mimc_input_hasher::get_iv() { // IV generated as: // zeth.core.mimc._keccak_256( @@ -97,15 +97,15 @@ FieldT mimc_input_hasher::get_iv() "7545324034315"); } -template -FieldT mimc_input_hasher::compute_hash( +template +FieldT mimc_input_hasher::compute_hash( const std::vector &values) { FieldT h = get_iv(); for (const FieldT &v : values) { - h = comp_fnT::get_hash(h, v); + h = compFnT::get_hash(h, v); } - return comp_fnT::get_hash(h, FieldT(values.size())); + return compFnT::get_hash(h, FieldT(values.size())); } } // namespace libzeth From d94a36a02570f600f61f60425ac2c82064c949f4 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 21 Jan 2021 12:49:43 +0000 Subject: [PATCH 041/137] libzeth: update some comments about public vs primary inputs in joinsplit --- libzeth/circuits/joinsplit.tcc | 70 +++++++++++++++++----------------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/libzeth/circuits/joinsplit.tcc b/libzeth/circuits/joinsplit.tcc index b4c41f3fb..b6dcd183d 100644 --- a/libzeth/circuits/joinsplit.tcc +++ b/libzeth/circuits/joinsplit.tcc @@ -63,7 +63,8 @@ private: libsnark::pb_variable ZERO; - // ---- Primary inputs (public) ---- // + // PUBLIC DATA: to be made available to the mixer + // Merkle Root std::shared_ptr> merkle_root; // List of nullifiers of the notes to spend @@ -82,7 +83,11 @@ private: std::array>, NumInputs> h_is; - // ---- Auxiliary inputs (private) ---- // + // PRIVATE DATA: must be auxiliary (private) inputs to the statement. + // Protoboard owner is responsible for ensuring this. (Note that the PUBLIC + // inputs above are allocated first, so only the first + // get_num_public_elements allocated by this gadget are "public"). + // Total amount transfered in the transaction libsnark::pb_variable_array zk_total_uint64; // List of all spending keys @@ -125,29 +130,26 @@ public: { // Block dedicated to generate the verifier inputs { - // The verification inputs are, except for the root, all bit-strings - // of various lengths (256-bit digests and 64-bit integers) and so - // we pack them into as few field elements as possible. (The more - // verification inputs you have, the more expensive verification - // is.) - - // --------- ALLOCATION OF PRIMARY INPUTS -------- // - // We make sure to have the primary inputs ordered as follow: - // [Root, NullifierS, CommitmentS, h_sig, h_iS, Residual field - // element(S)] ie, below is the index mapping of the primary input - // elements on the protoboard: - // - Index of the "Root" field element: {0} - // - Index of the "NullifierS" field elements: [1, 1 + NumInputs[ - // - Index of the "CommitmentS" field elements: [1 + NumInputs, - // 1 + NumInputs + NumOutputs[ - // - Index of the "h_sig" field element: {1 + NumInputs + - // NumOutputs} - // - Index of the "h_iS" field elements: [1 + NumInputs + NumOutputs - // + 1, 1 + NumInputs + NumOutputs + NumInputs[ - // - Index of the "Residual field element(S)", ie "v_pub_in", - // "v_pub_out", and bits of previous variables not fitting within - // FieldT::capacity() [1 + NumInputs + NumOutputs + NumInputs, - // 1 + NumInputs + NumOutputs + NumInputs + nb_field_residual[ + // PUBLIC DATA: allocated first so that the protoboard has access. + // + // Allocation is currently performed here in the following order + // (with the protoboard owner determining whether these are primary + // or auxiliary inputs to the circuit): + // - Root + // - NullifierS + // - CommitmentS + // - h_sig + // - h_iS + // - Residual field element(S) + // + // This yields the following index mappings: + // 0 : "Root" + // 1, ... : Nullifiers (NumInputs) + // 1 + NumInputs, ... : Commitments (Num Outputs) + // 1 + NumInputs + NumOutputs : h_sig + // 2 + NumInputs + NumOutputs, ... : h_iS (NumInputs) + // 2 + 2xNumInputs + NumOutputs, ... : v_in, v_out, residual + // (nb_field_residual) // We first allocate the root merkle_root.reset(new libsnark::pb_variable); @@ -184,20 +186,20 @@ public: nb_field_residual, FMT(this->annotation_prefix, " residual_bits")); - // The primary inputs are: - // [Root, NullifierS, CommitmentS, h_sig, h_iS, Residual Field - // Element(S)]. The root is represented on a single field element. - // H_sig, as well as each nullifier, commitment and h_i are in - // {0,1}^256 and thus take 1 field element and a few bits to be - // represented. The aggregation of these bits plus of value_pub_in, - // and value_pub_out take `nb_field_residual` field element(s) to be - // represented + // Compute the number of packed public elements, and the total + // number of public elements (see table above). The "packed" inputs + // (those represented as a field element and some residual bits) + // are: + // H_sig, nullifier, commitments and h_iS const size_t num_packed_public_elements = 2 * NumInputs + 1 + nb_field_residual; const size_t num_public_elements = 1 + NumOutputs + num_packed_public_elements; - // --------------------------------------------------------------- + // PRIVATE DATA: + + // Allocate a ZERO variable + // TODO: check whether/why this is actually needed ZERO.allocate(pb, FMT(this->annotation_prefix, " ZERO")); // Initialize the digest_variables From 9db934f93bcba29c4f423c60bca002ba449d8c8b Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Fri, 15 Jan 2021 12:25:07 +0000 Subject: [PATCH 042/137] Use hash of public joinsplit data as single primary input to zk-proof --- client/test_commands/scenario.py | 37 +++++--- ...py => test_groth16_altbn128_mixer_base.py} | 89 +++++++++--------- client/tests/test_mixer_client.py | 4 +- client/zeth/core/mixer_client.py | 32 +++++-- client/zeth/core/prover_client.py | 11 ++- libzeth/circuits/circuit_wrapper.hpp | 8 +- libzeth/circuits/circuit_wrapper.tcc | 34 ++++++- libzeth/circuits/mimc/mimc.tcc | 5 +- libzeth/tests/prover/prover_test.cpp | 92 ++++++++++++------- proto/zeth/api/prover.proto | 2 +- proto/zeth/api/zeth_messages.proto | 13 +++ prover_server/prover_server.cpp | 23 ++++- .../contracts/Groth16AltBN128Mixer.sol | 14 +-- ....sol => Groth16AltBN128MixerBase_test.sol} | 17 +++- .../contracts/Groth16BLS12_377Mixer.sol | 16 +--- zeth_contracts/contracts/MixerBase.sol | 50 ++++++++-- .../contracts/Pghr13AltBN128Mixer.sol | 23 +++-- 17 files changed, 313 insertions(+), 157 deletions(-) rename client/test_contracts/{test_altbn128_mixer_base.py => test_groth16_altbn128_mixer_base.py} (65%) rename zeth_contracts/contracts/{AltBN128MixerBase_test.sol => Groth16AltBN128MixerBase_test.sol} (77%) diff --git a/client/test_commands/scenario.py b/client/test_commands/scenario.py index 463eee7b2..dab9ee4df 100644 --- a/client/test_commands/scenario.py +++ b/client/test_commands/scenario.py @@ -63,7 +63,7 @@ def get_mix_parameters_components( v_in: EtherValue, v_out: EtherValue, compute_h_sig_cb: Optional[ComputeHSigCB] = None -) -> Tuple[ZethNote, ZethNote, ExtendedProof, JoinsplitSigKeyPair]: +) -> Tuple[ZethNote, ZethNote, ExtendedProof, List[int], JoinsplitSigKeyPair]: """ Manually create the components required for MixParameters. The tests below manipulate these to create custom MixParameters as part of attacks. @@ -78,11 +78,12 @@ def get_mix_parameters_components( compute_h_sig_cb) prover_inputs, signing_keypair = zeth_client.create_prover_inputs( mix_call_desc) - ext_proof = prover_client.get_proof(prover_inputs) + ext_proof, public_data = prover_client.get_proof(prover_inputs) return ( prover_inputs.js_outputs[0], prover_inputs.js_outputs[1], ext_proof, + public_data, signing_keypair) @@ -256,7 +257,7 @@ def compute_h_sig_attack_nf( return compute_h_sig( bytes.fromhex(attack_nf0), bytes.fromhex(attack_nf1), sign_vk) - output_note1, output_note2, proof, signing_keypair = \ + output_note1, output_note2, proof, public_data, signing_keypair = \ get_mix_parameters_components( zeth_client, prover_client, @@ -276,10 +277,10 @@ def compute_h_sig_attack_nf( assert attack_primary_input4 != 0 print("proof = ", proof) - print("proof.inputs[3] = ", proof.inputs[3]) - print("proof.inputs[4] = ", proof.inputs[4]) - proof.inputs[3] = hex(attack_primary_input3) - proof.inputs[4] = hex(attack_primary_input4) + print("public_data[3] = ", public_data[3]) + print("public_data[4] = ", public_data[4]) + public_data[3] = attack_primary_input3 + public_data[4] = attack_primary_input4 # ### ATTACK BLOCK # construct pk object from bytes @@ -297,10 +298,12 @@ def compute_h_sig_attack_nf( signing_keypair, charlie_eth_address, ciphertexts, - proof) + proof, + public_data) mix_params = MixParameters( proof, + public_data, signing_keypair.vk, joinsplit_sig_charlie, ciphertexts) @@ -363,7 +366,7 @@ def charlie_corrupt_bob_deposit( v_in = EtherValue(BOB_DEPOSIT_ETH) - output_note1, output_note2, proof, joinsplit_keypair = \ + output_note1, output_note2, proof, public_data, joinsplit_keypair = \ get_mix_parameters_components( zeth_client, prover_client, @@ -399,10 +402,12 @@ def charlie_corrupt_bob_deposit( joinsplit_keypair, charlie_eth_address, ciphertexts, - proof) + proof, + public_data) mix_params = MixParameters( proof, + public_data, joinsplit_keypair.vk, joinsplit_sig_charlie, [fake_ciphertext0, fake_ciphertext1]) @@ -439,9 +444,11 @@ def charlie_corrupt_bob_deposit( new_joinsplit_keypair, charlie_eth_address, [fake_ciphertext0, fake_ciphertext1], - proof) + proof, + public_data) mix_params = MixParameters( proof, + public_data, new_joinsplit_keypair.vk, joinsplit_sig_charlie, [fake_ciphertext0, fake_ciphertext1]) @@ -470,9 +477,11 @@ def charlie_corrupt_bob_deposit( joinsplit_keypair, bob_eth_address, ciphertexts, - proof) + proof, + public_data) mix_params = MixParameters( proof, + public_data, joinsplit_keypair.vk, joinsplit_sig_bob, ciphertexts) @@ -500,9 +509,11 @@ def charlie_corrupt_bob_deposit( joinsplit_keypair, bob_eth_address, ciphertexts, - proof) + proof, + public_data) mix_params = MixParameters( proof, + public_data, joinsplit_keypair.vk, joinsplit_sig_bob, ciphertexts) diff --git a/client/test_contracts/test_altbn128_mixer_base.py b/client/test_contracts/test_groth16_altbn128_mixer_base.py similarity index 65% rename from client/test_contracts/test_altbn128_mixer_base.py rename to client/test_contracts/test_groth16_altbn128_mixer_base.py index 4c3ecec79..85ccbb29c 100644 --- a/client/test_contracts/test_altbn128_mixer_base.py +++ b/client/test_contracts/test_groth16_altbn128_mixer_base.py @@ -7,6 +7,8 @@ from zeth.core.constants import \ JS_INPUTS, ZETH_PUBLIC_UNIT_VALUE, ZETH_MERKLE_TREE_DEPTH from zeth.core.prover_client import ProverConfiguration +from zeth.core.mimc import MiMC7 +from zeth.core.input_hasher import InputHasher from zeth.core.zksnark import get_zksnark_provider from zeth.core.utils import EtherValue, hex_list_to_uint256_list from zeth.core.signing import SigningKeyPair @@ -20,13 +22,6 @@ # pylint: disable=line-too-long -# TODO: These tests are specific to AltBN128MixerBase, however the mixer that -# is deployed is a function of the currently running prover server. Change this -# to deploy a test contract (inheriting from AltBN128MixerBase) which then -# calls the given methods with the expected data (i.e. remove the requirement -# for a running prover_server, and support type-checking of the test code -# against interface changes). - # Primary inputs ROOT = 0 @@ -113,21 +108,21 @@ MIX_PARAMETERS_SIGNING_KEYPAIR = SigningKeyPair.from_json_dict({ "sk": { - "psk": "19cca1b1f0a3389880a51c5dad6da41885f1aa2a85d3895a7ee57cd93b91d92d", - "ssk_y": "091f01468410d87af0308ca0e27580de7ce59b5771dbadf47c1831dcbd8d2ec2", # noqa + "psk": "0094c3bd11c967ded0712fb8aa833dc34c2e9e36a298f9bca75ca47b014f525b", + "ssk_y": "26762feff4e7a0fe3f24182caf13b7709818bef122c3c8395c9cc71664925e2f", # noqa "ssk_y_g1": { - "x": "0f9a984abbea6e4f61a927d7fc7aa1ac997fd98edc7c57f43888ec025ba58de9", # noqa - "y": "08c7c8dcea11753d8ce4c77b70f3da5f497f3ecd6745e108d5080fae9936e66f", # noqa - }, + "x": "065495bf33403570a2c0bc2e5eb193dce106c82270ff72a68df1f3255019c37c", # noqa + "y": "12ef732b1e3d2afe712f6414eb68f4bdf0bd610e2bb199dd3ba9c3b7a49e34b3" # noqa + } }, "vk": { "ppk": { - "x": "2142d7e3c856f37296366fbde935161d62f3e51685d91e541b2c44df830e9fd7", # noqa - "y": "2da8644fa7c59b29d23d6a16591838dbfee30d281e0837dcdbf18fcca9eea54a", # noqa + "x": "03ff72a98c117f06526da1ecf485ddc46130bd97f6254678ab42dec92b9b533b", # noqa + "y": "1cd3a1f4ceb50551d9aec66aace46e630a3f6ff17106696ea1937ed573df82aa" # noqa }, "spk": { - "x": "0f9a984abbea6e4f61a927d7fc7aa1ac997fd98edc7c57f43888ec025ba58de9", # noqa - "y": "08c7c8dcea11753d8ce4c77b70f3da5f497f3ecd6745e108d5080fae9936e66f", # noqa + "x": "065495bf33403570a2c0bc2e5eb193dce106c82270ff72a68df1f3255019c37c", # noqa + "y": "12ef732b1e3d2afe712f6414eb68f4bdf0bd610e2bb199dd3ba9c3b7a49e34b3" # noqa } } }) @@ -135,33 +130,34 @@ MIX_PARAMETERS_DICT: Dict[str, Any] = { "extended_proof": { "proof": { - "a": ["0x022fc050ed6c153dcbfb1f18fdffd86e99e76bf9f9ceeb74b921be467df44d4f", "0x0473a961d1990f60799eff2bc2b8cb33cbeb4644fb87c3a2b5fa16b3cb662c80"], # noqa - "b": [["0x14f5918361b5f09955f822b378d4cb363265cdbf43ac3eae9594f93b25c740a5", "0x1caab696a800e657558485215194cfb5915ddea3fc9001537d1811fba04068b3"], ["0x1e2552d77e7af276b2d92a3a61e4fdeab0487af08c63f65902de91a7d5a21824", "0x0f1380685f4aba028770692dd3ccdbdc3ba4758482344784e34cee54f9f8b4a1"]], # noqa - "c": ["0x2bc2e2bfe646a10d5f220b21b5149bf724a8d34fd5f713775095b65f108ce90e", "0x1dc8f1acf805daf143686385f17ad06f4768e600555abbd1b21b65393ff196e8"], # noqa + "a": ["0x19bb99d61b9fd80f83c62301b8b49a7721ff4b9169304ee2e565967dff6c1f50","0x10cf81855def824e4ebb56df71e63271c9c24778fb5022db0c0e5266c5dac8c0"], # noqa + "b": [["0x2e8709a700d887a6d98b5c9e8154dd5aa2e8b37e176f7ee4dde254a4f01cb5f2", "0x26776b5283e39376a076ea7c9effd6ac6a2eb4e153ff33beccc50ea8c9ea77f6"], ["0x21d59a0bded4b94e995d1056fa08a5b44626f936bc7ce90556f288f558a4d6bc", "0x0dfe988bdd7e0f793df7d9d2136ccc2bd2fb9187eaf8f38430a7bfbdd0b7a8d2"]], # noqa + "c": ["0x2e0f8bec7eebad06fab29c558e96cbd68d2d729bca8b56640b0f00f93593e372", "0x2276552ff16f6b4e67c06495941c1988eca4bc60c9aa75cfc57098beb4f19156"] # noqa }, - "inputs": [ - "0x01e202cf4ac3721b9bfd398ec65969c811f32cb1e46df020337e9fc2fda0f014", - "0x19917fa2eea86a9082ef7766c7e7737c4153a499796baf01f68787d267b278cc", - "0x15e8587966977c5c5430cb9e84e686ee5f327ec2651a86c978ed7973ee8cd4b9", - "0x10c16790b950db6a0fd94ee66015d37e506e7a970cbbc962325839188ddd4875", - "0x029eae0aed749a8e05565a5228b825ac6e9a8ad034dbc7b674786783bae64be2", - "0x0945c9391ddd49eb41234a2249c78203040bf337ab27e1dd7a3c112010bc160d", - "0x03fb8ae204697d92aa1cb161a8fd533d62c9d4113db1de78547aa330f8148510", - "0x03dc42c147cc05ef3e5c3aae875a860dd73e7be3bc9578499a171f52cc5949e7", - "0x00000000000000000000000000001663000000000bebc2000000000000000000", - ], + "inputs": ["0x01a5e7daab7ee618030641a16ae09ec8f67e121f209e6241b65924122f2ed94b"] # noqa }, + "public_data": [ + "0x1e202cf4ac3721b9bfd398ec65969c811f32cb1e46df020337e9fc2fda0f014", + "0xda3f23b4b07b9cf6ae3ddce133f7de065b1f933e2df5653b52ddc57a79b4ce7", + "0x153319f1ecdd7a6d25380dc08566a8b5a6a46cb7a14a920b5400d834ca66bdbe", + "0xd1179e6c517a300b86e6e99bba141ca6bd95ac41a02ecd4eeb2a19176de1069", + "0x16f67a9d4ad2656c1f2fbc0d39e4e7ddcbad04bb83e7a38511b1b5f42d5e5983", + "0xfa8d8b70f091bc6d9e5186c91968d37dcc5153e2ff39b5508c1e15016e2bace", + "0x91ac4bd99ed6bc7ff73df5cbfe6330f4875e2c180daccbf568d8146f86ba24b", + "0xd146d5f49d6461012ae4ab3f6f670e275098ed6369406c6f0e5bc4fd4828bce", + "0x9a7000000000bebc2000000000000000000" + ], "signature_vk": [ - "15044425925993845483393126099570793906913594542449620874334342139863918092247", # noqa - "20651600815268664951459086661967759114548020657233676039273591752689993033034", # noqa - "7057838256995470367292750127543080978509804434882431937449883270040531602921", # noqa - "3971491659664912517391994943672743161518296354269326311016522861877057218159", # noqa + "1808275917333726390675593630676660592284499790243906329164148357633591169851", # noqa + "13038682272157317746935630690273139043012615829064107162576212284919309632170", # noqa + "2863325759893808656457455214623293696676979172082516149962341594639946597244", # noqa + "8564702586272948230916163901148349984070935330485128468603906018200747127987" # noqa ], - "signature": "10654946530806799981365073476369904106395106992608919376340445285630856100688", # noqa + "signature": "19090395247809983100415210093724020502485107107595263044457463522078345927435", # noqa "ciphertexts": [ - "f976f9b61cb10cb3275c7dc5941c314e8a6f894e312426f005322fdc7cc7ec3ba895de2033c09e19e35720f416ac8cbfd131048e38e244a56bf0ade2a9367c5fbf8a7976f59d270f590f6eb5ab9fbf35afa4550866837a29553bb6610cd0a5f57ca5b9ae6cf1d536ace98f1a58b7fde2030d013a6c4869875c3689ffbe535dbe2dcaad2b7f396eb2124d2d328a88e54c4ff524e417f1b57b", # noqa - "31424a6831ff6b7b5948ba5d7472030cf3427eeb730e974475d756995e48a1266b4ba550b6e28eb8b6b6367b3e7b7308ff2c1d641adcebaa818d3f325869bc66889c5e269673acbdfaa481feb5c57ef0ecccdcb58a8293dd347cf9a8423717dbea48119ebdc5b660f94a9ad1f43848299e02bcf07c59d3c594d65a486aa850c7adb7793673b965dfe27309631de9cad66638669afc16abea", # noqa - ], + "642149825d05b2b6e40d5e479ac27718adde77563e1e4a924a10a01afc9f5c63bd72e87a9710c2ea97c78a051fcb82cd1cdc23817f5781baa8d3508189fc0963fa3f6209df70aa95db14f24080da94e32374da6e9ce6dc4c3c0efbcbb428e605d683034f672750dd8c1533bf814339800731330f74fd5d67fa24e2207e1b8225aab47ca918d5583f27305f3ea0fcd3c1689a25add0bbad50", # noqa + "296909be36fb44361a34134c5acc47b01f5037c1be0f021734b993d0c766be10acc611836e9b77a67b59f4cbb74479402daa2e3d7b6a0ca780de9d0802bd751c0191bcaed8b2b7d5d334c7eb3bc339795cfeb7e7ace9ede7c1ebb8f4fa79f01342856dc557b680dd6e2ead876a7a281ab935c94aeba77f48097038cc8df1b36b56a97f6a2cdd42e05ed6f3ca26622ae87b405276b9544dcd" # noqa + ] } WEB3: Optional[Any] = None @@ -173,7 +169,7 @@ MIXER_CLIENT: Optional[MixerClient] = None -class TestAltBN128MixerBaseContract(TestCase): +class TestGroth16AltBN128MixerBaseContract(TestCase): @staticmethod def setUpClass() -> None: @@ -183,7 +179,7 @@ def setUpClass() -> None: _mixer_interface, mixer_instance = mock.deploy_contract( eth, deployer_eth_address, - "AltBN128MixerBase_test", + "Groth16AltBN128MixerBase_test", { 'mk_depth': ZETH_MERKLE_TREE_DEPTH, 'permitted_dispatcher': deployer_eth_address, @@ -199,6 +195,15 @@ def setUpClass() -> None: global MIXER_CLIENT # pylint: disable=global-statement MIXER_CLIENT = MixerClient(web3, PROVER_CONFIG, MIXER_INSTANCE) + def test_hash_public_inputs(self) -> None: + zksnark = get_zksnark_provider(PROVER_CONFIG.zksnark_name) + mix_params = MixParameters.from_json_dict(zksnark, MIX_PARAMETERS_DICT) + public_data = mix_params.public_data + expect_hash = InputHasher(MiMC7()).hash(public_data) + actual_hash = MIXER_INSTANCE.functions.\ + hash_public_proof_data_test(public_data).call() + self.assertEqual(expect_hash, actual_hash) + def test_assemble_nullifiers(self) -> None: # Test retrieving nullifiers for i in range(JS_INPUTS): @@ -237,10 +242,12 @@ def test_dispatch_call(self) -> None: sender_eth_address=sender_eth_address, ciphertexts=mix_params.ciphertexts, extproof=mix_params.extended_proof, + public_data=mix_params.public_data, for_dispatch_call=True) mix_params.signature = new_signature - nested_inputs = hex_list_to_uint256_list(mix_params.extended_proof.inputs) + nested_inputs = \ + hex_list_to_uint256_list(mix_params.extended_proof.inputs) nested_parameters = mix_parameters_to_dispatch_parameters(mix_params) mixer_call = MIXER_INSTANCE.functions.dispatch( VK_HASH, nested_inputs, nested_parameters) diff --git a/client/tests/test_mixer_client.py b/client/tests/test_mixer_client.py index 03bc7edc2..256b6c769 100644 --- a/client/tests/test_mixer_client.py +++ b/client/tests/test_mixer_client.py @@ -28,6 +28,7 @@ def test_mix_parameters(self) -> None: "bcde", "cdef", ]) + public_data = [1234, 4321, 9876, 6789] sig_keypair = gen_signing_keypair() sig_vk = sig_keypair.vk sig = sign(sig_keypair.sk, bytes.fromhex("00112233")) @@ -37,7 +38,8 @@ def test_mix_parameters(self) -> None: encrypt(token_bytes(NOTE_LENGTH_BYTES), receiver_enc_keypair.k_pk), ] - mix_params = MixParameters(ext_proof, sig_vk, sig, ciphertexts) + mix_params = MixParameters( + ext_proof, public_data, sig_vk, sig, ciphertexts) mix_params_json = mix_params.to_json() mix_params_2 = MixParameters.from_json(zksnark, mix_params_json) diff --git a/client/zeth/core/mixer_client.py b/client/zeth/core/mixer_client.py index 0b7cbda5d..2c78d6a4f 100644 --- a/client/zeth/core/mixer_client.py +++ b/client/zeth/core/mixer_client.py @@ -21,7 +21,7 @@ ExtendedProof from zeth.core.utils import EtherValue, digest_to_binary_string, \ int64_to_hex, message_to_bytes, eth_address_to_bytes32, to_zeth_units, \ - get_contracts_dir, hex_list_to_uint256_list + get_contracts_dir from zeth.core.prover_client import ProverConfiguration, ProverClient from zeth.api.zeth_messages_pb2 import ZethNote, JoinsplitInput, ProofInputs @@ -103,10 +103,12 @@ class MixParameters: def __init__( self, extended_proof: ExtendedProof, + public_data: List[int], signature_vk: signing.SigningVerificationKey, signature: signing.Signature, ciphertexts: List[bytes]): self.extended_proof = extended_proof + self.public_data = public_data self.signature_vk = signature_vk self.signature = signature self.ciphertexts = ciphertexts @@ -120,6 +122,7 @@ def to_json(self) -> str: def to_json_dict(self) -> Dict[str, Any]: ext_proof_json = self.extended_proof.to_json_dict() + public_data = [hex(x) for x in self.public_data] signature_vk_json = [ str(x) for x in signing.verification_key_as_mix_parameter(self.signature_vk)] @@ -127,6 +130,7 @@ def to_json_dict(self) -> Dict[str, Any]: ciphertexts_json = [x.hex() for x in self.ciphertexts] return { "extended_proof": ext_proof_json, + "public_data": public_data, "signature_vk": signature_vk_json, "signature": signature_json, "ciphertexts": ciphertexts_json, @@ -138,6 +142,7 @@ def from_json_dict( json_dict: Dict[str, Any]) -> MixParameters: ext_proof = ExtendedProof.from_json_dict( zksnark, json_dict["extended_proof"]) + public_data = [int(x, 16) for x in json_dict["public_data"]] signature_pk_param = [int(x) for x in json_dict["signature_vk"]] signature_pk = signing.verification_key_from_mix_parameter( signature_pk_param) @@ -145,7 +150,7 @@ def from_json_dict( int(json_dict["signature"])) ciphertexts = [bytes.fromhex(x) for x in json_dict["ciphertexts"]] return MixParameters( - ext_proof, signature_pk, signature, ciphertexts) + ext_proof, public_data, signature_pk, signature, ciphertexts) def mix_parameters_to_contract_arguments( @@ -162,7 +167,7 @@ def mix_parameters_to_contract_arguments( proof_contract_params, signing.verification_key_as_mix_parameter(mix_parameters.signature_vk), signing.signature_as_mix_parameter(mix_parameters.signature), - hex_list_to_uint256_list(mix_parameters.extended_proof.inputs), + mix_parameters.public_data, mix_parameters.ciphertexts, ] @@ -177,9 +182,11 @@ def mix_parameters_to_dispatch_parameters(mix_parameters: MixParameters) -> byte vk_param = signing.verification_key_as_mix_parameter( mix_parameters.signature_vk) sigma_param = signing.signature_as_mix_parameter(mix_parameters.signature) + public_data = mix_parameters.public_data + ciphertexts = mix_parameters.ciphertexts return eth_abi.encode_abi( - ['uint256[4]', 'uint256', 'bytes[]'], - [vk_param, sigma_param, mix_parameters.ciphertexts]) # type: ignore + ['uint256[4]', 'uint256', 'uint256[]', 'bytes[]'], + [vk_param, sigma_param, public_data, ciphertexts]) # type: ignore class MixOutputEvents: @@ -511,6 +518,7 @@ def create_mix_parameters_from_proof( prover_inputs: ProofInputs, signing_keypair: signing.SigningKeyPair, ext_proof: ExtendedProof, + public_data: List[int], sender_eth_address: str, for_dispatch_call: bool = False ) -> MixParameters: @@ -542,10 +550,11 @@ def create_mix_parameters_from_proof( sender_eth_address, ciphertexts, ext_proof, + public_data, for_dispatch_call) mix_params = MixParameters( - ext_proof, signing_keypair.vk, signature, ciphertexts) + ext_proof, public_data, signing_keypair.vk, signature, ciphertexts) return mix_params def create_mix_parameters_and_signing_key( @@ -581,7 +590,7 @@ def create_mix_parameters_and_signing_key( mix_call_desc) # Query the prover_server for the related proof - ext_proof = prover_client.get_proof(prover_inputs) + ext_proof, public_data = prover_client.get_proof(prover_inputs) # Create the final MixParameters object mix_params = self.create_mix_parameters_from_proof( @@ -589,6 +598,7 @@ def create_mix_parameters_and_signing_key( prover_inputs, signing_keypair, ext_proof, + public_data, sender_eth_address, for_dispatch_call) @@ -669,6 +679,7 @@ def joinsplit_sign( sender_eth_address: str, ciphertexts: List[bytes], extproof: ExtendedProof, + public_data: List[int], for_dispatch_call: bool = False) -> int: """ Generate a signature on the hash of the ciphertexts, proofs and primary @@ -693,7 +704,7 @@ def joinsplit_sign( h.update(ciphertext) proof_bytes, pub_inputs_bytes = _proof_and_inputs_to_bytes( - zksnark, pp, extproof) + zksnark, pp, extproof, public_data) # If for_dispatch_call is set, omit proof from the signature. See # MixerBase.sol. @@ -788,7 +799,8 @@ def _create_zeth_notes( def _proof_and_inputs_to_bytes( snark: IZKSnarkProvider, pp: PairingParameters, - extproof: ExtendedProof) -> Tuple[bytes, bytes]: + extproof: ExtendedProof, + public_data: List[int]) -> Tuple[bytes, bytes]: """ Given a proof object, compute the byte encodings of the properties excluding "inputs", and the byte encoding of the "inputs". These are used @@ -799,7 +811,7 @@ def _proof_and_inputs_to_bytes( proof = extproof.proof return \ message_to_bytes(snark.proof_to_contract_parameters(proof, pp)), \ - message_to_bytes(hex_list_to_uint256_list(extproof.inputs)) + message_to_bytes(public_data) def _trap_r_randomness() -> str: diff --git a/client/zeth/core/prover_client.py b/client/zeth/core/prover_client.py index a9e387dea..f4cb149df 100644 --- a/client/zeth/core/prover_client.py +++ b/client/zeth/core/prover_client.py @@ -16,7 +16,7 @@ from os import unlink import json from google.protobuf import empty_pb2 -from typing import Dict, Optional, Any +from typing import Dict, List, Tuple, Optional, Any class ProverConfiguration: @@ -113,16 +113,19 @@ def get_verification_key(self) -> IVerificationKey: def get_proof( self, - proof_inputs: ProofInputs) -> ExtendedProof: + proof_inputs: ProofInputs) -> Tuple[ExtendedProof, List[int]]: """ Request a proof generation to the proving service """ with grpc.insecure_channel(self.endpoint) as channel: stub = prover_pb2_grpc.ProverStub(channel) # type: ignore print("-------------- Get the proof --------------") - extproof_proto = stub.Prove(proof_inputs) + extproof_and_pub_data = stub.Prove(proof_inputs) zksnark = self.get_zksnark_provider() - return zksnark.extended_proof_from_proto(extproof_proto) + extproof = zksnark.extended_proof_from_proto( + extproof_and_pub_data.extended_proof) + public_data = [int(x, 16) for x in extproof_and_pub_data.public_data] + return extproof, public_data def _make_empty_message() -> empty_pb2.Empty: diff --git a/libzeth/circuits/circuit_wrapper.hpp b/libzeth/circuits/circuit_wrapper.hpp index 0094c1c39..92ccd790e 100644 --- a/libzeth/circuits/circuit_wrapper.hpp +++ b/libzeth/circuits/circuit_wrapper.hpp @@ -6,6 +6,7 @@ #define __ZETH_CIRCUITS_CIRCUIT_WRAPPER_HPP__ #include "libzeth/circuits/joinsplit.tcc" +#include "libzeth/circuits/mimc/mimc_input_hasher.hpp" #include "libzeth/core/extended_proof.hpp" #include "libzeth/core/note.hpp" #include "libzeth/zeth_constants.hpp" @@ -36,6 +37,7 @@ class circuit_wrapper NumInputs, NumOutputs, TreeDepth>; + using input_hasher_type = mimc_input_hasher; circuit_wrapper(); circuit_wrapper(const circuit_wrapper &) = delete; @@ -56,11 +58,15 @@ class circuit_wrapper const bits64 &vpub_out, const bits256 &h_sig_in, const bits256 &phi_in, - const typename snarkT::proving_key &proving_key) const; + const typename snarkT::proving_key &proving_key, + std::vector &out_public_data) const; private: libsnark::protoboard pb; + libsnark::pb_variable public_data_hash; + libsnark::pb_variable_array public_data; std::shared_ptr joinsplit; + std::shared_ptr input_hasher; }; } // namespace libzeth diff --git a/libzeth/circuits/circuit_wrapper.tcc b/libzeth/circuits/circuit_wrapper.tcc index d30a93c8c..bb1e49c0c 100644 --- a/libzeth/circuits/circuit_wrapper.tcc +++ b/libzeth/circuits/circuit_wrapper.tcc @@ -27,14 +27,33 @@ circuit_wrapper< NumOutputs, TreeDepth>::circuit_wrapper() { + // Allocate a single public variable to hold the hash of the public + // joinsplit inputs. The public joinsplit inputs are then allocated + // immediately following this. + public_data_hash.allocate(pb, "public_data_hash"); + pb.set_input_sizes(1); + // Joinsplit gadget internally allocates its public data first. // TODO: joinsplit_gadget should be refactored to be properly composable. joinsplit = std::make_shared(pb); const size_t num_public_elements = joinsplit->get_num_public_elements(); - pb.set_input_sizes(num_public_elements); + + // Populate public_data to represent the joinsplit public data. Skip + // the first 2 variables (the constant 1, and the digest of the + // public_data), and use the num_public_elements variables that follow. + public_data.reserve(num_public_elements); + for (size_t i = 0; i < num_public_elements; ++i) { + public_data.emplace_back(i + 2); + } + assert(public_data.size() == num_public_elements); + + // Initialize the input hasher gadget + input_hasher = std::make_shared( + pb, public_data, public_data_hash, "input_hasher"); // Generate constraints joinsplit->generate_r1cs_constraints(); + input_hasher->generate_r1cs_constraints(); } template< @@ -103,7 +122,8 @@ extended_proof circuit_wrapper< const bits64 &vpub_out, const bits256 &h_sig_in, const bits256 &phi_in, - const typename snarkT::proving_key &proving_key) const + const typename snarkT::proving_key &proving_key, + std::vector &out_public_data) const { // left hand side and right hand side of the joinsplit bits64 lhs_value = vpub_in; @@ -129,11 +149,21 @@ extended_proof circuit_wrapper< joinsplit->generate_r1cs_witness( root, inputs, outputs, vpub_in, vpub_out, h_sig_in, phi_in); + input_hasher->generate_r1cs_witness(); bool is_valid_witness = pb.is_satisfied(); std::cout << "******* [DEBUG] Satisfiability result: " << is_valid_witness << " *******" << std::endl; + // Fill out the public data vector + const size_t num_public_elements = + joinsplit_type::get_num_public_elements(); + out_public_data.resize(0); + out_public_data.reserve(num_public_elements); + for (size_t i = 0; i < num_public_elements; ++i) { + out_public_data.push_back(pb.val(public_data[i])); + } + // Instantiate an extended_proof from the proof we generated and the given // primary_input return extended_proof( diff --git a/libzeth/circuits/mimc/mimc.tcc b/libzeth/circuits/mimc/mimc.tcc index ce18bad95..3e9bbe4f9 100644 --- a/libzeth/circuits/mimc/mimc.tcc +++ b/libzeth/circuits/mimc/mimc.tcc @@ -79,7 +79,7 @@ void MiMC_permutation_gadget:: generate_r1cs_constraints() { // For each round, generates the constraints for the corresponding round - // gadget + // gadget. for (auto &gadget : round_gadgets) { gadget.generate_r1cs_constraints(); } @@ -89,7 +89,8 @@ template void MiMC_permutation_gadget:: generate_r1cs_witness() const { - // For each round, generates the witness for the corresponding round gadget + // For each round, generates the witness for the corresponding round + // gadget. for (auto &gadget : round_gadgets) { gadget.generate_r1cs_witness(); } diff --git a/libzeth/tests/prover/prover_test.cpp b/libzeth/tests/prover/prover_test.cpp index 87aae2dbd..4532b7190 100644 --- a/libzeth/tests/prover/prover_test.cpp +++ b/libzeth/tests/prover/prover_test.cpp @@ -5,6 +5,7 @@ #include "libzeth/circuits/blake2s/blake2s.hpp" #include "libzeth/circuits/circuit_types.hpp" #include "libzeth/circuits/circuit_wrapper.hpp" +#include "libzeth/core/field_element_utils.hpp" #include "libzeth/core/utils.hpp" #include "libzeth/snarks/groth16/groth16_snark.hpp" #include "libzeth/snarks/pghr13/pghr13_snark.hpp" @@ -35,6 +36,9 @@ using prover = circuit_wrapper< 2, TreeDepth>; +template +using input_hasher_type = typename prover::input_hasher_type; + namespace { @@ -42,7 +46,7 @@ const bits256 zero_bits256 = bits256::from_hex( "0000000000000000000000000000000000000000000000000000000000000000"); template -bool TestValidJS2In2Case1( +void TestValidJS2In2Case1( const prover &prover, const typename snarkT::keypair &keypair) { // --- General setup for the tests --- // @@ -140,6 +144,7 @@ bool TestValidJS2In2Case1( libff::leave_block("Create JSOutput/zeth_note", true); libff::enter_block("Generate proof", true); + std::vector public_data; extended_proof ext_proof = prover.prove( updated_root_value, inputs, @@ -148,25 +153,33 @@ bool TestValidJS2In2Case1( value_pub_out_bits64, h_sig, phi, - keypair.pk); + keypair.pk, + public_data); libff::leave_block("Generate proof", true); + std::vector primary_inputs = ext_proof.get_primary_inputs(); + ASSERT_EQ(1, primary_inputs.size()); + ASSERT_NE(Field::zero(), primary_inputs[0]); + + // Check the hashed public data + ASSERT_GT(public_data.size(), 1); + ASSERT_EQ( + input_hasher_type::compute_hash(public_data), + primary_inputs[0]); libff::enter_block("Verify proof", true); // Get the verification key typename snarkT::verification_key vk = keypair.vk; - bool res = snarkT::verify( - ext_proof.get_primary_inputs(), ext_proof.get_proof(), vk); + bool res = snarkT::verify(primary_inputs, ext_proof.get_proof(), vk); std::cout << "Does the proof verify? " << res << std::endl; libff::leave_block("Verify proof", true); std::cout << "[DEBUG] Displaying the extended proof" << std::endl; ext_proof.write_json(std::cout); - - return res; + ASSERT_TRUE(res); } template -bool TestValidJS2In2Case2( +void TestValidJS2In2Case2( const prover &prover, const typename snarkT::keypair &keypair) { libff::print_header( @@ -261,6 +274,7 @@ bool TestValidJS2In2Case2( libff::enter_block("Generate proof", true); // RHS = 0x1A00000000000002 + 0x1500000000000002 + 0x000000000000000B = // 2F0000000000000F (LHS) + std::vector public_data; extended_proof ext_proof = prover.prove( updated_root_value, inputs, @@ -271,9 +285,15 @@ bool TestValidJS2In2Case2( bits64::from_hex("000000000000000B"), h_sig, phi, - keypair.pk); + keypair.pk, + public_data); libff::leave_block("Generate proof", true); + // Check the hashed public data + ASSERT_EQ( + ext_proof.get_primary_inputs()[0], + input_hasher_type::compute_hash(public_data)); + libff::enter_block("Verify proof", true); // Get the verification key typename snarkT::verification_key vk = keypair.vk; @@ -285,11 +305,11 @@ bool TestValidJS2In2Case2( std::cout << "[DEBUG] Displaying the extended proof" << std::endl; ext_proof.write_json(std::cout); - return res; + ASSERT_TRUE(res); } template -bool TestValidJS2In2Case3( +void TestValidJS2In2Case3( const prover &prover, const typename snarkT::keypair &keypair) { // --- General setup for the tests --- // @@ -386,6 +406,7 @@ bool TestValidJS2In2Case3( libff::enter_block("Generate proof", true); // (RHS) 0x1A00000000000012 + 0x1500000000000002 + 0x000000000000000B = // 2F0000000000000F + 0x0000000000000010 + 0x0 (LHS) + std::vector public_data; extended_proof ext_proof = prover.prove( updated_root_value, inputs, @@ -394,9 +415,15 @@ bool TestValidJS2In2Case3( bits64::from_hex("000000000000000B"), // v_pub_out = 0x000000000000000B h_sig, phi, - keypair.pk); + keypair.pk, + public_data); libff::leave_block("Generate proof", true); + // Check the hashed public data + ASSERT_EQ( + ext_proof.get_primary_inputs()[0], + input_hasher_type::compute_hash(public_data)); + libff::enter_block("Verify proof", true); // Get the verification key typename snarkT::verification_key vk = keypair.vk; @@ -408,11 +435,11 @@ bool TestValidJS2In2Case3( std::cout << "[DEBUG] Displaying the extended proof" << std::endl; ext_proof.write_json(std::cout); - return res; + ASSERT_TRUE(res); } template -bool TestValidJS2In2Deposit( +void TestValidJS2In2Deposit( const prover &prover, const typename snarkT::keypair &keypair) { // --- General setup for the tests --- // @@ -511,6 +538,7 @@ bool TestValidJS2In2Deposit( libff::enter_block("Generate proof", true); // RHS = 0x0 + 0x3782DACE9D900000 + 0x29A2241AF62C0000 = 0x6124FEE993BC0000 // (LHS) + std::vector public_data; extended_proof ext_proof = prover.prove( updated_root_value, inputs, @@ -521,9 +549,15 @@ bool TestValidJS2In2Deposit( bits64::from_hex("0000000000000000"), h_sig, phi, - keypair.pk); + keypair.pk, + public_data); libff::leave_block("Generate proof", true); + // Check the hashed public data + ASSERT_EQ( + ext_proof.get_primary_inputs()[0], + input_hasher_type::compute_hash(public_data)); + libff::enter_block("Verify proof", true); // Get the verification key typename snarkT::verification_key vk = keypair.vk; @@ -536,11 +570,11 @@ bool TestValidJS2In2Deposit( std::cout << "Does the proof verify? " << res << std::endl; libff::leave_block("Verify proof", true); - return res; + ASSERT_TRUE(res); } template -bool TestInvalidJS2In2( +void TestInvalidJS2In2( const prover &prover, const typename snarkT::keypair &keypair) { // --- General setup for the tests --- // @@ -644,6 +678,7 @@ bool TestInvalidJS2In2( // 0x8530000A00000001 (9.597170848876199937 ETH) + 0x7550000A00000000 // (8.453256543524093952 ETH) = RHS LHS = 18.050427392400293888 ETH RHS // = 18.050427392400293889 ETH (1 wei higher than LHS) + std::vector public_data; extended_proof ext_proof = prover.prove( updated_root_value, inputs, @@ -654,7 +689,8 @@ bool TestInvalidJS2In2( bits64::from_hex("0000000000000000"), h_sig, phi, - keypair.pk); + keypair.pk, + public_data); libff::leave_block("Generate proof", true); libff::enter_block("Verify proof", true); @@ -668,7 +704,7 @@ bool TestInvalidJS2In2( std::cout << "[DEBUG] Displaying the extended proof" << std::endl; ext_proof.write_json(std::cout); - return res; + ASSERT_FALSE(res); } template static void run_prover_tests() @@ -678,29 +714,23 @@ template static void run_prover_tests() prover proverJS2to2; typename snarkT::keypair keypair = proverJS2to2.generate_trusted_setup(); - bool res = false; - res = TestValidJS2In2Case1(proverJS2to2, keypair); - ASSERT_TRUE(res); + TestValidJS2In2Case1(proverJS2to2, keypair); - res = TestValidJS2In2Case2(proverJS2to2, keypair); - ASSERT_TRUE(res); + TestValidJS2In2Case2(proverJS2to2, keypair); - res = TestValidJS2In2Case3(proverJS2to2, keypair); - ASSERT_TRUE(res); + TestValidJS2In2Case3(proverJS2to2, keypair); - res = TestValidJS2In2Deposit(proverJS2to2, keypair); - ASSERT_TRUE(res); + TestValidJS2In2Deposit(proverJS2to2, keypair); // The following is expected to throw an exception because LHS =/= RHS. // Ensure that the exception is thrown. ASSERT_THROW( - (res = TestInvalidJS2In2(proverJS2to2, keypair)), - std::invalid_argument); + (TestInvalidJS2In2(proverJS2to2, keypair)), std::invalid_argument); + bool res = false; try { - res = false; - res = TestInvalidJS2In2(proverJS2to2, keypair); + TestInvalidJS2In2(proverJS2to2, keypair); res = true; } catch (const std::invalid_argument &e) { std::cerr << "Invalid argument exception: " << e.what() << '\n'; diff --git a/proto/zeth/api/prover.proto b/proto/zeth/api/prover.proto index a614ba0eb..025ce9504 100644 --- a/proto/zeth/api/prover.proto +++ b/proto/zeth/api/prover.proto @@ -27,5 +27,5 @@ service Prover { rpc GetVerificationKey(google.protobuf.Empty) returns (VerificationKey) {} // Request a proof generation on the given inputs - rpc Prove(ProofInputs) returns (ExtendedProof) {} + rpc Prove(ProofInputs) returns (ExtendedProofAndPublicData) {} } diff --git a/proto/zeth/api/zeth_messages.proto b/proto/zeth/api/zeth_messages.proto index 0edd4248c..122c997ef 100644 --- a/proto/zeth/api/zeth_messages.proto +++ b/proto/zeth/api/zeth_messages.proto @@ -2,6 +2,8 @@ syntax = "proto3"; package zeth_proto; +import "zeth/api/snark_messages.proto"; + message ZethNote { string apk = 1; // Hex string representing a int64 value @@ -34,3 +36,14 @@ message ProofInputs { string h_sig = 6; string phi = 7; } + +// The extended proof and related public data for the Zeth statement using ProofInputs data +message ExtendedProofAndPublicData { + // The extended proof (with single public input - the hash of public_data). + ExtendedProof extended_proof = 1; + + // The public data (public inputs to the Zeth statement). Each element in + // the array is a hex-encoded member of the scalar field for the pairing + // being used. + repeated string public_data = 2; +} diff --git a/prover_server/prover_server.cpp b/prover_server/prover_server.cpp index 8e9fda11c..ed1d8fce8 100644 --- a/prover_server/prover_server.cpp +++ b/prover_server/prover_server.cpp @@ -141,7 +141,7 @@ class prover_server final : public zeth_proto::Prover::Service grpc::Status Prove( grpc::ServerContext *, const zeth_proto::ProofInputs *proof_inputs, - zeth_proto::ExtendedProof *proof) override + zeth_proto::ExtendedProofAndPublicData *proof_and_public_data) override { std::cout << "[ACK] Received the request to generate a proof" << std::endl; @@ -150,6 +150,8 @@ class prover_server final : public zeth_proto::Prover::Service // Parse received message to feed to the prover try { + // TODO: Factor this into more maintainable smaller functions + Field root = libzeth::base_field_element_from_hex( proof_inputs->mk_root()); libzeth::bits64 vpub_in = @@ -204,6 +206,8 @@ class prover_server final : public zeth_proto::Prover::Service std::cout << "[DEBUG] Data parsed successfully" << std::endl; std::cout << "[DEBUG] Generating the proof..." << std::endl; + + std::vector public_data; libzeth::extended_proof ext_proof = this->prover.prove( root, joinsplit_inputs, @@ -212,10 +216,14 @@ class prover_server final : public zeth_proto::Prover::Service vpub_out, h_sig_in, phi_in, - this->keypair.pk); + this->keypair.pk, + public_data); - std::cout << "[DEBUG] Displaying the extended proof" << std::endl; + std::cout << "[DEBUG] Displaying extended proof and public data\n"; ext_proof.write_json(std::cout); + for (const Field &f : public_data) { + std::cout << libzeth::base_field_element_to_hex(f) << "\n"; + } // Write a copy of the proof for debugging. if (!proof_output_file.empty()) { @@ -225,7 +233,12 @@ class prover_server final : public zeth_proto::Prover::Service } std::cout << "[DEBUG] Preparing response..." << std::endl; - api_handler::extended_proof_to_proto(ext_proof, proof); + api_handler::extended_proof_to_proto( + ext_proof, proof_and_public_data->mutable_extended_proof()); + for (size_t i = 0; i < public_data.size(); ++i) { + proof_and_public_data->add_public_data( + libzeth::base_field_element_to_hex(public_data[i])); + } } catch (const std::exception &e) { std::cout << "[ERROR] " << e.what() << std::endl; @@ -370,7 +383,7 @@ int main(int argc, char **argv) } // Inititalize the curve parameters - std::cout << "[INFO] Init params" << std::endl; + std::cout << "[INFO] Init params (" << libzeth::pp_name() << ")\n"; pp::init_public_params(); // If the keypair file exists, load and use it, otherwise generate a new diff --git a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol b/zeth_contracts/contracts/Groth16AltBN128Mixer.sol index bd2fe6ccf..47fbab34a 100644 --- a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Groth16AltBN128Mixer.sol @@ -26,21 +26,15 @@ contract Groth16AltBN128Mixer is AltBN128MixerBase function verify_zk_proof( uint256[] memory proof, - uint256[NUM_INPUTS] memory inputs + uint256 public_inputs_hash ) internal returns (bool) { - // Convert the statically sized primaryInputs to a dynamic array + // Convert the single primary input to a dynamic array // expected by the verifier. - - // TODO: mechanism to pass static-sized input arrays to generic - // verifier functions to avoid this copy. - - uint256[] memory input_values = new uint256[](NUM_INPUTS); - for (uint256 i = 0 ; i < NUM_INPUTS; i++) { - input_values[i] = inputs[i]; - } + uint256[] memory input_values = new uint256[](1); + input_values[0] = public_inputs_hash; return Groth16AltBN128.verify(_vk, proof, input_values); } } diff --git a/zeth_contracts/contracts/AltBN128MixerBase_test.sol b/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol similarity index 77% rename from zeth_contracts/contracts/AltBN128MixerBase_test.sol rename to zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol index 7757413e8..12359c170 100644 --- a/zeth_contracts/contracts/AltBN128MixerBase_test.sol +++ b/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol @@ -5,12 +5,12 @@ pragma solidity ^0.5.0; pragma experimental ABIEncoderV2; -import "./AltBN128MixerBase.sol"; +import "./Groth16AltBN128Mixer.sol"; -// Implementation of abstract AltBN128MixerBase contract, to allow testing +// Implementation of Groth16AltBN128MixerBase contract, to allow testing // specific methods. -contract AltBN128MixerBase_test is AltBN128MixerBase +contract Groth16AltBN128MixerBase_test is Groth16AltBN128Mixer { constructor( uint256 mk_depth, @@ -18,7 +18,7 @@ contract AltBN128MixerBase_test is AltBN128MixerBase uint256 vk_hash ) public - AltBN128MixerBase( + Groth16AltBN128Mixer( mk_depth, address(0), new uint256[](0), @@ -27,6 +27,15 @@ contract AltBN128MixerBase_test is AltBN128MixerBase { } + function hash_public_proof_data_test( + uint256[NUM_INPUTS] memory public_data + ) + public + returns (uint256) + { + return hash_public_proof_data(public_data); + } + function assemble_public_values_test(uint256 residual_bits) public pure diff --git a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol b/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol index 0aa2c3ed4..6147b5cd7 100644 --- a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol +++ b/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol @@ -26,21 +26,15 @@ contract Groth16BLS12_377Mixer is BLS12_377MixerBase function verify_zk_proof( uint256[] memory proof, - uint256[NUM_INPUTS] memory inputs + uint256 public_inputs_hash ) internal returns (bool) { - // Convert the statically sized inputs to a dynamic array - // expected by the verifyer. - - // TODO: mechanism to pass static-sized input arrays to generic - // verifier functions to avoid this copy. - - uint256[] memory input_values = new uint256[](NUM_INPUTS); - for (uint256 i = 0 ; i < NUM_INPUTS; i++) { - input_values[i] = inputs[i]; - } + // Convert the single primary input to a dynamic array + // expected by the verifier. + uint256[] memory input_values = new uint256[](1); + input_values[0] = public_inputs_hash; return Groth16BLS12_377.verify(_vk, proof, input_values); } } diff --git a/zeth_contracts/contracts/MixerBase.sol b/zeth_contracts/contracts/MixerBase.sol index ab3970706..30ca57f29 100644 --- a/zeth_contracts/contracts/MixerBase.sol +++ b/zeth_contracts/contracts/MixerBase.sol @@ -148,14 +148,22 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract require( msg.sender == _permitted_dispatcher, "dispatcher not permitted"); require(nested_vk_hash == _vk_hash, "invalid nested_vk_hash"); - require(nested_inputs.length == NUM_INPUTS); + require(nested_inputs.length == 1, "invalid num nested inputs"); // Decode the nested parameters // TODO: convert ciphertext array without copying (uint256[4] memory vk, uint256 sigma, + uint256[] memory public_data, bytes[] memory decoded_ciphertexts) = abi.decode( - nested_parameters, (uint256[4], uint256, bytes[])); + nested_parameters, (uint256[4], uint256, uint256[], bytes[])); + require( + public_data.length == NUM_INPUTS, + "invalid number of public inputs in decoded data."); + require( + decoded_ciphertexts.length == JSOUT, + "invalid number of ciphertexts in decoded data."); + bytes[JSOUT] memory ciphertexts; for (uint256 i = 0 ; i < JSOUT ; ++i) { ciphertexts[i] = decoded_ciphertexts[i]; @@ -165,9 +173,15 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // TODO: convert without copying. uint256[NUM_INPUTS] memory inputs; for (uint256 i = 0 ; i < NUM_INPUTS ; ++i) { - inputs[i] = nested_inputs[i]; + inputs[i] = public_data[i]; } + // Ensure that the primary input to the zk-proof (validated and passed + // in by the dispatcher), matches the hash of the public inputs. + require( + nested_inputs[0] == hash_public_proof_data(inputs), + "hash of public data does not match primary input"); + // 1. Check the root and the nullifiers bytes32[JSIN] memory nullifiers; check_mkroot_nullifiers_hsig_append_nullifiers_state( @@ -203,7 +217,7 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract uint256[] memory proof, uint256[4] memory vk, uint256 sigma, - uint256[NUM_INPUTS] memory inputs, + uint256[NUM_INPUTS] memory public_inputs, bytes[JSOUT] memory ciphertexts ) public @@ -212,7 +226,7 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // 1. Check the root and the nullifiers bytes32[JSIN] memory nullifiers; check_mkroot_nullifiers_hsig_append_nullifiers_state( - vk, inputs, nullifiers); + vk, public_inputs, nullifiers); // 2.a Verify the signature on the hash of data_to_be_signed bytes32 hash_to_be_signed = sha256( @@ -224,7 +238,7 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract ciphertexts[0], ciphertexts[1], proof, - inputs + public_inputs ) ); require( @@ -234,13 +248,14 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract ); // 2.b Verify the proof + uint256 public_inputs_hash = hash_public_proof_data(public_inputs); require( - verify_zk_proof(proof, inputs), + verify_zk_proof(proof, public_inputs_hash), "Invalid proof: Unable to verify the proof correctly" ); mix_append_commitments_emit_and_handle_public_values( - inputs, ciphertexts, nullifiers); + public_inputs, ciphertexts, nullifiers); } function mix_append_commitments_emit_and_handle_public_values( @@ -271,6 +286,23 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract process_public_values(inputs); } + function hash_public_proof_data(uint256[NUM_INPUTS] memory public_data) + internal + returns (uint256) + { + // Initialize h with the IV and hash each public data value (see + // client/zeth/core/input_hasher.py for details) + bytes32 h; + h = bytes32(uint256( + // solhint-disable-next-line max-line-length + 13196537064117388418196223856311987714388543839552400408340921397545324034315)); + for (uint256 i = 0 ; i < NUM_INPUTS; ++i) { + h = hash(h, bytes32(public_data[i])); + } + h = hash(h, bytes32(NUM_INPUTS)); + return uint256(h); + } + /// This function is used to extract the public values (vpub_in, vpub_out) /// from the residual field element(S) function assemble_public_values(uint256 residual_bits) @@ -376,7 +408,7 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // selected SNARK. function verify_zk_proof( uint256[] memory proof, - uint256[NUM_INPUTS] memory inputs + uint256 public_inputs_hash ) internal returns (bool); diff --git a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol index 750a8c6ed..833568207 100644 --- a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol @@ -47,7 +47,7 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase } function verify( - uint256[NUM_INPUTS] memory input, + uint256[] memory inputs, Proof memory proof ) internal @@ -75,7 +75,7 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase // |I_{in}| == input.length, and vk.IC also contains A_0(s). Thus // ||vk.IC| == input.length + 1 require( - input.length + 1 == vk.IC.length, + inputs.length + 1 == vk.IC.length, "Using strong input consistency, and the input length differs from" " expected" ); @@ -90,8 +90,8 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase // |I_{in}| = n here as we assume that we have a vector x of inputs of // size n. Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0); - for (uint256 i = 0; i < input.length; i++) { - vk_x = Pairing.add(vk_x, Pairing.mul(vk.IC[i + 1], input[i])); + for (uint256 i = 0; i < inputs.length; i++) { + vk_x = Pairing.add(vk_x, Pairing.mul(vk.IC[i + 1], inputs[i])); } vk_x = Pairing.add(vk_x, vk.IC[0]); @@ -150,7 +150,7 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase function verify_zk_proof( uint256[] memory proof_data, - uint256[NUM_INPUTS] memory inputs + uint256 public_inputs_hash ) internal returns (bool) @@ -171,14 +171,13 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase proof.H = Pairing.G1Point(proof_data[14], proof_data[15]); proof.K = Pairing.G1Point(proof_data[16], proof_data[17]); - for(uint256 i = 0; i < inputs.length; i++){ - // Make sure that all primary inputs lie in the scalar field - require( - inputs[i] < r, - "Input is not is scalar field" - ); - } + require( + public_inputs_hash < r, + "Input is not is scalar field" + ); + uint256[] memory inputs = new uint256[](1); + inputs[0] = public_inputs_hash; uint256 verification_result = verify(inputs, proof); if (verification_result != 0) { return false; From b6d9784bcca100b08c249354c2f3723808dcaf5c Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 28 Jan 2021 11:51:27 +0000 Subject: [PATCH 043/137] scripts: extend mimc_constraints script to BW6-761 and MNT4/6 --- scripts/mimc_constraints.sage | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/scripts/mimc_constraints.sage b/scripts/mimc_constraints.sage index af5f8c8dc..8e3702af7 100644 --- a/scripts/mimc_constraints.sage +++ b/scripts/mimc_constraints.sage @@ -52,6 +52,8 @@ def output_valid_configs_and_constraints(r): for t in range(2, 22): e = (1 << t) - 1 output_valid_config_and_constraints(r, log_2_r, e) + e = (1 << t) + 1 + output_valid_config_and_constraints(r, log_2_r, e) # TODO: determine if these value are valid # output_valid_config_and_constraints(r, log_2_r, 11) @@ -61,6 +63,21 @@ def output_valid_configs_and_constraints(r): # output_valid_config_and_constraints(r, log_2_r, 23) +# BW6-761 +print("BW6-761:") +output_valid_configs_and_constraints( + r=258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177) + +# MNT4 +print("MNT4:") +output_valid_configs_and_constraints( + r=475922286169261325753349249653048451545124878552823515553267735739164647307408490559963137) + +# MNT6 +print("MNT6:") +output_valid_configs_and_constraints( + r=475922286169261325753349249653048451545124879242694725395555128576210262817955800483758081) + # BLS12-377 print("BLS12-377:") output_valid_configs_and_constraints( From adc91fc879782f70a3580bddc273fbc5b38007d7 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 28 Jan 2021 15:08:59 +0000 Subject: [PATCH 044/137] submodule: update libsnark [compile-warnings] --- depends/libsnark | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/libsnark b/depends/libsnark index fa306c6fc..d23fa10bb 160000 --- a/depends/libsnark +++ b/depends/libsnark @@ -1 +1 @@ -Subproject commit fa306c6fc981c5459adcb368f3e42cb0122681fb +Subproject commit d23fa10bb0c30295161b010a58df52edcd5c29b3 From daba226a5aab81fd7a783dbe80680bfe865a8c4e Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Fri, 29 Jan 2021 15:41:18 +0000 Subject: [PATCH 045/137] Set hex prefix flag to true and removed manual prefix --- libzeth/serialization/r1cs_serialization.tcc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libzeth/serialization/r1cs_serialization.tcc b/libzeth/serialization/r1cs_serialization.tcc index d6c575b02..38636f50c 100644 --- a/libzeth/serialization/r1cs_serialization.tcc +++ b/libzeth/serialization/r1cs_serialization.tcc @@ -30,7 +30,8 @@ void constraints_write_json( out_s << "{"; out_s << "\"index\":" << lt.index << ","; out_s << "\"value\":" - << "\"0x" + bigint_to_hex>(lt.coeff.as_bigint()) + << "\"" + + bigint_to_hex>(lt.coeff.as_bigint(), true) << "\""; out_s << "}"; count++; @@ -153,8 +154,8 @@ std::ostream &r1cs_write_json( out_s << "{\n"; out_s << "\"scalar_field_characteristic\":" - << "\"0x" + - bigint_to_hex>(libff::Fr::field_char()) + << "\"" + bigint_to_hex>( + libff::Fr::field_char(), true) << "\",\n"; out_s << "\"num_variables\":" << pb.num_variables() << ",\n"; out_s << "\"num_constraints\":" << pb.num_constraints() << ",\n"; From d33abf8d50c9cc4b7654f77f65d52bb43f6b1985 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 20 Jan 2021 14:36:23 +0000 Subject: [PATCH 046/137] scripts: use longer key for mpc server in tests (fixes sll error) --- scripts/test_mpc_common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/test_mpc_common.sh b/scripts/test_mpc_common.sh index 4f66f6d49..498d432e1 100644 --- a/scripts/test_mpc_common.sh +++ b/scripts/test_mpc_common.sh @@ -64,7 +64,7 @@ function prepare_server_common() { # TLS server certs if ! [ -e ${SERVER_KEY} ] || ! [ -e ${SERVER_CERT} ] ; then echo TLS certificate ... - KEY_BITS=1024 + KEY_BITS=4096 cp /etc/ssl/openssl.cnf openssl.tmp.cnf echo "[v3_req]" >> openssl.tmp.cnf echo "subjectAltName=DNS:localhost" >> openssl.tmp.cnf From c843074ec692f397d4e97f9c795b44eb77672ebe Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 20 Jan 2021 14:37:04 +0000 Subject: [PATCH 047/137] scripts: timeout waiting for mpc server --- scripts/test_mpc_common.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/test_mpc_common.sh b/scripts/test_mpc_common.sh index 498d432e1..686869723 100644 --- a/scripts/test_mpc_common.sh +++ b/scripts/test_mpc_common.sh @@ -93,9 +93,19 @@ function start_server_common() { $2 > server.stdout & echo $! > server.pid + x=1 while ! $3 ; do + if [ $x == 10 ] ; then + echo "FAILED TO LAUNCH" + exit 1 + fi + echo "TEST: waiting for server to start ..." sleep 1 + + x=$(( $x + 1 )) + echo "TEST: retrying ($x)" + done echo "TEST: server up (pid: "`cat server.pid`")" popd From acad712f1791b500981e41618848c883da66e549 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 20 Jan 2021 14:37:45 +0000 Subject: [PATCH 048/137] ci: add dependencies for building on ubuntu --- scripts/ci | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/scripts/ci b/scripts/ci index e64d0bacd..9143db255 100755 --- a/scripts/ci +++ b/scripts/ci @@ -60,6 +60,26 @@ function _stop_ganache() { popd } +function _build_setup() { + # Extra deps for native builds + if [ "${platform}" == "Linux" ] ; then + if (which apk) ; then + # Packages already available in Docker build + echo -n # null op required for syntax + else + sudo apt install \ + libboost-dev \ + libboost-system-dev \ + libboost-filesystem-dev \ + libboost-program-options-dev \ + libgmp-dev \ + libprocps-dev \ + libxslt1-dev \ + pkg-config + fi + fi +} + function check_format() { scripts/format git diff --no-ext-diff | head -n 20 > format_errors @@ -150,6 +170,9 @@ function mpc_tests() { } function build() { + + _build_setup + # Additional compilation flags cxx_flags="-Werror" From 738732c096e0bf7624ece561b4291c210c47d7ff Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 20 Jan 2021 14:39:03 +0000 Subject: [PATCH 049/137] prover_server: clean up some grpc dependency handling --- prover_server/CMakeLists.txt | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/prover_server/CMakeLists.txt b/prover_server/CMakeLists.txt index 548ccbd83..e0304b04d 100644 --- a/prover_server/CMakeLists.txt +++ b/prover_server/CMakeLists.txt @@ -44,30 +44,20 @@ add_executable( ${PROVER_SERVER_SOURCE} ${GRPC_SRCS} ) -if ("${STATIC_BUILD}") + +if (NOT APPLE) find_package(PkgConfig REQUIRED) pkg_check_modules(GRPC REQUIRED IMPORTED_TARGET grpc++) +endif() - target_link_libraries( - prover_server - - zeth - ${Boost_SYSTEM_LIBRARY} - ${Boost_FILESYSTEM_LIBRARY} - ${Boost_PROGRAM_OPTIONS_LIBRARY} - ${GRPC_LIBRARIES} - gRPC::grpc++_reflection - protobuf::libprotobuf - ) -else() - target_link_libraries( - prover_server +target_link_libraries( + prover_server - zeth - ${Boost_SYSTEM_LIBRARY} - ${Boost_FILESYSTEM_LIBRARY} - ${Boost_PROGRAM_OPTIONS_LIBRARY} - gRPC::grpc++_reflection - protobuf::libprotobuf + zeth + ${Boost_SYSTEM_LIBRARY} + ${Boost_FILESYSTEM_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ${GRPC_LIBRARIES} + gRPC::grpc++_reflection + protobuf::libprotobuf ) -endif() From 588bbf29b364def31db4796ce95c94c18b0a2267 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 20 Jan 2021 14:41:30 +0000 Subject: [PATCH 050/137] ci: cache submodule builds on mac, keyed by commit --- .github/workflows/onpush-build-macos.yml | 30 ++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/.github/workflows/onpush-build-macos.yml b/.github/workflows/onpush-build-macos.yml index 00ebae38c..3c4528944 100644 --- a/.github/workflows/onpush-build-macos.yml +++ b/.github/workflows/onpush-build-macos.yml @@ -9,17 +9,43 @@ env: jobs: + # Extract the commits of submodules for use by cache steps + submodules: + runs-on: ubuntu-20.04 + outputs: + libsodium: ${{ steps.get-commits.outputs.libsodium }} + libsnark: ${{ steps.get-commits.outputs.libsnark }} + steps: + - uses: actions/checkout@v2 + - name: Get Submodule Commits + id: get-commits + run: | + git submodule sync + echo "::set-output name=libsodium::"`git submodule status depends/libsodium | grep -oe '[0-9a-fA-F]\+' | head -c 8` + echo "::set-output name=libsnark::"`git submodule status depends/libsnark | grep -oe '[0-9a-fA-F]\+' | head -c 8` + + # Main build build-macos: runs-on: macos-10.15 + needs: submodules strategy: matrix: config: [ Debug, Release ] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 with: submodules: recursive + - name: Cache libsodium + uses: actions/cache@v1 + with: + key: libsodium-${{ needs.submodules.outputs.libsodium }}-${{ runner.os }}-${{ matrix.config }} + path: build/depends/libsodium-prefix + - name: Cache libsnark + uses: actions/cache@v1 + with: + key: libsnark-${{ needs.submodules.outputs.libsnark }}-${{ runner.os }}-${{ matrix.config }} + path: build/depends/libsnark - name: Install Dependencies run: brew install ${MACOS_BREW_PACKAGES} - name: Execute run: CI_CONFIG=${{ matrix.config }} scripts/ci build - From 2c866c1246022fa16927450f366e8803c31088b2 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 20 Jan 2021 14:54:53 +0000 Subject: [PATCH 051/137] ci: excute part of linux build on ci host, caching grpc build --- .github/workflows/onpush-build-ubuntu.yml | 30 ++++++++- scripts/install_grpc | 76 +++++++++++++++++++++++ 2 files changed, 104 insertions(+), 2 deletions(-) create mode 100755 scripts/install_grpc diff --git a/.github/workflows/onpush-build-ubuntu.yml b/.github/workflows/onpush-build-ubuntu.yml index 830443563..084a536d5 100644 --- a/.github/workflows/onpush-build-ubuntu.yml +++ b/.github/workflows/onpush-build-ubuntu.yml @@ -6,17 +6,43 @@ on: jobs: + # Job to build the grpc libraries. The grpc build directory is populated and + # cached so that all other jobs can mark this job as a prerequisite and just + # run `make install`. + # + # NOTE: the version number here (in `key` and in script arguments) must be + # kept in sync with the key used by the jobs. + build-grpc: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Cache grpc + uses: actions/cache@v2 + with: + key: grpc-1.31.x-${{ runner.os }}-test + path: depends/grpc + - name: Build grpc + run: if ! [ -d depends/grpc ] ; then scripts/install_grpc /usr v1.31.x depends/grpc ; fi + build-linux: runs-on: ubuntu-20.04 + needs: build-grpc strategy: matrix: config: [ Debug, Release ] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 with: submodules: recursive + - name: Cache grpc + uses: actions/cache@v1 + with: + key: grpc-1.31.x-${{ runner.os }}-test + path: depends/grpc + - name: Install grpc + run: scripts/install_grpc /usr v1.31.x depends/grpc - name: Execute - run: CI_CHECK_FORMAT=1 CI_USE_DOCKER=1 CI_CONFIG=${{ matrix.config }} scripts/ci build + run: CI_CHECK_FORMAT=1 CI_CONFIG=${{ matrix.config }} scripts/ci build build-linux-pghr13: runs-on: ubuntu-20.04 diff --git a/scripts/install_grpc b/scripts/install_grpc new file mode 100755 index 000000000..085ba1e75 --- /dev/null +++ b/scripts/install_grpc @@ -0,0 +1,76 @@ +#!/usr/bin/env bash + +# This script is only intended to run on the CI machines. Not for local +# development. + +if [ "" == "$1" ] || [ "" == "$2" ] || [ "" == "$3" ] ; then + echo "error: invalid arguments" + echo "Usage: $0 " + echo "" + exit 1 +fi + +set -e +set -x + +INSTALL_DIR=$1 +VERSION=$2 +BUILD_DIR=$3 + +# This script executes in one of 2 modes on the CI: +# +# - No pre-existing build directory (DO_BUILD=1). +# +# - Pre-existing build directory, cached a previous successful build +# (DO_BUILD=0). In this case, installation can be performed directly. + +if [ -d "${BUILD_DIR}" ] ; then + DO_BUILD=0 +else + DO_BUILD=1 +fi + +mkdir -p ${BUILD_DIR} +pushd ${BUILD_DIR} + + # Clone repo and submodules (if DO_BUILD == 1) + if [ "1" == "${DO_BUILD}" ] ; then + git clone --depth 1 -b ${VERSION} https://github.com/grpc/grpc . + git submodule update --depth 1 --init --recursive + fi + + # Install protobuf + pushd third_party/protobuf + if [ "1" == "${DO_BUILD}" ] ; then + [ -e ./configure ] || ./autogen.sh + DIST_LANG=cpp ./configure --prefix ${INSTALL_DIR} + make -j $(($(nproc)+1)) + fi + sudo make install + popd # third_party/protobuf + + # Install grpc + mkdir -p build + pushd build + if [ "1" == "${DO_BUILD}" ] ; then + cmake \ + -DCMAKE_PREFIX_PATH=${INSTALL_DIR} \ + -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \ + -DCMAKE_BUILD_TYPE=Release \ + -DgRPC_INSTALL=ON \ + -DgRPC_BUILD_TESTS=OFF \ + -DBUILD_TESTING=OFF \ + -DgRPC_SSL_PROVIDER=package \ + -DgRPC_PROTOBUF_PROVIDER=package \ + -DgRPC_BUILD_GRPC_CSHARP_PLUGIN=OFF \ + -DgRPC_BUILD_GRPC_NODE_PLUGIN=OFF \ + -DgRPC_BUILD_GRPC_OBJECTIVE_C_PLUGIN=OFF \ + -DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF \ + -DgRPC_BUILD_GRPC_RUBY_PLUGIN=OFF \ + .. + make -j"$(($(nproc)+1))" + fi + sudo make install + popd # build + +popd # ${INSTALL_DEST} From f3cfdadccadc0746e3a68389c43d9faf0e35aaf4 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 20 Jan 2021 16:42:08 +0000 Subject: [PATCH 052/137] ci: enable ccache where available --- depends/CMakeLists.txt | 3 ++- scripts/ci | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/depends/CMakeLists.txt b/depends/CMakeLists.txt index a805df286..f2c8836e7 100644 --- a/depends/CMakeLists.txt +++ b/depends/CMakeLists.txt @@ -23,11 +23,12 @@ endif() # libsodium set(LIBSODIUM_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libsodium) +set(LIBSODIUM_CONFIGURE_CMD "CC=\"${CMAKE_C_COMPILER_LAUNCHER} ${CMAKE_C_COMPILER}\" CXX=\"${CMAKE_C_COMPILER_LAUNCHER} ${CMAKE_CXX_COMPILER}\" ./configure --prefix= --enable-minimal --disable-shared --enable-static") include(ExternalProject) ExternalProject_Add( libsodium SOURCE_DIR ${LIBSODIUM_SOURCE_DIR} - CONFIGURE_COMMAND cd ${LIBSODIUM_SOURCE_DIR} && DO_NOT_UPDATE_CONFIG_SCRIPTS=1 ./autogen.sh && ./configure --prefix= --enable-minimal --disable-shared --enable-static + CONFIGURE_COMMAND cd ${LIBSODIUM_SOURCE_DIR} && DO_NOT_UPDATE_CONFIG_SCRIPTS=1 ./autogen.sh && eval ${LIBSODIUM_CONFIGURE_CMD} BUILD_COMMAND cd ${LIBSODIUM_SOURCE_DIR} && make ${MAKE_BUILD_FLAGS} INSTALL_COMMAND cd ${LIBSODIUM_SOURCE_DIR} && make install) diff --git a/scripts/ci b/scripts/ci index 9143db255..b74910737 100755 --- a/scripts/ci +++ b/scripts/ci @@ -193,6 +193,9 @@ function build() { if ! [ "${full_build}" == "1" ] ; then cmake_flags="${cmake_flags} -DFAST_TESTS_ONLY=ON" fi + if (which ccache) ; then + cmake_flags="${cmake_flags} -DCMAKE_C_COMPILER_LAUNCHER=ccache" + fi # Build and run unit tests . setup_env.sh From 220231f445ee4a63dd6dcd963ac25ce9dda85379 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 20 Jan 2021 16:23:22 +0000 Subject: [PATCH 053/137] ci: use ccache to cache submodule builds on macos --- .github/workflows/onpush-build-macos.yml | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/.github/workflows/onpush-build-macos.yml b/.github/workflows/onpush-build-macos.yml index 3c4528944..cecc82a9c 100644 --- a/.github/workflows/onpush-build-macos.yml +++ b/.github/workflows/onpush-build-macos.yml @@ -5,7 +5,7 @@ on: push: env: - MACOS_BREW_PACKAGES: "pkg-config libomp" + MACOS_BREW_PACKAGES: "pkg-config libomp ccache" jobs: @@ -13,16 +13,14 @@ jobs: submodules: runs-on: ubuntu-20.04 outputs: - libsodium: ${{ steps.get-commits.outputs.libsodium }} - libsnark: ${{ steps.get-commits.outputs.libsnark }} + commits: ${{ steps.get-commits.outputs.commits }} steps: - uses: actions/checkout@v2 - name: Get Submodule Commits id: get-commits run: | git submodule sync - echo "::set-output name=libsodium::"`git submodule status depends/libsodium | grep -oe '[0-9a-fA-F]\+' | head -c 8` - echo "::set-output name=libsnark::"`git submodule status depends/libsnark | grep -oe '[0-9a-fA-F]\+' | head -c 8` + echo "::set-output name=commits::"`git submodule status depends/libsodium | grep -oe '[0-9a-fA-F]\+' | head -c 8`-`git submodule status depends/libsnark | grep -oe '[0-9a-fA-F]\+' | head -c 8` # Main build build-macos: @@ -35,16 +33,11 @@ jobs: - uses: actions/checkout@v2 with: submodules: recursive - - name: Cache libsodium + - name: Cache ccache uses: actions/cache@v1 with: - key: libsodium-${{ needs.submodules.outputs.libsodium }}-${{ runner.os }}-${{ matrix.config }} - path: build/depends/libsodium-prefix - - name: Cache libsnark - uses: actions/cache@v1 - with: - key: libsnark-${{ needs.submodules.outputs.libsnark }}-${{ runner.os }}-${{ matrix.config }} - path: build/depends/libsnark + key: submodules-${{ needs.submodules.outputs.commits }}-${{ runner.os }}-${{ matrix.config }} + path: ~/Library/Caches/ccache - name: Install Dependencies run: brew install ${MACOS_BREW_PACKAGES} - name: Execute From 46c95eea6fb4ba4fbb9b4fa1a01dec3c19bd5547 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 26 Jan 2021 12:50:47 +0000 Subject: [PATCH 054/137] ci: run onpullrequest-build jobs natively using caches, and enable integration tests --- .../workflows/onpullrequest-build-ubuntu.yml | 67 ++++++++++++++++++- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/.github/workflows/onpullrequest-build-ubuntu.yml b/.github/workflows/onpullrequest-build-ubuntu.yml index 7a460e83c..383a1589c 100644 --- a/.github/workflows/onpullrequest-build-ubuntu.yml +++ b/.github/workflows/onpullrequest-build-ubuntu.yml @@ -1,13 +1,45 @@ # Actions for pull requests only -name: zeth-ci-pull-request +name: zeth-ci-onpullrequest-build-ubuntu on: pull_request: jobs: + # Job to build the grpc libraries. The grpc build directory is populated and + # cached so that all other jobs can mark this job as a prerequisite and just + # run `make install`. + # + # NOTE: the version number here (in `key` and in script arguments) must be + # kept in sync with the key used by the jobs. + onpr-build-grpc: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - name: Cache grpc + uses: actions/cache@v2 + with: + key: grpc-1.31.x-${{ runner.os }}-test + path: depends/grpc + - name: Build grpc + run: if ! [ -d depends/grpc ] ; then scripts/install_grpc /usr v1.31.x depends/grpc ; fi + + # Extract the commits of submodules for use by cache steps + onpr-submodules: + runs-on: ubuntu-20.04 + outputs: + commits: ${{ steps.get-commits.outputs.commits }} + steps: + - uses: actions/checkout@v2 + - name: Get Submodule Commits + id: get-commits + run: | + git submodule sync + echo "::set-output name=commits::"`git submodule status depends/libsodium | grep -oe '[0-9a-fA-F]\+' | head -c 8`-`git submodule status depends/libsnark | grep -oe '[0-9a-fA-F]\+' | head -c 8` + build-linux-full: runs-on: ubuntu-20.04 + needs: [onpr-build-grpc, onpr-submodules] strategy: matrix: curve: [ BLS12_377, ALT_BN128 ] @@ -15,5 +47,36 @@ jobs: - uses: actions/checkout@v1 with: submodules: recursive + - uses: actions/setup-node@v1 + with: + node-version: 10 + - name: Cache grpc + uses: actions/cache@v2 + with: + key: grpc-1.31.x-${{ runner.os }}-test + path: depends/grpc + # - name: Cache ccache + # uses: actions/cache@v2 + # with: + # key: submodules-${{ needs.onpr-submodules.outputs.commits }}-${{ runner.os }}-${{ matrix.curve }} + # path: ~/.ccache + - name: Cache pip + uses: actions/cache@v2 + with: + path: | + ~/.cache/pip + ~/Library/Caches/pip + key: build-linux-full-pip-${{ hashFiles('**/setup.py') }}-${{ runner.os }} + - name: Cache npm + uses: actions/cache@v2 + with: + path: | + ~/.npm + depends/ganache-cli/node_modules + key: build-linux-full-npm-${{ hashFiles('**/package-lock.json') }}-${{ runner.os }} + - name: Install dependencies + run: | + scripts/install_grpc /usr v1.31.x depends/grpc + sudo apt install -y ccache - name: Execute - run: CI_EVENT_NAME=pull_request CI_USE_DOCKER=1 CI_CONFIG=Release CI_CURVE=${{ matrix.curve }} scripts/ci build + run: CI_CONFIG=Release CI_CURVE=${{ matrix.curve }} CI_FULL_TESTS=1 CI_INTEGRATION_TESTS=1 scripts/ci build From 7333c68a5d5d286fd516b9c336541273ffec64d8 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 26 Jan 2021 12:51:51 +0000 Subject: [PATCH 055/137] ci: support for integration tests in ci script --- scripts/ci | 112 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 98 insertions(+), 14 deletions(-) diff --git a/scripts/ci b/scripts/ci index b74910737..a5e113e1b 100755 --- a/scripts/ci +++ b/scripts/ci @@ -19,6 +19,15 @@ function _setup_client() { popd } +function _setup_ganache() { + pushd zeth_contracts + npm config set python python2.7 + npm config set engine-strict true + npm config set unsafe-perm true + npm install --unsafe-perm + popd +} + function _ganache_is_active() { curl -sf \ -H "Content-Type: application/json" \ @@ -60,6 +69,48 @@ function _stop_ganache() { popd } +function _prover_server_is_active() { + # Assume the client env is active + zeth get-verification-key +} + +function _start_prover_server() { + # Requires the client env (for _prover_server_is_active) + . client/env/bin/activate + pushd build + + ./prover_server/prover_server > prover_server.stdout & + echo $! > prover_server.pid + + # Wait for prover_server to be active + while ! _prover_server_is_active ; do + echo "_start_prover_server: waiting for server ..." + sleep 1 + done + echo "_start_prover_server:: prover_server is active" + + popd # build + deactivate +} + +function _stop_prover_server() { + pushd build + + if ! [ -e prover_server.pid ] ; then + echo "_stop_prover_server: no PID file" + return 1 + fi + + pid=`cat prover_server.pid` + while (kill "${pid}") ; do + sleep 0.5 + done + rm prover_server.pid + echo "_stop_prover_server:: prover_server stopped" + + popd # build +} + function _build_setup() { # Extra deps for native builds if [ "${platform}" == "Linux" ] ; then @@ -95,11 +146,14 @@ function check_format() { } function check_contracts() { + + # Setup the zeth_contracts dir + _setup_ganache + + # Run checks in zeth_contracts pushd zeth_contracts - npm config set python python2.7 - npm install --unsafe-perm npm run check - popd + popd # zeth_contracts # Run contract tests (in python) _setup_client @@ -169,6 +223,30 @@ function mpc_tests() { scripts/test_mpc_server_phase2 } +function integration_tests() { + + # Native code is built. Setup client and ganache. + _setup_ganache + _setup_client + + # Start servers + _start_ganache + _start_prover_server + + # Enter client env and run client test script + . client/env/bin/activate + + ./scripts/test_zeth_cli + python -m test_commands.test_ether_mixing GROTH16 + python -m test_commands.test_erc_token_mixing GROTH16 + + deactivate + + # Stop servers + _stop_prover_server + _stop_ganache +} + function build() { _build_setup @@ -190,9 +268,11 @@ function build() { cmake_flags="-DCMAKE_BUILD_TYPE=${CI_CONFIG} -DZETH_SNARK=${CI_ZKSNARK}" cmake_flags="${cmake_flags} -DZETH_CURVE=${CI_CURVE}" - if ! [ "${full_build}" == "1" ] ; then + # Switch off slow tests unless CI_FULL_TESTS == 1 + if ! [ "${CI_FULL_TESTS}" == "1" ] ; then cmake_flags="${cmake_flags} -DFAST_TESTS_ONLY=ON" fi + # Use ccache if available if (which ccache) ; then cmake_flags="${cmake_flags} -DCMAKE_C_COMPILER_LAUNCHER=ccache" fi @@ -210,7 +290,13 @@ function build() { CTEST_OUTPUT_ON_FAILURE=1 make -j 2 check cd .. - mpc_tests + if [ "${CI_MPC_TESTS}" == "1" ] ; then + mpc_tests + fi + + if [ "${CI_INTEGRATION_TESTS}" == "1" ] ; then + integration_tests + fi } function ci_setup() { @@ -258,22 +344,17 @@ function ci_setup() { fi } - ci_task=$1 -full_build=$2 -if [ "${full_build}" == "" ] ; then - if [ "${CI_EVENT_NAME}" == "pull_request" ] ; then - full_build=1 - fi -fi echo ci_task = ${ci_task} -echo full_build=${full_build} echo CI_CONFIG=${CI_CONFIG} echo CI_ZKSNARK=${CI_ZKSNARK} echo CI_CURVE=${CI_CURVE} echo CI_CHECK_FORMAT=${CI_CHECK_FORMAT} echo CI_EVENT_NAME=${CI_EVENT_NAME} +echo CI_FULL_TEST=${CI_FULL_TESTS} +echo CI_MPC_TESTS=${CI_MPC_TESTS} +echo CI_INTEGRATION_TESTS=${CI_INTEGRATION_TESTS} if [ "${CI_CHECK_FORMAT}" == "1" ] ; then check_format @@ -299,7 +380,10 @@ if [ "${CI_USE_DOCKER}" == "1" ] ; then --env CI_CONFIG=${CI_CONFIG} \ --env CI_ZKSNARK=${CI_ZKSNARK} \ --env CI_CURVE=${CI_CURVE} \ - zeth-dev:latest $0 ${ci_task} ${full_build} + --env CI_FULL_TESTS=${CI_FULL_TESTS} \ + --env CI_MPC_TESTS=${CI_MPC_TESTS} \ + --env CI_INTEGRATION_TESTS=${CI_INTEGRATION_TESTS} \ + zeth-dev:latest $0 ${ci_task} else ci_setup ${ci_task} From c577144a4479028ec113b2dbf0d06137f5147dbb Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 26 Jan 2021 12:55:13 +0000 Subject: [PATCH 056/137] ci: caching in onpush-checks jobs --- .github/workflows/onpush-checks.yml | 32 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/.github/workflows/onpush-checks.yml b/.github/workflows/onpush-checks.yml index 4955c285c..d0fb3b386 100644 --- a/.github/workflows/onpush-checks.yml +++ b/.github/workflows/onpush-checks.yml @@ -1,5 +1,5 @@ # Check actions (linters, analysis tools etc.) -name: zeth-ci-push-checks +name: zeth-ci-onpush-checks on: push: @@ -9,28 +9,26 @@ jobs: check-contracts: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 with: submodules: recursive - - uses: actions/setup-node@v1 - with: - node-version: 10 - - name: Cache npm - uses: actions/cache@v1 + - uses: actions/setup-node@v2 with: - path: ~/.npm - key: check-contracts-npm-${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} - # Cache ganache-cli/node_modules to avoid recompiling native code - - name: Cache depends/ganache-cli/node_modules - uses: actions/cache@v1 + node-version: '10' + - name: Cache npm (incl ganache-cli/node_modules) + uses: actions/cache@v2 with: - path: depends/ganache-cli/node_modules - key: check-contracts-ganache-node-modules-${{ runner.os }}-${{ hashFiles('depends/ganache-cli/package-lock.json') }} + path: | + ~/.npm + depends/ganache-cli/node_modules + key: check-contracts-npm-${{ hashFiles('**/package-lock.json') }}-${{ runner.os }} - name: Cache pip uses: actions/cache@v2 with: - path: ~/.cache/pip - key: check-contracts-pip-${{ runner.os }}-${{ hashFiles('client/setup.py') }} + path: | + ~/.cache/pip + ~/.solcx + key: check-contracts-pip-solcx-${{ hashFiles('**/setup.py') }}-${{ runner.os }} - name: Check Contracts run: scripts/ci check_contracts @@ -44,7 +42,7 @@ jobs: uses: actions/cache@v2 with: path: ~/.cache/pip - key: check-client-pip-${{ runner.os }}-${{ hashFiles('client/setup.py') }} + key: check-client-pip-${{ hashFiles('**/setup.py') }}-${{ runner.os }} - name: Check Client run: scripts/ci check_client From fb63fd81a44440bc4ad544d7d1dbe12c3844bfa2 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 26 Jan 2021 12:58:27 +0000 Subject: [PATCH 057/137] ci: cache pip in code scanning job --- .github/workflows/code-scanning.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/code-scanning.yml b/.github/workflows/code-scanning.yml index 3583ed428..d13fb927e 100644 --- a/.github/workflows/code-scanning.yml +++ b/.github/workflows/code-scanning.yml @@ -46,6 +46,11 @@ jobs: uses: actions/setup-python@v2 with: python-version: '3.x' + - name: Cache pip + uses: actions/cache@v2 + with: + path: ~/.cache/pip + key: codeql-py-pip-${{ hashFiles('**/setup.py') }}-${{ runner.os }} - name: Custom dependencies installation run: | cd client @@ -63,4 +68,3 @@ jobs: setup-python-dependencies: false - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v1 - From ad4beee4ddc16bba5248254a482577606c75dcb8 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 26 Jan 2021 13:04:14 +0000 Subject: [PATCH 058/137] ci: caching in onpush-build-ubuntu --- .github/workflows/onpush-build-ubuntu.yml | 48 +++++++++++++++++------ 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/.github/workflows/onpush-build-ubuntu.yml b/.github/workflows/onpush-build-ubuntu.yml index 084a536d5..158971460 100644 --- a/.github/workflows/onpush-build-ubuntu.yml +++ b/.github/workflows/onpush-build-ubuntu.yml @@ -6,9 +6,9 @@ on: jobs: - # Job to build the grpc libraries. The grpc build directory is populated and - # cached so that all other jobs can mark this job as a prerequisite and just - # run `make install`. + # Job to build and cache the grpc libraries. The grpc build directory is + # populated and cached so that all other jobs can mark this job as a + # prerequisite and just run `make install`. # # NOTE: the version number here (in `key` and in script arguments) must be # kept in sync with the key used by the jobs. @@ -35,30 +35,56 @@ jobs: with: submodules: recursive - name: Cache grpc - uses: actions/cache@v1 + uses: actions/cache@v2 with: key: grpc-1.31.x-${{ runner.os }}-test path: depends/grpc - - name: Install grpc - run: scripts/install_grpc /usr v1.31.x depends/grpc + - name: Cache pip (for mpc tests) + uses: actions/cache@v2 + with: + path: ~/.cache/pip + key: build-linux-pip-${{ hashFiles('**/setup.py') }}-${{ runner.os }} + - name: Install dependencies + run: | + scripts/install_grpc /usr v1.31.x depends/grpc + sudo apt install -y ccache - name: Execute - run: CI_CHECK_FORMAT=1 CI_CONFIG=${{ matrix.config }} scripts/ci build + run: CI_CHECK_FORMAT=1 CI_MPC_TESTS=1 CI_CONFIG=${{ matrix.config }} scripts/ci build build-linux-pghr13: runs-on: ubuntu-20.04 + needs: build-grpc steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 with: submodules: recursive + - name: Cache grpc + uses: actions/cache@v1 + with: + key: grpc-1.31.x-${{ runner.os }}-test + path: depends/grpc + - name: Install dependencies + run: | + scripts/install_grpc /usr v1.31.x depends/grpc + sudo apt install -y ccache - name: Execute - run: CI_USE_DOCKER=1 CI_CONFIG=Release CI_ZKSNARK=PGHR13 scripts/ci build + run: CI_CONFIG=Release CI_ZKSNARK=PGHR13 scripts/ci build build-linux-bls12-377: runs-on: ubuntu-20.04 + needs: build-grpc steps: - uses: actions/checkout@v1 with: submodules: recursive + - name: Cache grpc + uses: actions/cache@v2 + with: + key: grpc-1.31.x-${{ runner.os }}-test + path: depends/grpc + - name: Install dependencies + run: | + scripts/install_grpc /usr v1.31.x depends/grpc + sudo apt install -y ccache - name: Execute - run: CI_USE_DOCKER=1 CI_CONFIG=Release CI_CURVE=BLS12_377 scripts/ci build - + run: CI_CONFIG=Release CI_CURVE=BLS12_377 scripts/ci build From 93a8126efc4d9c49735b51469c2d63d6c5b2ea67 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 26 Jan 2021 13:11:39 +0000 Subject: [PATCH 059/137] ci: caching and mpc test in onpush-build-macos --- .github/workflows/onpush-build-macos.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/onpush-build-macos.yml b/.github/workflows/onpush-build-macos.yml index cecc82a9c..02c5107ef 100644 --- a/.github/workflows/onpush-build-macos.yml +++ b/.github/workflows/onpush-build-macos.yml @@ -38,7 +38,12 @@ jobs: with: key: submodules-${{ needs.submodules.outputs.commits }}-${{ runner.os }}-${{ matrix.config }} path: ~/Library/Caches/ccache + - name: Cache pip (for mpc tests) + uses: actions/cache@v2 + with: + path: ~/Library/Caches/pip + key: build-macos-pip-${{ hashFiles('**/setup.py') }}-${{ runner.os }} - name: Install Dependencies run: brew install ${MACOS_BREW_PACKAGES} - name: Execute - run: CI_CONFIG=${{ matrix.config }} scripts/ci build + run: CI_MPC_TESTS=1 CI_CONFIG=${{ matrix.config }} scripts/ci build From 3e51d2ca7d6747b6cffc590cc1c5baf7275b0342 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Fri, 29 Jan 2021 17:31:56 +0000 Subject: [PATCH 060/137] ci: split the prover and integration tests --- .../workflows/onpullrequest-build-ubuntu.yml | 59 ++++++++++++++++--- scripts/ci | 30 ++++++++-- 2 files changed, 77 insertions(+), 12 deletions(-) diff --git a/.github/workflows/onpullrequest-build-ubuntu.yml b/.github/workflows/onpullrequest-build-ubuntu.yml index 383a1589c..6010efaa0 100644 --- a/.github/workflows/onpullrequest-build-ubuntu.yml +++ b/.github/workflows/onpullrequest-build-ubuntu.yml @@ -37,7 +37,50 @@ jobs: git submodule sync echo "::set-output name=commits::"`git submodule status depends/libsodium | grep -oe '[0-9a-fA-F]\+' | head -c 8`-`git submodule status depends/libsnark | grep -oe '[0-9a-fA-F]\+' | head -c 8` - build-linux-full: + # Run the prover testing python scripts + prover-tests-linux: + runs-on: ubuntu-20.04 + needs: [onpr-build-grpc, onpr-submodules] + steps: + - uses: actions/checkout@v1 + with: + submodules: recursive + - uses: actions/setup-node@v1 + with: + node-version: 10 + - name: Cache grpc + uses: actions/cache@v2 + with: + key: grpc-1.31.x-${{ runner.os }}-test + path: depends/grpc + - name: Cache ccache + uses: actions/cache@v2 + with: + key: prover-tests-ccache-${{ needs.onpr-submodules.outputs.commits }}-${{ runner.os }}-test + path: ~/.ccache + - name: Cache pip + uses: actions/cache@v2 + with: + path: | + ~/.cache/pip + ~/Library/Caches/pip + key: prover-tests-pip-${{ hashFiles('**/setup.py') }}-${{ runner.os }} + - name: Cache npm + uses: actions/cache@v2 + with: + path: | + ~/.npm + depends/ganache-cli/node_modules + key: prover-tests-npm-${{ hashFiles('**/package-lock.json') }}-${{ runner.os }} + - name: Install dependencies + run: | + scripts/install_grpc /usr v1.31.x depends/grpc + sudo apt install -y ccache + - name: Execute + run: CI_CONFIG=Release CI_CURVE=ALT_BN128 CI_PROVER_TESTS=1 scripts/ci build + + # Run all unit tests and integration tests + integration-tests-linux: runs-on: ubuntu-20.04 needs: [onpr-build-grpc, onpr-submodules] strategy: @@ -55,25 +98,25 @@ jobs: with: key: grpc-1.31.x-${{ runner.os }}-test path: depends/grpc - # - name: Cache ccache - # uses: actions/cache@v2 - # with: - # key: submodules-${{ needs.onpr-submodules.outputs.commits }}-${{ runner.os }}-${{ matrix.curve }} - # path: ~/.ccache + - name: Cache ccache + uses: actions/cache@v2 + with: + key: integration-tests-ccache-${{ needs.onpr-submodules.outputs.commits }}-${{ matrix.curve }}-${{ runner.os }}-test + path: ~/.ccache - name: Cache pip uses: actions/cache@v2 with: path: | ~/.cache/pip ~/Library/Caches/pip - key: build-linux-full-pip-${{ hashFiles('**/setup.py') }}-${{ runner.os }} + key: integration-tests-pip-${{ hashFiles('**/setup.py') }}-${{ runner.os }} - name: Cache npm uses: actions/cache@v2 with: path: | ~/.npm depends/ganache-cli/node_modules - key: build-linux-full-npm-${{ hashFiles('**/package-lock.json') }}-${{ runner.os }} + key: integration-tests-npm-${{ hashFiles('**/package-lock.json') }}-${{ runner.os }} - name: Install dependencies run: | scripts/install_grpc /usr v1.31.x depends/grpc diff --git a/scripts/ci b/scripts/ci index a5e113e1b..85a284f13 100755 --- a/scripts/ci +++ b/scripts/ci @@ -223,7 +223,7 @@ function mpc_tests() { scripts/test_mpc_server_phase2 } -function integration_tests() { +function prover_tests() { # Native code is built. Setup client and ganache. _setup_ganache @@ -233,13 +233,30 @@ function integration_tests() { _start_ganache _start_prover_server - # Enter client env and run client test script + # Enter client env and run prover test scripts . client/env/bin/activate - - ./scripts/test_zeth_cli python -m test_commands.test_ether_mixing GROTH16 python -m test_commands.test_erc_token_mixing GROTH16 + deactivate + # Stop servers + _stop_prover_server + _stop_ganache +} + +function integration_tests() { + + # Native code is built. Setup client and ganache. + _setup_ganache + _setup_client + + # Start servers + _start_ganache + _start_prover_server + + # Enter client env and run client test script + . client/env/bin/activate + ./scripts/test_zeth_cli deactivate # Stop servers @@ -294,6 +311,10 @@ function build() { mpc_tests fi + if [ "${CI_PROVER_TESTS}" == "1" ] ; then + prover_tests + fi + if [ "${CI_INTEGRATION_TESTS}" == "1" ] ; then integration_tests fi @@ -354,6 +375,7 @@ echo CI_CHECK_FORMAT=${CI_CHECK_FORMAT} echo CI_EVENT_NAME=${CI_EVENT_NAME} echo CI_FULL_TEST=${CI_FULL_TESTS} echo CI_MPC_TESTS=${CI_MPC_TESTS} +echo CI_PROVER_TESTS=${CI_PROVER_TESTS} echo CI_INTEGRATION_TESTS=${CI_INTEGRATION_TESTS} if [ "${CI_CHECK_FORMAT}" == "1" ] ; then From 69704157da2342441902a984b94de3589c600b94 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Fri, 29 Jan 2021 18:39:22 +0000 Subject: [PATCH 061/137] ci: disable ccache on linux --- .github/workflows/onpullrequest-build-ubuntu.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/onpullrequest-build-ubuntu.yml b/.github/workflows/onpullrequest-build-ubuntu.yml index 6010efaa0..b5c0eff43 100644 --- a/.github/workflows/onpullrequest-build-ubuntu.yml +++ b/.github/workflows/onpullrequest-build-ubuntu.yml @@ -98,11 +98,13 @@ jobs: with: key: grpc-1.31.x-${{ runner.os }}-test path: depends/grpc - - name: Cache ccache - uses: actions/cache@v2 - with: - key: integration-tests-ccache-${{ needs.onpr-submodules.outputs.commits }}-${{ matrix.curve }}-${{ runner.os }}-test - path: ~/.ccache + # ccache in this job seems to make the tests crash occasionally. Disabling + # until the cause is understood. + # - name: Cache ccache + # uses: actions/cache@v2 + # with: + # key: integration-tests-ccache-${{ needs.onpr-submodules.outputs.commits }}-${{ matrix.curve }}-${{ runner.os }}-test + # path: ~/.ccache - name: Cache pip uses: actions/cache@v2 with: From 3de33495c7be064a7f1476f63913013dbc1fa977 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 1 Feb 2021 10:46:57 +0000 Subject: [PATCH 062/137] ci: enable prover tests over all curves --- .github/workflows/onpullrequest-build-ubuntu.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/onpullrequest-build-ubuntu.yml b/.github/workflows/onpullrequest-build-ubuntu.yml index b5c0eff43..e5af31eb5 100644 --- a/.github/workflows/onpullrequest-build-ubuntu.yml +++ b/.github/workflows/onpullrequest-build-ubuntu.yml @@ -41,6 +41,9 @@ jobs: prover-tests-linux: runs-on: ubuntu-20.04 needs: [onpr-build-grpc, onpr-submodules] + strategy: + matrix: + curve: [ BLS12_377, ALT_BN128 ] steps: - uses: actions/checkout@v1 with: @@ -56,7 +59,7 @@ jobs: - name: Cache ccache uses: actions/cache@v2 with: - key: prover-tests-ccache-${{ needs.onpr-submodules.outputs.commits }}-${{ runner.os }}-test + key: prover-tests-ccache-${{ needs.onpr-submodules.outputs.commits }}-${{ matrix.curve }}-${{ runner.os }}-test path: ~/.ccache - name: Cache pip uses: actions/cache@v2 @@ -77,7 +80,7 @@ jobs: scripts/install_grpc /usr v1.31.x depends/grpc sudo apt install -y ccache - name: Execute - run: CI_CONFIG=Release CI_CURVE=ALT_BN128 CI_PROVER_TESTS=1 scripts/ci build + run: CI_CONFIG=Release CI_CURVE=${{ matrix.curve }} CI_PROVER_TESTS=1 scripts/ci build # Run all unit tests and integration tests integration-tests-linux: From 18bda7815a1417a278197cca46b7557955c64f0d Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 4 Feb 2021 10:05:34 +0000 Subject: [PATCH 063/137] ci: cosmetic script tweaks --- .github/workflows/onpullrequest-build-ubuntu.yml | 10 +++++----- .github/workflows/onpush-build-macos.yml | 2 +- .github/workflows/onpush-build-ubuntu.yml | 10 +++++----- scripts/install_grpc | 9 +++++---- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.github/workflows/onpullrequest-build-ubuntu.yml b/.github/workflows/onpullrequest-build-ubuntu.yml index e5af31eb5..829d4ebed 100644 --- a/.github/workflows/onpullrequest-build-ubuntu.yml +++ b/.github/workflows/onpullrequest-build-ubuntu.yml @@ -19,7 +19,7 @@ jobs: - name: Cache grpc uses: actions/cache@v2 with: - key: grpc-1.31.x-${{ runner.os }}-test + key: grpc-1.31.x-${{ runner.os }} path: depends/grpc - name: Build grpc run: if ! [ -d depends/grpc ] ; then scripts/install_grpc /usr v1.31.x depends/grpc ; fi @@ -54,12 +54,12 @@ jobs: - name: Cache grpc uses: actions/cache@v2 with: - key: grpc-1.31.x-${{ runner.os }}-test + key: grpc-1.31.x-${{ runner.os }} path: depends/grpc - name: Cache ccache uses: actions/cache@v2 with: - key: prover-tests-ccache-${{ needs.onpr-submodules.outputs.commits }}-${{ matrix.curve }}-${{ runner.os }}-test + key: prover-tests-ccache-${{ needs.onpr-submodules.outputs.commits }}-${{ matrix.curve }}-${{ runner.os }} path: ~/.ccache - name: Cache pip uses: actions/cache@v2 @@ -99,14 +99,14 @@ jobs: - name: Cache grpc uses: actions/cache@v2 with: - key: grpc-1.31.x-${{ runner.os }}-test + key: grpc-1.31.x-${{ runner.os }} path: depends/grpc # ccache in this job seems to make the tests crash occasionally. Disabling # until the cause is understood. # - name: Cache ccache # uses: actions/cache@v2 # with: - # key: integration-tests-ccache-${{ needs.onpr-submodules.outputs.commits }}-${{ matrix.curve }}-${{ runner.os }}-test + # key: integration-tests-ccache-${{ needs.onpr-submodules.outputs.commits }}-${{ matrix.curve }}-${{ runner.os }} # path: ~/.ccache - name: Cache pip uses: actions/cache@v2 diff --git a/.github/workflows/onpush-build-macos.yml b/.github/workflows/onpush-build-macos.yml index 02c5107ef..7b86fd776 100644 --- a/.github/workflows/onpush-build-macos.yml +++ b/.github/workflows/onpush-build-macos.yml @@ -34,7 +34,7 @@ jobs: with: submodules: recursive - name: Cache ccache - uses: actions/cache@v1 + uses: actions/cache@v2 with: key: submodules-${{ needs.submodules.outputs.commits }}-${{ runner.os }}-${{ matrix.config }} path: ~/Library/Caches/ccache diff --git a/.github/workflows/onpush-build-ubuntu.yml b/.github/workflows/onpush-build-ubuntu.yml index 158971460..1c711ff8a 100644 --- a/.github/workflows/onpush-build-ubuntu.yml +++ b/.github/workflows/onpush-build-ubuntu.yml @@ -19,7 +19,7 @@ jobs: - name: Cache grpc uses: actions/cache@v2 with: - key: grpc-1.31.x-${{ runner.os }}-test + key: grpc-1.31.x-${{ runner.os }} path: depends/grpc - name: Build grpc run: if ! [ -d depends/grpc ] ; then scripts/install_grpc /usr v1.31.x depends/grpc ; fi @@ -37,7 +37,7 @@ jobs: - name: Cache grpc uses: actions/cache@v2 with: - key: grpc-1.31.x-${{ runner.os }}-test + key: grpc-1.31.x-${{ runner.os }} path: depends/grpc - name: Cache pip (for mpc tests) uses: actions/cache@v2 @@ -59,9 +59,9 @@ jobs: with: submodules: recursive - name: Cache grpc - uses: actions/cache@v1 + uses: actions/cache@v2 with: - key: grpc-1.31.x-${{ runner.os }}-test + key: grpc-1.31.x-${{ runner.os }} path: depends/grpc - name: Install dependencies run: | @@ -80,7 +80,7 @@ jobs: - name: Cache grpc uses: actions/cache@v2 with: - key: grpc-1.31.x-${{ runner.os }}-test + key: grpc-1.31.x-${{ runner.os }} path: depends/grpc - name: Install dependencies run: | diff --git a/scripts/install_grpc b/scripts/install_grpc index 085ba1e75..1dfbcffe8 100755 --- a/scripts/install_grpc +++ b/scripts/install_grpc @@ -3,7 +3,8 @@ # This script is only intended to run on the CI machines. Not for local # development. -if [ "" == "$1" ] || [ "" == "$2" ] || [ "" == "$3" ] ; then +# Expect 3 arguments, all non-empty. +if [ "$#" -ne 3 ] || [ "" == "$1" ] || [ "" == "$2" ] || [ "" == "$3" ] ; then echo "error: invalid arguments" echo "Usage: $0 " echo "" @@ -34,14 +35,14 @@ mkdir -p ${BUILD_DIR} pushd ${BUILD_DIR} # Clone repo and submodules (if DO_BUILD == 1) - if [ "1" == "${DO_BUILD}" ] ; then + if [ "${DO_BUILD}" == "1" ] ; then git clone --depth 1 -b ${VERSION} https://github.com/grpc/grpc . git submodule update --depth 1 --init --recursive fi # Install protobuf pushd third_party/protobuf - if [ "1" == "${DO_BUILD}" ] ; then + if [ "${DO_BUILD}" == "1" ] ; then [ -e ./configure ] || ./autogen.sh DIST_LANG=cpp ./configure --prefix ${INSTALL_DIR} make -j $(($(nproc)+1)) @@ -52,7 +53,7 @@ pushd ${BUILD_DIR} # Install grpc mkdir -p build pushd build - if [ "1" == "${DO_BUILD}" ] ; then + if [ "${DO_BUILD}" == "1" ] ; then cmake \ -DCMAKE_PREFIX_PATH=${INSTALL_DIR} \ -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} \ From a49ba8e4c9aefdbad0fe0ccf8438b8d4e1823c16 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 4 Feb 2021 13:12:25 +0000 Subject: [PATCH 064/137] update dispatch call for new form of vk_digest --- .../test_groth16_altbn128_mixer_base.py | 3 ++- client/zeth/core/mixer_client.py | 6 ++++-- zeth_contracts/contracts/AltBN128MixerBase.sol | 2 +- zeth_contracts/contracts/BLS12_377MixerBase.sol | 2 +- zeth_contracts/contracts/Groth16AltBN128Mixer.sol | 2 +- .../contracts/Groth16AltBN128MixerBase_test.sol | 2 +- zeth_contracts/contracts/Groth16BLS12_377Mixer.sol | 2 +- zeth_contracts/contracts/MixerBase.sol | 11 +++++++---- zeth_contracts/contracts/Pghr13AltBN128Mixer.sol | 2 +- 9 files changed, 19 insertions(+), 13 deletions(-) diff --git a/client/test_contracts/test_groth16_altbn128_mixer_base.py b/client/test_contracts/test_groth16_altbn128_mixer_base.py index 85ccbb29c..7c2ec9e21 100644 --- a/client/test_contracts/test_groth16_altbn128_mixer_base.py +++ b/client/test_contracts/test_groth16_altbn128_mixer_base.py @@ -99,7 +99,8 @@ zksnark_name="GROTH16", pairing_parameters=test_pairing.ALT_BN128_PAIRING) -VK_HASH = 1 +# Arbitrary VK hash (array of 2 evm words) +VK_HASH = [2, 1] MIX_PARAMETERS_VIN = EtherValue(200) diff --git a/client/zeth/core/mixer_client.py b/client/zeth/core/mixer_client.py index 2c78d6a4f..5cc0dd8b0 100644 --- a/client/zeth/core/mixer_client.py +++ b/client/zeth/core/mixer_client.py @@ -21,7 +21,7 @@ ExtendedProof from zeth.core.utils import EtherValue, digest_to_binary_string, \ int64_to_hex, message_to_bytes, eth_address_to_bytes32, to_zeth_units, \ - get_contracts_dir + get_contracts_dir, hex_to_uint256_list from zeth.core.prover_client import ProverConfiguration, ProverClient from zeth.api.zeth_messages_pb2 import ZethNote, JoinsplitInput, ProofInputs @@ -291,6 +291,8 @@ def deploy( 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 @@ -301,7 +303,7 @@ def deploy( token_address or ZERO_ADDRESS, # token zksnark.verification_key_to_contract_parameters(vk, pp), # vk permitted_dispatcher or ZERO_ADDRESS, # permitted_dispatcher - int(vk_hash, 16) if vk_hash else 0, # vk_hash + vk_hash_evm # vk_hash ] mixer_description = contracts.InstanceDescription.deploy( web3, diff --git a/zeth_contracts/contracts/AltBN128MixerBase.sol b/zeth_contracts/contracts/AltBN128MixerBase.sol index 8df0c7cc2..b7f4c3675 100644 --- a/zeth_contracts/contracts/AltBN128MixerBase.sol +++ b/zeth_contracts/contracts/AltBN128MixerBase.sol @@ -40,7 +40,7 @@ contract AltBN128MixerBase is MixerBase address token, uint256[] memory vk, address permitted_dispatcher, - uint256 vk_hash + uint256[2] memory vk_hash ) public MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) diff --git a/zeth_contracts/contracts/BLS12_377MixerBase.sol b/zeth_contracts/contracts/BLS12_377MixerBase.sol index b4625548b..f0f90600e 100644 --- a/zeth_contracts/contracts/BLS12_377MixerBase.sol +++ b/zeth_contracts/contracts/BLS12_377MixerBase.sol @@ -47,7 +47,7 @@ contract BLS12_377MixerBase is MixerBase address token, uint256[] memory vk, address permitted_dispatcher, - uint256 vk_hash + uint256[2] memory vk_hash ) public MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) diff --git a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol b/zeth_contracts/contracts/Groth16AltBN128Mixer.sol index 47fbab34a..a21e132fb 100644 --- a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Groth16AltBN128Mixer.sol @@ -17,7 +17,7 @@ contract Groth16AltBN128Mixer is AltBN128MixerBase address token, uint256[] memory vk, address permitted_dispatcher, - uint256 vk_hash + uint256[2] memory vk_hash ) public AltBN128MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) diff --git a/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol b/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol index 12359c170..da2c13dff 100644 --- a/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol +++ b/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol @@ -15,7 +15,7 @@ contract Groth16AltBN128MixerBase_test is Groth16AltBN128Mixer constructor( uint256 mk_depth, address permitted_dispatcher, - uint256 vk_hash + uint256[2] memory vk_hash ) public Groth16AltBN128Mixer( diff --git a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol b/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol index 6147b5cd7..47045d981 100644 --- a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol +++ b/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol @@ -17,7 +17,7 @@ contract Groth16BLS12_377Mixer is BLS12_377MixerBase address token, uint256[] memory vk, address permitted_dispatcher, - uint256 vk_hash + uint256[2] memory vk_hash ) public BLS12_377MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) diff --git a/zeth_contracts/contracts/MixerBase.sol b/zeth_contracts/contracts/MixerBase.sol index 30ca57f29..f9b5f5f3a 100644 --- a/zeth_contracts/contracts/MixerBase.sol +++ b/zeth_contracts/contracts/MixerBase.sol @@ -33,7 +33,7 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract address private _permitted_dispatcher; // The acceptable value of _vk_hash, passed in by a trusted dispatcher. - uint256 private _vk_hash; + uint256[2] private _vk_hash; // JoinSplit description, gives the number of inputs (nullifiers) and // outputs (commitments/ciphertexts) to receive and process. @@ -97,7 +97,7 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract address token_address, uint256[] memory vk, address permitted_dispatcher, - uint256 vk_hash + uint256[2] memory vk_hash ) public BaseMerkleTree(depth) @@ -137,7 +137,7 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract /// IZecaleApplication interface, see /// https://github.com/clearmatics/zecale function dispatch( - uint256 nested_vk_hash, + uint256[2] memory nested_vk_hash, uint256[] memory nested_inputs, bytes memory nested_parameters ) @@ -147,7 +147,10 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // Sanity / permission checkcheck require( msg.sender == _permitted_dispatcher, "dispatcher not permitted"); - require(nested_vk_hash == _vk_hash, "invalid nested_vk_hash"); + require( + nested_vk_hash[0] == _vk_hash[0] && + nested_vk_hash[1] == _vk_hash[1], + "invalid nested_vk_hash"); require(nested_inputs.length == 1, "invalid num nested inputs"); // Decode the nested parameters diff --git a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol index 833568207..06c574947 100644 --- a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol @@ -37,7 +37,7 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase address token, uint256[] memory vk, address permitted_dispatcher, - uint256 vk_hash + uint256[2] memory vk_hash ) public AltBN128MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) From ea0decd72ed20c852c244ca3f1e9a73879207802 Mon Sep 17 00:00:00 2001 From: Aleksandr Poliakov Date: Fri, 5 Feb 2021 15:30:00 +0000 Subject: [PATCH 065/137] Migrate docker build from DockerHub to GitHub Container Registry --- .github/workflows/dev-docker-apps.yml | 57 ++++++++++++++++------- .github/workflows/release-docker-apps.yml | 50 +++++++++++--------- .github/workflows/release-docker-base.yml | 38 +++++++-------- Dockerfile-base | 2 + Dockerfile-client | 2 + Dockerfile-dev | 4 +- Dockerfile-mpc | 7 ++- Dockerfile-prover | 7 ++- README.md | 13 +++--- 9 files changed, 108 insertions(+), 72 deletions(-) diff --git a/.github/workflows/dev-docker-apps.yml b/.github/workflows/dev-docker-apps.yml index 5c72ca696..229f5abd0 100644 --- a/.github/workflows/dev-docker-apps.yml +++ b/.github/workflows/dev-docker-apps.yml @@ -4,6 +4,7 @@ on: push: branches: - develop + - docker-to-github pull_request: branches: - master @@ -16,10 +17,10 @@ jobs: docker-build: name: "Docker build" runs-on: ubuntu-20.04 - timeout-minutes: 360 + timeout-minutes: 180 strategy: - fail-fast: false + fail-fast: true matrix: app: ['mpc', 'client', 'prover'] max-parallel: 3 @@ -32,22 +33,44 @@ jobs: id: git_vars run: echo ::set-output name=COMMIT_HASH::$(git rev-parse --short HEAD) - - name: "Login to DockerHub" - uses: docker/login-action@v1 + - name: "Configure Docker" + run: echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin + + - name: "Set up Buildx" + id: buildx + uses: docker/setup-buildx-action@v1 with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + version: latest - - name: "Docker build" - run: docker build -f ./Dockerfile-${{ matrix.app }} -t $REPO_OWNER/zeth-${{ matrix.app }}:git-${{ steps.git_vars.outputs.COMMIT_HASH }} . + - name: "Build and push image git-SHA" + run: | + docker buildx build \ + --tag ghcr.io/$GITHUB_REPOSITORY:git-${{ steps.git_vars.outputs.COMMIT_HASH }}-${{ matrix.app }} \ + --cache-from=type=registry,ref=ghcr.io/$GITHUB_REPOSITORY:cache-${{ matrix.app }} \ + --cache-to=type=registry,ref=ghcr.io/$GITHUB_REPOSITORY:cache-${{ matrix.app }} \ + --platform linux/amd64 \ + --output "type=image,push=true" \ + --file ./Dockerfile-${{ matrix.app }} ./ - - name: "Docker push" - run: docker push $REPO_OWNER/zeth-${{ matrix.app }}:git-${{ steps.git_vars.outputs.COMMIT_HASH }} + test: + name: "Test" + needs: docker-build + runs-on: ubuntu-20.04 + timeout-minutes: 360 - - name: "Docker Info" - run: | - docker inspect $REPO_OWNER/zeth-${{ matrix.app }}:git-${{ steps.git_vars.outputs.COMMIT_HASH }} - docker history $REPO_OWNER/zeth-${{ matrix.app }}:git-${{ steps.git_vars.outputs.COMMIT_HASH }} --no-trunc - docker version - docker info - uname -a + steps: + - name: "Checkout" + uses: actions/checkout@v2 + + - name: "Get vars from git" + id: git_vars + run: echo ::set-output name=COMMIT_HASH::$(git rev-parse --short HEAD) + + - name: "Configure Docker" + run: echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin + + - name: "Run service" + run: echo "Here we will run docker-compose based on images git-"${{ steps.git_vars.outputs.COMMIT_HASH }} + + - name: "Test RPC" + run: echo "Here we will run a tests" diff --git a/.github/workflows/release-docker-apps.yml b/.github/workflows/release-docker-apps.yml index 606f55cf3..634adf7c1 100644 --- a/.github/workflows/release-docker-apps.yml +++ b/.github/workflows/release-docker-apps.yml @@ -5,17 +5,15 @@ on: tags: - v[0-9]+.[0-9]+.[0-9]+ # Triggered by git tags like: v0.2.12 -env: - REPO_OWNER: "clearmatics" - jobs: docker-build: name: "Docker build" runs-on: ubuntu-20.04 - timeout-minutes: 360 + timeout-minutes: 180 strategy: + fail-fast: true matrix: app: ['mpc', 'client', 'prover'] max-parallel: 3 @@ -26,27 +24,33 @@ jobs: - name: "Get vars from git" id: git_vars - run: echo ::set-output name=TAG::${GITHUB_REF/refs\/tags\//} + run: | + echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\/v/} + echo ::set-output name=COMMIT_HASH::$(git rev-parse --short HEAD) - - name: "Login to DockerHub" - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: "Configure Docker" + run: echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin - - name: "Docker build" - run: docker build -f ./Dockerfile-${{ matrix.app }} -t $REPO_OWNER/zeth-${{ matrix.app }}:${{ steps.git_vars.outputs.TAG }} . + - name: "Set up Buildx" + id: buildx + uses: docker/setup-buildx-action@v1 + with: + version: latest - - name: "Docker push" + - name: "Build and push image git-SHA" run: | - docker push $REPO_OWNER/zeth-${{ matrix.app }}:${{ steps.git_vars.outputs.TAG }} - docker tag $REPO_OWNER/zeth-${{ matrix.app }}:${{ steps.git_vars.outputs.TAG }} $REPO_OWNER/zeth-${{ matrix.app }}:latest - docker push $REPO_OWNER/zeth-${{ matrix.app }}:latest - - - name: "Docker Info" + docker buildx build \ + --tag ghcr.io/$GITHUB_REPOSITORY:git-${{ steps.git_vars.outputs.COMMIT_HASH }}-${{ matrix.app }} \ + --cache-from=type=registry,ref=ghcr.io/$GITHUB_REPOSITORY:cache-${{ matrix.app }} \ + --cache-to=type=registry,ref=ghcr.io/$GITHUB_REPOSITORY:cache-${{ matrix.app }} \ + --platform linux/amd64 \ + --output "type=image,push=true" \ + --file ./Dockerfile-${{ matrix.app }} ./ + + - name: "Tag and push latest image to registry" run: | - docker inspect $REPO_OWNER/zeth-${{ matrix.app }}:${{ steps.git_vars.outputs.TAG }} - docker history $REPO_OWNER/zeth-${{ matrix.app }}:${{ steps.git_vars.outputs.TAG }} --no-trunc - docker version - docker info - uname -a + docker pull ghcr.io/$GITHUB_REPOSITORY:git-${{ steps.git_vars.outputs.COMMIT_HASH }}-${{ matrix.app }} + docker tag ghcr.io/$GITHUB_REPOSITORY:git-${{ steps.git_vars.outputs.COMMIT_HASH }}-${{ matrix.app }} ghcr.io/$GITHUB_REPOSITORY:${{ steps.git_vars.outputs.VERSION }}-${{ matrix.app }} + docker tag ghcr.io/$GITHUB_REPOSITORY:git-${{ steps.git_vars.outputs.COMMIT_HASH }}-${{ matrix.app }} ghcr.io/$GITHUB_REPOSITORY:latest-${{ matrix.app }} + docker push ghcr.io/$GITHUB_REPOSITORY:${{ steps.git_vars.outputs.VERSION }}-${{ matrix.app }} + docker push ghcr.io/$GITHUB_REPOSITORY:latest-${{ matrix.app }} diff --git a/.github/workflows/release-docker-base.yml b/.github/workflows/release-docker-base.yml index ab0860a83..1f41861e4 100644 --- a/.github/workflows/release-docker-base.yml +++ b/.github/workflows/release-docker-base.yml @@ -5,13 +5,10 @@ on: tags: - docker-base-v[0-9]+.[0-9]+.[0-9]+ # Triggered by git tags like: docker-base-v0.2.12 -env: - REPO_OWNER: "clearmatics" - jobs: docker-build: - name: "Build docker zeth-base" + name: "Docker build" runs-on: ubuntu-20.04 timeout-minutes: 360 @@ -19,13 +16,9 @@ jobs: - name: "Checkout" uses: actions/checkout@v2 - - name: "Get vars from git" - id: git_vars - run: echo ::set-output name=TAG::${GITHUB_REF/refs\/tags\/docker-base-/} - - name: "Create swap from file" run: | - sudo fallocate -l 21G /swapfile2 + sudo fallocate -l 19G /swapfile2 sudo chmod 600 /swapfile2 sudo mkswap /swapfile2 sudo swapon /swapfile2 @@ -36,25 +29,26 @@ jobs: df -h nproc - - name: Login to DockerHub - uses: docker/login-action@v1 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: "Get vars from git" + id: git_vars + run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\/docker-base-v/} + + - name: "Configure Docker" + run: echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin - - name: Docker build - run: docker build -f ./Dockerfile-base -t $REPO_OWNER/zeth-base:${{ steps.git_vars.outputs.TAG }} . + - name: "Docker build" + run: docker build -f ./Dockerfile-base -t ghcr.io/$GITHUB_REPOSITORY:${{ steps.git_vars.outputs.VERSION }}-base . - - name: Docker push + - name: "Docker push" run: | - docker push $REPO_OWNER/zeth-base:${{ steps.git_vars.outputs.TAG }} - docker tag $REPO_OWNER/zeth-base:${{ steps.git_vars.outputs.TAG }} $REPO_OWNER/zeth-base:latest - docker push $REPO_OWNER/zeth-base:latest + docker push ghcr.io/$GITHUB_REPOSITORY:${{ steps.git_vars.outputs.VERSION }}-base + docker tag ghcr.io/$GITHUB_REPOSITORY:${{ steps.git_vars.outputs.VERSION }}-base ghcr.io/$GITHUB_REPOSITORY:latest-base + docker push ghcr.io/$GITHUB_REPOSITORY:latest-base - name: "Docker Info" run: | - docker inspect $REPO_OWNER/zeth-base:${{ steps.git_vars.outputs.TAG }} - docker history $REPO_OWNER/zeth-base:${{ steps.git_vars.outputs.TAG }} --no-trunc + docker inspect ghcr.io/$GITHUB_REPOSITORY:${{ steps.git_vars.outputs.VERSION }}-base + docker history ghcr.io/$GITHUB_REPOSITORY:${{ steps.git_vars.outputs.VERSION }}-base --no-trunc docker version docker info uname -a diff --git a/Dockerfile-base b/Dockerfile-base index 1930fb29f..5243c8810 100644 --- a/Dockerfile-base +++ b/Dockerfile-base @@ -1,5 +1,7 @@ FROM alpine:3.12 +LABEL org.opencontainers.image.source https://github.com/clearmatics/zeth + #### # This Dockerfile builds the base image # (installs all the dependencies) for Zeth diff --git a/Dockerfile-client b/Dockerfile-client index 8de3a66a2..2a8916fe7 100644 --- a/Dockerfile-client +++ b/Dockerfile-client @@ -1,5 +1,7 @@ FROM python:3.8-alpine3.12 +LABEL org.opencontainers.image.source https://github.com/clearmatics/zeth + RUN apk --update --no-cache add \ build-base \ linux-headers \ diff --git a/Dockerfile-dev b/Dockerfile-dev index 339f56adf..11b9c2069 100644 --- a/Dockerfile-dev +++ b/Dockerfile-dev @@ -1,4 +1,6 @@ -FROM clearmatics/zeth-base:latest +FROM ghcr.io/clearmatics/zeth:0.0.2-base + +LABEL org.opencontainers.image.source https://github.com/clearmatics/zeth COPY . /home/zeth diff --git a/Dockerfile-mpc b/Dockerfile-mpc index 0bee00a27..8d071a81d 100644 --- a/Dockerfile-mpc +++ b/Dockerfile-mpc @@ -1,4 +1,6 @@ -FROM clearmatics/zeth-base:v0.0.0 AS stage1 +FROM ghcr.io/clearmatics/zeth:0.0.2-base AS stage1 + +LABEL org.opencontainers.image.source https://github.com/clearmatics/zeth # 1. Build phase 1: powers of tau rust binaries ENV POT_PATH=/home/powersoftau @@ -28,6 +30,9 @@ RUN cd ${ZETH_PATH} && mkdir build && cd build \ ## FROM alpine:3.12 + +LABEL org.opencontainers.image.source https://github.com/clearmatics/zeth + # Move rust and c++ binaries from previous image and put it in the PATH COPY --from=stage1 /usr/local/bin/ /usr/local/bin # Move the mpc python code diff --git a/Dockerfile-prover b/Dockerfile-prover index 0c5e54959..c2fa91d5c 100644 --- a/Dockerfile-prover +++ b/Dockerfile-prover @@ -1,4 +1,6 @@ -FROM clearmatics/zeth-base:v0.0.0 AS stage1 +FROM ghcr.io/clearmatics/zeth:0.0.2-base AS stage1 + +LABEL org.opencontainers.image.source https://github.com/clearmatics/zeth ENV ZETH_PATH=/home/zeth # Copy necessary files in the docker container @@ -18,6 +20,9 @@ RUN cd ${ZETH_PATH} \ ## FROM alpine:3.12 + +LABEL org.opencontainers.image.source https://github.com/clearmatics/zeth + RUN apk add --no-cache bash ## Move `prover_server` from previous image and put it in the PATH COPY --from=stage1 /home/zeth/build/prover_server/prover_server /usr/local/bin diff --git a/README.md b/README.md index 13c8274a7..ff3fa1bc7 100644 --- a/README.md +++ b/README.md @@ -52,8 +52,8 @@ We propose 2 alternatives to run the `prover_server` below. ##### Fetch the prover_server image (recommended) ```bash -docker pull clearmatics/zeth-prover:latest -docker run -ti -p 50051:50051 --name prover zeth-prover:latest prover_server +docker pull ghcr.io/clearmatics/zeth:latest-prover +docker run -ti -p 50051:50051 --name prover ghcr.io/clearmatics/zeth:latest-prover prover_server ``` ##### Build and run the prover_server in the development container @@ -169,11 +169,10 @@ make check ## Docker images | Docker files | Image | Tags | Description | |---------------|------|-----|--| -| [./Dockerfile-prover](./Dockerfile-prover) | [clearmatics/zeth-prover](https://hub.docker.com/r/clearmatics/zeth-prover) | `latest`, `vX.Y.Z` - Release of zeth, `git-%HASH%` - developers build by git-commit | [Zeth Prover Server](./prover_server/README.md). Image use `zeth-base` for building | -| [./Dockerfile-client](./Dockerfile-client) | [clearmatics/zeth-client](https://hub.docker.com/r/clearmatics/zeth-client) | `latest`, `vX.Y.Z` - Release of zeth, `git-%HASH%` - developers build by git-commit | [Python client to interact with the prover](./client/README.md) | -| [./Dockerfile-mpc](./Dockerfile-mpc) | [clearmatics/zeth-mpc](https://hub.docker.com/r/clearmatics/zeth-mpc) | `latest`, `vX.Y.Z` - Release of zeth, `git-%HASH%` - developers build by git-commit | [Tools for Multi-Party Computation](./mpc/README.md). Image use `zeth-base` for building | -| [./Dockerfile-base](./Dockerfile-base) | [clearmatics/zeth-base](https://hub.docker.com/r/clearmatics/zeth-base) | `latest`, `vA.B.C` - Release of zeth-base | Base image for building other containers | - +| [./Dockerfile-prover](./Dockerfile-prover) | [ghcr.io/clearmatics/zeth:latest-prover](https://github.com/orgs/clearmatics/packages/container/package/zeth) | `latest-prover`, `X.Y.Z-prover` - Release of zeth, `git-%HASH%-prover` - developers build by git-commit | [Zeth Prover Server](./prover_server/README.md). Image use `zeth-base` for building | +| [./Dockerfile-client](./Dockerfile-client) | [ghcr.io/clearmatics/zeth:latest-client](https://github.com/orgs/clearmatics/packages/container/package/zeth) | `latest-client`, `X.Y.Z-client` - Release of zeth, `git-%HASH%-client` - developers build by git-commit | [Python client to interact with the prover](./client/README.md) | +| [./Dockerfile-mpc](./Dockerfile-mpc) | [ghcr.io/clearmatics/zeth:latest-mpc](https://github.com/orgs/clearmatics/packages/container/package/zeth) | `latest-mpc`, `X.Y.Z-mpc` - Release of zeth, `git-%HASH%-mpc` - developers build by git-commit | [Tools for Multi-Party Computation](./mpc/README.md). Image use `zeth-base` for building | +| [./Dockerfile-base](./Dockerfile-base) | [ghcr.io/clearmatics/zeth:latest-base](https://github.com/orgs/clearmatics/packages/container/package/zeth) | `latest-base`, `A.B.C-base` - Release of zeth-base | Base image for building other containers | ## Run analysis tools on the code From d489ef9ce82c09a1371eacc2cce6bba65340084e Mon Sep 17 00:00:00 2001 From: Aleksandr Poliakov Date: Fri, 5 Feb 2021 15:32:58 +0000 Subject: [PATCH 066/137] remove tmp branch name from CI for docker build --- .github/workflows/dev-docker-apps.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/dev-docker-apps.yml b/.github/workflows/dev-docker-apps.yml index 229f5abd0..8e084cf4f 100644 --- a/.github/workflows/dev-docker-apps.yml +++ b/.github/workflows/dev-docker-apps.yml @@ -4,7 +4,6 @@ on: push: branches: - develop - - docker-to-github pull_request: branches: - master From b5ede9a5ab34933d7ceb7ee64ee9f29403e3d024 Mon Sep 17 00:00:00 2001 From: Aleksandr Poliakov Date: Tue, 9 Feb 2021 10:44:32 +0000 Subject: [PATCH 067/137] Remove placeholder for tests --- .github/workflows/dev-docker-apps.yml | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/.github/workflows/dev-docker-apps.yml b/.github/workflows/dev-docker-apps.yml index 8e084cf4f..9e7d8c4c1 100644 --- a/.github/workflows/dev-docker-apps.yml +++ b/.github/workflows/dev-docker-apps.yml @@ -50,26 +50,3 @@ jobs: --platform linux/amd64 \ --output "type=image,push=true" \ --file ./Dockerfile-${{ matrix.app }} ./ - - test: - name: "Test" - needs: docker-build - runs-on: ubuntu-20.04 - timeout-minutes: 360 - - steps: - - name: "Checkout" - uses: actions/checkout@v2 - - - name: "Get vars from git" - id: git_vars - run: echo ::set-output name=COMMIT_HASH::$(git rev-parse --short HEAD) - - - name: "Configure Docker" - run: echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin - - - name: "Run service" - run: echo "Here we will run docker-compose based on images git-"${{ steps.git_vars.outputs.COMMIT_HASH }} - - - name: "Test RPC" - run: echo "Here we will run a tests" From 68e8aedfc9a595c4d2f3fba7c2d2db5f1a0468e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Feb 2021 02:07:30 +0000 Subject: [PATCH 068/137] build(deps): bump cryptography from 3.2 to 3.3.2 in /client Bumps [cryptography](https://github.com/pyca/cryptography) from 3.2 to 3.3.2. - [Release notes](https://github.com/pyca/cryptography/releases) - [Changelog](https://github.com/pyca/cryptography/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pyca/cryptography/compare/3.2...3.3.2) Signed-off-by: dependabot[bot] --- client/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/setup.py b/client/setup.py index 2c7b8ed0b..219de9f79 100644 --- a/client/setup.py +++ b/client/setup.py @@ -50,7 +50,7 @@ "py_ecc==1.7.1", "py-solc-x==0.7.0", "pycryptodome==3.9.8", - "cryptography==3.2", + "cryptography==3.3.2", "requests==2.21.0", "rlp==1.1.0", "semantic-version==2.8.4", From 74fa702658126efca93a032527b955bfe38d5c09 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 9 Feb 2021 12:52:10 +0000 Subject: [PATCH 069/137] update solidity compiler (0.8) --- client/setup.py | 2 +- client/test_commands/deploy_test_token.py | 6 +- client/zeth/core/constants.py | 2 +- zeth_contracts/.solhint.json | 2 +- zeth_contracts/.solhintignore | 1 + .../contracts/AltBN128MixerBase.sol | 13 +- .../contracts/BLS12_377MixerBase.sol | 13 +- zeth_contracts/contracts/BLS12_377_test.sol | 8 +- zeth_contracts/contracts/BW6_761_test.sol | 8 +- zeth_contracts/contracts/BaseMerkleTree.sol | 11 +- zeth_contracts/contracts/ERC20Mintable.sol | 330 ++++++++++++++++++ zeth_contracts/contracts/Groth16AltBN128.sol | 8 +- .../contracts/Groth16AltBN128Mixer.sol | 4 +- .../Groth16AltBN128MixerBase_test.sol | 3 +- zeth_contracts/contracts/Groth16BLS12_377.sol | 8 +- .../contracts/Groth16BLS12_377Mixer.sol | 4 +- .../contracts/Groth16BLS12_377_test.sol | 2 +- .../contracts/MerkleTreeMiMC7_test.sol | 11 +- zeth_contracts/contracts/MerkleTreeSha256.sol | 14 +- zeth_contracts/contracts/MiMC31.sol | 2 +- zeth_contracts/contracts/MiMC7.sol | 2 +- zeth_contracts/contracts/MiMC_test.sol | 2 +- zeth_contracts/contracts/Migrations.sol | 2 +- zeth_contracts/contracts/MixerBase.sol | 25 +- .../contracts/OTSchnorrVerifier.sol | 4 +- zeth_contracts/contracts/Pairing.sol | 8 +- .../contracts/Pghr13AltBN128Mixer.sol | 4 +- zeth_contracts/contracts/Tokens.sol | 28 +- zeth_contracts/package.json | 1 - 29 files changed, 445 insertions(+), 83 deletions(-) create mode 100644 zeth_contracts/contracts/ERC20Mintable.sol diff --git a/client/setup.py b/client/setup.py index 219de9f79..21e0f64e5 100644 --- a/client/setup.py +++ b/client/setup.py @@ -48,7 +48,7 @@ "parsimonious==0.8.1", "protobuf==3.13.0", "py_ecc==1.7.1", - "py-solc-x==0.7.0", + "py-solc-x==1.1.0", "pycryptodome==3.9.8", "cryptography==3.3.2", "requests==2.21.0", diff --git a/client/test_commands/deploy_test_token.py b/client/test_commands/deploy_test_token.py index 56973230d..e1e3193ce 100644 --- a/client/test_commands/deploy_test_token.py +++ b/client/test_commands/deploy_test_token.py @@ -65,11 +65,11 @@ def compile_token() -> Interface: zeth_dir = get_zeth_dir() allowed_path = join( zeth_dir, - "zeth_contracts/node_modules/openzeppelin-solidity/contracts") + "zeth_contracts/contracts") path_to_token = join( zeth_dir, - "zeth_contracts/node_modules/openzeppelin-solidity/contracts", - "token/ERC20/ERC20Mintable.sol") + "zeth_contracts/contracts", + "ERC20Mintable.sol") # Compilation set_solc_version(SOL_COMPILER_VERSION) compiled_sol = compile_files([path_to_token], allow_paths=allowed_path) diff --git a/client/zeth/core/constants.py b/client/zeth/core/constants.py index 050b19b10..bc40d5dff 100644 --- a/client/zeth/core/constants.py +++ b/client/zeth/core/constants.py @@ -88,7 +88,7 @@ def bit_length_to_byte_length(bit_length: int) -> int: NUM_INPUT_DIGESTS: int = (2 * JS_INPUTS) + 1 # Solidity compiler version -SOL_COMPILER_VERSION: str = 'v0.5.16' +SOL_COMPILER_VERSION: str = 'v0.8.1' # Seed for MIMC MIMC_MT_SEED: str = "clearmatics_mt_seed" diff --git a/zeth_contracts/.solhint.json b/zeth_contracts/.solhint.json index 6e5d5d91a..54eee2f43 100644 --- a/zeth_contracts/.solhint.json +++ b/zeth_contracts/.solhint.json @@ -11,7 +11,7 @@ "avoid-suicide": "error", "no-inline-assembly": "off", "avoid-sha3": "warn", - "func-visibility": "error", + "func-visibility": ["error", {"ignoreConstructors": true}], "max-line-length": ["error", 79] } } diff --git a/zeth_contracts/.solhintignore b/zeth_contracts/.solhintignore index 470ae503a..c41e7a6f7 100644 --- a/zeth_contracts/.solhintignore +++ b/zeth_contracts/.solhintignore @@ -1,2 +1,3 @@ +ERC20Mintable.sol node_modules/ contracts/Migrations.sol diff --git a/zeth_contracts/contracts/AltBN128MixerBase.sol b/zeth_contracts/contracts/AltBN128MixerBase.sol index b7f4c3675..c6404ce7f 100644 --- a/zeth_contracts/contracts/AltBN128MixerBase.sol +++ b/zeth_contracts/contracts/AltBN128MixerBase.sol @@ -2,15 +2,14 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; -pragma experimental ABIEncoderV2; +pragma solidity ^0.8.0; import "./MixerBase.sol"; import "./MiMC7.sol"; /// Partial implementation of abstract MixerBase which implements the /// curve-specific methods to use the ALT-BN128 pairing. -contract AltBN128MixerBase is MixerBase +abstract contract AltBN128MixerBase is MixerBase { // Constants regarding the hash digest length, the prime number used and // its associated length in bits and the max values (v_in and v_out) @@ -42,13 +41,16 @@ contract AltBN128MixerBase is MixerBase address permitted_dispatcher, uint256[2] memory vk_hash ) - public MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) { } /// Use MiMC7 as the Merkle tree hash function. - function hash(bytes32 left, bytes32 right) internal returns(bytes32) { + function hash(bytes32 left, bytes32 right) + internal + override + returns(bytes32) + { return MiMC7.hash(left, right); } @@ -61,6 +63,7 @@ contract AltBN128MixerBase is MixerBase ) internal pure + override returns(bytes32) { // The residual bits are located at: diff --git a/zeth_contracts/contracts/BLS12_377MixerBase.sol b/zeth_contracts/contracts/BLS12_377MixerBase.sol index f0f90600e..e3488ff7b 100644 --- a/zeth_contracts/contracts/BLS12_377MixerBase.sol +++ b/zeth_contracts/contracts/BLS12_377MixerBase.sol @@ -2,15 +2,14 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; -pragma experimental ABIEncoderV2; +pragma solidity ^0.8.0; import "./MixerBase.sol"; import "./MiMC31.sol"; /// Partial implementation of abstract MixerBase which implements the /// curve-specific methods to use the BLS12-377 pairing. -contract BLS12_377MixerBase is MixerBase +abstract contract BLS12_377MixerBase is MixerBase { // TODO: Code here is very similar to AltBN128MixerBase, with only the // constants changed. Look into sharing more code (possibly by making some @@ -49,12 +48,15 @@ contract BLS12_377MixerBase is MixerBase address permitted_dispatcher, uint256[2] memory vk_hash ) - public MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) { } - function hash(bytes32 left, bytes32 right) internal returns(bytes32) { + function hash(bytes32 left, bytes32 right) + internal + override + returns(bytes32) + { return MiMC31.hash(left, right); } @@ -67,6 +69,7 @@ contract BLS12_377MixerBase is MixerBase ) internal pure + override returns(bytes32) { // The residual_bits_set_idx-th set of residual bits (denoted r_i diff --git a/zeth_contracts/contracts/BLS12_377_test.sol b/zeth_contracts/contracts/BLS12_377_test.sol index 623082947..566cac5b9 100644 --- a/zeth_contracts/contracts/BLS12_377_test.sol +++ b/zeth_contracts/contracts/BLS12_377_test.sol @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; +pragma solidity ^0.8.0; contract BLS12_377_test { @@ -24,7 +24,7 @@ contract BLS12_377_test bool success = true; assembly { - success := call(gas, 0xc4, 0, input, 0x100, output, 0x80) + success := call(gas(), 0xc4, 0, input, 0x100, output, 0x80) } require(success, "precompiled contract call failed (ECAdd)"); @@ -40,7 +40,7 @@ contract BLS12_377_test bool success = true; assembly { - success := call(gas, 0xc5, 0, input, 0xa0, output, 0x80) + success := call(gas(), 0xc5, 0, input, 0xa0, output, 0x80) } require(success, "precompiled contract call failed (ECMul)"); @@ -60,7 +60,7 @@ contract BLS12_377_test bool success = true; assembly { - success := call(gas, 0xc6, 0, input, 0x600, output, 0x20) + success := call(gas(), 0xc6, 0, input, 0x600, output, 0x20) } require(success, "precompiled contract call failed (ECMul)"); diff --git a/zeth_contracts/contracts/BW6_761_test.sol b/zeth_contracts/contracts/BW6_761_test.sol index d2d12baa8..353a7e9e6 100644 --- a/zeth_contracts/contracts/BW6_761_test.sol +++ b/zeth_contracts/contracts/BW6_761_test.sol @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; +pragma solidity ^0.8.0; contract BW6_761_test { @@ -21,7 +21,7 @@ contract BW6_761_test bool success = true; assembly { - success := call(gas, 0xc1, 0, points, 0x180, output, 0xc0) + success := call(gas(), 0xc1, 0, points, 0x180, output, 0xc0) } require(success, "precompiled contract call failed (ECAdd)"); @@ -36,7 +36,7 @@ contract BW6_761_test bool success = true; assembly { - success := call(gas, 0xc2, 0, input, 0x100, output, 0xc0) + success := call(gas(), 0xc2, 0, input, 0x100, output, 0xc0) } require(success, "precompiled contract call failed (ECMul)"); @@ -53,7 +53,7 @@ contract BW6_761_test bool success = true; assembly { - success := call(gas, 0xc3, 0, input, 0x600, output, 0x20) + success := call(gas(), 0xc3, 0, input, 0x600, output, 0x20) } require(success, "precompiled contract call failed (ECMul)"); diff --git a/zeth_contracts/contracts/BaseMerkleTree.sol b/zeth_contracts/contracts/BaseMerkleTree.sol index 1b30c9694..4b58e4e11 100644 --- a/zeth_contracts/contracts/BaseMerkleTree.sol +++ b/zeth_contracts/contracts/BaseMerkleTree.sol @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; +pragma solidity ^0.8.0; /// Abstract Merkle tree implementation. Child classes should implement the /// hash function. @@ -13,7 +13,7 @@ pragma solidity ^0.5.0; /// This implementation stores all leaves and nodes, skipping those that have /// not been populated yet. The final entry in each layer stores that layer's /// default value. -contract BaseMerkleTree +abstract contract BaseMerkleTree { // Depth of the merkle tree (should be set with the same depth set in the // cpp prover) @@ -37,7 +37,7 @@ contract BaseMerkleTree uint256 internal num_leaves; /// Constructor - constructor(uint256 treeDepth) public { + constructor(uint256 treeDepth) { require ( treeDepth == DEPTH, "Invalid depth in BaseMerkleTree" @@ -65,7 +65,10 @@ contract BaseMerkleTree /// Abstract hash function to be supplied by a concrete implementation of /// this class. - function hash(bytes32 left, bytes32 right) internal returns (bytes32); + function hash(bytes32 left, bytes32 right) + internal + virtual + returns (bytes32); function recomputeRoot(uint num_new_leaves) internal returns (bytes32) { // Assume `num_new_leaves` have been written into the leaf slots. diff --git a/zeth_contracts/contracts/ERC20Mintable.sol b/zeth_contracts/contracts/ERC20Mintable.sol new file mode 100644 index 000000000..387454061 --- /dev/null +++ b/zeth_contracts/contracts/ERC20Mintable.sol @@ -0,0 +1,330 @@ +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +pragma solidity ^0.8.0; + +import "./Tokens.sol"; + +// Adapted from: +// https://github.com/OpenZeppelin/openzeppelin-contracts/blob/release-v2.5.0/contracts/token/ERC20/ERC20Mintable.sol +// and modified to be compatible with solidity 0.8.0. Original code is covered +// by the following copyright notice: +// +// The MIT License (MIT) +// +// Copyright (c) 2016-2019 zOS Global Limited +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +abstract contract Context { + function _msgSender() internal view returns (address payable) { + return payable(msg.sender); + } + + function _msgData() internal view returns (bytes memory) { + this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 + return msg.data; + } +} + +contract ERC20 is Context, IERC20 { + mapping (address => uint256) private _balances; + + mapping (address => mapping (address => uint256)) private _allowances; + + uint256 private _totalSupply; + + /** + * @dev See {IERC20-totalSupply}. + */ + function totalSupply() public view returns (uint256) { + return _totalSupply; + } + + /** + * @dev See {IERC20-balanceOf}. + */ + function balanceOf(address account) public view returns (uint256) { + return _balances[account]; + } + + /** + * @dev See {IERC20-transfer}. + * + * Requirements: + * + * - `recipient` cannot be the zero address. + * - the caller must have a balance of at least `amount`. + */ + function transfer(address recipient, uint256 amount) public override returns (bool) { + _transfer(_msgSender(), recipient, amount); + return true; + } + + /** + * @dev See {IERC20-allowance}. + */ + function allowance(address owner, address spender) public view returns (uint256) { + return _allowances[owner][spender]; + } + + /** + * @dev See {IERC20-approve}. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function approve(address spender, uint256 amount) public returns (bool) { + _approve(_msgSender(), spender, amount); + return true; + } + + /** + * @dev See {IERC20-transferFrom}. + * + * Emits an {Approval} event indicating the updated allowance. This is not + * required by the EIP. See the note at the beginning of {ERC20}; + * + * Requirements: + * - `sender` and `recipient` cannot be the zero address. + * - `sender` must have a balance of at least `amount`. + * - the caller must have allowance for `sender`'s tokens of at least + * `amount`. + */ + function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) { + _transfer(sender, recipient, amount); + _approve(sender, _msgSender(), _allowances[sender][_msgSender()] - amount); + return true; + } + + /** + * @dev Atomically increases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + */ + function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { + _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); + return true; + } + + /** + * @dev Atomically decreases the allowance granted to `spender` by the caller. + * + * This is an alternative to {approve} that can be used as a mitigation for + * problems described in {IERC20-approve}. + * + * Emits an {Approval} event indicating the updated allowance. + * + * Requirements: + * + * - `spender` cannot be the zero address. + * - `spender` must have allowance for the caller of at least + * `subtractedValue`. + */ + function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { + _approve(_msgSender(), spender, _allowances[_msgSender()][spender] - subtractedValue); + return true; + } + + /** + * @dev Moves tokens `amount` from `sender` to `recipient`. + * + * This is internal function is equivalent to {transfer}, and can be used to + * e.g. implement automatic token fees, slashing mechanisms, etc. + * + * Emits a {Transfer} event. + * + * Requirements: + * + * - `sender` cannot be the zero address. + * - `recipient` cannot be the zero address. + * - `sender` must have a balance of at least `amount`. + */ + function _transfer(address sender, address recipient, uint256 amount) internal { + require(sender != address(0), "ERC20: transfer from the zero address"); + require(recipient != address(0), "ERC20: transfer to the zero address"); + + _balances[sender] = _balances[sender] - amount; + _balances[recipient] = _balances[recipient] + amount; + emit Transfer(sender, recipient, amount); + } + + /** @dev Creates `amount` tokens and assigns them to `account`, increasing + * the total supply. + * + * Emits a {Transfer} event with `from` set to the zero address. + * + * Requirements + * + * - `to` cannot be the zero address. + */ + function _mint(address account, uint256 amount) internal { + require(account != address(0), "ERC20: mint to the zero address"); + + _totalSupply = _totalSupply + amount; + _balances[account] = _balances[account] + amount; + emit Transfer(address(0), account, amount); + } + + /** + * @dev Destroys `amount` tokens from `account`, reducing the + * total supply. + * + * Emits a {Transfer} event with `to` set to the zero address. + * + * Requirements + * + * - `account` cannot be the zero address. + * - `account` must have at least `amount` tokens. + */ + function _burn(address account, uint256 amount) internal { + require(account != address(0), "ERC20: burn from the zero address"); + + _balances[account] = _balances[account] - amount; + _totalSupply = _totalSupply - amount; + emit Transfer(account, address(0), amount); + } + + /** + * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. + * + * This is internal function is equivalent to `approve`, and can be used to + * e.g. set automatic allowances for certain subsystems, etc. + * + * Emits an {Approval} event. + * + * Requirements: + * + * - `owner` cannot be the zero address. + * - `spender` cannot be the zero address. + */ + function _approve(address owner, address spender, uint256 amount) internal { + require(owner != address(0), "ERC20: approve from the zero address"); + require(spender != address(0), "ERC20: approve to the zero address"); + + _allowances[owner][spender] = amount; + emit Approval(owner, spender, amount); + } + + /** + * @dev Destroys `amount` tokens from `account`.`amount` is then deducted + * from the caller's allowance. + * + * See {_burn} and {_approve}. + */ + function _burnFrom(address account, uint256 amount) internal { + _burn(account, amount); + _approve(account, _msgSender(), _allowances[account][_msgSender()] - amount); + } +} + +library Roles { + struct Role { + mapping (address => bool) bearer; + } + + /** + * @dev Give an account access to this role. + */ + function add(Role storage role, address account) internal { + require(!has(role, account), "Roles: account already has role"); + role.bearer[account] = true; + } + + /** + * @dev Remove an account's access to this role. + */ + function remove(Role storage role, address account) internal { + require(has(role, account), "Roles: account does not have role"); + role.bearer[account] = false; + } + + /** + * @dev Check if an account has this role. + * @return bool + */ + function has(Role storage role, address account) internal view returns (bool) { + require(account != address(0), "Roles: account is the zero address"); + return role.bearer[account]; + } +} + +abstract contract MinterRole is Context { + using Roles for Roles.Role; + + event MinterAdded(address indexed account); + event MinterRemoved(address indexed account); + + Roles.Role private _minters; + + constructor () { + _addMinter(_msgSender()); + } + + modifier onlyMinter() { + require(isMinter(_msgSender()), "MinterRole: caller does not have the Minter role"); + _; + } + + function isMinter(address account) public view returns (bool) { + return _minters.has(account); + } + + function addMinter(address account) public onlyMinter { + _addMinter(account); + } + + function renounceMinter() public { + _removeMinter(_msgSender()); + } + + function _addMinter(address account) internal { + _minters.add(account); + emit MinterAdded(account); + } + + function _removeMinter(address account) internal { + _minters.remove(account); + emit MinterRemoved(account); + } +} + +contract ERC20Mintable is ERC20, MinterRole { + /** + * @dev See {ERC20-_mint}. + * + * Requirements: + * + * - the caller must have the {MinterRole}. + */ + function mint(address account, uint256 amount) public onlyMinter returns (bool) { + _mint(account, amount); + return true; + } +} diff --git a/zeth_contracts/contracts/Groth16AltBN128.sol b/zeth_contracts/contracts/Groth16AltBN128.sol index ff9e5f316..f5cb427c5 100644 --- a/zeth_contracts/contracts/Groth16AltBN128.sol +++ b/zeth_contracts/contracts/Groth16AltBN128.sol @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; +pragma solidity ^0.8.0; library Groth16AltBN128 { @@ -113,10 +113,10 @@ library Groth16AltBN128 uint256 vk_slot_num; assembly { - let g := sub(gas, 2000) + let g := sub(gas(), 2000) // Compute starting slot of vk data. - mstore(pad, vk_slot) + mstore(pad, vk.slot) vk_slot_num := keccak256(pad, 0x20) let abc_slot_num := add(vk_slot_num, 0x0a) @@ -233,7 +233,7 @@ library Groth16AltBN128 mstore(add(pad, 0x2c0), sload(add(vk_slot_num, 8))) mstore(add(pad, 0x2e0), sload(add(vk_slot_num, 9))) - success := call(sub(gas, 2000), 8, 0, pad, 0x300, pad, 0x20) + success := call(sub(gas(), 2000), 8, 0, pad, 0x300, pad, 0x20) } require( diff --git a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol b/zeth_contracts/contracts/Groth16AltBN128Mixer.sol index a21e132fb..1df62dcb5 100644 --- a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Groth16AltBN128Mixer.sol @@ -2,8 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; -pragma experimental ABIEncoderV2; +pragma solidity ^0.8.0; import "./AltBN128MixerBase.sol"; import "./Groth16AltBN128.sol"; @@ -29,6 +28,7 @@ contract Groth16AltBN128Mixer is AltBN128MixerBase uint256 public_inputs_hash ) internal + override returns (bool) { // Convert the single primary input to a dynamic array diff --git a/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol b/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol index da2c13dff..37544e897 100644 --- a/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol +++ b/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol @@ -2,8 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; -pragma experimental ABIEncoderV2; +pragma solidity ^0.8.0; import "./Groth16AltBN128Mixer.sol"; diff --git a/zeth_contracts/contracts/Groth16BLS12_377.sol b/zeth_contracts/contracts/Groth16BLS12_377.sol index 8e8ca1289..5782b28d3 100644 --- a/zeth_contracts/contracts/Groth16BLS12_377.sol +++ b/zeth_contracts/contracts/Groth16BLS12_377.sol @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; +pragma solidity ^0.8.0; library Groth16BLS12_377 { @@ -91,10 +91,10 @@ library Groth16BLS12_377 assembly { // Copied from bn implemenation in zeth. - let g := sub(gas, 2000) + let g := sub(gas(), 2000) // Compute starting slot of the vk data and abc data. - mstore(pad, vk_slot) + mstore(pad, vk.slot) vk_slot_num := keccak256(pad, 0x20) let abc_slot_num := add(vk_slot_num, 0x14) @@ -255,7 +255,7 @@ library Groth16BLS12_377 mstore(add(pad, 0x5e0), sload(add(vk_slot_num, 0x13))) // Call ecpairing - result := call(gas, 0xc6, 0, pad, 0x600, pad, 0x20) + result := call(gas(), 0xc6, 0, pad, 0x600, pad, 0x20) } return 1 == pad[0]; diff --git a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol b/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol index 47045d981..538a7810f 100644 --- a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol +++ b/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol @@ -2,8 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; -pragma experimental ABIEncoderV2; +pragma solidity ^0.8.0; import "./Groth16BLS12_377.sol"; import "./BLS12_377MixerBase.sol"; @@ -29,6 +28,7 @@ contract Groth16BLS12_377Mixer is BLS12_377MixerBase uint256 public_inputs_hash ) internal + override returns (bool) { // Convert the single primary input to a dynamic array diff --git a/zeth_contracts/contracts/Groth16BLS12_377_test.sol b/zeth_contracts/contracts/Groth16BLS12_377_test.sol index fd95b7d91..d6493fd79 100644 --- a/zeth_contracts/contracts/Groth16BLS12_377_test.sol +++ b/zeth_contracts/contracts/Groth16BLS12_377_test.sol @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; +pragma solidity ^0.8.0; import "./Groth16BLS12_377.sol"; diff --git a/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol b/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol index a09deda42..82e34fede 100644 --- a/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol +++ b/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; +pragma solidity ^0.8.0; import "./BaseMerkleTree.sol"; import "./MiMC7.sol"; @@ -15,7 +15,8 @@ import "./MiMC7.sol"; /// default value. contract MerkleTreeMiMC7_test is BaseMerkleTree { - constructor(uint treeDepth) public BaseMerkleTree(treeDepth) { + constructor(uint treeDepth) public BaseMerkleTree(treeDepth) + { } /// Add some leaves, computing the root, then adding more leaves and @@ -42,7 +43,11 @@ contract MerkleTreeMiMC7_test is BaseMerkleTree } /// Use MiMC7 as the Merkle tree hash function. - function hash(bytes32 left, bytes32 right) internal returns(bytes32) { + function hash(bytes32 left, bytes32 right) + internal + override + returns(bytes32) + { return MiMC7.hash(left, right); } } diff --git a/zeth_contracts/contracts/MerkleTreeSha256.sol b/zeth_contracts/contracts/MerkleTreeSha256.sol index 554e0e657..7a2654cc3 100644 --- a/zeth_contracts/contracts/MerkleTreeSha256.sol +++ b/zeth_contracts/contracts/MerkleTreeSha256.sol @@ -2,17 +2,20 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; +pragma solidity ^0.8.0; import "./BaseMerkleTree.sol"; -contract MerkleTreeSha256 is BaseMerkleTree { +contract MerkleTreeSha256 is BaseMerkleTree +{ - constructor(uint256 treeDepth) public BaseMerkleTree(treeDepth) { + constructor(uint256 treeDepth) public BaseMerkleTree(treeDepth) + { } /// Returns the current merkle tree - function getTree() internal view returns (bytes32[] memory) { + function getTree() internal view returns (bytes32[] memory) + { uint256 nbNodes = 2**(depth + 1) - 1; bytes32[] memory tmpTree = new bytes32[](nbNodes); @@ -34,7 +37,8 @@ contract MerkleTreeSha256 is BaseMerkleTree { } /// Returns the root of the merkle tree - function getRoot() internal view returns(bytes32) { + function getRoot() internal view returns(bytes32) + { return getTree()[0]; } } diff --git a/zeth_contracts/contracts/MiMC31.sol b/zeth_contracts/contracts/MiMC31.sol index f3c7f7b50..385a797e5 100644 --- a/zeth_contracts/contracts/MiMC31.sol +++ b/zeth_contracts/contracts/MiMC31.sol @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; +pragma solidity ^0.8.0; /// Reference papers: /// diff --git a/zeth_contracts/contracts/MiMC7.sol b/zeth_contracts/contracts/MiMC7.sol index 747ddcdd1..1ba199adf 100644 --- a/zeth_contracts/contracts/MiMC7.sol +++ b/zeth_contracts/contracts/MiMC7.sol @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; +pragma solidity ^0.8.0; /// Reference papers: /// diff --git a/zeth_contracts/contracts/MiMC_test.sol b/zeth_contracts/contracts/MiMC_test.sol index 786d858b7..a5224fd1e 100644 --- a/zeth_contracts/contracts/MiMC_test.sol +++ b/zeth_contracts/contracts/MiMC_test.sol @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; +pragma solidity ^0.8.0; import "./MiMC7.sol"; import "./MiMC31.sol"; diff --git a/zeth_contracts/contracts/Migrations.sol b/zeth_contracts/contracts/Migrations.sol index 776c0250e..073c5d996 100644 --- a/zeth_contracts/contracts/Migrations.sol +++ b/zeth_contracts/contracts/Migrations.sol @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; +pragma solidity ^0.8.0; contract Migrations { address public owner; diff --git a/zeth_contracts/contracts/MixerBase.sol b/zeth_contracts/contracts/MixerBase.sol index f9b5f5f3a..202885ada 100644 --- a/zeth_contracts/contracts/MixerBase.sol +++ b/zeth_contracts/contracts/MixerBase.sol @@ -2,8 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; -pragma experimental ABIEncoderV2; +pragma solidity ^0.8.0; import "./Tokens.sol"; import "./OTSchnorrVerifier.sol"; @@ -11,7 +10,7 @@ import "./BaseMerkleTree.sol"; /// MixerBase implements the functions shared across all Mixers (regardless /// which zkSNARK is used) -contract MixerBase is BaseMerkleTree, ERC223ReceivingContract +abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract { // The roots of the different updated trees mapping(bytes32 => bool) private _roots; @@ -79,7 +78,7 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // The unit used for public values (ether in and out), in Wei. Must match // the python wrappers. Use Szabos (10^12 Wei). - uint64 internal constant PUBLIC_UNIT_VALUE_WEI = 1 szabo; + uint64 internal constant PUBLIC_UNIT_VALUE_WEI = 1e12; event LogMix( bytes32 root, @@ -99,7 +98,6 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract address permitted_dispatcher, uint256[2] memory vk_hash ) - public BaseMerkleTree(depth) { bytes32 initialRoot = nodes[0]; @@ -195,7 +193,7 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // data. bytes32 hash_to_be_signed = sha256( abi.encodePacked( - uint256(msg.sender), + uint256(uint160(msg.sender)), ciphertexts[0], ciphertexts[1], inputs @@ -234,7 +232,7 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // 2.a Verify the signature on the hash of data_to_be_signed bytes32 hash_to_be_signed = sha256( abi.encodePacked( - uint256(msg.sender), + uint256(uint160(msg.sender)), // Unfortunately, we have to unroll this for now. We could // replace encodePacked with a custom function but this would // increase complexity and possibly gas usage. @@ -405,6 +403,7 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract ) internal pure + virtual returns(bytes32); // Implementations must implement the verification algorithm of the @@ -414,6 +413,7 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract uint256 public_inputs_hash ) internal + virtual returns (bool); /// This function processes the primary inputs to append and check the root @@ -481,7 +481,7 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // If the vpub_in is > 0, we need to make sure the right amount is paid if (vpub_in > 0) { if (_token != address(0)) { - ERC20 erc20Token = ERC20(_token); + IERC20 erc20Token = IERC20(_token); erc20Token.transferFrom(msg.sender, address(this), vpub_in); } else { require( @@ -493,7 +493,7 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // If vpub_in = 0, return incoming Ether to the caller if (msg.value > 0) { // solhint-disable-next-line - (bool success, ) = msg.sender.call.value(msg.value)(""); + (bool success, ) = msg.sender.call{value: msg.value}(""); require(success, "vpub_in return transfer failed"); } } @@ -502,17 +502,18 @@ contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // msg.sender and send him the appropriate value IF proof is valid if (vpub_out > 0) { if (_token != address(0)) { - ERC20 erc20Token = ERC20(_token); + IERC20 erc20Token = IERC20(_token); erc20Token.transfer(msg.sender, vpub_out); } else { // solhint-disable-next-line - (bool success, ) = msg.sender.call.value(vpub_out)(""); + (bool success, ) = msg.sender.call{value: vpub_out}(""); require(success, "vpub_out transfer failed"); } } } - function add_merkle_root(bytes32 root) internal { + function add_merkle_root(bytes32 root) internal + { _roots[root] = true; } } diff --git a/zeth_contracts/contracts/OTSchnorrVerifier.sol b/zeth_contracts/contracts/OTSchnorrVerifier.sol index dbaa35777..1b16eea83 100644 --- a/zeth_contracts/contracts/OTSchnorrVerifier.sol +++ b/zeth_contracts/contracts/OTSchnorrVerifier.sol @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; +pragma solidity ^0.8.0; /// Reference paper: /// \[Bel07]: @@ -48,7 +48,7 @@ library OTSchnorrVerifier { assembly { - let g := sub(gas, 2000) + let g := sub(gas(), 2000) // pad: // 0x40 hash_to_be_signed diff --git a/zeth_contracts/contracts/Pairing.sol b/zeth_contracts/contracts/Pairing.sol index 4202dc3a8..be351c08b 100644 --- a/zeth_contracts/contracts/Pairing.sol +++ b/zeth_contracts/contracts/Pairing.sol @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; +pragma solidity ^0.8.0; /// Several pairing-related utility functions. /// @@ -69,7 +69,7 @@ library Pairing { bool success; assembly { // Call bn256Add([p1.X, p1.Y, p2.X, p2.Y]) - success := call(sub(gas, 2000), 6, 0, input, 0x80, r, 0x40) + success := call(sub(gas(), 2000), 6, 0, input, 0x80, r, 0x40) // Use "invalid" to make gas estimation work //switch success case 0 { invalid } } @@ -93,7 +93,7 @@ library Pairing { bool success; assembly { // Call bn256ScalarMul([p.X, p.Y, s]) - success := call(sub(gas, 2000), 7, 0, input, 0x60, r, 0x40) + success := call(sub(gas(), 2000), 7, 0, input, 0x60, r, 0x40) // Use "invalid" to make gas estimation work //switch success case 0 { invalid } } @@ -153,7 +153,7 @@ library Pairing { // in the form: e(g1, g2) = e(g'1, g'2), we need to call the // precompiled bn256Pairing on input [(g1, g2), (neg(g'1), g'2)] success := call( - sub(gas, 2000), + sub(gas(), 2000), 8, 0, add(input, 0x20), diff --git a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol index 06c574947..5e85982f1 100644 --- a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol @@ -2,8 +2,7 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; -pragma experimental ABIEncoderV2; +pragma solidity ^0.8.0; import "./Pairing.sol"; import "./AltBN128MixerBase.sol"; @@ -153,6 +152,7 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase uint256 public_inputs_hash ) internal + override returns (bool) { // Scalar field characteristic diff --git a/zeth_contracts/contracts/Tokens.sol b/zeth_contracts/contracts/Tokens.sol index 9a77c9e11..229801681 100644 --- a/zeth_contracts/contracts/Tokens.sol +++ b/zeth_contracts/contracts/Tokens.sol @@ -2,20 +2,34 @@ // // SPDX-License-Identifier: LGPL-3.0+ -pragma solidity ^0.5.0; -pragma experimental ABIEncoderV2; +pragma solidity ^0.8.0; -/// Declare the ERC20 interface in order to handle ERC20 tokens transfers to +/// Declare the IERC20 interface in order to handle ERC20 tokens transfers to /// and from the Mixer. Note that we only declare the functions we are /// interested in, namely, transferFrom() (used to do a Deposit), and /// transfer() (used to do a withdrawal) -contract ERC20 { - function transferFrom(address from, address to, uint256 value) public; - function transfer(address to, uint256 value) public; +abstract contract IERC20 +{ + function transferFrom(address from, address to, uint256 value) + public + virtual + returns (bool); + + function transfer(address to, uint256 value) + public + virtual + returns (bool); + + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval( + address indexed owner, + address indexed spender, + uint256 value); } /// ERC223 token compatible contract -contract ERC223ReceivingContract { +contract ERC223ReceivingContract +{ // See: // solhint-disable-next-line max-line-length // https://github.com/Dexaran/ERC223-token-standard/blob/Recommended/Receiver_Interface.sol diff --git a/zeth_contracts/package.json b/zeth_contracts/package.json index 447f7d629..939d00d73 100644 --- a/zeth_contracts/package.json +++ b/zeth_contracts/package.json @@ -17,7 +17,6 @@ "dependencies": { "add": "^2.0.6", "ethereumjs-abi": "^0.6.8", - "openzeppelin-solidity": "^2.4.0", "shell-escape": "^0.2.0", "solhint": "^3.3.2", "strip-hex-prefix": "^1.0.0", From 2da6126bbc173a103c3091027e32ab255275687a Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 10 Feb 2021 17:25:56 +0000 Subject: [PATCH 070/137] ci: allow better reuse of some util functions --- scripts/ci | 165 +++++------------------------------------- scripts/ci_utils.sh | 169 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+), 146 deletions(-) create mode 100644 scripts/ci_utils.sh diff --git a/scripts/ci b/scripts/ci index 85a284f13..5054e8bbf 100755 --- a/scripts/ci +++ b/scripts/ci @@ -4,6 +4,9 @@ platform=`uname` echo platform=${platform} echo "running against commit: "`git log --oneline --no-decorate -n 1` +# Include the CI utils functions +. scripts/ci_utils.sh + set -x set -e @@ -19,118 +22,6 @@ function _setup_client() { popd } -function _setup_ganache() { - pushd zeth_contracts - npm config set python python2.7 - npm config set engine-strict true - npm config set unsafe-perm true - npm install --unsafe-perm - popd -} - -function _ganache_is_active() { - curl -sf \ - -H "Content-Type: application/json" \ - -X POST \ - --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[]}' \ - http://localhost:8545 -} - -function _start_ganache() { - pushd zeth_contracts - - npm run testrpc > ganache.stdout & - echo $! > ganache.pid - - # Wait for ganache to be active - while ! _ganache_is_active ; do - echo "_start_ganache: waiting for ganache ..." - sleep 1 - done - echo "_start_ganache: ganache is active" - - popd -} - -function _stop_ganache() { - pushd zeth_contracts - if ! [ -e ganache.pid ] ; then - echo "_stop_ganache: no PID file" - return 1 - fi - - pid=`cat ganache.pid` - while (kill "${pid}") ; do - sleep 0.5 - done - rm ganache.pid - echo "_stop_ganache: ganache stopped" - - popd -} - -function _prover_server_is_active() { - # Assume the client env is active - zeth get-verification-key -} - -function _start_prover_server() { - # Requires the client env (for _prover_server_is_active) - . client/env/bin/activate - pushd build - - ./prover_server/prover_server > prover_server.stdout & - echo $! > prover_server.pid - - # Wait for prover_server to be active - while ! _prover_server_is_active ; do - echo "_start_prover_server: waiting for server ..." - sleep 1 - done - echo "_start_prover_server:: prover_server is active" - - popd # build - deactivate -} - -function _stop_prover_server() { - pushd build - - if ! [ -e prover_server.pid ] ; then - echo "_stop_prover_server: no PID file" - return 1 - fi - - pid=`cat prover_server.pid` - while (kill "${pid}") ; do - sleep 0.5 - done - rm prover_server.pid - echo "_stop_prover_server:: prover_server stopped" - - popd # build -} - -function _build_setup() { - # Extra deps for native builds - if [ "${platform}" == "Linux" ] ; then - if (which apk) ; then - # Packages already available in Docker build - echo -n # null op required for syntax - else - sudo apt install \ - libboost-dev \ - libboost-system-dev \ - libboost-filesystem-dev \ - libboost-program-options-dev \ - libgmp-dev \ - libprocps-dev \ - libxslt1-dev \ - pkg-config - fi - fi -} - function check_format() { scripts/format git diff --no-ext-diff | head -n 20 > format_errors @@ -146,9 +37,8 @@ function check_format() { } function check_contracts() { - # Setup the zeth_contracts dir - _setup_ganache + ganache_setup # Run checks in zeth_contracts pushd zeth_contracts @@ -158,7 +48,7 @@ function check_contracts() { # Run contract tests (in python) _setup_client - _start_ganache + ganache_start pushd client . env/bin/activate @@ -166,8 +56,7 @@ function check_contracts() { deactivate popd - _stop_ganache - + ganache_stop } function check_client() { @@ -226,12 +115,12 @@ function mpc_tests() { function prover_tests() { # Native code is built. Setup client and ganache. - _setup_ganache + ganache_setup _setup_client # Start servers - _start_ganache - _start_prover_server + ganache_start + prover_server_start # Enter client env and run prover test scripts . client/env/bin/activate @@ -240,19 +129,19 @@ function prover_tests() { deactivate # Stop servers - _stop_prover_server - _stop_ganache + prover_server_stop + ganache_stop } function integration_tests() { # Native code is built. Setup client and ganache. - _setup_ganache + ganache_setup _setup_client # Start servers - _start_ganache - _start_prover_server + ganache_start + prover_server_start # Enter client env and run client test script . client/env/bin/activate @@ -260,13 +149,13 @@ function integration_tests() { deactivate # Stop servers - _stop_prover_server - _stop_ganache + prover_server_stop + ganache_stop } function build() { - _build_setup + cpp_build_setup # Additional compilation flags cxx_flags="-Werror" @@ -322,29 +211,13 @@ function build() { function ci_setup() { - if [ "${platform}" == "Darwin" ] ; then - # Some of these commands can fail (if packages are already installed, - # etc), hence the `|| echo`. - brew update || echo - brew install \ - gmp \ - grpc \ - protobuf \ - boost \ - openssl \ - cmake \ - libtool \ - autoconf \ - automake \ - || echo - fi - # The base docker image we use is Alpine # See: https://www.alpinelinux.org/ if [ "${platform}" == "Linux" ] ; then if (which apk) ; then - apk add --update npm + + # apk add --update npm # `py3-virtualenv` depends on `python3` # which installs the latest version of python3 diff --git a/scripts/ci_utils.sh b/scripts/ci_utils.sh new file mode 100644 index 000000000..720f5e839 --- /dev/null +++ b/scripts/ci_utils.sh @@ -0,0 +1,169 @@ +# Utility functions for CI tasks. +# +# All functions expect to be executed the root directory of the repository, and +# will exit with this as the current directory. + +# +# GANACHE +# + +function ganache_setup() { + if [ "${platform}" == "Linux" ] ; then + if (which apk) ; then + apk add --update npm + + # # `py3-virtualenv` depends on `python3` + # # which installs the latest version of python3 + # # See: https://pkgs.alpinelinux.org/package/edge/main/x86/python3 + # # https://build.alpinelinux.org/buildlogs/build-edge-x86/main/python3/python3-3.8.2-r6.log + # apk add \ + # py3-virtualenv \ + # libffi-dev \ + # python3-dev + + # # Install openssl for the mpc tests + # apk add openssl + # else + # sudo apt update + # sudo apt install python3-venv + fi + fi + + pushd zeth_contracts + npm config set python python2.7 + npm config set engine-strict true + npm config set unsafe-perm true + npm install --unsafe-perm + popd +} + +function ganache_is_active() { + curl -sf \ + -H "Content-Type: application/json" \ + -X POST \ + --data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[]}' \ + http://localhost:8545 +} + +function ganache_start() { + pushd zeth_contracts + + npm run testrpc > ganache.stdout & + echo $! > ganache.pid + + # Wait for ganache to be active + while ! ganache_is_active ; do + echo "ganache_start: waiting for ganache ..." + sleep 1 + done + echo "ganache_start: ganache is ACTIVE" + + popd +} + +function ganache_stop() { + pushd zeth_contracts + if ! [ -e ganache.pid ] ; then + echo "ganache_stop: no PID file" + return 1 + fi + + pid=`cat ganache.pid` + while (kill "${pid}") ; do + sleep 0.5 + done + rm ganache.pid + echo "ganache_stop: STOPPED" + + popd +} + +# +# PROVER SERVER +# +# These functions assume that the prover_server has been built in the build +# directory. + +function prover_server_is_active() { + # Assume the client env is active + zeth get-verification-key +} + +function prover_server_start() { + # Requires the client env (for _prover_server_is_active) + . client/env/bin/activate + pushd build + + ./prover_server/prover_server > prover_server.stdout & + echo $! > prover_server.pid + + # Wait for prover_server to be active + while ! prover_server_is_active ; do + echo "prover_server_start: waiting for server ..." + sleep 1 + done + echo "prover_server_start:: prover_server is ACTIVE" + + popd # build + deactivate +} + +function prover_server_stop() { + pushd build + + if ! [ -e prover_server.pid ] ; then + echo "prover_server_stop: no PID file" + return 1 + fi + + pid=`cat prover_server.pid` + while (kill "${pid}") ; do + sleep 0.5 + done + rm prover_server.pid + echo "prover_server_stop:: STOPPED" + + popd # build +} + +# +# DEPENDENCIES +# + +function cpp_build_setup() { + # Extra deps for native builds + + if [ "${platform}" == "Darwin" ] ; then + # Some of these commands can fail (if packages are already installed, + # etc), hence the `|| echo`. + brew update || echo + brew install \ + gmp \ + grpc \ + protobuf \ + boost \ + openssl \ + cmake \ + libtool \ + autoconf \ + automake \ + || echo + fi + + if [ "${platform}" == "Linux" ] ; then + if (which apk) ; then + # Packages already available in Docker build + echo -n # null op required for syntax + else + sudo apt install \ + libboost-dev \ + libboost-system-dev \ + libboost-filesystem-dev \ + libboost-program-options-dev \ + libgmp-dev \ + libprocps-dev \ + libxslt1-dev \ + pkg-config + fi + fi +} From fde44b30269e330db4a2c25402d0d3aa1cf44e43 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 11 Feb 2021 11:01:33 +0000 Subject: [PATCH 071/137] ci: background launching --- scripts/ci | 8 +--- scripts/ci_utils.sh | 114 ++++++++++++++++++++------------------------ 2 files changed, 55 insertions(+), 67 deletions(-) diff --git a/scripts/ci b/scripts/ci index 5054e8bbf..73a62fbd3 100755 --- a/scripts/ci +++ b/scripts/ci @@ -78,8 +78,6 @@ function check_cpp() { # Configure and run clang-tidy cppcheck mkdir -p build pushd build - # cmake -DUSE_CPP_CHECK=ON -DUSE_CLANG_TIDY=ON .. - # make VERBOSE=1 clang-tidy -j 5 cmake -DUSE_CPP_CHECK=ON .. make VERBOSE=1 cppcheck -j 5 popd @@ -217,10 +215,8 @@ function ci_setup() { if (which apk) ; then - # apk add --update npm - - # `py3-virtualenv` depends on `python3` - # which installs the latest version of python3 + # `py3-virtualenv` depends on `python3` which installs the latest + # version of python3. # See: https://pkgs.alpinelinux.org/package/edge/main/x86/python3 # https://build.alpinelinux.org/buildlogs/build-edge-x86/main/python3/python3-3.8.2-r6.log apk add \ diff --git a/scripts/ci_utils.sh b/scripts/ci_utils.sh index 720f5e839..751994531 100644 --- a/scripts/ci_utils.sh +++ b/scripts/ci_utils.sh @@ -3,6 +3,46 @@ # All functions expect to be executed the root directory of the repository, and # will exit with this as the current directory. +# Launch a server in the background and wait for it to be ready, recording the +# pid in a file. +# +# 1 - server cmd +# 2 - server check cmd +# 3 - pid file +# 4 - stdout file +function server_start() { + $1 > $4 & + pid=$! + echo pid is ${pid} + echo ${pid} > $3 + + # Wait for prover_server to be active + while ! $2 ; do + echo "server_start: waiting for $1 ..." + sleep 1 + done + + echo "server_start: $1 is ACTIVE" +} + +# Stop a background server, given a name and pid file +# +# 1 - server name +# 2 - pid file +function server_stop() { + if ! [ -e $2 ] ; then + echo "server_stop: no PID file for $1" + return 1 + fi + + pid=`cat $2` + while (kill "${pid}") ; do + sleep 0.5 + done + rm $2 + echo "server_stop: $1 STOPPED" +} + # # GANACHE # @@ -11,21 +51,6 @@ function ganache_setup() { if [ "${platform}" == "Linux" ] ; then if (which apk) ; then apk add --update npm - - # # `py3-virtualenv` depends on `python3` - # # which installs the latest version of python3 - # # See: https://pkgs.alpinelinux.org/package/edge/main/x86/python3 - # # https://build.alpinelinux.org/buildlogs/build-edge-x86/main/python3/python3-3.8.2-r6.log - # apk add \ - # py3-virtualenv \ - # libffi-dev \ - # python3-dev - - # # Install openssl for the mpc tests - # apk add openssl - # else - # sudo apt update - # sudo apt install python3-venv fi fi @@ -47,34 +72,17 @@ function ganache_is_active() { function ganache_start() { pushd zeth_contracts - - npm run testrpc > ganache.stdout & - echo $! > ganache.pid - - # Wait for ganache to be active - while ! ganache_is_active ; do - echo "ganache_start: waiting for ganache ..." - sleep 1 - done - echo "ganache_start: ganache is ACTIVE" - + server_start \ + "npm run testrpc" \ + ganache_is_active \ + ganache.pid \ + ganache.stdout popd } function ganache_stop() { pushd zeth_contracts - if ! [ -e ganache.pid ] ; then - echo "ganache_stop: no PID file" - return 1 - fi - - pid=`cat ganache.pid` - while (kill "${pid}") ; do - sleep 0.5 - done - rm ganache.pid - echo "ganache_stop: STOPPED" - + server_stop ganache ganache.pid popd } @@ -90,19 +98,15 @@ function prover_server_is_active() { } function prover_server_start() { - # Requires the client env (for _prover_server_is_active) + # Requires the client env (for prover_server_is_active) . client/env/bin/activate pushd build - ./prover_server/prover_server > prover_server.stdout & - echo $! > prover_server.pid - - # Wait for prover_server to be active - while ! prover_server_is_active ; do - echo "prover_server_start: waiting for server ..." - sleep 1 - done - echo "prover_server_start:: prover_server is ACTIVE" + server_start \ + ./prover_server/prover_server \ + prover_server_is_active \ + prover_server.pid \ + prover_server.stdout popd # build deactivate @@ -110,19 +114,7 @@ function prover_server_start() { function prover_server_stop() { pushd build - - if ! [ -e prover_server.pid ] ; then - echo "prover_server_stop: no PID file" - return 1 - fi - - pid=`cat prover_server.pid` - while (kill "${pid}") ; do - sleep 0.5 - done - rm prover_server.pid - echo "prover_server_stop:: STOPPED" - + server_stop prover_server prover_server.pid popd # build } From 870a7fea8f2274137a65eb4c86809fa2fdf66c3a Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 11 Feb 2021 12:16:47 +0000 Subject: [PATCH 072/137] ci: recomment ccache --- .github/workflows/onpullrequest-build-ubuntu.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/onpullrequest-build-ubuntu.yml b/.github/workflows/onpullrequest-build-ubuntu.yml index 829d4ebed..025532ce8 100644 --- a/.github/workflows/onpullrequest-build-ubuntu.yml +++ b/.github/workflows/onpullrequest-build-ubuntu.yml @@ -56,11 +56,11 @@ jobs: with: key: grpc-1.31.x-${{ runner.os }} path: depends/grpc - - name: Cache ccache - uses: actions/cache@v2 - with: - key: prover-tests-ccache-${{ needs.onpr-submodules.outputs.commits }}-${{ matrix.curve }}-${{ runner.os }} - path: ~/.ccache + # - name: Cache ccache + # uses: actions/cache@v2 + # with: + # key: prover-tests-ccache-${{ needs.onpr-submodules.outputs.commits }}-${{ matrix.curve }}-${{ runner.os }} + # path: ~/.ccache - name: Cache pip uses: actions/cache@v2 with: From 0f77a97d2082a865504b7b4c76817a5667185bf5 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 18 Jan 2021 11:45:49 +0000 Subject: [PATCH 073/137] submodule: ganache-cli [v6.10.3-clearmatics] --- depends/ganache-cli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/ganache-cli b/depends/ganache-cli index 8adb190c9..6e762a5f8 160000 --- a/depends/ganache-cli +++ b/depends/ganache-cli @@ -1 +1 @@ -Subproject commit 8adb190c983436467dfa6ad71d49c5d830bcab32 +Subproject commit 6e762a5f83fbacd2f4dca6d17b996787bfc05d0b From e2b7262297a6f71eb4097576cf9881ff5a217ead Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 3 Mar 2021 16:02:45 +0000 Subject: [PATCH 074/137] libzeth: support writing constraint system from simple_test --- libzeth/tests/circuits/simple_test.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/libzeth/tests/circuits/simple_test.cpp b/libzeth/tests/circuits/simple_test.cpp index 5a2a2b048..49fb35b6c 100644 --- a/libzeth/tests/circuits/simple_test.cpp +++ b/libzeth/tests/circuits/simple_test.cpp @@ -5,8 +5,10 @@ #include "simple_test.hpp" #include "core/utils.hpp" +#include "libzeth/serialization/r1cs_serialization.hpp" #include "zeth_config.h" +#include #include using namespace libsnark; @@ -15,6 +17,8 @@ using namespace libzeth; using pp = defaults::pp; using Field = defaults::Field; +boost::filesystem::path g_output_dir = boost::filesystem::path(""); + namespace { @@ -28,6 +32,14 @@ TEST(SimpleTests, SimpleCircuitProof) const r1cs_constraint_system constraint_system = pb.get_constraint_system(); + // Write to file if output directory is given. + if (!g_output_dir.empty()) { + boost::filesystem::path outpath = + g_output_dir / "simple_circuit_r1cs.json"; + std::ofstream r1cs_stream(outpath.c_str()); + libzeth::r1cs_write_json(pb, r1cs_stream); + } + const r1cs_primary_input primary{12}; const r1cs_auxiliary_input auxiliary{1, 1, 1}; @@ -78,14 +90,18 @@ TEST(SimpleTests, SimpleCircuitProofPow2Domain) int main(int argc, char **argv) { - // /!\ WARNING: Do once for all tests. Do not - // forget to do this !!!! + // WARNING: Do once for all tests. Do not forget to do this. pp::init_public_params(); // Remove stdout noise from libff libff::inhibit_profiling_counters = true; libff::inhibit_profiling_info = true; - // Run ::testing::InitGoogleTest(&argc, argv); + + // Extract the test data destination dir, if passed on the command line. + if (argc > 1) { + g_output_dir = boost::filesystem::path(argv[1]); + } + return RUN_ALL_TESTS(); } From de7d5b8355d9fddddab352ab3d5d166d9c1e3be0 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Fri, 26 Feb 2021 18:59:57 +0000 Subject: [PATCH 075/137] libzeth: consistent naming of group elements serialization functions --- libzeth/core/group_element_utils.hpp | 9 ++--- libzeth/core/group_element_utils.tcc | 13 +++---- libzeth/serialization/r1cs_serialization.tcc | 8 ++--- libzeth/snarks/groth16/groth16_snark.tcc | 16 ++++----- libzeth/snarks/pghr13/pghr13_snark.tcc | 34 +++++++++---------- libzeth/tests/core/ec_operation_data_test.cpp | 16 ++++----- .../tests/core/group_element_utils_test.cpp | 12 +++---- 7 files changed, 55 insertions(+), 53 deletions(-) diff --git a/libzeth/core/group_element_utils.hpp b/libzeth/core/group_element_utils.hpp index 6c3577e91..36194cc7a 100644 --- a/libzeth/core/group_element_utils.hpp +++ b/libzeth/core/group_element_utils.hpp @@ -12,18 +12,19 @@ namespace libzeth /// Write a group element as a json string to a stream template -void point_affine_write_json(const GroupT &point, std::ostream &out_s); +void group_element_write_json(const GroupT &point, std::ostream &out_s); /// Read a JSON string from a stream and convert it into a group element template -void point_affine_read_json(GroupT &point, std::istream &in_s); +void group_element_read_json(GroupT &point, std::istream &in_s); /// Convert a group element to a json string (array of hexadecimal strings). -template std::string point_affine_to_json(const GroupT &point); +template +std::string group_element_to_json(const GroupT &point); /// Convert a JSON string into a group element template -GroupT point_affine_from_json(const std::string &json); +GroupT group_element_from_json(const std::string &json); } // namespace libzeth diff --git a/libzeth/core/group_element_utils.tcc b/libzeth/core/group_element_utils.tcc index e3f65327c..270264a5d 100644 --- a/libzeth/core/group_element_utils.tcc +++ b/libzeth/core/group_element_utils.tcc @@ -30,7 +30,7 @@ template static bool coordinate_equals_one(const FieldT &f) } // namespace internal template -void point_affine_write_json(const GroupT &point, std::ostream &out_s) +void group_element_write_json(const GroupT &point, std::ostream &out_s) { GroupT affine_p = point; affine_p.to_affine_coordinates(); @@ -42,7 +42,7 @@ void point_affine_write_json(const GroupT &point, std::ostream &out_s) } template -void point_affine_read_json(GroupT &point, std::istream &in_s) +void group_element_read_json(GroupT &point, std::istream &in_s) { char sep; @@ -73,18 +73,19 @@ void point_affine_read_json(GroupT &point, std::istream &in_s) } } -template std::string point_affine_to_json(const GroupT &point) +template std::string group_element_to_json(const GroupT &point) { std::stringstream ss; - point_affine_write_json(point, ss); + group_element_write_json(point, ss); return ss.str(); } -template GroupT point_affine_from_json(const std::string &json) +template +GroupT group_element_from_json(const std::string &json) { std::stringstream ss(json); GroupT result; - point_affine_read_json(result, ss); + group_element_read_json(result, ss); return result; } diff --git a/libzeth/serialization/r1cs_serialization.tcc b/libzeth/serialization/r1cs_serialization.tcc index 38636f50c..966761dc3 100644 --- a/libzeth/serialization/r1cs_serialization.tcc +++ b/libzeth/serialization/r1cs_serialization.tcc @@ -80,9 +80,9 @@ std::string accumulation_vector_to_json( { std::stringstream ss; unsigned vect_length = acc_vector.rest.indices.size() + 1; - ss << "[" << point_affine_to_json(acc_vector.first); + ss << "[" << group_element_to_json(acc_vector.first); for (size_t i = 0; i < vect_length - 1; ++i) { - ss << ", " << point_affine_to_json(acc_vector.rest.values[i]); + ss << ", " << group_element_to_json(acc_vector.rest.values[i]); } ss << "]"; std::string vect_json_str = ss.str(); @@ -122,7 +122,7 @@ libsnark::accumulation_vector> accumulation_vector_from_json( // start_idx end_idx element_str = acc_vector_str.substr(start_idx, end_idx + 2 - start_idx); - libff::G1 front = point_affine_from_json>(element_str); + libff::G1 front = group_element_from_json>(element_str); start_idx = acc_vector_str.find(prefix, end_idx); // Extract remaining elements @@ -134,7 +134,7 @@ libsnark::accumulation_vector> accumulation_vector_from_json( } element_str = acc_vector_str.substr(start_idx, end_idx + 2 - start_idx); - rest.push_back(point_affine_from_json>(element_str)); + rest.push_back(group_element_from_json>(element_str)); start_idx = acc_vector_str.find(prefix, end_idx); } while (start_idx != std::string::npos); diff --git a/libzeth/snarks/groth16/groth16_snark.tcc b/libzeth/snarks/groth16/groth16_snark.tcc index 7482810be..819802b13 100644 --- a/libzeth/snarks/groth16/groth16_snark.tcc +++ b/libzeth/snarks/groth16/groth16_snark.tcc @@ -56,13 +56,13 @@ std::ostream &groth16_snark::verification_key_write_json( const size_t abc_length = vk.ABC_g1.rest.indices.size() + 1; out_s << "{" << "\n" - << " \"alpha\": " << point_affine_to_json(vk.alpha_g1) << ",\n" - << " \"beta\": " << point_affine_to_json(vk.beta_g2) << ",\n" - << " \"delta\": " << point_affine_to_json(vk.delta_g2) << ",\n" - << " \"ABC\": [\n " << point_affine_to_json(vk.ABC_g1.first); + << " \"alpha\": " << group_element_to_json(vk.alpha_g1) << ",\n" + << " \"beta\": " << group_element_to_json(vk.beta_g2) << ",\n" + << " \"delta\": " << group_element_to_json(vk.delta_g2) << ",\n" + << " \"ABC\": [\n " << group_element_to_json(vk.ABC_g1.first); for (size_t i = 1; i < abc_length; ++i) { out_s << ",\n " - << point_affine_to_json(vk.ABC_g1.rest.values[i - 1]); + << group_element_to_json(vk.ABC_g1.rest.values[i - 1]); } return out_s << "\n ]\n}"; } @@ -134,9 +134,9 @@ template std::ostream &groth16_snark::proof_write_json( const typename groth16_snark::proof &proof, std::ostream &out_s) { - out_s << "{\n \"a\": " << point_affine_to_json(proof.g_A) - << ",\n \"b\": " << point_affine_to_json(proof.g_B) - << ",\n \"c\": " << point_affine_to_json(proof.g_C) << "\n}"; + out_s << "{\n \"a\": " << group_element_to_json(proof.g_A) + << ",\n \"b\": " << group_element_to_json(proof.g_B) + << ",\n \"c\": " << group_element_to_json(proof.g_C) << "\n}"; return out_s; } diff --git a/libzeth/snarks/pghr13/pghr13_snark.tcc b/libzeth/snarks/pghr13/pghr13_snark.tcc index 878dd8038..4d9278a3a 100644 --- a/libzeth/snarks/pghr13/pghr13_snark.tcc +++ b/libzeth/snarks/pghr13/pghr13_snark.tcc @@ -57,19 +57,19 @@ std::ostream &pghr13_snark::verification_key_write_json( unsigned ic_length = vk.encoded_IC_query.rest.indices.size() + 1; os << "{\n"; - os << " \"a\": " << point_affine_to_json(vk.alphaA_g2) << ",\n"; - os << " \"b\": " << point_affine_to_json(vk.alphaB_g1) << ",\n"; - os << " \"c\": " << point_affine_to_json(vk.alphaC_g2) << ",\n"; - os << " \"g\": " << point_affine_to_json(vk.gamma_g2) << ",\n"; - os << " \"gb1\": " << point_affine_to_json(vk.gamma_beta_g1) << ",\n"; - os << " \"gb2\": " << point_affine_to_json(vk.gamma_beta_g2) << ",\n"; - os << " \"z\": " << point_affine_to_json(vk.rC_Z_g2) << ",\n"; + os << " \"a\": " << group_element_to_json(vk.alphaA_g2) << ",\n"; + os << " \"b\": " << group_element_to_json(vk.alphaB_g1) << ",\n"; + os << " \"c\": " << group_element_to_json(vk.alphaC_g2) << ",\n"; + os << " \"g\": " << group_element_to_json(vk.gamma_g2) << ",\n"; + os << " \"gb1\": " << group_element_to_json(vk.gamma_beta_g1) << ",\n"; + os << " \"gb2\": " << group_element_to_json(vk.gamma_beta_g2) << ",\n"; + os << " \"z\": " << group_element_to_json(vk.rC_Z_g2) << ",\n"; - os << "\"IC\" :[" << point_affine_to_json(vk.encoded_IC_query.first); + os << "\"IC\" :[" << group_element_to_json(vk.encoded_IC_query.first); for (size_t i = 1; i < ic_length; ++i) { os << "," - << point_affine_to_json(vk.encoded_IC_query.rest.values[i - 1]); + << group_element_to_json(vk.encoded_IC_query.rest.values[i - 1]); } os << "]\n"; @@ -114,14 +114,14 @@ std::ostream &pghr13_snark::proof_write_json( const typename pghr13_snark::proof &proof, std::ostream &os) { os << "{\n"; - os << " \"a\": " << point_affine_to_json(proof.g_A.g) << ",\n"; - os << " \"a_p\": " << point_affine_to_json(proof.g_A.h) << ",\n"; - os << " \"b\": " << point_affine_to_json(proof.g_B.g) << ",\n"; - os << " \"b_p\": " << point_affine_to_json(proof.g_B.h) << ",\n"; - os << " \"c\": " << point_affine_to_json(proof.g_C.g) << ",\n"; - os << " \"c_p\": " << point_affine_to_json(proof.g_C.h) << ",\n"; - os << " \"h\": " << point_affine_to_json(proof.g_H) << ",\n"; - os << " \"k\": " << point_affine_to_json(proof.g_K) << "\n"; + os << " \"a\": " << group_element_to_json(proof.g_A.g) << ",\n"; + os << " \"a_p\": " << group_element_to_json(proof.g_A.h) << ",\n"; + os << " \"b\": " << group_element_to_json(proof.g_B.g) << ",\n"; + os << " \"b_p\": " << group_element_to_json(proof.g_B.h) << ",\n"; + os << " \"c\": " << group_element_to_json(proof.g_C.g) << ",\n"; + os << " \"c_p\": " << group_element_to_json(proof.g_C.h) << ",\n"; + os << " \"h\": " << group_element_to_json(proof.g_H) << ",\n"; + os << " \"k\": " << group_element_to_json(proof.g_K) << "\n"; os << "}"; return os; } diff --git a/libzeth/tests/core/ec_operation_data_test.cpp b/libzeth/tests/core/ec_operation_data_test.cpp index 9cc79a4eb..82327564c 100644 --- a/libzeth/tests/core/ec_operation_data_test.cpp +++ b/libzeth/tests/core/ec_operation_data_test.cpp @@ -134,13 +134,13 @@ TEST(ECOperationDataTest, BW6_761) ASSERT_FALSE(g2_not_in_subgroup.is_in_safe_subgroup()); std::cout << " g1_not_well_formed: "; - point_affine_write_json(g1_not_well_formed, std::cout); + group_element_write_json(g1_not_well_formed, std::cout); std::cout << "\n g1_not_in_subgroup: "; - point_affine_write_json(g1_not_in_subgroup, std::cout); + group_element_write_json(g1_not_in_subgroup, std::cout); std::cout << "\n g2_not_well_formed: "; - point_affine_write_json(g2_not_well_formed, std::cout); + group_element_write_json(g2_not_well_formed, std::cout); std::cout << "\n g2_not_in_subgroup: "; - point_affine_write_json(g2_not_in_subgroup, std::cout); + group_element_write_json(g2_not_in_subgroup, std::cout); std::cout << "\n"; } @@ -174,13 +174,13 @@ TEST(ECOperationDataTest, BLS12_377) ASSERT_FALSE(g2_not_in_subgroup.is_in_safe_subgroup()); std::cout << " g1_not_well_formed: "; - point_affine_write_json(g1_not_well_formed, std::cout); + group_element_write_json(g1_not_well_formed, std::cout); std::cout << "\n g1_not_in_subgroup: "; - point_affine_write_json(g1_not_in_subgroup, std::cout); + group_element_write_json(g1_not_in_subgroup, std::cout); std::cout << "\n g2_not_well_formed: "; - point_affine_write_json(g2_not_well_formed, std::cout); + group_element_write_json(g2_not_well_formed, std::cout); std::cout << "\n g2_not_in_subgroup: "; - point_affine_write_json(g2_not_in_subgroup, std::cout); + group_element_write_json(g2_not_in_subgroup, std::cout); std::cout << "\n"; } diff --git a/libzeth/tests/core/group_element_utils_test.cpp b/libzeth/tests/core/group_element_utils_test.cpp index daba16dd8..ba0817163 100644 --- a/libzeth/tests/core/group_element_utils_test.cpp +++ b/libzeth/tests/core/group_element_utils_test.cpp @@ -27,10 +27,10 @@ TEST(GroupElementUtilsTest, G1EncodeDecodeJsonTestVectorAltBN128) "\"0x2857bd14bbc09767bed8e913d3ccb42b2bc8738f715417dd6f020725d22bcd90\"" "]"; G1 g1 = Fr(13) * G1::one(); - std::string g1_json = libzeth::point_affine_to_json(g1); + std::string g1_json = libzeth::group_element_to_json(g1); ASSERT_EQ(g1_json_expected, g1_json); - G1 g1_decoded = libzeth::point_affine_from_json(g1_json); + G1 g1_decoded = libzeth::group_element_from_json(g1_json); ASSERT_EQ(g1, g1_decoded); } @@ -50,8 +50,8 @@ TEST(GroupElementUtilsTest, G2EncodeJsonTestVectorAltBN128) "\"0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa\"" "]]"; G2 g2 = G2::one(); - const std::string g2_json = libzeth::point_affine_to_json(g2); - const G2 g2_decoded = libzeth::point_affine_from_json(g2_json); + const std::string g2_json = libzeth::group_element_to_json(g2); + const G2 g2_decoded = libzeth::group_element_from_json(g2_json); ASSERT_EQ(g2_json_expected, g2_json); ASSERT_EQ(g2, g2_decoded); @@ -60,8 +60,8 @@ TEST(GroupElementUtilsTest, G2EncodeJsonTestVectorAltBN128) template static void single_group_element_encode_decode_test(const GroupT &g) { - const std::string g_json = libzeth::point_affine_to_json(g); - const GroupT g_decoded = libzeth::point_affine_from_json(g_json); + const std::string g_json = libzeth::group_element_to_json(g); + const GroupT g_decoded = libzeth::group_element_from_json(g_json); ASSERT_EQ(g, g_decoded); } From ed561054b7051eceb02f437d71ff6bc3e9bd6755 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Fri, 26 Feb 2021 18:54:17 +0000 Subject: [PATCH 076/137] libzeth: generic field element binary serialization functions --- libzeth/core/field_element_utils.hpp | 11 +++ libzeth/core/field_element_utils.tcc | 55 +++++++++++++ libzeth/core/group_element_utils.hpp | 11 +++ libzeth/core/group_element_utils.tcc | 22 ++++++ .../tests/core/field_element_utils_test.cpp | 44 +++++++++++ .../tests/core/group_element_utils_test.cpp | 78 +++++++++++++++---- 6 files changed, 204 insertions(+), 17 deletions(-) diff --git a/libzeth/core/field_element_utils.hpp b/libzeth/core/field_element_utils.hpp index 891d942b5..b38b59a82 100644 --- a/libzeth/core/field_element_utils.hpp +++ b/libzeth/core/field_element_utils.hpp @@ -58,6 +58,17 @@ template std::string field_element_to_json(const FieldT &el); template FieldT field_element_from_json(const std::string &json); +/// Write a field element as bytes. Base field elements are written in plain +/// (non-Montgomery) form as fixed-size big-endian integers. Extension fields +/// are written as a series of components. +template +void field_element_write_bytes(const FieldT &el, std::ostream &out_s); + +/// Read a field element as bytes, in the format described for +/// field_element_write_bytes. +template +void field_element_read_bytes(FieldT &el, std::istream &in_s); + } // namespace libzeth #include "libzeth/core/field_element_utils.tcc" diff --git a/libzeth/core/field_element_utils.tcc b/libzeth/core/field_element_utils.tcc index 709128aa3..824f2cd61 100644 --- a/libzeth/core/field_element_utils.tcc +++ b/libzeth/core/field_element_utils.tcc @@ -100,6 +100,49 @@ public: } }; +// Generic reader and write for fields and field extensions. +template class field_element_bytes +{ +public: + static void write(const FieldT &field_el, std::ostream &out_s) + { + for (size_t i = 0; i < FieldT::tower_extension_degree; ++i) { + field_element_write_bytes(field_el.coeffs[i], out_s); + } + } + static void read(FieldT &field_el, std::istream &in_s) + { + for (size_t i = 0; i < FieldT::tower_extension_degree; ++i) { + field_element_read_bytes(field_el.coeffs[i], in_s); + } + } +}; + +/// Implementation of field_element_bytes for the base-case of Fp_model types. +/// Big-endian bigint values (i.e. not in montgomery form). +template &modulus> +class field_element_bytes> +{ +public: + using Field = libff::Fp_model; + static void write(const Field &field_el, std::ostream &out_s) + { + // Convert to bigint, reverse bytes in-place, and write to stream. + const libff::bigint bi = field_el.as_bigint(); + std::reverse((char *)(&bi), (char *)(&bi + 1)); + out_s.write((const char *)(&bi.data[0]), sizeof(bi)); + } + static void read(Field &field_el, std::istream &in_s) + { + // Read bigint from stream, reverse bytes in-place and convert to field + // element. + libff::bigint res; + in_s.read((char *)(&res.data[0]), sizeof(res)); + std::reverse((char *)(&res), (char *)(&res + 1)); + field_el = Field(res); + } +}; + } // namespace internal template @@ -161,6 +204,18 @@ FieldT field_element_from_json(const std::string &json) return result; } +template +void field_element_write_bytes(const FieldT &el, std::ostream &out_s) +{ + internal::field_element_bytes::write(el, out_s); +} + +template +void field_element_read_bytes(FieldT &el, std::istream &in_s) +{ + internal::field_element_bytes::read(el, in_s); +} + } // namespace libzeth #endif // __ZETH_FIELD_ELEMENT_UTILS_TCC__ diff --git a/libzeth/core/group_element_utils.hpp b/libzeth/core/group_element_utils.hpp index 36194cc7a..a30b50c0b 100644 --- a/libzeth/core/group_element_utils.hpp +++ b/libzeth/core/group_element_utils.hpp @@ -26,6 +26,17 @@ std::string group_element_to_json(const GroupT &point); template GroupT group_element_from_json(const std::string &json); +/// Write a group element as bytes to a stream. The elements are written as X +/// and Y coordinates of the affine form, where each coordinate is written +/// using field_element_write_bytes. +template +void group_element_write_bytes(const GroupT &point, std::ostream &out_s); + +/// Read a group elements as bytes from a stream, in the format described for +/// group_element_write_bytes. +template +void group_element_read_bytes(GroupT &point, std::istream &in_s); + } // namespace libzeth #include "libzeth/core/group_element_utils.tcc" diff --git a/libzeth/core/group_element_utils.tcc b/libzeth/core/group_element_utils.tcc index 270264a5d..bd0b7790e 100644 --- a/libzeth/core/group_element_utils.tcc +++ b/libzeth/core/group_element_utils.tcc @@ -89,6 +89,28 @@ GroupT group_element_from_json(const std::string &json) return result; } +template +void group_element_write_bytes(const GroupT &point, std::ostream &out_s) +{ + GroupT affine_p = point; + affine_p.to_affine_coordinates(); + field_element_write_bytes(affine_p.X, out_s); + field_element_write_bytes(affine_p.Y, out_s); +} + +template +void group_element_read_bytes(GroupT &point, std::istream &in_s) +{ + field_element_read_bytes(point.X, in_s); + field_element_read_bytes(point.Y, in_s); + if (internal::coordinate_equals_zero(point.X) && + internal::coordinate_equals_one(point.Y)) { + point.Z = point.Z.zero(); + } else { + point.Z = point.Z.one(); + } +} + } // namespace libzeth #endif // __ZETH_CORE_GROUP_ELEMENT_UTILS_TCC__ diff --git a/libzeth/tests/core/field_element_utils_test.cpp b/libzeth/tests/core/field_element_utils_test.cpp index f678cc94e..e8c7d0f98 100644 --- a/libzeth/tests/core/field_element_utils_test.cpp +++ b/libzeth/tests/core/field_element_utils_test.cpp @@ -113,6 +113,41 @@ template void field_element_encode_decode_json_badstring_test() do_field_element_encode_decode_json_badstring_test>(); } +template void do_field_element_read_write_bytes_test() +{ + static const size_t elements_to_write = 4; + FieldT elements[elements_to_write]; + for (FieldT &el : elements) { + el = FieldT::random_element(); + } + + std::string buffer; + { + std::stringstream out_s; + for (const FieldT &el : elements) { + libzeth::field_element_write_bytes(el, out_s); + } + buffer = out_s.str(); + } + + { + std::stringstream in_s(buffer); + for (const FieldT &el : elements) { + FieldT read; + libzeth::field_element_read_bytes(read, in_s); + ASSERT_EQ(el, read); + } + } +} + +template void field_element_read_write_bytes_test() +{ + do_field_element_read_write_bytes_test>(); + do_field_element_read_write_bytes_test>(); + do_field_element_read_write_bytes_test>(); + do_field_element_read_write_bytes_test>(); +} + TEST(FieldElementUtilsTest, BigIntEncodeDecodeHex) { bigint_encode_decode_hex_test(); @@ -158,6 +193,15 @@ TEST(FieldElementUtilsTest, FieldElementEncodeDecodeJsonBadString) field_element_encode_decode_json_badstring_test(); } +TEST(FieldElementUtilsTest, FieldElementReadWriteBytes) +{ + field_element_read_write_bytes_test(); + field_element_read_write_bytes_test(); + field_element_read_write_bytes_test(); + field_element_read_write_bytes_test(); + field_element_read_write_bytes_test(); +} + } // namespace int main(int argc, char **argv) diff --git a/libzeth/tests/core/group_element_utils_test.cpp b/libzeth/tests/core/group_element_utils_test.cpp index ba0817163..765e11578 100644 --- a/libzeth/tests/core/group_element_utils_test.cpp +++ b/libzeth/tests/core/group_element_utils_test.cpp @@ -58,7 +58,7 @@ TEST(GroupElementUtilsTest, G2EncodeJsonTestVectorAltBN128) } template -static void single_group_element_encode_decode_test(const GroupT &g) +static void single_group_element_encode_decode_json_test(const GroupT &g) { const std::string g_json = libzeth::group_element_to_json(g); const GroupT g_decoded = libzeth::group_element_from_json(g_json); @@ -66,29 +66,73 @@ static void single_group_element_encode_decode_test(const GroupT &g) ASSERT_EQ(g, g_decoded); } -template static void group_element_encode_decode_test() +template static void group_element_encode_decode_json_test() { - single_group_element_encode_decode_test(GroupT::random_element()); - single_group_element_encode_decode_test(GroupT::zero()); - single_group_element_encode_decode_test(GroupT::one()); + single_group_element_encode_decode_json_test(GroupT::random_element()); + single_group_element_encode_decode_json_test(GroupT::zero()); + single_group_element_encode_decode_json_test(GroupT::one()); } -TEST(GroupElementUtilsTest, G1EncodeDecode) +TEST(GroupElementUtilsTest, G1EncodeDecodeJSON) { - group_element_encode_decode_test>(); - group_element_encode_decode_test>(); - group_element_encode_decode_test>(); - group_element_encode_decode_test>(); - group_element_encode_decode_test>(); + group_element_encode_decode_json_test>(); + group_element_encode_decode_json_test>(); + group_element_encode_decode_json_test>(); + group_element_encode_decode_json_test>(); + group_element_encode_decode_json_test>(); } -TEST(GroupElementUtilsTest, G2EncodeDecode) +TEST(GroupElementUtilsTest, G2EncodeDecodeJSON) { - group_element_encode_decode_test>(); - group_element_encode_decode_test>(); - group_element_encode_decode_test>(); - group_element_encode_decode_test>(); - group_element_encode_decode_test>(); + group_element_encode_decode_json_test>(); + group_element_encode_decode_json_test>(); + group_element_encode_decode_json_test>(); + group_element_encode_decode_json_test>(); + group_element_encode_decode_json_test>(); +} + +template +static void single_group_element_encode_decode_bytes_test(const GroupT &g) +{ + std::string buffer; + { + std::stringstream ss; + libzeth::group_element_write_bytes(g, ss); + buffer = ss.str(); + } + + GroupT g_decoded; + { + std::stringstream ss(buffer); + libzeth::group_element_read_bytes(g_decoded, ss); + } + + ASSERT_EQ(g, g_decoded); +} + +template static void group_element_encode_decode_bytes_test() +{ + single_group_element_encode_decode_bytes_test(GroupT::random_element()); + single_group_element_encode_decode_bytes_test(GroupT::zero()); + single_group_element_encode_decode_bytes_test(GroupT::one()); +} + +TEST(GroupElementUtilsTest, G1EncodeDecodeBytes) +{ + group_element_encode_decode_bytes_test>(); + group_element_encode_decode_bytes_test>(); + group_element_encode_decode_bytes_test>(); + group_element_encode_decode_bytes_test>(); + group_element_encode_decode_bytes_test>(); +} + +TEST(GroupElementUtilsTest, G2EncodeDecodeBytes) +{ + group_element_encode_decode_bytes_test>(); + group_element_encode_decode_bytes_test>(); + group_element_encode_decode_bytes_test>(); + group_element_encode_decode_bytes_test>(); + group_element_encode_decode_bytes_test>(); } } // namespace From f524ec978abaa25e1ed9e358f1d54e7c992ddde2 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 3 Mar 2021 15:55:23 +0000 Subject: [PATCH 077/137] libzeth: support writing out test data from ec_operation_data_test --- libzeth/tests/core/ec_operation_data_test.cpp | 71 +++++++++++++++---- 1 file changed, 58 insertions(+), 13 deletions(-) diff --git a/libzeth/tests/core/ec_operation_data_test.cpp b/libzeth/tests/core/ec_operation_data_test.cpp index 82327564c..a6d436eaa 100644 --- a/libzeth/tests/core/ec_operation_data_test.cpp +++ b/libzeth/tests/core/ec_operation_data_test.cpp @@ -4,7 +4,9 @@ #include "libzeth/core/field_element_utils.hpp" #include "libzeth/core/group_element_utils.hpp" +#include "libzeth/serialization/proto_utils.hpp" +#include #include #include #include @@ -13,6 +15,8 @@ using namespace libzeth; +boost::filesystem::path g_output_dir = boost::filesystem::path(""); + namespace { @@ -47,12 +51,22 @@ template void operation_test_data() const libff::G2 g2_4 = g2_2 + g2_2; const libff::G2 g2_8 = g2_4 + g2_4; + // Simultaneously write all field and group data to a string stream. + std::stringstream binary_stream; + std::cout << " Fr:"; std::cout << "\n r: " << bigint_to_hex>(libff::Fr::mod); + std::cout << "\n 1: "; + field_element_write_json(fr_1, std::cout); + field_element_write_bytes(fr_1, binary_stream); + std::cout << "\n 2: "; + field_element_write_json(fr_2, std::cout); + field_element_write_bytes(fr_2, binary_stream); std::cout << "\n -2: "; field_element_write_json(fr_minus_2, std::cout); + field_element_write_bytes(fr_minus_2, binary_stream); std::cout << " Fq:"; std::cout << "\n q: " @@ -60,35 +74,60 @@ template void operation_test_data() std::cout << "\n G1:"; std::cout << "\n 1: "; - point_affine_write_json(g1_1, std::cout); + group_element_write_json(g1_1, std::cout); + group_element_write_bytes(g1_1, binary_stream); std::cout << "\n -1: "; - point_affine_write_json(-g1_1, std::cout); + group_element_write_json(-g1_1, std::cout); + group_element_write_bytes(-g1_1, binary_stream); std::cout << "\n 2: "; - point_affine_write_json(g1_2, std::cout); + group_element_write_json(g1_2, std::cout); + group_element_write_bytes(g1_2, binary_stream); std::cout << "\n 3: "; - point_affine_write_json(g1_3, std::cout); + group_element_write_json(g1_3, std::cout); + group_element_write_bytes(g1_3, binary_stream); std::cout << "\n 4: "; - point_affine_write_json(g1_4, std::cout); + group_element_write_json(g1_4, std::cout); + group_element_write_bytes(g1_4, binary_stream); std::cout << "\n 6: "; - point_affine_write_json(g1_6, std::cout); + group_element_write_json(g1_6, std::cout); + group_element_write_bytes(g1_6, binary_stream); std::cout << "\n 8: "; - point_affine_write_json(g1_8, std::cout); + group_element_write_json(g1_8, std::cout); + group_element_write_bytes(g1_8, binary_stream); std::cout << "\n -8: "; - point_affine_write_json(-g1_8, std::cout); + group_element_write_json(-g1_8, std::cout); + group_element_write_bytes(-g1_8, binary_stream); std::cout << "\n G2:"; std::cout << "\n 1: "; - point_affine_write_json(g2_1, std::cout); + group_element_write_json(g2_1, std::cout); + group_element_write_bytes(g2_1, binary_stream); std::cout << "\n -1: "; - point_affine_write_json(-g2_1, std::cout); + group_element_write_json(-g2_1, std::cout); + group_element_write_bytes(-g2_1, binary_stream); std::cout << "\n 4: "; - point_affine_write_json(g2_4, std::cout); + group_element_write_json(g2_4, std::cout); + group_element_write_bytes(g2_4, binary_stream); std::cout << "\n 8: "; - point_affine_write_json(g2_8, std::cout); + group_element_write_json(g2_8, std::cout); + group_element_write_bytes(g2_8, binary_stream); std::cout << "\n -8: "; - point_affine_write_json(-g2_8, std::cout); + group_element_write_json(-g2_8, std::cout); + group_element_write_bytes(-g2_8, binary_stream); std::cout << "\n"; + // Write the binary data if output_dir given + if (!g_output_dir.empty()) { + boost::filesystem::path outpath = + g_output_dir / ("ec_test_data_" + libzeth::pp_name() + ".bin"); + std::cout << "(writing to file " << outpath << ")\n"; + std::ofstream out_s( + outpath.c_str(), std::ios_base::out | std::ios_base::binary); + out_s << binary_stream.str(); + } else { + std::cout << "(skipping binary data write)\n"; + } + // Check the statements above ASSERT_EQ(g1_6, g1_2 + g1_4); ASSERT_EQ(-g1_8, fr_minus_2 * g1_4); @@ -192,5 +231,11 @@ int main(int argc, char **argv) libff::bls12_377_pp::init_public_params(); libff::bw6_761_pp::init_public_params(); ::testing::InitGoogleTest(&argc, argv); + + // Extract the test data destination dir, if passed on the command line. + if (argc > 1) { + g_output_dir = boost::filesystem::path(argv[1]); + } + return RUN_ALL_TESTS(); } From 039fcbe471cc5fc604bae44aef04b0748ee336d0 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 30 Mar 2021 18:21:36 +0100 Subject: [PATCH 078/137] ganache-cli update [v6.10.4-clearmatics-prerelease] (build fix) --- depends/ganache-cli | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/ganache-cli b/depends/ganache-cli index 6e762a5f8..3b6ba1adf 160000 --- a/depends/ganache-cli +++ b/depends/ganache-cli @@ -1 +1 @@ -Subproject commit 6e762a5f83fbacd2f4dca6d17b996787bfc05d0b +Subproject commit 3b6ba1adf0f7ad08bc46171370fe29bd1d52ecab From 2e86100931902b7e24fb8716b13d3f7de8868042 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 4 Mar 2021 09:29:42 +0000 Subject: [PATCH 079/137] submodule: update libsnark [compile-warnings] --- depends/libsnark | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depends/libsnark b/depends/libsnark index d23fa10bb..104ed9021 160000 --- a/depends/libsnark +++ b/depends/libsnark @@ -1 +1 @@ -Subproject commit d23fa10bb0c30295161b010a58df52edcd5c29b3 +Subproject commit 104ed902141d41dfb4efb2b9270386031d98e12e From 23c3700b10471c0d2efa9de69e1c9eed226ca45c Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 4 Mar 2021 09:31:09 +0000 Subject: [PATCH 080/137] libzeth: clean up interface to r1cs serialization (user r1cs not protoboard, refs, inferrable type param) --- libzeth/circuits/circuit_wrapper.hpp | 3 +- libzeth/circuits/circuit_wrapper.tcc | 4 +- libzeth/serialization/r1cs_serialization.hpp | 4 +- libzeth/serialization/r1cs_serialization.tcc | 45 +++++++++----------- libzeth/tests/circuits/simple_test.cpp | 6 +-- prover_server/prover_server.cpp | 2 +- 6 files changed, 29 insertions(+), 35 deletions(-) diff --git a/libzeth/circuits/circuit_wrapper.hpp b/libzeth/circuits/circuit_wrapper.hpp index 92ccd790e..7ab1461a0 100644 --- a/libzeth/circuits/circuit_wrapper.hpp +++ b/libzeth/circuits/circuit_wrapper.hpp @@ -47,7 +47,8 @@ class circuit_wrapper typename snarkT::keypair generate_trusted_setup() const; // Retrieve the constraint system (intended for debugging purposes). - const libsnark::protoboard &get_constraint_system() const; + const libsnark::r1cs_constraint_system &get_constraint_system() + const; // Generate a proof and returns an extended proof extended_proof prove( diff --git a/libzeth/circuits/circuit_wrapper.tcc b/libzeth/circuits/circuit_wrapper.tcc index bb1e49c0c..5c20f3311 100644 --- a/libzeth/circuits/circuit_wrapper.tcc +++ b/libzeth/circuits/circuit_wrapper.tcc @@ -86,7 +86,7 @@ template< size_t NumInputs, size_t NumOutputs, size_t TreeDepth> -const libsnark::protoboard> &circuit_wrapper< +const libsnark::r1cs_constraint_system> &circuit_wrapper< HashT, HashTreeT, ppT, @@ -95,7 +95,7 @@ const libsnark::protoboard> &circuit_wrapper< NumOutputs, TreeDepth>::get_constraint_system() const { - return pb; + return pb.get_constraint_system(); } template< diff --git a/libzeth/serialization/r1cs_serialization.hpp b/libzeth/serialization/r1cs_serialization.hpp index 9fd3ead52..197be5c07 100644 --- a/libzeth/serialization/r1cs_serialization.hpp +++ b/libzeth/serialization/r1cs_serialization.hpp @@ -35,9 +35,9 @@ template libsnark::accumulation_vector> accumulation_vector_from_json( const std::string &acc_vector_str); -template +template std::ostream &r1cs_write_json( - const libsnark::protoboard> &pb, std::ostream &out_s); + const libsnark::r1cs_constraint_system &r1cs, std::ostream &out_s); } // namespace libzeth diff --git a/libzeth/serialization/r1cs_serialization.tcc b/libzeth/serialization/r1cs_serialization.tcc index 966761dc3..643ee3afe 100644 --- a/libzeth/serialization/r1cs_serialization.tcc +++ b/libzeth/serialization/r1cs_serialization.tcc @@ -15,14 +15,14 @@ namespace libzeth namespace internal { -template +template void constraints_write_json( - const libsnark::linear_combination> &constraints, + const libsnark::linear_combination &constraints, std::ostream &out_s) { out_s << "["; size_t count = 0; - for (const libsnark::linear_term> < : constraints.terms) { + for (const libsnark::linear_term < : constraints.terms) { if (count != 0) { out_s << ","; } @@ -30,8 +30,7 @@ void constraints_write_json( out_s << "{"; out_s << "\"index\":" << lt.index << ","; out_s << "\"value\":" - << "\"" + - bigint_to_hex>(lt.coeff.as_bigint(), true) + << "\"" + bigint_to_hex(lt.coeff.as_bigint(), true) << "\""; out_s << "}"; count++; @@ -142,31 +141,28 @@ libsnark::accumulation_vector> accumulation_vector_from_json( std::move(front), std::move(rest)); } -template +template std::ostream &r1cs_write_json( - const libsnark::protoboard> &pb, std::ostream &out_s) + const libsnark::r1cs_constraint_system &r1cs, std::ostream &out_s) { // output inputs, right now need to compile with debug flag so that the // `variable_annotations` exists. Having trouble setting that up so will // leave for now. - libsnark::r1cs_constraint_system> constraints = - pb.get_constraint_system(); out_s << "{\n"; out_s << "\"scalar_field_characteristic\":" - << "\"" + bigint_to_hex>( - libff::Fr::field_char(), true) + << "\"" + bigint_to_hex(FieldT::field_char(), true) << "\",\n"; - out_s << "\"num_variables\":" << pb.num_variables() << ",\n"; - out_s << "\"num_constraints\":" << pb.num_constraints() << ",\n"; - out_s << "\"num_inputs\": " << pb.num_inputs() << ",\n"; + out_s << "\"num_variables\":" << r1cs.num_variables() << ",\n"; + out_s << "\"num_constraints\":" << r1cs.num_constraints() << ",\n"; + out_s << "\"num_inputs\": " << r1cs.num_inputs() << ",\n"; out_s << "\"variables_annotations\":["; - for (size_t i = 0; i < constraints.num_variables(); ++i) { + for (size_t i = 0; i < r1cs.num_variables(); ++i) { out_s << "{"; out_s << "\"index\":" << i << ","; out_s << "\"annotation\":" - << "\"" << constraints.variable_annotations[i].c_str() << "\""; - if (i == constraints.num_variables() - 1) { + << "\"" << r1cs.variable_annotations.at(i).c_str() << "\""; + if (i == r1cs.num_variables() - 1) { out_s << "}"; } else { out_s << "},"; @@ -174,26 +170,23 @@ std::ostream &r1cs_write_json( } out_s << "],\n"; out_s << "\"constraints\":["; - for (size_t c = 0; c < constraints.num_constraints(); ++c) { + for (size_t c = 0; c < r1cs.num_constraints(); ++c) { out_s << "{"; out_s << "\"constraint_id\": " << c << ","; out_s << "\"constraint_annotation\": " - << "\"" << constraints.constraint_annotations[c].c_str() << "\","; + << "\"" << r1cs.constraint_annotations.at(c).c_str() << "\","; out_s << "\"linear_combination\":"; out_s << "{"; out_s << "\"A\":"; - internal::constraints_write_json( - constraints.constraints[c].a, out_s); + internal::constraints_write_json(r1cs.constraints[c].a, out_s); out_s << ","; out_s << "\"B\":"; - internal::constraints_write_json( - constraints.constraints[c].b, out_s); + internal::constraints_write_json(r1cs.constraints[c].b, out_s); out_s << ","; out_s << "\"C\":"; - internal::constraints_write_json( - constraints.constraints[c].c, out_s); + internal::constraints_write_json(r1cs.constraints[c].c, out_s); out_s << "}"; - if (c == constraints.num_constraints() - 1) { + if (c == r1cs.num_constraints() - 1) { out_s << "}"; } else { out_s << "},"; diff --git a/libzeth/tests/circuits/simple_test.cpp b/libzeth/tests/circuits/simple_test.cpp index 49fb35b6c..0ae8595f5 100644 --- a/libzeth/tests/circuits/simple_test.cpp +++ b/libzeth/tests/circuits/simple_test.cpp @@ -29,7 +29,7 @@ TEST(SimpleTests, SimpleCircuitProof) libzeth::tests::simple_circuit(pb); // Constraint system - const r1cs_constraint_system constraint_system = + const r1cs_constraint_system &constraint_system = pb.get_constraint_system(); // Write to file if output directory is given. @@ -37,7 +37,7 @@ TEST(SimpleTests, SimpleCircuitProof) boost::filesystem::path outpath = g_output_dir / "simple_circuit_r1cs.json"; std::ofstream r1cs_stream(outpath.c_str()); - libzeth::r1cs_write_json(pb, r1cs_stream); + libzeth::r1cs_write_json(pb.get_constraint_system(), r1cs_stream); } const r1cs_primary_input primary{12}; @@ -73,7 +73,7 @@ TEST(SimpleTests, SimpleCircuitProofPow2Domain) protoboard pb; libzeth::tests::simple_circuit(pb); - const r1cs_constraint_system constraint_system = + const r1cs_constraint_system &constraint_system = pb.get_constraint_system(); const r1cs_gg_ppzksnark_keypair keypair = r1cs_gg_ppzksnark_generator(constraint_system, true); diff --git a/prover_server/prover_server.cpp b/prover_server/prover_server.cpp index ed1d8fce8..c7213681f 100644 --- a/prover_server/prover_server.cpp +++ b/prover_server/prover_server.cpp @@ -71,7 +71,7 @@ static void write_constraint_system( const circuit_wrapper &prover, const boost::filesystem::path &r1cs_file) { std::ofstream r1cs_stream(r1cs_file.c_str()); - libzeth::r1cs_write_json(prover.get_constraint_system(), r1cs_stream); + libzeth::r1cs_write_json(prover.get_constraint_system(), r1cs_stream); } static void write_ext_proof_to_file( From c5943738632b46cbebc58a625c7275b910d53b79 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 4 Mar 2021 14:02:31 +0000 Subject: [PATCH 081/137] libzeth: rename some shared test functions --- libzeth/tests/snarks/common_api_tests.tcc | 4 ++-- libzeth/tests/snarks/groth16/groth16_api_handler_test.cpp | 7 +++++-- libzeth/tests/snarks/pghr13/pghr13_api_handler_test.cpp | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/libzeth/tests/snarks/common_api_tests.tcc b/libzeth/tests/snarks/common_api_tests.tcc index 623e7f511..cbdc91aac 100644 --- a/libzeth/tests/snarks/common_api_tests.tcc +++ b/libzeth/tests/snarks/common_api_tests.tcc @@ -4,7 +4,7 @@ #include -template void verification_key_encode_decode_test() +template void verification_key_encode_decode_json_test() { using snark = typename apiHandlerT::snark; @@ -20,7 +20,7 @@ template void verification_key_encode_decode_test() } template -void extended_proof_encode_decode_test( +void extended_proof_encode_decode_json_test( const libzeth::extended_proof &proof) { using snark = typename apiHandlerT::snark; diff --git a/libzeth/tests/snarks/groth16/groth16_api_handler_test.cpp b/libzeth/tests/snarks/groth16/groth16_api_handler_test.cpp index c478b8a93..4a389477a 100644 --- a/libzeth/tests/snarks/groth16/groth16_api_handler_test.cpp +++ b/libzeth/tests/snarks/groth16/groth16_api_handler_test.cpp @@ -20,7 +20,8 @@ namespace TEST(Groth16ApiHandlerTest, VerificationKeyEncodeDecode) { - verification_key_encode_decode_test>(); + verification_key_encode_decode_json_test< + libzeth::groth16_api_handler>(); } TEST(Groth16ApiHandlerTest, ProofEncodeDecode) @@ -29,7 +30,9 @@ TEST(Groth16ApiHandlerTest, ProofEncodeDecode) G1::random_element(), G2::random_element(), G1::random_element()}; libsnark::r1cs_primary_input dummy_inputs{ Fr::random_element(), Fr::random_element(), Fr::random_element()}; - extended_proof_encode_decode_test>( + extended_proof_encode_decode_json_test< + pp, + libzeth::groth16_api_handler>( {std::move(dummy_proof), std::move(dummy_inputs)}); } diff --git a/libzeth/tests/snarks/pghr13/pghr13_api_handler_test.cpp b/libzeth/tests/snarks/pghr13/pghr13_api_handler_test.cpp index f368a09fa..e003eeede 100644 --- a/libzeth/tests/snarks/pghr13/pghr13_api_handler_test.cpp +++ b/libzeth/tests/snarks/pghr13/pghr13_api_handler_test.cpp @@ -20,7 +20,7 @@ namespace TEST(PGHR13ApiHandlerTest, VerificationKeyEncodeDecode) { - verification_key_encode_decode_test>(); + verification_key_encode_decode_json_test>(); } TEST(PGHR13ApiHandlerTest, ProofEncodeDecode) @@ -33,7 +33,7 @@ TEST(PGHR13ApiHandlerTest, ProofEncodeDecode) G1::random_element()); libsnark::r1cs_primary_input dummy_inputs{ Fr::random_element(), Fr::random_element(), Fr::random_element()}; - extended_proof_encode_decode_test>( + extended_proof_encode_decode_json_test>( {std::move(dummy_proof), std::move(dummy_inputs)}); } From 68e0fad7eeab3adaf424c98e927ecae92ee9553a Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 4 Mar 2021 09:32:35 +0000 Subject: [PATCH 082/137] libzeth: constraint system serialization in binary format --- libzeth/serialization/r1cs_serialization.hpp | 8 ++ libzeth/serialization/r1cs_serialization.tcc | 79 +++++++++++++++++++ libzeth/serialization/stream_utils.hpp | 30 +++++++ libzeth/serialization/stream_utils.tcc | 38 +++++++++ .../serialization/r1cs_serialization_test.cpp | 47 +++++++++++ 5 files changed, 202 insertions(+) create mode 100644 libzeth/serialization/stream_utils.hpp create mode 100644 libzeth/serialization/stream_utils.tcc diff --git a/libzeth/serialization/r1cs_serialization.hpp b/libzeth/serialization/r1cs_serialization.hpp index 197be5c07..04514eaaa 100644 --- a/libzeth/serialization/r1cs_serialization.hpp +++ b/libzeth/serialization/r1cs_serialization.hpp @@ -39,6 +39,14 @@ template std::ostream &r1cs_write_json( const libsnark::r1cs_constraint_system &r1cs, std::ostream &out_s); +template +void r1cs_read_bytes( + libsnark::r1cs_constraint_system &r1cs, std::istream &in_s); + +template +void r1cs_write_bytes( + const libsnark::r1cs_constraint_system &r1cs, std::ostream &out_s); + } // namespace libzeth #include "libzeth/serialization/r1cs_serialization.tcc" diff --git a/libzeth/serialization/r1cs_serialization.tcc b/libzeth/serialization/r1cs_serialization.tcc index 643ee3afe..54947f57d 100644 --- a/libzeth/serialization/r1cs_serialization.tcc +++ b/libzeth/serialization/r1cs_serialization.tcc @@ -8,6 +8,7 @@ #include "libzeth/core/field_element_utils.hpp" #include "libzeth/core/group_element_utils.hpp" #include "libzeth/serialization/r1cs_serialization.hpp" +#include "libzeth/serialization/stream_utils.hpp" namespace libzeth { @@ -197,6 +198,84 @@ std::ostream &r1cs_write_json( return out_s; } +template +void linear_combination_read_bytes( + libsnark::linear_combination &linear_combination, + std::istream &in_s) +{ + const uint32_t num_terms = read_bytes(in_s); + + linear_combination.terms.clear(); + linear_combination.terms.reserve(num_terms); + for (uint32_t i = 0; i < num_terms; ++i) { + const libsnark::var_index_t idx = + read_bytes(in_s); + FieldT coeff; + field_element_read_bytes(coeff, in_s); + linear_combination.terms.emplace_back(idx, coeff); + } +} + +template +void linear_combination_write_bytes( + const libsnark::linear_combination &linear_combination, + std::ostream &out_s) +{ + // Write the number of terms as a uint32_t to save space. If this assert + // fires (a single linear combination contains 2^32 terms), change to + // size_t. + assert( + linear_combination.terms.size() <= + (size_t)std::numeric_limits::max); + const uint32_t num_terms = (uint32_t)linear_combination.terms.size(); + write_bytes(num_terms, out_s); + + for (const libsnark::linear_term &term : linear_combination.terms) { + write_bytes(term.index, out_s); + field_element_write_bytes(term.coeff, out_s); + } +} + +template +void r1cs_constraint_read_bytes( + libsnark::r1cs_constraint &constraint, std::istream &in_s) +{ + linear_combination_read_bytes(constraint.a, in_s); + linear_combination_read_bytes(constraint.b, in_s); + linear_combination_read_bytes(constraint.c, in_s); +} + +template +void r1cs_constraint_write_bytes( + const libsnark::r1cs_constraint &constraint, std::ostream &out_s) +{ + linear_combination_write_bytes(constraint.a, out_s); + linear_combination_write_bytes(constraint.b, out_s); + linear_combination_write_bytes(constraint.c, out_s); +} + +template +void r1cs_read_bytes( + libsnark::r1cs_constraint_system &r1cs, std::istream &in_s) +{ + read_bytes(r1cs.primary_input_size, in_s); + read_bytes(r1cs.auxiliary_input_size, in_s); + collection_read_bytes< + std::vector>, + r1cs_constraint_read_bytes>(r1cs.constraints, in_s); +} + +template +void r1cs_write_bytes( + const libsnark::r1cs_constraint_system &r1cs, std::ostream &out_s) +{ + write_bytes(r1cs.primary_input_size, out_s); + write_bytes(r1cs.auxiliary_input_size, out_s); + collection_write_bytes< + std::vector>, + r1cs_constraint_write_bytes>(r1cs.constraints, out_s); +} + } // namespace libzeth #endif // __ZETH_SERIALIZATION_R1CS_SERIALIZATION_TCC__ diff --git a/libzeth/serialization/stream_utils.hpp b/libzeth/serialization/stream_utils.hpp new file mode 100644 index 000000000..c9991be7e --- /dev/null +++ b/libzeth/serialization/stream_utils.hpp @@ -0,0 +1,30 @@ +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SERIALIZATION_STREAM_UTILS_HPP__ +#define __ZETH_SERIALIZATION_STREAM_UTILS_HPP__ + +namespace libzeth +{ + +/// Read a primitive datatype from a stream as raw bytes. +template +typename std::enable_if::value, T>::type read_bytes( + std::istream &in_s); + +/// Read a primitive datatype from a stream as raw bytes. +template +typename std::enable_if::value, void>::type read_bytes( + T &val, std::istream &in_s); + +// Write a primitive datatype to a stream as raw bytes.ap +template +typename std::enable_if::value, void>::type write_bytes( + const T &val, std::ostream &out_s); + +} // namespace libzeth + +#include "libzeth/serialization/stream_utils.tcc" + +#endif // __ZETH_SERIALIZATION_STREAM_UTILS_HPP__ diff --git a/libzeth/serialization/stream_utils.tcc b/libzeth/serialization/stream_utils.tcc new file mode 100644 index 000000000..f28809b66 --- /dev/null +++ b/libzeth/serialization/stream_utils.tcc @@ -0,0 +1,38 @@ +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SERIALIZATION_STREAM_UTILS_TCC__ +#define __ZETH_SERIALIZATION_STREAM_UTILS_TCC__ + +#include "libzeth/serialization/stream_utils.hpp" + +namespace libzeth +{ + +template +typename std::enable_if::value, T>::type read_bytes( + std::istream &in_s) +{ + T val; + read_bytes(val, in_s); + return val; +} + +template +typename std::enable_if::value, void>::type read_bytes( + T &val, std::istream &in_s) +{ + in_s.read((char *)(&val), sizeof(T)); +} + +template +typename std::enable_if::value, void>::type write_bytes( + const T &val, std::ostream &out_s) +{ + out_s.write((const char *)(&val), sizeof(T)); +} + +} // namespace libzeth + +#endif // __ZETH_SERIALIZATION_STREAM_UTILS_TCC__ diff --git a/libzeth/tests/serialization/r1cs_serialization_test.cpp b/libzeth/tests/serialization/r1cs_serialization_test.cpp index f3d686775..f77f910a4 100644 --- a/libzeth/tests/serialization/r1cs_serialization_test.cpp +++ b/libzeth/tests/serialization/r1cs_serialization_test.cpp @@ -2,7 +2,13 @@ // // SPDX-License-Identifier: LGPL-3.0+ +#include "libzeth/circuits/blake2s/blake2s.hpp" +#include "libzeth/circuits/circuit_types.hpp" +#include "libzeth/circuits/circuit_wrapper.hpp" +#include "libzeth/serialization/proto_utils.hpp" #include "libzeth/serialization/r1cs_serialization.hpp" +#include "libzeth/snarks/groth16/groth16_snark.hpp" +#include "libzeth/tests/circuits/simple_test.hpp" #include #include @@ -52,6 +58,41 @@ template void accumulation_vector_json_encode_decode() ASSERT_EQ(acc_vect_string, acc_vect_decoded_string); } +template void r1cs_bytes_encode_decode() +{ + using Field = libff::Fr; + + // Create the joinsplit constraint system. + libzeth::circuit_wrapper< + libzeth::HashT, + libzeth::HashTreeT, + ppT, + libzeth::groth16_snark, + 2, + 2, + 32> + circuit; + const libsnark::r1cs_constraint_system &r1cs = + circuit.get_constraint_system(); + + std::string r1cs_bytes = ([&r1cs]() { + std::stringstream ss; + libzeth::r1cs_write_bytes(r1cs, ss); + return ss.str(); + })(); + + std::cout << "Joinsplit constraint system(" << libzeth::pp_name() + << "): " << std::to_string(r1cs_bytes.size()) << " bytes\n"; + + libsnark::r1cs_constraint_system r1cs2; + { + std::stringstream ss(r1cs_bytes); + libzeth::r1cs_read_bytes(r1cs2, ss); + } + + ASSERT_EQ(r1cs, r1cs2); +} + TEST(R1CSSerializationTest, PrimaryInputsJsonEncodeDecode) { primary_inputs_json_encode_decode(); @@ -70,6 +111,12 @@ TEST(R1CSSerializationTest, AccumulationVectorJsonEncodeDecode) accumulation_vector_json_encode_decode(); } +TEST(R1CSSerializationTest, R1CSBytesEncodeDecode) +{ + r1cs_bytes_encode_decode(); + r1cs_bytes_encode_decode(); +} + } // namespace int main(int argc, char **argv) From 0e71b60b039265b53cdc38a549ddcb7c5bcc6138 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 4 Mar 2021 14:01:41 +0000 Subject: [PATCH 083/137] libzeth: support for binary serialization of r1cs assignments --- ...r1cs_variable_assignment_serialization.hpp | 26 +++++++++ ...r1cs_variable_assignment_serialization.tcc | 38 ++++++++++++ ...variable_assignment_serialization_test.cpp | 58 +++++++++++++++++++ 3 files changed, 122 insertions(+) create mode 100644 libzeth/serialization/r1cs_variable_assignment_serialization.hpp create mode 100644 libzeth/serialization/r1cs_variable_assignment_serialization.tcc create mode 100644 libzeth/tests/serialization/r1cs_variable_assignment_serialization_test.cpp diff --git a/libzeth/serialization/r1cs_variable_assignment_serialization.hpp b/libzeth/serialization/r1cs_variable_assignment_serialization.hpp new file mode 100644 index 000000000..fe3c3d609 --- /dev/null +++ b/libzeth/serialization/r1cs_variable_assignment_serialization.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SERIALIZATION_R1CS_VARIABLE_ASSIGNMENT_SERIALIZATION_HPP__ +#define __ZETH_SERIALIZATION_R1CS_VARIABLE_ASSIGNMENT_SERIALIZATION_HPP__ + +#include + +namespace libzeth +{ + +template +void r1cs_variable_assignment_read_bytes( + libsnark::r1cs_variable_assignment &assignment, std::istream &in_s); + +template +void r1cs_variable_assignment_write_bytes( + const libsnark::r1cs_variable_assignment &assignment, + std::ostream &out_s); + +} // namespace libzeth + +#include "libzeth/serialization/r1cs_variable_assignment_serialization.tcc" + +#endif // __ZETH_SERIALIZATION_R1CS_VARIABLE_ASSIGNMENT_SERIALIZATION_HPP__ diff --git a/libzeth/serialization/r1cs_variable_assignment_serialization.tcc b/libzeth/serialization/r1cs_variable_assignment_serialization.tcc new file mode 100644 index 000000000..06189e4a4 --- /dev/null +++ b/libzeth/serialization/r1cs_variable_assignment_serialization.tcc @@ -0,0 +1,38 @@ +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_SERIALIZATION_R1CS_VARIABLE_ASSIGNMENT_SERIALIZATION_TCC__ +#define __ZETH_SERIALIZATION_R1CS_VARIABLE_ASSIGNMENT_SERIALIZATION_TCC__ + +#include "libzeth/core/field_element_utils.hpp" +#include "libzeth/serialization/r1cs_variable_assignment_serialization.hpp" +#include "libzeth/serialization/stream_utils.hpp" + +namespace libzeth +{ + +template +void r1cs_variable_assignment_read_bytes( + libsnark::r1cs_variable_assignment &assignment, std::istream &in_s) +{ + collection_read_bytes< + FieldT, + libsnark::r1cs_variable_assignment, + field_element_read_bytes>(assignment, in_s); +} + +template +void r1cs_variable_assignment_write_bytes( + const libsnark::r1cs_variable_assignment &assignment, + std::ostream &out_s) +{ + collection_write_bytes< + FieldT, + libsnark::r1cs_variable_assignment, + field_element_write_bytes>(assignment, out_s); +} + +} // namespace libzeth + +#endif // __ZETH_SERIALIZATION_R1CS_VARIABLE_ASSIGNMENT_SERIALIZATION_TCC__ diff --git a/libzeth/tests/serialization/r1cs_variable_assignment_serialization_test.cpp b/libzeth/tests/serialization/r1cs_variable_assignment_serialization_test.cpp new file mode 100644 index 000000000..c61bae89b --- /dev/null +++ b/libzeth/tests/serialization/r1cs_variable_assignment_serialization_test.cpp @@ -0,0 +1,58 @@ +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#include "libzeth/serialization/r1cs_variable_assignment_serialization.hpp" + +#include +#include +#include + +namespace +{ + +template bool test_r1cs_variable_assignment_read_write_bytes() +{ + using FieldT = libff::Fr; + const size_t assignment_size = 37; + + libsnark::r1cs_variable_assignment assignment; + assignment.reserve(assignment_size); + for (size_t i = 0; i < assignment_size; ++i) { + assignment.push_back(FieldT::random_element()); + } + + std::string buffer = ([&assignment]() { + std::stringstream ss; + libzeth::r1cs_variable_assignment_write_bytes(assignment, ss); + return ss.str(); + })(); + + libsnark::r1cs_variable_assignment assignment2; + { + std::stringstream ss(buffer); + libzeth::r1cs_variable_assignment_read_bytes(assignment2, ss); + } + + return assignment == assignment2; +} + +TEST(R1CSVariableAssignementSerializationTest, AssignmentReeadWriteBytes) +{ + const bool test_alt_bn128 = + test_r1cs_variable_assignment_read_write_bytes(); + ASSERT_TRUE(test_alt_bn128); + const bool test_bls12_377 = + test_r1cs_variable_assignment_read_write_bytes(); + ASSERT_TRUE(test_bls12_377); +} + +} // namespace + +int main(int argc, char **argv) +{ + libff::alt_bn128_pp::init_public_params(); + libff::bls12_377_pp::init_public_params(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From 9412a8e20642d09fb68d8b3e970a91137df1b3a6 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 4 Mar 2021 18:20:20 +0000 Subject: [PATCH 084/137] libzeth: util functions for serializing lists of group elements --- libzeth/core/group_element_utils.hpp | 11 +++++ libzeth/core/group_element_utils.tcc | 23 ++++++++++ .../tests/core/group_element_utils_test.cpp | 43 +++++++++++++++++++ 3 files changed, 77 insertions(+) diff --git a/libzeth/core/group_element_utils.hpp b/libzeth/core/group_element_utils.hpp index a30b50c0b..40ec0bd85 100644 --- a/libzeth/core/group_element_utils.hpp +++ b/libzeth/core/group_element_utils.hpp @@ -37,6 +37,17 @@ void group_element_write_bytes(const GroupT &point, std::ostream &out_s); template void group_element_read_bytes(GroupT &point, std::istream &in_s); +/// Write a collection of group elements as bytes to a stream, using +/// group_element_write_bytes. +template +void group_elements_write_bytes( + const GroupCollectionT &points, std::ostream &out_s); + +/// Read a collection of group elements as bytes, usinng +/// group_elements_read_bytes. +template +void group_elements_read_bytes(GroupCollectionT &points, std::istream &in_s); + } // namespace libzeth #include "libzeth/core/group_element_utils.tcc" diff --git a/libzeth/core/group_element_utils.tcc b/libzeth/core/group_element_utils.tcc index bd0b7790e..a0ea4d9ff 100644 --- a/libzeth/core/group_element_utils.tcc +++ b/libzeth/core/group_element_utils.tcc @@ -111,6 +111,29 @@ void group_element_read_bytes(GroupT &point, std::istream &in_s) } } +template +void group_elements_write_bytes( + const GroupCollectionT &points, std::ostream &out_s) +{ + write_bytes(points.size(), out_s); + for (const auto &pt : points) { + group_element_write_bytes(pt, out_s); + } +} + +template +void group_elements_read_bytes(GroupCollectionT &points, std::istream &in_s) +{ + const size_t num_points = read_bytes(in_s); + + points.clear(); + points.reserve(num_points); + for (size_t i = 0; i < num_points; ++i) { + points.emplace_back(); + group_element_read_bytes(points.back(), in_s); + } +} + } // namespace libzeth #endif // __ZETH_CORE_GROUP_ELEMENT_UTILS_TCC__ diff --git a/libzeth/tests/core/group_element_utils_test.cpp b/libzeth/tests/core/group_element_utils_test.cpp index 765e11578..829bd31ec 100644 --- a/libzeth/tests/core/group_element_utils_test.cpp +++ b/libzeth/tests/core/group_element_utils_test.cpp @@ -135,6 +135,49 @@ TEST(GroupElementUtilsTest, G2EncodeDecodeBytes) group_element_encode_decode_bytes_test>(); } +template static void group_elements_encode_decode_bytes_test() +{ + const size_t num_elements = 17; + std::vector elements; + elements.reserve(num_elements); + for (size_t i = 0; i < num_elements; ++i) { + elements.emplace_back(GroupT::random_element()); + } + + std::string buffer; + { + std::stringstream ss; + libzeth::group_elements_write_bytes(elements, ss); + buffer = ss.str(); + } + + std::vector elements_decoded; + { + std::stringstream ss(buffer); + libzeth::group_elements_read_bytes(elements_decoded, ss); + } + + ASSERT_EQ(elements, elements_decoded); +} + +TEST(GroupElementUtilsTest, G1CollectionEncodeDecodeBytes) +{ + group_elements_encode_decode_bytes_test>(); + group_elements_encode_decode_bytes_test>(); + group_elements_encode_decode_bytes_test>(); + group_elements_encode_decode_bytes_test>(); + group_elements_encode_decode_bytes_test>(); +} + +TEST(GroupElementUtilsTest, G2CollectionEncodeDecodeBytes) +{ + group_elements_encode_decode_bytes_test>(); + group_elements_encode_decode_bytes_test>(); + group_elements_encode_decode_bytes_test>(); + group_elements_encode_decode_bytes_test>(); + group_elements_encode_decode_bytes_test>(); +} + } // namespace int main(int argc, char **argv) From 593c25e43dd4be0c666232decf1cf6c7dd102144 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 4 Mar 2021 14:03:13 +0000 Subject: [PATCH 085/137] WIP: libzeth: binary serialization of proving and verification keys --- libzeth/tests/snarks/common_snark_tests.tcc | 62 +++++++++++++++++++ .../snarks/groth16/groth16_snark_test.cpp | 51 +++++++++++++++ .../tests/snarks/pghr13/pghr13_snark_test.cpp | 52 ++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 libzeth/tests/snarks/common_snark_tests.tcc create mode 100644 libzeth/tests/snarks/groth16/groth16_snark_test.cpp create mode 100644 libzeth/tests/snarks/pghr13/pghr13_snark_test.cpp diff --git a/libzeth/tests/snarks/common_snark_tests.tcc b/libzeth/tests/snarks/common_snark_tests.tcc new file mode 100644 index 000000000..b1e8c889c --- /dev/null +++ b/libzeth/tests/snarks/common_snark_tests.tcc @@ -0,0 +1,62 @@ +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#ifndef __ZETH_TESTS_SNARKS_COMMON_SNARK_TESTS_TCC__ +#define __ZETH_TESTS_SNARKS_COMMON_SNARK_TESTS_TCC__ + +#include +#include + +namespace libzeth +{ + +namespace tests +{ + +static const size_t DUMMY_NUM_PRIMARY_INPUTS = 37; + +template +typename snarkT::proving_key dummy_proving_key() +{ +} + +template +bool verification_key_read_write_bytes_test() +{ + const typename snarkT::verification_key vk = + snarkT::verification_key::dummy_verification_key( + DUMMY_NUM_PRIMARY_INPUTS); + + std::string buffer = ([&vk]() { + std::stringstream ss; + snarkT::verification_key_write_bytes(vk, ss); + return ss.str(); + })(); + + std::stringstream ss(buffer); + const typename snarkT::verification_key vk2 = + snarkT::verification_key_read_bytes(ss); + return vk == vk2; +} + +template bool proving_key_read_write_bytes_test() +{ + const typename snarkT::proving_key pk = dummy_proving_key(); + + std::string buffer = ([&pk]() { + std::stringstream ss; + snarkT::proving_key_write_bytes(pk, ss); + return ss.str(); + })(); + + std::stringstream ss(buffer); + const typename snarkT::proving_key pk2 = snarkT::proving_key_read_bytes(ss); + return pk == pk2; +} + +} // namespace tests + +} // namespace libzeth + +#endif // __ZETH_TESTS_SNARKS_COMMON_SNARK_TESTS_TCC__ diff --git a/libzeth/tests/snarks/groth16/groth16_snark_test.cpp b/libzeth/tests/snarks/groth16/groth16_snark_test.cpp new file mode 100644 index 000000000..3193e1931 --- /dev/null +++ b/libzeth/tests/snarks/groth16/groth16_snark_test.cpp @@ -0,0 +1,51 @@ +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#include "libzeth/snarks/groth16/groth16_snark.hpp" +#include "libzeth/tests/snarks/common_snark_tests.tcc" + +#include +#include +#include + +namespace +{ + +TEST(Groth16SnarkTest, TestVerificationKeyReadWriteBytes) +{ + const bool test_alt_bn128 = + libzeth::tests::verification_key_read_write_bytes_test< + libff::alt_bn128_pp, + libzeth::groth16_snark>(); + ASSERT_TRUE(test_alt_bn128); + const bool test_bls12_377 = + libzeth::tests::verification_key_read_write_bytes_test< + libff::bls12_377_pp, + libzeth::groth16_snark>(); + ASSERT_TRUE(test_bls12_377); +} + +TEST(Groth16SnarkTest, TestProvingKeyReadWriteBytes) +{ + const bool test_alt_bn128 = + libzeth::tests::proving_key_read_write_bytes_test< + libff::alt_bn128_pp, + libzeth::groth16_snark>(); + ASSERT_TRUE(test_alt_bn128); + const bool test_bls12_377 = + libzeth::tests::proving_key_read_write_bytes_test< + libff::bls12_377_pp, + libzeth::groth16_snark>(); + ASSERT_TRUE(test_bls12_377); +} + +} // namespace + +int main(int argc, char **argv) +{ + libff::alt_bn128_pp::init_public_params(); + libff::bls12_377_pp::init_public_params(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/libzeth/tests/snarks/pghr13/pghr13_snark_test.cpp b/libzeth/tests/snarks/pghr13/pghr13_snark_test.cpp new file mode 100644 index 000000000..5eab9873e --- /dev/null +++ b/libzeth/tests/snarks/pghr13/pghr13_snark_test.cpp @@ -0,0 +1,52 @@ +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#include "libzeth/snarks/pghr13/pghr13_snark.hpp" +#include "libzeth/tests/snarks/common_snark_tests.tcc" + +#include +#include +#include + +namespace +{ + +TEST(Pghr13SnarkTest, TestVerificationKeyReadWriteBytes) +{ + const bool test_alt_bn128 = + libzeth::tests::verification_key_read_write_bytes_test< + libff::alt_bn128_pp, + libzeth::pghr13_snark>(); + ASSERT_TRUE(test_alt_bn128); + + const bool test_bls12_377 = + libzeth::tests::verification_key_read_write_bytes_test< + libff::bls12_377_pp, + libzeth::pghr13_snark>(); + ASSERT_TRUE(test_bls12_377); +} + +TEST(Pghr13SnarkTest, TestProvingKeyReadWriteBytes) +{ + const bool test_alt_bn128 = + libzeth::tests::proving_key_read_write_bytes_test< + libff::alt_bn128_pp, + libzeth::pghr13_snark>(); + ASSERT_TRUE(test_alt_bn128); + const bool test_bls12_377 = + libzeth::tests::proving_key_read_write_bytes_test< + libff::bls12_377_pp, + libzeth::pghr13_snark>(); + ASSERT_TRUE(test_bls12_377); +} + +} // namespace + +int main(int argc, char **argv) +{ + libff::alt_bn128_pp::init_public_params(); + libff::bls12_377_pp::init_public_params(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From abb7c0d9d353c63343ede9d89596dc17103b0253 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Fri, 5 Mar 2021 11:51:53 +0000 Subject: [PATCH 086/137] libzeth: make snark-specific serialization interface consistent with other functions. add tests. --- libzeth/snarks/groth16/groth16_snark.hpp | 23 +++++------ libzeth/snarks/groth16/groth16_snark.tcc | 40 ++++++++----------- libzeth/snarks/pghr13/pghr13_snark.hpp | 23 +++++------ libzeth/snarks/pghr13/pghr13_snark.tcc | 38 ++++++++---------- .../tests/core/group_element_utils_test.cpp | 4 +- libzeth/tests/mpc/groth16/mpc_test.cpp | 4 +- libzeth/tests/snarks/common_snark_tests.tcc | 28 ++++++++++--- prover_server/prover_server.cpp | 5 ++- 8 files changed, 85 insertions(+), 80 deletions(-) diff --git a/libzeth/snarks/groth16/groth16_snark.hpp b/libzeth/snarks/groth16/groth16_snark.hpp index c393cebfe..b129e8d16 100644 --- a/libzeth/snarks/groth16/groth16_snark.hpp +++ b/libzeth/snarks/groth16/groth16_snark.hpp @@ -40,33 +40,30 @@ template class groth16_snark const verification_key &verification_key); /// Write verification as json - static std::ostream &verification_key_write_json( + static void verification_key_write_json( const verification_key &, std::ostream &); /// Write verification key as bytes - static std::ostream &verification_key_write_bytes( + static void verification_key_write_bytes( const verification_key &, std::ostream &); /// Read a verification key as bytes - static verification_key verification_key_read_bytes(std::istream &); + static void verification_key_read_bytes(verification_key &, std::istream &); /// Write proving key as bytes - static std::ostream &proving_key_write_bytes( - const proving_key &, std::ostream &); + static void proving_key_write_bytes(const proving_key &, std::ostream &); /// Read proving key as bytes - static proving_key proving_key_read_bytes(std::istream &); + static void proving_key_read_bytes(proving_key &, std::istream &); /// Write proof as json. - static std::ostream &proof_write_json( - const proof &proof, std::ostream &out_s); - - /// Write a keypair as bytes - static std::ostream &keypair_write_bytes( - const keypair &keypair, std::ostream &out_s); + static void proof_write_json(const proof &, std::ostream &); /// Read a keypair from a stream. - static keypair keypair_read_bytes(std::istream &); + static void keypair_read_bytes(keypair &, std::istream &); + + /// Write a keypair as bytes + static void keypair_write_bytes(const keypair &, std::ostream &); }; /// Check well-formedness of a proving key diff --git a/libzeth/snarks/groth16/groth16_snark.tcc b/libzeth/snarks/groth16/groth16_snark.tcc index 819802b13..6e2dee729 100644 --- a/libzeth/snarks/groth16/groth16_snark.tcc +++ b/libzeth/snarks/groth16/groth16_snark.tcc @@ -50,7 +50,7 @@ bool groth16_snark::verify( } template -std::ostream &groth16_snark::verification_key_write_json( +void groth16_snark::verification_key_write_json( const verification_key &vk, std::ostream &out_s) { const size_t abc_length = vk.ABC_g1.rest.indices.size() + 1; @@ -64,80 +64,72 @@ std::ostream &groth16_snark::verification_key_write_json( out_s << ",\n " << group_element_to_json(vk.ABC_g1.rest.values[i - 1]); } - return out_s << "\n ]\n}"; + out_s << "\n ]\n}"; } template -std::ostream &groth16_snark::verification_key_write_bytes( +void groth16_snark::verification_key_write_bytes( const verification_key &vk, std::ostream &out_s) { if (!is_well_formed(vk)) { throw std::invalid_argument("verification key (write) not well-formed"); } - return out_s << vk; + out_s << vk; } template -std::ostream &groth16_snark::proving_key_write_bytes( +void groth16_snark::proving_key_write_bytes( const proving_key &pk, std::ostream &out_s) { if (!is_well_formed(pk)) { throw std::invalid_argument("proving key (write) not well-formed"); } - return out_s << pk; + out_s << pk; } template -typename groth16_snark::verification_key groth16_snark< - ppT>::verification_key_read_bytes(std::istream &in_s) +void groth16_snark::verification_key_read_bytes( + groth16_snark::verification_key &vk, std::istream &in_s) { - verification_key vk; in_s >> vk; if (!is_well_formed(vk)) { throw std::invalid_argument("verification key (read) not well-formed"); } - return vk; } template -typename groth16_snark::proving_key groth16_snark< - ppT>::proving_key_read_bytes(std::istream &in_s) +void groth16_snark::proving_key_read_bytes( + groth16_snark::proving_key &pk, std::istream &in_s) { - proving_key pk; in_s >> pk; if (!is_well_formed(pk)) { throw std::invalid_argument("proving key (read) not well-formed"); } - return pk; } template -std::ostream &groth16_snark::keypair_write_bytes( +void groth16_snark::keypair_write_bytes( const typename groth16_snark::keypair &keypair, std::ostream &out_s) { proving_key_write_bytes(keypair.pk, out_s); verification_key_write_bytes(keypair.vk, out_s); - return out_s; } template -typename groth16_snark::keypair groth16_snark::keypair_read_bytes( - std::istream &in_s) +void groth16_snark::keypair_read_bytes( + typename groth16_snark::keypair &keypair, std::istream &in_s) { - proving_key pk = proving_key_read_bytes(in_s); - verification_key vk = verification_key_read_bytes(in_s); - return libsnark::r1cs_gg_ppzksnark_keypair( - std::move(pk), std::move(vk)); + proving_key_read_bytes(keypair.pk, in_s); + verification_key_read_bytes(keypair.vk, in_s); } template -std::ostream &groth16_snark::proof_write_json( +void groth16_snark::proof_write_json( const typename groth16_snark::proof &proof, std::ostream &out_s) { out_s << "{\n \"a\": " << group_element_to_json(proof.g_A) << ",\n \"b\": " << group_element_to_json(proof.g_B) << ",\n \"c\": " << group_element_to_json(proof.g_C) << "\n}"; - return out_s; } template diff --git a/libzeth/snarks/pghr13/pghr13_snark.hpp b/libzeth/snarks/pghr13/pghr13_snark.hpp index 48c83a934..7f3654684 100644 --- a/libzeth/snarks/pghr13/pghr13_snark.hpp +++ b/libzeth/snarks/pghr13/pghr13_snark.hpp @@ -40,31 +40,30 @@ template class pghr13_snark const verification_key &verification_key); /// Write verification as json - static std::ostream &verification_key_write_json( + static void verification_key_write_json( const verification_key &, std::ostream &); /// Write verification key as bytes - static std::ostream &verification_key_write_bytes( + static void verification_key_write_bytes( const verification_key &, std::ostream &); /// Read a verification key as bytes - static verification_key verification_key_read_bytes(std::istream &); + static void verification_key_read_bytes(verification_key &, std::istream &); /// Write proving key as bytes - static std::ostream &proving_key_write_bytes( - const proving_key &, std::ostream &); + static void proving_key_write_bytes(const proving_key &, std::ostream &); /// Read proving key as bytes - static proving_key proving_key_read_bytes(std::istream &); + static void proving_key_read_bytes(proving_key &, std::istream &); - /// Write proof as json - static std::ostream &proof_write_json(const proof &, std::ostream &); - - /// Write a keypair to a stream. - static std::ostream &keypair_write_bytes(const keypair &, std::ostream &); + /// Write proof as json. + static void proof_write_json(const proof &, std::ostream &); /// Read a keypair from a stream. - static keypair keypair_read_bytes(std::istream &); + static void keypair_read_bytes(keypair &, std::istream &); + + /// Write a keypair as bytes + static void keypair_write_bytes(const keypair &, std::ostream &); }; } // namespace libzeth diff --git a/libzeth/snarks/pghr13/pghr13_snark.tcc b/libzeth/snarks/pghr13/pghr13_snark.tcc index 4d9278a3a..669534597 100644 --- a/libzeth/snarks/pghr13/pghr13_snark.tcc +++ b/libzeth/snarks/pghr13/pghr13_snark.tcc @@ -51,7 +51,7 @@ bool pghr13_snark::verify( } template -std::ostream &pghr13_snark::verification_key_write_json( +void pghr13_snark::verification_key_write_json( const pghr13_snark::verification_key &vk, std::ostream &os) { unsigned ic_length = vk.encoded_IC_query.rest.indices.size() + 1; @@ -74,43 +74,38 @@ std::ostream &pghr13_snark::verification_key_write_json( os << "]\n"; os << "}"; - return os; } template -std::ostream &pghr13_snark::verification_key_write_bytes( +void pghr13_snark::verification_key_write_bytes( const typename pghr13_snark::verification_key &vk, std::ostream &os) { - return os << vk; + os << vk; } template -typename pghr13_snark::verification_key pghr13_snark< - ppT>::verification_key_read_bytes(std::istream &in_s) +void pghr13_snark::verification_key_read_bytes( + typename pghr13_snark::verification_key &vk, std::istream &in_s) { - verification_key vk; in_s >> vk; - return vk; } template -std::ostream &pghr13_snark::proving_key_write_bytes( +void pghr13_snark::proving_key_write_bytes( const typename pghr13_snark::proving_key &pk, std::ostream &os) { - return os << pk; + os << pk; } template -typename pghr13_snark::proving_key pghr13_snark< - ppT>::proving_key_read_bytes(std::istream &in_s) +void pghr13_snark::proving_key_read_bytes( + typename pghr13_snark::proving_key &pk, std::istream &in_s) { - proving_key pk; in_s >> pk; - return pk; } template -std::ostream &pghr13_snark::proof_write_json( +void pghr13_snark::proof_write_json( const typename pghr13_snark::proof &proof, std::ostream &os) { os << "{\n"; @@ -123,23 +118,22 @@ std::ostream &pghr13_snark::proof_write_json( os << " \"h\": " << group_element_to_json(proof.g_H) << ",\n"; os << " \"k\": " << group_element_to_json(proof.g_K) << "\n"; os << "}"; - return os; } template -std::ostream &pghr13_snark::keypair_write_bytes( +void pghr13_snark::keypair_write_bytes( const typename pghr13_snark::keypair &keypair, std::ostream &os) { proving_key_write_bytes(keypair.pk, os); - return verification_key_write_bytes(keypair.vk, os); + verification_key_write_bytes(keypair.vk, os); } template -typename pghr13_snark::keypair pghr13_snark::keypair_read_bytes( - std::istream &in_s) +void pghr13_snark::keypair_read_bytes( + typename pghr13_snark::keypair &keypair, std::istream &in_s) { - return keypair( - proving_key_read_bytes(in_s), verification_key_read_bytes(in_s)); + proving_key_read_bytes(keypair.pk, in_s); + verification_key_read_bytes(keypair.vk, in_s); } } // namespace libzeth diff --git a/libzeth/tests/core/group_element_utils_test.cpp b/libzeth/tests/core/group_element_utils_test.cpp index 829bd31ec..28b3fe28f 100644 --- a/libzeth/tests/core/group_element_utils_test.cpp +++ b/libzeth/tests/core/group_element_utils_test.cpp @@ -147,14 +147,14 @@ template static void group_elements_encode_decode_bytes_test() std::string buffer; { std::stringstream ss; - libzeth::group_elements_write_bytes(elements, ss); + libzeth::group_elements_write_bytes(elements, ss); buffer = ss.str(); } std::vector elements_decoded; { std::stringstream ss(buffer); - libzeth::group_elements_read_bytes(elements_decoded, ss); + libzeth::group_elements_read_bytes(elements_decoded, ss); } ASSERT_EQ(elements, elements_decoded); diff --git a/libzeth/tests/mpc/groth16/mpc_test.cpp b/libzeth/tests/mpc/groth16/mpc_test.cpp index 5661633db..2dfc22943 100644 --- a/libzeth/tests/mpc/groth16/mpc_test.cpp +++ b/libzeth/tests/mpc/groth16/mpc_test.cpp @@ -443,7 +443,9 @@ TEST(MPCTests, KeyPairReadWrite) in.exceptions( std::ios_base::eofbit | std::ios_base::badbit | std::ios_base::failbit); - return groth16_snark::keypair_read_bytes(in); + typename groth16_snark::keypair kp; + groth16_snark::keypair_read_bytes(kp, in); + return kp; }(); ASSERT_EQ(keypair.pk, keypair_deserialized.pk); diff --git a/libzeth/tests/snarks/common_snark_tests.tcc b/libzeth/tests/snarks/common_snark_tests.tcc index b1e8c889c..4c7d7fbd9 100644 --- a/libzeth/tests/snarks/common_snark_tests.tcc +++ b/libzeth/tests/snarks/common_snark_tests.tcc @@ -5,6 +5,8 @@ #ifndef __ZETH_TESTS_SNARKS_COMMON_SNARK_TESTS_TCC__ #define __ZETH_TESTS_SNARKS_COMMON_SNARK_TESTS_TCC__ +#include "libzeth/tests/circuits/simple_test.hpp" + #include #include @@ -19,6 +21,15 @@ static const size_t DUMMY_NUM_PRIMARY_INPUTS = 37; template typename snarkT::proving_key dummy_proving_key() { + using Field = libff::Fr; + libsnark::protoboard pb; + libzeth::tests::simple_circuit(pb); + libzeth::tests::simple_circuit(pb); + libzeth::tests::simple_circuit(pb); + libzeth::tests::simple_circuit(pb); + + typename snarkT::keypair keypair = snarkT::generate_setup(pb); + return keypair.pk; } template @@ -34,9 +45,12 @@ bool verification_key_read_write_bytes_test() return ss.str(); })(); - std::stringstream ss(buffer); - const typename snarkT::verification_key vk2 = - snarkT::verification_key_read_bytes(ss); + typename snarkT::verification_key vk2; + { + std::stringstream ss(buffer); + snarkT::verification_key_read_bytes(vk2, ss); + } + return vk == vk2; } @@ -50,8 +64,12 @@ template bool proving_key_read_write_bytes_test() return ss.str(); })(); - std::stringstream ss(buffer); - const typename snarkT::proving_key pk2 = snarkT::proving_key_read_bytes(ss); + typename snarkT::proving_key pk2; + { + std::stringstream ss(buffer); + snarkT::proving_key_read_bytes(pk2, ss); + } + return pk == pk2; } diff --git a/prover_server/prover_server.cpp b/prover_server/prover_server.cpp index c7213681f..9b1f315a0 100644 --- a/prover_server/prover_server.cpp +++ b/prover_server/prover_server.cpp @@ -55,7 +55,10 @@ static snark::keypair load_keypair(const boost::filesystem::path &keypair_file) keypair_file.c_str(), std::ios_base::in | std::ios_base::binary); in_s.exceptions( std::ios_base::eofbit | std::ios_base::badbit | std::ios_base::failbit); - return snark::keypair_read_bytes(in_s); + + snark::keypair keypair; + snark::keypair_read_bytes(keypair, in_s); + return keypair; } static void write_keypair( From 28d32ce6662b959c02af0082534dd3feb5ac062c Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Fri, 5 Mar 2021 12:00:53 +0000 Subject: [PATCH 087/137] libzeth: some generic collection serialization util functions. vector of group element serialization. --- libzeth/core/group_element_utils.hpp | 4 +- libzeth/core/group_element_utils.tcc | 25 +++--- libzeth/serialization/stream_utils.hpp | 58 ++++++++++++- libzeth/serialization/stream_utils.tcc | 114 +++++++++++++++++++++++++ 4 files changed, 184 insertions(+), 17 deletions(-) diff --git a/libzeth/core/group_element_utils.hpp b/libzeth/core/group_element_utils.hpp index 40ec0bd85..13e7b0424 100644 --- a/libzeth/core/group_element_utils.hpp +++ b/libzeth/core/group_element_utils.hpp @@ -39,13 +39,13 @@ void group_element_read_bytes(GroupT &point, std::istream &in_s); /// Write a collection of group elements as bytes to a stream, using /// group_element_write_bytes. -template +template void group_elements_write_bytes( const GroupCollectionT &points, std::ostream &out_s); /// Read a collection of group elements as bytes, usinng /// group_elements_read_bytes. -template +template void group_elements_read_bytes(GroupCollectionT &points, std::istream &in_s); } // namespace libzeth diff --git a/libzeth/core/group_element_utils.tcc b/libzeth/core/group_element_utils.tcc index a0ea4d9ff..ced405a00 100644 --- a/libzeth/core/group_element_utils.tcc +++ b/libzeth/core/group_element_utils.tcc @@ -6,6 +6,7 @@ #define __ZETH_CORE_GROUP_ELEMENT_UTILS_TCC__ #include "libzeth/core/field_element_utils.hpp" +#include "libzeth/serialization/stream_utils.hpp" namespace libzeth { @@ -111,27 +112,23 @@ void group_element_read_bytes(GroupT &point, std::istream &in_s) } } -template +template void group_elements_write_bytes( const GroupCollectionT &points, std::ostream &out_s) { - write_bytes(points.size(), out_s); - for (const auto &pt : points) { - group_element_write_bytes(pt, out_s); - } + collection_write_bytes< + GroupT, + GroupCollectionT, + group_element_write_bytes>(points, out_s); } -template +template void group_elements_read_bytes(GroupCollectionT &points, std::istream &in_s) { - const size_t num_points = read_bytes(in_s); - - points.clear(); - points.reserve(num_points); - for (size_t i = 0; i < num_points; ++i) { - points.emplace_back(); - group_element_read_bytes(points.back(), in_s); - } + collection_read_bytes< + GroupT, + GroupCollectionT, + group_element_read_bytes>(points, in_s); } } // namespace libzeth diff --git a/libzeth/serialization/stream_utils.hpp b/libzeth/serialization/stream_utils.hpp index c9991be7e..2d07efd29 100644 --- a/libzeth/serialization/stream_utils.hpp +++ b/libzeth/serialization/stream_utils.hpp @@ -5,6 +5,11 @@ #ifndef __ZETH_SERIALIZATION_STREAM_UTILS_HPP__ #define __ZETH_SERIALIZATION_STREAM_UTILS_HPP__ +#include "libzeth/core/include_libsnark.hpp" + +#include +#include + namespace libzeth { @@ -18,11 +23,62 @@ template typename std::enable_if::value, void>::type read_bytes( T &val, std::istream &in_s); -// Write a primitive datatype to a stream as raw bytes.ap +// Write a primitive datatype to a stream as raw bytes. template typename std::enable_if::value, void>::type write_bytes( const T &val, std::ostream &out_s); +/// Write the first n from a collection of values, using a specified writer +/// function. +template< + typename ValueT, + typename CollectionT, + void(WriterT)(const ValueT &, std::ostream &)> +void collection_n_write_bytes( + const CollectionT &collection, const size_t n, std::ostream &out_s); + +/// Read n element using a specified reader function, appending to the given +/// collection. +template< + typename ValueT, + typename CollectionT, + void(ReaderT)(ValueT &, std::istream &)> +void collection_n_read_bytes_n( + CollectionT &collection, const size_t n, std::istream &in_s); + +/// Write a full collection of group elements to a stream as bytes, using +/// a specific writer function. +template< + typename ValueT, + typename CollectionT, + void(WriterT)(const ValueT &, std::ostream &)> +void collection_write_bytes(const CollectionT &collection, std::ostream &out_s); + +/// Read a collection of group elements as bytes, usinng +/// group_elements_read_bytes. +template< + typename ValueT, + typename CollectionT, + void(ReaderT)(ValueT &, std::istream &)> +void collection_read_bytes(CollectionT &points, std::istream &in_s); + +template +void sparse_vector_read_bytes( + libsnark::sparse_vector &sparse_vector, std::istream &in_s); + +template +void sparse_vector_write_bytes( + const libsnark::sparse_vector &sparse_vector, std::ostream &out_s); + +template +void accumulation_vector_read_bytes( + libsnark::accumulation_vector &acc_vector, std::istream &in_s); + +template +void accumulation_vector_write_bytes( + const libsnark::accumulation_vector &acc_vector, + std::ostream &out_s); + } // namespace libzeth #include "libzeth/serialization/stream_utils.tcc" diff --git a/libzeth/serialization/stream_utils.tcc b/libzeth/serialization/stream_utils.tcc index f28809b66..c7d2573ea 100644 --- a/libzeth/serialization/stream_utils.tcc +++ b/libzeth/serialization/stream_utils.tcc @@ -33,6 +33,120 @@ typename std::enable_if::value, void>::type write_bytes( out_s.write((const char *)(&val), sizeof(T)); } +/// Write the first n from a collection of values, using a specified writer +/// function. +template< + typename ValueT, + typename CollectionT, + void(WriterFn)(const ValueT &, std::ostream &)> +void collection_n_write_bytes( + const CollectionT &collection, const size_t n, std::ostream &out_s) +{ + for (size_t i = 0; i < n; ++i) { + WriterFn(collection[i], out_s); + } +} + +/// Read n element using a specified reader function, appending to the given +/// collection. +template< + typename ValueT, + typename CollectionT, + void(ReaderFn)(ValueT &, std::istream &)> +void collection_n_read_bytes( + CollectionT &collection, const size_t n, std::istream &in_s) +{ + for (size_t i = 0; i < n; ++i) { + collection.emplace_back(); + ReaderFn(collection.back(), in_s); + } +} + +/// Write a full collection of values to a stream as bytes, using +/// a specific writer function. +template< + typename ValueT, + typename CollectionT, + void(WriterT)(const ValueT &, std::ostream &)> +void collection_write_bytes(const CollectionT &collection, std::ostream &out_s) +{ + write_bytes(collection.size(), out_s); + collection_n_write_bytes( + collection, collection.size(), out_s); +} + +/// Read a collection of values, from a stream of bytes, using +/// a specific reader function. +template< + typename ValueT, + typename CollectionT, + void(ReaderT)(ValueT &, std::istream &)> +void collection_read_bytes(CollectionT &collection, std::istream &in_s) +{ + const size_t n = read_bytes(in_s); + + collection.clear(); + collection.reserve(n); + collection_n_read_bytes(collection, n, in_s); +} + +template +void sparse_vector_read_bytes( + libsnark::sparse_vector &sparse_vector, std::istream &in_s) +{ + sparse_vector.domain_size_ = read_bytes(in_s); + const size_t num_entries = read_bytes(in_s); + sparse_vector.indices.clear(); + sparse_vector.indices.reserve(num_entries); + sparse_vector.values.clear(); + sparse_vector.values.reserve(num_entries); + + for (size_t i = 0; i < num_entries; ++i) { + sparse_vector.indices.push_back(read_bytes(in_s)); + sparse_vector.values.emplace_back(); + ReaderFn(sparse_vector.values.back(), in_s); + } +} + +template +void sparse_vector_write_bytes( + const libsnark::sparse_vector &sparse_vector, std::ostream &out_s) +{ + const size_t num_entries = sparse_vector.indices.size(); + assert(num_entries == sparse_vector.values.size()); + + write_bytes(sparse_vector.domain_size_, out_s); + write_bytes(num_entries, out_s); + for (size_t i = 0; i < num_entries; ++i) { + write_bytes(sparse_vector.indices[i], out_s); + WriterFn(sparse_vector.values[i], out_s); + } +} + +template +void accumulation_vector_read_bytes( + libsnark::accumulation_vector &acc_vector, std::istream &in_s) +{ + // const size_t num_elements = read_bytes(in_s); + // assert(num_elements > 0); + // group_element_read_bytes(acc_vector.first); + // acc_vector.rest.clear(); + // acc_vector.rest.reserve(); + + // acc_vector. + + ReaderFn(acc_vector.first, in_s); + sparse_vector_read_bytes(acc_vector.rest, in_s); +} + +template +void accumulation_vector_write_bytes( + const libsnark::accumulation_vector &acc_vector, std::ostream &out_s) +{ + WriterFn(acc_vector.first, out_s); + sparse_vector_write_bytes(acc_vector.rest, out_s); +} + } // namespace libzeth #endif // __ZETH_SERIALIZATION_STREAM_UTILS_TCC__ From 38abe1e9faa21c81f42fb220626c9d202526f5fb Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Fri, 5 Mar 2021 16:59:32 +0000 Subject: [PATCH 088/137] libzeth: use more type-inference to simplify serialization function composability --- libzeth/core/group_element_utils.hpp | 4 +- libzeth/core/group_element_utils.tcc | 18 +++--- ...r1cs_variable_assignment_serialization.tcc | 2 - libzeth/serialization/stream_utils.hpp | 43 ++++++++----- libzeth/serialization/stream_utils.tcc | 63 +++++++++++++------ libzeth/snarks/groth16/groth16_snark.tcc | 43 +++++++++++-- .../tests/core/group_element_utils_test.cpp | 4 +- 7 files changed, 121 insertions(+), 56 deletions(-) diff --git a/libzeth/core/group_element_utils.hpp b/libzeth/core/group_element_utils.hpp index 13e7b0424..40ec0bd85 100644 --- a/libzeth/core/group_element_utils.hpp +++ b/libzeth/core/group_element_utils.hpp @@ -39,13 +39,13 @@ void group_element_read_bytes(GroupT &point, std::istream &in_s); /// Write a collection of group elements as bytes to a stream, using /// group_element_write_bytes. -template +template void group_elements_write_bytes( const GroupCollectionT &points, std::ostream &out_s); /// Read a collection of group elements as bytes, usinng /// group_elements_read_bytes. -template +template void group_elements_read_bytes(GroupCollectionT &points, std::istream &in_s); } // namespace libzeth diff --git a/libzeth/core/group_element_utils.tcc b/libzeth/core/group_element_utils.tcc index ced405a00..6dbadcc6b 100644 --- a/libzeth/core/group_element_utils.tcc +++ b/libzeth/core/group_element_utils.tcc @@ -93,7 +93,7 @@ GroupT group_element_from_json(const std::string &json) template void group_element_write_bytes(const GroupT &point, std::ostream &out_s) { - GroupT affine_p = point; + typename std::decay::type affine_p = point; affine_p.to_affine_coordinates(); field_element_write_bytes(affine_p.X, out_s); field_element_write_bytes(affine_p.Y, out_s); @@ -112,23 +112,19 @@ void group_element_read_bytes(GroupT &point, std::istream &in_s) } } -template +template void group_elements_write_bytes( const GroupCollectionT &points, std::ostream &out_s) { - collection_write_bytes< - GroupT, - GroupCollectionT, - group_element_write_bytes>(points, out_s); + collection_write_bytes( + points, out_s); } -template +template void group_elements_read_bytes(GroupCollectionT &points, std::istream &in_s) { - collection_read_bytes< - GroupT, - GroupCollectionT, - group_element_read_bytes>(points, in_s); + collection_read_bytes( + points, in_s); } } // namespace libzeth diff --git a/libzeth/serialization/r1cs_variable_assignment_serialization.tcc b/libzeth/serialization/r1cs_variable_assignment_serialization.tcc index 06189e4a4..a36cb095e 100644 --- a/libzeth/serialization/r1cs_variable_assignment_serialization.tcc +++ b/libzeth/serialization/r1cs_variable_assignment_serialization.tcc @@ -17,7 +17,6 @@ void r1cs_variable_assignment_read_bytes( libsnark::r1cs_variable_assignment &assignment, std::istream &in_s) { collection_read_bytes< - FieldT, libsnark::r1cs_variable_assignment, field_element_read_bytes>(assignment, in_s); } @@ -28,7 +27,6 @@ void r1cs_variable_assignment_write_bytes( std::ostream &out_s) { collection_write_bytes< - FieldT, libsnark::r1cs_variable_assignment, field_element_write_bytes>(assignment, out_s); } diff --git a/libzeth/serialization/stream_utils.hpp b/libzeth/serialization/stream_utils.hpp index 2d07efd29..dfd27b6c2 100644 --- a/libzeth/serialization/stream_utils.hpp +++ b/libzeth/serialization/stream_utils.hpp @@ -13,6 +13,12 @@ namespace libzeth { +/// Statically derive the type of the element contained in a (vector-like) +/// collection. +template +using MemberT = + typename std::decay::type; + /// Read a primitive datatype from a stream as raw bytes. template typename std::enable_if::value, T>::type read_bytes( @@ -31,53 +37,56 @@ typename std::enable_if::value, void>::type write_bytes( /// Write the first n from a collection of values, using a specified writer /// function. template< - typename ValueT, typename CollectionT, - void(WriterT)(const ValueT &, std::ostream &)> + void(WriterT)(const MemberT &, std::ostream &)> void collection_n_write_bytes( const CollectionT &collection, const size_t n, std::ostream &out_s); /// Read n element using a specified reader function, appending to the given /// collection. template< - typename ValueT, typename CollectionT, - void(ReaderT)(ValueT &, std::istream &)> + void(ReaderT)(MemberT &, std::istream &)> void collection_n_read_bytes_n( CollectionT &collection, const size_t n, std::istream &in_s); /// Write a full collection of group elements to a stream as bytes, using /// a specific writer function. template< - typename ValueT, typename CollectionT, - void(WriterT)(const ValueT &, std::ostream &)> + void(WriterT)(const MemberT &, std::ostream &)> void collection_write_bytes(const CollectionT &collection, std::ostream &out_s); /// Read a collection of group elements as bytes, usinng /// group_elements_read_bytes. template< - typename ValueT, typename CollectionT, - void(ReaderT)(ValueT &, std::istream &)> + void(ReaderT)(MemberT &, std::istream &)> void collection_read_bytes(CollectionT &points, std::istream &in_s); -template +template void sparse_vector_read_bytes( - libsnark::sparse_vector &sparse_vector, std::istream &in_s); + libsnark::sparse_vector &sparse_vector, std::istream &in_s); -template +template void sparse_vector_write_bytes( - const libsnark::sparse_vector &sparse_vector, std::ostream &out_s); + const libsnark::sparse_vector &sparse_vector, std::ostream &out_s); -template +template void accumulation_vector_read_bytes( - libsnark::accumulation_vector &acc_vector, std::istream &in_s); + libsnark::accumulation_vector &acc_vector, std::istream &in_s); -template +template void accumulation_vector_write_bytes( - const libsnark::accumulation_vector &acc_vector, - std::ostream &out_s); + const libsnark::accumulation_vector &acc_vector, std::ostream &out_s); + +template +void knowledge_commitment_vector_read_bytes( + kcvectorT &knowledge_commitment, std::istream &in_s); + +template +void knowledge_commitment_vector_write_bytes( + const kcvectorT &knowledge_commitment, std::ostream &out_s); } // namespace libzeth diff --git a/libzeth/serialization/stream_utils.tcc b/libzeth/serialization/stream_utils.tcc index c7d2573ea..d33c40cfc 100644 --- a/libzeth/serialization/stream_utils.tcc +++ b/libzeth/serialization/stream_utils.tcc @@ -5,6 +5,7 @@ #ifndef __ZETH_SERIALIZATION_STREAM_UTILS_TCC__ #define __ZETH_SERIALIZATION_STREAM_UTILS_TCC__ +#include "libzeth/core/group_element_utils.hpp" #include "libzeth/serialization/stream_utils.hpp" namespace libzeth @@ -36,9 +37,9 @@ typename std::enable_if::value, void>::type write_bytes( /// Write the first n from a collection of values, using a specified writer /// function. template< - typename ValueT, + // typename ValueT, typename CollectionT, - void(WriterFn)(const ValueT &, std::ostream &)> + void(WriterFn)(const MemberT &, std::ostream &)> void collection_n_write_bytes( const CollectionT &collection, const size_t n, std::ostream &out_s) { @@ -50,9 +51,8 @@ void collection_n_write_bytes( /// Read n element using a specified reader function, appending to the given /// collection. template< - typename ValueT, typename CollectionT, - void(ReaderFn)(ValueT &, std::istream &)> + void(ReaderFn)(MemberT &, std::istream &)> void collection_n_read_bytes( CollectionT &collection, const size_t n, std::istream &in_s) { @@ -65,29 +65,28 @@ void collection_n_read_bytes( /// Write a full collection of values to a stream as bytes, using /// a specific writer function. template< - typename ValueT, typename CollectionT, - void(WriterT)(const ValueT &, std::ostream &)> + void(WriterT)(const MemberT &, std::ostream &)> void collection_write_bytes(const CollectionT &collection, std::ostream &out_s) { write_bytes(collection.size(), out_s); - collection_n_write_bytes( + collection_n_write_bytes( collection, collection.size(), out_s); } /// Read a collection of values, from a stream of bytes, using /// a specific reader function. template< - typename ValueT, + // typename ValueT, typename CollectionT, - void(ReaderT)(ValueT &, std::istream &)> + void(ReaderT)(MemberT &, std::istream &)> void collection_read_bytes(CollectionT &collection, std::istream &in_s) { const size_t n = read_bytes(in_s); collection.clear(); collection.reserve(n); - collection_n_read_bytes(collection, n, in_s); + collection_n_read_bytes(collection, n, in_s); } template @@ -127,14 +126,6 @@ template void accumulation_vector_read_bytes( libsnark::accumulation_vector &acc_vector, std::istream &in_s) { - // const size_t num_elements = read_bytes(in_s); - // assert(num_elements > 0); - // group_element_read_bytes(acc_vector.first); - // acc_vector.rest.clear(); - // acc_vector.rest.reserve(); - - // acc_vector. - ReaderFn(acc_vector.first, in_s); sparse_vector_read_bytes(acc_vector.rest, in_s); } @@ -147,6 +138,42 @@ void accumulation_vector_write_bytes( sparse_vector_write_bytes(acc_vector.rest, out_s); } +template +void knowledge_commitment_read_bytes( + kcT &knowledge_commitment, std::istream &in_s) +{ + group_element_read_bytes(knowledge_commitment.g, in_s); + group_element_read_bytes(knowledge_commitment.h, in_s); +} + +template +void knowledge_commitment_write_bytes( + const kcT &knowledge_commitment, std::ostream &out_s) +{ + group_element_write_bytes(knowledge_commitment.g, out_s); + group_element_write_bytes(knowledge_commitment.h, out_s); +} + +template +void knowledge_commitment_vector_read_bytes( + kcvectorT &knowledge_commitment_vector, std::istream &in_s) +{ + using kcT = typename std::decay::type; + sparse_vector_read_bytes>( + knowledge_commitment_vector, in_s); +} + +template +void knowledge_commitment_vector_write_bytes( + const kcvectorT &knowledge_commitment_vector, std::ostream &out_s) +{ + using kcT = typename std::decay::type; + sparse_vector_write_bytes>( + knowledge_commitment_vector, out_s); +} + } // namespace libzeth #endif // __ZETH_SERIALIZATION_STREAM_UTILS_TCC__ diff --git a/libzeth/snarks/groth16/groth16_snark.tcc b/libzeth/snarks/groth16/groth16_snark.tcc index 6e2dee729..a10fc4dab 100644 --- a/libzeth/snarks/groth16/groth16_snark.tcc +++ b/libzeth/snarks/groth16/groth16_snark.tcc @@ -7,6 +7,7 @@ #include "libzeth/core/group_element_utils.hpp" #include "libzeth/core/utils.hpp" +#include "libzeth/serialization/r1cs_serialization.hpp" #include "libzeth/snarks/groth16/groth16_snark.hpp" namespace libzeth @@ -71,10 +72,17 @@ template void groth16_snark::verification_key_write_bytes( const verification_key &vk, std::ostream &out_s) { + using G1 = libff::G1; + if (!is_well_formed(vk)) { throw std::invalid_argument("verification key (write) not well-formed"); } - out_s << vk; + + group_element_write_bytes(vk.alpha_g1, out_s); + group_element_write_bytes(vk.beta_g2, out_s); + group_element_write_bytes(vk.delta_g2, out_s); + accumulation_vector_write_bytes>( + vk.ABC_g1, out_s); } template @@ -84,14 +92,31 @@ void groth16_snark::proving_key_write_bytes( if (!is_well_formed(pk)) { throw std::invalid_argument("proving key (write) not well-formed"); } - out_s << pk; + + group_element_write_bytes(pk.alpha_g1, out_s); + group_element_write_bytes(pk.beta_g1, out_s); + group_element_write_bytes(pk.beta_g2, out_s); + group_element_write_bytes(pk.delta_g1, out_s); + group_element_write_bytes(pk.delta_g2, out_s); + group_elements_write_bytes(pk.A_query, out_s); + knowledge_commitment_vector_write_bytes(pk.B_query, out_s); + group_elements_write_bytes(pk.H_query, out_s); + group_elements_write_bytes(pk.L_query, out_s); + r1cs_write_bytes(pk.constraint_system, out_s); } template void groth16_snark::verification_key_read_bytes( groth16_snark::verification_key &vk, std::istream &in_s) { - in_s >> vk; + using G1 = libff::G1; + + group_element_read_bytes(vk.alpha_g1, in_s); + group_element_read_bytes(vk.beta_g2, in_s); + group_element_read_bytes(vk.delta_g2, in_s); + accumulation_vector_read_bytes>( + vk.ABC_g1, in_s); + if (!is_well_formed(vk)) { throw std::invalid_argument("verification key (read) not well-formed"); } @@ -101,7 +126,17 @@ template void groth16_snark::proving_key_read_bytes( groth16_snark::proving_key &pk, std::istream &in_s) { - in_s >> pk; + group_element_read_bytes(pk.alpha_g1, in_s); + group_element_read_bytes(pk.beta_g1, in_s); + group_element_read_bytes(pk.beta_g2, in_s); + group_element_read_bytes(pk.delta_g1, in_s); + group_element_read_bytes(pk.delta_g2, in_s); + group_elements_read_bytes(pk.A_query, in_s); + knowledge_commitment_vector_read_bytes(pk.B_query, in_s); + group_elements_read_bytes(pk.H_query, in_s); + group_elements_read_bytes(pk.L_query, in_s); + r1cs_read_bytes(pk.constraint_system, in_s); + if (!is_well_formed(pk)) { throw std::invalid_argument("proving key (read) not well-formed"); } diff --git a/libzeth/tests/core/group_element_utils_test.cpp b/libzeth/tests/core/group_element_utils_test.cpp index 28b3fe28f..829bd31ec 100644 --- a/libzeth/tests/core/group_element_utils_test.cpp +++ b/libzeth/tests/core/group_element_utils_test.cpp @@ -147,14 +147,14 @@ template static void group_elements_encode_decode_bytes_test() std::string buffer; { std::stringstream ss; - libzeth::group_elements_write_bytes(elements, ss); + libzeth::group_elements_write_bytes(elements, ss); buffer = ss.str(); } std::vector elements_decoded; { std::stringstream ss(buffer); - libzeth::group_elements_read_bytes(elements_decoded, ss); + libzeth::group_elements_read_bytes(elements_decoded, ss); } ASSERT_EQ(elements, elements_decoded); From a2017ee2808804d9f1f82da3e2ef39a6d6d81e1f Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 10 Mar 2021 18:46:07 +0000 Subject: [PATCH 089/137] libzeth: write out binary snark object test data for compatibility tests --- .../snarks/groth16/groth16_snark_test.cpp | 158 ++++++++++++++++++ 1 file changed, 158 insertions(+) diff --git a/libzeth/tests/snarks/groth16/groth16_snark_test.cpp b/libzeth/tests/snarks/groth16/groth16_snark_test.cpp index 3193e1931..bee15e200 100644 --- a/libzeth/tests/snarks/groth16/groth16_snark_test.cpp +++ b/libzeth/tests/snarks/groth16/groth16_snark_test.cpp @@ -2,16 +2,168 @@ // // SPDX-License-Identifier: LGPL-3.0+ +#include "libzeth/serialization/proto_utils.hpp" +#include "libzeth/serialization/r1cs_variable_assignment_serialization.hpp" #include "libzeth/snarks/groth16/groth16_snark.hpp" #include "libzeth/tests/snarks/common_snark_tests.tcc" +#include #include #include #include +boost::filesystem::path g_output_dir = boost::filesystem::path(""); + namespace { +/// Simple function to generate serializations of snark-related data types for +/// groth16. These may not be well-formed, but have known values for testing +/// serialization compatibility in other components. Data is written to a file +/// with the given path. +template void generate_test_data() +{ + if (g_output_dir.empty()) { + std::cout << "Skipping groth16 test data output (" + << libzeth::pp_name() << ")\n"; + return; + } + + using groth16 = libzeth::groth16_snark; + using Field = libff::Fr; + using G1 = libff::G1; + using G2 = libff::G2; + const std::string curve_name = libzeth::pp_name(); + + // dummy constraint_system = + // primary_input = { x1, x2 }, (indices 1, 2) + // auxiliary_input = { w1, w2, w3 }, (3, 4, 5) + // constraints = { + // (2*x1 + 3*w1) * (4*x2 + 5*w2) = 6*w3 + 7*x1, + // (7*x2 + 6*w3) * (5*x1 + 4*w1) = 3*w2 + 2*x2, + // } + // + // (Note that these are constructed "manually" (rather than with a big + // constructor call) to avoid the sorting in the linear_combination + // constructor, which makes the order of terms less predictable. + libsnark::r1cs_constraint_system cs; + + libsnark::linear_combination cs1_A; + cs1_A.add_term({1, 2}); + cs1_A.add_term({3, 3}); + libsnark::linear_combination cs1_B; + cs1_B.add_term({2, 4}); + cs1_B.add_term({4, 5}); + libsnark::linear_combination cs1_C; + cs1_C.add_term({5, 6}); + cs1_C.add_term({1, 7}); + cs.add_constraint({cs1_A, cs1_B, cs1_C}); + + libsnark::linear_combination cs2_A; + cs2_A.add_term({2, 7}); + cs2_A.add_term({5, 6}); + libsnark::linear_combination cs2_B; + cs2_B.add_term({1, 5}); + cs2_B.add_term({3, 4}); + libsnark::linear_combination cs2_C; + cs2_C.add_term({4, 3}); + cs2_C.add_term({2, 2}); + cs.add_constraint({cs2_A, cs2_B, cs2_C}); + + cs.primary_input_size = 2; + cs.auxiliary_input_size = 3; + { + std::ofstream out_s( + (g_output_dir / ("groth16_r1cs_" + curve_name)).c_str(), + std::ios_base::out | std::ios_base::binary); + libzeth::r1cs_write_bytes(cs, out_s); + } + + // Proving key + const typename groth16::proving_key pk( + G1::one(), // alpha_g1 = [1]_1 + -G1::one(), // beta_g1 = [-1]_1 + -G2::one(), // beta_g2 = [-1]_2 + -(G1::one() + G1::one()), // beta_g1 = [-2]_1 + -(G2::one() + G2::one()), // beta_g2 = [-2]_2 + libff::G1_vector{{ + // A_query = { [7]_1, [-3]_1, [8]_1 } + Field("7") * G1::one(), + -Field("3") * G1::one(), + Field("8") * G1::one(), + }}, + libsnark::knowledge_commitment_vector( + std::vector>{{ + // B_query = { ([9]_1,[9]_2), ([-9]_1,[-9]_2), ([10]_1,[10}_2) } + libsnark::knowledge_commitment( + Field("9") * G2::one(), Field("9") * G1::one()), + libsnark::knowledge_commitment( + -Field("9") * G2::one(), -Field("9") * G1::one()), + libsnark::knowledge_commitment( + Field("10") * G2::one(), Field("10") * G1::one()), + }}), + {{ + // H_query = { [11]_1, [-11]_1, [12]_1 } + Field("11") * G1::one(), + -Field("11") * G1::one(), + Field("12") * G1::one(), + }}, + {{ + // L_query = { [13]_1, [-13]_1, [14]_1 } + Field("13") * G1::one(), + -Field("13") * G1::one(), + Field("14") * G1::one(), + }}, + std::move(cs)); + { + std::ofstream out_s( + (g_output_dir / ("groth16_proving_key_" + curve_name)).c_str(), + std::ios_base::out | std::ios_base::binary); + groth16::proving_key_write_bytes(pk, out_s); + } + + // Verification Key + const typename groth16::verification_key vk( + Field("21") * G1::one(), // alpha_g1 = [21]_1 + -Field("21") * G2::one(), // beta_g2 = [-21]_2 + Field("22") * G2::one(), // delta_g2 = [22]_2 + libsnark::accumulation_vector( + // ABC_g1 = { [13]_1, { [-13]_1, [14]_1 } } + Field("13") * G1::one(), + libff::G1_vector{{ + -Field("13") * G1::one(), + Field("14") * G1::one(), + }})); + { + std::ofstream out_s( + (g_output_dir / ("groth16_verification_key_" + curve_name)).c_str(), + std::ios_base::out | std::ios_base::binary); + groth16::verification_key_write_bytes(vk, out_s); + } + + // Variable assignment + const libsnark::r1cs_variable_assignment assignment{{ + Field("15"), + -Field("15"), + Field("16"), + -Field("16"), + Field("17"), + -Field("17"), + }}; + { + std::ofstream out_s( + (g_output_dir / ("groth16_assignment_" + curve_name)).c_str(), + std::ios_base::out | std::ios_base::binary); + libzeth::r1cs_variable_assignment_write_bytes(assignment, out_s); + } +} + +TEST(Groth16SnarkTest, Groth16TestData) +{ + generate_test_data(); + generate_test_data(); +} + TEST(Groth16SnarkTest, TestVerificationKeyReadWriteBytes) { const bool test_alt_bn128 = @@ -47,5 +199,11 @@ int main(int argc, char **argv) libff::alt_bn128_pp::init_public_params(); libff::bls12_377_pp::init_public_params(); ::testing::InitGoogleTest(&argc, argv); + + // Extract the test data destination dir, if passed on the command line. + if (argc > 1) { + g_output_dir = boost::filesystem::path(argv[1]); + } + return RUN_ALL_TESTS(); } From 1b9bb12e4881e6ace83fc797889291f6390222cb Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 30 Mar 2021 18:19:28 +0100 Subject: [PATCH 090/137] tests: support for writing out binary pk, vk and assignment for simple circuit --- libzeth/tests/circuits/simple_test.cpp | 35 +++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/libzeth/tests/circuits/simple_test.cpp b/libzeth/tests/circuits/simple_test.cpp index 0ae8595f5..47e35dc9a 100644 --- a/libzeth/tests/circuits/simple_test.cpp +++ b/libzeth/tests/circuits/simple_test.cpp @@ -6,16 +6,19 @@ #include "core/utils.hpp" #include "libzeth/serialization/r1cs_serialization.hpp" -#include "zeth_config.h" +#include "libzeth/snarks/groth16/groth16_snark.hpp" +#include "serialization/proto_utils.hpp" +#include "serialization/r1cs_variable_assignment_serialization.hpp" #include #include +#include using namespace libsnark; using namespace libzeth; -using pp = defaults::pp; -using Field = defaults::Field; +using pp = libff::alt_bn128_pp; +using Field = libff::Fr; boost::filesystem::path g_output_dir = boost::filesystem::path(""); @@ -34,8 +37,9 @@ TEST(SimpleTests, SimpleCircuitProof) // Write to file if output directory is given. if (!g_output_dir.empty()) { + boost::filesystem::path outpath = - g_output_dir / "simple_circuit_r1cs.json"; + g_output_dir / ("simple_circuit_r1cs_" + pp_name() + ".json"); std::ofstream r1cs_stream(outpath.c_str()); libzeth::r1cs_write_json(pb.get_constraint_system(), r1cs_stream); } @@ -65,6 +69,29 @@ TEST(SimpleTests, SimpleCircuitProof) ASSERT_TRUE( r1cs_gg_ppzksnark_verifier_strong_IC(keypair.vk, primary, proof)); + + if (!g_output_dir.empty()) { + { + boost::filesystem::path proving_key_path = + g_output_dir / ("simple_proving_key_" + pp_name() + ".bin"); + std::ofstream out_s(proving_key_path.c_str()); + groth16_snark::proving_key_write_bytes(keypair.pk, out_s); + } + { + boost::filesystem::path verification_key_path = + g_output_dir / + ("simple_verification_key_" + pp_name() + ".bin"); + std::ofstream out_s(verification_key_path.c_str()); + groth16_snark::verification_key_write_bytes(keypair.vk, out_s); + } + { + boost::filesystem::path primary_inputs_path = + g_output_dir / + ("simple_primary_input_" + pp_name() + ".bin"); + std::ofstream out_s(primary_inputs_path.c_str()); + r1cs_variable_assignment_write_bytes(primary, out_s); + } + } } TEST(SimpleTests, SimpleCircuitProofPow2Domain) From f50e60bfe9c88e30f1561bc27c02eefab2b2f307 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 31 Mar 2021 13:45:21 +0100 Subject: [PATCH 091/137] libsnark: more versatile proving interface --- libzeth/snarks/groth16/groth16_snark.hpp | 8 +++++++- libzeth/snarks/groth16/groth16_snark.tcc | 13 +++++++++---- libzeth/snarks/pghr13/pghr13_snark.hpp | 8 +++++++- libzeth/snarks/pghr13/pghr13_snark.tcc | 16 +++++++++------- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/libzeth/snarks/groth16/groth16_snark.hpp b/libzeth/snarks/groth16/groth16_snark.hpp index b129e8d16..4eaad4036 100644 --- a/libzeth/snarks/groth16/groth16_snark.hpp +++ b/libzeth/snarks/groth16/groth16_snark.hpp @@ -28,11 +28,17 @@ template class groth16_snark static keypair generate_setup( const libsnark::protoboard> &pb); - /// Generate the proof + /// Generate the proof (from the values set to the protoboard) static proof generate_proof( const libsnark::protoboard> &pb, const proving_key &proving_key); + /// Generate the proof (from given primary and auxiliary values) + static proof generate_proof( + const proving_key &proving_key, + const libsnark::r1cs_primary_input> &primary_input, + const libsnark::r1cs_auxiliary_input> auxiliary_input); + /// Verify proof static bool verify( const libsnark::r1cs_primary_input> &primary_inputs, diff --git a/libzeth/snarks/groth16/groth16_snark.tcc b/libzeth/snarks/groth16/groth16_snark.tcc index a10fc4dab..d1ccbfa56 100644 --- a/libzeth/snarks/groth16/groth16_snark.tcc +++ b/libzeth/snarks/groth16/groth16_snark.tcc @@ -29,11 +29,16 @@ typename groth16_snark::proof groth16_snark::generate_proof( const libsnark::protoboard> &pb, const typename groth16_snark::proving_key &proving_key) { - libsnark::r1cs_primary_input> primary_input = - pb.primary_input(); - libsnark::r1cs_auxiliary_input> auxiliary_input = - pb.auxiliary_input(); + return generate_proof( + proving_key, pb.primary_input(), pb.auxiliary_input()); +} +template +typename groth16_snark::proof groth16_snark::generate_proof( + const proving_key &proving_key, + const libsnark::r1cs_primary_input> &primary_input, + const libsnark::r1cs_auxiliary_input> auxiliary_input) +{ // Generate proof from public input, auxiliary input and proving key. // For now, force a pow2 domain, in case the key came from the MPC. return libsnark::r1cs_gg_ppzksnark_prover( diff --git a/libzeth/snarks/pghr13/pghr13_snark.hpp b/libzeth/snarks/pghr13/pghr13_snark.hpp index 7f3654684..d53bd1821 100644 --- a/libzeth/snarks/pghr13/pghr13_snark.hpp +++ b/libzeth/snarks/pghr13/pghr13_snark.hpp @@ -28,11 +28,17 @@ template class pghr13_snark static keypair generate_setup( const libsnark::protoboard> &pb); - /// Generate the proof + /// Generate the proof (from the values set to the protoboard) static proof generate_proof( const libsnark::protoboard> &pb, const proving_key &proving_key); + /// Generate the proof (from given primary and auxiliary values) + static proof generate_proof( + const proving_key &proving_key, + const libsnark::r1cs_primary_input> &primary_input, + const libsnark::r1cs_auxiliary_input> auxiliary_input); + /// Verify proof static bool verify( const libsnark::r1cs_primary_input> &primary_inputs, diff --git a/libzeth/snarks/pghr13/pghr13_snark.tcc b/libzeth/snarks/pghr13/pghr13_snark.tcc index 669534597..da6ce1714 100644 --- a/libzeth/snarks/pghr13/pghr13_snark.tcc +++ b/libzeth/snarks/pghr13/pghr13_snark.tcc @@ -26,14 +26,16 @@ typename pghr13_snark::proof pghr13_snark::generate_proof( const libsnark::protoboard> &pb, const pghr13_snark::proving_key &proving_key) { - // See: - // https://github.com/scipr-lab/libsnark/blob/92a80f74727091fdc40e6021dc42e9f6b67d5176/libsnark/relations/constraint_satisfaction_problems/r1cs/r1cs.hpp#L81 - // For the definition of r1cs_primary_input and r1cs_auxiliary_input - libsnark::r1cs_primary_input> primary_input = - pb.primary_input(); - libsnark::r1cs_auxiliary_input> auxiliary_input = - pb.auxiliary_input(); + return generate_proof( + proving_key, pb.primary_input(), pb.auxiliary_input()); +} +template +typename pghr13_snark::proof pghr13_snark::generate_proof( + const pghr13_snark::proving_key &proving_key, + const libsnark::r1cs_primary_input> &primary_input, + const libsnark::r1cs_auxiliary_input> auxiliary_input) +{ // Generate proof from public input, auxiliary input (private/secret data), // and proving key return libsnark::r1cs_ppzksnark_prover( From 7a5050bad8ce441f00891033bcd828b98e3e99d5 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 31 Mar 2021 13:46:24 +0100 Subject: [PATCH 092/137] libzeth: better encapsulation of simple_test --- libzeth/tests/circuits/simple_test.cpp | 65 ++++++++++++++++---------- libzeth/tests/circuits/simple_test.hpp | 17 ++++--- libzeth/tests/circuits/simple_test.tcc | 15 ++++++ 3 files changed, 67 insertions(+), 30 deletions(-) diff --git a/libzeth/tests/circuits/simple_test.cpp b/libzeth/tests/circuits/simple_test.cpp index 47e35dc9a..27c3e7508 100644 --- a/libzeth/tests/circuits/simple_test.cpp +++ b/libzeth/tests/circuits/simple_test.cpp @@ -7,6 +7,7 @@ #include "core/utils.hpp" #include "libzeth/serialization/r1cs_serialization.hpp" #include "libzeth/snarks/groth16/groth16_snark.hpp" +#include "libzeth/snarks/pghr13/pghr13_snark.hpp" #include "serialization/proto_utils.hpp" #include "serialization/r1cs_variable_assignment_serialization.hpp" @@ -17,16 +18,15 @@ using namespace libsnark; using namespace libzeth; -using pp = libff::alt_bn128_pp; -using Field = libff::Fr; - boost::filesystem::path g_output_dir = boost::filesystem::path(""); namespace { -TEST(SimpleTests, SimpleCircuitProof) +template void test_simple_circuit_proof() { + using Field = libff::Fr; + // Simple circuit protoboard pb; libzeth::tests::simple_circuit(pb); @@ -39,13 +39,14 @@ TEST(SimpleTests, SimpleCircuitProof) if (!g_output_dir.empty()) { boost::filesystem::path outpath = - g_output_dir / ("simple_circuit_r1cs_" + pp_name() + ".json"); + g_output_dir / ("simple_circuit_r1cs_" + pp_name() + ".json"); std::ofstream r1cs_stream(outpath.c_str()); libzeth::r1cs_write_json(pb.get_constraint_system(), r1cs_stream); } - const r1cs_primary_input primary{12}; - const r1cs_auxiliary_input auxiliary{1, 1, 1}; + r1cs_primary_input primary; + r1cs_auxiliary_input auxiliary; + libzeth::tests::simple_circuit_assignment(Field("78"), primary, auxiliary); { // Test solution x = 1 (g1 = 1, g2 = 1), y = 12 @@ -61,41 +62,57 @@ TEST(SimpleTests, SimpleCircuitProof) } } - const r1cs_gg_ppzksnark_keypair keypair = - r1cs_gg_ppzksnark_generator(constraint_system); + const typename snarkT::keypair keypair = snarkT::generate_setup(pb); - const r1cs_gg_ppzksnark_proof proof = - r1cs_gg_ppzksnark_prover(keypair.pk, primary, auxiliary); + const typename snarkT::proof proof = + snarkT::generate_proof(keypair.pk, primary, auxiliary); - ASSERT_TRUE( - r1cs_gg_ppzksnark_verifier_strong_IC(keypair.vk, primary, proof)); + ASSERT_TRUE(snarkT::verify(primary, proof, keypair.vk)); if (!g_output_dir.empty()) { { boost::filesystem::path proving_key_path = - g_output_dir / ("simple_proving_key_" + pp_name() + ".bin"); + g_output_dir / + ("simple_proving_key_" + pp_name() + ".bin"); std::ofstream out_s(proving_key_path.c_str()); - groth16_snark::proving_key_write_bytes(keypair.pk, out_s); + snarkT::proving_key_write_bytes(keypair.pk, out_s); } { boost::filesystem::path verification_key_path = - g_output_dir / - ("simple_verification_key_" + pp_name() + ".bin"); + g_output_dir / ("simple_verification_key_" + snarkT::name + + "_" + pp_name() + ".bin"); std::ofstream out_s(verification_key_path.c_str()); - groth16_snark::verification_key_write_bytes(keypair.vk, out_s); + snarkT::verification_key_write_bytes(keypair.vk, out_s); } { - boost::filesystem::path primary_inputs_path = - g_output_dir / - ("simple_primary_input_" + pp_name() + ".bin"); - std::ofstream out_s(primary_inputs_path.c_str()); - r1cs_variable_assignment_write_bytes(primary, out_s); + boost::filesystem::path assignment_path = + g_output_dir / ("simple_assignment_" + pp_name() + ".bin"); + std::ofstream out_s(assignment_path.c_str()); + r1cs_variable_assignment_write_bytes( + pb.full_variable_assignment(), out_s); } } } +TEST(SimpleTests, SimpleCircuitProofGroth16) +{ + test_simple_circuit_proof< + libff::alt_bn128_pp, + libzeth::groth16_snark>(); +} + +TEST(SimpleTests, SimpleCircuitProofPghr13) +{ + test_simple_circuit_proof< + libff::alt_bn128_pp, + pghr13_snark>(); +} + TEST(SimpleTests, SimpleCircuitProofPow2Domain) { + using pp = libff::alt_bn128_pp; + using Field = libff::Fr; + // Simple circuit protoboard pb; libzeth::tests::simple_circuit(pb); @@ -118,7 +135,7 @@ TEST(SimpleTests, SimpleCircuitProofPow2Domain) int main(int argc, char **argv) { // WARNING: Do once for all tests. Do not forget to do this. - pp::init_public_params(); + libff::alt_bn128_pp::init_public_params(); // Remove stdout noise from libff libff::inhibit_profiling_counters = true; diff --git a/libzeth/tests/circuits/simple_test.hpp b/libzeth/tests/circuits/simple_test.hpp index e613bc6ee..be0231d7d 100644 --- a/libzeth/tests/circuits/simple_test.hpp +++ b/libzeth/tests/circuits/simple_test.hpp @@ -13,17 +13,22 @@ namespace tests { /// Generate a simple test circuit with 1 public input 'y' and auxiliary -/// -/// input 'x', for the expression: -/// +/// inputs 'x', 'g1, and 'g2' for the expression: /// x^3 + 4x^2 + 2x + 5 = y -/// -/// Internal auxiliary inputs are: -/// +/// where: /// g1 = x * x /// g2 = g1 * x template void simple_circuit(libsnark::protoboard &pb); +/// Append a set of valid simple circuit inputs [ 'y', 'x', 'g1', 'g2' ] to +/// out_inputs. Note that out_primary can be the same as out_auxiliary (primary +/// input is appended first). +template +void simple_circuit_assignment( + const FieldT &x, + std::vector &out_primary, + std::vector &out_auxiliary); + } // namespace tests } // namespace libzeth diff --git a/libzeth/tests/circuits/simple_test.tcc b/libzeth/tests/circuits/simple_test.tcc index a6d1f8b1f..138b0c991 100644 --- a/libzeth/tests/circuits/simple_test.tcc +++ b/libzeth/tests/circuits/simple_test.tcc @@ -46,6 +46,21 @@ template void simple_circuit(libsnark::protoboard &pb) r1cs_constraint(g2 + (4 * g1) + (2 * x) + 5, 1, y), "y"); } +template +void simple_circuit_assignment( + const FieldT &x, + std::vector &out_primary, + std::vector &out_auxiliary) +{ + const FieldT g1 = x * x; + const FieldT g2 = g1 * x; + const FieldT y = g2 + (g1 * 4) + (x * 2) + 5; + out_primary.push_back(y); + out_auxiliary.push_back(x); + out_auxiliary.push_back(g1); + out_auxiliary.push_back(g2); +} + } // namespace tests } // namespace libzeth From df8b28e1992c2e701be5b46128297367ead088a5 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 31 Mar 2021 14:49:22 +0100 Subject: [PATCH 093/137] libzeth: binary proof reader and writer --- libzeth/serialization/stream_utils.hpp | 8 ++++ libzeth/snarks/groth16/groth16_snark.hpp | 10 +++- libzeth/snarks/groth16/groth16_snark.tcc | 36 ++++++++++---- libzeth/snarks/pghr13/pghr13_snark.hpp | 10 +++- libzeth/snarks/pghr13/pghr13_snark.tcc | 22 +++++++++ libzeth/tests/snarks/common_snark_tests.tcc | 48 +++++++++++++++++++ .../snarks/groth16/groth16_snark_test.cpp | 13 +++++ .../tests/snarks/pghr13/pghr13_snark_test.cpp | 13 +++++ 8 files changed, 147 insertions(+), 13 deletions(-) diff --git a/libzeth/serialization/stream_utils.hpp b/libzeth/serialization/stream_utils.hpp index dfd27b6c2..f9c00d79e 100644 --- a/libzeth/serialization/stream_utils.hpp +++ b/libzeth/serialization/stream_utils.hpp @@ -80,6 +80,14 @@ template void accumulation_vector_write_bytes( const libsnark::accumulation_vector &acc_vector, std::ostream &out_s); +template +void knowledge_commitment_read_bytes( + kcT &knowledge_commitment, std::istream &in_s); + +template +void knowledge_commitment_write_bytes( + const kcT &knowledge_commitment, std::ostream &out_s); + template void knowledge_commitment_vector_read_bytes( kcvectorT &knowledge_commitment, std::istream &in_s); diff --git a/libzeth/snarks/groth16/groth16_snark.hpp b/libzeth/snarks/groth16/groth16_snark.hpp index 4eaad4036..e447abc77 100644 --- a/libzeth/snarks/groth16/groth16_snark.hpp +++ b/libzeth/snarks/groth16/groth16_snark.hpp @@ -65,11 +65,17 @@ template class groth16_snark /// Write proof as json. static void proof_write_json(const proof &, std::ostream &); - /// Read a keypair from a stream. - static void keypair_read_bytes(keypair &, std::istream &); + /// Write proof as bytes + static void proof_write_bytes(const proof &, std::ostream &); + + /// Read proof as bytes + static void proof_read_bytes(proof &, std::istream &); /// Write a keypair as bytes static void keypair_write_bytes(const keypair &, std::ostream &); + + /// Read a keypair from a stream. + static void keypair_read_bytes(keypair &, std::istream &); }; /// Check well-formedness of a proving key diff --git a/libzeth/snarks/groth16/groth16_snark.tcc b/libzeth/snarks/groth16/groth16_snark.tcc index d1ccbfa56..15d0949c5 100644 --- a/libzeth/snarks/groth16/groth16_snark.tcc +++ b/libzeth/snarks/groth16/groth16_snark.tcc @@ -147,6 +147,33 @@ void groth16_snark::proving_key_read_bytes( } } +template +void groth16_snark::proof_write_json( + const typename groth16_snark::proof &proof, std::ostream &out_s) +{ + out_s << "{\n \"a\": " << group_element_to_json(proof.g_A) + << ",\n \"b\": " << group_element_to_json(proof.g_B) + << ",\n \"c\": " << group_element_to_json(proof.g_C) << "\n}"; +} + +template +void groth16_snark::proof_write_bytes( + const typename groth16_snark::proof &proof, std::ostream &out_s) +{ + group_element_write_bytes(proof.g_A, out_s); + group_element_write_bytes(proof.g_B, out_s); + group_element_write_bytes(proof.g_C, out_s); +} + +template +void groth16_snark::proof_read_bytes( + typename groth16_snark::proof &proof, std::istream &in_s) +{ + group_element_read_bytes(proof.g_A, in_s); + group_element_read_bytes(proof.g_B, in_s); + group_element_read_bytes(proof.g_C, in_s); +} + template void groth16_snark::keypair_write_bytes( const typename groth16_snark::keypair &keypair, std::ostream &out_s) @@ -163,15 +190,6 @@ void groth16_snark::keypair_read_bytes( verification_key_read_bytes(keypair.vk, in_s); } -template -void groth16_snark::proof_write_json( - const typename groth16_snark::proof &proof, std::ostream &out_s) -{ - out_s << "{\n \"a\": " << group_element_to_json(proof.g_A) - << ",\n \"b\": " << group_element_to_json(proof.g_B) - << ",\n \"c\": " << group_element_to_json(proof.g_C) << "\n}"; -} - template bool is_well_formed(const typename groth16_snark::proving_key &pk) { diff --git a/libzeth/snarks/pghr13/pghr13_snark.hpp b/libzeth/snarks/pghr13/pghr13_snark.hpp index d53bd1821..dd849e4e5 100644 --- a/libzeth/snarks/pghr13/pghr13_snark.hpp +++ b/libzeth/snarks/pghr13/pghr13_snark.hpp @@ -65,11 +65,17 @@ template class pghr13_snark /// Write proof as json. static void proof_write_json(const proof &, std::ostream &); - /// Read a keypair from a stream. - static void keypair_read_bytes(keypair &, std::istream &); + /// Write proof as bytes + static void proof_write_bytes(const proof &, std::ostream &); + + /// Read proof as bytes + static void proof_read_bytes(proof &, std::istream &); /// Write a keypair as bytes static void keypair_write_bytes(const keypair &, std::ostream &); + + /// Read a keypair from a stream. + static void keypair_read_bytes(keypair &, std::istream &); }; } // namespace libzeth diff --git a/libzeth/snarks/pghr13/pghr13_snark.tcc b/libzeth/snarks/pghr13/pghr13_snark.tcc index da6ce1714..2dac6bbc9 100644 --- a/libzeth/snarks/pghr13/pghr13_snark.tcc +++ b/libzeth/snarks/pghr13/pghr13_snark.tcc @@ -122,6 +122,28 @@ void pghr13_snark::proof_write_json( os << "}"; } +template +void pghr13_snark::proof_write_bytes( + const typename pghr13_snark::proof &proof, std::ostream &out_s) +{ + knowledge_commitment_write_bytes(proof.g_A, out_s); + knowledge_commitment_write_bytes(proof.g_B, out_s); + knowledge_commitment_write_bytes(proof.g_C, out_s); + group_element_write_bytes(proof.g_H, out_s); + group_element_write_bytes(proof.g_K, out_s); +} + +template +void pghr13_snark::proof_read_bytes( + typename pghr13_snark::proof &proof, std::istream &in_s) +{ + knowledge_commitment_read_bytes(proof.g_A, in_s); + knowledge_commitment_read_bytes(proof.g_B, in_s); + knowledge_commitment_read_bytes(proof.g_C, in_s); + group_element_read_bytes(proof.g_H, in_s); + group_element_read_bytes(proof.g_K, in_s); +} + template void pghr13_snark::keypair_write_bytes( const typename pghr13_snark::keypair &keypair, std::ostream &os) diff --git a/libzeth/tests/snarks/common_snark_tests.tcc b/libzeth/tests/snarks/common_snark_tests.tcc index 4c7d7fbd9..cc86534e3 100644 --- a/libzeth/tests/snarks/common_snark_tests.tcc +++ b/libzeth/tests/snarks/common_snark_tests.tcc @@ -7,6 +7,7 @@ #include "libzeth/tests/circuits/simple_test.hpp" +#include #include #include @@ -29,9 +30,37 @@ typename snarkT::proving_key dummy_proving_key() libzeth::tests::simple_circuit(pb); typename snarkT::keypair keypair = snarkT::generate_setup(pb); + return keypair.pk; } +template typename snarkT::proof dummy_proof() +{ + using Field = libff::Fr; + libsnark::protoboard pb; + libzeth::tests::simple_circuit(pb); + libzeth::tests::simple_circuit(pb); + libzeth::tests::simple_circuit(pb); + libzeth::tests::simple_circuit(pb); + + libsnark::r1cs_primary_input primary; + libsnark::r1cs_auxiliary_input auxiliary; + libzeth::tests::simple_circuit_assignment(Field("10"), primary, auxiliary); + libzeth::tests::simple_circuit_assignment( + Field("12"), auxiliary, auxiliary); + libzeth::tests::simple_circuit_assignment( + Field("14"), auxiliary, auxiliary); + libzeth::tests::simple_circuit_assignment( + Field("16"), auxiliary, auxiliary); + + if (!pb.get_constraint_system().is_satisfied(primary, auxiliary)) { + throw std::runtime_error("constraint system not satisfied"); + } + + const typename snarkT::keypair keypair = snarkT::generate_setup(pb); + return snarkT::generate_proof(keypair.pk, primary, auxiliary); +} + template bool verification_key_read_write_bytes_test() { @@ -73,6 +102,25 @@ template bool proving_key_read_write_bytes_test() return pk == pk2; } +template bool proof_read_write_bytes_test() +{ + const typename snarkT::proof proof = dummy_proof(); + + std::string buffer = ([&proof]() { + std::stringstream ss; + snarkT::proof_write_bytes(proof, ss); + return ss.str(); + })(); + + typename snarkT::proof proof2; + { + std::stringstream ss(buffer); + snarkT::proof_read_bytes(proof2, ss); + } + + return proof == proof2; +} + } // namespace tests } // namespace libzeth diff --git a/libzeth/tests/snarks/groth16/groth16_snark_test.cpp b/libzeth/tests/snarks/groth16/groth16_snark_test.cpp index bee15e200..3c5e0aefc 100644 --- a/libzeth/tests/snarks/groth16/groth16_snark_test.cpp +++ b/libzeth/tests/snarks/groth16/groth16_snark_test.cpp @@ -192,6 +192,19 @@ TEST(Groth16SnarkTest, TestProvingKeyReadWriteBytes) ASSERT_TRUE(test_bls12_377); } +TEST(Groth16SnarkTest, TestProofReadWriteBytes) +{ + const bool test_alt_bn128 = libzeth::tests::proof_read_write_bytes_test< + libff::alt_bn128_pp, + libzeth::groth16_snark>(); + ASSERT_TRUE(test_alt_bn128); + const bool test_bls12_377 = + libzeth::tests::proving_key_read_write_bytes_test< + libff::bls12_377_pp, + libzeth::groth16_snark>(); + ASSERT_TRUE(test_bls12_377); +} + } // namespace int main(int argc, char **argv) diff --git a/libzeth/tests/snarks/pghr13/pghr13_snark_test.cpp b/libzeth/tests/snarks/pghr13/pghr13_snark_test.cpp index 5eab9873e..1420d307f 100644 --- a/libzeth/tests/snarks/pghr13/pghr13_snark_test.cpp +++ b/libzeth/tests/snarks/pghr13/pghr13_snark_test.cpp @@ -41,6 +41,19 @@ TEST(Pghr13SnarkTest, TestProvingKeyReadWriteBytes) ASSERT_TRUE(test_bls12_377); } +TEST(Pghr13SnarkTest, TestProofReadWriteBytes) +{ + const bool test_alt_bn128 = libzeth::tests::proof_read_write_bytes_test< + libff::alt_bn128_pp, + libzeth::pghr13_snark>(); + ASSERT_TRUE(test_alt_bn128); + const bool test_bls12_377 = + libzeth::tests::proving_key_read_write_bytes_test< + libff::bls12_377_pp, + libzeth::pghr13_snark>(); + ASSERT_TRUE(test_bls12_377); +} + } // namespace int main(int argc, char **argv) From 74c8324ee30fe7ee313890a4b7706121b11d9f84 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 31 Mar 2021 16:13:44 +0100 Subject: [PATCH 094/137] tests: write binary proof from simple_test --- libzeth/tests/circuits/simple_test.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/libzeth/tests/circuits/simple_test.cpp b/libzeth/tests/circuits/simple_test.cpp index 27c3e7508..e33c93531 100644 --- a/libzeth/tests/circuits/simple_test.cpp +++ b/libzeth/tests/circuits/simple_test.cpp @@ -72,8 +72,8 @@ template void test_simple_circuit_proof() if (!g_output_dir.empty()) { { boost::filesystem::path proving_key_path = - g_output_dir / - ("simple_proving_key_" + pp_name() + ".bin"); + g_output_dir / ("simple_proving_key_" + snarkT::name + "_" + + pp_name() + ".bin"); std::ofstream out_s(proving_key_path.c_str()); snarkT::proving_key_write_bytes(keypair.pk, out_s); } @@ -85,11 +85,18 @@ template void test_simple_circuit_proof() snarkT::verification_key_write_bytes(keypair.vk, out_s); } { - boost::filesystem::path assignment_path = - g_output_dir / ("simple_assignment_" + pp_name() + ".bin"); - std::ofstream out_s(assignment_path.c_str()); - r1cs_variable_assignment_write_bytes( - pb.full_variable_assignment(), out_s); + boost::filesystem::path primary_inputs_path = + g_output_dir / + ("simple_primary_input_" + pp_name() + ".bin"); + std::ofstream out_s(primary_inputs_path.c_str()); + r1cs_variable_assignment_write_bytes(primary, out_s); + } + { + boost::filesystem::path proof_path = + g_output_dir / ("simple_proof_" + snarkT::name + "_" + + pp_name() + ".bin"); + std::ofstream out_s(proof_path.c_str()); + snarkT::proof_write_bytes(proof, out_s); } } } From 138adb506e6a479f3fd9aa6b17293576fe503bd8 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 31 Mar 2021 12:28:01 +0100 Subject: [PATCH 095/137] verifier: simple app to verify generated proof against verification key --- CMakeLists.txt | 1 + verifier/CMakeLists.txt | 14 ++++ verifier/verifier.cpp | 163 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 verifier/CMakeLists.txt create mode 100644 verifier/verifier.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 69f4b17e4..ca975bf20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -315,6 +315,7 @@ add_subdirectory(libzeth) # If zeth is being used as a dependency, skip the tools build if ("${IS_ZETH_PARENT}") add_subdirectory(prover_server) + add_subdirectory(verifier) # For now the MPC for Groth16 only is tailored to the alt_bn128 pairing group if((${ZETH_SNARK} STREQUAL "GROTH16") AND (${MPC})) add_subdirectory(mpc_tools) diff --git a/verifier/CMakeLists.txt b/verifier/CMakeLists.txt new file mode 100644 index 000000000..58a39be0e --- /dev/null +++ b/verifier/CMakeLists.txt @@ -0,0 +1,14 @@ + +find_package(Boost REQUIRED COMPONENTS system filesystem program_options) + +file(GLOB_RECURSE VERIFIER_SOURCE **.?pp **.tcc) +add_executable(verifier ${VERIFIER_SOURCE}) +target_include_directories(verifier PRIVATE SYSTEM ${Boost_INCLUDE_DIR}) +target_link_libraries( + verifier + + zeth + ${Boost_SYSTEM_LIBRARY} + ${Boost_FILESYSTEM_LIBRARY} + ${Boost_PROGRAM_OPTIONS_LIBRARY} + ) diff --git a/verifier/verifier.cpp b/verifier/verifier.cpp new file mode 100644 index 000000000..f85624ea3 --- /dev/null +++ b/verifier/verifier.cpp @@ -0,0 +1,163 @@ +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +#include "libzeth/serialization/r1cs_variable_assignment_serialization.hpp" +#include "libzeth/snarks/groth16/groth16_snark.hpp" +#include "libzeth/snarks/pghr13/pghr13_snark.hpp" + +#include +#include +#include +#include +#include +#include + +namespace po = boost::program_options; + +static std::ifstream open_file(const std::string &filename) +{ + std::ifstream in_s( + filename.c_str(), std::ios_base::in | std::ios_base::binary); + in_s.exceptions( + std::ios_base::eofbit | std::ios_base::badbit | std::ios_base::failbit); + return in_s; +} + +template +int verifier_main( + const std::string &vk_file, + const std::string &primary_input_file, + const std::string &proof_file) +{ + ppT::init_public_params(); + libff::inhibit_profiling_info = true; + libff::inhibit_profiling_counters = true; + + typename snarkT::verification_key verification_key; + { + std::ifstream in_s = open_file(vk_file); + snarkT::verification_key_read_bytes(verification_key, in_s); + } + + libsnark::r1cs_primary_input> primary_input; + { + std::ifstream in_s = open_file(primary_input_file); + libzeth::r1cs_variable_assignment_read_bytes(primary_input, in_s); + } + + typename snarkT::proof proof; + { + std::ifstream in_s = open_file(proof_file); + snarkT::proof_read_bytes(proof, in_s); + } + + if (!snarkT::verify(primary_input, proof, verification_key)) { + std::cout << "verification failed.\n"; + return 1; + } + + return 0; +} + +template +int verifier_resolve_snark( + const std::string &vk_file, + const std::string &primary_input_file, + const std::string &proof_file, + const std::string &snark) +{ + if (snark == "groth16") { + return verifier_main>( + vk_file, primary_input_file, proof_file); + } else if (snark == "pghr13") { + return verifier_main>( + vk_file, primary_input_file, proof_file); + } + + throw po::error("unrecognized snark"); +} + +int verifier_resolve_curve( + const std::string &vk_file, + const std::string &primary_input_file, + const std::string &proof_file, + const std::string &curve, + const std::string &snark) +{ + if (curve == "alt-bn128") { + return verifier_resolve_snark( + vk_file, primary_input_file, proof_file, snark); + } else if (curve == "bls12-377") { + return verifier_resolve_snark( + vk_file, primary_input_file, proof_file, snark); + } else if (curve == "bw6-761") { + return verifier_resolve_snark( + vk_file, primary_input_file, proof_file, snark); + } + + throw po::error("unrecognized curve"); +} + +int main(int argc, char **argv) +{ + // Options + po::options_description options("Options"); + options.add_options()( + "curve,c", + po::value(), + "Curve: alt-bn128, bls12-377 or bw6-761"); + options.add_options()( + "snark,s", po::value(), "Snark: groth16 or pghr13"); + + po::options_description all_options(options); + all_options.add_options()( + "vk_file", po::value(), "Verification key file"); + all_options.add_options()( + "primary_input_file", po::value(), "Proof file"); + all_options.add_options()( + "proof_file", po::value(), "Proof file"); + + po::positional_options_description pos; + pos.add("vk_file", 1); + pos.add("primary_input_file", 1); + pos.add("proof_file", 1); + + try { + po::parsed_options parsed = po::command_line_parser{argc, argv} + .options(all_options) + .positional(pos) + .run(); + po::variables_map vm; + po::store(parsed, vm); + + if (0 == vm.count("vk_file")) { + throw po::error("vk_file not specified"); + } + if (0 == vm.count("primary_input_file")) { + throw po::error("primary_input_file not specified"); + } + if (0 == vm.count("proof_file")) { + throw po::error("proof_file not specified"); + } + std::string vk_file = vm["vk_file"].as(); + std::string proof_file = vm["proof_file"].as(); + std::string primary_input_file = + vm["primary_input_file"].as(); + std::string curve = + vm.count("curve") ? vm["curve"].as() : "alt-bn128"; + std::string snark = + vm.count("snark") ? vm["snark"].as() : "groth16"; + + verifier_resolve_curve( + vk_file, primary_input_file, proof_file, curve, snark); + } catch (po::error &error) { + std::cerr << " ERROR: " << error.what() << "\n"; + std::cout + << "Usage:\n" + << " " << argv[0] + << " [] \n\n" + << options << std::endl; + return 1; + } +} From d3ed76bfc58679c3a670cf664ce3058a3d550596 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 12 Apr 2021 10:24:40 +0100 Subject: [PATCH 096/137] some cosmetic changes --- libzeth/circuits/circuit_wrapper.tcc | 2 +- libzeth/core/field_element_utils.hpp | 4 ++-- libzeth/core/group_element_utils.hpp | 2 +- libzeth/snarks/groth16/groth16_snark.hpp | 4 ++-- libzeth/snarks/groth16/groth16_snark.tcc | 4 ++-- libzeth/snarks/pghr13/pghr13_snark.hpp | 4 ++-- libzeth/snarks/pghr13/pghr13_snark.tcc | 4 ++-- verifier/verifier.cpp | 6 +++--- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/libzeth/circuits/circuit_wrapper.tcc b/libzeth/circuits/circuit_wrapper.tcc index 5c20f3311..5f34ec641 100644 --- a/libzeth/circuits/circuit_wrapper.tcc +++ b/libzeth/circuits/circuit_wrapper.tcc @@ -167,7 +167,7 @@ extended_proof circuit_wrapper< // Instantiate an extended_proof from the proof we generated and the given // primary_input return extended_proof( - snarkT::generate_proof(pb, proving_key), pb.primary_input()); + snarkT::generate_proof(proving_key, pb), pb.primary_input()); } } // namespace libzeth diff --git a/libzeth/core/field_element_utils.hpp b/libzeth/core/field_element_utils.hpp index b38b59a82..84e6c68e7 100644 --- a/libzeth/core/field_element_utils.hpp +++ b/libzeth/core/field_element_utils.hpp @@ -59,8 +59,8 @@ template FieldT field_element_from_json(const std::string &json); /// Write a field element as bytes. Base field elements are written in plain -/// (non-Montgomery) form as fixed-size big-endian integers. Extension fields -/// are written as a series of components. +/// (non-Montgomery) form as fixed-size big-endian integers. Extension field +/// elements are written as a series of components. template void field_element_write_bytes(const FieldT &el, std::ostream &out_s); diff --git a/libzeth/core/group_element_utils.hpp b/libzeth/core/group_element_utils.hpp index 40ec0bd85..d22a9733d 100644 --- a/libzeth/core/group_element_utils.hpp +++ b/libzeth/core/group_element_utils.hpp @@ -43,7 +43,7 @@ template void group_elements_write_bytes( const GroupCollectionT &points, std::ostream &out_s); -/// Read a collection of group elements as bytes, usinng +/// Read a collection of group elements as bytes, using /// group_elements_read_bytes. template void group_elements_read_bytes(GroupCollectionT &points, std::istream &in_s); diff --git a/libzeth/snarks/groth16/groth16_snark.hpp b/libzeth/snarks/groth16/groth16_snark.hpp index e447abc77..09c82bdc6 100644 --- a/libzeth/snarks/groth16/groth16_snark.hpp +++ b/libzeth/snarks/groth16/groth16_snark.hpp @@ -30,8 +30,8 @@ template class groth16_snark /// Generate the proof (from the values set to the protoboard) static proof generate_proof( - const libsnark::protoboard> &pb, - const proving_key &proving_key); + const proving_key &proving_key, + const libsnark::protoboard> &pb); /// Generate the proof (from given primary and auxiliary values) static proof generate_proof( diff --git a/libzeth/snarks/groth16/groth16_snark.tcc b/libzeth/snarks/groth16/groth16_snark.tcc index 15d0949c5..a58291b84 100644 --- a/libzeth/snarks/groth16/groth16_snark.tcc +++ b/libzeth/snarks/groth16/groth16_snark.tcc @@ -26,8 +26,8 @@ typename groth16_snark::keypair groth16_snark::generate_setup( template typename groth16_snark::proof groth16_snark::generate_proof( - const libsnark::protoboard> &pb, - const typename groth16_snark::proving_key &proving_key) + const typename groth16_snark::proving_key &proving_key, + const libsnark::protoboard> &pb) { return generate_proof( proving_key, pb.primary_input(), pb.auxiliary_input()); diff --git a/libzeth/snarks/pghr13/pghr13_snark.hpp b/libzeth/snarks/pghr13/pghr13_snark.hpp index dd849e4e5..d42570f9b 100644 --- a/libzeth/snarks/pghr13/pghr13_snark.hpp +++ b/libzeth/snarks/pghr13/pghr13_snark.hpp @@ -30,8 +30,8 @@ template class pghr13_snark /// Generate the proof (from the values set to the protoboard) static proof generate_proof( - const libsnark::protoboard> &pb, - const proving_key &proving_key); + const proving_key &proving_key, + const libsnark::protoboard> &pb); /// Generate the proof (from given primary and auxiliary values) static proof generate_proof( diff --git a/libzeth/snarks/pghr13/pghr13_snark.tcc b/libzeth/snarks/pghr13/pghr13_snark.tcc index 2dac6bbc9..a6a45d10f 100644 --- a/libzeth/snarks/pghr13/pghr13_snark.tcc +++ b/libzeth/snarks/pghr13/pghr13_snark.tcc @@ -23,8 +23,8 @@ typename pghr13_snark::keypair pghr13_snark::generate_setup( template typename pghr13_snark::proof pghr13_snark::generate_proof( - const libsnark::protoboard> &pb, - const pghr13_snark::proving_key &proving_key) + const pghr13_snark::proving_key &proving_key, + const libsnark::protoboard> &pb) { return generate_proof( proving_key, pb.primary_input(), pb.auxiliary_input()); diff --git a/verifier/verifier.cpp b/verifier/verifier.cpp index f85624ea3..e0889bf1f 100644 --- a/verifier/verifier.cpp +++ b/verifier/verifier.cpp @@ -131,13 +131,13 @@ int main(int argc, char **argv) po::variables_map vm; po::store(parsed, vm); - if (0 == vm.count("vk_file")) { + if (vm.count("vk_file") == 0) { throw po::error("vk_file not specified"); } - if (0 == vm.count("primary_input_file")) { + if (vm.count("primary_input_file") == 0) { throw po::error("primary_input_file not specified"); } - if (0 == vm.count("proof_file")) { + if (vm.count("proof_file") == 0) { throw po::error("proof_file not specified"); } std::string vk_file = vm["vk_file"].as(); From cb4b2055a8827367e3c2d80e9e629964b48117ec Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 12 Apr 2021 10:12:01 +0100 Subject: [PATCH 097/137] libzeth: write out full assignment from simple test --- ...r1cs_variable_assignment_serialization.hpp | 6 +++++ ...r1cs_variable_assignment_serialization.tcc | 18 ++++++++++++++ libzeth/tests/circuits/simple_test.cpp | 6 +++++ ...variable_assignment_serialization_test.cpp | 24 ++++++++++++++++++- 4 files changed, 53 insertions(+), 1 deletion(-) diff --git a/libzeth/serialization/r1cs_variable_assignment_serialization.hpp b/libzeth/serialization/r1cs_variable_assignment_serialization.hpp index fe3c3d609..f5de76000 100644 --- a/libzeth/serialization/r1cs_variable_assignment_serialization.hpp +++ b/libzeth/serialization/r1cs_variable_assignment_serialization.hpp @@ -19,6 +19,12 @@ void r1cs_variable_assignment_write_bytes( const libsnark::r1cs_variable_assignment &assignment, std::ostream &out_s); +template +void r1cs_variable_assignment_write_bytes( + const libsnark::r1cs_primary_input &primary, + const libsnark::r1cs_auxiliary_input &auxiliary, + std::ostream &out_s); + } // namespace libzeth #include "libzeth/serialization/r1cs_variable_assignment_serialization.tcc" diff --git a/libzeth/serialization/r1cs_variable_assignment_serialization.tcc b/libzeth/serialization/r1cs_variable_assignment_serialization.tcc index a36cb095e..de5a85726 100644 --- a/libzeth/serialization/r1cs_variable_assignment_serialization.tcc +++ b/libzeth/serialization/r1cs_variable_assignment_serialization.tcc @@ -31,6 +31,24 @@ void r1cs_variable_assignment_write_bytes( field_element_write_bytes>(assignment, out_s); } +template +void r1cs_variable_assignment_write_bytes( + const libsnark::r1cs_primary_input &primary, + const libsnark::r1cs_auxiliary_input &auxiliary, + std::ostream &out_s) +{ + // Manually write out the aggregation of primary and auxiliary as a single + // collection. + const size_t total_size = primary.size() + auxiliary.size(); + write_bytes(total_size, out_s); + collection_n_write_bytes< + libsnark::r1cs_primary_input, + field_element_write_bytes>(primary, primary.size(), out_s); + collection_n_write_bytes< + libsnark::r1cs_primary_input, + field_element_write_bytes>(auxiliary, auxiliary.size(), out_s); +} + } // namespace libzeth #endif // __ZETH_SERIALIZATION_R1CS_VARIABLE_ASSIGNMENT_SERIALIZATION_TCC__ diff --git a/libzeth/tests/circuits/simple_test.cpp b/libzeth/tests/circuits/simple_test.cpp index e33c93531..e280ec747 100644 --- a/libzeth/tests/circuits/simple_test.cpp +++ b/libzeth/tests/circuits/simple_test.cpp @@ -91,6 +91,12 @@ template void test_simple_circuit_proof() std::ofstream out_s(primary_inputs_path.c_str()); r1cs_variable_assignment_write_bytes(primary, out_s); } + { + boost::filesystem::path assignment_path = + g_output_dir / ("simple_assignment_" + pp_name() + ".bin"); + std::ofstream out_s(assignment_path.c_str()); + r1cs_variable_assignment_write_bytes(primary, auxiliary, out_s); + } { boost::filesystem::path proof_path = g_output_dir / ("simple_proof_" + snarkT::name + "_" + diff --git a/libzeth/tests/serialization/r1cs_variable_assignment_serialization_test.cpp b/libzeth/tests/serialization/r1cs_variable_assignment_serialization_test.cpp index c61bae89b..715e0c661 100644 --- a/libzeth/tests/serialization/r1cs_variable_assignment_serialization_test.cpp +++ b/libzeth/tests/serialization/r1cs_variable_assignment_serialization_test.cpp @@ -15,6 +15,7 @@ template bool test_r1cs_variable_assignment_read_write_bytes() { using FieldT = libff::Fr; const size_t assignment_size = 37; + const size_t primary_size = 3; libsnark::r1cs_variable_assignment assignment; assignment.reserve(assignment_size); @@ -34,10 +35,31 @@ template bool test_r1cs_variable_assignment_read_write_bytes() libzeth::r1cs_variable_assignment_read_bytes(assignment2, ss); } + if (assignment != assignment2) { + return false; + } + + // Write as separate primary and auxiliary iputs + buffer = ([&assignment]() { + std::stringstream ss; + libzeth::r1cs_variable_assignment_write_bytes( + libsnark::r1cs_primary_input( + assignment.begin(), assignment.begin() + primary_size), + libsnark::r1cs_primary_input( + assignment.begin() + primary_size, assignment.end()), + ss); + return ss.str(); + })(); + + { + std::stringstream ss(buffer); + libzeth::r1cs_variable_assignment_read_bytes(assignment2, ss); + } + return assignment == assignment2; } -TEST(R1CSVariableAssignementSerializationTest, AssignmentReeadWriteBytes) +TEST(R1CSVariableAssignementSerializationTest, AssignmentReadWriteBytes) { const bool test_alt_bn128 = test_r1cs_variable_assignment_read_write_bytes(); From be71d5e8ff18a07b58cfc8638848e5ec0b5fb4ad Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Fri, 23 Apr 2021 10:16:20 +0100 Subject: [PATCH 098/137] libzeth: fix form of generated test data --- .../tests/snarks/groth16/groth16_snark_test.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libzeth/tests/snarks/groth16/groth16_snark_test.cpp b/libzeth/tests/snarks/groth16/groth16_snark_test.cpp index 3c5e0aefc..92db02c06 100644 --- a/libzeth/tests/snarks/groth16/groth16_snark_test.cpp +++ b/libzeth/tests/snarks/groth16/groth16_snark_test.cpp @@ -87,20 +87,32 @@ template void generate_test_data() -(G1::one() + G1::one()), // beta_g1 = [-2]_1 -(G2::one() + G2::one()), // beta_g2 = [-2]_2 libff::G1_vector{{ - // A_query = { [7]_1, [-3]_1, [8]_1 } + // A_query = { [7]_1, [-3]_1, [8]_1, [-4]_1, [9]_1, [-5]_1 } Field("7") * G1::one(), -Field("3") * G1::one(), Field("8") * G1::one(), + -Field("4") * G1::one(), + Field("9") * G1::one(), + -Field("5") * G1::one(), }}, libsnark::knowledge_commitment_vector( std::vector>{{ - // B_query = { ([9]_1,[9]_2), ([-9]_1,[-9]_2), ([10]_1,[10}_2) } + // B_query = { + // ([9]_1,[9]_2), ([-9]_1,[-9]_2), ([10]_1,[10}_2), + // ([11]_1,[11}_2), ([12]_1,[12}_2), ([13]_1,[13}_2) + // } libsnark::knowledge_commitment( Field("9") * G2::one(), Field("9") * G1::one()), libsnark::knowledge_commitment( -Field("9") * G2::one(), -Field("9") * G1::one()), libsnark::knowledge_commitment( Field("10") * G2::one(), Field("10") * G1::one()), + libsnark::knowledge_commitment( + -Field("11") * G2::one(), -Field("11") * G1::one()), + libsnark::knowledge_commitment( + Field("12") * G2::one(), Field("12") * G1::one()), + libsnark::knowledge_commitment( + -Field("13") * G2::one(), -Field("13") * G1::one()), }}), {{ // H_query = { [11]_1, [-11]_1, [12]_1 } From 787498f5ed7a805fa4fa22cc8293b1c91ca49219 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Wed, 31 Mar 2021 15:38:27 +0100 Subject: [PATCH 099/137] Removed unused MerkleTreeSha256 contract which wasn't compiling --- zeth_contracts/contracts/MerkleTreeSha256.sol | 44 ------------------- 1 file changed, 44 deletions(-) delete mode 100644 zeth_contracts/contracts/MerkleTreeSha256.sol diff --git a/zeth_contracts/contracts/MerkleTreeSha256.sol b/zeth_contracts/contracts/MerkleTreeSha256.sol deleted file mode 100644 index 7a2654cc3..000000000 --- a/zeth_contracts/contracts/MerkleTreeSha256.sol +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2015-2021 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -pragma solidity ^0.8.0; - -import "./BaseMerkleTree.sol"; - -contract MerkleTreeSha256 is BaseMerkleTree -{ - - constructor(uint256 treeDepth) public BaseMerkleTree(treeDepth) - { - } - - /// Returns the current merkle tree - function getTree() internal view returns (bytes32[] memory) - { - uint256 nbNodes = 2**(depth + 1) - 1; - bytes32[] memory tmpTree = new bytes32[](nbNodes); - - // Dump the leaves in the right indexes in the tree - for (uint256 i = 0; i < nbLeaves; i++) { - tmpTree[(nbLeaves - 1) + i] = leaves[i]; - } - - // Compute the internal nodes of the merkle tree - for (uint256 i = nbLeaves - 2; i > 0; i--) { - tmpTree[i] = sha256( - abi.encodePacked(tmpTree[i*2+1], tmpTree[2*(i+1)])); - } - - // Compute the merkle root - tmpTree[0] = sha256(abi.encodePacked(tmpTree[1], tmpTree[2])); - - return tmpTree; - } - - /// Returns the root of the merkle tree - function getRoot() internal view returns(bytes32) - { - return getTree()[0]; - } -} From da1ad421b39fd3b4d66c96e94350c02fbbd14805 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Wed, 31 Mar 2021 15:40:45 +0100 Subject: [PATCH 100/137] Renamed functions in Pairing library to avoid collisions with assembly instructions --- zeth_contracts/contracts/Groth16AltBN128.sol | 2 +- .../contracts/OTSchnorrVerifier.sol | 4 ++-- zeth_contracts/contracts/Pairing.sol | 6 +++--- .../contracts/Pghr13AltBN128Mixer.sol | 20 +++++++++---------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/zeth_contracts/contracts/Groth16AltBN128.sol b/zeth_contracts/contracts/Groth16AltBN128.sol index f5cb427c5..8a3f5067e 100644 --- a/zeth_contracts/contracts/Groth16AltBN128.sol +++ b/zeth_contracts/contracts/Groth16AltBN128.sol @@ -71,7 +71,7 @@ library Groth16AltBN128 // Pairing.G1Point memory vk_x = vk.ABC[0]; // a_0 = 1 // for (uint256 i = 0; i < input.length; i++) { // vk_x = - // Pairing.add(vk_x, Pairing.mul(vk.ABC[i + 1], input[i])); + // Pairing.addG1(vk_x, Pairing.scalarMulG1(vk.ABC[i + 1], input[i])); // } // // The linear combination loop was the biggest cost center of the mixer diff --git a/zeth_contracts/contracts/OTSchnorrVerifier.sol b/zeth_contracts/contracts/OTSchnorrVerifier.sol index 1b16eea83..37760e417 100644 --- a/zeth_contracts/contracts/OTSchnorrVerifier.sol +++ b/zeth_contracts/contracts/OTSchnorrVerifier.sol @@ -36,9 +36,9 @@ library OTSchnorrVerifier { // Pairing.G1Point memory Y = Pairing.G1Point(vk[2], vk[3]); // // // S = g^{sigma} - // Pairing.G1Point memory S = Pairing.mul(Pairing.P1(), sigma); + // Pairing.G1Point memory S = Pairing.scalarMulG1(Pairing.P1(), sigma); // // S_comp = g^{y + xh} - // Pairing.G1Point memory S_comp = Pairing.add(Y, Pairing.mul(X, h)); + // Pairing.G1Point memory S_comp = Pairing.addG1(Y, Pairing.scalarMulG1(X, h)); // // // Check that g^{sigma} == g^{y + xh} // return (S.X == S_comp.X && S.Y == S_comp.Y); diff --git a/zeth_contracts/contracts/Pairing.sol b/zeth_contracts/contracts/Pairing.sol index be351c08b..9a4cc2768 100644 --- a/zeth_contracts/contracts/Pairing.sol +++ b/zeth_contracts/contracts/Pairing.sol @@ -47,7 +47,7 @@ library Pairing { } // Return the negation of p, i.e. p.add(p.negate()) should be zero. - function negate(G1Point memory p) internal pure returns (G1Point memory) { + function negateG1(G1Point memory p) internal pure returns (G1Point memory) { // The prime q in the base field F_q for G1 // solhint-disable-next-line uint256 q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; @@ -57,7 +57,7 @@ library Pairing { } // Return the sum of two points of G1 - function add(G1Point memory p1, G1Point memory p2) + function addG1(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) { @@ -82,7 +82,7 @@ library Pairing { // Return the product of a point on G1 and a scalar, i.e. // p == p.mul(1) and p.add(p) == p.mul(2) for all points p. - function mul(G1Point memory p, uint256 s) + function scalarMulG1(G1Point memory p, uint256 s) internal returns (G1Point memory r) { diff --git a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol index 5e85982f1..a91f88e7d 100644 --- a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol @@ -90,9 +90,9 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase // size n. Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0); for (uint256 i = 0; i < inputs.length; i++) { - vk_x = Pairing.add(vk_x, Pairing.mul(vk.IC[i + 1], inputs[i])); + vk_x = Pairing.addG1(vk_x, Pairing.scalarMulG1(vk.IC[i + 1], inputs[i])); } - vk_x = Pairing.add(vk_x, vk.IC[0]); + vk_x = Pairing.addG1(vk_x, vk.IC[0]); // 2. Check the validity of knowledge commitments for A, B, C // e(π_A, vk_A) = e(π′A, P2), e(vk_B, π_B) @@ -100,19 +100,19 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase // = e(π′_C, P2), if (!Pairing.pairingProd2( proof.A, vk.A, - Pairing.negate(proof.A_p), Pairing.P2()) + Pairing.negateG1(proof.A_p), Pairing.P2()) ) { return 1; } if (!Pairing.pairingProd2( vk.B, proof.B, - Pairing.negate(proof.B_p), Pairing.P2()) + Pairing.negateG1(proof.B_p), Pairing.P2()) ) { return 2; } if (!Pairing.pairingProd2( proof.C, vk.C, - Pairing.negate(proof.C_p), Pairing.P2()) + Pairing.negateG1(proof.C_p), Pairing.P2()) ) { return 3; } @@ -123,9 +123,9 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase bool pairing_check = Pairing.pairingProd3( proof.K, vk.gamma, - Pairing.negate(Pairing.add(vk_x, Pairing.add(proof.A, proof.C))), + Pairing.negateG1(Pairing.addG1(vk_x, Pairing.addG1(proof.A, proof.C))), vk.gammaBeta2, - Pairing.negate(vk.gammaBeta1), + Pairing.negateG1(vk.gammaBeta1), proof.B); if (!pairing_check) { return 4; @@ -134,11 +134,11 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase // 4. Check QAP divisibility // e(vk_x + π_A, π_B) = e(π_H, vk_Z) · e(π_C, P2) pairing_check = Pairing.pairingProd3( - Pairing.add(vk_x, proof.A), + Pairing.addG1(vk_x, proof.A), proof.B, - Pairing.negate(proof.H), + Pairing.negateG1(proof.H), vk.Z, - Pairing.negate(proof.C), + Pairing.negateG1(proof.C), Pairing.P2()); if (!pairing_check) { return 5; From d204cea092d096f44e1e10686a9aaf09a3d66f56 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Wed, 31 Mar 2021 15:46:16 +0100 Subject: [PATCH 101/137] Removed useless visisbility for constructors --- zeth_contracts/contracts/Groth16AltBN128Mixer.sol | 1 - zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol | 1 - zeth_contracts/contracts/Groth16BLS12_377Mixer.sol | 1 - zeth_contracts/contracts/MerkleTreeMiMC7_test.sol | 2 +- zeth_contracts/contracts/Migrations.sol | 2 +- zeth_contracts/contracts/Pghr13AltBN128Mixer.sol | 1 - 6 files changed, 2 insertions(+), 6 deletions(-) diff --git a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol b/zeth_contracts/contracts/Groth16AltBN128Mixer.sol index 1df62dcb5..8d127d3dd 100644 --- a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Groth16AltBN128Mixer.sol @@ -18,7 +18,6 @@ contract Groth16AltBN128Mixer is AltBN128MixerBase address permitted_dispatcher, uint256[2] memory vk_hash ) - public AltBN128MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) { } diff --git a/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol b/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol index 37544e897..1e42d3c06 100644 --- a/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol +++ b/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol @@ -16,7 +16,6 @@ contract Groth16AltBN128MixerBase_test is Groth16AltBN128Mixer address permitted_dispatcher, uint256[2] memory vk_hash ) - public Groth16AltBN128Mixer( mk_depth, address(0), diff --git a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol b/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol index 538a7810f..2a1364580 100644 --- a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol +++ b/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol @@ -18,7 +18,6 @@ contract Groth16BLS12_377Mixer is BLS12_377MixerBase address permitted_dispatcher, uint256[2] memory vk_hash ) - public BLS12_377MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) { } diff --git a/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol b/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol index 82e34fede..1a85acb7c 100644 --- a/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol +++ b/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol @@ -15,7 +15,7 @@ import "./MiMC7.sol"; /// default value. contract MerkleTreeMiMC7_test is BaseMerkleTree { - constructor(uint treeDepth) public BaseMerkleTree(treeDepth) + constructor(uint treeDepth) BaseMerkleTree(treeDepth) { } diff --git a/zeth_contracts/contracts/Migrations.sol b/zeth_contracts/contracts/Migrations.sol index 073c5d996..e2d399a11 100644 --- a/zeth_contracts/contracts/Migrations.sol +++ b/zeth_contracts/contracts/Migrations.sol @@ -8,7 +8,7 @@ contract Migrations { address public owner; uint public last_completed_migration; - constructor() public { + constructor() { owner = msg.sender; } diff --git a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol index a91f88e7d..e8b887ab4 100644 --- a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol @@ -38,7 +38,6 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase address permitted_dispatcher, uint256[2] memory vk_hash ) - public AltBN128MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) { uint256 vk_words = vk.length; From a4f8fe043d7d8b1ca282bb3e957b7ddfd6984ebe Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Wed, 31 Mar 2021 16:19:27 +0100 Subject: [PATCH 102/137] Restricted hash functions to pure state mutability --- zeth_contracts/contracts/AltBN128MixerBase.sol | 1 + zeth_contracts/contracts/BLS12_377MixerBase.sol | 1 + zeth_contracts/contracts/MerkleTreeMiMC7_test.sol | 1 + 3 files changed, 3 insertions(+) diff --git a/zeth_contracts/contracts/AltBN128MixerBase.sol b/zeth_contracts/contracts/AltBN128MixerBase.sol index c6404ce7f..d4827d36d 100644 --- a/zeth_contracts/contracts/AltBN128MixerBase.sol +++ b/zeth_contracts/contracts/AltBN128MixerBase.sol @@ -48,6 +48,7 @@ abstract contract AltBN128MixerBase is MixerBase /// Use MiMC7 as the Merkle tree hash function. function hash(bytes32 left, bytes32 right) internal + pure override returns(bytes32) { diff --git a/zeth_contracts/contracts/BLS12_377MixerBase.sol b/zeth_contracts/contracts/BLS12_377MixerBase.sol index e3488ff7b..e30aa5f36 100644 --- a/zeth_contracts/contracts/BLS12_377MixerBase.sol +++ b/zeth_contracts/contracts/BLS12_377MixerBase.sol @@ -54,6 +54,7 @@ abstract contract BLS12_377MixerBase is MixerBase function hash(bytes32 left, bytes32 right) internal + pure override returns(bytes32) { diff --git a/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol b/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol index 1a85acb7c..c18bee0e0 100644 --- a/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol +++ b/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol @@ -45,6 +45,7 @@ contract MerkleTreeMiMC7_test is BaseMerkleTree /// Use MiMC7 as the Merkle tree hash function. function hash(bytes32 left, bytes32 right) internal + pure override returns(bytes32) { From 5e9af735f14a330e52ec2ae9a8df8aa108cbcc39 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Wed, 31 Mar 2021 17:20:14 +0100 Subject: [PATCH 103/137] Renamed members in mixedCase --- .../contracts/AltBN128MixerBase.sol | 18 +-- .../contracts/BLS12_377MixerBase.sol | 20 +-- zeth_contracts/contracts/BaseMerkleTree.sol | 42 +++--- .../contracts/Groth16AltBN128Mixer.sol | 6 +- .../Groth16AltBN128MixerBase_test.sol | 16 +- .../contracts/Groth16BLS12_377Mixer.sol | 6 +- zeth_contracts/contracts/MiMC_test.sol | 4 +- zeth_contracts/contracts/MixerBase.sol | 140 +++++++++--------- .../contracts/OTSchnorrVerifier.sol | 22 +-- zeth_contracts/contracts/Pairing.sol | 13 +- .../contracts/Pghr13AltBN128Mixer.sol | 42 +++--- 11 files changed, 166 insertions(+), 163 deletions(-) diff --git a/zeth_contracts/contracts/AltBN128MixerBase.sol b/zeth_contracts/contracts/AltBN128MixerBase.sol index d4827d36d..8a74f1ffd 100644 --- a/zeth_contracts/contracts/AltBN128MixerBase.sol +++ b/zeth_contracts/contracts/AltBN128MixerBase.sol @@ -57,10 +57,10 @@ abstract contract AltBN128MixerBase is MixerBase /// Utility function to extract a full uint256 from a field element and the /// n-th set of residual bits from `residual`. - function extract_bytes32( - uint256 field_element, + function extractBytes32( + uint256 fieldElement, uint256 residual, - uint256 residual_bits_set_idx + uint256 residualBitsSetIdx ) internal pure @@ -68,20 +68,20 @@ abstract contract AltBN128MixerBase is MixerBase returns(bytes32) { // The residual bits are located at: - // (2*public_value_bits) + (residual_bits_set_idx*NUM_RESIDUAL_BITS) + // (2*public_value_bits) + (residualBitsSetIdx*NUM_RESIDUAL_BITS) // // Shift to occupy the highest order bits: // 255 128 64 0 - // | bits_to_shift | | residual_bits_idx | | | + // | bits_to_shift | | residualBitsIdx | | | // | <------------ | xxx | |)|| // residual bits // Number of bits AFTER public values - uint256 residual_bits_idx = residual_bits_set_idx * NUM_RESIDUAL_BITS; + uint256 residualBitsIdx = residualBitsSetIdx * NUM_RESIDUAL_BITS; uint256 bits_to_shift = - RESIDUAL_BITS_SHIFT - TOTAL_PUBLIC_VALUE_BITS - residual_bits_idx; - uint256 residual_bits = + RESIDUAL_BITS_SHIFT - TOTAL_PUBLIC_VALUE_BITS - residualBitsIdx; + uint256 residualBits = (residual << bits_to_shift) & RESIDUAL_BITS_MASK; - return bytes32(field_element | residual_bits); + return bytes32(fieldElement | residualBits); } } diff --git a/zeth_contracts/contracts/BLS12_377MixerBase.sol b/zeth_contracts/contracts/BLS12_377MixerBase.sol index e30aa5f36..0bfc7397b 100644 --- a/zeth_contracts/contracts/BLS12_377MixerBase.sol +++ b/zeth_contracts/contracts/BLS12_377MixerBase.sol @@ -63,31 +63,31 @@ abstract contract BLS12_377MixerBase is MixerBase /// Extract a full uint256 from a field element and the n-th set of /// residual bits from `residual`. - function extract_bytes32( - uint256 field_element, + function extractBytes32( + uint256 fieldElement, uint256 residual, - uint256 residual_bits_set_idx + uint256 residualBitsSetIdx ) internal pure override returns(bytes32) { - // The residual_bits_set_idx-th set of residual bits (denoted r_i + // The residualBitsSetIdx-th set of residual bits (denoted r_i // below) start at bit: - // (2*PUBLIC_VALUE_BITS) + (residual_bits_set_idx*num_residual_bits) + // (2*PUBLIC_VALUE_BITS) + (residualBitsSetIdx*num_residual_bits) // // Shift r_i to occupy the highest order bits: // 255 128 64 0 - // | bits_to_shift | | residual_bits_idx | | | + // | bits_to_shift | | residualBitsIdx | | | // | <------------ || ||| // Number of bits AFTER public values - uint256 residual_bits_idx = residual_bits_set_idx * NUM_RESIDUAL_BITS; + uint256 residualBitsIdx = residualBitsSetIdx * NUM_RESIDUAL_BITS; uint256 bits_to_shift = - RESIDUAL_BITS_SHIFT - TOTAL_PUBLIC_VALUE_BITS - residual_bits_idx; - uint256 residual_bits = + RESIDUAL_BITS_SHIFT - TOTAL_PUBLIC_VALUE_BITS - residualBitsIdx; + uint256 residualBits = (residual << bits_to_shift) & RESIDUAL_BITS_MASK; - return bytes32(field_element | residual_bits); + return bytes32(fieldElement | residualBits); } } diff --git a/zeth_contracts/contracts/BaseMerkleTree.sol b/zeth_contracts/contracts/BaseMerkleTree.sol index 4b58e4e11..27963b693 100644 --- a/zeth_contracts/contracts/BaseMerkleTree.sol +++ b/zeth_contracts/contracts/BaseMerkleTree.sol @@ -34,7 +34,7 @@ abstract contract BaseMerkleTree bytes32[MAX_NUM_NODES] internal nodes; // Number of leaves populated in `nodes`. - uint256 internal num_leaves; + uint256 internal numLeaves; /// Constructor constructor(uint256 treeDepth) { @@ -50,15 +50,15 @@ abstract contract BaseMerkleTree // If this require fails => the merkle tree is full, we can't append // leaves anymore. require( - num_leaves < MAX_NUM_LEAVES, + numLeaves < MAX_NUM_LEAVES, "Merkle tree full: Cannot append anymore" ); // Address of the next leaf is the current number of leaves (before // insertion). Compute the next index in the full set of nodes, and // write. - uint256 next_address = num_leaves; - ++num_leaves; + uint256 next_address = numLeaves; + ++numLeaves; uint256 next_entry_idx = (MAX_NUM_LEAVES - 1) + next_address; nodes[next_entry_idx] = commitment; } @@ -70,13 +70,13 @@ abstract contract BaseMerkleTree virtual returns (bytes32); - function recomputeRoot(uint num_new_leaves) internal returns (bytes32) { - // Assume `num_new_leaves` have been written into the leaf slots. + function recomputeRoot(uint numNewLeaves) internal returns (bytes32) { + // Assume `numNewLeaves` have been written into the leaf slots. // Update any affected nodes in the tree, up to the root, using the // default values for any missing nodes. - uint256 end_idx = num_leaves; - uint256 start_idx = num_leaves - num_new_leaves; + uint256 end_idx = numLeaves; + uint256 start_idx = numLeaves - numNewLeaves; uint256 layer_size = MAX_NUM_LEAVES; while (layer_size > 1) { @@ -104,8 +104,8 @@ abstract contract BaseMerkleTree } /// Recompute nodes in the parent layer that are affected by entries - /// [child_start_idx, child_end_idx[ in the child layer. If - /// `child_end_idx` is required in the calculation, the final entry of + /// [childStartIdx, childEndIdx[ in the child layer. If + /// `childEndIdx` is required in the calculation, the final entry of /// the child layer is used (since this contains the default entry for /// the layer if the tree is not full). /// @@ -114,19 +114,19 @@ abstract contract BaseMerkleTree /// / \ / \ / \ / \ / \ / \ /// Child: ? ? ? ? A B C D E ? ? 0 /// ^ ^ - /// child_start_idx child_end_idx + /// childStartIdx childEndIdx /// /// Returns the start and end indices (within the parent layer) of touched /// parent nodes. function recomputeParentLayer( - uint256 child_layer_size, - uint256 child_start_idx, - uint256 child_end_idx + uint256 childLayerSize, + uint256 childStartIdx, + uint256 childEndIdx ) private returns (uint256, uint256) { - uint256 child_layer_start = child_layer_size - 1; + uint256 child_layer_start = childLayerSize - 1; // Start at the right and iterate left, so we only execute the // default_value logic once. child_left_idx_rend (reverse-end) is the @@ -134,20 +134,20 @@ abstract contract BaseMerkleTree // parent node hash. uint256 child_left_idx_rend = - child_layer_start + (child_start_idx & MASK_LS_BIT); + child_layer_start + (childStartIdx & MASK_LS_BIT); - // If child_end_idx is odd, it is the RIGHT of a computation we need + // If childEndIdx is odd, it is the RIGHT of a computation we need // to make. Do the computation using the default value, and move to // the next pair (on the left). // Otherwise, we have a fully populated pair. uint256 child_left_idx; - if ((child_end_idx & 1) != 0) { - child_left_idx = child_layer_start + child_end_idx - 1; + if ((childEndIdx & 1) != 0) { + child_left_idx = child_layer_start + childEndIdx - 1; nodes[(child_left_idx - 1) / 2] = hash(nodes[child_left_idx], nodes[2 * child_layer_start]); } else { - child_left_idx = child_layer_start + child_end_idx; + child_left_idx = child_layer_start + childEndIdx; } // At this stage, pairs are all populated. Compute until we reach @@ -159,6 +159,6 @@ abstract contract BaseMerkleTree hash(nodes[child_left_idx], nodes[child_left_idx + 1]); } - return (child_start_idx / 2, (child_end_idx + 1) / 2); + return (childStartIdx / 2, (childEndIdx + 1) / 2); } } diff --git a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol b/zeth_contracts/contracts/Groth16AltBN128Mixer.sol index 8d127d3dd..f7a871d7b 100644 --- a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Groth16AltBN128Mixer.sol @@ -22,9 +22,9 @@ contract Groth16AltBN128Mixer is AltBN128MixerBase { } - function verify_zk_proof( + function verifyZkProof( uint256[] memory proof, - uint256 public_inputs_hash + uint256 publicInputsHash ) internal override @@ -33,7 +33,7 @@ contract Groth16AltBN128Mixer is AltBN128MixerBase // Convert the single primary input to a dynamic array // expected by the verifier. uint256[] memory input_values = new uint256[](1); - input_values[0] = public_inputs_hash; + input_values[0] = publicInputsHash; return Groth16AltBN128.verify(_vk, proof, input_values); } } diff --git a/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol b/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol index 1e42d3c06..83632f3b8 100644 --- a/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol +++ b/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol @@ -31,40 +31,40 @@ contract Groth16AltBN128MixerBase_test is Groth16AltBN128Mixer public returns (uint256) { - return hash_public_proof_data(public_data); + return hashPublicProofData(public_data); } - function assemble_public_values_test(uint256 residual_bits) + function assemble_public_values_test(uint256 residualBits) public pure returns (uint256 vpub_in, uint256 vpub_out) { - return assemble_public_values(residual_bits); + return assemblePublicValues(residualBits); } function assemble_hsig_test( - uint256[NUM_INPUTS] memory primary_inputs + uint256[NUM_INPUTS] memory primaryInputs ) public pure returns(bytes32 hsig) { - return assemble_hsig(primary_inputs); + return assembleHsig(primaryInputs); } function assemble_nullifier_test( uint256 index, - uint256[NUM_INPUTS] memory primary_inputs + uint256[NUM_INPUTS] memory primaryInputs ) public pure returns(bytes32 nf) { - return assemble_nullifier(index, primary_inputs); + return assembleNullifier(index, primaryInputs); } // Dummy implementation of abstract function - function verify_zk_proof( + function verifyZkProof( uint256[] memory /* proof */, uint256[NUM_INPUTS] memory /* inputs */ ) diff --git a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol b/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol index 2a1364580..cdd6b0380 100644 --- a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol +++ b/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol @@ -22,9 +22,9 @@ contract Groth16BLS12_377Mixer is BLS12_377MixerBase { } - function verify_zk_proof( + function verifyZkProof( uint256[] memory proof, - uint256 public_inputs_hash + uint256 publicInputsHash ) internal override @@ -33,7 +33,7 @@ contract Groth16BLS12_377Mixer is BLS12_377MixerBase // Convert the single primary input to a dynamic array // expected by the verifier. uint256[] memory input_values = new uint256[](1); - input_values[0] = public_inputs_hash; + input_values[0] = publicInputsHash; return Groth16BLS12_377.verify(_vk, proof, input_values); } } diff --git a/zeth_contracts/contracts/MiMC_test.sol b/zeth_contracts/contracts/MiMC_test.sol index a5224fd1e..25644ffc3 100644 --- a/zeth_contracts/contracts/MiMC_test.sol +++ b/zeth_contracts/contracts/MiMC_test.sol @@ -11,12 +11,12 @@ import "./MiMC31.sol"; contract MiMC_test { /// Test function for MiMC7 - function test_mimc7(bytes32 x, bytes32 y) public returns (bytes32) { + function testMimc7(bytes32 x, bytes32 y) public pure returns (bytes32) { return MiMC7.hash(x, y); } /// Test function for MiMC31 - function test_mimc31(bytes32 x, bytes32 y) public returns (bytes32) { + function testMimc31(bytes32 x, bytes32 y) public pure returns (bytes32) { return MiMC31.hash(x, y); } } diff --git a/zeth_contracts/contracts/MixerBase.sol b/zeth_contracts/contracts/MixerBase.sol index 202885ada..5c996d3d1 100644 --- a/zeth_contracts/contracts/MixerBase.sol +++ b/zeth_contracts/contracts/MixerBase.sol @@ -27,12 +27,12 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract address private _token; // Contract that is allowed to call the `dispatch` method, passing in the - // correct _vk_hash. (Disable the dispatch method by setting - // _permitted_dispatcher = 0, in which case _vk_hash is unused.) - address private _permitted_dispatcher; + // correct _vkHash. (Disable the dispatch method by setting + // _permittedDispatcher = 0, in which case _vkHash is unused.) + address private _permittedDispatcher; - // The acceptable value of _vk_hash, passed in by a trusted dispatcher. - uint256[2] private _vk_hash; + // The acceptable value of _vkHash, passed in by a trusted dispatcher. + uint256[2] private _vkHash; // JoinSplit description, gives the number of inputs (nullifiers) and // outputs (commitments/ciphertexts) to receive and process. @@ -104,8 +104,8 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract _roots[initialRoot] = true; _vk = vk; _token = token_address; - _permitted_dispatcher = permitted_dispatcher; - _vk_hash = vk_hash; + _permittedDispatcher = permitted_dispatcher; + _vkHash = vk_hash; } /// Function allowing external users of the contract to retrieve some of @@ -116,7 +116,7 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract /// /// Returns the number of input notes, the number of output notes and the /// total number of primary inputs. - function get_constants() + function getConstants() external pure returns ( @@ -135,21 +135,21 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract /// IZecaleApplication interface, see /// https://github.com/clearmatics/zecale function dispatch( - uint256[2] memory nested_vk_hash, - uint256[] memory nested_inputs, - bytes memory nested_parameters + uint256[2] memory nestedVkHash, + uint256[] memory nestedInputs, + bytes memory nestedParameters ) public payable { // Sanity / permission checkcheck require( - msg.sender == _permitted_dispatcher, "dispatcher not permitted"); + msg.sender == _permittedDispatcher, "dispatcher not permitted"); require( - nested_vk_hash[0] == _vk_hash[0] && - nested_vk_hash[1] == _vk_hash[1], - "invalid nested_vk_hash"); - require(nested_inputs.length == 1, "invalid num nested inputs"); + nestedVkHash[0] == _vkHash[0] && + nestedVkHash[1] == _vkHash[1], + "invalid nestedVkHash"); + require(nestedInputs.length == 1, "invalid num nested inputs"); // Decode the nested parameters // TODO: convert ciphertext array without copying @@ -157,7 +157,7 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract uint256 sigma, uint256[] memory public_data, bytes[] memory decoded_ciphertexts) = abi.decode( - nested_parameters, (uint256[4], uint256, uint256[], bytes[])); + nestedParameters, (uint256[4], uint256, uint256[], bytes[])); require( public_data.length == NUM_INPUTS, "invalid number of public inputs in decoded data."); @@ -180,18 +180,18 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // Ensure that the primary input to the zk-proof (validated and passed // in by the dispatcher), matches the hash of the public inputs. require( - nested_inputs[0] == hash_public_proof_data(inputs), + nestedInputs[0] == hashPublicProofData(inputs), "hash of public data does not match primary input"); // 1. Check the root and the nullifiers bytes32[JSIN] memory nullifiers; - check_mkroot_nullifiers_hsig_append_nullifiers_state( + checkMkrootNullifiersHsigAppendNullifiersState( vk, inputs, nullifiers); // 2.a Verify the signature on the hash of data_to_be_signed. - // hash_to_be_signed is expected to have been created without the proof + // hashToBeSigned is expected to have been created without the proof // data. - bytes32 hash_to_be_signed = sha256( + bytes32 hashToBeSigned = sha256( abi.encodePacked( uint256(uint160(msg.sender)), ciphertexts[0], @@ -202,11 +202,11 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract require( OTSchnorrVerifier.verify( - vk[0], vk[1], vk[2], vk[3], sigma, hash_to_be_signed), + vk[0], vk[1], vk[2], vk[3], sigma, hashToBeSigned), "Invalid signature in dispatch" ); - mix_append_commitments_emit_and_handle_public_values( + mixAppendCommitmentsEmitAndHandlePublicValues( inputs, ciphertexts, nullifiers); } @@ -218,7 +218,7 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract uint256[] memory proof, uint256[4] memory vk, uint256 sigma, - uint256[NUM_INPUTS] memory public_inputs, + uint256[NUM_INPUTS] memory publicInputs, bytes[JSOUT] memory ciphertexts ) public @@ -226,11 +226,11 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract { // 1. Check the root and the nullifiers bytes32[JSIN] memory nullifiers; - check_mkroot_nullifiers_hsig_append_nullifiers_state( - vk, public_inputs, nullifiers); + checkMkrootNullifiersHsigAppendNullifiersState( + vk, publicInputs, nullifiers); // 2.a Verify the signature on the hash of data_to_be_signed - bytes32 hash_to_be_signed = sha256( + bytes32 hashToBeSigned = sha256( abi.encodePacked( uint256(uint160(msg.sender)), // Unfortunately, we have to unroll this for now. We could @@ -239,27 +239,27 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract ciphertexts[0], ciphertexts[1], proof, - public_inputs + publicInputs ) ); require( OTSchnorrVerifier.verify( - vk[0], vk[1], vk[2], vk[3], sigma, hash_to_be_signed), + vk[0], vk[1], vk[2], vk[3], sigma, hashToBeSigned), "Invalid signature: Unable to verify the signature correctly" ); // 2.b Verify the proof - uint256 public_inputs_hash = hash_public_proof_data(public_inputs); + uint256 publicInputsHash = hashPublicProofData(publicInputs); require( - verify_zk_proof(proof, public_inputs_hash), + verifyZkProof(proof, publicInputsHash), "Invalid proof: Unable to verify the proof correctly" ); - mix_append_commitments_emit_and_handle_public_values( - public_inputs, ciphertexts, nullifiers); + mixAppendCommitmentsEmitAndHandlePublicValues( + publicInputs, ciphertexts, nullifiers); } - function mix_append_commitments_emit_and_handle_public_values( + function mixAppendCommitmentsEmitAndHandlePublicValues( uint256[NUM_INPUTS] memory inputs, bytes[JSOUT] memory ciphertexts, bytes32[JSIN] memory nullifiers @@ -268,11 +268,11 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract { // 3. Append the commitments to the tree bytes32[JSOUT] memory commitments; - assemble_commitments_and_append_to_state(inputs, commitments); + assembleCommitmentsAndAppendToState(inputs, commitments); // 4. Add the new root to the list of existing roots bytes32 new_merkle_root = recomputeRoot(JSOUT); - add_merkle_root(new_merkle_root); + addMerkleRoot(new_merkle_root); // 5. Emit the all Mix data emit LogMix( @@ -284,10 +284,10 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // 6. Get the public values in Wei and modify the state depending on // their values - process_public_values(inputs); + processPublicValues(inputs); } - function hash_public_proof_data(uint256[NUM_INPUTS] memory public_data) + function hashPublicProofData(uint256[NUM_INPUTS] memory public_data) internal returns (uint256) { @@ -306,7 +306,7 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract /// This function is used to extract the public values (vpub_in, vpub_out) /// from the residual field element(S) - function assemble_public_values(uint256 residual_bits) + function assemblePublicValues(uint256 residualBits) internal pure returns ( @@ -315,16 +315,16 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract ) { // vpub_out and vpub_in occupy the first and second PUBLIC_VALUE_BITS - vpub_out = (residual_bits & PUBLIC_VALUE_MASK) * PUBLIC_UNIT_VALUE_WEI; - vpub_in = ((residual_bits >> PUBLIC_VALUE_BITS) & PUBLIC_VALUE_MASK) + vpub_out = (residualBits & PUBLIC_VALUE_MASK) * PUBLIC_UNIT_VALUE_WEI; + vpub_in = ((residualBits >> PUBLIC_VALUE_BITS) & PUBLIC_VALUE_MASK) * PUBLIC_UNIT_VALUE_WEI; } - /// This function is used to reassemble hsig given the primary_inputs. + /// This function is used to reassemble hsig given the primaryInputs. /// To do so, we extract the remaining bits of hsig from the residual field /// element(S) and combine them with the hsig field element - function assemble_hsig( - uint256[NUM_INPUTS] memory primary_inputs + function assembleHsig( + uint256[NUM_INPUTS] memory primaryInputs ) internal pure @@ -332,20 +332,20 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract { // The h_sig residual bits are after the JSIN authentication tags and // JSIN nullifier bits. - return extract_bytes32( - primary_inputs[1 + JSIN + JSOUT], - primary_inputs[1 + JSOUT + NUM_HASH_DIGESTS], + return extractBytes32( + primaryInputs[1 + JSIN + JSOUT], + primaryInputs[1 + JSOUT + NUM_HASH_DIGESTS], 2 * JSIN ); } /// This function is used to reassemble the nullifiers given the nullifier - /// index [0, JSIN[ and the primary_inputs To do so, we extract the + /// index [0, JSIN[ and the primaryInputs To do so, we extract the /// remaining bits of the nullifier from the residual field element(S) and /// combine them with the nullifier field element - function assemble_nullifier( + function assembleNullifier( uint256 index, - uint256[NUM_INPUTS] memory primary_inputs + uint256[NUM_INPUTS] memory primaryInputs ) internal pure @@ -355,9 +355,9 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract require(index < JSIN, "nullifier index overflow"); // Nullifier residual bits follow the JSIN message authentication tags. - return extract_bytes32( - primary_inputs[1 + JSOUT + index], - primary_inputs[1 + JSOUT + NUM_HASH_DIGESTS], + return extractBytes32( + primaryInputs[1 + JSOUT + index], + primaryInputs[1 + JSOUT + NUM_HASH_DIGESTS], JSIN + index ); } @@ -396,10 +396,10 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // Utility function to extract a full uint256 from a field element and the // n-th set of residual bits from `residual`. This function is // curve-dependent. - function extract_bytes32( - uint256 field_element, + function extractBytes32( + uint256 fieldElement, uint256 residual, - uint256 residual_bits_set_idx + uint256 residualBitsSetIdx ) internal pure @@ -408,9 +408,9 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // Implementations must implement the verification algorithm of the // selected SNARK. - function verify_zk_proof( + function verifyZkProof( uint256[] memory proof, - uint256 public_inputs_hash + uint256 publicInputsHash ) internal virtual @@ -420,22 +420,22 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract /// and nullifiers in the primary inputs (instance) and modifies the state /// of the mixer contract accordingly. (ie: Appends the commitments to the /// tree, appends the nullifiers to the list and so on). - function check_mkroot_nullifiers_hsig_append_nullifiers_state( + function checkMkrootNullifiersHsigAppendNullifiersState( uint256[4] memory vk, - uint256[NUM_INPUTS] memory primary_inputs, + uint256[NUM_INPUTS] memory primaryInputs, bytes32[JSIN] memory nfs) internal { // 1. We re-assemble the full root digest and check it is in the tree require( - _roots[bytes32(primary_inputs[0])], + _roots[bytes32(primaryInputs[0])], "Invalid root: This root doesn't exist" ); // 2. We re-assemble the nullifiers (JSInputs) and check they were not // already seen. for (uint256 i = 0; i < JSIN; i++) { - bytes32 nullifier = assemble_nullifier(i, primary_inputs); + bytes32 nullifier = assembleNullifier(i, primaryInputs); require( !_nullifiers[nullifier], "Invalid nullifier: This nullifier has already been used" @@ -449,7 +449,7 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // they are equal (i.e. that h_sig re-assembled was correctly generated // from vk). bytes32 expected_hsig = sha256(abi.encodePacked(nfs, vk)); - bytes32 hsig = assemble_hsig(primary_inputs); + bytes32 hsig = assembleHsig(primaryInputs); require( expected_hsig == hsig, "Invalid hsig: This hsig does not correspond to the hash of vk and" @@ -457,26 +457,26 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract ); } - function assemble_commitments_and_append_to_state( - uint256[NUM_INPUTS] memory primary_inputs, + function assembleCommitmentsAndAppendToState( + uint256[NUM_INPUTS] memory primaryInputs, bytes32[JSOUT] memory comms ) internal { // We re-assemble the commitments (JSOutputs) for (uint256 i = 0; i < JSOUT; i++) { - bytes32 current_commitment = bytes32(primary_inputs[1 + i]); + bytes32 current_commitment = bytes32(primaryInputs[1 + i]); comms[i] = current_commitment; insert(current_commitment); } } - function process_public_values(uint256[NUM_INPUTS] memory primary_inputs) + function processPublicValues(uint256[NUM_INPUTS] memory primaryInputs) internal { // We get vpub_in and vpub_out in wei - (uint256 vpub_in, uint256 vpub_out) = assemble_public_values( - primary_inputs[1 + JSOUT + NUM_HASH_DIGESTS]); + (uint256 vpub_in, uint256 vpub_out) = assemblePublicValues( + primaryInputs[1 + JSOUT + NUM_HASH_DIGESTS]); // If the vpub_in is > 0, we need to make sure the right amount is paid if (vpub_in > 0) { @@ -512,7 +512,7 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract } } - function add_merkle_root(bytes32 root) internal + function addMerkleRoot(bytes32 root) internal { _roots[root] = true; } diff --git a/zeth_contracts/contracts/OTSchnorrVerifier.sol b/zeth_contracts/contracts/OTSchnorrVerifier.sol index 37760e417..952f772f7 100644 --- a/zeth_contracts/contracts/OTSchnorrVerifier.sol +++ b/zeth_contracts/contracts/OTSchnorrVerifier.sol @@ -19,7 +19,7 @@ library OTSchnorrVerifier { uint256 vk2, uint256 vk3, uint256 sigma, - bytes32 hash_to_be_signed + bytes32 hashToBeSigned ) internal returns (bool) @@ -27,7 +27,7 @@ library OTSchnorrVerifier { // Original code: // // bytes32 h_bytes = sha256( - // abi.encodePacked(vk[2], vk[3], hash_to_be_signed)); + // abi.encodePacked(vk[2], vk[3], hashToBeSigned)); // uint256 h = uint256(h_bytes); // // // X = g^{x}, where g represents a generator of the cyclic group G @@ -36,7 +36,7 @@ library OTSchnorrVerifier { // Pairing.G1Point memory Y = Pairing.G1Point(vk[2], vk[3]); // // // S = g^{sigma} - // Pairing.G1Point memory S = Pairing.scalarMulG1(Pairing.P1(), sigma); + // Pairing.G1Point memory S = Pairing.scalarMulG1(Pairing.genG1(), sigma); // // S_comp = g^{y + xh} // Pairing.G1Point memory S_comp = Pairing.addG1(Y, Pairing.scalarMulG1(X, h)); // @@ -51,18 +51,18 @@ library OTSchnorrVerifier { let g := sub(gas(), 2000) // pad: - // 0x40 hash_to_be_signed + // 0x40 hashToBeSigned // 0x20 Y[1] // 0x00 Y[0] // Compute sha256 into 0x40 mstore(pad, vk2) mstore(add(pad, 0x20), vk3) - mstore(add(pad, 0x40), hash_to_be_signed) + mstore(add(pad, 0x40), hashToBeSigned) pop(call(g, 2, 0, pad, 0x60, add(pad, 0x80), 0x20)) // pad: - // 0x80 h = sha256(Y || hash_to_be_signed) + // 0x80 h = sha256(Y || hashToBeSigned) // 0x60 // 0x40 // 0x20 Y[1] @@ -88,7 +88,7 @@ library OTSchnorrVerifier { // 0x40 // 0x20 (Y + h.X)[1] // 0x00 (Y + h.X)[0] - // copy P1 and sigma (see Pairing.sol for values) + // copy genG1 and sigma (see Pairing.sol for values) mstore(add(pad, 0x40), 1) mstore(add(pad, 0x60), 2) @@ -96,8 +96,8 @@ library OTSchnorrVerifier { // pad: // 0x80 sigma - // 0x60 P1[1] - // 0x40 P1[0] + // 0x60 genG1[1] + // 0x40 genG1[0] // 0x20 (Y + h.X)[1] // 0x00 (Y + h.X)[0] // call bn256ScalarMul(in: 0x40, out: 0x40) @@ -105,8 +105,8 @@ library OTSchnorrVerifier { pop(call(g, 7, 0, x_location, 0x60, x_location, 0x40)) // pad: - // 0x60 sigma.P1[1] - // 0x40 sigma.P1[0] + // 0x60 sigma.genG1[1] + // 0x40 sigma.genG1[0] // 0x20 (Y + h.X)[1] // 0x00 (Y + h.X)[0] } diff --git a/zeth_contracts/contracts/Pairing.sol b/zeth_contracts/contracts/Pairing.sol index 9a4cc2768..2d49ab545 100644 --- a/zeth_contracts/contracts/Pairing.sol +++ b/zeth_contracts/contracts/Pairing.sol @@ -29,12 +29,12 @@ library Pairing { } // Return the generator of G1 - function P1() internal pure returns (G1Point memory) { + function genG1() internal pure returns (G1Point memory) { return G1Point(1, 2); } // Return the generator of G2 - function P2() internal pure returns (G2Point memory) { + function genG2() internal pure returns (G2Point memory) { return G2Point( // solhint-disable-next-line 11559732032986387107991004021392285783925812861821192530917403151452391805634, @@ -178,7 +178,8 @@ library Pairing { G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal - returns (bool) { + returns (bool) + { G1Point[] memory p1 = new G1Point[](2); G2Point[] memory p2 = new G2Point[](2); p1[0] = a1; @@ -194,7 +195,8 @@ library Pairing { G1Point memory b1, G2Point memory b2, G1Point memory c1, G2Point memory c2) internal - returns (bool) { + returns (bool) + { G1Point[] memory p1 = new G1Point[](3); G2Point[] memory p2 = new G2Point[](3); p1[0] = a1; @@ -213,7 +215,8 @@ library Pairing { G1Point memory c1, G2Point memory c2, G1Point memory d1, G2Point memory d2) internal - returns (bool) { + returns (bool) + { G1Point[] memory p1 = new G1Point[](4); G2Point[] memory p2 = new G2Point[](4); p1[0] = a1; diff --git a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol index e8b887ab4..90695ca63 100644 --- a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol @@ -94,24 +94,24 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase vk_x = Pairing.addG1(vk_x, vk.IC[0]); // 2. Check the validity of knowledge commitments for A, B, C - // e(π_A, vk_A) = e(π′A, P2), e(vk_B, π_B) - // = e(π′_B, P2), e(vk_C, π_C) - // = e(π′_C, P2), + // e(π_A, vk_A) = e(π′A, genG2), e(vk_B, π_B) + // = e(π′_B, genG2), e(vk_C, π_C) + // = e(π′_C, genG2), if (!Pairing.pairingProd2( proof.A, vk.A, - Pairing.negateG1(proof.A_p), Pairing.P2()) + Pairing.negateG1(proof.A_p), Pairing.genG2()) ) { return 1; } if (!Pairing.pairingProd2( vk.B, proof.B, - Pairing.negateG1(proof.B_p), Pairing.P2()) + Pairing.negateG1(proof.B_p), Pairing.genG2()) ) { return 2; } if (!Pairing.pairingProd2( proof.C, vk.C, - Pairing.negateG1(proof.C_p), Pairing.P2()) + Pairing.negateG1(proof.C_p), Pairing.genG2()) ) { return 3; } @@ -131,14 +131,14 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase } // 4. Check QAP divisibility - // e(vk_x + π_A, π_B) = e(π_H, vk_Z) · e(π_C, P2) + // e(vk_x + π_A, π_B) = e(π_H, vk_Z) · e(π_C, genG2) pairing_check = Pairing.pairingProd3( Pairing.addG1(vk_x, proof.A), proof.B, Pairing.negateG1(proof.H), vk.Z, Pairing.negateG1(proof.C), - Pairing.P2()); + Pairing.genG2()); if (!pairing_check) { return 5; } @@ -146,9 +146,9 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase return 0; } - function verify_zk_proof( - uint256[] memory proof_data, - uint256 public_inputs_hash + function verifyZkProof( + uint256[] memory proofData, + uint256 publicInputsHash ) internal override @@ -160,23 +160,23 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase // Slightly redundant Proof memory proof; - proof.A = Pairing.G1Point(proof_data[0], proof_data[1]); - proof.A_p = Pairing.G1Point(proof_data[2], proof_data[3]); + proof.A = Pairing.G1Point(proofData[0], proofData[1]); + proof.A_p = Pairing.G1Point(proofData[2], proofData[3]); proof.B = Pairing.G2Point( - proof_data[4], proof_data[5], proof_data[6], proof_data[7]); - proof.B_p = Pairing.G1Point(proof_data[8], proof_data[9]); - proof.C = Pairing.G1Point(proof_data[10], proof_data[11]); - proof.C_p = Pairing.G1Point(proof_data[12], proof_data[13]); - proof.H = Pairing.G1Point(proof_data[14], proof_data[15]); - proof.K = Pairing.G1Point(proof_data[16], proof_data[17]); + proofData[4], proofData[5], proofData[6], proofData[7]); + proof.B_p = Pairing.G1Point(proofData[8], proofData[9]); + proof.C = Pairing.G1Point(proofData[10], proofData[11]); + proof.C_p = Pairing.G1Point(proofData[12], proofData[13]); + proof.H = Pairing.G1Point(proofData[14], proofData[15]); + proof.K = Pairing.G1Point(proofData[16], proofData[17]); require( - public_inputs_hash < r, + publicInputsHash < r, "Input is not is scalar field" ); uint256[] memory inputs = new uint256[](1); - inputs[0] = public_inputs_hash; + inputs[0] = publicInputsHash; uint256 verification_result = verify(inputs, proof); if (verification_result != 0) { return false; From 51b69476daa39c28fabb720cbf740484140b65a2 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Wed, 31 Mar 2021 17:24:14 +0100 Subject: [PATCH 104/137] Fixed comment formatting and missing renamings --- zeth_contracts/contracts/AltBN128MixerBase.sol | 6 +++--- zeth_contracts/contracts/BLS12_377MixerBase.sol | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/zeth_contracts/contracts/AltBN128MixerBase.sol b/zeth_contracts/contracts/AltBN128MixerBase.sol index 8a74f1ffd..d74f63acf 100644 --- a/zeth_contracts/contracts/AltBN128MixerBase.sol +++ b/zeth_contracts/contracts/AltBN128MixerBase.sol @@ -72,16 +72,16 @@ abstract contract AltBN128MixerBase is MixerBase // // Shift to occupy the highest order bits: // 255 128 64 0 - // | bits_to_shift | | residualBitsIdx | | | + // | bitsToShift | | residualBitsIdx | | | // | <------------ | xxx | |)|| // residual bits // Number of bits AFTER public values uint256 residualBitsIdx = residualBitsSetIdx * NUM_RESIDUAL_BITS; - uint256 bits_to_shift = + uint256 bitsToShift = RESIDUAL_BITS_SHIFT - TOTAL_PUBLIC_VALUE_BITS - residualBitsIdx; uint256 residualBits = - (residual << bits_to_shift) & RESIDUAL_BITS_MASK; + (residual << bitsToShift) & RESIDUAL_BITS_MASK; return bytes32(fieldElement | residualBits); } } diff --git a/zeth_contracts/contracts/BLS12_377MixerBase.sol b/zeth_contracts/contracts/BLS12_377MixerBase.sol index 0bfc7397b..aa3615021 100644 --- a/zeth_contracts/contracts/BLS12_377MixerBase.sol +++ b/zeth_contracts/contracts/BLS12_377MixerBase.sol @@ -79,15 +79,15 @@ abstract contract BLS12_377MixerBase is MixerBase // // Shift r_i to occupy the highest order bits: // 255 128 64 0 - // | bits_to_shift | | residualBitsIdx | | | + // | bitsToShift | | residualBitsIdx | | | // | <------------ || ||| // Number of bits AFTER public values uint256 residualBitsIdx = residualBitsSetIdx * NUM_RESIDUAL_BITS; - uint256 bits_to_shift = + uint256 bitsToShift = RESIDUAL_BITS_SHIFT - TOTAL_PUBLIC_VALUE_BITS - residualBitsIdx; uint256 residualBits = - (residual << bits_to_shift) & RESIDUAL_BITS_MASK; + (residual << bitsToShift) & RESIDUAL_BITS_MASK; return bytes32(fieldElement | residualBits); } } From 51badde8180f4bb1bb0751986e989ada97c40dd1 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Wed, 31 Mar 2021 17:36:19 +0100 Subject: [PATCH 105/137] Switched public functions to external when possible to read straight from calldata --- zeth_contracts/contracts/AltBN128MixerBase.sol | 6 ------ zeth_contracts/contracts/BLS12_377MixerBase.sol | 6 ------ zeth_contracts/contracts/BLS12_377_test.sol | 6 +++--- zeth_contracts/contracts/BW6_761_test.sol | 6 +++--- zeth_contracts/contracts/MerkleTreeMiMC7_test.sol | 2 +- zeth_contracts/contracts/MiMC_test.sol | 4 ++-- zeth_contracts/contracts/MixerBase.sol | 4 ++-- 7 files changed, 11 insertions(+), 23 deletions(-) diff --git a/zeth_contracts/contracts/AltBN128MixerBase.sol b/zeth_contracts/contracts/AltBN128MixerBase.sol index d74f63acf..508ec4e95 100644 --- a/zeth_contracts/contracts/AltBN128MixerBase.sol +++ b/zeth_contracts/contracts/AltBN128MixerBase.sol @@ -27,12 +27,6 @@ abstract contract AltBN128MixerBase is MixerBase uint256 internal constant RESIDUAL_BITS_MASK = ((1 << NUM_RESIDUAL_BITS) - 1) << RESIDUAL_BITS_SHIFT; - // Total number of residual bits from packing of 256-bit long string into - // 253-bit long field elements to which are added the public value of size - // 64 bits - uint256 internal constant TOTAL_NUM_RESIDUAL_BITS = - 2 * PUBLIC_VALUE_BITS + NUM_RESIDUAL_BITS * NUM_HASH_DIGESTS; - /// Constructor of the contract constructor( uint256 mk_depth, diff --git a/zeth_contracts/contracts/BLS12_377MixerBase.sol b/zeth_contracts/contracts/BLS12_377MixerBase.sol index aa3615021..0d18d88fa 100644 --- a/zeth_contracts/contracts/BLS12_377MixerBase.sol +++ b/zeth_contracts/contracts/BLS12_377MixerBase.sol @@ -35,12 +35,6 @@ abstract contract BLS12_377MixerBase is MixerBase uint256 internal constant RESIDUAL_BITS_MASK = ((1 << NUM_RESIDUAL_BITS) - 1) << RESIDUAL_BITS_SHIFT; - // Total number of bits required to hold all residual bits from, including - // the public vin and vout values (each 64 bits long). Denoted RSDBLEN in - // Zeth specifications. - uint256 internal constant RESIDUAL_BITS_LENGTH = - 2 * PUBLIC_VALUE_BITS + NUM_RESIDUAL_BITS * NUM_HASH_DIGESTS; - constructor( uint256 mk_depth, address token, diff --git a/zeth_contracts/contracts/BLS12_377_test.sol b/zeth_contracts/contracts/BLS12_377_test.sol index 566cac5b9..952ba80ea 100644 --- a/zeth_contracts/contracts/BLS12_377_test.sol +++ b/zeth_contracts/contracts/BLS12_377_test.sol @@ -17,7 +17,7 @@ contract BLS12_377_test /// `input` is the concatenation of 2 encoded points in G1 function testECAdd(bytes32[2 * G1_POINT_WORDS] memory input) - public + external returns(bytes32[G1_POINT_WORDS] memory) { bytes32[G1_POINT_WORDS] memory output; @@ -33,7 +33,7 @@ contract BLS12_377_test /// `input` is an encoded point in G1, followed by an encoded scalar. function testECMul(bytes32[G1_POINT_WORDS + SCALAR_WORDS] memory input) - public + external returns(bytes32[G1_POINT_WORDS] memory) { bytes32[G1_POINT_WORDS] memory output; @@ -53,7 +53,7 @@ contract BLS12_377_test function testECPairing( bytes32[4 * (G1_POINT_WORDS + G2_POINT_WORDS)] memory input ) - public + external returns(uint256) { uint256[1] memory output; diff --git a/zeth_contracts/contracts/BW6_761_test.sol b/zeth_contracts/contracts/BW6_761_test.sol index 353a7e9e6..61c7e8e22 100644 --- a/zeth_contracts/contracts/BW6_761_test.sol +++ b/zeth_contracts/contracts/BW6_761_test.sol @@ -15,7 +15,7 @@ contract BW6_761_test // `points` should be the concatenation of 2 encoded points function testECAdd(bytes32[2 * POINT_WORDS] memory points) - public returns (bytes32[POINT_WORDS] memory) + external returns (bytes32[POINT_WORDS] memory) { bytes32[POINT_WORDS] memory output; bool success = true; @@ -30,7 +30,7 @@ contract BW6_761_test // `inputs` is an encoded point, followed by an encoded scalar. function testECMul(bytes32[POINT_WORDS + SCALAR_WORDS] memory input) - public returns (bytes32[POINT_WORDS] memory) + external returns (bytes32[POINT_WORDS] memory) { bytes32[POINT_WORDS] memory output; bool success = true; @@ -47,7 +47,7 @@ contract BW6_761_test // a G1 point, followed by a G2 point. For BW6-761, both of these points // are 6 words, so there should be 4 * 2 * 6 = 48 words ( function testECPairing(bytes32[8 * POINT_WORDS] memory input) - public returns (uint256) + external returns (uint256) { uint256[1] memory output; bool success = true; diff --git a/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol b/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol index c18bee0e0..55c5b038e 100644 --- a/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol +++ b/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol @@ -27,7 +27,7 @@ contract MerkleTreeMiMC7_test is BaseMerkleTree bytes32[] memory first, bytes32[] memory second ) - public + external returns (bytes32) { for (uint i = 0 ; i < first.length ; ++i) { diff --git a/zeth_contracts/contracts/MiMC_test.sol b/zeth_contracts/contracts/MiMC_test.sol index 25644ffc3..c251fa4db 100644 --- a/zeth_contracts/contracts/MiMC_test.sol +++ b/zeth_contracts/contracts/MiMC_test.sol @@ -11,12 +11,12 @@ import "./MiMC31.sol"; contract MiMC_test { /// Test function for MiMC7 - function testMimc7(bytes32 x, bytes32 y) public pure returns (bytes32) { + function testMimc7(bytes32 x, bytes32 y) external pure returns (bytes32) { return MiMC7.hash(x, y); } /// Test function for MiMC31 - function testMimc31(bytes32 x, bytes32 y) public pure returns (bytes32) { + function testMimc31(bytes32 x, bytes32 y) external pure returns (bytes32) { return MiMC31.hash(x, y); } } diff --git a/zeth_contracts/contracts/MixerBase.sol b/zeth_contracts/contracts/MixerBase.sol index 5c996d3d1..9679b60a9 100644 --- a/zeth_contracts/contracts/MixerBase.sol +++ b/zeth_contracts/contracts/MixerBase.sol @@ -139,7 +139,7 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract uint256[] memory nestedInputs, bytes memory nestedParameters ) - public + external payable { // Sanity / permission checkcheck @@ -221,7 +221,7 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract uint256[NUM_INPUTS] memory publicInputs, bytes[JSOUT] memory ciphertexts ) - public + external payable { // 1. Check the root and the nullifiers From c660695c6ffccb2540c8171614cb41a1d4bf298b Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Wed, 31 Mar 2021 17:52:27 +0100 Subject: [PATCH 106/137] Fixed solidity linting issues and renamed functions in python tests --- client/test_contracts/test_mimc_contract.py | 4 ++-- zeth_contracts/contracts/Groth16AltBN128.sol | 3 ++- zeth_contracts/contracts/OTSchnorrVerifier.sol | 6 ++++-- zeth_contracts/contracts/Pairing.sol | 6 +++++- zeth_contracts/contracts/Pghr13AltBN128Mixer.sol | 6 ++++-- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/client/test_contracts/test_mimc_contract.py b/client/test_contracts/test_mimc_contract.py index 056988c6e..f45682f24 100644 --- a/client/test_contracts/test_mimc_contract.py +++ b/client/test_contracts/test_mimc_contract.py @@ -37,7 +37,7 @@ def test_mimc7(self) -> None: # pylint: enable=line-too-long h = MiMC7().hash(x, y) - result = CONTRACT_INSTANCE.functions.test_mimc7(x, y).call() + result = CONTRACT_INSTANCE.functions.testMimc7(x, y).call() self.assertEqual(h, result) def test_mimc31(self) -> None: @@ -47,5 +47,5 @@ def test_mimc31(self) -> None: # pylint: enable=line-too-long h = MiMC31().hash(x, y) - result = CONTRACT_INSTANCE.functions.test_mimc31(x, y).call() + result = CONTRACT_INSTANCE.functions.testMimc31(x, y).call() self.assertEqual(h, result) diff --git a/zeth_contracts/contracts/Groth16AltBN128.sol b/zeth_contracts/contracts/Groth16AltBN128.sol index 8a3f5067e..7f1227986 100644 --- a/zeth_contracts/contracts/Groth16AltBN128.sol +++ b/zeth_contracts/contracts/Groth16AltBN128.sol @@ -71,7 +71,8 @@ library Groth16AltBN128 // Pairing.G1Point memory vk_x = vk.ABC[0]; // a_0 = 1 // for (uint256 i = 0; i < input.length; i++) { // vk_x = - // Pairing.addG1(vk_x, Pairing.scalarMulG1(vk.ABC[i + 1], input[i])); + // Pairing.addG1(vk_x, + // Pairing.scalarMulG1(vk.ABC[i + 1], input[i])); // } // // The linear combination loop was the biggest cost center of the mixer diff --git a/zeth_contracts/contracts/OTSchnorrVerifier.sol b/zeth_contracts/contracts/OTSchnorrVerifier.sol index 952f772f7..59d978915 100644 --- a/zeth_contracts/contracts/OTSchnorrVerifier.sol +++ b/zeth_contracts/contracts/OTSchnorrVerifier.sol @@ -36,9 +36,11 @@ library OTSchnorrVerifier { // Pairing.G1Point memory Y = Pairing.G1Point(vk[2], vk[3]); // // // S = g^{sigma} - // Pairing.G1Point memory S = Pairing.scalarMulG1(Pairing.genG1(), sigma); + // Pairing.G1Point memory S = Pairing.scalarMulG1( + // Pairing.genG1(), sigma); // // S_comp = g^{y + xh} - // Pairing.G1Point memory S_comp = Pairing.addG1(Y, Pairing.scalarMulG1(X, h)); + // Pairing.G1Point memory S_comp = Pairing.addG1(Y, + // Pairing.scalarMulG1(X, h)); // // // Check that g^{sigma} == g^{y + xh} // return (S.X == S_comp.X && S.Y == S_comp.Y); diff --git a/zeth_contracts/contracts/Pairing.sol b/zeth_contracts/contracts/Pairing.sol index 2d49ab545..218c895e7 100644 --- a/zeth_contracts/contracts/Pairing.sol +++ b/zeth_contracts/contracts/Pairing.sol @@ -47,7 +47,11 @@ library Pairing { } // Return the negation of p, i.e. p.add(p.negate()) should be zero. - function negateG1(G1Point memory p) internal pure returns (G1Point memory) { + function negateG1(G1Point memory p) + internal + pure + returns (G1Point memory) + { // The prime q in the base field F_q for G1 // solhint-disable-next-line uint256 q = 21888242871839275222246405745257275088696311157297823662689037894645226208583; diff --git a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol index 90695ca63..e7dd66847 100644 --- a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol +++ b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol @@ -89,7 +89,8 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase // size n. Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0); for (uint256 i = 0; i < inputs.length; i++) { - vk_x = Pairing.addG1(vk_x, Pairing.scalarMulG1(vk.IC[i + 1], inputs[i])); + vk_x = Pairing.addG1(vk_x, + Pairing.scalarMulG1(vk.IC[i + 1], inputs[i])); } vk_x = Pairing.addG1(vk_x, vk.IC[0]); @@ -122,7 +123,8 @@ contract Pghr13AltBN128Mixer is AltBN128MixerBase bool pairing_check = Pairing.pairingProd3( proof.K, vk.gamma, - Pairing.negateG1(Pairing.addG1(vk_x, Pairing.addG1(proof.A, proof.C))), + Pairing.negateG1(Pairing.addG1(vk_x, + Pairing.addG1(proof.A, proof.C))), vk.gammaBeta2, Pairing.negateG1(vk.gammaBeta1), proof.B); From 4d57e824d2504ae5b6738d293fd9870687221b78 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Thu, 22 Apr 2021 19:31:18 +0100 Subject: [PATCH 107/137] Restricted verifyZkProof state mutability and added explicit public scope --- zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol b/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol index 83632f3b8..21da0952e 100644 --- a/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol +++ b/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol @@ -68,7 +68,8 @@ contract Groth16AltBN128MixerBase_test is Groth16AltBN128Mixer uint256[] memory /* proof */, uint256[NUM_INPUTS] memory /* inputs */ ) - internal + public + pure returns (bool) { return false; From 71872d9428c047f48481bdfafed4cd9b24297b44 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Thu, 22 Apr 2021 19:55:39 +0100 Subject: [PATCH 108/137] Fixed name styling and renaiming loose scopes --- .../test_groth16_altbn128_mixer_base.py | 8 +++---- .../test_groth16_bls12_377_contract.py | 2 +- zeth_contracts/contracts/Groth16AltBN128.sol | 5 ----- .../Groth16AltBN128MixerBase_test.sol | 22 +++++++++---------- .../contracts/Groth16BLS12_377_test.sol | 7 +++--- zeth_contracts/contracts/MixerBase.sol | 4 ++-- 6 files changed, 22 insertions(+), 26 deletions(-) diff --git a/client/test_contracts/test_groth16_altbn128_mixer_base.py b/client/test_contracts/test_groth16_altbn128_mixer_base.py index 7c2ec9e21..e9a4eefbc 100644 --- a/client/test_contracts/test_groth16_altbn128_mixer_base.py +++ b/client/test_contracts/test_groth16_altbn128_mixer_base.py @@ -202,27 +202,27 @@ def test_hash_public_inputs(self) -> None: public_data = mix_params.public_data expect_hash = InputHasher(MiMC7()).hash(public_data) actual_hash = MIXER_INSTANCE.functions.\ - hash_public_proof_data_test(public_data).call() + hashPublicProofDataTest(public_data).call() self.assertEqual(expect_hash, actual_hash) def test_assemble_nullifiers(self) -> None: # Test retrieving nullifiers for i in range(JS_INPUTS): res = MIXER_INSTANCE.functions.\ - assemble_nullifier_test(i, PACKED_PRIMARY_INPUTS).call() + assembleNullifierTest(i, PACKED_PRIMARY_INPUTS).call() val = int.from_bytes(res, byteorder="big") self.assertEqual(NULLIFIERS[i], val) def test_assemble_hsig(self) -> None: # Test retrieving hsig res = MIXER_INSTANCE.functions.\ - assemble_hsig_test(PACKED_PRIMARY_INPUTS).call() + assembleHsigTest(PACKED_PRIMARY_INPUTS).call() hsig = int.from_bytes(res, byteorder="big") self.assertEqual(HSIG, hsig) def test_assemble_vpub(self) -> None: # Test retrieving public values - v_in, v_out = MIXER_INSTANCE.functions.assemble_public_values_test( + v_in, v_out = MIXER_INSTANCE.functions.assemblePublicValuesTest( PACKED_PRIMARY_INPUTS[-1]).call() v_in_expect = VPUB[0] * ZETH_PUBLIC_UNIT_VALUE v_out_expect = VPUB[1] * ZETH_PUBLIC_UNIT_VALUE diff --git a/client/test_contracts/test_groth16_bls12_377_contract.py b/client/test_contracts/test_groth16_bls12_377_contract.py index 6f0ab4d74..b209795d4 100644 --- a/client/test_contracts/test_groth16_bls12_377_contract.py +++ b/client/test_contracts/test_groth16_bls12_377_contract.py @@ -92,7 +92,7 @@ def _invoke_groth16_bls12_377_verify( vk, BLS12_377_PAIRING) proof_evm = Groth16.proof_to_contract_parameters(proof, BLS12_377_PAIRING) inputs_evm = hex_list_to_uint256_list(inputs) - return CONTRACT_INSTANCE.functions.test_verify( + return CONTRACT_INSTANCE.functions.verifyTest( vk_evm, proof_evm, inputs_evm).call() def test_groth16_bls12_377_valid(self) -> None: diff --git a/zeth_contracts/contracts/Groth16AltBN128.sol b/zeth_contracts/contracts/Groth16AltBN128.sol index 7f1227986..793ef858e 100644 --- a/zeth_contracts/contracts/Groth16AltBN128.sol +++ b/zeth_contracts/contracts/Groth16AltBN128.sol @@ -18,11 +18,6 @@ library Groth16AltBN128 // solhint-disable-next-line max-line-length 21888242871839275222246405745257275088548364400416034343698204186575808495617; - // Return the value PRIME_R, the characteristic of the scalar field. - function scalar_r() internal pure returns (uint256) { - return PRIME_R; - } - // Fr elements and Fq elements can be held in a single uint256. Therefore // G1 elements require 2 uint256s. G2 elements have coordinates in Fp2, and // therefore occupy 4 uint256s. Based on this, the offsets and slot numbers diff --git a/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol b/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol index 21da0952e..ead0c21ed 100644 --- a/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol +++ b/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol @@ -25,38 +25,38 @@ contract Groth16AltBN128MixerBase_test is Groth16AltBN128Mixer { } - function hash_public_proof_data_test( - uint256[NUM_INPUTS] memory public_data + function hashPublicProofDataTest( + uint256[NUM_INPUTS] memory publicData ) - public + external returns (uint256) { - return hashPublicProofData(public_data); + return hashPublicProofData(publicData); } - function assemble_public_values_test(uint256 residualBits) - public + function assemblePublicValuesTest(uint256 residualBits) + external pure returns (uint256 vpub_in, uint256 vpub_out) { return assemblePublicValues(residualBits); } - function assemble_hsig_test( + function assembleHsigTest( uint256[NUM_INPUTS] memory primaryInputs ) - public + external pure returns(bytes32 hsig) { return assembleHsig(primaryInputs); } - function assemble_nullifier_test( + function assembleNullifierTest( uint256 index, uint256[NUM_INPUTS] memory primaryInputs ) - public + external pure returns(bytes32 nf) { @@ -68,7 +68,7 @@ contract Groth16AltBN128MixerBase_test is Groth16AltBN128Mixer uint256[] memory /* proof */, uint256[NUM_INPUTS] memory /* inputs */ ) - public + external pure returns (bool) { diff --git a/zeth_contracts/contracts/Groth16BLS12_377_test.sol b/zeth_contracts/contracts/Groth16BLS12_377_test.sol index d6493fd79..fde439f41 100644 --- a/zeth_contracts/contracts/Groth16BLS12_377_test.sol +++ b/zeth_contracts/contracts/Groth16BLS12_377_test.sol @@ -10,11 +10,12 @@ contract Groth16BLS12_377_test { uint256[] private _vk; - function test_verify( + function verifyTest( uint256[] memory vk, uint256[] memory proof, - uint256[] memory inputs) - public + uint256[] memory inputs + ) + external returns(bool) { _vk = vk; diff --git a/zeth_contracts/contracts/MixerBase.sol b/zeth_contracts/contracts/MixerBase.sol index 9679b60a9..6f6f848e6 100644 --- a/zeth_contracts/contracts/MixerBase.sol +++ b/zeth_contracts/contracts/MixerBase.sol @@ -287,7 +287,7 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract processPublicValues(inputs); } - function hashPublicProofData(uint256[NUM_INPUTS] memory public_data) + function hashPublicProofData(uint256[NUM_INPUTS] memory publicData) internal returns (uint256) { @@ -298,7 +298,7 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // solhint-disable-next-line max-line-length 13196537064117388418196223856311987714388543839552400408340921397545324034315)); for (uint256 i = 0 ; i < NUM_INPUTS; ++i) { - h = hash(h, bytes32(public_data[i])); + h = hash(h, bytes32(publicData[i])); } h = hash(h, bytes32(NUM_INPUTS)); return uint256(h); From 77b48344a377369e9fa9c840aee228026395131f Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Thu, 22 Apr 2021 20:08:22 +0100 Subject: [PATCH 109/137] Fixed inconsistent test function name --- client/test_contracts/test_mimc_contract.py | 4 ++-- zeth_contracts/contracts/MiMC_test.sol | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/test_contracts/test_mimc_contract.py b/client/test_contracts/test_mimc_contract.py index f45682f24..9031eefe7 100644 --- a/client/test_contracts/test_mimc_contract.py +++ b/client/test_contracts/test_mimc_contract.py @@ -37,7 +37,7 @@ def test_mimc7(self) -> None: # pylint: enable=line-too-long h = MiMC7().hash(x, y) - result = CONTRACT_INSTANCE.functions.testMimc7(x, y).call() + result = CONTRACT_INSTANCE.functions.mimc7Test(x, y).call() self.assertEqual(h, result) def test_mimc31(self) -> None: @@ -47,5 +47,5 @@ def test_mimc31(self) -> None: # pylint: enable=line-too-long h = MiMC31().hash(x, y) - result = CONTRACT_INSTANCE.functions.testMimc31(x, y).call() + result = CONTRACT_INSTANCE.functions.mimc31Test(x, y).call() self.assertEqual(h, result) diff --git a/zeth_contracts/contracts/MiMC_test.sol b/zeth_contracts/contracts/MiMC_test.sol index c251fa4db..4d035279a 100644 --- a/zeth_contracts/contracts/MiMC_test.sol +++ b/zeth_contracts/contracts/MiMC_test.sol @@ -11,12 +11,12 @@ import "./MiMC31.sol"; contract MiMC_test { /// Test function for MiMC7 - function testMimc7(bytes32 x, bytes32 y) external pure returns (bytes32) { + function mimc7Test(bytes32 x, bytes32 y) external pure returns (bytes32) { return MiMC7.hash(x, y); } /// Test function for MiMC31 - function testMimc31(bytes32 x, bytes32 y) external pure returns (bytes32) { + function mimc31Test(bytes32 x, bytes32 y) external pure returns (bytes32) { return MiMC31.hash(x, y); } } From fb950b64b48a8b3e92c2e74f289b8170a7d5541b Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Fri, 23 Apr 2021 16:06:37 +0100 Subject: [PATCH 110/137] Removed useless and deprecated files --- .../migrations/2_deploy_contracts.js | 47 ------ zeth_contracts/test/bytes.js | 32 ---- zeth_contracts/test/merkleTree.js | 150 ------------------ 3 files changed, 229 deletions(-) delete mode 100644 zeth_contracts/migrations/2_deploy_contracts.js delete mode 100644 zeth_contracts/test/bytes.js delete mode 100644 zeth_contracts/test/merkleTree.js diff --git a/zeth_contracts/migrations/2_deploy_contracts.js b/zeth_contracts/migrations/2_deploy_contracts.js deleted file mode 100644 index 845eb8637..000000000 --- a/zeth_contracts/migrations/2_deploy_contracts.js +++ /dev/null @@ -1,47 +0,0 @@ -// Get verification key -var path = require('path'); -var setup_path = process.env.ZETH_SETUP_DIR; -var vk_json = path.join(setup_path, 'vk.json'); -var vk = require(vk_json); - -var tmp = [] -for (var i = 0; i < vk.IC.length; i++) { - tmp = [].concat(tmp, vk.IC[i]) -} -vk.IC = tmp; - -const MerkleTreeSha256 = artifacts.require("./MerkleTreeSha256.sol"); -const Mixer = artifacts.require("./Mixer.sol"); -const Verifier = artifacts.require("./Verifier.sol"); -const Bytes = artifacts.require("./Bytes.sol"); -const Bytes_tests = artifacts.require("./Bytes_tests.sol"); - -module.exports = (deployer) => { - console.log("[WARNING] Make sure you have the right verification key stored in the `ZETH_SETUP_DIR`!") - deployer.deploy( - Verifier, - vk.a[0], - vk.a[1], - vk.b, - vk.c[0], - vk.c[1], - vk.g[0], - vk.g[1], - vk.gb1, - vk.gb2[0], - vk.gb2[1], - vk.z[0], - vk.z[1], - vk.IC - ).then(function () { - // We deploy a mixer with a merkle tree of depth 4 - return deployer.deploy(Mixer, Verifier.address, 4); - }) - - deployer.deploy(Bytes); - deployer.link(Bytes, Bytes_tests); - deployer.deploy(Bytes_tests); - - // Deploy a merkle tree of depth 3 for the tests - deployer.deploy(MerkleTreeSha256, 3); -}; diff --git a/zeth_contracts/test/bytes.js b/zeth_contracts/test/bytes.js deleted file mode 100644 index b95aa825d..000000000 --- a/zeth_contracts/test/bytes.js +++ /dev/null @@ -1,32 +0,0 @@ -const Bytes_tests = artifacts.require("./Bytes_tests.sol"); - -const testContracts = { - Bytes_tests: Bytes_tests -}; - -const allSimpleTests = { - Bytes_tests: [ - "testReverseByte", - "testGetLastByte", - "testFlipEndiannessBytes32", - "testBytesToBytes32", - "testSha256DigestFromFieldElements" - ] -}; - -Object.keys(allSimpleTests).forEach(function(k) { - var obj = testContracts[k]; - contract(k, (accounts) => { - allSimpleTests[k].forEach(function (name) { - it(name, (done) => { - obj.deployed().then((instance) => { - const txObj = {from: accounts[0]}; - instance[name].call(txObj).then(result => { - assert.ok(result, k + "." + name + " [Test Fail] Boolean value expected true"); - done(); - }); - }); - }); - }); - }); -}); diff --git a/zeth_contracts/test/merkleTree.js b/zeth_contracts/test/merkleTree.js deleted file mode 100644 index bcc41399f..000000000 --- a/zeth_contracts/test/merkleTree.js +++ /dev/null @@ -1,150 +0,0 @@ -const crypto = require('crypto'); - -const MerkleTreeSha256 = artifacts.require("./MerkleTreeSha256.sol"); - -function prefixHexadecimalString(hex_str) { - return "0x" + hex_str; -} - -contract('MerkleTreeSha256', (accounts) => { - it('Test default value of merkle tree', async () => { - // We have a merkle tree of depth 3 for the tests - let instance = await MerkleTreeSha256.deployed(); - - // --- Expected values --- // - // All the nodes at index [7, 8, 9, 10, 11, 12, 13, 14] have the zero value - let expectedValueNodeLayer3 = Buffer.from(new Uint8Array(32)).toString('hex'); - // All the nodes at index [3,4,5,6] have the same value (= sha256(initialValueLeftNodeLayer3 + initialValueRightNodeLayer3)) - let expectedValueNodeLayer2 = crypto.createHash('sha256'). - update(Buffer.from(expectedValueNodeLayer3 + expectedValueNodeLayer3, 'hex')). - digest('hex'); - // All the nodes at index [1,2] have the same value (= sha256(initialValueLeftNodeLayer2 + initialValueRightNodeLayer2)) - let expectedValueNodeLayer1 = crypto.createHash('sha256'). - update(Buffer.from(expectedValueNodeLayer2 + expectedValueNodeLayer2, 'hex')). - digest('hex'); - // The value of the root node at index [0] (= sha256(initialValueLeftNodeLayer1 + initialValueRightNodeLayer1)) - let expectedValueNodeLayer0 = crypto.createHash('sha256'). - update(Buffer.from(expectedValueNodeLayer1 + expectedValueNodeLayer1, 'hex')). - digest('hex'); - - // --- Actual values from the smart contract --- // - let actualInitialTree = await instance.getTree(); - - // --- Asserts --- // - for(var i = 7; i < actualInitialTree.length; i++) { - console.log("(Layer3-Leaves) Node" + i + " => " + actualInitialTree[i]); - assert.equal( - prefixHexadecimalString(expectedValueNodeLayer3), - actualInitialTree[i], - "Mismatch between actual and expected value for node (" + i + ") of Layer3" - ); - } - for(var i = 3; i < 7; i++) { - console.log("(Layer2) Node" + i + " => " + actualInitialTree[i]); - assert.equal( - prefixHexadecimalString(expectedValueNodeLayer2), - actualInitialTree[i], - "Mismatch between actual and expected value for node (" + i + ") of Layer2" - ); - } - for(var i = 1; i < 3; i++) { - console.log("(Layer1) Node" + i + " => " + actualInitialTree[i]); - assert.equal( - prefixHexadecimalString(expectedValueNodeLayer1), - actualInitialTree[i], - "Mismatch between actual and expected value for node (" + i + ") of Layer1" - ); - } - console.log("(Layer0-Root) Node 0 => " + actualInitialTree[0]); - assert.equal( - prefixHexadecimalString(expectedValueNodeLayer0), - actualInitialTree[0], - "Mismatch between actual and expected value for node (0) of Layer0-Root" - ); - }); - - it('Test insertion in the merkle tree', async () => { - // We have a merkle tree of depth 3 for the tests - let instance = await MerkleTreeSha256.deployed(); - - // --- Leaves layer (layer 3) --- // - // We insert at the first available leaf (leftmost leaf --> index 7 in the tree of depth 3) - var expectedValueNode7 = crypto.createHash('sha256').update("test-commitment").digest('hex') - // All the nodes at index [8, 9, 10, 11, 12, 13, 14] have the zero value - let expectedValueOtherNodesLayer3 = Buffer.from(new Uint8Array(32)).toString('hex'); - - // --- Layer 2 --- // - // The value of node3 - let expectedValueNode3 = crypto.createHash('sha256'). - update(Buffer.from(expectedValueNode7 + expectedValueOtherNodesLayer3, 'hex')). - digest('hex'); - // All the nodes at index [4,5,6] have the same value (= sha256(initialValueLeftNodeLayer3 || initialValueRightNodeLayer3)) - let expectedValueOtherNodesLayer2 = crypto.createHash('sha256'). - update(Buffer.from(expectedValueOtherNodesLayer3 + expectedValueOtherNodesLayer3, 'hex')). - digest('hex'); - - // --- Layer 1 --- // - // The value of node 1 - let expectedValueNode1 = crypto.createHash('sha256'). - update(Buffer.from(expectedValueNode3 + expectedValueOtherNodesLayer2, 'hex')). - digest('hex'); - // The value of node 2 - let expectedValueNode2 = crypto.createHash('sha256'). - update(Buffer.from(expectedValueOtherNodesLayer2 + expectedValueOtherNodesLayer2, 'hex')). - digest('hex'); - - // --- Layer 0 - Root --- // - // The value of the root node at index [0] (= sha256(value node 1(Left) || value node 2(Right))) - let expectedValueNodeLayer0 = crypto.createHash('sha256'). - update(Buffer.from(expectedValueNode1 + expectedValueNode2, 'hex')). - digest('hex'); - - // --- Insertion of the commitment at the left most free leaf (Leaf 7 here) --- // - let addressInsertion = await instance.insert("0x" + expectedValueNode7); - - // --- Assert to verify that the new merkle tree has the expected values --- // - let actualInitialTree = await instance.getTree(); - console.log("(Layer3-Location of insertion) Node7 => " + actualInitialTree[7]); - assert.equal( - prefixHexadecimalString(expectedValueNode7), actualInitialTree[7], - "Mismatch between actual and expected value for node (7) of Layer3" - ); - for(var i = 8; i < actualInitialTree.length; i++) { - console.log("(Layer3-Leaves) Node" + i + " => " + actualInitialTree[i]); - assert.equal( - prefixHexadecimalString(expectedValueOtherNodesLayer3), actualInitialTree[i], - "Mismatch between actual and expected value for node (" + i + ") of Layer3" - ); - } - - console.log("(Layer2-Parent of inserted commitment) Node3 => " + actualInitialTree[3]); - assert.equal( - prefixHexadecimalString(expectedValueNode3), actualInitialTree[3], - "Mismatch between actual and expected value for node (3) of Layer2" - ); - for(var i = 4; i < 7; i++) { - console.log("(Layer2) Node" + i + " => " + actualInitialTree[i]); - assert.equal( - prefixHexadecimalString(expectedValueOtherNodesLayer2), actualInitialTree[i], - "Mismatch between actual and expected value for node (" + i + ") of Layer2" - ); - } - - console.log("(Layer1-Grand Parent of inserted commitment) Node1 => " + actualInitialTree[1]); - assert.equal( - prefixHexadecimalString(expectedValueNode1), actualInitialTree[1], - "Mismatch between actual and expected value for node (1) of Layer1" - ); - console.log("(Layer1) Node 2 => " + actualInitialTree[2]); - assert.equal( - prefixHexadecimalString(expectedValueNode2), actualInitialTree[2], - "Mismatch between actual and expected value for node (2) of Layer1" - ); - - console.log("(Layer0-Root) Node 0 => " + actualInitialTree[0]); - assert.equal( - prefixHexadecimalString(expectedValueNodeLayer0), actualInitialTree[0], - "Mismatch between actual and expected value for node (0) of Layer0-Root" - ); - }); -}); From 4e863a047e3e8dad48d23c9ec07865afd4f04678 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Fri, 23 Apr 2021 15:52:21 +0100 Subject: [PATCH 111/137] Refined coding standards and cascaded changes to the code base --- CODING_STANDARDS.md | 12 +- .../test_contracts/test_bls12_377_contract.py | 12 +- .../test_contracts/test_bw6_761_contract.py | 12 +- .../test_groth16_altbn128_mixer_base.py | 10 +- .../test_groth16_bls12_377_contract.py | 4 +- .../test_merkle_tree_contract.py | 6 +- client/test_contracts/test_mimc_contract.py | 4 +- client/zeth/core/constants.py | 2 +- client/zeth/core/mixer_client.py | 2 +- zeth_contracts/contracts/BaseMerkleTree.sol | 80 +++--- .../{MixerBase.sol => BaseMixer.sol} | 232 +++++++++--------- ...128MixerBase.sol => BaseMixerAltBN128.sol} | 44 ++-- ...77MixerBase.sol => BaseMixerBLS12_377.sol} | 48 ++-- .../contracts/Groth16AltBN128Mixer.sol | 39 --- ...oth16AltBN128.sol => LGroth16AltBN128.sol} | 19 +- ...h16BLS12_377.sol => LGroth16BLS12_377.sol} | 4 +- .../contracts/{MiMC31.sol => LMiMC31.sol} | 6 +- .../contracts/{MiMC7.sol => LMiMC7.sol} | 4 +- ...orrVerifier.sol => LOTSchnorrVerifier.sol} | 26 +- .../contracts/{Pairing.sol => LPairing.sol} | 26 +- .../contracts/MixerGroth16AltBN128.sol | 39 +++ ...377Mixer.sol => MixerGroth16BLS12_377.sol} | 20 +- .../contracts/MixerPghr13AltBN128.sol | 189 ++++++++++++++ .../contracts/Pghr13AltBN128Mixer.sol | 189 -------------- .../{BLS12_377_test.sol => TestBLS12_377.sol} | 28 +-- .../{BW6_761_test.sol => TestBW6_761.sol} | 30 +-- ...ase_test.sol => TestBaseMixerAltBN128.sol} | 38 +-- ..._377_test.sol => TestGroth16BLS12_377.sol} | 6 +- ...MiMC7_test.sol => TestMerkleTreeMiMC7.sol} | 16 +- .../contracts/{MiMC_test.sol => TestMiMC.sol} | 14 +- 30 files changed, 588 insertions(+), 573 deletions(-) rename zeth_contracts/contracts/{MixerBase.sol => BaseMixer.sol} (69%) rename zeth_contracts/contracts/{AltBN128MixerBase.sol => BaseMixerAltBN128.sol} (59%) rename zeth_contracts/contracts/{BLS12_377MixerBase.sol => BaseMixerBLS12_377.sol} (58%) delete mode 100644 zeth_contracts/contracts/Groth16AltBN128Mixer.sol rename zeth_contracts/contracts/{Groth16AltBN128.sol => LGroth16AltBN128.sol} (94%) rename zeth_contracts/contracts/{Groth16BLS12_377.sol => LGroth16BLS12_377.sol} (99%) rename zeth_contracts/contracts/{MiMC31.sol => LMiMC31.sol} (95%) rename zeth_contracts/contracts/{MiMC7.sol => LMiMC7.sol} (96%) rename zeth_contracts/contracts/{OTSchnorrVerifier.sol => LOTSchnorrVerifier.sol} (80%) rename zeth_contracts/contracts/{Pairing.sol => LPairing.sol} (93%) create mode 100644 zeth_contracts/contracts/MixerGroth16AltBN128.sol rename zeth_contracts/contracts/{Groth16BLS12_377Mixer.sol => MixerGroth16BLS12_377.sol} (56%) create mode 100644 zeth_contracts/contracts/MixerPghr13AltBN128.sol delete mode 100644 zeth_contracts/contracts/Pghr13AltBN128Mixer.sol rename zeth_contracts/contracts/{BLS12_377_test.sol => TestBLS12_377.sol} (65%) rename zeth_contracts/contracts/{BW6_761_test.sol => TestBW6_761.sol} (55%) rename zeth_contracts/contracts/{Groth16AltBN128MixerBase_test.sol => TestBaseMixerAltBN128.sol} (53%) rename zeth_contracts/contracts/{Groth16BLS12_377_test.sol => TestGroth16BLS12_377.sol} (73%) rename zeth_contracts/contracts/{MerkleTreeMiMC7_test.sol => TestMerkleTreeMiMC7.sol} (78%) rename zeth_contracts/contracts/{MiMC_test.sol => TestMiMC.sol} (62%) diff --git a/CODING_STANDARDS.md b/CODING_STANDARDS.md index 987cfefc0..2a8ba9e03 100644 --- a/CODING_STANDARDS.md +++ b/CODING_STANDARDS.md @@ -15,7 +15,17 @@ We adhere to the `pep8` standard, using `flake8`, `pylint` and `mypy` to catch f ## Solidity -As of now, the solidity code does not follow consistent style conventions. Nevertheless, new solidity code must adhere to the [solidity coding standards](https://docs.soliditylang.org/en/develop/style-guide.html). Old code will progressively be updated to converge towards the recommended style. +Solidity code must adhere to the [solidity coding standards](https://docs.soliditylang.org/en/develop/style-guide.html), with the following amendments: +- Test functions must end with the suffix `Test` (e.g. `reverseBytesTest`) +- Private/internal state variables and functions must have an underscore prefix (e.g. `_myInternalFunction`) +- Function parameters must not be prefixed with an underscore +- Interface names must have a capital I prefix (e.g. `IERC20`) +- Library names must have a capital L prefix (e.g. `LPairing`) +- Test contract names must have a `Test` prefix (e.g. `TestMyContract`) +- Event names must be prefixed by `Log` (e.g. `LogDeposit`) +- Contract names may not be PascalCase if using PascalCase is introducing confusions in the name (e.g. `BLS12377.sol` vs `BLS12_377.sol`). PascalCase should be used whenever possible + +**Note:** Some of the files of the current code base may not fully comply with the coding standards above. Old code will progressively be updated to converge towards the recommended style. ## C++ diff --git a/client/test_contracts/test_bls12_377_contract.py b/client/test_contracts/test_bls12_377_contract.py index 77e333c29..145657b9d 100644 --- a/client/test_contracts/test_bls12_377_contract.py +++ b/client/test_contracts/test_bls12_377_contract.py @@ -82,12 +82,12 @@ class TestBLS12_377Contract(TestCase): @staticmethod def setUpClass() -> None: - print("Deploying BLS12_377_test.sol") + print("Deploying TestBLS12_377.sol") _web3, eth = mock.open_test_web3() _bls12_interface, bls12_instance = mock.deploy_contract( eth, eth.accounts[0], - "BLS12_377_test", + "TestBLS12_377", {}) global BLS12_INSTANCE # pylint: disable=global-statement BLS12_INSTANCE = bls12_instance @@ -96,14 +96,14 @@ def test_bls12_ecadd(self) -> None: """ Check that [6] == [2] + [4] """ - result = BLS12_INSTANCE.functions.testECAdd(G1_2 + G1_4).call() + result = BLS12_INSTANCE.functions.ecAddTest(G1_2 + G1_4).call() self.assertEqual(G1_6, result) def test_bls12_ecmul(self) -> None: """ Check that [-8] == -2 * [4] """ - result = BLS12_INSTANCE.functions.testECMul(G1_4 + FR_MINUS_2).call() + result = BLS12_INSTANCE.functions.ecMulTest(G1_4 + FR_MINUS_2).call() self.assertEqual(G1_MINUS_8, result) def test_bls12_ecpairing(self) -> None: @@ -113,9 +113,9 @@ def test_bls12_ecpairing(self) -> None: # Note, return result here is uint256(1) or uint256(0) depending on the # pairing check result. points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_8 - result = BLS12_INSTANCE.functions.testECPairing(points).call() + result = BLS12_INSTANCE.functions.ecPairingTest(points).call() self.assertEqual(1, result) points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_4 - result = BLS12_INSTANCE.functions.testECPairing(points).call() + result = BLS12_INSTANCE.functions.ecPairingTest(points).call() self.assertEqual(0, result) diff --git a/client/test_contracts/test_bw6_761_contract.py b/client/test_contracts/test_bw6_761_contract.py index ba35a6d16..445e7f32f 100644 --- a/client/test_contracts/test_bw6_761_contract.py +++ b/client/test_contracts/test_bw6_761_contract.py @@ -88,12 +88,12 @@ class TestBW6_761Contract(TestCase): @staticmethod def setUpClass() -> None: - print("Deploying BW6_761_test.sol") + print("Deploying TestBW6_761.sol") _web3, eth = mock.open_test_web3() _bw6_interface, bw6_instance = mock.deploy_contract( eth, eth.accounts[0], - "BW6_761_test", + "TestBW6_761", {}) global BW6_INSTANCE # pylint: disable=global-statement BW6_INSTANCE = bw6_instance @@ -102,14 +102,14 @@ def test_bw6_ecadd(self) -> None: """ Check that [6] == [2] + [4] """ - result = BW6_INSTANCE.functions.testECAdd(G1_2 + G1_4).call() + result = BW6_INSTANCE.functions.ecAddTest(G1_2 + G1_4).call() self.assertEqual(G1_6, result) def test_bw6_ecmul(self) -> None: """ Check that [-8] == -2 * [4] """ - result = BW6_INSTANCE.functions.testECMul(G1_4 + FR_MINUS_2).call() + result = BW6_INSTANCE.functions.ecMulTest(G1_4 + FR_MINUS_2).call() self.assertEqual(G1_MINUS_8, result) def test_bw6_ecpairing(self) -> None: @@ -119,9 +119,9 @@ def test_bw6_ecpairing(self) -> None: # Note, return result here is uint256(1) or uint256(0) depending on the # pairing check result. points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_8 - result = BW6_INSTANCE.functions.testECPairing(points).call() + result = BW6_INSTANCE.functions.ecPairingTest(points).call() self.assertEqual(1, result) points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_4 - result = BW6_INSTANCE.functions.testECPairing(points).call() + result = BW6_INSTANCE.functions.ecPairingTest(points).call() self.assertEqual(0, result) diff --git a/client/test_contracts/test_groth16_altbn128_mixer_base.py b/client/test_contracts/test_groth16_altbn128_mixer_base.py index e9a4eefbc..152f015c7 100644 --- a/client/test_contracts/test_groth16_altbn128_mixer_base.py +++ b/client/test_contracts/test_groth16_altbn128_mixer_base.py @@ -174,17 +174,17 @@ class TestGroth16AltBN128MixerBaseContract(TestCase): @staticmethod def setUpClass() -> None: - print("Deploying AltBN128MixerBase_test.sol") + print("Deploying TestBaseMixerAltBN128.sol") web3, eth = mock.open_test_web3() deployer_eth_address = eth.accounts[0] _mixer_interface, mixer_instance = mock.deploy_contract( eth, deployer_eth_address, - "Groth16AltBN128MixerBase_test", + "TestBaseMixerAltBN128", { - 'mk_depth': ZETH_MERKLE_TREE_DEPTH, - 'permitted_dispatcher': deployer_eth_address, - 'vk_hash': VK_HASH, + 'mkDepth': ZETH_MERKLE_TREE_DEPTH, + 'permittedDispatcher': deployer_eth_address, + 'vkHash': VK_HASH, }) global WEB3 # pylint: disable=global-statement diff --git a/client/test_contracts/test_groth16_bls12_377_contract.py b/client/test_contracts/test_groth16_bls12_377_contract.py index b209795d4..2bd6da598 100644 --- a/client/test_contracts/test_groth16_bls12_377_contract.py +++ b/client/test_contracts/test_groth16_bls12_377_contract.py @@ -74,8 +74,8 @@ def setUpClass() -> None: contracts_dir = get_contracts_dir() contract_instance_desc = InstanceDescription.deploy( web3, - join(contracts_dir, "Groth16BLS12_377_test.sol"), - "Groth16BLS12_377_test", + join(contracts_dir, "TestGroth16BLS12_377.sol"), + "TestGroth16BLS12_377", web3.eth.accounts[0], # pylint: disable=no-member None, 500000, diff --git a/client/test_contracts/test_merkle_tree_contract.py b/client/test_contracts/test_merkle_tree_contract.py index 98592ff87..2aa9d859f 100644 --- a/client/test_contracts/test_merkle_tree_contract.py +++ b/client/test_contracts/test_merkle_tree_contract.py @@ -44,7 +44,7 @@ def setUpClass() -> None: _mktree_interface, mktree_instance = mock.deploy_contract( eth, deployer_eth_address, - "MerkleTreeMiMC7_test", + "TestMerkleTreeMiMC7", {'treeDepth': ZETH_MERKLE_TREE_DEPTH}) global MKTREE_INSTANCE # pylint: disable=global-statement MKTREE_INSTANCE = mktree_instance @@ -52,7 +52,7 @@ def setUpClass() -> None: def test_tree_empty(self) -> None: mktree = MerkleTree.empty_with_depth(ZETH_MERKLE_TREE_DEPTH, MiMC7()) expected_root = mktree.recompute_root() - root = MKTREE_INSTANCE.functions.testAddLeaves([], []).call() + root = MKTREE_INSTANCE.functions.addLeavesTest([], []).call() self.assertEqual(expected_root, root, "test_tree_empty") def _test_partial(self, num_entries: int, step: int = 1) -> None: @@ -72,7 +72,7 @@ def _test_partial(self, num_entries: int, step: int = 1) -> None: print(f"_test_partial: num_entries={num_entries}, cut={cut}") first = leaves[:cut] second = leaves[cut:] - root = MKTREE_INSTANCE.functions.testAddLeaves(first, second).call() + root = MKTREE_INSTANCE.functions.addLeavesTest(first, second).call() self.assertEqual( expected_root, root, diff --git a/client/test_contracts/test_mimc_contract.py b/client/test_contracts/test_mimc_contract.py index 9031eefe7..8bf3e2161 100644 --- a/client/test_contracts/test_mimc_contract.py +++ b/client/test_contracts/test_mimc_contract.py @@ -21,8 +21,8 @@ def setUpClass() -> None: contracts_dir = get_contracts_dir() contract_instance_desc = InstanceDescription.deploy( web3, - join(contracts_dir, "MiMC_test.sol"), - "MiMC_test", + join(contracts_dir, "TestMiMC.sol"), + "TestMiMC", web3.eth.accounts[0], # pylint: disable=no-member None, 500000, diff --git a/client/zeth/core/constants.py b/client/zeth/core/constants.py index bc40d5dff..8c577f31a 100644 --- a/client/zeth/core/constants.py +++ b/client/zeth/core/constants.py @@ -56,7 +56,7 @@ def bit_length_to_byte_length(bit_length: int) -> int: # Public value length (v_pub_in and v_pub_out) PUBLIC_VALUE_LENGTH: int = 64 PUBLIC_VALUE_LENGTH_BYTES: int = bit_length_to_byte_length(PUBLIC_VALUE_LENGTH) -PUBLIC_VALUE_MASK: int = (1 << PUBLIC_VALUE_LENGTH) - 1 +_PUBLIC_VALUE_MASK: int = (1 << PUBLIC_VALUE_LENGTH) - 1 PHI_LENGTH: int = 256 PHI_LENGTH_BYTES: int = bit_length_to_byte_length(PHI_LENGTH) diff --git a/client/zeth/core/mixer_client.py b/client/zeth/core/mixer_client.py index 5cc0dd8b0..ede66d619 100644 --- a/client/zeth/core/mixer_client.py +++ b/client/zeth/core/mixer_client.py @@ -709,7 +709,7 @@ def joinsplit_sign( zksnark, pp, extproof, public_data) # If for_dispatch_call is set, omit proof from the signature. See - # MixerBase.sol. + # BaseMixer.sol. if not for_dispatch_call: h.update(proof_bytes) diff --git a/zeth_contracts/contracts/BaseMerkleTree.sol b/zeth_contracts/contracts/BaseMerkleTree.sol index 27963b693..658a04abf 100644 --- a/zeth_contracts/contracts/BaseMerkleTree.sol +++ b/zeth_contracts/contracts/BaseMerkleTree.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.0; /// Abstract Merkle tree implementation. Child classes should implement the -/// hash function. +/// _hash function. /// /// The Merkle tree implementation must trade-off complexity, storage, /// initialization cost, and update & root computation cost. @@ -17,32 +17,32 @@ abstract contract BaseMerkleTree { // Depth of the merkle tree (should be set with the same depth set in the // cpp prover) - uint256 internal constant DEPTH = 32; + uint256 internal constant _DEPTH = 32; - // Number of leaves - uint256 internal constant MAX_NUM_LEAVES = 2**DEPTH; + // Maximum number of leaves in the tree + uint256 internal constant _MAX_NUM_LEAVES = 2**_DEPTH; - // Number of nodes - uint256 internal constant MAX_NUM_NODES = (MAX_NUM_LEAVES * 2) - 1; + // Maximum number of nodes in the tree + uint256 internal constant _MAX_NUM_NODES = (_MAX_NUM_LEAVES * 2) - 1; - uint256 internal constant MASK_LS_BIT = ~uint256(1); + uint256 internal constant _MASK_LS_BIT = ~uint256(1); - bytes32 internal constant DEFAULT_LEAF_VALUE = 0x0; + bytes32 internal constant _DEFAULT_LEAF_VALUE = 0x0; // Sparse array of populated leaves of the merkle tree. - // Unpopulated leaves have the DEFAULT_LEAF_VALUE. - bytes32[MAX_NUM_NODES] internal nodes; + // Unpopulated leaves have the _DEFAULT_LEAF_VALUE. + bytes32[_MAX_NUM_NODES] internal _nodes; - // Number of leaves populated in `nodes`. - uint256 internal numLeaves; + // Number of leaves populated in `_nodes`. + uint256 internal _numLeaves; /// Constructor constructor(uint256 treeDepth) { require ( - treeDepth == DEPTH, + treeDepth == _DEPTH, "Invalid depth in BaseMerkleTree" ); - initializeTree(); + _initializeTree(); } /// Appends a commitment to the tree, and returns its address @@ -50,55 +50,55 @@ abstract contract BaseMerkleTree // If this require fails => the merkle tree is full, we can't append // leaves anymore. require( - numLeaves < MAX_NUM_LEAVES, + _numLeaves < _MAX_NUM_LEAVES, "Merkle tree full: Cannot append anymore" ); // Address of the next leaf is the current number of leaves (before // insertion). Compute the next index in the full set of nodes, and // write. - uint256 next_address = numLeaves; - ++numLeaves; - uint256 next_entry_idx = (MAX_NUM_LEAVES - 1) + next_address; - nodes[next_entry_idx] = commitment; + uint256 next_address = _numLeaves; + ++_numLeaves; + uint256 next_entry_idx = (_MAX_NUM_LEAVES - 1) + next_address; + _nodes[next_entry_idx] = commitment; } - /// Abstract hash function to be supplied by a concrete implementation of + /// Abstract _hash function to be supplied by a concrete implementation of /// this class. - function hash(bytes32 left, bytes32 right) + function _hash(bytes32 left, bytes32 right) internal virtual returns (bytes32); - function recomputeRoot(uint numNewLeaves) internal returns (bytes32) { + function _recomputeRoot(uint numNewLeaves) internal returns (bytes32) { // Assume `numNewLeaves` have been written into the leaf slots. // Update any affected nodes in the tree, up to the root, using the // default values for any missing nodes. - uint256 end_idx = numLeaves; - uint256 start_idx = numLeaves - numNewLeaves; - uint256 layer_size = MAX_NUM_LEAVES; + uint256 end_idx = _numLeaves; + uint256 start_idx = _numLeaves - numNewLeaves; + uint256 layer_size = _MAX_NUM_LEAVES; while (layer_size > 1) { (start_idx, end_idx) = - recomputeParentLayer(layer_size, start_idx, end_idx); + _recomputeParentLayer(layer_size, start_idx, end_idx); layer_size = layer_size / 2; } - return nodes[0]; + return _nodes[0]; } - function initializeTree() private { + function _initializeTree() private { // First layer - bytes32 default_value = DEFAULT_LEAF_VALUE; - nodes[2 * MAX_NUM_LEAVES - 2] = default_value; - uint256 layer_size = MAX_NUM_LEAVES / 2; + bytes32 default_value = _DEFAULT_LEAF_VALUE; + _nodes[2 * _MAX_NUM_LEAVES - 2] = default_value; + uint256 layer_size = _MAX_NUM_LEAVES / 2; // Subsequent layers while (layer_size > 0) { - default_value = hash(default_value, default_value); + default_value = _hash(default_value, default_value); uint256 layer_final_entry_idx = 2 * layer_size - 2; - nodes[layer_final_entry_idx] = default_value; + _nodes[layer_final_entry_idx] = default_value; layer_size = layer_size / 2; } } @@ -118,7 +118,7 @@ abstract contract BaseMerkleTree /// /// Returns the start and end indices (within the parent layer) of touched /// parent nodes. - function recomputeParentLayer( + function _recomputeParentLayer( uint256 childLayerSize, uint256 childStartIdx, uint256 childEndIdx @@ -131,10 +131,10 @@ abstract contract BaseMerkleTree // Start at the right and iterate left, so we only execute the // default_value logic once. child_left_idx_rend (reverse-end) is the // smallest value of child_left_idx at which we should recompute the - // parent node hash. + // parent node _hash. uint256 child_left_idx_rend = - child_layer_start + (childStartIdx & MASK_LS_BIT); + child_layer_start + (childStartIdx & _MASK_LS_BIT); // If childEndIdx is odd, it is the RIGHT of a computation we need // to make. Do the computation using the default value, and move to @@ -144,8 +144,8 @@ abstract contract BaseMerkleTree uint256 child_left_idx; if ((childEndIdx & 1) != 0) { child_left_idx = child_layer_start + childEndIdx - 1; - nodes[(child_left_idx - 1) / 2] = - hash(nodes[child_left_idx], nodes[2 * child_layer_start]); + _nodes[(child_left_idx - 1) / 2] = + _hash(_nodes[child_left_idx], _nodes[2 * child_layer_start]); } else { child_left_idx = child_layer_start + childEndIdx; } @@ -155,8 +155,8 @@ abstract contract BaseMerkleTree while (child_left_idx > child_left_idx_rend) { child_left_idx = child_left_idx - 2; - nodes[(child_left_idx - 1) / 2] = - hash(nodes[child_left_idx], nodes[child_left_idx + 1]); + _nodes[(child_left_idx - 1) / 2] = + _hash(_nodes[child_left_idx], _nodes[child_left_idx + 1]); } return (childStartIdx / 2, (childEndIdx + 1) / 2); diff --git a/zeth_contracts/contracts/MixerBase.sol b/zeth_contracts/contracts/BaseMixer.sol similarity index 69% rename from zeth_contracts/contracts/MixerBase.sol rename to zeth_contracts/contracts/BaseMixer.sol index 6f6f848e6..fd53b7093 100644 --- a/zeth_contracts/contracts/MixerBase.sol +++ b/zeth_contracts/contracts/BaseMixer.sol @@ -5,12 +5,12 @@ pragma solidity ^0.8.0; import "./Tokens.sol"; -import "./OTSchnorrVerifier.sol"; +import "./LOTSchnorrVerifier.sol"; import "./BaseMerkleTree.sol"; -/// MixerBase implements the functions shared across all Mixers (regardless +/// BaseMixer implements the functions shared across all Mixers (regardless /// which zkSNARK is used) -abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract +abstract contract BaseMixer is BaseMerkleTree, ERC223ReceivingContract { // The roots of the different updated trees mapping(bytes32 => bool) private _roots; @@ -40,51 +40,53 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // IMPORTANT NOTE: We need to employ the same JS configuration than the one // used in the cpp prover. Here we use 2 inputs and 2 outputs (it is a 2-2 // JS). - uint256 internal constant JSIN = 2; // Number of nullifiers - uint256 internal constant JSOUT = 2; // Number of commitments/ciphertexts + uint256 internal constant _JSIN = 2; // Number of nullifiers + uint256 internal constant _JSOUT = 2; // Number of commitments/ciphertexts // Size of the public values in bits - uint256 internal constant PUBLIC_VALUE_BITS = 64; + uint256 internal constant _PUBLIC_VALUE_BITS = 64; // Public values mask - uint256 internal constant PUBLIC_VALUE_MASK = (1 << PUBLIC_VALUE_BITS) - 1; + uint256 internal constant _PUBLIC_VALUE_MASK = + (1 << _PUBLIC_VALUE_BITS) - 1; // Total number of bits for public values. Digest residual bits appear // after these. - uint256 internal constant TOTAL_PUBLIC_VALUE_BITS = 2 * PUBLIC_VALUE_BITS; + uint256 internal constant _TOTAL_PUBLIC_VALUE_BITS = + 2 * _PUBLIC_VALUE_BITS; - uint256 internal constant DIGEST_LENGTH = 256; + uint256 internal constant _DIGEST_LENGTH = 256; // Number of hash digests in the primary inputs: // 1 (the root) - // 2 * JSIN (nullifier and message auth tag per JS input) - // JSOUT (commitment per JS output) - uint256 internal constant NUM_HASH_DIGESTS = 1 + 2 * JSIN; + // 2 * _JSIN (nullifier and message auth tag per JS input) + // _JSOUT (commitment per JS output) + uint256 internal constant _NUM_HASH_DIGESTS = 1 + 2 * _JSIN; // All code assumes that public values and residual bits can be encoded in // a single field element. - uint256 internal constant NUM_FIELD_RESIDUAL = 1; + uint256 internal constant _NUM_FIELD_RESIDUAL = 1; // The number of public inputs are: // - 1 (the root) - // - JSIN (the nullifiers) - // - JSOUT (the commitments) + // - _JSIN (the nullifiers) + // - _JSOUT (the commitments) // - 1 (hsig) // - JsIn (the message auth. tags) - // - NUM_FIELD_RESIDUAL (the residual bits not fitting in a single field + // - _NUM_FIELD_RESIDUAL (the residual bits not fitting in a single field // element and the in and out public values) - uint256 internal constant NUM_INPUTS = - 1 + JSOUT + NUM_HASH_DIGESTS + NUM_FIELD_RESIDUAL; + uint256 internal constant _NUM_INPUTS = + 1 + _JSOUT + _NUM_HASH_DIGESTS + _NUM_FIELD_RESIDUAL; // The unit used for public values (ether in and out), in Wei. Must match // the python wrappers. Use Szabos (10^12 Wei). - uint64 internal constant PUBLIC_UNIT_VALUE_WEI = 1e12; + uint64 internal constant _PUBLIC_UNIT_VALUE_WEI = 1e12; event LogMix( bytes32 root, - bytes32[JSIN] nullifiers, - bytes32[JSOUT] commitments, - bytes[JSOUT] ciphertexts + bytes32[_JSIN] nullifiers, + bytes32[_JSOUT] commitments, + bytes[_JSOUT] ciphertexts ); /// Debug only @@ -93,19 +95,19 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract /// Constructor constructor( uint256 depth, - address token_address, + address tokenAddress, uint256[] memory vk, - address permitted_dispatcher, - uint256[2] memory vk_hash + address permittedDispatcher, + uint256[2] memory vkHash ) BaseMerkleTree(depth) { - bytes32 initialRoot = nodes[0]; + bytes32 initialRoot = _nodes[0]; _roots[initialRoot] = true; _vk = vk; - _token = token_address; - _permittedDispatcher = permitted_dispatcher; - _vkHash = vk_hash; + _token = tokenAddress; + _permittedDispatcher = permittedDispatcher; + _vkHash = vkHash; } /// Function allowing external users of the contract to retrieve some of @@ -120,14 +122,14 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract external pure returns ( - uint256 js_in_out, - uint256 js_out_out, - uint256 num_inputs_out + uint256 jsinOut, + uint256 jsoutOut, + uint256 numinputsOut ) { - js_in_out = JSIN; - js_out_out = JSOUT; - num_inputs_out = NUM_INPUTS; + jsinOut = _JSIN; + jsoutOut = _JSOUT; + numinputsOut = _NUM_INPUTS; } /// Permitted dispatchers may call this entry point if they have verified @@ -142,7 +144,7 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract external payable { - // Sanity / permission checkcheck + // Sanity / permission check require( msg.sender == _permittedDispatcher, "dispatcher not permitted"); require( @@ -159,33 +161,33 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract bytes[] memory decoded_ciphertexts) = abi.decode( nestedParameters, (uint256[4], uint256, uint256[], bytes[])); require( - public_data.length == NUM_INPUTS, + public_data.length == _NUM_INPUTS, "invalid number of public inputs in decoded data."); require( - decoded_ciphertexts.length == JSOUT, + decoded_ciphertexts.length == _JSOUT, "invalid number of ciphertexts in decoded data."); - bytes[JSOUT] memory ciphertexts; - for (uint256 i = 0 ; i < JSOUT ; ++i) { + bytes[_JSOUT] memory ciphertexts; + for (uint256 i = 0 ; i < _JSOUT ; ++i) { ciphertexts[i] = decoded_ciphertexts[i]; } // Copy the public inputs into a fixed-size array. // TODO: convert without copying. - uint256[NUM_INPUTS] memory inputs; - for (uint256 i = 0 ; i < NUM_INPUTS ; ++i) { + uint256[_NUM_INPUTS] memory inputs; + for (uint256 i = 0 ; i < _NUM_INPUTS ; ++i) { inputs[i] = public_data[i]; } // Ensure that the primary input to the zk-proof (validated and passed // in by the dispatcher), matches the hash of the public inputs. require( - nestedInputs[0] == hashPublicProofData(inputs), + nestedInputs[0] == _hashPublicProofData(inputs), "hash of public data does not match primary input"); // 1. Check the root and the nullifiers - bytes32[JSIN] memory nullifiers; - checkMkrootNullifiersHsigAppendNullifiersState( + bytes32[_JSIN] memory nullifiers; + _checkMkrootNullifiersHsigAppendNullifiersState( vk, inputs, nullifiers); // 2.a Verify the signature on the hash of data_to_be_signed. @@ -201,12 +203,12 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract ); require( - OTSchnorrVerifier.verify( + LOTSchnorrVerifier._verify( vk[0], vk[1], vk[2], vk[3], sigma, hashToBeSigned), "Invalid signature in dispatch" ); - mixAppendCommitmentsEmitAndHandlePublicValues( + _mixAppendCommitmentsEmitAndHandlePublicValues( inputs, ciphertexts, nullifiers); } @@ -218,15 +220,15 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract uint256[] memory proof, uint256[4] memory vk, uint256 sigma, - uint256[NUM_INPUTS] memory publicInputs, - bytes[JSOUT] memory ciphertexts + uint256[_NUM_INPUTS] memory publicInputs, + bytes[_JSOUT] memory ciphertexts ) external payable { // 1. Check the root and the nullifiers - bytes32[JSIN] memory nullifiers; - checkMkrootNullifiersHsigAppendNullifiersState( + bytes32[_JSIN] memory nullifiers; + _checkMkrootNullifiersHsigAppendNullifiersState( vk, publicInputs, nullifiers); // 2.a Verify the signature on the hash of data_to_be_signed @@ -243,36 +245,36 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract ) ); require( - OTSchnorrVerifier.verify( + LOTSchnorrVerifier._verify( vk[0], vk[1], vk[2], vk[3], sigma, hashToBeSigned), "Invalid signature: Unable to verify the signature correctly" ); // 2.b Verify the proof - uint256 publicInputsHash = hashPublicProofData(publicInputs); + uint256 publicInputsHash = _hashPublicProofData(publicInputs); require( - verifyZkProof(proof, publicInputsHash), + _verifyZkProof(proof, publicInputsHash), "Invalid proof: Unable to verify the proof correctly" ); - mixAppendCommitmentsEmitAndHandlePublicValues( + _mixAppendCommitmentsEmitAndHandlePublicValues( publicInputs, ciphertexts, nullifiers); } - function mixAppendCommitmentsEmitAndHandlePublicValues( - uint256[NUM_INPUTS] memory inputs, - bytes[JSOUT] memory ciphertexts, - bytes32[JSIN] memory nullifiers + function _mixAppendCommitmentsEmitAndHandlePublicValues( + uint256[_NUM_INPUTS] memory inputs, + bytes[_JSOUT] memory ciphertexts, + bytes32[_JSIN] memory nullifiers ) internal { // 3. Append the commitments to the tree - bytes32[JSOUT] memory commitments; - assembleCommitmentsAndAppendToState(inputs, commitments); + bytes32[_JSOUT] memory commitments; + _assembleCommitmentsAndAppendToState(inputs, commitments); // 4. Add the new root to the list of existing roots - bytes32 new_merkle_root = recomputeRoot(JSOUT); - addMerkleRoot(new_merkle_root); + bytes32 new_merkle_root = _recomputeRoot(_JSOUT); + _addMerkleRoot(new_merkle_root); // 5. Emit the all Mix data emit LogMix( @@ -284,10 +286,10 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // 6. Get the public values in Wei and modify the state depending on // their values - processPublicValues(inputs); + _processPublicValues(inputs); } - function hashPublicProofData(uint256[NUM_INPUTS] memory publicData) + function _hashPublicProofData(uint256[_NUM_INPUTS] memory publicData) internal returns (uint256) { @@ -297,16 +299,16 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract h = bytes32(uint256( // solhint-disable-next-line max-line-length 13196537064117388418196223856311987714388543839552400408340921397545324034315)); - for (uint256 i = 0 ; i < NUM_INPUTS; ++i) { - h = hash(h, bytes32(publicData[i])); + for (uint256 i = 0 ; i < _NUM_INPUTS; ++i) { + h = _hash(h, bytes32(publicData[i])); } - h = hash(h, bytes32(NUM_INPUTS)); + h = _hash(h, bytes32(_NUM_INPUTS)); return uint256(h); } /// This function is used to extract the public values (vpub_in, vpub_out) /// from the residual field element(S) - function assemblePublicValues(uint256 residualBits) + function _assemblePublicValues(uint256 residualBits) internal pure returns ( @@ -314,51 +316,53 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract uint256 vpub_out ) { - // vpub_out and vpub_in occupy the first and second PUBLIC_VALUE_BITS - vpub_out = (residualBits & PUBLIC_VALUE_MASK) * PUBLIC_UNIT_VALUE_WEI; - vpub_in = ((residualBits >> PUBLIC_VALUE_BITS) & PUBLIC_VALUE_MASK) - * PUBLIC_UNIT_VALUE_WEI; + // vpub_out and vpub_in occupy the first and second _PUBLIC_VALUE_BITS + vpub_out = + (residualBits & _PUBLIC_VALUE_MASK) * _PUBLIC_UNIT_VALUE_WEI; + vpub_in = ((residualBits >> _PUBLIC_VALUE_BITS) & _PUBLIC_VALUE_MASK) + * _PUBLIC_UNIT_VALUE_WEI; } /// This function is used to reassemble hsig given the primaryInputs. /// To do so, we extract the remaining bits of hsig from the residual field /// element(S) and combine them with the hsig field element - function assembleHsig( - uint256[NUM_INPUTS] memory primaryInputs + function _assembleHsig( + uint256[_NUM_INPUTS] memory primaryInputs ) internal pure returns(bytes32 hsig) { - // The h_sig residual bits are after the JSIN authentication tags and - // JSIN nullifier bits. - return extractBytes32( - primaryInputs[1 + JSIN + JSOUT], - primaryInputs[1 + JSOUT + NUM_HASH_DIGESTS], - 2 * JSIN + // The h_sig residual bits are after the _JSIN authentication tags and + // _JSIN nullifier bits. + return _extractBytes32( + primaryInputs[1 + _JSIN + _JSOUT], + primaryInputs[1 + _JSOUT + _NUM_HASH_DIGESTS], + 2 * _JSIN ); } /// This function is used to reassemble the nullifiers given the nullifier - /// index [0, JSIN[ and the primaryInputs To do so, we extract the + /// index [0, _JSIN[ and the primaryInputs To do so, we extract the /// remaining bits of the nullifier from the residual field element(S) and /// combine them with the nullifier field element - function assembleNullifier( + function _assembleNullifier( uint256 index, - uint256[NUM_INPUTS] memory primaryInputs + uint256[_NUM_INPUTS] memory primaryInputs ) internal pure returns(bytes32 nf) { // We first check that the nullifier we want to retrieve exists - require(index < JSIN, "nullifier index overflow"); - - // Nullifier residual bits follow the JSIN message authentication tags. - return extractBytes32( - primaryInputs[1 + JSOUT + index], - primaryInputs[1 + JSOUT + NUM_HASH_DIGESTS], - JSIN + index + require(index < _JSIN, "nullifier index overflow"); + + // Nullifier residual bits follow the `_JSIN` message authentication + // tags + return _extractBytes32( + primaryInputs[1 + _JSOUT + index], + primaryInputs[1 + _JSOUT + _NUM_HASH_DIGESTS], + _JSIN + index ); } @@ -373,15 +377,15 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // 0 // 1 // ... - // JSOUT - // JSOUT + 1 + // _JSOUT + // _JSOUT + 1 // ... - // JSOUT + JSIN - // JSOUT + JSIN + 1 - // JSOUT + JSIN + 2 + // _JSOUT + _JSIN + // _JSOUT + _JSIN + 1 + // _JSOUT + _JSIN + 2 // ... - // JSOUT + 2*JSIN + 1 - // JSOUT + 2*JSIN + 2 + // _JSOUT + 2*_JSIN + 1 + // _JSOUT + 2*_JSIN + 2 // // The Residual field elements are structured as follows: // @@ -396,7 +400,7 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // Utility function to extract a full uint256 from a field element and the // n-th set of residual bits from `residual`. This function is // curve-dependent. - function extractBytes32( + function _extractBytes32( uint256 fieldElement, uint256 residual, uint256 residualBitsSetIdx @@ -408,7 +412,7 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // Implementations must implement the verification algorithm of the // selected SNARK. - function verifyZkProof( + function _verifyZkProof( uint256[] memory proof, uint256 publicInputsHash ) @@ -420,10 +424,10 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract /// and nullifiers in the primary inputs (instance) and modifies the state /// of the mixer contract accordingly. (ie: Appends the commitments to the /// tree, appends the nullifiers to the list and so on). - function checkMkrootNullifiersHsigAppendNullifiersState( + function _checkMkrootNullifiersHsigAppendNullifiersState( uint256[4] memory vk, - uint256[NUM_INPUTS] memory primaryInputs, - bytes32[JSIN] memory nfs) + uint256[_NUM_INPUTS] memory primaryInputs, + bytes32[_JSIN] memory nfs) internal { // 1. We re-assemble the full root digest and check it is in the tree @@ -434,8 +438,8 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // 2. We re-assemble the nullifiers (JSInputs) and check they were not // already seen. - for (uint256 i = 0; i < JSIN; i++) { - bytes32 nullifier = assembleNullifier(i, primaryInputs); + for (uint256 i = 0; i < _JSIN; i++) { + bytes32 nullifier = _assembleNullifier(i, primaryInputs); require( !_nullifiers[nullifier], "Invalid nullifier: This nullifier has already been used" @@ -449,7 +453,7 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract // they are equal (i.e. that h_sig re-assembled was correctly generated // from vk). bytes32 expected_hsig = sha256(abi.encodePacked(nfs, vk)); - bytes32 hsig = assembleHsig(primaryInputs); + bytes32 hsig = _assembleHsig(primaryInputs); require( expected_hsig == hsig, "Invalid hsig: This hsig does not correspond to the hash of vk and" @@ -457,26 +461,26 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract ); } - function assembleCommitmentsAndAppendToState( - uint256[NUM_INPUTS] memory primaryInputs, - bytes32[JSOUT] memory comms + function _assembleCommitmentsAndAppendToState( + uint256[_NUM_INPUTS] memory primaryInputs, + bytes32[_JSOUT] memory comms ) internal { // We re-assemble the commitments (JSOutputs) - for (uint256 i = 0; i < JSOUT; i++) { + for (uint256 i = 0; i < _JSOUT; i++) { bytes32 current_commitment = bytes32(primaryInputs[1 + i]); comms[i] = current_commitment; insert(current_commitment); } } - function processPublicValues(uint256[NUM_INPUTS] memory primaryInputs) + function _processPublicValues(uint256[_NUM_INPUTS] memory primaryInputs) internal { // We get vpub_in and vpub_out in wei - (uint256 vpub_in, uint256 vpub_out) = assemblePublicValues( - primaryInputs[1 + JSOUT + NUM_HASH_DIGESTS]); + (uint256 vpub_in, uint256 vpub_out) = _assemblePublicValues( + primaryInputs[1 + _JSOUT + _NUM_HASH_DIGESTS]); // If the vpub_in is > 0, we need to make sure the right amount is paid if (vpub_in > 0) { @@ -512,7 +516,7 @@ abstract contract MixerBase is BaseMerkleTree, ERC223ReceivingContract } } - function addMerkleRoot(bytes32 root) internal + function _addMerkleRoot(bytes32 root) internal { _roots[root] = true; } diff --git a/zeth_contracts/contracts/AltBN128MixerBase.sol b/zeth_contracts/contracts/BaseMixerAltBN128.sol similarity index 59% rename from zeth_contracts/contracts/AltBN128MixerBase.sol rename to zeth_contracts/contracts/BaseMixerAltBN128.sol index 508ec4e95..9078b049a 100644 --- a/zeth_contracts/contracts/AltBN128MixerBase.sol +++ b/zeth_contracts/contracts/BaseMixerAltBN128.sol @@ -4,54 +4,54 @@ pragma solidity ^0.8.0; -import "./MixerBase.sol"; -import "./MiMC7.sol"; +import "./BaseMixer.sol"; +import "./LMiMC7.sol"; -/// Partial implementation of abstract MixerBase which implements the +/// Partial implementation of abstract BaseMixer which implements the /// curve-specific methods to use the ALT-BN128 pairing. -abstract contract AltBN128MixerBase is MixerBase +abstract contract BaseMixerAltBN128 is BaseMixer { - // Constants regarding the hash digest length, the prime number used and + // Constants regarding the _hash digest length, the prime number used and // its associated length in bits and the max values (v_in and v_out) // FIELD_CAPACITY = floor( log_2(r) ) - uint256 internal constant FIELD_CAPACITY = 253; + uint256 internal constant _FIELD_CAPACITY = 253; // Number of residual bits per bytes32 - uint256 internal constant NUM_RESIDUAL_BITS = - DIGEST_LENGTH - FIELD_CAPACITY; + uint256 internal constant _NUM_RESIDUAL_BITS = + _DIGEST_LENGTH - _FIELD_CAPACITY; // Shift to move residual bits from lowest order to highest order - uint256 internal constant RESIDUAL_BITS_SHIFT = 256 - NUM_RESIDUAL_BITS; + uint256 internal constant _RESIDUAL_BITS_SHIFT = 256 - _NUM_RESIDUAL_BITS; // Mask to extract the residual bits in the high-order position - uint256 internal constant RESIDUAL_BITS_MASK = - ((1 << NUM_RESIDUAL_BITS) - 1) << RESIDUAL_BITS_SHIFT; + uint256 internal constant _RESIDUAL_BITS_MASK = + ((1 << _NUM_RESIDUAL_BITS) - 1) << _RESIDUAL_BITS_SHIFT; /// Constructor of the contract constructor( - uint256 mk_depth, + uint256 mkDepth, address token, uint256[] memory vk, - address permitted_dispatcher, - uint256[2] memory vk_hash + address permittedDispatcher, + uint256[2] memory vkHash ) - MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) + BaseMixer(mkDepth, token, vk, permittedDispatcher, vkHash) { } - /// Use MiMC7 as the Merkle tree hash function. - function hash(bytes32 left, bytes32 right) + /// Use LMiMC7 as the Merkle tree _hash function. + function _hash(bytes32 left, bytes32 right) internal pure override returns(bytes32) { - return MiMC7.hash(left, right); + return LMiMC7._hash(left, right); } /// Utility function to extract a full uint256 from a field element and the /// n-th set of residual bits from `residual`. - function extractBytes32( + function _extractBytes32( uint256 fieldElement, uint256 residual, uint256 residualBitsSetIdx @@ -71,11 +71,11 @@ abstract contract AltBN128MixerBase is MixerBase // residual bits // Number of bits AFTER public values - uint256 residualBitsIdx = residualBitsSetIdx * NUM_RESIDUAL_BITS; + uint256 residualBitsIdx = residualBitsSetIdx * _NUM_RESIDUAL_BITS; uint256 bitsToShift = - RESIDUAL_BITS_SHIFT - TOTAL_PUBLIC_VALUE_BITS - residualBitsIdx; + _RESIDUAL_BITS_SHIFT - _TOTAL_PUBLIC_VALUE_BITS - residualBitsIdx; uint256 residualBits = - (residual << bitsToShift) & RESIDUAL_BITS_MASK; + (residual << bitsToShift) & _RESIDUAL_BITS_MASK; return bytes32(fieldElement | residualBits); } } diff --git a/zeth_contracts/contracts/BLS12_377MixerBase.sol b/zeth_contracts/contracts/BaseMixerBLS12_377.sol similarity index 58% rename from zeth_contracts/contracts/BLS12_377MixerBase.sol rename to zeth_contracts/contracts/BaseMixerBLS12_377.sol index 0d18d88fa..9729ef048 100644 --- a/zeth_contracts/contracts/BLS12_377MixerBase.sol +++ b/zeth_contracts/contracts/BaseMixerBLS12_377.sol @@ -4,60 +4,60 @@ pragma solidity ^0.8.0; -import "./MixerBase.sol"; -import "./MiMC31.sol"; +import "./BaseMixer.sol"; +import "./LMiMC31.sol"; -/// Partial implementation of abstract MixerBase which implements the +/// Partial implementation of abstract BaseMixer which implements the /// curve-specific methods to use the BLS12-377 pairing. -abstract contract BLS12_377MixerBase is MixerBase +abstract contract BaseMixerBLS12_377 is BaseMixer { - // TODO: Code here is very similar to AltBN128MixerBase, with only the + // TODO: Code here is very similar to BaseMixerAltBN128, with only the // constants changed. Look into sharing more code (possibly by making some // of these constants dynamic). - // Constants regarding the hash digest length, the prime number used and + // Constants regarding the _hash digest length, the prime number used and // its associated length in bits and the max values (v_in and v_out) // Number of bits that can be reliably represented by a single field // element: - // FIELD_CAPACITY = floor( log_2(r) ) + // _FIELD_CAPACITY = floor( log_2(r) ) // Denoted FIELDCAP in Zeth specifications. - uint256 internal constant FIELD_CAPACITY = 252; + uint256 internal constant _FIELD_CAPACITY = 252; // Number of residual bits per bytes32 - uint256 internal constant NUM_RESIDUAL_BITS = - DIGEST_LENGTH - FIELD_CAPACITY; + uint256 internal constant _NUM_RESIDUAL_BITS = + _DIGEST_LENGTH - _FIELD_CAPACITY; // Shift to move residual bits from lowest order to highest order - uint256 internal constant RESIDUAL_BITS_SHIFT = 256 - NUM_RESIDUAL_BITS; + uint256 internal constant _RESIDUAL_BITS_SHIFT = 256 - _NUM_RESIDUAL_BITS; // Mask to extract the residual bits in the high-order position - uint256 internal constant RESIDUAL_BITS_MASK = - ((1 << NUM_RESIDUAL_BITS) - 1) << RESIDUAL_BITS_SHIFT; + uint256 internal constant _RESIDUAL_BITS_MASK = + ((1 << _NUM_RESIDUAL_BITS) - 1) << _RESIDUAL_BITS_SHIFT; constructor( - uint256 mk_depth, + uint256 mkDepth, address token, uint256[] memory vk, - address permitted_dispatcher, - uint256[2] memory vk_hash + address permittedDispatcher, + uint256[2] memory vkHash ) - MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) + BaseMixer(mkDepth, token, vk, permittedDispatcher, vkHash) { } - function hash(bytes32 left, bytes32 right) + function _hash(bytes32 left, bytes32 right) internal pure override returns(bytes32) { - return MiMC31.hash(left, right); + return LMiMC31._hash(left, right); } /// Extract a full uint256 from a field element and the n-th set of /// residual bits from `residual`. - function extractBytes32( + function _extractBytes32( uint256 fieldElement, uint256 residual, uint256 residualBitsSetIdx @@ -69,7 +69,7 @@ abstract contract BLS12_377MixerBase is MixerBase { // The residualBitsSetIdx-th set of residual bits (denoted r_i // below) start at bit: - // (2*PUBLIC_VALUE_BITS) + (residualBitsSetIdx*num_residual_bits) + // (2*_PUBLIC_VALUE_BITS) + (residualBitsSetIdx*num_residual_bits) // // Shift r_i to occupy the highest order bits: // 255 128 64 0 @@ -77,11 +77,11 @@ abstract contract BLS12_377MixerBase is MixerBase // | <------------ || ||| // Number of bits AFTER public values - uint256 residualBitsIdx = residualBitsSetIdx * NUM_RESIDUAL_BITS; + uint256 residualBitsIdx = residualBitsSetIdx * _NUM_RESIDUAL_BITS; uint256 bitsToShift = - RESIDUAL_BITS_SHIFT - TOTAL_PUBLIC_VALUE_BITS - residualBitsIdx; + _RESIDUAL_BITS_SHIFT - _TOTAL_PUBLIC_VALUE_BITS - residualBitsIdx; uint256 residualBits = - (residual << bitsToShift) & RESIDUAL_BITS_MASK; + (residual << bitsToShift) & _RESIDUAL_BITS_MASK; return bytes32(fieldElement | residualBits); } } diff --git a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol b/zeth_contracts/contracts/Groth16AltBN128Mixer.sol deleted file mode 100644 index f7a871d7b..000000000 --- a/zeth_contracts/contracts/Groth16AltBN128Mixer.sol +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2015-2021 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -pragma solidity ^0.8.0; - -import "./AltBN128MixerBase.sol"; -import "./Groth16AltBN128.sol"; - -/// Instance of AltBN128MixerBase implementing the Groth16 verifier for the -/// alt-bn128 pairing. -contract Groth16AltBN128Mixer is AltBN128MixerBase -{ - constructor( - uint256 mk_depth, - address token, - uint256[] memory vk, - address permitted_dispatcher, - uint256[2] memory vk_hash - ) - AltBN128MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) - { - } - - function verifyZkProof( - uint256[] memory proof, - uint256 publicInputsHash - ) - internal - override - returns (bool) - { - // Convert the single primary input to a dynamic array - // expected by the verifier. - uint256[] memory input_values = new uint256[](1); - input_values[0] = publicInputsHash; - return Groth16AltBN128.verify(_vk, proof, input_values); - } -} diff --git a/zeth_contracts/contracts/Groth16AltBN128.sol b/zeth_contracts/contracts/LGroth16AltBN128.sol similarity index 94% rename from zeth_contracts/contracts/Groth16AltBN128.sol rename to zeth_contracts/contracts/LGroth16AltBN128.sol index 793ef858e..337cb8d6c 100644 --- a/zeth_contracts/contracts/Groth16AltBN128.sol +++ b/zeth_contracts/contracts/LGroth16AltBN128.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; -library Groth16AltBN128 +library LGroth16AltBN128 { // The structure of the verification key differs from the reference paper. // It doesn't contain any element of GT, but only elements of G1 and G2 @@ -14,7 +14,7 @@ library Groth16AltBN128 // contract code. // Used by client code to verify that inputs are in the correct field. - uint256 internal constant PRIME_R = + uint256 internal constant _PRIME_R = // solhint-disable-next-line max-line-length 21888242871839275222246405745257275088548364400416034343698204186575808495617; @@ -36,7 +36,7 @@ library Groth16AltBN128 // uint256[2] c, (offset 06 - 0x06) // (offset 08 - 0x08) - function verify( + function _verify( uint256[] storage vk, uint256[] memory proof, uint256[] memory input @@ -56,18 +56,18 @@ library Groth16AltBN128 // Ensure that all inputs belong to the scalar field. for (uint256 i = 0 ; i < numInputs; i++) { - require(input[i] < PRIME_R, "Input is not in scalar field"); + require(input[i] < _PRIME_R, "Input is not in scalar field"); } // 1. Compute the linear combination // vk_x = \sum_{i=0}^{l} a_i * vk.ABC[i], vk_x in G1. // // ORIGINAL CODE: - // Pairing.G1Point memory vk_x = vk.ABC[0]; // a_0 = 1 + // LPairing.G1Point memory vk_x = vk.ABC[0]; // a_0 = 1 // for (uint256 i = 0; i < input.length; i++) { // vk_x = - // Pairing.addG1(vk_x, - // Pairing.scalarMulG1(vk.ABC[i + 1], input[i])); + // LPairing._addG1(vk_x, + // LPairing._scalarMulG1(vk.ABC[i + 1], input[i])); // } // // The linear combination loop was the biggest cost center of the mixer @@ -169,8 +169,9 @@ library Groth16AltBN128 // e(vk_x, -g2) * e(vk.Alpha, vk.Minus_Beta) * // e(negate(Proof.A), Proof.B) * e(Proof.C, vk.Minus_Delta) == 1 // - // See Pairing.pairing(). Note terms have been re-ordered since vk_x is - // already at offset 0x00. Memory is laid out: + // See LPairing.pairing(). + // Note terms have been re-ordered since vk_x is already at offset + // 0x00. Memory is laid out: // // 0x0300 // 0x0280 - verifyKey.Minus_Delta in G2 diff --git a/zeth_contracts/contracts/Groth16BLS12_377.sol b/zeth_contracts/contracts/LGroth16BLS12_377.sol similarity index 99% rename from zeth_contracts/contracts/Groth16BLS12_377.sol rename to zeth_contracts/contracts/LGroth16BLS12_377.sol index 5782b28d3..6d8413d86 100644 --- a/zeth_contracts/contracts/Groth16BLS12_377.sol +++ b/zeth_contracts/contracts/LGroth16BLS12_377.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; -library Groth16BLS12_377 +library LGroth16BLS12_377 { // Fr elements occupy 1 uint256, and Fq elements occupy 2 uint256s. // Therefore G1 elements occupy 4 uint256s. G2 elements have coordinates in @@ -42,7 +42,7 @@ library Groth16BLS12_377 // uint256[4] c, // offset 0x0c (0x180 bytes) // // offset 0x10 (0x200 bytes) - function verify( + function _verify( uint256[] storage vk, uint256[] memory proof, uint256[] memory inputs diff --git a/zeth_contracts/contracts/MiMC31.sol b/zeth_contracts/contracts/LMiMC31.sol similarity index 95% rename from zeth_contracts/contracts/MiMC31.sol rename to zeth_contracts/contracts/LMiMC31.sol index 385a797e5..a4ec73b85 100644 --- a/zeth_contracts/contracts/MiMC31.sol +++ b/zeth_contracts/contracts/LMiMC31.sol @@ -23,10 +23,10 @@ pragma solidity ^0.8.0; /// e (exponent) = 31, so that e=2^t-1 (t=5) and 1 == gcd(e, r-1) /// rounds = 51 /// -/// See MiMC7.sol for details. -library MiMC31 +/// See LMiMC7.sol for details. +library LMiMC31 { - function hash(bytes32 x, bytes32 y) internal pure returns(bytes32 out) { + function _hash(bytes32 x, bytes32 y) internal pure returns(bytes32 out) { // Round function (see [AGRRT16]): // F_i(a, key, rc_i) -> (a + key + rc)^31 // diff --git a/zeth_contracts/contracts/MiMC7.sol b/zeth_contracts/contracts/LMiMC7.sol similarity index 96% rename from zeth_contracts/contracts/MiMC7.sol rename to zeth_contracts/contracts/LMiMC7.sol index 1ba199adf..4f74831b7 100644 --- a/zeth_contracts/contracts/MiMC7.sol +++ b/zeth_contracts/contracts/LMiMC7.sol @@ -16,9 +16,9 @@ pragma solidity ^0.8.0; /// Section: "Miyaguchi–Preneel" // solhint-disable-next-line max-line-length /// -library MiMC7 +library LMiMC7 { - function hash(bytes32 x, bytes32 y) internal pure returns (bytes32 out) { + function _hash(bytes32 x, bytes32 y) internal pure returns (bytes32 out) { // See [AGRRT16]: // The round function is: // F_i(a, key, rc_i) -> a^7 + key + rc diff --git a/zeth_contracts/contracts/OTSchnorrVerifier.sol b/zeth_contracts/contracts/LOTSchnorrVerifier.sol similarity index 80% rename from zeth_contracts/contracts/OTSchnorrVerifier.sol rename to zeth_contracts/contracts/LOTSchnorrVerifier.sol index 59d978915..f277d7a5a 100644 --- a/zeth_contracts/contracts/OTSchnorrVerifier.sol +++ b/zeth_contracts/contracts/LOTSchnorrVerifier.sol @@ -11,9 +11,9 @@ pragma solidity ^0.8.0; /// Mihir Bellare, Sarah Shoup, /// International Workshop on Public Key Cryptography, 2007, /// -library OTSchnorrVerifier { +library LOTSchnorrVerifier { - function verify( + function _verify( uint256 vk0, uint256 vk1, uint256 vk2, @@ -31,16 +31,16 @@ library OTSchnorrVerifier { // uint256 h = uint256(h_bytes); // // // X = g^{x}, where g represents a generator of the cyclic group G - // Pairing.G1Point memory X = Pairing.G1Point(vk[0], vk[1]); + // LPairing.G1Point memory X = LPairing.G1Point(vk[0], vk[1]); // // Y = g^{y} - // Pairing.G1Point memory Y = Pairing.G1Point(vk[2], vk[3]); + // LPairing.G1Point memory Y = LPairing.G1Point(vk[2], vk[3]); // // // S = g^{sigma} - // Pairing.G1Point memory S = Pairing.scalarMulG1( - // Pairing.genG1(), sigma); + // LPairing.G1Point memory S = LPairing._scalarMulG1( + // LPairing._genG1(), sigma); // // S_comp = g^{y + xh} - // Pairing.G1Point memory S_comp = Pairing.addG1(Y, - // Pairing.scalarMulG1(X, h)); + // LPairing.G1Point memory S_comp = LPairing._addG1(Y, + // LPairing._scalarMulG1(X, h)); // // // Check that g^{sigma} == g^{y + xh} // return (S.X == S_comp.X && S.Y == S_comp.Y); @@ -90,7 +90,7 @@ library OTSchnorrVerifier { // 0x40 // 0x20 (Y + h.X)[1] // 0x00 (Y + h.X)[0] - // copy genG1 and sigma (see Pairing.sol for values) + // copy _genG1 and sigma (see LPairing.sol for values) mstore(add(pad, 0x40), 1) mstore(add(pad, 0x60), 2) @@ -98,8 +98,8 @@ library OTSchnorrVerifier { // pad: // 0x80 sigma - // 0x60 genG1[1] - // 0x40 genG1[0] + // 0x60 _genG1[1] + // 0x40 _genG1[0] // 0x20 (Y + h.X)[1] // 0x00 (Y + h.X)[0] // call bn256ScalarMul(in: 0x40, out: 0x40) @@ -107,8 +107,8 @@ library OTSchnorrVerifier { pop(call(g, 7, 0, x_location, 0x60, x_location, 0x40)) // pad: - // 0x60 sigma.genG1[1] - // 0x40 sigma.genG1[0] + // 0x60 sigma._genG1[1] + // 0x40 sigma._genG1[0] // 0x20 (Y + h.X)[1] // 0x00 (Y + h.X)[0] } diff --git a/zeth_contracts/contracts/Pairing.sol b/zeth_contracts/contracts/LPairing.sol similarity index 93% rename from zeth_contracts/contracts/Pairing.sol rename to zeth_contracts/contracts/LPairing.sol index 218c895e7..e1709d4db 100644 --- a/zeth_contracts/contracts/Pairing.sol +++ b/zeth_contracts/contracts/LPairing.sol @@ -13,7 +13,7 @@ pragma solidity ^0.8.0; /// gas and costs: // solhint-disable-next-line /// https://github.com/ethereum/go-ethereum/blob/master/params/protocol_params.go -library Pairing { +library LPairing { struct G1Point { uint256 X; @@ -29,12 +29,12 @@ library Pairing { } // Return the generator of G1 - function genG1() internal pure returns (G1Point memory) { + function _genG1() internal pure returns (G1Point memory) { return G1Point(1, 2); } // Return the generator of G2 - function genG2() internal pure returns (G2Point memory) { + function _genG2() internal pure returns (G2Point memory) { return G2Point( // solhint-disable-next-line 11559732032986387107991004021392285783925812861821192530917403151452391805634, @@ -47,7 +47,7 @@ library Pairing { } // Return the negation of p, i.e. p.add(p.negate()) should be zero. - function negateG1(G1Point memory p) + function _negateG2(G1Point memory p) internal pure returns (G1Point memory) @@ -61,7 +61,7 @@ library Pairing { } // Return the sum of two points of G1 - function addG1(G1Point memory p1, G1Point memory p2) + function _addG1(G1Point memory p1, G1Point memory p2) internal returns (G1Point memory r) { @@ -86,7 +86,7 @@ library Pairing { // Return the product of a point on G1 and a scalar, i.e. // p == p.mul(1) and p.add(p) == p.mul(2) for all points p. - function scalarMulG1(G1Point memory p, uint256 s) + function _scalarMulG1(G1Point memory p, uint256 s) internal returns (G1Point memory r) { @@ -108,7 +108,7 @@ library Pairing { } // Return the result of computing the pairing check - function pairing(G1Point[] memory p1, G2Point[] memory p2) + function _pairing(G1Point[] memory p1, G2Point[] memory p2) internal returns (bool) { @@ -178,7 +178,7 @@ library Pairing { } // Convenience method for a pairing check for two pairs. - function pairingProd2( + function _pairingProd2( G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2) internal @@ -190,11 +190,11 @@ library Pairing { p1[1] = b1; p2[0] = a2; p2[1] = b2; - return pairing(p1, p2); + return _pairing(p1, p2); } // Convenience method for a pairing check for three pairs. - function pairingProd3( + function _pairingProd3( G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2, G1Point memory c1, G2Point memory c2) @@ -209,11 +209,11 @@ library Pairing { p2[0] = a2; p2[1] = b2; p2[2] = c2; - return pairing(p1, p2); + return _pairing(p1, p2); } // Convenience method for a pairing check for 4 pairs. - function pairingProd4( + function _pairingProd4( G1Point memory a1, G2Point memory a2, G1Point memory b1, G2Point memory b2, G1Point memory c1, G2Point memory c2, @@ -231,6 +231,6 @@ library Pairing { p2[1] = b2; p2[2] = c2; p2[3] = d2; - return pairing(p1, p2); + return _pairing(p1, p2); } } diff --git a/zeth_contracts/contracts/MixerGroth16AltBN128.sol b/zeth_contracts/contracts/MixerGroth16AltBN128.sol new file mode 100644 index 000000000..676e4cde0 --- /dev/null +++ b/zeth_contracts/contracts/MixerGroth16AltBN128.sol @@ -0,0 +1,39 @@ +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +pragma solidity ^0.8.0; + +import "./BaseMixerAltBN128.sol"; +import "./LGroth16AltBN128.sol"; + +/// Instance of BaseMixerAltBN128 implementing the Groth16 verifier for the +/// alt-bn128 pairing. +contract MixerGroth16AltBN128 is BaseMixerAltBN128 +{ + constructor( + uint256 mkDepth, + address token, + uint256[] memory vk, + address permittedDispatcher, + uint256[2] memory vkHash + ) + BaseMixerAltBN128(mkDepth, token, vk, permittedDispatcher, vkHash) + { + } + + function _verifyZkProof( + uint256[] memory proof, + uint256 publicInputsHash + ) + internal + override + returns (bool) + { + // Convert the single primary input to a dynamic array + // expected by the verifier. + uint256[] memory inputValues = new uint256[](1); + inputValues[0] = publicInputsHash; + return LGroth16AltBN128._verify(_vk, proof, inputValues); + } +} diff --git a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol b/zeth_contracts/contracts/MixerGroth16BLS12_377.sol similarity index 56% rename from zeth_contracts/contracts/Groth16BLS12_377Mixer.sol rename to zeth_contracts/contracts/MixerGroth16BLS12_377.sol index cdd6b0380..ae38b58c0 100644 --- a/zeth_contracts/contracts/Groth16BLS12_377Mixer.sol +++ b/zeth_contracts/contracts/MixerGroth16BLS12_377.sol @@ -4,25 +4,25 @@ pragma solidity ^0.8.0; -import "./Groth16BLS12_377.sol"; -import "./BLS12_377MixerBase.sol"; +import "./LGroth16BLS12_377.sol"; +import "./BaseMixerBLS12_377.sol"; -// Instance of BLS12_377MixerBase implementing the Groth16 verifier for the +// Instance of BaseMixerBLS12_377 implementing the Groth16 verifier for the // bls12-377 pairing. -contract Groth16BLS12_377Mixer is BLS12_377MixerBase +contract MixerGroth16BLS12_377 is BaseMixerBLS12_377 { constructor( - uint256 mk_depth, + uint256 mkDepth, address token, uint256[] memory vk, - address permitted_dispatcher, - uint256[2] memory vk_hash + address permittedDispatcher, + uint256[2] memory vkHash ) - BLS12_377MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) + BaseMixerBLS12_377(mkDepth, token, vk, permittedDispatcher, vkHash) { } - function verifyZkProof( + function _verifyZkProof( uint256[] memory proof, uint256 publicInputsHash ) @@ -34,6 +34,6 @@ contract Groth16BLS12_377Mixer is BLS12_377MixerBase // expected by the verifier. uint256[] memory input_values = new uint256[](1); input_values[0] = publicInputsHash; - return Groth16BLS12_377.verify(_vk, proof, input_values); + return LGroth16BLS12_377._verify(_vk, proof, input_values); } } diff --git a/zeth_contracts/contracts/MixerPghr13AltBN128.sol b/zeth_contracts/contracts/MixerPghr13AltBN128.sol new file mode 100644 index 000000000..fc4074685 --- /dev/null +++ b/zeth_contracts/contracts/MixerPghr13AltBN128.sol @@ -0,0 +1,189 @@ +// Copyright (c) 2015-2021 Clearmatics Technologies Ltd +// +// SPDX-License-Identifier: LGPL-3.0+ + +pragma solidity ^0.8.0; + +import "./LPairing.sol"; +import "./BaseMixerAltBN128.sol"; + +contract MixerAltBN128Pghr13 is BaseMixerAltBN128 +{ + struct VerifyingKey { + LPairing.G2Point A; + LPairing.G1Point B; + LPairing.G2Point C; + LPairing.G2Point gamma; + LPairing.G1Point gammaBeta1; + LPairing.G2Point gammaBeta2; + LPairing.G2Point Z; + LPairing.G1Point[] IC; + } + + struct Proof { + LPairing.G1Point A; + LPairing.G1Point A_p; + LPairing.G2Point B; + LPairing.G1Point B_p; + LPairing.G1Point C; + LPairing.G1Point C_p; + LPairing.G1Point K; + LPairing.G1Point H; + } + + constructor( + uint256 mkDepth, + address token, + uint256[] memory vk, + address permittedDispatcher, + uint256[2] memory vkHash + ) + BaseMixerAltBN128(mkDepth, token, vk, permittedDispatcher, vkHash) + { + uint256 vk_words = vk.length; + require(vk_words >= 26, "invalid vk length"); + } + + function _verify( + uint256[] memory inputs, + Proof memory proof + ) + internal + returns (uint) + { + + // Decode _vk into a VerifyKey struct + uint256 vk_words = _vk.length; + require(vk_words >= 26, "invalid vk length"); + uint256 ic_length = (vk_words - 24) / 2; + + VerifyingKey memory vk; + vk.IC = new LPairing.G1Point[](ic_length); + vk.A = LPairing.G2Point(_vk[0], _vk[1], _vk[2], _vk[3]); + vk.B = LPairing.G1Point(_vk[4], _vk[5]); + vk.C = LPairing.G2Point(_vk[6], _vk[7], _vk[8], _vk[9]); + vk.gamma = LPairing.G2Point(_vk[10], _vk[11], _vk[12], _vk[13]); + vk.gammaBeta1 = LPairing.G1Point(_vk[14], _vk[15]); + vk.gammaBeta2 = LPairing.G2Point(_vk[16], _vk[17], _vk[18], _vk[19]); + vk.Z = LPairing.G2Point(_vk[20], _vk[21], _vk[22], _vk[23]); + for (uint256 i = 24; i < vk_words ; i += 2) { + vk.IC[(i-24)/2] = LPairing.G1Point(_vk[i], _vk[i+1]); + } + + // |I_{in}| == input.length, and vk.IC also contains A_0(s). Thus + // ||vk.IC| == input.length + 1 + require( + inputs.length + 1 == vk.IC.length, + "Using strong input consistency, and the input length differs from" + " expected" + ); + + // 1. Compute the linear combination + // vk_x := vk_{IC,0} + \sum_{i=1}^{n} x_i * vk_{IC,i}, vk_x ∈ G1 + // + // E(A_{in}(s)) if the encoding of + // A_{in}(s) = \sum_{k ∈ I_{in}} a_k · A_k(s), + // where I_{in} denotes the indices of the input wires. + // + // |I_{in}| = n here as we assume that we have a vector x of inputs of + // size n. + LPairing.G1Point memory vk_x = LPairing.G1Point(0, 0); + for (uint256 i = 0; i < inputs.length; i++) { + vk_x = LPairing._addG1(vk_x, + LPairing._scalarMulG1(vk.IC[i + 1], inputs[i])); + } + vk_x = LPairing._addG1(vk_x, vk.IC[0]); + + // 2. Check the validity of knowledge commitments for A, B, C + // e(π_A, vk_A) = e(π′A, _genG2), e(vk_B, π_B) + // = e(π′_B, _genG2), e(vk_C, π_C) + // = e(π′_C, _genG2), + if (!LPairing._pairingProd2( + proof.A, vk.A, + LPairing._negateG2(proof.A_p), LPairing._genG2()) + ) { + return 1; + } + if (!LPairing._pairingProd2( + vk.B, proof.B, + LPairing._negateG2(proof.B_p), LPairing._genG2()) + ) { + return 2; + } + if (!LPairing._pairingProd2( + proof.C, vk.C, + LPairing._negateG2(proof.C_p), LPairing._genG2()) + ) { + return 3; + } + + // 3. Check same coefficients were used + // e(π_K, vk_γ) = e(vk_x + π_A + π_C, vk_{γβ2}) · e(vk_{γβ1}, π_B) + + bool pairing_check = LPairing._pairingProd3( + proof.K, + vk.gamma, + LPairing._negateG2(LPairing._addG1(vk_x, + LPairing._addG1(proof.A, proof.C))), + vk.gammaBeta2, + LPairing._negateG2(vk.gammaBeta1), + proof.B); + if (!pairing_check) { + return 4; + } + + // 4. Check QAP divisibility + // e(vk_x + π_A, π_B) = e(π_H, vk_Z) · e(π_C, _genG2) + pairing_check = LPairing._pairingProd3( + LPairing._addG1(vk_x, proof.A), + proof.B, + LPairing._negateG2(proof.H), + vk.Z, + LPairing._negateG2(proof.C), + LPairing._genG2()); + if (!pairing_check) { + return 5; + } + + return 0; + } + + function _verifyZkProof( + uint256[] memory proofData, + uint256 publicInputsHash + ) + internal + override + returns (bool) + { + // Scalar field characteristic + // solhint-disable-next-line + uint256 r = 21888242871839275222246405745257275088548364400416034343698204186575808495617; + + // Slightly redundant + Proof memory proof; + proof.A = LPairing.G1Point(proofData[0], proofData[1]); + proof.A_p = LPairing.G1Point(proofData[2], proofData[3]); + proof.B = LPairing.G2Point( + proofData[4], proofData[5], proofData[6], proofData[7]); + proof.B_p = LPairing.G1Point(proofData[8], proofData[9]); + proof.C = LPairing.G1Point(proofData[10], proofData[11]); + proof.C_p = LPairing.G1Point(proofData[12], proofData[13]); + proof.H = LPairing.G1Point(proofData[14], proofData[15]); + proof.K = LPairing.G1Point(proofData[16], proofData[17]); + + require( + publicInputsHash < r, + "Input is not is scalar field" + ); + + uint256[] memory inputs = new uint256[](1); + inputs[0] = publicInputsHash; + uint256 verification_result = _verify(inputs, proof); + if (verification_result != 0) { + return false; + } + + return true; + } +} diff --git a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol b/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol deleted file mode 100644 index e7dd66847..000000000 --- a/zeth_contracts/contracts/Pghr13AltBN128Mixer.sol +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (c) 2015-2021 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -pragma solidity ^0.8.0; - -import "./Pairing.sol"; -import "./AltBN128MixerBase.sol"; - -contract Pghr13AltBN128Mixer is AltBN128MixerBase -{ - struct VerifyingKey { - Pairing.G2Point A; - Pairing.G1Point B; - Pairing.G2Point C; - Pairing.G2Point gamma; - Pairing.G1Point gammaBeta1; - Pairing.G2Point gammaBeta2; - Pairing.G2Point Z; - Pairing.G1Point[] IC; - } - - struct Proof { - Pairing.G1Point A; - Pairing.G1Point A_p; - Pairing.G2Point B; - Pairing.G1Point B_p; - Pairing.G1Point C; - Pairing.G1Point C_p; - Pairing.G1Point K; - Pairing.G1Point H; - } - - constructor( - uint256 mk_depth, - address token, - uint256[] memory vk, - address permitted_dispatcher, - uint256[2] memory vk_hash - ) - AltBN128MixerBase(mk_depth, token, vk, permitted_dispatcher, vk_hash) - { - uint256 vk_words = vk.length; - require(vk_words >= 26, "invalid vk length"); - } - - function verify( - uint256[] memory inputs, - Proof memory proof - ) - internal - returns (uint) - { - - // Decode _vk into a VerifyKey struct - uint256 vk_words = _vk.length; - require(vk_words >= 26, "invalid vk length"); - uint256 ic_length = (vk_words - 24) / 2; - - VerifyingKey memory vk; - vk.IC = new Pairing.G1Point[](ic_length); - vk.A = Pairing.G2Point(_vk[0], _vk[1], _vk[2], _vk[3]); - vk.B = Pairing.G1Point(_vk[4], _vk[5]); - vk.C = Pairing.G2Point(_vk[6], _vk[7], _vk[8], _vk[9]); - vk.gamma = Pairing.G2Point(_vk[10], _vk[11], _vk[12], _vk[13]); - vk.gammaBeta1 = Pairing.G1Point(_vk[14], _vk[15]); - vk.gammaBeta2 = Pairing.G2Point(_vk[16], _vk[17], _vk[18], _vk[19]); - vk.Z = Pairing.G2Point(_vk[20], _vk[21], _vk[22], _vk[23]); - for (uint256 i = 24; i < vk_words ; i += 2) { - vk.IC[(i-24)/2] = Pairing.G1Point(_vk[i], _vk[i+1]); - } - - // |I_{in}| == input.length, and vk.IC also contains A_0(s). Thus - // ||vk.IC| == input.length + 1 - require( - inputs.length + 1 == vk.IC.length, - "Using strong input consistency, and the input length differs from" - " expected" - ); - - // 1. Compute the linear combination - // vk_x := vk_{IC,0} + \sum_{i=1}^{n} x_i * vk_{IC,i}, vk_x ∈ G1 - // - // E(A_{in}(s)) if the encoding of - // A_{in}(s) = \sum_{k ∈ I_{in}} a_k · A_k(s), - // where I_{in} denotes the indices of the input wires. - // - // |I_{in}| = n here as we assume that we have a vector x of inputs of - // size n. - Pairing.G1Point memory vk_x = Pairing.G1Point(0, 0); - for (uint256 i = 0; i < inputs.length; i++) { - vk_x = Pairing.addG1(vk_x, - Pairing.scalarMulG1(vk.IC[i + 1], inputs[i])); - } - vk_x = Pairing.addG1(vk_x, vk.IC[0]); - - // 2. Check the validity of knowledge commitments for A, B, C - // e(π_A, vk_A) = e(π′A, genG2), e(vk_B, π_B) - // = e(π′_B, genG2), e(vk_C, π_C) - // = e(π′_C, genG2), - if (!Pairing.pairingProd2( - proof.A, vk.A, - Pairing.negateG1(proof.A_p), Pairing.genG2()) - ) { - return 1; - } - if (!Pairing.pairingProd2( - vk.B, proof.B, - Pairing.negateG1(proof.B_p), Pairing.genG2()) - ) { - return 2; - } - if (!Pairing.pairingProd2( - proof.C, vk.C, - Pairing.negateG1(proof.C_p), Pairing.genG2()) - ) { - return 3; - } - - // 3. Check same coefficients were used - // e(π_K, vk_γ) = e(vk_x + π_A + π_C, vk_{γβ2}) · e(vk_{γβ1}, π_B) - - bool pairing_check = Pairing.pairingProd3( - proof.K, - vk.gamma, - Pairing.negateG1(Pairing.addG1(vk_x, - Pairing.addG1(proof.A, proof.C))), - vk.gammaBeta2, - Pairing.negateG1(vk.gammaBeta1), - proof.B); - if (!pairing_check) { - return 4; - } - - // 4. Check QAP divisibility - // e(vk_x + π_A, π_B) = e(π_H, vk_Z) · e(π_C, genG2) - pairing_check = Pairing.pairingProd3( - Pairing.addG1(vk_x, proof.A), - proof.B, - Pairing.negateG1(proof.H), - vk.Z, - Pairing.negateG1(proof.C), - Pairing.genG2()); - if (!pairing_check) { - return 5; - } - - return 0; - } - - function verifyZkProof( - uint256[] memory proofData, - uint256 publicInputsHash - ) - internal - override - returns (bool) - { - // Scalar field characteristic - // solhint-disable-next-line - uint256 r = 21888242871839275222246405745257275088548364400416034343698204186575808495617; - - // Slightly redundant - Proof memory proof; - proof.A = Pairing.G1Point(proofData[0], proofData[1]); - proof.A_p = Pairing.G1Point(proofData[2], proofData[3]); - proof.B = Pairing.G2Point( - proofData[4], proofData[5], proofData[6], proofData[7]); - proof.B_p = Pairing.G1Point(proofData[8], proofData[9]); - proof.C = Pairing.G1Point(proofData[10], proofData[11]); - proof.C_p = Pairing.G1Point(proofData[12], proofData[13]); - proof.H = Pairing.G1Point(proofData[14], proofData[15]); - proof.K = Pairing.G1Point(proofData[16], proofData[17]); - - require( - publicInputsHash < r, - "Input is not is scalar field" - ); - - uint256[] memory inputs = new uint256[](1); - inputs[0] = publicInputsHash; - uint256 verification_result = verify(inputs, proof); - if (verification_result != 0) { - return false; - } - - return true; - } -} diff --git a/zeth_contracts/contracts/BLS12_377_test.sol b/zeth_contracts/contracts/TestBLS12_377.sol similarity index 65% rename from zeth_contracts/contracts/BLS12_377_test.sol rename to zeth_contracts/contracts/TestBLS12_377.sol index 952ba80ea..0aa682962 100644 --- a/zeth_contracts/contracts/BLS12_377_test.sol +++ b/zeth_contracts/contracts/TestBLS12_377.sol @@ -4,23 +4,23 @@ pragma solidity ^0.8.0; -contract BLS12_377_test +contract TestBLS12_377 { // In many cases, these numbers must be used as literals in the assembly // code. - uint256 private constant SCALAR_WORDS = 1; - uint256 private constant G1_COORD_WORDS = 2; - uint256 private constant G1_POINT_WORDS = 2 * G1_COORD_WORDS; - uint256 private constant G2_COORD_WORDS = 4; - uint256 private constant G2_POINT_WORDS = 2 * G2_COORD_WORDS; + uint256 private constant _SCALAR_WORDS = 1; + uint256 private constant _G1_COORD_WORDS = 2; + uint256 private constant _G1_POINT_WORDS = 2 * _G1_COORD_WORDS; + uint256 private constant _G2_COORD_WORDS = 4; + uint256 private constant _G2_POINT_WORDS = 2 * _G2_COORD_WORDS; /// `input` is the concatenation of 2 encoded points in G1 - function testECAdd(bytes32[2 * G1_POINT_WORDS] memory input) + function ecAddTest(bytes32[2 * _G1_POINT_WORDS] memory input) external - returns(bytes32[G1_POINT_WORDS] memory) + returns(bytes32[_G1_POINT_WORDS] memory) { - bytes32[G1_POINT_WORDS] memory output; + bytes32[_G1_POINT_WORDS] memory output; bool success = true; assembly { @@ -32,11 +32,11 @@ contract BLS12_377_test } /// `input` is an encoded point in G1, followed by an encoded scalar. - function testECMul(bytes32[G1_POINT_WORDS + SCALAR_WORDS] memory input) + function ecMulTest(bytes32[_G1_POINT_WORDS + _SCALAR_WORDS] memory input) external - returns(bytes32[G1_POINT_WORDS] memory) + returns(bytes32[_G1_POINT_WORDS] memory) { - bytes32[G1_POINT_WORDS] memory output; + bytes32[_G1_POINT_WORDS] memory output; bool success = true; assembly { @@ -50,8 +50,8 @@ contract BLS12_377_test /// `input` is the concatenation of 4 pairs of encoded points. Each pair is /// a G1 point, followed by a G2 point. For BW6-761, both of these points /// are 6 words, so there should be 4 * 2 * 6 = 48 words. - function testECPairing( - bytes32[4 * (G1_POINT_WORDS + G2_POINT_WORDS)] memory input + function ecPairingTest( + bytes32[4 * (_G1_POINT_WORDS + _G2_POINT_WORDS)] memory input ) external returns(uint256) diff --git a/zeth_contracts/contracts/BW6_761_test.sol b/zeth_contracts/contracts/TestBW6_761.sol similarity index 55% rename from zeth_contracts/contracts/BW6_761_test.sol rename to zeth_contracts/contracts/TestBW6_761.sol index 61c7e8e22..be885c092 100644 --- a/zeth_contracts/contracts/BW6_761_test.sol +++ b/zeth_contracts/contracts/TestBW6_761.sol @@ -4,35 +4,35 @@ pragma solidity ^0.8.0; -contract BW6_761_test +contract TestBW6_761 { // In many cases, these numbers must be used as literals in the assembly // code. - uint256 private constant SCALAR_WORDS = 2; - uint256 private constant COORD_WORDS = 3; - uint256 private constant POINT_WORDS = 2 * COORD_WORDS; + uint256 private constant _SCALAR_WORDS = 2; + uint256 private constant _COORD_WORDS = 3; + uint256 private constant _POINT_WORDS = 2 * _COORD_WORDS; - // `points` should be the concatenation of 2 encoded points - function testECAdd(bytes32[2 * POINT_WORDS] memory points) - external returns (bytes32[POINT_WORDS] memory) + /// `input` is the concatenation of 2 encoded points in G1 + function ecAddTest(bytes32[2 * _POINT_WORDS] memory input) + external returns (bytes32[_POINT_WORDS] memory) { - bytes32[POINT_WORDS] memory output; + bytes32[_POINT_WORDS] memory output; bool success = true; assembly { - success := call(gas(), 0xc1, 0, points, 0x180, output, 0xc0) + success := call(gas(), 0xc1, 0, input, 0x180, output, 0xc0) } require(success, "precompiled contract call failed (ECAdd)"); return output; } - // `inputs` is an encoded point, followed by an encoded scalar. - function testECMul(bytes32[POINT_WORDS + SCALAR_WORDS] memory input) - external returns (bytes32[POINT_WORDS] memory) + // `input` is an encoded point, followed by an encoded scalar. + function ecMulTest(bytes32[_POINT_WORDS + _SCALAR_WORDS] memory input) + external returns (bytes32[_POINT_WORDS] memory) { - bytes32[POINT_WORDS] memory output; + bytes32[_POINT_WORDS] memory output; bool success = true; assembly { @@ -43,10 +43,10 @@ contract BW6_761_test return output; } - // `points` is the concatenation of 4 pairs of encoded points. Each pair is + // `input` is the concatenation of 4 pairs of encoded points. Each pair is // a G1 point, followed by a G2 point. For BW6-761, both of these points // are 6 words, so there should be 4 * 2 * 6 = 48 words ( - function testECPairing(bytes32[8 * POINT_WORDS] memory input) + function ecPairingTest(bytes32[8 * _POINT_WORDS] memory input) external returns (uint256) { uint256[1] memory output; diff --git a/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol b/zeth_contracts/contracts/TestBaseMixerAltBN128.sol similarity index 53% rename from zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol rename to zeth_contracts/contracts/TestBaseMixerAltBN128.sol index ead0c21ed..ebee68866 100644 --- a/zeth_contracts/contracts/Groth16AltBN128MixerBase_test.sol +++ b/zeth_contracts/contracts/TestBaseMixerAltBN128.sol @@ -4,34 +4,34 @@ pragma solidity ^0.8.0; -import "./Groth16AltBN128Mixer.sol"; +import "./BaseMixerAltBN128.sol"; -// Implementation of Groth16AltBN128MixerBase contract, to allow testing +// Implementation of BaseMixerAltBN128 contract, to allow testing // specific methods. -contract Groth16AltBN128MixerBase_test is Groth16AltBN128Mixer +contract TestBaseMixerAltBN128 is BaseMixerAltBN128 { constructor( - uint256 mk_depth, - address permitted_dispatcher, - uint256[2] memory vk_hash + uint256 mkDepth, + address permittedDispatcher, + uint256[2] memory vkHash ) - Groth16AltBN128Mixer( - mk_depth, + BaseMixerAltBN128( + mkDepth, address(0), new uint256[](0), - permitted_dispatcher, - vk_hash) + permittedDispatcher, + vkHash) { } function hashPublicProofDataTest( - uint256[NUM_INPUTS] memory publicData + uint256[_NUM_INPUTS] memory publicData ) external returns (uint256) { - return hashPublicProofData(publicData); + return _hashPublicProofData(publicData); } function assemblePublicValuesTest(uint256 residualBits) @@ -39,34 +39,34 @@ contract Groth16AltBN128MixerBase_test is Groth16AltBN128Mixer pure returns (uint256 vpub_in, uint256 vpub_out) { - return assemblePublicValues(residualBits); + return _assemblePublicValues(residualBits); } function assembleHsigTest( - uint256[NUM_INPUTS] memory primaryInputs + uint256[_NUM_INPUTS] memory primaryInputs ) external pure returns(bytes32 hsig) { - return assembleHsig(primaryInputs); + return _assembleHsig(primaryInputs); } function assembleNullifierTest( uint256 index, - uint256[NUM_INPUTS] memory primaryInputs + uint256[_NUM_INPUTS] memory primaryInputs ) external pure returns(bytes32 nf) { - return assembleNullifier(index, primaryInputs); + return _assembleNullifier(index, primaryInputs); } // Dummy implementation of abstract function - function verifyZkProof( + function _verifyZkProof( uint256[] memory /* proof */, - uint256[NUM_INPUTS] memory /* inputs */ + uint256[_NUM_INPUTS] memory /* inputs */ ) external pure diff --git a/zeth_contracts/contracts/Groth16BLS12_377_test.sol b/zeth_contracts/contracts/TestGroth16BLS12_377.sol similarity index 73% rename from zeth_contracts/contracts/Groth16BLS12_377_test.sol rename to zeth_contracts/contracts/TestGroth16BLS12_377.sol index fde439f41..2883dbca2 100644 --- a/zeth_contracts/contracts/Groth16BLS12_377_test.sol +++ b/zeth_contracts/contracts/TestGroth16BLS12_377.sol @@ -4,9 +4,9 @@ pragma solidity ^0.8.0; -import "./Groth16BLS12_377.sol"; +import "./LGroth16BLS12_377.sol"; -contract Groth16BLS12_377_test +contract TestGroth16BLS12_377 { uint256[] private _vk; @@ -19,6 +19,6 @@ contract Groth16BLS12_377_test returns(bool) { _vk = vk; - return Groth16BLS12_377.verify(_vk, proof, inputs); + return LGroth16BLS12_377._verify(_vk, proof, inputs); } } diff --git a/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol b/zeth_contracts/contracts/TestMerkleTreeMiMC7.sol similarity index 78% rename from zeth_contracts/contracts/MerkleTreeMiMC7_test.sol rename to zeth_contracts/contracts/TestMerkleTreeMiMC7.sol index 55c5b038e..362647402 100644 --- a/zeth_contracts/contracts/MerkleTreeMiMC7_test.sol +++ b/zeth_contracts/contracts/TestMerkleTreeMiMC7.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.0; import "./BaseMerkleTree.sol"; -import "./MiMC7.sol"; +import "./LMiMC7.sol"; /// The Merkle tree implementation must trade-off complexity, storage, /// initialization cost, and update & root computation cost. @@ -13,7 +13,7 @@ import "./MiMC7.sol"; /// This implementation stores all leaves and nodes, skipping those that have /// not been populated yet. The final entry in each layer stores that layer's /// default value. -contract MerkleTreeMiMC7_test is BaseMerkleTree +contract TestMerkleTreeMiMC7 is BaseMerkleTree { constructor(uint treeDepth) BaseMerkleTree(treeDepth) { @@ -23,7 +23,7 @@ contract MerkleTreeMiMC7_test is BaseMerkleTree /// recomputing the root. Returns the full set of nodes at the end. This /// allows testing of the update code paths for any starting / finishing /// state combination. - function testAddLeaves( + function addLeavesTest( bytes32[] memory first, bytes32[] memory second ) @@ -33,22 +33,22 @@ contract MerkleTreeMiMC7_test is BaseMerkleTree for (uint i = 0 ; i < first.length ; ++i) { insert(first[i]); } - bytes32 root = recomputeRoot(first.length); + bytes32 root = _recomputeRoot(first.length); for (uint i = 0 ; i < second.length ; ++i) { insert(second[i]); } - root = recomputeRoot(second.length); + root = _recomputeRoot(second.length); return root; } - /// Use MiMC7 as the Merkle tree hash function. - function hash(bytes32 left, bytes32 right) + /// Use LMiMC7 as the Merkle tree hash function. + function _hash(bytes32 left, bytes32 right) internal pure override returns(bytes32) { - return MiMC7.hash(left, right); + return LMiMC7._hash(left, right); } } diff --git a/zeth_contracts/contracts/MiMC_test.sol b/zeth_contracts/contracts/TestMiMC.sol similarity index 62% rename from zeth_contracts/contracts/MiMC_test.sol rename to zeth_contracts/contracts/TestMiMC.sol index 4d035279a..b6d534908 100644 --- a/zeth_contracts/contracts/MiMC_test.sol +++ b/zeth_contracts/contracts/TestMiMC.sol @@ -4,19 +4,19 @@ pragma solidity ^0.8.0; -import "./MiMC7.sol"; -import "./MiMC31.sol"; +import "./LMiMC7.sol"; +import "./LMiMC31.sol"; /// Contract to test the MiMC libraries -contract MiMC_test +contract TestMiMC { - /// Test function for MiMC7 + /// Test function for LMiMC7 function mimc7Test(bytes32 x, bytes32 y) external pure returns (bytes32) { - return MiMC7.hash(x, y); + return LMiMC7._hash(x, y); } - /// Test function for MiMC31 + /// Test function for LMiMC31 function mimc31Test(bytes32 x, bytes32 y) external pure returns (bytes32) { - return MiMC31.hash(x, y); + return LMiMC31._hash(x, y); } } From e1de5827f976215e2e05c83be05ee4df4c79d497 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Fri, 23 Apr 2021 17:24:51 +0100 Subject: [PATCH 112/137] Fixed erroneous signature of verifyZkProof function in tests --- zeth_contracts/contracts/BaseMixer.sol | 108 +++++++++--------- .../contracts/TestBaseMixerAltBN128.sol | 5 +- 2 files changed, 57 insertions(+), 56 deletions(-) diff --git a/zeth_contracts/contracts/BaseMixer.sol b/zeth_contracts/contracts/BaseMixer.sol index fd53b7093..b8223fc12 100644 --- a/zeth_contracts/contracts/BaseMixer.sol +++ b/zeth_contracts/contracts/BaseMixer.sol @@ -366,60 +366,6 @@ abstract contract BaseMixer is BaseMerkleTree, ERC223ReceivingContract ); } - // ====================================================================== - // Reminder: Remember that the primary inputs are ordered as follows: - // - // [Root, CommitmentS, NullifierS, h_sig, h_iS, Residual Element(s)] - // - // ie, below is the index mapping of the primary input elements on the - // protoboard: - // - // 0 - // 1 - // ... - // _JSOUT - // _JSOUT + 1 - // ... - // _JSOUT + _JSIN - // _JSOUT + _JSIN + 1 - // _JSOUT + _JSIN + 2 - // ... - // _JSOUT + 2*_JSIN + 1 - // _JSOUT + 2*_JSIN + 2 - // - // The Residual field elements are structured as follows: - // - // 255 128 64 0 - // |||||)|| - // - // where each entry entry after public output and input holds the - // (curve-specific) number residual bits for the corresponding 256 bit - // value. - // ====================================================================== - // - // Utility function to extract a full uint256 from a field element and the - // n-th set of residual bits from `residual`. This function is - // curve-dependent. - function _extractBytes32( - uint256 fieldElement, - uint256 residual, - uint256 residualBitsSetIdx - ) - internal - pure - virtual - returns(bytes32); - - // Implementations must implement the verification algorithm of the - // selected SNARK. - function _verifyZkProof( - uint256[] memory proof, - uint256 publicInputsHash - ) - internal - virtual - returns (bool); - /// This function processes the primary inputs to append and check the root /// and nullifiers in the primary inputs (instance) and modifies the state /// of the mixer contract accordingly. (ie: Appends the commitments to the @@ -520,4 +466,58 @@ abstract contract BaseMixer is BaseMerkleTree, ERC223ReceivingContract { _roots[root] = true; } + + // ====================================================================== + // Reminder: Remember that the primary inputs are ordered as follows: + // + // [Root, CommitmentS, NullifierS, h_sig, h_iS, Residual Element(s)] + // + // ie, below is the index mapping of the primary input elements on the + // protoboard: + // + // 0 + // 1 + // ... + // _JSOUT + // _JSOUT + 1 + // ... + // _JSOUT + _JSIN + // _JSOUT + _JSIN + 1 + // _JSOUT + _JSIN + 2 + // ... + // _JSOUT + 2*_JSIN + 1 + // _JSOUT + 2*_JSIN + 2 + // + // The Residual field elements are structured as follows: + // + // 255 128 64 0 + // |||||)|| + // + // where each entry entry after public output and input holds the + // (curve-specific) number residual bits for the corresponding 256 bit + // value. + // ====================================================================== + + /// Utility function to extract a full uint256 from a field element and the + /// n-th set of residual bits from `residual`. This function is + /// curve-dependent. + function _extractBytes32( + uint256 fieldElement, + uint256 residual, + uint256 residualBitsSetIdx + ) + internal + pure + virtual + returns(bytes32); + + /// Implementations must implement the verification algorithm of the + /// selected SNARK. + function _verifyZkProof( + uint256[] memory proof, + uint256 publicInputsHash + ) + internal + virtual + returns (bool); } diff --git a/zeth_contracts/contracts/TestBaseMixerAltBN128.sol b/zeth_contracts/contracts/TestBaseMixerAltBN128.sol index ebee68866..bd58c6db1 100644 --- a/zeth_contracts/contracts/TestBaseMixerAltBN128.sol +++ b/zeth_contracts/contracts/TestBaseMixerAltBN128.sol @@ -66,10 +66,11 @@ contract TestBaseMixerAltBN128 is BaseMixerAltBN128 // Dummy implementation of abstract function function _verifyZkProof( uint256[] memory /* proof */, - uint256[_NUM_INPUTS] memory /* inputs */ + uint256 /* publicInputsHash */ ) - external + internal pure + override returns (bool) { return false; From 77b4298a64408d42b6437cb2fe519181feda8149 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Fri, 23 Apr 2021 18:24:08 +0100 Subject: [PATCH 113/137] Refactored _contract_name function in zeth cli backend to match solidity renamings --- client/zeth/core/zksnark.py | 2 +- zeth_contracts/contracts/MixerPghr13AltBN128.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/zeth/core/zksnark.py b/client/zeth/core/zksnark.py index f78eaf400..d8ecca224 100644 --- a/client/zeth/core/zksnark.py +++ b/client/zeth/core/zksnark.py @@ -496,4 +496,4 @@ def _contract_name(zksnark_name: str, pp: PairingParameters) -> str: Given a snark name fragment (as used in contract naming conventions) and pairing parameters, determine the full contract name. """ - return zksnark_name + PAIRING_NAME_TO_CONTRACT_NAME[pp.name] + "Mixer" + return "Mixer" + zksnark_name + PAIRING_NAME_TO_CONTRACT_NAME[pp.name] diff --git a/zeth_contracts/contracts/MixerPghr13AltBN128.sol b/zeth_contracts/contracts/MixerPghr13AltBN128.sol index fc4074685..577b7285d 100644 --- a/zeth_contracts/contracts/MixerPghr13AltBN128.sol +++ b/zeth_contracts/contracts/MixerPghr13AltBN128.sol @@ -7,7 +7,7 @@ pragma solidity ^0.8.0; import "./LPairing.sol"; import "./BaseMixerAltBN128.sol"; -contract MixerAltBN128Pghr13 is BaseMixerAltBN128 +contract MixerPghr13AltBN128 is BaseMixerAltBN128 { struct VerifyingKey { LPairing.G2Point A; From 3bf2b7fc776c655fc01b906d0a20a5146ac631e9 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Tue, 27 Apr 2021 17:07:21 +0100 Subject: [PATCH 114/137] Renamed python class to match new solidity contract name --- ...bn128_mixer_base.py => test_base_mixer_altbn128_contract.py} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename client/test_contracts/{test_groth16_altbn128_mixer_base.py => test_base_mixer_altbn128_contract.py} (99%) diff --git a/client/test_contracts/test_groth16_altbn128_mixer_base.py b/client/test_contracts/test_base_mixer_altbn128_contract.py similarity index 99% rename from client/test_contracts/test_groth16_altbn128_mixer_base.py rename to client/test_contracts/test_base_mixer_altbn128_contract.py index 152f015c7..a6e4ed583 100644 --- a/client/test_contracts/test_groth16_altbn128_mixer_base.py +++ b/client/test_contracts/test_base_mixer_altbn128_contract.py @@ -170,7 +170,7 @@ MIXER_CLIENT: Optional[MixerClient] = None -class TestGroth16AltBN128MixerBaseContract(TestCase): +class TestBaseMixerAltBN128Contract(TestCase): @staticmethod def setUpClass() -> None: From 4b5921a2d2c354488254bea89d4216c36a708025 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Tue, 27 Apr 2021 17:14:23 +0100 Subject: [PATCH 115/137] Added requirement for virtual functions to be written last --- CODING_STANDARDS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CODING_STANDARDS.md b/CODING_STANDARDS.md index 2a8ba9e03..59f0d46c3 100644 --- a/CODING_STANDARDS.md +++ b/CODING_STANDARDS.md @@ -18,12 +18,13 @@ We adhere to the `pep8` standard, using `flake8`, `pylint` and `mypy` to catch f Solidity code must adhere to the [solidity coding standards](https://docs.soliditylang.org/en/develop/style-guide.html), with the following amendments: - Test functions must end with the suffix `Test` (e.g. `reverseBytesTest`) - Private/internal state variables and functions must have an underscore prefix (e.g. `_myInternalFunction`) +- Virtual functions in abstract contracts must be written last and located at the end of the contract source - Function parameters must not be prefixed with an underscore - Interface names must have a capital I prefix (e.g. `IERC20`) - Library names must have a capital L prefix (e.g. `LPairing`) - Test contract names must have a `Test` prefix (e.g. `TestMyContract`) -- Event names must be prefixed by `Log` (e.g. `LogDeposit`) - Contract names may not be PascalCase if using PascalCase is introducing confusions in the name (e.g. `BLS12377.sol` vs `BLS12_377.sol`). PascalCase should be used whenever possible +- Event names must be prefixed by `Log` (e.g. `LogDeposit`) **Note:** Some of the files of the current code base may not fully comply with the coding standards above. Old code will progressively be updated to converge towards the recommended style. From dd5f6e7907c550eaf28081fe35f214aed7d09444 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Tue, 27 Apr 2021 17:26:39 +0100 Subject: [PATCH 116/137] Fixed erroneous renaming in comments --- zeth_contracts/contracts/BaseMerkleTree.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zeth_contracts/contracts/BaseMerkleTree.sol b/zeth_contracts/contracts/BaseMerkleTree.sol index 658a04abf..8c1e784d2 100644 --- a/zeth_contracts/contracts/BaseMerkleTree.sol +++ b/zeth_contracts/contracts/BaseMerkleTree.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.0; /// Abstract Merkle tree implementation. Child classes should implement the -/// _hash function. +/// hash function. /// /// The Merkle tree implementation must trade-off complexity, storage, /// initialization cost, and update & root computation cost. @@ -63,7 +63,7 @@ abstract contract BaseMerkleTree _nodes[next_entry_idx] = commitment; } - /// Abstract _hash function to be supplied by a concrete implementation of + /// Abstract hash function to be supplied by a concrete implementation of /// this class. function _hash(bytes32 left, bytes32 right) internal @@ -131,7 +131,7 @@ abstract contract BaseMerkleTree // Start at the right and iterate left, so we only execute the // default_value logic once. child_left_idx_rend (reverse-end) is the // smallest value of child_left_idx at which we should recompute the - // parent node _hash. + // parent node hash. uint256 child_left_idx_rend = child_layer_start + (childStartIdx & _MASK_LS_BIT); From 845123d9a0d62c39dca290d5b3cc6e9667cbdeae Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Wed, 28 Apr 2021 13:40:33 +0100 Subject: [PATCH 117/137] Updated the coding standards as per the discussion with DT --- CODING_STANDARDS.md | 7 +- .../test_base_mixer_altbn128_contract.py | 265 ------------------ .../test_contracts/test_bls12_377_contract.py | 8 +- .../test_contracts/test_bw6_761_contract.py | 8 +- .../test_groth16_bls12_377_contract.py | 2 +- .../test_merkle_tree_contract.py | 93 ------ client/test_contracts/test_mimc_contract.py | 4 +- client/zeth/core/constants.py | 2 +- client/zeth/core/mixer_client.py | 2 +- ...eMerkleTree.sol => AbstractMerkleTree.sol} | 4 +- .../{BaseMixer.sol => AbstractMixer.sol} | 14 +- ...AltBN128.sol => AbstractMixerAltBN128.sol} | 16 +- ...S12_377.sol => AbstractMixerBLS12_377.sol} | 17 +- ...h16AltBN128.sol => LibGroth16AltBN128.sol} | 10 +- ...6BLS12_377.sol => LibGroth16BLS12_377.sol} | 2 +- .../contracts/{LMiMC31.sol => LibMiMC31.sol} | 4 +- .../contracts/{LMiMC7.sol => LibMiMC7.sol} | 2 +- ...rVerifier.sol => LibOTSchnorrVerifier.sol} | 18 +- .../{LPairing.sol => LibPairing.sol} | 2 +- .../contracts/MixerGroth16AltBN128.sol | 12 +- .../contracts/MixerGroth16BLS12_377.sol | 12 +- .../contracts/MixerPghr13AltBN128.sol | 112 ++++---- zeth_contracts/contracts/TestBLS12_377.sol | 6 +- zeth_contracts/contracts/TestBW6_761.sol | 6 +- .../contracts/TestBaseMixerAltBN128.sol | 16 +- .../contracts/TestGroth16BLS12_377.sol | 6 +- .../contracts/TestMerkleTreeMiMC7.sol | 14 +- zeth_contracts/contracts/TestMiMC.sol | 16 +- zeth_contracts/contracts/Tokens.sol | 6 +- 29 files changed, 164 insertions(+), 522 deletions(-) delete mode 100644 client/test_contracts/test_base_mixer_altbn128_contract.py delete mode 100644 client/test_contracts/test_merkle_tree_contract.py rename zeth_contracts/contracts/{BaseMerkleTree.sol => AbstractMerkleTree.sol} (98%) rename zeth_contracts/contracts/{BaseMixer.sol => AbstractMixer.sol} (98%) rename zeth_contracts/contracts/{BaseMixerAltBN128.sol => AbstractMixerAltBN128.sol} (84%) rename zeth_contracts/contracts/{BaseMixerBLS12_377.sol => AbstractMixerBLS12_377.sol} (83%) rename zeth_contracts/contracts/{LGroth16AltBN128.sol => LibGroth16AltBN128.sol} (97%) rename zeth_contracts/contracts/{LGroth16BLS12_377.sol => LibGroth16BLS12_377.sol} (99%) rename zeth_contracts/contracts/{LMiMC31.sol => LibMiMC31.sol} (98%) rename zeth_contracts/contracts/{LMiMC7.sol => LibMiMC7.sol} (99%) rename zeth_contracts/contracts/{LOTSchnorrVerifier.sol => LibOTSchnorrVerifier.sol} (83%) rename zeth_contracts/contracts/{LPairing.sol => LibPairing.sol} (99%) diff --git a/CODING_STANDARDS.md b/CODING_STANDARDS.md index 59f0d46c3..36ecbe6a0 100644 --- a/CODING_STANDARDS.md +++ b/CODING_STANDARDS.md @@ -16,13 +16,14 @@ We adhere to the `pep8` standard, using `flake8`, `pylint` and `mypy` to catch f ## Solidity Solidity code must adhere to the [solidity coding standards](https://docs.soliditylang.org/en/develop/style-guide.html), with the following amendments: -- Test functions must end with the suffix `Test` (e.g. `reverseBytesTest`) +- Test functions must have a `test` prefix (e.g. `testReverseBytes`) - Private/internal state variables and functions must have an underscore prefix (e.g. `_myInternalFunction`) -- Virtual functions in abstract contracts must be written last and located at the end of the contract source +- The order in which contract members are written must driven by their scope (i.e. `public/external` functions must appear first in the contract code, `internal/private` functions must appear last). Additionally, `virtual` functions in abstract contracts must be written last in their visibility group. - Function parameters must not be prefixed with an underscore - Interface names must have a capital I prefix (e.g. `IERC20`) -- Library names must have a capital L prefix (e.g. `LPairing`) +- Library names must have a capital L prefix (e.g. `LibPairing`) - Test contract names must have a `Test` prefix (e.g. `TestMyContract`) +- Abstract contract names must have an `Abstract` prefix (e.g. `AbstractMyContract`) - Contract names may not be PascalCase if using PascalCase is introducing confusions in the name (e.g. `BLS12377.sol` vs `BLS12_377.sol`). PascalCase should be used whenever possible - Event names must be prefixed by `Log` (e.g. `LogDeposit`) diff --git a/client/test_contracts/test_base_mixer_altbn128_contract.py b/client/test_contracts/test_base_mixer_altbn128_contract.py deleted file mode 100644 index a6e4ed583..000000000 --- a/client/test_contracts/test_base_mixer_altbn128_contract.py +++ /dev/null @@ -1,265 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2015-2021 Clearmatics Technologies Ltd -# -# SPDX-License-Identifier: LGPL-3.0+ - -from zeth.core.constants import \ - JS_INPUTS, ZETH_PUBLIC_UNIT_VALUE, ZETH_MERKLE_TREE_DEPTH -from zeth.core.prover_client import ProverConfiguration -from zeth.core.mimc import MiMC7 -from zeth.core.input_hasher import InputHasher -from zeth.core.zksnark import get_zksnark_provider -from zeth.core.utils import EtherValue, hex_list_to_uint256_list -from zeth.core.signing import SigningKeyPair -from zeth.core.mixer_client import MixParameters, MixerClient, joinsplit_sign, \ - mix_parameters_to_dispatch_parameters -import zeth.core.contracts as contracts -import tests.test_pairing as test_pairing -import test_commands.mock as mock -from unittest import TestCase -from typing import Dict, Optional, Any - -# pylint: disable=line-too-long - -# Primary inputs - -ROOT = 0 - -NULLIFIERS = [ - int( - "0010000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000011000", - 2), - int( - "0100000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000100001", - 2), -] - -COMMITMENTS = [ - int( - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000001", - 2), - int( - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000010", - 2), -] - -HSIG = int( - "1010000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000101111", - 2) - -HTAGS = [ - int( - "1100000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000110010", - 2), - int( - "1110000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000111011", - 2), -] - -VPUB = (0x5555555555555500, 0x00eeeeeeeeeeeeee) - -# 255 128 64 0 -# |||||)|| -RESIDUAL_BITS = int( - "101" # h_sig - "010" # nf_1 - "001" # nf_0 - "111" # htag_1 - "110" # htag_0 - "0101010101010101010101010101010101010101010101010101010100000000" # vin - "0000000011101110111011101110111011101110111011101110111011101110", # vout - 2) - -PACKED_PRIMARY_INPUTS = \ - [ROOT] + COMMITMENTS + NULLIFIERS + [HSIG] + HTAGS + [RESIDUAL_BITS] - -PROVER_CONFIG = ProverConfiguration( - zksnark_name="GROTH16", - pairing_parameters=test_pairing.ALT_BN128_PAIRING) - -# Arbitrary VK hash (array of 2 evm words) -VK_HASH = [2, 1] - -MIX_PARAMETERS_VIN = EtherValue(200) - -# Signing key and mix parameters obtained from the test_zeth_cli scripts. See -# scripts/test_zeth_cli. - -MIX_PARAMETERS_SIGNING_KEYPAIR = SigningKeyPair.from_json_dict({ - "sk": { - "psk": "0094c3bd11c967ded0712fb8aa833dc34c2e9e36a298f9bca75ca47b014f525b", - "ssk_y": "26762feff4e7a0fe3f24182caf13b7709818bef122c3c8395c9cc71664925e2f", # noqa - "ssk_y_g1": { - "x": "065495bf33403570a2c0bc2e5eb193dce106c82270ff72a68df1f3255019c37c", # noqa - "y": "12ef732b1e3d2afe712f6414eb68f4bdf0bd610e2bb199dd3ba9c3b7a49e34b3" # noqa - } - }, - "vk": { - "ppk": { - "x": "03ff72a98c117f06526da1ecf485ddc46130bd97f6254678ab42dec92b9b533b", # noqa - "y": "1cd3a1f4ceb50551d9aec66aace46e630a3f6ff17106696ea1937ed573df82aa" # noqa - }, - "spk": { - "x": "065495bf33403570a2c0bc2e5eb193dce106c82270ff72a68df1f3255019c37c", # noqa - "y": "12ef732b1e3d2afe712f6414eb68f4bdf0bd610e2bb199dd3ba9c3b7a49e34b3" # noqa - } - } -}) - -MIX_PARAMETERS_DICT: Dict[str, Any] = { - "extended_proof": { - "proof": { - "a": ["0x19bb99d61b9fd80f83c62301b8b49a7721ff4b9169304ee2e565967dff6c1f50","0x10cf81855def824e4ebb56df71e63271c9c24778fb5022db0c0e5266c5dac8c0"], # noqa - "b": [["0x2e8709a700d887a6d98b5c9e8154dd5aa2e8b37e176f7ee4dde254a4f01cb5f2", "0x26776b5283e39376a076ea7c9effd6ac6a2eb4e153ff33beccc50ea8c9ea77f6"], ["0x21d59a0bded4b94e995d1056fa08a5b44626f936bc7ce90556f288f558a4d6bc", "0x0dfe988bdd7e0f793df7d9d2136ccc2bd2fb9187eaf8f38430a7bfbdd0b7a8d2"]], # noqa - "c": ["0x2e0f8bec7eebad06fab29c558e96cbd68d2d729bca8b56640b0f00f93593e372", "0x2276552ff16f6b4e67c06495941c1988eca4bc60c9aa75cfc57098beb4f19156"] # noqa - }, - "inputs": ["0x01a5e7daab7ee618030641a16ae09ec8f67e121f209e6241b65924122f2ed94b"] # noqa - }, - "public_data": [ - "0x1e202cf4ac3721b9bfd398ec65969c811f32cb1e46df020337e9fc2fda0f014", - "0xda3f23b4b07b9cf6ae3ddce133f7de065b1f933e2df5653b52ddc57a79b4ce7", - "0x153319f1ecdd7a6d25380dc08566a8b5a6a46cb7a14a920b5400d834ca66bdbe", - "0xd1179e6c517a300b86e6e99bba141ca6bd95ac41a02ecd4eeb2a19176de1069", - "0x16f67a9d4ad2656c1f2fbc0d39e4e7ddcbad04bb83e7a38511b1b5f42d5e5983", - "0xfa8d8b70f091bc6d9e5186c91968d37dcc5153e2ff39b5508c1e15016e2bace", - "0x91ac4bd99ed6bc7ff73df5cbfe6330f4875e2c180daccbf568d8146f86ba24b", - "0xd146d5f49d6461012ae4ab3f6f670e275098ed6369406c6f0e5bc4fd4828bce", - "0x9a7000000000bebc2000000000000000000" - ], - "signature_vk": [ - "1808275917333726390675593630676660592284499790243906329164148357633591169851", # noqa - "13038682272157317746935630690273139043012615829064107162576212284919309632170", # noqa - "2863325759893808656457455214623293696676979172082516149962341594639946597244", # noqa - "8564702586272948230916163901148349984070935330485128468603906018200747127987" # noqa - ], - "signature": "19090395247809983100415210093724020502485107107595263044457463522078345927435", # noqa - "ciphertexts": [ - "642149825d05b2b6e40d5e479ac27718adde77563e1e4a924a10a01afc9f5c63bd72e87a9710c2ea97c78a051fcb82cd1cdc23817f5781baa8d3508189fc0963fa3f6209df70aa95db14f24080da94e32374da6e9ce6dc4c3c0efbcbb428e605d683034f672750dd8c1533bf814339800731330f74fd5d67fa24e2207e1b8225aab47ca918d5583f27305f3ea0fcd3c1689a25add0bbad50", # noqa - "296909be36fb44361a34134c5acc47b01f5037c1be0f021734b993d0c766be10acc611836e9b77a67b59f4cbb74479402daa2e3d7b6a0ca780de9d0802bd751c0191bcaed8b2b7d5d334c7eb3bc339795cfeb7e7ace9ede7c1ebb8f4fa79f01342856dc557b680dd6e2ead876a7a281ab935c94aeba77f48097038cc8df1b36b56a97f6a2cdd42e05ed6f3ca26622ae87b405276b9544dcd" # noqa - ] -} - -WEB3: Optional[Any] = None - -ETH: Optional[Any] = None - -MIXER_INSTANCE: Any = None - -MIXER_CLIENT: Optional[MixerClient] = None - - -class TestBaseMixerAltBN128Contract(TestCase): - - @staticmethod - def setUpClass() -> None: - print("Deploying TestBaseMixerAltBN128.sol") - web3, eth = mock.open_test_web3() - deployer_eth_address = eth.accounts[0] - _mixer_interface, mixer_instance = mock.deploy_contract( - eth, - deployer_eth_address, - "TestBaseMixerAltBN128", - { - 'mkDepth': ZETH_MERKLE_TREE_DEPTH, - 'permittedDispatcher': deployer_eth_address, - 'vkHash': VK_HASH, - }) - - global WEB3 # pylint: disable=global-statement - WEB3 = web3 - global ETH # pylint: disable=global-statement - ETH = eth - global MIXER_INSTANCE # pylint: disable=global-statement - MIXER_INSTANCE = mixer_instance - global MIXER_CLIENT # pylint: disable=global-statement - MIXER_CLIENT = MixerClient(web3, PROVER_CONFIG, MIXER_INSTANCE) - - def test_hash_public_inputs(self) -> None: - zksnark = get_zksnark_provider(PROVER_CONFIG.zksnark_name) - mix_params = MixParameters.from_json_dict(zksnark, MIX_PARAMETERS_DICT) - public_data = mix_params.public_data - expect_hash = InputHasher(MiMC7()).hash(public_data) - actual_hash = MIXER_INSTANCE.functions.\ - hashPublicProofDataTest(public_data).call() - self.assertEqual(expect_hash, actual_hash) - - def test_assemble_nullifiers(self) -> None: - # Test retrieving nullifiers - for i in range(JS_INPUTS): - res = MIXER_INSTANCE.functions.\ - assembleNullifierTest(i, PACKED_PRIMARY_INPUTS).call() - val = int.from_bytes(res, byteorder="big") - self.assertEqual(NULLIFIERS[i], val) - - def test_assemble_hsig(self) -> None: - # Test retrieving hsig - res = MIXER_INSTANCE.functions.\ - assembleHsigTest(PACKED_PRIMARY_INPUTS).call() - hsig = int.from_bytes(res, byteorder="big") - self.assertEqual(HSIG, hsig) - - def test_assemble_vpub(self) -> None: - # Test retrieving public values - v_in, v_out = MIXER_INSTANCE.functions.assemblePublicValuesTest( - PACKED_PRIMARY_INPUTS[-1]).call() - v_in_expect = VPUB[0] * ZETH_PUBLIC_UNIT_VALUE - v_out_expect = VPUB[1] * ZETH_PUBLIC_UNIT_VALUE - self.assertEqual(v_in_expect, v_in) - self.assertEqual(v_out_expect, v_out) - - def test_dispatch_call(self) -> None: - # Test calling dispatch. Use the "dummy" MixParameters and signing key, - # recreating the signature for the sender. - - zksnark = get_zksnark_provider(PROVER_CONFIG.zksnark_name) - sender_eth_address = ETH.accounts[0] # type: ignore - mix_params = MixParameters.from_json_dict(zksnark, MIX_PARAMETERS_DICT) - new_signature = joinsplit_sign( - zksnark=get_zksnark_provider(PROVER_CONFIG.zksnark_name), - pp=PROVER_CONFIG.pairing_parameters, - signing_keypair=MIX_PARAMETERS_SIGNING_KEYPAIR, - sender_eth_address=sender_eth_address, - ciphertexts=mix_params.ciphertexts, - extproof=mix_params.extended_proof, - public_data=mix_params.public_data, - for_dispatch_call=True) - mix_params.signature = new_signature - - nested_inputs = \ - hex_list_to_uint256_list(mix_params.extended_proof.inputs) - nested_parameters = mix_parameters_to_dispatch_parameters(mix_params) - mixer_call = MIXER_INSTANCE.functions.dispatch( - VK_HASH, nested_inputs, nested_parameters) - - # Broadcast transaction and wait for the result. - tx_id = contracts.send_contract_call( - web3=WEB3, - call=mixer_call, - sender_eth_addr=sender_eth_address, - sender_eth_private_key=None, - value=MIX_PARAMETERS_VIN) - tx_receipt = ETH.waitForTransactionReceipt(tx_id, 10000) # type: ignore - status = tx_receipt.status - self.assertEqual(True, status) diff --git a/client/test_contracts/test_bls12_377_contract.py b/client/test_contracts/test_bls12_377_contract.py index 145657b9d..e03c7336d 100644 --- a/client/test_contracts/test_bls12_377_contract.py +++ b/client/test_contracts/test_bls12_377_contract.py @@ -96,14 +96,14 @@ def test_bls12_ecadd(self) -> None: """ Check that [6] == [2] + [4] """ - result = BLS12_INSTANCE.functions.ecAddTest(G1_2 + G1_4).call() + result = BLS12_INSTANCE.functions.testECAdd(G1_2 + G1_4).call() self.assertEqual(G1_6, result) def test_bls12_ecmul(self) -> None: """ Check that [-8] == -2 * [4] """ - result = BLS12_INSTANCE.functions.ecMulTest(G1_4 + FR_MINUS_2).call() + result = BLS12_INSTANCE.functions.testECMul(G1_4 + FR_MINUS_2).call() self.assertEqual(G1_MINUS_8, result) def test_bls12_ecpairing(self) -> None: @@ -113,9 +113,9 @@ def test_bls12_ecpairing(self) -> None: # Note, return result here is uint256(1) or uint256(0) depending on the # pairing check result. points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_8 - result = BLS12_INSTANCE.functions.ecPairingTest(points).call() + result = BLS12_INSTANCE.functions.testECPairing(points).call() self.assertEqual(1, result) points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_4 - result = BLS12_INSTANCE.functions.ecPairingTest(points).call() + result = BLS12_INSTANCE.functions.testECPairing(points).call() self.assertEqual(0, result) diff --git a/client/test_contracts/test_bw6_761_contract.py b/client/test_contracts/test_bw6_761_contract.py index 445e7f32f..82cc75356 100644 --- a/client/test_contracts/test_bw6_761_contract.py +++ b/client/test_contracts/test_bw6_761_contract.py @@ -102,14 +102,14 @@ def test_bw6_ecadd(self) -> None: """ Check that [6] == [2] + [4] """ - result = BW6_INSTANCE.functions.ecAddTest(G1_2 + G1_4).call() + result = BW6_INSTANCE.functions.testECAdd(G1_2 + G1_4).call() self.assertEqual(G1_6, result) def test_bw6_ecmul(self) -> None: """ Check that [-8] == -2 * [4] """ - result = BW6_INSTANCE.functions.ecMulTest(G1_4 + FR_MINUS_2).call() + result = BW6_INSTANCE.functions.testECMul(G1_4 + FR_MINUS_2).call() self.assertEqual(G1_MINUS_8, result) def test_bw6_ecpairing(self) -> None: @@ -119,9 +119,9 @@ def test_bw6_ecpairing(self) -> None: # Note, return result here is uint256(1) or uint256(0) depending on the # pairing check result. points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_8 - result = BW6_INSTANCE.functions.ecPairingTest(points).call() + result = BW6_INSTANCE.functions.testECPairing(points).call() self.assertEqual(1, result) points = G1_6 + G2_4 + G1_3 + G2_8 + G1_4 + G2_4 + G1_MINUS_8 + G2_4 - result = BW6_INSTANCE.functions.ecPairingTest(points).call() + result = BW6_INSTANCE.functions.testECPairing(points).call() self.assertEqual(0, result) diff --git a/client/test_contracts/test_groth16_bls12_377_contract.py b/client/test_contracts/test_groth16_bls12_377_contract.py index 2bd6da598..160e5486b 100644 --- a/client/test_contracts/test_groth16_bls12_377_contract.py +++ b/client/test_contracts/test_groth16_bls12_377_contract.py @@ -92,7 +92,7 @@ def _invoke_groth16_bls12_377_verify( vk, BLS12_377_PAIRING) proof_evm = Groth16.proof_to_contract_parameters(proof, BLS12_377_PAIRING) inputs_evm = hex_list_to_uint256_list(inputs) - return CONTRACT_INSTANCE.functions.verifyTest( + return CONTRACT_INSTANCE.functions.testVerify( vk_evm, proof_evm, inputs_evm).call() def test_groth16_bls12_377_valid(self) -> None: diff --git a/client/test_contracts/test_merkle_tree_contract.py b/client/test_contracts/test_merkle_tree_contract.py deleted file mode 100644 index 2aa9d859f..000000000 --- a/client/test_contracts/test_merkle_tree_contract.py +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2015-2021 Clearmatics Technologies Ltd -# -# SPDX-License-Identifier: LGPL-3.0+ - -from zeth.core.constants import ZETH_MERKLE_TREE_DEPTH -from zeth.core.merkle_tree import MerkleTree -from zeth.core.utils import extend_32bytes -from zeth.core.mimc import MiMC7 -from typing import Any -from unittest import TestCase -import test_commands.mock as mock - - -TEST_VALUES = [ - extend_32bytes(bytes.fromhex("f0")), - extend_32bytes(bytes.fromhex("f1")), - extend_32bytes(bytes.fromhex("f2")), - extend_32bytes(bytes.fromhex("f3")), - extend_32bytes(bytes.fromhex("f4")), - extend_32bytes(bytes.fromhex("f5")), - extend_32bytes(bytes.fromhex("f6")), - extend_32bytes(bytes.fromhex("f7")), - extend_32bytes(bytes.fromhex("f8")), - extend_32bytes(bytes.fromhex("f9")), - extend_32bytes(bytes.fromhex("fa")), - extend_32bytes(bytes.fromhex("fb")), - extend_32bytes(bytes.fromhex("fc")), - extend_32bytes(bytes.fromhex("fd")), - extend_32bytes(bytes.fromhex("fe")), - extend_32bytes(bytes.fromhex("ff")), -] - -MKTREE_INSTANCE: Any = None - - -class TestMerkleTreeContract(TestCase): - - @staticmethod - def setUpClass() -> None: - _web3, eth = mock.open_test_web3() - deployer_eth_address = eth.accounts[0] - _mktree_interface, mktree_instance = mock.deploy_contract( - eth, - deployer_eth_address, - "TestMerkleTreeMiMC7", - {'treeDepth': ZETH_MERKLE_TREE_DEPTH}) - global MKTREE_INSTANCE # pylint: disable=global-statement - MKTREE_INSTANCE = mktree_instance - - def test_tree_empty(self) -> None: - mktree = MerkleTree.empty_with_depth(ZETH_MERKLE_TREE_DEPTH, MiMC7()) - expected_root = mktree.recompute_root() - root = MKTREE_INSTANCE.functions.addLeavesTest([], []).call() - self.assertEqual(expected_root, root, "test_tree_empty") - - def _test_partial(self, num_entries: int, step: int = 1) -> None: - """ - Take the first 'num_entries' from TEST_VALUES. Cut them at each possible - place and submit them as two halves to the contract, receiving back the - root for the updated tree. - """ - leaves = TEST_VALUES[:num_entries] - - mktree = MerkleTree.empty_with_depth(ZETH_MERKLE_TREE_DEPTH, MiMC7()) - for leaf in leaves: - mktree.insert(leaf) - expected_root = mktree.recompute_root() - - for cut in range(0, num_entries + 1, step): - print(f"_test_partial: num_entries={num_entries}, cut={cut}") - first = leaves[:cut] - second = leaves[cut:] - root = MKTREE_INSTANCE.functions.addLeavesTest(first, second).call() - self.assertEqual( - expected_root, - root, - f"num_entries: {num_entries}, cut: {cut}: ") - - def test_tree_partial(self) -> None: - """ - Send a series of different arrays of leaves to the contract and check that - the root is as expected. Send as 2 batches, to test updating the tree, - from various states. - """ - # Perform the filling tests using arrays of these sizes - self._test_partial(1) - self._test_partial(7) - self._test_partial(8) - self._test_partial(9) - self._test_partial(15, 3) - self._test_partial(16, 3) diff --git a/client/test_contracts/test_mimc_contract.py b/client/test_contracts/test_mimc_contract.py index 8bf3e2161..8d21306cb 100644 --- a/client/test_contracts/test_mimc_contract.py +++ b/client/test_contracts/test_mimc_contract.py @@ -37,7 +37,7 @@ def test_mimc7(self) -> None: # pylint: enable=line-too-long h = MiMC7().hash(x, y) - result = CONTRACT_INSTANCE.functions.mimc7Test(x, y).call() + result = CONTRACT_INSTANCE.functions.testMimc7(x, y).call() self.assertEqual(h, result) def test_mimc31(self) -> None: @@ -47,5 +47,5 @@ def test_mimc31(self) -> None: # pylint: enable=line-too-long h = MiMC31().hash(x, y) - result = CONTRACT_INSTANCE.functions.mimc31Test(x, y).call() + result = CONTRACT_INSTANCE.functions.testMimc31(x, y).call() self.assertEqual(h, result) diff --git a/client/zeth/core/constants.py b/client/zeth/core/constants.py index 8c577f31a..4e46d3032 100644 --- a/client/zeth/core/constants.py +++ b/client/zeth/core/constants.py @@ -73,7 +73,7 @@ def bit_length_to_byte_length(bit_length: int) -> int: NOTE_LENGTH: int = APK_LENGTH + PUBLIC_VALUE_LENGTH + RHO_LENGTH + TRAPR_LENGTH NOTE_LENGTH_BYTES: int = bit_length_to_byte_length(NOTE_LENGTH) -# Public inputs are (see BaseMixer.sol): +# Public inputs are (see AbstractMixer.sol): # [0 ] - 1 x merkle root # [1 ] - jsOut x commitment # [1 + jsOut ] - jsIn x nullifier (partial) diff --git a/client/zeth/core/mixer_client.py b/client/zeth/core/mixer_client.py index ede66d619..f57ba21a1 100644 --- a/client/zeth/core/mixer_client.py +++ b/client/zeth/core/mixer_client.py @@ -709,7 +709,7 @@ def joinsplit_sign( zksnark, pp, extproof, public_data) # If for_dispatch_call is set, omit proof from the signature. See - # BaseMixer.sol. + # AbstractMixer.sol. if not for_dispatch_call: h.update(proof_bytes) diff --git a/zeth_contracts/contracts/BaseMerkleTree.sol b/zeth_contracts/contracts/AbstractMerkleTree.sol similarity index 98% rename from zeth_contracts/contracts/BaseMerkleTree.sol rename to zeth_contracts/contracts/AbstractMerkleTree.sol index 8c1e784d2..731e44aa9 100644 --- a/zeth_contracts/contracts/BaseMerkleTree.sol +++ b/zeth_contracts/contracts/AbstractMerkleTree.sol @@ -13,7 +13,7 @@ pragma solidity ^0.8.0; /// This implementation stores all leaves and nodes, skipping those that have /// not been populated yet. The final entry in each layer stores that layer's /// default value. -abstract contract BaseMerkleTree +abstract contract AbstractMerkleTree { // Depth of the merkle tree (should be set with the same depth set in the // cpp prover) @@ -40,7 +40,7 @@ abstract contract BaseMerkleTree constructor(uint256 treeDepth) { require ( treeDepth == _DEPTH, - "Invalid depth in BaseMerkleTree" + "Invalid depth in AbstractMerkleTree" ); _initializeTree(); } diff --git a/zeth_contracts/contracts/BaseMixer.sol b/zeth_contracts/contracts/AbstractMixer.sol similarity index 98% rename from zeth_contracts/contracts/BaseMixer.sol rename to zeth_contracts/contracts/AbstractMixer.sol index b8223fc12..7dcc73c80 100644 --- a/zeth_contracts/contracts/BaseMixer.sol +++ b/zeth_contracts/contracts/AbstractMixer.sol @@ -5,12 +5,12 @@ pragma solidity ^0.8.0; import "./Tokens.sol"; -import "./LOTSchnorrVerifier.sol"; -import "./BaseMerkleTree.sol"; +import "./LibOTSchnorrVerifier.sol"; +import "./AbstractMerkleTree.sol"; -/// BaseMixer implements the functions shared across all Mixers (regardless +/// AbstractMixer implements the functions shared across all Mixers (regardless /// which zkSNARK is used) -abstract contract BaseMixer is BaseMerkleTree, ERC223ReceivingContract +abstract contract AbstractMixer is AbstractMerkleTree, ERC223ReceivingContract { // The roots of the different updated trees mapping(bytes32 => bool) private _roots; @@ -100,7 +100,7 @@ abstract contract BaseMixer is BaseMerkleTree, ERC223ReceivingContract address permittedDispatcher, uint256[2] memory vkHash ) - BaseMerkleTree(depth) + AbstractMerkleTree(depth) { bytes32 initialRoot = _nodes[0]; _roots[initialRoot] = true; @@ -203,7 +203,7 @@ abstract contract BaseMixer is BaseMerkleTree, ERC223ReceivingContract ); require( - LOTSchnorrVerifier._verify( + LibOTSchnorrVerifier._verify( vk[0], vk[1], vk[2], vk[3], sigma, hashToBeSigned), "Invalid signature in dispatch" ); @@ -245,7 +245,7 @@ abstract contract BaseMixer is BaseMerkleTree, ERC223ReceivingContract ) ); require( - LOTSchnorrVerifier._verify( + LibOTSchnorrVerifier._verify( vk[0], vk[1], vk[2], vk[3], sigma, hashToBeSigned), "Invalid signature: Unable to verify the signature correctly" ); diff --git a/zeth_contracts/contracts/BaseMixerAltBN128.sol b/zeth_contracts/contracts/AbstractMixerAltBN128.sol similarity index 84% rename from zeth_contracts/contracts/BaseMixerAltBN128.sol rename to zeth_contracts/contracts/AbstractMixerAltBN128.sol index 9078b049a..d68802fa9 100644 --- a/zeth_contracts/contracts/BaseMixerAltBN128.sol +++ b/zeth_contracts/contracts/AbstractMixerAltBN128.sol @@ -4,14 +4,14 @@ pragma solidity ^0.8.0; -import "./BaseMixer.sol"; -import "./LMiMC7.sol"; +import "./AbstractMixer.sol"; +import "./LibMiMC7.sol"; -/// Partial implementation of abstract BaseMixer which implements the +/// Partial implementation of AbstractMixer which implements the /// curve-specific methods to use the ALT-BN128 pairing. -abstract contract BaseMixerAltBN128 is BaseMixer +abstract contract AbstractMixerAltBN128 is AbstractMixer { - // Constants regarding the _hash digest length, the prime number used and + // Constants regarding the hash digest length, the prime number used and // its associated length in bits and the max values (v_in and v_out) // FIELD_CAPACITY = floor( log_2(r) ) uint256 internal constant _FIELD_CAPACITY = 253; @@ -35,18 +35,18 @@ abstract contract BaseMixerAltBN128 is BaseMixer address permittedDispatcher, uint256[2] memory vkHash ) - BaseMixer(mkDepth, token, vk, permittedDispatcher, vkHash) + AbstractMixer(mkDepth, token, vk, permittedDispatcher, vkHash) { } - /// Use LMiMC7 as the Merkle tree _hash function. + /// Use MiMC7 as the Merkle tree hash function. function _hash(bytes32 left, bytes32 right) internal pure override returns(bytes32) { - return LMiMC7._hash(left, right); + return LibMiMC7._hash(left, right); } /// Utility function to extract a full uint256 from a field element and the diff --git a/zeth_contracts/contracts/BaseMixerBLS12_377.sol b/zeth_contracts/contracts/AbstractMixerBLS12_377.sol similarity index 83% rename from zeth_contracts/contracts/BaseMixerBLS12_377.sol rename to zeth_contracts/contracts/AbstractMixerBLS12_377.sol index 9729ef048..a8672d71a 100644 --- a/zeth_contracts/contracts/BaseMixerBLS12_377.sol +++ b/zeth_contracts/contracts/AbstractMixerBLS12_377.sol @@ -4,18 +4,18 @@ pragma solidity ^0.8.0; -import "./BaseMixer.sol"; -import "./LMiMC31.sol"; +import "./AbstractMixer.sol"; +import "./LibMiMC31.sol"; -/// Partial implementation of abstract BaseMixer which implements the +/// Partial implementation of AbstractMixer which implements the /// curve-specific methods to use the BLS12-377 pairing. -abstract contract BaseMixerBLS12_377 is BaseMixer +abstract contract AbstractMixerBLS12_377 is AbstractMixer { - // TODO: Code here is very similar to BaseMixerAltBN128, with only the + // TODO: Code here is very similar to AbstractMixerAltBN128, with only the // constants changed. Look into sharing more code (possibly by making some // of these constants dynamic). - // Constants regarding the _hash digest length, the prime number used and + // Constants regarding the hash digest length, the prime number used and // its associated length in bits and the max values (v_in and v_out) // Number of bits that can be reliably represented by a single field @@ -42,17 +42,18 @@ abstract contract BaseMixerBLS12_377 is BaseMixer address permittedDispatcher, uint256[2] memory vkHash ) - BaseMixer(mkDepth, token, vk, permittedDispatcher, vkHash) + AbstractMixer(mkDepth, token, vk, permittedDispatcher, vkHash) { } + /// Use MiMC31 as the Merkle tree hash function. function _hash(bytes32 left, bytes32 right) internal pure override returns(bytes32) { - return LMiMC31._hash(left, right); + return LibMiMC31._hash(left, right); } /// Extract a full uint256 from a field element and the n-th set of diff --git a/zeth_contracts/contracts/LGroth16AltBN128.sol b/zeth_contracts/contracts/LibGroth16AltBN128.sol similarity index 97% rename from zeth_contracts/contracts/LGroth16AltBN128.sol rename to zeth_contracts/contracts/LibGroth16AltBN128.sol index 337cb8d6c..ff0144422 100644 --- a/zeth_contracts/contracts/LGroth16AltBN128.sol +++ b/zeth_contracts/contracts/LibGroth16AltBN128.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; -library LGroth16AltBN128 +library LibGroth16AltBN128 { // The structure of the verification key differs from the reference paper. // It doesn't contain any element of GT, but only elements of G1 and G2 @@ -63,11 +63,11 @@ library LGroth16AltBN128 // vk_x = \sum_{i=0}^{l} a_i * vk.ABC[i], vk_x in G1. // // ORIGINAL CODE: - // LPairing.G1Point memory vk_x = vk.ABC[0]; // a_0 = 1 + // LibPairing.G1Point memory vk_x = vk.ABC[0]; // a_0 = 1 // for (uint256 i = 0; i < input.length; i++) { // vk_x = - // LPairing._addG1(vk_x, - // LPairing._scalarMulG1(vk.ABC[i + 1], input[i])); + // LibPairing._addG1(vk_x, + // LibPairing._scalarMulG1(vk.ABC[i + 1], input[i])); // } // // The linear combination loop was the biggest cost center of the mixer @@ -169,7 +169,7 @@ library LGroth16AltBN128 // e(vk_x, -g2) * e(vk.Alpha, vk.Minus_Beta) * // e(negate(Proof.A), Proof.B) * e(Proof.C, vk.Minus_Delta) == 1 // - // See LPairing.pairing(). + // See LibPairing.pairing(). // Note terms have been re-ordered since vk_x is already at offset // 0x00. Memory is laid out: // diff --git a/zeth_contracts/contracts/LGroth16BLS12_377.sol b/zeth_contracts/contracts/LibGroth16BLS12_377.sol similarity index 99% rename from zeth_contracts/contracts/LGroth16BLS12_377.sol rename to zeth_contracts/contracts/LibGroth16BLS12_377.sol index 6d8413d86..746285eeb 100644 --- a/zeth_contracts/contracts/LGroth16BLS12_377.sol +++ b/zeth_contracts/contracts/LibGroth16BLS12_377.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; -library LGroth16BLS12_377 +library LibGroth16BLS12_377 { // Fr elements occupy 1 uint256, and Fq elements occupy 2 uint256s. // Therefore G1 elements occupy 4 uint256s. G2 elements have coordinates in diff --git a/zeth_contracts/contracts/LMiMC31.sol b/zeth_contracts/contracts/LibMiMC31.sol similarity index 98% rename from zeth_contracts/contracts/LMiMC31.sol rename to zeth_contracts/contracts/LibMiMC31.sol index a4ec73b85..9239cff13 100644 --- a/zeth_contracts/contracts/LMiMC31.sol +++ b/zeth_contracts/contracts/LibMiMC31.sol @@ -23,8 +23,8 @@ pragma solidity ^0.8.0; /// e (exponent) = 31, so that e=2^t-1 (t=5) and 1 == gcd(e, r-1) /// rounds = 51 /// -/// See LMiMC7.sol for details. -library LMiMC31 +/// See LibMiMC7.sol for details. +library LibMiMC31 { function _hash(bytes32 x, bytes32 y) internal pure returns(bytes32 out) { // Round function (see [AGRRT16]): diff --git a/zeth_contracts/contracts/LMiMC7.sol b/zeth_contracts/contracts/LibMiMC7.sol similarity index 99% rename from zeth_contracts/contracts/LMiMC7.sol rename to zeth_contracts/contracts/LibMiMC7.sol index 4f74831b7..a7a4cd3b8 100644 --- a/zeth_contracts/contracts/LMiMC7.sol +++ b/zeth_contracts/contracts/LibMiMC7.sol @@ -16,7 +16,7 @@ pragma solidity ^0.8.0; /// Section: "Miyaguchi–Preneel" // solhint-disable-next-line max-line-length /// -library LMiMC7 +library LibMiMC7 { function _hash(bytes32 x, bytes32 y) internal pure returns (bytes32 out) { // See [AGRRT16]: diff --git a/zeth_contracts/contracts/LOTSchnorrVerifier.sol b/zeth_contracts/contracts/LibOTSchnorrVerifier.sol similarity index 83% rename from zeth_contracts/contracts/LOTSchnorrVerifier.sol rename to zeth_contracts/contracts/LibOTSchnorrVerifier.sol index f277d7a5a..041dee97e 100644 --- a/zeth_contracts/contracts/LOTSchnorrVerifier.sol +++ b/zeth_contracts/contracts/LibOTSchnorrVerifier.sol @@ -11,7 +11,7 @@ pragma solidity ^0.8.0; /// Mihir Bellare, Sarah Shoup, /// International Workshop on Public Key Cryptography, 2007, /// -library LOTSchnorrVerifier { +library LibOTSchnorrVerifier { function _verify( uint256 vk0, @@ -30,17 +30,17 @@ library LOTSchnorrVerifier { // abi.encodePacked(vk[2], vk[3], hashToBeSigned)); // uint256 h = uint256(h_bytes); // - // // X = g^{x}, where g represents a generator of the cyclic group G - // LPairing.G1Point memory X = LPairing.G1Point(vk[0], vk[1]); + // // X = g^{x}, where g is a generator of the cyclic group G + // LibPairing.G1Point memory X = LibPairing.G1Point(vk[0], vk[1]); // // Y = g^{y} - // LPairing.G1Point memory Y = LPairing.G1Point(vk[2], vk[3]); + // LibPairing.G1Point memory Y = LibPairing.G1Point(vk[2], vk[3]); // // // S = g^{sigma} - // LPairing.G1Point memory S = LPairing._scalarMulG1( - // LPairing._genG1(), sigma); + // LibPairing.G1Point memory S = + // LibPairing._scalarMulG1(LibPairing._genG1(), sigma); // // S_comp = g^{y + xh} - // LPairing.G1Point memory S_comp = LPairing._addG1(Y, - // LPairing._scalarMulG1(X, h)); + // LibPairing.G1Point memory S_comp = + // LibPairing._addG1(Y, LibPairing._scalarMulG1(X, h)); // // // Check that g^{sigma} == g^{y + xh} // return (S.X == S_comp.X && S.Y == S_comp.Y); @@ -90,7 +90,7 @@ library LOTSchnorrVerifier { // 0x40 // 0x20 (Y + h.X)[1] // 0x00 (Y + h.X)[0] - // copy _genG1 and sigma (see LPairing.sol for values) + // copy _genG1 and sigma (see LibPairing.sol for values) mstore(add(pad, 0x40), 1) mstore(add(pad, 0x60), 2) diff --git a/zeth_contracts/contracts/LPairing.sol b/zeth_contracts/contracts/LibPairing.sol similarity index 99% rename from zeth_contracts/contracts/LPairing.sol rename to zeth_contracts/contracts/LibPairing.sol index e1709d4db..f09064c26 100644 --- a/zeth_contracts/contracts/LPairing.sol +++ b/zeth_contracts/contracts/LibPairing.sol @@ -13,7 +13,7 @@ pragma solidity ^0.8.0; /// gas and costs: // solhint-disable-next-line /// https://github.com/ethereum/go-ethereum/blob/master/params/protocol_params.go -library LPairing { +library LibPairing { struct G1Point { uint256 X; diff --git a/zeth_contracts/contracts/MixerGroth16AltBN128.sol b/zeth_contracts/contracts/MixerGroth16AltBN128.sol index 676e4cde0..7fc4953d5 100644 --- a/zeth_contracts/contracts/MixerGroth16AltBN128.sol +++ b/zeth_contracts/contracts/MixerGroth16AltBN128.sol @@ -4,12 +4,12 @@ pragma solidity ^0.8.0; -import "./BaseMixerAltBN128.sol"; -import "./LGroth16AltBN128.sol"; +import "./AbstractMixerAltBN128.sol"; +import "./LibGroth16AltBN128.sol"; -/// Instance of BaseMixerAltBN128 implementing the Groth16 verifier for the +/// Instance of AbstractMixerAltBN128 implementing the Groth16 verifier for the /// alt-bn128 pairing. -contract MixerGroth16AltBN128 is BaseMixerAltBN128 +contract MixerGroth16AltBN128 is AbstractMixerAltBN128 { constructor( uint256 mkDepth, @@ -18,7 +18,7 @@ contract MixerGroth16AltBN128 is BaseMixerAltBN128 address permittedDispatcher, uint256[2] memory vkHash ) - BaseMixerAltBN128(mkDepth, token, vk, permittedDispatcher, vkHash) + AbstractMixerAltBN128(mkDepth, token, vk, permittedDispatcher, vkHash) { } @@ -34,6 +34,6 @@ contract MixerGroth16AltBN128 is BaseMixerAltBN128 // expected by the verifier. uint256[] memory inputValues = new uint256[](1); inputValues[0] = publicInputsHash; - return LGroth16AltBN128._verify(_vk, proof, inputValues); + return LibGroth16AltBN128._verify(_vk, proof, inputValues); } } diff --git a/zeth_contracts/contracts/MixerGroth16BLS12_377.sol b/zeth_contracts/contracts/MixerGroth16BLS12_377.sol index ae38b58c0..9226e09ef 100644 --- a/zeth_contracts/contracts/MixerGroth16BLS12_377.sol +++ b/zeth_contracts/contracts/MixerGroth16BLS12_377.sol @@ -4,12 +4,12 @@ pragma solidity ^0.8.0; -import "./LGroth16BLS12_377.sol"; -import "./BaseMixerBLS12_377.sol"; +import "./LibGroth16BLS12_377.sol"; +import "./AbstractMixerBLS12_377.sol"; -// Instance of BaseMixerBLS12_377 implementing the Groth16 verifier for the +// Instance of AbstractMixerBLS12_377 implementing the Groth16 verifier for the // bls12-377 pairing. -contract MixerGroth16BLS12_377 is BaseMixerBLS12_377 +contract MixerGroth16BLS12_377 is AbstractMixerBLS12_377 { constructor( uint256 mkDepth, @@ -18,7 +18,7 @@ contract MixerGroth16BLS12_377 is BaseMixerBLS12_377 address permittedDispatcher, uint256[2] memory vkHash ) - BaseMixerBLS12_377(mkDepth, token, vk, permittedDispatcher, vkHash) + AbstractMixerBLS12_377(mkDepth, token, vk, permittedDispatcher, vkHash) { } @@ -34,6 +34,6 @@ contract MixerGroth16BLS12_377 is BaseMixerBLS12_377 // expected by the verifier. uint256[] memory input_values = new uint256[](1); input_values[0] = publicInputsHash; - return LGroth16BLS12_377._verify(_vk, proof, input_values); + return LibGroth16BLS12_377._verify(_vk, proof, input_values); } } diff --git a/zeth_contracts/contracts/MixerPghr13AltBN128.sol b/zeth_contracts/contracts/MixerPghr13AltBN128.sol index 577b7285d..afecee2a9 100644 --- a/zeth_contracts/contracts/MixerPghr13AltBN128.sol +++ b/zeth_contracts/contracts/MixerPghr13AltBN128.sol @@ -4,31 +4,31 @@ pragma solidity ^0.8.0; -import "./LPairing.sol"; -import "./BaseMixerAltBN128.sol"; +import "./LibPairing.sol"; +import "./AbstractMixerAltBN128.sol"; -contract MixerPghr13AltBN128 is BaseMixerAltBN128 +contract MixerPghr13AltBN128 is AbstractMixerAltBN128 { struct VerifyingKey { - LPairing.G2Point A; - LPairing.G1Point B; - LPairing.G2Point C; - LPairing.G2Point gamma; - LPairing.G1Point gammaBeta1; - LPairing.G2Point gammaBeta2; - LPairing.G2Point Z; - LPairing.G1Point[] IC; + LibPairing.G2Point A; + LibPairing.G1Point B; + LibPairing.G2Point C; + LibPairing.G2Point gamma; + LibPairing.G1Point gammaBeta1; + LibPairing.G2Point gammaBeta2; + LibPairing.G2Point Z; + LibPairing.G1Point[] IC; } struct Proof { - LPairing.G1Point A; - LPairing.G1Point A_p; - LPairing.G2Point B; - LPairing.G1Point B_p; - LPairing.G1Point C; - LPairing.G1Point C_p; - LPairing.G1Point K; - LPairing.G1Point H; + LibPairing.G1Point A; + LibPairing.G1Point A_p; + LibPairing.G2Point B; + LibPairing.G1Point B_p; + LibPairing.G1Point C; + LibPairing.G1Point C_p; + LibPairing.G1Point K; + LibPairing.G1Point H; } constructor( @@ -38,7 +38,7 @@ contract MixerPghr13AltBN128 is BaseMixerAltBN128 address permittedDispatcher, uint256[2] memory vkHash ) - BaseMixerAltBN128(mkDepth, token, vk, permittedDispatcher, vkHash) + AbstractMixerAltBN128(mkDepth, token, vk, permittedDispatcher, vkHash) { uint256 vk_words = vk.length; require(vk_words >= 26, "invalid vk length"); @@ -58,16 +58,16 @@ contract MixerPghr13AltBN128 is BaseMixerAltBN128 uint256 ic_length = (vk_words - 24) / 2; VerifyingKey memory vk; - vk.IC = new LPairing.G1Point[](ic_length); - vk.A = LPairing.G2Point(_vk[0], _vk[1], _vk[2], _vk[3]); - vk.B = LPairing.G1Point(_vk[4], _vk[5]); - vk.C = LPairing.G2Point(_vk[6], _vk[7], _vk[8], _vk[9]); - vk.gamma = LPairing.G2Point(_vk[10], _vk[11], _vk[12], _vk[13]); - vk.gammaBeta1 = LPairing.G1Point(_vk[14], _vk[15]); - vk.gammaBeta2 = LPairing.G2Point(_vk[16], _vk[17], _vk[18], _vk[19]); - vk.Z = LPairing.G2Point(_vk[20], _vk[21], _vk[22], _vk[23]); + vk.IC = new LibPairing.G1Point[](ic_length); + vk.A = LibPairing.G2Point(_vk[0], _vk[1], _vk[2], _vk[3]); + vk.B = LibPairing.G1Point(_vk[4], _vk[5]); + vk.C = LibPairing.G2Point(_vk[6], _vk[7], _vk[8], _vk[9]); + vk.gamma = LibPairing.G2Point(_vk[10], _vk[11], _vk[12], _vk[13]); + vk.gammaBeta1 = LibPairing.G1Point(_vk[14], _vk[15]); + vk.gammaBeta2 = LibPairing.G2Point(_vk[16], _vk[17], _vk[18], _vk[19]); + vk.Z = LibPairing.G2Point(_vk[20], _vk[21], _vk[22], _vk[23]); for (uint256 i = 24; i < vk_words ; i += 2) { - vk.IC[(i-24)/2] = LPairing.G1Point(_vk[i], _vk[i+1]); + vk.IC[(i-24)/2] = LibPairing.G1Point(_vk[i], _vk[i+1]); } // |I_{in}| == input.length, and vk.IC also contains A_0(s). Thus @@ -87,32 +87,32 @@ contract MixerPghr13AltBN128 is BaseMixerAltBN128 // // |I_{in}| = n here as we assume that we have a vector x of inputs of // size n. - LPairing.G1Point memory vk_x = LPairing.G1Point(0, 0); + LibPairing.G1Point memory vk_x = LibPairing.G1Point(0, 0); for (uint256 i = 0; i < inputs.length; i++) { - vk_x = LPairing._addG1(vk_x, - LPairing._scalarMulG1(vk.IC[i + 1], inputs[i])); + vk_x = LibPairing._addG1(vk_x, + LibPairing._scalarMulG1(vk.IC[i + 1], inputs[i])); } - vk_x = LPairing._addG1(vk_x, vk.IC[0]); + vk_x = LibPairing._addG1(vk_x, vk.IC[0]); // 2. Check the validity of knowledge commitments for A, B, C // e(π_A, vk_A) = e(π′A, _genG2), e(vk_B, π_B) // = e(π′_B, _genG2), e(vk_C, π_C) // = e(π′_C, _genG2), - if (!LPairing._pairingProd2( + if (!LibPairing._pairingProd2( proof.A, vk.A, - LPairing._negateG2(proof.A_p), LPairing._genG2()) + LibPairing._negateG2(proof.A_p), LibPairing._genG2()) ) { return 1; } - if (!LPairing._pairingProd2( + if (!LibPairing._pairingProd2( vk.B, proof.B, - LPairing._negateG2(proof.B_p), LPairing._genG2()) + LibPairing._negateG2(proof.B_p), LibPairing._genG2()) ) { return 2; } - if (!LPairing._pairingProd2( + if (!LibPairing._pairingProd2( proof.C, vk.C, - LPairing._negateG2(proof.C_p), LPairing._genG2()) + LibPairing._negateG2(proof.C_p), LibPairing._genG2()) ) { return 3; } @@ -120,13 +120,13 @@ contract MixerPghr13AltBN128 is BaseMixerAltBN128 // 3. Check same coefficients were used // e(π_K, vk_γ) = e(vk_x + π_A + π_C, vk_{γβ2}) · e(vk_{γβ1}, π_B) - bool pairing_check = LPairing._pairingProd3( + bool pairing_check = LibPairing._pairingProd3( proof.K, vk.gamma, - LPairing._negateG2(LPairing._addG1(vk_x, - LPairing._addG1(proof.A, proof.C))), + LibPairing._negateG2(LibPairing._addG1(vk_x, + LibPairing._addG1(proof.A, proof.C))), vk.gammaBeta2, - LPairing._negateG2(vk.gammaBeta1), + LibPairing._negateG2(vk.gammaBeta1), proof.B); if (!pairing_check) { return 4; @@ -134,13 +134,13 @@ contract MixerPghr13AltBN128 is BaseMixerAltBN128 // 4. Check QAP divisibility // e(vk_x + π_A, π_B) = e(π_H, vk_Z) · e(π_C, _genG2) - pairing_check = LPairing._pairingProd3( - LPairing._addG1(vk_x, proof.A), + pairing_check = LibPairing._pairingProd3( + LibPairing._addG1(vk_x, proof.A), proof.B, - LPairing._negateG2(proof.H), + LibPairing._negateG2(proof.H), vk.Z, - LPairing._negateG2(proof.C), - LPairing._genG2()); + LibPairing._negateG2(proof.C), + LibPairing._genG2()); if (!pairing_check) { return 5; } @@ -162,15 +162,15 @@ contract MixerPghr13AltBN128 is BaseMixerAltBN128 // Slightly redundant Proof memory proof; - proof.A = LPairing.G1Point(proofData[0], proofData[1]); - proof.A_p = LPairing.G1Point(proofData[2], proofData[3]); - proof.B = LPairing.G2Point( + proof.A = LibPairing.G1Point(proofData[0], proofData[1]); + proof.A_p = LibPairing.G1Point(proofData[2], proofData[3]); + proof.B = LibPairing.G2Point( proofData[4], proofData[5], proofData[6], proofData[7]); - proof.B_p = LPairing.G1Point(proofData[8], proofData[9]); - proof.C = LPairing.G1Point(proofData[10], proofData[11]); - proof.C_p = LPairing.G1Point(proofData[12], proofData[13]); - proof.H = LPairing.G1Point(proofData[14], proofData[15]); - proof.K = LPairing.G1Point(proofData[16], proofData[17]); + proof.B_p = LibPairing.G1Point(proofData[8], proofData[9]); + proof.C = LibPairing.G1Point(proofData[10], proofData[11]); + proof.C_p = LibPairing.G1Point(proofData[12], proofData[13]); + proof.H = LibPairing.G1Point(proofData[14], proofData[15]); + proof.K = LibPairing.G1Point(proofData[16], proofData[17]); require( publicInputsHash < r, diff --git a/zeth_contracts/contracts/TestBLS12_377.sol b/zeth_contracts/contracts/TestBLS12_377.sol index 0aa682962..9326d4fb9 100644 --- a/zeth_contracts/contracts/TestBLS12_377.sol +++ b/zeth_contracts/contracts/TestBLS12_377.sol @@ -16,7 +16,7 @@ contract TestBLS12_377 uint256 private constant _G2_POINT_WORDS = 2 * _G2_COORD_WORDS; /// `input` is the concatenation of 2 encoded points in G1 - function ecAddTest(bytes32[2 * _G1_POINT_WORDS] memory input) + function testECAdd(bytes32[2 * _G1_POINT_WORDS] memory input) external returns(bytes32[_G1_POINT_WORDS] memory) { @@ -32,7 +32,7 @@ contract TestBLS12_377 } /// `input` is an encoded point in G1, followed by an encoded scalar. - function ecMulTest(bytes32[_G1_POINT_WORDS + _SCALAR_WORDS] memory input) + function testECMul(bytes32[_G1_POINT_WORDS + _SCALAR_WORDS] memory input) external returns(bytes32[_G1_POINT_WORDS] memory) { @@ -50,7 +50,7 @@ contract TestBLS12_377 /// `input` is the concatenation of 4 pairs of encoded points. Each pair is /// a G1 point, followed by a G2 point. For BW6-761, both of these points /// are 6 words, so there should be 4 * 2 * 6 = 48 words. - function ecPairingTest( + function testECPairing( bytes32[4 * (_G1_POINT_WORDS + _G2_POINT_WORDS)] memory input ) external diff --git a/zeth_contracts/contracts/TestBW6_761.sol b/zeth_contracts/contracts/TestBW6_761.sol index be885c092..6638b1497 100644 --- a/zeth_contracts/contracts/TestBW6_761.sol +++ b/zeth_contracts/contracts/TestBW6_761.sol @@ -14,7 +14,7 @@ contract TestBW6_761 uint256 private constant _POINT_WORDS = 2 * _COORD_WORDS; /// `input` is the concatenation of 2 encoded points in G1 - function ecAddTest(bytes32[2 * _POINT_WORDS] memory input) + function testECAdd(bytes32[2 * _POINT_WORDS] memory input) external returns (bytes32[_POINT_WORDS] memory) { bytes32[_POINT_WORDS] memory output; @@ -29,7 +29,7 @@ contract TestBW6_761 } // `input` is an encoded point, followed by an encoded scalar. - function ecMulTest(bytes32[_POINT_WORDS + _SCALAR_WORDS] memory input) + function testECMul(bytes32[_POINT_WORDS + _SCALAR_WORDS] memory input) external returns (bytes32[_POINT_WORDS] memory) { bytes32[_POINT_WORDS] memory output; @@ -46,7 +46,7 @@ contract TestBW6_761 // `input` is the concatenation of 4 pairs of encoded points. Each pair is // a G1 point, followed by a G2 point. For BW6-761, both of these points // are 6 words, so there should be 4 * 2 * 6 = 48 words ( - function ecPairingTest(bytes32[8 * _POINT_WORDS] memory input) + function testECPairing(bytes32[8 * _POINT_WORDS] memory input) external returns (uint256) { uint256[1] memory output; diff --git a/zeth_contracts/contracts/TestBaseMixerAltBN128.sol b/zeth_contracts/contracts/TestBaseMixerAltBN128.sol index bd58c6db1..84634227d 100644 --- a/zeth_contracts/contracts/TestBaseMixerAltBN128.sol +++ b/zeth_contracts/contracts/TestBaseMixerAltBN128.sol @@ -4,19 +4,19 @@ pragma solidity ^0.8.0; -import "./BaseMixerAltBN128.sol"; +import "./AbstractMixerAltBN128.sol"; -// Implementation of BaseMixerAltBN128 contract, to allow testing +// Implementation of AbstractMixerAltBN128 contract, to allow testing // specific methods. -contract TestBaseMixerAltBN128 is BaseMixerAltBN128 +contract TestAbstractMixerAltBN128 is AbstractMixerAltBN128 { constructor( uint256 mkDepth, address permittedDispatcher, uint256[2] memory vkHash ) - BaseMixerAltBN128( + AbstractMixerAltBN128( mkDepth, address(0), new uint256[](0), @@ -25,7 +25,7 @@ contract TestBaseMixerAltBN128 is BaseMixerAltBN128 { } - function hashPublicProofDataTest( + function testHashPublicProofData( uint256[_NUM_INPUTS] memory publicData ) external @@ -34,7 +34,7 @@ contract TestBaseMixerAltBN128 is BaseMixerAltBN128 return _hashPublicProofData(publicData); } - function assemblePublicValuesTest(uint256 residualBits) + function testAssemblePublicValues(uint256 residualBits) external pure returns (uint256 vpub_in, uint256 vpub_out) @@ -42,7 +42,7 @@ contract TestBaseMixerAltBN128 is BaseMixerAltBN128 return _assemblePublicValues(residualBits); } - function assembleHsigTest( + function testAssembleHsig( uint256[_NUM_INPUTS] memory primaryInputs ) external @@ -52,7 +52,7 @@ contract TestBaseMixerAltBN128 is BaseMixerAltBN128 return _assembleHsig(primaryInputs); } - function assembleNullifierTest( + function testAssembleNullifier( uint256 index, uint256[_NUM_INPUTS] memory primaryInputs ) diff --git a/zeth_contracts/contracts/TestGroth16BLS12_377.sol b/zeth_contracts/contracts/TestGroth16BLS12_377.sol index 2883dbca2..adc0f2097 100644 --- a/zeth_contracts/contracts/TestGroth16BLS12_377.sol +++ b/zeth_contracts/contracts/TestGroth16BLS12_377.sol @@ -4,13 +4,13 @@ pragma solidity ^0.8.0; -import "./LGroth16BLS12_377.sol"; +import "./LibGroth16BLS12_377.sol"; contract TestGroth16BLS12_377 { uint256[] private _vk; - function verifyTest( + function testVerify( uint256[] memory vk, uint256[] memory proof, uint256[] memory inputs @@ -19,6 +19,6 @@ contract TestGroth16BLS12_377 returns(bool) { _vk = vk; - return LGroth16BLS12_377._verify(_vk, proof, inputs); + return LibGroth16BLS12_377._verify(_vk, proof, inputs); } } diff --git a/zeth_contracts/contracts/TestMerkleTreeMiMC7.sol b/zeth_contracts/contracts/TestMerkleTreeMiMC7.sol index 362647402..4d69f9524 100644 --- a/zeth_contracts/contracts/TestMerkleTreeMiMC7.sol +++ b/zeth_contracts/contracts/TestMerkleTreeMiMC7.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.0; -import "./BaseMerkleTree.sol"; -import "./LMiMC7.sol"; +import "./AbstractMerkleTree.sol"; +import "./LibMiMC7.sol"; /// The Merkle tree implementation must trade-off complexity, storage, /// initialization cost, and update & root computation cost. @@ -13,9 +13,9 @@ import "./LMiMC7.sol"; /// This implementation stores all leaves and nodes, skipping those that have /// not been populated yet. The final entry in each layer stores that layer's /// default value. -contract TestMerkleTreeMiMC7 is BaseMerkleTree +contract TestMerkleTreeMiMC7 is AbstractMerkleTree { - constructor(uint treeDepth) BaseMerkleTree(treeDepth) + constructor(uint treeDepth) AbstractMerkleTree(treeDepth) { } @@ -23,7 +23,7 @@ contract TestMerkleTreeMiMC7 is BaseMerkleTree /// recomputing the root. Returns the full set of nodes at the end. This /// allows testing of the update code paths for any starting / finishing /// state combination. - function addLeavesTest( + function testAddLeaves( bytes32[] memory first, bytes32[] memory second ) @@ -42,13 +42,13 @@ contract TestMerkleTreeMiMC7 is BaseMerkleTree return root; } - /// Use LMiMC7 as the Merkle tree hash function. + /// Use MiMC7 as the Merkle tree hash function. function _hash(bytes32 left, bytes32 right) internal pure override returns(bytes32) { - return LMiMC7._hash(left, right); + return LibMiMC7._hash(left, right); } } diff --git a/zeth_contracts/contracts/TestMiMC.sol b/zeth_contracts/contracts/TestMiMC.sol index b6d534908..fd0e4168d 100644 --- a/zeth_contracts/contracts/TestMiMC.sol +++ b/zeth_contracts/contracts/TestMiMC.sol @@ -4,19 +4,19 @@ pragma solidity ^0.8.0; -import "./LMiMC7.sol"; -import "./LMiMC31.sol"; +import "./LibMiMC7.sol"; +import "./LibMiMC31.sol"; /// Contract to test the MiMC libraries contract TestMiMC { - /// Test function for LMiMC7 - function mimc7Test(bytes32 x, bytes32 y) external pure returns (bytes32) { - return LMiMC7._hash(x, y); + /// Test function for LibMiMC7 + function testMimc7(bytes32 x, bytes32 y) external pure returns (bytes32) { + return LibMiMC7._hash(x, y); } - /// Test function for LMiMC31 - function mimc31Test(bytes32 x, bytes32 y) external pure returns (bytes32) { - return LMiMC31._hash(x, y); + /// Test function for LibMiMC31 + function testMimc31(bytes32 x, bytes32 y) external pure returns (bytes32) { + return LibMiMC31._hash(x, y); } } diff --git a/zeth_contracts/contracts/Tokens.sol b/zeth_contracts/contracts/Tokens.sol index 229801681..c6d35cea4 100644 --- a/zeth_contracts/contracts/Tokens.sol +++ b/zeth_contracts/contracts/Tokens.sol @@ -11,13 +11,11 @@ pragma solidity ^0.8.0; abstract contract IERC20 { function transferFrom(address from, address to, uint256 value) - public - virtual + external returns (bool); function transfer(address to, uint256 value) - public - virtual + external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); From f261a9cbe09221a1b400d2617c0ede5bad3cd180 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Wed, 28 Apr 2021 13:42:02 +0100 Subject: [PATCH 118/137] Switched IERC20 to an interface --- zeth_contracts/contracts/Tokens.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zeth_contracts/contracts/Tokens.sol b/zeth_contracts/contracts/Tokens.sol index c6d35cea4..eb8267c82 100644 --- a/zeth_contracts/contracts/Tokens.sol +++ b/zeth_contracts/contracts/Tokens.sol @@ -8,7 +8,7 @@ pragma solidity ^0.8.0; /// and from the Mixer. Note that we only declare the functions we are /// interested in, namely, transferFrom() (used to do a Deposit), and /// transfer() (used to do a withdrawal) -abstract contract IERC20 +interface IERC20 { function transferFrom(address from, address to, uint256 value) external From 63fd3cd17897da71ef8d0736cd840f76695fa5fd Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Wed, 28 Apr 2021 13:47:01 +0100 Subject: [PATCH 119/137] Added compiler version to truffle config --- zeth_contracts/truffle.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/zeth_contracts/truffle.js b/zeth_contracts/truffle.js index 4e8b68954..4ac6becab 100644 --- a/zeth_contracts/truffle.js +++ b/zeth_contracts/truffle.js @@ -24,10 +24,15 @@ module.exports = { useColors: true, enableTimeouts: false }, - solc: { - optimizer: { - enabled: true, - runs: 200 + compilers: { + solc: { + version: "^0.8.0", + settings: { + optimizer: { + enabled: true, + runs: 200 + } + } } } }; From 93e36c68133cb9508d6b3bad0641b259cb0a9f55 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Thu, 29 Apr 2021 13:59:00 +0100 Subject: [PATCH 120/137] Fixed missed prefix update for libraries in coding standards Co-authored-by: Duncan Tebbs --- CODING_STANDARDS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODING_STANDARDS.md b/CODING_STANDARDS.md index 36ecbe6a0..5f3255a7a 100644 --- a/CODING_STANDARDS.md +++ b/CODING_STANDARDS.md @@ -21,7 +21,7 @@ Solidity code must adhere to the [solidity coding standards](https://docs.solidi - The order in which contract members are written must driven by their scope (i.e. `public/external` functions must appear first in the contract code, `internal/private` functions must appear last). Additionally, `virtual` functions in abstract contracts must be written last in their visibility group. - Function parameters must not be prefixed with an underscore - Interface names must have a capital I prefix (e.g. `IERC20`) -- Library names must have a capital L prefix (e.g. `LibPairing`) +- Library names must have a `Lib` prefix (e.g. `LibPairing`) - Test contract names must have a `Test` prefix (e.g. `TestMyContract`) - Abstract contract names must have an `Abstract` prefix (e.g. `AbstractMyContract`) - Contract names may not be PascalCase if using PascalCase is introducing confusions in the name (e.g. `BLS12377.sol` vs `BLS12_377.sol`). PascalCase should be used whenever possible From a2a563b3e9d7efe39338be22faf328f2f0aaefb8 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 26 Apr 2021 18:26:36 +0100 Subject: [PATCH 121/137] libzeth: support for extracting full assignment from circuit wrapper --- libzeth/circuits/circuit_wrapper.hpp | 2 ++ libzeth/circuits/circuit_wrapper.tcc | 20 ++++++++++++++++++++ libzeth/tests/prover/prover_test.cpp | 7 +++++++ 3 files changed, 29 insertions(+) diff --git a/libzeth/circuits/circuit_wrapper.hpp b/libzeth/circuits/circuit_wrapper.hpp index 7ab1461a0..1eaf34a51 100644 --- a/libzeth/circuits/circuit_wrapper.hpp +++ b/libzeth/circuits/circuit_wrapper.hpp @@ -62,6 +62,8 @@ class circuit_wrapper const typename snarkT::proving_key &proving_key, std::vector &out_public_data) const; + const std::vector &get_last_assignment() const; + private: libsnark::protoboard pb; libsnark::pb_variable public_data_hash; diff --git a/libzeth/circuits/circuit_wrapper.tcc b/libzeth/circuits/circuit_wrapper.tcc index 5f34ec641..a77344178 100644 --- a/libzeth/circuits/circuit_wrapper.tcc +++ b/libzeth/circuits/circuit_wrapper.tcc @@ -170,6 +170,26 @@ extended_proof circuit_wrapper< snarkT::generate_proof(proving_key, pb), pb.primary_input()); } +template< + typename HashT, + typename HashTreeT, + typename ppT, + typename snarkT, + size_t NumInputs, + size_t NumOutputs, + size_t TreeDepth> +const std::vector> &circuit_wrapper< + HashT, + HashTreeT, + ppT, + snarkT, + NumInputs, + NumOutputs, + TreeDepth>::get_last_assignment() const +{ + return pb.full_variable_assignment(); +} + } // namespace libzeth #endif // __ZETH_CIRCUITS_CIRCUIT_WRAPPER_TCC__ diff --git a/libzeth/tests/prover/prover_test.cpp b/libzeth/tests/prover/prover_test.cpp index 4532b7190..0fa0f844e 100644 --- a/libzeth/tests/prover/prover_test.cpp +++ b/libzeth/tests/prover/prover_test.cpp @@ -156,6 +156,7 @@ void TestValidJS2In2Case1( keypair.pk, public_data); libff::leave_block("Generate proof", true); + std::vector primary_inputs = ext_proof.get_primary_inputs(); ASSERT_EQ(1, primary_inputs.size()); ASSERT_NE(Field::zero(), primary_inputs[0]); @@ -166,6 +167,12 @@ void TestValidJS2In2Case1( input_hasher_type::compute_hash(public_data), primary_inputs[0]); + // The full assignment should be strictly larger than the public data, and + // begin with the primary input. + const std::vector &full_assignment = prover.get_last_assignment(); + ASSERT_GT(full_assignment.size(), public_data.size()); + ASSERT_EQ(primary_inputs[0], full_assignment[0]); + libff::enter_block("Verify proof", true); // Get the verification key typename snarkT::verification_key vk = keypair.vk; From 48932a23711b2991c8e9bef422732976f1f727f6 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Mon, 26 Apr 2021 18:28:06 +0100 Subject: [PATCH 122/137] libzeth: output alt-bn128 and bls12-377 key and assignment data for simple circuit --- libzeth/tests/circuits/simple_test.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/libzeth/tests/circuits/simple_test.cpp b/libzeth/tests/circuits/simple_test.cpp index e280ec747..dc33cc80c 100644 --- a/libzeth/tests/circuits/simple_test.cpp +++ b/libzeth/tests/circuits/simple_test.cpp @@ -14,6 +14,7 @@ #include #include #include +#include using namespace libsnark; using namespace libzeth; @@ -23,7 +24,8 @@ boost::filesystem::path g_output_dir = boost::filesystem::path(""); namespace { -template void test_simple_circuit_proof() +template +void test_simple_circuit_proof(bool support_output = true) { using Field = libff::Fr; @@ -36,7 +38,7 @@ template void test_simple_circuit_proof() pb.get_constraint_system(); // Write to file if output directory is given. - if (!g_output_dir.empty()) { + if (!g_output_dir.empty() && support_output) { boost::filesystem::path outpath = g_output_dir / ("simple_circuit_r1cs_" + pp_name() + ".json"); @@ -69,7 +71,7 @@ template void test_simple_circuit_proof() ASSERT_TRUE(snarkT::verify(primary, proof, keypair.vk)); - if (!g_output_dir.empty()) { + if (!g_output_dir.empty() && support_output) { { boost::filesystem::path proving_key_path = g_output_dir / ("simple_proving_key_" + snarkT::name + "_" + @@ -107,18 +109,25 @@ template void test_simple_circuit_proof() } } -TEST(SimpleTests, SimpleCircuitProofGroth16) +TEST(SimpleTests, SimpleCircuitProofGroth16AltBN128) { test_simple_circuit_proof< libff::alt_bn128_pp, libzeth::groth16_snark>(); } +TEST(SimpleTests, SimpleCircuitProofGroth16BLS12_377) +{ + test_simple_circuit_proof< + libff::bls12_377_pp, + libzeth::groth16_snark>(); +} + TEST(SimpleTests, SimpleCircuitProofPghr13) { test_simple_circuit_proof< libff::alt_bn128_pp, - pghr13_snark>(); + pghr13_snark>(false); } TEST(SimpleTests, SimpleCircuitProofPow2Domain) @@ -149,6 +158,7 @@ int main(int argc, char **argv) { // WARNING: Do once for all tests. Do not forget to do this. libff::alt_bn128_pp::init_public_params(); + libff::bls12_377_pp::init_public_params(); // Remove stdout noise from libff libff::inhibit_profiling_counters = true; From f405a39957b6201a204324dd5695ccc993ca0e84 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 27 Apr 2021 10:27:15 +0100 Subject: [PATCH 123/137] libzeth: whitespace fix --- libzeth/core/extended_proof.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libzeth/core/extended_proof.hpp b/libzeth/core/extended_proof.hpp index c793fcb5d..8aa4d51d3 100644 --- a/libzeth/core/extended_proof.hpp +++ b/libzeth/core/extended_proof.hpp @@ -24,6 +24,7 @@ template class extended_proof extended_proof( typename snarkT::proof &&in_proof, libsnark::r1cs_primary_input> &&in_primary_inputs); + const typename snarkT::proof &get_proof() const; const libsnark::r1cs_primary_input> &get_primary_inputs() From 1b7a940944d68995195a4801bc17d86bf3a42c73 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 27 Apr 2021 10:27:56 +0100 Subject: [PATCH 124/137] prover_server: support for dumping keys and assignment data --- prover_server/prover_server.cpp | 177 +++++++++++++++++++++++++++++--- 1 file changed, 162 insertions(+), 15 deletions(-) diff --git a/prover_server/prover_server.cpp b/prover_server/prover_server.cpp index 9b1f315a0..42d4d7b75 100644 --- a/prover_server/prover_server.cpp +++ b/prover_server/prover_server.cpp @@ -7,6 +7,7 @@ #include "libzeth/core/utils.hpp" #include "libzeth/serialization/proto_utils.hpp" #include "libzeth/serialization/r1cs_serialization.hpp" +#include "libzeth/serialization/r1cs_variable_assignment_serialization.hpp" #include "libzeth/zeth_constants.hpp" #include "zeth_config.h" @@ -70,6 +71,24 @@ static void write_keypair( snark::keypair_write_bytes(keypair, out_s); } +static void write_proving_key( + const typename snark::proving_key &pk, + const boost::filesystem::path &pk_file) +{ + std::ofstream out_s( + pk_file.c_str(), std::ios_base::out | std::ios_base::binary); + snark::proving_key_write_bytes(pk, out_s); +} + +static void write_verification_key( + const typename snark::verification_key &vk, + const boost::filesystem::path &vk_file) +{ + std::ofstream out_s( + vk_file.c_str(), std::ios_base::out | std::ios_base::binary); + snark::verification_key_write_bytes(vk, out_s); +} + static void write_constraint_system( const circuit_wrapper &prover, const boost::filesystem::path &r1cs_file) { @@ -77,12 +96,30 @@ static void write_constraint_system( libzeth::r1cs_write_json(prover.get_constraint_system(), r1cs_stream); } -static void write_ext_proof_to_file( +static void write_extproof_to_json_file( const libzeth::extended_proof &ext_proof, - boost::filesystem::path proof_path) + const boost::filesystem::path &proof_path) { - std::ofstream os(proof_path.c_str()); - ext_proof.write_json(os); + std::ofstream out_s(proof_path.c_str()); + ext_proof.write_json(out_s); +} + +static void write_proof_to_file( + const typename snark::proof &proof, + const boost::filesystem::path &proof_path) +{ + std::ofstream out_s( + proof_path.c_str(), std::ios_base::out | std::ios_base::binary); + snark::proof_write_bytes(proof, out_s); +} + +static void write_assignment_to_file( + const std::vector &assignment, + const boost::filesystem::path &assignment_path) +{ + std::ofstream out_s( + assignment_path.c_str(), std::ios_base::out | std::ios_base::binary); + libzeth::r1cs_variable_assignment_write_bytes(assignment, out_s); } /// The prover_server class inherits from the Prover service @@ -96,15 +133,32 @@ class prover_server final : public zeth_proto::Prover::Service // The keypair is the result of the setup. Store a copy internally. snark::keypair keypair; + // Optional file to write proofs into (for debugging). + boost::filesystem::path extproof_json_output_file; + // Optional file to write proofs into (for debugging). boost::filesystem::path proof_output_file; + // Optional file to write primary input data into (for debugging). + boost::filesystem::path primary_output_file; + + // Optional file to write full assignments into (for debugging). + boost::filesystem::path assignment_output_file; + public: explicit prover_server( circuit_wrapper &prover, const snark::keypair &keypair, - const boost::filesystem::path &proof_output_file) - : prover(prover), keypair(keypair), proof_output_file(proof_output_file) + const boost::filesystem::path &extproof_json_output_file, + const boost::filesystem::path &proof_output_file, + const boost::filesystem::path &primary_output_file, + const boost::filesystem::path &assignment_output_file) + : prover(prover) + , keypair(keypair) + , extproof_json_output_file(extproof_json_output_file) + , proof_output_file(proof_output_file) + , primary_output_file(primary_output_file) + , assignment_output_file(assignment_output_file) { } @@ -229,10 +283,28 @@ class prover_server final : public zeth_proto::Prover::Service } // Write a copy of the proof for debugging. + if (!extproof_json_output_file.empty()) { + std::cout << "[DEBUG] Writing extended proof (JSON) to " + << extproof_json_output_file << "\n"; + write_extproof_to_json_file( + ext_proof, extproof_json_output_file); + } if (!proof_output_file.empty()) { - std::cout << "[DEBUG] Writing extended proof to " - << proof_output_file << "\n"; - write_ext_proof_to_file(ext_proof, proof_output_file); + std::cout << "[DEBUG] Writing proof to " << proof_output_file + << "\n"; + write_proof_to_file(ext_proof.get_proof(), proof_output_file); + } + if (!primary_output_file.empty()) { + std::cout << "[DEBUG] Writing primary input to " + << primary_output_file << "\n"; + write_assignment_to_file( + ext_proof.get_primary_inputs(), primary_output_file); + } + if (!assignment_output_file.empty()) { + std::cout << "[DEBUG] WARNING! Writing assignment to " + << assignment_output_file << "\n"; + write_assignment_to_file( + prover.get_last_assignment(), assignment_output_file); } std::cout << "[DEBUG] Preparing response..." << std::endl; @@ -294,12 +366,21 @@ void display_server_start_message() static void RunServer( circuit_wrapper &prover, const typename snark::keypair &keypair, - const boost::filesystem::path &proof_output_file) + const boost::filesystem::path &extproof_json_output_file, + const boost::filesystem::path &proof_output_file, + const boost::filesystem::path &primary_output_file, + const boost::filesystem::path &assignment_output_file) { // Listen for incoming connections on 0.0.0.0:50051 std::string server_address("0.0.0.0:50051"); - prover_server service(prover, keypair, proof_output_file); + prover_server service( + prover, + keypair, + extproof_json_output_file, + proof_output_file, + primary_output_file, + assignment_output_file); grpc::ServerBuilder builder; @@ -335,9 +416,29 @@ int main(int argc, char **argv) po::value(), "file in which to export the r1cs (in json format)"); options.add_options()( - "proof-output,p", + "proving-key-output", + po::value(), + "write proving key to file (if generated)"); + options.add_options()( + "verification-key-output", + po::value(), + "write verification key to file (if generated)"); + options.add_options()( + "extproof-json-output", po::value(), - "(DEBUG) file to write generated proofs into"); + "(DEBUG) write generated extended proofs (JSON) to file"); + options.add_options()( + "proof-output", + po::value(), + "(DEBUG) write generated proofs to file"); + options.add_options()( + "primary-output", + po::value(), + "(DEBUG) write primary input to file"); + options.add_options()( + "assignment-output", + po::value(), + "(DEBUG) write full assignment to file (INSECURE!)"); auto usage = [&]() { std::cout << "Usage:" @@ -350,7 +451,12 @@ int main(int argc, char **argv) boost::filesystem::path keypair_file; boost::filesystem::path r1cs_file; + boost::filesystem::path proving_key_output_file; + boost::filesystem::path verification_key_output_file; + boost::filesystem::path extproof_json_output_file; boost::filesystem::path proof_output_file; + boost::filesystem::path primary_output_file; + boost::filesystem::path assignment_output_file; try { po::variables_map vm; po::store( @@ -365,10 +471,30 @@ int main(int argc, char **argv) if (vm.count("r1cs")) { r1cs_file = vm["r1cs"].as(); } + if (vm.count("proving-key-output")) { + proving_key_output_file = + vm["proving-key-output"].as(); + } + if (vm.count("verification-key-output")) { + verification_key_output_file = + vm["verification-key-output"].as(); + } + if (vm.count("extproof-json-output")) { + extproof_json_output_file = + vm["extproof-json-output"].as(); + } if (vm.count("proof-output")) { proof_output_file = vm["proof-output"].as(); } + if (vm.count("primary-output")) { + primary_output_file = + vm["primary-output"].as(); + } + if (vm.count("assignment-output")) { + assignment_output_file = + vm["assignment-output"].as(); + } } catch (po::error &error) { std::cerr << " ERROR: " << error.what() << std::endl; usage(); @@ -392,7 +518,10 @@ int main(int argc, char **argv) // If the keypair file exists, load and use it, otherwise generate a new // keypair and write it to the file. circuit_wrapper prover; - snark::keypair keypair = [&keypair_file, &prover]() { + snark::keypair keypair = [&keypair_file, + &proving_key_output_file, + &verification_key_output_file, + &prover]() { if (boost::filesystem::exists(keypair_file)) { std::cout << "[INFO] Loading keypair: " << keypair_file << "\n"; return load_keypair(keypair_file); @@ -403,6 +532,18 @@ int main(int argc, char **argv) const snark::keypair keypair = prover.generate_trusted_setup(); std::cout << "[INFO] Writing new keypair to " << keypair_file << "\n"; write_keypair(keypair, keypair_file); + + if (!proving_key_output_file.empty()) { + std::cout << "[DEBUG] Writing separate proving key to " + << proving_key_output_file << "\n"; + write_proving_key(keypair.pk, proving_key_output_file); + } + if (!verification_key_output_file.empty()) { + std::cout << "[DEBUG] Writing separate verification key to " + << verification_key_output_file << "\n"; + write_verification_key(keypair.vk, verification_key_output_file); + } + return keypair; }(); @@ -414,6 +555,12 @@ int main(int argc, char **argv) } std::cout << "[INFO] Setup successful, starting the server..." << std::endl; - RunServer(prover, keypair, proof_output_file); + RunServer( + prover, + keypair, + extproof_json_output_file, + proof_output_file, + primary_output_file, + assignment_output_file); return 0; } From b759ca8564ec2010fbe869d54200c6af665c5f10 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 29 Apr 2021 10:58:54 +0100 Subject: [PATCH 125/137] libzeth: clearer naming of some mimc files --- libzeth/circuits/mimc/mimc_mp.hpp | 2 +- .../mimc/{mimc.hpp => mimc_permutation.hpp} | 14 ++++++++------ .../mimc/{mimc.tcc => mimc_permutation.tcc} | 8 ++++---- 3 files changed, 13 insertions(+), 11 deletions(-) rename libzeth/circuits/mimc/{mimc.hpp => mimc_permutation.hpp} (75%) rename libzeth/circuits/mimc/{mimc.tcc => mimc_permutation.tcc} (98%) diff --git a/libzeth/circuits/mimc/mimc_mp.hpp b/libzeth/circuits/mimc/mimc_mp.hpp index 64747624e..b17578ec7 100644 --- a/libzeth/circuits/mimc/mimc_mp.hpp +++ b/libzeth/circuits/mimc/mimc_mp.hpp @@ -5,7 +5,7 @@ #ifndef __ZETH_CIRCUITS_MIMC_MP_HPP__ #define __ZETH_CIRCUITS_MIMC_MP_HPP__ -#include "libzeth/circuits/mimc/mimc.hpp" +#include "libzeth/circuits/mimc/mimc_permutation.hpp" namespace libzeth { diff --git a/libzeth/circuits/mimc/mimc.hpp b/libzeth/circuits/mimc/mimc_permutation.hpp similarity index 75% rename from libzeth/circuits/mimc/mimc.hpp rename to libzeth/circuits/mimc/mimc_permutation.hpp index aad68e26b..8390ebd1c 100644 --- a/libzeth/circuits/mimc/mimc.hpp +++ b/libzeth/circuits/mimc/mimc_permutation.hpp @@ -2,16 +2,18 @@ // Content taken and adapted from: // https://github.com/HarryR/ethsnarks/blob/master/src/gadgets/mimc.hpp -#ifndef __ZETH_CIRCUITS_MIMC_HPP__ -#define __ZETH_CIRCUITS_MIMC_HPP__ +#ifndef __ZETH_CIRCUITS_MIMC_PERMUTATION_HPP__ +#define __ZETH_CIRCUITS_MIMC_PERMUTATION_HPP__ #include "libzeth/circuits/mimc/mimc_round.hpp" namespace libzeth { -/// MiMC_permutation_gadget enforces correct computation of a MiMC round -/// function applied some number of rounds. +/// MiMC_permutation_gadget enforces correct computation of the MiMC +/// permutation, denoted MiMC_r(k, m) in the Zeth specifications +/// (https://github.com/clearmatics/zeth-specifications), by peforming +/// NumRounds MiMC rounds with the given Exponent. template class MiMC_permutation_gadget : public libsnark::gadget { @@ -49,6 +51,6 @@ class MiMC_permutation_gadget : public libsnark::gadget } // namespace libzeth -#include "libzeth/circuits/mimc/mimc.tcc" +#include "libzeth/circuits/mimc/mimc_permutation.tcc" -#endif // __ZETH_CIRCUITS_MIMC_HPP__ +#endif // __ZETH_CIRCUITS_MIMC_PERMUTATION_HPP__ diff --git a/libzeth/circuits/mimc/mimc.tcc b/libzeth/circuits/mimc/mimc_permutation.tcc similarity index 98% rename from libzeth/circuits/mimc/mimc.tcc rename to libzeth/circuits/mimc/mimc_permutation.tcc index 3e9bbe4f9..3e2154545 100644 --- a/libzeth/circuits/mimc/mimc.tcc +++ b/libzeth/circuits/mimc/mimc_permutation.tcc @@ -2,10 +2,10 @@ // Content taken and adapted from: // https://github.com/HarryR/ethsnarks/blob/master/src/gadgets/mimc.hpp -#ifndef __ZETH_CIRCUITS_MIMC_TCC__ -#define __ZETH_CIRCUITS_MIMC_TCC__ +#ifndef __ZETH_CIRCUITS_MIMC_PERMUTATION_TCC__ +#define __ZETH_CIRCUITS_MIMC_PERMUTATION_TCC__ -#include "libzeth/circuits/mimc/mimc.hpp" +#include "libzeth/circuits/mimc/mimc_permutation.hpp" namespace libzeth { @@ -304,4 +304,4 @@ void MiMC_permutation_gadget:: } // namespace libzeth -#endif // __ZETH_CIRCUITS_MIMC_TCC__ +#endif // __ZETH_CIRCUITS_MIMC_PERMUTATION_TCC__ From 5d040601c2bff48be9e3369d69744561c6ca653b Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 29 Apr 2021 12:24:20 +0100 Subject: [PATCH 126/137] libzeth: support adding arbitrary lin comb to mimc round result --- libzeth/circuits/mimc/mimc_permutation.tcc | 39 ++++++++------- libzeth/circuits/mimc/mimc_round.hpp | 22 ++++++-- libzeth/circuits/mimc/mimc_round.tcc | 58 ++++++++++++++++------ libzeth/tests/circuits/mimc_mp_test.cpp | 24 ++++----- 4 files changed, 94 insertions(+), 49 deletions(-) diff --git a/libzeth/circuits/mimc/mimc_permutation.tcc b/libzeth/circuits/mimc/mimc_permutation.tcc index 3e2154545..6eb7e7b9d 100644 --- a/libzeth/circuits/mimc/mimc_permutation.tcc +++ b/libzeth/circuits/mimc/mimc_permutation.tcc @@ -42,36 +42,37 @@ MiMC_permutation_gadget::MiMC_permutation_gadget( key, round_constants[0], round_results[0], - false, FMT(this->annotation_prefix, " round[0]")); - // All other rounds use the output of the previous round and output to an - // intermediate variable, except the last round, which outputs to the - // result parameter. - for (size_t i = 1; i < NumRounds; i++) { - const bool is_last = (i == (NumRounds - 1)); + // Intermediate rounds use the output of the previous round and output to + // an intermediate variable (allocated here) + for (size_t i = 1; i < NumRounds - 1; i++) { + // Allocate intermediate round result. + round_results[i].allocate( + this->pb, FMT(this->annotation_prefix, " round_result[%zu]", i)); - // Allocate output variable (except for last round, which outputs to - // the result variable). - if (is_last) { - round_results[i] = result; - } else { - round_results[i].allocate( - this->pb, - FMT(this->annotation_prefix, " round_result[%zu]", i)); - } - - // Initialize and add the current round gadget into the rounds gadget - // vector, picking the relative constant + // Initialize the current round gadget into the vector of round gadgets + // vector, picking the correct round constant. round_gadgets.emplace_back( this->pb, round_results[i - 1], key, round_constants[i], round_results[i], - is_last, FMT(this->annotation_prefix, " round[%zu]", i)); } + + // For last round, output to the result variable and add `key` to the + // result. + round_results[NumRounds - 1] = result; + round_gadgets.emplace_back( + this->pb, + round_results[NumRounds - 2], + key, + round_constants[NumRounds - 1], + round_results[NumRounds - 1], + key, + FMT(this->annotation_prefix, " round[%zu]", NumRounds - 1)); } template diff --git a/libzeth/circuits/mimc/mimc_round.hpp b/libzeth/circuits/mimc/mimc_round.hpp index 87c7ad757..c8eccb674 100644 --- a/libzeth/circuits/mimc/mimc_round.hpp +++ b/libzeth/circuits/mimc/mimc_round.hpp @@ -36,12 +36,18 @@ class MiMC_round_gadget : public libsnark::gadget // Result variable const libsnark::pb_variable result; - // Boolean variable to add the key after the round - const bool add_key_to_result; + // Optional linear combination to add after the final round + const libsnark::pb_linear_combination add_to_result; + + // Flag indicating whether add_to_result is valid + const bool have_add_to_result; // Intermediate values std::vector> exponents; + // Initialization code shared by constructors. + void initialize(); + public: MiMC_round_gadget( libsnark::protoboard &pb, @@ -49,7 +55,17 @@ class MiMC_round_gadget : public libsnark::gadget const libsnark::pb_linear_combination &key, const FieldT &round_const, libsnark::pb_variable &result, - const bool add_k_to_result, + const std::string &annotation_prefix = "MiMC_round_gadget"); + + /// Constructor that supports adding some linear_combination to the final + /// result. + MiMC_round_gadget( + libsnark::protoboard &pb, + const libsnark::pb_linear_combination &msg, + const libsnark::pb_linear_combination &key, + const FieldT &round_const, + libsnark::pb_variable &result, + const libsnark::pb_linear_combination &add_to_result, const std::string &annotation_prefix = "MiMC_round_gadget"); void generate_r1cs_constraints(); diff --git a/libzeth/circuits/mimc/mimc_round.tcc b/libzeth/circuits/mimc/mimc_round.tcc index 02186624d..c707e7f2d 100644 --- a/libzeth/circuits/mimc/mimc_round.tcc +++ b/libzeth/circuits/mimc/mimc_round.tcc @@ -10,6 +10,14 @@ namespace libzeth { +template +void MiMC_round_gadget::initialize() +{ + // Each condition requires an intermediate variable, except the final one, + // which uses _result (and optionally _k). + exponents.resize(NUM_CONDITIONS - 1); +} + template MiMC_round_gadget::MiMC_round_gadget( libsnark::protoboard &pb, @@ -17,18 +25,35 @@ MiMC_round_gadget::MiMC_round_gadget( const libsnark::pb_linear_combination &key, const FieldT &round_const, libsnark::pb_variable &result, - const bool add_key_to_result, const std::string &annotation_prefix) : libsnark::gadget(pb, annotation_prefix) , msg(msg) , key(key) , round_const(round_const) , result(result) - , add_key_to_result(add_key_to_result) + , have_add_to_result(false) { - // Each condition requires an intermediate variable, except the final one, - // which uses _result (and optionally _k). - exponents.resize(NUM_CONDITIONS - 1); + initialize(); +} + +template +MiMC_round_gadget::MiMC_round_gadget( + libsnark::protoboard &pb, + const libsnark::pb_linear_combination &msg, + const libsnark::pb_linear_combination &key, + const FieldT &round_const, + libsnark::pb_variable &result, + const libsnark::pb_linear_combination &add_to_result, + const std::string &annotation_prefix) + : libsnark::gadget(pb, annotation_prefix) + , msg(msg) + , key(key) + , round_const(round_const) + , result(result) + , add_to_result(add_to_result) + , have_add_to_result(true) +{ + initialize(); } template @@ -82,14 +107,16 @@ void MiMC_round_gadget::generate_r1cs_constraints() } assert(exp_idx == exponents.size()); - // Final multiply (lowest-order bit is known to be 1): - // result = last * t (+ k) - // such that: - // result (- k) = last * t - if (add_key_to_result) { + // Final multiply (lowest-order bit is known to be 1), + if (have_add_to_result) { + // addition of add_to_result: + // result = last * t + add_to_result + // <=> result - add_to_result = last * t this->pb.add_r1cs_constraint( - libsnark::r1cs_constraint(*last, t, result - key), - FMT(this->annotation_prefix, " calc_t^%zu_add_key", Exponent)); + libsnark::r1cs_constraint(*last, t, result - add_to_result), + FMT(this->annotation_prefix, + " calc_t^%zu_add_to_result", + Exponent)); } else { this->pb.add_r1cs_constraint( libsnark::r1cs_constraint(*last, t, result), @@ -125,10 +152,11 @@ void MiMC_round_gadget::generate_r1cs_witness() const this->pb.val(exponents[var_idx++]) = v; } - // v = v * t (+ k) + // v = v * t + add_to_result v = v * t; - if (add_key_to_result) { - v = v + k_val; + if (have_add_to_result) { + add_to_result.evaluate(this->pb); + v = v + this->pb.lc_val(add_to_result); } this->pb.val(result) = v; } diff --git a/libzeth/tests/circuits/mimc_mp_test.cpp b/libzeth/tests/circuits/mimc_mp_test.cpp index ca081c8e4..65d4a444f 100644 --- a/libzeth/tests/circuits/mimc_mp_test.cpp +++ b/libzeth/tests/circuits/mimc_mp_test.cpp @@ -28,7 +28,7 @@ namespace // Testing that (15212 + 98645 + 216319)**7 = // 427778066313557225181231220812180094976 -TEST(TestMiMC, MiMC7RoundTrueNoAddKToResult) +TEST(TestMiMC, MiMC7Round) { libsnark::protoboard pb; libsnark::pb_variable in_x; @@ -43,7 +43,7 @@ TEST(TestMiMC, MiMC7RoundTrueNoAddKToResult) result.allocate(pb, "result"); MiMCe7_round_gadget round_gadget( - pb, in_x, in_k, in_C, result, false, "round_gadget"); + pb, in_x, in_k, in_C, result, "round_gadget"); round_gadget.generate_r1cs_constraints(); round_gadget.generate_r1cs_witness(); @@ -52,7 +52,7 @@ TEST(TestMiMC, MiMC7RoundTrueNoAddKToResult) ASSERT_TRUE(expected_out == pb.val(result)); } -TEST(TestMiMC, MiMC7RoundFalseNoAddKToResult) +TEST(TestMiMC, MiMC7RoundIncorrect) { libsnark::protoboard pb; libsnark::pb_variable in_x; @@ -67,7 +67,7 @@ TEST(TestMiMC, MiMC7RoundFalseNoAddKToResult) result.allocate(pb, "result"); MiMCe7_round_gadget round_gadget( - pb, in_x, in_k, in_C, result, false, "round_gadget"); + pb, in_x, in_k, in_C, result, "round_gadget"); round_gadget.generate_r1cs_constraints(); round_gadget.generate_r1cs_witness(); @@ -78,7 +78,7 @@ TEST(TestMiMC, MiMC7RoundFalseNoAddKToResult) // Testing that (15212 + 98645 + 216319)**7 + 98645 = // 427778066313557225181231220812180193621 -TEST(TestMiMC, MiMC7RoundTrueAddKToResult) +TEST(TestMiMC, MiMC7RoundAddToResult) { libsnark::protoboard pb; libsnark::pb_variable in_x; @@ -93,7 +93,7 @@ TEST(TestMiMC, MiMC7RoundTrueAddKToResult) result.allocate(pb, "result"); MiMCe7_round_gadget round_gadget( - pb, in_x, in_k, in_C, result, true, "round_gadget"); + pb, in_x, in_k, in_C, result, in_k, "round_gadget"); round_gadget.generate_r1cs_constraints(); round_gadget.generate_r1cs_witness(); @@ -102,7 +102,7 @@ TEST(TestMiMC, MiMC7RoundTrueAddKToResult) ASSERT_TRUE(expected_out == pb.val(result)); } -TEST(TestMiMC, MiMC7RoundFalseAddKToResult) +TEST(TestMiMC, MiMC7RoundAddToResultIncorrect) { libsnark::protoboard pb; libsnark::pb_variable in_x; @@ -117,7 +117,7 @@ TEST(TestMiMC, MiMC7RoundFalseAddKToResult) result.allocate(pb, "result"); MiMCe7_round_gadget round_gadget( - pb, in_x, in_k, in_C, result, true, "round_gadget"); + pb, in_x, in_k, in_C, result, in_k, "round_gadget"); round_gadget.generate_r1cs_constraints(); round_gadget.generate_r1cs_witness(); @@ -126,7 +126,7 @@ TEST(TestMiMC, MiMC7RoundFalseAddKToResult) ASSERT_FALSE(unexpected_out == pb.val(result)); } -TEST(TestMiMC, MiMC7PermTrue) +TEST(TestMiMC, MiMC7Perm) { libsnark::protoboard pb; @@ -153,7 +153,7 @@ TEST(TestMiMC, MiMC7PermTrue) ASSERT_TRUE(expected_out == pb.val(result)); } -TEST(TestMiMC, MiMC7PermFalse) +TEST(TestMiMC, MiMC7PermIncorrect) { libsnark::protoboard pb; @@ -179,7 +179,7 @@ TEST(TestMiMC, MiMC7PermFalse) ASSERT_FALSE(unexpected_out == pb.val(result)); } -TEST(TestMiMC, MiMC7MpTrue) +TEST(TestMiMC, MiMC7Mp) { libsnark::protoboard pb; @@ -212,7 +212,7 @@ TEST(TestMiMC, MiMC7MpTrue) ASSERT_TRUE(expected_out == pb.val(result)); } -TEST(TestMiMC, MiMC7MpFalse) +TEST(TestMiMC, MiMC7MpIncorrect) { libsnark::protoboard pb; From 4a41cd6693ad063f62376b04a26b038ee17fae1f Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 29 Apr 2021 13:07:31 +0100 Subject: [PATCH 127/137] libzeth: addition of arbitrary lc to mimc permutation without extra constraint --- libzeth/circuits/mimc/mimc_permutation.hpp | 24 +++++++- libzeth/circuits/mimc/mimc_permutation.tcc | 65 +++++++++++++++++++--- 2 files changed, 78 insertions(+), 11 deletions(-) diff --git a/libzeth/circuits/mimc/mimc_permutation.hpp b/libzeth/circuits/mimc/mimc_permutation.hpp index 8390ebd1c..3792f6ece 100644 --- a/libzeth/circuits/mimc/mimc_permutation.hpp +++ b/libzeth/circuits/mimc/mimc_permutation.hpp @@ -13,7 +13,9 @@ namespace libzeth /// MiMC_permutation_gadget enforces correct computation of the MiMC /// permutation, denoted MiMC_r(k, m) in the Zeth specifications /// (https://github.com/clearmatics/zeth-specifications), by peforming -/// NumRounds MiMC rounds with the given Exponent. +/// NumRounds MiMC rounds with the given Exponent. An optional `add_to_result` +/// value can be passed in to be added to the result of the regular MiMC +/// permutation (without requiring extra constraints). template class MiMC_permutation_gadget : public libsnark::gadget { @@ -34,13 +36,31 @@ class MiMC_permutation_gadget : public libsnark::gadget // Vector of MiMC round_gadgets std::vector round_gadgets; + // Common initialization + MiMC_permutation_gadget( + libsnark::protoboard &pb, + const libsnark::pb_linear_combination &msg, + const libsnark::pb_linear_combination &key, + const libsnark::pb_variable &result, + const libsnark::pb_linear_combination &add_to_result, + const bool have_add_to_result, + const std::string &annotation_prefix); + public: MiMC_permutation_gadget( libsnark::protoboard &pb, const libsnark::pb_linear_combination &msg, const libsnark::pb_linear_combination &key, const libsnark::pb_variable &result, - const std::string &annotation_prefix = "MiMCe7_permutation_gadget"); + const std::string &annotation_prefix = "MiMC_permutation_gadget"); + + MiMC_permutation_gadget( + libsnark::protoboard &pb, + const libsnark::pb_linear_combination &msg, + const libsnark::pb_linear_combination &key, + const libsnark::pb_variable &result, + const libsnark::pb_linear_combination &add_to_result, + const std::string &annotation_prefix = "MiMC_permutation_gadget"); void generate_r1cs_constraints(); void generate_r1cs_witness() const; diff --git a/libzeth/circuits/mimc/mimc_permutation.tcc b/libzeth/circuits/mimc/mimc_permutation.tcc index 6eb7e7b9d..b9966c4ad 100644 --- a/libzeth/circuits/mimc/mimc_permutation.tcc +++ b/libzeth/circuits/mimc/mimc_permutation.tcc @@ -24,6 +24,8 @@ MiMC_permutation_gadget::MiMC_permutation_gadget( const libsnark::pb_linear_combination &msg, const libsnark::pb_linear_combination &key, const libsnark::pb_variable &result, + const libsnark::pb_linear_combination &add_to_result, + const bool have_add_to_result, const std::string &annotation_prefix) : libsnark::gadget(pb, annotation_prefix) { @@ -63,16 +65,61 @@ MiMC_permutation_gadget::MiMC_permutation_gadget( } // For last round, output to the result variable and add `key` to the - // result. + // result, along with any add_to_result. round_results[NumRounds - 1] = result; - round_gadgets.emplace_back( - this->pb, - round_results[NumRounds - 2], - key, - round_constants[NumRounds - 1], - round_results[NumRounds - 1], - key, - FMT(this->annotation_prefix, " round[%zu]", NumRounds - 1)); + + if (have_add_to_result) { + libsnark::pb_linear_combination key_plus_add_to_result; + key_plus_add_to_result.assign(this->pb, key + add_to_result); + round_gadgets.emplace_back( + this->pb, + round_results[NumRounds - 2], + key, + round_constants[NumRounds - 1], + round_results[NumRounds - 1], + key_plus_add_to_result, + FMT(this->annotation_prefix, " round[%zu]", NumRounds - 1)); + } else { + round_gadgets.emplace_back( + this->pb, + round_results[NumRounds - 2], + key, + round_constants[NumRounds - 1], + round_results[NumRounds - 1], + key, + FMT(this->annotation_prefix, " round[%zu]", NumRounds - 1)); + } +} + +template +MiMC_permutation_gadget::MiMC_permutation_gadget( + libsnark::protoboard &pb, + const libsnark::pb_linear_combination &msg, + const libsnark::pb_linear_combination &key, + const libsnark::pb_variable &result, + const std::string &annotation_prefix) + : MiMC_permutation_gadget( + pb, + msg, + key, + result, + libsnark::pb_linear_combination(), + false, + annotation_prefix) +{ +} + +template +MiMC_permutation_gadget::MiMC_permutation_gadget( + libsnark::protoboard &pb, + const libsnark::pb_linear_combination &msg, + const libsnark::pb_linear_combination &key, + const libsnark::pb_variable &result, + const libsnark::pb_linear_combination &add_to_result, + const std::string &annotation_prefix) + : MiMC_permutation_gadget( + pb, msg, key, result, add_to_result, true, annotation_prefix) +{ } template From 26021286ff5d2edb7642c48f6f372bf89dff8fb8 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 29 Apr 2021 13:08:45 +0100 Subject: [PATCH 128/137] libzeth: align mimc_mp gadget with description in zeth spec (remove unnecessary final constraint) --- libzeth/circuits/mimc/mimc_mp.hpp | 29 +++++++++++++++-------------- libzeth/circuits/mimc/mimc_mp.tcc | 29 ++++++++--------------------- 2 files changed, 23 insertions(+), 35 deletions(-) diff --git a/libzeth/circuits/mimc/mimc_mp.hpp b/libzeth/circuits/mimc/mimc_mp.hpp index b17578ec7..3933a8947 100644 --- a/libzeth/circuits/mimc/mimc_mp.hpp +++ b/libzeth/circuits/mimc/mimc_mp.hpp @@ -10,25 +10,26 @@ namespace libzeth { -/// This gadget implements the interface of the HashTreeT template +/// This gadget implements the interface of the HashTreeT template. /// -/// MiMC_mp_gadget enforces correct computation of MiMC compression function -/// based on a the Miyaguchi-Preneel compression construct and a +/// MiMC_mp_gadget enforces correct computation of the MiMC compression +/// function, based on a the Miyaguchi-Preneel compression construct using a /// MiMC_permutation_gadget instance, PermutationT, operating on FieldT /// elements. -template -class MiMC_mp_gadget : public libsnark::gadget +/// +/// This class contains only an instance of PermutationT, with parameters +/// configured to make it efficiently compute Miyaguchi-Preneel. As such, it +/// may appear as first sight that it should inherit from PermutationT. We do +/// not inherit from PermutationT, either publicly (because the "is-a" +/// relationship does not hold in general), or privately (because the +/// pb_linear_combination interface does not support immediate construction of +/// `x + y`, making the constructor very awkard - this is also the reason that +/// a pointer is required, rather than a simple instance of PermutationT). +/// Further, we do not inherit from libsnark::gadget<>, as it is not necessary +/// and would just add unused data to the class. +template class MiMC_mp_gadget { private: - // First input - libsnark::pb_linear_combination x; - // Second input - libsnark::pb_linear_combination y; - // Output variable - libsnark::pb_variable result; - // Permutation output - libsnark::pb_variable perm_output; - // Permutation gadget std::shared_ptr permutation_gadget; public: diff --git a/libzeth/circuits/mimc/mimc_mp.tcc b/libzeth/circuits/mimc/mimc_mp.tcc index ff66204f2..332dae5d7 100644 --- a/libzeth/circuits/mimc/mimc_mp.tcc +++ b/libzeth/circuits/mimc/mimc_mp.tcc @@ -17,41 +17,28 @@ MiMC_mp_gadget::MiMC_mp_gadget( const libsnark::pb_linear_combination &y, const libsnark::pb_variable &result, const std::string &annotation_prefix) - : libsnark::gadget(pb, annotation_prefix) - , x(x) - , y(y) - , result(result) { - perm_output.allocate(this->pb, FMT(annotation_prefix, " perm_output")); + // Adding x+y to the output of the permutation yields the Miyaguchi-Preneel + // equation: + // + // result = permutation(x, y) + x + y + + libsnark::pb_linear_combination x_plus_y; + x_plus_y.assign(pb, x + y); permutation_gadget.reset(new PermutationT( - pb, - x, - y, - perm_output, - FMT(this->annotation_prefix, " permutation_gadget"))); + pb, x, y, result, x_plus_y, FMT(annotation_prefix, " MP"))); } template void MiMC_mp_gadget::generate_r1cs_constraints() { - // Setting constraints for the permutation gadget permutation_gadget->generate_r1cs_constraints(); - - // Adding constraint for the Miyaguchi-Preneel equation - this->pb.add_r1cs_constraint( - libsnark::r1cs_constraint(perm_output + x + y, 1, result), - FMT(this->annotation_prefix, " out=k+E_k(m_i)+m_i")); } template void MiMC_mp_gadget::generate_r1cs_witness() const { - // Generating witness for the gadget permutation_gadget->generate_r1cs_witness(); - - // Filling output variables for Miyaguchi-Preenel equation - this->pb.val(result) = - this->pb.lc_val(y) + this->pb.val(perm_output) + this->pb.lc_val(x); } // Returns the hash of two elements From cebda64ee5f9d8506535f95533d3853b76112728 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Fri, 30 Apr 2021 11:12:48 +0100 Subject: [PATCH 129/137] update mimc constants in line with spec changes --- client/test_contracts/test_mimc_contract.py | 19 ++- client/tests/test_input_hasher.py | 16 +-- client/tests/test_merkle_tree.py | 8 +- client/tests/test_mimc.py | 38 ++--- client/zeth/core/mimc.py | 54 +++---- libzeth/circuits/circuit_types.hpp | 8 +- .../tests/circuits/mimc_input_hasher_test.cpp | 10 +- libzeth/tests/circuits/mimc_mp_test.cpp | 134 ++++++++++++++++-- .../contracts/AbstractMixerAltBN128.sol | 5 +- .../contracts/AbstractMixerBLS12_377.sol | 5 +- .../contracts/{LibMiMC7.sol => LibMiMC.sol} | 55 +++++-- zeth_contracts/contracts/LibMiMC31.sol | 80 ----------- ...MC7.sol => TestMerkleTreeMiMCAltBN128.sol} | 14 +- zeth_contracts/contracts/TestMiMC.sol | 21 +-- 14 files changed, 273 insertions(+), 194 deletions(-) rename zeth_contracts/contracts/{LibMiMC7.sol => LibMiMC.sol} (58%) delete mode 100644 zeth_contracts/contracts/LibMiMC31.sol rename zeth_contracts/contracts/{TestMerkleTreeMiMC7.sol => TestMerkleTreeMiMCAltBN128.sol} (69%) diff --git a/client/test_contracts/test_mimc_contract.py b/client/test_contracts/test_mimc_contract.py index 8d21306cb..3c9a5b78c 100644 --- a/client/test_contracts/test_mimc_contract.py +++ b/client/test_contracts/test_mimc_contract.py @@ -4,7 +4,7 @@ from zeth.core.utils import get_contracts_dir from zeth.core.contracts import InstanceDescription -from zeth.core.mimc import MiMC7, MiMC31 +from zeth.core.mimc import MiMCAltBN128, MiMCBLS12_377 from zeth.cli.utils import get_eth_network, open_web3_from_network from os.path import join from unittest import TestCase @@ -12,6 +12,11 @@ CONTRACT_INSTANCE: Any = None +""" +Test data here matches that used in test_mimc.py, which is also used in the +tests of mimc circuits. +""" + class TestMiMCContract(TestCase): @@ -30,22 +35,22 @@ def setUpClass() -> None: global CONTRACT_INSTANCE # pylint: disable=global-statement CONTRACT_INSTANCE = contract_instance_desc.instantiate(web3) - def test_mimc7(self) -> None: + def test_mimc_alt_bn128(self) -> None: # pylint: disable=line-too-long x = int(28948022309329048855892746252171976963317496166410141009864396001978282409983).to_bytes(32, 'big') # noqa y = int(14220067918847996031108144435763672811050758065945364308986253046354060608451).to_bytes(32, 'big') # noqa # pylint: enable=line-too-long - h = MiMC7().hash(x, y) + h = MiMCAltBN128().hash(x, y) - result = CONTRACT_INSTANCE.functions.testMimc7(x, y).call() + result = CONTRACT_INSTANCE.functions.testMimcAltBN128(x, y).call() self.assertEqual(h, result) - def test_mimc31(self) -> None: + def test_mimc_bls12_377(self) -> None: # pylint: disable=line-too-long x = int(28948022309329048855892746252171976963317496166410141009864396001978282409983).to_bytes(32, 'big') # noqa y = int(14220067918847996031108144435763672811050758065945364308986253046354060608451).to_bytes(32, 'big') # noqa # pylint: enable=line-too-long - h = MiMC31().hash(x, y) + h = MiMCBLS12_377().hash(x, y) - result = CONTRACT_INSTANCE.functions.testMimc31(x, y).call() + result = CONTRACT_INSTANCE.functions.testMimcBLS12_377(x, y).call() self.assertEqual(h, result) diff --git a/client/tests/test_input_hasher.py b/client/tests/test_input_hasher.py index 10043937e..cc7c4b99e 100644 --- a/client/tests/test_input_hasher.py +++ b/client/tests/test_input_hasher.py @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: LGPL-3.0+ -from zeth.core.mimc import MiMC7, MiMC31 +from zeth.core.mimc import MiMCAltBN128, MiMCBLS12_377 from zeth.core.input_hasher import InputHasher from unittest import TestCase @@ -13,7 +13,7 @@ class TestInputHasher(TestCase): def test_input_hasher_simple(self) -> None: # Some very simple cases - mimc = MiMC7() + mimc = MiMCAltBN128() input_hasher = InputHasher(mimc, 7) self.assertEqual(mimc.hash_int(7, 0), input_hasher.hash([])) self.assertEqual( @@ -25,20 +25,20 @@ def test_input_hasher_simple(self) -> None: 2), input_hasher.hash([1, 2])) - def test_input_hasher_mimc7(self) -> None: - mimc = MiMC7() + def test_input_hasher_mimc_alt_bn128(self) -> None: + mimc = MiMCAltBN128() input_hasher = InputHasher(mimc) values = [x % mimc.prime for x in DUMMY_INPUT_VALUES] # pylint:disable=line-too-long - expect = 5568471640435576440988459485125198359192118312228711462978763973844457667180 # noqa + expect = 1147542777914688064255377945014225852776952826405497760158376896026758431650 # noqa # pylint:enable=line-too-long self.assertEqual(expect, input_hasher.hash(values)) - def test_input_hasher_mimc31(self) -> None: - mimc = MiMC31() + def test_input_hasher_mimc_bls12_377(self) -> None: + mimc = MiMCBLS12_377() input_hasher = InputHasher(mimc) values = [x % mimc.prime for x in DUMMY_INPUT_VALUES] # pylint: disable=line-too-long - expect = 1029772481427643815119825324071277815354972734622711297984795198139876181749 # noqa + expect = 3481757288350338818975783012202519902801563645563026508811358096682731778741 # noqa # pylint: enable=line-too-long self.assertEqual(expect, input_hasher.hash(values)) diff --git a/client/tests/test_merkle_tree.py b/client/tests/test_merkle_tree.py index 85a0937e1..43e58a255 100644 --- a/client/tests/test_merkle_tree.py +++ b/client/tests/test_merkle_tree.py @@ -6,7 +6,7 @@ from zeth.core.merkle_tree import MerkleTree, PersistentMerkleTree, ZERO_ENTRY, \ compute_merkle_path from zeth.core.utils import extend_32bytes -from zeth.core.mimc import MiMC7 +from zeth.core.mimc import MiMCAltBN128 from os.path import exists, join from os import makedirs from shutil import rmtree @@ -16,7 +16,7 @@ MERKLE_TREE_TEST_DIR = "_merkle_tests" MERKLE_TREE_TEST_DEPTH = 4 MERKLE_TREE_TEST_NUM_LEAVES = pow(2, MERKLE_TREE_TEST_DEPTH) -MERKLE_TREE_HASH = MiMC7() +MERKLE_TREE_HASH = MiMCAltBN128() TEST_VALUES = [ extend_32bytes(i.to_bytes(1, 'big')) for i in range(1, MERKLE_TREE_TEST_NUM_LEAVES)] @@ -43,7 +43,7 @@ def test_combine(self) -> None: right = self._test_vector_to_bytes32( 15683951496311901749339509118960676303290224812129752890706581988986633412003) # noqa expect = self._test_vector_to_bytes32( - 16797922449555994684063104214233396200599693715764605878168345782964540311877) # noqa + 449619487941393604225985437455969025878050402333083242690002834641114429734) # noqa result = MERKLE_TREE_HASH.hash(left, right) self.assertEqual(expect, result) @@ -147,7 +147,7 @@ def _expected_empty(self) -> bytes: self.assertEqual(16, MERKLE_TREE_TEST_NUM_LEAVES) # Test vector generated by test_mimc.py return self._test_vector_to_bytes32( - 1792447880902456454889084480864374954299744757125100424674028184042059183092) # noqa + 20048582095008167683805983195827846276103487741417695738966466927999203944276) # noqa def _check_merkle_path( self, address: int, mkpath: List[str], mktree: MerkleTree) -> None: diff --git a/client/tests/test_mimc.py b/client/tests/test_mimc.py index d1a1ff8da..70ef0328d 100644 --- a/client/tests/test_mimc.py +++ b/client/tests/test_mimc.py @@ -2,7 +2,7 @@ # # SPDX-License-Identifier: LGPL-3.0+ -from zeth.core.mimc import MiMC7, MiMC31 +from zeth.core.mimc import MiMCAltBN128, MiMCBLS12_377 from unittest import TestCase # pylint: disable=line-too-long @@ -10,37 +10,41 @@ class TestMiMC(TestCase): - def test_mimc7_round(self) -> None: - mimc = MiMC7("Clearmatics") + def test_mimc_alt_bn128_round(self) -> None: + mimc = MiMCAltBN128("Clearmatics") msg = 340282366920938463463374607431768211456 key = 28948022309329048855892746252171976963317496166410141009864396001978282409983 # noqa round_const = 14220067918847996031108144435763672811050758065945364308986253046354060608451 # noqa - expect_result = 7970444205539657036866618419973693567765196138501849736587140180515018751924 # noqa + expect_result = 15194574649778181158537940501307832704788048781286507777438072456493095881604 # noqa self.assertEqual(expect_result, mimc.mimc_round(msg, key, round_const)) - def test_mimc7(self) -> None: - left = 28948022309329048855892746252171976963317496166410141009864396001978282409983 # noqa - right = 14220067918847996031108144435763672811050758065945364308986253046354060608451 # noqa - expect_result = 14404914332179247771191118015445305957789480573634910846417052002923707343766 # noqa - result = MiMC7().hash(_int_to_bytes(left), _int_to_bytes(right)) - self.assertEqual(_int_to_bytes(expect_result), result) + def test_mimc_alt_bn128_hash(self) -> None: + left = 340282366920938463463374607431768211456 + right = 28948022309329048855892746252171976963317496166410141009864396001978282409983 # noqa + expect_result = 14599678357063082723814206975733222579132256174923645170354481857040188426666 # noqa + result = MiMCAltBN128().hash(_int_to_bytes(left), _int_to_bytes(right)) + self.assertEqual(expect_result, _bytes_to_int(result)) - def test_mimc31_round(self) -> None: + def test_mimc_bls12_377_round(self) -> None: msg = 340282366920938463463374607431768211456 key = 3614637061043937583146271435827337369189798160947949526058695634226054692860 # noqa round_const = 5775606169419625606859319496982126279674858730791300481051019590436651369410 # noqa - expect_result = 5523634951166384704739554074217840169048851347397743343350526776025419511991 # noqa + expect_result = 706529233840138407487116494744828417642056684171152884149736992660816802274 # noqa self.assertEqual( - expect_result, MiMC31().mimc_round(msg, key, round_const)) + expect_result, MiMCBLS12_377().mimc_round(msg, key, round_const)) - def test_mimc31(self) -> None: + def test_mimc_bls12_377_hash(self) -> None: left = 3614637061043937583146271435827337369189798160947949526058695634226054692860 # noqa right = 5775606169419625606859319496982126279674858730791300481051019590436651369410 # noqa - expect_result = 7575204549404107478830739557698679330537656688050664462892741835534561279075 # noqa - result = MiMC31().hash(_int_to_bytes(left), _int_to_bytes(right)) - self.assertEqual(_int_to_bytes(expect_result), result) + expect_result = 5803106354831571205534057512593837953191890709037390680911925249983717812220 # noqa + result = MiMCBLS12_377().hash(_int_to_bytes(left), _int_to_bytes(right)) + self.assertEqual(expect_result, _bytes_to_int(result)) # pylint: enable=line-too-long def _int_to_bytes(value: int) -> bytes: return value.to_bytes(32, byteorder='big') + + +def _bytes_to_int(value: bytes) -> int: + return int.from_bytes(value, byteorder='big') diff --git a/client/zeth/core/mimc.py b/client/zeth/core/mimc.py index b05dc2648..9fd584fff 100644 --- a/client/zeth/core/mimc.py +++ b/client/zeth/core/mimc.py @@ -76,44 +76,46 @@ def mimc_round(self, message: int, key: int, rc: int) -> int: pass -class MiMC7(MiMCBase): +class MiMC17Base(MiMCBase): """ - MiMC specialized for Fr in ALT-BN128, in which the exponent is 7 and 91 - rounds are used. + Implementation of MiMCBase with exponent 17 + """ + def mimc_round(self, message: int, key: int, rc: int) -> int: + # May not be optimal to operate on huge numbers (256 * e bits). For + # reference, the manual version is below: + # a = (message + key + rc) % self.prime + # a_2 = (a * a) % self.prime + # a_4 = (a_2 * a_2) % self.prime + # a_8 = (a_4 * a_4) % self.prime + # a_16 = (a_8 * a_8) % self.prime + # return (a_16 * a) % self.prime + return ((message + key + rc) ** 17) % self.prime + + +class MiMCAltBN128(MiMC17Base): + """ + MiMC specialized for Fr in ALT-BN128, using exponent 17 and 65 rounds. See + zeth specifications (Section 3.2) for details. """ def __init__(self, seed_str: str = MIMC_MT_SEED): - MiMCBase.__init__( - self, + super().__init__( seed_str, 21888242871839275222246405745257275088548364400416034343698204186575808495617, # noqa # pylint: disable=line-too-long - 91) + 65) - def mimc_round(self, message: int, key: int, rc: int) -> int: - xored = (message + key + rc) % self.prime - return xored ** 7 % self.prime +class MiMCBLS12_377(MiMC17Base): # pylint: disable=invalid-name -class MiMC31(MiMCBase): """ - MiMC implementation using exponent of 31 and 51 rounds. Note that this is - suitable for BLS12-377, since 31=2^5-1, and 1 == gcd(31, r-1). See - [AGRRT16] for details. + MiMC specialized for Fr in BLS12-377, using exponent 17 and 62 rounds. See + zeth specifications (Section 3.2) for details. """ def __init__(self, seed_str: str = MIMC_MT_SEED): - MiMCBase.__init__( - self, + super().__init__( seed_str, 8444461749428370424248824938781546531375899335154063827935233455917409239041, # noqa - 51) - - def mimc_round(self, message: int, key: int, rc: int) -> int: - a = (message + key + rc) % self.prime - a_2 = (a * a) % self.prime - a_4 = (a_2 * a_2) % self.prime - a_8 = (a_4 * a_4) % self.prime - a_16 = (a_8 * a_8) % self.prime - return (a_16 * a_8 * a_4 * a_2 * a) % self.prime + 62) def get_tree_hash_for_pairing(pairing_name: str) -> ITreeHash: @@ -122,9 +124,9 @@ def get_tree_hash_for_pairing(pairing_name: str) -> ITreeHash: the selection logic in `libzeth/circuits/circuit_types.hpp`. """ if pairing_name == "alt-bn128": - return MiMC7() + return MiMCAltBN128() if pairing_name == "bls12-377": - return MiMC31() + return MiMCBLS12_377() raise Exception(f"no tree hash for pairing: {pairing_name}") diff --git a/libzeth/circuits/circuit_types.hpp b/libzeth/circuits/circuit_types.hpp index fe2817fe4..e8b02c923 100644 --- a/libzeth/circuits/circuit_types.hpp +++ b/libzeth/circuits/circuit_types.hpp @@ -28,22 +28,22 @@ template class tree_hash_selector { }; -// For alt-bn128, use MiMC7 with 91 rounds +// For alt-bn128, use MiMC17 with 65 rounds. template<> class tree_hash_selector { public: using tree_hash = MiMC_mp_gadget< libff::alt_bn128_Fr, - MiMC_permutation_gadget>; + MiMC_permutation_gadget>; }; -// For bls12-377, use MiMC31 with 51 rounds +// For bls12-377, use MiMC17 with 62 rounds template<> class tree_hash_selector { public: using tree_hash = MiMC_mp_gadget< libff::bls12_377_Fr, - MiMC_permutation_gadget>; + MiMC_permutation_gadget>; }; // Hash function to be used in the Merkle Tree diff --git a/libzeth/tests/circuits/mimc_input_hasher_test.cpp b/libzeth/tests/circuits/mimc_input_hasher_test.cpp index 0c8e706f4..0f5669910 100644 --- a/libzeth/tests/circuits/mimc_input_hasher_test.cpp +++ b/libzeth/tests/circuits/mimc_input_hasher_test.cpp @@ -19,11 +19,11 @@ using input_hasher = libzeth::mimc_input_hasher; TEST(MiMCInputHasherTest, SimpleInputValues) { - // Test data generated as follows: + // Test data generated by test_input_hasher_mimc_bls12_377: // $ python - // >>> from zeth.core.mimc import MiMC31 + // >>> from zeth.core.mimc import MiMCBLS12_377 // >>> from zeth.core.input_hasher import InputHasher - // >>> InputHasher(MiMC31()).hash([0,1,-1,2,-2]) + // >>> InputHasher(MiMCBLS12_377()).hash([0,1,-1,2,-2]) const std::vector simple_values{{ Field::zero(), Field::one(), @@ -31,8 +31,8 @@ TEST(MiMCInputHasherTest, SimpleInputValues) Field("2"), -Field("2"), }}; - const Field expect_hash("47690627216444699952391427631776755329098419241452" - "8676152606007181154538262"); + const Field expect_hash("24413724837428607704066638210762875107426186849414" + "55909840195654797701248623"); libsnark::protoboard pb; diff --git a/libzeth/tests/circuits/mimc_mp_test.cpp b/libzeth/tests/circuits/mimc_mp_test.cpp index 65d4a444f..809a96e57 100644 --- a/libzeth/tests/circuits/mimc_mp_test.cpp +++ b/libzeth/tests/circuits/mimc_mp_test.cpp @@ -13,11 +13,15 @@ using namespace libzeth; template using MiMCe7_round_gadget = MiMC_round_gadget; template -using MiMCe31_round_gadget = MiMC_round_gadget; -template using MiMCe7_permutation_gadget = MiMC_permutation_gadget; template -using MiMCe31_permutation_gadget = MiMC_permutation_gadget; +using MiMCe17_round_gadget = MiMC_round_gadget; +template +using MiMCe17_ALT_BN128_permutation_gadget = + MiMC_permutation_gadget; +template +using MiMCe17_BLS12_377_permutation_gadget = + MiMC_permutation_gadget; // Test data here specialized for alt_bn128 using pp = libff::alt_bn128_pp; @@ -243,11 +247,123 @@ TEST(TestMiMC, MiMC7MpIncorrect) ASSERT_FALSE(unexpected_out == pb.val(result)); } -TEST(TestMiMC, TestMiMC31) +// Testing that (15212 + 98645 + 216319)**7 = +// 427778066313557225181231220812180094976 +TEST(TestMiMC, MiMC17_ALT_BN128_Round) +{ + using Field = libff::alt_bn128_Fr; + + libsnark::protoboard pb; + libsnark::pb_variable in_x; + libsnark::pb_variable in_k; + libsnark::pb_variable result; + + in_x.allocate(pb, "x"); + in_k.allocate(pb, "k"); + result.allocate(pb, "result"); + + // Test data from client test (test_mimc_alt_bn128_round), to ensure + // consistency between implementations. + + pb.val(in_x) = Field("340282366920938463463374607431768211456"); + pb.val(in_k) = Field("28948022309329048855892746252171976963317496166410141" + "009864396001978282409983"); + Field in_C = Field("1422006791884799603110814443576367281105075806594536430" + "8986253046354060608451"); + + MiMCe17_round_gadget round_gadget( + pb, in_x, in_k, in_C, result, "round_gadget"); + round_gadget.generate_r1cs_constraints(); + round_gadget.generate_r1cs_witness(); + + Field expected_out = Field("15194574649778181158537940501307832704788048781" + "286507777438072456493095881604"); + ASSERT_TRUE(pb.is_satisfied()); + ASSERT_TRUE(expected_out == pb.val(result)); +} + +TEST(TestMiMC, MiMC17_ALT_BN128_MP) +{ + using Field = libff::alt_bn128_Fr; + + // Test data from client test (test_mimc_alt_bn128_hash), to ensure + // consistency between implementations. + + const Field m_val("340282366920938463463374607431768211456"); + const Field k_val("28948022309329048855892746252171976963317496166410141009" + "864396001978282409983"); + const Field h_val("14599678357063082723814206975733222579132256174923645170" + "354481857040188426666"); + + libsnark::protoboard pb; + + // Public input + libsnark::pb_variable k; + k.allocate(pb, "k"); + pb.set_input_sizes(1); + pb.val(k) = k_val; + + // Private inputs + libsnark::pb_variable m; + m.allocate(pb, "m"); + pb.val(m) = m_val; + + libsnark::pb_variable h; + h.allocate(pb, "h"); + + MiMC_mp_gadget> + mimc_mp_gadget(pb, m, k, h, "mimc_mp"); + mimc_mp_gadget.generate_r1cs_constraints(); + mimc_mp_gadget.generate_r1cs_witness(); + + // Check that the circuit is satisfied, and that the expected result is + // generated. + ASSERT_TRUE(pb.is_satisfied()); + ASSERT_EQ(h_val, pb.val(h)); +} + +// Testing that (15212 + 98645 + 216319)**7 = +// 427778066313557225181231220812180094976 +TEST(TestMiMC, MiMC17_BLS12_377_Round) { using Field = libff::bls12_377_Fr; - // Test data from client test + libsnark::protoboard pb; + libsnark::pb_variable in_x; + libsnark::pb_variable in_k; + libsnark::pb_variable result; + + in_x.allocate(pb, "x"); + in_k.allocate(pb, "k"); + result.allocate(pb, "result"); + + // Test data from client test (test_mimc_bls12_377_round), to ensure + // consistency between implementations. + + pb.val(in_x) = Field("340282366920938463463374607431768211456"); + pb.val(in_k) = Field("36146370610439375831462714358273373691897981609479495" + "26058695634226054692860"); + Field in_C = Field("5775606169419625606859319496982126279674858730791300481" + "051019590436651369410"); + + MiMCe17_round_gadget round_gadget( + pb, in_x, in_k, in_C, result, "round_gadget"); + round_gadget.generate_r1cs_constraints(); + round_gadget.generate_r1cs_witness(); + + Field expected_out = Field("70652923384013840748711649474482841764205668417" + "1152884149736992660816802274"); + ASSERT_TRUE(pb.is_satisfied()); + ASSERT_EQ(expected_out, pb.val(result)); +} + +TEST(TestMiMC, MiMC17_BLS12_377_MP) +{ + using Field = libff::bls12_377_Fr; + + // Test data from client test (test_mimc_bls12_377_hash), to ensure + // consistency between implementations. + const Field m_val( "361463706104393758314627143582733736918979816094794952605869" "5634226054692860"); @@ -255,8 +371,8 @@ TEST(TestMiMC, TestMiMC31) "577560616941962560685931949698212627967485873079130048105101" "9590436651369410"); const Field h_val( - "757520454940410747883073955769867933053765668805066446289274" - "1835534561279075"); + "580310635483157120553405751259383795319189070903739068091192" + "5249983717812220"); libsnark::protoboard pb; @@ -274,8 +390,8 @@ TEST(TestMiMC, TestMiMC31) libsnark::pb_variable h; h.allocate(pb, "h"); - MiMC_mp_gadget> mimc_mp_gadget( - pb, m, k, h, "mimc_mp"); + MiMC_mp_gadget> + mimc_mp_gadget(pb, m, k, h, "mimc_mp"); mimc_mp_gadget.generate_r1cs_constraints(); mimc_mp_gadget.generate_r1cs_witness(); diff --git a/zeth_contracts/contracts/AbstractMixerAltBN128.sol b/zeth_contracts/contracts/AbstractMixerAltBN128.sol index d68802fa9..1769b5830 100644 --- a/zeth_contracts/contracts/AbstractMixerAltBN128.sol +++ b/zeth_contracts/contracts/AbstractMixerAltBN128.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.0; import "./AbstractMixer.sol"; -import "./LibMiMC7.sol"; +import "./LibMiMC.sol"; /// Partial implementation of AbstractMixer which implements the /// curve-specific methods to use the ALT-BN128 pairing. @@ -39,14 +39,13 @@ abstract contract AbstractMixerAltBN128 is AbstractMixer { } - /// Use MiMC7 as the Merkle tree hash function. function _hash(bytes32 left, bytes32 right) internal pure override returns(bytes32) { - return LibMiMC7._hash(left, right); + return LibMiMC._hashAltBN128(left, right); } /// Utility function to extract a full uint256 from a field element and the diff --git a/zeth_contracts/contracts/AbstractMixerBLS12_377.sol b/zeth_contracts/contracts/AbstractMixerBLS12_377.sol index a8672d71a..acf9da926 100644 --- a/zeth_contracts/contracts/AbstractMixerBLS12_377.sol +++ b/zeth_contracts/contracts/AbstractMixerBLS12_377.sol @@ -5,7 +5,7 @@ pragma solidity ^0.8.0; import "./AbstractMixer.sol"; -import "./LibMiMC31.sol"; +import "./LibMiMC.sol"; /// Partial implementation of AbstractMixer which implements the /// curve-specific methods to use the BLS12-377 pairing. @@ -46,14 +46,13 @@ abstract contract AbstractMixerBLS12_377 is AbstractMixer { } - /// Use MiMC31 as the Merkle tree hash function. function _hash(bytes32 left, bytes32 right) internal pure override returns(bytes32) { - return LibMiMC31._hash(left, right); + return LibMiMC._hashBLS12_377(left, right); } /// Extract a full uint256 from a field element and the n-th set of diff --git a/zeth_contracts/contracts/LibMiMC7.sol b/zeth_contracts/contracts/LibMiMC.sol similarity index 58% rename from zeth_contracts/contracts/LibMiMC7.sol rename to zeth_contracts/contracts/LibMiMC.sol index a7a4cd3b8..bd18ffb6e 100644 --- a/zeth_contracts/contracts/LibMiMC7.sol +++ b/zeth_contracts/contracts/LibMiMC.sol @@ -16,12 +16,45 @@ pragma solidity ^0.8.0; /// Section: "Miyaguchi–Preneel" // solhint-disable-next-line max-line-length /// -library LibMiMC7 +/// +/// \[ZETHSPEC]: +/// "Zeth Protocol Specification", Clearmatics R&D, +/// +library LibMiMC { - function _hash(bytes32 x, bytes32 y) internal pure returns (bytes32 out) { - // See [AGRRT16]: + function _hashAltBN128(bytes32 x, bytes32 y) + internal + pure + returns (bytes32 out) { + // Use exponent 17 over 65 rounds (see [ZETHSPEC]) + return _hash_e17( + x, + y, + // solhint-disable-next-line max-line-length + 21888242871839275222246405745257275088548364400416034343698204186575808495617, + 65); + } + + function _hashBLS12_377(bytes32 x, bytes32 y) + internal + pure + returns (bytes32 out) { + // Use exponent 17 over 62 rounds (see [ZETHSPEC]) + return _hash_e17( + x, + y, + // solhint-disable-next-line max-line-length + 8444461749428370424248824938781546531375899335154063827935233455917409239041, + 62); + } + + function _hash_e17(bytes32 x, bytes32 y, uint256 r, uint8 rounds) + private + pure + returns (bytes32 out) { + // See [AGRRT16] and [ZETHSPEC]: // The round function is: - // F_i(a, key, rc_i) -> a^7 + key + rc + // F_i(a, key, rc_i) -> a^17 + key + rc // // where: // rc_0 = 0 @@ -32,20 +65,20 @@ library LibMiMC7 assembly { - // solhint-disable-next-line max-line-length - let r := 21888242871839275222246405745257275088548364400416034343698204186575808495617 - // Perform round 0 with x + y (rc = 0 in first round) let a := addmod(x, y, r) let a2 := mulmod(a, a, r) - a := mulmod(mulmod(mulmod(a2, a2, r), a2, r), a, r) + let a4 := mulmod(a2, a2, r) + let a8 := mulmod(a4, a4, r) + a := mulmod(mulmod(a8, a8, r), a, r) // Write round constant seed to pad at 0x00, where keccak256 will // be applied iteratively // solhint-disable-next-line max-line-length mstore(0x0, 0xdec937b7fa8db3de380427a8cc947bfab68514522c3439cfa2e9965509836814) - for {let j := 0} slt(j, 90) {j := add(j,1)} { + rounds := sub(rounds, 1) + for {let j := 0} slt(j, rounds) {j := add(j,1)} { // roundConstant = H(roundConstant); // Derive the (round) constants by iterative hash on the seed @@ -55,7 +88,9 @@ library LibMiMC7 // a = (outPermutation + roundConstant + key) ^ 7 mod r a := addmod(addmod(a, roundConstant, r), y, r) a2 := mulmod(a, a, r) - a := mulmod(mulmod(mulmod(a2, a2, r), a2, r), a, r) + a4 := mulmod(a2, a2, r) + a8 := mulmod(a4, a4, r) + a := mulmod(mulmod(a8, a8, r), a, r) } // In MiMC, the final round output is summed with the round key diff --git a/zeth_contracts/contracts/LibMiMC31.sol b/zeth_contracts/contracts/LibMiMC31.sol deleted file mode 100644 index 9239cff13..000000000 --- a/zeth_contracts/contracts/LibMiMC31.sol +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2015-2021 Clearmatics Technologies Ltd -// -// SPDX-License-Identifier: LGPL-3.0+ - -pragma solidity ^0.8.0; - -/// Reference papers: -/// -/// \[AGRRT16]: -/// "MiMC: Efficient Encryption and Cryptographic Hashing with Minimal -/// Multiplicative Complexity", Martin Albrecht, Lorenzo Grassi, Christian -/// Rechberger, Arnab Roy, and Tyge Tiessen, ASIACRYPT 2016, -/// -/// -/// "One-way compression function" -/// Section: "Miyaguchi–Preneel" -// solhint-disable-next-line max-line-length -/// -/// -/// Implementation of MiMC hash targeting BLS12-377 Fr. This means: -// solhint-disable-next-line max-line-length -/// r = 8444461749428370424248824938781546531375899335154063827935233455917409239041 -/// e (exponent) = 31, so that e=2^t-1 (t=5) and 1 == gcd(e, r-1) -/// rounds = 51 -/// -/// See LibMiMC7.sol for details. -library LibMiMC31 -{ - function _hash(bytes32 x, bytes32 y) internal pure returns(bytes32 out) { - // Round function (see [AGRRT16]): - // F_i(a, key, rc_i) -> (a + key + rc)^31 - // - // where: - // rc_0 = 0 - // rc_1 = keccak(seed) - // rc_i = keccak(rc_{i-1}), for i = 2, ... - - assembly - { - // solhint-disable-next-line max-line-length - let r := 8444461749428370424248824938781546531375899335154063827935233455917409239041 - - // Perform round 0, in which rc = 0 - let a := addmod(x, y, r) - let a2 := mulmod(a, a, r) - let a4 := mulmod(a2, a2, r) - let a8 := mulmod(a4, a4, r) - let a16 := mulmod(a8, a8, r) - a := mulmod(mulmod(mulmod(mulmod(a16, a8, r), a4, r), a2, r), a, r) - - // Write round constant seed to pad at 0x00, where keccak256 will - // be applied iteratively - // solhint-disable-next-line max-line-length - mstore(0x0, 0xdec937b7fa8db3de380427a8cc947bfab68514522c3439cfa2e9965509836814) - - for {let i := 0} slt(i, 50) {i := add(i,1)} { - - // Compute rc_i, and store it back in the pad - let roundConstant := keccak256(0x0, 32) - mstore(0x0, roundConstant) - - // Apply F_i - a := addmod(addmod(a, roundConstant, r), y, r) - a2 := mulmod(a, a, r) - a4 := mulmod(a2, a2, r) - a8 := mulmod(a4, a4, r) - a16 := mulmod(a8, a8, r) - a := mulmod( - mulmod(mulmod(mulmod(a16, a8, r), a4, r), a2, r), a, r) - } - - // Sum output with key, as described in [AGRRT16]. - a := addmod(a, y, r) - - // Myjaguchi-Preneel OWCF is then applied, which adds the key and - // message to the output of MiMC. - out := addmod(addmod(a, x, r), y, r) - } - } -} diff --git a/zeth_contracts/contracts/TestMerkleTreeMiMC7.sol b/zeth_contracts/contracts/TestMerkleTreeMiMCAltBN128.sol similarity index 69% rename from zeth_contracts/contracts/TestMerkleTreeMiMC7.sol rename to zeth_contracts/contracts/TestMerkleTreeMiMCAltBN128.sol index 4d69f9524..0114bf36e 100644 --- a/zeth_contracts/contracts/TestMerkleTreeMiMC7.sol +++ b/zeth_contracts/contracts/TestMerkleTreeMiMCAltBN128.sol @@ -5,15 +5,10 @@ pragma solidity ^0.8.0; import "./AbstractMerkleTree.sol"; -import "./LibMiMC7.sol"; +import "./LibMiMC.sol"; -/// The Merkle tree implementation must trade-off complexity, storage, -/// initialization cost, and update & root computation cost. -/// -/// This implementation stores all leaves and nodes, skipping those that have -/// not been populated yet. The final entry in each layer stores that layer's -/// default value. -contract TestMerkleTreeMiMC7 is AbstractMerkleTree +/// Implementation of AbstractMerkleTree for testing. +contract TestMerkleTreeMiMCAltBN128 is AbstractMerkleTree { constructor(uint treeDepth) AbstractMerkleTree(treeDepth) { @@ -42,13 +37,12 @@ contract TestMerkleTreeMiMC7 is AbstractMerkleTree return root; } - /// Use MiMC7 as the Merkle tree hash function. function _hash(bytes32 left, bytes32 right) internal pure override returns(bytes32) { - return LibMiMC7._hash(left, right); + return LibMiMC._hashAltBN128(left, right); } } diff --git a/zeth_contracts/contracts/TestMiMC.sol b/zeth_contracts/contracts/TestMiMC.sol index fd0e4168d..e02226f20 100644 --- a/zeth_contracts/contracts/TestMiMC.sol +++ b/zeth_contracts/contracts/TestMiMC.sol @@ -4,19 +4,24 @@ pragma solidity ^0.8.0; -import "./LibMiMC7.sol"; -import "./LibMiMC31.sol"; +import "./LibMiMC.sol"; /// Contract to test the MiMC libraries contract TestMiMC { - /// Test function for LibMiMC7 - function testMimc7(bytes32 x, bytes32 y) external pure returns (bytes32) { - return LibMiMC7._hash(x, y); + /// Test function for LibMiMC._hashAltBN128 + function testMimcAltBN128(bytes32 x, bytes32 y) + external + pure + returns (bytes32) { + return LibMiMC._hashAltBN128(x, y); } - /// Test function for LibMiMC31 - function testMimc31(bytes32 x, bytes32 y) external pure returns (bytes32) { - return LibMiMC31._hash(x, y); + /// Test function for LibMiMC._hashBLS12_377 + function testMimcBLS12_377(bytes32 x, bytes32 y) + external + pure + returns (bytes32) { + return LibMiMC._hashBLS12_377(x, y); } } From d2ffa777966a49e66505d418b593cac4dce2d261 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 4 May 2021 10:32:14 +0100 Subject: [PATCH 130/137] libff: use e=17 in mimc tests, and check circuit non-satifiability for incorrect results --- client/zeth/core/mimc.py | 1 - libzeth/tests/circuits/mimc_mp_test.cpp | 242 ++++++++++-------------- 2 files changed, 101 insertions(+), 142 deletions(-) diff --git a/client/zeth/core/mimc.py b/client/zeth/core/mimc.py index 9fd584fff..8585cf519 100644 --- a/client/zeth/core/mimc.py +++ b/client/zeth/core/mimc.py @@ -106,7 +106,6 @@ def __init__(self, seed_str: str = MIMC_MT_SEED): class MiMCBLS12_377(MiMC17Base): # pylint: disable=invalid-name - """ MiMC specialized for Fr in BLS12-377, using exponent 17 and 62 rounds. See zeth specifications (Section 3.2) for details. diff --git a/libzeth/tests/circuits/mimc_mp_test.cpp b/libzeth/tests/circuits/mimc_mp_test.cpp index 809a96e57..6c692d974 100644 --- a/libzeth/tests/circuits/mimc_mp_test.cpp +++ b/libzeth/tests/circuits/mimc_mp_test.cpp @@ -10,10 +10,6 @@ using namespace libzeth; -template -using MiMCe7_round_gadget = MiMC_round_gadget; -template -using MiMCe7_permutation_gadget = MiMC_permutation_gadget; template using MiMCe17_round_gadget = MiMC_round_gadget; template @@ -23,41 +19,46 @@ template using MiMCe17_BLS12_377_permutation_gadget = MiMC_permutation_gadget; -// Test data here specialized for alt_bn128 -using pp = libff::alt_bn128_pp; -using Field = libff::Fr; - namespace { -// Testing that (15212 + 98645 + 216319)**7 = -// 427778066313557225181231220812180094976 -TEST(TestMiMC, MiMC7Round) +TEST(TestMiMC, MiMC17_ALT_BN128_Round) { + using Field = libff::alt_bn128_Fr; + libsnark::protoboard pb; libsnark::pb_variable in_x; libsnark::pb_variable in_k; libsnark::pb_variable result; - Field in_C = Field("216319"); in_x.allocate(pb, "x"); in_k.allocate(pb, "k"); - pb.val(in_x) = Field("15212"); - pb.val(in_k) = Field("98645"); - result.allocate(pb, "result"); - MiMCe7_round_gadget round_gadget( + + // Test data from client test (test_mimc.py), to ensure consistency between + // implementations. + + pb.val(in_x) = Field("340282366920938463463374607431768211456"); + pb.val(in_k) = Field("28948022309329048855892746252171976963317496166410141" + "009864396001978282409983"); + Field in_C = Field("1422006791884799603110814443576367281105075806594536430" + "8986253046354060608451"); + + MiMCe17_round_gadget round_gadget( pb, in_x, in_k, in_C, result, "round_gadget"); round_gadget.generate_r1cs_constraints(); round_gadget.generate_r1cs_witness(); - Field expected_out = Field("427778066313557225181231220812180094976"); + Field expected_out = Field("15194574649778181158537940501307832704788048781" + "286507777438072456493095881604"); ASSERT_TRUE(pb.is_satisfied()); ASSERT_TRUE(expected_out == pb.val(result)); } -TEST(TestMiMC, MiMC7RoundIncorrect) +TEST(TestMiMC, MiMC17_ALT_BN128_Round_Incorrect) { + using Field = libff::alt_bn128_Fr; + libsnark::protoboard pb; libsnark::pb_variable in_x; libsnark::pb_variable in_k; @@ -70,25 +71,32 @@ TEST(TestMiMC, MiMC7RoundIncorrect) pb.val(in_k) = Field("98645"); result.allocate(pb, "result"); - MiMCe7_round_gadget round_gadget( + MiMCe17_round_gadget round_gadget( pb, in_x, in_k, in_C, result, "round_gadget"); round_gadget.generate_r1cs_constraints(); round_gadget.generate_r1cs_witness(); - Field unexpected_out = Field("427778066313557225181231220812180094976"); - ASSERT_TRUE(pb.is_satisfied()); - ASSERT_FALSE(unexpected_out == pb.val(result)); + // Force incorrect result value and check that circuit is not satisfied. + pb.val(result) = Field("427778066313557225181231220812180094976"); + ASSERT_FALSE(pb.is_satisfied()); } -// Testing that (15212 + 98645 + 216319)**7 + 98645 = -// 427778066313557225181231220812180193621 -TEST(TestMiMC, MiMC7RoundAddToResult) +TEST(TestMiMC, MiMC17_ALT_BN128_Round_AddToResult) { + using Field = libff::alt_bn128_Fr; + libsnark::protoboard pb; libsnark::pb_variable in_x; libsnark::pb_variable in_k; libsnark::pb_variable result; + // Test data generated by: + // $ python + // >>> r = + // 21888242871839275222246405745257275088548364400416034343698204186575808495617 + // >>> ((15212 + 98645 + 216319)**17) % r + 98645 + // 15395941923199146769662515429975727210847361451765447661089541693078496064650 + Field in_C = Field("216319"); in_x.allocate(pb, "x"); in_k.allocate(pb, "k"); @@ -96,18 +104,21 @@ TEST(TestMiMC, MiMC7RoundAddToResult) pb.val(in_k) = Field("98645"); result.allocate(pb, "result"); - MiMCe7_round_gadget round_gadget( + MiMCe17_round_gadget round_gadget( pb, in_x, in_k, in_C, result, in_k, "round_gadget"); round_gadget.generate_r1cs_constraints(); round_gadget.generate_r1cs_witness(); - Field expected_out = Field("427778066313557225181231220812180193621"); + Field expected_out = Field("15395941923199146769662515429975727210847361451" + "765447661089541693078496064650"); ASSERT_TRUE(pb.is_satisfied()); ASSERT_TRUE(expected_out == pb.val(result)); } -TEST(TestMiMC, MiMC7RoundAddToResultIncorrect) +TEST(TestMiMC, MiMC17_ALT_BN128_Round_AddToResult_Incorrect) { + using Field = libff::alt_bn128_Fr; + libsnark::protoboard pb; libsnark::pb_variable in_x; libsnark::pb_variable in_k; @@ -120,18 +131,20 @@ TEST(TestMiMC, MiMC7RoundAddToResultIncorrect) pb.val(in_k) = Field("98645"); result.allocate(pb, "result"); - MiMCe7_round_gadget round_gadget( + MiMCe17_round_gadget round_gadget( pb, in_x, in_k, in_C, result, in_k, "round_gadget"); round_gadget.generate_r1cs_constraints(); round_gadget.generate_r1cs_witness(); - Field unexpected_out = Field("427778066313557225181231220812180193621"); - ASSERT_TRUE(pb.is_satisfied()); - ASSERT_FALSE(unexpected_out == pb.val(result)); + // Force incorrect result value and check that circuit is not satisfied. + pb.val(result) = Field("427778066313557225181231220812180193621"); + ASSERT_FALSE(pb.is_satisfied()); } -TEST(TestMiMC, MiMC7Perm) +TEST(TestMiMC, MiMC17_ALT_BN128_Permutation) { + using Field = libff::alt_bn128_Fr; + libsnark::protoboard pb; libsnark::pb_variable in_x; @@ -141,24 +154,34 @@ TEST(TestMiMC, MiMC7Perm) in_k.allocate(pb, "k"); result.allocate(pb, "result"); + // Test data generated: + // $ python + // >>> import zeth.core.mimc + // >>> MiMCAltBN128().encrypt( + // 3703141493535563179657531719960160174296085208671919316200479060314459804651, + // 15683951496311901749339509118960676303290224812129752890706581988986633412003) + // 2950769369933203897475350343792407636840104781947445379481145971915829708697 + pb.val(in_x) = Field("3703141493535563179657531719960160174296085208671919" "316200479060314459804651"); pb.val(in_k) = Field("1568395149631190174933950911896067630329022481212975" "2890706581988986633412003"); - MiMC_permutation_gadget mimc_gadget( + MiMCe17_ALT_BN128_permutation_gadget mimc_perm_gadget( pb, in_x, in_k, result, "mimc_gadget"); - mimc_gadget.generate_r1cs_constraints(); - mimc_gadget.generate_r1cs_witness(); + mimc_perm_gadget.generate_r1cs_constraints(); + mimc_perm_gadget.generate_r1cs_witness(); - Field expected_out = Field("192990723315478049773124691205698348115617480" - "95378968014959488920239255590840"); + Field expected_out = Field("29507693699332038974753503437924076368401047819" + "47445379481145971915829708697"); ASSERT_TRUE(pb.is_satisfied()); ASSERT_TRUE(expected_out == pb.val(result)); } -TEST(TestMiMC, MiMC7PermIncorrect) +TEST(TestMiMC, MiMC17_ALT_BN128_Permutation_Incorrect) { + using Field = libff::alt_bn128_Fr; + libsnark::protoboard pb; libsnark::pb_variable in_x; @@ -172,128 +195,67 @@ TEST(TestMiMC, MiMC7PermIncorrect) "316200479060314459804651"); pb.val(in_k) = Field("13455131405143248756924738814405142"); - MiMCe7_permutation_gadget mimc_gadget( + MiMCe17_ALT_BN128_permutation_gadget mimc_gadget( pb, in_x, in_k, result, "mimc_gadget"); mimc_gadget.generate_r1cs_constraints(); mimc_gadget.generate_r1cs_witness(); - Field unexpected_out = Field("1929907233154780497731246912056983481156174" - "8095378968014959488920239255590840"); - ASSERT_TRUE(pb.is_satisfied()); - ASSERT_FALSE(unexpected_out == pb.val(result)); + // Force invalid result + pb.val(result) = Field("1929907233154780497731246912056983481156174" + "8095378968014959488920239255590840"); + ASSERT_FALSE(pb.is_satisfied()); } -TEST(TestMiMC, MiMC7Mp) +TEST(TestMiMC, MiMC17_ALT_BN128_MP) { - libsnark::protoboard pb; - - // Public input - libsnark::pb_variable y; - y.allocate(pb, "y"); - pb.set_input_sizes(1); - - // y = sha3_256("mimc") - pb.val(y) = Field("1568395149631190174933950911896067630329022481212975289" - "0706581988986633412003"); - - // Private inputs - libsnark::pb_variable x; - x.allocate(pb, "x"); - pb.val(x) = Field("3703141493535563179657531719960160174296085208671919316" - "200479060314459804651"); - - libsnark::pb_variable result; - result.allocate(pb, "result"); + using Field = libff::alt_bn128_Fr; - MiMC_mp_gadget> mimc_mp_gadget( - pb, x, y, result, "gadget"); - mimc_mp_gadget.generate_r1cs_constraints(); - mimc_mp_gadget.generate_r1cs_witness(); + // Test data from client test (test_mimc.py), to ensure consistency between + // implementations. - Field expected_out = Field("167979224495559946840631042142333962005996937" - "15764605878168345782964540311877"); - ASSERT_TRUE(pb.is_satisfied()); - ASSERT_TRUE(expected_out == pb.val(result)); -} + const Field m_val("340282366920938463463374607431768211456"); + const Field k_val("28948022309329048855892746252171976963317496166410141009" + "864396001978282409983"); + const Field h_val("14599678357063082723814206975733222579132256174923645170" + "354481857040188426666"); -TEST(TestMiMC, MiMC7MpIncorrect) -{ libsnark::protoboard pb; // Public input - libsnark::pb_variable y; - y.allocate(pb, "y"); + libsnark::pb_variable k; + k.allocate(pb, "k"); pb.set_input_sizes(1); - pb.val(y) = Field("8272473133185905403731511349671041314111289765433456653" - "2528783843265082629790"); + pb.val(k) = k_val; // Private inputs - libsnark::pb_variable x; - x.allocate(pb, "x"); - pb.val(x) = Field("3703141493535563179657531719960160174296085208671919316" - "200479060314459804651"); + libsnark::pb_variable m; + m.allocate(pb, "m"); + pb.val(m) = m_val; - libsnark::pb_variable result; - result.allocate(pb, "result"); + libsnark::pb_variable h; + h.allocate(pb, "h"); - MiMC_mp_gadget> mimc_mp_gadget( - pb, x, y, result, "gadget"); + MiMC_mp_gadget> + mimc_mp_gadget(pb, m, k, h, "mimc_mp"); mimc_mp_gadget.generate_r1cs_constraints(); mimc_mp_gadget.generate_r1cs_witness(); - Field unexpected_out = Field("1679792244955599468406310421423339620059969" - "3715764605878168345782964540311877"); - ASSERT_TRUE(pb.is_satisfied()); - ASSERT_FALSE(unexpected_out == pb.val(result)); -} - -// Testing that (15212 + 98645 + 216319)**7 = -// 427778066313557225181231220812180094976 -TEST(TestMiMC, MiMC17_ALT_BN128_Round) -{ - using Field = libff::alt_bn128_Fr; - - libsnark::protoboard pb; - libsnark::pb_variable in_x; - libsnark::pb_variable in_k; - libsnark::pb_variable result; - - in_x.allocate(pb, "x"); - in_k.allocate(pb, "k"); - result.allocate(pb, "result"); - - // Test data from client test (test_mimc_alt_bn128_round), to ensure - // consistency between implementations. - - pb.val(in_x) = Field("340282366920938463463374607431768211456"); - pb.val(in_k) = Field("28948022309329048855892746252171976963317496166410141" - "009864396001978282409983"); - Field in_C = Field("1422006791884799603110814443576367281105075806594536430" - "8986253046354060608451"); - - MiMCe17_round_gadget round_gadget( - pb, in_x, in_k, in_C, result, "round_gadget"); - round_gadget.generate_r1cs_constraints(); - round_gadget.generate_r1cs_witness(); - - Field expected_out = Field("15194574649778181158537940501307832704788048781" - "286507777438072456493095881604"); + // Check that the circuit is satisfied, and that the expected result is + // generated. ASSERT_TRUE(pb.is_satisfied()); - ASSERT_TRUE(expected_out == pb.val(result)); + ASSERT_EQ(h_val, pb.val(h)); } -TEST(TestMiMC, MiMC17_ALT_BN128_MP) +TEST(TestMiMC, MiMC17_ALT_BN128_MP_Incorrect) { using Field = libff::alt_bn128_Fr; - // Test data from client test (test_mimc_alt_bn128_hash), to ensure - // consistency between implementations. + // Test data from client test (test_mimc.py), to ensure consistency between + // implementations. const Field m_val("340282366920938463463374607431768211456"); const Field k_val("28948022309329048855892746252171976963317496166410141009" "864396001978282409983"); - const Field h_val("14599678357063082723814206975733222579132256174923645170" - "354481857040188426666"); libsnark::protoboard pb; @@ -316,14 +278,12 @@ TEST(TestMiMC, MiMC17_ALT_BN128_MP) mimc_mp_gadget.generate_r1cs_constraints(); mimc_mp_gadget.generate_r1cs_witness(); - // Check that the circuit is satisfied, and that the expected result is - // generated. - ASSERT_TRUE(pb.is_satisfied()); - ASSERT_EQ(h_val, pb.val(h)); + // Force incorrect result value and check that circuit is not satisfied. + pb.val(h) = Field("145996783570630827238142069757332225791322561749236" + "45170354481857040188426667"); + ASSERT_FALSE(pb.is_satisfied()); } -// Testing that (15212 + 98645 + 216319)**7 = -// 427778066313557225181231220812180094976 TEST(TestMiMC, MiMC17_BLS12_377_Round) { using Field = libff::bls12_377_Fr; @@ -337,8 +297,8 @@ TEST(TestMiMC, MiMC17_BLS12_377_Round) in_k.allocate(pb, "k"); result.allocate(pb, "result"); - // Test data from client test (test_mimc_bls12_377_round), to ensure - // consistency between implementations. + // Test data from client test (test_mimc.py), to ensure consistency between + // implementations. pb.val(in_x) = Field("340282366920938463463374607431768211456"); pb.val(in_k) = Field("36146370610439375831462714358273373691897981609479495" @@ -361,8 +321,8 @@ TEST(TestMiMC, MiMC17_BLS12_377_MP) { using Field = libff::bls12_377_Fr; - // Test data from client test (test_mimc_bls12_377_hash), to ensure - // consistency between implementations. + // Test data from client test (test_mimc.py), to ensure consistency between + // implementations. const Field m_val( "361463706104393758314627143582733736918979816094794952605869" @@ -407,7 +367,7 @@ int main(int argc, char **argv) { // /!\ WARNING: Do once for all tests. Do not // forget to do this !!!! - pp::init_public_params(); + libff::alt_bn128_pp::init_public_params(); libff::bls12_377_pp::init_public_params(); ::testing::InitGoogleTest(&argc, argv); From a1c7e22805a5c30eb8e416cc8a1fc68579c201d3 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 4 May 2021 10:39:26 +0100 Subject: [PATCH 131/137] libzeth: remove some unused mimc round constants --- libzeth/circuits/mimc/mimc_permutation.hpp | 6 ++- libzeth/circuits/mimc/mimc_permutation.tcc | 56 ++------------------- libzeth/tests/circuits/merkle_tree_test.cpp | 54 ++++++++------------ libzeth/tests/circuits/note_test.cpp | 2 +- 4 files changed, 30 insertions(+), 88 deletions(-) diff --git a/libzeth/circuits/mimc/mimc_permutation.hpp b/libzeth/circuits/mimc/mimc_permutation.hpp index 3792f6ece..c531f6b7c 100644 --- a/libzeth/circuits/mimc/mimc_permutation.hpp +++ b/libzeth/circuits/mimc/mimc_permutation.hpp @@ -20,8 +20,10 @@ template class MiMC_permutation_gadget : public libsnark::gadget { private: - // Round constants only available up to 91 rounds - static_assert(NumRounds <= 91, "NumRounds must be less than 91"); + // Round constants only available up to some maximum number of rounds + static const size_t MaxRounds = 65; + static_assert( + NumRounds <= MaxRounds, "NumRounds must be less than MaxRounds"); // Instantiate round gadget with exponent = Exponent using RoundT = MiMC_round_gadget; diff --git a/libzeth/circuits/mimc/mimc_permutation.tcc b/libzeth/circuits/mimc/mimc_permutation.tcc index b9966c4ad..b3e81118f 100644 --- a/libzeth/circuits/mimc/mimc_permutation.tcc +++ b/libzeth/circuits/mimc/mimc_permutation.tcc @@ -155,7 +155,8 @@ void MiMC_permutation_gadget:: return; } - round_constants.reserve(NumRounds); + // For simplicity, always generate constants for MaxRounds. + round_constants.reserve(MaxRounds); // The constant is set to "0" in the first round of MiMC permutation (see: // https://eprint.iacr.org/2016/492.pdf) @@ -293,60 +294,9 @@ void MiMC_permutation_gadget:: "74544443080560119509560262720937836494902079641131221139823065933367514898276")); round_constants.push_back(FieldT( "36856043990250139109110674451326757800006928098085552406998173198427373834846")); - round_constants.push_back(FieldT( - "89876265522016337550524744707009312276376790319197860491657618155961055194949")); - round_constants.push_back(FieldT( - "110827903006446644954303964609043521818500007209339765337677716791359271709709")); - round_constants.push_back(FieldT( - "19507166101303357762640682204614541813131172968402646378144792525256753001746")); - round_constants.push_back(FieldT( - "107253144238416209039771223682727408821599541893659793703045486397265233272366")); - round_constants.push_back(FieldT( - "50595349797145823467207046063156205987118773849740473190540000392074846997926")); - round_constants.push_back(FieldT( - "44703482889665897122601827877356260454752336134846793080442136212838463818460")); - round_constants.push_back(FieldT( - "72587689163044446617379334085046687704026377073069181869522598220420039333904")); - round_constants.push_back(FieldT( - "102651401786920090371975453907921346781687924794638352783098945209363379010084")); - round_constants.push_back(FieldT( - "93452870373806728605513560063145330258676656934938716540885043830342716774537")); - round_constants.push_back(FieldT( - "78296669596559313198894751403351590225284664485458045241864014863714864424243")); - round_constants.push_back(FieldT( - "115089219682233450926699488628267277641700041858332325616476033644461392438459")); - round_constants.push_back(FieldT( - "12503229023709380637667243769419362848195673442247523096260626221166887267863")); - round_constants.push_back(FieldT( - "4710254915107472945023322521703570589554948344762175784852248799008742965033")); - round_constants.push_back(FieldT( - "7718237385336937042064321465151951780913850666971695410931421653062451982185")); - round_constants.push_back(FieldT( - "115218487714637830492048339157964615618803212766527542809597433013530253995292")); - round_constants.push_back(FieldT( - "30146276054995781136885926012526705051587400199196161599789168368938819073525")); - round_constants.push_back(FieldT( - "81645575619063610562025782726266715757461113967190574155696199274188206173145")); - round_constants.push_back(FieldT( - "103065286526250765895346723898189993161715212663393551904337911885906019058491")); - round_constants.push_back(FieldT( - "19401253163389218637767300383887292725233192135251696535631823232537040754970")); - round_constants.push_back(FieldT( - "39843332085422732827481601668576197174769872102167705377474553046529879993254")); - round_constants.push_back(FieldT( - "27288628349107331632228897768386713717171618488175838305048363657709955104492")); - round_constants.push_back(FieldT( - "63512042813079522866974560192099016266996589861590638571563519363305976473166")); - round_constants.push_back(FieldT( - "88099896769123586138541398153669061847681467623298355942484821247745931328016")); - round_constants.push_back(FieldT( - "69497565113721491657291572438744729276644895517335084478398926389231201598482")); - round_constants.push_back(FieldT( - "17118586436782638926114048491697362406660860405685472757612739816905521144705")); - round_constants.push_back(FieldT( - "50507769484714413215987736701379019852081133212073163694059431350432441698257")); // clang-format on + assert(round_constants.size() == MaxRounds); round_constants_initialized = true; } diff --git a/libzeth/tests/circuits/merkle_tree_test.cpp b/libzeth/tests/circuits/merkle_tree_test.cpp index 5e5172f63..0b1bc15b3 100644 --- a/libzeth/tests/circuits/merkle_tree_test.cpp +++ b/libzeth/tests/circuits/merkle_tree_test.cpp @@ -12,7 +12,7 @@ using namespace libzeth; template -using MiMCe7_permutation_gadget = MiMC_permutation_gadget; +using MiMCe7_permutation_gadget = MiMC_permutation_gadget; // Instantiation of the templates for the tests. Data here assumes alt_bn128 using pp = libff::alt_bn128_pp; @@ -84,13 +84,12 @@ bool test_merkle_path_authenticator_depth1() // right leaf: // 134551314051432487569247388144051420116740427803855572138106146683954151557, // root: - // 7121700468981037559893852455893095765125417767594185027454590493596569372187 + // hash(left, right) Field left = Field("37031414935355631796575317199601601742960852086719193" "16200479060314459804651"); Field right = Field("1345513140514324875692473881440514201167404278038555" "72138106146683954151557"); - Field root = Field("71217004689810375598938524558930957651254177675941850" - "27454590493596569372187"); + Field root = HashTree::get_hash(left, right); // Set the authenticator for right leaf (`is_right` = 1) Field is_right = 1; @@ -167,8 +166,8 @@ bool test_merkle_path_authenticator_depth3() "3374630310875272509334396"); Field left2 = Field("9881790034808292405036271961589462686158587796044671" "417688221824074647491645"); - Field root = Field("13476730430097836153970274382710787532919044453117948" - "373701924629587143655224"); + Field root = HashTree::get_hash( + left2, HashTree::get_hash(left1, HashTree::get_hash(left0, right0))); Field is_right = 1; // Bit representation of the leaf to authenticate @@ -227,33 +226,24 @@ bool test_merkle_path_authenticator_depth3() return true; } -TEST(MainTests, TestMerkleTreeField) +TEST(MerkleTreeTest, PathSelector0) { - bool res = false; - - res = test_merkle_path_selector(0); - std::cout - << "[test_merkle_path_selector 0] Expected (True), Obtained result: " - << res << std::endl; - ASSERT_TRUE(res); - - res = test_merkle_path_selector(1); - std::cout - << "[test_merkle_path_selector 1] Expected (True), Obtained result: " - << res << std::endl; - ASSERT_TRUE(res); - - res = test_merkle_path_authenticator_depth1(); - std::cout << "[test_merkle_path_authenticator_depth1] Expected (True), " - "Obtained result: " - << res << std::endl; - ASSERT_TRUE(res); - - res = test_merkle_path_authenticator_depth3(); - std::cout << "[test_merkle_path_authenticator_depth3] Expected (True), " - "Obtained result: " - << res << std::endl; - ASSERT_TRUE(res); + ASSERT_TRUE(test_merkle_path_selector(0)); +} + +TEST(MerkleTreeTest, PathSelector1) +{ + ASSERT_TRUE(test_merkle_path_selector(1)); +} + +TEST(MerkleTreeTest, PathAuthenticatorDepth1) +{ + ASSERT_TRUE(test_merkle_path_authenticator_depth1()); +} + +TEST(MerkleTreeTest, PathAuthenticatorDepth3) +{ + ASSERT_TRUE(test_merkle_path_authenticator_depth3()); } } // namespace diff --git a/libzeth/tests/circuits/note_test.cpp b/libzeth/tests/circuits/note_test.cpp index 2c706ed61..8bf3315ed 100644 --- a/libzeth/tests/circuits/note_test.cpp +++ b/libzeth/tests/circuits/note_test.cpp @@ -20,7 +20,7 @@ using namespace libzeth; using pp = defaults::pp; using Field = defaults::Field; using Hash = BLAKE2s_256; -using HashTree = MiMC_mp_gadget>; +using HashTree = MiMC_mp_gadget>; static const size_t TreeDepth = 4; namespace From e873d1945ad0656a863a8e55c1f16942bea5f55b Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Tue, 4 May 2021 10:54:08 +0100 Subject: [PATCH 132/137] libzeth: rename member --- libzeth/circuits/mimc/mimc_permutation.hpp | 2 +- libzeth/circuits/mimc/mimc_permutation.tcc | 4 ++-- libzeth/circuits/mimc/mimc_round.hpp | 2 +- libzeth/circuits/mimc/mimc_round.tcc | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libzeth/circuits/mimc/mimc_permutation.hpp b/libzeth/circuits/mimc/mimc_permutation.hpp index c531f6b7c..2cc82f9e1 100644 --- a/libzeth/circuits/mimc/mimc_permutation.hpp +++ b/libzeth/circuits/mimc/mimc_permutation.hpp @@ -45,7 +45,7 @@ class MiMC_permutation_gadget : public libsnark::gadget const libsnark::pb_linear_combination &key, const libsnark::pb_variable &result, const libsnark::pb_linear_combination &add_to_result, - const bool have_add_to_result, + const bool add_to_result_is_valid, const std::string &annotation_prefix); public: diff --git a/libzeth/circuits/mimc/mimc_permutation.tcc b/libzeth/circuits/mimc/mimc_permutation.tcc index b3e81118f..827b53cf2 100644 --- a/libzeth/circuits/mimc/mimc_permutation.tcc +++ b/libzeth/circuits/mimc/mimc_permutation.tcc @@ -25,7 +25,7 @@ MiMC_permutation_gadget::MiMC_permutation_gadget( const libsnark::pb_linear_combination &key, const libsnark::pb_variable &result, const libsnark::pb_linear_combination &add_to_result, - const bool have_add_to_result, + const bool add_to_result_is_valid, const std::string &annotation_prefix) : libsnark::gadget(pb, annotation_prefix) { @@ -68,7 +68,7 @@ MiMC_permutation_gadget::MiMC_permutation_gadget( // result, along with any add_to_result. round_results[NumRounds - 1] = result; - if (have_add_to_result) { + if (add_to_result_is_valid) { libsnark::pb_linear_combination key_plus_add_to_result; key_plus_add_to_result.assign(this->pb, key + add_to_result); round_gadgets.emplace_back( diff --git a/libzeth/circuits/mimc/mimc_round.hpp b/libzeth/circuits/mimc/mimc_round.hpp index c8eccb674..2c7084e74 100644 --- a/libzeth/circuits/mimc/mimc_round.hpp +++ b/libzeth/circuits/mimc/mimc_round.hpp @@ -40,7 +40,7 @@ class MiMC_round_gadget : public libsnark::gadget const libsnark::pb_linear_combination add_to_result; // Flag indicating whether add_to_result is valid - const bool have_add_to_result; + const bool add_to_result_is_valid; // Intermediate values std::vector> exponents; diff --git a/libzeth/circuits/mimc/mimc_round.tcc b/libzeth/circuits/mimc/mimc_round.tcc index c707e7f2d..a54c12eca 100644 --- a/libzeth/circuits/mimc/mimc_round.tcc +++ b/libzeth/circuits/mimc/mimc_round.tcc @@ -31,7 +31,7 @@ MiMC_round_gadget::MiMC_round_gadget( , key(key) , round_const(round_const) , result(result) - , have_add_to_result(false) + , add_to_result_is_valid(false) { initialize(); } @@ -51,7 +51,7 @@ MiMC_round_gadget::MiMC_round_gadget( , round_const(round_const) , result(result) , add_to_result(add_to_result) - , have_add_to_result(true) + , add_to_result_is_valid(true) { initialize(); } @@ -108,7 +108,7 @@ void MiMC_round_gadget::generate_r1cs_constraints() assert(exp_idx == exponents.size()); // Final multiply (lowest-order bit is known to be 1), - if (have_add_to_result) { + if (add_to_result_is_valid) { // addition of add_to_result: // result = last * t + add_to_result // <=> result - add_to_result = last * t @@ -154,7 +154,7 @@ void MiMC_round_gadget::generate_r1cs_witness() const // v = v * t + add_to_result v = v * t; - if (have_add_to_result) { + if (add_to_result_is_valid) { add_to_result.evaluate(this->pb); v = v + this->pb.lc_val(add_to_result); } From 3a23b18a36d809dac658283d8775d3b24f58622f Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Wed, 5 May 2021 17:10:54 +0100 Subject: [PATCH 133/137] client: fall back to source install of solc if binary fails --- client/zeth/core/contracts.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/zeth/core/contracts.py b/client/zeth/core/contracts.py index 85201c57e..1adc9140b 100644 --- a/client/zeth/core/contracts.py +++ b/client/zeth/core/contracts.py @@ -11,6 +11,7 @@ from web3.utils.events import get_event_data # type: ignore from eth_utils import event_abi_to_log_topic # type: ignore import solcx +import solcx.install # type: ignore from typing import Dict, List, Iterator, Optional, Union, Iterable, Any # Avoid trying to read too much data into memory @@ -117,7 +118,10 @@ def get_block_number(web3: Any) -> int: def install_sol() -> None: - solcx.install_solc(SOL_COMPILER_VERSION) + try: + solcx.install_solc(SOL_COMPILER_VERSION) + except solcx.exceptions.SolcInstallationError: + solcx.install.compile_solc(SOL_COMPILER_VERSION) def compile_files(files: List[str], **kwargs: Any) -> Any: From 85d39d714c5c2f70d467cef2bef63317604e5e61 Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 6 May 2021 10:02:50 +0100 Subject: [PATCH 134/137] ci: copy alpine solc binary into client container --- Dockerfile-client | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Dockerfile-client b/Dockerfile-client index 2a8916fe7..76e75803f 100644 --- a/Dockerfile-client +++ b/Dockerfile-client @@ -1,7 +1,13 @@ +# Image to copy solc compiler from +FROM ethereum/solc:0.8.1-alpine as solc-0.8.1 + FROM python:3.8-alpine3.12 LABEL org.opencontainers.image.source https://github.com/clearmatics/zeth +# Image to copy solc compiler from +COPY --from=solc-0.8.1 /usr/local/bin/solc /root/.solcx/solc-v0.8.1 + RUN apk --update --no-cache add \ build-base \ linux-headers \ From d7a642014ca97efa269554a58c2e8b44beba1930 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Thu, 6 May 2021 11:19:40 +0100 Subject: [PATCH 135/137] Removed surrounding quotes in GA names for consistency --- .github/workflows/dev-docker-apps.yml | 12 ++++++------ .github/workflows/release-docker-apps.yml | 14 +++++++------- .github/workflows/release-docker-base.yml | 18 +++++++++--------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/.github/workflows/dev-docker-apps.yml b/.github/workflows/dev-docker-apps.yml index 9e7d8c4c1..a3224448a 100644 --- a/.github/workflows/dev-docker-apps.yml +++ b/.github/workflows/dev-docker-apps.yml @@ -14,7 +14,7 @@ env: jobs: docker-build: - name: "Docker build" + name: Docker build runs-on: ubuntu-20.04 timeout-minutes: 180 @@ -25,23 +25,23 @@ jobs: max-parallel: 3 steps: - - name: "Checkout" + - name: Checkout uses: actions/checkout@v2 - - name: "Get vars from git" + - name: Get vars from git id: git_vars run: echo ::set-output name=COMMIT_HASH::$(git rev-parse --short HEAD) - - name: "Configure Docker" + - name: Configure Docker run: echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin - - name: "Set up Buildx" + - name: Set up Buildx id: buildx uses: docker/setup-buildx-action@v1 with: version: latest - - name: "Build and push image git-SHA" + - name: Build and push image git-SHA run: | docker buildx build \ --tag ghcr.io/$GITHUB_REPOSITORY:git-${{ steps.git_vars.outputs.COMMIT_HASH }}-${{ matrix.app }} \ diff --git a/.github/workflows/release-docker-apps.yml b/.github/workflows/release-docker-apps.yml index 634adf7c1..6b55dbf82 100644 --- a/.github/workflows/release-docker-apps.yml +++ b/.github/workflows/release-docker-apps.yml @@ -8,7 +8,7 @@ on: jobs: docker-build: - name: "Docker build" + name: Docker build runs-on: ubuntu-20.04 timeout-minutes: 180 @@ -19,25 +19,25 @@ jobs: max-parallel: 3 steps: - - name: "Checkout" + - name: Checkout uses: actions/checkout@v2 - - name: "Get vars from git" + - name: Get vars from git id: git_vars run: | echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\/v/} echo ::set-output name=COMMIT_HASH::$(git rev-parse --short HEAD) - - name: "Configure Docker" + - name: Configure Docker run: echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin - - name: "Set up Buildx" + - name: Set up Buildx id: buildx uses: docker/setup-buildx-action@v1 with: version: latest - - name: "Build and push image git-SHA" + - name: Build and push image git-SHA run: | docker buildx build \ --tag ghcr.io/$GITHUB_REPOSITORY:git-${{ steps.git_vars.outputs.COMMIT_HASH }}-${{ matrix.app }} \ @@ -47,7 +47,7 @@ jobs: --output "type=image,push=true" \ --file ./Dockerfile-${{ matrix.app }} ./ - - name: "Tag and push latest image to registry" + - name: Tag and push latest image to registry run: | docker pull ghcr.io/$GITHUB_REPOSITORY:git-${{ steps.git_vars.outputs.COMMIT_HASH }}-${{ matrix.app }} docker tag ghcr.io/$GITHUB_REPOSITORY:git-${{ steps.git_vars.outputs.COMMIT_HASH }}-${{ matrix.app }} ghcr.io/$GITHUB_REPOSITORY:${{ steps.git_vars.outputs.VERSION }}-${{ matrix.app }} diff --git a/.github/workflows/release-docker-base.yml b/.github/workflows/release-docker-base.yml index 1f41861e4..95e5e4db5 100644 --- a/.github/workflows/release-docker-base.yml +++ b/.github/workflows/release-docker-base.yml @@ -8,44 +8,44 @@ on: jobs: docker-build: - name: "Docker build" + name: Docker build runs-on: ubuntu-20.04 timeout-minutes: 360 steps: - - name: "Checkout" + - name: Checkout uses: actions/checkout@v2 - - name: "Create swap from file" + - name: Create swap from file run: | sudo fallocate -l 19G /swapfile2 sudo chmod 600 /swapfile2 sudo mkswap /swapfile2 sudo swapon /swapfile2 - - name: "Show build host parameters" + - name: Show build host parameters run: | free -h df -h nproc - - name: "Get vars from git" + - name: Get vars from git id: git_vars run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\/docker-base-v/} - - name: "Configure Docker" + - name: Configure Docker run: echo ${{ secrets.CR_PAT }} | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin - - name: "Docker build" + - name: Docker build run: docker build -f ./Dockerfile-base -t ghcr.io/$GITHUB_REPOSITORY:${{ steps.git_vars.outputs.VERSION }}-base . - - name: "Docker push" + - name: Docker push run: | docker push ghcr.io/$GITHUB_REPOSITORY:${{ steps.git_vars.outputs.VERSION }}-base docker tag ghcr.io/$GITHUB_REPOSITORY:${{ steps.git_vars.outputs.VERSION }}-base ghcr.io/$GITHUB_REPOSITORY:latest-base docker push ghcr.io/$GITHUB_REPOSITORY:latest-base - - name: "Docker Info" + - name: Docker Info run: | docker inspect ghcr.io/$GITHUB_REPOSITORY:${{ steps.git_vars.outputs.VERSION }}-base docker history ghcr.io/$GITHUB_REPOSITORY:${{ steps.git_vars.outputs.VERSION }}-base --no-trunc From 7ea4562115c676db07cc60e322b422603cc6de71 Mon Sep 17 00:00:00 2001 From: Antoine Rondelet Date: Thu, 6 May 2021 12:06:56 +0100 Subject: [PATCH 136/137] Bumped version for Daric release --- CMakeLists.txt | 2 +- client/setup.py | 2 +- mpc/setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ca975bf20..146c72ee7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ project(zeth CXX) # Versionning of the project set(ZETH_VERSION_MAJOR 0) -set(ZETH_VERSION_MINOR 6) +set(ZETH_VERSION_MINOR 7) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/client/setup.py b/client/setup.py index 21e0f64e5..b6d331dd1 100644 --- a/client/setup.py +++ b/client/setup.py @@ -18,7 +18,7 @@ setup( name='zeth', - version='0.6', + version='0.7', description='Interface to zeth operations', packages=find_packages(), install_requires=[ diff --git a/mpc/setup.py b/mpc/setup.py index 35d6bbe81..2965dc6dc 100644 --- a/mpc/setup.py +++ b/mpc/setup.py @@ -20,7 +20,7 @@ setup( name='coordinator', - version='0.6', + version='0.7', description='MPC Coordinator for Zeth SRS', packages=find_packages(), install_requires=[ From 3849994b4bd7e39137ec04d5a4a9f28cb7d84aff Mon Sep 17 00:00:00 2001 From: Duncan Tebbs Date: Thu, 6 May 2021 12:50:19 +0100 Subject: [PATCH 137/137] Revert "client: fall back to source install of solc if binary fails" This reverts commit 3a23b18a36d809dac658283d8775d3b24f58622f. --- client/zeth/core/contracts.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/client/zeth/core/contracts.py b/client/zeth/core/contracts.py index 1adc9140b..85201c57e 100644 --- a/client/zeth/core/contracts.py +++ b/client/zeth/core/contracts.py @@ -11,7 +11,6 @@ from web3.utils.events import get_event_data # type: ignore from eth_utils import event_abi_to_log_topic # type: ignore import solcx -import solcx.install # type: ignore from typing import Dict, List, Iterator, Optional, Union, Iterable, Any # Avoid trying to read too much data into memory @@ -118,10 +117,7 @@ def get_block_number(web3: Any) -> int: def install_sol() -> None: - try: - solcx.install_solc(SOL_COMPILER_VERSION) - except solcx.exceptions.SolcInstallationError: - solcx.install.compile_solc(SOL_COMPILER_VERSION) + solcx.install_solc(SOL_COMPILER_VERSION) def compile_files(files: List[str], **kwargs: Any) -> Any: