Botan 3.10.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
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 131 of file polyn_gf2m.cpp.

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

Referenced by calc_degree_secure(), degppf(), eea_with_coefficients(), encode(), 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 634 of file polyn_gf2m.cpp.

634 :
635 m_sp_field(sp_field) {
636 if(encoded.size() % 2) {
637 throw Decoding_Error("encoded polynomial has odd length");
638 }
639 for(uint32_t i = 0; i < encoded.size(); i += 2) {
640 gf2m el = (encoded[i] << 8) | encoded[i + 1];
641 m_coeff.push_back(el);
642 }
643 get_degree();
644}
int get_degree() const
uint16_t gf2m

References get_degree().

◆ ~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 :
101 m_deg(-1), m_coeff(d + 1), m_sp_field(sp_field) {}

◆ 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 534 of file polyn_gf2m.cpp.

534 :
535 m_deg(static_cast<int>(t)), m_coeff(t + 1), m_sp_field(sp_field) {
536 this->set_coef(t, 1);
537 for(;;) {
538 for(size_t i = 0; i < t; ++i) {
539 this->set_coef(i, random_code_element(sp_field->get_cardinality(), rng));
540 }
541
542 const size_t degree = polyn_gf2m::degppf(*this);
543
544 if(degree >= t) {
545 break;
546 }
547 }
548}
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 110 of file polyn_gf2m.cpp.

110 :
111 m_deg(-1), m_sp_field(sp_field) {
112 if(mem_len % sizeof(gf2m)) {
113 throw Decoding_Error("illegal length of memory to decode ");
114 }
115
116 uint32_t size = (mem_len / sizeof(this->m_coeff[0]));
117 this->m_coeff = secure_vector<gf2m>(size);
118 this->m_deg = -1;
119 for(uint32_t i = 0; i < size; i++) {
120 this->m_coeff[i] = decode_gf2m(mem);
121 mem += sizeof(this->m_coeff[0]);
122 }
123 for(uint32_t i = 0; i < size; i++) {
124 if(this->m_coeff[i] >= (1 << sp_field->get_extension_degree())) {
125 throw Decoding_Error("error decoding polynomial");
126 }
127 }
128 this->get_degree();
129}
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:69
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 133 of file polyn_gf2m.cpp.

136 :
137 m_sp_field(sp_field) {
138 const uint32_t polyn_size = degree + 1;
139 if(polyn_size * sp_field->get_extension_degree() > 8 * mem_byte_len) {
140 throw Decoding_Error("memory vector for polynomial has wrong size");
141 }
142 this->m_coeff = secure_vector<gf2m>(degree + 1);
143 const gf2m ext_deg = static_cast<gf2m>(this->m_sp_field->get_extension_degree());
144 for(uint32_t l = 0; l < polyn_size; l++) {
145 uint32_t k = (l * ext_deg) / 8;
146
147 uint32_t j = (l * ext_deg) % 8;
148 gf2m a = mem[k] >> j;
149 if(j + ext_deg > 8) {
150 a ^= mem[k + 1] << (8 - j);
151 }
152 if(j + ext_deg > 16) {
153 a ^= mem[k + 2] << (16 - j);
154 }
155 a &= ((1 << ext_deg) - 1);
156 (*this).set_coef(l, a);
157 }
158
159 this->get_degree();
160}

◆ 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 307 of file polyn_gf2m.cpp.

307 {
308 polyn_gf2m s(g.get_sp_field());
309
310 const size_t ext_deg = g.m_sp_field->get_extension_degree();
311 const int d = g.get_degree();
312 std::vector<polyn_gf2m> u = polyn_gf2m::sqmod_init(g);
313
314 polyn_gf2m p(d - 1, g.m_sp_field);
315
316 p.set_degree(1);
317 (*&p).set_coef(1, 1);
318 size_t result = static_cast<size_t>(d);
319 for(size_t i = 1; i <= (d / 2) * ext_deg; ++i) {
320 polyn_gf2m r = p.sqmod(u, d);
321 if((i % ext_deg) == 0) {
322 r[1] ^= 1;
323 r.get_degree(); // The degree may change
324 s = polyn_gf2m::gcd(g, r);
325
326 if(s.get_degree() > 0) {
327 result = i / ext_deg;
328 break;
329 }
330 r[1] ^= 1;
331 r.get_degree(); // The degree may change
332 }
333 // No need for the exchange s
334 s = p;
335 p = r;
336 r = s;
337 }
338
339 return result;
340}
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 357 of file polyn_gf2m.cpp.

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

646 {
648
649 if(m_deg < 1) {
650 result.push_back(0);
651 result.push_back(0);
652 return result;
653 }
654
655 uint32_t len = m_deg + 1;
656 for(unsigned i = 0; i < len; i++) {
657 // "big endian" encoding of the GF(2^m) elements
658 result.push_back(get_byte<0>(m_coeff[i]));
659 result.push_back(get_byte<1>(m_coeff[i]));
660 }
661 return result;
662}
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

References polyn_gf2m().

◆ eval()

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

Definition at line 192 of file polyn_gf2m.cpp.

192 {
193 return eval_aux(this->m_coeff.data(), a, this->m_deg, this->m_sp_field);
194}

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_degree()

int Botan::polyn_gf2m::get_degree ( ) const

Definition at line 167 of file polyn_gf2m.cpp.

