Botan 3.13.0
Crypto and TLS for C&
Botan::polyn_gf2m Class Reference

#include <polyn_gf2m.h>

Public Member Functions

void add_to_coef (size_t i, gf2m v)
int calc_degree_secure () const
secure_vector< uint8_t > encode () const
void encode (uint32_t min_numo_coeffs, uint8_t *mem, uint32_t mem_len) const
gf2m eval (gf2m a)
gf2m get_coef (size_t i) const
size_t get_coeff_count () const
int get_degree () const
gf2m get_lead_coef () const
std::shared_ptr< GF2m_Fieldget_sp_field () const
bool operator!= (const polyn_gf2m &other) const
polyn_gf2moperator= (const polyn_gf2m &)=default
polyn_gf2moperator= (polyn_gf2m &&other) noexcept
bool operator== (const polyn_gf2m &other) const
gf2moperator[] (size_t i)
gf2m operator[] (size_t i) const
void patchup_deg_secure (uint32_t trgt_deg, gf2m patch_elem)
 polyn_gf2m ()
 polyn_gf2m (const polyn_gf2m &other)
 polyn_gf2m (const secure_vector< uint8_t > &encoded, const std::shared_ptr< GF2m_Field > &sp_field)
 polyn_gf2m (const std::shared_ptr< GF2m_Field > &sp_field)
 polyn_gf2m (const uint8_t *mem, uint32_t mem_len, const std::shared_ptr< GF2m_Field > &sp_field)
 polyn_gf2m (int d, const std::shared_ptr< GF2m_Field > &sp_field)
 polyn_gf2m (int degree, const uint8_t *mem, size_t mem_byte_len, const std::shared_ptr< GF2m_Field > &sp_field)
 polyn_gf2m (polyn_gf2m &&other) noexcept
 polyn_gf2m (size_t t, RandomNumberGenerator &rng, const std::shared_ptr< GF2m_Field > &sp_field)
void set_coef (size_t i, gf2m v)
void set_to_zero ()
polyn_gf2m sqmod (const std::vector< polyn_gf2m > &sq, int d)
void swap (polyn_gf2m &other) noexcept
 ~polyn_gf2m ()=default

Static Public Member Functions

static size_t degppf (const polyn_gf2m &g)
static std::pair< polyn_gf2m, polyn_gf2meea_with_coefficients (const polyn_gf2m &p, const polyn_gf2m &g, int break_deg)
static std::vector< polyn_gf2msqmod_init (const polyn_gf2m &g)
static std::vector< polyn_gf2msqrt_mod_init (const polyn_gf2m &g)

Detailed Description

Definition at line 27 of file polyn_gf2m.h.

Constructor & Destructor Documentation

◆ polyn_gf2m() [1/9]

Botan::polyn_gf2m::polyn_gf2m ( const std::shared_ptr< GF2m_Field > & sp_field)
explicit

create a zero polynomial:

Definition at line 139 of file polyn_gf2m.cpp.

139: m_deg(-1), m_coeff(1), m_sp_field(sp_field) {}

Referenced by calc_degree_secure(), degppf(), eea_with_coefficients(), get_degree(), operator!=(), operator=(), operator=(), operator==(), polyn_gf2m(), polyn_gf2m(), polyn_gf2m(), sqmod(), sqmod_init(), sqrt_mod_init(), and swap().

◆ polyn_gf2m() [2/9]

Botan::polyn_gf2m::polyn_gf2m ( )
inline

Definition at line 34 of file polyn_gf2m.h.

34: m_deg(-1) {}

Referenced by sqrt_mod_init().

◆ polyn_gf2m() [3/9]

Botan::polyn_gf2m::polyn_gf2m ( const secure_vector< uint8_t > & encoded,
const std::shared_ptr< GF2m_Field > & sp_field )

Definition at line 650 of file polyn_gf2m.cpp.

