From 648c88878c53eb31ccc00e9ae6b6020f246cdd35 Mon Sep 17 00:00:00 2001 From: Ilias Khairullin Date: Tue, 21 Sep 2021 18:56:22 +0300 Subject: [PATCH] Eddsa verification added. Tests updated. #7 --- include/nil/crypto3/pubkey/eddsa.hpp | 66 ++++++++++++++++++++++++++-- test/eddsa.cpp | 58 +++++++++++++----------- 2 files changed, 94 insertions(+), 30 deletions(-) diff --git a/include/nil/crypto3/pubkey/eddsa.hpp b/include/nil/crypto3/pubkey/eddsa.hpp index 70031ce..d818815 100644 --- a/include/nil/crypto3/pubkey/eddsa.hpp +++ b/include/nil/crypto3/pubkey/eddsa.hpp @@ -167,9 +167,6 @@ namespace nil { typedef nil::crypto3::marshalling::types::field_element, scalar_field_type> marshalling_scalar_field_value_type; - // typedef nil::crypto3::marshalling::types::integral, - // scalar_integral_type> - // marshalling_scalar_integral_type; typedef nil::crypto3::marshalling::types::integral, base_integral_type> marshalling_base_integral_type; @@ -185,7 +182,57 @@ namespace nil { typedef std::array signature_type; public_key() = delete; - public_key(const public_key_type &key) : pubkey(key) { + public_key(const public_key_type &key) : pubkey_point(read_pubkey(key)), pubkey(key) { + } + + static inline void init_accumulator(internal_accumulator_type &acc) { + } + + template + inline void update(internal_accumulator_type &acc, const InputRange &range) const { + encode(range, acc); + } + + template + inline void update(internal_accumulator_type &acc, InputIterator first, InputIterator last) const { + encode(first, last, acc); + } + + // https://datatracker.ietf.org/doc/html/rfc8032#section-5.1.7 + inline bool verify(internal_accumulator_type &acc, const signature_type &signature) const { + // 1. + marshalling_group_value_type marshalling_group_value_1; + auto R_iter_1 = std::cbegin(signature); + // TODO: process status + nil::marshalling::status_type status = + marshalling_group_value_1.read(R_iter_1, marshalling_group_value_type::bit_length()); + group_value_type R = marshalling_group_value_1.value(); + + marshalling_scalar_field_value_type marshalling_scalar_field_value_1; + auto S_iter_1 = std::cbegin(signature) + public_key_octets; + // TODO: process status + status = marshalling_scalar_field_value_1.read(S_iter_1, + marshalling_scalar_field_value_type::bit_length()); + scalar_field_value_type S = marshalling_scalar_field_value_1.value(); + + // 2. + auto ph_m = padding::accumulators::extract::encode>(acc); + accumulator_set hash_acc_2; + hash(policy_type::get_dom(), hash_acc_2); + hash(std::cbegin(signature), std::cbegin(signature) + public_key_octets, hash_acc_2); + hash(this->pubkey, hash_acc_2); + hash(ph_m, hash_acc_2); + typename hash_type::digest_type h_2 = + nil::crypto3::accumulators::extract::hash(hash_acc_2); + marshalling_uint512_t_type marshalling_uint512_t_2; + auto h_2_iter = std::cbegin(h_2); + // TODO: process status + status = marshalling_uint512_t_2.read(h_2_iter, hash_type::digest_bits); + nil::crypto3::multiprecision::uint512_t k = marshalling_uint512_t_2.value(); + scalar_field_value_type k_reduced(k); + + // 3. + return (S * group_value_type::one()) == (R + k_reduced * this->pubkey_point); } inline public_key_type public_key_data() const { @@ -193,6 +240,16 @@ namespace nil { } protected: + static inline group_value_type read_pubkey(const public_key_type &pubkey) { + marshalling_group_value_type marshalling_group_value_1; + auto pubkey_iter = std::cbegin(pubkey); + // TODO: process status + nil::marshalling::status_type status = + marshalling_group_value_1.read(pubkey_iter, marshalling_group_value_type::bit_length()); + return marshalling_group_value_1.value(); + } + + group_value_type pubkey_point; public_key_type pubkey; }; @@ -339,6 +396,7 @@ namespace nil { return s; } + // TODO: refactor eddsa private key internal fields private_key_type privkey; typename hash_type::digest_type h_privkey; scalar_field_value_type s_reduced; diff --git a/test/eddsa.cpp b/test/eddsa.cpp index d617fee..b88e5e5 100644 --- a/test/eddsa.cpp +++ b/test/eddsa.cpp @@ -118,6 +118,38 @@ struct test_eddsa_params_void { static inline const context_type context = {}; }; +template> +void check_eddsa( + const InputRange &msg, + const pubkey::private_key> &private_key, + const pubkey::public_key> &etalon_public_key, + const typename pubkey::private_key>::signature_type &etalon_sig) { + using scheme_type = pubkey::eddsa; + using private_key_type = pubkey::private_key; + using public_key_type = pubkey::public_key; + using _private_key_type = typename private_key_type::private_key_type; + using _public_key_type = typename public_key_type::public_key_type; + + typename private_key_type::signature_type sig = sign(msg, private_key); + + BOOST_CHECK(etalon_public_key.public_key_data() == private_key.public_key_data()); + BOOST_CHECK(etalon_sig == sig); + BOOST_CHECK(static_cast(verify(msg, sig, private_key))); + // TODO: add checks after catching exceptions in marshalling will be fixed + // auto wrong_sig = sig; + // wrong_sig[1] = 0; + // BOOST_CHECK(!static_cast(verify(msg, wrong_sig, private_key))); + // wrong_sig[1] = sig[1]; + // wrong_sig[33] = 0; + // BOOST_CHECK(!static_cast(verify(msg, wrong_sig, private_key))); + // wrong_sig[1] = 0; + // wrong_sig[33] = 0; + // BOOST_CHECK(!static_cast(verify(msg, wrong_sig, private_key))); +} + BOOST_AUTO_TEST_SUITE(eddsa_conformity_test_suite) BOOST_AUTO_TEST_CASE(eddsa_key_gen_test) { @@ -150,32 +182,6 @@ BOOST_AUTO_TEST_CASE(eddsa_key_gen_test) { std::array msg = {0xf7, 0x26, 0x93, 0x6d, 0x19, 0xc8, 0x00, 0x49, 0x4e, 0x3f, 0xda, 0xff, 0x20, 0xb2, 0x76, 0xa8}; typename private_key_type::signature_type sig = sign(msg, private_key); - - for (auto c : sig) { - std::cout << std::hex << int(c) << " "; - } - std::cout << std::endl; -} - -template> -void check_eddsa( - const InputRange &msg, - const pubkey::private_key> &private_key, - const pubkey::public_key> &etalon_public_key, - const typename pubkey::private_key>::signature_type &etalon_sig) { - using scheme_type = pubkey::eddsa; - using private_key_type = pubkey::private_key; - using public_key_type = pubkey::public_key; - using _private_key_type = typename private_key_type::private_key_type; - using _public_key_type = typename public_key_type::public_key_type; - - typename private_key_type::signature_type sig = sign(msg, private_key); - - BOOST_CHECK(etalon_public_key.public_key_data() == private_key.public_key_data()); - BOOST_CHECK(etalon_sig == sig); } // https://datatracker.ietf.org/doc/html/rfc8032#section-7.1