mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-06 18:56:40 +01:00
First iteration sha256
This commit is contained in:
@@ -46,22 +46,4 @@ template NOR() {
|
||||
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
circuits/sha256/ch.circom
Normal file
27
circuits/sha256/ch.circom
Normal file
@@ -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
circuits/sha256/gates.circom
Normal file
49
circuits/sha256/gates.circom
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,50 +1,15 @@
|
||||
|
||||
/*
|
||||
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;
|
||||
|
||||
component n2b;
|
||||
component b2n;
|
||||
component sha256_2 = SHA256_2();
|
||||
|
||||
n2b = Num2Bits(216);
|
||||
b2n = Bits2Num(216);
|
||||
|
||||
n2b.in <== in;
|
||||
|
||||
for (var i=0; i<216; i++) {
|
||||
b2n.in[i] <== n2b.out[i];
|
||||
}
|
||||
|
||||
out <== b2n.out;
|
||||
sha256_2.a <== a;
|
||||
sha256_2.b <== a;
|
||||
out <== sha256_2.out;
|
||||
}
|
||||
|
||||
component main = A();
|
||||
component main = Main();
|
||||
|
||||
25
circuits/sha256/maj.circom
Normal file
25
circuits/sha256/maj.circom
Normal file
@@ -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];
|
||||
}
|
||||
}
|
||||
@@ -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 b;
|
||||
signal output out;
|
||||
|
||||
component num2bits[2] = Num2Bits(216);
|
||||
component bits2num = Bits2Num(216);
|
||||
component num2bits[2] = Num2Bits(216);
|
||||
|
||||
num2bits[0].inp <== a;
|
||||
num2bits[1].inp <== b;
|
||||
|
||||
@@ -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 output out[256];
|
||||
signal a[64][32];
|
||||
@@ -16,14 +16,14 @@ template sha256compression() {
|
||||
signal f[64][32];
|
||||
signal g[64][32];
|
||||
signal h[64][32];
|
||||
signal w[64][512];
|
||||
signal w[64][32];
|
||||
|
||||
var i;
|
||||
|
||||
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 hb0 = H0(1);
|
||||
@@ -37,20 +37,20 @@ template sha256compression() {
|
||||
component t1[64] = T1();
|
||||
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 t;
|
||||
|
||||
for (t=0; t<64; t++) {
|
||||
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 {
|
||||
for (k=0; k<256; k++) {
|
||||
for (k=0; k<32; k++) {
|
||||
sigmaPlus[t-16].in2[k] <== w[t-2][k];
|
||||
sigmaPlus[t-16].in7[k] <== w[t-2][k];
|
||||
sigmaPlus[t-16].in15[k] <== w[t-15][k];
|
||||
@@ -77,20 +77,12 @@ template sha256compression() {
|
||||
t1[t].e[k] <== e[k];
|
||||
t1[t].f[k] <== f[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];
|
||||
|
||||
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++) {
|
||||
@@ -114,32 +106,32 @@ template sha256compression() {
|
||||
}
|
||||
|
||||
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++) {
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
include "gates.jaz";
|
||||
include "rotate.jaz";
|
||||
include "xor3.circom";
|
||||
include "rotate.circom";
|
||||
|
||||
template Sigma(ra, rb, rc) {
|
||||
signal input in;
|
||||
signal input in[32];
|
||||
signal output out;
|
||||
|
||||
component xor3 = Xor3(32);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
include "sum.jaz"
|
||||
include "sigma.jaz"
|
||||
include "binsum.circom"
|
||||
include "sigma.circom"
|
||||
|
||||
template SigmaPlus() {
|
||||
signal input in2[32];
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
circuits/sha256/xor3.circom
Normal file
25
circuits/sha256/xor3.circom
Normal file
@@ -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];
|
||||
}
|
||||
}
|
||||
16
package-lock.json
generated
16
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "circom",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.5",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -1470,12 +1470,12 @@
|
||||
}
|
||||
},
|
||||
"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,
|
||||
"requires": {
|
||||
"big-integer": "^1.6.34",
|
||||
"big-integer": "^1.6.35",
|
||||
"chai": "^4.1.2",
|
||||
"eslint": "^5.3.0"
|
||||
},
|
||||
@@ -1493,9 +1493,9 @@
|
||||
}
|
||||
},
|
||||
"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
|
||||
},
|
||||
"chardet": {
|
||||
|
||||
2371
test/circuits/out.json
Normal file
2371
test/circuits/out.json
Normal file
File diff suppressed because it is too large
Load Diff
15
test/circuits/sha256_2_test.circom
Normal file
15
test/circuits/sha256_2_test.circom
Normal file
@@ -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();
|
||||
@@ -1,6 +1,7 @@
|
||||
const chai = require("chai");
|
||||
const path = require("path");
|
||||
const zkSnark = require("zksnark");
|
||||
const crypto = require("crypto");
|
||||
|
||||
const compiler = require("../index.js");
|
||||
|
||||
@@ -31,6 +32,23 @@ describe("SHA256 test", () => {
|
||||
assert(witness[0].equals(zkSnark.bigInt(1)));
|
||||
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)));
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user