650 :
651 m_sp_field(sp_field) {
652 if(!sp_field) {
653 throw Decoding_Error("missing field for polynomial decoding");
654 }
655
656 if(encoded.size() % 2) {
657 throw Decoding_Error("encoded polynomial has odd length");
658 }
659 const size_t field_cardinality = static_cast<size_t>(1) << sp_field->get_extension_degree();
660 for(uint32_t i = 0; i < encoded.size(); i += 2) {
661 const gf2m el = (encoded[i] << 8) | encoded[i + 1];
662 if(el >= field_cardinality) {
663 throw Decoding_Error("encoded polynomial coefficient is out of range");
664 }
665 m_coeff.push_back(el);
666 }
667 get_degree();
668}
int get_degree() const
uint16_t gf2m

◆ ~polyn_gf2m()

Botan::polyn_gf2m::~polyn_gf2m ( )
default

◆ polyn_gf2m() [4/9]

Botan::polyn_gf2m::polyn_gf2m ( int d,
const std::shared_ptr< GF2m_Field > & sp_field )

create zero polynomial with reservation of space for a degree d polynomial

Definition at line 100 of file polyn_gf2m.cpp.

100 : m_deg(-1), m_sp_field(sp_field) {
101 if(d < 0) {
102 throw Invalid_Argument("invalid polynomial degree");
103 }
104 m_coeff.resize(d + 1);
105}

◆ polyn_gf2m() [5/9]

Botan::polyn_gf2m::polyn_gf2m ( const polyn_gf2m & other)
default

References polyn_gf2m().

◆ polyn_gf2m() [6/9]

Botan::polyn_gf2m::polyn_gf2m ( size_t t,
RandomNumberGenerator & rng,
const std::shared_ptr< GF2m_Field > & sp_field )

random irreducible polynomial of degree t

Definition at line 550 of file polyn_gf2m.cpp.

550 :
551 m_deg(static_cast<int>(t)), m_coeff(t + 1), m_sp_field(sp_field) {
552 this->set_coef(t, 1);
553 for(;;) {
554 for(size_t i = 0; i < t; ++i) {
555 this->set_coef(i, random_code_element(sp_field->get_cardinality(), rng));
556 }
557
558 const size_t degree = polyn_gf2m::degppf(*this);
559
560 if(degree >= t) {
561 break;
562 }
563 }
564}
void set_coef(size_t i, gf2m v)
Definition polyn_gf2m.h:89
static size_t degppf(const polyn_gf2m &g)
gf2m random_code_element(uint16_t code_length, RandomNumberGenerator &rng)

References degppf(), polyn_gf2m(), Botan::random_code_element(), and set_coef().

◆ polyn_gf2m() [7/9]

Botan::polyn_gf2m::polyn_gf2m ( const uint8_t * mem,
uint32_t mem_len,
const std::shared_ptr< GF2m_Field > & sp_field )

decode a polynomial from memory:

Definition at line 114 of file polyn_gf2m.cpp.

114 :
115 m_deg(-1), m_sp_field(sp_field) {
116 if(!sp_field) {
117 throw Decoding_Error("missing field for polynomial decoding");
118 }
119
120 if(mem_len % sizeof(gf2m)) {
121 throw Decoding_Error("illegal length of memory to decode ");
122 }
123
124 const uint32_t size = (mem_len / sizeof(this->m_coeff[0]));
125 this->m_coeff = secure_vector<gf2m>(size);
126 this->m_deg = -1;
127 for(uint32_t i = 0; i < size; i++) {
128 this->m_coeff[i] = decode_gf2m(mem);
129 mem += sizeof(this->m_coeff[0]);
130 }
131 for(uint32_t i = 0; i < size; i++) {
132 if(this->m_coeff[i] >= (static_cast<size_t>(1) << sp_field->get_extension_degree())) {
133 throw Decoding_Error("error decoding polynomial");
134 }
135 }
136 this->get_degree();
137}
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128
gf2m decode_gf2m(const uint8_t *mem)

References Botan::decode_gf2m(), and get_degree().

◆ polyn_gf2m() [8/9]

Botan::polyn_gf2m::polyn_gf2m ( int degree,
const uint8_t * mem,
size_t mem_byte_len,
const std::shared_ptr< GF2m_Field > & sp_field )

create a polynomial from memory area (encoded)

Definition at line 141 of file polyn_gf2m.cpp.

