keccak256-circom/test/keccak256.js
test/keccak256.jsRaw
1const chai = require("chai");
2const path = require("path");
3const crypto = require("crypto");
4const F1Field = require("ffjavascript").F1Field;
5const Scalar = require("ffjavascript").Scalar;
6exports.p = Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
7const Fr = new F1Field(exports.p);
8
9const assert = chai.assert;
10
11const keccak256 = require("keccak256");
12
13const wasm_tester = require("circom_tester").wasm;
14
15// const printSignal = require("./helpers/printsignal");
16
17function bytesToU64(byteArray) {
18 var value = 0;
19 for ( var i = byteArray.length - 1; i >= 0; i--) {
20 value = (value * 256) + byteArray[i];
21 }
22
23 return value;
24}
25function u64ToBytes(long) {
26 var byteArray = [0, 0, 0, 0, 0, 0, 0, 0];
27
28 for ( var index = 0; index < byteArray.length; index ++ ) {
29 var byte = long & 0xff;
30 byteArray [ index ] = byte;
31 long = (long - byte) / 256 ;
32 }
33
34 return byteArray;
35}
36
37function u64ToBits(a) {
38 const aBytes = u64ToBytes(a);
39 return bytesToBits(aBytes);
40}
41function bytesToBits(b) {
42 const bits = [];
43 for (let i = 0; i < b.length; i++) {
44 for (let j = 0; j < 8; j++) {
45 if ((b[i]&(1<<j)) > 0) {
46 bits.push(Fr.e(1));
47 } else {
48 bits.push(Fr.e(0));
49 }
50 }
51 }
52 return bits
53}
54function u64ArrayToBits(u) {
55 let r = [];
56 for (let i = 0; i < u.length; i++) {
57 r = r.concat(u64ToBits(u[i]));
58 }
59 return r
60}
61function bitsToU64(b) {
62 if (b.length != 64) {
63 console.log("b.length = ", b.length, " max=64");
64 return;
65 }
66 const by = bitsToBytes(b)
67 return bytesToU64(by)
68}
69function bitsToBytes(a) {
70 const b = [];
71
72 for (let i=0; i<a.length; i++) {
73 const p = Math.floor(i/8);
74 if (b[p]==undefined) {
75 b[p] = 0;
76 }
77 if (a[i]==1) {
78 b[p] |= 1<<(i%8);
79 }
80 }
81 return b;
82}
83
84function bitsToU64Array(b) {
85 const r = [];
86 for (let i = 0; i < b.length/64; i++) {
87 r.push(bitsToU64(b.slice(i*64, i*64+64)));
88 }
89 return r
90}
91
92function intsToBigInts(a) {
93 let b = [];
94 for (let i=0; i<a.length; i++) {
95 b[i] = Fr.e(a[i]);
96 }
97 return b;
98}
99
100describe("Utils test", function () {
101 this.timeout(100000);
102
103 it ("utils", async () => {
104 let a = 3;
105 let aBits = u64ToBits(a);
106 let a2 = bitsToU64(aBits);
107 assert.equal(a2, a);
108 a = 12345;
109 aBits = u64ToBits(a);
110 a2 = bitsToU64(aBits);
111 assert.equal(a2, a);
112
113 a = [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];
114 aBits = u64ArrayToBits(a);
115 a2 = bitsToU64Array(aBits);
116 // console.log(a2, a);
117 assert.deepEqual(a2, a);
118 });
119});
120
121
122describe("Theta test", function () {
123 this.timeout(100000);
124
125 it ("Theta (testvector generated from go)", async () => {
126 const cir = await wasm_tester(path.join(__dirname, "circuits", "theta_test.circom"));
127
128 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];
129 const expectedOut = [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];
130 const stateIn = u64ArrayToBits(input);
131 const expectedOutBits = u64ArrayToBits(expectedOut);
132
133 const witness = await cir.calculateWitness({ "in": stateIn }, true);
134
135 const stateOut = witness.slice(1, 1+(25*64));
136 const stateOutU64 = bitsToU64Array(stateOut);
137 // console.log(stateOutU64, expectedOut);
138 assert.deepEqual(stateOutU64, expectedOut);
139 });
140});
141
142describe("RhoPi test", function () {
143 this.timeout(100000);
144
145 it ("RhoPi (testvector generated from go)", async () => {
146 const cir = await wasm_tester(path.join(__dirname, "circuits", "rhopi_test.circom"));
147
148 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];
149 const expectedOut = [0, 105553116266496, 105553116266496, 37748736, 393216,
150 805306368, 9437184, 80, 562949953421312, 13835058055282163714,
151 2, 448, 436207616, 4864, 5242880, 536870912, 343597383680,
152 11264, 557056, 1657324662872342528, 9223372036854775808,
153 288230376151711744, 7696581394432, 32985348833280, 84];
154 const stateIn = u64ArrayToBits(input);
155 const expectedOutBits = u64ArrayToBits(expectedOut);
156
157 const witness = await cir.calculateWitness({ "in": stateIn }, true);
158
159 const stateOut = witness.slice(1, 1+(25*64));
160 const stateOutU64 = bitsToU64Array(stateOut);
161 // console.log(stateOutU64, expectedOut);
162 assert.deepEqual(stateOutU64, expectedOut);
163 });
164});
165
166describe("Chi test", function () {
167 this.timeout(100000);
168
169 it ("Chi (testvector generated from go)", async () => {
170 const cir = await wasm_tester(path.join(__dirname, "circuits", "chi_test.circom"));
171
172 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];
173 const expectedOut = [2, 0, 6, 3, 5, 4, 14, 6, 12, 11, 14, 10, 14, 13, 15,
174 14, 18, 16, 30, 3, 22, 20, 30, 19, 25];
175 const stateIn = u64ArrayToBits(input);
176 const expectedOutBits = u64ArrayToBits(expectedOut);
177
178 const witness = await cir.calculateWitness({ "in": stateIn }, true);
179
180 const stateOut = witness.slice(1, 1+(25*64));
181 const stateOutU64 = bitsToU64Array(stateOut);
182 // console.log(stateOutU64, expectedOut);
183 assert.deepEqual(stateOutU64, expectedOut);
184 });
185});
186
187describe("Iota test", function () {
188 this.timeout(100000);
189
190 it ("Iota 3 (testvector generated from go)", async () => {
191 const cir = await wasm_tester(path.join(__dirname, "circuits", "iota3_test.circom"));
192
193 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];
194 const expectedOut = [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];
195 const stateIn = u64ArrayToBits(input);
196 const expectedOutBits = u64ArrayToBits(expectedOut);
197
198 const witness = await cir.calculateWitness({ "in": stateIn }, true);
199
200 const stateOut = witness.slice(1, 1+(25*64));
201 const stateOutU64 = bitsToU64Array(stateOut);
202 // console.log(stateOutU64, expectedOut);
203 assert.deepEqual(stateOutU64, expectedOut);
204 });
205 it ("Iota 10 (testvector generated from go)", async () => {
206 const cir = await wasm_tester(path.join(__dirname, "circuits", "iota10_test.circom"));
207
208 const input = [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];
209 const expectedOut = [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];
210 const stateIn = u64ArrayToBits(input);
211 const expectedOutBits = u64ArrayToBits(expectedOut);
212
213 const witness = await cir.calculateWitness({ "in": stateIn }, true);
214
215 const stateOut = witness.slice(1, 1+(25*64));
216 const stateOutU64 = bitsToU64Array(stateOut);
217 // console.log(stateOutU64, expectedOut);
218 assert.deepEqual(stateOutU64, expectedOut);
219 });
220});
221
222describe("Keccak-Pad test", function () {
223 this.timeout(100000);
224
225 it ("Pad (testvector generated from go)", async () => {
226 const cir = await wasm_tester(path.join(__dirname, "circuits", "pad_test.circom"));
227
228 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];
229 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];
230
231 const stateIn = bytesToBits(input);
232
233 const witness = await cir.calculateWitness({ "in": stateIn }, true);
234
235 const stateOut = witness.slice(1, 1+(136*8));
236 const stateOutBytes = bitsToBytes(stateOut);
237 // console.log(stateOutBytes, expectedOut);
238 assert.deepEqual(stateOutBytes, expectedOut);
239 });
240});
241