arnaucube
arnaucube/grapevine-sonobePublic Self-hosted repository
grapevine-sonobe/circom/node_modules/circomlib/circuits/poseidon_old.circom
circom/node_modules/circomlib/circuits/poseidon_old.circomRaw
 1pragma circom 2.0.0;
 2
 3include "./poseidon_constants.circom";
 4
 5template Sigma() {
 6    signal input in;
 7    signal output out;
 8
 9    signal in2;
10    signal in4;
11
12    in2 <== in*in;
13    in4 <== in2*in2;
14
15    out <== in4*in;
16}
17
18template Ark(t, C, r) {
19    signal input in[t];
20    signal output out[t];
21
22    for (var i=0; i<t; i++) {
23        out[i] <== in[i] + C[i + r];
24    }
25}
26
27template Mix(t, M) {
28    signal input in[t];
29    signal output out[t];
30
31    var lc;
32    for (var i=0; i<t; i++) {
33        lc = 0;
34        for (var j=0; j<t; j++) {
35            lc += M[i][j]*in[j];
36        }
37        out[i] <== lc;
38    }
39}
40
41template Poseidon(nInputs) {
42    signal input inputs[nInputs];
43    signal output out;
44
45    // Using recommended parameters from whitepaper https://eprint.iacr.org/2019/458.pdf (table 2, table 8)
46    // Generated by https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/calc_round_numbers.py
47    // And rounded up to nearest integer that divides by t
48    var N_ROUNDS_P[16] = [56, 57, 56, 60, 60, 63, 64, 63, 60, 66, 60, 65, 70, 60, 64, 68];
49    var t = nInputs + 1;
50    var nRoundsF = 8;
51    var nRoundsP = N_ROUNDS_P[t - 2];
52    var C[t*(nRoundsF + nRoundsP)] = POSEIDON_C(t);
53    var M[t][t] = POSEIDON_M(t);
54
55    component ark[nRoundsF + nRoundsP];
56    component sigmaF[nRoundsF][t];
57    component sigmaP[nRoundsP];
58    component mix[nRoundsF + nRoundsP];
59
60    var k;
61
62    for (var i=0; i<nRoundsF + nRoundsP; i++) {
63        ark[i] = Ark(t, C, t*i);
64        for (var j=0; j<t; j++) {
65            if (i==0) {
66                if (j>0) {
67                    ark[i].in[j] <== inputs[j-1];
68                } else {
69                    ark[i].in[j] <== 0;
70                }
71            } else {
72                ark[i].in[j] <== mix[i-1].out[j];
73            }
74        }
75
76        if (i < nRoundsF/2 || i >= nRoundsP + nRoundsF/2) {
77            k = i < nRoundsF/2 ? i : i - nRoundsP;
78            mix[i] = Mix(t, M);
79            for (var j=0; j<t; j++) {
80                sigmaF[k][j] = Sigma();
81                sigmaF[k][j].in <== ark[i].out[j];
82                mix[i].in[j] <== sigmaF[k][j].out;
83            }
84        } else {
85            k = i - nRoundsF/2;
86            mix[i] = Mix(t, M);
87            sigmaP[k] = Sigma();
88            sigmaP[k].in <== ark[i].out[0];
89            mix[i].in[0] <== sigmaP[k].out;
90            for (var j=1; j<t; j++) {
91                mix[i].in[j] <== ark[i].out[j];
92            }
93        }
94    }
95
96    out <== mix[nRoundsF + nRoundsP -1].out[0];
97}