144 :
145 m_sp_field(sp_field) {
146 if(!sp_field) {
147 throw Decoding_Error("missing field for polynomial decoding");
148 }
149
150 if(degree < 0) {
151 throw Decoding_Error("invalid polynomial degree");
152 }
153
154 const uint32_t polyn_size = degree + 1;
155 if(polyn_size * sp_field->get_extension_degree() > 8 * mem_byte_len) {
156 throw Decoding_Error("memory vector for polynomial has wrong size");
157 }
158 this->m_coeff = secure_vector<gf2m>(degree + 1);
159 const gf2m ext_deg = static_cast<gf2m>(this->m_sp_field->get_extension_degree());
160 for(uint32_t l = 0; l < polyn_size; l++) {
161 const uint32_t k = (l * ext_deg) / 8;
162
163 const uint32_t j = (l * ext_deg) % 8;
164 gf2m a = mem[k] >> j;
165 if(j + ext_deg > 8) {
166 a ^= mem[k + 1] << (8 - j);
167 }
168 if(j + ext_deg > 16) {
169 a ^= mem[k + 2] << (16 - j);
170 }
171 a &= ((1 << ext_deg) - 1);
172 (*this).set_coef(l, a);
173 }
174
175 this->get_degree();
176}

◆ polyn_gf2m() [9/9]

Botan::polyn_gf2m::polyn_gf2m ( polyn_gf2m && other)
inlinenoexcept

Definition at line 66 of file polyn_gf2m.h.

66{ this->swap(other); }
void swap(polyn_gf2m &other) noexcept

References polyn_gf2m(), and swap().

Member Function Documentation

◆ add_to_coef()

void Botan::polyn_gf2m::add_to_coef ( size_t i,
gf2m v )
inline

Definition at line 91 of file polyn_gf2m.h.

91{ m_coeff[i] ^= v; }

◆ calc_degree_secure()

int Botan::polyn_gf2m::calc_degree_secure ( ) 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

Definition at line 59 of file polyn_gf2m.cpp.

59 {
60 int i = static_cast<int>(this->m_coeff.size()) - 1;
61 int result = 0;
62 uint32_t found_mask = 0;
63 uint32_t tracker_mask = 0xffff;
64 for(; i >= 0; i--) {
65 found_mask = expand_mask_16bit(this->m_coeff[i]);
66 result |= i & found_mask & tracker_mask;
67 // tracker mask shall become zero once found mask is set
68 // it shall remain zero from then on
69 tracker_mask = tracker_mask & ~found_mask;
70 }
71 const_cast<polyn_gf2m*>(this)->m_deg = result;
72 return result;
73}
polyn_gf2m(const std::shared_ptr< GF2m_Field > &sp_field)
uint16_t expand_mask_16bit(T tst)

References Botan::expand_mask_16bit(), and polyn_gf2m().

Referenced by eea_with_coefficients(), and patchup_deg_secure().

◆ degppf()

size_t Botan::polyn_gf2m::degppf ( const polyn_gf2m & g)
static

Definition at line 323 of file polyn_gf2m.cpp.

323 {
324 polyn_gf2m s(g.get_sp_field());
325
326 const size_t ext_deg = g.m_sp_field->get_extension_degree();
327 const int d = g.get_degree();
328 const std::vector<polyn_gf2m> u = polyn_gf2m::sqmod_init(g);
329
330 polyn_gf2m p(d - 1, g.m_sp_field);
331
332 p.set_degree(1);
333 (*&p).set_coef(1, 1);
334 size_t result = static_cast<size_t>(d);
335 for(size_t i = 1; i <= (d / 2) * ext_deg; ++i) {
336 polyn_gf2m r = p.sqmod(u, d);
337 if((i % ext_deg) == 0) {
338 r[1] ^= 1;
339 r.get_degree(); // The degree may change
340 s = polyn_gf2m::gcd(g, r);
341
342 if(s.get_degree() > 0) {
343 result = i / ext_deg;
344 break;
345 }
346 r[1] ^= 1;
347 r.get_degree(); // The degree may change
348 }
349 // No need for the exchange s
350 s = p;
351 p = r;
352 r = s;
353 }
354
355 return result;
356}
static std::vector< polyn_gf2m > sqmod_init(const polyn_gf2m &g)

