Browse Source

First iteration sha256

wasm
Jordi Baylina 6 years ago
parent
commit
2f1e74dd38
No known key found for this signature in database GPG Key ID: 7480C80C1BE43112
16 changed files with 2658 additions and 128 deletions
  1. +0
    -18
      circuits/gates.circom
  2. +27
    -0
      circuits/sha256/ch.circom
  3. +49
    -0
      circuits/sha256/gates.circom
  4. +8
    -43
      circuits/sha256/main.circom
  5. +25
    -0
      circuits/sha256/maj.circom
  6. +4
    -4
      circuits/sha256/sha256_2.circom
  7. +42
    -50
      circuits/sha256/sha256compression.circom
  8. +3
    -3
      circuits/sha256/sigma.circom
  9. +2
    -2
      circuits/sha256/sigmaplus.circom
  10. +33
    -0
      circuits/sha256/t1.circom
  11. +28
    -0
      circuits/sha256/t2.circom
  12. +25
    -0
      circuits/sha256/xor3.circom
  13. +8
    -8
      package-lock.json
  14. +2371
    -0
      test/circuits/out.json
  15. +15
    -0
      test/circuits/sha256_2_test.circom
  16. +18
    -0
      test/sha256.js

+ 0
- 18
circuits/gates.circom

@ -46,22 +46,4 @@ template NOR() {
out <== a*b + 1 - a - b; out <== a*b + 1 - a - b;
} }
template Xor3(n) {
signal input a[n];
signal input b[n];
signal input c[n];
signal output out[n];
component xor1[n] = XOR();
component xor2[n] = XOR();
for (var k=0; k<n; k++) {
xor1[k].a <== a[k];
xor1[k].b <== b[k];
xor2[k].a <== xor1[k].out;
xor2[k].b <== c[k];
out[k] <== xor2[k].out;
}
}

+ 27
- 0
circuits/sha256/ch.circom

@ -0,0 +1,27 @@
/* Ch
000 0
001 1
010 0
011 1
100 0
101 0
110 1
111 1
out = a&b ^ (!a)&c =>
out = a*(b-c) + c
*/
template Ch(n) {
signal input a[n];
signal input b[n];
signal input c[n];
signal output out[n];
for (var k=0; k<n; k++) {
out[k] <== a[k] * (b[k]-c[k]) + c[k];
}
}

+ 49
- 0
circuits/sha256/gates.circom

@ -0,0 +1,49 @@
template XOR() {
signal input a;
signal input b;
signal output out;
out <== a + b - 2*a*b;
}
template AND() {
signal input a;
signal input b;
signal output out;
out <== a*b;
}
template OR() {
signal input a;
signal input b;
signal output out;
out <== a + b - a*b;
}
template NOT() {
signal input in;
signal output out;
out <== 1 + in - 2*in;
}
template NAND() {
signal input a;
signal input b;
signal output out;
out <== 1 - a*b;
}
template NOR() {
signal input a;
signal input b;
signal output out;
out <== a*b + 1 - a - b;
}

+ 8
- 43
circuits/sha256/main.circom

@ -1,50 +1,15 @@
/*
include "sha256_2.jaz"; include "sha256_2.jaz";
component main = SHA256_2();
*/
/*
include "constants.jaz"
template A() {
signal input in;
component h0;
h0 = K(8);
var lc = 0;
var e = 1;
for (var i=0; i<32; i++) {
lc = lc + e*h0.out[i];
e *= 2;
}
lc === in;
}
component main = A();
*/
include "bitify.jaz"
template A() {
signal input in;
template Main() {
signal private input a;
signal private input b;
signal output out; signal output out;
component n2b;
component b2n;
n2b = Num2Bits(216);
b2n = Bits2Num(216);
n2b.in <== in;
for (var i=0; i<216; i++) {
b2n.in[i] <== n2b.out[i];
}
component sha256_2 = SHA256_2();
out <== b2n.out;
sha256_2.a <== a;
sha256_2.b <== a;
out <== sha256_2.out;
} }
component main = A();
component main = Main();

+ 25
- 0
circuits/sha256/maj.circom

@ -0,0 +1,25 @@
/* Maj function for sha256
out = a&b ^ a&c ^ b&c =>
out = a*b + a*c + b*c - 2*a*b*c =>
out = a*( b + c - 2*b*c ) + b*c =>
mid = b*c
out = a*( b + c - 2*mid ) + mid
*/
template Maj(n) {
signal input a[n];
signal input b[n];
signal input c[n];
signal output out[n];
signal mid[n];
for (var k=0; k<n; k++) {
mid[k] <== b[k]*c[k];
out[k] <== a[k] * (b[k]+c[k]-2*mid[k]) + mid[k];
}
}

