Botan 3.9.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 132 of file polyn_gf2m.cpp.

132: 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 635 of file polyn_gf2m.cpp.

635 :
636 m_sp_field(sp_field) {
637 if(encoded.size() % 2) {
638 throw Decoding_Error("encoded polynomial has odd length");
639 }
640 for(uint32_t i = 0; i < encoded.size(); i += 2) {
641 gf2m el = (encoded[i] << 8) | encoded[i + 1];
642 m_coeff.push_back(el);
643 }
644 get_degree();
645}
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 101 of file polyn_gf2m.cpp.

101 :
102 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 535 of file polyn_gf2m.cpp.

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

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

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

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

60 {
61 int i = static_cast<int>(this->m_coeff.size()) - 1;
62 int result = 0;
63 uint32_t found_mask = 0;
64 uint32_t tracker_mask = 0xffff;
65 for(; i >= 0; i--) {
66 found_mask = expand_mask_16bit(this->m_coeff[i]);
67 result |= i & found_mask & tracker_mask;
68 // tracker mask shall become zero once found mask is set
69 // it shall remain zero from then on
70 tracker_mask = tracker_mask & ~found_mask;
71 }
72 const_cast<polyn_gf2m*>(this)->m_deg = result;
73 return result;
74}
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 308 of file polyn_gf2m.cpp.

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

Definition at line 358 of file polyn_gf2m.cpp.

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

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

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

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

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

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

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

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

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

163 {
164 clear_mem(this->m_coeff.data(), this->m_coeff.size());
165 this->m_deg = -1;
166}
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 257 of file polyn_gf2m.cpp.

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

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

226 {
227 std::vector<polyn_gf2m> sq;
228 const int signed_deg = g.get_degree();
229 if(signed_deg <= 0) {
230 throw Invalid_Argument("cannot compute sqmod for such low degree");
231 }
232
233 const uint32_t d = static_cast<uint32_t>(signed_deg);
234 uint32_t t = g.m_deg;
235 // create t zero polynomials
236 uint32_t i = 0;
237 for(i = 0; i < t; ++i) {
238 sq.push_back(polyn_gf2m(t + 1, g.get_sp_field()));
239 }
240 for(i = 0; i < d / 2; ++i) {
241 sq[i].set_degree(2 * i);
242 (*&sq[i]).set_coef(2 * i, 1);
243 }
244
245 for(; i < d; ++i) {
246 clear_mem(sq[i].m_coeff.data(), 2);
247 copy_mem(sq[i].m_coeff.data() + 2, sq[i - 1].m_coeff.data(), d);
248 sq[i].set_degree(sq[i - 1].get_degree() + 2);
249 polyn_gf2m::remainder(sq[i], g);
250 }
251 return sq;
252}
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 565 of file polyn_gf2m.cpp.

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

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

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

References polyn_gf2m().

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


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