circom/c/buildasm/fr.c
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 mpz_import(r, Fr_N64, -1, 8, -1, 0, (const void *)pE->longVal);
23 }
24}
25
26void Fr_fromMpz(PFrElement pE, mpz_t v) {
27 if (mpz_fits_sint_p(v)) {
28 pE->type = Fr_SHORT;
29 pE->shortVal = mpz_get_si(v);
30 } else {
31 pE->type = Fr_LONG;
32 for (int i=0; i<Fr_N64; i++) pE->longVal[i] = 0;
33 mpz_export((void *)(pE->longVal), NULL, -1, 8, -1, 0, v);
34 }
35}
36
37
38void Fr_init() {
39 mpz_init(q);
40 mpz_import(q, Fr_N64, -1, 8, -1, 0, (const void *)Fr_q.longVal);
41 mpz_init_set_ui(zero, 0);
42 mpz_init_set_ui(one, 1);
43 nBits = mpz_sizeinbase (q, 2);
44 mpz_init(mask);
45 mpz_mul_2exp(mask, one, nBits-1);
46 mpz_sub(mask, mask, one);
47
48}
49
50void Fr_str2element(PFrElement pE, char const *s) {
51 mpz_t mr;
52 mpz_init_set_str(mr, s, 10);
53 Fr_fromMpz(pE, mr);
54}
55
56char *Fr_element2str(PFrElement pE) {
57 mpz_t r;
58 if (!(pE->type & Fr_LONG)) {
59 if (pE->shortVal>=0) {
60 char *r = new char[32];
61 sprintf(r, "%d", pE->shortVal);
62 return r;
63 } else {
64 mpz_init_set_si(r, pE->shortVal);
65 mpz_add(r, r, q);
66 mpz_clear(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_set(mr, zero);
124 } else {
125 mpz_mul_2exp(mr, ma, mpz_get_ui(mb));
126 mpz_and(mr, mr, mask);
127 }
128 Fr_fromMpz(r, mr);
129}
130
131void Fr_shr(PFrElement r, PFrElement a, PFrElement b) {
132 mpz_t ma;
133 mpz_t mb;
134 mpz_t mr;
135 mpz_init(ma);
136 mpz_init(mb);
137 mpz_init(mr);
138
139 Fr_toMpz(ma, a);
140 Fr_toMpz(mb, b);
141 if (mpz_cmp_ui(mb, nBits) >= 0) {
142 mpz_set(mr, zero);
143 } else {
144 mpz_tdiv_q_2exp(mr, ma, mpz_get_ui(mb));
145 mpz_and(mr, mr, mask);
146 }
147 Fr_fromMpz(r, mr);
148}
149
150
151void Fr_pow(PFrElement r, PFrElement a, PFrElement b) {
152 mpz_t ma;
153 mpz_t mb;
154 mpz_t mr;
155 mpz_init(ma);
156 mpz_init(mb);
157 mpz_init(mr);
158
159 Fr_toMpz(ma, a);
160 Fr_toMpz(mb, b);
161 mpz_powm(mr, ma, mb, q);
162 Fr_fromMpz(r, mr);
163}
164
165void Fr_inv(PFrElement r, PFrElement a) {
166 mpz_t ma;
167 mpz_t mr;
168 mpz_init(ma);
169 mpz_init(mr);
170
171 Fr_toMpz(ma, a);
172 mpz_invert(mr, ma, q);
173 Fr_fromMpz(r, mr);
174}
175
176void Fr_div(PFrElement r, PFrElement a, PFrElement b) {
177 FrElement tmp;
178 Fr_inv(&tmp, b);
179 Fr_mul(r, a, &tmp);
180}
181
182int Fr_isTrue(PFrElement pE) {
183 if (!(pE->type & Fr_LONG)) return pE->shortVal != 0;
184 for (int i=0; i< Fr_N64; i++) {
185 if (pE->longVal[i]) return 1;
186 }
187 return 0;
188}
189
190int Fr_toInt(PFrElement pE) {
191 Fr_toNormal(pE);
192 if (!(pE->type & Fr_LONG)) {
193 return pE->shortVal;
194 } else {
195 mpz_t ma;
196 mpz_init(ma);
197 Fr_toMpz(ma, pE);
198 if (mpz_fits_sint_p(ma)) {
199 return mpz_get_si(ma);
200 }
201
202 mpz_sub(ma, ma, q);
203 if (mpz_fits_sint_p(ma)) {
204 return mpz_get_si(ma);
205 } else {
206 assert(false);
207 }
208 }
209}
210