circomlibjs-hinkal-fork 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,125 +0,0 @@
1
- // Copyright (c) 2018 Jordi Baylina
2
- // License: LGPL-3.0+
3
- //
4
-
5
- import { ethers } from "ethers";
6
-
7
- import Contract from "./evmasm.js";
8
-
9
- export function createCode(seed, n) {
10
-
11
- let ci = ethers.utils.keccak256(ethers.utils.toUtf8Bytes(seed));
12
-
13
- const C = new Contract();
14
-
15
- C.push(0x64);
16
- C.push("0x00");
17
- C.push("0x00");
18
- C.calldatacopy();
19
- C.push("0x0100000000000000000000000000000000000000000000000000000000");
20
- C.push("0x00");
21
- C.mload();
22
- C.div();
23
- C.push("0x3f1a1187"); // MiMCSponge(uint256,uint256,uint256)
24
- C.eq();
25
- C.jmpi("start");
26
- C.invalid();
27
-
28
- C.label("start");
29
- C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
30
- C.push("0x44");
31
- C.mload(); // k q
32
- C.push("0x04");
33
- C.mload(); // xL k q
34
- C.dup(2); // q xL k q
35
- C.push("0x24");
36
- C.mload(); // xR q xL k q
37
- C.dup(1); // q xR q xL k q
38
- C.dup(0); // q q xR q xL k q
39
- C.dup(4); // xL q q xR q xL k q
40
- C.dup(6); // k xL q q xR q xL k q
41
- C.addmod(); // t=k+xL q xR q xL k q
42
- C.dup(1); // q t q xR q xL k q
43
- C.dup(0); // q q t q xR q xL k q
44
- C.dup(2); // t q q t q xR q xL k q
45
- C.dup(0); // t t q q t q xR q xL k q
46
- C.mulmod(); // b=t^2 q t q xR q xL k q
47
- C.dup(0); // b b q t q xR q xL k q
48
- C.mulmod(); // c=t^4 t q xR q xL k q
49
- C.mulmod(); // d=t^5 xR q xL k q
50
- C.addmod(); // e=t^5+xR xL k q (for next round: xL xR k q)
51
-
52
- for (let i=0; i<n-1; i++) {
53
- if (i < n-2) {
54
- ci = ethers.utils.keccak256(ci);
55
- } else {
56
- ci = "0x00";
57
- }
58
- C.swap(1); // xR xL k q
59
- C.dup(3); // q xR xL k q
60
- C.dup(3); // k q xR xL k q
61
- C.dup(1); // q k q xR xL k q
62
- C.dup(4); // xL q k q xR xL k q
63
- C.push(ci); // ci xL q k q xR xL k q
64
- C.addmod(); // a=ci+xL k q xR xL k q
65
- C.addmod(); // t=a+k xR xL k q
66
- C.dup(4); // q t xR xL k q
67
- C.swap(1); // t q xR xL k q
68
- C.dup(1); // q t q xR xL k q
69
- C.dup(0); // q q t q xR xL k q
70
- C.dup(2); // t q q t q xR xL k q
71
- C.dup(0); // t t q q t q xR xL k q
72
- C.mulmod(); // b=t^2 q t q xR xL k q
73
- C.dup(0); // b b q t q xR xL k q
74
- C.mulmod(); // c=t^4 t q xR xL k q
75
- C.mulmod(); // d=t^5 xR xL k q
76
- C.dup(4); // q d xR xL k q
77
- C.swap(2); // xR d q xL k q
78
- C.addmod(); // e=t^5+xR xL k q (for next round: xL xR k q)
79
- }
80
-
81
- C.push("0x20");
82
- C.mstore(); // Save it to pos 0;
83
- C.push("0x00");
84
- C.mstore(); // Save it to pos 1;
85
- C.push("0x40");
86
- C.push("0x00");
87
- C.return();
88
-
89
- return C.createTxData();
90
- }
91
-
92
- export const abi = [
93
- {
94
- "constant": true,
95
- "inputs": [
96
- {
97
- "name": "xL_in",
98
- "type": "uint256"
99
- },
100
- {
101
- "name": "xR_in",
102
- "type": "uint256"
103
- },
104
- {
105
- "name": "k",
106
- "type": "uint256"
107
- }
108
- ],
109
- "name": "MiMCSponge",
110
- "outputs": [
111
- {
112
- "name": "xL",
113
- "type": "uint256"
114
- },
115
- {
116
- "name": "xR",
117
- "type": "uint256"
118
- }
119
- ],
120
- "payable": false,
121
- "stateMutability": "pure",
122
- "type": "function"
123
- }
124
- ];
125
-
@@ -1,25 +0,0 @@
1
- import buildMimcSponge from "./mimcsponge.js";
2
- import process from "process";
3
-
4
- async function run() {
5
- const mimcsponge = await buildMimcSponge();
6
- const nRounds = 220;
7
- let S = "[\n";
8
- const cts = mimcsponge.getConstants();
9
- for (let i=0; i<nRounds; i++) {
10
- S = S + mimcsponge.F.toString(cts[i]);
11
- if (i<nRounds-1) S = S + ",";
12
- S=S+"\n";
13
- }
14
- S = S + "]\n";
15
-
16
- console.log(S);
17
- }
18
-
19
- run().then(()=> {
20
- process.exit(0);
21
- }, (err) => {
22
- console.log(err.stack);
23
- console.log(err.message);
24
- process.exit(1);
25
- });
@@ -1,14 +0,0 @@
1
- import {createCode} from "./mimcsponge_gencontract.js";
2
- import process from "process";
3
-
4
- const SEED = "mimcsponge";
5
-
6
- let nRounds;
7
- if (typeof process.argv[2] != "undefined") {
8
- nRounds = parseInt(process.argv[2]);
9
- } else {
10
- nRounds = 220;
11
- }
12
-
13
- console.log(createCode(SEED, nRounds));
14
-
@@ -1,36 +0,0 @@
1
- import buildPedersenHash from "./pedersenhash.js";
2
- import process from "process";
3
-
4
- async function run() {
5
- const pedersenHash = await buildPedersenHash();
6
-
7
- let nBases;
8
- if (typeof process.argv[2] != "undefined") {
9
- nBases = parseInt(process.argv[2]);
10
- } else {
11
- nBases = 5;
12
- }
13
-
14
- let baseHash;
15
- if (typeof process.argv[3] != "undefined") {
16
- baseHash = process.argv[3];
17
- } else {
18
- baseHash = "blake";
19
- }
20
-
21
- for (let i=0; i < nBases; i++) {
22
- const p = pedersenHash.getBasePoint(i);
23
- console.log(`[${pedersenHash.babyJub.F.toString(p[0])},${pedersenHash.babyJub.F.toString(p[1])}]`);
24
- }
25
-
26
-
27
- }
28
-
29
- run().then(()=> {
30
- process.exit(0);
31
- }, (err) => {
32
- console.log(err.stack);
33
- console.log(err.message);
34
- process.exit(1);
35
- });
36
-
@@ -1,209 +0,0 @@
1
- // Copyright (c) 2018 Jordi Baylina
2
- // License: LGPL-3.0+
3
- //
4
-
5
- import Contract from "./evmasm.js";
6
- import { utils } from "ffjavascript";
7
- const { unstringifyBigInts } = utils;
8
- import { ethers } from "ethers";
9
-
10
- import poseidonConstants from "./poseidon_constants.js";
11
-
12
- const { C:K, M } = unstringifyBigInts(poseidonConstants);
13
-
14
- const N_ROUNDS_F = 8;
15
- const N_ROUNDS_P = [56, 57, 56, 60, 60, 63, 64, 63];
16
-
17
- function toHex256(a) {
18
- let S = a.toString(16);
19
- while (S.length < 64) S="0"+S;
20
- return "0x" + S;
21
- }
22
-
23
- export function createCode(nInputs) {
24
-
25
- if (( nInputs<1) || (nInputs>8)) throw new Error("Invalid number of inputs. Must be 1<=nInputs<=8");
26
- const t = nInputs + 1;
27
- const nRoundsF = N_ROUNDS_F;
28
- const nRoundsP = N_ROUNDS_P[t - 2];
29
-
30
- const C = new Contract();
31
-
32
- function saveM() {
33
- for (let i=0; i<t; i++) {
34
- for (let j=0; j<t; j++) {
35
- C.push(toHex256(M[t-2][i][j]));
36
- C.push((1+i*t+j)*32);
37
- C.mstore();
38
- }
39
- }
40
- }
41
-
42
- function ark(r) { // st, q
43
- for (let i=0; i<t; i++) {
44
- C.dup(t); // q, st, q
45
- C.push(toHex256(K[t-2][r*t+i])); // K, q, st, q
46
- C.dup(2+i); // st[i], K, q, st, q
47
- C.addmod(); // newSt[i], st, q
48
- C.swap(1 + i); // xx, st, q
49
- C.pop();
50
- }
51
- }
52
-
53
- function sigma(p) {
54
- // sq, q
55
- C.dup(t); // q, st, q
56
- C.dup(1+p); // st[p] , q , st, q
57
- C.dup(1); // q, st[p] , q , st, q
58
- C.dup(0); // q, q, st[p] , q , st, q
59
- C.dup(2); // st[p] , q, q, st[p] , q , st, q
60
- C.dup(0); // st[p] , st[p] , q, q, st[p] , q , st, q
61
- C.mulmod(); // st2[p], q, st[p] , q , st, q
62
- C.dup(0); // st2[p], st2[p], q, st[p] , q , st, q
63
- C.mulmod(); // st4[p], st[p] , q , st, q
64
- C.mulmod(); // st5[p], st, q
65
- C.swap(1+p);
66
- C.pop(); // newst, q
67
- }
68
-
69
- function mix() {
70
- C.label("mix");
71
- for (let i=0; i<t; i++) {
72
- for (let j=0; j<t; j++) {
73
- if (j==0) {
74
- C.dup(i+t); // q, newSt, oldSt, q
75
- C.push((1+i*t+j)*32);
76
- C.mload(); // M, q, newSt, oldSt, q
77
- C.dup(2+i+j); // oldSt[j], M, q, newSt, oldSt, q
78
- C.mulmod(); // acc, newSt, oldSt, q
79
- } else {
80
- C.dup(1+i+t); // q, acc, newSt, oldSt, q
81
- C.push((1+i*t+j)*32);
82
- C.mload(); // M, q, acc, newSt, oldSt, q
83
- C.dup(3+i+j); // oldSt[j], M, q, acc, newSt, oldSt, q
84
- C.mulmod(); // aux, acc, newSt, oldSt, q
85
- C.dup(2+i+t); // q, aux, acc, newSt, oldSt, q
86
- C.swap(2); // acc, aux, q, newSt, oldSt, q
87
- C.addmod(); // acc, newSt, oldSt, q
88
- }
89
- }
90
- }
91
- for (let i=0; i<t; i++) {
92
- C.swap((t -i) + (t -i-1));
93
- C.pop();
94
- }
95
- C.push(0);
96
- C.mload();
97
- C.jmp();
98
- }
99
-
100
-
101
- // Check selector
102
- C.push("0x0100000000000000000000000000000000000000000000000000000000");
103
- C.push(0);
104
- C.calldataload();
105
- C.div();
106
- C.dup(0);
107
- C.push(ethers.utils.keccak256(ethers.utils.toUtf8Bytes(`poseidon(uint256[${nInputs}])`)).slice(0, 10)); // poseidon(uint256[n])
108
- C.eq();
109
- C.swap(1);
110
- C.push(ethers.utils.keccak256(ethers.utils.toUtf8Bytes(`poseidon(bytes32[${nInputs}])`)).slice(0, 10)); // poseidon(bytes32[n])
111
- C.eq();
112
- C.or();
113
- C.jmpi("start");
114
- C.invalid();
115
-
116
- C.label("start");
117
-
118
- saveM();
119
-
120
- C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
121
-
122
- // Load t values from the call data.
123
- // The function has a single array param param
124
- // [Selector (4)] [item1 (32)] [item2 (32)] ....
125
- // Stack positions 0-nInputs.
126
- for (let i=0; i<nInputs; i++) {
127
- C.push(0x04+(0x20*(nInputs-i-1)));
128
- C.calldataload();
129
- }
130
-
131
- C.push(0);
132
-
133
- for (let i=0; i<nRoundsF+nRoundsP; i++) {
134
- ark(i);
135
- if ((i<nRoundsF/2) || (i>=nRoundsP+nRoundsF/2)) {
136
- for (let j=0; j<t; j++) {
137
- sigma(j);
138
- }
139
- } else {
140
- sigma(0);
141
- }
142
- const strLabel = "aferMix"+i;
143
- C._pushLabel(strLabel);
144
- C.push(0);
145
- C.mstore();
146
- C.jmp("mix");
147
- C.label(strLabel);
148
- }
149
-
150
- C.push("0x00");
151
- C.mstore(); // Save it to pos 0;
152
- C.push("0x20");
153
- C.push("0x00");
154
- C.return();
155
-
156
- mix();
157
-
158
- return C.createTxData();
159
- }
160
-
161
- export function generateABI(nInputs) {
162
- return [
163
- {
164
- "constant": true,
165
- "inputs": [
166
- {
167
- "internalType": `bytes32[${nInputs}]`,
168
- "name": "input",
169
- "type": `bytes32[${nInputs}]`
170
- }
171
- ],
172
- "name": "poseidon",
173
- "outputs": [
174
- {
175
- "internalType": "bytes32",
176
- "name": "",
177
- "type": "bytes32"
178
- }
179
- ],
180
- "payable": false,
181
- "stateMutability": "pure",
182
- "type": "function"
183
- },
184
- {
185
- "constant": true,
186
- "inputs": [
187
- {
188
- "internalType": `uint256[${nInputs}]`,
189
- "name": "input",
190
- "type": `uint256[${nInputs}]`
191
- }
192
- ],
193
- "name": "poseidon",
194
- "outputs": [
195
- {
196
- "internalType": "uint256",
197
- "name": "",
198
- "type": "uint256"
199
- }
200
- ],
201
- "payable": false,
202
- "stateMutability": "pure",
203
- "type": "function"
204
- }
205
- ];
206
- }
207
-
208
-
209
-
@@ -1,119 +0,0 @@
1
- // Parameters are generated by a reference script https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/generate_parameters_grain.sage
2
- // Used like so: sage generate_parameters_grain.sage 1 0 254 2 8 56 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
3
-
4
- // Using recommended parameters from whitepaper https://eprint.iacr.org/2019/458.pdf (table 2, table 8)
5
- // Generated by https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/calc_round_numbers.py
6
- // And rounded up to nearest integer that divides by t
7
-
8
- // Optimization is taken from https://github.com/filecoin-project/neptune
9
-
10
- import assert from "assert";
11
- import { getCurveFromName } from "ffjavascript";
12
-
13
- import poseidonConstants from "./poseidon_constants_opt.js";
14
-
15
- function unsringifyConstants(Fr, o) {
16
- if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) {
17
- return Fr.e(o);
18
- } else if ((typeof(o) == "string") && (/^0x[0-9a-fA-F]+$/.test(o) )) {
19
- return Fr.e(o);
20
- } else if (Array.isArray(o)) {
21
- return o.map(unsringifyConstants.bind(null, Fr));
22
- } else if (typeof o == "object") {
23
- if (o===null) return null;
24
- const res = {};
25
- const keys = Object.keys(o);
26
- keys.forEach( (k) => {
27
- res[k] = unsringifyConstants(Fr, o[k]);
28
- });
29
- return res;
30
- } else {
31
- return o;
32
- }
33
- }
34
-
35
- export default async function buildPoseidon() {
36
- const bn128 = await getCurveFromName("bn128", true);
37
-
38
- const F = bn128.Fr;
39
-
40
- const opt = unsringifyConstants(F, poseidonConstants);
41
-
42
- const N_ROUNDS_F = 8;
43
- const N_ROUNDS_P = [56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68];
44
-
45
- const pow5 = a => F.mul(a, F.square(F.square(a, a)));
46
-
47
- function poseidon(inputs, initState, nOut) {
48
- assert(inputs.length > 0);
49
- assert(inputs.length <= N_ROUNDS_P.length);
50
-
51
- if (initState) {
52
- initState = F.e(initState);
53
- } else {
54
- initState = F.zero;
55
- }
56
- nOut = nOut || 1;
57
-
58
-
59
- const t = inputs.length + 1;
60
- const nRoundsF = N_ROUNDS_F;
61
- const nRoundsP = N_ROUNDS_P[t - 2];
62
- const C = opt.C[t-2];
63
- const S = opt.S[t-2];
64
- const M = opt.M[t-2];
65
- const P = opt.P[t-2];
66
-
67
- let state = [initState, ...inputs.map(a => F.e(a))];
68
-
69
- state = state.map((a, i) => F.add(a, C[i]));
70
-
71
- for (let r = 0; r < nRoundsF/2-1; r++) {
72
- state = state.map(a => pow5(a));
73
- state = state.map((a, i) => F.add(a, C[(r +1)* t +i]));
74
- state = state.map((_, i) =>
75
- state.reduce((acc, a, j) => F.add(acc, F.mul(M[j][i], a)), F.zero)
76
- );
77
- }
78
- state = state.map(a => pow5(a));
79
- state = state.map((a, i) => F.add(a, C[(nRoundsF/2-1 +1)* t +i]));
80
- state = state.map((_, i) =>
81
- state.reduce((acc, a, j) => F.add(acc, F.mul(P[j][i], a)), F.zero)
82
- );
83
- for (let r = 0; r < nRoundsP; r++) {
84
- state[0] = pow5(state[0]);
85
- state[0] = F.add(state[0], C[(nRoundsF/2 +1)*t + r]);
86
-
87
-
88
- const s0 = state.reduce((acc, a, j) => {
89
- return F.add(acc, F.mul(S[(t*2-1)*r+j], a));
90
- }, F.zero);
91
- for (let k=1; k<t; k++) {
92
- state[k] = F.add(state[k], F.mul(state[0], S[(t*2-1)*r+t+k-1] ));
93
- }
94
- state[0] =s0;
95
- }
96
- for (let r = 0; r < nRoundsF/2-1; r++) {
97
- state = state.map(a => pow5(a));
98
- state = state.map((a, i) => F.add(a, C[ (nRoundsF/2 +1)*t + nRoundsP + r*t + i ]));
99
- state = state.map((_, i) =>
100
- state.reduce((acc, a, j) => F.add(acc, F.mul(M[j][i], a)), F.zero)
101
- );
102
- }
103
- state = state.map(a => pow5(a));
104
- state = state.map((_, i) =>
105
- state.reduce((acc, a, j) => F.add(acc, F.mul(M[j][i], a)), F.zero)
106
- );
107
-
108
- if (nOut == 1) {
109
- return state[0]
110
- } else {
111
- return state.slice(0, nOut);
112
- }
113
- }
114
-
115
- poseidon.F = F;
116
- return poseidon;
117
- }
118
-
119
-
@@ -1,14 +0,0 @@
1
- import {createCode} from "./poseidon_gencontract.js";
2
- import process from 'process';
3
-
4
- if (process.argv.length != 3) {
5
- console.log("Usage: node poseidon_gencontract.js [numberOfInputs]");
6
- process.exit(1);
7
- }
8
-
9
- const nInputs = Number(process.argv[2]);
10
-
11
- console.log(nInputs);
12
-
13
- console.log(createCode(nInputs));
14
-
@@ -1,22 +0,0 @@
1
-
2
-
3
- const Poseidon = require("./poseidon.js");
4
-
5
- const M = Poseidon.getMatrix();
6
-
7
- let S = "[\n ";
8
-
9
- for (let i=0; i<M.length; i++) {
10
- const LC = M[i];
11
- S = S + "[\n";
12
- for (let j=0; j<LC.length; j++) {
13
- S = S + " " + M[i][j].toString();
14
- if (j<LC.length-1) S = S + ",";
15
- S = S + "\n";
16
- }
17
- S = S + " ]";
18
- if (i<M.length-1) S = S + ",";
19
- }
20
- S=S+ "\n]\n";
21
-
22
- console.log(S);
@@ -1,83 +0,0 @@
1
-
2
- import assert from "assert";
3
- import { getCurveFromName } from "ffjavascript";
4
-
5
- import poseidonConstants from "./poseidon_constants.js";
6
-
7
- function unsringifyConstants(Fr, o) {
8
- if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) {
9
- return Fr.e(o);
10
- } else if ((typeof(o) == "string") && (/^0x[0-9a-fA-F]+$/.test(o) )) {
11
- return Fr.e(o);
12
- } else if (Array.isArray(o)) {
13
- return o.map(unsringifyConstants.bind(null, Fr));
14
- } else if (typeof o == "object") {
15
- if (o===null) return null;
16
- const res = {};
17
- const keys = Object.keys(o);
18
- keys.forEach( (k) => {
19
- res[k] = unsringifyConstants(Fr, o[k]);
20
- });
21
- return res;
22
- } else {
23
- return o;
24
- }
25
- }
26
-
27
- export default async function buildPoseidon() {
28
- const bn128 = await getCurveFromName("bn128", true);
29
-
30
- const F = bn128.Fr;
31
-
32
- // Parameters are generated by a reference script https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/generate_parameters_grain.sage
33
- // Used like so: sage generate_parameters_grain.sage 1 0 254 2 8 56 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
34
- const {C, M} = unsringifyConstants(F, poseidonConstants);
35
-
36
- // Using recommended parameters from whitepaper https://eprint.iacr.org/2019/458.pdf (table 2, table 8)
37
- // Generated by https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/calc_round_numbers.py
38
- // And rounded up to nearest integer that divides by t
39
- const N_ROUNDS_F = 8;
40
- const N_ROUNDS_P = [56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68];
41
-
42
- const pow5 = a => F.mul(a, F.square(F.square(a, a)));
43
-
44
- function poseidon(inputs, initState, nOut) {
45
- assert(inputs.length > 0);
46
- assert(inputs.length <= N_ROUNDS_P.length);
47
-
48
- const t = inputs.length + 1;
49
- const nRoundsF = N_ROUNDS_F;
50
- const nRoundsP = N_ROUNDS_P[t - 2];
51
-
52
- if (initState) {
53
- initState = F.e(initState);
54
- } else {
55
- initState = F.zero;
56
- }
57
- nOut = nOut || 1;
58
-
59
- let state = [initState, ...inputs.map(a => F.e(a))];
60
- for (let r = 0; r < nRoundsF + nRoundsP; r++) {
61
- state = state.map((a, i) => F.add(a, C[t - 2][r * t + i]));
62
-
63
- if (r < nRoundsF / 2 || r >= nRoundsF / 2 + nRoundsP) {
64
- state = state.map(a => pow5(a));
65
- } else {
66
- state[0] = pow5(state[0]);
67
- }
68
-
69
- state = state.map((_, i) =>
70
- state.reduce((acc, a, j) => F.add(acc, F.mul(M[t - 2][i][j], a)), F.zero)
71
- );
72
- }
73
- if (nOut == 1) {
74
- return state[0]
75
- } else {
76
- return state.slice(0, nOut);
77
- }
78
- }
79
-
80
- poseidon.F = F;
81
- return poseidon;
82
- }
83
-