@ -1,3 +1,3 @@ |
|||||
module.exports.compiler = require("./src/compiler.js"); |
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"); |
@ -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 |
@ -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> |
@ -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"); |
||||
|
|
||||
|
}; |
@ -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"}, |
||||
|
}; |
@ -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; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
@ -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); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
@ -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; |
|
@ -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) { |
|
||||
|
|
||||
|
|
||||
} |
|
@ -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; |
||||
|
}; |
@ -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}], |
||||
|
] |
||||
|
); |
||||
|
}); |
||||
|
|
||||
|
}); |
@ -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}] |
||||
|
] |
||||
|
} |
||||
|
] |
@ -1 +0,0 @@ |
|||||
{"x": "3"} |
|