Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6bcbf3370e | ||
|
|
9d876a1b32 | ||
|
|
d422471b5b | ||
|
|
01da5f90db | ||
|
|
fabc586fea | ||
|
|
7e93b3fcf8 | ||
|
|
3f4734d4dd | ||
|
|
1cd3d203c5 | ||
|
|
01e3f0d680 | ||
|
|
86c6a2a6f5 | ||
|
|
5269afee0a | ||
|
|
48c721c8af | ||
|
|
0efecf16fa | ||
|
|
7705fe8339 |
@@ -49,7 +49,7 @@ Folder containing the circuit implementation of Sparse Merkle Trees.
|
|||||||
- OUTPUT
|
- OUTPUT
|
||||||
- BENCHMARKS
|
- BENCHMARKS
|
||||||
- EXAMPLE
|
- EXAMPLE
|
||||||
|
|
||||||
### babyjub
|
### babyjub
|
||||||
|
|
||||||
Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby_jubjub) in twisted Edwards form. (TODO: Expose here the characteristics of the curve?)
|
Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby_jubjub) in twisted Edwards form. (TODO: Expose here the characteristics of the curve?)
|
||||||
@@ -58,22 +58,22 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
- `BabyAdd()`
|
- `BabyAdd()`
|
||||||
|
|
||||||
- DESCRIPTION
|
- DESCRIPTION
|
||||||
|
|
||||||
It adds two points on the Baby Jubjub curve. More specifically, given two points P1 = (`x1`, `y1`) and P2 = (`x2`, `y2`) it returns a point P3 = (`xout`, `yout`) such that
|
It adds two points on the Baby Jubjub curve. More specifically, given two points P1 = (`x1`, `y1`) and P2 = (`x2`, `y2`) it returns a point P3 = (`xout`, `yout`) such that
|
||||||
|
|
||||||
(`xout`, `yout`) = (`x1`,`y1`) + (`x2`,`y2`)
|
(`xout`, `yout`) = (`x1`,`y1`) + (`x2`,`y2`)
|
||||||
= ((`x1y2`+`y1x2`)/(1+`dx1x2y1y2`)),(`y1y2`-`ax1x2`)/(1-`dx1x2y1y2`))
|
= ((`x1y2`+`y1x2`)/(1+`dx1x2y1y2`)),(`y1y2`-`ax1x2`)/(1-`dx1x2y1y2`))
|
||||||
|
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
```
|
```
|
||||||
var a var d
|
var a var d
|
||||||
| |
|
| |
|
||||||
| |
|
| |
|
||||||
______v_________v_______
|
______v_________v_______
|
||||||
input x1 ----> | |
|
input x1 ----> | |
|
||||||
input y1 ----> | BabyAdd() | ----> output xout
|
input y1 ----> | BabyAdd() | ----> output xout
|
||||||
input x2 ----> | | ----> output yout
|
input x2 ----> | | ----> output yout
|
||||||
input y2 ----> |________________________|
|
input y2 ----> |________________________|
|
||||||
```
|
```
|
||||||
|
|
||||||
- INPUTS
|
- INPUTS
|
||||||
@@ -84,16 +84,16 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
| `y1` | Bigint | Field element of Fp | Second coordinate of a point (x1, y1) on E. |
|
| `y1` | Bigint | Field element of Fp | Second coordinate of a point (x1, y1) on E. |
|
||||||
| `x2` | Bigint | Field element of Fp | First coordinate of a point (x2, y2) on E. |
|
| `x2` | Bigint | Field element of Fp | First coordinate of a point (x2, y2) on E. |
|
||||||
| `y2` | Bigint | Field element of Fp | Second coordinate of a point (x2, y2) on E. |
|
| `y2` | Bigint | Field element of Fp | Second coordinate of a point (x2, y2) on E. |
|
||||||
|
|
||||||
Requirement: at least `x1`!=`x2` or `y1`!=`y2`.
|
Requirement: at least `x1`!=`x2` or `y1`!=`y2`.
|
||||||
|
|
||||||
- OUTPUT
|
- OUTPUT
|
||||||
|
|
||||||
| Input | Representation | Description | |
|
| Input | Representation | Description | |
|
||||||
| ------------- | ------------- | ------------- | ------------- |
|
| ------------- | ------------- | ------------- | ------------- |
|
||||||
| `xout` | Bigint | Field element of Fp | First coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). |
|
| `xout` | Bigint | Field element of Fp | First coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). |
|
||||||
| `yout` | Bigint | Field element of Fp | Second coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). |
|
| `yout` | Bigint | Field element of Fp | Second coordinate of the addition point (xout, yout) = (x1, y1) + (x2, y2). |
|
||||||
|
|
||||||
- BENCHMARKS (constraints)
|
- BENCHMARKS (constraints)
|
||||||
|
|
||||||
- EXAMPLE
|
- EXAMPLE
|
||||||
@@ -108,7 +108,7 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
|
|
||||||
- `BabyCheck()`
|
- `BabyCheck()`
|
||||||
|
|
||||||
- DESCRIPTION : checks if a given point is in the curve.
|
- DESCRIPTION : checks if a given point is in the curve.
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
- INPUT
|
- INPUT
|
||||||
- OUTPUT
|
- OUTPUT
|
||||||
@@ -127,7 +127,7 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
|
|
||||||
### binsub
|
### binsub
|
||||||
|
|
||||||
- `BinSub(n)`
|
- `BinSub(n)`
|
||||||
|
|
||||||
- DESCRIPTION: binary substraction.
|
- DESCRIPTION: binary substraction.
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
@@ -140,7 +140,7 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
|
|
||||||
- `nbits(a)`
|
- `nbits(a)`
|
||||||
|
|
||||||
- DESCRIPTION : binary sum.
|
- DESCRIPTION : binary sum.
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
- INPUT
|
- INPUT
|
||||||
- OUTPUT
|
- OUTPUT
|
||||||
@@ -149,7 +149,7 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
|
|
||||||
- `BinSum(n, ops)`
|
- `BinSum(n, ops)`
|
||||||
|
|
||||||
- DESCRIPTION
|
- DESCRIPTION
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
- INPUT
|
- INPUT
|
||||||
- OUTPUT
|
- OUTPUT
|
||||||
@@ -169,7 +169,7 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
|
|
||||||
- `Num2Bits_strict()`
|
- `Num2Bits_strict()`
|
||||||
|
|
||||||
- DESCRIPTION
|
- DESCRIPTION
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
- INPUT
|
- INPUT
|
||||||
- OUTPUT
|
- OUTPUT
|
||||||
@@ -259,7 +259,7 @@ Arithmetic on [Baby Jubjub elliptic curve](https://github.com/barryWhiteHat/baby
|
|||||||
- BENCHMARKS
|
- BENCHMARKS
|
||||||
- EXAMPLE
|
- EXAMPLE
|
||||||
|
|
||||||
### compconstant
|
### compconstant
|
||||||
|
|
||||||
- `CompConstant(ct)`
|
- `CompConstant(ct)`
|
||||||
|
|
||||||
@@ -688,7 +688,7 @@ Implementation of MiMC-7 hash in Fp being... (link to description of the hash)
|
|||||||
|
|
||||||
### pedersen_old
|
### pedersen_old
|
||||||
|
|
||||||
Old version of the Pedersen hash (do not use any
|
Old version of the Pedersen hash (do not use any
|
||||||
more?).
|
more?).
|
||||||
|
|
||||||
### pedersen
|
### pedersen
|
||||||
@@ -720,7 +720,7 @@ more?).
|
|||||||
- BENCHMARKS
|
- BENCHMARKS
|
||||||
- EXAMPLE
|
- EXAMPLE
|
||||||
|
|
||||||
### pointbits
|
### pointbits
|
||||||
|
|
||||||
- `sqrt(n)`
|
- `sqrt(n)`
|
||||||
|
|
||||||
@@ -780,7 +780,7 @@ Implementation of Poseidon hash function (LINK)
|
|||||||
- BENCHMARKS
|
- BENCHMARKS
|
||||||
- EXAMPLE
|
- EXAMPLE
|
||||||
|
|
||||||
- `Ark(t, C)`
|
- `Ark(t, C, r)`
|
||||||
|
|
||||||
- DESCRIPTION
|
- DESCRIPTION
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
@@ -798,7 +798,7 @@ Implementation of Poseidon hash function (LINK)
|
|||||||
- BENCHMARKS
|
- BENCHMARKS
|
||||||
- EXAMPLE
|
- EXAMPLE
|
||||||
|
|
||||||
- `Poseidon(nInputs, t, nRoundsF, nRoundsP)`
|
- `Poseidon(nInputs)`
|
||||||
|
|
||||||
- DESCRIPTION
|
- DESCRIPTION
|
||||||
- SCHEMA
|
- SCHEMA
|
||||||
|
|||||||
@@ -86,10 +86,11 @@ template LessThan(n) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
template LessThan(n) {
|
template LessThan(n) {
|
||||||
|
assert(n <= 252);
|
||||||
signal input in[2];
|
signal input in[2];
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
component n2b = Num2Bits(n*2+1);
|
component n2b = Num2Bits(n+1);
|
||||||
|
|
||||||
n2b.in <== in[0]+ (1<<n) - in[1];
|
n2b.in <== in[0]+ (1<<n) - in[1];
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ template EdDSAPoseidonVerifier() {
|
|||||||
|
|
||||||
// Calculate the h = H(R,A, msg)
|
// Calculate the h = H(R,A, msg)
|
||||||
|
|
||||||
component hash = Poseidon(5, 6, 8, 57);
|
component hash = Poseidon(5);
|
||||||
|
|
||||||
hash.inputs[0] <== R8x;
|
hash.inputs[0] <== R8x;
|
||||||
hash.inputs[1] <== R8y;
|
hash.inputs[1] <== R8y;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
include "./poseidon_constants.circom";
|
||||||
|
|
||||||
template Sigma() {
|
template Sigma() {
|
||||||
signal input in;
|
signal input in;
|
||||||
@@ -12,169 +13,53 @@ template Sigma() {
|
|||||||
out <== in4*in;
|
out <== in4*in;
|
||||||
}
|
}
|
||||||
|
|
||||||
template Ark(t, C) {
|
template Ark(t, C, r) {
|
||||||
signal input in[t];
|
signal input in[t];
|
||||||
signal output out[t];
|
signal output out[t];
|
||||||
|
|
||||||
for (var i=0; i<t; i++) {
|
for (var i=0; i<t; i++) {
|
||||||
out[i] <== in[i] + C;
|
out[i] <== in[i] + C[i + r];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template Mix(t, M) {
|
template Mix(t, M) {
|
||||||
signal input in[t];
|
signal input in[t];
|
||||||
signal output out[t];
|
signal output out[t];
|
||||||
|
|
||||||
var lc;
|
var lc;
|
||||||
|
for (var i=0; i<t; i++) {
|
||||||
var i;
|
|
||||||
var j;
|
|
||||||
|
|
||||||
for (i=0; i<t; i++) {
|
|
||||||
lc = 0;
|
lc = 0;
|
||||||
for (j=0; j<t; j++) {
|
for (var j=0; j<t; j++) {
|
||||||
lc = lc + M[i][j]*in[j];
|
lc += M[j][i]*in[j];
|
||||||
}
|
}
|
||||||
out[i] <== lc;
|
out[i] <== lc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// var nRoundsF = 8;
|
template Poseidon(nInputs) {
|
||||||
// var nRoundsP = 57;
|
|
||||||
// var t = 6;
|
|
||||||
|
|
||||||
template Poseidon(nInputs, t, nRoundsF, nRoundsP) {
|
|
||||||
|
|
||||||
var C[65] = [
|
|
||||||
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[6][6] = [
|
|
||||||
[
|
|
||||||
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 input inputs[nInputs];
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
component ark[nRoundsF + nRoundsP];
|
// Using recommended parameters from whitepaper https://eprint.iacr.org/2019/458.pdf (table 2, table 8)
|
||||||
component sigmaF[nRoundsF][t];
|
// Generated by https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/calc_round_numbers.py
|
||||||
component sigmaP[nRoundsP];
|
// And rounded up to nearest integer that divides by t
|
||||||
component mix[nRoundsF + nRoundsP];
|
var N_ROUNDS_P[8] = [56, 57, 56, 60, 60, 63, 64, 63];
|
||||||
|
var t = nInputs + 1;
|
||||||
|
var nRoundsF = 8;
|
||||||
|
var nRoundsP = N_ROUNDS_P[t - 2];
|
||||||
|
var C[t*(nRoundsF + nRoundsP)] = POSEIDON_C(t);
|
||||||
|
var M[t][t] = POSEIDON_M(t);
|
||||||
|
|
||||||
|
component ark[nRoundsF + nRoundsP - 1];
|
||||||
|
component sigmaF[nRoundsF - 1][t];
|
||||||
|
component sigmaP[nRoundsP];
|
||||||
|
component mix[nRoundsF + nRoundsP - 1];
|
||||||
|
|
||||||
var i;
|
|
||||||
var j;
|
|
||||||
var k;
|
var k;
|
||||||
|
|
||||||
for (i=0; i<(nRoundsF + nRoundsP); i++) {
|
for (var i=0; i<nRoundsF + nRoundsP - 1; i++) {
|
||||||
ark[i] = Ark(t, C[i]);
|
ark[i] = Ark(t, C, t*i);
|
||||||
mix[i] = Mix(t, M);
|
for (var j=0; j<t; j++) {
|
||||||
|
|
||||||
for (j=0; j<t; j++) {
|
|
||||||
if (i==0) {
|
if (i==0) {
|
||||||
if (j<nInputs) {
|
if (j<nInputs) {
|
||||||
ark[i].in[j] <== inputs[j];
|
ark[i].in[j] <== inputs[j];
|
||||||
@@ -186,23 +71,28 @@ template Poseidon(nInputs, t, nRoundsF, nRoundsP) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((i<(nRoundsF/2)) || (i>= (nRoundsP + nRoundsF/2))) {
|
if (i < nRoundsF/2 || i >= nRoundsP + nRoundsF/2) {
|
||||||
k= i<nRoundsF/2 ? i : (i-nRoundsP);
|
k = i < nRoundsF/2 ? i : i - nRoundsP;
|
||||||
for (j=0; j<t; j++) {
|
mix[i] = Mix(t, M);
|
||||||
|
for (var j=0; j<t; j++) {
|
||||||
sigmaF[k][j] = Sigma();
|
sigmaF[k][j] = Sigma();
|
||||||
sigmaF[k][j].in <== ark[i].out[j];
|
sigmaF[k][j].in <== ark[i].out[j];
|
||||||
mix[i].in[j] <== sigmaF[k][j].out;
|
mix[i].in[j] <== sigmaF[k][j].out;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
k= i-nRoundsF/2;
|
k = i - nRoundsF/2;
|
||||||
|
mix[i] = Mix(t, M);
|
||||||
sigmaP[k] = Sigma();
|
sigmaP[k] = Sigma();
|
||||||
sigmaP[k].in <== ark[i].out[0];
|
sigmaP[k].in <== ark[i].out[0];
|
||||||
mix[i].in[0] <== sigmaP[k].out;
|
mix[i].in[0] <== sigmaP[k].out;
|
||||||
for (j=1; j<t; j++) {
|
for (var j=1; j<t; j++) {
|
||||||
mix[i].in[j] <== ark[i].out[j];
|
mix[i].in[j] <== ark[i].out[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out <== mix[nRoundsF + nRoundsP -1].out[0];
|
// last round is done only for the first word, so we do it manually to save constraints
|
||||||
|
component lastSigmaF = Sigma();
|
||||||
|
lastSigmaF.in <== mix[nRoundsF + nRoundsP - 2].out[0] + C[t*(nRoundsF + nRoundsP - 1)];
|
||||||
|
out <== lastSigmaF.out;
|
||||||
}
|
}
|
||||||
|
|||||||
94
circuits/poseidon_constants.circom
Normal file
94
circuits/poseidon_constants.circom
Normal file
File diff suppressed because one or more lines are too long
@@ -29,7 +29,7 @@ template SMTHash1() {
|
|||||||
signal input value;
|
signal input value;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
component h = Poseidon(3, 6, 8, 57); // Constant
|
component h = Poseidon(3); // Constant
|
||||||
h.inputs[0] <== key;
|
h.inputs[0] <== key;
|
||||||
h.inputs[1] <== value;
|
h.inputs[1] <== value;
|
||||||
h.inputs[2] <== 1;
|
h.inputs[2] <== 1;
|
||||||
@@ -48,7 +48,7 @@ template SMTHash2() {
|
|||||||
signal input R;
|
signal input R;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
component h = Poseidon(2, 6, 8, 57); // Constant
|
component h = Poseidon(2); // Constant
|
||||||
h.inputs[0] <== L;
|
h.inputs[0] <== L;
|
||||||
h.inputs[1] <== R;
|
h.inputs[1] <== R;
|
||||||
|
|
||||||
|
|||||||
2198
package-lock.json
generated
2198
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "circomlib",
|
"name": "circomlib",
|
||||||
"version": "0.2.1",
|
"version": "0.2.4",
|
||||||
"description": "Basic circuits library for Circom",
|
"description": "Basic circuits library for Circom",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@@ -26,13 +26,13 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"blake-hash": "^1.1.0",
|
"blake-hash": "^1.1.0",
|
||||||
"blake2b": "^2.1.3",
|
"blake2b": "^2.1.3",
|
||||||
"circom": "0.5.8",
|
"circom": "0.5.21",
|
||||||
"ffjavascript": "0.1.0",
|
"ffjavascript": "0.1.0"
|
||||||
"web3": "^1.2.6"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^6.8.0",
|
||||||
"ganache-cli": "^6.9.1",
|
"ganache-cli": "^6.10.1",
|
||||||
"mocha": "^7.1.1"
|
"mocha": "^7.1.1",
|
||||||
|
"web3": "^1.2.11"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,8 +112,7 @@ function signPoseidon(prv, msg) {
|
|||||||
const Fr = new F1Field(babyJub.subOrder);
|
const Fr = new F1Field(babyJub.subOrder);
|
||||||
r = Fr.e(r);
|
r = Fr.e(r);
|
||||||
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
const R8 = babyJub.mulPointEscalar(babyJub.Base8, r);
|
||||||
const hash = poseidon.createHash(6, 8, 57);
|
const hm = poseidon([R8[0], R8[1], A[0], A[1], msg]);
|
||||||
const hm = hash([R8[0], R8[1], A[0], A[1], msg]);
|
|
||||||
const S = Fr.add(r , Fr.mul(hm, s));
|
const S = Fr.add(r , Fr.mul(hm, s));
|
||||||
return {
|
return {
|
||||||
R8: R8,
|
R8: R8,
|
||||||
@@ -180,8 +179,7 @@ function verifyPoseidon(msg, sig, A) {
|
|||||||
if (!babyJub.inCurve(A)) return false;
|
if (!babyJub.inCurve(A)) return false;
|
||||||
if (sig.S>= babyJub.subOrder) return false;
|
if (sig.S>= babyJub.subOrder) return false;
|
||||||
|
|
||||||
const hash = poseidon.createHash(6, 8, 57);
|
const hm = poseidon([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
||||||
const hm = hash([sig.R8[0], sig.R8[1], A[0], A[1], msg]);
|
|
||||||
|
|
||||||
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
const Pleft = babyJub.mulPointEscalar(babyJub.Base8, sig.S);
|
||||||
let Pright = babyJub.mulPointEscalar(A, Scalar.mul(hm, 8));
|
let Pright = babyJub.mulPointEscalar(A, Scalar.mul(hm, 8));
|
||||||
|
|||||||
@@ -154,6 +154,17 @@ class Contract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
push(data) {
|
push(data) {
|
||||||
|
if (typeof data === "number") {
|
||||||
|
let isNeg;
|
||||||
|
if (data<0) {
|
||||||
|
isNeg = true;
|
||||||
|
data = -data;
|
||||||
|
}
|
||||||
|
data = data.toString(16);
|
||||||
|
if (data.length % 2 == 1) data = "0" + data;
|
||||||
|
data = "0x" + data;
|
||||||
|
if (isNeg) data = "-"+data;
|
||||||
|
}
|
||||||
const d = Web3Utils.hexToBytes(Web3Utils.toHex(data));
|
const d = Web3Utils.hexToBytes(Web3Utils.toHex(data));
|
||||||
if (d.length == 0 || d.length > 32) {
|
if (d.length == 0 || d.length > 32) {
|
||||||
throw new Error("Assertion failed");
|
throw new Error("Assertion failed");
|
||||||
|
|||||||
146
src/poseidon.js
146
src/poseidon.js
@@ -1,121 +1,49 @@
|
|||||||
const Scalar = require("ffjavascript").Scalar;
|
|
||||||
const blake2b = require("blake2b");
|
|
||||||
const assert = require("assert");
|
const assert = require("assert");
|
||||||
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
const ZqField = require("ffjavascript").ZqField;
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
const utils = require("ffjavascript").utils;
|
const { unstringifyBigInts } = require("ffjavascript").utils;
|
||||||
|
|
||||||
|
// Prime 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
||||||
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
||||||
exports.F = F;
|
|
||||||
|
|
||||||
const SEED = "poseidon";
|
// Parameters are generated by a reference script https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/generate_parameters_grain.sage
|
||||||
const NROUNDSF = 8;
|
// Used like so: sage generate_parameters_grain.sage 1 0 254 2 8 56 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
||||||
const NROUNDSP = 57;
|
const { C, M } = unstringifyBigInts(require("./poseidon_constants.json"));
|
||||||
const T = 6;
|
|
||||||
|
|
||||||
function getPseudoRandom(seed, n) {
|
// Using recommended parameters from whitepaper https://eprint.iacr.org/2019/458.pdf (table 2, table 8)
|
||||||
const res = [];
|
// Generated by https://extgit.iaik.tugraz.at/krypto/hadeshash/-/blob/master/code/calc_round_numbers.py
|
||||||
let input = Buffer.from(seed);
|
// And rounded up to nearest integer that divides by t
|
||||||
let h = blake2b(32).update(input).digest();
|
const N_ROUNDS_F = 8;
|
||||||
while (res.length<n) {
|
const N_ROUNDS_P = [56, 57, 56, 60, 60, 63, 64, 63];
|
||||||
const n = F.normalize(utils.leBuff2int(Buffer.from(h)));
|
|
||||||
res.push(n);
|
|
||||||
h = blake2b(32).update(h).digest();
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
const pow5 = a => F.mul(a, F.square(F.square(a, a)));
|
||||||
}
|
|
||||||
|
|
||||||
function allDifferent(v) {
|
function poseidon(inputs) {
|
||||||
for (let i=0; i<v.length; i++) {
|
assert(inputs.length > 0);
|
||||||
if (F.isZero(v[i])) return false;
|
assert(inputs.length < N_ROUNDS_P.length - 1);
|
||||||
for (let j=i+1; j<v.length; j++) {
|
|
||||||
if (F.eq(v[i],v[j])) return false;
|
const t = inputs.length + 1;
|
||||||
|
const nRoundsF = N_ROUNDS_F;
|
||||||
|
const nRoundsP = N_ROUNDS_P[t - 2];
|
||||||
|
|
||||||
|
let state = [...inputs.map(a => F.e(a)), F.zero];
|
||||||
|
for (let r = 0; r < nRoundsF + nRoundsP; r++) {
|
||||||
|
state = state.map((a, i) => F.add(a, C[t - 2][r * t + i]));
|
||||||
|
|
||||||
|
if (r < nRoundsF / 2 || r >= nRoundsF / 2 + nRoundsP) {
|
||||||
|
state = state.map(a => pow5(a));
|
||||||
|
} else {
|
||||||
|
state[0] = pow5(state[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// no matrix multiplication in the last round
|
||||||
|
if (r < nRoundsF + nRoundsP - 1) {
|
||||||
|
state = state.map((_, i) =>
|
||||||
|
state.reduce((acc, a, j) => F.add(acc, F.mul(M[t - 2][j][i], a)), F.zero)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return F.normalize(state[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getMatrix = (t, seed, nRounds) => {
|
module.exports = poseidon;
|
||||||
if (typeof seed === "undefined") seed = SEED;
|
|
||||||
if (typeof nRounds === "undefined") nRounds = NROUNDSF + NROUNDSP;
|
|
||||||
if (typeof t === "undefined") t = T;
|
|
||||||
assert(t<=6); // Force the same matrix for all.
|
|
||||||
t=6;
|
|
||||||
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.normalize(F.inv(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] = F.e(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.normalize(state[0]);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
3449
src/poseidon_constants.json
Normal file
3449
src/poseidon_constants.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -2,14 +2,13 @@
|
|||||||
// License: LGPL-3.0+
|
// License: LGPL-3.0+
|
||||||
//
|
//
|
||||||
|
|
||||||
const Poseidon = require("./poseidon.js");
|
|
||||||
|
|
||||||
const Contract = require("./evmasm");
|
const Contract = require("./evmasm");
|
||||||
|
const { unstringifyBigInts } = require("ffjavascript").utils;
|
||||||
|
|
||||||
const SEED = "poseidon";
|
const { C:K, M } = unstringifyBigInts(require("./poseidon_constants.json"));
|
||||||
const NROUNDSF = 8;
|
|
||||||
const NROUNDSP = 57;
|
const N_ROUNDS_F = 8;
|
||||||
const T = 6;
|
const N_ROUNDS_P = [56, 57, 56, 60, 60, 63, 64, 63];
|
||||||
|
|
||||||
function toHex256(a) {
|
function toHex256(a) {
|
||||||
let S = a.toString(16);
|
let S = a.toString(16);
|
||||||
@@ -17,38 +16,34 @@ function toHex256(a) {
|
|||||||
return "0x" + S;
|
return "0x" + S;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createCode(t, nRoundsF, nRoundsP, seed) {
|
function createCode(nInputs) {
|
||||||
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);
|
if (( nInputs<1) || (nInputs>8)) throw new Error("Invalid number of inputs. Must be 1<=nInputs<=8");
|
||||||
const M = Poseidon.getMatrix(t, seed, nRoundsP + nRoundsF);
|
const t = nInputs + 1;
|
||||||
|
const nRoundsF = N_ROUNDS_F;
|
||||||
|
const nRoundsP = N_ROUNDS_P[t - 2];
|
||||||
|
|
||||||
const C = new Contract();
|
const C = new Contract();
|
||||||
|
|
||||||
function saveM() {
|
function saveM() {
|
||||||
for (let i=0; i<t; i++) {
|
for (let i=0; i<t; i++) {
|
||||||
for (let j=0; j<t; j++) {
|
for (let j=0; j<t; j++) {
|
||||||
C.push(toHex256(M[i][j]));
|
C.push(toHex256(M[t-2][j][i]));
|
||||||
C.push((1+i*t+j)*32);
|
C.push((1+i*t+j)*32);
|
||||||
C.mstore();
|
C.mstore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ark(r) {
|
function ark(r) { // st, q
|
||||||
C.push(toHex256(K[r])); // K, st, q
|
|
||||||
for (let i=0; i<t; i++) {
|
for (let i=0; i<t; i++) {
|
||||||
C.dup(1+t); // q, K, st, q
|
C.dup(t); // q, st, q
|
||||||
C.dup(1); // K, q, K, st, q
|
C.push(toHex256(K[t-2][r*t+i])); // K, q, st, q
|
||||||
C.dup(3+i); // st[i], K, q, K, st, q
|
C.dup(2+i); // st[i], K, q, st, q
|
||||||
C.addmod(); // newSt[i], K, st, q
|
C.addmod(); // newSt[i], st, q
|
||||||
C.swap(2 + i); // xx, K, st, q
|
C.swap(1 + i); // xx, st, q
|
||||||
C.pop();
|
C.pop();
|
||||||
}
|
}
|
||||||
C.pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function sigma(p) {
|
function sigma(p) {
|
||||||
@@ -115,17 +110,17 @@ function createCode(t, nRoundsF, nRoundsP, seed) {
|
|||||||
|
|
||||||
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
C.push("0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"); // q
|
||||||
|
|
||||||
// Load 6 values from the call data.
|
// Load t values from the call data.
|
||||||
// The function has a single array param param
|
// The function has a single array param param
|
||||||
// [Selector (4)] [Pointer (32)][Length (32)] [data1 (32)] ....
|
// [Selector (4)] [Pointer (32)][Length (32)] [data1 (32)] ....
|
||||||
// We ignore the pointer and the length and just load 6 values to the state
|
// We ignore the pointer and the length and just load t values to the state
|
||||||
// (Stack positions 0-5) If the array is shorter, we just set zeros.
|
// (Stack positions 0-{t-1}) If the array is shorter, we just set zeros.
|
||||||
for (let i=0; i<t; i++) {
|
for (let i=0; i<t; i++) {
|
||||||
C.push(0x44+(0x20*(t-1-i)));
|
C.push(0x44+(0x20*(t-1-i)));
|
||||||
C.calldataload();
|
C.calldataload();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i=0; i<nRoundsF+nRoundsP; i++) {
|
for (let i=0; i<nRoundsF+nRoundsP-1; i++) {
|
||||||
ark(i);
|
ark(i);
|
||||||
if ((i<nRoundsF/2) || (i>=nRoundsP+nRoundsF/2)) {
|
if ((i<nRoundsF/2) || (i>=nRoundsP+nRoundsF/2)) {
|
||||||
for (let j=0; j<t; j++) {
|
for (let j=0; j<t; j++) {
|
||||||
@@ -142,6 +137,13 @@ function createCode(t, nRoundsF, nRoundsP, seed) {
|
|||||||
C.label(strLabel);
|
C.label(strLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
C.push(toHex256(K[t-2][(nRoundsF+nRoundsP-1)*t])); // K, st, q
|
||||||
|
C.dup(t+1); // q, K, st, q
|
||||||
|
C.swap(2); // st[0], K, q, st\st[0]
|
||||||
|
C.addmod(); // st q
|
||||||
|
|
||||||
|
sigma(0);
|
||||||
|
|
||||||
C.push("0x00");
|
C.push("0x00");
|
||||||
C.mstore(); // Save it to pos 0;
|
C.mstore(); // Save it to pos 0;
|
||||||
C.push("0x20");
|
C.push("0x20");
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
@@ -1,5 +1,13 @@
|
|||||||
const poseidonGenContract = require("./poseidon_gencontract");
|
const poseidonGenContract = require("./poseidon_gencontract");
|
||||||
|
|
||||||
|
if (process.argv.length != 3) {
|
||||||
|
console.log("Usage: node poseidon_gencontract.js [numberOfInputs]");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
console.log(poseidonGenContract.createCode(6, 8, 57));
|
const nInputs = Number(process.argv[2]);
|
||||||
|
|
||||||
|
console.log(nInputs);
|
||||||
|
|
||||||
|
console.log(poseidonGenContract.createCode(nInputs));
|
||||||
|
|
||||||
|
|||||||
@@ -58,10 +58,10 @@ class SMT {
|
|||||||
|
|
||||||
res.newRoot = rtNew;
|
res.newRoot = rtNew;
|
||||||
|
|
||||||
|
await this.db.multiDel(dels);
|
||||||
await this.db.multiIns(ins);
|
await this.db.multiIns(ins);
|
||||||
await this.db.setRoot(rtNew);
|
await this.db.setRoot(rtNew);
|
||||||
this.root = rtNew;
|
this.root = rtNew;
|
||||||
await this.db.multiDel(dels);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,18 @@
|
|||||||
const Poseidon = require("./poseidon");
|
|
||||||
|
|
||||||
const hash = Poseidon.createHash(6, 8, 57);
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
|
||||||
|
const poseidon = require("./poseidon");
|
||||||
|
|
||||||
|
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
||||||
|
|
||||||
|
|
||||||
exports.hash0 = function (left, right) {
|
exports.hash0 = function (left, right) {
|
||||||
return hash([left, right]);
|
return poseidon([left, right]);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.hash1 = function(key, value) {
|
exports.hash1 = function(key, value) {
|
||||||
return hash([key, value, Poseidon.F.one]);
|
return poseidon([key, value, F.one]);
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.F = Poseidon.F;
|
exports.F = F;
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
|
|
||||||
const F = require("./poseidon.js").F;
|
|
||||||
const Scalar = require("ffjavascript").Scalar;
|
const Scalar = require("ffjavascript").Scalar;
|
||||||
|
const ZqField = require("ffjavascript").ZqField;
|
||||||
|
|
||||||
|
// Prime 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001
|
||||||
|
const F = new ZqField(Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617"));
|
||||||
|
|
||||||
class SMTMemDb {
|
class SMTMemDb {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -14,7 +17,7 @@ class SMTMemDb {
|
|||||||
|
|
||||||
_key2str(k) {
|
_key2str(k) {
|
||||||
// const keyS = bigInt(key).leInt2Buff(32).toString("hex");
|
// const keyS = bigInt(key).leInt2Buff(32).toString("hex");
|
||||||
const keyS = Scalar.e(k);
|
const keyS = k.toString();
|
||||||
return keyS;
|
return keyS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
include "../../circuits/poseidon.circom"
|
include "../../circuits/poseidon.circom"
|
||||||
|
|
||||||
component main = Poseidon(2, 3, 8, 57);
|
component main = Poseidon(2);
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
include "../../circuits/poseidon.circom"
|
include "../../circuits/poseidon.circom"
|
||||||
|
|
||||||
component main = Poseidon(2, 6, 8, 57);
|
component main = Poseidon(5);
|
||||||
|
|||||||
@@ -67,12 +67,12 @@ describe("EdDSA js test", function () {
|
|||||||
assert.equal(signature.R8[1].toString(),
|
assert.equal(signature.R8[1].toString(),
|
||||||
"15383486972088797283337779941324724402501462225528836549661220478783371668959");
|
"15383486972088797283337779941324724402501462225528836549661220478783371668959");
|
||||||
assert.equal(signature.S.toString(),
|
assert.equal(signature.S.toString(),
|
||||||
"248298168863866362217836334079793350221620631973732197668910946177382043688");
|
"1398758333392199195742243841591064350253744445503462896781493968760929513778");
|
||||||
|
|
||||||
const pSignature = eddsa.packSignature(signature);
|
const pSignature = eddsa.packSignature(signature);
|
||||||
assert.equal(pSignature.toString("hex"), ""+
|
assert.equal(pSignature.toString("hex"), ""+
|
||||||
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+
|
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+
|
||||||
"28506bce274aa1b3f7e7c2fd7e4fe09bff8f9aa37a42def7994e98f322888c00");
|
"32f16b0f2f4c4e1169aa59685637e1429b6581a9531d058d65f4ab224eab1703");
|
||||||
|
|
||||||
const uSignature = eddsa.unpackSignature(pSignature);
|
const uSignature = eddsa.unpackSignature(pSignature);
|
||||||
assert(eddsa.verifyPoseidon(msg, uSignature, pubKey));
|
assert(eddsa.verifyPoseidon(msg, uSignature, pubKey));
|
||||||
|
|||||||
@@ -1,21 +1,11 @@
|
|||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
var blake2b = require("blake2b");
|
|
||||||
const tester = require("circom").tester;
|
const tester = require("circom").tester;
|
||||||
|
|
||||||
const poseidon = require("../src/poseidon.js");
|
const poseidon = require("../src/poseidon.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
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");
|
|
||||||
const h = blake2b(output.length).update(input).digest("hex");
|
|
||||||
assert.equal("e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1", h);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("Poseidon Circuit test", function () {
|
describe("Poseidon Circuit test", function () {
|
||||||
let circuit6;
|
let circuit6;
|
||||||
let circuit3;
|
let circuit3;
|
||||||
@@ -28,24 +18,20 @@ describe("Poseidon Circuit test", function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Should check constrain of hash([1, 2]) t=6", async () => {
|
it("Should check constrain of hash([1, 2]) t=6", async () => {
|
||||||
const w = await circuit6.calculateWitness({inputs: [1, 2]}, true);
|
const w = await circuit6.calculateWitness({inputs: [1, 2, 0,0,0]}, true);
|
||||||
|
|
||||||
const hash = poseidon.createHash(6, 8, 57);
|
const res2 = poseidon([1,2,0,0,0]);
|
||||||
|
assert.equal("3975478831357328722254985704342968745327876719981393787143845259590563829094", res2.toString());
|
||||||
const res2 = hash([1,2]);
|
|
||||||
assert.equal("12242166908188651009877250812424843524687801523336557272219921456462821518061", res2.toString());
|
|
||||||
await circuit6.assertOut(w, {out : res2});
|
await circuit6.assertOut(w, {out : res2});
|
||||||
await circuit6.checkConstraints(w);
|
await circuit6.checkConstraints(w);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should check constrain of hash([3, 4]) t=6", async () => {
|
it("Should check constrain of hash([3, 4]) t=6", async () => {
|
||||||
const w = await circuit6.calculateWitness({inputs: [3, 4]});
|
const w = await circuit6.calculateWitness({inputs: [3, 4,5,10,23]});
|
||||||
|
|
||||||
const hash = poseidon.createHash(6, 8, 57);
|
const res2 = poseidon([3, 4,5,10,23]);
|
||||||
|
|
||||||
const res2 = hash([3, 4]);
|
assert.equal("18540626624821144952552691894137986276337186174352554475896834101336254024067", res2.toString());
|
||||||
|
|
||||||
assert.equal("17185195740979599334254027721507328033796809509313949281114643312710535000993", res2.toString());
|
|
||||||
await circuit6.assertOut(w, {out : res2});
|
await circuit6.assertOut(w, {out : res2});
|
||||||
await circuit6.checkConstraints(w);
|
await circuit6.checkConstraints(w);
|
||||||
});
|
});
|
||||||
@@ -54,10 +40,8 @@ describe("Poseidon Circuit test", function () {
|
|||||||
it("Should check constrain of hash([1, 2]) t=3", async () => {
|
it("Should check constrain of hash([1, 2]) t=3", async () => {
|
||||||
const w = await circuit3.calculateWitness({inputs: [1, 2]});
|
const w = await circuit3.calculateWitness({inputs: [1, 2]});
|
||||||
|
|
||||||
const hash = poseidon.createHash(3, 8, 57);
|
const res2 = poseidon([1,2]);
|
||||||
|
assert.equal("17117985411748610629288516079940078114952304104811071254131751175361957805920", res2.toString());
|
||||||
const res2 = hash([1,2]);
|
|
||||||
assert.equal("2104035019328376391822106787753454168168617545136592089411833517434990977743", res2.toString());
|
|
||||||
await circuit3.assertOut(w, {out : res2});
|
await circuit3.assertOut(w, {out : res2});
|
||||||
await circuit3.checkConstraints(w);
|
await circuit3.checkConstraints(w);
|
||||||
});
|
});
|
||||||
@@ -65,10 +49,8 @@ describe("Poseidon Circuit test", function () {
|
|||||||
it("Should check constrain of hash([3, 4]) t=3", async () => {
|
it("Should check constrain of hash([3, 4]) t=3", async () => {
|
||||||
const w = await circuit3.calculateWitness({inputs: [3, 4]});
|
const w = await circuit3.calculateWitness({inputs: [3, 4]});
|
||||||
|
|
||||||
const hash = poseidon.createHash(3, 8, 57);
|
const res2 = poseidon([3, 4]);
|
||||||
|
assert.equal("21867347236198497199818917118739170715216974132230970409806500217655788551452", res2.toString());
|
||||||
const res2 = hash([3, 4]);
|
|
||||||
assert.equal("12456141564250880945411182508630957604732712316993112736876413121277158512223", res2.toString());
|
|
||||||
await circuit3.assertOut(w, {out : res2});
|
await circuit3.assertOut(w, {out : res2});
|
||||||
await circuit3.checkConstraints(w);
|
await circuit3.checkConstraints(w);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const ganache = require("ganache-cli");
|
|||||||
const Web3 = require("web3");
|
const Web3 = require("web3");
|
||||||
const chai = require("chai");
|
const chai = require("chai");
|
||||||
const poseidonGenContract = require("../src/poseidon_gencontract.js");
|
const poseidonGenContract = require("../src/poseidon_gencontract.js");
|
||||||
const Poseidon = require("../src/poseidon.js");
|
const poseidon = require("../src/poseidon.js");
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); };
|
const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); };
|
||||||
@@ -24,28 +24,26 @@ describe("Poseidon Smart contract test", function () {
|
|||||||
const C = new web3.eth.Contract(poseidonGenContract.abi);
|
const C = new web3.eth.Contract(poseidonGenContract.abi);
|
||||||
|
|
||||||
poseidon6 = await C.deploy({
|
poseidon6 = await C.deploy({
|
||||||
data: poseidonGenContract.createCode(6)
|
data: poseidonGenContract.createCode(5)
|
||||||
}).send({
|
}).send({
|
||||||
gas: 2500000,
|
gas: 5000000,
|
||||||
from: accounts[0]
|
from: accounts[0]
|
||||||
});
|
});
|
||||||
poseidon3 = await C.deploy({
|
poseidon3 = await C.deploy({
|
||||||
data: poseidonGenContract.createCode(3)
|
data: poseidonGenContract.createCode(2)
|
||||||
}).send({
|
}).send({
|
||||||
gas: 2500000,
|
gas: 5000000,
|
||||||
from: accounts[0]
|
from: accounts[0]
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Shold calculate the poseidon correctly t=6", async () => {
|
it("Shold calculate the poseidon correctly t=6", async () => {
|
||||||
|
|
||||||
const res = await poseidon6.methods.poseidon([1,2]).call();
|
const res = await poseidon6.methods.poseidon([1,2, 0, 0, 0]).call();
|
||||||
|
|
||||||
// console.log("Cir: " + bigInt(res.toString(16)).toString(16));
|
// console.log("Cir: " + bigInt(res.toString(16)).toString(16));
|
||||||
|
|
||||||
const hash = Poseidon.createHash(6, 8, 57);
|
const res2 = poseidon([1,2, 0, 0, 0]);
|
||||||
|
|
||||||
const res2 = hash([1,2]);
|
|
||||||
// console.log("Ref: " + bigInt(res2).toString(16));
|
// console.log("Ref: " + bigInt(res2).toString(16));
|
||||||
|
|
||||||
assert.equal(res.toString(), res2.toString());
|
assert.equal(res.toString(), res2.toString());
|
||||||
@@ -56,9 +54,7 @@ describe("Poseidon Smart contract test", function () {
|
|||||||
|
|
||||||
// console.log("Cir: " + bigInt(res.toString(16)).toString(16));
|
// console.log("Cir: " + bigInt(res.toString(16)).toString(16));
|
||||||
|
|
||||||
const hash = Poseidon.createHash(3, 8, 57);
|
const res2 = poseidon([1,2]);
|
||||||
|
|
||||||
const res2 = hash([1,2]);
|
|
||||||
// console.log("Ref: " + bigInt(res2).toString(16));
|
// console.log("Ref: " + bigInt(res2).toString(16));
|
||||||
|
|
||||||
assert.equal(res.toString(), res2.toString());
|
assert.equal(res.toString(), res2.toString());
|
||||||
|
|||||||
@@ -161,4 +161,13 @@ describe("SMT Javascript test", function () {
|
|||||||
assert(Fr.eq(tree1.root, tree2.root));
|
assert(Fr.eq(tree1.root, tree2.root));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should test update with same key-value", async () => {
|
||||||
|
const tree1 = await smt.newMemEmptyTrie();
|
||||||
|
|
||||||
|
await tree1.insert(8,88);
|
||||||
|
await tree1.update(8,88);
|
||||||
|
|
||||||
|
const res = await tree1.db.get(tree1.root);
|
||||||
|
assert.notEqual(res, undefined);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user