@ -0,0 +1,33 @@ |
|||||
|
module.exports = { |
||||
|
"plugins": [ |
||||
|
"mocha" |
||||
|
], |
||||
|
"env": { |
||||
|
"es6": true, |
||||
|
"node": true, |
||||
|
"mocha": true |
||||
|
}, |
||||
|
"parserOptions": { |
||||
|
"ecmaVersion": 2017 |
||||
|
}, |
||||
|
"extends": "eslint:recommended", |
||||
|
"rules": { |
||||
|
"indent": [ |
||||
|
"error", |
||||
|
4 |
||||
|
], |
||||
|
"linebreak-style": [ |
||||
|
"error", |
||||
|
"unix" |
||||
|
], |
||||
|
"quotes": [ |
||||
|
"error", |
||||
|
"double" |
||||
|
], |
||||
|
"semi": [ |
||||
|
"error", |
||||
|
"always" |
||||
|
], |
||||
|
"mocha/no-exclusive-tests": "error" |
||||
|
} |
||||
|
}; |
@ -0,0 +1,65 @@ |
|||||
|
# Logs |
||||
|
logs |
||||
|
*.log |
||||
|
npm-debug.log* |
||||
|
yarn-debug.log* |
||||
|
yarn-error.log* |
||||
|
|
||||
|
# Runtime data |
||||
|
pids |
||||
|
*.pid |
||||
|
*.seed |
||||
|
*.pid.lock |
||||
|
|
||||
|
# Directory for instrumented libs generated by jscoverage/JSCover |
||||
|
lib-cov |
||||
|
|
||||
|
# Coverage directory used by tools like istanbul |
||||
|
coverage |
||||
|
|
||||
|
# nyc test coverage |
||||
|
.nyc_output |
||||
|
|
||||
|
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) |
||||
|
.grunt |
||||
|
|
||||
|
# Bower dependency directory (https://bower.io/) |
||||
|
bower_components |
||||
|
|
||||
|
# node-waf configuration |
||||
|
.lock-wscript |
||||
|
|
||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html) |
||||
|
build/Release |
||||
|
|
||||
|
# Dependency directories |
||||
|
node_modules/ |
||||
|
jspm_packages/ |
||||
|
|
||||
|
# Typescript v1 declaration files |
||||
|
typings/ |
||||
|
|
||||
|
# Optional npm cache directory |
||||
|
.npm |
||||
|
|
||||
|
# Optional eslint cache |
||||
|
.eslintcache |
||||
|
|
||||
|
# Optional REPL history |
||||
|
.node_repl_history |
||||
|
|
||||
|
# Output of 'npm pack' |
||||
|
*.tgz |
||||
|
|
||||
|
# Yarn Integrity file |
||||
|
.yarn-integrity |
||||
|
|
||||
|
# dotenv environment variables file |
||||
|
.env |
||||
|
|
||||
|
# next.js build output |
||||
|
.next |
||||
|
|
||||
|
tmp |
||||
|
|
||||
|
.DS_Store |
@ -0,0 +1,2 @@ |
|||||
|
# cirpedersen |
||||
|
|
@ -0,0 +1,31 @@ |
|||||
|
|
||||
|
|
||||
|
template BabyAdd() { |
||||
|
signal input x1; |
||||
|
signal input y1; |
||||
|
signal input x2; |
||||
|
signal input y2; |
||||
|
signal output xout; |
||||
|
signal output yout; |
||||
|
|
||||
|
signal beta; |
||||
|
signal gamma; |
||||
|
signal delta; |
||||
|
signal epsilon; |
||||
|
signal tau; |
||||
|
|
||||
|
var a = 168700; |
||||
|
var d = 168696; |
||||
|
|
||||
|
beta <== x1*y2; |
||||
|
gamma <== y1*x2; |
||||
|
delta <== y1*y2; |
||||
|
epsilon <== x1*x2; |
||||
|
tau <== delta * epsilon; |
||||
|
|
||||
|
xout <-- (beta + gamma) / (1+ d*tau); |
||||
|
(1+ d*tau) * xout === (beta + gamma); |
||||
|
|
||||
|
yout <-- (delta - a * epsilon) / (1-d*tau); |
||||
|
(1-d*tau)*yout === (delta - a * epsilon); |
||||
|
} |
@ -0,0 +1,145 @@ |
|||||
|
/* |
||||
|
|
||||
|
┏━━━━━━━━━━━┓ |
||||
|
┃ ┃ |
||||
|
┃ ┃ |
||||
|
(inx, iny) ══════════════════════════════════════════▶┃ EC Point ┃ |
||||
|
┃ ╠═▶ (outx, outy) |
||||
|
╔══▶┃ Adder ┃ |
||||
|
║ ┃ ┃ |
||||
|
║ ┃ ┃ |
||||
|
║ ┃ ┃ |
||||
|
┏━━━━━━━━━━━┓ ┏━━━━━━━━━━━━┓ ║ ┗━━━━━━━━━━━┛ |
||||
|
┃ ┃ ┃ ┃ ║ |
||||
|
┃ ┃ ┃ ┃ ║ |
||||
|
┃ ╠═══(p0x,p0y)═══▶┃ ┃ ║ |
||||
|
┃ ╠═══(p1x,p1y)═══▶┃ ┃ ║ |
||||
|
┃ ╠═══(p2x,p2y)═══▶┃ ┃ ║ |
||||
|
┃ ╠═══(p3x,p3y)═══▶┃ ┃ ║ |
||||
|
┃ ╠═══(p4x,p4y)═══▶┃ ┃ ║ |
||||
|
┃ ╠═══(p5x,p5y)═══▶┃ ┃ ║ |
||||
|
┃ ╠═══(p6x,p6y)═══▶┃ ┃ ║ |
||||
|
┃ Constant ╠═══(p7x,p7y)═══▶┃ ┃ ║ |
||||
|
┃ Points ┃ ┃ Mux4 ╠══╝ |
||||
|
┃ ╠═══(p8x,p8y)═══▶┃ ┃ |
||||
|
┃ ╠═══(p9x,p9y)═══▶┃ ┃ |
||||
|
┃ ╠══(p10x,p10y)══▶┃ ┃ |
||||
|
┃ ╠══(p11x,p11y)══▶┃ ┃ |
||||
|
┃ ╠══(p12x,p12y)══▶┃ ┃ |
||||
|
┃ ╠══(p13x,p13y)══▶┃ ┃ |
||||
|
┃ ╠══(p14x,p14y)══▶┃ ┃ |
||||
|
┃ ╠══(p15x,p15y)══▶┃ ┃ |
||||
|
┃ ┃ ┃ ┃ |
||||
|
┃ ┃ ┃ ┃ |
||||
|
┗━━━━━━━━━━━┛ ┗━━━━━━━━━━━━┛ |
||||
|
▲ ▲ ▲ ▲ |
||||
|
│ │ │ │ |
||||
|
s0 ─────────────────────────────────┘ │ │ │ |
||||
|
s1 ────────────────────────────────────┘ │ │ |
||||
|
s2 ───────────────────────────────────────┘ │ |
||||
|
s3 ──────────────────────────────────────────┘ |
||||
|
|
||||
|
|
||||
|
*/ |
||||
|
|
||||
|
include "mux4.circom"; |
||||
|
include "expw4table.circom"; |
||||
|
include "babyjub.circom"; |
||||
|
|
||||
|
template ExpWindow(k) { |
||||
|
|
||||
|
signal input in[2]; |
||||
|
signal input sel[4]; |
||||
|
signal output out[2]; |
||||
|
|
||||
|
component table; |
||||
|
component mux; |
||||
|
component adder; |
||||
|
|
||||
|
var i; |
||||
|
|
||||
|
table = ExpW4Table(k); |
||||
|
mux = MultiMux4(2); |
||||
|
adder = BabyAdd(); |
||||
|
|
||||
|
for (i=0; i<4; i++) { |
||||
|
sel[i] ==> mux.s[i]; |
||||
|
} |
||||
|
|
||||
|
for (i=0; i<16; i++) { |
||||
|
table.out[i][0] ==> mux.c[0][i]; |
||||
|
table.out[i][1] ==> mux.c[1][i]; |
||||
|
} |
||||
|
|
||||
|
in[0] ==> adder.x1; |
||||
|
in[1] ==> adder.y1; |
||||
|
|
||||
|
mux.out[0] ==> adder.x2; |
||||
|
mux.out[1] ==> adder.y2; |
||||
|
|
||||
|
adder.xout ==> out[0]; |
||||
|
adder.yout ==> out[1]; |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
|
||||
|
|
||||
|
┏━━━━━━━━━┓ ┏━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━━┓ |
||||
|
┃ ┃ ┃ ┃ ┃ ┃ |
||||
|
(0,1) ════▶┃Window(0)┃═════▶┃Window(1)┃════════ . . . . ═════════▶┃ Window(nBlocks-1) ┃═════▶ out |
||||
|
┃ ┃ ┃ ┃ ┃ ┃ |
||||
|
┗━━━━━━━━━┛ ┗━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━━┛ |
||||
|
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ |
||||
|
in[0]─────────┘ │ │ │ │ │ │ │ │ │ │ │ |
||||
|
in[1]───────────┘ │ │ │ │ │ │ │ │ │ │ |
||||
|
in[2]─────────────┘ │ │ │ │ │ │ │ 0 0 |
||||
|
in[3]───────────────┘ │ │ │ │ │ │ |
||||
|
in[4]──────────────────────────┘ │ │ │ │ │ |
||||
|
in[5]────────────────────────────┘ │ │ │ │ |
||||
|
in[6]──────────────────────────────┘ │ │ │ |
||||
|
in[7]────────────────────────────────┘ │ │ |
||||
|
. │ │ |
||||
|
. │ │ |
||||
|
in[n-2]─────────────────────────────────────────────────────────────────────┘ │ |
||||
|
in[n-1]───────────────────────────────────────────────────────────────────────┘ |
||||
|
|
||||
|
*/ |
||||
|
|
||||
|
template Exp(n) { |
||||
|
signal input in[n]; |
||||
|
signal output out[2]; |
||||
|
|
||||
|
var nBlocks = ((n-1)>>2)+1; |
||||
|
var i; |
||||
|
var j; |
||||
|
|
||||
|
component windows[nBlocks]; |
||||
|
|
||||
|
// Construct the windows |
||||
|
for (i=0; i<nBlocks; i++) { |
||||
|
windows[i] = ExpWindow(i); |
||||
|
} |
||||
|
|
||||
|
// Connect the selectors |
||||
|
for (i=0; i<nBlocks; i++) { |
||||
|
for (j=0; j<4; j++) { |
||||
|
if (i*4+j >= n) { |
||||
|
windows[i].sel[j] <== 0; |
||||
|
} else { |
||||
|
windows[i].sel[j] <== in[i*4+j]; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Start with generator |
||||
|
windows[0].in[0] <== 0; |
||||
|
windows[0].in[1] <== 1; |
||||
|
|
||||
|
for(i=0; i<nBlocks-1; i++) { |
||||
|
windows[i].out[0] ==> windows[i+1].in[0]; |
||||
|
windows[i].out[1] ==> windows[i+1].in[1]; |
||||
|
} |
||||
|
|
||||
|
windows[nBlocks-1].out[0] ==> out[0]; |
||||
|
windows[nBlocks-1].out[1] ==> out[1]; |
||||
|
} |
@ -0,0 +1,33 @@ |
|||||
|
function pointAdd(x1,y1,x2,y2) { |
||||
|
var a = 168700; |
||||
|
var d = 168696; |
||||
|
|
||||
|
var res[2]; |
||||
|
res[0] = (x1*y2 + y1*x2) / (1 + d*x1*x2*y1*y2); |
||||
|
res[1] = (y1*y2 - a*x1*x2) / (1 - d*x1*x2*y1*y2); |
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
template ExpW4Table(k) { |
||||
|
signal output out[16][2]; |
||||
|
|
||||
|
var i; |
||||
|
var p[2]; |
||||
|
|
||||
|
var g = [17777552123799933955779906779655732241715742912184938656739573121738514868268, |
||||
|
2626589144620713026669568689430873010625803728049924121243784502389097019475]; |
||||
|
|
||||
|
var dbl = g; |
||||
|
|
||||
|
for (i=0; i<k*4; i++) { |
||||
|
dbl = pointAdd(dbl[0], dbl[1], dbl[0], dbl[1]); |
||||
|
} |
||||
|
|
||||
|
out[0][0] <== 0; |
||||
|
out[0][1] <== 1; |
||||
|
for (i=1; i<16; i++) { |
||||
|
p = pointAdd(out[i-1][0], out[i-1][1], dbl[0], dbl[1]); |
||||
|
out[i][0] <== p[0]; |
||||
|
out[i][1] <== p[1]; |
||||
|
} |
||||
|
} |
@ -0,0 +1,103 @@ |
|||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
template MultiMux4(n) { |
||||
|
signal input c[n][16]; // Constants |
||||
|
signal input s[4]; // Selector |
||||
|
signal output out[n]; |
||||
|
|
||||
|
signal a3210[n]; |
||||
|
signal a321[n]; |
||||
|
signal a320[n]; |
||||
|
signal a310[n]; |
||||
|
signal a32[n]; |
||||
|
signal a31[n]; |
||||
|
signal a30[n]; |
||||
|
signal a3[n]; |
||||
|
|
||||
|
signal a210[n]; |
||||
|
signal a21[n]; |
||||
|
signal a20[n]; |
||||
|
signal a10[n]; |
||||
|
signal a2[n]; |
||||
|
signal a1[n]; |
||||
|
signal a0[n]; |
||||
|
signal a[n]; |
||||
|
|
||||
|
// 4 constrains for the intermediary variables |
||||
|
signal s10; |
||||
|
s10 <== s[1] * s[0]; |
||||
|
signal s20; |
||||
|
s20 <== s[2] * s[0]; |
||||
|
signal s21; |
||||
|
s21 <== s[2] * s[1]; |
||||
|
signal s210; |
||||
|
s210 <== s21 * s[0]; |
||||
|
|
||||
|
|
||||
|
for (var i=0; i<n; i++) { |
||||
|
|
||||
|
a3210[i] <== ( c[i][15]-c[i][14]-c[i][13]+c[i][12] - c[i][11]+c[i][10]+c[i][ 9]-c[i][ 8] |
||||
|
-c[i][ 7]+c[i][ 6]+c[i][ 5]-c[i][ 4] + c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) * s210; |
||||
|
a321[i] <== ( c[i][14]-c[i][12]-c[i][10]+c[i][ 8] - c[i][ 6]+c[i][ 4]+c[i][ 2]-c[i][ 0] ) * s21; |
||||
|
a320[i] <== ( c[i][13]-c[i][12]-c[i][ 9]+c[i][ 8] - c[i][ 5]+c[i][ 4]+c[i][ 1]-c[i][ 0] ) * s20; |
||||
|
a310[i] <== ( c[i][11]-c[i][10]-c[i][ 9]+c[i][ 8] - c[i][ 3]+c[i][ 2]+c[i][ 1]-c[i][ 0] ) * s10; |
||||
|
a32[i] <== ( c[i][12]-c[i][ 8]-c[i][ 4]+c[i][ 0] ) * s[2]; |
||||
|
a31[i] <== ( c[i][10]-c[i][ 8]-c[i][ 2]+c[i][ 0] ) * s[1]; |
||||
|
a30[i] <== ( c[i][ 9]-c[i][ 8]-c[i][ 1]+c[i][ 0] ) * s[0]; |
||||
|
a3[i] <== ( c[i][ 8]-c[i][ 0] ); |
||||
|
|
||||
|
a210[i] <== ( c[i][ 7]-c[i][ 6]-c[i][ 5]+c[i][ 4] - c[i][ 3]+c[i][ 2]+c[i][ 1]-c[i][ 0] ) * s210; |
||||
|
a21[i] <== ( c[i][ 6]-c[i][ 4]-c[i][ 2]+c[i][ 0] ) * s21; |
||||
|
a20[i] <== ( c[i][ 5]-c[i][ 4]-c[i][ 1]+c[i][ 0] ) * s20; |
||||
|
a10[i] <== ( c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) * s10; |
||||
|
a2[i] <== ( c[i][ 4]-c[i][ 0] ) * s[2]; |
||||
|
a1[i] <== ( c[i][ 2]-c[i][ 0] ) * s[1]; |
||||
|
a0[i] <== ( c[i][ 1]-c[i][ 0] ) * s[0]; |
||||
|
a[i] <== ( c[i][ 0] ) |
||||
|
|
||||
|
out[i] <== ( a3210[i] + a321[i] + a320[i] + a310[i] + a32[i] + a31[i] + a30[i] + a3[i] ) * s[3] + |
||||
|
( a210[i] + a21[i] + a20[i] + a10[i] + a2[i] + a1[i] + a0[i] + a[i] ); |
||||
|
|
||||
|
/* |
||||
|
out[i] <== ( s210 * ( c[i][15]-c[i][14]-c[i][13]+c[i][12] - c[i][11]+c[i][10]+c[i][ 9]-c[i][ 8] |
||||
|
-c[i][ 7]+c[i][ 6]+c[i][ 5]-c[i][ 4] + c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) + |
||||
|
s21 * ( c[i][14]-c[i][12]-c[i][10]+c[i][ 8] - c[i][ 6]+c[i][ 4]+c[i][ 2]-c[i][ 0] ) + |
||||
|
s20 * ( c[i][13]-c[i][12]-c[i][ 9]+c[i][ 8] - c[i][ 5]+c[i][ 4]+c[i][ 1]-c[i][ 0] ) + |
||||
|
s10 * ( c[i][11]-c[i][10]-c[i][ 9]+c[i][ 8] - c[i][ 3]+c[i][ 2]+c[i][ 1]-c[i][ 0] ) + |
||||
|
s[2] * ( c[i][12]-c[i][ 8]-c[i][ 4]+c[i][ 0] ) + |
||||
|
s[1] * ( c[i][10]-c[i][ 8]-c[i][ 2]+c[i][ 0] ) + |
||||
|
s[0] * ( c[i][ 9]-c[i][ 8]-c[i][ 1]+c[i][ 0] ) + |
||||
|
( c[i][ 8]-c[i][ 0] ) ) * s[3] + |
||||
|
( s210 * ( c[i][ 7]-c[i][ 6]-c[i][ 5]+c[i][ 4] - c[i][ 3]+c[i][ 2]+c[i][ 1]-c[i][ 0] ) + |
||||
|
s21 * ( c[i][ 6]-c[i][ 4]-c[i][ 2]+c[i][ 0] ) + |
||||
|
s20 * ( c[i][ 5]-c[i][ 4]-c[i][ 1]+c[i][ 0] ) + |
||||
|
s10 * ( c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) + |
||||
|
s[2] * ( c[i][ 4]-c[i][ 0] ) + |
||||
|
s[1] * ( c[i][ 2]-c[i][ 0] ) + |
||||
|
s[0] * ( c[i][ 1]-c[i][ 0] ) + |
||||
|
( c[i][ 0] )); |
||||
|
|
||||
|
*/ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
template Mux4() { |
||||
|
var i; |
||||
|
signal input c[16]; // Constants |
||||
|
signal input s[4]; // Selector |
||||
|
signal output out; |
||||
|
|
||||
|
component mux = MultiMux4(1); |
||||
|
|
||||
|
for (i=0; i<16; i++) { |
||||
|
mux.c[0][i] <== c[i]; |
||||
|
} |
||||
|
|
||||
|
for (i=0; i<4; i++) { |
||||
|
s[i] ==> mux.s[i]; |
||||
|
} |
||||
|
|
||||
|
mux.out[0] ==> out; |
||||
|
} |
@ -0,0 +1,29 @@ |
|||||
|
{ |
||||
|
"name": "cirpedersen", |
||||
|
"version": "0.0.1", |
||||
|
"description": "Pesersen Circuit for Circom", |
||||
|
"main": "index.js", |
||||
|
"directories": { |
||||
|
"test": "test" |
||||
|
}, |
||||
|
"scripts": { |
||||
|
"test": "mocha" |
||||
|
}, |
||||
|
"keywords": [ |
||||
|
"pedersen", |
||||
|
"hash", |
||||
|
"ethereum", |
||||
|
"circuit", |
||||
|
"circom", |
||||
|
"zksnark" |
||||
|
], |
||||
|
"author": "Jordi Baylina", |
||||
|
"license": "GPL-3.0", |
||||
|
"dependencies": { |
||||
|
"circom": "0.0.7", |
||||
|
"zksnark": "0.0.11" |
||||
|
}, |
||||
|
"devDependencies": { |
||||
|
"mocha": "^5.2.0" |
||||
|
} |
||||
|
} |
@ -0,0 +1,98 @@ |
|||||
|
const chai = require("chai"); |
||||
|
const path = require("path"); |
||||
|
const zkSnark = require("zksnark"); |
||||
|
const compiler = require("circom"); |
||||
|
|
||||
|
const assert = chai.assert; |
||||
|
|
||||
|
const bigInt = require("big-integer"); |
||||
|
|
||||
|
|
||||
|
describe("Baby Jub test", () => { |
||||
|
it("Should add point (0,1) and (0,1)", async () => { |
||||
|
|
||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "babyadd_tester.circom")); |
||||
|
|
||||
|
// console.log(JSON.stringify(cirDef, null, 1));
|
||||
|
|
||||
|
// assert.equal(cirDef.nVars, 2);
|
||||
|
|
||||
|
const circuit = new zkSnark.Circuit(cirDef); |
||||
|
|
||||
|
console.log("NConstrains: " + circuit.nConstraints); |
||||
|
|
||||
|
const input={ |
||||
|
x1: zkSnark.bigInt(0), |
||||
|
y1: zkSnark.bigInt(1), |
||||
|
x2: zkSnark.bigInt(0), |
||||
|
y2: zkSnark.bigInt(1) |
||||
|
} |
||||
|
|
||||
|
const w = circuit.calculateWitness(input); |
||||
|
|
||||
|
const xout = w[circuit.getSignalIdx("main.xout")]; |
||||
|
const yout = w[circuit.getSignalIdx("main.yout")]; |
||||
|
|
||||
|
assert(xout.equals(0)); |
||||
|
assert(yout.equals(1)); |
||||
|
}); |
||||
|
|
||||
|
it("Should add 2 same numbers", async () => { |
||||
|
|
||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "babyadd_tester.circom")); |
||||
|
|
||||
|
// console.log(JSON.stringify(cirDef, null, 1));
|
||||
|
|
||||
|
// assert.equal(cirDef.nVars, 2);
|
||||
|
|
||||
|
const circuit = new zkSnark.Circuit(cirDef); |
||||
|
|
||||
|
console.log("NConstrains: " + circuit.nConstraints); |
||||
|
|
||||
|
const input={ |
||||
|
x1: zkSnark.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), |
||||
|
y1: zkSnark.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), |
||||
|
x2: zkSnark.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), |
||||
|
y2: zkSnark.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475") |
||||
|
} |
||||
|
|
||||
|
const w = circuit.calculateWitness(input); |
||||
|
|
||||
|
const xout = w[circuit.getSignalIdx("main.xout")]; |
||||
|
const yout = w[circuit.getSignalIdx("main.yout")]; |
||||
|
|
||||
|
assert(xout.equals(zkSnark.bigInt("6890855772600357754907169075114257697580319025794532037257385534741338397365"))); |
||||
|
assert(yout.equals(zkSnark.bigInt("4338620300185947561074059802482547481416142213883829469920100239455078257889"))); |
||||
|
}); |
||||
|
|
||||
|
it("Should add 2 different numbers", async () => { |
||||
|
|
||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "babyadd_tester.circom")); |
||||
|
|
||||
|
// console.log(JSON.stringify(cirDef, null, 1));
|
||||
|
|
||||
|
// assert.equal(cirDef.nVars, 2);
|
||||
|
|
||||
|
const circuit = new zkSnark.Circuit(cirDef); |
||||
|
|
||||
|
console.log("NConstrains: " + circuit.nConstraints); |
||||
|
|
||||
|
const input={ |
||||
|
x1: zkSnark.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), |
||||
|
y1: zkSnark.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475"), |
||||
|
x2: zkSnark.bigInt("16540640123574156134436876038791482806971768689494387082833631921987005038935"), |
||||
|
y2: zkSnark.bigInt("20819045374670962167435360035096875258406992893633759881276124905556507972311") |
||||
|
} |
||||
|
|
||||
|
const w = circuit.calculateWitness(input); |
||||
|
|
||||
|
const xout = w[circuit.getSignalIdx("main.xout")]; |
||||
|
const yout = w[circuit.getSignalIdx("main.yout")]; |
||||
|
|
||||
|
console.log(xout.toString()); |
||||
|
console.log(yout.toString()); |
||||
|
|
||||
|
assert(xout.equals(zkSnark.bigInt("7916061937171219682591368294088513039687205273691143098332585753343424131937"))); |
||||
|
assert(yout.equals(zkSnark.bigInt("14035240266687799601661095864649209771790948434046947201833777492504781204499"))); |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,3 @@ |
|||||
|
include "../../circuit/babyjub.circom"; |
||||
|
|
||||
|
component main = BabyAdd(); |
@ -0,0 +1,24 @@ |
|||||
|
include "../../circuit/exp.circom"; |
||||
|
include "../../node_modules/circom/circuits/sha256/bitify.circom"; |
||||
|
|
||||
|
|
||||
|
template Main() { |
||||
|
signal input in; |
||||
|
signal output out[2]; |
||||
|
|
||||
|
component n2b = Num2Bits(253); |
||||
|
component exp = Exp(253); |
||||
|
|
||||
|
var i; |
||||
|
|
||||
|
in ==> n2b.in; |
||||
|
|
||||
|
for (i=0; i<253; i++) { |
||||
|
n2b.out[i] ==> exp.in[i]; |
||||
|
} |
||||
|
|
||||
|
exp.out[0] ==> out[0]; |
||||
|
exp.out[1] ==> out[1]; |
||||
|
} |
||||
|
|
||||
|
component main = Main(); |
@ -0,0 +1,20 @@ |
|||||
|
include "../../circuit/exp.circom"; |
||||
|
|
||||
|
|
||||
|
template Main() { |
||||
|
signal input in[256]; |
||||
|
signal output out[2]; |
||||
|
|
||||
|
var i; |
||||
|
|
||||
|
component exp = Exp(256); |
||||
|
|
||||
|
for (i=0; i<256; i++) { |
||||
|
in[i] ==> exp.in[i]; |
||||
|
} |
||||
|
|
||||
|
exp.out[0] ==> out[0]; |
||||
|
exp.out[1] ==> out[1]; |
||||
|
} |
||||
|
|
||||
|
component main = Main(); |
@ -0,0 +1,3 @@ |
|||||
|
include "../../circuit/ExpW4Table.circom"; |
||||
|
|
||||
|
component main = ExpW4Table(0); |
@ -0,0 +1,3 @@ |
|||||
|
include "../../circuit/ExpW4Table.circom"; |
||||
|
|
||||
|
component main = ExpW4Table(3); |
@ -0,0 +1,54 @@ |
|||||
|
include "../../circuit/mux4.circom"; |
||||
|
include "../../node_modules/circom/circuits/sha256/bitify.circom"; |
||||
|
|
||||
|
|
||||
|
template Constants() { |
||||
|
var i; |
||||
|
signal output out[16]; |
||||
|
|
||||
|
out[0] <== 123; |
||||
|
out[1] <== 456; |
||||
|
out[2] <== 789; |
||||
|
out[3] <== 012; |
||||
|
out[4] <== 111; |
||||
|
out[5] <== 222; |
||||
|
out[6] <== 333; |
||||
|
out[7] <== 4546; |
||||
|
out[8] <== 134523; |
||||
|
out[9] <== 44356; |
||||
|
out[10] <== 15623; |
||||
|
out[11] <== 4566; |
||||
|
out[12] <== 1223; |
||||
|
out[13] <== 4546; |
||||
|
out[14] <== 4256; |
||||
|
out[15] <== 4456; |
||||
|
|
||||
|
/* |
||||
|
for (i=0;i<16; i++) { |
||||
|
out[i] <== i*2+100; |
||||
|
} |
||||
|
*/ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
template Main() { |
||||
|
var i; |
||||
|
signal private input selector; |
||||
|
signal output out; |
||||
|
|
||||
|
component mux = Mux4(); |
||||
|
component n2b = Num2Bits(4); |
||||
|
component cst = Constants(); |
||||
|
|
||||
|
selector ==> n2b.in; |
||||
|
for (i=0; i<4; i++) { |
||||
|
n2b.out[i] ==> mux.s[i]; |
||||
|
} |
||||
|
for (i=0; i<16; i++) { |
||||
|
cst.out[i] ==> mux.c[i]; |
||||
|
} |
||||
|
|
||||
|
mux.out ==> out; |
||||
|
} |
||||
|
|
||||
|
component main = Main(); |
@ -0,0 +1,168 @@ |
|||||
|
const chai = require("chai"); |
||||
|
const path = require("path"); |
||||
|
const zkSnark = require("zksnark"); |
||||
|
const compiler = require("circom"); |
||||
|
|
||||
|
const assert = chai.assert; |
||||
|
|
||||
|
const bigInt = require("big-integer"); |
||||
|
|
||||
|
|
||||
|
const q=21888242871839275222246405745257275088548364400416034343698204186575808495617n |
||||
|
function addPoint(a,b) { |
||||
|
const cta = 168700n; |
||||
|
const d = 168696n; |
||||
|
|
||||
|
const res = []; |
||||
|
res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(1n + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q); |
||||
|
res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(1n - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q); |
||||
|
return res; |
||||
|
} |
||||
|
|
||||
|
function print(circuit, w, s) { |
||||
|
console.log(s + ": " + w[circuit.getSignalIdx(s)]); |
||||
|
} |
||||
|
|
||||
|
describe("Exponentioation test", () => { |
||||
|
it("Should generate the Exponentiation table in k=0", async () => { |
||||
|
|
||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "expw4table_test.circom")); |
||||
|
|
||||
|
// console.log(JSON.stringify(cirDef, null, 1));
|
||||
|
|
||||
|
// assert.equal(cirDef.nVars, 2);
|
||||
|
|
||||
|
const circuit = new zkSnark.Circuit(cirDef); |
||||
|
|
||||
|
console.log("NConstrains: " + circuit.nConstraints); |
||||
|
|
||||
|
const w = circuit.calculateWitness({}); |
||||
|
|
||||
|
let g = [zkSnark.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), |
||||
|
zkSnark.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475")] |
||||
|
|
||||
|
dbl= [zkSnark.bigInt("0"), zkSnark.bigInt("1")]; |
||||
|
|
||||
|
for (let i=0; i<16; i++) { |
||||
|
const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)]; |
||||
|
const yout1 = w[circuit.getSignalIdx(`main.out[${i}][1]`)]; |
||||
|
/* |
||||
|
console.log(xout1.toString()); |
||||
|
console.log(yout1.toString()); |
||||
|
console.log(dbl[0]); |
||||
|
console.log(dbl[1]); |
||||
|
*/ |
||||
|
assert(xout1.equals(dbl[0])); |
||||
|
assert(yout1.equals(dbl[1])); |
||||
|
|
||||
|
dbl = addPoint([xout1, yout1],g); |
||||
|
} |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
it("Should generate the Exponentiation table in k=3", async () => { |
||||
|
|
||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "expw4table_test3.circom")); |
||||
|
|
||||
|
// console.log(JSON.stringify(cirDef, null, 1));
|
||||
|
|
||||
|
// assert.equal(cirDef.nVars, 2);
|
||||
|
|
||||
|
const circuit = new zkSnark.Circuit(cirDef); |
||||
|
|
||||
|
console.log("NConstrains: " + circuit.nConstraints); |
||||
|
|
||||
|
const w = circuit.calculateWitness({}); |
||||
|
|
||||
|
let g = [zkSnark.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), |
||||
|
zkSnark.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475")] |
||||
|
|
||||
|
for (let i=0; i<12;i++) { |
||||
|
g = addPoint(g,g); |
||||
|
} |
||||
|
|
||||
|
dbl= [zkSnark.bigInt("0"), zkSnark.bigInt("1")]; |
||||
|
|
||||
|
for (let i=0; i<16; i++) { |
||||
|
const xout1 = w[circuit.getSignalIdx(`main.out[${i}][0]`)]; |
||||
|
const yout1 = w[circuit.getSignalIdx(`main.out[${i}][1]`)]; |
||||
|
|
||||
|
/* |
||||
|
console.log(xout1.toString()); |
||||
|
console.log(yout1.toString()); |
||||
|
console.log(dbl[0]); |
||||
|
console.log(dbl[1]); |
||||
|
*/ |
||||
|
assert(xout1.equals(dbl[0])); |
||||
|
assert(yout1.equals(dbl[1])); |
||||
|
|
||||
|
dbl = addPoint([xout1, yout1],g); |
||||
|
} |
||||
|
|
||||
|
}); |
||||
|
|
||||
|
it("Should exponentiate g^31", async () => { |
||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "exp_test.circom")); |
||||
|
|
||||
|
// console.log(JSON.stringify(cirDef, null, 1));
|
||||
|
|
||||
|
// assert.equal(cirDef.nVars, 2);
|
||||
|
|
||||
|
const circuit = new zkSnark.Circuit(cirDef); |
||||
|
|
||||
|
console.log("NConstrains: " + circuit.nConstraints); |
||||
|
|
||||
|
const w = circuit.calculateWitness({"in": 31}); |
||||
|
|
||||
|
assert(circuit.checkWitness(w)); |
||||
|
|
||||
|
let g = [zkSnark.bigInt("17777552123799933955779906779655732241715742912184938656739573121738514868268"), |
||||
|
zkSnark.bigInt("2626589144620713026669568689430873010625803728049924121243784502389097019475")] |
||||
|
|
||||
|
let c = [0n, 1n]; |
||||
|
|
||||
|
for (let i=0; i<31;i++) { |
||||
|
c = addPoint(c,g); |
||||
|
} |
||||
|
|
||||
|
const xout = w[circuit.getSignalIdx(`main.out[0]`)]; |
||||
|
const yout = w[circuit.getSignalIdx(`main.out[1]`)]; |
||||
|
|
||||
|
/* |
||||
|
console.log(xout.toString()); |
||||
|
console.log(yout.toString()); |
||||
|
*/ |
||||
|
assert(xout.equals(c[0])); |
||||
|
assert(yout.equals(c[1])); |
||||
|
|
||||
|
console.log("-------") |
||||
|
const w2 = circuit.calculateWitness({"in": (1n<<252n)+1n}); |
||||
|
|
||||
|
const xout2 = w2[circuit.getSignalIdx(`main.out[0]`)]; |
||||
|
const yout2 = w2[circuit.getSignalIdx(`main.out[1]`)]; |
||||
|
|
||||
|
c = [g[0], g[1]]; |
||||
|
for (let i=0; i<252;i++) { |
||||
|
c = addPoint(c,c); |
||||
|
} |
||||
|
c = addPoint(c,g); |
||||
|
/* |
||||
|
console.log(xout2.toString()); |
||||
|
console.log(yout2.toString()); |
||||
|
console.log(c[0].toString()); |
||||
|
console.log(c[1].toString()); |
||||
|
*/ |
||||
|
assert(xout2.equals(c[0])); |
||||
|
assert(yout2.equals(c[1])); |
||||
|
|
||||
|
}).timeout(10000000); |
||||
|
|
||||
|
it("Number of constrains for 256 bits", async () => { |
||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "exp_test_min.circom")); |
||||
|
|
||||
|
const circuit = new zkSnark.Circuit(cirDef); |
||||
|
|
||||
|
console.log("NConstrains: " + circuit.nConstraints); |
||||
|
}).timeout(10000000); |
||||
|
|
||||
|
}); |
@ -0,0 +1,33 @@ |
|||||
|
const chai = require("chai"); |
||||
|
const path = require("path"); |
||||
|
const zkSnark = require("zksnark"); |
||||
|
const compiler = require("circom"); |
||||
|
|
||||
|
const assert = chai.assert; |
||||
|
|
||||
|
const bigInt = require("big-integer"); |
||||
|
|
||||
|
|
||||
|
describe("Mux4 test", () => { |
||||
|
it("Should create a constant multiplexer", async () => { |
||||
|
|
||||
|
const cirDef = await compiler(path.join(__dirname, "circuits", "mux4_1.circom")); |
||||
|
|
||||
|
// console.log(JSON.stringify(cirDef, null, 1));
|
||||
|
|
||||
|
// assert.equal(cirDef.nVars, 2);
|
||||
|
|
||||
|
const circuit = new zkSnark.Circuit(cirDef); |
||||
|
|
||||
|
console.log("NConstrains: " + circuit.nConstraints); |
||||
|
|
||||
|
for (i=0; i<16; i++) { |
||||
|
const w = circuit.calculateWitness({ "selector": zkSnark.bigInt(i).toString() }); |
||||
|
|
||||
|
assert(w[0].equals(zkSnark.bigInt(1))); |
||||
|
|
||||
|
console.log(i + " -> " + w[circuit.getSignalIdx("main.out")].toString()); |
||||
|
// assert(w[circuit.getSignalIdx("main.out")].equals(zkSnark.bigInt("100").add(zkSnark.bigInt(i))));
|
||||
|
} |
||||
|
}); |
||||
|
}); |