References degppf(), get_degree(), get_sp_field(), polyn_gf2m(), set_coef(), sqmod(), and sqmod_init().

Referenced by degppf(), and polyn_gf2m().

◆ eea_with_coefficients()

std::pair< polyn_gf2m, polyn_gf2m > Botan::polyn_gf2m::eea_with_coefficients ( const polyn_gf2m & p,
const polyn_gf2m & g,
int break_deg )
static

countermeasure against the low weight attacks for w=4, w=6 and w=8. Higher values are not covered since for w=8 we already have a probability for a positive of 1/n^3 from random ciphertexts with the given weight. For w = 10 it would be 1/n^4 and so on. Thus attacks based on such high values of w are considered impractical.

The outer test for the degree of u ( Omega in the paper ) needs not to be disguised. Each of the three is performed at most once per EEA (syndrome inversion) execution, the attacker knows this already when preparing the ciphertext with the given weight. Inside these three cases however, we must use timing neutral (branch free) operations to implement the condition detection and the counteractions.

Condition that the EEA would break now

Now come the conditions for all odd coefficients of this sigma candidate. If they are all fulfilled, then we know that we have a low weight error vector, since the key-equation solving EEA is skipped if the degree of tau^2 is low (=m_deg(u0)) and all its odd coefficients are zero (they would cause "full-length" contributions from the square root computation).

Definition at line 373 of file polyn_gf2m.cpp.

