#include "fr.hpp" #include #include #include #include #include static mpz_t q; static mpz_t zero; static mpz_t one; static mpz_t mask; static size_t nBits; static bool initialized = false; void Fr_toMpz(mpz_t r, PFrElement pE) { Fr_toNormal(pE, pE); if (!(pE->type & Fr_LONG)) { mpz_set_si(r, pE->shortVal); if (pE->shortVal<0) { mpz_add(r, r, q); } } else { Fr_toNormal(pE, pE); mpz_import(r, Fr_N64, -1, 8, -1, 0, (const void *)pE->longVal); } } void Fr_fromMpz(PFrElement pE, mpz_t v) { if (mpz_fits_sint_p(v)) { pE->type = Fr_SHORT; pE->shortVal = mpz_get_si(v); } else { pE->type = Fr_LONG; for (int i=0; ilongVal[i] = 0; mpz_export((void *)(pE->longVal), NULL, -1, 8, -1, 0, v); } } bool Fr_init() { if (initialized) return false; initialized = true; mpz_init(q); mpz_import(q, Fr_N64, -1, 8, -1, 0, (const void *)Fr_q.longVal); mpz_init_set_ui(zero, 0); mpz_init_set_ui(one, 1); nBits = mpz_sizeinbase (q, 2); mpz_init(mask); mpz_mul_2exp(mask, one, nBits); mpz_sub(mask, mask, one); return true; } void Fr_str2element(PFrElement pE, char const *s) { mpz_t mr; mpz_init_set_str(mr, s, 10); mpz_fdiv_r(mr, mr, q); Fr_fromMpz(pE, mr); mpz_clear(mr); } char *Fr_element2str(PFrElement pE) { mpz_t r; if (!(pE->type & Fr_LONG)) { if (pE->shortVal>=0) { char *r = new char[32]; sprintf(r, "%d", pE->shortVal); return r; } else { mpz_init_set_si(r, pE->shortVal); mpz_add(r, r, q); } } else { Fr_toNormal(pE, pE); mpz_init(r); mpz_import(r, Fr_N64, -1, 8, -1, 0, (const void *)pE->longVal); } char *res = mpz_get_str (0, 10, r); mpz_clear(r); return res; } void Fr_idiv(PFrElement r, PFrElement a, PFrElement b) { mpz_t ma; mpz_t mb; mpz_t mr; mpz_init(ma); mpz_init(mb); mpz_init(mr); Fr_toMpz(ma, a); // char *s1 = mpz_get_str (0, 10, ma); // printf("s1 %s\n", s1); Fr_toMpz(mb, b); // char *s2 = mpz_get_str (0, 10, mb); // printf("s2 %s\n", s2); mpz_fdiv_q(mr, ma, mb); // char *sr = mpz_get_str (0, 10, mr); // printf("r %s\n", sr); Fr_fromMpz(r, mr); mpz_clear(ma); mpz_clear(mb); mpz_clear(mr); } void Fr_mod(PFrElement r, PFrElement a, PFrElement b) { mpz_t ma; mpz_t mb; mpz_t mr; mpz_init(ma); mpz_init(mb); mpz_init(mr); Fr_toMpz(ma, a); Fr_toMpz(mb, b); mpz_fdiv_r(mr, ma, mb); Fr_fromMpz(r, mr); mpz_clear(ma); mpz_clear(mb); mpz_clear(mr); } void Fr_shl(PFrElement r, PFrElement a, PFrElement b) { mpz_t ma; mpz_t mb; mpz_t mr; mpz_init(ma); mpz_init(mb); mpz_init(mr); Fr_toMpz(ma, a); Fr_toMpz(mb, b); if (mpz_cmp_ui(mb, nBits) < 0) { mpz_mul_2exp(mr, ma, mpz_get_ui(mb)); mpz_and(mr, mr, mask); if (mpz_cmp(mr, q) >= 0) { mpz_sub(mr, mr, q); } } else { mpz_sub(mb, q, mb); if (mpz_cmp_ui(mb, nBits) < 0) { mpz_tdiv_q_2exp(mr, ma, mpz_get_ui(mb)); } else { mpz_set(mr, zero); } } Fr_fromMpz(r, mr); mpz_clear(ma); mpz_clear(mb); mpz_clear(mr); } void Fr_shr(PFrElement r, PFrElement a, PFrElement b) { mpz_t ma; mpz_t mb; mpz_t mr; mpz_init(ma); mpz_init(mb); mpz_init(mr); Fr_toMpz(ma, a); Fr_toMpz(mb, b); if (mpz_cmp_ui(mb, nBits) < 0) { mpz_tdiv_q_2exp(mr, ma, mpz_get_ui(mb)); } else { mpz_sub(mb, q, mb); if (mpz_cmp_ui(mb, nBits) < 0) { mpz_mul_2exp(mr, ma, mpz_get_ui(mb)); mpz_and(mr, mr, mask); if (mpz_cmp(mr, q) >= 0) { mpz_sub(mr, mr, q); } } else { mpz_set(mr, zero); } } Fr_fromMpz(r, mr); mpz_clear(ma); mpz_clear(mb); mpz_clear(mr); } void Fr_pow(PFrElement r, PFrElement a, PFrElement b) { mpz_t ma; mpz_t mb; mpz_t mr; mpz_init(ma); mpz_init(mb); mpz_init(mr); Fr_toMpz(ma, a); Fr_toMpz(mb, b); mpz_powm(mr, ma, mb, q); Fr_fromMpz(r, mr); mpz_clear(ma); mpz_clear(mb); mpz_clear(mr); } void Fr_inv(PFrElement r, PFrElement a) { mpz_t ma; mpz_t mr; mpz_init(ma); mpz_init(mr); Fr_toMpz(ma, a); mpz_invert(mr, ma, q); Fr_fromMpz(r, mr); mpz_clear(ma); mpz_clear(mr); } void Fr_div(PFrElement r, PFrElement a, PFrElement b) { FrElement tmp; Fr_inv(&tmp, b); Fr_mul(r, a, &tmp); } void Fr_fail() { assert(false); } RawFr::RawFr() { Fr_init(); fromString(fZero, "0"); fromString(fOne, "1"); neg(fNegOne, fOne); } RawFr::~RawFr() { } void RawFr::fromString(Element &r, std::string s) { mpz_t mr; mpz_init_set_str(mr, s.c_str(), 10); mpz_fdiv_r(mr, mr, q); for (int i=0; i> 6; int bit = i & 0x3F; r.v[i] = (tmp.v[word] & (1LL << bit)) >> bit; if (r.v[i]) r.l = i+1; } } */ void RawFr::toMpz(mpz_t r, Element &a) { Element tmp; Fr_rawFromMontgomery(tmp.v, a.v); mpz_import(r, Fr_N64, -1, 8, -1, 0, (const void *)tmp.v); } static bool init = Fr_init();