aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pubkey/mce/mceliece_key.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pubkey/mce/mceliece_key.cpp')
-rw-r--r--src/lib/pubkey/mce/mceliece_key.cpp75
1 files changed, 43 insertions, 32 deletions
diff --git a/src/lib/pubkey/mce/mceliece_key.cpp b/src/lib/pubkey/mce/mceliece_key.cpp
index 8cda0af89..8edbbf88a 100644
--- a/src/lib/pubkey/mce/mceliece_key.cpp
+++ b/src/lib/pubkey/mce/mceliece_key.cpp
@@ -9,15 +9,12 @@
*
*/
-#include <botan/mceliece_key.h>
-#include <botan/internal/bit_ops.h>
-#include <botan/gf2m_small_m.h>
#include <botan/mceliece.h>
-#include <botan/internal/code_based_key_gen.h>
-#include <botan/code_based_util.h>
+#include <botan/internal/mce_internal.h>
+#include <botan/internal/bit_ops.h>
+#include <botan/internal/code_based_util.h>
#include <botan/der_enc.h>
#include <botan/ber_dec.h>
-#include <botan/workfactor.h>
namespace Botan {
@@ -42,12 +39,29 @@ McEliece_PrivateKey::McEliece_PrivateKey(RandomNumberGenerator& rng, size_t code
*this = generate_mceliece_key(rng, ext_deg, code_length, t);
}
-unsigned McEliece_PublicKey::get_message_word_bit_length() const
+u32bit McEliece_PublicKey::get_message_word_bit_length() const
{
u32bit codimension = ceil_log2(m_code_length) * m_t;
return m_code_length - codimension;
}
+secure_vector<byte> McEliece_PublicKey::random_plaintext_element(RandomNumberGenerator& rng) const
+ {
+ const size_t bits = get_message_word_bit_length();
+
+ secure_vector<byte> plaintext((bits+7)/8);
+ rng.randomize(plaintext.data(), plaintext.size());
+
+ // unset unused bits in the last plaintext byte
+ if(u32bit used = bits % 8)
+ {
+ const byte mask = (1 << used) - 1;
+ plaintext[plaintext.size() - 1] &= mask;
+ }
+
+ return plaintext;
+ }
+
AlgorithmIdentifier McEliece_PublicKey::algorithm_identifier() const
{
return AlgorithmIdentifier(get_oid(), std::vector<byte>());
@@ -55,16 +69,15 @@ AlgorithmIdentifier McEliece_PublicKey::algorithm_identifier() const
std::vector<byte> McEliece_PublicKey::x509_subject_public_key() const
{
- // encode the public key
- return unlock(DER_Encoder()
- .start_cons(SEQUENCE)
- .start_cons(SEQUENCE)
- .encode(static_cast<size_t>(get_code_length()))
- .encode(static_cast<size_t>(get_t()))
- .end_cons()
- .encode(m_public_matrix, OCTET_STRING)
- .end_cons()
- .get_contents());
+ return DER_Encoder()
+ .start_cons(SEQUENCE)
+ .start_cons(SEQUENCE)
+ .encode(static_cast<size_t>(get_code_length()))
+ .encode(static_cast<size_t>(get_t()))
+ .end_cons()
+ .encode(m_public_matrix, OCTET_STRING)
+ .end_cons()
+ .get_contents_unlocked();
}
McEliece_PublicKey::McEliece_PublicKey(const McEliece_PublicKey & other) :
@@ -76,9 +89,7 @@ McEliece_PublicKey::McEliece_PublicKey(const McEliece_PublicKey & other) :
size_t McEliece_PublicKey::estimated_strength() const
{
- const u32bit ext_deg = ceil_log2(m_code_length);
- const size_t k = m_code_length - ext_deg * m_t;
- return mceliece_work_factor(m_code_length, k, m_t);
+ return mceliece_work_factor(m_code_length, m_t);
}
McEliece_PublicKey::McEliece_PublicKey(const std::vector<byte>& key_bits)
@@ -135,19 +146,20 @@ secure_vector<byte> McEliece_PrivateKey::pkcs8_private_key() const
bool McEliece_PrivateKey::check_key(RandomNumberGenerator& rng, bool) const
{
- McEliece_Private_Operation priv_op(*this);
- McEliece_Public_Operation pub_op(*this, get_code_length());
+ const secure_vector<byte> plaintext = this->random_plaintext_element(rng);
- secure_vector<byte> plaintext((this->get_message_word_bit_length()+7)/8);
- rng.randomize(plaintext.data(), plaintext.size() - 1);
- const secure_vector<gf2m> err_pos = create_random_error_positions(this->get_code_length(), this->get_t(), rng);
+ secure_vector<byte> ciphertext;
+ secure_vector<byte> errors;
+ mceliece_encrypt(ciphertext, errors, plaintext, *this, rng);
- mceliece_message_parts parts(err_pos, plaintext, this->get_code_length());
- secure_vector<byte> message_and_error_input = parts.get_concat();
- secure_vector<byte> ciphertext = pub_op.encrypt(message_and_error_input.data(), message_and_error_input.size(), rng);
- secure_vector<byte> message_and_error_output = priv_op.decrypt(ciphertext.data(), ciphertext.size());
+ secure_vector<byte> plaintext_out;
+ secure_vector<byte> errors_out;
+ mceliece_decrypt(plaintext_out, errors_out, ciphertext, *this);
- return (message_and_error_input == message_and_error_output);
+ if(errors != errors_out || plaintext != plaintext_out)
+ return false;
+
+ return true;
}
McEliece_PrivateKey::McEliece_PrivateKey(const secure_vector<byte>& key_bits)
@@ -172,7 +184,7 @@ McEliece_PrivateKey::McEliece_PrivateKey(const secure_vector<byte>& key_bits)
m_codimension = (ext_deg * t);
m_dimension = (n - m_codimension);
- std::shared_ptr<gf2m_small_m::Gf2m_Field> sp_field(new gf2m_small_m::Gf2m_Field(ext_deg));
+ std::shared_ptr<GF2m_Field> sp_field(new GF2m_Field(ext_deg));
m_g = polyn_gf2m(g_enc, sp_field);
if(m_g.get_degree() != static_cast<int>(t))
{
@@ -231,7 +243,6 @@ McEliece_PrivateKey::McEliece_PrivateKey(const secure_vector<byte>& key_bits)
}
-
bool McEliece_PrivateKey::operator==(const McEliece_PrivateKey & other) const
{
if(*static_cast<const McEliece_PublicKey*>(this) != *static_cast<const McEliece_PublicKey*>(&other))