375 {
376 const std::shared_ptr<GF2m_Field> m_sp_field = g.m_sp_field;
377 polyn_gf2m aux;
378
379 // initialisation of the local variables
380 // r0 <- g, r1 <- p, u0 <- 0, u1 <- 1
381 int dr = g.get_degree();
382
383 BOTAN_ASSERT(dr > 3, "Valid polynomial");
384
385 polyn_gf2m r0(dr, g.m_sp_field);
386 polyn_gf2m r1(dr - 1, g.m_sp_field);
387 polyn_gf2m u0(dr - 1, g.m_sp_field);
388 polyn_gf2m u1(dr - 1, g.m_sp_field);
389
390 r0 = g;
391 r1 = p;
392 u0.set_to_zero();
393 u1.set_to_zero();
394 (*&u1).set_coef(0, 1);
395 u1.set_degree(0);
396
397 // invariants:
398 // r1 = u1 * p + v1 * g
399 // r0 = u0 * p + v0 * g
400 // and m_deg(u1) = m_deg(g) - m_deg(r0)
401 // It stops when m_deg (r1) <t (m_deg (r0)> = t)
402 // And therefore m_deg (u1) = m_deg (g) - m_deg (r0) <m_deg (g) - break_deg
403 int du = 0;
404 dr = r1.get_degree();
405 int delta = r0.get_degree() - dr;
406
407 int i = 0;
408 int j = 0;
409 while(dr >= break_deg) {
410 for(j = delta; j >= 0; --j) {
411 const gf2m a = m_sp_field->gf_div(r0[dr + j], r1[dr]);
412 if(a != 0) {
413 const gf2m la = m_sp_field->gf_log(a);
414 // u0(z) <- u0(z) + a * u1(z) * z^j
415 for(i = 0; i <= du; ++i) {
416 u0[i + j] ^= m_sp_field->gf_mul_zrz(la, u1[i]);
417 }
418 // r0(z) <- r0(z) + a * r1(z) * z^j
419 for(i = 0; i <= dr; ++i) {
420 r0[i + j] ^= m_sp_field->gf_mul_zrz(la, r1[i]);
421 }
422 }
423 } // end loop over j
424
425 if(break_deg != 1) /* key eq. solving */
426 {
427 /* [ssms_icisc09] Countermeasure
428 * d_break from paper equals break_deg - 1
429 * */
430
431 volatile gf2m fake_elem = 0x01;
432 volatile gf2m cond1 = 0;
433 volatile gf2m cond2 = 0;
434 const int trgt_deg = r1.get_degree() - 1;
435 r0.calc_degree_secure();
436 u0.calc_degree_secure();
437 if(!(g.get_degree() % 2)) {
438 /* t even */
439 cond1 = r0.get_degree() < break_deg - 1;
440 } else {
441 /* t odd */
442 cond1 = r0.get_degree() < break_deg;
443 cond2 = u0.get_degree() < break_deg - 1;
444 cond1 = cond1 & cond2;
445 }
446 /* expand cond1 to a full mask */
447 const gf2m mask = generate_gf2m_mask(cond1);
448 fake_elem = fake_elem & mask;
449 r0.patchup_deg_secure(trgt_deg, fake_elem);
450 }
451 if(break_deg == 1) /* syndrome inversion */
452 {
453 volatile gf2m fake_elem = 0x00;
454 volatile uint32_t trgt_deg = 0;
455 r0.calc_degree_secure();
456 u0.calc_degree_secure();
457 /**
458 * countermeasure against the low weight attacks for w=4, w=6 and w=8.
459 * Higher values are not covered since for w=8 we already have a
460 * probability for a positive of 1/n^3 from random ciphertexts with the
461 * given weight. For w = 10 it would be 1/n^4 and so on. Thus attacks
462 * based on such high values of w are considered impractical.
463 *
464 * The outer test for the degree of u ( Omega in the paper ) needs not to
465 * be disguised. Each of the three is performed at most once per EEA
466 * (syndrome inversion) execution, the attacker knows this already when
467 * preparing the ciphertext with the given weight. Inside these three
468 * cases however, we must use timing neutral (branch free) operations to
469 * implement the condition detection and the counteractions.
470 *
471 */
472 if(u0.get_degree() == 4) {
473 uint32_t mask = 0;
474 /**
475 * Condition that the EEA would break now
476 */
477 int cond_r = r0.get_degree() == 0;
478 /**
479 * Now come the conditions for all odd coefficients of this sigma
480 * candidate. If they are all fulfilled, then we know that we have a low
481 * weight error vector, since the key-equation solving EEA is skipped if
482 * the degree of tau^2 is low (=m_deg(u0)) and all its odd coefficients are
483 * zero (they would cause "full-length" contributions from the square
484 * root computation).
485 */
486 // Condition for the coefficient to Y to be cancelled out by the
487 // addition of Y before the square root computation:
488 const int cond_u1 = m_sp_field->gf_mul(u0.m_coeff[1], m_sp_field->gf_inv(r0.m_coeff[0])) == 1;
489
490 // Condition sigma_3 = 0:
491 const int cond_u3 = u0.m_coeff[3] == 0;
492 // combine the conditions:
493 cond_r &= (cond_u1 & cond_u3);
494 // mask generation:
495 mask = expand_mask_16bit(cond_r);
496 trgt_deg = 2 & mask;
497 fake_elem = 1 & mask;
498 } else if(u0.get_degree() == 6) {
499 uint32_t mask = 0;
500 int cond_r = r0.get_degree() == 0;
501 const int cond_u1 = m_sp_field->gf_mul(u0.m_coeff[1], m_sp_field->gf_inv(r0.m_coeff[0])) == 1;
502 const int cond_u3 = u0.m_coeff[3] == 0;
503
504 const int cond_u5 = u0.m_coeff[5] == 0;
505
506 cond_r &= (cond_u1 & cond_u3 & cond_u5);
507 mask = expand_mask_16bit(cond_r);
508 trgt_deg = 4 & mask;
509 fake_elem = 1 & mask;
510 } else if(u0.get_degree() == 8) {
511 uint32_t mask = 0;
512 int cond_r = r0.get_degree() == 0;
513 const int cond_u1 = m_sp_field->gf_mul(u0[1], m_sp_field->gf_inv(r0[0])) == 1;
514 const int cond_u3 = u0.m_coeff[3] == 0;
515
516 const int cond_u5 = u0.m_coeff[5] == 0;
517
518 const int cond_u7 = u0.m_coeff[7] == 0;
519
520 cond_r &= (cond_u1 & cond_u3 & cond_u5 & cond_u7);
521 mask = expand_mask_16bit(cond_r);
522 trgt_deg = 6 & mask;
523 fake_elem = 1 & mask;
524 }
525 r0.patchup_deg_secure(trgt_deg, fake_elem);
526 }
527 // exchange
528 aux = r0;
529 r0 = r1;
530 r1 = aux;
531 aux = u0;
532 u0 = u1;
533 u1 = aux;
534
535 du = du + delta;
536 delta = 1;
537 while(r1[dr - delta] == 0) {
538 delta++;
539 }
540
541 dr -= delta;
542 } /* end while loop (dr >= break_deg) */
543
544 u1.set_degree(du);
545 r1.set_degree(dr);
546 //return u1 and r1;
547 return std::make_pair(u1, r1); // coefficients u,v
548}
#define BOTAN_ASSERT(expr, assertion_made)
Definition assert.h:62

