@ -0,0 +1,14 @@ |
|||
* compconstant - Returns 1 if `in` (expanded to binary array) > `ct` |
|||
* aliascheck - check if `in` (expanded to binary array) oveflowed its 254 bits (<= -1) |
|||
* babyjub - twisted Edwards curve 168700.x^2 + y^2 = 1 + 168696.x^2.y^2 |
|||
* BabyAdd - (`xout`,`yout`) = (`x1`,`y1`) + (`x2`,`y2`) |
|||
* BabyDbl - (`xout`,`yout`) = 2*(`x`,`y`) |
|||
* BabyCheck - check that (`x`,`y`) is on the curve |
|||
* binsub - binary subtraction |
|||
* gates - logical gates |
|||
* mimc - SNARK-friendly hash Minimal Multiplicative Complexity. |
|||
* https://eprint.iacr.org/2016/492.pdf |
|||
* zcash/zcash#2233 |
|||
* smt - Sparse Merkle Tree |
|||
* https://ethresear.ch/t/optimizing-sparse-merkle-trees/3751 |
|||
* montgomery https://en.wikipedia.org/wiki/Montgomery_curve |
@ -0,0 +1,123 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
include "compconstant.circom"; |
|||
include "pointbits.circom"; |
|||
include "mimcsponge.circom"; |
|||
include "bitify.circom"; |
|||
include "escalarmulany.circom"; |
|||
include "escalarmulfix.circom"; |
|||
|
|||
template EdDSAMiMCSpongeVerifier() { |
|||
signal input enabled; |
|||
signal input Ax; |
|||
signal input Ay; |
|||
|
|||
signal input S; |
|||
signal input R8x; |
|||
signal input R8y; |
|||
|
|||
signal input M; |
|||
|
|||
var i; |
|||
|
|||
// Ensure S<Subgroup Order |
|||
|
|||
component snum2bits = Num2Bits(253); |
|||
snum2bits.in <== S; |
|||
|
|||
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040); |
|||
|
|||
for (i=0; i<253; i++) { |
|||
snum2bits.out[i] ==> compConstant.in[i]; |
|||
} |
|||
compConstant.in[253] <== 0; |
|||
compConstant.out === 0; |
|||
|
|||
// Calculate the h = H(R,A, msg) |
|||
|
|||
component hash = MiMCSponge(5, 220, 1); |
|||
hash.ins[0] <== R8x; |
|||
hash.ins[1] <== R8y; |
|||
hash.ins[2] <== Ax; |
|||
hash.ins[3] <== Ay; |
|||
hash.ins[4] <== M; |
|||
hash.k <== 0; |
|||
|
|||
component h2bits = Num2Bits_strict(); |
|||
h2bits.in <== hash.outs[0]; |
|||
|
|||
// Calculate second part of the right side: right2 = h*8*A |
|||
|
|||
// Multiply by 8 by adding it 3 times. This also ensure that the result is in |
|||
// the subgroup. |
|||
component dbl1 = BabyDbl(); |
|||
dbl1.x <== Ax; |
|||
dbl1.y <== Ay; |
|||
component dbl2 = BabyDbl(); |
|||
dbl2.x <== dbl1.xout; |
|||
dbl2.y <== dbl1.yout; |
|||
component dbl3 = BabyDbl(); |
|||
dbl3.x <== dbl2.xout; |
|||
dbl3.y <== dbl2.yout; |
|||
|
|||
// We check that A is not zero. |
|||
component isZero = IsZero(); |
|||
isZero.in <== dbl3.x; |
|||
isZero.out === 0; |
|||
|
|||
component mulAny = EscalarMulAny(254); |
|||
for (i=0; i<254; i++) { |
|||
mulAny.e[i] <== h2bits.out[i]; |
|||
} |
|||
mulAny.p[0] <== dbl3.xout; |
|||
mulAny.p[1] <== dbl3.yout; |
|||
|
|||
|
|||
// Compute the right side: right = R8 + right2 |
|||
|
|||
component addRight = BabyAdd(); |
|||
addRight.x1 <== R8x; |
|||
addRight.y1 <== R8y; |
|||
addRight.x2 <== mulAny.out[0]; |
|||
addRight.y2 <== mulAny.out[1]; |
|||
|
|||
// Calculate left side of equation left = S*B8 |
|||
|
|||
var BASE8 = [ |
|||
17777552123799933955779906779655732241715742912184938656739573121738514868268, |
|||
2626589144620713026669568689430873010625803728049924121243784502389097019475 |
|||
]; |
|||
component mulFix = EscalarMulFix(253, BASE8); |
|||
for (i=0; i<253; i++) { |
|||
mulFix.e[i] <== snum2bits.out[i]; |
|||
} |
|||
|
|||
// Do the comparation left == right if enabled; |
|||
|
|||
component eqCheckX = ForceEqualIfEnabled(); |
|||
eqCheckX.enabled <== enabled; |
|||
eqCheckX.in[0] <== mulFix.out[0]; |
|||
eqCheckX.in[1] <== addRight.xout; |
|||
|
|||
component eqCheckY = ForceEqualIfEnabled(); |
|||
eqCheckY.enabled <== enabled; |
|||
eqCheckY.in[0] <== mulFix.out[1]; |
|||
eqCheckY.in[1] <== addRight.yout; |
|||
} |
@ -0,0 +1,122 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
include "compconstant.circom"; |
|||
include "poseidon.circom"; |
|||
include "bitify.circom"; |
|||
include "escalarmulany.circom"; |
|||
include "escalarmulfix.circom"; |
|||
|
|||
template EdDSAPoseidonVerifier() { |
|||
signal input enabled; |
|||
signal input Ax; |
|||
signal input Ay; |
|||
|
|||
signal input S; |
|||
signal input R8x; |
|||
signal input R8y; |
|||
|
|||
signal input M; |
|||
|
|||
var i; |
|||
|
|||
// Ensure S<Subgroup Order |
|||
|
|||
component snum2bits = Num2Bits(253); |
|||
snum2bits.in <== S; |
|||
|
|||
component compConstant = CompConstant(2736030358979909402780800718157159386076813972158567259200215660948447373040); |
|||
|
|||
for (i=0; i<253; i++) { |
|||
snum2bits.out[i] ==> compConstant.in[i]; |
|||
} |
|||
compConstant.in[253] <== 0; |
|||
compConstant.out === 0; |
|||
|
|||
// Calculate the h = H(R,A, msg) |
|||
|
|||
component hash = Poseidon(5, 6, 8, 57); |
|||
|
|||
hash.inputs[0] <== R8x; |
|||
hash.inputs[1] <== R8y; |
|||
hash.inputs[2] <== Ax; |
|||
hash.inputs[3] <== Ay; |
|||
hash.inputs[4] <== M; |
|||
|
|||
component h2bits = Num2Bits_strict(); |
|||
h2bits.in <== hash.out; |
|||
|
|||
// Calculate second part of the right side: right2 = h*8*A |
|||
|
|||
// Multiply by 8 by adding it 3 times. This also ensure that the result is in |
|||
// the subgroup. |
|||
component dbl1 = BabyDbl(); |
|||
dbl1.x <== Ax; |
|||
dbl1.y <== Ay; |
|||
component dbl2 = BabyDbl(); |
|||
dbl2.x <== dbl1.xout; |
|||
dbl2.y <== dbl1.yout; |
|||
component dbl3 = BabyDbl(); |
|||
dbl3.x <== dbl2.xout; |
|||
dbl3.y <== dbl2.yout; |
|||
|
|||
// We check that A is not zero. |
|||
component isZero = IsZero(); |
|||
isZero.in <== dbl3.x; |
|||
isZero.out === 0; |
|||
|
|||
component mulAny = EscalarMulAny(254); |
|||
for (i=0; i<254; i++) { |
|||
mulAny.e[i] <== h2bits.out[i]; |
|||
} |
|||
mulAny.p[0] <== dbl3.xout; |
|||
mulAny.p[1] <== dbl3.yout; |
|||
|
|||
|
|||
// Compute the right side: right = R8 + right2 |
|||
|
|||
component addRight = BabyAdd(); |
|||
addRight.x1 <== R8x; |
|||
addRight.y1 <== R8y; |
|||
addRight.x2 <== mulAny.out[0]; |
|||
addRight.y2 <== mulAny.out[1]; |
|||
|
|||
// Calculate left side of equation left = S*B8 |
|||
|
|||
var BASE8 = [ |
|||
17777552123799933955779906779655732241715742912184938656739573121738514868268, |
|||
2626589144620713026669568689430873010625803728049924121243784502389097019475 |
|||
]; |
|||
component mulFix = EscalarMulFix(253, BASE8); |
|||
for (i=0; i<253; i++) { |
|||
mulFix.e[i] <== snum2bits.out[i]; |
|||
} |
|||
|
|||
// Do the comparation left == right if enabled; |
|||
|
|||
component eqCheckX = ForceEqualIfEnabled(); |
|||
eqCheckX.enabled <== enabled; |
|||
eqCheckX.in[0] <== mulFix.out[0]; |
|||
eqCheckX.in[1] <== addRight.xout; |
|||
|
|||
component eqCheckY = ForceEqualIfEnabled(); |
|||
eqCheckY.enabled <== enabled; |
|||
eqCheckY.in[0] <== mulFix.out[1]; |
|||
eqCheckY.in[1] <== addRight.yout; |
|||
} |
@ -0,0 +1,283 @@ |
|||
// implements MiMC-2n/n as hash using a sponge construction. |
|||
// log_5(21888242871839275222246405745257275088548364400416034343698204186575808495617) ~= 110 |
|||
// => nRounds should be 220 |
|||
template MiMCSponge(nInputs, nRounds, nOutputs) { |
|||
signal input ins[nInputs]; |
|||
signal input k; |
|||
signal output outs[nOutputs]; |
|||
|
|||
// S = R||C |
|||
component S[nInputs + nOutputs - 1]; |
|||
|
|||
for (var i = 0; i < nInputs; i++) { |
|||
S[i] = MiMCFeistel(nRounds); |
|||
S[i].k <== k; |
|||
if (i == 0) { |
|||
S[i].xL_in <== ins[0]; |
|||
S[i].xR_in <== 0; |
|||
} else { |
|||
S[i].xL_in <== S[i-1].xL_out + ins[i]; |
|||
S[i].xR_in <== S[i-1].xR_out; |
|||
} |
|||
} |
|||
|
|||
outs[0] = S[nInputs - 1].xL_out; |
|||
|
|||
for (var i = 0; i < nOutputs - 1; i++) { |
|||
S[nInputs + i] = MiMCFeistel(nRounds); |
|||
S[nInputs + i].k <== k; |
|||
S[nInputs + i].xL_in <== S[nInputs + i - 1].xL_out; |
|||
S[nInputs + i].xR_in <== S[nInputs + i - 1].xR_out; |
|||
outs[i + 1] <== S[nInputs + i].xL_out; |
|||
} |
|||
} |
|||
|
|||
template MiMCFeistel(nrounds) { |
|||
signal input xL_in; |
|||
signal input xR_in; |
|||
signal input k; |
|||
signal output xL_out; |
|||
signal output xR_out; |
|||
|
|||
var c = [ |
|||
0, |
|||
7120861356467848435263064379192047478074060781135320967663101236819528304084, |
|||
5024705281721889198577876690145313457398658950011302225525409148828000436681, |
|||
17980351014018068290387269214713820287804403312720763401943303895585469787384, |
|||
19886576439381707240399940949310933992335779767309383709787331470398675714258, |
|||
1213715278223786725806155661738676903520350859678319590331207960381534602599, |
|||
18162138253399958831050545255414688239130588254891200470934232514682584734511, |
|||
7667462281466170157858259197976388676420847047604921256361474169980037581876, |
|||
7207551498477838452286210989212982851118089401128156132319807392460388436957, |
|||
9864183311657946807255900203841777810810224615118629957816193727554621093838, |
|||
4798196928559910300796064665904583125427459076060519468052008159779219347957, |
|||
17387238494588145257484818061490088963673275521250153686214197573695921400950, |
|||
10005334761930299057035055370088813230849810566234116771751925093634136574742, |
|||
11897542014760736209670863723231849628230383119798486487899539017466261308762, |
|||
16771780563523793011283273687253985566177232886900511371656074413362142152543, |
|||
749264854018824809464168489785113337925400687349357088413132714480582918506, |
|||
3683645737503705042628598550438395339383572464204988015434959428676652575331, |
|||
7556750851783822914673316211129907782679509728346361368978891584375551186255, |
|||
20391289379084797414557439284689954098721219201171527383291525676334308303023, |
|||
18146517657445423462330854383025300323335289319277199154920964274562014376193, |
|||
8080173465267536232534446836148661251987053305394647905212781979099916615292, |
|||
10796443006899450245502071131975731672911747129805343722228413358507805531141, |
|||
5404287610364961067658660283245291234008692303120470305032076412056764726509, |
|||
4623894483395123520243967718315330178025957095502546813929290333264120223168, |
|||
16845753148201777192406958674202574751725237939980634861948953189320362207797, |
|||
4622170486584704769521001011395820886029808520586507873417553166762370293671, |
|||
16688277490485052681847773549197928630624828392248424077804829676011512392564, |
|||
11878652861183667748838188993669912629573713271883125458838494308957689090959, |
|||
2436445725746972287496138382764643208791713986676129260589667864467010129482, |
|||
1888098689545151571063267806606510032698677328923740058080630641742325067877, |
|||
148924106504065664829055598316821983869409581623245780505601526786791681102, |
|||
18875020877782404439294079398043479420415331640996249745272087358069018086569, |
|||
15189693413320228845990326214136820307649565437237093707846682797649429515840, |
|||
19669450123472657781282985229369348220906547335081730205028099210442632534079, |
|||
5521922218264623411380547905210139511350706092570900075727555783240701821773, |
|||
4144769320246558352780591737261172907511489963810975650573703217887429086546, |
|||
10097732913112662248360143041019433907849917041759137293018029019134392559350, |
|||
1720059427972723034107765345743336447947522473310069975142483982753181038321, |
|||
6302388219880227251325608388535181451187131054211388356563634768253301290116, |
|||
6745410632962119604799318394592010194450845483518862700079921360015766217097, |
|||
10858157235265583624235850660462324469799552996870780238992046963007491306222, |
|||
20241898894740093733047052816576694435372877719072347814065227797906130857593, |
|||
10165780782761211520836029617746977303303335603838343292431760011576528327409, |
|||
2832093654883670345969792724123161241696170611611744759675180839473215203706, |
|||
153011722355526826233082383360057587249818749719433916258246100068258954737, |
|||
20196970640587451358539129330170636295243141659030208529338914906436009086943, |
|||
3180973917010545328313139835982464870638521890385603025657430208141494469656, |
|||
17198004293191777441573635123110935015228014028618868252989374962722329283022, |
|||
7642160509228669138628515458941659189680509753651629476399516332224325757132, |
|||
19346204940546791021518535594447257347218878114049998691060016493806845179755, |
|||
11501810868606870391127866188394535330696206817602260610801897042898616817272, |
|||
3113973447392053821824427670386252797811804954746053461397972968381571297505, |
|||
6545064306297957002139416752334741502722251869537551068239642131448768236585, |
|||
5203908808704813498389265425172875593837960384349653691918590736979872578408, |
|||
2246692432011290582160062129070762007374502637007107318105405626910313810224, |
|||
11760570435432189127645691249600821064883781677693087773459065574359292849137, |
|||
5543749482491340532547407723464609328207990784853381797689466144924198391839, |
|||
8837549193990558762776520822018694066937602576881497343584903902880277769302, |
|||
12855514863299373699594410385788943772765811961581749194183533625311486462501, |
|||
5363660674689121676875069134269386492382220935599781121306637800261912519729, |
|||
13162342403579303950549728848130828093497701266240457479693991108217307949435, |
|||
916941639326869583414469202910306428966657806899788970948781207501251816730, |
|||
15618589556584434434009868216186115416835494805174158488636000580759692174228, |
|||
8959562060028569701043973060670353733575345393653685776974948916988033453971, |
|||
16390754464333401712265575949874369157699293840516802426621216808905079127650, |
|||
168282396747788514908709091757591226095443902501365500003618183905496160435, |
|||
8327443473179334761744301768309008451162322941906921742120510244986704677004, |
|||
17213012626801210615058753489149961717422101711567228037597150941152495100640, |
|||
10394369641533736715250242399198097296122982486516256408681925424076248952280, |
|||
17784386835392322654196171115293700800825771210400152504776806618892170162248, |
|||
16533189939837087893364000390641148516479148564190420358849587959161226782982, |
|||
18725396114211370207078434315900726338547621160475533496863298091023511945076, |
|||
7132325028834551397904855671244375895110341505383911719294705267624034122405, |
|||
148317947440800089795933930720822493695520852448386394775371401743494965187, |
|||
19001050671757720352890779127693793630251266879994702723636759889378387053056, |
|||
18824274411769830274877839365728651108434404855803844568234862945613766611460, |
|||
12771414330193951156383998390424063470766226667986423961689712557338777174205, |
|||
11332046574800279729678603488745295198038913503395629790213378101166488244657, |
|||
9607550223176946388146938069307456967842408600269548190739947540821716354749, |
|||
8756385288462344550200229174435953103162307705310807828651304665320046782583, |
|||
176061952957067086877570020242717222844908281373122372938833890096257042779, |
|||
12200212977482648306758992405065921724409841940671166017620928947866825250857, |
|||
10868453624107875516866146499877130701929063632959660262366632833504750028858, |
|||
2016095394399807253596787752134573207202567875457560571095586743878953450738, |
|||
21815578223768330433802113452339488275704145896544481092014911825656390567514, |
|||
4923772847693564777744725640710197015181591950368494148029046443433103381621, |
|||
1813584943682214789802230765734821149202472893379265320098816901270224589984, |
|||
10810123816265612772922113403831964815724109728287572256602010709288980656498, |
|||
1153669123397255702524721206511185557982017410156956216465120456256288427021, |
|||
5007518659266430200134478928344522649876467369278722765097865662497773767152, |
|||
2511432546938591792036639990606464315121646668029252285288323664350666551637, |
|||
32883284540320451295484135704808083452381176816565850047310272290579727564, |
|||
10484856914279112612610993418405543310546746652738541161791501150994088679557, |
|||
2026733759645519472558796412979210009170379159866522399881566309631434814953, |
|||
14731806221235869882801331463708736361296174006732553130708107037190460654379, |
|||
14740327483193277147065845135561988641238516852487657117813536909482068950652, |
|||
18787428285295558781869865751953016580493190547148386433580291216673009884554, |
|||
3804047064713122820157099453648459188816376755739202017447862327783289895072, |
|||
16709604795697901641948603019242067672006293290826991671766611326262532802914, |
|||
11061717085931490100602849654034280576915102867237101935487893025907907250695, |
|||
2821730726367472966906149684046356272806484545281639696873240305052362149654, |
|||
17467794879902895769410571945152708684493991588672014763135370927880883292655, |
|||
1571520786233540988201616650622796363168031165456869481368085474420849243232, |
|||
10041051776251223165849354194892664881051125330236567356945669006147134614302, |
|||
3981753758468103976812813304477670033098707002886030847251581853700311567551, |
|||
4365864398105436789177703571412645548020537580493599380018290523813331678900, |
|||
2391801327305361293476178683853802679507598622000359948432171562543560193350, |
|||
214219368547551689972421167733597094823289857206402800635962137077096090722, |
|||
18192064100315141084242006659317257023098826945893371479835220462302399655674, |
|||
15487549757142039139328911515400805508248576685795694919457041092150651939253, |
|||
10142447197759703415402259672441315777933858467700579946665223821199077641122, |
|||
11246573086260753259993971254725613211193686683988426513880826148090811891866, |
|||
6574066859860991369704567902211886840188702386542112593710271426704432301235, |
|||
11311085442652291634822798307831431035776248927202286895207125867542470350078, |
|||
20977948360215259915441258687649465618185769343138135384346964466965010873779, |
|||
792781492853909872425531014397300057232399608769451037135936617996830018501, |
|||
5027602491523497423798779154966735896562099398367163998686335127580757861872, |
|||
14595204575654316237672764823862241845410365278802914304953002937313300553572, |
|||
13973538843621261113924259058427434053808430378163734641175100160836376897004, |
|||
16395063164993626722686882727042150241125309409717445381854913964674649318585, |
|||
8465768840047024550750516678171433288207841931251654898809033371655109266663, |
|||
21345603324471810861925019445720576814602636473739003852898308205213912255830, |
|||
21171984405852590343970239018692870799717057961108910523876770029017785940991, |
|||
10761027113757988230637066281488532903174559953630210849190212601991063767647, |
|||
6678298831065390834922566306988418588227382406175769592902974103663687992230, |
|||
4993662582188632374202316265508850988596880036291765531885657575099537176757, |
|||
18364168158495573675698600238443218434246806358811328083953887470513967121206, |
|||
3506345610354615013737144848471391553141006285964325596214723571988011984829, |
|||
248732676202643792226973868626360612151424823368345645514532870586234380100, |
|||
10090204501612803176317709245679152331057882187411777688746797044706063410969, |
|||
21297149835078365363970699581821844234354988617890041296044775371855432973500, |
|||
16729368143229828574342820060716366330476985824952922184463387490091156065099, |
|||
4467191506765339364971058668792642195242197133011672559453028147641428433293, |
|||
8677548159358013363291014307402600830078662555833653517843708051504582990832, |
|||
1022951765127126818581466247360193856197472064872288389992480993218645055345, |
|||
1888195070251580606973417065636430294417895423429240431595054184472931224452, |
|||
4221265384902749246920810956363310125115516771964522748896154428740238579824, |
|||
2825393571154632139467378429077438870179957021959813965940638905853993971879, |
|||
19171031072692942278056619599721228021635671304612437350119663236604712493093, |
|||
10780807212297131186617505517708903709488273075252405602261683478333331220733, |
|||
18230936781133176044598070768084230333433368654744509969087239465125979720995, |
|||
16901065971871379877929280081392692752968612240624985552337779093292740763381, |
|||
146494141603558321291767829522948454429758543710648402457451799015963102253, |
|||
2492729278659146790410698334997955258248120870028541691998279257260289595548, |
|||
2204224910006646535594933495262085193210692406133533679934843341237521233504, |
|||
16062117410185840274616925297332331018523844434907012275592638570193234893570, |
|||
5894928453677122829055071981254202951712129328678534592916926069506935491729, |
|||
4947482739415078212217504789923078546034438919537985740403824517728200332286, |
|||
16143265650645676880461646123844627780378251900510645261875867423498913438066, |
|||
397690828254561723549349897112473766901585444153303054845160673059519614409, |
|||
11272653598912269895509621181205395118899451234151664604248382803490621227687, |
|||
15566927854306879444693061574322104423426072650522411176731130806720753591030, |
|||
14222898219492484180162096141564251903058269177856173968147960855133048449557, |
|||
16690275395485630428127725067513114066329712673106153451801968992299636791385, |
|||
3667030990325966886479548860429670833692690972701471494757671819017808678584, |
|||
21280039024501430842616328642522421302481259067470872421086939673482530783142, |
|||
15895485136902450169492923978042129726601461603404514670348703312850236146328, |
|||
7733050956302327984762132317027414325566202380840692458138724610131603812560, |
|||
438123800976401478772659663183448617575635636575786782566035096946820525816, |
|||
814913922521637742587885320797606426167962526342166512693085292151314976633, |
|||
12368712287081330853637674140264759478736012797026621876924395982504369598764, |
|||
2494806857395134874309386694756263421445039103814920780777601708371037591569, |
|||
16101132301514338989512946061786320637179843435886825102406248183507106312877, |
|||
6252650284989960032925831409804233477770646333900692286731621844532438095656, |
|||
9277135875276787021836189566799935097400042171346561246305113339462708861695, |
|||
10493603554686607050979497281838644324893776154179810893893660722522945589063, |
|||
8673089750662709235894359384294076697329948991010184356091130382437645649279, |
|||
9558393272910366944245875920138649617479779893610128634419086981339060613250, |
|||
19012287860122586147374214541764572282814469237161122489573881644994964647218, |
|||
9783723818270121678386992630754842961728702994964214799008457449989291229500, |
|||
15550788416669474113213749561488122552422887538676036667630838378023479382689, |
|||
15016165746156232864069722572047169071786333815661109750860165034341572904221, |
|||
6506225705710197163670556961299945987488979904603689017479840649664564978574, |
|||
10796631184889302076168355684722130903785890709107732067446714470783437829037, |
|||
19871836214837460419845806980869387567383718044439891735114283113359312279540, |
|||
20871081766843466343749609089986071784031203517506781251203251608363835140622, |
|||
5100105771517691442278432864090229416166996183792075307747582375962855820797, |
|||
8777887112076272395250620301071581171386440850451972412060638225741125310886, |
|||
5300440870136391278944213332144327695659161151625757537632832724102670898756, |
|||
1205448543652932944633962232545707633928124666868453915721030884663332604536, |
|||
5542499997310181530432302492142574333860449305424174466698068685590909336771, |
|||
11028094245762332275225364962905938096659249161369092798505554939952525894293, |
|||
19187314764836593118404597958543112407224947638377479622725713735224279297009, |
|||
17047263688548829001253658727764731047114098556534482052135734487985276987385, |
|||
19914849528178967155534624144358541535306360577227460456855821557421213606310, |
|||
2929658084700714257515872921366736697080475676508114973627124569375444665664, |
|||
15092262360719700162343163278648422751610766427236295023221516498310468956361, |
|||
21578580340755653236050830649990190843552802306886938815497471545814130084980, |
|||
1258781501221760320019859066036073675029057285507345332959539295621677296991, |
|||
3819598418157732134449049289585680301176983019643974929528867686268702720163, |
|||
8653175945487997845203439345797943132543211416447757110963967501177317426221, |
|||
6614652990340435611114076169697104582524566019034036680161902142028967568142, |
|||
19212515502973904821995111796203064175854996071497099383090983975618035391558, |
|||
18664315914479294273286016871365663486061896605232511201418576829062292269769, |
|||
11498264615058604317482574216318586415670903094838791165247179252175768794889, |
|||
10814026414212439999107945133852431304483604215416531759535467355316227331774, |
|||
17566185590731088197064706533119299946752127014428399631467913813769853431107, |
|||
14016139747289624978792446847000951708158212463304817001882956166752906714332, |
|||
8242601581342441750402731523736202888792436665415852106196418942315563860366, |
|||
9244680976345080074252591214216060854998619670381671198295645618515047080988, |
|||
12216779172735125538689875667307129262237123728082657485828359100719208190116, |
|||
10702811721859145441471328511968332847175733707711670171718794132331147396634, |
|||
6479667912792222539919362076122453947926362746906450079329453150607427372979, |
|||
15117544653571553820496948522381772148324367479772362833334593000535648316185, |
|||
6842203153996907264167856337497139692895299874139131328642472698663046726780, |
|||
12732823292801537626009139514048596316076834307941224506504666470961250728055, |
|||
6936272626871035740815028148058841877090860312517423346335878088297448888663, |
|||
17297554111853491139852678417579991271009602631577069694853813331124433680030, |
|||
16641596134749940573104316021365063031319260205559553673368334842484345864859, |
|||
7400481189785154329569470986896455371037813715804007747228648863919991399081, |
|||
2273205422216987330510475127669563545720586464429614439716564154166712854048, |
|||
15162538063742142685306302282127534305212832649282186184583465569986719234456, |
|||
5628039096440332922248578319648483863204530861778160259559031331287721255522, |
|||
16085392195894691829567913404182676871326863890140775376809129785155092531260, |
|||
14227467863135365427954093998621993651369686288941275436795622973781503444257, |
|||
18224457394066545825553407391290108485121649197258948320896164404518684305122, |
|||
274945154732293792784580363548970818611304339008964723447672490026510689427, |
|||
11050822248291117548220126630860474473945266276626263036056336623671308219529, |
|||
2119542016932434047340813757208803962484943912710204325088879681995922344971, |
|||
0 |
|||
]; |
|||
|
|||
var t; |
|||
signal t2[nrounds]; |
|||
signal t4[nrounds]; |
|||
signal xL[nrounds-1]; |
|||
signal xR[nrounds-1]; |
|||
|
|||
for (var i=0; i<nrounds; i++) { |
|||
t = (i==0) ? k+xL_in : k + xL[i-1] + c[i]; |
|||
t2[i] <== t*t; |
|||
t4[i] <== t2[i]*t2[i]; |
|||
if (i<nrounds-1) { |
|||
xL[i] <== ((i==0) ? xR_in : xR[i-1]) + t4[i]*t; |
|||
xR[i] = (i==0) ? xL_in : xL[i-1]; |
|||
} else { |
|||
xR_out <== xR[i-1] + t4[i]*t; |
|||
xL_out <== xL[i-1]; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,47 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
template MultiMux1(n) { |
|||
signal input c[n][2]; // Constants |
|||
signal input s; // Selector |
|||
signal output out[n]; |
|||
|
|||
for (var i=0; i<n; i++) { |
|||
|
|||
out[i] <== (c[i][1] - c[i][0])*s + c[i][0]; |
|||
|
|||
} |
|||
} |
|||
|
|||
template Mux1() { |
|||
var i; |
|||
signal input c[2]; // Constants |
|||
signal input s; // Selector |
|||
signal output out; |
|||
|
|||
component mux = MultiMux1(1); |
|||
|
|||
for (i=0; i<2; i++) { |
|||
mux.c[0][i] <== c[i]; |
|||
} |
|||
|
|||
s ==> mux.s; |
|||
|
|||
mux.out[0] ==> out; |
|||
} |
@ -0,0 +1,62 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
template MultiMux2(n) { |
|||
signal input c[n][4]; // Constants |
|||
signal input s[2]; // Selector |
|||
signal output out[n]; |
|||
|
|||
signal a10[n]; |
|||
signal a1[n]; |
|||
signal a0[n]; |
|||
signal a[n]; |
|||
|
|||
signal s10; |
|||
s10 <== s[1] * s[0]; |
|||
|
|||
for (var i=0; i<n; i++) { |
|||
|
|||
a10[i] <== ( c[i][ 3]-c[i][ 2]-c[i][ 1]+c[i][ 0] ) * s10; |
|||
a1[i] <== ( c[i][ 2]-c[i][ 0] ) * s[1]; |
|||
a0[i] <== ( c[i][ 1]-c[i][ 0] ) * s[0]; |
|||
a[i] <== ( c[i][ 0] ) |
|||
|
|||
out[i] <== ( a10[i] + a1[i] + a0[i] + a[i] ); |
|||
|
|||
} |
|||
} |
|||
|
|||
template Mux2() { |
|||
var i; |
|||
signal input c[4]; // Constants |
|||
signal input s[2]; // Selector |
|||
signal output out; |
|||
|
|||
component mux = MultiMux2(1); |
|||
|
|||
for (i=0; i<4; i++) { |
|||
mux.c[0][i] <== c[i]; |
|||
} |
|||
|
|||
for (i=0; i<2; i++) { |
|||
s[i] ==> mux.s[i]; |
|||
} |
|||
|
|||
mux.out[0] ==> out; |
|||
} |
@ -0,0 +1,203 @@ |
|||
|
|||
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 = [ |
|||
14397397413755236225575615486459253198602422701513067526754101844196324375522, |
|||
10405129301473404666785234951972711717481302463898292859783056520670200613128, |
|||
5179144822360023508491245509308555580251733042407187134628755730783052214509, |
|||
9132640374240188374542843306219594180154739721841249568925550236430986592615, |
|||
20360807315276763881209958738450444293273549928693737723235350358403012458514, |
|||
17933600965499023212689924809448543050840131883187652471064418452962948061619, |
|||
3636213416533737411392076250708419981662897009810345015164671602334517041153, |
|||
2008540005368330234524962342006691994500273283000229509835662097352946198608, |
|||
16018407964853379535338740313053768402596521780991140819786560130595652651567, |
|||
20653139667070586705378398435856186172195806027708437373983929336015162186471, |
|||
17887713874711369695406927657694993484804203950786446055999405564652412116765, |
|||
4852706232225925756777361208698488277369799648067343227630786518486608711772, |
|||
8969172011633935669771678412400911310465619639756845342775631896478908389850, |
|||
20570199545627577691240476121888846460936245025392381957866134167601058684375, |
|||
16442329894745639881165035015179028112772410105963688121820543219662832524136, |
|||
20060625627350485876280451423010593928172611031611836167979515653463693899374, |
|||
16637282689940520290130302519163090147511023430395200895953984829546679599107, |
|||
15599196921909732993082127725908821049411366914683565306060493533569088698214, |
|||
16894591341213863947423904025624185991098788054337051624251730868231322135455, |
|||
1197934381747032348421303489683932612752526046745577259575778515005162320212, |
|||
6172482022646932735745595886795230725225293469762393889050804649558459236626, |
|||
21004037394166516054140386756510609698837211370585899203851827276330669555417, |
|||
15262034989144652068456967541137853724140836132717012646544737680069032573006, |
|||
15017690682054366744270630371095785995296470601172793770224691982518041139766, |
|||
15159744167842240513848638419303545693472533086570469712794583342699782519832, |
|||
11178069035565459212220861899558526502477231302924961773582350246646450941231, |
|||
21154888769130549957415912997229564077486639529994598560737238811887296922114, |
|||
20162517328110570500010831422938033120419484532231241180224283481905744633719, |
|||
2777362604871784250419758188173029886707024739806641263170345377816177052018, |
|||
15732290486829619144634131656503993123618032247178179298922551820261215487562, |
|||
6024433414579583476444635447152826813568595303270846875177844482142230009826, |
|||
17677827682004946431939402157761289497221048154630238117709539216286149983245, |
|||
10716307389353583413755237303156291454109852751296156900963208377067748518748, |
|||
14925386988604173087143546225719076187055229908444910452781922028996524347508, |
|||
8940878636401797005293482068100797531020505636124892198091491586778667442523, |
|||
18911747154199663060505302806894425160044925686870165583944475880789706164410, |
|||
8821532432394939099312235292271438180996556457308429936910969094255825456935, |
|||
20632576502437623790366878538516326728436616723089049415538037018093616927643, |
|||
71447649211767888770311304010816315780740050029903404046389165015534756512, |
|||
2781996465394730190470582631099299305677291329609718650018200531245670229393, |
|||
12441376330954323535872906380510501637773629931719508864016287320488688345525, |
|||
2558302139544901035700544058046419714227464650146159803703499681139469546006, |
|||
10087036781939179132584550273563255199577525914374285705149349445480649057058, |
|||
4267692623754666261749551533667592242661271409704769363166965280715887854739, |
|||
4945579503584457514844595640661884835097077318604083061152997449742124905548, |
|||
17742335354489274412669987990603079185096280484072783973732137326144230832311, |
|||
6266270088302506215402996795500854910256503071464802875821837403486057988208, |
|||
2716062168542520412498610856550519519760063668165561277991771577403400784706, |
|||
19118392018538203167410421493487769944462015419023083813301166096764262134232, |
|||
9386595745626044000666050847309903206827901310677406022353307960932745699524, |
|||
9121640807890366356465620448383131419933298563527245687958865317869840082266, |
|||
3078975275808111706229899605611544294904276390490742680006005661017864583210, |
|||
7157404299437167354719786626667769956233708887934477609633504801472827442743, |
|||
14056248655941725362944552761799461694550787028230120190862133165195793034373, |
|||
14124396743304355958915937804966111851843703158171757752158388556919187839849, |
|||
11851254356749068692552943732920045260402277343008629727465773766468466181076, |
|||
9799099446406796696742256539758943483211846559715874347178722060519817626047, |
|||
10156146186214948683880719664738535455146137901666656566575307300522957959544, |
|||
19908645952733301583346063785055921934459499091029406575311417879963332475861, |
|||
11766105336238068471342414351862472329437473380853789942065610694000443387471, |
|||
11002137593249972174092192767251572171769044073555430468487809799220351297047, |
|||
284136377911685911941431040940403846843630064858778505937392780738953624163, |
|||
19448733709802908339787967270452055364068697565906862913410983275341804035680, |
|||
14423660424692802524250720264041003098290275890428483723270346403986712981505, |
|||
10635360132728137321700090133109897687122647659471659996419791842933639708516 |
|||
]; |
|||
|
|||
var M = [ |
|||
[ |
|||
19167410339349846567561662441069598364702008768579734801591448511131028229281, |
|||
14183033936038168803360723133013092560869148726790180682363054735190196956789, |
|||
9067734253445064890734144122526450279189023719890032859456830213166173619761, |
|||
16378664841697311562845443097199265623838619398287411428110917414833007677155, |
|||
12968540216479938138647596899147650021419273189336843725176422194136033835172, |
|||
3636162562566338420490575570584278737093584021456168183289112789616069756675 |
|||
],[ |
|||
17034139127218860091985397764514160131253018178110701196935786874261236172431, |
|||
2799255644797227968811798608332314218966179365168250111693473252876996230317, |
|||
2482058150180648511543788012634934806465808146786082148795902594096349483974, |
|||
16563522740626180338295201738437974404892092704059676533096069531044355099628, |
|||
10468644849657689537028565510142839489302836569811003546969773105463051947124, |
|||
3328913364598498171733622353010907641674136720305714432354138807013088636408 |
|||
],[ |
|||
18985203040268814769637347880759846911264240088034262814847924884273017355969, |
|||
8652975463545710606098548415650457376967119951977109072274595329619335974180, |
|||
970943815872417895015626519859542525373809485973005165410533315057253476903, |
|||
19406667490568134101658669326517700199745817783746545889094238643063688871948, |
|||
17049854690034965250221386317058877242629221002521630573756355118745574274967, |
|||
4964394613021008685803675656098849539153699842663541444414978877928878266244 |
|||
],[ |
|||
19025623051770008118343718096455821045904242602531062247152770448380880817517, |
|||
9077319817220936628089890431129759976815127354480867310384708941479362824016, |
|||
4770370314098695913091200576539533727214143013236894216582648993741910829490, |
|||
4298564056297802123194408918029088169104276109138370115401819933600955259473, |
|||
6905514380186323693285869145872115273350947784558995755916362330070690839131, |
|||
4783343257810358393326889022942241108539824540285247795235499223017138301952 |
|||
],[ |
|||
16205238342129310687768799056463408647672389183328001070715567975181364448609, |
|||
8303849270045876854140023508764676765932043944545416856530551331270859502246, |
|||
20218246699596954048529384569730026273241102596326201163062133863539137060414, |
|||
1712845821388089905746651754894206522004527237615042226559791118162382909269, |
|||
13001155522144542028910638547179410124467185319212645031214919884423841839406, |
|||
16037892369576300958623292723740289861626299352695838577330319504984091062115 |
|||
],[ |
|||
15162889384227198851506890526431746552868519326873025085114621698588781611738, |
|||
13272957914179340594010910867091459756043436017766464331915862093201960540910, |
|||
9416416589114508529880440146952102328470363729880726115521103179442988482948, |
|||
8035240799672199706102747147502951589635001418759394863664434079699838251138, |
|||
21642389080762222565487157652540372010968704000567605990102641816691459811717, |
|||
20261355950827657195644012399234591122288573679402601053407151083849785332516 |
|||
] |
|||
]; |
|||
|
|||
|
|||
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,56 @@ |
|||
/* |
|||
Copyright 2018 0KIMS association. |
|||
|
|||
This file is part of circom (Zero Knowledge Circuit Compiler). |
|||
|
|||
circom is a free software: you can redistribute it and/or modify it |
|||
under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
circom is distributed in the hope that it will be useful, but WITHOUT |
|||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
|||
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
|||
License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with circom. If not, see <https://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
include "../poseidon.circom"; |
|||
|
|||
|
|||
/* |
|||
Hash1 = H(1 | key | value) |
|||
*/ |
|||
|
|||
template SMTHash1() { |
|||
signal input key; |
|||
signal input value; |
|||
signal output out; |
|||
|
|||
component h = Poseidon(3, 6, 8, 57); // Constant |
|||
h.inputs[0] <== key; |
|||
h.inputs[1] <== value; |
|||
h.inputs[2] <== 1; |
|||
|
|||
out <== h.out; |
|||
} |
|||
|
|||
/* |
|||
This component is used to create the 2 nodes. |
|||
|
|||
Hash2 = H(Hl | Hr) |
|||
*/ |
|||
|
|||
template SMTHash2() { |
|||
signal input L; |
|||
signal input R; |
|||
signal output out; |
|||
|
|||
component h = Poseidon(2, 6, 8, 57); // Constant |
|||
h.inputs[0] <== L; |
|||
h.inputs[1] <== R; |
|||
|
|||
out <== h.out; |
|||
} |
@ -1,4 +1,6 @@ |
|||
exports.smt = require("./src/smt"); |
|||
exports.eddsa = require("./src/eddsa"); |
|||
exports.mimc7 = require("./src/mimc7"); |
|||
exports.mimcsponge = require("./src/mimcsponge"); |
|||
exports.babyJub = require("./src/babyjub"); |
|||
exports.pedersenHash = require("./src/pedersenHash"); |
@ -0,0 +1,583 @@ |
|||
// Copyright (c) 2018 Jordi Baylina
|
|||
// License: LGPL-3.0+
|
|||
//
|
|||
|
|||
const Contract = require("./evmasm"); |
|||
const G2 = require("snarkjs").bn128.G2; |
|||
const bigInt = require("snarkjs").bigInt; |
|||
|
|||
|
|||
function toHex256(a) { |
|||
let S = a.toString(16); |
|||
while (S.length < 64) S="0"+S; |
|||
return "0x" + S; |
|||
} |
|||
|
|||
function createCode(P, w) { |
|||
|
|||
const C = new Contract(); |
|||
|
|||
const NPOINTS = 1 << (w-1); |
|||
|
|||
const VAR_POS = C.allocMem(32); |
|||
const VAR_POINTS = C.allocMem( (NPOINTS)*4*32); |
|||
const savedP = C.allocMem(32); |
|||
const savedZ3 = C.allocMem(32); |
|||
|
|||
// Check selector
|
|||
C.push("0x0100000000000000000000000000000000000000000000000000000000"); |
|||
C.push(0); |
|||
C.calldataload(); |
|||
C.div(); |
|||
C.push("b65c7c74"); // mulexp(uint256)
|
|||
C.eq(); |
|||
C.jmpi("start"); |
|||
C.invalid(); |
|||
|
|||
C.label("start"); |
|||
|
|||
storeVals(); |
|||
|
|||
C.push( Math.floor(255/w)*w ); // pos := 255
|
|||
C.push(VAR_POS); |
|||
C.mstore(); |
|||
|
|||
C.push("21888242871839275222246405745257275088696311157297823662689037894645226208583"); |
|||
C.push(0); |
|||
C.push(0); |
|||
C.push(0); |
|||
C.push(0); |
|||
C.push(0); |
|||
C.push(0); |
|||
|
|||
C.label("begin_loop"); // ACC_X ACC_Y ACC_Z q
|
|||
|
|||
C.internalCall("double"); |
|||
|
|||
// g = (e>>pos)&MASK
|
|||
C.push(4); |
|||
C.calldataload(); // e ACC_X ACC_Y ACC_Z q
|
|||
|
|||
C.push(VAR_POS); |
|||
C.mload(); // pos e ACC_X ACC_Y ACC_Z q
|
|||
C.shr(); |
|||
|
|||
C.push(NPOINTS-1); |
|||
C.and(); // g ACC_X ACC_Y ACC_Z q
|
|||
|
|||
C.internalCall("add"); // acc_x acc_y acc_z
|
|||
|
|||
C.push(VAR_POS); |
|||
C.mload(); // pos acc_x acc_y acc_z
|
|||
C.dup(0); // pos pos acc_x acc_y acc_z
|
|||
C.push(0); // 0 pos pos acc_x acc_y acc_z
|
|||
C.eq(); // eq pos acc_x acc_y acc_z
|
|||
C.jmpi("after_loop"); // pos acc_x acc_y acc_z
|
|||
C.push(w); // 5 pos acc_x acc_y acc_z
|
|||
C.sub(); // pos acc_x acc_y acc_z
|
|||
C.push(VAR_POS); |
|||
C.mstore(); // acc_x acc_y acc_z
|
|||
C.jmp("begin_loop"); |
|||
C.label("after_loop"); // pos acc_x acc_y acc_z
|
|||
C.pop(); // acc_x acc_y acc_z
|
|||
|
|||
C.internalCall("affine"); // acc_x acc_y
|
|||
|
|||
C.push(0); |
|||
C.mstore(); |
|||
C.push(20); |
|||
C.mstore(); |
|||
C.push(40); |
|||
C.mstore(); |
|||
C.push(60); |
|||
C.mstore(); |
|||
|
|||
C.push("0x80"); |
|||
C.push("0x00"); |
|||
C.return(); |
|||
|
|||
|
|||
double(); |
|||
addPoint(); |
|||
affine(); |
|||
|
|||
return C.createTxData(); |
|||
|
|||
function add(a,b,q) { |
|||
C.dup(q); |
|||
C.dup(a+1 + 1); |
|||
C.dup(b+1 + 2); |
|||
C.addmod(); |
|||
C.dup(q + 1); |
|||
C.dup(a + 2); |
|||
C.dup(b + 3); |
|||
C.addmod(); |
|||
} |
|||
|
|||
function sub(a,b,q) { |
|||
C.dup(q); // q
|
|||
C.dup(a+1 + 1); // ai q
|
|||
C.dub(q + 2); // q ai q
|
|||
C.dup(b+1 + 3); // bi q ai q
|
|||
C.sub(); // -bi ai q
|
|||
C.addmod(); // ci
|
|||
C.dup(q + 1); // q ci
|
|||
C.dup(a + 2); // ar q ci
|
|||
C.dup(q + 3); // q ar q ci
|
|||
C.dup(b + 4); // br q ar q ci
|
|||
C.sub(); // -br ar q ci
|
|||
C.addmod(); // cr ci
|
|||
} |
|||
|
|||
function mul(a, b, q) { |
|||
C.dup(q); // q
|
|||
C.dup(q + 1); // q q
|
|||
C.dup(a + 2); // ar q q
|
|||
C.dup(b+1 + 3); // bi ar q q
|
|||
C.mulmod(); // ci1 q
|
|||
C.dup(q + 2); // q ci1 q
|
|||
C.dup(a+1 + 3); // ai q ci1 q
|
|||
C.dup(b + 4); // ar ai q ci1 q
|
|||
C.mulmod(); // ci2 ci1 q
|
|||
C.addmod(); // ci
|
|||
C.dup(q + 1); // q ci
|
|||
C.dup(q + 2); // q q ci
|
|||
C.dup(q + 3); // q q q ci
|
|||
C.dup(a+1 + 4); // ai q q ci
|
|||
C.dup(b+1 + 5); // bi ai q q ci
|
|||
C.mulmod(); // cr2 q q ci
|
|||
C.sub(); // -cr2 q ci
|
|||
C.dup(q + 3); // q -cr2 q ci
|
|||
C.dup(a + 4); // ar q -cr2 q ci
|
|||
C.dup(b + 5); // br ar q -cr2 q ci
|
|||
C.mulmod(); // cr1 -cr2 q ci
|
|||
C.addmod(); // cr ci
|
|||
} |
|||
|
|||
function square(a, q) { |
|||
C.dup(q); // q
|
|||
C.dup(q + 1); // q q
|
|||
C.dup(a + 2); // ar q q
|
|||
C.dup(a+1 + 3); // ai ar q q
|
|||
C.mulmod(); // arai q
|
|||
C.dup(0); // arai arai q
|
|||
C.addmod(); // ci
|
|||
C.dup(q + 1); // q ci
|
|||
C.dup(q + 2); // q q ci
|
|||
C.dup(q + 3); // q q q ci
|
|||
C.dup(a+1 + 4); // ai q q ci
|
|||
C.dup(a+1 + 5); // ai ai q q ci
|
|||
C.mulmod(); // cr2 q q ci
|
|||
C.sub(); // -cr2 q ci
|
|||
C.dup(q + 3); // q -cr2 q ci
|
|||
C.dup(a + 4); // ar q -cr2 q ci
|
|||
C.dup(a + 5); // br ar q -cr2 q ci
|
|||
C.mulmod(); // cr1 -cr2 q ci
|
|||
C.addmod(); // cr ci
|
|||
} |
|||
|
|||
function add1(a, q) { |
|||
C.dup(a+1); // im
|
|||
C.dup(1 + q); // q
|
|||
C.dup(2 + a); // re q im
|
|||
C.push(1); // 1 re q im
|
|||
C.addmod(); |
|||
} |
|||
|
|||
function cmp(a, b) { |
|||
C.dup(a); |
|||
C.dup(b); |
|||
C.eq(); |
|||
C.dup(a+1); |
|||
C.dup(a+1); |
|||
C.and(); |
|||
} |
|||
|
|||
function rm(a) { |
|||
if (a>0) C.swap(a); |
|||
C.pop(); |
|||
if (a>0) C.swap(a); |
|||
C.pop(); |
|||
} |
|||
|
|||
function double() { |
|||
C.label("double"); // xR, xI, yR, yI, zR zI, q
|
|||
|
|||
C.dup(4); |
|||
C.iszero(); |
|||
C.dup(6); |
|||
C.iszero(); |
|||
C.and(); |
|||
C.jumpi("enddouble"); // X Y Z q
|
|||
|
|||
|
|||
// Z3 = 2*Y*Z // Remove Z
|
|||
mul(2, 4, 6); // yz X Y Z q
|
|||
rm(6); // X Y yz q
|
|||
|
|||
add(4, 4, 6); // 2yz X Y yz q
|
|||
rm(6); // X Y Z3 q
|
|||
|
|||
// A = X^2
|
|||
square(0,6); // A X Y Z3 q
|
|||
|
|||
// B = Y^2 // Remove Y
|
|||
square(4,8); // B A X Y Z3 q
|
|||
rm(6); // A X B Z3 q
|
|||
|
|||
// C = B^2
|
|||
square(4,8); // C A X B Z3 q
|
|||
|
|||
// D = (X+B)^2-A-C // Remove X, Remove B
|
|||
add(4,6, 10); // X+B C A X B Z3 q
|
|||
rm(6); // C A X+B B Z3 q
|
|||
rm(6); // A X+B C Z3 q
|
|||
square(2,8); // (X+B)^2 A X+B C Z3 q
|
|||
rm(4); // A (X+B)^2 C Z3 q
|
|||
sub(2, 0, 8); // (X+B)^2-A A (X+B)^2 C Z3 q
|
|||
rm(4); // A (X+B)^2-A C Z3 q
|
|||
sub(2, 4, 8); // (X+B)^2-A-C A (X+B)^2-A C Z3 q
|
|||
rm(4); // A D C Z3 q
|
|||
|
|||
// D = D+D
|
|||
add(2,2, 8); // D+D A D C Z3 q
|
|||
rm(4); // A D C Z3 q
|
|||
|
|||
// E=A+A+A
|
|||
add(0, 0, 8); // 2A A D C Z3 q
|
|||
add(0, 2, 10); // 3A 2A A D C Z3 q
|
|||
rm(4); // 2A 3A D C Z3 q
|
|||
rm(0); // E D C Z3 q
|
|||
|
|||
// F=E^2
|
|||
square(0, 8); // F E D C Z3 q
|
|||
|
|||
// X3= F - 2*D // Remove F
|
|||
add(4, 4, 10); // 2D F E D C Z3 q
|
|||
sub(2, 0, 12); // F-2D 2D F E D C Z3 q
|
|||
rm(4); // 2D X3 E D C Z3 q
|
|||
rm(0); // X3 E D C Z3 q
|
|||
|
|||
// Y3 = E * (D - X3) - 8 * C // Remove D C E
|
|||
|
|||
sub(4, 0, 10); // D-X3 X3 E D C Z3 q
|
|||
rm(6); // X3 E D-X3 C Z3 q
|
|||
mul(2, 4, 10); // E*(D-X3) X3 E D-X3 C Z3 q
|
|||
rm(6); // X3 E E*(D-X3) C Z3 q
|
|||
rm(2); // X3 E*(D-X3) C Z3 q
|
|||
add(4, 4, 8); // 2C X3 E*(D-X3) C Z3 q
|
|||
rm(6); // X3 E*(D-X3) 2C Z3 q
|
|||
add(4, 4, 8); // 4C X3 E*(D-X3) 2C Z3 q
|
|||
rm(6); // X3 E*(D-X3) 4C Z3 q
|
|||
add(4, 4, 8); // 8C X3 E*(D-X3) 4C Z3 q
|
|||
rm(6); // X3 E*(D-X3) 8C Z3 q
|
|||
sub(2, 4, 8); // E*(D-X3)-8C X3 E*(D-X3) 8C Z3 q
|
|||
rm(6); // X3 E*(D-X3) Y3 Z3 q
|
|||
rm(2); // X3 Y3 Z3 q
|
|||
|
|||
C.label("enddouble"); |
|||
C.returnCall(); |
|||
} |
|||
|
|||
function addPoint() { // p, xR, xI, yR, yI, zR zI, q
|
|||
|
|||
|
|||
C.dup(0); // p p X2 Y2 Z2 q
|
|||
|
|||
C.push(savedP); |
|||
C.mstore(); |
|||
|
|||
C.iszero(); // X2 Y2 Z2 q
|
|||
C.jumpi("endpadd"); |
|||
|
|||
|
|||
C.dup(4); |
|||
C.iszero(); |
|||
C.dup(6); |
|||
C.iszero(); |
|||
C.and(); |
|||
C.jumpi("returnP"); // X2 Y2 Z2 q
|
|||
|
|||
|
|||
|
|||
// lastZ3 = (Z2+1)^2 - Z2^2
|
|||
add1(4, 6); // Z2+1 X2 Y2 Z2 q
|
|||
square(0, 8); // (Z2+1)^2 Z2+1 X2 Y2 Z2 q
|
|||
rm(2); // (Z2+1)^2 X2 Y2 Z2 q
|
|||
square(6, 8); // Z2^2 (Z2+1)^2 X2 Y2 Z2 q
|
|||
|
|||
|
|||
sub(2, 0, 10); // (Z2+1)^2-Z2^2 Z2^2 (Z2+1)^2 X2 Y2 Z2 q
|
|||
|
|||
saveZ3(); // Z2^2 (Z2+1)^2 X2 Y2 Z2 q
|
|||
rm(2); // Z2^2 X2 Y2 Z2 q
|
|||
|
|||
// U2 = X2
|
|||
// S2 = Y2 // Z2^2 U2 S2 Z2 q
|
|||
|
|||
|
|||
// U1 = X1 * Z2^2
|
|||
loadX(); // X1 Z2^2 U2 S2 Z2 q
|
|||
mul(0, 2, 10); // X1*Z2^2 X1 Z2^2 U2 S2 Z2 q
|
|||
rm(2); // X1*Z2^2 Z2^2 U2 S2 Z2 q
|
|||
|
|||
|
|||
mul(2, 8, 10); // Z2^3 U1 Z2^2 U2 S2 Z2 q
|
|||
rm(4); // U1 Z2^3 U2 S2 Z2 q
|
|||
rm(8); // Z2^3 U2 S2 U1 q
|
|||
|
|||
// S1 = Y1 * Z1^3
|
|||
loadY(); // Y1 Z2^3 U2 S2 U1 q
|
|||
mul(0, 2, 10); // S1 Y1 Z2^3 U2 S2 U1 q
|
|||
rm(4); // Y1 S1 U2 S2 U1 q
|
|||
rm(0); // S1 U2 S2 U1 q
|
|||
|
|||
cmp(0, 4); // c1 S1 U2 S2 U1 q
|
|||
cmp(3, 7); // c2 c1 S1 U2 S2 U1 q
|
|||
C.and(); // c2&c1 S1 U2 S2 U1 q
|
|||
C.jumpi("double1"); // S1 U2 S2 U1 q
|
|||
|
|||
|
|||
// Returns the double
|
|||
|
|||
// H = U2-U1 // Remove U2
|
|||
C.sub(4, 8, 10); // H S1 U2 S2 U1 q
|
|||
rm(4); // S1 H S2 U1 q
|
|||
|
|||
// // r = 2 * (S2-S1) // Remove S2
|
|||
C.sub(4, 4, 8); // S1-S2 S1 H S2 U1 q
|
|||
rm(6); // S1 H S1-S2 U1 q
|
|||
C.add(4, 4, 8); // 2*(S1-S2) S1 H S1-S2 U1 q
|
|||
rm(6); // S1 H r U1 q
|
|||
|
|||
// I = (2 * H)^2
|
|||
C.add(2, 2, 8); // 2*H S1 H r U1 q
|
|||
C.square(0, 10); // (2*H)^2 2*H S1 H r U1 q
|
|||
rm(2); // I S1 H r U1 q
|
|||
|
|||
// V = U1 * I
|
|||
mul(8, 0, 10); // V I S1 H r U1 q
|
|||
rm(10); // I S1 H r V q
|
|||
|
|||
// J = H * I // Remove I
|
|||
mul(4, 0, 10); // J I S1 H r V q
|
|||
rm(2); // J S1 H r V q
|
|||
|
|||
// X3 = r^2 - J - 2 * V
|
|||
|
|||
// S1J2 = (S1*J)*2 // Remove S1
|
|||
mul(2, 0, 10); // S1*J J S1 H r V q
|
|||
rm(4); // J S1*J H r V q
|
|||
add(2,2, 10); // (S1*J)*2 J S1*J H r V q
|
|||
rm(4); // J S1J2 H r V q
|
|||
|
|||
// X3 = r^2 - J - 2 * V
|
|||
square(6, 10); // r^2 J S1J2 H r V q
|
|||
sub(0, 2, 12); // r^2-J r^2 J S1J2 H r V q
|
|||
rm(2); // r^2-J J S1J2 H r V q
|
|||
rm(2); // r^2-J S1J2 H r V q
|
|||
add(8, 8, 10); // 2*V r^2-J S1J2 H r V q
|
|||
sub(2, 0, 12); // r^2-J-2*V 2*V r^2-J S1J2 H r V q
|
|||
rm(4); // 2*V X3 S1J2 H r V q
|
|||
rm(0); // X3 S1J2 H r V q
|
|||
|
|||
// Y3 = r * (V-X3)-S1J2
|
|||
|
|||
sub(8, 0, 10); // V-X3 X3 S1J2 H r V q
|
|||
rm(10); // X3 S1J2 H r V-X3 q
|
|||
mul(6, 8, 10); // r*(V-X3) X3 S1J2 H r V-X3 q
|
|||
rm(8); // X3 S1J2 H r*(V-X3) V-X3 q
|
|||
rm(8); // S1J2 H r*(V-X3) X3 q
|
|||
sub(4, 0, 8); // Y3 S1J2 H r*(V-X3) X3 q
|
|||
rm(6); // S1J2 H Y3 X3 q
|
|||
rm(0); // H Y3 X3 q
|
|||
|
|||
// Z3 = lastZ * H
|
|||
loadZ3(); // lastZ3 H Y3 X3 q
|
|||
mul(0, 2, 8); // Z3 lastZ3 H Y3 X3 q
|
|||
rm(4); // lastZ3 Z3 Y3 X3 q
|
|||
rm(0); // Z3 Y3 X3 q
|
|||
|
|||
C.swap(1); |
|||
C.swap(5); |
|||
C.swap(1); |
|||
C.swap(4); // X3 Y3 Z3 q
|
|||
|
|||
// returns the point in memory
|
|||
C.label("returnP"); // X Y Z q
|
|||
rm(0); |
|||
rm(0); |
|||
rm(0); |
|||
C.push(0); |
|||
C.push(1); |
|||
loadX(); |
|||
loadY(); |
|||
C.jump("endpadd"); |
|||
|
|||
C.label("double1"); // S1 U2 S2 U1 q
|
|||
rm(0); |
|||
rm(0); |
|||
rm(0); |
|||
rm(0); |
|||
C.push(0); |
|||
C.push(1); |
|||
loadX(); |
|||
loadY(); |
|||
C.jump("double"); |
|||
|
|||
C.label("endpadd"); |
|||
C.returnCall(); |
|||
|
|||
function loadX() { |
|||
C.push(savedP); |
|||
C.mload(); // p
|
|||
C.push(32); |
|||
C.mul(); // P*32
|
|||
C.push(VAR_POINTS+32); |
|||
C.add(); // P*32+32
|
|||
C.dup(); // P*32+32 P*32+32
|
|||
C.mload(); // im P*32+32
|
|||
C.swap(1); // P*32+32 im
|
|||
C.push(0x20); // 32 P*32+32 im
|
|||
C.sub(); // P*32 im
|
|||
C.mload(); // re im
|
|||
} |
|||
|
|||
function loadY() { |
|||
C.push(savedP); |
|||
C.mload(); // p
|
|||
C.push(32); |
|||
C.mul(); // P*32
|
|||
C.push(VAR_POINTS+32*3); |
|||
C.add(); // P*32+32
|
|||
C.dup(); // P*32+32 P*32+32
|
|||
C.mload(); // im P*32+32
|
|||
C.swap(1); // P*32+32 im
|
|||
C.push(0x20); // 32 P*32+32 im
|
|||
C.sub(); // P*32 im
|
|||
C.mload(); // re im
|
|||
} |
|||
|
|||
function loadZ3() { |
|||
C.push(savedZ3+32); |
|||
C.mload(); // p
|
|||
C.push(savedZ3); |
|||
C.mload(); |
|||
} |
|||
|
|||
function saveZ3() { |
|||
C.push(savedZ3); |
|||
C.mstore(); |
|||
C.push(savedZ3+32); |
|||
C.mstore(); |
|||
} |
|||
} |
|||
|
|||
function affine() { // X Y Z q
|
|||
// If Z2=0 return 0
|
|||
C.label("affine"); |
|||
C.dup(4); |
|||
C.dup(5 + 1); |
|||
C.or(); |
|||
C.jumpi("notZero"); // X Y Z q
|
|||
rm(0); |
|||
rm(0); |
|||
C.push(0); |
|||
C.push(0); |
|||
|
|||
C.jmp("endAffine"); |
|||
C.label("notZero"); |
|||
|
|||
inverse2(4,6); // Z_inv X Y Z q
|
|||
square(2, 8); // Z2_inv Z_inv X Y Z q
|
|||
mul(0, 2, 10); // Z3_inv Z2_inv Z_inv X Y Z q
|
|||
rm(4); // Z2_inv Z3_inv X Y Z q
|
|||
C.push(1); |
|||
C.push(0); // 1 Z2_inv Z3_inv X Y Z q
|
|||
rm(10); // Z2_inv Z3_inv X Y 1 q
|
|||
mul(2, 6, 10); // YI Z2_inv Z3_inv X Y 1 q
|
|||
rm(8); // Z2_inv Z3_inv X YI 1 q
|
|||
mul(0, 4, 10); // XI Z2_inv Z3_inv X YI 1 q
|
|||
rm(6); // Z2_inv Z3_inv XI YI 1 q
|
|||
rm(0); // Z3_inv XI YI 1 q
|
|||
rm(0); // XI YI 1 q
|
|||
C.label("endAffine"); |
|||
C.returnCall(); |
|||
} |
|||
|
|||
function inverse2(a, q) { |
|||
C.dup(q); // q
|
|||
C.dup(q + 1); // q q
|
|||
C.push(2); // 2 q q
|
|||
C.sub(); // q-2 q
|
|||
C.dup(q + 2); // q q-2 q
|
|||
C.dup(q + 3); // q q q-2 q
|
|||
C.dup(a + 4); // ar q q q-2 q
|
|||
C.dup(a + 5); // ar ar q q q-2 q
|
|||
C.mulmod(); // t0 q q-2 q
|
|||
|
|||
C.dup(q + 4); // q t0 q q-2 q
|
|||
C.dup(a+1 + 5); // ai q t0 q q-2 q
|
|||
C.dup(a+1 + 6); // ai ai q t0 q q-2 q
|
|||
C.mulmod(); // t1 t0 q q-2 q
|
|||
|
|||
C.addmod(); // t2 q-2 q
|
|||
C.expmod(); // t3
|
|||
|
|||
C.dup(q + 1); // q t3
|
|||
C.dup(q + 2); // q q t3
|
|||
C.dup(q + 3); // q q q t3
|
|||
C.dup(1); // t3 q q q t3
|
|||
C.sub(); // -t3 q q t3
|
|||
C.dup(a+1 + 3); // ai -t3 q q t3
|
|||
C.mulmod(); // ii q t3
|
|||
C.swap(2); // t3 q ii
|
|||
C.dup(a + 3); // ar t3 q ii
|
|||
C.mulmod(); // ir ii
|
|||
} |
|||
|
|||
function storeVals() { |
|||
C.push(VAR_POINTS); // p
|
|||
for (let i=0; i<NPOINTS; i++) { |
|||
const MP = G2.affine(G2.mulScalar(P, bigInt(i))); |
|||
for (let j=0; j<2; j++) { |
|||
for (let k=0; k<2; k++) { |
|||
C.push(toHex256(MP[j][k])); // MP[0][0] p
|
|||
C.dup(1); // p MP[0][0] p
|
|||
C.mstore(); // p
|
|||
C.push(32); // 32 p
|
|||
C.add(); // p+32
|
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
module.exports.abi = [ |
|||
{ |
|||
"constant": true, |
|||
"inputs": [ |
|||
{ |
|||
"name": "escalar", |
|||
"type": "uint256" |
|||
} |
|||
], |
|||
"name": "mulexp", |
|||
"outputs": [ |
|||
{ |
|||
"name": "", |
|||
"type": "uint256" |
|||
}, |
|||
{ |
|||
"name": "", |
|||
"type": "uint256" |
|||
} |
|||
], |
|||
"payable": false, |
|||
"stateMutability": "pure", |
|||
"type": "function" |
|||
} |
|||
]; |
|||
|
|||
module.exports.createCode = createCode; |
@ -0,0 +1,86 @@ |
|||
const bn128 = require("snarkjs").bn128; |
|||
const bigInt = require("snarkjs").bigInt; |
|||
const Web3Utils = require("web3-utils"); |
|||
const F = bn128.Fr; |
|||
|
|||
const SEED = "mimcsponge"; |
|||
const NROUNDS = 220; |
|||
|
|||
exports.getIV = (seed) => { |
|||
if (typeof seed === "undefined") seed = SEED; |
|||
const c = Web3Utils.keccak256(seed+"_iv"); |
|||
const cn = bigInt(Web3Utils.toBN(c).toString()); |
|||
const iv = cn.mod(F.q); |
|||
return iv; |
|||
}; |
|||
|
|||
exports.getConstants = (seed, nRounds) => { |
|||
if (typeof seed === "undefined") seed = SEED; |
|||
if (typeof nRounds === "undefined") nRounds = NROUNDS; |
|||
const cts = new Array(nRounds); |
|||
let c = Web3Utils.keccak256(SEED); |
|||
for (let i=1; i<nRounds; i++) { |
|||
c = Web3Utils.keccak256(c); |
|||
|
|||
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString())); |
|||
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64); |
|||
cts[i] = bigInt(Web3Utils.toBN(c2).toString()); |
|||
} |
|||
cts[0] = bigInt(0); |
|||
cts[cts.length - 1] = bigInt(0); |
|||
return cts; |
|||
}; |
|||
|
|||
const cts = exports.getConstants(SEED, NROUNDS); |
|||
|
|||
exports.hash = (_xL_in, _xR_in, _k) =>{ |
|||
let xL = bigInt(_xL_in); |
|||
let xR = bigInt(_xR_in); |
|||
const k = bigInt(_k); |
|||
for (let i=0; i<NROUNDS; i++) { |
|||
const c = cts[i]; |
|||
const t = (i==0) ? F.add(xL, k) : F.add(F.add(xL, k), c); |
|||
const xR_tmp = bigInt(xR); |
|||
if (i < (NROUNDS - 1)) { |
|||
xR = xL; |
|||
xL = F.add(xR_tmp, F.exp(t, 5)); |
|||
} else { |
|||
xR = F.add(xR_tmp, F.exp(t, 5)); |
|||
} |
|||
} |
|||
return { |
|||
xL: F.affine(xL), |
|||
xR: F.affine(xR), |
|||
}; |
|||
}; |
|||
|
|||
exports.multiHash = (arr, key, numOutputs) => { |
|||
if (typeof(numOutputs) === "undefined") { |
|||
numOutputs = 1; |
|||
} |
|||
if (typeof(key) === "undefined") { |
|||
key = F.zero; |
|||
} |
|||
|
|||
let R = F.zero; |
|||
let C = F.zero; |
|||
|
|||
for (let i=0; i<arr.length; i++) { |
|||
R = F.add(R, bigInt(arr[i])); |
|||
const S = exports.hash(R, C, key); |
|||
R = S.xL; |
|||
C = S.xR; |
|||
} |
|||
let outputs = [R]; |
|||
for (let i=1; i < numOutputs; i++) { |
|||
const S = exports.hash(R, C, key); |
|||
R = S.xL; |
|||
C = S.xR; |
|||
outputs.push(R); |
|||
} |
|||
if (numOutputs == 1) { |
|||
return F.affine(outputs[0]); |
|||
} else { |
|||
return outputs.map(x => F.affine(x)); |
|||
} |
|||
}; |
@ -0,0 +1,128 @@ |
|||
// Copyright (c) 2018 Jordi Baylina
|
|||
// License: LGPL-3.0+
|
|||
//
|
|||
|
|||
const Web3Utils = require("web3-utils"); |
|||
|
|||
const Contract = require("./evmasm"); |
|||
|
|||
function createCode(seed, n) { |
|||
|
|||
let ci = Web3Utils.keccak256(seed); |
|||
|
|||
const C = new Contract(); |
|||
|
|||
C.push(0x64); |
|||
C.push("0x00"); |
|||
C.push("0x00"); |
|||
C.calldatacopy(); |
|||
C.push("0x0100000000000000000000000000000000000000000000000000000000"); |
|||
C.push("0x00"); |
|||
C.mload(); |
|||
C.div(); |
|||
C.push("0x3f1a1187"); // MiMCSponge(uint256,uint256,uint256)
|
|||
C.eq(); |
|||
C.jmpi("start"); |
|||
C.invalid(); |
|||
|
|||
C.label("start"); |
|||
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
|||
C.push("0x44"); |
|||
C.mload(); // k q
|
|||
C.push("0x04"); |
|||
C.mload(); // xL k q
|
|||
C.dup(2); // q xL k q
|
|||
C.push("0x24"); |
|||
C.mload(); // xR q xL k q
|
|||
C.dup(1); // q xR q xL k q
|
|||
C.dup(0); // q q xR q xL k q
|
|||
C.dup(4); // xL q q xR q xL k q
|
|||
C.dup(6); // k xL q q xR q xL k q
|
|||
C.addmod(); // t=k+xL q xR q xL k q
|
|||
C.dup(1); // q t q xR q xL k q
|
|||
C.dup(0); // q q t q xR q xL k q
|
|||
C.dup(2); // t q q t q xR q xL k q
|
|||
C.dup(0); // t t q q t q xR q xL k q
|
|||
C.mulmod(); // b=t^2 q t q xR q xL k q
|
|||
C.dup(0); // b b q t q xR q xL k q
|
|||
C.mulmod(); // c=t^4 t q xR q xL k q
|
|||
C.mulmod(); // d=t^5 xR q xL k q
|
|||
C.addmod(); // e=t^5+xR xL k q (for next round: xL xR k q)
|
|||
|
|||
for (let i=0; i<n-1; i++) { |
|||
if (i < n-2) { |
|||
ci = Web3Utils.keccak256(ci); |
|||
} else { |
|||
ci = "0x00"; |
|||
} |
|||
C.swap(1); // xR xL k q
|
|||
C.dup(3); // q xR xL k q
|
|||
C.dup(3); // k q xR xL k q
|
|||
C.dup(1); // q k q xR xL k q
|
|||
C.dup(4); // xL q k q xR xL k q
|
|||
C.push(ci); // ci xL q k q xR xL k q
|
|||
C.addmod(); // a=ci+xL k q xR xL k q
|
|||
C.addmod(); // t=a+k xR xL k q
|
|||
C.dup(4); // q t xR xL k q
|
|||
C.swap(1); // t q xR xL k q
|
|||
C.dup(1); // q t q xR xL k q
|
|||
C.dup(0); // q q t q xR xL k q
|
|||
C.dup(2); // t q q t q xR xL k q
|
|||
C.dup(0); // t t q q t q xR xL k q
|
|||
C.mulmod(); // b=t^2 q t q xR xL k q
|
|||
C.dup(0); // b b q t q xR xL k q
|
|||
C.mulmod(); // c=t^4 t q xR xL k q
|
|||
C.mulmod(); // d=t^5 xR xL k q
|
|||
C.dup(4); // q d xR xL k q
|
|||
C.swap(2); // xR d q xL k q
|
|||
C.addmod(); // e=t^5+xR xL k q (for next round: xL xR k q)
|
|||
} |
|||
|
|||
C.push("0x20"); |
|||
C.mstore(); // Save it to pos 0;
|
|||
C.push("0x00"); |
|||
C.mstore(); // Save it to pos 1;
|
|||
C.push("0x40"); |
|||
C.push("0x00"); |
|||
C.return(); |
|||
|
|||
return C.createTxData(); |
|||
} |
|||
|
|||
module.exports.abi = [ |
|||
{ |
|||
"constant": true, |
|||
"inputs": [ |
|||
{ |
|||
"name": "xL_in", |
|||
"type": "uint256" |
|||
}, |
|||
{ |
|||
"name": "xR_in", |
|||
"type": "uint256" |
|||
}, |
|||
{ |
|||
"name": "k", |
|||
"type": "uint256" |
|||
} |
|||
], |
|||
"name": "MiMCSponge", |
|||
"outputs": [ |
|||
{ |
|||
"name": "xL", |
|||
"type": "uint256" |
|||
}, |
|||
{ |
|||
"name": "xR", |
|||
"type": "uint256" |
|||
} |
|||
], |
|||
"payable": false, |
|||
"stateMutability": "pure", |
|||
"type": "function" |
|||
} |
|||
]; |
|||
|
|||
module.exports.createCode = createCode; |
|||
|
|||
|
@ -0,0 +1,13 @@ |
|||
const mimcsponge = require("./mimcsponge.js"); |
|||
|
|||
const nRounds = 220; |
|||
let S = "[\n"; |
|||
const cts = mimcsponge.getConstants(); |
|||
for (let i=0; i<nRounds; i++) { |
|||
S = S + cts[i].toString(); |
|||
if (i<nRounds-1) S = S + ","; |
|||
S=S+"\n"; |
|||
} |
|||
S = S + "]\n"; |
|||
|
|||
console.log(S); |
@ -0,0 +1,13 @@ |
|||
const mimcGenContract = require("./mimcsponge_gencontract"); |
|||
|
|||
const SEED = "mimcsponge"; |
|||
|
|||
let nRounds; |
|||
if (typeof process.argv[2] != "undefined") { |
|||
nRounds = parseInt(process.argv[2]); |
|||
} else { |
|||
nRounds = 220; |
|||
} |
|||
|
|||
console.log(mimcGenContract.createCode(SEED, nRounds)); |
|||
|
@ -0,0 +1,116 @@ |
|||
const bn128 = require("snarkjs").bn128; |
|||
const bigInt = require("snarkjs").bigInt; |
|||
const blake2b = require('blake2b'); |
|||
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 input = Buffer.from(seed); |
|||
let h = blake2b(32).update(input).digest() |
|||
while (res.length<n) { |
|||
const n = F.affine(bigInt.leBuff2int(h)); |
|||
res.push(n); |
|||
h = blake2b(32).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,10 @@ |
|||
const mimc7 = require("./mimc7"); |
|||
const bigInt = require("snarkjs").bigInt; |
|||
|
|||
exports.hash0 = function (left, right) { |
|||
return mimc7.multiHash(left, right); |
|||
}; |
|||
|
|||
exports.hash1 = function(key, value) { |
|||
return mimc7.multiHash([key, value], bigInt.one); |
|||
}; |
@ -0,0 +1,12 @@ |
|||
const Poseidon = require("./poseidon"); |
|||
const bigInt = require("snarkjs").bigInt; |
|||
|
|||
const hash = Poseidon.createHash(6, 8, 57); |
|||
|
|||
exports.hash0 = function (left, right) { |
|||
return hash([left, right]); |
|||
}; |
|||
|
|||
exports.hash1 = function(key, value) { |
|||
return hash([key, value, bigInt.one]); |
|||
}; |
@ -0,0 +1,3 @@ |
|||
include "../../circuits/babyjub.circom"; |
|||
|
|||
component main = BabyPbk(); |
@ -0,0 +1,3 @@ |
|||
include "../../circuits/eddsaposeidon.circom"; |
|||
|
|||
component main = EdDSAPoseidonVerifier(); |
@ -0,0 +1,4 @@ |
|||
|
|||
include "../../circuits/comparators.circom"; |
|||
|
|||
component main = GreaterEqThan(32); |
@ -0,0 +1,4 @@ |
|||
|
|||
include "../../circuits/comparators.circom"; |
|||
|
|||
component main = GreaterThan(32); |
@ -0,0 +1,4 @@ |
|||
|
|||
include "../../circuits/comparators.circom"; |
|||
|
|||
component main = LessEqThan(32); |
@ -0,0 +1,3 @@ |
|||
include "../../circuits/mimcsponge.circom" |
|||
|
|||
component main = MiMCSponge(2, 220, 3); |
@ -0,0 +1,3 @@ |
|||
include "../../circuits/mimcsponge.circom" |
|||
|
|||
component main = MiMCFeistel(220); |
@ -0,0 +1,31 @@ |
|||
include "../../circuits/mux1.circom"; |
|||
include "../../circuits/bitify.circom"; |
|||
|
|||
|
|||
template Constants() { |
|||
var i; |
|||
signal output out[2]; |
|||
|
|||
out[0] <== 37; |
|||
out[1] <== 47; |
|||
} |
|||
|
|||
template Main() { |
|||
var i; |
|||
signal private input selector; |
|||
signal output out; |
|||
|
|||
component mux = Mux1(); |
|||
component n2b = Num2Bits(1); |
|||
component cst = Constants(); |
|||
|
|||
selector ==> n2b.in; |
|||
n2b.out[0] ==> mux.s; |
|||
for (i=0; i<2; i++) { |
|||
cst.out[i] ==> mux.c[i]; |
|||
} |
|||
|
|||
mux.out ==> out; |
|||
} |
|||
|
|||
component main = Main(); |
@ -0,0 +1,35 @@ |
|||
include "../../circuits/mux2.circom"; |
|||
include "../../circuits/bitify.circom"; |
|||
|
|||
|
|||
template Constants() { |
|||
var i; |
|||
signal output out[4]; |
|||
|
|||
out[0] <== 37; |
|||
out[1] <== 47; |
|||
out[2] <== 53; |
|||
out[3] <== 71; |
|||
} |
|||
|
|||
template Main() { |
|||
var i; |
|||
signal private input selector; |
|||
signal output out; |
|||
|
|||
component mux = Mux2(); |
|||
component n2b = Num2Bits(2); |
|||
component cst = Constants(); |
|||
|
|||
selector ==> n2b.in; |
|||
for (i=0; i<2; i++) { |
|||
n2b.out[i] ==> mux.s[i]; |
|||
} |
|||
for (i=0; i<4; i++) { |
|||
cst.out[i] ==> mux.c[i]; |
|||
} |
|||
|
|||
mux.out ==> out; |
|||
} |
|||
|
|||
component main = Main(); |
@ -0,0 +1,3 @@ |
|||
include "../../circuits/poseidon.circom" |
|||
|
|||
component main = Poseidon(2, 6, 8, 57); |
@ -0,0 +1,98 @@ |
|||
const chai = require("chai"); |
|||
const path = require("path"); |
|||
const snarkjs = require("snarkjs"); |
|||
const compiler = require("circom"); |
|||
|
|||
const eddsa = require("../src/eddsa.js"); |
|||
|
|||
const assert = chai.assert; |
|||
|
|||
const bigInt = snarkjs.bigInt; |
|||
|
|||
describe("EdDSA Poseidon test", function () { |
|||
let circuit; |
|||
|
|||
this.timeout(100000); |
|||
|
|||
before( async () => { |
|||
const cirDef = await compiler(path.join(__dirname, "circuits", "eddsaposeidon_test.circom")); |
|||
|
|||
circuit = new snarkjs.Circuit(cirDef); |
|||
|
|||
console.log("NConstrains EdDSA Poseidon: " + circuit.nConstraints); |
|||
}); |
|||
|
|||
it("Sign a single number", async () => { |
|||
const msg = bigInt(1234); |
|||
|
|||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); |
|||
|
|||
const pubKey = eddsa.prv2pub(prvKey); |
|||
|
|||
const signature = eddsa.signPoseidon(prvKey, msg); |
|||
|
|||
assert(eddsa.verifyPoseidon(msg, signature, pubKey)); |
|||
|
|||
const w = circuit.calculateWitness({ |
|||
enabled: 1, |
|||
Ax: pubKey[0], |
|||
Ay: pubKey[1], |
|||
R8x: signature.R8[0], |
|||
R8y: signature.R8[1], |
|||
S: signature.S, |
|||
M: msg}); |
|||
|
|||
assert(circuit.checkWitness(w)); |
|||
}); |
|||
|
|||
it("Detect Invalid signature", async () => { |
|||
const msg = bigInt(1234); |
|||
|
|||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); |
|||
|
|||
const pubKey = eddsa.prv2pub(prvKey); |
|||
|
|||
|
|||
const signature = eddsa.signPoseidon(prvKey, msg); |
|||
|
|||
assert(eddsa.verifyPoseidon(msg, signature, pubKey)); |
|||
try { |
|||
circuit.calculateWitness({ |
|||
enabled: 1, |
|||
Ax: pubKey[0], |
|||
Ay: pubKey[1], |
|||
R8x: signature.R8[0].add(bigInt(1)), |
|||
R8y: signature.R8[1], |
|||
S: signature.S, |
|||
M: msg}); |
|||
assert(false); |
|||
} catch(err) { |
|||
assert.equal(err.message, "Constraint doesn't match: 1 != 0"); |
|||
} |
|||
}); |
|||
|
|||
|
|||
it("Test a dissabled circuit with a bad signature", async () => { |
|||
const msg = bigInt(1234); |
|||
|
|||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex"); |
|||
|
|||
const pubKey = eddsa.prv2pub(prvKey); |
|||
|
|||
|
|||
const signature = eddsa.signPoseidon(prvKey, msg); |
|||
|
|||
assert(eddsa.verifyPoseidon(msg, signature, pubKey)); |
|||
|
|||
const w = circuit.calculateWitness({ |
|||
enabled: 0, |
|||
Ax: pubKey[0], |
|||
Ay: pubKey[1], |
|||
R8x: signature.R8[0].add(bigInt(1)), |
|||
R8y: signature.R8[1], |
|||
S: signature.S, |
|||
M: msg}); |
|||
|
|||
assert(circuit.checkWitness(w)); |
|||
}); |
|||
}); |
@ -0,0 +1,58 @@ |
|||
const chai = require("chai"); |
|||
const path = require("path"); |
|||
const snarkjs = require("snarkjs"); |
|||
const compiler = require("circom"); |
|||
|
|||
const mimcjs = require("../src/mimcsponge.js"); |
|||
|
|||
const assert = chai.assert; |
|||
|
|||
describe("MiMC Sponge Circuit test", function () { |
|||
let circuit; |
|||
|
|||
this.timeout(100000); |
|||
|
|||
it("Should check permutation", async () => { |
|||
const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_sponge_test.circom")); |
|||
|
|||
circuit = new snarkjs.Circuit(cirDef); |
|||
|
|||
console.log("MiMC Feistel constraints: " + circuit.nConstraints); |
|||
|
|||
const w = circuit.calculateWitness({xL_in: 1, xR_in: 2, k: 3}); |
|||
|
|||
const xLout = w[circuit.getSignalIdx("main.xL_out")]; |
|||
const xRout = w[circuit.getSignalIdx("main.xR_out")]; |
|||
|
|||
const out2 = mimcjs.hash(1,2,3); |
|||
|
|||
assert.equal(xLout.toString(), out2.xL.toString()); |
|||
assert.equal(xRout.toString(), out2.xR.toString()); |
|||
|
|||
assert(circuit.checkWitness(w)); |
|||
|
|||
}); |
|||
|
|||
it("Should check hash", async () => { |
|||
const cirDef = await compiler(path.join(__dirname, "circuits", "mimc_sponge_hash_test.circom")); |
|||
|
|||
circuit = new snarkjs.Circuit(cirDef); |
|||
|
|||
console.log("MiMC Sponge constraints: " + circuit.nConstraints); |
|||
|
|||
const w = circuit.calculateWitness({ins: [1, 2], k: 0}); |
|||
|
|||
const o1 = w[circuit.getSignalIdx("main.outs[0]")]; |
|||
const o2 = w[circuit.getSignalIdx("main.outs[1]")]; |
|||
const o3 = w[circuit.getSignalIdx("main.outs[2]")]; |
|||
|
|||
const out2 = mimcjs.multiHash([1,2], 0, 3); |
|||
|
|||
assert.equal(o1.toString(), out2[0].toString()); |
|||
assert.equal(o2.toString(), out2[1].toString()); |
|||
assert.equal(o3.toString(), out2[2].toString()); |
|||
|
|||
assert(circuit.checkWitness(w)); |
|||
|
|||
}); |
|||
}); |
@ -0,0 +1,43 @@ |
|||
const ganache = require("ganache-cli"); |
|||
const Web3 = require("web3"); |
|||
const chai = require("chai"); |
|||
const mimcGenContract = require("../src/mimcsponge_gencontract.js"); |
|||
const mimcjs = require("../src/mimcsponge.js"); |
|||
|
|||
|
|||
const assert = chai.assert; |
|||
const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); }; |
|||
|
|||
const SEED = "mimcsponge"; |
|||
|
|||
describe("MiMC Sponge Smart contract test", () => { |
|||
let testrpc; |
|||
let web3; |
|||
let mimc; |
|||
let accounts; |
|||
|
|||
before(async () => { |
|||
web3 = new Web3(ganache.provider(), null, { transactionConfirmationBlocks: 1 }); |
|||
accounts = await web3.eth.getAccounts(); |
|||
}); |
|||
|
|||
it("Should deploy the contract", async () => { |
|||
const C = new web3.eth.Contract(mimcGenContract.abi); |
|||
|
|||
mimc = await C.deploy({ |
|||
data: mimcGenContract.createCode(SEED, 220) |
|||
}).send({ |
|||
gas: 3500000, |
|||
from: accounts[0] |
|||
}); |
|||
}); |
|||
|
|||
it("Shold calculate the mimc correctly", async () => { |
|||
const res = await mimc.methods.MiMCSponge(1,2,3).call(); |
|||
const res2 = await mimcjs.hash(1,2,3); |
|||
|
|||
assert.equal(res.xL.toString(), res2.xL.toString()); |
|||
assert.equal(res.xR.toString(), res2.xR.toString()); |
|||
}); |
|||
}); |
|||
|
@ -0,0 +1,60 @@ |
|||
const chai = require("chai"); |
|||
const path = require("path"); |
|||
const snarkjs = require("snarkjs"); |
|||
const compiler = require("circom"); |
|||
var blake2b = require('blake2b'); |
|||
|
|||
const poseidon = require("../src/poseidon.js"); |
|||
|
|||
const assert = chai.assert; |
|||
|
|||
describe("Blake2b version test", function() { |
|||
it("Should give the expected output for blake2b version", async () => { |
|||
var output = new Uint8Array(32); |
|||
var input = Buffer.from('poseidon_constants'); |
|||
h = blake2b(output.length).update(input).digest('hex') |
|||
assert.equal('e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1', h); |
|||
}); |
|||
}); |
|||
|
|||
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 of hash([1, 2])", 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]); |
|||
assert.equal('12242166908188651009877250812424843524687801523336557272219921456462821518061', res2.toString()); |
|||
assert.equal(res.toString(), res2.toString()); |
|||
assert(circuit.checkWitness(w)); |
|||
}); |
|||
|
|||
it("Should check constrain of hash([3, 4])", async () => { |
|||
const w = circuit.calculateWitness({inputs: [3, 4]}); |
|||
|
|||
const res = w[circuit.getSignalIdx("main.out")]; |
|||
|
|||
const hash = poseidon.createHash(6, 8, 57); |
|||
|
|||
const res2 = hash([3, 4]); |
|||
assert.equal('17185195740979599334254027721507328033796809509313949281114643312710535000993', res2.toString()); |
|||
|
|||
assert.equal(res.toString(), res2.toString()); |
|||
|
|||
assert(circuit.checkWitness(w)); |
|||
}); |
|||
}); |
@ -0,0 +1,49 @@ |
|||
const ganache = 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 () => { |
|||
web3 = new Web3(ganache.provider(), null, { transactionConfirmationBlocks: 1 }); |
|||
accounts = await web3.eth.getAccounts(); |
|||
}); |
|||
|
|||
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()); |
|||
}); |
|||
}); |
|||
|