+ 4
- 4
circuits/sha256/sha256_2.circom

@ -1,14 +1,14 @@
include "sha256compression.jaz";
include "bitify.jaz"
include "sha256compression.circom";
include "bitify.circom"
component sha256_2() {
template Sha256_2() {
signal input a; signal input a;
signal input b; signal input b;
signal output out; signal output out;
component num2bits[2] = Num2Bits(216);
component bits2num = Bits2Num(216); component bits2num = Bits2Num(216);
component num2bits[2] = Num2Bits(216);
num2bits[0].inp <== a; num2bits[0].inp <== a;
num2bits[1].inp <== b; num2bits[1].inp <== b;

+ 42
- 50
circuits/sha256/sha256compression.circom

@ -1,11 +1,11 @@
include "constants.jaz";
include "t1.jaz";
include "t2.jaz";
include "binsum.jaz";
include "sigmaplus.jaz";
include "constants.circom";
include "t1.circom";
include "t2.circom";
include "binsum.circom";
include "sigmaplus.circom";
template sha256compression() {
template Sha256compression() {
signal input inp[512]; signal input inp[512];
signal output out[256]; signal output out[256];
signal a[64][32]; signal a[64][32];
@ -16,14 +16,14 @@ template sha256compression() {
signal f[64][32]; signal f[64][32];
signal g[64][32]; signal g[64][32];
signal h[64][32]; signal h[64][32];
signal w[64][512];
signal w[64][32];
var i; var i;
component sigmaPlus[48] = SigmaPlus(); component sigmaPlus[48] = SigmaPlus();
component k[64];
for (i=0; i<64; i++) k[i] = K(i);
component ct_k[64];
for (i=0; i<64; i++) ct_k[i] = K(i);
component ha0 = H0(0); component ha0 = H0(0);
component hb0 = H0(1); component hb0 = H0(1);
@ -37,20 +37,20 @@ template sha256compression() {
component t1[64] = T1(); component t1[64] = T1();
component t2[64] = T2(); component t2[64] = T2();
component suma[64] = Sum2(32);
component sume[64] = Sum2(32);
component fsum[8] = Sum2(32);
component suma[64] = Sum(32, 2);
component sume[64] = Sum(32, 2);
component fsum[8] = Sum(32, 2);
var k; var k;
var t; var t;
for (t=0; t<64; t++) { for (t=0; t<64; t++) {
if (t<16) { if (t<16) {
for (k=0; k<256; k++) {
w[t][k] <== inp[k];
for (k=0; k<32; k++) {
w[t][k] <== inp[t*32+k];
} }
} else { } else {
for (k=0; k<256; k++) {
for (k=0; k<32; k++) {
sigmaPlus[t-16].in2[k] <== w[t-2][k]; sigmaPlus[t-16].in2[k] <== w[t-2][k];
sigmaPlus[t-16].in7[k] <== w[t-2][k]; sigmaPlus[t-16].in7[k] <== w[t-2][k];
sigmaPlus[t-16].in15[k] <== w[t-15][k]; sigmaPlus[t-16].in15[k] <== w[t-15][k];
@ -77,20 +77,12 @@ template sha256compression() {
t1[t].e[k] <== e[k]; t1[t].e[k] <== e[k];
t1[t].f[k] <== f[k]; t1[t].f[k] <== f[k];
t1[t].g[k] <== g[k]; t1[t].g[k] <== g[k];
if (t<20) {
t1[t].g[k] <== K0.out[k];
} else if (t<40) {
t1[t].g[k] <== K20.out[k];
} else if (t<60) {
t1[t].g[k] <== K40.out[k];
} else {
t1[t].g[k] <== K60.out[k];
}
t1[t].k[k] <== ct_K[t].out[k];
t1[t].w[k] <== w[t][k]; t1[t].w[k] <== w[t][k];
t2[t].a[k] <== a[k]; t2[t].a[k] <== a[k];
t2[t].b[k] <== a[k];
t2[t].c[k] <== a[k];
t2[t].b[k] <== b[k];
t2[t].c[k] <== c[k];
} }
for (k=0; k<32; k++) { for (k=0; k<32; k++) {
@ -114,32 +106,32 @@ template sha256compression() {
} }
for (k=0; k<32; k++) { for (k=0; k<32; k++) {
fsum[0].a[k] <== ha0.out[k];
fsum[0].b[k] <== a[64][k];
fsum[1].a[k] <== hb0.out[k];
fsum[1].b[k] <== b[64][k];
fsum[2].a[k] <== hc0.out[k];
fsum[2].b[k] <== c[64][k];
fsum[3].a[k] <== hd0.out[k];
fsum[3].b[k] <== d[64][k];
fsum[4].a[k] <== he0.out[k];
fsum[4].b[k] <== e[64][k];
fsum[5].a[k] <== hf0.out[k];
fsum[5].b[k] <== f[64][k];
fsum[6].a[k] <== hg0.out[k];
fsum[6].b[k] <== g[64][k];
fsum[7].a[k] <== hh0.out[k];
fsum[7].b[k] <== h[64][k];
fsum[0].in[0][k] <== ha0.out[k];
fsum[0].in[1][k] <== a[64][k];
fsum[1].in[0][k] <== hb0.out[k];
fsum[1].in[1][k] <== b[64][k];
fsum[2].in[0][k] <== hc0.out[k];
fsum[2].in[1][k] <== c[64][k];
fsum[3].in[0][k] <== hd0.out[k];
fsum[3].in[1][k] <== d[64][k];
fsum[4].in[0][k] <== he0.out[k];
fsum[4].in[1][k] <== e[64][k];
fsum[5].in[0][k] <== hf0.out[k];
fsum[5].in[1][k] <== f[64][k];
fsum[6].in[0][k] <== hg0.out[k];
fsum[6].in[1][k] <== g[64][k];
fsum[7].in[0][k] <== hh0.out[k];
fsum[7].in[1][k] <== h[64][k];
} }
for (k=0; k<32; k++) { for (k=0; k<32; k++) {
out[k] <== fsum[0].out[k];
out[32+k] <== fsum[1].out[k];
out[64+k] <== fsum[2].out[k];
out[96+k] <== fsum[2].out[k];
out[128+k] <== fsum[2].out[k];
out[160+k] <== fsum[2].out[k];
out[192+k] <== fsum[2].out[k];
out[224+k] <== fsum[2].out[k];
out[k] <== fsum[0].out[k];
out[32+k] <== fsum[1].out[k];
out[64+k] <== fsum[2].out[k];
out[96+k] <== fsum[3].out[k];
out[128+k] <== fsum[4].out[k];
out[160+k] <== fsum[5].out[k];
out[192+k] <== fsum[6].out[k];
out[224+k] <== fsum[7].out[k];
} }
} }

+ 3
- 3
circuits/sha256/sigma.circom

@ -1,8 +1,8 @@
include "gates.jaz";
include "rotate.jaz";
include "xor3.circom";
include "rotate.circom";
template Sigma(ra, rb, rc) { template Sigma(ra, rb, rc) {
signal input in;
signal input in[32];
signal output out; signal output out;
component xor3 = Xor3(32); component xor3 = Xor3(32);

+ 2
- 2
circuits/sha256/sigmaplus.circom

@ -1,5 +1,5 @@
include "sum.jaz"
include "sigma.jaz"
include "binsum.circom"
include "sigma.circom"
template SigmaPlus() { template SigmaPlus() {
signal input in2[32]; signal input in2[32];

+ 33
- 0
circuits/sha256/t1.circom

@ -0,0 +1,33 @@
include "binsum.circom";
include "sigma.circom";
include "ch.circom";
template T1() {
signal input h[32];
signal input e[32];
signal input f[32];
signal input g[32];
signal input k[32];
signal input w[32];
signal output out[32];
component sum = Sum(32, 5);
component ch = Ch(32);
component bigsigma1 = Sigma(6, 11, 25);
for (var k=0; k<32; k++) {
bigsigma1.in[k] <== e[k];
ch.a[k] <== e[k];
ch.b[k] <== f[k];
ch.c[k] <== g[k]
sum.in[0][k] <== h[k];
sum.in[1][k] <== bigsigma1.out[k];
sum.in[2][k] <== ch.out[k];
sum.in[3][k] <== k[k];
sum.in[4][k] <== w[k];
out[k] <== sum.out[k];
}
}

+ 28
- 0
circuits/sha256/t2.circom

@ -0,0 +1,28 @@
include "binsum.circom";
include "sigma.circom";
include "maj.circom"
template T2() {
signal input a[32];
signal input b[32];
signal input c[32];
signal output out[32];
component sum = Sum(32, 2);
component bigsigma0 = Sigma(2, 13, 22);
component maj = Maj(32);
for (var k=0; k<32; k++) {
bigsigma0.in[k] <== a[k];
maj.a[k] <== a[k];
maj.b[k] <== b[k];
maj.c[k] <== c[k];
sum.in[0][k] <== bigsigma0.out[k];
sum.in[1][k] <== maj.out[k];
out[k] <== sum.out[k];
}
}

+ 25
- 0
circuits/sha256/xor3.circom

@ -0,0 +1,25 @@
/* Xor3 function for sha256
out = a ^ b ^ c =>
out = a+b+c - 2*a*b - 2*a*c - 2*b*c + 4*a*b*c =>
out = a*( 1 - 2*b - 2*c + 4*b*c ) + b + c - 2*b*c =>
mid = b*c
out = a*( 1 - 2*b -2*c + 4*mid ) + b + c - 2 * mid
*/
template Xor3(n) {
signal input a[n];
signal input b[n];
signal input c[n];
signal output out[n];
signal mid[n];
for (var k=0; k<n; k++) {
mid[k] <== b[k]*c[k];
out[k] <== a[k] * (1 -2*b[k] -2*c[k] +4*mid[k]) + b[k] + c[k] -2*mid[k];
}
}

+ 8
- 8
package-lock.json

@ -1,6 +1,6 @@
{ {
"name": "circom", "name": "circom",
"version": "0.0.2",
"version": "0.0.5",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -1470,12 +1470,12 @@
} }
}, },
"zksnark": { "zksnark": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/zksnark/-/zksnark-0.0.2.tgz",
"integrity": "sha512-+MYducXidMTCRRuxSLLNXBEQRIzi8nA7us2jDzlf8d+yySFRymK56z7tQUics97nl1+AoGH40GhtNlWgTFBbig==",
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/zksnark/-/zksnark-0.0.5.tgz",
"integrity": "sha512-GmcAzmFdDI5iF7SHUiFOHnhZdW++7lbwttuZMEOEFkWHTg4Hk+dlmcYAGZ0LjpCf0zRTALODt6nystuUXF6RRw==",
"dev": true, "dev": true,
"requires": { "requires": {
"big-integer": "^1.6.34",
"big-integer": "^1.6.35",
"chai": "^4.1.2", "chai": "^4.1.2",
"eslint": "^5.3.0" "eslint": "^5.3.0"
}, },
@ -1493,9 +1493,9 @@
} }
}, },
"big-integer": { "big-integer": {
"version": "1.6.35",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.35.tgz",
"integrity": "sha512-jqLsX6dzmPHOhApAUyGwrpzqn3DXpdTqbOM6baPys7A423ys7IsTpcucDVGP0PmzxGsPYbW3xVOJ4SxAzI0vqQ==",
"version": "1.6.36",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.36.tgz",
"integrity": "sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==",
"dev": true "dev": true
}, },
"chardet": { "chardet": {

+ 2371
- 0
test/circuits/out.json
File diff suppressed because it is too large
View File


+ 15
- 0
test/circuits/sha256_2_test.circom

@ -0,0 +1,15 @@
include "../../circuits/sha256/sha256_2.circom";
template Main() {
signal private input a;
signal private input b;
signal output out;
component sha256_2 = Sha256_2();
sha256_2.a <== a;
sha256_2.b <== a;
out <== sha256_2.out;
}
component main = Main();

+ 18
- 0
test/sha256.js

@ -1,6 +1,7 @@
const chai = require("chai"); const chai = require("chai");
const path = require("path"); const path = require("path");
const zkSnark = require("zksnark"); const zkSnark = require("zksnark");
const crypto = require("crypto");
const compiler = require("../index.js"); const compiler = require("../index.js");
@ -31,6 +32,23 @@ describe("SHA256 test", () => {
assert(witness[0].equals(zkSnark.bigInt(1))); assert(witness[0].equals(zkSnark.bigInt(1)));
assert(witness[1].equals(zkSnark.bigInt("333"))); assert(witness[1].equals(zkSnark.bigInt("333")));
}); });
it("Should calculate a hash", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "sha256_2_test.circom"));
const circuit = new zkSnark.Circuit(cirDef);
const witness = circuit.calculateWitness({ "a": "1", "b": "2" });
const b = new Buffer.alloc(432);
b[115] = 1;
b[431] = 2;
const hash = crypto.createHash("sha256")
.update(b)
.digest("hex");
const r = "0x" + hash.slice(40);
assert(witness[1].equals(zkSnark.bigInt(r)));
});
}); });

Loading…
Cancel
Save