References BOTAN_ASSERT, calc_degree_secure(), eea_with_coefficients(), Botan::expand_mask_16bit(), get_degree(), patchup_deg_secure(), polyn_gf2m(), set_coef(), and set_to_zero().

Referenced by eea_with_coefficients().

◆ encode() [1/2]

secure_vector< uint8_t > Botan::polyn_gf2m::encode ( ) const

Definition at line 670 of file polyn_gf2m.cpp.

670 {
672
673 if(m_deg < 1) {
674 result.push_back(0);
675 result.push_back(0);
676 return result;
677 }
678
679 const uint32_t len = m_deg + 1;
680 for(unsigned i = 0; i < len; i++) {
681 // "big endian" encoding of the GF(2^m) elements
682 result.push_back(get_byte<0>(m_coeff[i]));
683 result.push_back(get_byte<1>(m_coeff[i]));
684 }
685 return result;
686}
constexpr uint8_t get_byte(T input)
Definition loadstor.h:79

References Botan::get_byte().

◆ encode() [2/2]

void Botan::polyn_gf2m::encode ( uint32_t min_numo_coeffs,
uint8_t * mem,
uint32_t mem_len ) const

◆ eval()

gf2m Botan::polyn_gf2m::eval ( gf2m a)

Definition at line 208 of file polyn_gf2m.cpp.

208 {
209 return eval_aux(this->m_coeff.data(), a, this->m_deg, this->m_sp_field);
210}

References eval().

Referenced by eval().

◆ get_coef()

gf2m Botan::polyn_gf2m::get_coef ( size_t i) const
inline

Definition at line 87 of file polyn_gf2m.h.

87{ return m_coeff[i]; }

◆ get_coeff_count()

size_t Botan::polyn_gf2m::get_coeff_count ( ) const
inline

Definition at line 97 of file polyn_gf2m.h.

97{ return m_coeff.size(); }

◆ get_degree()

int Botan::polyn_gf2m::get_degree ( ) const

Definition at line 183 of file polyn_gf2m.cpp.

183 {
184 int d = static_cast<int>(this->m_coeff.size()) - 1;
185 while((d >= 0) && (this->m_coeff[d] == 0)) {
186 --d;
187 }
188 const_cast<polyn_gf2m*>(this)->m_deg = d;
189 return d;
190}

References get_degree(), and polyn_gf2m().

Referenced by degppf(), eea_with_coefficients(), get_degree(), Botan::mceliece_decrypt(), polyn_gf2m(), sqmod(), sqmod_init(), sqrt_mod_init(), and Botan::syndrome_init().

◆ get_lead_coef()

gf2m Botan::polyn_gf2m::get_lead_coef ( ) const
inline

Definition at line 85 of file polyn_gf2m.h.

85{ return m_coeff[m_deg]; }

◆ get_sp_field()

std::shared_ptr< GF2m_Field > Botan::polyn_gf2m::get_sp_field ( ) const
inline

Definition at line 79 of file polyn_gf2m.h.

79{ return m_sp_field; }

Referenced by degppf(), Botan::mceliece_decrypt(), sqmod_init(), sqrt_mod_init(), and Botan::syndrome_init().

◆ operator!=()

bool Botan::polyn_gf2m::operator!= ( const polyn_gf2m & other) const
inline

Definition at line 64 of file polyn_gf2m.h.

64{ return !(*this == other); }

References polyn_gf2m().

◆ operator=() [1/2]

polyn_gf2m & Botan::polyn_gf2m::operator= ( const polyn_gf2m & )
default

