@ -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))));
|
|||
} |
|||
}); |
|||
}); |