Skip to content

Commit

Permalink
Eddsa verification added. Tests updated. #7
Browse files Browse the repository at this point in the history
  • Loading branch information
Ilias Khairullin committed Sep 21, 2021
1 parent 5fbfc1b commit 648c888
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 30 deletions.
66 changes: 62 additions & 4 deletions include/nil/crypto3/pubkey/eddsa.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,6 @@ namespace nil {
typedef nil::crypto3::marshalling::types::field_element<nil::marshalling::field_type<endianness>,
scalar_field_type>
marshalling_scalar_field_value_type;
// typedef nil::crypto3::marshalling::types::integral<nil::marshalling::field_type<endianness>,
// scalar_integral_type>
// marshalling_scalar_integral_type;
typedef nil::crypto3::marshalling::types::integral<nil::marshalling::field_type<endianness>,
base_integral_type>
marshalling_base_integral_type;
Expand All @@ -185,14 +182,74 @@ namespace nil {
typedef std::array<std::uint8_t, signature_octets> 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<typename InputRange>
inline void update(internal_accumulator_type &acc, const InputRange &range) const {
encode<padding_policy>(range, acc);
}

template<typename InputIterator>
inline void update(internal_accumulator_type &acc, InputIterator first, InputIterator last) const {
encode<padding_policy>(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<padding::encoding_policy<padding_policy>>(acc);
accumulator_set<hash_type> hash_acc_2;
hash<hash_type>(policy_type::get_dom(), hash_acc_2);
hash<hash_type>(std::cbegin(signature), std::cbegin(signature) + public_key_octets, hash_acc_2);
hash<hash_type>(this->pubkey, hash_acc_2);
hash<hash_type>(ph_m, hash_acc_2);
typename hash_type::digest_type h_2 =
nil::crypto3::accumulators::extract::hash<hash_type>(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 {
return pubkey;
}

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;
};

Expand Down Expand Up @@ -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;
Expand Down
58 changes: 32 additions & 26 deletions test/eddsa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,38 @@ struct test_eddsa_params_void {
static inline const context_type context = {};
};

template<pubkey::EddsaVariant eddsa_variant,
typename Params,
typename InputRange,
typename Group = algebra::curves::curve25519::template g1_type<>>
void check_eddsa(
const InputRange &msg,
const pubkey::private_key<pubkey::eddsa<Group, eddsa_variant, Params>> &private_key,
const pubkey::public_key<pubkey::eddsa<Group, eddsa_variant, Params>> &etalon_public_key,
const typename pubkey::private_key<pubkey::eddsa<Group, eddsa_variant, Params>>::signature_type &etalon_sig) {
using scheme_type = pubkey::eddsa<Group, eddsa_variant, Params>;
using private_key_type = pubkey::private_key<scheme_type>;
using public_key_type = pubkey::public_key<scheme_type>;
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<scheme_type>(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<bool>(verify<scheme_type>(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<bool>(verify<scheme_type>(msg, wrong_sig, private_key)));
// wrong_sig[1] = sig[1];
// wrong_sig[33] = 0;
// BOOST_CHECK(!static_cast<bool>(verify<scheme_type>(msg, wrong_sig, private_key)));
// wrong_sig[1] = 0;
// wrong_sig[33] = 0;
// BOOST_CHECK(!static_cast<bool>(verify<scheme_type>(msg, wrong_sig, private_key)));
}

BOOST_AUTO_TEST_SUITE(eddsa_conformity_test_suite)

BOOST_AUTO_TEST_CASE(eddsa_key_gen_test) {
Expand Down Expand Up @@ -150,32 +182,6 @@ BOOST_AUTO_TEST_CASE(eddsa_key_gen_test) {
std::array<std::uint8_t, 16> 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<scheme_type>(msg, private_key);

for (auto c : sig) {
std::cout << std::hex << int(c) << " ";
}
std::cout << std::endl;
}

template<pubkey::EddsaVariant eddsa_variant,
typename Params,
typename InputRange,
typename Group = algebra::curves::curve25519::template g1_type<>>
void check_eddsa(
const InputRange &msg,
const pubkey::private_key<pubkey::eddsa<Group, eddsa_variant, Params>> &private_key,
const pubkey::public_key<pubkey::eddsa<Group, eddsa_variant, Params>> &etalon_public_key,
const typename pubkey::private_key<pubkey::eddsa<Group, eddsa_variant, Params>>::signature_type &etalon_sig) {
using scheme_type = pubkey::eddsa<Group, eddsa_variant, Params>;
using private_key_type = pubkey::private_key<scheme_type>;
using public_key_type = pubkey::public_key<scheme_type>;
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<scheme_type>(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
Expand Down

0 comments on commit 648c888

Please sign in to comment.