diff --git a/pyClient/zethTestScenario.py b/pyClient/zethTestScenario.py index 3ce473a55..8c161bc17 100644 --- a/pyClient/zethTestScenario.py +++ b/pyClient/zethTestScenario.py @@ -61,9 +61,6 @@ def bob_deposit(test_grpc_endpoint, mixer_instance, mk_root, bob_eth_address, ke # Hash the pk_sender and cipher-texts ciphers = eph_pk_sender_bytes + ciphertext1 + ciphertext2 - - # Hash the cipher-texts TODO TO REMOVE - ciphers = ciphertext1 + ciphertext2 hash_ciphers = sha256(ciphers).hexdigest() # Hash the proof diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c865fd423..4f3c12cc2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -137,8 +137,8 @@ endfunction(zeth_test) zeth_test(test_simple test/simple_test.cpp TRUE) zeth_test(test_addition test/packed_addition_test.cpp TRUE) zeth_test(test_hex_to_field test/hex_to_field_test.cpp TRUE) -zeth_test(test_sha256 test/sha256_test.cpp) -zeth_test(test_blake2s test/blake2s_test.cpp) +zeth_test(test_sha256 test/sha256_test.cpp TRUE) +zeth_test(test_blake2s test/blake2s_test.cpp TRUE) zeth_test(test_round test/round_test.cpp TRUE) zeth_test(test_mimc test/mimc_test.cpp TRUE) zeth_test(test_mimc_mp test/mimc_mp_test.cpp TRUE) diff --git a/src/circuits/commitments/commitments.hpp b/src/circuits/commitments/commitments.hpp index af042094c..3d765fe0d 100644 --- a/src/circuits/commitments/commitments.hpp +++ b/src/circuits/commitments/commitments.hpp @@ -5,7 +5,6 @@ // Content Taken and adapted from Zcash // https://github.com/zcash/zcash/blob/master/src/zcash/circuit/commitment.tcc -#include "circuits/sha256/sha256_ethereum.hpp" #include #include @@ -27,7 +26,7 @@ class COMM_gadget : libsnark::gadget libsnark::pb_variable_array x, libsnark::pb_variable_array y, std::shared_ptr> - result, // sha256(x || y) + result, // blake2s(x || y) const std::string &annotation_prefix = "COMM_gadget"); void generate_r1cs_constraints(); void generate_r1cs_witness(); @@ -48,8 +47,8 @@ libsnark::pb_variable_array getRightSideCMCOMM( // the value of the commitment_k without needing 2 distinct gadgets for this. // // See Zerocash extended paper, page 22 -// The commitment k is computed as k = sha256(r || [sha256(a_pk || rho)]_128) -// where we define the left part: inner_k = sha256(a_pk || rho) +// The commitment k is computed as k = blake2s(r || [blake2s(a_pk || rho)]_128) +// where we define the left part: inner_k = blake2s(a_pk || rho) // as being the inner commitment of k template class COMM_inner_k_gadget : public COMM_gadget @@ -61,13 +60,13 @@ class COMM_inner_k_gadget : public COMM_gadget &a_pk, // public address key, 256 bits libsnark::pb_variable_array &rho, // 256 bits std::shared_ptr> - result, // sha256(a_pk || rho) + result, // blake2s(a_pk || rho) const std::string &annotation_prefix = "COMM_inner_k_gadget"); }; // See Zerocash extended paper, page 22 -// The commitment k is computed as k = sha256(r || [sha256(a_pk || rho)]_128) -// where we define: outer_k = sha256(r || [inner_commitment]_128) +// The commitment k is computed as k = blake2s(r || [blake2s(a_pk || rho)]_128) +// where we define: outer_k = blake2s(r || [inner_commitment]_128) // as being the outer commitment of k // We denote by trap_r the trapdoor r template @@ -80,11 +79,11 @@ class COMM_outer_k_gadget : public COMM_gadget libsnark::pb_variable_array &inner_k, // 256 bits, but we only keep 128 bits out of it std::shared_ptr> - result, // sha256(trap_r || [inner_k]_128) + result, // blake2s(trap_r || [inner_k]_128) const std::string &annotation_prefix = "COMM_outer_k_gadget"); }; -// cm = sha256(outer_k || 0^192 || value_v) +// cm = blake2s(outer_k || 0^192 || value_v) template class COMM_cm_gadget : public COMM_gadget { @@ -95,7 +94,7 @@ class COMM_cm_gadget : public COMM_gadget libsnark::pb_variable_array &outer_k, // 256 bits libsnark::pb_variable_array &value_v, // 64 bits std::shared_ptr> - result, // sha256(outer_k || 0^192 || value_v) + result, // blake2s(outer_k || 0^192 || value_v) const std::string &annotation_prefix = "COMM_cm_gadget"); }; diff --git a/src/circuits/commitments/commitments.tcc b/src/circuits/commitments/commitments.tcc index a996ec1e4..8ec002d12 100644 --- a/src/circuits/commitments/commitments.tcc +++ b/src/circuits/commitments/commitments.tcc @@ -90,8 +90,8 @@ libsnark::pb_variable_array getRightSideCMCOMM( // commitment // // See Zerocash extended paper, page 22 -// The commitment k is computed as k = sha256(r || [sha256(a_pk || rho)]_128) -// where we define the left part: inner_k = sha256(a_pk || rho) +// The commitment k is computed as k = blake2s(r || [blake2s(a_pk || rho)]_128) +// where we define the left part: inner_k = blake2s(a_pk || rho) // as being the inner commitment of k template COMM_inner_k_gadget::COMM_inner_k_gadget( @@ -106,8 +106,8 @@ COMM_inner_k_gadget::COMM_inner_k_gadget( } // See Zerocash extended paper, page 22 -// The commitment k is computed as k = sha256(r || [sha256(a_pk || rho)]_128) -// where we define: outer_k = sha256(r || [inner_commitment]_128) +// The commitment k is computed as k = blake2s(r || [blake2s(a_pk || rho)]_128) +// where we define: outer_k = blake2s(r || [inner_commitment]_128) // as being the outer commitment of k // We denote by trap_r the trapdoor r template @@ -124,7 +124,7 @@ COMM_outer_k_gadget::COMM_outer_k_gadget( // Nothing } -// cm = sha256(outer_k || 0^192 || value_v) +// cm = blake2s(outer_k || 0^192 || value_v) template COMM_cm_gadget::COMM_cm_gadget( libsnark::protoboard &pb, diff --git a/src/circuits/joinsplit.tcc b/src/circuits/joinsplit.tcc index d8203f689..99e198089 100644 --- a/src/circuits/joinsplit.tcc +++ b/src/circuits/joinsplit.tcc @@ -2,7 +2,6 @@ #define __ZETH_JOINSPLIT_CIRCUIT_TCC__ #include "circuits/notes/note.hpp" // Contains the circuits for the notes -#include "circuits/sha256/sha256_ethereum.hpp" #include "libsnark_helpers/libsnark_helpers.hpp" #include "types/joinsplit.hpp" #include "zeth.h" // Contains the definitions of the constants we use diff --git a/src/circuits/prfs/prfs.hpp b/src/circuits/prfs/prfs.hpp index f4267803e..32fc50861 100644 --- a/src/circuits/prfs/prfs.hpp +++ b/src/circuits/prfs/prfs.hpp @@ -5,8 +5,6 @@ // Content Taken and adapted from Zcash // https://github.com/zcash/zcash/blob/master/src/zcash/circuit/prfs.tcc -#include "circuits/sha256/sha256_ethereum.hpp" - #include namespace libzeth @@ -26,7 +24,7 @@ class PRF_gadget : public libsnark::gadget libsnark::pb_variable_array x, libsnark::pb_variable_array y, std::shared_ptr> - result, // sha256(x || y) + result, // blake2s(x || y) const std::string &annotation_prefix = "PRF_gadget"); void generate_r1cs_constraints(); @@ -34,7 +32,7 @@ class PRF_gadget : public libsnark::gadget }; // This function is useful as the generation of a_pk is done via a_pk = -// sha256(a_sk || 0^256) See Zerocash extended paper, page 22, paragraph +// blake2s(a_sk || 0^256) See Zerocash extended paper, page 22, paragraph // "Instantiating the NP statement POUR" template libsnark::pb_variable_array gen_256_zeroes( @@ -90,7 +88,7 @@ class PRF_nf_gadget : public PRF_gadget libsnark::pb_variable_array &a_sk, libsnark::pb_variable_array &rho, std::shared_ptr> - result, // sha256(a_sk || 01 || [rho]_254) + result, // blake2s(a_sk || 01 || [rho]_254) const std::string &annotation_prefix = "PRF_nf_gadget"); }; diff --git a/src/circuits/prfs/prfs.tcc b/src/circuits/prfs/prfs.tcc index c177030e9..7a7cd0cc5 100644 --- a/src/circuits/prfs/prfs.tcc +++ b/src/circuits/prfs/prfs.tcc @@ -47,7 +47,7 @@ libsnark::pb_variable_array gen_256_zeroes( } // Check that we correctly built a 256-bit (half a block) string since we - // use sha256 + // use blake2s 256 assert(ret.size() == 256); return ret; diff --git a/src/prover_server.cc b/src/prover_server.cc index 2a7bf9ea5..f51b126ff 100644 --- a/src/prover_server.cc +++ b/src/prover_server.cc @@ -55,7 +55,7 @@ typedef libff::default_ec_pp ppT; // Instantiated from the curve specified in the CMakelists.txt typedef libff::Fr FieldT; typedef MiMC_mp_gadget HashTreeT; // Hash used in the merkle tree -typedef sha256_ethereum HashT; // Hash used for the commitments and PRFs +typedef BLAKE2s_256_comp HashT; // Hash used for the commitments and PRFs class ProverImpl final : public Prover::Service { diff --git a/src/test/commitments_test.cpp b/src/test/commitments_test.cpp index f61384a24..3cb29cdd4 100644 --- a/src/test/commitments_test.cpp +++ b/src/test/commitments_test.cpp @@ -6,8 +6,8 @@ // Header to use the merkle tree data structure #include -// Header to use the sha256_ethereum gadget -#include "circuits/sha256/sha256_ethereum.hpp" +// Header to use the blake2s gadget +#include "circuits/blake2s/blake2s_comp.hpp" // Access the `from_bits` function and other utils #include "circuits/circuits-util.hpp" @@ -21,7 +21,7 @@ using namespace libzeth; // Instantiation of the templates for the tests typedef libff::default_ec_pp ppT; typedef libff::Fr FieldT; // Should be alt_bn128 in the CMakeLists.txt -typedef sha256_ethereum +typedef BLAKE2s_256_comp HashT; // We use our hash function to do the tests namespace diff --git a/src/test/mimc_test.cpp b/src/test/mimc_test.cpp index 638665f43..d838630b2 100644 --- a/src/test/mimc_test.cpp +++ b/src/test/mimc_test.cpp @@ -1,9 +1,13 @@ -#include "circuits/mimc/mimc.hpp" -#include "snarks_alias.hpp" - #include "gtest/gtest.h" + #include +#include "snarks_alias.hpp" +#include "circuits/mimc/mimc.hpp" +#include "circuits/mimc/mimc_mp.hpp" +#include "circuits/mimc/round.hpp" + + using namespace libsnark; using namespace libzeth; @@ -83,8 +87,64 @@ TEST(TestRound, TestFalseAddKToResult) { pb.val(in_x) = FieldT("15212"); pb.val(in_k) = FieldT("98645"); -TEST(TestRound, TestTrue) -{ + MiMCe7_round_gadget round_gadget(pb, in_x, in_k, in_C, true, "round_gadget"); + round_gadget.generate_r1cs_witness(); + round_gadget.generate_r1cs_constraints(); + + FieldT expected_out = FieldT("42777806631355722518123"); + ASSERT_FALSE(expected_out == pb.val(round_gadget.result())); +} + + + +TEST(TestMiMCMp, TestTrue) { + libsnark::protoboard pb; + + // Public input + libsnark::pb_variable y; + y.allocate(pb, "y"); + pb.set_input_sizes(1); + pb.val(y) = FieldT("15683951496311901749339509118960676303290224812129752890706581988986633412003"); // sha3_256("mimc") + + // Private inputs + libsnark::pb_variable x; + x.allocate(pb, "x"); + pb.val(x) = FieldT("3703141493535563179657531719960160174296085208671919316200479060314459804651"); + + MiMC_mp_gadget mimc_mp_gadget(pb, x, y, "gadget"); + mimc_mp_gadget.generate_r1cs_witness(); + mimc_mp_gadget.generate_r1cs_constraints(); + + FieldT expected_out = FieldT("16797922449555994684063104214233396200599693715764605878168345782964540311877"); + ASSERT_TRUE(expected_out == pb.val(mimc_mp_gadget.result())); +} + + +TEST(TestMiMCMp, TestFalse) { + libsnark::protoboard pb; + + // Public input + libsnark::pb_variable y; + y.allocate(pb, "y"); + pb.set_input_sizes(1); + pb.val(y) = FieldT("82724731331859054037315113496710413141112897654334566532528783843265082629790"); + + // Private inputs + libsnark::pb_variable x; + x.allocate(pb, "x"); + pb.val(x) = FieldT("3703141493535563179657531719960160174296085208671919316200479060314459804651"); + + MiMC_mp_gadget mimc_mp_gadget(pb, x, y, "gadget"); + mimc_mp_gadget.generate_r1cs_witness(); + mimc_mp_gadget.generate_r1cs_constraints(); + + FieldT not_expected_out = FieldT("15683951496311901749339509118960676303290224812129752890706581988986633412003"); + ASSERT_FALSE(not_expected_out == pb.val(mimc_mp_gadget.result())); +} + + + +TEST(TestMiMC, TestTrue) { libsnark::protoboard pb; libsnark::pb_variable in_x; @@ -92,23 +152,19 @@ TEST(TestRound, TestTrue) in_x.allocate(pb, "x"); in_k.allocate(pb, "k"); - pb.val(in_x) = FieldT("3703141493535563179657531719960160174296085208671919" - "316200479060314459804651"); - pb.val(in_k) = FieldT("1568395149631190174933950911896067630329022481212975" - "2890706581988986633412003"); + pb.val(in_x) = FieldT("3703141493535563179657531719960160174296085208671919316200479060314459804651"); + pb.val(in_k) = FieldT("15683951496311901749339509118960676303290224812129752890706581988986633412003"); - MiMCe7_permutation_gadget mimc_gadget( - pb, in_x, in_k, "mimc_gadget"); + MiMCe7_permutation_gadget mimc_gadget(pb, in_x, in_k, "mimc_gadget"); mimc_gadget.generate_r1cs_constraints(); mimc_gadget.generate_r1cs_witness(); - FieldT expected_out = FieldT("192990723315478049773124691205698348115617480" - "95378968014959488920239255590840"); + FieldT expected_out = FieldT("19299072331547804977312469120569834811561748095378968014959488920239255590840"); ASSERT_TRUE(expected_out == pb.val(mimc_gadget.result())); } -TEST(TestRound, TestFalse) -{ + + TEST(TestMiMC, TestFalse) { libsnark::protoboard pb; libsnark::pb_variable in_x; @@ -116,26 +172,21 @@ TEST(TestRound, TestFalse) in_x.allocate(pb, "x"); in_k.allocate(pb, "k"); - pb.val(in_x) = FieldT("3703141493535563179657531719960160174296085208671919" - "316200479060314459804651"); + pb.val(in_x) = FieldT("3703141493535563179657531719960160174296085208671919316200479060314459804651"); pb.val(in_k) = FieldT("13455131405143248756924738814405142"); - MiMCe7_permutation_gadget mimc_gadget( - pb, in_x, in_k, "mimc_gadget"); + MiMCe7_permutation_gadget mimc_gadget(pb, in_x, in_k, "mimc_gadget"); mimc_gadget.generate_r1cs_witness(); mimc_gadget.generate_r1cs_constraints(); - - FieldT expected_out = FieldT("114374678233937903873991372494419413137176864" - "41929791910070352316474327319704"); + + FieldT expected_out = FieldT("11437467823393790387399137249441941313717686441929791910070352316474327319704"); ASSERT_FALSE(expected_out == pb.val(mimc_gadget.result())); } } // namespace -int main(int argc, char **argv) -{ - ppT::init_public_params(); // /!\ WARNING: Do once for all tests. Do not - // forget to do this !!!! +int main(int argc, char **argv) { + ppT::init_public_params(); // /!\ WARNING: Do once for all tests. Do not forget to do this !!!! ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); -} +} \ No newline at end of file diff --git a/src/test/note_test.cpp b/src/test/note_test.cpp index f664637ac..5241228bd 100644 --- a/src/test/note_test.cpp +++ b/src/test/note_test.cpp @@ -6,8 +6,8 @@ // Header to use the merkle tree data structure #include "src/types/merkle_tree_field.hpp" -// Header to use the sha256_ethereum gadget -#include "circuits/sha256/sha256_ethereum.hpp" +// Header to use the blake2s gadget +#include "circuits/blake2s/blake2s_comp.hpp" // Access the `from_bits` function and other utils #include "circuits/circuits-util.hpp" @@ -27,7 +27,7 @@ using namespace libzeth; typedef libff::default_ec_pp ppT; typedef libff::Fr FieldT; // Should be alt_bn128 in the CMakeLists.txt -typedef sha256_ethereum +typedef BLAKE2s_256_comp HashT; // We use our hash function to do the tests typedef MiMC_mp_gadget HashTreeT; // We use our hash function to do the tests @@ -146,74 +146,63 @@ TEST(TestNoteCircuits, TestInputNoteGadget) ASSERT_TRUE(is_valid_witness); }; -TEST(TestNoteCircuits, TestOutputNoteGadget) -{ +TEST(TestNoteCircuits, TestOutputNoteGadget) { libsnark::protoboard pb; libsnark::pb_variable ZERO; ZERO.allocate(pb, "zero"); pb.val(ZERO) = FieldT::zero(); - libff::enter_block( - "Initialize the output coins' data (a_pk, cm, rho)", true); - bits384 trap_r_bits384 = - get_bits384_from_vector(hexadecimal_str_to_binary_vector( - "0F000000000000FF00000000000000FF00000000000000FF00000000000000FF00" - "000000000000FF00000000000000FF")); - bits64 value_bits64 = get_bits64_from_vector( - hexadecimal_str_to_binary_vector("2F0000000000000F")); - bits256 rho_bits256 = get_bits256_from_vector( - hexadecimal_digest_to_binary_vector("FFFF000000000000000000000000000000" - "000000000000000000000000009009")); - bits256 a_pk_bits256 = get_bits256_from_vector( - hexadecimal_digest_to_binary_vector("6461f753bfe21ba2219ced74875b8dbd8c" - "114c3c79d7e41306dd82118de1895b")); + libff::enter_block("Initialize the output coins' data (a_pk, cm, rho)", true); + bits384 trap_r_bits384 = get_bits384_from_vector(hexadecimal_str_to_binary_vector("0F000000000000FF00000000000000FF00000000000000FF00000000000000FF00000000000000FF00000000000000FF")); + bits64 value_bits64 = get_bits64_from_vector(hexadecimal_str_to_binary_vector("2F0000000000000F")); + bits256 rho_bits256 = get_bits256_from_vector(hexadecimal_digest_to_binary_vector("FFFF000000000000000000000000000000000000000000000000000000009009")); + bits256 a_pk_bits256 = get_bits256_from_vector(hexadecimal_digest_to_binary_vector("6461f753bfe21ba2219ced74875b8dbd8c114c3c79d7e41306dd82118de1895b")); // Get the coin's commitment (COMM) // - // inner_k = sha256(a_pk || rho) - // outer_k = sha256(r || [inner_commitment]_128) - // cm = sha256(outer_k || 0^192 || value_v) - bits256 cm_bits256 = get_bits256_from_vector( - hexadecimal_digest_to_binary_vector("823d19485c94f74b4739ba7d17e4b43469" - "3086a996fa2e8d1438a91b1c220331")); - libff::leave_block( - "Initialize the output coins' data (a_pk, cm, rho)", true); + // inner_k = blake2s(a_pk || rho) + // outer_k = blake2s(r || [inner_commitment]_128) + // cm = blake2s(outer_k || 0^192 || value_v) + bits256 cm_bits256 = get_bits256_from_vector(hexadecimal_digest_to_binary_vector("626876b3e2747325f469df067b1f86c8474ffe85e97f56f273c5798dcfccd925")); + libff::leave_block("Initialize the output coins' data (a_pk, cm, rho)", true); - libff::enter_block( - "Data conversion to generate a witness of the note gadget", true); + libff::enter_block("[BEGIN] Data conversion to generate a witness of the note gadget", true); - std::shared_ptr> rho_digest; - rho_digest.reset(new libsnark::digest_variable( - pb, HashT::get_digest_len(), "rho_digest")); + std::shared_ptr > rho_digest; + rho_digest.reset(new libsnark::digest_variable(pb, HashT::get_digest_len(), "rho_digest")); rho_digest->generate_r1cs_constraints(); - rho_digest->generate_r1cs_witness( - libff::bit_vector(get_vector_from_bits256(rho_bits256))); - - std::shared_ptr> commitment; - commitment.reset(new libsnark::digest_variable( - pb, HashT::get_digest_len(), "root_digest")); - std::shared_ptr> output_note_g = - std::shared_ptr>( - new output_note_gadget( - pb, ZERO, rho_digest, commitment)); + rho_digest->generate_r1cs_witness(libff::bit_vector(get_vector_from_bits256(rho_bits256))); + + std::shared_ptr > commitment; + commitment.reset(new libsnark::digest_variable(pb, HashT::get_digest_len(), "root_digest")); + std::shared_ptr> output_note_g = std::shared_ptr>( + new output_note_gadget( + pb, + ZERO, + rho_digest, + commitment + ) + ); // Create a note from the coin's data - ZethNote note(a_pk_bits256, value_bits64, rho_bits256, trap_r_bits384); + ZethNote note( + a_pk_bits256, + value_bits64, + rho_bits256, + trap_r_bits384 + ); output_note_g->generate_r1cs_constraints(); output_note_g->generate_r1cs_witness(note); - libff::leave_block( - "Data conversion to generate a witness of the note gadget", true); + libff::leave_block("Data conversion to generate a witness of the note gadget", true); bool is_valid_witness = pb.is_satisfied(); - std::cout << "************* SAT result: " << is_valid_witness - << " ******************" << std::endl; + std::cout << "************* SAT result: " << is_valid_witness << " ******************" << std::endl; ASSERT_TRUE(is_valid_witness); // Last check to make sure the commitment computed is the expected one libff::bit_vector obtained_digest = commitment->get_digest(); - libff::bit_vector expected_digest = - libff::bit_vector(get_vector_from_bits256(cm_bits256)); + libff::bit_vector expected_digest = libff::bit_vector(get_vector_from_bits256(cm_bits256)); ASSERT_EQ(obtained_digest, expected_digest); }; diff --git a/src/test/prfs_test.cpp b/src/test/prfs_test.cpp index 662514375..c08f7de6a 100644 --- a/src/test/prfs_test.cpp +++ b/src/test/prfs_test.cpp @@ -11,8 +11,8 @@ #include #include -// Header to use the sha256_ethereum gadget -#include "circuits/sha256/sha256_ethereum.hpp" +// Header to use the blake2s gadget +#include "circuits/blake2s/blake2s_comp.hpp" // Access the `from_bits` function and other utils #include "circuits/circuits-util.hpp" @@ -28,7 +28,7 @@ typedef libff::default_ec_pp ppT; // Should be alt_bn128 in the CMakeLists.txt typedef libff::Fr FieldT; // We use our hash function to do the tests -typedef sha256_ethereum HashT; +typedef BLAKE2s_256_comp HashT; namespace { @@ -130,13 +130,13 @@ TEST(TestPRFs, TestPRFAddrApkGadget) // a_pk should equal: // 0x208f95ee37621c3c2d9c74be39bf687c47e84c679b88df270858067c08a16daf Since - // a_pk = sha256( 1100 || [a_sk]_252 || 0^256), where: + // a_pk = blake2s( 1100 || [a_sk]_252 || 0^256), where: // - a_sk = // 0x0F000000000000FF00000000000000FF00000000000000FF00000000000000FF // - 0^256 = // 0x0000000000000000000000000000000000000000000000000000000000000000 // Note: - // This test vector has been generated by using the solidity sha256 function + // This test vector has been generated by using the solidity blake2s function // Note: (we want to make sure that we generate the same digests both // on-chain and off-chain) libsnark::pb_variable_array a_pk_expected = from_bits( @@ -246,10 +246,10 @@ TEST(TestPRFs, TestPRFNFGadget) // nf should equal: // 4a5f4f585dda39cc597366f9172bae924d22e832487e12e76742dbab9393b620 - // nf = sha256( 1110 || [a_sk]_252 || rho) a_sk: + // nf = blake2s( 1110 || [a_sk]_252 || rho) a_sk: // 0x0F000000000000FF00000000000000FF00000000000000FF00000000000000FF rho: // 0x0F000000000000FF00000000000000FF00000000000000FF00000000000000FF Note: - // This test vector has been generated by using the solidity sha256 function + // This test vector has been generated by using the solidity blake2s function // (we want to make sure that we generate the same digests both on-chain and // off-chain) libsnark::pb_variable_array nf_expected = from_bits( @@ -359,10 +359,10 @@ TEST(TestPRFs, TestPRFPKGadget) // h_i should equal: // 7ea1525fdbf9462c5144796937e1f80b9dad42369f7d4987c436b2f79257f9ac h_i = - // sha256( 0i00 || [a_sk]_252 || h_sig) a_sk: + // blake2s( 0i00 || [a_sk]_252 || h_sig) a_sk: // 0x0F000000000000FF00000000000000FF00000000000000FF00000000000000FF h_sig: // 0x0F000000000000FF00000000000000FF00000000000000FF00000000000000FF Note: - // This test vector has been generated by using the solidity sha256 function + // This test vector has been generated by using the solidity blake2s function // (we want to make sure that we generate the same digests both on-chain and // off-chain)) libsnark::pb_variable_array h_expected0 = from_bits( @@ -489,10 +489,10 @@ TEST(TestPRFs, TestPRFRhoGadget) // rho should equal: // a87c47a6c721bdbbb4aa8875c2aa72d4db31b9526aa920656049e00786f7f8a4 - // rho = sha256( 0i10 || [phi]_252 || h_sig) phi: + // rho = blake2s( 0i10 || [phi]_252 || h_sig) phi: // 0x0F000000000000FF00000000000000FF00000000000000FF00000000000000FF hsig: // 0x0F000000000000FF00000000000000FF00000000000000FF00000000000000FF Note: - // This test vector has been generated by using the solidity sha256 function + // This test vector has been generated by using the solidity blake2s function // (we want to make sure that we generate the same digests both on-chain and // off-chain) libsnark::pb_variable_array rho_expected0 = from_bits( diff --git a/src/test/prover_test.cpp b/src/test/prover_test.cpp index 1836d89db..0886c46a5 100644 --- a/src/test/prover_test.cpp +++ b/src/test/prover_test.cpp @@ -15,7 +15,7 @@ #include // Import only the core components of the SNARK (not the API components) #include "circuit-wrapper.hpp" -#include "circuits/sha256/sha256_ethereum.hpp" +#include "circuits/blake2s/blake2s_comp.hpp" #include "libsnark_helpers/libsnark_helpers.hpp" #include "snarks_core_imports.hpp" #include "util.hpp" @@ -25,7 +25,7 @@ using namespace libzeth; // Instantiation of the templates for the tests typedef libff::default_ec_pp ppT; typedef libff::Fr FieldT; // Should be alt_bn128 in the CMakeLists.txt -typedef sha256_ethereum HashT; +typedef BLAKE2s_256_comp HashT; typedef MiMC_mp_gadget HashTreeT; namespace diff --git a/src/types/bits.cpp b/src/types/bits.cpp index 910c5e9ce..df8ff81c2 100644 --- a/src/types/bits.cpp +++ b/src/types/bits.cpp @@ -18,6 +18,11 @@ bits64 get_bits64_from_vector(std::vector vect) return dump_vector_in_array<64>(vect); } +bits32 get_bits32_from_vector(std::vector vect) +{ + return dump_vector_in_array<32>(vect); +} + bitsAddr get_bitsAddr_from_vector(std::vector vect) { return dump_vector_in_array(vect); @@ -38,6 +43,11 @@ std::vector get_vector_from_bits64(bits64 arr) return dump_array_in_vector<64>(arr); } +std::vector get_vector_from_bits32(bits32 arr) +{ + return dump_array_in_vector<32>(arr); +} + std::vector get_vector_from_bitsAddr(bitsAddr arr) { return dump_array_in_vector(arr); diff --git a/src/types/bits.hpp b/src/types/bits.hpp index 32b002b4b..5a7ada29a 100644 --- a/src/types/bits.hpp +++ b/src/types/bits.hpp @@ -13,6 +13,7 @@ namespace libzeth typedef std::array bits384; typedef std::array bits256; typedef std::array bits64; +typedef std::array bits32; typedef std::array bitsAddr; // Dump a vector into an array @@ -22,6 +23,7 @@ std::array dump_vector_in_array(std::vector vect); bits384 get_bits384_from_vector(std::vector vect); bits256 get_bits256_from_vector(std::vector vect); bits64 get_bits64_from_vector(std::vector vect); +bits32 get_bits32_from_vector(std::vector vect); bitsAddr get_bitsAddr_from_vector(std::vector vect); // Dump an array into a vector @@ -31,12 +33,16 @@ std::vector dump_array_in_vector(std::array arr); std::vector get_vector_from_bits384(bits384 arr); std::vector get_vector_from_bits256(bits256 arr); std::vector get_vector_from_bits64(bits64 arr); +std::vector get_vector_from_bits32(bits32 arr); std::vector get_vector_from_bitsAddr(bitsAddr arr); // Sum 2 binary strings template -std::array binaryAddition( - std::array A, std::array B); +std::array binaryAddition(std::array A, std::array B); +template +std::array binaryAdditionNoCarry(std::array A, std::array B); +template +std::array binaryXOR(std::array A, std::array B); bits64 sum_bits64(bits64 a, bits64 b); diff --git a/src/types/bits.tcc b/src/types/bits.tcc index 2afde1bf7..e7e160445 100644 --- a/src/types/bits.tcc +++ b/src/types/bits.tcc @@ -51,6 +51,34 @@ std::array binaryAddition( return sum; } +// Sum 2 binary strings, discard last carry +template +std::array binaryAdditionNoCarry(std::array A, std::array B) { + std::array sum; + sum.fill(0); + + bool carry = 0; + for(int i = BitLen - 1; i >= 0; i--){ + sum[i] = ((A[i] ^ B[i]) ^ carry); // c is carry + carry = ((A[i] & B[i]) | (A[i] & carry)) | (B[i] & carry); + } + + return sum; +} + +// XOR 2 binary strings +template +std::array binaryXOR(std::array A, std::array B) { + std::array xor_array; + xor_array.fill(0); + + for(int i = BitLen - 1; i >= 0; i--){ + xor_array[i] = A[i] != B[i]; // c is carry + } + + return xor_array; +} + } // namespace libzeth #endif // __ZETH_BITS_TCC__ \ No newline at end of file diff --git a/src/zeth.h b/src/zeth.h index 75e64f5de..6e150e283 100644 --- a/src/zeth.h +++ b/src/zeth.h @@ -12,7 +12,7 @@ #define ZETH_A_SK_SIZE 32 // 256 bits for rho #define ZETH_R_SIZE 48 // 384 bits for r -#define ZETH_DIGEST_BIT_SIZE 256 // Size of a sha256 digest in bits -#define ZETH_DIGEST_HEX_SIZE 64 // Size of a sha256 digest in hex characters +#define ZETH_DIGEST_BIT_SIZE 256 // Size of a HashT digest in bits +#define ZETH_DIGEST_HEX_SIZE 64 // Size of a HashT digest in hex characters #endif // __ZETH_CONSTANTS__