@ -0,0 +1,202 @@ |
|||
|
|||
template Sigma() { |
|||
signal input in; |
|||
signal output out; |
|||
|
|||
signal in2; |
|||
signal in4; |
|||
|
|||
in2 <== in*in; |
|||
in4 <== in2*in2; |
|||
|
|||
out <== in4*in; |
|||
} |
|||
|
|||
template Ark(t, C) { |
|||
signal input in[t]; |
|||
signal output out[t]; |
|||
for (var i=0; i<t; i++) { |
|||
out[i] <== in[i] + C; |
|||
} |
|||
} |
|||
|
|||
template Mix(t, M) { |
|||
signal input in[t]; |
|||
signal output out[t]; |
|||
var lc; |
|||
|
|||
for (var i=0; i<t; i++) { |
|||
lc = 0; |
|||
for (var j=0; j<t; j++) { |
|||
lc = lc + M[i][j]*in[j]; |
|||
} |
|||
out[i] <== lc; |
|||
} |
|||
} |
|||
|
|||
// var nRoundsF = 8; |
|||
// var nRoundsP = 57; |
|||
// var t = 6; |
|||
|
|||
template Poseidon(nInputs, t, nRoundsF, nRoundsP) { |
|||
|
|||
var C = [ |
|||
1354025385229961744769229343273868518314335569873439558835166239576773343708, |
|||
14378844218625331047742339561309620904043097700980163591187076404481144585564, |
|||
19370813333785034372560258124535206525278124675105547990205946542330734467847, |
|||
19339919977375282793227987561727366424934767905100680591050582380667086628202, |
|||
8422275364316831706903446151602338206948363474119622730702497535467809432414, |
|||
7433947928146794739292515659214608949964639549664630885486968546133071892830, |
|||
20753350951496713264979200428833003140825588922450200809553577914404143341040, |
|||
21437018888080559864996889038552602698883513894753499324572098534369350747880, |
|||
6815447461573214810645016226370803316854141900901895816072622961504507953749, |
|||
11746901014017411226283657362310634990885933032228701131899561585228216986615, |
|||
13428722985713722660261823704226749286675766756093697029778643398137361221114, |
|||
10894749142018158588533110743373157663019829222177356873395009880383491602356, |
|||
13720066349319517776784660327982201297420012713976744204318378121767771862484, |
|||
4665971664531891307640113589671067488692829783046247264698659233443166028412, |
|||
5364541878673041196937884015923978656299860601766012213141306792903990539664, |
|||
1747411112078838632103476037026417344408680910500491241306123941341644055714, |
|||
1835035066071759522152578007305026433897204459772540871869487151042238374039, |
|||
21055637025200882290106914253232617255445210101773537879323245961051751183138, |
|||
19215142378199333594641095299020637309879189505235993967243075316794127016728, |
|||
5264915734761449905856538116909638235466879053604660991987579054616980096262, |
|||
10045917614023673044141331581538797960977704806582630277050701175565262856382, |
|||
7789533631025313780520004400945166898631872921910178131342071973345076732672, |
|||
19972498130123740615813398456152565371201412297339860820234719562997192378694, |
|||
14216077977931104808041453382683965630500368477063603536695472115075869912121, |
|||
2555981910568472028679439033700033287358333564454149464965229699417319912931, |
|||
11735111941739477522347883122573591136355121750109794306409399099068977659499, |
|||
16957890207070910233505303498878270130436461648242792271152604513138986611609, |
|||
358520143235124107055243451716507147499373646513864848163778795927281509793, |
|||
6389190271835493841487214043252929516390267871881261173336690351147926750010, |
|||
12939611907106878137030264379019786496625916664142697309441198804098015086205, |
|||
456696638239570875759108333278090964360604015255503302016190396687826618227, |
|||
20569764931577491771523222445135914903999292206008007769649255123342890660989, |
|||
3341317247281280728261320226215152668194921091152837358683334635401182164637, |
|||
11821224368797169892747612081573458772211068320533296007836648033607696236615, |
|||
2185176387193659864764608304330502180888068591409305411859725028056771843945, |
|||
17161758741114551704796078639849789476380746803787101178795737276111464575519, |
|||
11889888355183092530573415929875444766831739308191993115663429638848547668798, |
|||
19503084309842095729857399025417533485089330284851492085544757107759925099089, |
|||
20280152151768521735424910115623976684589382048161526796204268413029416266256, |
|||
17607351334578006856860845064970248988416315904757246948622629528628773644114, |
|||
20769468546336672951384440602623018830493119282829911435465737079851020547355, |
|||
1546429204704408801701093430086546742691081844046642451323347737810191940866, |
|||
11200569249561318620053458114013886527484999499632128671282997438827107108229, |
|||
20198213289062010915914579158889968647687156198219713083074315178786791524034, |
|||
12911209060630719799682705729835581341676468319742562559036843993017369855977, |
|||
18925188847138989248835676768641716482476141553833902070405850166412140133887, |
|||
20376466983584239909415025821007315251422803039634139484663713769887712746966, |
|||
5250536177612235431141386983455571232984126980327432803966957255414592397060, |
|||
344847263093423485167610155050688875010578621416939967999896518937961396680, |
|||
19870333728541576497318505013425518731999037041271340888970559590767369935385, |
|||
20604512495859902382577228682521142736989261702707317046150335692410020156250, |
|||
18293964088694556689667514948280720605277532123251572448395882397578643211622, |
|||
21211253784206079547762943120791531326787601501123474236198383850531142559075, |
|||
17247914781304154940895909185506123510423535554247372833321968000513811053190, |
|||
16432189025237084563810000088202867449333673799705533820685782829379758927490, |
|||
7204783063529242442830743239980168374343946353418800547956909848044774363774, |
|||
2108268032972510691814120801033692084861951866306906253604497017452204030001, |
|||
13483247063999686990721729188827693318708500027762095503921527692630827328070, |
|||
18194665574704709729868916970580318177272365766028499528691737819467051567534, |
|||
9275639092314761435364537152118796424056864859607619908791935597976913759411, |
|||
12700165678727983685032332532042155014245610964583614362270316386368455898604, |
|||
19127554193875137546212792134421555344854604853165878912238751527694270097310, |
|||
16817455471920423226570476063669349525676437756352144502692679769377074040335, |
|||
17331185397945904160678487303485263376032543419657328137924881433628614769955, |
|||
11605569208043267134285833752214422326246425655661043119023566733685555142420 |
|||
]; |
|||
|
|||
var M = [ |
|||
[ |
|||
12037235000515189726428793905458162231976011685774991261061889278958802340039, |
|||
15885254491685089152627111704751054604879027605518712546805347341940526552948, |
|||
12220682901774309471330657931458552366575439534877271150866614914170639536810, |
|||
11195096069395318710866553226959674457987772316145705151894647995087349332576, |
|||
598000700605575401177173118514166571064818339748567530524299773749024042768, |
|||
1430722853270801285936618367966028727146977818314178365893636191280860605092 |
|||
],[ |
|||
2478807512283787086755520696277192042388812450777005645736937700857950416751, |
|||
2233078558675693495109307103888903813217767160310116996267068037131890781382, |
|||
18876120310576321787684235034151243856925703159922712959767164734820803570163, |
|||
16850806847813838898693870637445284830832219430572133120914449039176718036761, |
|||
1333036876405396107763619427367607232034082504897380383847654332653606615427, |
|||
8024813862822108072341428765418554797098705487914663416123759888639403831315 |
|||
],[ |
|||
6500095533434910955474026763873910167129305339747639394388586826716085593160, |
|||
8370208895752773828195461153114215021863221486187756770286440396339432061839, |
|||
9303960191058819387902927958335344077259478983903385066838134730814638010892, |
|||
12233235273183315334651707749232602313616943260130930740801007863528547113209, |
|||
9140649423847813564210562288927015604065254723368331178903734405333716165919, |
|||
1715897011776785698388835993891828784112980527691698420841641796168725014542 |
|||
],[ |
|||
19092640119254952117901733765506685707486610088248205883870061221436629780176, |
|||
3099417239661426161523333446616746096617346084970490427773391639810420659748, |
|||
4498351799178816410443394768364090919370619407529999860500200773846156676605, |
|||
17766546613911504681964882079687098358108049762069064124348111606619240189874, |
|||
19735199036142202254810745273503942799136628866093225336283966579447096889407, |
|||
18618071352177331467649099054615438672487187348128402045695624605978242597928 |
|||
],[ |
|||
13282641901514824677915134398195165361567825236648422290753355584311135817423, |
|||
842963276112770184096507757019973399127531993386626262873928307889423235104, |
|||
5724939764407712239242783736588389538981693110806985476155198757555171230777, |
|||
3015568820237516884743892014063659856564948150197038824747891972506031149123, |
|||
8926202997251578932273751544826990276848999132609774201265891812369804099098, |
|||
13523975980414815337318802343464374889255493007711857898760066111901192774093 |
|||
],[ |
|||
13163705634211158833717167498904899472888572514300041636511944020589976373689, |
|||
6705743158328622712684686369234272301477431173971663001146157949982901448493, |
|||
5341285785102635724684809992160578025785996331334612975598752577556138916495, |
|||
2365134732811643517126128253974711531515283135672252986518431351700239265326, |
|||
11812366860142870031000585328436207067560705932658624313008187741187899702321, |
|||
11192751017231920972897699839932659451476356148115786649719660565307185769796 |
|||
] |
|||
]; |
|||
|
|||
signal input inputs[nInputs]; |
|||
signal output out; |
|||
|
|||
component ark[nRoundsF + nRoundsP]; |
|||
component sigmaF[nRoundsF][t]; |
|||
component sigmaP[nRoundsP]; |
|||
component mix[nRoundsF + nRoundsP]; |
|||
|
|||
var k; |
|||
|
|||
for (var i=0; i<(nRoundsF + nRoundsP); i++) { |
|||
ark[i] = Ark(t, C[i]); |
|||
mix[i] = Mix(t, M); |
|||
|
|||
for (var j=0; j<t; j++) { |
|||
if (i==0) { |
|||
if (j<nInputs) { |
|||
ark[i].in[j] <== inputs[j]; |
|||
} else { |
|||
ark[i].in[j] <== 0; |
|||
} |
|||
} else { |
|||
ark[i].in[j] <== mix[i-1].out[j]; |
|||
} |
|||
} |
|||
|
|||
if ((i<(nRoundsF/2)) || (i>= (nRoundsP + nRoundsF/2))) { |
|||
k= i<nRoundsF/2 ? i : (i-nRoundsP); |
|||
for (var j=0; j<t; j++) { |
|||
sigmaF[k][j] = Sigma(); |
|||
sigmaF[k][j].in <== ark[i].out[j]; |
|||
mix[i].in[j] <== sigmaF[k][j].out; |
|||
} |
|||
} else { |
|||
k= i-nRoundsF/2; |
|||
sigmaP[k] = Sigma(); |
|||
sigmaP[k].in <== ark[i].out[0]; |
|||
mix[i].in[0] <== sigmaP[k].out; |
|||
for (var j=1; j<t; j++) { |
|||
mix[i].in[j] <== ark[i].out[j]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
out <== mix[nRoundsF + nRoundsP -1].out[0]; |
|||
} |
@ -0,0 +1,115 @@ |
|||
const bn128 = require("snarkjs").bn128; |
|||
const bigInt = require("snarkjs").bigInt; |
|||
const createBlakeHash = require("blake-hash"); |
|||
const assert = require("assert"); |
|||
const F = bn128.Fr; |
|||
|
|||
const SEED = "poseidon"; |
|||
const NROUNDSF = 8; |
|||
const NROUNDSP = 57; |
|||
const T = 6; |
|||
|
|||
function getPseudoRandom(seed, n) { |
|||
const res = []; |
|||
let h = createBlakeHash("blake256").update(seed).digest(); |
|||
while (res.length<n) { |
|||
const n = F.affine(bigInt.leBuff2int(h)); |
|||
res.push(n); |
|||
h = createBlakeHash("blake256").update(h).digest(); |
|||
} |
|||
|
|||
return res; |
|||
} |
|||
|
|||
function allDifferent(v) { |
|||
for (let i=0; i<v.length; i++) { |
|||
if (v[i].isZero()) return false; |
|||
for (let j=i+1; j<v.length; j++) { |
|||
if (v[i].equals(v[j])) return false; |
|||
} |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
exports.getMatrix = (t, seed, nRounds) => { |
|||
if (typeof seed === "undefined") seed = SEED; |
|||
if (typeof nRounds === "undefined") nRounds = NROUNDSF + NROUNDSP; |
|||
if (typeof t === "undefined") t = T; |
|||
let nonce = "0000"; |
|||
let cmatrix = getPseudoRandom(seed+"_matrix_"+nonce, t*2); |
|||
while (!allDifferent(cmatrix)) { |
|||
nonce = (Number(nonce)+1)+""; |
|||
while(nonce.length<4) nonce = "0"+nonce; |
|||
cmatrix = getPseudoRandom(seed+"_matrix_"+nonce, t*2); |
|||
} |
|||
|
|||
const M = new Array(t); |
|||
for (let i=0; i<t; i++) { |
|||
M[i] = new Array(t); |
|||
for (let j=0; j<t; j++) { |
|||
M[i][j] = F.affine(F.inverse(F.sub(cmatrix[i], cmatrix[t+j]))); |
|||
} |
|||
} |
|||
return M; |
|||
}; |
|||
|
|||
exports.getConstants = (t, seed, nRounds) => { |
|||
if (typeof seed === "undefined") seed = SEED; |
|||
if (typeof nRounds === "undefined") nRounds = NROUNDSF + NROUNDSP; |
|||
if (typeof t === "undefined") t = T; |
|||
const cts = getPseudoRandom(seed+"_constants", nRounds); |
|||
return cts; |
|||
}; |
|||
|
|||
function ark(state, c) { |
|||
for (let j=0; j<state.length; j++ ) { |
|||
state[j] = F.add(state[j], c); |
|||
} |
|||
} |
|||
|
|||
function sigma(a) { |
|||
return F.mul(a, F.square(F.square(a,a))); |
|||
} |
|||
|
|||
function mix(state, M) { |
|||
const newState = new Array(state.length); |
|||
for (let i=0; i<state.length; i++) { |
|||
newState[i] = F.zero; |
|||
for (let j=0; j<state.length; j++) { |
|||
newState[i] = F.add(newState[i], F.mul(M[i][j], state[j]) ); |
|||
} |
|||
} |
|||
for (let i=0; i<state.length; i++) state[i] = newState[i]; |
|||
} |
|||
|
|||
exports.createHash = (t, nRoundsF, nRoundsP, seed) => { |
|||
|
|||
if (typeof seed === "undefined") seed = SEED; |
|||
if (typeof nRoundsF === "undefined") nRoundsF = NROUNDSF; |
|||
if (typeof nRoundsP === "undefined") nRoundsP = NROUNDSP; |
|||
if (typeof t === "undefined") t = T; |
|||
|
|||
assert(nRoundsF % 2 == 0); |
|||
const C = exports.getConstants(t, seed, nRoundsF + nRoundsP); |
|||
const M = exports.getMatrix(t, seed, nRoundsF + nRoundsP); |
|||
return function(inputs) { |
|||
let state = []; |
|||
assert(inputs.length < t); |
|||
assert(inputs.length > 0); |
|||
for (let i=0; i<inputs.length; i++) state[i] = bigInt(inputs[i]); |
|||
for (let i=inputs.length; i<t; i++) state[i] = F.zero; |
|||
|
|||
for (let i=0; i< nRoundsF + nRoundsP; i++) { |
|||
ark(state, C[i]); |
|||
if ((i<nRoundsF/2) || (i >= nRoundsF/2 + nRoundsP)) { |
|||
for (let j=0; j<t; j++) state[j] = sigma(state[j]); |
|||
} else { |
|||
state[0] = sigma(state[0]); |
|||
} |
|||
mix(state, M); |
|||
} |
|||
return F.affine(state[0]); |
|||
}; |
|||
}; |
|||
|
|||
|
@ -0,0 +1,180 @@ |
|||
// Copyright (c) 2018 Jordi Baylina
|
|||
// License: LGPL-3.0+
|
|||
//
|
|||
|
|||
const Poseidon = require("./poseidon.js"); |
|||
|
|||
const Contract = require("./evmasm"); |
|||
|
|||
const SEED = "poseidon"; |
|||
const NROUNDSF = 8; |
|||
const NROUNDSP = 57; |
|||
const T = 6; |
|||
|
|||
function toHex256(a) { |
|||
let S = a.toString(16); |
|||
while (S.length < 64) S="0"+S; |
|||
return "0x" + S; |
|||
} |
|||
|
|||
function createCode(t, nRoundsF, nRoundsP, seed) { |
|||
if (typeof seed === "undefined") seed = SEED; |
|||
if (typeof nRoundsF === "undefined") nRoundsF = NROUNDSF; |
|||
if (typeof nRoundsP === "undefined") nRoundsP = NROUNDSP; |
|||
if (typeof t === "undefined") t = T; |
|||
|
|||
const K = Poseidon.getConstants(t, seed, nRoundsP + nRoundsF); |
|||
const M = Poseidon.getMatrix(t, seed, nRoundsP + nRoundsF); |
|||
|
|||
const C = new Contract(); |
|||
|
|||
function saveM() { |
|||
for (let i=0; i<t; i++) { |
|||
for (let j=0; j<t; j++) { |
|||
C.push(toHex256(M[i][j])); |
|||
C.push((1+i*t+j)*32); |
|||
C.mstore(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
function ark(r) { |
|||
C.push(toHex256(K[r])); // K, st, q
|
|||
for (let i=0; i<t; i++) { |
|||
C.dup(1+t); // q, K, st, q
|
|||
C.dup(1); // K, q, K, st, q
|
|||
C.dup(3+i); // st[i], K, q, K, st, q
|
|||
C.addmod(); // newSt[i], K, st, q
|
|||
C.swap(2 + i); // xx, K, st, q
|
|||
C.pop(); |
|||
} |
|||
C.pop(); |
|||
} |
|||
|
|||
function sigma(p) { |
|||
// sq, q
|
|||
C.dup(t); // q, st, q
|
|||
C.dup(1+p); // st[p] , q , st, q
|
|||
C.dup(1); // q, st[p] , q , st, q
|
|||
C.dup(0); // q, q, st[p] , q , st, q
|
|||
C.dup(2); // st[p] , q, q, st[p] , q , st, q
|
|||
C.dup(0); // st[p] , st[p] , q, q, st[p] , q , st, q
|
|||
C.mulmod(); // st2[p], q, st[p] , q , st, q
|
|||
C.dup(0); // st2[p], st2[p], q, st[p] , q , st, q
|
|||
C.mulmod(); // st4[p], st[p] , q , st, q
|
|||
C.mulmod(); // st5[p], st, q
|
|||
C.swap(1+p); |
|||
C.pop(); // newst, q
|
|||
} |
|||
|
|||
function mix() { |
|||
C.label("mix"); |
|||
for (let i=0; i<t; i++) { |
|||
for (let j=0; j<t; j++) { |
|||
if (j==0) { |
|||
C.dup(i+t); // q, newSt, oldSt, q
|
|||
C.push((1+i*t+j)*32); |
|||
C.mload(); // M, q, newSt, oldSt, q
|
|||
C.dup(2+i+j); // oldSt[j], M, q, newSt, oldSt, q
|
|||
C.mulmod(); // acc, newSt, oldSt, q
|
|||
} else { |
|||
C.dup(1+i+t); // q, acc, newSt, oldSt, q
|
|||
C.push((1+i*t+j)*32); |
|||
C.mload(); // M, q, acc, newSt, oldSt, q
|
|||
C.dup(3+i+j); // oldSt[j], M, q, acc, newSt, oldSt, q
|
|||
C.mulmod(); // aux, acc, newSt, oldSt, q
|
|||
C.dup(2+i+t); // q, aux, acc, newSt, oldSt, q
|
|||
C.swap(2); // acc, aux, q, newSt, oldSt, q
|
|||
C.addmod(); // acc, newSt, oldSt, q
|
|||
} |
|||
} |
|||
} |
|||
for (let i=0; i<t; i++) { |
|||
C.swap((t -i) + (t -i-1)); |
|||
C.pop(); |
|||
} |
|||
C.push(0); |
|||
C.mload(); |
|||
C.jmp(); |
|||
} |
|||
|
|||
|
|||
// Check selector
|
|||
C.push("0x0100000000000000000000000000000000000000000000000000000000"); |
|||
C.push(0); |
|||
C.calldataload(); |
|||
C.div(); |
|||
C.push("0xc4420fb4"); // poseidon(uint256[])
|
|||
C.eq(); |
|||
C.jmpi("start"); |
|||
C.invalid(); |
|||
|
|||
C.label("start"); |
|||
|
|||
saveM(); |
|||
|
|||
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
|||
|
|||
// Load 6 values from the call data.
|
|||
// The function has a single array param param
|
|||
// [Selector (4)] [Pointer (32)][Length (32)] [data1 (32)] ....
|
|||
// We ignore the pointer and the length and just load 6 values to the state
|
|||
// (Stack positions 0-5) If the array is shorter, we just set zeros.
|
|||
for (let i=0; i<t; i++) { |
|||
C.push(0x44+(0x20*(5-i))); |
|||
C.calldataload(); |
|||
} |
|||
|
|||
for (let i=0; i<nRoundsF+nRoundsP; i++) { |
|||
ark(i); |
|||
if ((i<nRoundsF/2) || (i>=nRoundsP+nRoundsF/2)) { |
|||
for (let j=0; j<t; j++) { |
|||
sigma(j); |
|||
} |
|||
} else { |
|||
sigma(0); |
|||
} |
|||
const strLabel = "aferMix"+i; |
|||
C._pushLabel(strLabel); |
|||
C.push(0); |
|||
C.mstore(); |
|||
C.jmp("mix"); |
|||
C.label(strLabel); |
|||
} |
|||
|
|||
C.push("0x00"); |
|||
C.mstore(); // Save it to pos 0;
|
|||
C.push("0x20"); |
|||
C.push("0x00"); |
|||
C.return(); |
|||
|
|||
mix(); |
|||
|
|||
return C.createTxData(); |
|||
} |
|||
|
|||
module.exports.abi = [ |
|||
{ |
|||
"constant": true, |
|||
"inputs": [ |
|||
{ |
|||
"name": "input", |
|||
"type": "uint256[]" |
|||
} |
|||
], |
|||
"name": "poseidon", |
|||
"outputs": [ |
|||
{ |
|||
"name": "", |
|||
"type": "uint256" |
|||
} |
|||
], |
|||
"payable": false, |
|||
"stateMutability": "pure", |
|||
"type": "function" |
|||
} |
|||
]; |
|||
|
|||
module.exports.createCode = createCode; |
|||
|
|||
|
@ -0,0 +1,16 @@ |
|||
|
|||
|
|||
const Poseidon = require("./poseidon.js"); |
|||
|
|||
const C = Poseidon.getConstants(); |
|||
|
|||
let S = "[\n"; |
|||
|
|||
for (let i=0; i<C.length; i++) { |
|||
S = S + " " + C[i].toString(); |
|||
if (i<C.length-1) S = S + ","; |
|||
S = S + "\n"; |
|||
} |
|||
S=S+ "]\n"; |
|||
|
|||
console.log(S); |
@ -0,0 +1,5 @@ |
|||
const poseidonGenContract = require("./poseidon_gencontract"); |
|||
|
|||
|
|||
console.log(poseidonGenContract.createCode(6, 8, 57)); |
|||
|
@ -0,0 +1,22 @@ |
|||
|
|||
|
|||
const Poseidon = require("./poseidon.js"); |
|||
|
|||
const M = Poseidon.getMatrix(); |
|||
|
|||
let S = "[\n "; |
|||
|
|||
for (let i=0; i<M.length; i++) { |
|||
const LC = M[i]; |
|||
S = S + "[\n"; |
|||
for (let j=0; j<LC.length; j++) { |
|||
S = S + " " + M[i][j].toString(); |
|||
if (j<LC.length-1) S = S + ","; |
|||
S = S + "\n"; |
|||
} |
|||
S = S + " ]"; |
|||
if (i<M.length-1) S = S + ","; |
|||
} |
|||
S=S+ "\n]\n"; |
|||
|
|||
console.log(S); |
@ -0,0 +1,3 @@ |
|||
include "../../circuits/poseidon.circom" |
|||
|
|||
component main = Poseidon(2, 6, 8, 57); |
@ -0,0 +1,39 @@ |
|||
const chai = require("chai"); |
|||
const path = require("path"); |
|||
const snarkjs = require("snarkjs"); |
|||
const compiler = require("circom"); |
|||
|
|||
const poseidon = require("../src/poseidon.js"); |
|||
|
|||
const assert = chai.assert; |
|||
|
|||
describe("Poseidon Circuit test", function () { |
|||
let circuit; |
|||
|
|||
this.timeout(100000); |
|||
|
|||
before( async () => { |
|||
const cirDef = await compiler(path.join(__dirname, "circuits", "poseidon_test.circom")); |
|||
|
|||
circuit = new snarkjs.Circuit(cirDef); |
|||
|
|||
console.log("Poseidon constraints: " + circuit.nConstraints); |
|||
}); |
|||
|
|||
it("Should check constrain", async () => { |
|||
const w = circuit.calculateWitness({inputs: [1, 2]}); |
|||
|
|||
const res = w[circuit.getSignalIdx("main.out")]; |
|||
|
|||
const hash = poseidon.createHash(6, 8, 57); |
|||
|
|||
const res2 = hash([1,2]); |
|||
|
|||
console.log(res.toString()); |
|||
|
|||
assert.equal(res.toString(), res2.toString()); |
|||
|
|||
assert(circuit.checkWitness(w)); |
|||
|
|||
}); |
|||
}); |
@ -0,0 +1,59 @@ |
|||
const TestRPC = require("ganache-cli"); |
|||
const Web3 = require("web3"); |
|||
const chai = require("chai"); |
|||
const poseidonGenContract = require("../src/poseidon_gencontract.js"); |
|||
const Poseidon = require("../src/poseidon.js"); |
|||
const bigInt = require("snarkjs").bigInt; |
|||
|
|||
const assert = chai.assert; |
|||
const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); }; |
|||
|
|||
const SEED = "mimc"; |
|||
|
|||
describe("Poseidon Smart contract test", () => { |
|||
let testrpc; |
|||
let web3; |
|||
let mimc; |
|||
let accounts; |
|||
|
|||
before(async () => { |
|||
testrpc = TestRPC.server({ |
|||
ws: true, |
|||
gasLimit: 5800000, |
|||
total_accounts: 10, |
|||
}); |
|||
|
|||
testrpc.listen(8546, "127.0.0.1"); |
|||
|
|||
web3 = new Web3("ws://127.0.0.1:8546"); |
|||
accounts = await web3.eth.getAccounts(); |
|||
}); |
|||
|
|||
after(async () => testrpc.close()); |
|||
|
|||
it("Should deploy the contract", async () => { |
|||
const C = new web3.eth.Contract(poseidonGenContract.abi); |
|||
|
|||
mimc = await C.deploy({ |
|||
data: poseidonGenContract.createCode() |
|||
}).send({ |
|||
gas: 2500000, |
|||
from: accounts[0] |
|||
}); |
|||
}); |
|||
|
|||
it("Shold calculate the mimic correctly", async () => { |
|||
|
|||
const res = await mimc.methods.poseidon([1,2]).call(); |
|||
|
|||
console.log("Cir: " + bigInt(res.toString(16)).toString(16)); |
|||
|
|||
const hash = Poseidon.createHash(6, 8, 57); |
|||
|
|||
const res2 = hash([1,2]); |
|||
console.log("Ref: " + bigInt(res2).toString(16)); |
|||
|
|||
assert.equal(res.toString(), res2.toString()); |
|||
}); |
|||
}); |
|||
|