167 {
168 int d = static_cast<int>(this->m_coeff.size()) - 1;
169 while((d >= 0) && (this->m_coeff[d] == 0)) {
170 --d;
171 }
172 const_cast<polyn_gf2m*>(this)->m_deg = d;
173 return d;
174}

References get_degree(), and polyn_gf2m().

Referenced by degppf(), eea_with_coefficients(), get_degree(), Botan::mceliece_decrypt(), polyn_gf2m(), 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 670 of file polyn_gf2m.cpp.

670 {
671 return m_deg == other.m_deg && m_coeff == other.m_coeff;
672}

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 342 of file polyn_gf2m.cpp.

342 {
343 if(this->m_coeff.size() < trgt_deg) {
344 return;
345 }
346 for(uint32_t i = 0; i < this->m_coeff.size(); i++) {
347 this->m_coeff[i] |= patch_elem;
348 uint32_t equal = (i == trgt_deg);
349 uint32_t equal_mask = expand_mask_16bit(equal);
350 patch_elem &= ~equal_mask;
351 }
352 this->calc_degree_secure();
353}
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 162 of file polyn_gf2m.cpp.

162 {
163 clear_mem(this->m_coeff.data(), this->m_coeff.size());
164 this->m_deg = -1;
165}
constexpr void clear_mem(T *ptr, size_t n)
Definition mem_ops.h:119

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 256 of file polyn_gf2m.cpp.

256 {
257 int i = 0;
258 std::shared_ptr<GF2m_Field> sp_field = this->m_sp_field;
259
260 polyn_gf2m result(d - 1, sp_field);
261 // terms of low degree
262 for(i = 0; i < d / 2; ++i) {
263 (*&result).set_coef(i * 2, sp_field->gf_square((*this)[i]));
264 }
265
266 // terms of high degree
267 for(; i < d; ++i) {
268 gf2m lpi = (*this)[i];
269 if(lpi != 0) {
270 lpi = sp_field->gf_log(lpi);
271 gf2m la = sp_field->gf_mul_rrr(lpi, lpi);
272 for(int j = 0; j < d; ++j) {
273 result[j] ^= sp_field->gf_mul_zrz(la, sq[i][j]);
274 }
275 }
276 }
277
278 // Update degre
279 result.set_degree(d - 1);
280 while((result.get_degree() >= 0) && (result[result.get_degree()] == 0)) {
281 result.set_degree(result.get_degree() - 1);
282 }
283 return result;
284}

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 225 of file polyn_gf2m.cpp.

225 {
226 std::vector<polyn_gf2m> sq;
227 const int signed_deg = g.get_degree();
228 if(signed_deg <= 0) {
229 throw Invalid_Argument("cannot compute sqmod for such low degree");
230 }
231
232 const uint32_t d = static_cast<uint32_t>(signed_deg);
233 uint32_t t = g.m_deg;
234 // create t zero polynomials
235 uint32_t i = 0;
236 for(i = 0; i < t; ++i) {
237 sq.push_back(polyn_gf2m(t + 1, g.get_sp_field()));
238 }
239 for(i = 0; i < d / 2; ++i) {
240 sq[i].set_degree(2 * i);
241 (*&sq[i]).set_coef(2 * i, 1);
242 }
243
244 for(; i < d; ++i) {
245 clear_mem(sq[i].m_coeff.data(), 2);
246 copy_mem(sq[i].m_coeff.data() + 2, sq[i - 1].m_coeff.data(), d);
247 sq[i].set_degree(sq[i - 1].get_degree() + 2);
248 polyn_gf2m::remainder(sq[i], g);
249 }
250 return sq;
251}
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:145

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 564 of file polyn_gf2m.cpp.

564 {
565 uint32_t i = 0;
566 uint32_t t = 0;
567 uint32_t nb_polyn_sqrt_mat = 0;
568 std::shared_ptr<GF2m_Field> m_sp_field = g.m_sp_field;
569 std::vector<polyn_gf2m> result;
570 t = g.get_degree();
571 nb_polyn_sqrt_mat = t / 2;
572
573 std::vector<polyn_gf2m> sq_aux = polyn_gf2m::sqmod_init(g);
574
575 polyn_gf2m p(t - 1, g.get_sp_field());
576 p.set_degree(1);
577
578 (*&p).set_coef(1, 1);
579 // q(z) = 0, p(z) = z
580 for(i = 0; i < t * m_sp_field->get_extension_degree() - 1; ++i) {
581 // q(z) <- p(z)^2 mod g(z)
582 polyn_gf2m q = p.sqmod(sq_aux, t);
583 // q(z) <-> p(z)
584 polyn_gf2m aux = q;
585 q = p;
586 p = aux;
587 }
588 // p(z) = z^(2^(tm-1)) mod g(z) = sqrt(z) mod g(z)
589
590 for(i = 0; i < nb_polyn_sqrt_mat; ++i) {
591 result.push_back(polyn_gf2m(t - 1, g.get_sp_field()));
592 }
593
594 result[0] = p;
595 result[0].get_degree();
596 for(i = 1; i < nb_polyn_sqrt_mat; i++) {
597 result[i] = result[i - 1];
598 result[i].poly_shiftmod(g);
599 result[i].get_degree();
600 }
601
602 return result;
603}

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 664 of file polyn_gf2m.cpp.

664 {
665 std::swap(this->m_deg, other.m_deg);
666 std::swap(this->m_sp_field, other.m_sp_field);
667 std::swap(this->m_coeff, other.m_coeff);
668}

References polyn_gf2m().

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


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