/* * (C) Copyright Projet SECRET, INRIA, Rocquencourt * (C) Bhaskar Biswas and Nicolas Sendrier * * (C) 2014 cryptosource GmbH * (C) 2014 Falko Strenzke fstrenzke@cryptosource.de * * Botan is released under the Simplified BSD License (see license.txt) * */ #ifndef BOTAN_POLYN_GF2M_H_ #define BOTAN_POLYN_GF2M_H_ #include #include #include // Currently must be visible for MSVC //BOTAN_FUTURE_INTERNAL_HEADER(polyn_gf2m.h) namespace Botan { typedef uint16_t gf2m; class GF2m_Field; class RandomNumberGenerator; class polyn_gf2m { public: /** * create a zero polynomial: */ explicit polyn_gf2m(std::shared_ptr sp_field); polyn_gf2m() : m_deg(-1) {} polyn_gf2m(const secure_vector& encoded, std::shared_ptr sp_field); polyn_gf2m& operator=(const polyn_gf2m&) = default; /** * create zero polynomial with reservation of space for a degree d polynomial */ polyn_gf2m(int d, std::shared_ptr sp_field); polyn_gf2m(polyn_gf2m const& other); /** * random irreducible polynomial of degree t */ polyn_gf2m(size_t t, RandomNumberGenerator& rng, std::shared_ptr sp_field); /** decode a polynomial from memory: **/ polyn_gf2m(const uint8_t* mem, uint32_t mem_len, std::shared_ptr sp_field); /** * create a polynomial from memory area (encoded) */ polyn_gf2m(int degree, const uint8_t* mem, size_t mem_byte_len, std::shared_ptr sp_field); bool operator==(const polyn_gf2m & other) const ; bool operator!=(const polyn_gf2m & other) const { return !(*this == other); } polyn_gf2m(polyn_gf2m&& other) { this->swap(other); } polyn_gf2m & operator=(polyn_gf2m&& other) { if(this != &other) { this->swap(other); } return *this; } void swap(polyn_gf2m& other); secure_vector encode() const; std::shared_ptr get_sp_field() const { return m_sp_field; } gf2m& operator[](size_t i) { return coeff[i]; } gf2m operator[](size_t i) const { return coeff[i]; } gf2m get_lead_coef() const { return coeff[m_deg]; } gf2m get_coef(size_t i) const { return coeff[i]; } inline void set_coef(size_t i, gf2m v) { coeff[i] = v; } inline void add_to_coef(size_t i, gf2m v) { coeff[i] ^= v; } std::string to_string() const; void encode(uint32_t min_numo_coeffs, uint8_t* mem, uint32_t mem_len) const; int get_degree() const; /** * determine the degree in a timing secure manner. the timing of this function * only depends on the number of allocated coefficients, not on the actual * degree */ int calc_degree_secure() const; size_t degppf(const polyn_gf2m& g); static std::vector sqmod_init(const polyn_gf2m & g); static std::vector sqrt_mod_init(const polyn_gf2m & g); polyn_gf2m sqmod(const std::vector & sq, int d); void set_to_zero(); gf2m eval(gf2m a); static std::pair eea_with_coefficients(const polyn_gf2m & p, const polyn_gf2m & g, int break_deg); void patchup_deg_secure( uint32_t trgt_deg, volatile gf2m patch_elem); private: void set_degree(int d) { m_deg = d; } void poly_shiftmod( const polyn_gf2m & g); void realloc(uint32_t new_size); static polyn_gf2m gcd(polyn_gf2m const& p1, polyn_gf2m const& p2); /** * destructive: */ static void remainder(polyn_gf2m & p, const polyn_gf2m & g); static polyn_gf2m gcd_aux(polyn_gf2m& p1, polyn_gf2m& p2); public: // public member variable: int m_deg; // public member variable: secure_vector coeff; // public member variable: std::shared_ptr m_sp_field; }; gf2m random_gf2m(RandomNumberGenerator& rng); gf2m random_code_element(uint16_t code_length, RandomNumberGenerator& rng); std::vector syndrome_init(polyn_gf2m const& generator, std::vector const& support, int n); /** * Find the roots of a polynomial over GF(2^m) using the method by Federenko et al. */ secure_vector find_roots_gf2m_decomp(const polyn_gf2m & polyn, size_t code_length); } #endif