mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-07 03:06:42 +01:00
Integrated with asm and tested
This commit is contained in:
@@ -1,3 +1,45 @@
|
|||||||
|
;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; copy
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; Copies
|
||||||
|
; Params:
|
||||||
|
; rsi <= the src
|
||||||
|
; rdi <= the dest
|
||||||
|
;
|
||||||
|
; Nidified registers:
|
||||||
|
; rax
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
<%=name%>_copy:
|
||||||
|
<% for (let i=0; i<=n64; i++) { %>
|
||||||
|
mov rax, [rsi + <%= i*8 %>]
|
||||||
|
mov [rdi + <%= i*8 %>], rax
|
||||||
|
<% } %>
|
||||||
|
ret
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; copy an array of integers
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; Copies
|
||||||
|
; Params:
|
||||||
|
; rsi <= the src
|
||||||
|
; rdi <= the dest
|
||||||
|
; rdx <= number of integers to copy
|
||||||
|
;
|
||||||
|
; Nidified registers:
|
||||||
|
; rax
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
<%=name%>_copyn:
|
||||||
|
<%=name%>_copyn_loop:
|
||||||
|
mov r8, rsi
|
||||||
|
mov r9, rdi
|
||||||
|
mov rax, <%= n64+1 %>
|
||||||
|
mul rdx
|
||||||
|
mov rcx, rax
|
||||||
|
cld
|
||||||
|
rep movsq
|
||||||
|
mov rsi, r8
|
||||||
|
mov rdi, r9
|
||||||
|
ret
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;
|
||||||
; rawCopyS2L
|
; rawCopyS2L
|
||||||
|
|||||||
5713
c/buildasm/fr.asm
Normal file
5713
c/buildasm/fr.asm
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
global <%=name%>_copy
|
||||||
|
global <%=name%>_copyn
|
||||||
global <%=name%>_add
|
global <%=name%>_add
|
||||||
global <%=name%>_sub
|
global <%=name%>_sub
|
||||||
global <%=name%>_neg
|
global <%=name%>_neg
|
||||||
@@ -19,6 +21,7 @@
|
|||||||
global <%=name%>_lor
|
global <%=name%>_lor
|
||||||
global <%=name%>_lnot
|
global <%=name%>_lnot
|
||||||
global <%=name%>_toNormal
|
global <%=name%>_toNormal
|
||||||
|
global <%=name%>_toLongNormal
|
||||||
global <%=name%>_toMontgomery
|
global <%=name%>_toMontgomery
|
||||||
global <%=name%>_q
|
global <%=name%>_q
|
||||||
DEFAULT REL
|
DEFAULT REL
|
||||||
|
|||||||
210
c/buildasm/fr.c
Normal file
210
c/buildasm/fr.c
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
#include "fr.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <gmp.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
mpz_t q;
|
||||||
|
mpz_t zero;
|
||||||
|
mpz_t one;
|
||||||
|
mpz_t mask;
|
||||||
|
size_t nBits;
|
||||||
|
|
||||||
|
|
||||||
|
void Fr_toMpz(mpz_t r, PFrElement pE) {
|
||||||
|
Fr_toNormal(pE);
|
||||||
|
if (!(pE->type & Fr_LONG)) {
|
||||||
|
mpz_set_si(r, pE->shortVal);
|
||||||
|
if (pE->shortVal<0) {
|
||||||
|
mpz_add(r, r, q);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
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; i<Fr_N64; i++) pE->longVal[i] = 0;
|
||||||
|
mpz_export((void *)(pE->longVal), NULL, -1, 8, -1, 0, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Fr_init() {
|
||||||
|
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-1);
|
||||||
|
mpz_sub(mask, mask, one);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fr_str2element(PFrElement pE, char const *s) {
|
||||||
|
mpz_t mr;
|
||||||
|
mpz_init_set_str(mr, s, 10);
|
||||||
|
Fr_fromMpz(pE, 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);
|
||||||
|
mpz_clear(q);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Fr_toNormal(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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_set(mr, zero);
|
||||||
|
} else {
|
||||||
|
mpz_mul_2exp(mr, ma, mpz_get_ui(mb));
|
||||||
|
mpz_and(mr, mr, mask);
|
||||||
|
}
|
||||||
|
Fr_fromMpz(r, 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_set(mr, zero);
|
||||||
|
} else {
|
||||||
|
mpz_tdiv_q_2exp(mr, ma, mpz_get_ui(mb));
|
||||||
|
mpz_and(mr, mr, mask);
|
||||||
|
}
|
||||||
|
Fr_fromMpz(r, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Fr_div(PFrElement r, PFrElement a, PFrElement b) {
|
||||||
|
FrElement tmp;
|
||||||
|
Fr_inv(&tmp, b);
|
||||||
|
Fr_mul(r, a, &tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Fr_isTrue(PFrElement pE) {
|
||||||
|
if (!(pE->type & Fr_LONG)) return pE->shortVal != 0;
|
||||||
|
for (int i=0; i< Fr_N64; i++) {
|
||||||
|
if (pE->longVal[i]) return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Fr_toInt(PFrElement pE) {
|
||||||
|
Fr_toNormal(pE);
|
||||||
|
if (!(pE->type & Fr_LONG)) {
|
||||||
|
return pE->shortVal;
|
||||||
|
} else {
|
||||||
|
mpz_t ma;
|
||||||
|
mpz_init(ma);
|
||||||
|
Fr_toMpz(ma, pE);
|
||||||
|
if (mpz_fits_sint_p(ma)) {
|
||||||
|
return mpz_get_si(ma);
|
||||||
|
}
|
||||||
|
|
||||||
|
mpz_sub(ma, ma, q);
|
||||||
|
if (mpz_fits_sint_p(ma)) {
|
||||||
|
return mpz_get_si(ma);
|
||||||
|
} else {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -2,49 +2,20 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <gmp.h>
|
#include <gmp.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
void <%=name%>_str2element(P<%=name%>Element pE, char *s) {
|
mpz_t q;
|
||||||
mpz_t r;
|
mpz_t zero;
|
||||||
mpz_init(r);
|
mpz_t one;
|
||||||
mpz_set_str(r, s, 10);
|
mpz_t mask;
|
||||||
pE->type = <%=name%>_LONG;
|
size_t nBits;
|
||||||
for (int i=0; i<<%=name%>_N64; i++) pE->longVal[i] = 0;
|
|
||||||
mpz_export((void *)pE->longVal, NULL, -1, 8, -1, 0, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *<%=name%>_element2str(P<%=name%>Element pE) {
|
|
||||||
mpz_t r;
|
|
||||||
mpz_t q;
|
|
||||||
if (!(pE->type & <%=name%>_LONG)) {
|
|
||||||
if (pE->shortVal>=0) {
|
|
||||||
char *r = new char[32];
|
|
||||||
sprintf(r, "%d", pE->shortVal);
|
|
||||||
return r;
|
|
||||||
} else {
|
|
||||||
mpz_init(q);
|
|
||||||
mpz_import(q, <%=name%>_N64, -1, 8, -1, 0, (const void *)Fr_q.longVal);
|
|
||||||
mpz_init_set_si(r, pE->shortVal);
|
|
||||||
mpz_add(r, r, q);
|
|
||||||
mpz_clear(q);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
<%=name%>_toNormal(pE);
|
|
||||||
mpz_init(r);
|
|
||||||
mpz_import(r, <%=name%>_N64, -1, 8, -1, 0, (const void *)pE->longVal);
|
|
||||||
}
|
|
||||||
char *res = mpz_get_str (0, 10, r);
|
|
||||||
mpz_clear(r);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void <%=name%>_toMpz(mpz_t r, P<%=name%>Element pE) {
|
void <%=name%>_toMpz(mpz_t r, P<%=name%>Element pE) {
|
||||||
mpz_t q;
|
|
||||||
<%=name%>_toNormal(pE);
|
<%=name%>_toNormal(pE);
|
||||||
if (!(pE->type & <%=name%>_LONG)) {
|
if (!(pE->type & <%=name%>_LONG)) {
|
||||||
mpz_set_si(r, pE->shortVal);
|
mpz_set_si(r, pE->shortVal);
|
||||||
if (pE->shortVal<0) {
|
if (pE->shortVal<0) {
|
||||||
mpz_init(q);
|
|
||||||
mpz_import(q, <%=name%>_N64, -1, 8, -1, 0, (const void *)Fr_q.longVal);
|
|
||||||
mpz_add(r, r, q);
|
mpz_add(r, r, q);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -63,6 +34,47 @@ void <%=name%>_fromMpz(P<%=name%>Element pE, mpz_t v) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void <%=name%>_init() {
|
||||||
|
mpz_init(q);
|
||||||
|
mpz_import(q, <%=name%>_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-1);
|
||||||
|
mpz_sub(mask, mask, one);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void <%=name%>_str2element(P<%=name%>Element pE, char const *s) {
|
||||||
|
mpz_t mr;
|
||||||
|
mpz_init_set_str(mr, s, 10);
|
||||||
|
<%=name%>_fromMpz(pE, mr);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *<%=name%>_element2str(P<%=name%>Element pE) {
|
||||||
|
mpz_t r;
|
||||||
|
if (!(pE->type & <%=name%>_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);
|
||||||
|
mpz_clear(q);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
<%=name%>_toNormal(pE);
|
||||||
|
mpz_init(r);
|
||||||
|
mpz_import(r, <%=name%>_N64, -1, 8, -1, 0, (const void *)pE->longVal);
|
||||||
|
}
|
||||||
|
char *res = mpz_get_str (0, 10, r);
|
||||||
|
mpz_clear(r);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
void <%=name%>_idiv(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b) {
|
void <%=name%>_idiv(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b) {
|
||||||
mpz_t ma;
|
mpz_t ma;
|
||||||
mpz_t mb;
|
mpz_t mb;
|
||||||
@@ -83,16 +95,79 @@ void <%=name%>_idiv(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element
|
|||||||
<%=name%>_fromMpz(r, mr);
|
<%=name%>_fromMpz(r, mr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void <%=name%>_mod(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b) {
|
||||||
|
mpz_t ma;
|
||||||
|
mpz_t mb;
|
||||||
|
mpz_t mr;
|
||||||
|
mpz_init(ma);
|
||||||
|
mpz_init(mb);
|
||||||
|
mpz_init(mr);
|
||||||
|
|
||||||
|
<%=name%>_toMpz(ma, a);
|
||||||
|
<%=name%>_toMpz(mb, b);
|
||||||
|
mpz_fdiv_r(mr, ma, mb);
|
||||||
|
<%=name%>_fromMpz(r, mr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void <%=name%>_shl(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b) {
|
||||||
|
mpz_t ma;
|
||||||
|
mpz_t mb;
|
||||||
|
mpz_t mr;
|
||||||
|
mpz_init(ma);
|
||||||
|
mpz_init(mb);
|
||||||
|
mpz_init(mr);
|
||||||
|
|
||||||
|
<%=name%>_toMpz(ma, a);
|
||||||
|
<%=name%>_toMpz(mb, b);
|
||||||
|
if (mpz_cmp_ui(mb, nBits) >= 0) {
|
||||||
|
mpz_set(mr, zero);
|
||||||
|
} else {
|
||||||
|
mpz_mul_2exp(mr, ma, mpz_get_ui(mb));
|
||||||
|
mpz_and(mr, mr, mask);
|
||||||
|
}
|
||||||
|
<%=name%>_fromMpz(r, mr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void <%=name%>_shr(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b) {
|
||||||
|
mpz_t ma;
|
||||||
|
mpz_t mb;
|
||||||
|
mpz_t mr;
|
||||||
|
mpz_init(ma);
|
||||||
|
mpz_init(mb);
|
||||||
|
mpz_init(mr);
|
||||||
|
|
||||||
|
<%=name%>_toMpz(ma, a);
|
||||||
|
<%=name%>_toMpz(mb, b);
|
||||||
|
if (mpz_cmp_ui(mb, nBits) >= 0) {
|
||||||
|
mpz_set(mr, zero);
|
||||||
|
} else {
|
||||||
|
mpz_tdiv_q_2exp(mr, ma, mpz_get_ui(mb));
|
||||||
|
mpz_and(mr, mr, mask);
|
||||||
|
}
|
||||||
|
<%=name%>_fromMpz(r, mr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void <%=name%>_pow(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b) {
|
||||||
|
mpz_t ma;
|
||||||
|
mpz_t mb;
|
||||||
|
mpz_t mr;
|
||||||
|
mpz_init(ma);
|
||||||
|
mpz_init(mb);
|
||||||
|
mpz_init(mr);
|
||||||
|
|
||||||
|
<%=name%>_toMpz(ma, a);
|
||||||
|
<%=name%>_toMpz(mb, b);
|
||||||
|
mpz_powm(mr, ma, mb, q);
|
||||||
|
<%=name%>_fromMpz(r, mr);
|
||||||
|
}
|
||||||
|
|
||||||
void <%=name%>_inv(P<%=name%>Element r, P<%=name%>Element a) {
|
void <%=name%>_inv(P<%=name%>Element r, P<%=name%>Element a) {
|
||||||
mpz_t ma;
|
mpz_t ma;
|
||||||
mpz_t mr;
|
mpz_t mr;
|
||||||
mpz_t q;
|
|
||||||
mpz_init(ma);
|
mpz_init(ma);
|
||||||
mpz_init(mr);
|
mpz_init(mr);
|
||||||
|
|
||||||
mpz_init(q);
|
|
||||||
mpz_import(q, <%=name%>_N64, -1, 8, -1, 0, (const void *)Fr_q.longVal);
|
|
||||||
|
|
||||||
<%=name%>_toMpz(ma, a);
|
<%=name%>_toMpz(ma, a);
|
||||||
mpz_invert(mr, ma, q);
|
mpz_invert(mr, ma, q);
|
||||||
<%=name%>_fromMpz(r, mr);
|
<%=name%>_fromMpz(r, mr);
|
||||||
@@ -104,3 +179,32 @@ void <%=name%>_div(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b
|
|||||||
<%=name%>_mul(r, a, &tmp);
|
<%=name%>_mul(r, a, &tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int <%=name%>_isTrue(P<%=name%>Element pE) {
|
||||||
|
if (!(pE->type & <%=name%>_LONG)) return pE->shortVal != 0;
|
||||||
|
for (int i=0; i< <%=name%>_N64; i++) {
|
||||||
|
if (pE->longVal[i]) return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int <%=name%>_toInt(P<%=name%>Element pE) {
|
||||||
|
Fr_toNormal(pE);
|
||||||
|
if (!(pE->type & <%=name%>_LONG)) {
|
||||||
|
return pE->shortVal;
|
||||||
|
} else {
|
||||||
|
mpz_t ma;
|
||||||
|
mpz_init(ma);
|
||||||
|
<%=name%>_toMpz(ma, pE);
|
||||||
|
if (mpz_fits_sint_p(ma)) {
|
||||||
|
return mpz_get_si(ma);
|
||||||
|
}
|
||||||
|
|
||||||
|
mpz_sub(ma, ma, q);
|
||||||
|
if (mpz_fits_sint_p(ma)) {
|
||||||
|
return mpz_get_si(ma);
|
||||||
|
} else {
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
60
c/buildasm/fr.h
Normal file
60
c/buildasm/fr.h
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#ifndef __FR_H
|
||||||
|
#define __FR_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#define Fr_N64 4
|
||||||
|
#define Fr_SHORT 0x00000000
|
||||||
|
#define Fr_LONG 0x80000000
|
||||||
|
#define Fr_LONGMONTGOMERY 0xC0000000
|
||||||
|
typedef struct __attribute__((__packed__)) {
|
||||||
|
int32_t shortVal;
|
||||||
|
u_int32_t type;
|
||||||
|
u_int64_t longVal[Fr_N64];
|
||||||
|
} FrElement;
|
||||||
|
typedef FrElement *PFrElement;
|
||||||
|
extern FrElement Fr_q;
|
||||||
|
extern "C" void Fr_copy(PFrElement r, PFrElement a);
|
||||||
|
extern "C" void Fr_copyn(PFrElement r, PFrElement a, int n);
|
||||||
|
extern "C" void Fr_add(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
extern "C" void Fr_sub(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
extern "C" void Fr_neg(PFrElement r, PFrElement a);
|
||||||
|
extern "C" void Fr_mul(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
extern "C" void Fr_square(PFrElement r, PFrElement a);
|
||||||
|
extern "C" void Fr_band(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
extern "C" void Fr_bor(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
extern "C" void Fr_bxor(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
extern "C" void Fr_bnot(PFrElement r, PFrElement a);
|
||||||
|
extern "C" void Fr_eq(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
extern "C" void Fr_neq(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
extern "C" void Fr_lt(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
extern "C" void Fr_gt(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
extern "C" void Fr_leq(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
extern "C" void Fr_geq(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
extern "C" void Fr_land(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
extern "C" void Fr_lor(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
extern "C" void Fr_lnot(PFrElement r, PFrElement a);
|
||||||
|
extern "C" void Fr_toNormal(PFrElement pE);
|
||||||
|
extern "C" void Fr_toLongNormal(PFrElement pE);
|
||||||
|
extern "C" void Fr_toMontgomery(PFrElement pE);
|
||||||
|
void Fr_str2element(PFrElement pE, char const*s);
|
||||||
|
char *Fr_element2str(PFrElement pE);
|
||||||
|
void Fr_idiv(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
void Fr_mod(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
void Fr_inv(PFrElement r, PFrElement a);
|
||||||
|
void Fr_div(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
void Fr_shl(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
void Fr_shr(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
void Fr_pow(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
|
||||||
|
int Fr_isTrue(PFrElement pE);
|
||||||
|
int Fr_toInt(PFrElement pE);
|
||||||
|
|
||||||
|
void Fr_init();
|
||||||
|
|
||||||
|
extern FrElement Fr_q;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __FR_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
#ifndef __<%=name.toUpperCase()%>_H
|
||||||
|
#define __<%=name.toUpperCase()%>_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#define <%=name%>_N64 <%= n64 %>
|
#define <%=name%>_N64 <%= n64 %>
|
||||||
#define <%=name%>_SHORT 0x00000000
|
#define <%=name%>_SHORT 0x00000000
|
||||||
@@ -10,6 +13,8 @@ typedef struct __attribute__((__packed__)) {
|
|||||||
} <%=name%>Element;
|
} <%=name%>Element;
|
||||||
typedef <%=name%>Element *P<%=name%>Element;
|
typedef <%=name%>Element *P<%=name%>Element;
|
||||||
extern <%=name%>Element <%=name%>_q;
|
extern <%=name%>Element <%=name%>_q;
|
||||||
|
extern "C" void <%=name%>_copy(P<%=name%>Element r, P<%=name%>Element a);
|
||||||
|
extern "C" void <%=name%>_copyn(P<%=name%>Element r, P<%=name%>Element a, int n);
|
||||||
extern "C" void <%=name%>_add(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
extern "C" void <%=name%>_add(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
||||||
extern "C" void <%=name%>_sub(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
extern "C" void <%=name%>_sub(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
||||||
extern "C" void <%=name%>_neg(P<%=name%>Element r, P<%=name%>Element a);
|
extern "C" void <%=name%>_neg(P<%=name%>Element r, P<%=name%>Element a);
|
||||||
@@ -29,12 +34,27 @@ extern "C" void <%=name%>_land(P<%=name%>Element r, P<%=name%>Element a, P<%=nam
|
|||||||
extern "C" void <%=name%>_lor(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
extern "C" void <%=name%>_lor(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
||||||
extern "C" void <%=name%>_lnot(P<%=name%>Element r, P<%=name%>Element a);
|
extern "C" void <%=name%>_lnot(P<%=name%>Element r, P<%=name%>Element a);
|
||||||
extern "C" void <%=name%>_toNormal(P<%=name%>Element pE);
|
extern "C" void <%=name%>_toNormal(P<%=name%>Element pE);
|
||||||
|
extern "C" void <%=name%>_toLongNormal(P<%=name%>Element pE);
|
||||||
extern "C" void <%=name%>_toMontgomery(P<%=name%>Element pE);
|
extern "C" void <%=name%>_toMontgomery(P<%=name%>Element pE);
|
||||||
void <%=name%>_str2element(P<%=name%>Element pE, char *s);
|
void <%=name%>_str2element(P<%=name%>Element pE, char const*s);
|
||||||
char *<%=name%>_element2str(P<%=name%>Element pE);
|
char *<%=name%>_element2str(P<%=name%>Element pE);
|
||||||
void <%=name%>_idiv(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
void <%=name%>_idiv(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
||||||
|
void <%=name%>_mod(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
||||||
void <%=name%>_inv(P<%=name%>Element r, P<%=name%>Element a);
|
void <%=name%>_inv(P<%=name%>Element r, P<%=name%>Element a);
|
||||||
void <%=name%>_div(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
void <%=name%>_div(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
||||||
|
void <%=name%>_shl(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
||||||
|
void <%=name%>_shr(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
||||||
|
void <%=name%>_pow(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
||||||
|
|
||||||
|
int <%=name%>_isTrue(P<%=name%>Element pE);
|
||||||
|
int <%=name%>_toInt(P<%=name%>Element pE);
|
||||||
|
|
||||||
|
void <%=name%>_init();
|
||||||
|
|
||||||
extern <%=name%>Element <%=name%>_q;
|
extern <%=name%>Element <%=name%>_q;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __<%=name.toUpperCase()%>_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
BIN
c/buildasm/fr.o
Normal file
BIN
c/buildasm/fr.o
Normal file
Binary file not shown.
@@ -1,4 +1,5 @@
|
|||||||
#include "stdio.h"
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include "fr.h"
|
#include "fr.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
@@ -9,16 +10,39 @@ int main() {
|
|||||||
/*
|
/*
|
||||||
FrElement a={0x43e1f593f0000000ULL,0x2833e84879b97091ULL,0xb85045b68181585dULL,0x30644e72e131a029ULL};
|
FrElement a={0x43e1f593f0000000ULL,0x2833e84879b97091ULL,0xb85045b68181585dULL,0x30644e72e131a029ULL};
|
||||||
FrElement b = {3,0,0,0};
|
FrElement b = {3,0,0,0};
|
||||||
*/
|
|
||||||
FrElement c;
|
|
||||||
|
|
||||||
|
FrElement c;
|
||||||
|
*/
|
||||||
// Fr_add(&(c[0]), a, a);
|
// Fr_add(&(c[0]), a, a);
|
||||||
// Fr_add(&(c[0]), c, b);
|
// Fr_add(&(c[0]), c, b);
|
||||||
|
|
||||||
|
/*
|
||||||
for (int i=0; i<1000000000; i++) {
|
for (int i=0; i<1000000000; i++) {
|
||||||
Fr_mul(&c, &a, &b);
|
Fr_mul(&c, &a, &b);
|
||||||
}
|
}
|
||||||
|
|
||||||
Fr_mul(&c,&a, &b);
|
Fr_mul(&c,&a, &b);
|
||||||
printf("%llu, %llu, %llu, %llu\n", c.longVal[0], c.longVal[1], c.longVal[2], c.longVal[3]);
|
*/
|
||||||
|
|
||||||
|
FrElement a1[10];
|
||||||
|
FrElement a2[10];
|
||||||
|
for (int i=0; i<10; i++) {
|
||||||
|
a1[i].type = Fr_LONGMONTGOMERY;
|
||||||
|
a1[i].shortVal =0;
|
||||||
|
for (int j=0; j<Fr_N64; j++) {
|
||||||
|
a2[i].longVal[j] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Fr_copyn(a2, a1, 10);
|
||||||
|
|
||||||
|
for (int i=0; i<10; i++) {
|
||||||
|
char *c1 = Fr_element2str(&a1[i]);
|
||||||
|
char *c2 = Fr_element2str(&a2[i]);
|
||||||
|
printf("%s\n%s\n\n", c1, c2);
|
||||||
|
free(c1);
|
||||||
|
free(c2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("%llu, %llu, %llu, %llu\n", c.longVal[0], c.longVal[1], c.longVal[2], c.longVal[3]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -298,17 +298,44 @@ toMontgomery_doNothing:
|
|||||||
<%=name%>_toNormal:
|
<%=name%>_toNormal:
|
||||||
mov rax, [rdi]
|
mov rax, [rdi]
|
||||||
btc rax, 62 ; check if montgomery
|
btc rax, 62 ; check if montgomery
|
||||||
jnc fromMontgomery_doNothing
|
jnc toNormal_doNothing
|
||||||
bt rax, 63 ; if short, it means it's converted
|
bt rax, 63 ; if short, it means it's converted
|
||||||
jnc fromMontgomery_doNothing
|
jnc toNormal_doNothing
|
||||||
|
|
||||||
fromMontgomeryLong:
|
toNormalLong:
|
||||||
mov [rdi], rax
|
mov [rdi], rax
|
||||||
add rdi, 8
|
add rdi, 8
|
||||||
call rawFromMontgomery
|
call rawFromMontgomery
|
||||||
sub rdi, 8
|
sub rdi, 8
|
||||||
|
|
||||||
fromMontgomery_doNothing:
|
toNormal_doNothing:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; toLongNormal
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; Convert a number to long normal
|
||||||
|
; rdi <= Pointer element to convert
|
||||||
|
; Modified registers:
|
||||||
|
; r8, r9, 10, r11, rax, rcx
|
||||||
|
;;;;;;;;;;;;;;;;;;;;
|
||||||
|
<%=name%>_toLongNormal:
|
||||||
|
mov rax, [rdi]
|
||||||
|
bt rax, 62 ; check if montgomery
|
||||||
|
jc toLongNormal_fromMontgomery
|
||||||
|
bt rax, 63 ; check if long
|
||||||
|
jnc toLongNormal_fromShort
|
||||||
|
ret ; It is already long
|
||||||
|
|
||||||
|
toLongNormal_fromMontgomery:
|
||||||
|
add rdi, 8
|
||||||
|
call rawFromMontgomery
|
||||||
|
sub rdi, 8
|
||||||
|
ret
|
||||||
|
|
||||||
|
toLongNormal_fromShort:
|
||||||
|
mov r8, rsi ; save rsi
|
||||||
|
movsx rsi, eax
|
||||||
|
call rawCopyS2L
|
||||||
|
mov rsi, r8 ; recover rsi
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <gmp.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include "calcwit.h"
|
#include "calcwit.h"
|
||||||
@@ -21,25 +20,16 @@ Circom_CalcWit::Circom_CalcWit(Circom_Circuit *aCircuit) {
|
|||||||
mutexes = new std::mutex[NMUTEXES];
|
mutexes = new std::mutex[NMUTEXES];
|
||||||
cvs = new std::condition_variable[NMUTEXES];
|
cvs = new std::condition_variable[NMUTEXES];
|
||||||
inputSignalsToTrigger = new int[circuit->NComponents];
|
inputSignalsToTrigger = new int[circuit->NComponents];
|
||||||
signalValues = new BigInt[circuit->NSignals];
|
signalValues = new FrElement[circuit->NSignals];
|
||||||
|
|
||||||
// Set one signal
|
// Set one signal
|
||||||
mpz_init_set_ui(signalValues[0], 1);
|
Fr_copy(&signalValues[0], circuit->constants + 1);
|
||||||
|
|
||||||
// Initialize remaining signals
|
|
||||||
for (int i=1; i<circuit->NSignals; i++) mpz_init2(signalValues[i], 256);
|
|
||||||
|
|
||||||
BigInt p;
|
|
||||||
mpz_init_set_str(p, circuit->P, 10);
|
|
||||||
field = new ZqField(&p);
|
|
||||||
mpz_clear(p);
|
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Circom_CalcWit::~Circom_CalcWit() {
|
Circom_CalcWit::~Circom_CalcWit() {
|
||||||
delete field;
|
|
||||||
|
|
||||||
#ifdef SANITY_CHECK
|
#ifdef SANITY_CHECK
|
||||||
delete signalAssigned;
|
delete signalAssigned;
|
||||||
@@ -48,8 +38,6 @@ Circom_CalcWit::~Circom_CalcWit() {
|
|||||||
delete[] cvs;
|
delete[] cvs;
|
||||||
delete[] mutexes;
|
delete[] mutexes;
|
||||||
|
|
||||||
for (int i=0; i<circuit->NSignals; i++) mpz_clear(signalValues[i]);
|
|
||||||
|
|
||||||
delete[] signalValues;
|
delete[] signalValues;
|
||||||
delete[] inputSignalsToTrigger;
|
delete[] inputSignalsToTrigger;
|
||||||
|
|
||||||
@@ -128,18 +116,7 @@ Circom_Sizes Circom_CalcWit::getSignalSizes(int cIdx, u64 hash) {
|
|||||||
return circuit->components[cIdx].entries[entryPos].sizes;
|
return circuit->components[cIdx].entries[entryPos].sizes;
|
||||||
}
|
}
|
||||||
|
|
||||||
PBigInt Circom_CalcWit::allocBigInts(int n) {
|
void Circom_CalcWit::getSignal(int currentComponentIdx, int cIdx, int sIdx, PFrElement value) {
|
||||||
PBigInt res = new BigInt[n];
|
|
||||||
for (int i=0; i<n; i++) mpz_init2(res[i], 256);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Circom_CalcWit::freeBigInts(PBigInt bi, int n) {
|
|
||||||
for (int i=0; i<n; i++) mpz_clear(bi[i]);
|
|
||||||
delete[] bi;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Circom_CalcWit::getSignal(int currentComponentIdx, int cIdx, int sIdx, PBigInt value) {
|
|
||||||
// syncPrintf("getSignal: %d\n", sIdx);
|
// syncPrintf("getSignal: %d\n", sIdx);
|
||||||
if ((circuit->components[cIdx].newThread)&&(currentComponentIdx != cIdx)) {
|
if ((circuit->components[cIdx].newThread)&&(currentComponentIdx != cIdx)) {
|
||||||
std::unique_lock<std::mutex> lk(mutexes[cIdx % NMUTEXES]);
|
std::unique_lock<std::mutex> lk(mutexes[cIdx % NMUTEXES]);
|
||||||
@@ -155,7 +132,7 @@ void Circom_CalcWit::getSignal(int currentComponentIdx, int cIdx, int sIdx, PBig
|
|||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
mpz_set(*value, signalValues[sIdx]);
|
Fr_copy(value, signalValues + sIdx);
|
||||||
/*
|
/*
|
||||||
char *valueStr = mpz_get_str(0, 10, *value);
|
char *valueStr = mpz_get_str(0, 10, *value);
|
||||||
syncPrintf("%d, Get %d --> %s\n", currentComponentIdx, sIdx, valueStr);
|
syncPrintf("%d, Get %d --> %s\n", currentComponentIdx, sIdx, valueStr);
|
||||||
@@ -172,7 +149,7 @@ void Circom_CalcWit::finished(int cIdx) {
|
|||||||
cvs[cIdx % NMUTEXES].notify_all();
|
cvs[cIdx % NMUTEXES].notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Circom_CalcWit::setSignal(int currentComponentIdx, int cIdx, int sIdx, PBigInt value) {
|
void Circom_CalcWit::setSignal(int currentComponentIdx, int cIdx, int sIdx, PFrElement value) {
|
||||||
// syncPrintf("setSignal: %d\n", sIdx);
|
// syncPrintf("setSignal: %d\n", sIdx);
|
||||||
|
|
||||||
#ifdef SANITY_CHECK
|
#ifdef SANITY_CHECK
|
||||||
@@ -188,7 +165,7 @@ void Circom_CalcWit::setSignal(int currentComponentIdx, int cIdx, int sIdx, PBig
|
|||||||
syncPrintf("%d, Set %d --> %s\n", currentComponentIdx, sIdx, valueStr);
|
syncPrintf("%d, Set %d --> %s\n", currentComponentIdx, sIdx, valueStr);
|
||||||
free(valueStr);
|
free(valueStr);
|
||||||
*/
|
*/
|
||||||
mpz_set(signalValues[sIdx], *value);
|
Fr_copy(signalValues + sIdx, value);
|
||||||
if ( BITMAP_ISSET(circuit->mapIsInput, sIdx) ) {
|
if ( BITMAP_ISSET(circuit->mapIsInput, sIdx) ) {
|
||||||
if (inputSignalsToTrigger[cIdx]>0) {
|
if (inputSignalsToTrigger[cIdx]>0) {
|
||||||
inputSignalsToTrigger[cIdx]--;
|
inputSignalsToTrigger[cIdx]--;
|
||||||
@@ -198,11 +175,13 @@ void Circom_CalcWit::setSignal(int currentComponentIdx, int cIdx, int sIdx, PBig
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Circom_CalcWit::checkConstraint(int currentComponentIdx, PBigInt value1, PBigInt value2, char const *err) {
|
void Circom_CalcWit::checkConstraint(int currentComponentIdx, PFrElement value1, PFrElement value2, char const *err) {
|
||||||
#ifdef SANITY_CHECK
|
#ifdef SANITY_CHECK
|
||||||
if (mpz_cmp(*value1, *value2) != 0) {
|
FrElement tmp;
|
||||||
char *pcV1 = mpz_get_str(0, 10, *value1);
|
Fr_eq(&tmp, value1, value2);
|
||||||
char *pcV2 = mpz_get_str(0, 10, *value2);
|
if (!Fr_isTrue(&tmp)) {
|
||||||
|
char *pcV1 = Fr_element2str(value1);
|
||||||
|
char *pcV2 = Fr_element2str(value2);
|
||||||
// throw std::runtime_error(std::to_string(currentComponentIdx) + std::string(", Constraint doesn't match, ") + err + ". " + sV1 + " != " + sV2 );
|
// throw std::runtime_error(std::to_string(currentComponentIdx) + std::string(", Constraint doesn't match, ") + err + ". " + sV1 + " != " + sV2 );
|
||||||
fprintf(stderr, "Constraint doesn't match, %s: %s != %s", err, pcV1, pcV2);
|
fprintf(stderr, "Constraint doesn't match, %s: %s != %s", err, pcV1, pcV2);
|
||||||
free(pcV1);
|
free(pcV1);
|
||||||
@@ -227,8 +206,8 @@ void Circom_CalcWit::triggerComponent(int newCIdx) {
|
|||||||
// cIdx = oldCIdx;
|
// cIdx = oldCIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Circom_CalcWit::log(PBigInt value) {
|
void Circom_CalcWit::log(PFrElement value) {
|
||||||
char *pcV = mpz_get_str(0, 10, *value);
|
char *pcV = Fr_element2str(value);
|
||||||
syncPrintf("Log: %s\n", pcV);
|
syncPrintf("Log: %s\n", pcV);
|
||||||
free(pcV);
|
free(pcV);
|
||||||
}
|
}
|
||||||
|
|||||||
25
c/calcwit.h
25
c/calcwit.h
@@ -2,7 +2,7 @@
|
|||||||
#define CIRCOM_CALCWIT_H
|
#define CIRCOM_CALCWIT_H
|
||||||
|
|
||||||
#include "circom.h"
|
#include "circom.h"
|
||||||
#include "zqfield.h"
|
#include "fr.h"
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
|
||||||
@@ -24,9 +24,8 @@ class Circom_CalcWit {
|
|||||||
|
|
||||||
std::mutex printf_mutex;
|
std::mutex printf_mutex;
|
||||||
|
|
||||||
BigInt *signalValues;
|
FrElement *signalValues;
|
||||||
|
|
||||||
Circom_Circuit *circuit;
|
|
||||||
|
|
||||||
void triggerComponent(int newCIdx);
|
void triggerComponent(int newCIdx);
|
||||||
void calculateWitness(void *input, void *output);
|
void calculateWitness(void *input, void *output);
|
||||||
@@ -35,7 +34,8 @@ class Circom_CalcWit {
|
|||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ZqField *field;
|
Circom_Circuit *circuit;
|
||||||
|
|
||||||
// Functions called by the circuit
|
// Functions called by the circuit
|
||||||
Circom_CalcWit(Circom_Circuit *aCircuit);
|
Circom_CalcWit(Circom_Circuit *aCircuit);
|
||||||
~Circom_CalcWit();
|
~Circom_CalcWit();
|
||||||
@@ -45,26 +45,23 @@ public:
|
|||||||
int getSignalOffset(int cIdx, u64 hash);
|
int getSignalOffset(int cIdx, u64 hash);
|
||||||
Circom_Sizes getSignalSizes(int cIdx, u64 hash);
|
Circom_Sizes getSignalSizes(int cIdx, u64 hash);
|
||||||
|
|
||||||
PBigInt allocBigInts(int n);
|
void getSignal(int currentComponentIdx, int cIdx, int sIdx, PFrElement value);
|
||||||
void freeBigInts(PBigInt bi, int n);
|
void setSignal(int currentComponentIdx, int cIdx, int sIdx, PFrElement value);
|
||||||
|
|
||||||
void getSignal(int currentComponentIdx, int cIdx, int sIdx, PBigInt value);
|
void checkConstraint(int currentComponentIdx, PFrElement value1, PFrElement value2, char const *err);
|
||||||
void setSignal(int currentComponentIdx, int cIdx, int sIdx, PBigInt value);
|
|
||||||
|
|
||||||
void checkConstraint(int currentComponentIdx, PBigInt value1, PBigInt value2, char const *err);
|
void log(PFrElement value);
|
||||||
|
|
||||||
void log(PBigInt value);
|
|
||||||
|
|
||||||
void finished(int cIdx);
|
void finished(int cIdx);
|
||||||
void join();
|
void join();
|
||||||
|
|
||||||
|
|
||||||
// Public functions
|
// Public functions
|
||||||
inline void setInput(int idx, PBigInt val) {
|
inline void setInput(int idx, PFrElement val) {
|
||||||
setSignal(0, 0, circuit->wit2sig[idx], val);
|
setSignal(0, 0, circuit->wit2sig[idx], val);
|
||||||
}
|
}
|
||||||
inline void getWitness(int idx, PBigInt val) {
|
inline void getWitness(int idx, PFrElement val) {
|
||||||
mpz_set(*val, signalValues[circuit->wit2sig[idx]]);
|
Fr_copy(val, &signalValues[circuit->wit2sig[idx]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|||||||
@@ -3,13 +3,12 @@
|
|||||||
|
|
||||||
#include <gmp.h>
|
#include <gmp.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "fr.h"
|
||||||
|
|
||||||
class Circom_CalcWit;
|
class Circom_CalcWit;
|
||||||
typedef unsigned long long u64;
|
typedef unsigned long long u64;
|
||||||
typedef uint32_t u32;
|
typedef uint32_t u32;
|
||||||
typedef uint8_t u8;
|
typedef uint8_t u8;
|
||||||
typedef mpz_t BigInt;
|
|
||||||
typedef BigInt *PBigInt;
|
|
||||||
|
|
||||||
typedef int Circom_Size;
|
typedef int Circom_Size;
|
||||||
typedef Circom_Size *Circom_Sizes;
|
typedef Circom_Size *Circom_Sizes;
|
||||||
@@ -49,6 +48,7 @@ public:
|
|||||||
int *wit2sig;
|
int *wit2sig;
|
||||||
Circom_Component *components;
|
Circom_Component *components;
|
||||||
u32 *mapIsInput;
|
u32 *mapIsInput;
|
||||||
|
PFrElement constants;
|
||||||
const char *P;
|
const char *P;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
35
c/main.cpp
35
c/main.cpp
@@ -7,7 +7,6 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <gmp.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
@@ -40,14 +39,14 @@ void loadBin(Circom_CalcWit *ctx, std::string filename) {
|
|||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
BigInt v;
|
FrElement v;
|
||||||
mpz_init2(v, 256);
|
|
||||||
u8 *p = in;
|
u8 *p = in;
|
||||||
for (int i=0; i<_circuit.NInputs; i++) {
|
for (int i=0; i<_circuit.NInputs; i++) {
|
||||||
int len = *(u8 *)p;
|
v.type = Fr_LONG;
|
||||||
p++;
|
for (int j=0; j<Fr_N64; j++) {
|
||||||
mpz_import(v,len , -1 , 1, 0, 0, p);
|
v.longVal[j] = *(u64 *)p;
|
||||||
p+=len;
|
}
|
||||||
|
p += 8;
|
||||||
ctx->setSignal(0, 0, _circuit.wit2sig[1 + _circuit.NOutputs + i], &v);
|
ctx->setSignal(0, 0, _circuit.wit2sig[1 + _circuit.NOutputs + i], &v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,8 +68,7 @@ void iterateArr(Circom_CalcWit *ctx, int o, Circom_Sizes sizes, json jarr, ItFun
|
|||||||
|
|
||||||
void itFunc(Circom_CalcWit *ctx, int o, json val) {
|
void itFunc(Circom_CalcWit *ctx, int o, json val) {
|
||||||
|
|
||||||
BigInt v;
|
FrElement v;
|
||||||
mpz_init2(v, 256);
|
|
||||||
|
|
||||||
std::string s;
|
std::string s;
|
||||||
|
|
||||||
@@ -86,7 +84,7 @@ void itFunc(Circom_CalcWit *ctx, int o, json val) {
|
|||||||
handle_error("Invalid JSON type");
|
handle_error("Invalid JSON type");
|
||||||
}
|
}
|
||||||
|
|
||||||
mpz_set_str (v, s.c_str(), 10);
|
Fr_str2element (&v, s.c_str());
|
||||||
|
|
||||||
ctx->setSignal(0, 0, o, &v);
|
ctx->setSignal(0, 0, o, &v);
|
||||||
}
|
}
|
||||||
@@ -120,16 +118,14 @@ void writeOutBin(Circom_CalcWit *ctx, std::string filename) {
|
|||||||
|
|
||||||
write_ptr = fopen(filename.c_str(),"wb");
|
write_ptr = fopen(filename.c_str(),"wb");
|
||||||
|
|
||||||
BigInt v;
|
FrElement v;
|
||||||
mpz_init2(v, 256);
|
|
||||||
|
|
||||||
u8 buffOut[256];
|
u8 buffOut[256];
|
||||||
for (int i=0;i<_circuit.NVars;i++) {
|
for (int i=0;i<_circuit.NVars;i++) {
|
||||||
size_t size=256;
|
size_t size=256;
|
||||||
ctx->getWitness(i, &v);
|
ctx->getWitness(i, &v);
|
||||||
mpz_export(buffOut+1, &size, -1, 1, -1, 0, v);
|
Fr_toLongNormal(&v);
|
||||||
*buffOut = (u8)size;
|
fwrite(v.longVal, Fr_N64*8, 1, write_ptr);
|
||||||
fwrite(buffOut, size+1, 1, write_ptr);
|
|
||||||
}
|
}
|
||||||
fclose(write_ptr);
|
fclose(write_ptr);
|
||||||
|
|
||||||
@@ -143,16 +139,14 @@ void writeOutJson(Circom_CalcWit *ctx, std::string filename) {
|
|||||||
|
|
||||||
outFile << "[\n";
|
outFile << "[\n";
|
||||||
|
|
||||||
BigInt v;
|
FrElement v;
|
||||||
mpz_init2(v, 256);
|
|
||||||
|
|
||||||
char pcV[256];
|
|
||||||
|
|
||||||
for (int i=0;i<_circuit.NVars;i++) {
|
for (int i=0;i<_circuit.NVars;i++) {
|
||||||
ctx->getWitness(i, &v);
|
ctx->getWitness(i, &v);
|
||||||
mpz_get_str(pcV, 10, v);
|
char *pcV = Fr_element2str(&v);
|
||||||
std::string sV = std::string(pcV);
|
std::string sV = std::string(pcV);
|
||||||
outFile << (i ? "," : " ") << "\"" << sV << "\"\n";
|
outFile << (i ? "," : " ") << "\"" << sV << "\"\n";
|
||||||
|
free(pcV);
|
||||||
}
|
}
|
||||||
|
|
||||||
outFile << "]\n";
|
outFile << "]\n";
|
||||||
@@ -168,6 +162,7 @@ bool hasEnding (std::string const &fullString, std::string const &ending) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
Fr_init();
|
||||||
if (argc!=3) {
|
if (argc!=3) {
|
||||||
std::string cl = argv[0];
|
std::string cl = argv[0];
|
||||||
std::string base_filename = cl.substr(cl.find_last_of("/\\") + 1);
|
std::string base_filename = cl.substr(cl.find_last_of("/\\") + 1);
|
||||||
|
|||||||
@@ -35,6 +35,11 @@ function buildC(ctx) {
|
|||||||
ctx.codes_sizes = [];
|
ctx.codes_sizes = [];
|
||||||
ctx.definedSizes = {};
|
ctx.definedSizes = {};
|
||||||
ctx.addSizes = addSizes;
|
ctx.addSizes = addSizes;
|
||||||
|
ctx.constants = [];
|
||||||
|
ctx.constantsMap = {};
|
||||||
|
ctx.addConstant = addConstant;
|
||||||
|
ctx.addConstant(bigInt.zero);
|
||||||
|
ctx.addConstant(bigInt.one);
|
||||||
|
|
||||||
const entryTables = buildEntryTables(ctx);
|
const entryTables = buildEntryTables(ctx);
|
||||||
ctx.globalNames = ctx.uniqueNames;
|
ctx.globalNames = ctx.uniqueNames;
|
||||||
@@ -45,6 +50,7 @@ function buildC(ctx) {
|
|||||||
|
|
||||||
const headder = buildHeader(ctx);
|
const headder = buildHeader(ctx);
|
||||||
const sizes = buildSizes(ctx);
|
const sizes = buildSizes(ctx);
|
||||||
|
const constants = buildConstants(ctx);
|
||||||
const mapIsInput = buildMapIsInput(ctx);
|
const mapIsInput = buildMapIsInput(ctx);
|
||||||
const wit2Sig = buildWit2Sig(ctx);
|
const wit2Sig = buildWit2Sig(ctx);
|
||||||
const circuitVar = buildCircuitVar(ctx);
|
const circuitVar = buildCircuitVar(ctx);
|
||||||
@@ -52,6 +58,7 @@ function buildC(ctx) {
|
|||||||
return "" +
|
return "" +
|
||||||
headder + "\n" +
|
headder + "\n" +
|
||||||
sizes + "\n" +
|
sizes + "\n" +
|
||||||
|
constants + "\n" +
|
||||||
entryTables + "\n" +
|
entryTables + "\n" +
|
||||||
functions + "\n" +
|
functions + "\n" +
|
||||||
code + "\n" +
|
code + "\n" +
|
||||||
@@ -244,6 +251,69 @@ function buildSizes(ctx) {
|
|||||||
ctx.codes_sizes.join("\n");
|
ctx.codes_sizes.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildConstants(ctx) {
|
||||||
|
const n64 = Math.floor((ctx.field.p.bitLength() - 1) / 64)+1;
|
||||||
|
const R = bigInt.one.shiftLeft(n64*64);
|
||||||
|
|
||||||
|
const lines = [];
|
||||||
|
lines.push("// Constants");
|
||||||
|
lines.push(`FrElement _constants[${ctx.constants.length}] = {`);
|
||||||
|
for (let i=0; i<ctx.constants.length; i++) {
|
||||||
|
lines.push((i>0 ? "," : " ") + "{" + number2Code(ctx.constants[i]) + "}");
|
||||||
|
}
|
||||||
|
lines.push("};");
|
||||||
|
|
||||||
|
return lines.join("\n");
|
||||||
|
|
||||||
|
function number2Code(n) {
|
||||||
|
if (n.lt(bigInt("80000000", 16)) ) {
|
||||||
|
return addShortMontgomeryPositive(n);
|
||||||
|
}
|
||||||
|
if (n.geq(ctx.field.p.minus(bigInt("80000000", 16))) ) {
|
||||||
|
return addShortMontgomeryNegative(n);
|
||||||
|
}
|
||||||
|
return addLongMontgomery(n);
|
||||||
|
|
||||||
|
|
||||||
|
function addShortMontgomeryPositive(a) {
|
||||||
|
return `${a.toString()}, 0x40000000, { ${getLongString(toMontgomery(a))} }`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function addShortMontgomeryNegative(a) {
|
||||||
|
const b = a.minus(ctx.field.p);
|
||||||
|
return `${b.toString()}, 0x40000000, { ${getLongString(toMontgomery(a))} }`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addLongMontgomery(a) {
|
||||||
|
return `0, 0xC0000000, { ${getLongString(toMontgomery(a))} }`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLongString(a) {
|
||||||
|
let r = bigInt(a);
|
||||||
|
let S = "";
|
||||||
|
let i = 0;
|
||||||
|
while (!r.isZero()) {
|
||||||
|
if (S!= "") S = S+",";
|
||||||
|
S += "0x" + r.and(bigInt("FFFFFFFFFFFFFFFF", 16)).toString(16) + "LL";
|
||||||
|
i++;
|
||||||
|
r = r.shiftRight(64);
|
||||||
|
}
|
||||||
|
while (i<n64) {
|
||||||
|
if (S!= "") S = S+",";
|
||||||
|
S += "0LL";
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return S;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toMontgomery(a) {
|
||||||
|
return a.times(R).mod(ctx.field.p);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function buildMapIsInput(ctx) {
|
function buildMapIsInput(ctx) {
|
||||||
const arr = [];
|
const arr = [];
|
||||||
@@ -338,6 +408,7 @@ function buildCircuitVar() {
|
|||||||
" _wit2sig,\n"+
|
" _wit2sig,\n"+
|
||||||
" _components,\n"+
|
" _components,\n"+
|
||||||
" _mapIsInput,\n"+
|
" _mapIsInput,\n"+
|
||||||
|
" _constants,\n" +
|
||||||
" __P__\n" +
|
" __P__\n" +
|
||||||
"};\n";
|
"};\n";
|
||||||
}
|
}
|
||||||
@@ -370,6 +441,16 @@ function addSizes(_sizes) {
|
|||||||
return labelName;
|
return labelName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addConstant(c) {
|
||||||
|
c = bigInt(c);
|
||||||
|
const s = c.toString();
|
||||||
|
if (typeof (this.constantsMap[s]) !== "undefined") return this.constantsMap[s];
|
||||||
|
const newId = this.constants.length;
|
||||||
|
this.constants.push(c);
|
||||||
|
this.constantsMap[s] = newId;
|
||||||
|
return newId;
|
||||||
|
}
|
||||||
|
|
||||||
function buildFunction(name, paramValues) {
|
function buildFunction(name, paramValues) {
|
||||||
const ctx = this;
|
const ctx = this;
|
||||||
const {h, instanceDef} = hashFunctionCall(ctx, name, paramValues);
|
const {h, instanceDef} = hashFunctionCall(ctx, name, paramValues);
|
||||||
@@ -409,7 +490,7 @@ function buildFunction(name, paramValues) {
|
|||||||
for (let i=0; i<ctx.functions[name].params.length; i++) {
|
for (let i=0; i<ctx.functions[name].params.length; i++) {
|
||||||
|
|
||||||
if (paramValues[i].used) {
|
if (paramValues[i].used) {
|
||||||
paramsStr += `,PBigInt ${ctx.functions[name].params[i]}`;
|
paramsStr += `,PFrElement ${ctx.functions[name].params[i]}`;
|
||||||
const idRef = ctx.refs.length;
|
const idRef = ctx.refs.length;
|
||||||
ctx.refs.push({
|
ctx.refs.push({
|
||||||
type: "BIGINT",
|
type: "BIGINT",
|
||||||
@@ -444,11 +525,12 @@ function buildFunction(name, paramValues) {
|
|||||||
"/*\n" +
|
"/*\n" +
|
||||||
instanceDef +
|
instanceDef +
|
||||||
"\n*/\n" +
|
"\n*/\n" +
|
||||||
`void ${name}_${h}(Circom_CalcWit *ctx, PBigInt __retValue ${paramsStr}) {`;
|
`void ${name}_${h}(Circom_CalcWit *ctx, PFrElement __retValue ${paramsStr}) {`;
|
||||||
code += utils.ident(ctx.codeHeader);
|
code += utils.ident(ctx.codeHeader);
|
||||||
code += utils.ident(ctx.code);
|
code += utils.ident(ctx.code);
|
||||||
code += utils.ident("returnFunc:\n");
|
code += utils.ident("returnFunc:\n");
|
||||||
code += utils.ident(ctx.codeFooter);
|
code += utils.ident(ctx.codeFooter);
|
||||||
|
code += utils.ident(";\n");
|
||||||
code += "}\n";
|
code += "}\n";
|
||||||
res.returnSizes = ctx.returnSizes;
|
res.returnSizes = ctx.returnSizes;
|
||||||
ctx.functionCodes.push(code);
|
ctx.functionCodes.push(code);
|
||||||
|
|||||||
48
src/c_gen.js
48
src/c_gen.js
@@ -43,8 +43,7 @@ function instantiateRef(ctx, refId, initValue) {
|
|||||||
if (!v.sizes) v.sizes = [1,0];
|
if (!v.sizes) v.sizes = [1,0];
|
||||||
|
|
||||||
if (v.type=="BIGINT") {
|
if (v.type=="BIGINT") {
|
||||||
ctx.codeHeader += `PBigInt ${v.label} = ctx->allocBigInts(${v.sizes[0]});\n`;
|
ctx.codeHeader += `FrElement ${v.label}[${v.sizes[0]}];\n`;
|
||||||
ctx.codeFooter += `ctx->freeBigInts(${v.label}, ${v.sizes[0]});\n`;
|
|
||||||
} else if (v.type=="INT") {
|
} else if (v.type=="INT") {
|
||||||
ctx.codeHeader += `int ${v.label};\n`;
|
ctx.codeHeader += `int ${v.label};\n`;
|
||||||
} else if (v.type=="SIZES") {
|
} else if (v.type=="SIZES") {
|
||||||
@@ -55,8 +54,8 @@ function instantiateRef(ctx, refId, initValue) {
|
|||||||
if (v.type == "BIGINT") {
|
if (v.type == "BIGINT") {
|
||||||
for (let i=0; i<initValue.length; i++) {
|
for (let i=0; i<initValue.length; i++) {
|
||||||
if (utils.isDefined(initValue[i])) {
|
if (utils.isDefined(initValue[i])) {
|
||||||
const c = `mpz_set_str(${v.label}[${i}], "${initValue[i].toString(10)}", 10);\n`;
|
const idConstant = ctx.addConstant(initValue[i]);
|
||||||
ctx.code += c;
|
ctx.code += `Fr_copy(&(${v.label}[${i}]), ctx->circuit->constants +${idConstant});\n`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,12 +66,11 @@ function instantiateConstant(ctx, value) {
|
|||||||
const sizes = utils.accSizes(utils.extractSizes(value));
|
const sizes = utils.accSizes(utils.extractSizes(value));
|
||||||
const flatedValue = utils.flatArray(value);
|
const flatedValue = utils.flatArray(value);
|
||||||
const label = ctx.getUniqueName("_const");
|
const label = ctx.getUniqueName("_const");
|
||||||
ctx.codeHeader += `PBigInt ${label};\n`;
|
ctx.codeHeader += `FrElement ${label}[${sizes[0]}];\n`;
|
||||||
ctx.codeHeader += `${label} = ctx->allocBigInts(${sizes[0]});\n`;
|
|
||||||
for (let i=0; i<flatedValue.length; i++) {
|
for (let i=0; i<flatedValue.length; i++) {
|
||||||
ctx.codeHeader += `mpz_set_str(${label}[${i}], "${flatedValue[i].toString(10)}", 10);\n`;
|
const idConstant = ctx.addConstant(flatedValue[i]);
|
||||||
|
ctx.codeHeader += `Fr_copy(&(${label}[${i}]), ctx->circuit->constants +${idConstant});\n`;
|
||||||
}
|
}
|
||||||
ctx.codeFooter += `ctx->freeBigInts(${label}, ${sizes[0]});\n`;
|
|
||||||
const refId = ctx.refs.length;
|
const refId = ctx.refs.length;
|
||||||
ctx.refs.push({
|
ctx.refs.push({
|
||||||
type: "BIGINT",
|
type: "BIGINT",
|
||||||
@@ -392,7 +390,7 @@ function genGetOffset(ctx, refOffset, vSizes, sels) {
|
|||||||
|
|
||||||
if (rStr != "") rStr += " + ";
|
if (rStr != "") rStr += " + ";
|
||||||
if (iIdx.used) {
|
if (iIdx.used) {
|
||||||
rStr += `ctx->field->toInt(${iIdx.label})`;
|
rStr += `Fr_toInt(${iIdx.label})`;
|
||||||
} else {
|
} else {
|
||||||
rStr += iIdx.value[0].toString();
|
rStr += iIdx.value[0].toString();
|
||||||
}
|
}
|
||||||
@@ -451,14 +449,14 @@ function genVariable(ctx, ast) {
|
|||||||
const refRes = newRef(ctx, "BIGINT", "_v", null, v.sizes.slice(l));
|
const refRes = newRef(ctx, "BIGINT", "_v", null, v.sizes.slice(l));
|
||||||
const res = ctx.refs[refRes];
|
const res = ctx.refs[refRes];
|
||||||
res.used = true;
|
res.used = true;
|
||||||
ctx.codeHeader += `PBigInt ${res.label};\n`;
|
ctx.codeHeader += `PFrElement ${res.label};\n`;
|
||||||
ctx.code += `${res.label} = ${v.label} + ${offset.label};\n`;
|
ctx.code += `${res.label} = ${v.label} + ${offset.label};\n`;
|
||||||
return refRes;
|
return refRes;
|
||||||
} else if ((offset.value[0])||(l>0)) {
|
} else if ((offset.value[0])||(l>0)) {
|
||||||
const refRes = newRef(ctx, "BIGINT", "_v", null, v.sizes.slice(l));
|
const refRes = newRef(ctx, "BIGINT", "_v", null, v.sizes.slice(l));
|
||||||
const res = ctx.refs[refRes];
|
const res = ctx.refs[refRes];
|
||||||
res.used = true;
|
res.used = true;
|
||||||
ctx.codeHeader += `PBigInt ${res.label};\n`;
|
ctx.codeHeader += `PFrElement ${res.label};\n`;
|
||||||
ctx.code += `${res.label} = ${v.label} + ${offset.value[0]};\n`;
|
ctx.code += `${res.label} = ${v.label} + ${offset.value[0]};\n`;
|
||||||
return refRes;
|
return refRes;
|
||||||
} else {
|
} else {
|
||||||
@@ -470,7 +468,7 @@ function genVariable(ctx, ast) {
|
|||||||
const resRef = newRef(ctx, "BIGINT", "_v", null, v.sizes.slice(l));
|
const resRef = newRef(ctx, "BIGINT", "_v", null, v.sizes.slice(l));
|
||||||
const res = ctx.refs[resRef];
|
const res = ctx.refs[resRef];
|
||||||
res.used = true;
|
res.used = true;
|
||||||
ctx.codeHeader += `PBigInt ${res.label};\n`;
|
ctx.codeHeader += `PFrElement ${res.label};\n`;
|
||||||
ctx.code += `${res.label} = ${v.label} + ${offset.label};\n`;
|
ctx.code += `${res.label} = ${v.label} + ${offset.label};\n`;
|
||||||
return resRef;
|
return resRef;
|
||||||
} else {
|
} else {
|
||||||
@@ -685,12 +683,12 @@ function genVarAssignment(ctx, ast, lRef, sels, rRef) {
|
|||||||
|
|
||||||
if (instantiated) {
|
if (instantiated) {
|
||||||
if (offset.used) {
|
if (offset.used) {
|
||||||
ctx.code += `ctx->field->copyn(${left.label} + ${offset.label}, ${right.label}, ${right.sizes[0]});\n`;
|
ctx.code += `Fr_copyn(${left.label} + ${offset.label}, ${right.label}, ${right.sizes[0]});\n`;
|
||||||
} else {
|
} else {
|
||||||
if (offset.value[0]>0) {
|
if (offset.value[0]>0) {
|
||||||
ctx.code += `ctx->field->copyn(${left.label} + ${offset.value[0]}, ${right.label}, ${right.sizes[0]});\n`;
|
ctx.code += `Fr_copyn(${left.label} + ${offset.value[0]}, ${right.label}, ${right.sizes[0]});\n`;
|
||||||
} else {
|
} else {
|
||||||
ctx.code += `ctx->field->copyn(${left.label}, ${right.label}, ${right.sizes[0]});\n`;
|
ctx.code += `Fr_copyn(${left.label}, ${right.label}, ${right.sizes[0]});\n`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -783,7 +781,7 @@ function genArray(ctx, ast) {
|
|||||||
for (let i=0; i<ast.values.length; i++) {
|
for (let i=0; i<ast.values.length; i++) {
|
||||||
const v = ctx.refs[refs[i]];
|
const v = ctx.refs[refs[i]];
|
||||||
const r = ctx.refs[rRef];
|
const r = ctx.refs[rRef];
|
||||||
ctx.code += `ctx->field->copyn(${r.label}+${i*subSizes[0]}, ${v.label}, ${subSizes[0]});\n`;
|
ctx.code += `Fr_copyn(${r.label}+${i*subSizes[0]}, ${v.label}, ${subSizes[0]});\n`;
|
||||||
}
|
}
|
||||||
return rRef;
|
return rRef;
|
||||||
} else {
|
} else {
|
||||||
@@ -883,7 +881,7 @@ function genLoop(ctx, ast) {
|
|||||||
instantiateRef(ctx, condVarRef);
|
instantiateRef(ctx, condVarRef);
|
||||||
|
|
||||||
ctx.code +=
|
ctx.code +=
|
||||||
`${condVar.label} = ctx->field->isTrue(${cond.label});\n` +
|
`${condVar.label} = Fr_isTrue(${cond.label});\n` +
|
||||||
`while (${condVar.label}) {\n`;
|
`while (${condVar.label}) {\n`;
|
||||||
} else {
|
} else {
|
||||||
if (!utils.isDefined(cond.value)) return ctx.throwError(ast, "condition value not assigned");
|
if (!utils.isDefined(cond.value)) return ctx.throwError(ast, "condition value not assigned");
|
||||||
@@ -924,7 +922,7 @@ function genLoop(ctx, ast) {
|
|||||||
instantiateRef(ctx, condVarRef);
|
instantiateRef(ctx, condVarRef);
|
||||||
|
|
||||||
ctx.code +=
|
ctx.code +=
|
||||||
`${condVar.label} = ctx->field->isTrue(${cond2.label});\n` +
|
`${condVar.label} = Fr_isTrue(${cond2.label});\n` +
|
||||||
`while (${condVar.label}) {\n`;
|
`while (${condVar.label}) {\n`;
|
||||||
} else {
|
} else {
|
||||||
ctx.code = oldCode + ctx.code;
|
ctx.code = oldCode + ctx.code;
|
||||||
@@ -935,7 +933,7 @@ function genLoop(ctx, ast) {
|
|||||||
oldCode +
|
oldCode +
|
||||||
utils.ident(
|
utils.ident(
|
||||||
ctx.code +
|
ctx.code +
|
||||||
`${condVar.label} = ctx->field->isTrue(${cond2.label});\n`);
|
`${condVar.label} = Fr_isTrue(${cond2.label});\n`);
|
||||||
end=true;
|
end=true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -960,7 +958,7 @@ function genIf(ctx, ast) {
|
|||||||
if (cond.used) {
|
if (cond.used) {
|
||||||
enterConditionalCode(ctx, ast);
|
enterConditionalCode(ctx, ast);
|
||||||
|
|
||||||
ctx.code += `if (ctx->field->isTrue(${cond.label})) {\n`;
|
ctx.code += `if (Fr_isTrue(${cond.label})) {\n`;
|
||||||
|
|
||||||
const oldCode = ctx.code;
|
const oldCode = ctx.code;
|
||||||
ctx.code = "";
|
ctx.code = "";
|
||||||
@@ -1007,7 +1005,7 @@ function genReturn(ctx, ast) {
|
|||||||
instantiateRef(ctx, vRef, v.value);
|
instantiateRef(ctx, vRef, v.value);
|
||||||
}
|
}
|
||||||
if (v.used) {
|
if (v.used) {
|
||||||
ctx.code += `ctx->field->copyn(__retValue, ${v.label}, ${v.sizes[0]});\n`;
|
ctx.code += `Fr_copyn(__retValue, ${v.label}, ${v.sizes[0]});\n`;
|
||||||
} else {
|
} else {
|
||||||
if (!utils.isDefined(v.value)) return ctx.throwError(ast, "Returning an unknown value");
|
if (!utils.isDefined(v.value)) return ctx.throwError(ast, "Returning an unknown value");
|
||||||
if (!utils.isDefined(ctx.returnValue)) {
|
if (!utils.isDefined(ctx.returnValue)) {
|
||||||
@@ -1051,7 +1049,7 @@ function genOpOp(ctx, ast, op, lr) {
|
|||||||
const res = ctx.refs[resRef];
|
const res = ctx.refs[resRef];
|
||||||
if (veval.used) {
|
if (veval.used) {
|
||||||
instantiateRef(ctx, resRef);
|
instantiateRef(ctx, resRef);
|
||||||
ctx.code += `ctx->field->${op}(${res.label}, ${veval.label}, &(ctx->field->one));\n`;
|
ctx.code += `Fr_${op}(${res.label}, ${veval.label}, ctx->circuit->constants + ${ctx.addConstant(bigInt.one)});\n`;
|
||||||
} else {
|
} else {
|
||||||
res.value = [ctx.field[op](veval.value[0], bigInt(1))];
|
res.value = [ctx.field[op](veval.value[0], bigInt(1))];
|
||||||
}
|
}
|
||||||
@@ -1097,7 +1095,7 @@ function genOp(ctx, ast, op, nOps) {
|
|||||||
rRef = newRef(ctx, "BIGINT", "_tmp");
|
rRef = newRef(ctx, "BIGINT", "_tmp");
|
||||||
instantiateRef(ctx, rRef);
|
instantiateRef(ctx, rRef);
|
||||||
const r = ctx.refs[rRef];
|
const r = ctx.refs[rRef];
|
||||||
let c = `ctx->field->${op}(${r.label}`;
|
let c = `Fr_${op}(${r.label}`;
|
||||||
for (let i=0; i<nOps; i++) {
|
for (let i=0; i<nOps; i++) {
|
||||||
c+=`,${vals[i].label}`;
|
c+=`,${vals[i].label}`;
|
||||||
}
|
}
|
||||||
@@ -1126,8 +1124,8 @@ function genTerCon(ctx, ast) {
|
|||||||
|
|
||||||
const rLabel = ctx.getUniqueName("_ter");
|
const rLabel = ctx.getUniqueName("_ter");
|
||||||
|
|
||||||
ctx.codeHeader += `PBigInt ${rLabel};\n`;
|
ctx.codeHeader += `PFrElement ${rLabel};\n`;
|
||||||
ctx.code += `if (ctx->field->isTrue(${cond.label})) {\n`;
|
ctx.code += `if (Fr_isTrue(${cond.label})) {\n`;
|
||||||
|
|
||||||
oldCode = ctx.code;
|
oldCode = ctx.code;
|
||||||
ctx.code = "";
|
ctx.code = "";
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ async function c_tester(circomFile, _options) {
|
|||||||
|
|
||||||
const dir = await tmp.dir({prefix: "circom_", unsafeCleanup: true });
|
const dir = await tmp.dir({prefix: "circom_", unsafeCleanup: true });
|
||||||
|
|
||||||
|
// console.log(dir.path);
|
||||||
|
|
||||||
const baseName = path.basename(circomFile, ".circom");
|
const baseName = path.basename(circomFile, ".circom");
|
||||||
const options = Object.assign({}, _options);
|
const options = Object.assign({}, _options);
|
||||||
|
|
||||||
@@ -40,7 +42,8 @@ async function c_tester(circomFile, _options) {
|
|||||||
` ${path.join(cdir, "main.cpp")}` +
|
` ${path.join(cdir, "main.cpp")}` +
|
||||||
` ${path.join(cdir, "calcwit.cpp")}` +
|
` ${path.join(cdir, "calcwit.cpp")}` +
|
||||||
` ${path.join(cdir, "utils.cpp")}` +
|
` ${path.join(cdir, "utils.cpp")}` +
|
||||||
` ${path.join(cdir, "zqfield.cpp")}` +
|
` ${path.join(cdir, "fr.c")}` +
|
||||||
|
` ${path.join(cdir, "fr.o")}` +
|
||||||
` ${path.join(dir.path, baseName + ".cpp")} ` +
|
` ${path.join(dir.path, baseName + ".cpp")} ` +
|
||||||
` -o ${path.join(dir.path, baseName)}` +
|
` -o ${path.join(dir.path, baseName)}` +
|
||||||
` -I ${cdir}` +
|
` -I ${cdir}` +
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ async function doTest(circuit, testVectors) {
|
|||||||
|
|
||||||
describe("basic cases", function () {
|
describe("basic cases", function () {
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
/*
|
|
||||||
it("inout", async () => {
|
it("inout", async () => {
|
||||||
await doTest(
|
await doTest(
|
||||||
"inout.circom",
|
"inout.circom",
|
||||||
@@ -112,6 +111,7 @@ describe("basic cases", function () {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("function1", async () => {
|
it("function1", async () => {
|
||||||
await doTest(
|
await doTest(
|
||||||
"function1.circom",
|
"function1.circom",
|
||||||
@@ -239,7 +239,7 @@ describe("basic cases", function () {
|
|||||||
[{in: [ 8, 9]}, {lt: 1, leq: 1, eq:0, neq:1, geq: 0, gt:0}],
|
[{in: [ 8, 9]}, {lt: 1, leq: 1, eq:0, neq:1, geq: 0, gt:0}],
|
||||||
[{in: [-2,-2]}, {lt: 0, leq: 1, eq:1, neq:0, geq: 1, gt:0}],
|
[{in: [-2,-2]}, {lt: 0, leq: 1, eq:1, neq:0, geq: 1, gt:0}],
|
||||||
[{in: [-1,-2]}, {lt: 0, leq: 0, eq:0, neq:1, geq: 1, gt:1}],
|
[{in: [-1,-2]}, {lt: 0, leq: 0, eq:0, neq:1, geq: 1, gt:1}],
|
||||||
[{in: [ 1,-1]}, {lt: 1, leq: 1, eq:0, neq:1, geq: 0, gt:0}], // In mod, negative values are higher than positive.
|
[{in: [ 1,-1]}, {lt: 0, leq: 0, eq:0, neq:1, geq: 1, gt:1}], // In mod, negative values are higher than positive.
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -299,7 +299,6 @@ describe("basic cases", function () {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
*/
|
|
||||||
it("Component array 2d", async () => {
|
it("Component array 2d", async () => {
|
||||||
await doTest(
|
await doTest(
|
||||||
"componentarray2.circom",
|
"componentarray2.circom",
|
||||||
@@ -309,7 +308,6 @@ describe("basic cases", function () {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
/*
|
|
||||||
it("Constant circuit", async () => {
|
it("Constant circuit", async () => {
|
||||||
await doTest(
|
await doTest(
|
||||||
"constantcircuit.circom",
|
"constantcircuit.circom",
|
||||||
@@ -339,5 +337,4 @@ describe("basic cases", function () {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
*/
|
|
||||||
});
|
});
|
||||||
|
|||||||
1
test/circuits/inc.json
Normal file
1
test/circuits/inc.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"x": "3"}
|
||||||
Reference in New Issue
Block a user