Botan 3.4.0
Crypto and TLS for C&
Public Member Functions | Static Public Member Functions | List of all members
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)
 

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

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

◆ polyn_gf2m() [2/9]

Botan::polyn_gf2m::polyn_gf2m ( )
inline

Definition at line 33 of file polyn_gf2m.h.

33: m_deg(-1) {}

Referenced by sqmod_init(), and 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() [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 99 of file polyn_gf2m.cpp.

99 :
100 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

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

538 :
539 m_deg(static_cast<int>(t)), m_coeff(t + 1), m_sp_field(sp_field) {
540 this->set_coef(t, 1);
541 for(;;) {
542 for(size_t i = 0; i < t; ++i) {
543 this->set_coef(i, random_code_element(sp_field->get_cardinality(), rng));
544 }
545
546 const size_t degree = polyn_gf2m::degppf(*this);
547
548 if(degree >= t) {
549 break;
550 }
551 }
552}
void set_coef(size_t i, gf2m v)
Definition polyn_gf2m.h:86
static size_t degppf(const polyn_gf2m &g)
gf2m random_code_element(uint16_t code_length, RandomNumberGenerator &rng)

References degppf(), 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 109 of file polyn_gf2m.cpp.

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

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

References get_degree().

◆ polyn_gf2m() [9/9]

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

Definition at line 63 of file polyn_gf2m.h.

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

References swap().

Member Function Documentation

◆ add_to_coef()

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

Definition at line 88 of file polyn_gf2m.h.

88{ 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 58 of file polyn_gf2m.cpp.

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

References Botan::expand_mask_16bit().

Referenced by eea_with_coefficients(), and patchup_deg_secure().

◆ degppf()

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

Definition at line 310 of file polyn_gf2m.cpp.

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

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

Referenced by 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 362 of file polyn_gf2m.cpp.

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

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

◆ encode() [1/2]

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

Definition at line 647 of file polyn_gf2m.cpp.

647 {
648 secure_vector<uint8_t> result;
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}

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

195 {
196 return eval_aux(&this->m_coeff[0], a, this->m_deg, this->m_sp_field);
197}

◆ get_coef()

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

Definition at line 84 of file polyn_gf2m.h.

84{ return m_coeff[i]; }

◆ get_degree()

int Botan::polyn_gf2m::get_degree ( ) const

Definition at line 169 of file polyn_gf2m.cpp.

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

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

82{ return m_coeff[m_deg]; }

◆ get_sp_field()

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

Definition at line 76 of file polyn_gf2m.h.

76{ 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 61 of file polyn_gf2m.h.

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

◆ operator=() [1/2]

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

◆ operator=() [2/2]

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

Definition at line 65 of file polyn_gf2m.h.

65 {
66 if(this != &other) {
67 this->swap(other);
68 }
69 return *this;
70 }

References swap().

◆ operator==()

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

Definition at line 671 of file polyn_gf2m.cpp.

671 {
672 if(m_deg != other.m_deg || m_coeff != other.m_coeff) {
673 return false;
674 }
675 return true;
676}

◆ operator[]() [1/2]

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

Definition at line 78 of file polyn_gf2m.h.

78{ return m_coeff[i]; }

◆ operator[]() [2/2]

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

Definition at line 80 of file polyn_gf2m.h.

80{ return m_coeff[i]; }

◆ patchup_deg_secure()

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

Definition at line 345 of file polyn_gf2m.cpp.

345 {
346 uint32_t i;
347 if(this->m_coeff.size() < trgt_deg) {
348 return;
349 }
350 for(i = 0; i < this->m_coeff.size(); i++) {
351 uint32_t equal, equal_mask;
352 this->m_coeff[i] |= patch_elem;
353 equal = (i == trgt_deg);
354 equal_mask = expand_mask_16bit(equal);
355 patch_elem &= ~equal_mask;
356 }
357 this->calc_degree_secure();
358}
int calc_degree_secure() const

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

Referenced by eea_with_coefficients().

◆ set_coef()

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

Definition at line 86 of file polyn_gf2m.h.

86{ 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 164 of file polyn_gf2m.cpp.

164 {
165 clear_mem(&this->m_coeff[0], this->m_coeff.size());
166 this->m_deg = -1;
167}
constexpr void clear_mem(T *ptr, size_t n)
Definition mem_ops.h:120

References Botan::clear_mem().

Referenced by eea_with_coefficients().

◆ sqmod()

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

Definition at line 258 of file polyn_gf2m.cpp.

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

References get_degree(), and set_coef().

Referenced by degppf(), and sqrt_mod_init().

◆ sqmod_init()

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

Definition at line 227 of file polyn_gf2m.cpp.

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

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

Referenced by degppf(), 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 568 of file polyn_gf2m.cpp.

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

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

Referenced by Botan::generate_mceliece_key().

◆ swap()

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

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}

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


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