arnaucube
arnaucube/keccak256-circomPublic Self-hosted repository
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;
 14const c_tester = require("circom_tester").c;
 15
 16// const printSignal = require("./helpers/printsignal");
 17
 18function bytesToU64(byteArray) {
 19    // var value = 0;
 20    var value = Fr.e(0);
 21    for ( var i = byteArray.length - 1; i >= 0; i--) {
 22	// value = (value * 256) + byteArray[i];
 23	value = Fr.add(Fr.mul(Fr.e(value), Fr.e(256)), Fr.e(byteArray[i]));
 24    }
 25
 26    return value;
 27}
 28function u64ToBytes(a) {
 29    var b = Fr.e(a);
 30
 31    const buff = new Uint8Array(8);
 32    Scalar.toRprLE(buff, 0, b, 8);
 33    return buff;
 34}
 35function u64ToBits(a) {
 36    const aBytes = u64ToBytes(a);
 37    return bytesToBits(aBytes);
 38}
 39function bytesToBits(b) {
 40    const bits = [];
 41    for (let i = 0; i < b.length; i++) {
 42	for (let j = 0; j < 8; j++) {
 43	    if ((Number(b[i])&(1<<j)) > 0) {
 44		// bits.push(Fr.e(1));
 45		bits.push(1);
 46	    } else {
 47		// bits.push(Fr.e(0));
 48		bits.push(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 strsToBigInts(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}
 99function intsToBigInts(a) {
100    let b = [];
101    for (let i=0; i<a.length; i++) {
102	b[i] = Fr.e(a[i]);
103    }
104    return b;
105}
106function bigIntsToInts(a) {
107    let b = [];
108    for (let i=0; i<a.length; i++) {
109	b[i] = Number(a[i]);
110    }
111    return b;
112}
113
114describe("Utils test", function () {
115    this.timeout(100000);
116
117    it ("utils", async () => {
118	let a = 3;
119	let aBits = u64ToBits(a);
120	let a2 = bitsToU64(aBits);
121	assert.equal(a2, a);
122	a = 12345;
123	aBits = u64ToBits(a);
124	a2 = bitsToU64(aBits);
125	assert.equal(a2, a);
126
127	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]);
128	aBits = u64ArrayToBits(a);
129	a2 = bitsToU64Array(aBits);
130	assert.deepEqual(a2, a);
131    });
132});
133
134
135describe("Theta test", function () {
136    this.timeout(100000);
137
138    it ("Theta (testvector generated from go)", async () => {
139	const cir = await wasm_tester(path.join(__dirname, "circuits", "theta_test.circom"));
140
141	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]);
142	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]);
143	const stateIn = u64ArrayToBits(input);
144	const expectedOutBits = u64ArrayToBits(expectedOut);
145
146	const witness = await cir.calculateWitness({ "in": stateIn }, true);
147
148	const stateOut = witness.slice(1, 1+(25*64));
149	const stateOutU64 = bitsToU64Array(stateOut);
150	// console.log(stateOutU64, expectedOut);
151	assert.deepEqual(stateOutU64, expectedOut);
152    });
153    it ("Theta (same test as previous, but using c_tester to ensure that circom_tester with c works as expected)", async () => {
154	const cir = await c_tester(path.join(__dirname, "circuits", "theta_test.circom"));
155
156	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]);
157	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]);
158	const stateIn = u64ArrayToBits(input);
159	const expectedOutBits = u64ArrayToBits(expectedOut);
160
161	const witness = await cir.calculateWitness({ "in": stateIn }, true);
162
163	const stateOut = witness.slice(1, 1+(25*64));
164	const stateOutU64 = bitsToU64Array(stateOut);
165	// console.log(stateOutU64, expectedOut);
166	assert.deepEqual(stateOutU64, expectedOut);
167    });
168
169    it ("Theta (testvector generated from go)", async () => {
170	const cir = await wasm_tester(path.join(__dirname, "circuits", "theta_test.circom"));
171	// const cir = await c_tester(path.join(__dirname, "circuits", "theta_test.circom"));
172
173	const input = strsToBigInts(["26388279066651", "246290629787648", "26388279902208",
174	    "25165850", "246290605457408", "7784628352", "844424965783552",
175	    "2305843009213694083", "844432714760192", "2305843009249345539",
176	    "637534226", "14848", "641204224", "14354", "3670528", "6308236288",
177	    "2130304761856", "648518346341354496", "6309216256", "648520476645130240",
178	    "4611706359392501763", "792677514882318336", "20340965113972",
179	    "4611732197915754499", "792633534417207412"]);
180	const expectedOut = strsToBigInts(["3749081831850030700", "1297317621190464868",
181	    "10017560217643747862", "7854780639862409219", "13836147678645575967",
182	    "3749090635727681271", "1297915755455157604", "12323429615135705749",
183	    "7855062122598582297", "16141814766035214620", "3749090628446369381",
184	    "1297071330560683876", "10017586606556924438", "7854780639837253643",
185	    "13835971756788491039", "3749090634251287159", "1297070162329376100",
186	    "9369068259580659222", "7854780645071013913", "14484490034407743775",
187	    "8360757404916954740", "1801500877105239396", "10017570663003408994",
188	    "3243123208712177690", "14628605291203076459"]);
189
190	const stateIn = u64ArrayToBits(input);
191	const expectedOutBits = u64ArrayToBits(expectedOut);
192
193	const witness = await cir.calculateWitness({ "in": stateIn }, true);
194
195	const stateOut = witness.slice(1, 1+(25*64));
196	const stateOutU64 = bitsToU64Array(stateOut);
197	assert.deepEqual(stateOutU64, expectedOut);
198    });
199
200
201});
202
203describe("RhoPi test", function () {
204    this.timeout(100000);
205
206    it ("RhoPi (testvector generated from go)", async () => {
207	const cir = await wasm_tester(path.join(__dirname, "circuits", "rhopi_test.circom"));
208
209	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]);
210	const expectedOut = strsToBigInts(["0", "105553116266496", "105553116266496", "37748736", "393216",
211	    "805306368", "9437184", "80", "562949953421312", "13835058055282163714",
212	    "2", "448", "436207616", "4864", "5242880", "536870912", "343597383680",
213	    "11264", "557056", "1657324662872342528", "9223372036854775808",
214	    "288230376151711744", "7696581394432", "32985348833280", "84"]);
215	const stateIn = u64ArrayToBits(input);
216	const expectedOutBits = u64ArrayToBits(expectedOut);
217
218	const witness = await cir.calculateWitness({ "in": stateIn }, true);
219
220	const stateOut = witness.slice(1, 1+(25*64));
221	const stateOutU64 = bitsToU64Array(stateOut);
222	// console.log(stateOutU64, expectedOut);
223	assert.deepEqual(stateOutU64, expectedOut);
224    });
225});
226
227describe("Chi test", function () {
228    this.timeout(100000);
229
230    it ("Chi (testvector generated from go)", async () => {
231	const cir = await wasm_tester(path.join(__dirname, "circuits", "chi_test.circom"));
232
233	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]);
234	const expectedOut = intsToBigInts([2, 0, 6, 3, 5, 4, 14, 6, 12, 11, 14, 10, 14, 13, 15,
235	    14, 18, 16, 30, 3, 22, 20, 30, 19, 25]);
236	const stateIn = u64ArrayToBits(input);
237	const expectedOutBits = u64ArrayToBits(expectedOut);
238
239	const witness = await cir.calculateWitness({ "in": stateIn }, true);
240
241	const stateOut = witness.slice(1, 1+(25*64));
242	const stateOutU64 = bitsToU64Array(stateOut);
243	// console.log(stateOutU64, expectedOut);
244	assert.deepEqual(stateOutU64, expectedOut);
245    });
246});
247
248describe("Iota test", function () {
249    this.timeout(100000);
250
251    it ("Iota 3 (testvector generated from go)", async () => {
252	const cir = await wasm_tester(path.join(__dirname, "circuits", "iota3_test.circom"));
253
254	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]);
255	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]);
256	const stateIn = u64ArrayToBits(input);
257	const expectedOutBits = u64ArrayToBits(expectedOut);
258
259	const witness = await cir.calculateWitness({ "in": stateIn }, true);
260
261	const stateOut = witness.slice(1, 1+(25*64));
262	const stateOutU64 = bitsToU64Array(stateOut);
263	// console.log(stateOutU64, expectedOut);
264	assert.deepEqual(stateOutU64, expectedOut);
265    });
266    it ("Iota 10 (testvector generated from go)", async () => {
267	const cir = await wasm_tester(path.join(__dirname, "circuits", "iota10_test.circom"));
268
269	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]);
270	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]);
271	const stateIn = u64ArrayToBits(input);
272	const expectedOutBits = u64ArrayToBits(expectedOut);
273
274	const witness = await cir.calculateWitness({ "in": stateIn }, true);
275
276	const stateOut = witness.slice(1, 1+(25*64));
277	const stateOutU64 = bitsToU64Array(stateOut);
278	// console.log(stateOutU64, expectedOut);
279	assert.deepEqual(stateOutU64, expectedOut);
280    });
281});
282
283describe("Keccak-Pad test", function () {
284    this.timeout(100000);
285
286    it ("Pad (testvector generated from go)", async () => {
287	const cir = await wasm_tester(path.join(__dirname, "circuits", "pad_test.circom"));
288
289	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];
290	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];
291
292	const stateIn = bytesToBits(input);
293
294	const witness = await cir.calculateWitness({ "in": stateIn }, true);
295
296	const stateOut = witness.slice(1, 1+(136*8));
297	const stateOutBytes = bitsToBytes(stateOut);
298	// console.log(stateOutBytes, expectedOut);
299	assert.deepEqual(stateOutBytes, expectedOut);
300    });
301});
302
303describe("keccakfRound test", function () {
304    this.timeout(100000);
305
306    // apt install nlohmann-json3-dev
307    // apt install nasm
308
309    it ("keccakfRound (testvector generated from go)", async () => {
310	// const cir = await wasm_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
311	const cir = await c_tester(path.join(__dirname, "circuits", "keccakfRound0_test.circom"));
312	await cir.loadConstraints();
313	// console.log("n_constraints", cir.constraints.length);
314
315	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];
316	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"]);
317
318	const stateIn = u64ArrayToBits(input);
319	const expectedOutBits = u64ArrayToBits(expectedOut);
320
321	const witness = await cir.calculateWitness({ "in": stateIn }, true);
322
323	const stateOut = witness.slice(1, 1+(25*64));
324	const stateOutU64 = bitsToU64Array(stateOut);
325	// console.log(stateOutU64, expectedOut);
326	assert.deepEqual(stateOutU64, expectedOut);
327    });
328
329    it ("keccakfRound 20 (testvector generated from go)", async () => {
330	// const cir = await wasm_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
331	const cir = await c_tester(path.join(__dirname, "circuits", "keccakfRound20_test.circom"));
332	await cir.loadConstraints();
333	// console.log("n_constraints", cir.constraints.length);
334
335	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"]);
336	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"]);
337
338	const stateIn = u64ArrayToBits(input);
339	const expectedOutBits = u64ArrayToBits(expectedOut);
340
341	const witness = await cir.calculateWitness({ "in": stateIn }, true);
342
343	const stateOut = witness.slice(1, 1+(25*64));
344	const stateOutU64 = bitsToU64Array(stateOut);
345	// console.log(stateOutU64, expectedOut);
346	assert.deepEqual(stateOutU64, expectedOut);
347    });
348});
349
350describe("keccakf test", function () {
351    this.timeout(100000);
352
353    let cir;
354    before(async () => {
355	// const cir = await wasm_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
356	cir = await c_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
357	await cir.loadConstraints();
358	console.log("n_constraints", cir.constraints.length);
359    });
360
361    it ("keccakf 1 (testvector generated from go)", async () => {
362	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];
363	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"]);
364
365	const stateIn = u64ArrayToBits(input);
366	const expectedOutBits = u64ArrayToBits(expectedOut);
367
368	const witness = await cir.calculateWitness({ "in": stateIn }, true);
369
370	const stateOut = witness.slice(1, 1+(25*64));
371	const stateOutU64 = bitsToU64Array(stateOut);
372	// console.log(stateOutU64, expectedOut);
373	assert.deepEqual(stateOutU64, expectedOut);
374    });
375
376    it ("keccakf 2 (testvector generated from go)", async () => {
377	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"]);
378	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"]);
379
380	const stateIn = u64ArrayToBits(input);
381	const expectedOutBits = u64ArrayToBits(expectedOut);
382
383	const witness = await cir.calculateWitness({ "in": stateIn }, true);
384
385	const stateOut = witness.slice(1, 1+(25*64));
386	const stateOutU64 = bitsToU64Array(stateOut);
387	// console.log(stateOutU64, expectedOut);
388	assert.deepEqual(stateOutU64, expectedOut);
389    });
390});
391
392describe("absorb test", function () {
393    this.timeout(100000);
394
395    let cir;
396    before(async () => {
397	// const cir = await wasm_tester(path.join(__dirname, "circuits", "keccakf_test.circom"));
398	cir = await c_tester(path.join(__dirname, "circuits", "absorb_test.circom"));
399	await cir.loadConstraints();
400	console.log("n_constraints", cir.constraints.length);
401    });
402
403    it ("absorb 1 (testvector generated from go)", async () => {
404	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"]);
405
406	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"]);
407
408	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"]);
409
410	const sIn = u64ArrayToBits(s);
411	const blockIn = bytesToBits(block);
412	const expectedOutBits = u64ArrayToBits(expectedOut);
413
414	const witness = await cir.calculateWitness({ "s": sIn, "block": blockIn }, true);
415
416	const stateOut = witness.slice(1, 1+(25*64));
417	const stateOutU64 = bitsToU64Array(stateOut);
418	// console.log(stateOutU64, expectedOut);
419	assert.deepEqual(stateOutU64, expectedOut);
420    });
421
422    it ("absorb 2 (testvector generated from go)", async () => {
423	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"]);
424
425	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"]);
426
427	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"]);
428
429	const sIn = u64ArrayToBits(s);
430	const blockIn = bytesToBits(block);
431	const expectedOutBits = u64ArrayToBits(expectedOut);
432
433	const witness = await cir.calculateWitness({ "s": sIn, "block": blockIn }, true);
434
435	const stateOut = witness.slice(1, 1+(25*64));
436	const stateOutU64 = bitsToU64Array(stateOut);
437	// console.log(stateOutU64, expectedOut);
438	assert.deepEqual(stateOutU64, expectedOut);
439    });
440});
441
442describe("Keccak-Final test", function () {
443    this.timeout(100000);
444
445    let cir;
446    before(async () => {
447	cir = await c_tester(path.join(__dirname, "circuits", "final_test.circom"));
448	await cir.loadConstraints();
449	console.log("n_constraints", cir.constraints.length);
450    });
451
452    it ("Final 1 (testvector generated from go)", async () => {
453	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];
454	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"]);
455
456	const inIn = bytesToBits(input);
457	const expectedOutBits = u64ArrayToBits(expectedOut);
458
459	const witness = await cir.calculateWitness({ "in": inIn }, true);
460
461	const stateOut = witness.slice(1, 1+(25*64));
462	const stateOutU64 = bitsToU64Array(stateOut);
463	// console.log(stateOutU64, expectedOut);
464	assert.deepEqual(stateOutU64, expectedOut);
465    });
466
467    it ("Final 2 (testvector generated from go)", async () => {
468	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"]);
469	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"]);
470
471	const inIn = bytesToBits(input);
472	const expectedOutBits = u64ArrayToBits(expectedOut);
473
474	const witness = await cir.calculateWitness({ "in": inIn }, true);
475
476	const stateOut = witness.slice(1, 1+(25*64));
477	const stateOutU64 = bitsToU64Array(stateOut);
478	// console.log(stateOutU64, expectedOut);
479	assert.deepEqual(stateOutU64, expectedOut);
480    });
481});