@ -1,227 +0,0 @@ |
|||||
pragma circom 2.0.0; |
|
||||
|
|
||||
include "./utils.circom"; |
|
||||
|
|
||||
template step() { |
|
||||
// out = a ^ (^b) & c |
|
||||
signal input a[64]; |
|
||||
signal input b[64]; |
|
||||
signal input c[64]; |
|
||||
signal output out[64]; |
|
||||
var i; |
|
||||
|
|
||||
// ^b |
|
||||
component bXor = XorArraySingle(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
bXor.a[i] <== b[i]; |
|
||||
} |
|
||||
// (^b)&c |
|
||||
component bc = AndArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
bc.a[i] <== bXor.out[i]; |
|
||||
bc.b[i] <== c[i]; |
|
||||
} |
|
||||
// a^(^b)&c |
|
||||
component abc = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
abc.a[i] <== a[i]; |
|
||||
abc.b[i] <== bc.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[i] <== abc.out[i]; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
template Chi() { |
|
||||
signal input in[25*64]; |
|
||||
signal output out[25*64]; |
|
||||
|
|
||||
var i; |
|
||||
|
|
||||
component r0 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r0.a[i] <== in[i]; |
|
||||
r0.b[i] <== in[1*64+i]; |
|
||||
r0.c[i] <== in[2*64+i]; |
|
||||
} |
|
||||
component r1 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r1.a[i] <== in[1*64+i]; |
|
||||
r1.b[i] <== in[2*64+i]; |
|
||||
r1.c[i] <== in[3*64+i]; |
|
||||
} |
|
||||
component r2 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r2.a[i] <== in[2*64+i]; |
|
||||
r2.b[i] <== in[3*64+i]; |
|
||||
r2.c[i] <== in[4*64+i]; |
|
||||
} |
|
||||
component r3 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r3.a[i] <== in[3*64+i]; |
|
||||
r3.b[i] <== in[4*64+i]; |
|
||||
r3.c[i] <== in[0*64+i]; |
|
||||
} |
|
||||
component r4 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r4.a[i] <== in[4*64+i]; |
|
||||
r4.b[i] <== in[i]; |
|
||||
r4.c[i] <== in[1*64+i]; |
|
||||
} |
|
||||
|
|
||||
component r5 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r5.a[i] <== in[5*64+i]; |
|
||||
r5.b[i] <== in[6*64+i]; |
|
||||
r5.c[i] <== in[7*64+i]; |
|
||||
} |
|
||||
component r6 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r6.a[i] <== in[6*64+i]; |
|
||||
r6.b[i] <== in[7*64+i]; |
|
||||
r6.c[i] <== in[8*64+i]; |
|
||||
} |
|
||||
component r7 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r7.a[i] <== in[7*64+i]; |
|
||||
r7.b[i] <== in[8*64+i]; |
|
||||
r7.c[i] <== in[9*64+i]; |
|
||||
} |
|
||||
component r8 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r8.a[i] <== in[8*64+i]; |
|
||||
r8.b[i] <== in[9*64+i]; |
|
||||
r8.c[i] <== in[5*64+i]; |
|
||||
} |
|
||||
component r9 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r9.a[i] <== in[9*64+i]; |
|
||||
r9.b[i] <== in[5*64+i]; |
|
||||
r9.c[i] <== in[6*64+i]; |
|
||||
} |
|
||||
|
|
||||
component r10 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r10.a[i] <== in[10*64+i]; |
|
||||
r10.b[i] <== in[11*64+i]; |
|
||||
r10.c[i] <== in[12*64+i]; |
|
||||
} |
|
||||
component r11 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r11.a[i] <== in[11*64+i]; |
|
||||
r11.b[i] <== in[12*64+i]; |
|
||||
r11.c[i] <== in[13*64+i]; |
|
||||
} |
|
||||
component r12 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r12.a[i] <== in[12*64+i]; |
|
||||
r12.b[i] <== in[13*64+i]; |
|
||||
r12.c[i] <== in[14*64+i]; |
|
||||
} |
|
||||
component r13 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r13.a[i] <== in[13*64+i]; |
|
||||
r13.b[i] <== in[14*64+i]; |
|
||||
r13.c[i] <== in[10*64+i]; |
|
||||
} |
|
||||
component r14 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r14.a[i] <== in[14*64+i]; |
|
||||
r14.b[i] <== in[10*64+i]; |
|
||||
r14.c[i] <== in[11*64+i]; |
|
||||
} |
|
||||
|
|
||||
component r15 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r15.a[i] <== in[15*64+i]; |
|
||||
r15.b[i] <== in[16*64+i]; |
|
||||
r15.c[i] <== in[17*64+i]; |
|
||||
} |
|
||||
component r16 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r16.a[i] <== in[16*64+i]; |
|
||||
r16.b[i] <== in[17*64+i]; |
|
||||
r16.c[i] <== in[18*64+i]; |
|
||||
} |
|
||||
component r17 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r17.a[i] <== in[17*64+i]; |
|
||||
r17.b[i] <== in[18*64+i]; |
|
||||
r17.c[i] <== in[19*64+i]; |
|
||||
} |
|
||||
component r18 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r18.a[i] <== in[18*64+i]; |
|
||||
r18.b[i] <== in[19*64+i]; |
|
||||
r18.c[i] <== in[15*64+i]; |
|
||||
} |
|
||||
component r19 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r19.a[i] <== in[19*64+i]; |
|
||||
r19.b[i] <== in[15*64+i]; |
|
||||
r19.c[i] <== in[16*64+i]; |
|
||||
} |
|
||||
|
|
||||
component r20 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r20.a[i] <== in[20*64+i]; |
|
||||
r20.b[i] <== in[21*64+i]; |
|
||||
r20.c[i] <== in[22*64+i]; |
|
||||
} |
|
||||
component r21 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r21.a[i] <== in[21*64+i]; |
|
||||
r21.b[i] <== in[22*64+i]; |
|
||||
r21.c[i] <== in[23*64+i]; |
|
||||
} |
|
||||
component r22 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r22.a[i] <== in[22*64+i]; |
|
||||
r22.b[i] <== in[23*64+i]; |
|
||||
r22.c[i] <== in[24*64+i]; |
|
||||
} |
|
||||
component r23 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r23.a[i] <== in[23*64+i]; |
|
||||
r23.b[i] <== in[24*64+i]; |
|
||||
r23.c[i] <== in[20*64+i]; |
|
||||
} |
|
||||
component r24 = step(); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r24.a[i] <== in[24*64+i]; |
|
||||
r24.b[i] <== in[20*64+i]; |
|
||||
r24.c[i] <== in[21*64+i]; |
|
||||
} |
|
||||
|
|
||||
for (i=0; i<64; i++) { |
|
||||
out[i] <== r0.out[i]; |
|
||||
out[1*64+i] <== r1.out[i]; |
|
||||
out[2*64+i] <== r2.out[i]; |
|
||||
out[3*64+i] <== r3.out[i]; |
|
||||
out[4*64+i] <== r4.out[i]; |
|
||||
|
|
||||
out[5*64+i] <== r5.out[i]; |
|
||||
out[6*64+i] <== r6.out[i]; |
|
||||
out[7*64+i] <== r7.out[i]; |
|
||||
out[8*64+i] <== r8.out[i]; |
|
||||
out[9*64+i] <== r9.out[i]; |
|
||||
|
|
||||
out[10*64+i] <== r10.out[i]; |
|
||||
out[11*64+i] <== r11.out[i]; |
|
||||
out[12*64+i] <== r12.out[i]; |
|
||||
out[13*64+i] <== r13.out[i]; |
|
||||
out[14*64+i] <== r14.out[i]; |
|
||||
|
|
||||
out[15*64+i] <== r15.out[i]; |
|
||||
out[16*64+i] <== r16.out[i]; |
|
||||
out[17*64+i] <== r17.out[i]; |
|
||||
out[18*64+i] <== r18.out[i]; |
|
||||
out[19*64+i] <== r19.out[i]; |
|
||||
|
|
||||
out[20*64+i] <== r20.out[i]; |
|
||||
out[21*64+i] <== r21.out[i]; |
|
||||
out[22*64+i] <== r22.out[i]; |
|
||||
out[23*64+i] <== r23.out[i]; |
|
||||
out[24*64+i] <== r24.out[i]; |
|
||||
} |
|
||||
} |
|
@ -1,41 +0,0 @@ |
|||||
pragma circom 2.0.0; |
|
||||
|
|
||||
include "./utils.circom"; |
|
||||
|
|
||||
template RC(r) { |
|
||||
signal output out[64]; |
|
||||
var rc[24] = [ |
|
||||
0x0000000000000001, 0x0000000000008082, 0x800000000000808A, |
|
||||
0x8000000080008000, 0x000000000000808B, 0x0000000080000001, |
|
||||
0x8000000080008081, 0x8000000000008009, 0x000000000000008A, |
|
||||
0x0000000000000088, 0x0000000080008009, 0x000000008000000A, |
|
||||
0x000000008000808B, 0x800000000000008B, 0x8000000000008089, |
|
||||
0x8000000000008003, 0x8000000000008002, 0x8000000000000080, |
|
||||
0x000000000000800A, 0x800000008000000A, 0x8000000080008081, |
|
||||
0x8000000000008080, 0x0000000080000001, 0x8000000080008008 |
|
||||
]; |
|
||||
for (var i=0; i<64; i++) { |
|
||||
out[i] <== (rc[r] >> i) & 1; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
template Iota(r) { |
|
||||
signal input in[25*64]; |
|
||||
signal output out[25*64]; |
|
||||
var i; |
|
||||
|
|
||||
component rc = RC(r); |
|
||||
|
|
||||
component iota = XorArray(64); |
|
||||
for (var i=0; i<64; i++) { |
|
||||
iota.a[i] <== in[i]; |
|
||||
iota.b[i] <== rc.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[i] <== iota.out[i]; |
|
||||
} |
|
||||
for (i=64; i<25*64; i++) { |
|
||||
out[i] <== in[i]; |
|
||||
} |
|
||||
} |
|
||||
|
|
@ -1,10 +1,7 @@ |
|||||
pragma circom 2.0.0; |
pragma circom 2.0.0; |
||||
|
|
||||
include "./utils.circom"; |
include "./utils.circom"; |
||||
include "./theta.circom"; |
|
||||
include "./rhopi.circom"; |
|
||||
include "./chi.circom"; |
|
||||
include "./iota.circom"; |
|
||||
|
include "./permutations.circom"; |
||||
|
|
||||
template Pad(nBits) { |
template Pad(nBits) { |
||||
signal input in[nBits]; |
signal input in[nBits]; |
@ -0,0 +1,796 @@ |
|||||
|
pragma circom 2.0.0; |
||||
|
|
||||
|
include "./utils.circom"; |
||||
|
|
||||
|
|
||||
|
// Theta |
||||
|
|
||||
|
template D(n, shl, shr) { |
||||
|
// d = b ^ (a<<shl | a>>shr) |
||||
|
signal input a[n]; |
||||
|
signal input b[n]; |
||||
|
signal output out[n]; |
||||
|
var i; |
||||
|
|
||||
|
component aux0 = ShR(64, shr); |
||||
|
for (i=0; i<64; i++) { |
||||
|
aux0.in[i] <== a[i]; |
||||
|
} |
||||
|
component aux1 = ShL(64, shl); |
||||
|
for (i=0; i<64; i++) { |
||||
|
aux1.in[i] <== a[i]; |
||||
|
} |
||||
|
component aux2 = OrArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
aux2.a[i] <== aux0.out[i]; |
||||
|
aux2.b[i] <== aux1.out[i]; |
||||
|
} |
||||
|
component aux3 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
aux3.a[i] <== b[i]; |
||||
|
aux3.b[i] <== aux2.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[i] <== aux3.out[i]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
template Theta() { |
||||
|
signal input in[25*64]; |
||||
|
signal output out[25*64]; |
||||
|
|
||||
|
var i; |
||||
|
|
||||
|
component c0 = Xor5(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
c0.a[i] <== in[i]; |
||||
|
c0.b[i] <== in[5*64+i]; |
||||
|
c0.c[i] <== in[10*64+i]; |
||||
|
c0.d[i] <== in[15*64+i]; |
||||
|
c0.e[i] <== in[20*64+i]; |
||||
|
} |
||||
|
|
||||
|
component c1 = Xor5(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
c1.a[i] <== in[1*64+i]; |
||||
|
c1.b[i] <== in[6*64+i]; |
||||
|
c1.c[i] <== in[11*64+i]; |
||||
|
c1.d[i] <== in[16*64+i]; |
||||
|
c1.e[i] <== in[21*64+i]; |
||||
|
} |
||||
|
|
||||
|
component c2 = Xor5(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
c2.a[i] <== in[2*64+i]; |
||||
|
c2.b[i] <== in[7*64+i]; |
||||
|
c2.c[i] <== in[12*64+i]; |
||||
|
c2.d[i] <== in[17*64+i]; |
||||
|
c2.e[i] <== in[22*64+i]; |
||||
|
} |
||||
|
|
||||
|
component c3 = Xor5(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
c3.a[i] <== in[3*64+i]; |
||||
|
c3.b[i] <== in[8*64+i]; |
||||
|
c3.c[i] <== in[13*64+i]; |
||||
|
c3.d[i] <== in[18*64+i]; |
||||
|
c3.e[i] <== in[23*64+i]; |
||||
|
} |
||||
|
|
||||
|
component c4 = Xor5(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
c4.a[i] <== in[4*64+i]; |
||||
|
c4.b[i] <== in[9*64+i]; |
||||
|
c4.c[i] <== in[14*64+i]; |
||||
|
c4.d[i] <== in[19*64+i]; |
||||
|
c4.e[i] <== in[24*64+i]; |
||||
|
} |
||||
|
|
||||
|
// d = c4 ^ (c1<<1 | c1>>(64-1)) |
||||
|
component d0 = D(64, 1, 64-1); |
||||
|
for (i=0; i<64; i++) { |
||||
|
d0.a[i] <== c1.out[i]; |
||||
|
d0.b[i] <== c4.out[i]; |
||||
|
} |
||||
|
// r[0] = a[0] ^ d |
||||
|
component r0 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r0.a[i] <== in[i]; |
||||
|
r0.b[i] <== d0.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[i] <== r0.out[i]; |
||||
|
} |
||||
|
// r[5] = a[5] ^ d |
||||
|
component r5 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r5.a[i] <== in[5*64+i]; |
||||
|
r5.b[i] <== d0.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[5*64+i] <== r5.out[i]; |
||||
|
} |
||||
|
// r[10] = a[10] ^ d |
||||
|
component r10 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r10.a[i] <== in[10*64+i]; |
||||
|
r10.b[i] <== d0.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[10*64+i] <== r10.out[i]; |
||||
|
} |
||||
|
// r[15] = a[15] ^ d |
||||
|
component r15 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r15.a[i] <== in[15*64+i]; |
||||
|
r15.b[i] <== d0.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[15*64+i] <== r15.out[i]; |
||||
|
} |
||||
|
// r[20] = a[20] ^ d |
||||
|
component r20 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r20.a[i] <== in[20*64+i]; |
||||
|
r20.b[i] <== d0.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[20*64+i] <== r20.out[i]; |
||||
|
} |
||||
|
|
||||
|
// d = c0 ^ (c2<<1 | c2>>(64-1)) |
||||
|
component d1 = D(64, 1, 64-1); |
||||
|
for (i=0; i<64; i++) { |
||||
|
d1.a[i] <== c2.out[i]; |
||||
|
d1.b[i] <== c0.out[i]; |
||||
|
} |
||||
|
// r[1] = a[1] ^ d |
||||
|
component r1 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r1.a[i] <== in[1*64+i]; |
||||
|
r1.b[i] <== d1.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[1*64+i] <== r1.out[i]; |
||||
|
} |
||||
|
// r[6] = a[6] ^ d |
||||
|
component r6 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r6.a[i] <== in[6*64+i]; |
||||
|
r6.b[i] <== d1.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[6*64+i] <== r6.out[i]; |
||||
|
} |
||||
|
// r[11] = a[11] ^ d |
||||
|
component r11 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r11.a[i] <== in[11*64+i]; |
||||
|
r11.b[i] <== d1.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[11*64+i] <== r11.out[i]; |
||||
|
} |
||||
|
// r[16] = a[16] ^ d |
||||
|
component r16 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r16.a[i] <== in[16*64+i]; |
||||
|
r16.b[i] <== d1.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[16*64+i] <== r16.out[i]; |
||||
|
} |
||||
|
// r[21] = a[21] ^ d |
||||
|
component r21 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r21.a[i] <== in[21*64+i]; |
||||
|
r21.b[i] <== d1.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[21*64+i] <== r21.out[i]; |
||||
|
} |
||||
|
|
||||
|
// d = c1 ^ (c3<<1 | c3>>(64-1)) |
||||
|
component d2 = D(64, 1, 64-1); |
||||
|
for (i=0; i<64; i++) { |
||||
|
d2.a[i] <== c3.out[i]; |
||||
|
d2.b[i] <== c1.out[i]; |
||||
|
} |
||||
|
// r[2] = a[2] ^ d |
||||
|
component r2 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r2.a[i] <== in[2*64+i]; |
||||
|
r2.b[i] <== d2.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[2*64+i] <== r2.out[i]; |
||||
|
} |
||||
|
// r[7] = a[7] ^ d |
||||
|
component r7 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r7.a[i] <== in[7*64+i]; |
||||
|
r7.b[i] <== d2.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[7*64+i] <== r7.out[i]; |
||||
|
} |
||||
|
// r[12] = a[12] ^ d |
||||
|
component r12 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r12.a[i] <== in[12*64+i]; |
||||
|
r12.b[i] <== d2.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[12*64+i] <== r12.out[i]; |
||||
|
} |
||||
|
// r[17] = a[17] ^ d |
||||
|
component r17 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r17.a[i] <== in[17*64+i]; |
||||
|
r17.b[i] <== d2.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[17*64+i] <== r17.out[i]; |
||||
|
} |
||||
|
// r[22] = a[22] ^ d |
||||
|
component r22 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r22.a[i] <== in[22*64+i]; |
||||
|
r22.b[i] <== d2.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[22*64+i] <== r22.out[i]; |
||||
|
} |
||||
|
|
||||
|
// d = c2 ^ (c4<<1 | c4>>(64-1)) |
||||
|
component d3 = D(64, 1, 64-1); |
||||
|
for (i=0; i<64; i++) { |
||||
|
d3.a[i] <== c4.out[i]; |
||||
|
d3.b[i] <== c2.out[i]; |
||||
|
} |
||||
|
// r[3] = a[3] ^ d |
||||
|
component r3 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r3.a[i] <== in[3*64+i]; |
||||
|
r3.b[i] <== d3.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[3*64+i] <== r3.out[i]; |
||||
|
} |
||||
|
// r[8] = a[8] ^ d |
||||
|
component r8 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r8.a[i] <== in[8*64+i]; |
||||
|
r8.b[i] <== d3.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[8*64+i] <== r8.out[i]; |
||||
|
} |
||||
|
// r[13] = a[13] ^ d |
||||
|
component r13 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r13.a[i] <== in[13*64+i]; |
||||
|
r13.b[i] <== d3.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[13*64+i] <== r13.out[i]; |
||||
|
} |
||||
|
// r[18] = a[18] ^ d |
||||
|
component r18 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r18.a[i] <== in[18*64+i]; |
||||
|
r18.b[i] <== d3.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[18*64+i] <== r18.out[i]; |
||||
|
} |
||||
|
// r[23] = a[23] ^ d |
||||
|
component r23 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r23.a[i] <== in[23*64+i]; |
||||
|
r23.b[i] <== d3.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[23*64+i] <== r23.out[i]; |
||||
|
} |
||||
|
|
||||
|
// d = c3 ^ (c0<<1 | c0>>(64-1)) |
||||
|
component d4 = D(64, 1, 64-1); |
||||
|
for (i=0; i<64; i++) { |
||||
|
d4.a[i] <== c0.out[i]; |
||||
|
d4.b[i] <== c3.out[i]; |
||||
|
} |
||||
|
// r[4] = a[4] ^ d |
||||
|
component r4 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r4.a[i] <== in[4*64+i]; |
||||
|
r4.b[i] <== d4.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[4*64+i] <== r4.out[i]; |
||||
|
} |
||||
|
// r[9] = a[9] ^ d |
||||
|
component r9 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r9.a[i] <== in[9*64+i]; |
||||
|
r9.b[i] <== d4.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[9*64+i] <== r9.out[i]; |
||||
|
} |
||||
|
// r[14] = a[14] ^ d |
||||
|
component r14 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r14.a[i] <== in[14*64+i]; |
||||
|
r14.b[i] <== d4.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[14*64+i] <== r14.out[i]; |
||||
|
} |
||||
|
// r[19] = a[19] ^ d |
||||
|
component r19 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r19.a[i] <== in[19*64+i]; |
||||
|
r19.b[i] <== d4.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[19*64+i] <== r19.out[i]; |
||||
|
} |
||||
|
// r[24] = a[24] ^ d |
||||
|
component r24 = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r24.a[i] <== in[24*64+i]; |
||||
|
r24.b[i] <== d4.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[24*64+i] <== r24.out[i]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// RhoPi |
||||
|
|
||||
|
template stepRhoPi(shl, shr) { |
||||
|
// out = a<<shl|a>>shr |
||||
|
signal input a[64]; |
||||
|
signal output out[64]; |
||||
|
var i; |
||||
|
|
||||
|
component aux0 = ShR(64, shr); |
||||
|
for (i=0; i<64; i++) { |
||||
|
aux0.in[i] <== a[i]; |
||||
|
} |
||||
|
component aux1 = ShL(64, shl); |
||||
|
for (i=0; i<64; i++) { |
||||
|
aux1.in[i] <== a[i]; |
||||
|
} |
||||
|
component aux2 = OrArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
aux2.a[i] <== aux0.out[i]; |
||||
|
aux2.b[i] <== aux1.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[i] <== aux2.out[i]; |
||||
|
} |
||||
|
} |
||||
|
template RhoPi() { |
||||
|
signal input in[25*64]; |
||||
|
signal output out[25*64]; |
||||
|
|
||||
|
var i; |
||||
|
|
||||
|
// r[10] = a[1]<<1|a[1]>>(64-1) |
||||
|
component s10 = stepRhoPi(1, 64-1); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s10.a[i] <== in[1*64+i]; |
||||
|
} |
||||
|
// r[7] = a[10]<<3|a[10]>>(64-3) |
||||
|
component s7 = stepRhoPi(3, 64-3); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s7.a[i] <== in[10*64+i]; |
||||
|
} |
||||
|
// r[11] = a[7]<<6|a[7]>>(64-6) |
||||
|
component s11 = stepRhoPi(6, 64-6); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s11.a[i] <== in[7*64+i]; |
||||
|
} |
||||
|
// r[17] = a[11]<<10|a[11]>>(64-10) |
||||
|
component s17 = stepRhoPi(10, 64-10); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s17.a[i] <== in[11*64+i]; |
||||
|
} |
||||
|
// r[18] = a[17]<<15|a[17]>>(64-15) |
||||
|
component s18 = stepRhoPi(15, 64-15); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s18.a[i] <== in[17*64+i]; |
||||
|
} |
||||
|
// r[3] = a[18]<<21|a[18]>>(64-21) |
||||
|
component s3 = stepRhoPi(21, 64-21); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s3.a[i] <== in[18*64+i]; |
||||
|
} |
||||
|
// r[5] = a[3]<<28|a[3]>>(64-28) |
||||
|
component s5 = stepRhoPi(28, 64-28); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s5.a[i] <== in[3*64+i]; |
||||
|
} |
||||
|
// r[16] = a[5]<<36|a[5]>>(64-36) |
||||
|
component s16 = stepRhoPi(36, 64-36); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s16.a[i] <== in[5*64+i]; |
||||
|
} |
||||
|
// r[8] = a[16]<<45|a[16]>>(64-45) |
||||
|
component s8 = stepRhoPi(45, 64-45); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s8.a[i] <== in[16*64+i]; |
||||
|
} |
||||
|
// r[21] = a[8]<<55|a[8]>>(64-55) |
||||
|
component s21 = stepRhoPi(55, 64-55); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s21.a[i] <== in[8*64+i]; |
||||
|
} |
||||
|
// r[24] = a[21]<<2|a[21]>>(64-2) |
||||
|
component s24 = stepRhoPi(2, 64-2); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s24.a[i] <== in[21*64+i]; |
||||
|
} |
||||
|
// r[4] = a[24]<<14|a[24]>>(64-14) |
||||
|
component s4 = stepRhoPi(14, 64-14); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s4.a[i] <== in[24*64+i]; |
||||
|
} |
||||
|
// r[15] = a[4]<<27|a[4]>>(64-27) |
||||
|
component s15 = stepRhoPi(27, 64-27); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s15.a[i] <== in[4*64+i]; |
||||
|
} |
||||
|
// r[23] = a[15]<<41|a[15]>>(64-41) |
||||
|
component s23 = stepRhoPi(41, 64-41); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s23.a[i] <== in[15*64+i]; |
||||
|
} |
||||
|
// r[19] = a[23]<<56|a[23]>>(64-56) |
||||
|
component s19 = stepRhoPi(56, 64-56); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s19.a[i] <== in[23*64+i]; |
||||
|
} |
||||
|
// r[13] = a[19]<<8|a[19]>>(64-8) |
||||
|
component s13 = stepRhoPi(8, 64-8); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s13.a[i] <== in[19*64+i]; |
||||
|
} |
||||
|
// r[12] = a[13]<<25|a[13]>>(64-25) |
||||
|
component s12 = stepRhoPi(25, 64-25); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s12.a[i] <== in[13*64+i]; |
||||
|
} |
||||
|
// r[2] = a[12]<<43|a[12]>>(64-43) |
||||
|
component s2 = stepRhoPi(43, 64-43); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s2.a[i] <== in[12*64+i]; |
||||
|
} |
||||
|
// r[20] = a[2]<<62|a[2]>>(64-62) |
||||
|
component s20 = stepRhoPi(62, 64-62); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s20.a[i] <== in[2*64+i]; |
||||
|
} |
||||
|
// r[14] = a[20]<<18|a[20]>>(64-18) |
||||
|
component s14 = stepRhoPi(18, 64-18); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s14.a[i] <== in[20*64+i]; |
||||
|
} |
||||
|
// r[22] = a[14]<<39|a[14]>>(64-39) |
||||
|
component s22 = stepRhoPi(39, 64-39); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s22.a[i] <== in[14*64+i]; |
||||
|
} |
||||
|
// r[9] = a[22]<<61|a[22]>>(64-61) |
||||
|
component s9 = stepRhoPi(61, 64-61); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s9.a[i] <== in[22*64+i]; |
||||
|
} |
||||
|
// r[6] = a[9]<<20|a[9]>>(64-20) |
||||
|
component s6 = stepRhoPi(20, 64-20); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s6.a[i] <== in[9*64+i]; |
||||
|
} |
||||
|
// r[1] = a[6]<<44|a[6]>>(64-44) |
||||
|
component s1 = stepRhoPi(44, 64-44); |
||||
|
for (i=0; i<64; i++) { |
||||
|
s1.a[i] <== in[6*64+i]; |
||||
|
} |
||||
|
|
||||
|
for (i=0; i<64; i++) { |
||||
|
out[i] <== in[i]; |
||||
|
out[10*64+i] <== s10.out[i]; |
||||
|
out[7*64+i] <== s7.out[i]; |
||||
|
out[11*64+i] <== s11.out[i]; |
||||
|
out[17*64+i] <== s17.out[i]; |
||||
|
out[18*64+i] <== s18.out[i]; |
||||
|
out[3*64+i] <== s3.out[i]; |
||||
|
out[5*64+i] <== s5.out[i]; |
||||
|
out[16*64+i] <== s16.out[i]; |
||||
|
out[8*64+i] <== s8.out[i]; |
||||
|
out[21*64+i] <== s21.out[i]; |
||||
|
out[24*64+i] <== s24.out[i]; |
||||
|
out[4*64+i] <== s4.out[i]; |
||||
|
out[15*64+i] <== s15.out[i]; |
||||
|
out[23*64+i] <== s23.out[i]; |
||||
|
out[19*64+i] <== s19.out[i]; |
||||
|
out[13*64+i] <== s13.out[i]; |
||||
|
out[12*64+i] <== s12.out[i]; |
||||
|
out[2*64+i] <== s2.out[i]; |
||||
|
out[20*64+i] <== s20.out[i]; |
||||
|
out[14*64+i] <== s14.out[i]; |
||||
|
out[22*64+i] <== s22.out[i]; |
||||
|
out[9*64+i] <== s9.out[i]; |
||||
|
out[6*64+i] <== s6.out[i]; |
||||
|
out[1*64+i] <== s1.out[i]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// Chi |
||||
|
|
||||
|
template stepChi() { |
||||
|
// out = a ^ (^b) & c |
||||
|
signal input a[64]; |
||||
|
signal input b[64]; |
||||
|
signal input c[64]; |
||||
|
signal output out[64]; |
||||
|
var i; |
||||
|
|
||||
|
// ^b |
||||
|
component bXor = XorArraySingle(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
bXor.a[i] <== b[i]; |
||||
|
} |
||||
|
// (^b)&c |
||||
|
component bc = AndArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
bc.a[i] <== bXor.out[i]; |
||||
|
bc.b[i] <== c[i]; |
||||
|
} |
||||
|
// a^(^b)&c |
||||
|
component abc = XorArray(64); |
||||
|
for (i=0; i<64; i++) { |
||||
|
abc.a[i] <== a[i]; |
||||
|
abc.b[i] <== bc.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[i] <== abc.out[i]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
template Chi() { |
||||
|
signal input in[25*64]; |
||||
|
signal output out[25*64]; |
||||
|
|
||||
|
var i; |
||||
|
|
||||
|
component r0 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r0.a[i] <== in[i]; |
||||
|
r0.b[i] <== in[1*64+i]; |
||||
|
r0.c[i] <== in[2*64+i]; |
||||
|
} |
||||
|
component r1 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r1.a[i] <== in[1*64+i]; |
||||
|
r1.b[i] <== in[2*64+i]; |
||||
|
r1.c[i] <== in[3*64+i]; |
||||
|
} |
||||
|
component r2 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r2.a[i] <== in[2*64+i]; |
||||
|
r2.b[i] <== in[3*64+i]; |
||||
|
r2.c[i] <== in[4*64+i]; |
||||
|
} |
||||
|
component r3 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r3.a[i] <== in[3*64+i]; |
||||
|
r3.b[i] <== in[4*64+i]; |
||||
|
r3.c[i] <== in[0*64+i]; |
||||
|
} |
||||
|
component r4 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r4.a[i] <== in[4*64+i]; |
||||
|
r4.b[i] <== in[i]; |
||||
|
r4.c[i] <== in[1*64+i]; |
||||
|
} |
||||
|
|
||||
|
component r5 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r5.a[i] <== in[5*64+i]; |
||||
|
r5.b[i] <== in[6*64+i]; |
||||
|
r5.c[i] <== in[7*64+i]; |
||||
|
} |
||||
|
component r6 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r6.a[i] <== in[6*64+i]; |
||||
|
r6.b[i] <== in[7*64+i]; |
||||
|
r6.c[i] <== in[8*64+i]; |
||||
|
} |
||||
|
component r7 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r7.a[i] <== in[7*64+i]; |
||||
|
r7.b[i] <== in[8*64+i]; |
||||
|
r7.c[i] <== in[9*64+i]; |
||||
|
} |
||||
|
component r8 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r8.a[i] <== in[8*64+i]; |
||||
|
r8.b[i] <== in[9*64+i]; |
||||
|
r8.c[i] <== in[5*64+i]; |
||||
|
} |
||||
|
component r9 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r9.a[i] <== in[9*64+i]; |
||||
|
r9.b[i] <== in[5*64+i]; |
||||
|
r9.c[i] <== in[6*64+i]; |
||||
|
} |
||||
|
|
||||
|
component r10 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r10.a[i] <== in[10*64+i]; |
||||
|
r10.b[i] <== in[11*64+i]; |
||||
|
r10.c[i] <== in[12*64+i]; |
||||
|
} |
||||
|
component r11 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r11.a[i] <== in[11*64+i]; |
||||
|
r11.b[i] <== in[12*64+i]; |
||||
|
r11.c[i] <== in[13*64+i]; |
||||
|
} |
||||
|
component r12 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r12.a[i] <== in[12*64+i]; |
||||
|
r12.b[i] <== in[13*64+i]; |
||||
|
r12.c[i] <== in[14*64+i]; |
||||
|
} |
||||
|
component r13 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r13.a[i] <== in[13*64+i]; |
||||
|
r13.b[i] <== in[14*64+i]; |
||||
|
r13.c[i] <== in[10*64+i]; |
||||
|
} |
||||
|
component r14 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r14.a[i] <== in[14*64+i]; |
||||
|
r14.b[i] <== in[10*64+i]; |
||||
|
r14.c[i] <== in[11*64+i]; |
||||
|
} |
||||
|
|
||||
|
component r15 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r15.a[i] <== in[15*64+i]; |
||||
|
r15.b[i] <== in[16*64+i]; |
||||
|
r15.c[i] <== in[17*64+i]; |
||||
|
} |
||||
|
component r16 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r16.a[i] <== in[16*64+i]; |
||||
|
r16.b[i] <== in[17*64+i]; |
||||
|
r16.c[i] <== in[18*64+i]; |
||||
|
} |
||||
|
component r17 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r17.a[i] <== in[17*64+i]; |
||||
|
r17.b[i] <== in[18*64+i]; |
||||
|
r17.c[i] <== in[19*64+i]; |
||||
|
} |
||||
|
component r18 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r18.a[i] <== in[18*64+i]; |
||||
|
r18.b[i] <== in[19*64+i]; |
||||
|
r18.c[i] <== in[15*64+i]; |
||||
|
} |
||||
|
component r19 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r19.a[i] <== in[19*64+i]; |
||||
|
r19.b[i] <== in[15*64+i]; |
||||
|
r19.c[i] <== in[16*64+i]; |
||||
|
} |
||||
|
|
||||
|
component r20 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r20.a[i] <== in[20*64+i]; |
||||
|
r20.b[i] <== in[21*64+i]; |
||||
|
r20.c[i] <== in[22*64+i]; |
||||
|
} |
||||
|
component r21 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r21.a[i] <== in[21*64+i]; |
||||
|
r21.b[i] <== in[22*64+i]; |
||||
|
r21.c[i] <== in[23*64+i]; |
||||
|
} |
||||
|
component r22 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r22.a[i] <== in[22*64+i]; |
||||
|
r22.b[i] <== in[23*64+i]; |
||||
|
r22.c[i] <== in[24*64+i]; |
||||
|
} |
||||
|
component r23 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r23.a[i] <== in[23*64+i]; |
||||
|
r23.b[i] <== in[24*64+i]; |
||||
|
r23.c[i] <== in[20*64+i]; |
||||
|
} |
||||
|
component r24 = stepChi(); |
||||
|
for (i=0; i<64; i++) { |
||||
|
r24.a[i] <== in[24*64+i]; |
||||
|
r24.b[i] <== in[20*64+i]; |
||||
|
r24.c[i] <== in[21*64+i]; |
||||
|
} |
||||
|
|
||||
|
for (i=0; i<64; i++) { |
||||
|
out[i] <== r0.out[i]; |
||||
|
out[1*64+i] <== r1.out[i]; |
||||
|
out[2*64+i] <== r2.out[i]; |
||||
|
out[3*64+i] <== r3.out[i]; |
||||
|
out[4*64+i] <== r4.out[i]; |
||||
|
|
||||
|
out[5*64+i] <== r5.out[i]; |
||||
|
out[6*64+i] <== r6.out[i]; |
||||
|
out[7*64+i] <== r7.out[i]; |
||||
|
out[8*64+i] <== r8.out[i]; |
||||
|
out[9*64+i] <== r9.out[i]; |
||||
|
|
||||
|
out[10*64+i] <== r10.out[i]; |
||||
|
out[11*64+i] <== r11.out[i]; |
||||
|
out[12*64+i] <== r12.out[i]; |
||||
|
out[13*64+i] <== r13.out[i]; |
||||
|
out[14*64+i] <== r14.out[i]; |
||||
|
|
||||
|
out[15*64+i] <== r15.out[i]; |
||||
|
out[16*64+i] <== r16.out[i]; |
||||
|
out[17*64+i] <== r17.out[i]; |
||||
|
out[18*64+i] <== r18.out[i]; |
||||
|
out[19*64+i] <== r19.out[i]; |
||||
|
|
||||
|
out[20*64+i] <== r20.out[i]; |
||||
|
out[21*64+i] <== r21.out[i]; |
||||
|
out[22*64+i] <== r22.out[i]; |
||||
|
out[23*64+i] <== r23.out[i]; |
||||
|
out[24*64+i] <== r24.out[i]; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Iota |
||||
|
|
||||
|
template RC(r) { |
||||
|
signal output out[64]; |
||||
|
var rc[24] = [ |
||||
|
0x0000000000000001, 0x0000000000008082, 0x800000000000808A, |
||||
|
0x8000000080008000, 0x000000000000808B, 0x0000000080000001, |
||||
|
0x8000000080008081, 0x8000000000008009, 0x000000000000008A, |
||||
|
0x0000000000000088, 0x0000000080008009, 0x000000008000000A, |
||||
|
0x000000008000808B, 0x800000000000008B, 0x8000000000008089, |
||||
|
0x8000000000008003, 0x8000000000008002, 0x8000000000000080, |
||||
|
0x000000000000800A, 0x800000008000000A, 0x8000000080008081, |
||||
|
0x8000000000008080, 0x0000000080000001, 0x8000000080008008 |
||||
|
]; |
||||
|
for (var i=0; i<64; i++) { |
||||
|
out[i] <== (rc[r] >> i) & 1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
template Iota(r) { |
||||
|
signal input in[25*64]; |
||||
|
signal output out[25*64]; |
||||
|
var i; |
||||
|
|
||||
|
component rc = RC(r); |
||||
|
|
||||
|
component iota = XorArray(64); |
||||
|
for (var i=0; i<64; i++) { |
||||
|
iota.a[i] <== in[i]; |
||||
|
iota.b[i] <== rc.out[i]; |
||||
|
} |
||||
|
for (i=0; i<64; i++) { |
||||
|
out[i] <== iota.out[i]; |
||||
|
} |
||||
|
for (i=64; i<25*64; i++) { |
||||
|
out[i] <== in[i]; |
||||
|
} |
||||
|
} |
||||
|
|
@ -1,182 +0,0 @@ |
|||||
pragma circom 2.0.0; |
|
||||
|
|
||||
include "./utils.circom"; |
|
||||
|
|
||||
template stepRhoPi(shl, shr) { |
|
||||
// out = a<<shl|a>>shr |
|
||||
signal input a[64]; |
|
||||
signal output out[64]; |
|
||||
var i; |
|
||||
|
|
||||
component aux0 = ShR(64, shr); |
|
||||
for (i=0; i<64; i++) { |
|
||||
aux0.in[i] <== a[i]; |
|
||||
} |
|
||||
component aux1 = ShL(64, shl); |
|
||||
for (i=0; i<64; i++) { |
|
||||
aux1.in[i] <== a[i]; |
|
||||
} |
|
||||
component aux2 = OrArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
aux2.a[i] <== aux0.out[i]; |
|
||||
aux2.b[i] <== aux1.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[i] <== aux2.out[i]; |
|
||||
} |
|
||||
} |
|
||||
template RhoPi() { |
|
||||
signal input in[25*64]; |
|
||||
signal output out[25*64]; |
|
||||
|
|
||||
var i; |
|
||||
|
|
||||
// r[10] = a[1]<<1|a[1]>>(64-1) |
|
||||
component s10 = stepRhoPi(1, 64-1); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s10.a[i] <== in[1*64+i]; |
|
||||
} |
|
||||
// r[7] = a[10]<<3|a[10]>>(64-3) |
|
||||
component s7 = stepRhoPi(3, 64-3); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s7.a[i] <== in[10*64+i]; |
|
||||
} |
|
||||
// r[11] = a[7]<<6|a[7]>>(64-6) |
|
||||
component s11 = stepRhoPi(6, 64-6); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s11.a[i] <== in[7*64+i]; |
|
||||
} |
|
||||
// r[17] = a[11]<<10|a[11]>>(64-10) |
|
||||
component s17 = stepRhoPi(10, 64-10); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s17.a[i] <== in[11*64+i]; |
|
||||
} |
|
||||
// r[18] = a[17]<<15|a[17]>>(64-15) |
|
||||
component s18 = stepRhoPi(15, 64-15); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s18.a[i] <== in[17*64+i]; |
|
||||
} |
|
||||
// r[3] = a[18]<<21|a[18]>>(64-21) |
|
||||
component s3 = stepRhoPi(21, 64-21); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s3.a[i] <== in[18*64+i]; |
|
||||
} |
|
||||
// r[5] = a[3]<<28|a[3]>>(64-28) |
|
||||
component s5 = stepRhoPi(28, 64-28); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s5.a[i] <== in[3*64+i]; |
|
||||
} |
|
||||
// r[16] = a[5]<<36|a[5]>>(64-36) |
|
||||
component s16 = stepRhoPi(36, 64-36); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s16.a[i] <== in[5*64+i]; |
|
||||
} |
|
||||
// r[8] = a[16]<<45|a[16]>>(64-45) |
|
||||
component s8 = stepRhoPi(45, 64-45); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s8.a[i] <== in[16*64+i]; |
|
||||
} |
|
||||
// r[21] = a[8]<<55|a[8]>>(64-55) |
|
||||
component s21 = stepRhoPi(55, 64-55); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s21.a[i] <== in[8*64+i]; |
|
||||
} |
|
||||
// r[24] = a[21]<<2|a[21]>>(64-2) |
|
||||
component s24 = stepRhoPi(2, 64-2); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s24.a[i] <== in[21*64+i]; |
|
||||
} |
|
||||
// r[4] = a[24]<<14|a[24]>>(64-14) |
|
||||
component s4 = stepRhoPi(14, 64-14); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s4.a[i] <== in[24*64+i]; |
|
||||
} |
|
||||
// r[15] = a[4]<<27|a[4]>>(64-27) |
|
||||
component s15 = stepRhoPi(27, 64-27); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s15.a[i] <== in[4*64+i]; |
|
||||
} |
|
||||
// r[23] = a[15]<<41|a[15]>>(64-41) |
|
||||
component s23 = stepRhoPi(41, 64-41); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s23.a[i] <== in[15*64+i]; |
|
||||
} |
|
||||
// r[19] = a[23]<<56|a[23]>>(64-56) |
|
||||
component s19 = stepRhoPi(56, 64-56); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s19.a[i] <== in[23*64+i]; |
|
||||
} |
|
||||
// r[13] = a[19]<<8|a[19]>>(64-8) |
|
||||
component s13 = stepRhoPi(8, 64-8); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s13.a[i] <== in[19*64+i]; |
|
||||
} |
|
||||
// r[12] = a[13]<<25|a[13]>>(64-25) |
|
||||
component s12 = stepRhoPi(25, 64-25); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s12.a[i] <== in[13*64+i]; |
|
||||
} |
|
||||
// r[2] = a[12]<<43|a[12]>>(64-43) |
|
||||
component s2 = stepRhoPi(43, 64-43); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s2.a[i] <== in[12*64+i]; |
|
||||
} |
|
||||
// r[20] = a[2]<<62|a[2]>>(64-62) |
|
||||
component s20 = stepRhoPi(62, 64-62); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s20.a[i] <== in[2*64+i]; |
|
||||
} |
|
||||
// r[14] = a[20]<<18|a[20]>>(64-18) |
|
||||
component s14 = stepRhoPi(18, 64-18); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s14.a[i] <== in[20*64+i]; |
|
||||
} |
|
||||
// r[22] = a[14]<<39|a[14]>>(64-39) |
|
||||
component s22 = stepRhoPi(39, 64-39); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s22.a[i] <== in[14*64+i]; |
|
||||
} |
|
||||
// r[9] = a[22]<<61|a[22]>>(64-61) |
|
||||
component s9 = stepRhoPi(61, 64-61); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s9.a[i] <== in[22*64+i]; |
|
||||
} |
|
||||
// r[6] = a[9]<<20|a[9]>>(64-20) |
|
||||
component s6 = stepRhoPi(20, 64-20); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s6.a[i] <== in[9*64+i]; |
|
||||
} |
|
||||
// r[1] = a[6]<<44|a[6]>>(64-44) |
|
||||
component s1 = stepRhoPi(44, 64-44); |
|
||||
for (i=0; i<64; i++) { |
|
||||
s1.a[i] <== in[6*64+i]; |
|
||||
} |
|
||||
|
|
||||
for (i=0; i<64; i++) { |
|
||||
out[i] <== in[i]; |
|
||||
out[10*64+i] <== s10.out[i]; |
|
||||
out[7*64+i] <== s7.out[i]; |
|
||||
out[11*64+i] <== s11.out[i]; |
|
||||
out[17*64+i] <== s17.out[i]; |
|
||||
out[18*64+i] <== s18.out[i]; |
|
||||
out[3*64+i] <== s3.out[i]; |
|
||||
out[5*64+i] <== s5.out[i]; |
|
||||
out[16*64+i] <== s16.out[i]; |
|
||||
out[8*64+i] <== s8.out[i]; |
|
||||
out[21*64+i] <== s21.out[i]; |
|
||||
out[24*64+i] <== s24.out[i]; |
|
||||
out[4*64+i] <== s4.out[i]; |
|
||||
out[15*64+i] <== s15.out[i]; |
|
||||
out[23*64+i] <== s23.out[i]; |
|
||||
out[19*64+i] <== s19.out[i]; |
|
||||
out[13*64+i] <== s13.out[i]; |
|
||||
out[12*64+i] <== s12.out[i]; |
|
||||
out[2*64+i] <== s2.out[i]; |
|
||||
out[20*64+i] <== s20.out[i]; |
|
||||
out[14*64+i] <== s14.out[i]; |
|
||||
out[22*64+i] <== s22.out[i]; |
|
||||
out[9*64+i] <== s9.out[i]; |
|
||||
out[6*64+i] <== s6.out[i]; |
|
||||
out[1*64+i] <== s1.out[i]; |
|
||||
} |
|
||||
} |
|
@ -1,346 +0,0 @@ |
|||||
pragma circom 2.0.0; |
|
||||
|
|
||||
include "./utils.circom"; |
|
||||
|
|
||||
|
|
||||
template D(n, shl, shr) { |
|
||||
// d = b ^ (a<<shl | a>>shr) |
|
||||
signal input a[n]; |
|
||||
signal input b[n]; |
|
||||
signal output out[n]; |
|
||||
var i; |
|
||||
|
|
||||
component aux0 = ShR(64, shr); |
|
||||
for (i=0; i<64; i++) { |
|
||||
aux0.in[i] <== a[i]; |
|
||||
} |
|
||||
component aux1 = ShL(64, shl); |
|
||||
for (i=0; i<64; i++) { |
|
||||
aux1.in[i] <== a[i]; |
|
||||
} |
|
||||
component aux2 = OrArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
aux2.a[i] <== aux0.out[i]; |
|
||||
aux2.b[i] <== aux1.out[i]; |
|
||||
} |
|
||||
component aux3 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
aux3.a[i] <== b[i]; |
|
||||
aux3.b[i] <== aux2.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[i] <== aux3.out[i]; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
template Theta() { |
|
||||
signal input in[25*64]; |
|
||||
signal output out[25*64]; |
|
||||
|
|
||||
var i; |
|
||||
|
|
||||
component c0 = Xor5(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
c0.a[i] <== in[i]; |
|
||||
c0.b[i] <== in[5*64+i]; |
|
||||
c0.c[i] <== in[10*64+i]; |
|
||||
c0.d[i] <== in[15*64+i]; |
|
||||
c0.e[i] <== in[20*64+i]; |
|
||||
} |
|
||||
|
|
||||
component c1 = Xor5(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
c1.a[i] <== in[1*64+i]; |
|
||||
c1.b[i] <== in[6*64+i]; |
|
||||
c1.c[i] <== in[11*64+i]; |
|
||||
c1.d[i] <== in[16*64+i]; |
|
||||
c1.e[i] <== in[21*64+i]; |
|
||||
} |
|
||||
|
|
||||
component c2 = Xor5(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
c2.a[i] <== in[2*64+i]; |
|
||||
c2.b[i] <== in[7*64+i]; |
|
||||
c2.c[i] <== in[12*64+i]; |
|
||||
c2.d[i] <== in[17*64+i]; |
|
||||
c2.e[i] <== in[22*64+i]; |
|
||||
} |
|
||||
|
|
||||
component c3 = Xor5(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
c3.a[i] <== in[3*64+i]; |
|
||||
c3.b[i] <== in[8*64+i]; |
|
||||
c3.c[i] <== in[13*64+i]; |
|
||||
c3.d[i] <== in[18*64+i]; |
|
||||
c3.e[i] <== in[23*64+i]; |
|
||||
} |
|
||||
|
|
||||
component c4 = Xor5(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
c4.a[i] <== in[4*64+i]; |
|
||||
c4.b[i] <== in[9*64+i]; |
|
||||
c4.c[i] <== in[14*64+i]; |
|
||||
c4.d[i] <== in[19*64+i]; |
|
||||
c4.e[i] <== in[24*64+i]; |
|
||||
} |
|
||||
|
|
||||
// d = c4 ^ (c1<<1 | c1>>(64-1)) |
|
||||
component d0 = D(64, 1, 64-1); |
|
||||
for (i=0; i<64; i++) { |
|
||||
d0.a[i] <== c1.out[i]; |
|
||||
d0.b[i] <== c4.out[i]; |
|
||||
} |
|
||||
// r[0] = a[0] ^ d |
|
||||
component r0 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r0.a[i] <== in[i]; |
|
||||
r0.b[i] <== d0.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[i] <== r0.out[i]; |
|
||||
} |
|
||||
// r[5] = a[5] ^ d |
|
||||
component r5 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r5.a[i] <== in[5*64+i]; |
|
||||
r5.b[i] <== d0.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[5*64+i] <== r5.out[i]; |
|
||||
} |
|
||||
// r[10] = a[10] ^ d |
|
||||
component r10 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r10.a[i] <== in[10*64+i]; |
|
||||
r10.b[i] <== d0.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[10*64+i] <== r10.out[i]; |
|
||||
} |
|
||||
// r[15] = a[15] ^ d |
|
||||
component r15 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r15.a[i] <== in[15*64+i]; |
|
||||
r15.b[i] <== d0.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[15*64+i] <== r15.out[i]; |
|
||||
} |
|
||||
// r[20] = a[20] ^ d |
|
||||
component r20 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r20.a[i] <== in[20*64+i]; |
|
||||
r20.b[i] <== d0.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[20*64+i] <== r20.out[i]; |
|
||||
} |
|
||||
|
|
||||
// d = c0 ^ (c2<<1 | c2>>(64-1)) |
|
||||
component d1 = D(64, 1, 64-1); |
|
||||
for (i=0; i<64; i++) { |
|
||||
d1.a[i] <== c2.out[i]; |
|
||||
d1.b[i] <== c0.out[i]; |
|
||||
} |
|
||||
// r[1] = a[1] ^ d |
|
||||
component r1 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r1.a[i] <== in[1*64+i]; |
|
||||
r1.b[i] <== d1.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[1*64+i] <== r1.out[i]; |
|
||||
} |
|
||||
// r[6] = a[6] ^ d |
|
||||
component r6 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r6.a[i] <== in[6*64+i]; |
|
||||
r6.b[i] <== d1.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[6*64+i] <== r6.out[i]; |
|
||||
} |
|
||||
// r[11] = a[11] ^ d |
|
||||
component r11 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r11.a[i] <== in[11*64+i]; |
|
||||
r11.b[i] <== d1.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[11*64+i] <== r11.out[i]; |
|
||||
} |
|
||||
// r[16] = a[16] ^ d |
|
||||
component r16 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r16.a[i] <== in[16*64+i]; |
|
||||
r16.b[i] <== d1.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[16*64+i] <== r16.out[i]; |
|
||||
} |
|
||||
// r[21] = a[21] ^ d |
|
||||
component r21 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r21.a[i] <== in[21*64+i]; |
|
||||
r21.b[i] <== d1.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[21*64+i] <== r21.out[i]; |
|
||||
} |
|
||||
|
|
||||
// d = c1 ^ (c3<<1 | c3>>(64-1)) |
|
||||
component d2 = D(64, 1, 64-1); |
|
||||
for (i=0; i<64; i++) { |
|
||||
d2.a[i] <== c3.out[i]; |
|
||||
d2.b[i] <== c1.out[i]; |
|
||||
} |
|
||||
// r[2] = a[2] ^ d |
|
||||
component r2 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r2.a[i] <== in[2*64+i]; |
|
||||
r2.b[i] <== d2.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[2*64+i] <== r2.out[i]; |
|
||||
} |
|
||||
// r[7] = a[7] ^ d |
|
||||
component r7 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r7.a[i] <== in[7*64+i]; |
|
||||
r7.b[i] <== d2.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[7*64+i] <== r7.out[i]; |
|
||||
} |
|
||||
// r[12] = a[12] ^ d |
|
||||
component r12 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r12.a[i] <== in[12*64+i]; |
|
||||
r12.b[i] <== d2.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[12*64+i] <== r12.out[i]; |
|
||||
} |
|
||||
// r[17] = a[17] ^ d |
|
||||
component r17 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r17.a[i] <== in[17*64+i]; |
|
||||
r17.b[i] <== d2.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[17*64+i] <== r17.out[i]; |
|
||||
} |
|
||||
// r[22] = a[22] ^ d |
|
||||
component r22 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r22.a[i] <== in[22*64+i]; |
|
||||
r22.b[i] <== d2.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[22*64+i] <== r22.out[i]; |
|
||||
} |
|
||||
|
|
||||
// d = c2 ^ (c4<<1 | c4>>(64-1)) |
|
||||
component d3 = D(64, 1, 64-1); |
|
||||
for (i=0; i<64; i++) { |
|
||||
d3.a[i] <== c4.out[i]; |
|
||||
d3.b[i] <== c2.out[i]; |
|
||||
} |
|
||||
// r[3] = a[3] ^ d |
|
||||
component r3 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r3.a[i] <== in[3*64+i]; |
|
||||
r3.b[i] <== d3.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[3*64+i] <== r3.out[i]; |
|
||||
} |
|
||||
// r[8] = a[8] ^ d |
|
||||
component r8 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r8.a[i] <== in[8*64+i]; |
|
||||
r8.b[i] <== d3.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[8*64+i] <== r8.out[i]; |
|
||||
} |
|
||||
// r[13] = a[13] ^ d |
|
||||
component r13 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r13.a[i] <== in[13*64+i]; |
|
||||
r13.b[i] <== d3.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[13*64+i] <== r13.out[i]; |
|
||||
} |
|
||||
// r[18] = a[18] ^ d |
|
||||
component r18 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r18.a[i] <== in[18*64+i]; |
|
||||
r18.b[i] <== d3.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[18*64+i] <== r18.out[i]; |
|
||||
} |
|
||||
// r[23] = a[23] ^ d |
|
||||
component r23 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r23.a[i] <== in[23*64+i]; |
|
||||
r23.b[i] <== d3.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[23*64+i] <== r23.out[i]; |
|
||||
} |
|
||||
|
|
||||
// d = c3 ^ (c0<<1 | c0>>(64-1)) |
|
||||
component d4 = D(64, 1, 64-1); |
|
||||
for (i=0; i<64; i++) { |
|
||||
d4.a[i] <== c0.out[i]; |
|
||||
d4.b[i] <== c3.out[i]; |
|
||||
} |
|
||||
// r[4] = a[4] ^ d |
|
||||
component r4 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r4.a[i] <== in[4*64+i]; |
|
||||
r4.b[i] <== d4.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[4*64+i] <== r4.out[i]; |
|
||||
} |
|
||||
// r[9] = a[9] ^ d |
|
||||
component r9 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r9.a[i] <== in[9*64+i]; |
|
||||
r9.b[i] <== d4.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[9*64+i] <== r9.out[i]; |
|
||||
} |
|
||||
// r[14] = a[14] ^ d |
|
||||
component r14 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r14.a[i] <== in[14*64+i]; |
|
||||
r14.b[i] <== d4.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[14*64+i] <== r14.out[i]; |
|
||||
} |
|
||||
// r[19] = a[19] ^ d |
|
||||
component r19 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r19.a[i] <== in[19*64+i]; |
|
||||
r19.b[i] <== d4.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[19*64+i] <== r19.out[i]; |
|
||||
} |
|
||||
// r[24] = a[24] ^ d |
|
||||
component r24 = XorArray(64); |
|
||||
for (i=0; i<64; i++) { |
|
||||
r24.a[i] <== in[24*64+i]; |
|
||||
r24.b[i] <== d4.out[i]; |
|
||||
} |
|
||||
for (i=0; i<64; i++) { |
|
||||
out[24*64+i] <== r24.out[i]; |
|
||||
} |
|
||||
} |
|
@ -1,5 +1,5 @@ |
|||||
pragma circom 2.0.0; |
pragma circom 2.0.0; |
||||
|
|
||||
include "../../circuits/keccak256.circom"; |
|
||||
|
include "../../circuits/keccak.circom"; |
||||
|
|
||||
component main = Absorb(); |
component main = Absorb(); |
@ -1,5 +1,5 @@ |
|||||
pragma circom 2.0.0; |
pragma circom 2.0.0; |
||||
|
|
||||
include "../../circuits/chi.circom"; |
|
||||
|
include "../../circuits/permutations.circom"; |
||||
|
|
||||
component main = Chi(); |
component main = Chi(); |
@ -1,5 +1,5 @@ |
|||||
pragma circom 2.0.0; |
pragma circom 2.0.0; |
||||
|
|
||||
include "../../circuits/keccak256.circom"; |
|
||||
|
include "../../circuits/keccak.circom"; |
||||
|
|
||||
component main = Final(32*8); |
component main = Final(32*8); |
@ -1,6 +1,6 @@ |
|||||
pragma circom 2.0.0; |
pragma circom 2.0.0; |
||||
|
|
||||
include "../../circuits/iota.circom"; |
|
||||
|
include "../../circuits/permutations.circom"; |
||||
|
|
||||
component main = Iota(10); |
component main = Iota(10); |
||||
|
|
@ -1,6 +1,6 @@ |
|||||
pragma circom 2.0.0; |
pragma circom 2.0.0; |
||||
|
|
||||
include "../../circuits/iota.circom"; |
|
||||
|
include "../../circuits/permutations.circom"; |
||||
|
|
||||
component main = Iota(3); |
component main = Iota(3); |
||||
|
|
@ -1,5 +1,5 @@ |
|||||
pragma circom 2.0.0; |
pragma circom 2.0.0; |
||||
|
|
||||
include "../../circuits/keccak256.circom"; |
|
||||
|
include "../../circuits/keccak.circom"; |
||||
|
|
||||
component main = Keccak(32*8); |
component main = Keccak(32*8); |
@ -1,5 +1,5 @@ |
|||||
pragma circom 2.0.0; |
pragma circom 2.0.0; |
||||
|
|
||||
include "../../circuits/keccak256.circom"; |
|
||||
|
include "../../circuits/keccak.circom"; |
||||
|
|
||||
component main = KeccakfRound(0); |
component main = KeccakfRound(0); |
@ -1,5 +1,5 @@ |
|||||
pragma circom 2.0.0; |
pragma circom 2.0.0; |
||||
|
|
||||
include "../../circuits/keccak256.circom"; |
|
||||
|
include "../../circuits/keccak.circom"; |
||||
|
|
||||
component main = KeccakfRound(20); |
component main = KeccakfRound(20); |
@ -1,5 +1,5 @@ |
|||||
pragma circom 2.0.0; |
pragma circom 2.0.0; |
||||
|
|
||||
include "../../circuits/keccak256.circom"; |
|
||||
|
include "../../circuits/keccak.circom"; |
||||
|
|
||||
component main = Keccakf(); |
component main = Keccakf(); |
@ -1,5 +1,5 @@ |
|||||
pragma circom 2.0.0; |
pragma circom 2.0.0; |
||||
|
|
||||
include "../../circuits/keccak256.circom"; |
|
||||
|
include "../../circuits/keccak.circom"; |
||||
|
|
||||
component main = Pad(32*8); |
component main = Pad(32*8); |
@ -1,6 +1,6 @@ |
|||||
pragma circom 2.0.0; |
pragma circom 2.0.0; |
||||
|
|
||||
include "../../circuits/rhopi.circom"; |
|
||||
|
include "../../circuits/permutations.circom"; |
||||
|
|
||||
component main = RhoPi(); |
component main = RhoPi(); |
||||
|
|
@ -1,5 +1,5 @@ |
|||||
pragma circom 2.0.0; |
pragma circom 2.0.0; |
||||
|
|
||||
include "../../circuits/keccak256.circom"; |
|
||||
|
include "../../circuits/keccak.circom"; |
||||
|
|
||||
component main = Squeeze(32*8); |
component main = Squeeze(32*8); |
@ -1,5 +1,5 @@ |
|||||
pragma circom 2.0.0; |
pragma circom 2.0.0; |
||||
|
|
||||
include "../../circuits/theta.circom"; |
|
||||
|
include "../../circuits/permutations.circom"; |
||||
|
|
||||
component main = Theta(); |
component main = Theta(); |
@ -0,0 +1,283 @@ |
|||||
|
const path = require("path"); |
||||
|
|
||||
|
const chai = require("chai"); |
||||
|
const assert = chai.assert; |
||||
|
|
||||
|
const wasm_tester = require("circom_tester").wasm; |
||||
|
const c_tester = require("circom_tester").c; |
||||
|
|
||||
|
const utils = require("./utils"); |
||||
|
|
||||
|
describe("Keccak-Pad test", function () { |
||||
|
this.timeout(100000); |
||||
|
|
||||
|
it ("Pad (testvector generated from go)", async () => { |
||||
|
const cir = await wasm_tester(path.join(__dirname, "circuits", "pad_test.circom")); |
||||
|
|
||||
|
const input = |
||||
|
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]; |
||||
|
const expectedOut = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, |
||||
|
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, |
||||
|
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128]; |
||||
|
|
||||
|
const stateIn = utils.bytesToBits(input); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(136*8)); |
||||
|
const stateOutBytes = utils.bitsToBytes(stateOut); |
||||
|
// console.log(stateOutBytes, expectedOut);
|
||||
|
assert.deepEqual(stateOutBytes, expectedOut); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
describe("absorb test", function () { |
||||
|
this.timeout(100000); |
||||
|
|
||||
|
let cir; |
||||
|
before(async () => { |
||||
|
// const cir = await wasm_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
|
||||
|
cir = await c_tester(path.join(__dirname, "circuits", "absorb_test.circom")); |
||||
|
await cir.loadConstraints(); |
||||
|
console.log("n_constraints", cir.constraints.length); |
||||
|
}); |
||||
|
|
||||
|
it ("absorb 1 (testvector generated from go)", async () => { |
||||
|
const s = utils.strsToBigInts(["0", "1", "2", "3", "4", "5", "6", "7", |
||||
|
"8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", |
||||
|
"19", "20", "21", "22", "23", "24"]); |
||||
|
|
||||
|
const block = utils.strsToBigInts(["0", "1", "2", "3", "4", "5", "6", |
||||
|
"7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", |
||||
|
"18", "19", "20", "21", "22", "23", "24", "25", "26", "27", |
||||
|
"28","29", "30", "31", "1", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0","0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0", "0", "0", "128"]); |
||||
|
|
||||
|
const expectedOut = utils.strsToBigInts(["8342348566319207042", |
||||
|
"319359607942176202", "14410076088654599075", |
||||
|
"15666111399434436772", "9558421567405313402", |
||||
|
"3396178318116504023", "794353847439963108", |
||||
|
"12717011319735989377", "3503398863218919239", |
||||
|
"5517201702366862678", "15999361614129160496", |
||||
|
"1325524015888689985", "11971708408118944333", |
||||
|
"14874486179441062217", "12554876384974234666", |
||||
|
"11129975558302206043", "11257826431949606534", |
||||
|
"2740710607956478714", "15000019752453010167", |
||||
|
"15593606854132419294", |
||||
|
"2598425978562809333","8872504799797239246", "1212062965004664308", |
||||
|
"5443427421087086722", "10946808592826700411"]); |
||||
|
|
||||
|
const sIn = utils.u64ArrayToBits(s); |
||||
|
const blockIn = utils.bytesToBits(block); |
||||
|
const expectedOutBits = utils.u64ArrayToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "s": sIn, "block": blockIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(25*64)); |
||||
|
const stateOutU64 = utils.bitsToU64Array(stateOut); |
||||
|
// console.log(stateOutU64, expectedOut);
|
||||
|
assert.deepEqual(stateOutU64, expectedOut); |
||||
|
}); |
||||
|
|
||||
|
it ("absorb 2 (testvector generated from go)", async () => { |
||||
|
const s = utils.strsToBigInts(["8342348566319207042", |
||||
|
"319359607942176202", "14410076088654599075", |
||||
|
"15666111399434436772", "9558421567405313402", |
||||
|
"3396178318116504023", "794353847439963108", |
||||
|
"12717011319735989377", "3503398863218919239", |
||||
|
"5517201702366862678", "15999361614129160496", |
||||
|
"1325524015888689985", "11971708408118944333", |
||||
|
"14874486179441062217", "12554876384974234666", |
||||
|
"11129975558302206043", "11257826431949606534", |
||||
|
"2740710607956478714", "15000019752453010167", |
||||
|
"15593606854132419294", |
||||
|
"2598425978562809333","8872504799797239246", "1212062965004664308", |
||||
|
"5443427421087086722", "10946808592826700411"]); |
||||
|
|
||||
|
const block = utils.strsToBigInts(["0", "1", "2", "3", "4", "5", "6", |
||||
|
"7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", |
||||
|
"18", "19", "20", "21", "22", "23", "24", "25", "26", "27", |
||||
|
"28","29", "30", "31", "1", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0","0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", |
||||
|
"0", "0", "0", "128"]); |
||||
|
|
||||
|
const expectedOut = utils.strsToBigInts(["8909243822027471379", |
||||
|
"1111840847970088140", "12093072708540612559", |
||||
|
"11255033638786021658", "2082116894939842214", |
||||
|
"12821085060245261575", "6901785969834988344", |
||||
|
"3182430130277914993", "2164708585929408975", |
||||
|
"14402143231999718904", "16231444410553803968", |
||||
|
"1850945423480060493", "12856855675247400303", |
||||
|
"1137248620532111171", "7389129221921446308", |
||||
|
"12932467982741614601", "1350606937385760406", |
||||
|
"10983682292859713641", "10305595434820307765", |
||||
|
"13958651111365489854", "17206620388135196198", |
||||
|
"4238113785249530092", "7230868147643218103", "603011106238724524", |
||||
|
"16480095441097880488"]); |
||||
|
|
||||
|
const sIn = utils.u64ArrayToBits(s); |
||||
|
const blockIn = utils.bytesToBits(block); |
||||
|
const expectedOutBits = utils.u64ArrayToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "s": sIn, "block": blockIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(25*64)); |
||||
|
const stateOutU64 = utils.bitsToU64Array(stateOut); |
||||
|
// console.log(stateOutU64, expectedOut);
|
||||
|
assert.deepEqual(stateOutU64, expectedOut); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
describe("Keccak-Final test", function () { |
||||
|
this.timeout(100000); |
||||
|
|
||||
|
let cir; |
||||
|
before(async () => { |
||||
|
cir = await c_tester(path.join(__dirname, "circuits", "final_test.circom")); |
||||
|
await cir.loadConstraints(); |
||||
|
console.log("n_constraints", cir.constraints.length); |
||||
|
}); |
||||
|
|
||||
|
it ("Final 1 (testvector generated from go)", async () => { |
||||
|
const input = |
||||
|
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]; |
||||
|
const expectedOut = utils.strsToBigInts(["16953415415620100490", |
||||
|
"7495738965189503699", "12723370805759944158", |
||||
|
"3295955328722933810", "12121371508560456016", |
||||
|
"174876831679863147", "15944933357501475584", |
||||
|
"7502339663607726274", "12048918224562833898", |
||||
|
"16715284461100269102", "15582559130083209842", |
||||
|
"1743886467337678829", "2424196198791253761", |
||||
|
"1116417308245482383", "10367365997906434042", |
||||
|
"1849801549382613906", "13294939539683415102", |
||||
|
"4478091053375708790", "2969967870313332958", |
||||
|
"14618962068930014237", "2721742233407503451", |
||||
|
"12003265593030191290", "8109318293656735684", |
||||
|
"6346795302983965746", "12210038122000333046"]); |
||||
|
|
||||
|
const inIn = utils.bytesToBits(input); |
||||
|
const expectedOutBits = utils.u64ArrayToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": inIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(25*64)); |
||||
|
const stateOutU64 = utils.bitsToU64Array(stateOut); |
||||
|
// console.log(stateOutU64, expectedOut);
|
||||
|
assert.deepEqual(stateOutU64, expectedOut); |
||||
|
}); |
||||
|
|
||||
|
it ("Final 2 (testvector generated from go)", async () => { |
||||
|
const input = utils.strsToBigInts(["254", "254", "254", "254", "254", |
||||
|
"254", "254", "254", "254", "254", "254", "254", "254", "254", |
||||
|
"254", "254", "254", "254", "254", "254", "254", "254", "254", |
||||
|
"254", "254", "254", "254", "254", "254", "254", "254", "254"]); |
||||
|
const expectedOut = utils.strsToBigInts(["16852464862333879129", |
||||
|
"9588646233186836430", "693207875935078627", "6545910230963382296", |
||||
|
"3599194178366828471", "13130606490077331384", |
||||
|
"10374798023615518933", "7285576075118720444", |
||||
|
"4097382401500492461", "3968685317688314807", |
||||
|
"3350659309646210303", "640023485234837464", "2550030127986774041", |
||||
|
"8948768022010378840", "10678227883444996205", |
||||
|
"1395278318096830339", "2744077813166753978", |
||||
|
"13362598477502046010", "14601579319881128511", |
||||
|
"4070707967569603186", "16833768365875755098", |
||||
|
"1486295134719870048", "9161068934282437999", |
||||
|
"8245604251371175619", "8421994351908003183"]); |
||||
|
|
||||
|
const inIn = utils.bytesToBits(input); |
||||
|
const expectedOutBits = utils.u64ArrayToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": inIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(25*64)); |
||||
|
const stateOutU64 = utils.bitsToU64Array(stateOut); |
||||
|
// console.log(stateOutU64, expectedOut);
|
||||
|
assert.deepEqual(stateOutU64, expectedOut); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
describe("Keccak-Squeeze test", function () { |
||||
|
this.timeout(100000); |
||||
|
|
||||
|
let cir; |
||||
|
before(async () => { |
||||
|
cir = await c_tester(path.join(__dirname, "circuits", "squeeze_test.circom")); |
||||
|
await cir.loadConstraints(); |
||||
|
console.log("n_constraints", cir.constraints.length); |
||||
|
}); |
||||
|
|
||||
|
it ("Squeeze 1 (testvector generated from go)", async () => { |
||||
|
const input = utils.strsToBigInts(["16852464862333879129", |
||||
|
"9588646233186836430", "693207875935078627", "6545910230963382296", |
||||
|
"3599194178366828471", "13130606490077331384", |
||||
|
"10374798023615518933", "7285576075118720444", |
||||
|
"4097382401500492461", "3968685317688314807", |
||||
|
"3350659309646210303", "640023485234837464", "2550030127986774041", |
||||
|
"8948768022010378840", "10678227883444996205", |
||||
|
"1395278318096830339", "2744077813166753978", |
||||
|
"13362598477502046010", "14601579319881128511", |
||||
|
"4070707967569603186", "16833768365875755098", |
||||
|
"1486295134719870048", "9161068934282437999", |
||||
|
"8245604251371175619", "8421994351908003183"]); |
||||
|
|
||||
|
const expectedOut = [89, 195, 41, 13, 129, 251, 223, 233, 206, 31, 253, |
||||
|
61, 242, 182, 17, 133, 227, 8, 157, 240, 227, 196, 158, 9, 24, 232, |
||||
|
42, 96, 172, 190, 215, 90]; |
||||
|
|
||||
|
const inIn = utils.u64ArrayToBits(input); |
||||
|
const expectedOutBits = utils.bytesToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "s": inIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(32*8)); |
||||
|
const stateOutBytes = utils.bitsToBytes(stateOut); |
||||
|
// console.log(stateOutBytes, expectedOut);
|
||||
|
assert.deepEqual(stateOutBytes, expectedOut); |
||||
|
}); |
||||
|
it ("Squeeze 2 (testvector generated from go)", async () => { |
||||
|
const input = utils.strsToBigInts(["16953415415620100490", |
||||
|
"7495738965189503699", "12723370805759944158", |
||||
|
"3295955328722933810", "12121371508560456016", |
||||
|
"174876831679863147", "15944933357501475584", |
||||
|
"7502339663607726274", "12048918224562833898", |
||||
|
"16715284461100269102", "15582559130083209842", |
||||
|
"1743886467337678829", "2424196198791253761", |
||||
|
"1116417308245482383", "10367365997906434042", |
||||
|
"1849801549382613906", "13294939539683415102", |
||||
|
"4478091053375708790", "2969967870313332958", |
||||
|
"14618962068930014237", "2721742233407503451", |
||||
|
"12003265593030191290", "8109318293656735684", |
||||
|
"6346795302983965746", "12210038122000333046"]); |
||||
|
|
||||
|
const expectedOut = [138, 225, 170, 89, 127, 161, 70, 235, 211, 170, |
||||
|
44, 237, 223, 54, 6, 104, 222, 165, 229, 38, 86, 126, 146, 176, 50, |
||||
|
24, 22, 164, 232, 149, 189, 45]; |
||||
|
|
||||
|
const inIn = utils.u64ArrayToBits(input); |
||||
|
const expectedOutBits = utils.bytesToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "s": inIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(32*8)); |
||||
|
const stateOutBytes = utils.bitsToBytes(stateOut); |
||||
|
// console.log(stateOutBytes, expectedOut);
|
||||
|
assert.deepEqual(stateOutBytes, expectedOut); |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,111 @@ |
|||||
|
const path = require("path"); |
||||
|
|
||||
|
const chai = require("chai"); |
||||
|
const assert = chai.assert; |
||||
|
|
||||
|
const c_tester = require("circom_tester").c; |
||||
|
|
||||
|
const utils = require("./utils"); |
||||
|
const keccak256 = require("keccak256"); |
||||
|
|
||||
|
describe("Keccak full hash test", function () { |
||||
|
this.timeout(100000); |
||||
|
|
||||
|
let cir; |
||||
|
before(async () => { |
||||
|
cir = await c_tester(path.join(__dirname, "circuits", "keccak256_test.circom")); |
||||
|
await cir.loadConstraints(); |
||||
|
console.log("n_constraints", cir.constraints.length); |
||||
|
}); |
||||
|
|
||||
|
it ("Keccak 1 (testvector generated from go)", async () => { |
||||
|
const input = [116, 101, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; |
||||
|
const expectedOut = [37, 17, 98, 135, 161, 178, 88, 97, 125, 150, 143, |
||||
|
65, 228, 211, 170, 133, 153, 9, 88, 212, 4, 212, 175, 238, 249, |
||||
|
210, 214, 116, 170, 85, 45, 21]; |
||||
|
|
||||
|
const inIn = utils.bytesToBits(input); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": inIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(32*8)); |
||||
|
const stateOutBytes = utils.bitsToBytes(stateOut); |
||||
|
// console.log(stateOutBytes, expectedOut);
|
||||
|
assert.deepEqual(stateOutBytes, expectedOut); |
||||
|
}); |
||||
|
it ("Keccak 2 (testvector generated from go)", async () => { |
||||
|
const input = [37, 17, 98, 135, 161, 178, 88, 97, 125, 150, 143, 65, |
||||
|
228, 211, 170, 133, 153, 9, 88, 212, 4, 212, 175, 238, 249, 210, |
||||
|
214, 116, 170, 85, 45, 21]; |
||||
|
const expectedOut = [182, 104, 121, 2, 8, 48, 224, 11, 238, 244, 73, |
||||
|
142, 67, 205, 166, 27, 10, 223, 142, 209, 10, 46, 171, 110, 239, |
||||
|
68, 111, 116, 164, 127, 103, 141]; |
||||
|
|
||||
|
const inIn = utils.bytesToBits(input); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": inIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(32*8)); |
||||
|
const stateOutBytes = utils.bitsToBytes(stateOut); |
||||
|
// console.log(stateOutBytes, expectedOut);
|
||||
|
assert.deepEqual(stateOutBytes, expectedOut); |
||||
|
}); |
||||
|
it ("Keccak 3 (testvector generated from go)", async () => { |
||||
|
const input = [182, 104, 121, 2, 8, 48, 224, 11, 238, 244, 73, 142, 67, |
||||
|
205, 166, 27, 10, 223, 142, 209, 10, 46, 171, 110, 239, 68, 111, |
||||
|
116, 164, 127, 103, 141]; |
||||
|
const expectedOut = [191, 235, 249, 254, 70, 24, 106, 244, 212, 163, |
||||
|
52, 240, 1, 128, 235, 61, 158, 52, 138, 60, 197, 80, 113, 36, 44, |
||||
|
217, 55, 211, 97, 231, 26, 7]; |
||||
|
|
||||
|
const inIn = utils.bytesToBits(input); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": inIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(32*8)); |
||||
|
const stateOutBytes = utils.bitsToBytes(stateOut); |
||||
|
// console.log(stateOutBytes, expectedOut);
|
||||
|
assert.deepEqual(stateOutBytes, expectedOut); |
||||
|
}); |
||||
|
it ("Keccak 4 (testvector generated from go)", async () => { |
||||
|
const input = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; |
||||
|
const expectedOut = [41, 13, 236, 217, 84, 139, 98, 168, 214, 3, 69, |
||||
|
169, 136, 56, 111, 200, 75, 166, 188, 149, 72, 64, 8, 246, 54, 47, |
||||
|
147, 22, 14, 243, 229, 99]; |
||||
|
|
||||
|
const inIn = utils.bytesToBits(input); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": inIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(32*8)); |
||||
|
const stateOutBytes = utils.bitsToBytes(stateOut); |
||||
|
// console.log(stateOutBytes, expectedOut);
|
||||
|
assert.deepEqual(stateOutBytes, expectedOut); |
||||
|
}); |
||||
|
|
||||
|
describe("Keccak256 circuit check with js version", function () { |
||||
|
this.timeout(100000); |
||||
|
|
||||
|
it ("Keccak256 circom-js 1", async () => { |
||||
|
let input, inputBits, expectedOut, witness, stateOut, stateOutBytes; |
||||
|
input = Buffer.from("0000000000000000000000000000000000000000000000000000000000000000", "hex"); |
||||
|
for(let i=0; i<10; i++) { |
||||
|
inputBits = utils.bytesToBits(input); |
||||
|
|
||||
|
let jsOutRaw = keccak256(input); |
||||
|
expectedOut = utils.bufferToBytes(jsOutRaw); |
||||
|
console.log(i, "in:", input.toString('hex'), "\n out:", jsOutRaw.toString('hex')); |
||||
|
|
||||
|
witness = await cir.calculateWitness({ "in": inputBits }, true); |
||||
|
stateOut = witness.slice(1, 1+(32*8)); |
||||
|
stateOutBytes = utils.bitsToBytes(stateOut); |
||||
|
assert.deepEqual(stateOutBytes, expectedOut); |
||||
|
|
||||
|
// assign output into input for next iteration
|
||||
|
input = jsOutRaw; |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
}); |
@ -1,601 +0,0 @@ |
|||||
const chai = require("chai"); |
|
||||
const path = require("path"); |
|
||||
const crypto = require("crypto"); |
|
||||
const F1Field = require("ffjavascript").F1Field; |
|
||||
const Scalar = require("ffjavascript").Scalar; |
|
||||
exports.p = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); |
|
||||
const Fr = new F1Field(exports.p); |
|
||||
|
|
||||
const assert = chai.assert; |
|
||||
|
|
||||
const keccak256 = require("keccak256"); |
|
||||
|
|
||||
const wasm_tester = require("circom_tester").wasm; |
|
||||
const c_tester = require("circom_tester").c; |
|
||||
|
|
||||
// const printSignal = require("./helpers/printsignal");
|
|
||||
|
|
||||
function bytesToU64(byteArray) { |
|
||||
// var value = 0;
|
|
||||
var value = Fr.e(0); |
|
||||
for ( var i = byteArray.length - 1; i >= 0; i--) { |
|
||||
// value = (value * 256) + byteArray[i];
|
|
||||
value = Fr.add(Fr.mul(Fr.e(value), Fr.e(256)), Fr.e(byteArray[i])); |
|
||||
} |
|
||||
|
|
||||
return value; |
|
||||
} |
|
||||
function u64ToBytes(a) { |
|
||||
var b = Fr.e(a); |
|
||||
|
|
||||
const buff = new Uint8Array(8); |
|
||||
Scalar.toRprLE(buff, 0, b, 8); |
|
||||
return buff; |
|
||||
} |
|
||||
function u64ToBits(a) { |
|
||||
const aBytes = u64ToBytes(a); |
|
||||
return bytesToBits(aBytes); |
|
||||
} |
|
||||
function bytesToBits(b) { |
|
||||
const bits = []; |
|
||||
for (let i = 0; i < b.length; i++) { |
|
||||
for (let j = 0; j < 8; j++) { |
|
||||
if ((Number(b[i])&(1<<j)) > 0) { |
|
||||
// bits.push(Fr.e(1));
|
|
||||
bits.push(1); |
|
||||
} else { |
|
||||
// bits.push(Fr.e(0));
|
|
||||
bits.push(0); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return bits |
|
||||
} |
|
||||
function u64ArrayToBits(u) { |
|
||||
let r = []; |
|
||||
for (let i = 0; i < u.length; i++) { |
|
||||
r = r.concat(u64ToBits(u[i])); |
|
||||
} |
|
||||
return r |
|
||||
} |
|
||||
function bitsToU64(b) { |
|
||||
if (b.length != 64) { |
|
||||
console.log("b.length = ", b.length, " max=64"); |
|
||||
return; |
|
||||
} |
|
||||
const by = bitsToBytes(b) |
|
||||
return bytesToU64(by) |
|
||||
} |
|
||||
function bitsToBytes(a) { |
|
||||
const b = []; |
|
||||
|
|
||||
for (let i=0; i<a.length; i++) { |
|
||||
const p = Math.floor(i/8); |
|
||||
if (b[p]==undefined) { |
|
||||
b[p] = 0; |
|
||||
} |
|
||||
if (a[i]==1) { |
|
||||
b[p] |= 1<<(i%8); |
|
||||
} |
|
||||
} |
|
||||
return b; |
|
||||
} |
|
||||
|
|
||||
function bitsToU64Array(b) { |
|
||||
const r = []; |
|
||||
for (let i = 0; i < b.length/64; i++) { |
|
||||
r.push(bitsToU64(b.slice(i*64, i*64+64))); |
|
||||
} |
|
||||
return r |
|
||||
} |
|
||||
|
|
||||
function strsToBigInts(a) { |
|
||||
let b = []; |
|
||||
for (let i=0; i<a.length; i++) { |
|
||||
b[i] = Fr.e(a[i]); |
|
||||
} |
|
||||
return b; |
|
||||
} |
|
||||
function intsToBigInts(a) { |
|
||||
let b = []; |
|
||||
for (let i=0; i<a.length; i++) { |
|
||||
b[i] = Fr.e(a[i]); |
|
||||
} |
|
||||
return b; |
|
||||
} |
|
||||
function bigIntsToInts(a) { |
|
||||
let b = []; |
|
||||
for (let i=0; i<a.length; i++) { |
|
||||
b[i] = Number(a[i]); |
|
||||
} |
|
||||
return b; |
|
||||
} |
|
||||
|
|
||||
describe("Utils test", function () { |
|
||||
this.timeout(100000); |
|
||||
|
|
||||
it ("utils", async () => { |
|
||||
let a = 3; |
|
||||
let aBits = u64ToBits(a); |
|
||||
let a2 = bitsToU64(aBits); |
|
||||
assert.equal(a2, a); |
|
||||
a = 12345; |
|
||||
aBits = u64ToBits(a); |
|
||||
a2 = bitsToU64(aBits); |
|
||||
assert.equal(a2, a); |
|
||||
|
|
||||
a = intsToBigInts([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
|
||||
aBits = u64ArrayToBits(a); |
|
||||
a2 = bitsToU64Array(aBits); |
|
||||
assert.deepEqual(a2, a); |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
|
|
||||
describe("Theta test", function () { |
|
||||
this.timeout(100000); |
|
||||
|
|
||||
it ("Theta (testvector generated from go)", async () => { |
|
||||
const cir = await wasm_tester(path.join(__dirname, "circuits", "theta_test.circom")); |
|
||||
|
|
||||
const input = intsToBigInts([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
|
||||
const expectedOut = intsToBigInts([26,9,13,29,47,31,14,8,22,34,16,3,3,19,37,21,24,30,12,56,14,29,25,9,51]); |
|
||||
const stateIn = u64ArrayToBits(input); |
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(25*64)); |
|
||||
const stateOutU64 = bitsToU64Array(stateOut); |
|
||||
// console.log(stateOutU64, expectedOut);
|
|
||||
assert.deepEqual(stateOutU64, expectedOut); |
|
||||
}); |
|
||||
it ("Theta (same test as previous, but using c_tester to ensure that circom_tester with c works as expected)", async () => { |
|
||||
const cir = await c_tester(path.join(__dirname, "circuits", "theta_test.circom")); |
|
||||
|
|
||||
const input = intsToBigInts([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
|
||||
const expectedOut = intsToBigInts([26,9,13,29,47,31,14,8,22,34,16,3,3,19,37,21,24,30,12,56,14,29,25,9,51]); |
|
||||
const stateIn = u64ArrayToBits(input); |
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(25*64)); |
|
||||
const stateOutU64 = bitsToU64Array(stateOut); |
|
||||
// console.log(stateOutU64, expectedOut);
|
|
||||
assert.deepEqual(stateOutU64, expectedOut); |
|
||||
}); |
|
||||
|
|
||||
it ("Theta (testvector generated from go)", async () => { |
|
||||
const cir = await wasm_tester(path.join(__dirname, "circuits", "theta_test.circom")); |
|
||||
// const cir = await c_tester(path.join(__dirname, "circuits", "theta_test.circom"));
|
|
||||
|
|
||||
const input = strsToBigInts(["26388279066651", "246290629787648", "26388279902208", |
|
||||
"25165850", "246290605457408", "7784628352", "844424965783552", |
|
||||
"2305843009213694083", "844432714760192", "2305843009249345539", |
|
||||
"637534226", "14848", "641204224", "14354", "3670528", "6308236288", |
|
||||
"2130304761856", "648518346341354496", "6309216256", "648520476645130240", |
|
||||
"4611706359392501763", "792677514882318336", "20340965113972", |
|
||||
"4611732197915754499", "792633534417207412"]); |
|
||||
const expectedOut = strsToBigInts(["3749081831850030700", "1297317621190464868", |
|
||||
"10017560217643747862", "7854780639862409219", "13836147678645575967", |
|
||||
"3749090635727681271", "1297915755455157604", "12323429615135705749", |
|
||||
"7855062122598582297", "16141814766035214620", "3749090628446369381", |
|
||||
"1297071330560683876", "10017586606556924438", "7854780639837253643", |
|
||||
"13835971756788491039", "3749090634251287159", "1297070162329376100", |
|
||||
"9369068259580659222", "7854780645071013913", "14484490034407743775", |
|
||||
"8360757404916954740", "1801500877105239396", "10017570663003408994", |
|
||||
"3243123208712177690", "14628605291203076459"]); |
|
||||
|
|
||||
const stateIn = u64ArrayToBits(input); |
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(25*64)); |
|
||||
const stateOutU64 = bitsToU64Array(stateOut); |
|
||||
assert.deepEqual(stateOutU64, expectedOut); |
|
||||
}); |
|
||||
|
|
||||
|
|
||||
}); |
|
||||
|
|
||||
describe("RhoPi test", function () { |
|
||||
this.timeout(100000); |
|
||||
|
|
||||
it ("RhoPi (testvector generated from go)", async () => { |
|
||||
const cir = await wasm_tester(path.join(__dirname, "circuits", "rhopi_test.circom")); |
|
||||
|
|
||||
const input = intsToBigInts([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
|
||||
const expectedOut = strsToBigInts(["0", "105553116266496", "105553116266496", "37748736", "393216", |
|
||||
"805306368", "9437184", "80", "562949953421312", "13835058055282163714", |
|
||||
"2", "448", "436207616", "4864", "5242880", "536870912", "343597383680", |
|
||||
"11264", "557056", "1657324662872342528", "9223372036854775808", |
|
||||
"288230376151711744", "7696581394432", "32985348833280", "84"]); |
|
||||
const stateIn = u64ArrayToBits(input); |
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(25*64)); |
|
||||
const stateOutU64 = bitsToU64Array(stateOut); |
|
||||
// console.log(stateOutU64, expectedOut);
|
|
||||
assert.deepEqual(stateOutU64, expectedOut); |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
describe("Chi test", function () { |
|
||||
this.timeout(100000); |
|
||||
|
|
||||
it ("Chi (testvector generated from go)", async () => { |
|
||||
const cir = await wasm_tester(path.join(__dirname, "circuits", "chi_test.circom")); |
|
||||
|
|
||||
const input = intsToBigInts([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
|
||||
const expectedOut = intsToBigInts([2, 0, 6, 3, 5, 4, 14, 6, 12, 11, 14, 10, 14, 13, 15, |
|
||||
14, 18, 16, 30, 3, 22, 20, 30, 19, 25]); |
|
||||
const stateIn = u64ArrayToBits(input); |
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(25*64)); |
|
||||
const stateOutU64 = bitsToU64Array(stateOut); |
|
||||
// console.log(stateOutU64, expectedOut);
|
|
||||
assert.deepEqual(stateOutU64, expectedOut); |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
describe("Iota test", function () { |
|
||||
this.timeout(100000); |
|
||||
|
|
||||
it ("Iota 3 (testvector generated from go)", async () => { |
|
||||
const cir = await wasm_tester(path.join(__dirname, "circuits", "iota3_test.circom")); |
|
||||
|
|
||||
const input = intsToBigInts([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
|
||||
const expectedOut = strsToBigInts(["9223372039002292224",1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
|
||||
const stateIn = u64ArrayToBits(input); |
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(25*64)); |
|
||||
const stateOutU64 = bitsToU64Array(stateOut); |
|
||||
// console.log(stateOutU64, expectedOut);
|
|
||||
assert.deepEqual(stateOutU64, expectedOut); |
|
||||
}); |
|
||||
it ("Iota 10 (testvector generated from go)", async () => { |
|
||||
const cir = await wasm_tester(path.join(__dirname, "circuits", "iota10_test.circom")); |
|
||||
|
|
||||
const input = strsToBigInts(["9223372039002292224",1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
|
||||
const expectedOut = strsToBigInts(["9223372036854775817",1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
|
||||
const stateIn = u64ArrayToBits(input); |
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(25*64)); |
|
||||
const stateOutU64 = bitsToU64Array(stateOut); |
|
||||
// console.log(stateOutU64, expectedOut);
|
|
||||
assert.deepEqual(stateOutU64, expectedOut); |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
describe("Keccak-Pad test", function () { |
|
||||
this.timeout(100000); |
|
||||
|
|
||||
it ("Pad (testvector generated from go)", async () => { |
|
||||
const cir = await wasm_tester(path.join(__dirname, "circuits", "pad_test.circom")); |
|
||||
|
|
||||
const input = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]; |
|
||||
const expectedOut = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128]; |
|
||||
|
|
||||
const stateIn = bytesToBits(input); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(136*8)); |
|
||||
const stateOutBytes = bitsToBytes(stateOut); |
|
||||
// console.log(stateOutBytes, expectedOut);
|
|
||||
assert.deepEqual(stateOutBytes, expectedOut); |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
describe("keccakfRound test", function () { |
|
||||
this.timeout(100000); |
|
||||
|
|
||||
// apt install nlohmann-json3-dev
|
|
||||
// apt install nasm
|
|
||||
|
|
||||
it ("keccakfRound (testvector generated from go)", async () => { |
|
||||
// const cir = await wasm_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
|
|
||||
const cir = await c_tester(path.join(__dirname, "circuits", "keccakfRound0_test.circom")); |
|
||||
await cir.loadConstraints(); |
|
||||
// console.log("n_constraints", cir.constraints.length);
|
|
||||
|
|
||||
const input = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]; |
|
||||
const expectedOut = strsToBigInts(["26388279066651", "246290629787648", "26388279902208", "25165850", "246290605457408", "7784628352", "844424965783552", "2305843009213694083", "844432714760192", "2305843009249345539", "637534226", "14848", "641204224", "14354", "3670528", "6308236288", "2130304761856", "648518346341354496", "6309216256", "648520476645130240", "4611706359392501763", "792677514882318336", "20340965113972", "4611732197915754499", "792633534417207412"]); |
|
||||
|
|
||||
const stateIn = u64ArrayToBits(input); |
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(25*64)); |
|
||||
const stateOutU64 = bitsToU64Array(stateOut); |
|
||||
// console.log(stateOutU64, expectedOut);
|
|
||||
assert.deepEqual(stateOutU64, expectedOut); |
|
||||
}); |
|
||||
|
|
||||
it ("keccakfRound 20 (testvector generated from go)", async () => { |
|
||||
// const cir = await wasm_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
|
|
||||
const cir = await c_tester(path.join(__dirname, "circuits", "keccakfRound20_test.circom")); |
|
||||
await cir.loadConstraints(); |
|
||||
// console.log("n_constraints", cir.constraints.length);
|
|
||||
|
|
||||
const input = strsToBigInts(["26388279066651", "246290629787648", "26388279902208", "25165850", "246290605457408", "7784628352", "844424965783552", "2305843009213694083", "844432714760192", "2305843009249345539", "637534226", "14848", "641204224", "14354", "3670528", "6308236288", "2130304761856", "648518346341354496", "6309216256", "648520476645130240", "4611706359392501763", "792677514882318336", "20340965113972", "4611732197915754499", "792633534417207412"]); |
|
||||
const expectedOut = strsToBigInts(["17728382861289829725", "13654073086381141005", "9912591532945168756", "2030068283137172501", "5084683018496047808", "151244976540463006", "11718217461613725815", "11636071286320763433", "15039144509240642782", "11629028282864249197", "2594633730779457624", "14005558505838459171", "4612881094252610438", "2828009553220809993", "4838578484623267135", "1006588603063111352", "11109191860075454495", "1187545859779038208", "14661669042642437042", "5345317080454741069", "8196674451365552863", "635818354583088260", "13515759754032305626", "1708499319988748543", "7509292798507899312"]); |
|
||||
|
|
||||
const stateIn = u64ArrayToBits(input); |
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(25*64)); |
|
||||
const stateOutU64 = bitsToU64Array(stateOut); |
|
||||
// console.log(stateOutU64, expectedOut);
|
|
||||
assert.deepEqual(stateOutU64, expectedOut); |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
describe("keccakf test", function () { |
|
||||
this.timeout(100000); |
|
||||
|
|
||||
let cir; |
|
||||
before(async () => { |
|
||||
// const cir = await wasm_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
|
|
||||
cir = await c_tester(path.join(__dirname, "circuits", "keccakf_test.circom")); |
|
||||
await cir.loadConstraints(); |
|
||||
console.log("n_constraints", cir.constraints.length); |
|
||||
}); |
|
||||
|
|
||||
it ("keccakf 1 (testvector generated from go)", async () => { |
|
||||
const input = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]; |
|
||||
const expectedOut = strsToBigInts(["9472389783892099349", "2159377575142921216", "17826682512249813373", "2325963263767348549", "15086930817298358378", "11661812091723830419", "3517755057770134847", "5223775837645169598", "933274647126506074", "3451250694486589320", "825065683101361807", "6192414258352188799", "14426505790672879210", "3326742392640380689", "16749975585634164134", "17847697619892908514", "11598434253200954839", "6049795840392747215", "8610635351954084385", "18234131770974529925", "15330347418010067760", "12047099911907354591", "4763389569697138851", "6779624089296570504", "15083668107635345971"]); |
|
||||
|
|
||||
const stateIn = u64ArrayToBits(input); |
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(25*64)); |
|
||||
const stateOutU64 = bitsToU64Array(stateOut); |
|
||||
// console.log(stateOutU64, expectedOut);
|
|
||||
assert.deepEqual(stateOutU64, expectedOut); |
|
||||
}); |
|
||||
|
|
||||
it ("keccakf 2 (testvector generated from go)", async () => { |
|
||||
const input = strsToBigInts(["9472389783892099349", "2159377575142921216", "17826682512249813373", "2325963263767348549", "15086930817298358378", "11661812091723830419", "3517755057770134847", "5223775837645169598", "933274647126506074", "3451250694486589320", "825065683101361807", "6192414258352188799", "14426505790672879210", "3326742392640380689", "16749975585634164134", "17847697619892908514", "11598434253200954839", "6049795840392747215", "8610635351954084385", "18234131770974529925", "15330347418010067760", "12047099911907354591", "4763389569697138851", "6779624089296570504", "15083668107635345971"]); |
|
||||
const expectedOut = strsToBigInts(["269318771259381490", "15892848561416382510", "12485559500958802382", "4360182510883008729", "14284025675983944434", "8800366419087562177", "7881853509112258378", "9503857914080778528", "17110477940977988953", "13825318756568052601", "11460650932194163315", "13272167288297399439", "13599957064256729412", "12730838251751851758", "13736647180617564382", "5651695613583298166", "15496251216716036782", "9748494184433838858", "3637745438296580159", "3821184813198767406", "15603239432236101315", "3726326332491237029", "7819962668913661099", "2285898735263816116", "13518516210247555620"]); |
|
||||
|
|
||||
const stateIn = u64ArrayToBits(input); |
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(25*64)); |
|
||||
const stateOutU64 = bitsToU64Array(stateOut); |
|
||||
// console.log(stateOutU64, expectedOut);
|
|
||||
assert.deepEqual(stateOutU64, expectedOut); |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
describe("absorb test", function () { |
|
||||
this.timeout(100000); |
|
||||
|
|
||||
let cir; |
|
||||
before(async () => { |
|
||||
// const cir = await wasm_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
|
|
||||
cir = await c_tester(path.join(__dirname, "circuits", "absorb_test.circom")); |
|
||||
await cir.loadConstraints(); |
|
||||
console.log("n_constraints", cir.constraints.length); |
|
||||
}); |
|
||||
|
|
||||
it ("absorb 1 (testvector generated from go)", async () => { |
|
||||
const s = strsToBigInts(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"]); |
|
||||
|
|
||||
const block = strsToBigInts(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28","29", "30", "31", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0","0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "128"]); |
|
||||
|
|
||||
const expectedOut = strsToBigInts(["8342348566319207042", "319359607942176202", "14410076088654599075", "15666111399434436772", "9558421567405313402", "3396178318116504023", "794353847439963108", "12717011319735989377", "3503398863218919239", "5517201702366862678", "15999361614129160496", "1325524015888689985", "11971708408118944333", "14874486179441062217", "12554876384974234666", "11129975558302206043", "11257826431949606534", "2740710607956478714", "15000019752453010167", "15593606854132419294", "2598425978562809333","8872504799797239246", "1212062965004664308", "5443427421087086722", "10946808592826700411"]); |
|
||||
|
|
||||
const sIn = u64ArrayToBits(s); |
|
||||
const blockIn = bytesToBits(block); |
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "s": sIn, "block": blockIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(25*64)); |
|
||||
const stateOutU64 = bitsToU64Array(stateOut); |
|
||||
// console.log(stateOutU64, expectedOut);
|
|
||||
assert.deepEqual(stateOutU64, expectedOut); |
|
||||
}); |
|
||||
|
|
||||
it ("absorb 2 (testvector generated from go)", async () => { |
|
||||
const s = strsToBigInts(["8342348566319207042", "319359607942176202", "14410076088654599075", "15666111399434436772", "9558421567405313402", "3396178318116504023", "794353847439963108", "12717011319735989377", "3503398863218919239", "5517201702366862678", "15999361614129160496", "1325524015888689985", "11971708408118944333", "14874486179441062217", "12554876384974234666", "11129975558302206043", "11257826431949606534", "2740710607956478714", "15000019752453010167", "15593606854132419294", "2598425978562809333","8872504799797239246", "1212062965004664308", "5443427421087086722", "10946808592826700411"]); |
|
||||
|
|
||||
const block = strsToBigInts(["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28","29", "30", "31", "1", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0","0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "128"]); |
|
||||
|
|
||||
const expectedOut = strsToBigInts(["8909243822027471379", "1111840847970088140", "12093072708540612559", "11255033638786021658", "2082116894939842214", "12821085060245261575", "6901785969834988344", "3182430130277914993", "2164708585929408975", "14402143231999718904", "16231444410553803968", "1850945423480060493", "12856855675247400303", "1137248620532111171", "7389129221921446308", "12932467982741614601", "1350606937385760406", "10983682292859713641", "10305595434820307765", "13958651111365489854", "17206620388135196198", "4238113785249530092", "7230868147643218103", "603011106238724524", "16480095441097880488"]); |
|
||||
|
|
||||
const sIn = u64ArrayToBits(s); |
|
||||
const blockIn = bytesToBits(block); |
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "s": sIn, "block": blockIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(25*64)); |
|
||||
const stateOutU64 = bitsToU64Array(stateOut); |
|
||||
// console.log(stateOutU64, expectedOut);
|
|
||||
assert.deepEqual(stateOutU64, expectedOut); |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
describe("Keccak-Final test", function () { |
|
||||
this.timeout(100000); |
|
||||
|
|
||||
let cir; |
|
||||
before(async () => { |
|
||||
cir = await c_tester(path.join(__dirname, "circuits", "final_test.circom")); |
|
||||
await cir.loadConstraints(); |
|
||||
console.log("n_constraints", cir.constraints.length); |
|
||||
}); |
|
||||
|
|
||||
it ("Final 1 (testvector generated from go)", async () => { |
|
||||
const input = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]; |
|
||||
const expectedOut = strsToBigInts(["16953415415620100490", "7495738965189503699", "12723370805759944158", "3295955328722933810", "12121371508560456016", "174876831679863147", "15944933357501475584", "7502339663607726274", "12048918224562833898", "16715284461100269102", "15582559130083209842", "1743886467337678829", "2424196198791253761", "1116417308245482383", "10367365997906434042", "1849801549382613906", "13294939539683415102", "4478091053375708790", "2969967870313332958", "14618962068930014237", "2721742233407503451", "12003265593030191290", "8109318293656735684", "6346795302983965746", "12210038122000333046"]); |
|
||||
|
|
||||
const inIn = bytesToBits(input); |
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": inIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(25*64)); |
|
||||
const stateOutU64 = bitsToU64Array(stateOut); |
|
||||
// console.log(stateOutU64, expectedOut);
|
|
||||
assert.deepEqual(stateOutU64, expectedOut); |
|
||||
}); |
|
||||
|
|
||||
it ("Final 2 (testvector generated from go)", async () => { |
|
||||
const input = strsToBigInts(["254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254", "254"]); |
|
||||
const expectedOut = strsToBigInts(["16852464862333879129", "9588646233186836430", "693207875935078627", "6545910230963382296", "3599194178366828471", "13130606490077331384", "10374798023615518933", "7285576075118720444", "4097382401500492461", "3968685317688314807", "3350659309646210303", "640023485234837464", "2550030127986774041", "8948768022010378840", "10678227883444996205", "1395278318096830339", "2744077813166753978", "13362598477502046010", "14601579319881128511", "4070707967569603186", "16833768365875755098", "1486295134719870048", "9161068934282437999", "8245604251371175619", "8421994351908003183"]); |
|
||||
|
|
||||
const inIn = bytesToBits(input); |
|
||||
const expectedOutBits = u64ArrayToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": inIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(25*64)); |
|
||||
const stateOutU64 = bitsToU64Array(stateOut); |
|
||||
// console.log(stateOutU64, expectedOut);
|
|
||||
assert.deepEqual(stateOutU64, expectedOut); |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
describe("Keccak-Squeeze test", function () { |
|
||||
this.timeout(100000); |
|
||||
|
|
||||
let cir; |
|
||||
before(async () => { |
|
||||
cir = await c_tester(path.join(__dirname, "circuits", "squeeze_test.circom")); |
|
||||
await cir.loadConstraints(); |
|
||||
console.log("n_constraints", cir.constraints.length); |
|
||||
}); |
|
||||
|
|
||||
it ("Squeeze 1 (testvector generated from go)", async () => { |
|
||||
const input = strsToBigInts(["16852464862333879129", "9588646233186836430", "693207875935078627", "6545910230963382296", "3599194178366828471", "13130606490077331384", "10374798023615518933", "7285576075118720444", "4097382401500492461", "3968685317688314807", "3350659309646210303", "640023485234837464", "2550030127986774041", "8948768022010378840", "10678227883444996205", "1395278318096830339", "2744077813166753978", "13362598477502046010", "14601579319881128511", "4070707967569603186", "16833768365875755098", "1486295134719870048", "9161068934282437999", "8245604251371175619", "8421994351908003183"]); |
|
||||
|
|
||||
const expectedOut = [89, 195, 41, 13, 129, 251, 223, 233, 206, 31, 253, 61, 242, 182, 17, 133, 227, 8, 157, 240, 227, 196, 158, 9, 24, 232, 42, 96, 172, 190, 215, 90]; |
|
||||
|
|
||||
const inIn = u64ArrayToBits(input); |
|
||||
const expectedOutBits = bytesToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "s": inIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(32*8)); |
|
||||
const stateOutBytes = bitsToBytes(stateOut); |
|
||||
// console.log(stateOutBytes, expectedOut);
|
|
||||
assert.deepEqual(stateOutBytes, expectedOut); |
|
||||
}); |
|
||||
it ("Squeeze 2 (testvector generated from go)", async () => { |
|
||||
const input = strsToBigInts(["16953415415620100490", "7495738965189503699", "12723370805759944158", "3295955328722933810", "12121371508560456016", "174876831679863147", "15944933357501475584", "7502339663607726274", "12048918224562833898", "16715284461100269102", "15582559130083209842", "1743886467337678829", "2424196198791253761", "1116417308245482383", "10367365997906434042", "1849801549382613906", "13294939539683415102", "4478091053375708790", "2969967870313332958", "14618962068930014237", "2721742233407503451", "12003265593030191290", "8109318293656735684", "6346795302983965746", "12210038122000333046"]); |
|
||||
|
|
||||
const expectedOut = [138, 225, 170, 89, 127, 161, 70, 235, 211, 170, 44, 237, 223, 54, 6, 104, 222, 165, 229, 38, 86, 126, 146, 176, 50, 24, 22, 164, 232, 149, 189, 45]; |
|
||||
|
|
||||
const inIn = u64ArrayToBits(input); |
|
||||
const expectedOutBits = bytesToBits(expectedOut); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "s": inIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(32*8)); |
|
||||
const stateOutBytes = bitsToBytes(stateOut); |
|
||||
// console.log(stateOutBytes, expectedOut);
|
|
||||
assert.deepEqual(stateOutBytes, expectedOut); |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
describe("Keccak full hash test", function () { |
|
||||
this.timeout(100000); |
|
||||
|
|
||||
let cir; |
|
||||
before(async () => { |
|
||||
cir = await c_tester(path.join(__dirname, "circuits", "keccak256_test.circom")); |
|
||||
await cir.loadConstraints(); |
|
||||
console.log("n_constraints", cir.constraints.length); |
|
||||
}); |
|
||||
|
|
||||
it ("Keccak 1 (testvector generated from go)", async () => { |
|
||||
const input = [116, 101, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; |
|
||||
const expectedOut = [37, 17, 98, 135, 161, 178, 88, 97, 125, 150, 143, |
|
||||
65, 228, 211, 170, 133, 153, 9, 88, 212, 4, 212, 175, 238, 249, |
|
||||
210, 214, 116, 170, 85, 45, 21]; |
|
||||
|
|
||||
const inIn = bytesToBits(input); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": inIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(32*8)); |
|
||||
const stateOutBytes = bitsToBytes(stateOut); |
|
||||
// console.log(stateOutBytes, expectedOut);
|
|
||||
assert.deepEqual(stateOutBytes, expectedOut); |
|
||||
}); |
|
||||
it ("Keccak 2 (testvector generated from go)", async () => { |
|
||||
const input = [37, 17, 98, 135, 161, 178, 88, 97, 125, 150, 143, 65, |
|
||||
228, 211, 170, 133, 153, 9, 88, 212, 4, 212, 175, 238, 249, 210, |
|
||||
214, 116, 170, 85, 45, 21]; |
|
||||
const expectedOut = [182, 104, 121, 2, 8, 48, 224, 11, 238, 244, 73, |
|
||||
142, 67, 205, 166, 27, 10, 223, 142, 209, 10, 46, 171, 110, 239, |
|
||||
68, 111, 116, 164, 127, 103, 141]; |
|
||||
|
|
||||
const inIn = bytesToBits(input); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": inIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(32*8)); |
|
||||
const stateOutBytes = bitsToBytes(stateOut); |
|
||||
// console.log(stateOutBytes, expectedOut);
|
|
||||
assert.deepEqual(stateOutBytes, expectedOut); |
|
||||
}); |
|
||||
it ("Keccak 3 (testvector generated from go)", async () => { |
|
||||
const input = [182, 104, 121, 2, 8, 48, 224, 11, 238, 244, 73, 142, 67, |
|
||||
205, 166, 27, 10, 223, 142, 209, 10, 46, 171, 110, 239, 68, 111, |
|
||||
116, 164, 127, 103, 141]; |
|
||||
const expectedOut = [191, 235, 249, 254, 70, 24, 106, 244, 212, 163, |
|
||||
52, 240, 1, 128, 235, 61, 158, 52, 138, 60, 197, 80, 113, 36, 44, |
|
||||
217, 55, 211, 97, 231, 26, 7]; |
|
||||
|
|
||||
const inIn = bytesToBits(input); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": inIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(32*8)); |
|
||||
const stateOutBytes = bitsToBytes(stateOut); |
|
||||
// console.log(stateOutBytes, expectedOut);
|
|
||||
assert.deepEqual(stateOutBytes, expectedOut); |
|
||||
}); |
|
||||
it ("Keccak 4 (testvector generated from go)", async () => { |
|
||||
const input = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; |
|
||||
const expectedOut = [41, 13, 236, 217, 84, 139, 98, 168, 214, 3, 69, |
|
||||
169, 136, 56, 111, 200, 75, 166, 188, 149, 72, 64, 8, 246, 54, 47, |
|
||||
147, 22, 14, 243, 229, 99]; |
|
||||
|
|
||||
const inIn = bytesToBits(input); |
|
||||
|
|
||||
const witness = await cir.calculateWitness({ "in": inIn }, true); |
|
||||
|
|
||||
const stateOut = witness.slice(1, 1+(32*8)); |
|
||||
const stateOutBytes = bitsToBytes(stateOut); |
|
||||
// console.log(stateOutBytes, expectedOut);
|
|
||||
assert.deepEqual(stateOutBytes, expectedOut); |
|
||||
}); |
|
||||
}); |
|
@ -0,0 +1,159 @@ |
|||||
|
const path = require("path"); |
||||
|
|
||||
|
const chai = require("chai"); |
||||
|
const assert = chai.assert; |
||||
|
|
||||
|
const c_tester = require("circom_tester").c; |
||||
|
|
||||
|
const utils = require("./utils"); |
||||
|
|
||||
|
describe("keccakfRound test", function () { |
||||
|
this.timeout(100000); |
||||
|
|
||||
|
// apt install nlohmann-json3-dev
|
||||
|
// apt install nasm
|
||||
|
// apt install libgmp3-dev
|
||||
|
|
||||
|
it ("keccakfRound (testvector generated from go)", async () => { |
||||
|
const cir = await c_tester(path.join(__dirname, "circuits", "keccakfRound0_test.circom")); |
||||
|
await cir.loadConstraints(); |
||||
|
// console.log("n_constraints", cir.constraints.length);
|
||||
|
|
||||
|
const input = |
||||
|
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]; |
||||
|
const expectedOut = utils.strsToBigInts(["26388279066651", |
||||
|
"246290629787648", "26388279902208", "25165850", "246290605457408", |
||||
|
"7784628352", "844424965783552", "2305843009213694083", |
||||
|
"844432714760192", "2305843009249345539", "637534226", "14848", |
||||
|
"641204224", "14354", "3670528", "6308236288", "2130304761856", |
||||
|
"648518346341354496", "6309216256", "648520476645130240", |
||||
|
"4611706359392501763", "792677514882318336", "20340965113972", |
||||
|
"4611732197915754499", "792633534417207412"]); |
||||
|
|
||||
|
const stateIn = utils.u64ArrayToBits(input); |
||||
|
const expectedOutBits = utils.u64ArrayToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(25*64)); |
||||
|
const stateOutU64 = utils.bitsToU64Array(stateOut); |
||||
|
// console.log(stateOutU64, expectedOut);
|
||||
|
assert.deepEqual(stateOutU64, expectedOut); |
||||
|
}); |
||||
|
|
||||
|
it ("keccakfRound 20 (testvector generated from go)", async () => { |
||||
|
const cir = await c_tester(path.join(__dirname, "circuits", "keccakfRound20_test.circom")); |
||||
|
await cir.loadConstraints(); |
||||
|
// console.log("n_constraints", cir.constraints.length);
|
||||
|
|
||||
|
const input = utils.strsToBigInts(["26388279066651", "246290629787648", |
||||
|
"26388279902208", "25165850", "246290605457408", "7784628352", |
||||
|
"844424965783552", "2305843009213694083", "844432714760192", |
||||
|
"2305843009249345539", "637534226", "14848", "641204224", "14354", |
||||
|
"3670528", "6308236288", "2130304761856", "648518346341354496", |
||||
|
"6309216256", "648520476645130240", "4611706359392501763", |
||||
|
"792677514882318336", "20340965113972", "4611732197915754499", |
||||
|
"792633534417207412"]); |
||||
|
const expectedOut = utils.strsToBigInts(["17728382861289829725", |
||||
|
"13654073086381141005", "9912591532945168756", |
||||
|
"2030068283137172501", "5084683018496047808", "151244976540463006", |
||||
|
"11718217461613725815", "11636071286320763433", |
||||
|
"15039144509240642782", "11629028282864249197", |
||||
|
"2594633730779457624", "14005558505838459171", |
||||
|
"4612881094252610438", "2828009553220809993", |
||||
|
"4838578484623267135", "1006588603063111352", |
||||
|
"11109191860075454495", "1187545859779038208", |
||||
|
"14661669042642437042", "5345317080454741069", |
||||
|
"8196674451365552863", "635818354583088260", |
||||
|
"13515759754032305626", "1708499319988748543", |
||||
|
"7509292798507899312"]); |
||||
|
|
||||
|
const stateIn = utils.u64ArrayToBits(input); |
||||
|
const expectedOutBits = utils.u64ArrayToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(25*64)); |
||||
|
const stateOutU64 = utils.bitsToU64Array(stateOut); |
||||
|
// console.log(stateOutU64, expectedOut);
|
||||
|
assert.deepEqual(stateOutU64, expectedOut); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
describe("keccakf test", function () { |
||||
|
this.timeout(100000); |
||||
|
|
||||
|
let cir; |
||||
|
before(async () => { |
||||
|
cir = await c_tester(path.join(__dirname, "circuits", "keccakf_test.circom")); |
||||
|
await cir.loadConstraints(); |
||||
|
console.log("n_constraints", cir.constraints.length); |
||||
|
}); |
||||
|
|
||||
|
it ("keccakf 1 (testvector generated from go)", async () => { |
||||
|
const input = |
||||
|
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]; |
||||
|
const expectedOut = utils.strsToBigInts(["9472389783892099349", |
||||
|
"2159377575142921216", "17826682512249813373", |
||||
|
"2325963263767348549", "15086930817298358378", |
||||
|
"11661812091723830419", "3517755057770134847", |
||||
|
"5223775837645169598", "933274647126506074", "3451250694486589320", |
||||
|
"825065683101361807", "6192414258352188799", |
||||
|
"14426505790672879210", "3326742392640380689", |
||||
|
"16749975585634164134", "17847697619892908514", |
||||
|
"11598434253200954839", "6049795840392747215", |
||||
|
"8610635351954084385", "18234131770974529925", |
||||
|
"15330347418010067760", "12047099911907354591", |
||||
|
"4763389569697138851", "6779624089296570504", |
||||
|
"15083668107635345971"]); |
||||
|
|
||||
|
const stateIn = utils.u64ArrayToBits(input); |
||||
|
const expectedOutBits = utils.u64ArrayToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(25*64)); |
||||
|
const stateOutU64 = utils.bitsToU64Array(stateOut); |
||||
|
// console.log(stateOutU64, expectedOut);
|
||||
|
assert.deepEqual(stateOutU64, expectedOut); |
||||
|
}); |
||||
|
|
||||
|
it ("keccakf 2 (testvector generated from go)", async () => { |
||||
|
const input = utils.strsToBigInts(["9472389783892099349", |
||||
|
"2159377575142921216", "17826682512249813373", |
||||
|
"2325963263767348549", "15086930817298358378", |
||||
|
"11661812091723830419", "3517755057770134847", |
||||
|
"5223775837645169598", "933274647126506074", "3451250694486589320", |
||||
|
"825065683101361807", "6192414258352188799", |
||||
|
"14426505790672879210", "3326742392640380689", |
||||
|
"16749975585634164134", "17847697619892908514", |
||||
|
"11598434253200954839", "6049795840392747215", |
||||
|
"8610635351954084385", "18234131770974529925", |
||||
|
"15330347418010067760", "12047099911907354591", |
||||
|
"4763389569697138851", "6779624089296570504", |
||||
|
"15083668107635345971"]); |
||||
|
const expectedOut = utils.strsToBigInts(["269318771259381490", |
||||
|
"15892848561416382510", "12485559500958802382", |
||||
|
"4360182510883008729", "14284025675983944434", |
||||
|
"8800366419087562177", "7881853509112258378", |
||||
|
"9503857914080778528", "17110477940977988953", |
||||
|
"13825318756568052601", "11460650932194163315", |
||||
|
"13272167288297399439", "13599957064256729412", |
||||
|
"12730838251751851758", "13736647180617564382", |
||||
|
"5651695613583298166", "15496251216716036782", |
||||
|
"9748494184433838858", "3637745438296580159", |
||||
|
"3821184813198767406", "15603239432236101315", |
||||
|
"3726326332491237029", "7819962668913661099", |
||||
|
"2285898735263816116", "13518516210247555620"]); |
||||
|
|
||||
|
const stateIn = utils.u64ArrayToBits(input); |
||||
|
const expectedOutBits = utils.u64ArrayToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(25*64)); |
||||
|
const stateOutU64 = utils.bitsToU64Array(stateOut); |
||||
|
// console.log(stateOutU64, expectedOut);
|
||||
|
assert.deepEqual(stateOutU64, expectedOut); |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,174 @@ |
|||||
|
const path = require("path"); |
||||
|
|
||||
|
const chai = require("chai"); |
||||
|
const assert = chai.assert; |
||||
|
|
||||
|
const wasm_tester = require("circom_tester").wasm; |
||||
|
const c_tester = require("circom_tester").c; |
||||
|
|
||||
|
const utils = require("./utils"); |
||||
|
|
||||
|
describe("Theta test", function () { |
||||
|
this.timeout(100000); |
||||
|
|
||||
|
it ("Theta (testvector generated from go)", async () => { |
||||
|
const cir = await wasm_tester(path.join(__dirname, "circuits", "theta_test.circom")); |
||||
|
|
||||
|
const input = |
||||
|
utils.intsToBigInts([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
||||
|
const expectedOut = |
||||
|
utils.intsToBigInts([26,9,13,29,47,31,14,8,22,34,16,3,3,19,37,21,24,30,12,56,14,29,25,9,51]); |
||||
|
const stateIn = utils.u64ArrayToBits(input); |
||||
|
const expectedOutBits = utils.u64ArrayToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(25*64)); |
||||
|
const stateOutU64 = utils.bitsToU64Array(stateOut); |
||||
|
// console.log(stateOutU64, expectedOut);
|
||||
|
assert.deepEqual(stateOutU64, expectedOut); |
||||
|
}); |
||||
|
it ("Theta (same test as previous, but using c_tester to ensure that"+ |
||||
|
"circom_tester with c works as expected)", async () => { |
||||
|
const cir = await c_tester(path.join(__dirname, "circuits", "theta_test.circom")); |
||||
|
|
||||
|
const input = |
||||
|
utils.intsToBigInts([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
||||
|
const expectedOut = |
||||
|
utils.intsToBigInts([26,9,13,29,47,31,14,8,22,34,16,3,3,19,37,21,24,30,12,56,14,29,25,9,51]); |
||||
|
const stateIn = utils.u64ArrayToBits(input); |
||||
|
const expectedOutBits = utils.u64ArrayToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(25*64)); |
||||
|
const stateOutU64 = utils.bitsToU64Array(stateOut); |
||||
|
// console.log(stateOutU64, expectedOut);
|
||||
|
assert.deepEqual(stateOutU64, expectedOut); |
||||
|
}); |
||||
|
|
||||
|
it ("Theta (testvector generated from go)", async () => { |
||||
|
const cir = await wasm_tester(path.join(__dirname, "circuits", "theta_test.circom")); |
||||
|
// const cir = await c_tester(path.join(__dirname, "circuits", "theta_test.circom"));
|
||||
|
|
||||
|
const input = utils.strsToBigInts(["26388279066651", "246290629787648", |
||||
|
"26388279902208", "25165850", "246290605457408", "7784628352", |
||||
|
"844424965783552", "2305843009213694083", "844432714760192", |
||||
|
"2305843009249345539", "637534226", "14848", "641204224", "14354", |
||||
|
"3670528", "6308236288", "2130304761856", "648518346341354496", |
||||
|
"6309216256", "648520476645130240", "4611706359392501763", |
||||
|
"792677514882318336", "20340965113972", "4611732197915754499", |
||||
|
"792633534417207412"]); |
||||
|
const expectedOut = utils.strsToBigInts(["3749081831850030700", |
||||
|
"1297317621190464868", "10017560217643747862", |
||||
|
"7854780639862409219", "13836147678645575967", |
||||
|
"3749090635727681271", "1297915755455157604", |
||||
|
"12323429615135705749", "7855062122598582297", |
||||
|
"16141814766035214620", "3749090628446369381", |
||||
|
"1297071330560683876", "10017586606556924438", |
||||
|
"7854780639837253643", "13835971756788491039", |
||||
|
"3749090634251287159", "1297070162329376100", |
||||
|
"9369068259580659222", "7854780645071013913", |
||||
|
"14484490034407743775", "8360757404916954740", |
||||
|
"1801500877105239396", "10017570663003408994", |
||||
|
"3243123208712177690", "14628605291203076459"]); |
||||
|
|
||||
|
const stateIn = utils.u64ArrayToBits(input); |
||||
|
const expectedOutBits = utils.u64ArrayToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(25*64)); |
||||
|
const stateOutU64 = utils.bitsToU64Array(stateOut); |
||||
|
assert.deepEqual(stateOutU64, expectedOut); |
||||
|
}); |
||||
|
|
||||
|
|
||||
|
}); |
||||
|
|
||||
|
describe("RhoPi test", function () { |
||||
|
this.timeout(100000); |
||||
|
|
||||
|
it ("RhoPi (testvector generated from go)", async () => { |
||||
|
const cir = await wasm_tester(path.join(__dirname, "circuits", "rhopi_test.circom")); |
||||
|
|
||||
|
const input = |
||||
|
utils.intsToBigInts([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
||||
|
const expectedOut = utils.strsToBigInts(["0", "105553116266496", |
||||
|
"105553116266496", "37748736", "393216", "805306368", "9437184", |
||||
|
"80", "562949953421312", "13835058055282163714", "2", "448", |
||||
|
"436207616", "4864", "5242880", "536870912", "343597383680", |
||||
|
"11264", "557056", "1657324662872342528", "9223372036854775808", |
||||
|
"288230376151711744", "7696581394432", "32985348833280", "84"]); |
||||
|
const stateIn = utils.u64ArrayToBits(input); |
||||
|
const expectedOutBits = utils.u64ArrayToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(25*64)); |
||||
|
const stateOutU64 = utils.bitsToU64Array(stateOut); |
||||
|
// console.log(stateOutU64, expectedOut);
|
||||
|
assert.deepEqual(stateOutU64, expectedOut); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
describe("Chi test", function () { |
||||
|
this.timeout(100000); |
||||
|
|
||||
|
it ("Chi (testvector generated from go)", async () => { |
||||
|
const cir = await wasm_tester(path.join(__dirname, "circuits", "chi_test.circom")); |
||||
|
|
||||
|
const input = |
||||
|
utils.intsToBigInts([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
||||
|
const expectedOut = utils.intsToBigInts([2, 0, 6, 3, 5, 4, 14, 6, 12, |
||||
|
11, 14, 10, 14, 13, 15, 14, 18, 16, 30, 3, 22, 20, 30, 19, 25]); |
||||
|
const stateIn = utils.u64ArrayToBits(input); |
||||
|
const expectedOutBits = utils.u64ArrayToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(25*64)); |
||||
|
const stateOutU64 = utils.bitsToU64Array(stateOut); |
||||
|
// console.log(stateOutU64, expectedOut);
|
||||
|
assert.deepEqual(stateOutU64, expectedOut); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
describe("Iota test", function () { |
||||
|
this.timeout(100000); |
||||
|
|
||||
|
it ("Iota 3 (testvector generated from go)", async () => { |
||||
|
const cir = await wasm_tester(path.join(__dirname, "circuits", "iota3_test.circom")); |
||||
|
|
||||
|
const input = |
||||
|
utils.intsToBigInts([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
||||
|
const expectedOut = |
||||
|
utils.strsToBigInts(["9223372039002292224",1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
||||
|
const stateIn = utils.u64ArrayToBits(input); |
||||
|
const expectedOutBits = utils.u64ArrayToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(25*64)); |
||||
|
const stateOutU64 = utils.bitsToU64Array(stateOut); |
||||
|
// console.log(stateOutU64, expectedOut);
|
||||
|
assert.deepEqual(stateOutU64, expectedOut); |
||||
|
}); |
||||
|
it ("Iota 10 (testvector generated from go)", async () => { |
||||
|
const cir = await wasm_tester(path.join(__dirname, "circuits", "iota10_test.circom")); |
||||
|
|
||||
|
const input = |
||||
|
utils.strsToBigInts(["9223372039002292224",1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
||||
|
const expectedOut = |
||||
|
utils.strsToBigInts(["9223372036854775817",1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
||||
|
const stateIn = utils.u64ArrayToBits(input); |
||||
|
const expectedOutBits = utils.u64ArrayToBits(expectedOut); |
||||
|
|
||||
|
const witness = await cir.calculateWitness({ "in": stateIn }, true); |
||||
|
|
||||
|
const stateOut = witness.slice(1, 1+(25*64)); |
||||
|
const stateOutU64 = utils.bitsToU64Array(stateOut); |
||||
|
// console.log(stateOutU64, expectedOut);
|
||||
|
assert.deepEqual(stateOutU64, expectedOut); |
||||
|
}); |
||||
|
}); |
@ -0,0 +1,147 @@ |
|||||
|
const F1Field = require("ffjavascript").F1Field; |
||||
|
const Scalar = require("ffjavascript").Scalar; |
||||
|
exports.p = |
||||
|
Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"); |
||||
|
const Fr = new F1Field(exports.p); |
||||
|
|
||||
|
const chai = require("chai"); |
||||
|
const assert = chai.assert; |
||||
|
|
||||
|
module.exports = { |
||||
|
bytesToU64, |
||||
|
u64ToBytes, |
||||
|
u64ToBits, |
||||
|
bytesToBits, |
||||
|
u64ArrayToBits, |
||||
|
bitsToU64, |
||||
|
bitsToBytes, |
||||
|
bitsToU64Array, |
||||
|
strsToBigInts, |
||||
|
intsToBigInts, |
||||
|
bigIntsToInts, |
||||
|
bufferToBytes |
||||
|
}; |
||||
|
|
||||
|
function bytesToU64(byteArray) { |
||||
|
// var value = 0;
|
||||
|
var value = Fr.e(0); |
||||
|
for ( var i = byteArray.length - 1; i >= 0; i--) { |
||||
|
// value = (value * 256) + byteArray[i];
|
||||
|
value = Fr.add(Fr.mul(Fr.e(value), Fr.e(256)), Fr.e(byteArray[i])); |
||||
|
} |
||||
|
|
||||
|
return value; |
||||
|
} |
||||
|
function u64ToBytes(a) { |
||||
|
var b = Fr.e(a); |
||||
|
|
||||
|
const buff = new Uint8Array(8); |
||||
|
Scalar.toRprLE(buff, 0, b, 8); |
||||
|
return buff; |
||||
|
} |
||||
|
function u64ToBits(a) { |
||||
|
const aBytes = u64ToBytes(a); |
||||
|
return bytesToBits(aBytes); |
||||
|
} |
||||
|
function bytesToBits(b) { |
||||
|
const bits = []; |
||||
|
for (let i = 0; i < b.length; i++) { |
||||
|
for (let j = 0; j < 8; j++) { |
||||
|
if ((Number(b[i])&(1<<j)) > 0) { |
||||
|
// bits.push(Fr.e(1));
|
||||
|
bits.push(1); |
||||
|
} else { |
||||
|
// bits.push(Fr.e(0));
|
||||
|
bits.push(0); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return bits |
||||
|
} |
||||
|
function u64ArrayToBits(u) { |
||||
|
let r = []; |
||||
|
for (let i = 0; i < u.length; i++) { |
||||
|
r = r.concat(u64ToBits(u[i])); |
||||
|
} |
||||
|
return r |
||||
|
} |
||||
|
function bitsToU64(b) { |
||||
|
if (b.length != 64) { |
||||
|
console.log("b.length = ", b.length, " max=64"); |
||||
|
return; |
||||
|
} |
||||
|
const by = bitsToBytes(b) |
||||
|
return bytesToU64(by) |
||||
|
} |
||||
|
function bitsToBytes(a) { |
||||
|
const b = []; |
||||
|
|
||||
|
for (let i=0; i<a.length; i++) { |
||||
|
const p = Math.floor(i/8); |
||||
|
if (b[p]==undefined) { |
||||
|
b[p] = 0; |
||||
|
} |
||||
|
if (a[i]==1) { |
||||
|
b[p] |= 1<<(i%8); |
||||
|
} |
||||
|
} |
||||
|
return b; |
||||
|
} |
||||
|
|
||||
|
function bitsToU64Array(b) { |
||||
|
const r = []; |
||||
|
for (let i = 0; i < b.length/64; i++) { |
||||
|
r.push(bitsToU64(b.slice(i*64, i*64+64))); |
||||
|
} |
||||
|
return r |
||||
|
} |
||||
|
|
||||
|
function strsToBigInts(a) { |
||||
|
let b = []; |
||||
|
for (let i=0; i<a.length; i++) { |
||||
|
b[i] = Fr.e(a[i]); |
||||
|
} |
||||
|
return b; |
||||
|
} |
||||
|
function intsToBigInts(a) { |
||||
|
let b = []; |
||||
|
for (let i=0; i<a.length; i++) { |
||||
|
b[i] = Fr.e(a[i]); |
||||
|
} |
||||
|
return b; |
||||
|
} |
||||
|
function bigIntsToInts(a) { |
||||
|
let b = []; |
||||
|
for (let i=0; i<a.length; i++) { |
||||
|
b[i] = Number(a[i]); |
||||
|
} |
||||
|
return b; |
||||
|
} |
||||
|
function bufferToBytes(buff) { |
||||
|
const bytes = []; |
||||
|
for (let i = 0; i < buff.length; i++) { |
||||
|
bytes.push(buff[i]); |
||||
|
} |
||||
|
return bytes; |
||||
|
} |
||||
|
|
||||
|
describe("Utils test", function () { |
||||
|
this.timeout(100000); |
||||
|
|
||||
|
it ("utils", async () => { |
||||
|
let a = 3; |
||||
|
let aBits = u64ToBits(a); |
||||
|
let a2 = bitsToU64(aBits); |
||||
|
assert.equal(a2, a); |
||||
|
a = 12345; |
||||
|
aBits = u64ToBits(a); |
||||
|
a2 = bitsToU64(aBits); |
||||
|
assert.equal(a2, a); |
||||
|
|
||||
|
a = intsToBigInts([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]); |
||||
|
aBits = u64ArrayToBits(a); |
||||
|
a2 = bitsToU64Array(aBits); |
||||
|
assert.deepEqual(a2, a); |
||||
|
}); |
||||
|
}); |
||||
|
|