diff options
author | Jack Lloyd <[email protected]> | 2021-05-22 11:33:42 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2021-05-24 19:04:12 -0400 |
commit | c772d2748299c18359b2b401300d58e00b6fa010 (patch) | |
tree | 9d888e21f1cafae8edf0fe076a6f8857b5e9d34d /src/lib | |
parent | 4aa1a8b403d4453e33106ba6667ab0f587e8f0f3 (diff) |
Fix an ECKCDSA bug
Add some more test vectors (taken from https://github.com/ANSSI-FR/libecc)
and fix a bug which occured when either the group was not an even multiple
of 8 bits, or when the x,y coordinates had any leading zero bytes.
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/pubkey/eckcdsa/eckcdsa.cpp | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/src/lib/pubkey/eckcdsa/eckcdsa.cpp b/src/lib/pubkey/eckcdsa/eckcdsa.cpp index 5398946a8..d50d5864e 100644 --- a/src/lib/pubkey/eckcdsa/eckcdsa.cpp +++ b/src/lib/pubkey/eckcdsa/eckcdsa.cpp @@ -57,10 +57,15 @@ class ECKCDSA_Signature_Operation final : public PK_Ops::Signature_with_EMSA const BigInt public_point_x = eckcdsa.public_point().get_affine_x(); const BigInt public_point_y = eckcdsa.public_point().get_affine_y(); - m_prefix.resize(public_point_x.bytes() + public_point_y.bytes()); - public_point_x.binary_encode(m_prefix.data()); - public_point_y.binary_encode(&m_prefix[public_point_x.bytes()]); - m_prefix.resize(HashFunction::create(hash_for_signature())->hash_block_size()); // use only the "hash input block size" leftmost bits + const size_t order_bytes = m_group.get_order_bytes(); + + m_prefix.resize(2*order_bytes); + BigInt::encode_1363(&m_prefix[0], order_bytes, public_point_x); + BigInt::encode_1363(&m_prefix[order_bytes], order_bytes, public_point_y); + + const size_t block_size = HashFunction::create(hash_for_signature())->hash_block_size(); + // Either truncate or zero-extend to match the hash block size + m_prefix.resize(block_size); } secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len, @@ -126,10 +131,15 @@ class ECKCDSA_Verification_Operation final : public PK_Ops::Verification_with_EM const BigInt public_point_x = eckcdsa.public_point().get_affine_x(); const BigInt public_point_y = eckcdsa.public_point().get_affine_y(); - m_prefix.resize(public_point_x.bytes() + public_point_y.bytes()); - public_point_x.binary_encode(&m_prefix[0]); - public_point_y.binary_encode(&m_prefix[public_point_x.bytes()]); - m_prefix.resize(HashFunction::create(hash_for_signature())->hash_block_size()); // use only the "hash input block size" leftmost bits + const size_t order_bytes = m_group.get_order_bytes(); + + m_prefix.resize(2*order_bytes); + BigInt::encode_1363(&m_prefix[0], order_bytes, public_point_x); + BigInt::encode_1363(&m_prefix[order_bytes], order_bytes, public_point_y); + + const size_t block_size = HashFunction::create(hash_for_signature())->hash_block_size(); + // Either truncate or zero-extend to match the hash block size + m_prefix.resize(block_size); } bool has_prefix() override { return true; } @@ -178,7 +188,10 @@ bool ECKCDSA_Verification_Operation::verify(const uint8_t msg[], size_t, const PointGFp q = m_gy_mul.multi_exp(w, s); if(q.is_zero()) + { return false; + } + const BigInt q_x = q.get_affine_x(); secure_vector<uint8_t> c(q_x.bytes()); q_x.binary_encode(c.data()); |