References polyn_gf2m().

◆ operator=() [2/2]

polyn_gf2m & Botan::polyn_gf2m::operator= ( polyn_gf2m && other)
inlinenoexcept

Definition at line 68 of file polyn_gf2m.h.

68 {
69 if(this != &other) {
70 this->swap(other);
71 }
72 return *this;
73 }

References polyn_gf2m(), and swap().

◆ operator==()

bool Botan::polyn_gf2m::operator== ( const polyn_gf2m & other) const

Definition at line 694 of file polyn_gf2m.cpp.

694 {
695 return m_deg == other.m_deg && m_coeff == other.m_coeff;
696}

References polyn_gf2m().

◆ operator[]() [1/2]

gf2m & Botan::polyn_gf2m::operator[] ( size_t i)
inline

Definition at line 81 of file polyn_gf2m.h.

81{ return m_coeff[i]; }

◆ operator[]() [2/2]

gf2m Botan::polyn_gf2m::operator[] ( size_t i) const
inline

Definition at line 83 of file polyn_gf2m.h.

83{ return m_coeff[i]; }

◆ patchup_deg_secure()

void Botan::polyn_gf2m::patchup_deg_secure ( uint32_t trgt_deg,
gf2m patch_elem )

Definition at line 358 of file polyn_gf2m.cpp.

358 {
359 if(this->m_coeff.size() < trgt_deg) {
360 return;
361 }
362 for(uint32_t i = 0; i < this->m_coeff.size(); i++) {
363 this->m_coeff[i] |= patch_elem;
364 const uint32_t equal = (i == trgt_deg);
365 const uint32_t equal_mask = expand_mask_16bit(equal);
366 patch_elem &= ~equal_mask;
367 }
368 this->calc_degree_secure();
369}
int calc_degree_secure() const

References calc_degree_secure(), Botan::expand_mask_16bit(), and patchup_deg_secure().

Referenced by eea_with_coefficients(), and patchup_deg_secure().

◆ set_coef()

void Botan::polyn_gf2m::set_coef ( size_t i,
gf2m v )
inline

Definition at line 89 of file polyn_gf2m.h.

89{ m_coeff[i] = v; }

Referenced by degppf(), eea_with_coefficients(), polyn_gf2m(), sqmod(), sqmod_init(), and sqrt_mod_init().

◆ set_to_zero()

void Botan::polyn_gf2m::set_to_zero ( )

Definition at line 178 of file polyn_gf2m.cpp.

178 {
179 clear_mem(this->m_coeff.data(), this->m_coeff.size());
180 this->m_deg = -1;
181}
constexpr void clear_mem(T *ptr, size_t n)
Definition mem_ops.h:118

References Botan::clear_mem(), and set_to_zero().

Referenced by eea_with_coefficients(), and set_to_zero().

◆ sqmod()

polyn_gf2m Botan::polyn_gf2m::sqmod ( const std::vector< polyn_gf2m > & sq,
int d )

Definition at line 272 of file polyn_gf2m.cpp.

272 {
273 int i = 0;
274 const std::shared_ptr<GF2m_Field> sp_field = this->m_sp_field;
275
276 polyn_gf2m result(d - 1, sp_field);
277 // terms of low degree
278 for(i = 0; i < d / 2; ++i) {
279 (*&result).set_coef(i * 2, sp_field->gf_square((*this)[i]));
280 }
281
282 // terms of high degree
283 for(; i < d; ++i) {
284 gf2m lpi = (*this)[i];
285 if(lpi != 0) {
286 lpi = sp_field->gf_log(lpi);
287 const gf2m la = sp_field->gf_mul_rrr(lpi, lpi);
288 for(int j = 0; j < d; ++j) {
289 result[j] ^= sp_field->gf_mul_zrz(la, sq[i][j]);
290 }
291 }
292 }
293
294 // Update degre
295 result.set_degree(d - 1);
296 while((result.get_degree() >= 0) && (result[result.get_degree()] == 0)) {
297 result.set_degree(result.get_degree() - 1);
298 }
299 return result;
300}

References get_degree(), polyn_gf2m(), set_coef(), and sqmod().

