arnaucube
arnaucube/circomPublic Self-hosted repository
circom/ports/c/buildasm/fr.c
ports/c/buildasm/fr.cRaw
  1#include "fr.h"
  2#include <stdio.h>
  3#include <stdlib.h>
  4#include <gmp.h>
  5#include <assert.h>
  6
  7mpz_t q;
  8mpz_t zero;
  9mpz_t one;
 10mpz_t mask;
 11size_t nBits;
 12
 13
 14void Fr_toMpz(mpz_t r, PFrElement pE) {
 15    Fr_toNormal(pE);
 16    if (!(pE->type & Fr_LONG)) {
 17        mpz_set_si(r, pE->shortVal);
 18        if (pE->shortVal<0) {
 19            mpz_add(r, r, q);
 20        }
 21    } else {
 22        Fr_toNormal(pE);
 23        mpz_import(r, Fr_N64, -1, 8, -1, 0, (const void *)pE->longVal);
 24    }
 25}
 26
 27void Fr_fromMpz(PFrElement pE, mpz_t v) {
 28    if (mpz_fits_sint_p(v)) {
 29        pE->type = Fr_SHORT;
 30        pE->shortVal = mpz_get_si(v);
 31    } else {
 32        pE->type = Fr_LONG;
 33        for (int i=0; i<Fr_N64; i++) pE->longVal[i] = 0;
 34        mpz_export((void *)(pE->longVal), NULL, -1, 8, -1, 0, v);
 35    }
 36}
 37
 38
 39void Fr_init() {
 40    mpz_init(q);
 41    mpz_import(q, Fr_N64, -1, 8, -1, 0, (const void *)Fr_q.longVal);
 42    mpz_init_set_ui(zero, 0);
 43    mpz_init_set_ui(one, 1);
 44    nBits = mpz_sizeinbase (q, 2);
 45    mpz_init(mask);
 46    mpz_mul_2exp(mask, one, nBits);
 47    mpz_sub(mask, mask, one);
 48
 49}
 50
 51void Fr_str2element(PFrElement pE, char const *s) {
 52    mpz_t mr;
 53    mpz_init_set_str(mr, s, 10);
 54    Fr_fromMpz(pE, mr);
 55}
 56
 57char *Fr_element2str(PFrElement pE) {
 58    mpz_t r;
 59    if (!(pE->type & Fr_LONG)) {
 60        if (pE->shortVal>=0) {
 61            char *r = new char[32];
 62            sprintf(r, "%d", pE->shortVal);
 63            return r;
 64        } else {
 65            mpz_init_set_si(r, pE->shortVal);
 66            mpz_add(r, r, q);
 67        }
 68    } else {
 69        Fr_toNormal(pE);
 70        mpz_init(r);
 71        mpz_import(r, Fr_N64, -1, 8, -1, 0, (const void *)pE->longVal);
 72    }
 73    char *res = mpz_get_str (0, 10, r);
 74    mpz_clear(r);
 75    return res;
 76}
 77
 78void Fr_idiv(PFrElement r, PFrElement a, PFrElement b) {
 79    mpz_t ma;
 80    mpz_t mb;
 81    mpz_t mr;
 82    mpz_init(ma);
 83    mpz_init(mb);
 84    mpz_init(mr);
 85
 86    Fr_toMpz(ma, a);
 87    // char *s1 = mpz_get_str (0, 10, ma);
 88    // printf("s1 %s\n", s1);
 89    Fr_toMpz(mb, b);
 90    // char *s2 = mpz_get_str (0, 10, mb);
 91    // printf("s2 %s\n", s2);
 92    mpz_fdiv_q(mr, ma, mb);
 93    // char *sr = mpz_get_str (0, 10, mr);
 94    // printf("r %s\n", sr);
 95    Fr_fromMpz(r, mr);
 96}
 97
 98void Fr_mod(PFrElement r, PFrElement a, PFrElement b) {
 99    mpz_t ma;
100    mpz_t mb;
101    mpz_t mr;
102    mpz_init(ma);
103    mpz_init(mb);
104    mpz_init(mr);
105
106    Fr_toMpz(ma, a);
107    Fr_toMpz(mb, b);
108    mpz_fdiv_r(mr, ma, mb);
109    Fr_fromMpz(r, mr);
110}
111
112void Fr_shl(PFrElement r, PFrElement a, PFrElement b) {
113    mpz_t ma;
114    mpz_t mb;
115    mpz_t mr;
116    mpz_init(ma);
117    mpz_init(mb);
118    mpz_init(mr);
119
120    Fr_toMpz(ma, a);
121    Fr_toMpz(mb, b);
122    if (mpz_cmp_ui(mb, nBits) < 0) {
123        mpz_mul_2exp(mr, ma, mpz_get_ui(mb));
124        mpz_and(mr, mr, mask);
125        if (mpz_cmp(mr, q) >= 0) {
126            mpz_sub(mr, mr, q);
127        }
128    } else {
129        mpz_sub(mb, q, mb);
130        if (mpz_cmp_ui(mb, nBits) < 0) {
131            mpz_tdiv_q_2exp(mr, ma, mpz_get_ui(mb));
132        } else {
133            mpz_set(mr, zero);
134        }
135    }
136    Fr_fromMpz(r, mr);
137}
138
139void Fr_shr(PFrElement r, PFrElement a, PFrElement b) {
140    mpz_t ma;
141    mpz_t mb;
142    mpz_t mr;
143    mpz_init(ma);
144    mpz_init(mb);
145    mpz_init(mr);
146
147    Fr_toMpz(ma, a);
148    Fr_toMpz(mb, b);
149    if (mpz_cmp_ui(mb, nBits) < 0) {
150        mpz_tdiv_q_2exp(mr, ma, mpz_get_ui(mb));
151    } else {
152        mpz_sub(mb, q, mb);
153        if (mpz_cmp_ui(mb, nBits) < 0) {
154            mpz_mul_2exp(mr, ma, mpz_get_ui(mb));
155            mpz_and(mr, mr, mask);
156            if (mpz_cmp(mr, q) >= 0) {
157                mpz_sub(mr, mr, q);
158            }
159        } else {
160            mpz_set(mr, zero);
161        }
162    }
163    Fr_fromMpz(r, mr);
164}
165
166
167void Fr_pow(PFrElement r, PFrElement a, PFrElement b) {
168    mpz_t ma;
169    mpz_t mb;
170    mpz_t mr;
171    mpz_init(ma);
172    mpz_init(mb);
173    mpz_init(mr);
174
175    Fr_toMpz(ma, a);
176    Fr_toMpz(mb, b);
177    mpz_powm(mr, ma, mb, q);
178    Fr_fromMpz(r, mr);
179}
180
181void Fr_inv(PFrElement r, PFrElement a) {
182    mpz_t ma;
183    mpz_t mr;
184    mpz_init(ma);
185    mpz_init(mr);
186
187    Fr_toMpz(ma, a);
188    mpz_invert(mr, ma, q);
189    Fr_fromMpz(r, mr);
190}
191
192void Fr_div(PFrElement r, PFrElement a, PFrElement b) {
193    FrElement tmp;
194    Fr_inv(&tmp, b);
195    Fr_mul(r, a, &tmp);
196}
197
198void Fr_fail() {
199    assert(false);
200}
201