@ -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()); |
||||
|
}); |
||||
|
}); |
||||
|
|