123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- #include "Fp.hpp"
- extern const double bn_v;
- Fp::Fp()
- {
- fpe_setzero(element);
- no_change = false;
- }
- Fp::Fp(const fpe_t & input)
- {
- set(input);
- no_change = false;
- }
- Fp::Fp(int input)
- {
- set(input);
- no_change = false;
- }
- void Fp::set(const fpe_t & fpe)
- {
- fpe_set(element, fpe);
- no_change = false;
- }
- void Fp::set(int input)
- {
- mydouble[12] coefficient_matrix;
- for (int i = 0; i < 12; i++)
- {
- switch (i)
- {
- case 0:
- coefficient_matrix[i] = ((mydouble) input);
- break;
- default:
- coefficient_matrix[i] = 0.;
- }
- }
- fpe_set_doublearray(element, coefficient_matrix);
- if (input > ((int) bn_v) * 3)
- {
- fpe_short_coeffred(element)
- }
- no_change = false;
- }
- void Fp::set_random()
- {
- // c.f. https://www.cryptojedi.org/papers/dclxvi-20100714.pdf for these maxes
- const int MAX_A = ((int) bn_v) * 3;
- const int MAX_B = ((int) bn_v) / 2 + 1;
-
- std::random_device generator;
- std::uniform_int_distribution<int> distribution_a(-MAX_A, MAX_A);
- std::uniform_int_distribution<int> distribution_b(-MAX_B, MAX_B);
- mydouble[12] coefficient_matrix;
- for (int i = 0; i < 12; i++)
- {
- switch (i)
- {
- case 0:
- case 6:
- coefficient_matrix[i] = ((mydouble) distribution_a(generator));
- break;
- default:
- coefficient_matrix[i] = ((mydouble) distribution_b(generator));
- }
- }
- fpe_set_doublearray(element, coefficient_matrix);
- no_change = false;
- }
- Fp Fp::operator-() const
- {
- fpe_t temp;
- fpe_neg(temp, element);
- return Fp(temp);
- }
- Fp Fp::operator+(const Fp & b) const
- {
- fpe_t temp;
- fpe_add(temp, element, b.element);
- return Fp(temp);
- }
- Fp Fp::operator-(const Fp & b) const
- {
- fpe_t temp;
- fpe_sub(temp, element, b.element);
- return Fp(temp);
- }
- Fp Fp::operator*(const Fp & b) const
- {
- fpe_t temp;
- fpe_mul(temp, element, b.element);
- return Fp(temp);
- }
- Fp Fp::operator/(const Fp & b) const
- {
- fpe_t temp;
- fpe_invert(temp, b.element);
- fpe_mul(temp, element, temp);
- return Fp(temp);
- }
- bool Fp::operator==(const Fp & b) const
- {
- return fpe_iseq(element, b.element) == 1;
- }
- bool Fp::operator!=(const Fp & b) const
- {
- return fpe_iseq(element, b.element) == 0;
- }
- bool Fp::is_zero() const
- {
- return fpe_iszero(element) == 1;
- }
-
- scalar_t& Fp::to_scalar() const
- {
- if (no_change)
- return scalar;
- mpz_class poly_at_one = 1.;
- mpz_class increment_factor = bn_v * 6;
- for (int i = 0; i < 12; i++)
- {
- switch (i)
- {
- case 0:
- poly_at_one = todouble(element->v[0]);
- break;
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- poly_at_one += increment_factor * todouble(element->v[i]);
- increment_factor *= bn_v;
- break;
- case 7:
- increment_factor *= 6.;
- poly_at_one += increment_factor * todouble(element->v[i]);
- increment_factor *= bn_v;
- break;
- default:
- poly_at_one += increment_factor * todouble(element->v[i]);
- increment_factor *= bn_v;
- break;
- }
- }
-
- mpz_class bn_u = 1;
- for (int i = 0; i < 3; i++)
- bn_u *= bn_v;
-
- mpz_class bn_p;
- bn_p = 36*bn_u*bn_u*bn_u*bn_u + 36*bn_u*bn_u*bn_u + 24*bn_u*bn_u + 6*bn_u + 1;
- mpz_class field_element = poly_at_one % bn_p;
- mpz_class mask = 0xffffffffffffffff; // 8 octets 64 bits
- scalar[0] = mpz2ull( field_element & mask);
- scalar[1] = mpz2ull((field_element >> 64) & mask);
- scalar[2] = mpz2ull((field_element >> 128) & mask);
- scalar[3] = mpz2ull((field_element >> 192) & mask);
- no_change = true;
- return scalar;
- }
- std::ostream& operator<<(std::ostream& os, const Fp& output)
- {
- if (!output.no_change)
- output.to_scalar();
- os << output.scalar[3] << output.scalar[2] << output.scalar[1] << output.scalar[0];
- return os;
- }
- unsigned long long Fp::mpz2ull(const mpz_class& n) const
- {
- stringstream str;
- unsigned long long retval;
-
- str << n;
- str >> retval;
- return retval;
- }
|