mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-06 18:56:40 +01:00
Begining of wasm
This commit is contained in:
BIN
c/buildasm/fr.o
BIN
c/buildasm/fr.o
Binary file not shown.
BIN
c/mainjson
BIN
c/mainjson
Binary file not shown.
16
cli.js
16
cli.js
@@ -34,6 +34,7 @@ const argv = require("yargs")
|
||||
.alias("o", "output")
|
||||
.alias("c", "csource")
|
||||
.alias("w", "wasm")
|
||||
.alias("t", "wat")
|
||||
.alias("s", "sym")
|
||||
.alias("r", "r1cs")
|
||||
.alias("n", "newThreadTemplates")
|
||||
@@ -71,6 +72,7 @@ const fullFileName = path.resolve(process.cwd(), inputFile);
|
||||
const fileName = path.basename(fullFileName, ".circom");
|
||||
const cSourceName = typeof(argv.csource) === "string" ? argv.csource : fileName + ".cpp";
|
||||
const wasmName = typeof(argv.wasm) === "string" ? argv.wasm : fileName + ".wasm";
|
||||
const watName = typeof(argv.wat) === "string" ? argv.wat : fileName + ".wat";
|
||||
const r1csName = typeof(argv.r1cs) === "string" ? argv.r1cs : fileName + ".r1cs";
|
||||
const symName = typeof(argv.sym) === "string" ? argv.sym : fileName + ".sym";
|
||||
|
||||
@@ -83,6 +85,9 @@ if (argv.csource) {
|
||||
if (argv.wasm) {
|
||||
options.wasmWriteStream = fs.createWriteStream(wasmName);
|
||||
}
|
||||
if (argv.wat) {
|
||||
options.watWriteStream = fs.createWriteStream(watName);
|
||||
}
|
||||
if (argv.r1cs) {
|
||||
options.r1csFileName = r1csName;
|
||||
}
|
||||
@@ -97,6 +102,7 @@ compiler(fullFileName, options).then( () => {
|
||||
let cSourceDone = false;
|
||||
let wasmDone = false;
|
||||
let symDone = false;
|
||||
let watDone = false;
|
||||
if (options.cSourceWriteStream) {
|
||||
options.cSourceWriteStream.on("finish", () => {
|
||||
cSourceDone = true;
|
||||
@@ -113,6 +119,14 @@ compiler(fullFileName, options).then( () => {
|
||||
} else {
|
||||
wasmDone = true;
|
||||
}
|
||||
if (options.watWriteStream) {
|
||||
options.watWriteStream.on("finish", () => {
|
||||
watDone = true;
|
||||
finishIfDone();
|
||||
});
|
||||
} else {
|
||||
watDone = true;
|
||||
}
|
||||
if (options.symWriteStream) {
|
||||
options.symWriteStream.on("finish", () => {
|
||||
symDone = true;
|
||||
@@ -122,7 +136,7 @@ compiler(fullFileName, options).then( () => {
|
||||
symDone = true;
|
||||
}
|
||||
function finishIfDone() {
|
||||
if ((cSourceDone)&&(symDone)&&(wasmDone)) {
|
||||
if ((cSourceDone)&&(symDone)&&(wasmDone)&&(watDone)) {
|
||||
setTimeout(() => {
|
||||
process.exit(0);
|
||||
}, 300);
|
||||
|
||||
4
index.js
4
index.js
@@ -1,3 +1,3 @@
|
||||
module.exports.compiler = require("./src/compiler.js");
|
||||
module.exports.c_tester = require("./src/c_tester.js");
|
||||
module.exports.tester = require("./src/c_tester.js");
|
||||
module.exports.c_tester = require("./ports/c/tester.js");
|
||||
module.exports.wasm_tester = require("./ports/wasm/tester.js");
|
||||
|
||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -1482,6 +1482,14 @@
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"wasmbuilder": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/wasmbuilder/-/wasmbuilder-0.0.8.tgz",
|
||||
"integrity": "sha512-d63cIsDmHnybA5hTlRRLadgys5r3Tl4W8SbcBRh13FauEPOo48dqjgzdL1xefpZkpKKybDRlFqgm+9cX04B3+w==",
|
||||
"requires": {
|
||||
"big-integer": "^1.6.43"
|
||||
}
|
||||
},
|
||||
"which": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"optimist": "^0.6.1",
|
||||
"rimraf-promise": "^2.0.0",
|
||||
"tmp-promise": "^2.0.2",
|
||||
"wasmbuilder": "0.0.8",
|
||||
"yargs": "^12.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
439
ports/c/buildasm/cmpops.asm.ejs
Normal file
439
ports/c/buildasm/cmpops.asm.ejs
Normal file
@@ -0,0 +1,439 @@
|
||||
<% function signL(reg, label_pos, label_neg) { %>
|
||||
<% for (let i=n64-1; i>=0; i--) { %>
|
||||
mov rax, [<%=reg%> + <%= 8+(i*8) %>]
|
||||
cmp [half + <%= (i*8) %>], rax ; comare with (q-1)/2
|
||||
jc <%=label_neg%> ; half<rax => e1-e2 is neg => e1 < e2
|
||||
<% if (i>0) { %>
|
||||
jnz <%=label_pos%> ; half>rax => e1 -e2 is pos => e1 > e2
|
||||
<% } else { %>
|
||||
jmp <%=label_pos%>
|
||||
<% } %>
|
||||
<% } %>
|
||||
<% } %>
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; rgt - Raw Greater Than
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; returns in ax 1 id *rsi > *rdx
|
||||
; Params:
|
||||
; rsi <= Pointer to element 1
|
||||
; rdx <= Pointer to element 2
|
||||
; rax <= Return 1 or 0
|
||||
; Modified Registers:
|
||||
; r8, r9, rax
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
<%=name%>_rgt:
|
||||
mov r8, [rsi]
|
||||
mov r9, [rdx]
|
||||
bt r8, 63 ; Check if is short first operand
|
||||
jc rgt_l1
|
||||
bt r9, 63 ; Check if is short second operand
|
||||
jc rgt_s1l2
|
||||
|
||||
rgt_s1s2: ; Both operands are short
|
||||
cmp r8d, r9d
|
||||
jg rgt_ret1
|
||||
jmp rgt_ret0
|
||||
|
||||
|
||||
rgt_l1:
|
||||
bt r9, 63 ; Check if is short second operand
|
||||
jc rgt_l1l2
|
||||
|
||||
;;;;;;;;
|
||||
rgt_l1s2:
|
||||
bt r8, 62 ; check if montgomery first
|
||||
jc rgt_l1ms2
|
||||
rgt_l1ns2:
|
||||
<%= global.toLong_b() %>
|
||||
jmp rgtL1L2
|
||||
|
||||
rgt_l1ms2:
|
||||
<%= global.toLong_b() %>
|
||||
<%= global.fromMont_a() %>
|
||||
jmp rgtL1L2
|
||||
|
||||
|
||||
;;;;;;;;
|
||||
rgt_s1l2:
|
||||
bt r9, 62 ; check if montgomery second
|
||||
jc rgt_s1l2m
|
||||
rgt_s1l2n:
|
||||
<%= global.toLong_a() %>
|
||||
jmp rgtL1L2
|
||||
|
||||
rgt_s1l2m:
|
||||
<%= global.toLong_a() %>
|
||||
<%= global.fromMont_b() %>
|
||||
jmp rgtL1L2
|
||||
|
||||
;;;;
|
||||
rgt_l1l2:
|
||||
bt r8, 62 ; check if montgomery first
|
||||
jc rgt_l1ml2
|
||||
rgt_l1nl2:
|
||||
bt r9, 62 ; check if montgomery second
|
||||
jc rgt_l1nl2m
|
||||
rgt_l1nl2n:
|
||||
jmp rgtL1L2
|
||||
|
||||
rgt_l1nl2m:
|
||||
<%= global.fromMont_b() %>
|
||||
jmp rgtL1L2
|
||||
|
||||
rgt_l1ml2:
|
||||
bt r9, 62 ; check if montgomery second
|
||||
jc rgt_l1ml2m
|
||||
rgt_l1ml2n:
|
||||
<%= global.fromMont_a() %>
|
||||
jmp rgtL1L2
|
||||
|
||||
rgt_l1ml2m:
|
||||
<%= global.fromMont_a() %>
|
||||
<%= global.fromMont_b() %>
|
||||
jmp rgtL1L2
|
||||
|
||||
|
||||
;;;;;;
|
||||
; rgtL1L2
|
||||
;;;;;;
|
||||
|
||||
rgtL1L2:
|
||||
<%= signL("rsi", "rgtl1l2_p1", "rgtl1l2_n1") %>
|
||||
rgtl1l2_p1:
|
||||
<%= signL("rdx", "rgtRawL1L2", "rgt_ret1") %>
|
||||
|
||||
rgtl1l2_n1:
|
||||
<%= signL("rdx", "rgt_ret0", "rgtRawL1L2") %>
|
||||
|
||||
|
||||
rgtRawL1L2:
|
||||
<% for (let i=n64-1; i>=0; i--) { %>
|
||||
mov rax, [rsi + <%= 8+(i*8) %>]
|
||||
cmp [rdx + <%= 8+(i*8) %>], rax ; comare with (q-1)/2
|
||||
jc rgt_ret1 ; rsi<rdx => 1st > 2nd
|
||||
<% if (i>0) { %>
|
||||
jnz rgt_ret0
|
||||
<% } %>
|
||||
<% } %>
|
||||
|
||||
rgt_ret0:
|
||||
xor rax, rax
|
||||
ret
|
||||
rgt_ret1:
|
||||
mov rax, 1
|
||||
ret
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; rlt - Raw Less Than
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; returns in ax 1 id *rsi > *rdx
|
||||
; Params:
|
||||
; rsi <= Pointer to element 1
|
||||
; rdx <= Pointer to element 2
|
||||
; rax <= Return 1 or 0
|
||||
; Modified Registers:
|
||||
; r8, r9, rax
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
<%=name%>_rlt:
|
||||
mov r8, [rsi]
|
||||
mov r9, [rdx]
|
||||
bt r8, 63 ; Check if is short first operand
|
||||
jc rlt_l1
|
||||
bt r9, 63 ; Check if is short second operand
|
||||
jc rlt_s1l2
|
||||
|
||||
rlt_s1s2: ; Both operands are short
|
||||
cmp r8d, r9d
|
||||
jl rlt_ret1
|
||||
jmp rlt_ret0
|
||||
|
||||
|
||||
rlt_l1:
|
||||
bt r9, 63 ; Check if is short second operand
|
||||
jc rlt_l1l2
|
||||
|
||||
;;;;;;;;
|
||||
rlt_l1s2:
|
||||
bt r8, 62 ; check if montgomery first
|
||||
jc rlt_l1ms2
|
||||
rlt_l1ns2:
|
||||
<%= global.toLong_b() %>
|
||||
jmp rltL1L2
|
||||
|
||||
rlt_l1ms2:
|
||||
<%= global.toLong_b() %>
|
||||
<%= global.fromMont_a() %>
|
||||
jmp rltL1L2
|
||||
|
||||
|
||||
;;;;;;;;
|
||||
rlt_s1l2:
|
||||
bt r9, 62 ; check if montgomery second
|
||||
jc rlt_s1l2m
|
||||
rlt_s1l2n:
|
||||
<%= global.toLong_a() %>
|
||||
jmp rltL1L2
|
||||
|
||||
rlt_s1l2m:
|
||||
<%= global.toLong_a() %>
|
||||
<%= global.fromMont_b() %>
|
||||
jmp rltL1L2
|
||||
|
||||
;;;;
|
||||
rlt_l1l2:
|
||||
bt r8, 62 ; check if montgomery first
|
||||
jc rlt_l1ml2
|
||||
rlt_l1nl2:
|
||||
bt r9, 62 ; check if montgomery second
|
||||
jc rlt_l1nl2m
|
||||
rlt_l1nl2n:
|
||||
jmp rltL1L2
|
||||
|
||||
rlt_l1nl2m:
|
||||
<%= global.fromMont_b() %>
|
||||
jmp rltL1L2
|
||||
|
||||
rlt_l1ml2:
|
||||
bt r9, 62 ; check if montgomery second
|
||||
jc rlt_l1ml2m
|
||||
rlt_l1ml2n:
|
||||
<%= global.fromMont_a() %>
|
||||
jmp rltL1L2
|
||||
|
||||
rlt_l1ml2m:
|
||||
<%= global.fromMont_a() %>
|
||||
<%= global.fromMont_b() %>
|
||||
jmp rltL1L2
|
||||
|
||||
|
||||
;;;;;;
|
||||
; rltL1L2
|
||||
;;;;;;
|
||||
|
||||
rltL1L2:
|
||||
<%= signL("rsi", "rltl1l2_p1", "rltl1l2_n1") %>
|
||||
rltl1l2_p1:
|
||||
<%= signL("rdx", "rltRawL1L2", "rlt_ret0") %>
|
||||
|
||||
rltl1l2_n1:
|
||||
<%= signL("rdx", "rlt_ret1", "rltRawL1L2") %>
|
||||
|
||||
|
||||
rltRawL1L2:
|
||||
<% for (let i=n64-1; i>=0; i--) { %>
|
||||
mov rax, [rsi + <%= 8+(i*8) %>]
|
||||
cmp [rdx + <%= 8+(i*8) %>], rax ; comare with (q-1)/2
|
||||
jc rlt_ret0 ; rsi<rdx => 1st > 2nd
|
||||
jnz rlt_ret1
|
||||
<% } %>
|
||||
|
||||
rlt_ret0:
|
||||
xor rax, rax
|
||||
ret
|
||||
rlt_ret1:
|
||||
mov rax, 1
|
||||
ret
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; req - Raw Eq
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; returns in ax 1 id *rsi == *rdx
|
||||
; Params:
|
||||
; rsi <= Pointer to element 1
|
||||
; rdx <= Pointer to element 2
|
||||
; rax <= Return 1 or 0
|
||||
; Modified Registers:
|
||||
; r8, r9, rax
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
<%=name%>_req:
|
||||
mov r8, [rsi]
|
||||
mov r9, [rdx]
|
||||
bt r8, 63 ; Check if is short first operand
|
||||
jc req_l1
|
||||
bt r9, 63 ; Check if is short second operand
|
||||
jc req_s1l2
|
||||
|
||||
req_s1s2: ; Both operands are short
|
||||
cmp r8d, r9d
|
||||
je req_ret1
|
||||
jmp req_ret0
|
||||
|
||||
|
||||
req_l1:
|
||||
bt r9, 63 ; Check if is short second operand
|
||||
jc req_l1l2
|
||||
|
||||
;;;;;;;;
|
||||
req_l1s2:
|
||||
bt r8, 62 ; check if montgomery first
|
||||
jc req_l1ms2
|
||||
req_l1ns2:
|
||||
<%= global.toLong_b() %>
|
||||
jmp reqL1L2
|
||||
|
||||
req_l1ms2:
|
||||
<%= global.toMont_b() %>
|
||||
jmp reqL1L2
|
||||
|
||||
|
||||
;;;;;;;;
|
||||
req_s1l2:
|
||||
bt r9, 62 ; check if montgomery second
|
||||
jc req_s1l2m
|
||||
req_s1l2n:
|
||||
<%= global.toLong_a() %>
|
||||
jmp reqL1L2
|
||||
|
||||
req_s1l2m:
|
||||
<%= global.toMont_a() %>
|
||||
jmp reqL1L2
|
||||
|
||||
;;;;
|
||||
req_l1l2:
|
||||
bt r8, 62 ; check if montgomery first
|
||||
jc req_l1ml2
|
||||
req_l1nl2:
|
||||
bt r9, 62 ; check if montgomery second
|
||||
jc req_l1nl2m
|
||||
req_l1nl2n:
|
||||
jmp reqL1L2
|
||||
|
||||
req_l1nl2m:
|
||||
<%= global.toMont_a() %>
|
||||
jmp reqL1L2
|
||||
|
||||
req_l1ml2:
|
||||
bt r9, 62 ; check if montgomery second
|
||||
jc req_l1ml2m
|
||||
req_l1ml2n:
|
||||
<%= global.toMont_b() %>
|
||||
jmp reqL1L2
|
||||
|
||||
req_l1ml2m:
|
||||
jmp reqL1L2
|
||||
|
||||
|
||||
;;;;;;
|
||||
; eqL1L2
|
||||
;;;;;;
|
||||
|
||||
reqL1L2:
|
||||
<% for (let i=0; i<n64; i++) { %>
|
||||
mov rax, [rsi + <%= 8+(i*8) %>]
|
||||
cmp [rdx + <%= 8+(i*8) %>], rax
|
||||
jne req_ret0 ; rsi<rdi => 1st > 2nd
|
||||
<% } %>
|
||||
|
||||
req_ret1:
|
||||
mov rax, 1
|
||||
ret
|
||||
|
||||
req_ret0:
|
||||
xor rax, rax
|
||||
ret
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; gt
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Compares two elements of any kind
|
||||
; Params:
|
||||
; rsi <= Pointer to element 1
|
||||
; rdx <= Pointer to element 2
|
||||
; rdi <= Pointer to result can be zero or one.
|
||||
; Modified Registers:
|
||||
; rax, rcx
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
<%=name%>_gt:
|
||||
call <%=name%>_rgt
|
||||
mov [rdi], rax
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; lt
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Compares two elements of any kind
|
||||
; Params:
|
||||
; rsi <= Pointer to element 1
|
||||
; rdx <= Pointer to element 2
|
||||
; rdi <= Pointer to result can be zero or one.
|
||||
; Modified Registers:
|
||||
; rax, rcx
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
<%=name%>_lt:
|
||||
call <%=name%>_rlt
|
||||
mov [rdi], rax
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; eq
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Compares two elements of any kind
|
||||
; Params:
|
||||
; rsi <= Pointer to element 1
|
||||
; rdx <= Pointer to element 2
|
||||
; rdi <= Pointer to result can be zero or one.
|
||||
; Modified Registers:
|
||||
; rax, rcx
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
<%=name%>_eq:
|
||||
call <%=name%>_req
|
||||
mov [rdi], rax
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; neq
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Compares two elements of any kind
|
||||
; Params:
|
||||
; rsi <= Pointer to element 1
|
||||
; rdx <= Pointer to element 2
|
||||
; rdi <= Pointer to result can be zero or one.
|
||||
; Modified Registers:
|
||||
; rax, rcx
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
<%=name%>_neq:
|
||||
call <%=name%>_req
|
||||
xor rax, 1
|
||||
mov [rdi], rax
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; geq
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Compares two elements of any kind
|
||||
; Params:
|
||||
; rsi <= Pointer to element 1
|
||||
; rdx <= Pointer to element 2
|
||||
; rdi <= Pointer to result can be zero or one.
|
||||
; Modified Registers:
|
||||
; rax, rcx
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
<%=name%>_geq:
|
||||
call <%=name%>_rlt
|
||||
xor rax, 1
|
||||
mov [rdi], rax
|
||||
ret
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; leq
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Compares two elements of any kind
|
||||
; Params:
|
||||
; rsi <= Pointer to element 1
|
||||
; rdx <= Pointer to element 2
|
||||
; rdi <= Pointer to result can be zero or one.
|
||||
; Modified Registers:
|
||||
; rax, rcx
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
<%=name%>_leq:
|
||||
call <%=name%>_rgt
|
||||
xor rax, 1
|
||||
mov [rdi], rax
|
||||
ret
|
||||
@@ -40,7 +40,7 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; <%= op %>
|
||||
;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Adds two elements of any kind
|
||||
; Compares two elements of any kind
|
||||
; Params:
|
||||
; rsi <= Pointer to element 1
|
||||
; rdx <= Pointer to element 2
|
||||
@@ -97,6 +97,12 @@ u64toLong_adjust_neg:
|
||||
ret
|
||||
|
||||
<%=name%>_long:
|
||||
bt rax, 62
|
||||
jnc <%=name%>_longNormal
|
||||
<%=name%>_longMontgomery:
|
||||
call <%=name%>_toLongNormal
|
||||
|
||||
<%=name%>_longNormal:
|
||||
mov rax, [rdi + 8]
|
||||
mov rcx, rax
|
||||
shr rcx, 31
|
||||
File diff suppressed because it is too large
Load Diff
@@ -63,7 +63,6 @@ char *Fr_element2str(PFrElement pE) {
|
||||
} else {
|
||||
mpz_init_set_si(r, pE->shortVal);
|
||||
mpz_add(r, r, q);
|
||||
mpz_clear(q);
|
||||
}
|
||||
} else {
|
||||
Fr_toNormal(pE);
|
||||
BIN
ports/c/buildasm/fr.o
Normal file
BIN
ports/c/buildasm/fr.o
Normal file
Binary file not shown.
BIN
ports/c/buildasm/tester
Executable file
BIN
ports/c/buildasm/tester
Executable file
Binary file not shown.
20
ports/c/buildasm/tester.dSYM/Contents/Info.plist
Normal file
20
ports/c/buildasm/tester.dSYM/Contents/Info.plist
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.xcode.dsym.tester</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>dSYM</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
BIN
ports/c/buildasm/tester.dSYM/Contents/Resources/DWARF/tester
Normal file
BIN
ports/c/buildasm/tester.dSYM/Contents/Resources/DWARF/tester
Normal file
Binary file not shown.
@@ -70,4 +70,3 @@ return (
|
||||
pop rdi`);
|
||||
} %>
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
const streamFromMultiArray = require("./stream_from_multiarray");
|
||||
const streamFromMultiArray = require("../../src/streamfromarray_txt.js");
|
||||
const bigInt = require("big-integer");
|
||||
const utils = require("./utils");
|
||||
const utils = require("../../src/utils");
|
||||
const assert = require("assert");
|
||||
|
||||
function ref2src(c) {
|
||||
if (c[0] == "R") {
|
||||
if ((c[0] == "R")||(c[0] == "RI")) {
|
||||
return c[1];
|
||||
} else if (c[0] == "V") {
|
||||
return c[1].toString();
|
||||
@@ -94,6 +94,9 @@ class CodeBuilderC {
|
||||
this.ops.push({op: "CHECKCONSTRAINT", a, b, strErr});
|
||||
}
|
||||
|
||||
log(val) {
|
||||
this.ops.push({op: "LOG", val});
|
||||
}
|
||||
|
||||
concat(cb) {
|
||||
this.ops.push(...cb.ops);
|
||||
@@ -211,6 +214,8 @@ class CodeBuilderC {
|
||||
code.push(`${o.fnName}(ctx, ${o.retLabel}, ${o.params.join(",")});`);
|
||||
} else if (o.op == "CHECKCONSTRAINT") {
|
||||
code.push(`ctx->checkConstraint(__cIdx, ${ref2src(o.a)}, ${ref2src(o.b)}, "${o.strErr}");`);
|
||||
} else if (o.op == "LOG") {
|
||||
code.push(`ctx->log(${ref2src(o.val)});`);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -342,6 +347,8 @@ class BuilderC {
|
||||
this.constants = [];
|
||||
this.functions = [];
|
||||
this.components = [];
|
||||
this.usedConstants = {};
|
||||
|
||||
}
|
||||
|
||||
setHeader(header) {
|
||||
@@ -362,7 +369,11 @@ class BuilderC {
|
||||
}
|
||||
|
||||
addConstant(c) {
|
||||
c = bigInt(c);
|
||||
const cS = c.toString();
|
||||
if (this.usedConstants[cS]) return this.usedConstants[cS];
|
||||
this.constants.push(c);
|
||||
this.usedConstants[cS] = this.constants.length - 1;
|
||||
return this.constants.length - 1;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,8 @@ void Circom_CalcWit::reset() {
|
||||
|
||||
for (int i=0; i<circuit->NComponents; i++) {
|
||||
inputSignalsToTrigger[i] = circuit->components[i].inputSignals;
|
||||
}
|
||||
for (int i=0; i<circuit->NComponents; i++) {
|
||||
if (inputSignalsToTrigger[i] == 0) triggerComponent(i);
|
||||
}
|
||||
}
|
||||
@@ -171,6 +173,9 @@ void Circom_CalcWit::setSignal(int currentComponentIdx, int cIdx, int sIdx, PFrE
|
||||
if (inputSignalsToTrigger[cIdx]>0) {
|
||||
inputSignalsToTrigger[cIdx]--;
|
||||
if (inputSignalsToTrigger[cIdx] == 0) triggerComponent(cIdx);
|
||||
} else {
|
||||
fprintf(stderr, "Input signals does not match with map: %d\n", sIdx);
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,15 +4,15 @@ const assert = chai.assert;
|
||||
const fs = require("fs");
|
||||
var tmp = require("tmp-promise");
|
||||
const path = require("path");
|
||||
const compiler = require("./compiler");
|
||||
const compiler = require("../../src/compiler");
|
||||
const util = require("util");
|
||||
const exec = util.promisify(require("child_process").exec);
|
||||
|
||||
const stringifyBigInts = require("./utils").stringifyBigInts;
|
||||
const unstringifyBigInts = require("./utils").unstringifyBigInts;
|
||||
const stringifyBigInts = require("../../src/utils").stringifyBigInts;
|
||||
const unstringifyBigInts = require("../../src/utils").unstringifyBigInts;
|
||||
const bigInt = require("big-integer");
|
||||
const utils = require("./utils");
|
||||
const loadR1cs = require("./r1csfile").loadR1cs;
|
||||
const utils = require("../../src/utils");
|
||||
const loadR1cs = require("../../src/r1csfile").loadR1cs;
|
||||
const ZqField = require("fflib").ZqField;
|
||||
|
||||
module.exports = c_tester;
|
||||
748
ports/wasm/build_runtime.js
Normal file
748
ports/wasm/build_runtime.js
Normal file
@@ -0,0 +1,748 @@
|
||||
const errs = require("./errs");
|
||||
|
||||
|
||||
const buildWasmFf = require("fflib").buildWasmFf;
|
||||
|
||||
|
||||
module.exports = function buildRuntime(module, builder) {
|
||||
|
||||
function buildInit() {
|
||||
const f = module.addFunction("init");
|
||||
f.addLocal("i", "i32");
|
||||
|
||||
const c = f.getCodeBuilder();
|
||||
|
||||
// Set the stack to current memory
|
||||
f.addCode(
|
||||
c.i32_store(
|
||||
c.i32_const(4),
|
||||
c.i32_shl(
|
||||
c.i32_and(
|
||||
c.current_memory(),
|
||||
c.i32_const(0xFFFFFFF8)
|
||||
),
|
||||
c.i32_const(16)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
f.addCode(
|
||||
// i=0
|
||||
c.setLocal("i", c.i32_const(0)),
|
||||
c.block(c.loop(
|
||||
// if (i==NComponents) break
|
||||
c.br_if(1, c.i32_eq(c.getLocal("i"), c.i32_const(builder.header.NComponents))),
|
||||
|
||||
// inputSignalsToTrigger[i] = components[i].nInputSignals
|
||||
c.i32_store(
|
||||
c.i32_add(
|
||||
c.i32_const(builder.pInputSignalsToTrigger),
|
||||
c.i32_mul(
|
||||
c.getLocal("i"),
|
||||
c.i32_const(4)
|
||||
)
|
||||
),
|
||||
c.i32_load(
|
||||
c.i32_add(
|
||||
c.i32_load(c.i32_const(builder.ppComponents)),
|
||||
c.i32_mul(
|
||||
c.getLocal("i"),
|
||||
c.i32_const(builder.sizeofComponent) // Sizeof component
|
||||
)
|
||||
),
|
||||
builder.offsetComponentNInputSignals
|
||||
)
|
||||
),
|
||||
|
||||
// i=i+1
|
||||
c.setLocal(
|
||||
"i",
|
||||
c.i32_add(
|
||||
c.getLocal("i"),
|
||||
c.i32_const(1)
|
||||
)
|
||||
),
|
||||
c.br(0)
|
||||
))
|
||||
);
|
||||
|
||||
if (builder.sanityCheck) {
|
||||
f.addCode(
|
||||
// i=0
|
||||
c.setLocal("i", c.i32_const(0)),
|
||||
c.block(c.loop(
|
||||
// if (i==NSignals) break
|
||||
c.br_if(1, c.i32_eq(c.getLocal("i"), c.i32_const(builder.header.NSignals))),
|
||||
|
||||
// signalsAssigned[i] = false
|
||||
c.i32_store(
|
||||
c.i32_add(
|
||||
c.i32_const(builder.pSignalsAssigned),
|
||||
c.i32_mul(
|
||||
c.getLocal("i"),
|
||||
c.i32_const(4)
|
||||
)
|
||||
),
|
||||
c.i32_const(0)
|
||||
),
|
||||
|
||||
// i=i+1
|
||||
c.setLocal(
|
||||
"i",
|
||||
c.i32_add(
|
||||
c.getLocal("i"),
|
||||
c.i32_const(1)
|
||||
)
|
||||
),
|
||||
c.br(0)
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
f.addCode(
|
||||
c.call(
|
||||
"Fr_copy",
|
||||
c.i32_const(builder.pSignals),
|
||||
c.i32_add(
|
||||
c.i32_load(c.i32_const(builder.ppConstants)),
|
||||
c.i32_const(builder.addConstant(1) * builder.sizeFr)
|
||||
)
|
||||
)
|
||||
);
|
||||
if (builder.sanityCheck) {
|
||||
f.addCode(
|
||||
c.i32_store(
|
||||
c.i32_const(builder.pSignalsAssigned),
|
||||
c.i32_const(1)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
f.addCode(
|
||||
// i=0
|
||||
c.setLocal("i", c.i32_const(0)),
|
||||
c.block(c.loop(
|
||||
// if (i==NComponents) break
|
||||
c.br_if(1, c.i32_eq(c.getLocal("i"), c.i32_const(builder.header.NComponents))),
|
||||
|
||||
// if (inputSignalsToTrigger[i] == 0) triggerComponent(i)
|
||||
c.if(
|
||||
c.i32_eqz(
|
||||
c.i32_load(
|
||||
c.i32_add(
|
||||
c.i32_const(builder.pInputSignalsToTrigger),
|
||||
c.i32_mul(
|
||||
c.getLocal("i"),
|
||||
c.i32_const(4)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
c.call(
|
||||
"triggerComponent",
|
||||
c.getLocal("i")
|
||||
)
|
||||
),
|
||||
|
||||
// i=i+1
|
||||
c.setLocal(
|
||||
"i",
|
||||
c.i32_add(
|
||||
c.getLocal("i"),
|
||||
c.i32_const(1)
|
||||
)
|
||||
),
|
||||
c.br(0)
|
||||
))
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function buildTriggerComponent() {
|
||||
const f = module.addFunction("triggerComponent");
|
||||
f.addParam("component", "i32");
|
||||
|
||||
const c = f.getCodeBuilder();
|
||||
|
||||
f.addCode(
|
||||
c.call_indirect(
|
||||
c.getLocal("component"), // Idx in table
|
||||
c.getLocal("component") // Parameter
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function buildHash2ComponentEntry() {
|
||||
const f = module.addFunction("hash2ComponentEntry");
|
||||
f.addParam("component", "i32");
|
||||
f.addParam("hash", "i64");
|
||||
f.setReturnType("i32");
|
||||
|
||||
f.addLocal("pComponent", "i32");
|
||||
f.addLocal("pHashTable", "i32");
|
||||
f.addLocal("hIdx", "i32");
|
||||
f.addLocal("h", "i64");
|
||||
|
||||
const c = f.getCodeBuilder();
|
||||
|
||||
f.addCode(
|
||||
c.setLocal(
|
||||
"pComponent",
|
||||
c.i32_add(
|
||||
c.i32_load(c.i32_const(builder.ppComponents)), // pComponents
|
||||
c.i32_mul(
|
||||
c.getLocal("component"),
|
||||
c.i32_const(20) // sizeof(Component)
|
||||
)
|
||||
)
|
||||
),
|
||||
c.setLocal(
|
||||
"pHashTable",
|
||||
c.i32_load(c.getLocal("pComponent"))
|
||||
),
|
||||
c.setLocal(
|
||||
"hIdx",
|
||||
c.i32_and(
|
||||
c.i32_wrap_i64(c.getLocal("hash")),
|
||||
c.i32_const(0xFF)
|
||||
)
|
||||
),
|
||||
c.block(c.loop(
|
||||
c.setLocal(
|
||||
"h",
|
||||
c.i64_load(
|
||||
c.i32_add(
|
||||
c.getLocal("pHashTable"),
|
||||
c.i32_mul(
|
||||
c.getLocal("hIdx"),
|
||||
c.i32_const(12)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
c.br_if(1, c.i64_eq(c.getLocal("h"), c.getLocal("hash"))),
|
||||
c.if(
|
||||
c.i64_eqz(c.getLocal("h")),
|
||||
c.call(
|
||||
"err",
|
||||
c.i32_const(errs.HASH_NOT_FOUND.code),
|
||||
c.i32_const(errs.HASH_NOT_FOUND.pointer)
|
||||
)
|
||||
),
|
||||
c.setLocal(
|
||||
"hIdx",
|
||||
c.i32_and(
|
||||
c.i32_add(
|
||||
c.getLocal("hIdx"),
|
||||
c.i32_const(1)
|
||||
),
|
||||
c.i32_const(0xFF)
|
||||
)
|
||||
),
|
||||
c.br(0)
|
||||
)),
|
||||
|
||||
c.i32_add( // pComponentEntry
|
||||
c.i32_load( // pComponentEntryTable
|
||||
c.i32_add(
|
||||
c.getLocal("pComponent"),
|
||||
c.i32_const(4)
|
||||
)
|
||||
),
|
||||
c.i32_mul(
|
||||
c.i32_load( // idx to the componentEntry
|
||||
c.i32_add(
|
||||
c.getLocal("pHashTable"),
|
||||
c.i32_mul(
|
||||
c.getLocal("hIdx"),
|
||||
c.i32_const(12)
|
||||
)
|
||||
),
|
||||
8
|
||||
),
|
||||
c.i32_const(12)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function buildGetFromComponentEntry(fnName, offset, type) {
|
||||
const f = module.addFunction(fnName);
|
||||
f.addParam("pR", "i32");
|
||||
f.addParam("component", "i32");
|
||||
f.addParam("hash", "i64");
|
||||
f.addLocal("pComponentEntry", "i32");
|
||||
|
||||
const c = f.getCodeBuilder();
|
||||
|
||||
f.addCode(
|
||||
c.setLocal(
|
||||
"pComponentEntry",
|
||||
c.call(
|
||||
"hash2ComponentEntry",
|
||||
c.getLocal("component"),
|
||||
c.getLocal("hash")
|
||||
)
|
||||
),
|
||||
c.if( // If type is not signal
|
||||
c.i32_ne(
|
||||
c.i32_load(
|
||||
c.getLocal("pComponentEntry"),
|
||||
8 // type offset
|
||||
),
|
||||
c.i32_const(type)
|
||||
),
|
||||
c.call(
|
||||
"err",
|
||||
c.i32_const(errs.INVALID_TYPE.code),
|
||||
c.i32_const(errs.INVALID_TYPE.pointer)
|
||||
)
|
||||
),
|
||||
c.i32_store(
|
||||
c.getLocal("pR"),
|
||||
c.i32_load(
|
||||
c.getLocal("pComponentEntry"),
|
||||
offset
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
const f2 = module.addFunction(fnName + "32");
|
||||
f2.addParam("pR", "i32");
|
||||
f2.addParam("component", "i32");
|
||||
f2.addParam("hashMSB", "i32");
|
||||
f2.addParam("hashLSB", "i32");
|
||||
|
||||
const c2 = f2.getCodeBuilder();
|
||||
|
||||
f2.addCode(
|
||||
c2.call(
|
||||
fnName,
|
||||
c2.getLocal("pR"),
|
||||
c2.getLocal("component"),
|
||||
c2.i64_or(
|
||||
c2.i64_shl(
|
||||
c2.i64_extend_i32_u(c2.getLocal("hashMSB")),
|
||||
c2.i64_const(32)
|
||||
),
|
||||
c2.i64_extend_i32_u(c2.getLocal("hashLSB"))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function buildGetSignal() {
|
||||
const f = module.addFunction("getSignal");
|
||||
f.addParam("cIdx", "i32");
|
||||
f.addParam("pR", "i32");
|
||||
f.addParam("component", "i32");
|
||||
f.addParam("signal", "i32");
|
||||
|
||||
const c = f.getCodeBuilder();
|
||||
|
||||
if (builder.sanityCheck) {
|
||||
f.addCode(
|
||||
c.if(
|
||||
c.i32_eqz(
|
||||
c.i32_load(
|
||||
c.i32_add(
|
||||
c.i32_const(builder.pSignalsAssigned),
|
||||
c.i32_mul(
|
||||
c.getLocal("signal"),
|
||||
c.i32_const(4)
|
||||
)
|
||||
),
|
||||
)
|
||||
),
|
||||
c.call(
|
||||
"err",
|
||||
c.i32_const(errs.ACCESSING_NOT_ASSIGNED_SIGNAL.code),
|
||||
c.i32_const(errs.ACCESSING_NOT_ASSIGNED_SIGNAL.pointer)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
f.addCode(
|
||||
c.call(
|
||||
"Fr_copy",
|
||||
c.getLocal("pR"),
|
||||
c.i32_add(
|
||||
c.i32_const(builder.pSignals),
|
||||
c.i32_mul(
|
||||
c.getLocal("signal"),
|
||||
c.i32_const(builder.sizeFr)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function buildSetSignal() {
|
||||
const f = module.addFunction("setSignal");
|
||||
f.addParam("cIdx", "i32");
|
||||
f.addParam("component", "i32");
|
||||
f.addParam("signal", "i32");
|
||||
f.addParam("pVal", "i32");
|
||||
f.addLocal("signalsToTrigger", "i32");
|
||||
|
||||
const c = f.getCodeBuilder();
|
||||
|
||||
|
||||
if (builder.sanityCheck) {
|
||||
f.addCode(
|
||||
c.if(
|
||||
c.i32_load(
|
||||
c.i32_add(
|
||||
c.i32_const(builder.pSignalsAssigned),
|
||||
c.i32_mul(
|
||||
c.getLocal("signal"),
|
||||
c.i32_const(4)
|
||||
)
|
||||
),
|
||||
),
|
||||
c.call(
|
||||
"err",
|
||||
c.i32_const(errs.SIGNAL_ASSIGNED_TWICE.code),
|
||||
c.i32_const(errs.SIGNAL_ASSIGNED_TWICE.pointer)
|
||||
)
|
||||
),
|
||||
c.i32_store(
|
||||
c.i32_add(
|
||||
c.i32_const(builder.pSignalsAssigned),
|
||||
c.i32_mul(
|
||||
c.getLocal("signal"),
|
||||
c.i32_const(4)
|
||||
)
|
||||
),
|
||||
c.i32_const(1)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
f.addCode(
|
||||
c.call(
|
||||
"Fr_copy",
|
||||
c.i32_add(
|
||||
c.i32_const(builder.pSignals),
|
||||
c.i32_mul(
|
||||
c.getLocal("signal"),
|
||||
c.i32_const(builder.sizeFr)
|
||||
)
|
||||
),
|
||||
c.getLocal("pVal"),
|
||||
)
|
||||
);
|
||||
|
||||
f.addCode(
|
||||
c.if( // If ( mapIsInput[s >> 5] & 1 << (s & 0x1f) )
|
||||
c.i32_and(
|
||||
c.i32_load(
|
||||
c.i32_add(
|
||||
c.i32_load(c.i32_const(builder.ppMapIsInput)),
|
||||
c.i32_shl(
|
||||
c.i32_shr_u(
|
||||
c.getLocal("signal"),
|
||||
c.i32_const(5)
|
||||
),
|
||||
c.i32_const(2)
|
||||
)
|
||||
)
|
||||
),
|
||||
c.i32_shl(
|
||||
c.i32_const(1),
|
||||
c.i32_and(
|
||||
c.getLocal("signal"),
|
||||
c.i32_const(0x1F)
|
||||
)
|
||||
)
|
||||
),
|
||||
[
|
||||
|
||||
...c.setLocal(
|
||||
"signalsToTrigger",
|
||||
c.i32_load(
|
||||
c.i32_add(
|
||||
c.i32_const(builder.pInputSignalsToTrigger),
|
||||
c.i32_mul(
|
||||
c.getLocal("component"),
|
||||
c.i32_const(4)
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
...c.if( // if (signalsToTrigger > 0)
|
||||
c.i32_gt_u(
|
||||
c.getLocal("signalsToTrigger"),
|
||||
c.i32_const(0)
|
||||
),
|
||||
[
|
||||
...c.setLocal( // signalsToTrigger--
|
||||
"signalsToTrigger",
|
||||
c.i32_sub(
|
||||
c.getLocal("signalsToTrigger"),
|
||||
c.i32_const(1)
|
||||
)
|
||||
),
|
||||
...c.i32_store(
|
||||
c.i32_add(
|
||||
c.i32_const(builder.pInputSignalsToTrigger),
|
||||
c.i32_mul(
|
||||
c.getLocal("component"),
|
||||
c.i32_const(4)
|
||||
)
|
||||
),
|
||||
c.getLocal("signalsToTrigger"),
|
||||
),
|
||||
...c.if( // if (signalsToTrigger==0) triggerCompomnent(component)
|
||||
c.i32_eqz(c.getLocal("signalsToTrigger")),
|
||||
c.call(
|
||||
"triggerComponent",
|
||||
c.getLocal("component")
|
||||
)
|
||||
)
|
||||
],
|
||||
c.call(
|
||||
"err2",
|
||||
c.i32_const(errs.MAPISINPUT_DONT_MATCH.code),
|
||||
c.i32_const(errs.MAPISINPUT_DONT_MATCH.pointer),
|
||||
c.getLocal("component"),
|
||||
c.getLocal("signal")
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function buildComponentFinished() {
|
||||
const f = module.addFunction("componentFinished");
|
||||
f.addParam("cIdx", "i32");
|
||||
|
||||
const c = f.getCodeBuilder();
|
||||
|
||||
f.addCode(c.ret([]));
|
||||
}
|
||||
|
||||
function buildCheckConstraint() {
|
||||
const pTmp = module.alloc(builder.sizeFr);
|
||||
const f = module.addFunction("checkConstraint");
|
||||
f.addParam("cIdx", "i32");
|
||||
f.addParam("pA", "i32");
|
||||
f.addParam("pB", "i32");
|
||||
f.addParam("pStr", "i32");
|
||||
|
||||
const c = f.getCodeBuilder();
|
||||
|
||||
if (builder.sanityCheck) {
|
||||
f.addCode(
|
||||
c.call(
|
||||
"Fr_eq",
|
||||
c.getLocal(c.i32_const(pTmp)),
|
||||
c.getLocal("pA"),
|
||||
c.getLocal("pB")
|
||||
),
|
||||
c.if (
|
||||
c.eqz(
|
||||
c.call(
|
||||
"Fr_isTrue",
|
||||
c.getLocal(c.i32_const(pTmp)),
|
||||
)
|
||||
),
|
||||
c.call(
|
||||
"err4",
|
||||
c.i32_const(errs.CONSTRAIN_DOES_NOT_MATCH.code),
|
||||
c.i32_const(errs.CONSTRAIN_DOES_NOT_MATCH.pointer),
|
||||
c.getLocal("cIdx"),
|
||||
c.getLocal("pA"),
|
||||
c.getLocal("pB"),
|
||||
c.getLocal("pStr"),
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function buildGetNVars() {
|
||||
const f = module.addFunction("getNVars");
|
||||
f.setReturnType("i32");
|
||||
|
||||
const c = f.getCodeBuilder();
|
||||
|
||||
f.addCode(c.i32_const(builder.header.NVars));
|
||||
}
|
||||
|
||||
function buildGetFrLen() {
|
||||
const f = module.addFunction("getFrLen");
|
||||
f.setReturnType("i32");
|
||||
|
||||
const c = f.getCodeBuilder();
|
||||
|
||||
f.addCode(
|
||||
c.i32_const(builder.sizeFr));
|
||||
}
|
||||
|
||||
function buildGetPRawPrime() {
|
||||
const f = module.addFunction("getPRawPrime");
|
||||
f.setReturnType("i32");
|
||||
|
||||
const c = f.getCodeBuilder();
|
||||
|
||||
f.addCode(
|
||||
c.i32_const(module.modules["Fr_F1m"].pq));
|
||||
}
|
||||
|
||||
function buildGetPWitness() {
|
||||
const f = module.addFunction("getPWitness");
|
||||
f.addParam("w", "i32");
|
||||
f.addLocal("signal", "i32");
|
||||
f.setReturnType("i32");
|
||||
|
||||
const c = f.getCodeBuilder();
|
||||
|
||||
|
||||
f.addCode(
|
||||
c.setLocal(
|
||||
"signal",
|
||||
c.i32_load( // wit2sig[w]
|
||||
c.i32_add(
|
||||
c.i32_load( c.i32_const(builder.ppWit2sig)),
|
||||
c.i32_mul(
|
||||
c.getLocal("w"),
|
||||
c.i32_const(4)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if (builder.sanityCheck) {
|
||||
f.addCode(
|
||||
c.if(
|
||||
c.i32_eqz(
|
||||
c.i32_load(
|
||||
c.i32_add(
|
||||
c.i32_const(builder.pSignalsAssigned),
|
||||
c.i32_mul(
|
||||
c.getLocal("signal"),
|
||||
c.i32_const(4)
|
||||
)
|
||||
),
|
||||
)
|
||||
),
|
||||
c.call(
|
||||
"err",
|
||||
c.i32_const(errs.ACCESSING_NOT_ASSIGNED_SIGNAL.code),
|
||||
c.i32_const(errs.ACCESSING_NOT_ASSIGNED_SIGNAL.pointer)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
f.addCode(
|
||||
c.i32_add(
|
||||
c.i32_const(builder.pSignals),
|
||||
|
||||
c.i32_mul(
|
||||
c.getLocal("signal"),
|
||||
c.i32_const(builder.sizeFr)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function buildFrToInt() {
|
||||
const f = module.addFunction("Fr_toInt");
|
||||
f.addParam("p", "i32");
|
||||
f.setReturnType("i32");
|
||||
|
||||
const c = f.getCodeBuilder();
|
||||
|
||||
f.addCode(
|
||||
c.i32_load(c.getLocal("p"))
|
||||
);
|
||||
|
||||
// TODO Handle long and montgomery.
|
||||
}
|
||||
|
||||
|
||||
const fErr = module.addIimportFunction("err", "runtime");
|
||||
fErr.addParam("code", "i32");
|
||||
fErr.addParam("pStr", "i32");
|
||||
|
||||
const fErr1 = module.addIimportFunction("err1", "runtime");
|
||||
fErr1.addParam("code", "i32");
|
||||
fErr1.addParam("pStr", "i32");
|
||||
fErr1.addParam("param1", "i32");
|
||||
|
||||
const fErr2 = module.addIimportFunction("err2", "runtime");
|
||||
fErr2.addParam("code", "i32");
|
||||
fErr2.addParam("pStr", "i32");
|
||||
fErr2.addParam("param1", "i32");
|
||||
fErr2.addParam("param2", "i32");
|
||||
|
||||
const fErr3 = module.addIimportFunction("err3", "runtime");
|
||||
fErr3.addParam("code", "i32");
|
||||
fErr3.addParam("pStr", "i32");
|
||||
fErr3.addParam("param1", "i32");
|
||||
fErr3.addParam("param2", "i32");
|
||||
fErr3.addParam("param3", "i32");
|
||||
|
||||
const fErr4 = module.addIimportFunction("err4", "runtime");
|
||||
fErr4.addParam("code", "i32");
|
||||
fErr4.addParam("pStr", "i32");
|
||||
fErr4.addParam("param1", "i32");
|
||||
fErr4.addParam("param2", "i32");
|
||||
fErr4.addParam("param3", "i32");
|
||||
fErr4.addParam("param4", "i32");
|
||||
|
||||
buildWasmFf(module, "Fr", builder.header.P);
|
||||
|
||||
builder.pSignals=module.alloc(builder.header.NSignals*builder.sizeFr);
|
||||
builder.pInputSignalsToTrigger=module.alloc(builder.header.NComponents*4);
|
||||
if (builder.sanityCheck) {
|
||||
builder.pSignalsAssigned=module.alloc(builder.header.NSignals*4);
|
||||
}
|
||||
|
||||
buildHash2ComponentEntry();
|
||||
|
||||
buildTriggerComponent();
|
||||
buildInit();
|
||||
|
||||
buildGetFromComponentEntry("getSubComponentOffset", 0 /* offset */, builder.TYPE_COMPONENT);
|
||||
buildGetFromComponentEntry("getSubComponentSizes", 4 /* offset */, builder.TYPE_COMPONENT);
|
||||
|
||||
buildGetFromComponentEntry("getSignalOffset", 0 /* offset */, builder.TYPE_SIGNAL);
|
||||
buildGetFromComponentEntry("getSignalSizes", 4 /* offset */, builder.TYPE_SIGNAL);
|
||||
|
||||
buildGetSignal();
|
||||
buildSetSignal();
|
||||
|
||||
buildComponentFinished();
|
||||
|
||||
buildCheckConstraint();
|
||||
|
||||
buildGetNVars();
|
||||
buildGetFrLen();
|
||||
buildGetPWitness();
|
||||
buildGetPRawPrime();
|
||||
|
||||
buildFrToInt();
|
||||
|
||||
module.exportFunction("init");
|
||||
module.exportFunction("getNVars");
|
||||
module.exportFunction("getFrLen");
|
||||
module.exportFunction("getSignalOffset32");
|
||||
module.exportFunction("setSignal");
|
||||
module.exportFunction("getPWitness");
|
||||
module.exportFunction("Fr_toInt");
|
||||
module.exportFunction("getPRawPrime");
|
||||
|
||||
};
|
||||
1003
ports/wasm/builder.js
Normal file
1003
ports/wasm/builder.js
Normal file
File diff suppressed because it is too large
Load Diff
10
ports/wasm/errs.js
Normal file
10
ports/wasm/errs.js
Normal file
@@ -0,0 +1,10 @@
|
||||
module.exports = {
|
||||
STACK_OUT_OF_MEM: {code: 1, str: "Stack out of memory"},
|
||||
STACK_TOO_SMALL: {code: 2, str: "Stack too small"},
|
||||
HASH_NOT_FOUND: {code: 3, str: "Hash not found"},
|
||||
INVALID_TYPE: {code: 4, str: "Invalid type"},
|
||||
ACCESSING_NOT_ASSIGNED_SIGNAL: {code: 5, str: "Accessing a not assigned signal"},
|
||||
SIGNAL_ASSIGNED_TWICE: {code: 6, str: "Signal assigned twice"},
|
||||
CONSTRAIN_DOES_NOT_MATCH: {code: 7, str: "Constraint doesn't match"},
|
||||
MAPISINPUT_DONT_MATCH: {code: 8, str: "MapIsInput don't match"},
|
||||
};
|
||||
167
ports/wasm/tester.js
Normal file
167
ports/wasm/tester.js
Normal file
@@ -0,0 +1,167 @@
|
||||
const chai = require("chai");
|
||||
const assert = chai.assert;
|
||||
|
||||
const fs = require("fs");
|
||||
var tmp = require("tmp-promise");
|
||||
const path = require("path");
|
||||
const compiler = require("../../src/compiler");
|
||||
const util = require("util");
|
||||
const exec = util.promisify(require("child_process").exec);
|
||||
|
||||
const stringifyBigInts = require("../../src/utils").stringifyBigInts;
|
||||
const unstringifyBigInts = require("../../src/utils").unstringifyBigInts;
|
||||
const bigInt = require("big-integer");
|
||||
const utils = require("../../src/utils");
|
||||
const loadR1cs = require("../../src/r1csfile").loadR1cs;
|
||||
const ZqField = require("fflib").ZqField;
|
||||
|
||||
const WitnessCalculator = require("./witness_calculator");
|
||||
|
||||
module.exports = wasm_tester;
|
||||
|
||||
|
||||
async function wasm_tester(circomFile, _options) {
|
||||
tmp.setGracefulCleanup();
|
||||
|
||||
const dir = await tmp.dir({prefix: "circom_", unsafeCleanup: true });
|
||||
|
||||
// console.log(dir.path);
|
||||
|
||||
const baseName = path.basename(circomFile, ".circom");
|
||||
const options = Object.assign({}, _options);
|
||||
|
||||
options.wasmWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".wasm"));
|
||||
options.symWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".sym"));
|
||||
options.r1csFileName = path.join(dir.path, baseName + ".r1cs");
|
||||
|
||||
const promisesArr = [];
|
||||
promisesArr.push(new Promise(fulfill => options.wasmWriteStream.on("finish", fulfill)));
|
||||
|
||||
await compiler(circomFile, options);
|
||||
|
||||
await Promise.all(promisesArr);
|
||||
|
||||
const wc = await WitnessCalculator.fromFile(path.join(dir.path, baseName + ".wasm"));
|
||||
|
||||
return new WasmTester(dir, baseName, wc);
|
||||
}
|
||||
|
||||
class WasmTester {
|
||||
|
||||
constructor(dir, baseName, witnessCalculator) {
|
||||
this.dir=dir;
|
||||
this.baseName = baseName;
|
||||
this.witnessCalculator = witnessCalculator;
|
||||
}
|
||||
|
||||
async release() {
|
||||
await this.dir.cleanup();
|
||||
}
|
||||
|
||||
async calculateWitness(input) {
|
||||
|
||||
return await this.witnessCalculator.calculateWitness(input);
|
||||
}
|
||||
|
||||
async loadSymbols() {
|
||||
if (this.symbols) return;
|
||||
this.symbols = {};
|
||||
const symsStr = await fs.promises.readFile(
|
||||
path.join(this.dir.path, this.baseName + ".sym"),
|
||||
"utf8"
|
||||
);
|
||||
const lines = symsStr.split("\n");
|
||||
for (let i=0; i<lines.length; i++) {
|
||||
const arr = lines[i].split(",");
|
||||
if (arr.length!=3) continue;
|
||||
this.symbols[arr[2]] = {
|
||||
idx: Number(arr[0]),
|
||||
idxWit: Number(arr[1])
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async loadConstraints() {
|
||||
const self = this;
|
||||
if (this.constraints) return;
|
||||
const r1cs = await loadR1cs(path.join(this.dir.path, this.baseName + ".r1cs"),true, false);
|
||||
self.field = new ZqField(r1cs.prime);
|
||||
self.nWires = r1cs.nWires;
|
||||
self.constraints = r1cs.constraints;
|
||||
}
|
||||
|
||||
async assertOut(actualOut, expectedOut) {
|
||||
const self = this;
|
||||
if (!self.symbols) await self.loadSymbols();
|
||||
|
||||
checkObject("main", expectedOut);
|
||||
|
||||
function checkObject(prefix, eOut) {
|
||||
|
||||
if (Array.isArray(eOut)) {
|
||||
for (let i=0; i<eOut.length; i++) {
|
||||
checkObject(prefix + "["+i+"]", eOut[i]);
|
||||
}
|
||||
} else if ((typeof eOut == "object")&&(eOut.constructor.name == "Object")) {
|
||||
for (let k in eOut) {
|
||||
checkObject(prefix + "."+k, eOut[k]);
|
||||
}
|
||||
} else {
|
||||
if (typeof self.symbols[prefix] == "undefined") {
|
||||
assert(false, "Output variable not defined: "+ prefix);
|
||||
}
|
||||
const ba = bigInt(actualOut[self.symbols[prefix].idxWit]).toString();
|
||||
const be = bigInt(eOut).toString();
|
||||
assert.strictEqual(ba, be, prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async getDecoratedOutput(witness) {
|
||||
const self = this;
|
||||
const lines = [];
|
||||
if (!self.symbols) await self.loadSymbols();
|
||||
for (let n in self.symbols) {
|
||||
let v;
|
||||
if (utils.isDefined(witness[self.symbols[n].idxWit])) {
|
||||
v = witness[self.symbols[n].idxWit].toString();
|
||||
} else {
|
||||
v = "undefined";
|
||||
}
|
||||
lines.push(`${n} --> ${v}`);
|
||||
}
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
async checkConstraints(witness) {
|
||||
const self = this;
|
||||
if (!self.constraints) await self.loadConstraints();
|
||||
for (let i=0; i<self.constraints.length; i++) {
|
||||
checkConstraint(self.constraints[i]);
|
||||
}
|
||||
|
||||
function checkConstraint(constraint) {
|
||||
const F = self.field;
|
||||
const a = evalLC(constraint.a);
|
||||
const b = evalLC(constraint.b);
|
||||
const c = evalLC(constraint.c);
|
||||
|
||||
assert (F.sub(F.mul(a,b), c).isZero(), "Constraint doesn't match");
|
||||
}
|
||||
|
||||
function evalLC(lc) {
|
||||
const F = self.field;
|
||||
let v = F.zero;
|
||||
for (let w in lc) {
|
||||
v = F.add(
|
||||
v,
|
||||
F.mul( lc[w], witness[w] )
|
||||
);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
186
ports/wasm/witness_calculator.js
Normal file
186
ports/wasm/witness_calculator.js
Normal file
@@ -0,0 +1,186 @@
|
||||
/* globals WebAssembly */
|
||||
|
||||
const fs = require("fs");
|
||||
const utils = require("../../src/utils");
|
||||
const bigInt = require("big-integer");
|
||||
|
||||
module.exports.fromFile = async function(file) {
|
||||
|
||||
|
||||
const code = await fs.promises.readFile(file);
|
||||
|
||||
return await module.exports.fromBuffer(code);
|
||||
};
|
||||
|
||||
module.exports.fromBuffer = async function(code) {
|
||||
|
||||
const memory = new WebAssembly.Memory({initial:20000});
|
||||
const wasmModule = await WebAssembly.compile(code);
|
||||
|
||||
const instance = await WebAssembly.instantiate(wasmModule, {
|
||||
env: {
|
||||
"memory": memory
|
||||
},
|
||||
runtime: {
|
||||
err: function(code, pstr) {
|
||||
console.log("ERROR", code, p2str(pstr));
|
||||
},
|
||||
err1: function(code, pstr, a) {
|
||||
console.log("ERROR: ", code, p2str(pstr), a);
|
||||
},
|
||||
err2: function(code, pstr, a, b) {
|
||||
console.log("ERROR: ", code, p2str(pstr), a, b);
|
||||
},
|
||||
err3: function(code, pstr, a, b, c) {
|
||||
console.log("ERROR: ", code, p2str(pstr), a, b, c);
|
||||
},
|
||||
err4: function(code, pstr, a,b,c,d) {
|
||||
console.log("ERROR: ", code, p2str(pstr), a, b, c, d);
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
return new WitnessCalculator(memory, instance);
|
||||
|
||||
function p2str(p) {
|
||||
return "TODO"+p;
|
||||
}
|
||||
};
|
||||
|
||||
class WitnessCalculator {
|
||||
constructor(memory, instance) {
|
||||
this.memory = memory;
|
||||
this.i32 = new Uint32Array(memory.buffer);
|
||||
this.instance = instance;
|
||||
|
||||
this.n32 = (this.instance.exports.getFrLen() >> 2) - 2;
|
||||
const pRawPrime = this.instance.exports.getPRawPrime();
|
||||
|
||||
this.prime = bigInt(0);
|
||||
for (let i=this.n32-1; i>=0; i--) {
|
||||
this.prime = this.prime.shiftLeft(32);
|
||||
this.prime = this.prime.add(bigInt(this.i32[(pRawPrime >> 2) + i]));
|
||||
}
|
||||
|
||||
this.mask32 = bigInt("FFFFFFFF", 16);
|
||||
this.NVars = this.instance.exports.getNVars();
|
||||
this.n64 = Math.floor((this.prime.bitLength() - 1) / 64)+1;
|
||||
this.R = bigInt.one.shiftLeft(this.n64*64);
|
||||
this.RInv = this.R.modInv(this.prime);
|
||||
|
||||
}
|
||||
|
||||
async calculateWitness(input) {
|
||||
const w = [];
|
||||
const old0 = this.i32[0];
|
||||
this.instance.exports.init();
|
||||
const pSigOffset = this.allocInt();
|
||||
const pFr = this.allocFr();
|
||||
for (let k in input) {
|
||||
const h = utils.fnvHash(k);
|
||||
const hMSB = parseInt(h.slice(0,8), 16);
|
||||
const hLSB = parseInt(h.slice(8,16), 16);
|
||||
this.instance.exports.getSignalOffset32(pSigOffset, 0, hMSB, hLSB);
|
||||
const sigOffset = this.getInt(pSigOffset);
|
||||
const fArr = utils.flatArray(input[k]);
|
||||
for (let i=0; i<fArr.length; i++) {
|
||||
this.setFr(pFr, fArr[i]);
|
||||
this.instance.exports.setSignal(0, 0, sigOffset + i, pFr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (let i=0; i<this.NVars; i++) {
|
||||
const pWitness = this.instance.exports.getPWitness(i);
|
||||
w.push(this.getFr(pWitness));
|
||||
}
|
||||
|
||||
this.i32[0] = old0;
|
||||
return w;
|
||||
}
|
||||
|
||||
allocInt() {
|
||||
const p = this.i32[0];
|
||||
this.i32[0] = p+8;
|
||||
return p;
|
||||
}
|
||||
|
||||
allocFr() {
|
||||
const p = this.i32[0];
|
||||
this.i32[0] = p+this.n32*4 + 8;
|
||||
return p;
|
||||
}
|
||||
|
||||
getInt(p) {
|
||||
return this.i32[p>>2];
|
||||
}
|
||||
|
||||
setInt(p, v) {
|
||||
this.i32[p>>2] = v;
|
||||
}
|
||||
|
||||
getFr(p) {
|
||||
const idx = (p>>2);
|
||||
|
||||
if (this.i32[idx + 1] & 0x80000000) {
|
||||
let res= bigInt(0);
|
||||
for (let i=this.n32-1; i>=0; i--) {
|
||||
res = res.shiftLeft(32);
|
||||
res = res.add(bigInt(this.i32[idx+2+i]));
|
||||
}
|
||||
if (this.i32[idx + 1] & 0x40000000) {
|
||||
return fromMontgomery(res);
|
||||
} else {
|
||||
return res;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (this.i32[idx] & 0x80000000) {
|
||||
return this.prime.add( bigInt(this.i32[idx]).minus(bigInt(0x100000000)) );
|
||||
} else {
|
||||
return bigInt(this.i32[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
function fromMontgomery(n) {
|
||||
return n.times(this.RInv).mod(this.prime);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
setFr(p, v) {
|
||||
const self = this;
|
||||
v = bigInt(v);
|
||||
|
||||
if (v.lt(bigInt("80000000", 16)) ) {
|
||||
return setShortPositive(v);
|
||||
}
|
||||
if (v.geq(self.prime.minus(bigInt("80000000", 16))) ) {
|
||||
return setShortNegative(v);
|
||||
}
|
||||
return setLongNormal(v);
|
||||
|
||||
function setShortPositive(a) {
|
||||
self.i32[(p >> 2)] = parseInt(a);
|
||||
self.i32[(p >> 2) + 1] = 0;
|
||||
}
|
||||
|
||||
function setShortNegative(a) {
|
||||
const b = bigInt("80000000", 16 ).add(a.minus( self.prime.minus(bigInt("80000000", 16 ))));
|
||||
self.i32[(p >> 2)] = parseInt(b);
|
||||
self.i32[(p >> 2) + 1] = 0;
|
||||
}
|
||||
|
||||
function setLongNormal(a) {
|
||||
self.i32[(p >> 2)] = 0;
|
||||
self.i32[(p >> 2) + 1] = 0x80000000;
|
||||
for (let i=0; i<self.n32; i++) {
|
||||
self.i32[(p >> 2) + 2 + i] = a.shiftRight(i*32).and(self.mask32);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
10
src/build.js
10
src/build.js
@@ -34,7 +34,6 @@ function build(ctx) {
|
||||
ctx.codes_sizes = [];
|
||||
ctx.definedSizes = {};
|
||||
ctx.addSizes = addSizes;
|
||||
ctx.constantsMap = {};
|
||||
ctx.addConstant = addConstant;
|
||||
ctx.addConstant(bigInt.zero);
|
||||
ctx.addConstant(bigInt.one);
|
||||
@@ -287,12 +286,7 @@ function addSizes(_sizes) {
|
||||
}
|
||||
|
||||
function addConstant(c) {
|
||||
c = bigInt(c);
|
||||
const s = c.toString();
|
||||
if (typeof (this.constantsMap[s]) !== "undefined") return this.constantsMap[s];
|
||||
const cIdx = this.builder.addConstant(c);
|
||||
this.constantsMap[s] = cIdx;
|
||||
return cIdx;
|
||||
return this.builder.addConstant(c);
|
||||
}
|
||||
|
||||
function buildFunction(name, paramValues) {
|
||||
@@ -320,7 +314,7 @@ function buildFunction(name, paramValues) {
|
||||
ctx.scopes = [{}];
|
||||
ctx.refs = [];
|
||||
ctx.conditionalCode = false;
|
||||
ctx.fnBuilder = ctx.builder.newFunctionBuilder(`${name}_${h}`, instanceDef);
|
||||
ctx.fnBuilder = ctx.builder.newFunctionBuilder(`${name}_${h}`, instanceDef, ctx.functions[name].params);
|
||||
ctx.codeBuilder = ctx.fnBuilder.newCodeBuilder();
|
||||
ctx.uniqueNames = Object.assign({},ctx.globalNames);
|
||||
ctx.returnValue = null;
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
class BuilderWasm {
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
||||
setHeader(header) {
|
||||
this.header=header;
|
||||
}
|
||||
|
||||
// ht is an array of 256 element that can be undefined or [Hash, Idx, KeyName] elements.
|
||||
addHashMap(name, ht) {
|
||||
this.hashTables[name] = ht;
|
||||
}
|
||||
|
||||
addComponentEntriesTable(name, cet) {
|
||||
this.componentEntriesTables[name] = cet;
|
||||
}
|
||||
|
||||
addSizes(name, accSizes) {
|
||||
this.sizes[name] = accSizes;
|
||||
}
|
||||
|
||||
build() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BuilderWasm;
|
||||
156
src/buildsyms.js
Normal file
156
src/buildsyms.js
Normal file
@@ -0,0 +1,156 @@
|
||||
const Readable = require("stream").Readable;
|
||||
|
||||
module.exports = function buildSyms(ctx) {
|
||||
const rs = Readable();
|
||||
|
||||
let it = new ComponentIt(ctx, 0, "main");
|
||||
|
||||
let counter = 0;
|
||||
|
||||
rs._read = function() {
|
||||
const actual = it.current();
|
||||
if (actual == null ) {
|
||||
rs.push(null);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let s=actual.offset;
|
||||
while (ctx.signals[s].e >= 0) s = ctx.signals[s].e;
|
||||
let wId = ctx.signals[s].id;
|
||||
if (typeof(wId) == "undefined") wId=-1;
|
||||
rs.push(`${actual.offset},${wId},${actual.name}\n`);
|
||||
|
||||
it.next();
|
||||
counter ++;
|
||||
if ((ctx.verbose)&&(counter%10000 == 0)) console.log("Symbols saved: "+counter);
|
||||
};
|
||||
|
||||
return rs;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class SignalIt {
|
||||
constructor (ctx, offset, prefix) {
|
||||
this.ctx = ctx;
|
||||
this.offset = offset;
|
||||
this.prefix = prefix;
|
||||
this.cur = 0;
|
||||
}
|
||||
|
||||
next() {
|
||||
this.cur = 1;
|
||||
|
||||
return this.current();
|
||||
}
|
||||
|
||||
current() {
|
||||
if (this.cur == 0) {
|
||||
return {offset: this.offset, name: this.prefix};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ArrayIt {
|
||||
constructor (ctx, type, sizes, offset, prefix) {
|
||||
if (sizes.length == 0) {
|
||||
if (type == "S") {
|
||||
return new SignalIt(ctx, offset, prefix);
|
||||
} else {
|
||||
return new ComponentIt(ctx, offset, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
this.ctx = ctx;
|
||||
this.type = type;
|
||||
this.sizes = sizes;
|
||||
this.offset = offset;
|
||||
this.prefix = prefix;
|
||||
|
||||
|
||||
|
||||
this.subIt = null;
|
||||
this.cur = 0;
|
||||
|
||||
this.subArrSize = 1;
|
||||
|
||||
for (let i=1; i<sizes.length; i++) {
|
||||
this.subArrSize *= sizes[i];
|
||||
}
|
||||
|
||||
this._loadSubIt();
|
||||
|
||||
|
||||
}
|
||||
|
||||
_loadSubIt() {
|
||||
if (this.cur < this.sizes[0]) {
|
||||
this.subIt = new ArrayIt(this.ctx, this.type, this.sizes.slice(1), this.offset + this.cur*this.subArrSize, this.prefix + "[" + this.cur + "]");
|
||||
}
|
||||
}
|
||||
|
||||
next() {
|
||||
if (this.subIt) {
|
||||
const res = this.subIt.next();
|
||||
if (res == null) {
|
||||
this.subIt = null;
|
||||
this.cur++;
|
||||
this._loadSubIt();
|
||||
}
|
||||
}
|
||||
|
||||
return this.current();
|
||||
|
||||
}
|
||||
|
||||
current() {
|
||||
if (this.subIt) {
|
||||
return this.subIt.current();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ComponentIt {
|
||||
constructor (ctx, idxComponent, prefix) {
|
||||
this.ctx = ctx;
|
||||
this.idxComponent = idxComponent;
|
||||
this.prefix = prefix;
|
||||
this.names = Object.keys(ctx.components[idxComponent].names.o);
|
||||
|
||||
this.subIt = null;
|
||||
this.cur = 0;
|
||||
this._loadSubIt();
|
||||
|
||||
}
|
||||
|
||||
_loadSubIt() {
|
||||
if (this.cur < this.names.length) {
|
||||
const entrie = this.ctx.components[this.idxComponent].names.o[this.names[this.cur]];
|
||||
this.subIt = new ArrayIt(this.ctx, entrie.type, entrie.sizes, entrie.offset, this.prefix + "." + this.names[this.cur]);
|
||||
}
|
||||
}
|
||||
|
||||
next() {
|
||||
if (this.subIt) {
|
||||
const res = this.subIt.next();
|
||||
if (res == null) {
|
||||
this.subIt = null;
|
||||
this.cur++;
|
||||
this._loadSubIt();
|
||||
}
|
||||
}
|
||||
|
||||
return this.current();
|
||||
}
|
||||
|
||||
current() {
|
||||
if (this.subIt) {
|
||||
return this.subIt.current();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
|
||||
const ModuleBuilder = require("wasmbuilder").ModuleBuilder;
|
||||
const gen = require("./gencode");
|
||||
|
||||
|
||||
module.exports = function buildWasm(ctx) {
|
||||
|
||||
const fDefined = {};
|
||||
|
||||
ctx.module = new ModuleBuilder();
|
||||
for (let f in ctx.functions) {
|
||||
ctx.f = ctx.module.addFunction(f);
|
||||
ctx.c = ctx.f.getCodeBuilder();
|
||||
|
||||
ctx.scope = {};
|
||||
for (let p in ctx.functions[f].params) {
|
||||
const param = ctx.functions[f].params[p];
|
||||
ctx.f.addParam(param.name, "i32");
|
||||
ctx.scope[param.name] = {
|
||||
type: "PARAM",
|
||||
sels: param.sels,
|
||||
getter: () => { return ctx.c.getLocal(param.name); },
|
||||
setter: (v) => { return ctx.c.setLocal(param.name, v); }
|
||||
};
|
||||
}
|
||||
|
||||
gen(ctx, ctx.functions[f].block);
|
||||
}
|
||||
|
||||
for (let i=0; i<ctx.components.length; i++) {
|
||||
const h = hashComponentCall(ctx, i);
|
||||
const fName = ctx.components[i].temlate+"_"+h;
|
||||
if (!fDefined[fName]) {
|
||||
|
||||
ctx.f = ctx.module.addFunction(fName);
|
||||
ctx.c = ctx.f.getCodeBuilder();
|
||||
|
||||
ctx.scope = {};
|
||||
for (let p in ctx.components[i].params) {
|
||||
ctx.scope[p] = createConstant(ctx, ctx.components[i].params[p]);
|
||||
}
|
||||
|
||||
gen(ctx, ctx.templates[ctx.components[i].temlate].block);
|
||||
}
|
||||
ctx.components[i].f = fName;
|
||||
}
|
||||
};
|
||||
|
||||
function buildSetSignal(ctx) {
|
||||
|
||||
|
||||
}
|
||||
@@ -21,14 +21,15 @@ const bigInt = require("big-integer");
|
||||
const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
const sONE = 0;
|
||||
const build = require("./build");
|
||||
const BuilderC = require("./builder_c");
|
||||
const BuilderWasm = require("./builder_wasm");
|
||||
const BuilderC = require("../ports/c/builder.js");
|
||||
const BuilderWasm = require("../ports/wasm/builder.js");
|
||||
const constructionPhase = require("./construction_phase");
|
||||
const Ctx = require("./ctx");
|
||||
const ZqField = require("fflib").ZqField;
|
||||
const utils = require("./utils");
|
||||
const buildR1cs = require("./r1csfile").buildR1cs;
|
||||
const BigArray = require("./bigarray");
|
||||
const buildSyms = require("./buildsyms");
|
||||
|
||||
module.exports = compile;
|
||||
|
||||
@@ -92,11 +93,17 @@ async function compile(srcFile, options) {
|
||||
// await new Promise(fulfill => options.cSourceWriteStream.on("finish", fulfill));
|
||||
}
|
||||
|
||||
if (options.wasmWriteStream) {
|
||||
if ((options.wasmWriteStream)||(options.watWriteStream)) {
|
||||
ctx.builder = new BuilderWasm();
|
||||
build(ctx);
|
||||
const rdStream = ctx.builder.build();
|
||||
rdStream.pipe(options.wasmWriteStream);
|
||||
if (options.wasmWriteStream) {
|
||||
const rdStream = ctx.builder.build("wasm");
|
||||
rdStream.pipe(options.wasmWriteStream);
|
||||
}
|
||||
if (options.watWriteStream) {
|
||||
const rdStream = ctx.builder.build("wat");
|
||||
rdStream.pipe(options.watWriteStream);
|
||||
}
|
||||
|
||||
// await new Promise(fulfill => options.wasmWriteStream.on("finish", fulfill));
|
||||
}
|
||||
@@ -109,7 +116,10 @@ async function compile(srcFile, options) {
|
||||
}
|
||||
|
||||
if (options.symWriteStream) {
|
||||
buildSyms(ctx, options.symWriteStream);
|
||||
const rdStream = buildSyms(ctx);
|
||||
rdStream.pipe(options.symWriteStream);
|
||||
|
||||
// await new Promise(fulfill => options.symWriteStream.on("finish", fulfill));
|
||||
}
|
||||
|
||||
// const def = buildCircuitDef(ctx, mainCode);
|
||||
@@ -504,6 +514,8 @@ function buildConstraints(ctx) {
|
||||
return res;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
function buildSyms(ctx, strm) {
|
||||
|
||||
let nSyms;
|
||||
@@ -543,5 +555,5 @@ function buildSyms(ctx, strm) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@@ -754,7 +754,13 @@ function toRefA_Int1(ctx, ast, aRef) {
|
||||
const a = ctx.refs[aRef];
|
||||
if (a.sizes[0] != 1) return ctx.throwError(ast, "Expected only one element");
|
||||
if (a.used) {
|
||||
return ["R", a.label];
|
||||
if (a.type == "INT") {
|
||||
return ["RI", a.label];
|
||||
} else if (a.type == "BIGINT") {
|
||||
return ["R", a.label];
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
} else {
|
||||
return ["V", a.value[0]];
|
||||
}
|
||||
@@ -818,9 +824,7 @@ function genArray(ctx, ast) {
|
||||
function genFunctionCall(ctx, ast) {
|
||||
if (ast.name == "log") {
|
||||
const vRef = gen(ctx, ast.params[0]);
|
||||
const val = ctx.refs[vRef];
|
||||
instantiateRef(ctx, vRef, val.value);
|
||||
ctx.code+=`ctx->log(${val.label});`;
|
||||
ctx.codeBuilder.log(toRefA_Fr1(ctx, ast.params[0], vRef));
|
||||
return vRef;
|
||||
}
|
||||
const params = [];
|
||||
|
||||
@@ -235,7 +235,7 @@ async function buildR1cs(ctx, fileName) {
|
||||
}
|
||||
for (let i=0; i<arr.length; i++) {
|
||||
await writeU32(arr[i]);
|
||||
if ((ctx.verbose)&&(i%100000)) console.log("writing label2wire map: ", i);
|
||||
if ((ctx.verbose)&&(i%100000)) console.log("writing wire2label map: ", i);
|
||||
}
|
||||
|
||||
const mapSize = p - pMapSize -4;
|
||||
|
||||
21
src/streamfromarray_bin.js
Normal file
21
src/streamfromarray_bin.js
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
const Readable = require("stream").Readable;
|
||||
|
||||
module.exports = function streamFromArrayBin(a) {
|
||||
const rs = Readable();
|
||||
|
||||
let curIndex = 0;
|
||||
|
||||
rs._read = function(size) {
|
||||
if (curIndex >= a.length) {
|
||||
rs.push(null);
|
||||
return;
|
||||
}
|
||||
const start = curIndex;
|
||||
const end = Math.min(a.length, curIndex+size);
|
||||
curIndex = end;
|
||||
rs.push(a.slice(start, end));
|
||||
};
|
||||
|
||||
return rs;
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
const Readable = require("stream").Readable;
|
||||
|
||||
module.exports = function streamFromMultiarray(ma) {
|
||||
module.exports = function streamFromArrayTxt(ma) {
|
||||
const rs = Readable();
|
||||
|
||||
let curIndex = getFirstIdx(ma);
|
||||
@@ -10,7 +10,7 @@ module.exports = function streamFromMultiarray(ma) {
|
||||
let res;
|
||||
res = objFromIdx(ma, curIndex);
|
||||
curIndex = nextIdx(curIndex);
|
||||
if (res!=null) {
|
||||
if (res!==null) {
|
||||
rs.push(res + "\n");
|
||||
} else {
|
||||
rs.push(null);
|
||||
@@ -2,9 +2,11 @@ const path = require("path");
|
||||
|
||||
const bigInt = require("big-integer");
|
||||
const c_tester = require("../index.js").c_tester;
|
||||
const wasm_tester = require("../index.js").wasm_tester;
|
||||
|
||||
const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
|
||||
const basicCases = require("./basiccases.json");
|
||||
|
||||
function normalize(o) {
|
||||
if ((typeof(o) == "bigint") || o.isZero !== undefined) {
|
||||
@@ -31,11 +33,14 @@ function normalize(o) {
|
||||
}
|
||||
|
||||
|
||||
async function doTest(circuit, testVectors) {
|
||||
const cir = await c_tester(path.join(__dirname, "circuits", circuit));
|
||||
async function doTest(tester, circuit, testVectors) {
|
||||
const cir = await tester(path.join(__dirname, "circuits", circuit));
|
||||
|
||||
for (let i=0; i<testVectors.length; i++) {
|
||||
const w = await cir.calculateWitness(normalize(testVectors[i][0]));
|
||||
// console.log(testVectors[i][0]);
|
||||
// console.log(w);
|
||||
// console.log(testVectors[i][1]);
|
||||
await cir.assertOut(w, normalize(testVectors[i][1]) );
|
||||
}
|
||||
|
||||
@@ -44,300 +49,18 @@ async function doTest(circuit, testVectors) {
|
||||
|
||||
describe("basic cases", function () {
|
||||
this.timeout(100000);
|
||||
/*
|
||||
for (let i=0; i<basicCases.length; i++) {
|
||||
it("c/c++ " + basicCases[i].name, async () => {
|
||||
await doTest(c_tester, basicCases[i].circuit, basicCases[i].tv);
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
it("inout", async () => {
|
||||
await doTest(
|
||||
"inout.circom",
|
||||
[
|
||||
[{in1: 1, in2: [2,3], in3:[[4,5], [6,7], [8,9]]}, {out1: 1, out2: [2,3], out3: [[4,5], [6,7],[8,9]]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("add", async () => {
|
||||
await doTest(
|
||||
"add.circom",
|
||||
[
|
||||
[{in: [0,0]}, {out: 0}],
|
||||
[{in: [0,1]}, {out: 1}],
|
||||
[{in: [1,2]}, {out: 3}],
|
||||
[{in: [__P__.minus(1),1]}, {out: 0}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("add constant", async () => {
|
||||
await doTest(
|
||||
"addconst1.circom",
|
||||
[
|
||||
[{in: 0}, {out: 15}],
|
||||
[{in: 10}, {out: 25}],
|
||||
[{in: __P__.minus(2)}, {out: 13}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("for unrolled", async () => {
|
||||
await doTest(
|
||||
"forunrolled.circom",
|
||||
[
|
||||
[{in: 0}, {out: [0,1,2]}],
|
||||
[{in: 10}, {out: [10, 11, 12]}],
|
||||
[{in: __P__.minus(2)}, {out: [__P__.minus(2), __P__.minus(1), 0]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("for rolled", async () => {
|
||||
await doTest(
|
||||
"forrolled.circom",
|
||||
[
|
||||
[{in: 0}, {out: 0}],
|
||||
[{in: 10}, {out: 10}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("while unrolled", async () => {
|
||||
await doTest(
|
||||
"whileunrolled.circom",
|
||||
[
|
||||
[{in: 0}, {out: [0,1,2]}],
|
||||
[{in: 10}, {out: [10, 11, 12]}],
|
||||
[{in: __P__.minus(2)}, {out: [__P__.minus(2), __P__.minus(1), 0]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("while rolled", async () => {
|
||||
await doTest(
|
||||
"whilerolled.circom",
|
||||
[
|
||||
[{in: 0}, {out: 0}],
|
||||
[{in: 10}, {out: 10}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("function1", async () => {
|
||||
await doTest(
|
||||
"function1.circom",
|
||||
[
|
||||
[{in: 0}, {out: 3}],
|
||||
[{in: 10}, {out: 13}],
|
||||
[{in: __P__.minus(2)}, {out: 1}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("function2", async () => {
|
||||
await doTest(
|
||||
"function2.circom",
|
||||
[
|
||||
[{in: 0}, {out: 3}],
|
||||
[{in: 10}, {out: 13}],
|
||||
[{in: __P__.minus(2)}, {out: 1}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("constants1", async () => {
|
||||
await doTest(
|
||||
"constants1.circom",
|
||||
[
|
||||
[{in: 0}, {out: 42}],
|
||||
[{in: 10}, {out: 52}],
|
||||
[{in: __P__.minus(2)}, {out: 40}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("arrays", async () => {
|
||||
await doTest(
|
||||
"arrays.circom",
|
||||
[
|
||||
[{in: 0}, {out: [1, 8, 51]}],
|
||||
[{in: 10}, {out: [11, 28, 111]}],
|
||||
[{in: __P__.minus(2)}, {out: [__P__.minus(1), 4, 39]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("if unrolled", async () => {
|
||||
await doTest(
|
||||
"ifunrolled.circom",
|
||||
[
|
||||
[{in: 0}, {out: [1, 3, 6]}],
|
||||
[{in: 10}, {out: [11, 13, 16]}],
|
||||
[{in: __P__.minus(2)}, {out: [__P__.minus(1), 1, 4]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("if rolled", async () => {
|
||||
await doTest(
|
||||
"ifrolled.circom",
|
||||
[
|
||||
[{in: 0}, {out: [1, 0, 0]}],
|
||||
[{in: 1}, {out: [0, 1, 0]}],
|
||||
[{in: 2}, {out: [0, 0, 1]}],
|
||||
[{in: 3}, {out: [0, 0, 0]}],
|
||||
[{in: __P__.minus(2)}, {out: [0,0,0]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("inc", async () => {
|
||||
await doTest(
|
||||
"inc.circom",
|
||||
[
|
||||
[{in: 0}, {out: [5, 2]}],
|
||||
[{in: 1}, {out: [6, 4]}],
|
||||
[{in: 2}, {out: [7, 6]}],
|
||||
[{in: 3}, {out: [8, 8]}],
|
||||
[{in: __P__.minus(2)}, {out: [3,__P__.minus(2)]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("dec", async () => {
|
||||
await doTest(
|
||||
"dec.circom",
|
||||
[
|
||||
[{in: 0}, {out: [1, __P__.minus(2)]}],
|
||||
[{in: 1}, {out: [2, 0]}],
|
||||
[{in: 2}, {out: [3, 2]}],
|
||||
[{in: 3}, {out: [4, 4]}],
|
||||
[{in: __P__.minus(2)}, {out: [__P__.minus(1),__P__.minus(6)]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("ops", async () => {
|
||||
await doTest(
|
||||
"ops.circom",
|
||||
[
|
||||
[{in: [-2, 2]}, {add: 0, sub: -4, mul: -4}],
|
||||
[{in: [-1, 1]}, {add: 0, sub: -2, mul: -1}],
|
||||
[{in: [ 0, 0]}, {add: 0, sub: 0, mul: 0}],
|
||||
[{in: [ 1,-1]}, {add: 0, sub: 2, mul: -1}],
|
||||
[{in: [ 2,-2]}, {add: 0, sub: 4, mul: -4}],
|
||||
[{in: [-2,-3]}, {add: -5, sub: 1, mul: 6}],
|
||||
[{in: [ 2, 3]}, {add: 5, sub: -1, mul: 6}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("ops2", async () => {
|
||||
await doTest(
|
||||
"ops2.circom",
|
||||
[
|
||||
[{in: [-2, 2]}, {div: -1, idiv: bigInt("10944121435919637611123202872628637544274182200208017171849102093287904247807"), mod: 1}],
|
||||
[{in: [-1, 1]}, {div: -1, idiv: -1, mod: 0}],
|
||||
[{in: [ 1,-1]}, {div: -1, idiv: 0, mod: 1}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("ops3", async () => {
|
||||
await doTest(
|
||||
"ops3.circom",
|
||||
[
|
||||
[{in: [-2, 2]}, {neg1: 2,neg2: -2, pow: 4}],
|
||||
[{in: [0, 1]}, {neg1: 0, neg2: -1, pow: 0}],
|
||||
[{in: [ 1,-1]}, {neg1: -1, neg2: 1, pow: 1}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("Comparation ops", async () => {
|
||||
await doTest(
|
||||
"opscmp.circom",
|
||||
[
|
||||
[{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: [-1,-2]}, {lt: 0, leq: 0, eq:0, neq:1, geq: 1, gt:1}],
|
||||
[{in: [ 1,-1]}, {lt: 0, leq: 0, eq:0, neq:1, geq: 1, gt:1}], // In mod, negative values are higher than positive.
|
||||
]
|
||||
);
|
||||
});
|
||||
it("Bit ops", async () => {
|
||||
const mask = bigInt("14474011154664524427946373126085988481658748083205070504932198000989141204991");
|
||||
const m1m = bigInt("7414231717174750794300032619171286606889616317210963838766006185586667290624");
|
||||
await doTest(
|
||||
"opsbit.circom",
|
||||
[
|
||||
[{in: [ 5, 3]}, {and: 1, or: 7, xor:6, not1:mask.minus(5), shl: 40, shr:0}],
|
||||
[{in: [ 0, 0]}, {and: 0, or: 0, xor:0, not1:mask, shl: 0, shr:0}],
|
||||
[{in: [-1, 1]}, {and: 0, or: m1m.add(bigInt.one), xor:m1m.add(bigInt.one), not1:mask.minus(m1m), shl: m1m.shiftLeft(1).and(mask), shr:__P__.shiftRight(1).and(mask)}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("Logical ops", async () => {
|
||||
await doTest(
|
||||
"opslog.circom",
|
||||
[
|
||||
[{in: [ 5, 0]}, {and: 0, or: 1, not1:0}],
|
||||
[{in: [ 0, 1]}, {and: 0, or: 1, not1:1}],
|
||||
[{in: [-1, 9]}, {and: 1, or: 1, not1:0}],
|
||||
[{in: [ 0, 0]}, {and: 0, or: 0, not1:1}],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
it("Conditional Ternary operator", async () => {
|
||||
await doTest(
|
||||
"condternary.circom",
|
||||
[
|
||||
[{in: 0}, {out: 21}],
|
||||
[{in: 1}, {out: 1}],
|
||||
[{in: 2}, {out: 23}],
|
||||
[{in:-1}, {out: 20}],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
it("Compute block", async () => {
|
||||
await doTest(
|
||||
"compute.circom",
|
||||
[
|
||||
[{x: 1}, {y: 7}],
|
||||
[{x: 2}, {y: 7}],
|
||||
[{x: 3}, {y: 11}],
|
||||
[{x:-1}, {y: -5}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("Component array ", async () => {
|
||||
await doTest(
|
||||
"componentarray.circom",
|
||||
[
|
||||
[{in: 1}, {out: 1}],
|
||||
[{in: 2}, {out: 256}],
|
||||
[{in: 3}, {out: 6561}],
|
||||
[{in:-1}, {out: 1}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("Component array 2d", async () => {
|
||||
await doTest(
|
||||
"componentarray2.circom",
|
||||
[
|
||||
[{in: [1,2]}, {out: [1, 256]}],
|
||||
[{in: [0,3]}, {out: [0, 6561]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("Constant circuit", async () => {
|
||||
await doTest(
|
||||
"constantcircuit.circom",
|
||||
[
|
||||
// 0xbb67ae85
|
||||
[{}, {out: [1,0,1,0, 0,0,0,1, 0,1,1,1, 0,1,0,1, 1,1,1,0, 0,1,1,0, 1,1,0,1, 1,1,0,1]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("Constant internal circuit", async () => {
|
||||
await doTest(
|
||||
"constantinternalcircuit.circom",
|
||||
[
|
||||
[{in: 1}, {out: 5}],
|
||||
[{in: 0}, {out: 4}],
|
||||
[{in: -2}, {out: 2}],
|
||||
[{in: 10}, {out: 14}]
|
||||
]
|
||||
);
|
||||
});
|
||||
it("include", async () => {
|
||||
await doTest(
|
||||
"include.circom",
|
||||
[
|
||||
[{in: 3}, {out: 6}],
|
||||
[{in: 6}, {out: 15}],
|
||||
]
|
||||
);
|
||||
});
|
||||
for (let i=16; i<17; i++) {
|
||||
it("wasm " + basicCases[i].name, async () => {
|
||||
await doTest(wasm_tester, basicCases[i].circuit, basicCases[i].tv);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
343
test/basiccases.js.old
Normal file
343
test/basiccases.js.old
Normal file
@@ -0,0 +1,343 @@
|
||||
const path = require("path");
|
||||
|
||||
const bigInt = require("big-integer");
|
||||
const c_tester = require("../index.js").c_tester;
|
||||
|
||||
const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
|
||||
|
||||
function normalize(o) {
|
||||
if ((typeof(o) == "bigint") || o.isZero !== undefined) {
|
||||
const res = bigInt(o);
|
||||
return norm(res);
|
||||
} else if (Array.isArray(o)) {
|
||||
return o.map(normalize);
|
||||
} else if (typeof o == "object") {
|
||||
const res = {};
|
||||
for (let k in o) {
|
||||
res[k] = normalize(o[k]);
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
const res = bigInt(o);
|
||||
return norm(res);
|
||||
}
|
||||
|
||||
function norm(n) {
|
||||
let res = n.mod(__P__);
|
||||
if (res.isNegative()) res = __P__.add(res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function doTest(circuit, testVectors) {
|
||||
const cir = await c_tester(path.join(__dirname, "circuits", circuit));
|
||||
|
||||
for (let i=0; i<testVectors.length; i++) {
|
||||
const w = await cir.calculateWitness(normalize(testVectors[i][0]));
|
||||
await cir.assertOut(w, normalize(testVectors[i][1]) );
|
||||
}
|
||||
|
||||
await cir.release();
|
||||
}
|
||||
|
||||
describe("basic cases", function () {
|
||||
this.timeout(100000);
|
||||
|
||||
it("inout", async () => {
|
||||
await doTest(
|
||||
"inout.circom",
|
||||
[
|
||||
[{in1: 1, in2: [2,3], in3:[[4,5], [6,7], [8,9]]}, {out1: 1, out2: [2,3], out3: [[4,5], [6,7],[8,9]]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("add", async () => {
|
||||
await doTest(
|
||||
"add.circom",
|
||||
[
|
||||
[{in: [0,0]}, {out: 0}],
|
||||
[{in: [0,1]}, {out: 1}],
|
||||
[{in: [1,2]}, {out: 3}],
|
||||
[{in: [__P__.minus(1),1]}, {out: 0}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("add constant", async () => {
|
||||
await doTest(
|
||||
"addconst1.circom",
|
||||
[
|
||||
[{in: 0}, {out: 15}],
|
||||
[{in: 10}, {out: 25}],
|
||||
[{in: __P__.minus(2)}, {out: 13}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("for unrolled", async () => {
|
||||
await doTest(
|
||||
"forunrolled.circom",
|
||||
[
|
||||
[{in: 0}, {out: [0,1,2]}],
|
||||
[{in: 10}, {out: [10, 11, 12]}],
|
||||
[{in: __P__.minus(2)}, {out: [__P__.minus(2), __P__.minus(1), 0]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("for rolled", async () => {
|
||||
await doTest(
|
||||
"forrolled.circom",
|
||||
[
|
||||
[{in: 0}, {out: 0}],
|
||||
[{in: 10}, {out: 10}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("while unrolled", async () => {
|
||||
await doTest(
|
||||
"whileunrolled.circom",
|
||||
[
|
||||
[{in: 0}, {out: [0,1,2]}],
|
||||
[{in: 10}, {out: [10, 11, 12]}],
|
||||
[{in: __P__.minus(2)}, {out: [__P__.minus(2), __P__.minus(1), 0]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("while rolled", async () => {
|
||||
await doTest(
|
||||
"whilerolled.circom",
|
||||
[
|
||||
[{in: 0}, {out: 0}],
|
||||
[{in: 10}, {out: 10}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("function1", async () => {
|
||||
await doTest(
|
||||
"function1.circom",
|
||||
[
|
||||
[{in: 0}, {out: 3}],
|
||||
[{in: 10}, {out: 13}],
|
||||
[{in: __P__.minus(2)}, {out: 1}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("function2", async () => {
|
||||
await doTest(
|
||||
"function2.circom",
|
||||
[
|
||||
[{in: 0}, {out: 3}],
|
||||
[{in: 10}, {out: 13}],
|
||||
[{in: __P__.minus(2)}, {out: 1}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("constants1", async () => {
|
||||
await doTest(
|
||||
"constants1.circom",
|
||||
[
|
||||
[{in: 0}, {out: 42}],
|
||||
[{in: 10}, {out: 52}],
|
||||
[{in: __P__.minus(2)}, {out: 40}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("arrays", async () => {
|
||||
await doTest(
|
||||
"arrays.circom",
|
||||
[
|
||||
[{in: 0}, {out: [1, 8, 51]}],
|
||||
[{in: 10}, {out: [11, 28, 111]}],
|
||||
[{in: __P__.minus(2)}, {out: [__P__.minus(1), 4, 39]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("if unrolled", async () => {
|
||||
await doTest(
|
||||
"ifunrolled.circom",
|
||||
[
|
||||
[{in: 0}, {out: [1, 3, 6]}],
|
||||
[{in: 10}, {out: [11, 13, 16]}],
|
||||
[{in: __P__.minus(2)}, {out: [__P__.minus(1), 1, 4]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("if rolled", async () => {
|
||||
await doTest(
|
||||
"ifrolled.circom",
|
||||
[
|
||||
[{in: 0}, {out: [1, 0, 0]}],
|
||||
[{in: 1}, {out: [0, 1, 0]}],
|
||||
[{in: 2}, {out: [0, 0, 1]}],
|
||||
[{in: 3}, {out: [0, 0, 0]}],
|
||||
[{in: __P__.minus(2)}, {out: [0,0,0]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("inc", async () => {
|
||||
await doTest(
|
||||
"inc.circom",
|
||||
[
|
||||
[{in: 0}, {out: [5, 2]}],
|
||||
[{in: 1}, {out: [6, 4]}],
|
||||
[{in: 2}, {out: [7, 6]}],
|
||||
[{in: 3}, {out: [8, 8]}],
|
||||
[{in: __P__.minus(2)}, {out: [3,__P__.minus(2)]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("dec", async () => {
|
||||
await doTest(
|
||||
"dec.circom",
|
||||
[
|
||||
[{in: 0}, {out: [1, __P__.minus(2)]}],
|
||||
[{in: 1}, {out: [2, 0]}],
|
||||
[{in: 2}, {out: [3, 2]}],
|
||||
[{in: 3}, {out: [4, 4]}],
|
||||
[{in: __P__.minus(2)}, {out: [__P__.minus(1),__P__.minus(6)]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("ops", async () => {
|
||||
await doTest(
|
||||
"ops.circom",
|
||||
[
|
||||
[{in: [-2, 2]}, {add: 0, sub: -4, mul: -4}],
|
||||
[{in: [-1, 1]}, {add: 0, sub: -2, mul: -1}],
|
||||
[{in: [ 0, 0]}, {add: 0, sub: 0, mul: 0}],
|
||||
[{in: [ 1,-1]}, {add: 0, sub: 2, mul: -1}],
|
||||
[{in: [ 2,-2]}, {add: 0, sub: 4, mul: -4}],
|
||||
[{in: [-2,-3]}, {add: -5, sub: 1, mul: 6}],
|
||||
[{in: [ 2, 3]}, {add: 5, sub: -1, mul: 6}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("ops2", async () => {
|
||||
await doTest(
|
||||
"ops2.circom",
|
||||
[
|
||||
[{in: [-2, 2]}, {div: -1, idiv: bigInt("10944121435919637611123202872628637544274182200208017171849102093287904247807"), mod: 1}],
|
||||
[{in: [-1, 1]}, {div: -1, idiv: -1, mod: 0}],
|
||||
[{in: [ 1,-1]}, {div: -1, idiv: 0, mod: 1}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("ops3", async () => {
|
||||
await doTest(
|
||||
"ops3.circom",
|
||||
[
|
||||
[{in: [-2, 2]}, {neg1: 2,neg2: -2, pow: 4}],
|
||||
[{in: [0, 1]}, {neg1: 0, neg2: -1, pow: 0}],
|
||||
[{in: [ 1,-1]}, {neg1: -1, neg2: 1, pow: 1}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("Comparation ops", async () => {
|
||||
await doTest(
|
||||
"opscmp.circom",
|
||||
[
|
||||
[{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: [-1,-2]}, {lt: 0, leq: 0, eq:0, neq:1, geq: 1, gt:1}],
|
||||
[{in: [ 1,-1]}, {lt: 0, leq: 0, eq:0, neq:1, geq: 1, gt:1}], // In mod, negative values are higher than positive.
|
||||
]
|
||||
);
|
||||
});
|
||||
it("Bit ops", async () => {
|
||||
const mask = bigInt("14474011154664524427946373126085988481658748083205070504932198000989141204991");
|
||||
const m1m = bigInt("7414231717174750794300032619171286606889616317210963838766006185586667290624");
|
||||
await doTest(
|
||||
"opsbit.circom",
|
||||
[
|
||||
[{in: [ 5, 3]}, {and: 1, or: 7, xor:6, not1:mask.minus(5), shl: 40, shr:0}],
|
||||
[{in: [ 0, 0]}, {and: 0, or: 0, xor:0, not1:mask, shl: 0, shr:0}],
|
||||
[{in: [-1, 1]}, {and: 0, or: m1m.add(bigInt.one), xor:m1m.add(bigInt.one), not1:mask.minus(m1m), shl: m1m.shiftLeft(1).and(mask), shr:__P__.shiftRight(1).and(mask)}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("Logical ops", async () => {
|
||||
await doTest(
|
||||
"opslog.circom",
|
||||
[
|
||||
[{in: [ 5, 0]}, {and: 0, or: 1, not1:0}],
|
||||
[{in: [ 0, 1]}, {and: 0, or: 1, not1:1}],
|
||||
[{in: [-1, 9]}, {and: 1, or: 1, not1:0}],
|
||||
[{in: [ 0, 0]}, {and: 0, or: 0, not1:1}],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
it("Conditional Ternary operator", async () => {
|
||||
await doTest(
|
||||
"condternary.circom",
|
||||
[
|
||||
[{in: 0}, {out: 21}],
|
||||
[{in: 1}, {out: 1}],
|
||||
[{in: 2}, {out: 23}],
|
||||
[{in:-1}, {out: 20}],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
it("Compute block", async () => {
|
||||
await doTest(
|
||||
"compute.circom",
|
||||
[
|
||||
[{x: 1}, {y: 7}],
|
||||
[{x: 2}, {y: 7}],
|
||||
[{x: 3}, {y: 11}],
|
||||
[{x:-1}, {y: -5}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("Component array ", async () => {
|
||||
await doTest(
|
||||
"componentarray.circom",
|
||||
[
|
||||
[{in: 1}, {out: 1}],
|
||||
[{in: 2}, {out: 256}],
|
||||
[{in: 3}, {out: 6561}],
|
||||
[{in:-1}, {out: 1}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("Component array 2d", async () => {
|
||||
await doTest(
|
||||
"componentarray2.circom",
|
||||
[
|
||||
[{in: [1,2]}, {out: [1, 256]}],
|
||||
[{in: [0,3]}, {out: [0, 6561]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("Constant circuit", async () => {
|
||||
await doTest(
|
||||
"constantcircuit.circom",
|
||||
[
|
||||
// 0xbb67ae85
|
||||
[{}, {out: [1,0,1,0, 0,0,0,1, 0,1,1,1, 0,1,0,1, 1,1,1,0, 0,1,1,0, 1,1,0,1, 1,1,0,1]}],
|
||||
]
|
||||
);
|
||||
});
|
||||
it("Constant internal circuit", async () => {
|
||||
await doTest(
|
||||
"constantinternalcircuit.circom",
|
||||
[
|
||||
[{in: 1}, {out: 5}],
|
||||
[{in: 0}, {out: 4}],
|
||||
[{in: -2}, {out: 2}],
|
||||
[{in: 10}, {out: 14}]
|
||||
]
|
||||
);
|
||||
});
|
||||
it("include", async () => {
|
||||
await doTest(
|
||||
"include.circom",
|
||||
[
|
||||
[{in: 3}, {out: 6}],
|
||||
[{in: 6}, {out: 15}],
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
});
|
||||
307
test/basiccases.json
Normal file
307
test/basiccases.json
Normal file
@@ -0,0 +1,307 @@
|
||||
[
|
||||
{
|
||||
"name": "inout",
|
||||
"circuit": "inout.circom",
|
||||
"tv": [
|
||||
[{
|
||||
"in1": 1,
|
||||
"in2": [2,3],
|
||||
"in3" : [[4,5], [6,7], [8,9]]
|
||||
}, {
|
||||
"out1": 1,
|
||||
"out2": [2,3],
|
||||
"out3": [[4,5], [6,7],[8,9]]
|
||||
}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "add",
|
||||
"circuit": "add.circom",
|
||||
"tv": [
|
||||
[{"in": [0,0]}, {"out": 0}],
|
||||
[{"in": [0 ,1]}, {"out": 1}],
|
||||
[{"in": [1 ,2]}, {"out": 3}],
|
||||
[{"in": [-1,1]}, {"out": 0}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "add constant",
|
||||
"circuit": "addconst1.circom",
|
||||
"tv": [
|
||||
[{"in": 0}, {"out": 15}],
|
||||
[{"in": 10}, {"out": 25}],
|
||||
[{"in": -2}, {"out": 13}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "for unrolled",
|
||||
"circuit": "forunrolled.circom",
|
||||
"tv": [
|
||||
[{"in": 0}, {"out": [ 0, 1, 2]}],
|
||||
[{"in": 10}, {"out": [10, 11, 12]}],
|
||||
[{"in": -2}, {"out": [-2, -1, 0]}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "for rolled",
|
||||
"circuit": "forrolled.circom",
|
||||
"tv": [
|
||||
[{"in": 0}, {"out": 0}],
|
||||
[{"in": 10}, {"out": 10}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "while unrolled",
|
||||
"circuit": "whileunrolled.circom",
|
||||
"tv": [
|
||||
[{"in": 0}, {"out": [ 0, 1, 2]}],
|
||||
[{"in": 10}, {"out": [10, 11, 12]}],
|
||||
[{"in": -2}, {"out": [-2, -1, 0]}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "while rolled",
|
||||
"circuit": "whilerolled.circom",
|
||||
"tv": [
|
||||
[{"in": 0}, {"out": 0}],
|
||||
[{"in": 10}, {"out": 10}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "function1",
|
||||
"circuit": "function1.circom",
|
||||
"tv": [
|
||||
[{"in": 0}, {"out": 3}],
|
||||
[{"in": 10}, {"out": 13}],
|
||||
[{"in": -2}, {"out": 1}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "function2",
|
||||
"circuit": "function2.circom",
|
||||
"tv": [
|
||||
[{"in": 0 }, {"out": 3}],
|
||||
[{"in": 10}, {"out": 13}],
|
||||
[{"in": -2}, {"out": 1}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "constants1",
|
||||
"circuit": "constants1.circom",
|
||||
"tv": [
|
||||
[{"in": 0}, {"out": 42}],
|
||||
[{"in": 10}, {"out": 52}],
|
||||
[{"in": -2}, {"out": 40}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "arrays",
|
||||
"circuit": "arrays.circom",
|
||||
"tv": [
|
||||
[{"in": 0}, {"out": [ 1, 8, 51]}],
|
||||
[{"in": 10}, {"out": [11, 28, 111]}],
|
||||
[{"in": -2}, {"out": [-1, 4, 39]}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "if unrolled",
|
||||
"circuit": "ifunrolled.circom",
|
||||
"tv": [
|
||||
[{"in": 0}, {"out": [ 1, 3, 6]}],
|
||||
[{"in": 10}, {"out": [11, 13, 16]}],
|
||||
[{"in": -2}, {"out": [-1, 1, 4]}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "if rolled",
|
||||
"circuit": "ifrolled.circom",
|
||||
"tv": [
|
||||
[{"in": 0}, {"out": [1, 0, 0]}],
|
||||
[{"in": 1}, {"out": [0, 1, 0]}],
|
||||
[{"in": 2}, {"out": [0, 0, 1]}],
|
||||
[{"in": 3}, {"out": [0, 0, 0]}],
|
||||
[{"in": -2}, {"out": [0, 0, 0]}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "inc",
|
||||
"circuit": "inc.circom",
|
||||
"tv": [
|
||||
[{"in": 0}, {"out": [5, 2]}],
|
||||
[{"in": 1}, {"out": [6, 4]}],
|
||||
[{"in": 2}, {"out": [7, 6]}],
|
||||
[{"in": 3}, {"out": [8, 8]}],
|
||||
[{"in": -2}, {"out": [3,-2]}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "dec",
|
||||
"circuit": "dec.circom",
|
||||
"tv": [
|
||||
[{"in": 0}, {"out": [ 1, -2]}],
|
||||
[{"in": 1}, {"out": [ 2, 0]}],
|
||||
[{"in": 2}, {"out": [ 3, 2]}],
|
||||
[{"in": 3}, {"out": [ 4, 4]}],
|
||||
[{"in": -2}, {"out": [-1, -6]}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ops",
|
||||
"circuit": "ops.circom",
|
||||
"tv": [
|
||||
[{"in": [-2, 2]}, {"add": 0, "sub": -4, "mul": -4}],
|
||||
[{"in": [-1, 1]}, {"add": 0, "sub": -2, "mul": -1}],
|
||||
[{"in": [ 0, 0]}, {"add": 0, "sub": 0, "mul": 0}],
|
||||
[{"in": [ 1,-1]}, {"add": 0, "sub": 2, "mul": -1}],
|
||||
[{"in": [ 2,-2]}, {"add": 0, "sub": 4, "mul": -4}],
|
||||
[{"in": [-2,-3]}, {"add": -5, "sub": 1, "mul": 6}],
|
||||
[{"in": [ 2, 3]}, {"add": 5, "sub": -1, "mul": 6}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ops2",
|
||||
"circuit": "ops2.circom",
|
||||
"tv": [
|
||||
[{"in": [-2, 2]}, {"div": -1, "idiv": "10944121435919637611123202872628637544274182200208017171849102093287904247807", "mod": 1}],
|
||||
[{"in": [-1, 1]}, {"div": -1, "idiv": -1, "mod": 0}],
|
||||
[{"in": [ 1,-1]}, {"div": -1, "idiv": 0, "mod": 1}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ops3",
|
||||
"circuit": "ops3.circom",
|
||||
"tv": [
|
||||
[{"in": [-2, 2]}, {"neg1": 2, "neg2": -2, "pow": 4}],
|
||||
[{"in": [ 0, 1]}, {"neg1": 0, "neg2": -1, "pow": 0}],
|
||||
[{"in": [ 1,-1]}, {"neg1": -1, "neg2": 1, "pow": 1}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Comparation ops",
|
||||
"circuit": "opscmp.circom",
|
||||
"tv": [
|
||||
[{"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": [-1,-2]}, {"lt": 0, "leq": 0, "eq":0, "neq":1, "geq": 1, "gt":1}],
|
||||
[{"in": [ 1,-1]}, {"lt": 0, "leq": 0, "eq":0, "neq":1, "geq": 1, "gt":1}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Bit ops",
|
||||
"circuit": "opsbit.circom",
|
||||
"tv": [
|
||||
[
|
||||
{
|
||||
"in": [ 5, 3]
|
||||
},
|
||||
{
|
||||
"and": 1,
|
||||
"or": 7,
|
||||
"xor":6,
|
||||
"not1": "14474011154664524427946373126085988481658748083205070504932198000989141204986",
|
||||
"shl": 40,
|
||||
"shr":0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"in": [ 0, 0]
|
||||
},
|
||||
{
|
||||
"and": 0,
|
||||
"or": 0,
|
||||
"xor":0,
|
||||
"not1":"14474011154664524427946373126085988481658748083205070504932198000989141204991",
|
||||
"shl": 0,
|
||||
"shr":0
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"in": [-1, 1]
|
||||
},
|
||||
{
|
||||
"and": 0,
|
||||
"or": "7414231717174750794300032619171286606889616317210963838766006185586667290625",
|
||||
"xor":"7414231717174750794300032619171286606889616317210963838766006185586667290625",
|
||||
"not1": "7059779437489773633646340506914701874769131765994106666166191815402473914367",
|
||||
"shl": "354452279684977160653692112256584732120484551216857172599814370184193376256",
|
||||
"shr": "10944121435919637611123202872628637544274182200208017171849102093287904247808"
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Logical ops",
|
||||
"circuit": "opslog.circom",
|
||||
"tv": [
|
||||
[{"in": [ 5, 0]}, {"and": 0, "or": 1, "not1":0}],
|
||||
[{"in": [ 0, 1]}, {"and": 0, "or": 1, "not1":1}],
|
||||
[{"in": [-1, 9]}, {"and": 1, "or": 1, "not1":0}],
|
||||
[{"in": [ 0, 0]}, {"and": 0, "or": 0, "not1":1}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Conditional Ternary operator",
|
||||
"circuit": "condternary.circom",
|
||||
"tv": [
|
||||
[{"in": 0}, {"out": 21}],
|
||||
[{"in": 1}, {"out": 1}],
|
||||
[{"in": 2}, {"out": 23}],
|
||||
[{"in":-1}, {"out": 20}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Compute block",
|
||||
"circuit": "compute.circom",
|
||||
"tv": [
|
||||
[{"x": 1}, {"y": 7}],
|
||||
[{"x": 2}, {"y": 7}],
|
||||
[{"x": 3}, {"y": 11}],
|
||||
[{"x":-1}, {"y": -5}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Component array",
|
||||
"circuit": "componentarray.circom",
|
||||
"tv": [
|
||||
[{"in": 1}, {"out": 1}],
|
||||
[{"in": 2}, {"out": 256}],
|
||||
[{"in": 3}, {"out": 6561}],
|
||||
[{"in":-1}, {"out": 1}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Component array 2d",
|
||||
"circuit": "componentarray2.circom",
|
||||
"tv": [
|
||||
[{"in": [1,2]}, {"out": [1, 256]}],
|
||||
[{"in": [0,3]}, {"out": [0, 6561]}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Constant circuit",
|
||||
"circuit": "constantcircuit.circom",
|
||||
"tv": [
|
||||
[{}, {"out": [1,0,1,0, 0,0,0,1, 0,1,1,1, 0,1,0,1, 1,1,1,0, 0,1,1,0, 1,1,0,1, 1,1,0,1]}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Constant internal circuit",
|
||||
"circuit": "constantinternalcircuit.circom",
|
||||
"tv": [
|
||||
[{"in": 1}, {"out": 5}],
|
||||
[{"in": 0}, {"out": 4}],
|
||||
[{"in": -2}, {"out": 2}],
|
||||
[{"in": 10}, {"out": 14}]
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "include",
|
||||
"circuit": "include.circom",
|
||||
"tv": [
|
||||
[{"in": 3}, {"out": 6}],
|
||||
[{"in": 6}, {"out": 15}]
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -31,9 +31,11 @@ template Main() {
|
||||
out[0] === in+c[0];
|
||||
|
||||
out[1] <-- d[1]+c[1];
|
||||
// out[1] === (in+in)+3+c[1];
|
||||
out[1] === 2*in+3+c[1];
|
||||
|
||||
out[2] <-- d[2]+c[2];
|
||||
// out[2] === (in+in+in+in+in+in)+12+c[2];
|
||||
out[2] === 6*in+12+c[2];
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
{"x": "3"}
|
||||
@@ -1,4 +1,4 @@
|
||||
const tester = require("../c/buildasm/buildzqfieldtester.js");
|
||||
const tester = require("../ports/c/buildasm/buildzqfieldtester.js");
|
||||
|
||||
const ZqField = require("fflib").ZqField;
|
||||
|
||||
@@ -17,7 +17,6 @@ describe("field asm test", function () {
|
||||
const tv = buildTestVector2(bn128r, "add");
|
||||
await tester(bn128r, tv);
|
||||
});
|
||||
|
||||
it("secp256k1q add", async () => {
|
||||
const tv = buildTestVector2(secp256k1q, "add");
|
||||
await tester(secp256k1q, tv);
|
||||
@@ -267,7 +266,6 @@ describe("field asm test", function () {
|
||||
const tv = buildTestVector1(mnt6753q, "square");
|
||||
await tester(mnt6753q, tv);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function buildTestVector2(p, op) {
|
||||
|
||||
Reference in New Issue
Block a user