You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

241 lines
7.4 KiB

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