Botan  1.11.15
src/lib/pubkey/mce/mceliece.h
Go to the documentation of this file.
00001 /**
00002  * (C) Copyright Projet SECRET, INRIA, Rocquencourt
00003  * (C) Bhaskar Biswas and  Nicolas Sendrier
00004  *
00005  * (C) 2014 cryptosource GmbH
00006  * (C) 2014 Falko Strenzke fstrenzke@cryptosource.de
00007  *
00008  * Botan is released under the Simplified BSD License (see license.txt)
00009  *
00010  */
00011 
00012 #ifndef BOTAN_MCELIECE_H__
00013 #define BOTAN_MCELIECE_H__
00014 
00015 #include <botan/secmem.h>
00016 #include <botan/types.h>
00017 #include <botan/pk_ops.h>
00018 #include <botan/mceliece_key.h>
00019 
00020 #define MASK_LOG2_BYTE ((1 << 3) - 1)
00021 #define _BITP_TO_BYTEP(__bit_pos) (__bit_pos >> 3)
00022 #define _BITP_TO_BYTEOFFS(__bit_pos) (__bit_pos & MASK_LOG2_BYTE)
00023 
00024 namespace Botan {
00025 
00026 secure_vector<gf2m> BOTAN_DLL create_random_error_positions(unsigned code_length, unsigned error_weight, RandomNumberGenerator& rng);
00027 
00028 class mceliece_message_parts
00029    {
00030    public:
00031 
00032       mceliece_message_parts(const secure_vector<gf2m>& err_pos, const byte* message, u32bit message_length, u32bit code_length) :
00033          m_error_vector(error_vector_from_error_positions(&err_pos[0], err_pos.size(), code_length)),
00034          m_code_length(code_length)
00035          {
00036          m_message_word.resize(message_length);
00037          copy_mem(&m_message_word[0], message, message_length);
00038          }
00039 
00040       mceliece_message_parts(const secure_vector<gf2m>& err_pos, const secure_vector<byte>& message, unsigned code_length) :
00041          m_error_vector(error_vector_from_error_positions(&err_pos[0], err_pos.size(), code_length)),
00042          m_message_word(message),
00043          m_code_length(code_length)
00044          {}
00045 
00046       static secure_vector<byte> error_vector_from_error_positions(const gf2m* err_pos, size_t err_pos_len, size_t code_length)
00047          {
00048          secure_vector<byte> result((code_length+7)/8);
00049          for(unsigned i = 0; i < err_pos_len; i++)
00050             {
00051             u16bit pos = err_pos[i];
00052             u32bit byte_pos = _BITP_TO_BYTEP(pos);
00053             if(byte_pos > result.size())
00054                {
00055                throw Invalid_Argument("error position larger than code size");
00056                }
00057             result[byte_pos] |= (1 << _BITP_TO_BYTEOFFS(pos));
00058             }
00059          return result;
00060          }
00061 
00062       mceliece_message_parts(const byte* message_concat_errors, size_t message_concat_errors_len, unsigned code_length) :
00063          m_code_length(code_length)
00064          {
00065          size_t err_vec_len = (code_length+7)/8;
00066          if(message_concat_errors_len < err_vec_len )
00067             {
00068             throw Invalid_Argument("cannot split McEliece message parts");
00069             }
00070          size_t err_vec_start_pos = message_concat_errors_len - err_vec_len;
00071          m_message_word = secure_vector<byte>(err_vec_start_pos );
00072          copy_mem(&m_message_word[0], &message_concat_errors[0], err_vec_start_pos);
00073          m_error_vector = secure_vector<byte>(err_vec_len );
00074          copy_mem(&m_error_vector[0],  &message_concat_errors[err_vec_start_pos], err_vec_len);
00075          }
00076 
00077       secure_vector<byte> get_concat() const
00078          {
00079          secure_vector<byte> result(m_error_vector.size() + m_message_word.size());
00080          copy_mem(&result[0], &m_message_word[0], m_message_word.size());
00081          copy_mem(&result[m_message_word.size()], &m_error_vector[0], m_error_vector.size());
00082          return result;
00083          }
00084 
00085       secure_vector<gf2m> get_error_positions() const
00086          {
00087          secure_vector<gf2m> result;
00088          for(unsigned i = 0; i < m_code_length; i++)
00089             {
00090             if(i >= m_code_length)
00091                {
00092                throw Invalid_Argument("index out of range in get_error_positions()");
00093                }
00094             if((m_error_vector[_BITP_TO_BYTEP(i)] >> _BITP_TO_BYTEOFFS(i)) & 1)
00095                {
00096                result.push_back(i);
00097                }
00098             }
00099          return result;
00100          }
00101 
00102       secure_vector<byte> get_error_vector() const { return m_error_vector; }
00103       secure_vector<byte> get_message_word() const { return m_message_word; }
00104    private:
00105       secure_vector<byte> m_error_vector;
00106       secure_vector<byte> m_message_word;
00107       unsigned m_code_length;
00108    };
00109 
00110 class BOTAN_DLL McEliece_Private_Operation : public PK_Ops::Decryption
00111    {
00112    public:
00113       McEliece_Private_Operation(const McEliece_PrivateKey& mce_key);
00114 
00115       size_t max_input_bits() const { return m_priv_key.max_input_bits();  }
00116 
00117       secure_vector<byte> decrypt(const byte msg[], size_t msg_len);
00118 
00119       McEliece_PrivateKey const& get_key() const { return m_priv_key; }
00120 
00121    private:
00122       const McEliece_PrivateKey m_priv_key;
00123    };
00124 
00125 class BOTAN_DLL McEliece_Public_Operation : public PK_Ops::Encryption
00126    {
00127    public:
00128       McEliece_Public_Operation(const McEliece_PublicKey& public_key, u32bit code_length);
00129 
00130       size_t max_input_bits() const { return m_pub_key.max_input_bits(); }
00131       secure_vector<byte> encrypt(const byte msg[], size_t msg_len, RandomNumberGenerator&);
00132 
00133       McEliece_PublicKey const& get_key() const { return m_pub_key; }
00134 
00135    private:
00136       McEliece_PublicKey m_pub_key;
00137       u32bit m_code_length;
00138    };
00139 
00140 /**
00141 * Estimate work factor for McEliece
00142 * @return estimated security level for these key parameters
00143 */
00144 BOTAN_DLL size_t mceliece_work_factor(size_t code_size, size_t k, size_t t);
00145 
00146 }
00147 
00148 
00149 #endif