Referenced by degppf(), sqmod(), and sqrt_mod_init().

◆ sqmod_init()

std::vector< polyn_gf2m > Botan::polyn_gf2m::sqmod_init ( const polyn_gf2m & g)
static

Definition at line 241 of file polyn_gf2m.cpp.

241 {
242 std::vector<polyn_gf2m> sq;
243 const int signed_deg = g.get_degree();
244 if(signed_deg <= 0) {
245 throw Invalid_Argument("cannot compute sqmod for such low degree");
246 }
247
248 const uint32_t d = static_cast<uint32_t>(signed_deg);
249 const uint32_t t = g.m_deg;
250 // create t zero polynomials
251 uint32_t i = 0;
252 for(i = 0; i < t; ++i) {
253 sq.push_back(polyn_gf2m(t + 1, g.get_sp_field()));
254 }
255 for(i = 0; i < d / 2; ++i) {
256 sq[i].set_degree(2 * i);
257 (*&sq[i]).set_coef(2 * i, 1);
258 }
259
260 for(; i < d; ++i) {
261 clear_mem(sq[i].m_coeff.data(), 2);
262 copy_mem(sq[i].m_coeff.data() + 2, sq[i - 1].m_coeff.data(), d);
263 sq[i].set_degree(sq[i - 1].get_degree() + 2);
264 polyn_gf2m::remainder(sq[i], g);
265 }
266 return sq;
267}
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:144

References Botan::clear_mem(), Botan::copy_mem(), get_degree(), get_sp_field(), polyn_gf2m(), set_coef(), and sqmod_init().

Referenced by degppf(), sqmod_init(), and sqrt_mod_init().

◆ sqrt_mod_init()

std::vector< polyn_gf2m > Botan::polyn_gf2m::sqrt_mod_init ( const polyn_gf2m & g)
static

Definition at line 580 of file polyn_gf2m.cpp.

580 {
581 uint32_t i = 0;
582 uint32_t t = 0;
583 uint32_t nb_polyn_sqrt_mat = 0;
584 const std::shared_ptr<GF2m_Field> m_sp_field = g.m_sp_field;
585 std::vector<polyn_gf2m> result;
586 t = g.get_degree();
587 nb_polyn_sqrt_mat = t / 2;
588
589 const std::vector<polyn_gf2m> sq_aux = polyn_gf2m::sqmod_init(g);
590
591 polyn_gf2m p(t - 1, g.get_sp_field());
592 p.set_degree(1);
593
594 (*&p).set_coef(1, 1);
595 // q(z) = 0, p(z) = z
596 for(i = 0; i < t * m_sp_field->get_extension_degree() - 1; ++i) {
597 // q(z) <- p(z)^2 mod g(z)
598 polyn_gf2m q = p.sqmod(sq_aux, t);
599 // q(z) <-> p(z)
600 const polyn_gf2m aux = q;
601 q = p;
602 p = aux;
603 }
604 // p(z) = z^(2^(tm-1)) mod g(z) = sqrt(z) mod g(z)
605
606 for(i = 0; i < nb_polyn_sqrt_mat; ++i) {
607 result.push_back(polyn_gf2m(t - 1, g.get_sp_field()));
608 }
609
610 result[0] = p;
611 result[0].get_degree();
612 for(i = 1; i < nb_polyn_sqrt_mat; i++) {
613 result[i] = result[i - 1];
614 result[i].poly_shiftmod(g);
615 result[i].get_degree();
616 }
617
618 return result;
619}

References get_degree(), get_sp_field(), polyn_gf2m(), polyn_gf2m(), set_coef(), sqmod(), and sqmod_init().

Referenced by Botan::generate_mceliece_key().

◆ swap()

void Botan::polyn_gf2m::swap ( polyn_gf2m & other)
noexcept

Definition at line 688 of file polyn_gf2m.cpp.

688 {
689 std::swap(this->m_deg, other.m_deg);
690 std::swap(this->m_sp_field, other.m_sp_field);
691 std::swap(this->m_coeff, other.m_coeff);
692}

References polyn_gf2m().

Referenced by operator=(), and polyn_gf2m().


The documentation for this class was generated from the following files: