Integrated with asm and tested

This commit is contained in:
Jordi Baylina
2020-01-23 07:20:58 +07:00
parent e11e6768e4
commit f6092e3944
22 changed files with 6410 additions and 152 deletions

View File

@@ -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

5713
c/buildasm/fr.asm Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,7 @@
global <%=name%>_copy
global <%=name%>_copyn
global <%=name%>_add
global <%=name%>_sub
global <%=name%>_neg
@@ -19,6 +21,7 @@
global <%=name%>_lor
global <%=name%>_lnot
global <%=name%>_toNormal
global <%=name%>_toLongNormal
global <%=name%>_toMontgomery
global <%=name%>_q
DEFAULT REL

210
c/buildasm/fr.c Normal file
View 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);
}
}
}

View File

@@ -2,49 +2,20 @@
#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>
#include <assert.h>
void <%=name%>_str2element(P<%=name%>Element pE, char *s) {
mpz_t r;
mpz_init(r);
mpz_set_str(r, s, 10);
pE->type = <%=name%>_LONG;
for (int i=0; i<<%=name%>_N64; i++) pE->longVal[i] = 0;
mpz_export((void *)pE->longVal, NULL, -1, 8, -1, 0, r);
}
mpz_t q;
mpz_t zero;
mpz_t one;
mpz_t mask;
size_t nBits;
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) {
mpz_t q;
<%=name%>_toNormal(pE);
if (!(pE->type & <%=name%>_LONG)) {
mpz_set_si(r, pE->shortVal);
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);
}
} 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) {
mpz_t ma;
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);
}
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) {
mpz_t ma;
mpz_t mr;
mpz_t q;
mpz_init(ma);
mpz_init(mr);
mpz_init(q);
mpz_import(q, <%=name%>_N64, -1, 8, -1, 0, (const void *)Fr_q.longVal);
<%=name%>_toMpz(ma, a);
mpz_invert(mr, ma, q);
<%=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);
}
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
View 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

View File

@@ -1,3 +1,6 @@
#ifndef __<%=name.toUpperCase()%>_H
#define __<%=name.toUpperCase()%>_H
#include <stdint.h>
#define <%=name%>_N64 <%= n64 %>
#define <%=name%>_SHORT 0x00000000
@@ -10,6 +13,8 @@ typedef struct __attribute__((__packed__)) {
} <%=name%>Element;
typedef <%=name%>Element *P<%=name%>Element;
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%>_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);
@@ -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%>_lnot(P<%=name%>Element r, P<%=name%>Element a);
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);
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);
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%>_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;
#endif // __<%=name.toUpperCase()%>_H

BIN
c/buildasm/fr.o Normal file

Binary file not shown.

View File

@@ -1,4 +1,5 @@
#include "stdio.h"
#include <stdio.h>
#include <stdlib.h>
#include "fr.h"
int main() {
@@ -9,16 +10,39 @@ int main() {
/*
FrElement a={0x43e1f593f0000000ULL,0x2833e84879b97091ULL,0xb85045b68181585dULL,0x30644e72e131a029ULL};
FrElement b = {3,0,0,0};
*/
FrElement c;
FrElement c;
*/
// Fr_add(&(c[0]), a, a);
// Fr_add(&(c[0]), c, b);
/*
for (int i=0; i<1000000000; i++) {
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]);
}

View File

@@ -298,17 +298,44 @@ toMontgomery_doNothing:
<%=name%>_toNormal:
mov rax, [rdi]
btc rax, 62 ; check if montgomery
jnc fromMontgomery_doNothing
jnc toNormal_doNothing
bt rax, 63 ; if short, it means it's converted
jnc fromMontgomery_doNothing
jnc toNormal_doNothing
fromMontgomeryLong:
toNormalLong:
mov [rdi], rax
add rdi, 8
call rawFromMontgomery
sub rdi, 8
fromMontgomery_doNothing:
toNormal_doNothing:
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

View File

@@ -4,7 +4,6 @@
#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include <gmp.h>
#include <assert.h>
#include <thread>
#include "calcwit.h"
@@ -21,25 +20,16 @@ Circom_CalcWit::Circom_CalcWit(Circom_Circuit *aCircuit) {
mutexes = new std::mutex[NMUTEXES];
cvs = new std::condition_variable[NMUTEXES];
inputSignalsToTrigger = new int[circuit->NComponents];
signalValues = new BigInt[circuit->NSignals];
signalValues = new FrElement[circuit->NSignals];
// Set one signal
mpz_init_set_ui(signalValues[0], 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);
Fr_copy(&signalValues[0], circuit->constants + 1);
reset();
}
Circom_CalcWit::~Circom_CalcWit() {
delete field;
#ifdef SANITY_CHECK
delete signalAssigned;
@@ -48,8 +38,6 @@ Circom_CalcWit::~Circom_CalcWit() {
delete[] cvs;
delete[] mutexes;
for (int i=0; i<circuit->NSignals; i++) mpz_clear(signalValues[i]);
delete[] signalValues;
delete[] inputSignalsToTrigger;
@@ -128,18 +116,7 @@ Circom_Sizes Circom_CalcWit::getSignalSizes(int cIdx, u64 hash) {
return circuit->components[cIdx].entries[entryPos].sizes;
}
PBigInt Circom_CalcWit::allocBigInts(int n) {
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) {
void Circom_CalcWit::getSignal(int currentComponentIdx, int cIdx, int sIdx, PFrElement value) {
// syncPrintf("getSignal: %d\n", sIdx);
if ((circuit->components[cIdx].newThread)&&(currentComponentIdx != cIdx)) {
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);
}
#endif
mpz_set(*value, signalValues[sIdx]);
Fr_copy(value, signalValues + sIdx);
/*
char *valueStr = mpz_get_str(0, 10, *value);
syncPrintf("%d, Get %d --> %s\n", currentComponentIdx, sIdx, valueStr);
@@ -172,7 +149,7 @@ void Circom_CalcWit::finished(int cIdx) {
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);
#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);
free(valueStr);
*/
mpz_set(signalValues[sIdx], *value);
Fr_copy(signalValues + sIdx, value);
if ( BITMAP_ISSET(circuit->mapIsInput, sIdx) ) {
if (inputSignalsToTrigger[cIdx]>0) {
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
if (mpz_cmp(*value1, *value2) != 0) {
char *pcV1 = mpz_get_str(0, 10, *value1);
char *pcV2 = mpz_get_str(0, 10, *value2);
FrElement tmp;
Fr_eq(&tmp, value1, 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 );
fprintf(stderr, "Constraint doesn't match, %s: %s != %s", err, pcV1, pcV2);
free(pcV1);
@@ -227,8 +206,8 @@ void Circom_CalcWit::triggerComponent(int newCIdx) {
// cIdx = oldCIdx;
}
void Circom_CalcWit::log(PBigInt value) {
char *pcV = mpz_get_str(0, 10, *value);
void Circom_CalcWit::log(PFrElement value) {
char *pcV = Fr_element2str(value);
syncPrintf("Log: %s\n", pcV);
free(pcV);
}

View File

@@ -2,7 +2,7 @@
#define CIRCOM_CALCWIT_H
#include "circom.h"
#include "zqfield.h"
#include "fr.h"
#include <mutex>
#include <condition_variable>
@@ -24,9 +24,8 @@ class Circom_CalcWit {
std::mutex printf_mutex;
BigInt *signalValues;
FrElement *signalValues;
Circom_Circuit *circuit;
void triggerComponent(int newCIdx);
void calculateWitness(void *input, void *output);
@@ -35,7 +34,8 @@ class Circom_CalcWit {
public:
ZqField *field;
Circom_Circuit *circuit;
// Functions called by the circuit
Circom_CalcWit(Circom_Circuit *aCircuit);
~Circom_CalcWit();
@@ -45,26 +45,23 @@ public:
int getSignalOffset(int cIdx, u64 hash);
Circom_Sizes getSignalSizes(int cIdx, u64 hash);
PBigInt allocBigInts(int n);
void freeBigInts(PBigInt bi, int n);
void getSignal(int currentComponentIdx, int cIdx, int sIdx, PFrElement value);
void setSignal(int currentComponentIdx, int cIdx, int sIdx, PFrElement value);
void getSignal(int currentComponentIdx, int cIdx, int sIdx, PBigInt value);
void setSignal(int currentComponentIdx, int cIdx, int sIdx, PBigInt value);
void checkConstraint(int currentComponentIdx, PFrElement value1, PFrElement value2, char const *err);
void checkConstraint(int currentComponentIdx, PBigInt value1, PBigInt value2, char const *err);
void log(PBigInt value);
void log(PFrElement value);
void finished(int cIdx);
void join();
// Public functions
inline void setInput(int idx, PBigInt val) {
inline void setInput(int idx, PFrElement val) {
setSignal(0, 0, circuit->wit2sig[idx], val);
}
inline void getWitness(int idx, PBigInt val) {
mpz_set(*val, signalValues[circuit->wit2sig[idx]]);
inline void getWitness(int idx, PFrElement val) {
Fr_copy(val, &signalValues[circuit->wit2sig[idx]]);
}
void reset();

View File

@@ -3,13 +3,12 @@
#include <gmp.h>
#include <stdint.h>
#include "fr.h"
class Circom_CalcWit;
typedef unsigned long long u64;
typedef uint32_t u32;
typedef uint8_t u8;
typedef mpz_t BigInt;
typedef BigInt *PBigInt;
typedef int Circom_Size;
typedef Circom_Size *Circom_Sizes;
@@ -49,6 +48,7 @@ public:
int *wit2sig;
Circom_Component *components;
u32 *mapIsInput;
PFrElement constants;
const char *P;
};

1
c/fr.c Symbolic link
View File

@@ -0,0 +1 @@
buildasm/fr.c

1
c/fr.h Symbolic link
View File

@@ -0,0 +1 @@
buildasm/fr.h

1
c/fr.o Symbolic link
View File

@@ -0,0 +1 @@
buildasm/fr.o

View File

@@ -7,7 +7,6 @@
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <gmp.h>
#include <unistd.h>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
@@ -40,14 +39,14 @@ void loadBin(Circom_CalcWit *ctx, std::string filename) {
close(fd);
BigInt v;
mpz_init2(v, 256);
FrElement v;
u8 *p = in;
for (int i=0; i<_circuit.NInputs; i++) {
int len = *(u8 *)p;
p++;
mpz_import(v,len , -1 , 1, 0, 0, p);
p+=len;
v.type = Fr_LONG;
for (int j=0; j<Fr_N64; j++) {
v.longVal[j] = *(u64 *)p;
}
p += 8;
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) {
BigInt v;
mpz_init2(v, 256);
FrElement v;
std::string s;
@@ -86,7 +84,7 @@ void itFunc(Circom_CalcWit *ctx, int o, json val) {
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);
}
@@ -120,16 +118,14 @@ void writeOutBin(Circom_CalcWit *ctx, std::string filename) {
write_ptr = fopen(filename.c_str(),"wb");
BigInt v;
mpz_init2(v, 256);
FrElement v;
u8 buffOut[256];
for (int i=0;i<_circuit.NVars;i++) {
size_t size=256;
ctx->getWitness(i, &v);
mpz_export(buffOut+1, &size, -1, 1, -1, 0, v);
*buffOut = (u8)size;
fwrite(buffOut, size+1, 1, write_ptr);
Fr_toLongNormal(&v);
fwrite(v.longVal, Fr_N64*8, 1, write_ptr);
}
fclose(write_ptr);
@@ -143,16 +139,14 @@ void writeOutJson(Circom_CalcWit *ctx, std::string filename) {
outFile << "[\n";
BigInt v;
mpz_init2(v, 256);
char pcV[256];
FrElement v;
for (int i=0;i<_circuit.NVars;i++) {
ctx->getWitness(i, &v);
mpz_get_str(pcV, 10, v);
char *pcV = Fr_element2str(&v);
std::string sV = std::string(pcV);
outFile << (i ? "," : " ") << "\"" << sV << "\"\n";
free(pcV);
}
outFile << "]\n";
@@ -168,6 +162,7 @@ bool hasEnding (std::string const &fullString, std::string const &ending) {
}
int main(int argc, char *argv[]) {
Fr_init();
if (argc!=3) {
std::string cl = argv[0];
std::string base_filename = cl.substr(cl.find_last_of("/\\") + 1);