mirror of
https://github.com/arnaucube/circomlib.git
synced 2026-02-07 11:16:45 +01:00
Compare commits
1 Commits
v0.0.8
...
feature/sy
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5bc12a2cb8 |
@@ -1,15 +1,14 @@
|
|||||||
const bn128 = require("snarkjs").bn128;
|
const bn128 = require("snarkjs").bn128;
|
||||||
const bigInt = require("snarkjs").bigInt;
|
const bigInt = require("snarkjs").bigInt;
|
||||||
const createBlakeHash = require("blake-hash");
|
const createBlakeHash = require("blake-hash");
|
||||||
|
const assert = require("assert");
|
||||||
const babyJub = require("../src/babyjub");
|
const babyJub = require("../src/babyjub");
|
||||||
|
|
||||||
function getPoint(S) {
|
function getPoint(S) {
|
||||||
const F = bn128.Fr;
|
const F = bn128.Fr;
|
||||||
const h = createBlakeHash("blake256").update(S).digest();
|
const h = createBlakeHash("blake256").update(S).digest();
|
||||||
|
|
||||||
if (h.length != 32) {
|
assert(h.length == 32);
|
||||||
throw new Error("Invalid length")
|
|
||||||
}
|
|
||||||
|
|
||||||
let sign = false;
|
let sign = false;
|
||||||
if (h[31] & 0x80) {
|
if (h[31] & 0x80) {
|
||||||
@@ -53,9 +52,7 @@ function generatePoint(S) {
|
|||||||
p = getPoint(S+"_"+sidx);
|
p = getPoint(S+"_"+sidx);
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
if (!babyJub.inCurve(p)){
|
assert(babyJub.inCurve(p), "Point not in curve");
|
||||||
throw new Error("Point not in curve");
|
|
||||||
}
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
* 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
|
|
||||||
@@ -17,9 +17,6 @@
|
|||||||
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
along with circom. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
include "bitify.circom";
|
|
||||||
include "escalarmulfix.circom";
|
|
||||||
|
|
||||||
template BabyAdd() {
|
template BabyAdd() {
|
||||||
signal input x1;
|
signal input x1;
|
||||||
signal input y1;
|
signal input y1;
|
||||||
@@ -80,27 +77,3 @@ template BabyCheck() {
|
|||||||
|
|
||||||
a*x2 + y2 === 1 + d*x2*y2;
|
a*x2 + y2 === 1 + d*x2*y2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extracts the public key from private key
|
|
||||||
template BabyPbk() {
|
|
||||||
signal private input in;
|
|
||||||
signal output Ax;
|
|
||||||
signal output Ay;
|
|
||||||
|
|
||||||
var BASE8 = [
|
|
||||||
17777552123799933955779906779655732241715742912184938656739573121738514868268,
|
|
||||||
2626589144620713026669568689430873010625803728049924121243784502389097019475
|
|
||||||
];
|
|
||||||
|
|
||||||
component pvkBits = Num2Bits(253);
|
|
||||||
pvkBits.in <== in;
|
|
||||||
|
|
||||||
component mulFix = EscalarMulFix(253, BASE8);
|
|
||||||
|
|
||||||
var i;
|
|
||||||
for (i=0; i<253; i++) {
|
|
||||||
mulFix.e[i] <== pvkBits.out[i];
|
|
||||||
}
|
|
||||||
Ax <== mulFix.out[0];
|
|
||||||
Ay <== mulFix.out[1];
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ template EdDSAMiMCVerifier() {
|
|||||||
hash.in[2] <== Ax;
|
hash.in[2] <== Ax;
|
||||||
hash.in[3] <== Ay;
|
hash.in[3] <== Ay;
|
||||||
hash.in[4] <== M;
|
hash.in[4] <== M;
|
||||||
hash.k <== 0;
|
|
||||||
|
|
||||||
component h2bits = Num2Bits_strict();
|
component h2bits = Num2Bits_strict();
|
||||||
h2bits.in <== hash.out;
|
h2bits.in <== hash.out;
|
||||||
|
|||||||
@@ -137,19 +137,18 @@ template MiMC7(nrounds) {
|
|||||||
|
|
||||||
template MultiMiMC7(nInputs, nRounds) {
|
template MultiMiMC7(nInputs, nRounds) {
|
||||||
signal input in[nInputs];
|
signal input in[nInputs];
|
||||||
signal input k;
|
|
||||||
signal output out;
|
signal output out;
|
||||||
signal r[nInputs +1];
|
|
||||||
|
|
||||||
component mims[nInputs];
|
component mims[nInputs];
|
||||||
|
|
||||||
r[0] <== k;
|
|
||||||
for (var i=0; i<nInputs; i++) {
|
for (var i=0; i<nInputs; i++) {
|
||||||
mims[i] = MiMC7(nRounds);
|
mims[i] = MiMC7(nRounds);
|
||||||
mims[i].x_in <== in[i];
|
if (i==0) {
|
||||||
mims[i].k <== r[i];
|
mims[i].x_in <== 15021630795539610737508582392395901278341266317943626182700664337106830745361;
|
||||||
r[i+1] <== r[i] + in[i] + mims[i].out;
|
} else {
|
||||||
|
mims[i].x_in <== mims[i-1].out;
|
||||||
|
}
|
||||||
|
mims[i].k <== in[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
out <== r[nInputs];
|
out <== mims[nInputs-1].out;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,17 +90,12 @@ template Decoder(w) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template Multiplexer(wIn, nIn) {
|
template Multiplexor(wIn, nIn) {
|
||||||
signal input inp[nIn][wIn];
|
signal input inp[nIn][wIn];
|
||||||
signal input sel;
|
signal input sel;
|
||||||
signal output out[wIn];
|
signal output out[wIn];
|
||||||
component dec = Decoder(nIn);
|
component Decoder(nIn) dec;
|
||||||
component ep[wIn];
|
component EscalarProduct(nIn) ep[wIn];
|
||||||
|
|
||||||
for (var k=0; k<wIn; k++) {
|
|
||||||
ep[k] = EscalarProduct(nIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
sel ==> dec.inp;
|
sel ==> dec.inp;
|
||||||
for (var j=0; j<wIn; j++) {
|
for (var j=0; j<wIn; j++) {
|
||||||
for (var k=0; k<nIn; k++) {
|
for (var k=0; k<nIn; k++) {
|
||||||
@@ -111,3 +106,7 @@ template Multiplexer(wIn, nIn) {
|
|||||||
}
|
}
|
||||||
dec.success === 1;
|
dec.success === 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
component Multiplexor(8,3) main;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,202 +0,0 @@
|
|||||||
|
|
||||||
template Sigma() {
|
|
||||||
signal input in;
|
|
||||||
signal output out;
|
|
||||||
|
|
||||||
signal in2;
|
|
||||||
signal in4;
|
|
||||||
|
|
||||||
in2 <== in*in;
|
|
||||||
in4 <== in2*in2;
|
|
||||||
|
|
||||||
out <== in4*in;
|
|
||||||
}
|
|
||||||
|
|
||||||
template Ark(t, C) {
|
|
||||||
signal input in[t];
|
|
||||||
signal output out[t];
|
|
||||||
for (var i=0; i<t; i++) {
|
|
||||||
out[i] <== in[i] + C;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template Mix(t, M) {
|
|
||||||
signal input in[t];
|
|
||||||
signal output out[t];
|
|
||||||
var lc;
|
|
||||||
|
|
||||||
for (var i=0; i<t; i++) {
|
|
||||||
lc = 0;
|
|
||||||
for (var j=0; j<t; j++) {
|
|
||||||
lc = lc + M[i][j]*in[j];
|
|
||||||
}
|
|
||||||
out[i] <== lc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// var nRoundsF = 8;
|
|
||||||
// var nRoundsP = 57;
|
|
||||||
// var t = 6;
|
|
||||||
|
|
||||||
template Poseidon(nInputs, t, nRoundsF, nRoundsP) {
|
|
||||||
|
|
||||||
var C = [
|
|
||||||
1354025385229961744769229343273868518314335569873439558835166239576773343708,
|
|
||||||
14378844218625331047742339561309620904043097700980163591187076404481144585564,
|
|
||||||
19370813333785034372560258124535206525278124675105547990205946542330734467847,
|
|
||||||
19339919977375282793227987561727366424934767905100680591050582380667086628202,
|
|
||||||
8422275364316831706903446151602338206948363474119622730702497535467809432414,
|
|
||||||
7433947928146794739292515659214608949964639549664630885486968546133071892830,
|
|
||||||
20753350951496713264979200428833003140825588922450200809553577914404143341040,
|
|
||||||
21437018888080559864996889038552602698883513894753499324572098534369350747880,
|
|
||||||
6815447461573214810645016226370803316854141900901895816072622961504507953749,
|
|
||||||
11746901014017411226283657362310634990885933032228701131899561585228216986615,
|
|
||||||
13428722985713722660261823704226749286675766756093697029778643398137361221114,
|
|
||||||
10894749142018158588533110743373157663019829222177356873395009880383491602356,
|
|
||||||
13720066349319517776784660327982201297420012713976744204318378121767771862484,
|
|
||||||
4665971664531891307640113589671067488692829783046247264698659233443166028412,
|
|
||||||
5364541878673041196937884015923978656299860601766012213141306792903990539664,
|
|
||||||
1747411112078838632103476037026417344408680910500491241306123941341644055714,
|
|
||||||
1835035066071759522152578007305026433897204459772540871869487151042238374039,
|
|
||||||
21055637025200882290106914253232617255445210101773537879323245961051751183138,
|
|
||||||
19215142378199333594641095299020637309879189505235993967243075316794127016728,
|
|
||||||
5264915734761449905856538116909638235466879053604660991987579054616980096262,
|
|
||||||
10045917614023673044141331581538797960977704806582630277050701175565262856382,
|
|
||||||
7789533631025313780520004400945166898631872921910178131342071973345076732672,
|
|
||||||
19972498130123740615813398456152565371201412297339860820234719562997192378694,
|
|
||||||
14216077977931104808041453382683965630500368477063603536695472115075869912121,
|
|
||||||
2555981910568472028679439033700033287358333564454149464965229699417319912931,
|
|
||||||
11735111941739477522347883122573591136355121750109794306409399099068977659499,
|
|
||||||
16957890207070910233505303498878270130436461648242792271152604513138986611609,
|
|
||||||
358520143235124107055243451716507147499373646513864848163778795927281509793,
|
|
||||||
6389190271835493841487214043252929516390267871881261173336690351147926750010,
|
|
||||||
12939611907106878137030264379019786496625916664142697309441198804098015086205,
|
|
||||||
456696638239570875759108333278090964360604015255503302016190396687826618227,
|
|
||||||
20569764931577491771523222445135914903999292206008007769649255123342890660989,
|
|
||||||
3341317247281280728261320226215152668194921091152837358683334635401182164637,
|
|
||||||
11821224368797169892747612081573458772211068320533296007836648033607696236615,
|
|
||||||
2185176387193659864764608304330502180888068591409305411859725028056771843945,
|
|
||||||
17161758741114551704796078639849789476380746803787101178795737276111464575519,
|
|
||||||
11889888355183092530573415929875444766831739308191993115663429638848547668798,
|
|
||||||
19503084309842095729857399025417533485089330284851492085544757107759925099089,
|
|
||||||
20280152151768521735424910115623976684589382048161526796204268413029416266256,
|
|
||||||
17607351334578006856860845064970248988416315904757246948622629528628773644114,
|
|
||||||
20769468546336672951384440602623018830493119282829911435465737079851020547355,
|
|
||||||
1546429204704408801701093430086546742691081844046642451323347737810191940866,
|
|
||||||
11200569249561318620053458114013886527484999499632128671282997438827107108229,
|
|
||||||
20198213289062010915914579158889968647687156198219713083074315178786791524034,
|
|
||||||
12911209060630719799682705729835581341676468319742562559036843993017369855977,
|
|
||||||
18925188847138989248835676768641716482476141553833902070405850166412140133887,
|
|
||||||
20376466983584239909415025821007315251422803039634139484663713769887712746966,
|
|
||||||
5250536177612235431141386983455571232984126980327432803966957255414592397060,
|
|
||||||
344847263093423485167610155050688875010578621416939967999896518937961396680,
|
|
||||||
19870333728541576497318505013425518731999037041271340888970559590767369935385,
|
|
||||||
20604512495859902382577228682521142736989261702707317046150335692410020156250,
|
|
||||||
18293964088694556689667514948280720605277532123251572448395882397578643211622,
|
|
||||||
21211253784206079547762943120791531326787601501123474236198383850531142559075,
|
|
||||||
17247914781304154940895909185506123510423535554247372833321968000513811053190,
|
|
||||||
16432189025237084563810000088202867449333673799705533820685782829379758927490,
|
|
||||||
7204783063529242442830743239980168374343946353418800547956909848044774363774,
|
|
||||||
2108268032972510691814120801033692084861951866306906253604497017452204030001,
|
|
||||||
13483247063999686990721729188827693318708500027762095503921527692630827328070,
|
|
||||||
18194665574704709729868916970580318177272365766028499528691737819467051567534,
|
|
||||||
9275639092314761435364537152118796424056864859607619908791935597976913759411,
|
|
||||||
12700165678727983685032332532042155014245610964583614362270316386368455898604,
|
|
||||||
19127554193875137546212792134421555344854604853165878912238751527694270097310,
|
|
||||||
16817455471920423226570476063669349525676437756352144502692679769377074040335,
|
|
||||||
17331185397945904160678487303485263376032543419657328137924881433628614769955,
|
|
||||||
11605569208043267134285833752214422326246425655661043119023566733685555142420
|
|
||||||
];
|
|
||||||
|
|
||||||
var M = [
|
|
||||||
[
|
|
||||||
12037235000515189726428793905458162231976011685774991261061889278958802340039,
|
|
||||||
15885254491685089152627111704751054604879027605518712546805347341940526552948,
|
|
||||||
12220682901774309471330657931458552366575439534877271150866614914170639536810,
|
|
||||||
11195096069395318710866553226959674457987772316145705151894647995087349332576,
|
|
||||||
598000700605575401177173118514166571064818339748567530524299773749024042768,
|
|
||||||
1430722853270801285936618367966028727146977818314178365893636191280860605092
|
|
||||||
],[
|
|
||||||
2478807512283787086755520696277192042388812450777005645736937700857950416751,
|
|
||||||
2233078558675693495109307103888903813217767160310116996267068037131890781382,
|
|
||||||
18876120310576321787684235034151243856925703159922712959767164734820803570163,
|
|
||||||
16850806847813838898693870637445284830832219430572133120914449039176718036761,
|
|
||||||
1333036876405396107763619427367607232034082504897380383847654332653606615427,
|
|
||||||
8024813862822108072341428765418554797098705487914663416123759888639403831315
|
|
||||||
],[
|
|
||||||
6500095533434910955474026763873910167129305339747639394388586826716085593160,
|
|
||||||
8370208895752773828195461153114215021863221486187756770286440396339432061839,
|
|
||||||
9303960191058819387902927958335344077259478983903385066838134730814638010892,
|
|
||||||
12233235273183315334651707749232602313616943260130930740801007863528547113209,
|
|
||||||
9140649423847813564210562288927015604065254723368331178903734405333716165919,
|
|
||||||
1715897011776785698388835993891828784112980527691698420841641796168725014542
|
|
||||||
],[
|
|
||||||
19092640119254952117901733765506685707486610088248205883870061221436629780176,
|
|
||||||
3099417239661426161523333446616746096617346084970490427773391639810420659748,
|
|
||||||
4498351799178816410443394768364090919370619407529999860500200773846156676605,
|
|
||||||
17766546613911504681964882079687098358108049762069064124348111606619240189874,
|
|
||||||
19735199036142202254810745273503942799136628866093225336283966579447096889407,
|
|
||||||
18618071352177331467649099054615438672487187348128402045695624605978242597928
|
|
||||||
],[
|
|
||||||
13282641901514824677915134398195165361567825236648422290753355584311135817423,
|
|
||||||
842963276112770184096507757019973399127531993386626262873928307889423235104,
|
|
||||||
5724939764407712239242783736588389538981693110806985476155198757555171230777,
|
|
||||||
3015568820237516884743892014063659856564948150197038824747891972506031149123,
|
|
||||||
8926202997251578932273751544826990276848999132609774201265891812369804099098,
|
|
||||||
13523975980414815337318802343464374889255493007711857898760066111901192774093
|
|
||||||
],[
|
|
||||||
13163705634211158833717167498904899472888572514300041636511944020589976373689,
|
|
||||||
6705743158328622712684686369234272301477431173971663001146157949982901448493,
|
|
||||||
5341285785102635724684809992160578025785996331334612975598752577556138916495,
|
|
||||||
2365134732811643517126128253974711531515283135672252986518431351700239265326,
|
|
||||||
11812366860142870031000585328436207067560705932658624313008187741187899702321,
|
|
||||||
11192751017231920972897699839932659451476356148115786649719660565307185769796
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
signal input inputs[nInputs];
|
|
||||||
signal output out;
|
|
||||||
|
|
||||||
component ark[nRoundsF + nRoundsP];
|
|
||||||
component sigmaF[nRoundsF][t];
|
|
||||||
component sigmaP[nRoundsP];
|
|
||||||
component mix[nRoundsF + nRoundsP];
|
|
||||||
|
|
||||||
var k;
|
|
||||||
|
|
||||||
for (var i=0; i<(nRoundsF + nRoundsP); i++) {
|
|
||||||
ark[i] = Ark(t, C[i]);
|
|
||||||
mix[i] = Mix(t, M);
|
|
||||||
|
|
||||||
for (var j=0; j<t; j++) {
|
|
||||||
if (i==0) {
|
|
||||||
if (j<nInputs) {
|
|
||||||
ark[i].in[j] <== inputs[j];
|
|
||||||
} else {
|
|
||||||
ark[i].in[j] <== 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ark[i].in[j] <== mix[i-1].out[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((i<(nRoundsF/2)) || (i>= (nRoundsP + nRoundsF/2))) {
|
|
||||||
k= i<nRoundsF/2 ? i : (i-nRoundsP);
|
|
||||||
for (var j=0; j<t; j++) {
|
|
||||||
sigmaF[k][j] = Sigma();
|
|
||||||
sigmaF[k][j].in <== ark[i].out[j];
|
|
||||||
mix[i].in[j] <== sigmaF[k][j].out;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
k= i-nRoundsF/2;
|
|
||||||
sigmaP[k] = Sigma();
|
|
||||||
sigmaP[k].in <== ark[i].out[0];
|
|
||||||
mix[i].in[0] <== sigmaP[k].out;
|
|
||||||
for (var j=1; j<t; j++) {
|
|
||||||
mix[i].in[j] <== ark[i].out[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out <== mix[nRoundsF + nRoundsP -1].out[0];
|
|
||||||
}
|
|
||||||
@@ -29,12 +29,19 @@ template SMTHash1() {
|
|||||||
signal input value;
|
signal input value;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
component h = MultiMiMC7(2, 91); // Constant
|
component h1 = MiMC7(91); // Constant
|
||||||
h.in[0] <== key;
|
h1.x_in <== 15021630795539610737508582392395901278341266317943626182700664337106830745361;
|
||||||
h.in[1] <== value;
|
h1.k <== 1;
|
||||||
h.k <== 1;
|
|
||||||
|
|
||||||
out <== h.out;
|
component h2 = MiMC7(91);
|
||||||
|
h2.x_in <== h1.out;
|
||||||
|
h2.k <== key;
|
||||||
|
|
||||||
|
component h3 = MiMC7(91);
|
||||||
|
h3.x_in <== h2.out;
|
||||||
|
h3.k <== value;
|
||||||
|
|
||||||
|
out <== h3.out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -48,10 +55,13 @@ template SMTHash2() {
|
|||||||
signal input R;
|
signal input R;
|
||||||
signal output out;
|
signal output out;
|
||||||
|
|
||||||
component h = MultiMiMC7(2, 91); // Constant
|
component h1 = MiMC7(91);
|
||||||
h.in[0] <== L;
|
h1.x_in <== 15021630795539610737508582392395901278341266317943626182700664337106830745361;
|
||||||
h.in[1] <== R;
|
h1.k <== L;
|
||||||
h.k <== 0;
|
|
||||||
|
|
||||||
out <== h.out;
|
component h2 = MiMC7(91);
|
||||||
|
h2.x_in <== h1.out;
|
||||||
|
h2.k <== R;
|
||||||
|
|
||||||
|
out <== h2.out;
|
||||||
}
|
}
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
@@ -135,7 +135,7 @@ include "../switcher.circom";
|
|||||||
include "smtlevins.circom";
|
include "smtlevins.circom";
|
||||||
include "smtprocessorlevel.circom";
|
include "smtprocessorlevel.circom";
|
||||||
include "smtprocessorsm.circom";
|
include "smtprocessorsm.circom";
|
||||||
include "smthash_poseidon.circom";
|
include "smthash.circom";
|
||||||
|
|
||||||
template SMTProcessor(nLevels) {
|
template SMTProcessor(nLevels) {
|
||||||
signal input oldRoot;
|
signal input oldRoot;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ include "../switcher.circom";
|
|||||||
include "smtlevins.circom";
|
include "smtlevins.circom";
|
||||||
include "smtverifierlevel.circom";
|
include "smtverifierlevel.circom";
|
||||||
include "smtverifiersm.circom";
|
include "smtverifiersm.circom";
|
||||||
include "smthash_poseidon.circom";
|
include "smthash.circom";
|
||||||
|
|
||||||
template SMTVerifier(nLevels) {
|
template SMTVerifier(nLevels) {
|
||||||
signal input enabled;
|
signal input enabled;
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
1
index.js
1
index.js
@@ -1,4 +1,3 @@
|
|||||||
exports.smt = require("./src/smt");
|
exports.smt = require("./src/smt");
|
||||||
exports.eddsa = require("./src/eddsa");
|
exports.eddsa = require("./src/eddsa");
|
||||||
exports.mimc7 = require("./src/mimc7");
|
exports.mimc7 = require("./src/mimc7");
|
||||||
exports.babyJub = require("./src/babyjub");
|
|
||||||
|
|||||||
1332
package-lock.json
generated
1332
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "circomlib",
|
"name": "circomlib",
|
||||||
"version": "0.0.8",
|
"version": "0.0.5",
|
||||||
"description": "Basic circuits library for Circom",
|
"description": "Basic circuits library for Circom",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@@ -25,12 +25,11 @@
|
|||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"blake-hash": "^1.1.0",
|
"blake-hash": "^1.1.0",
|
||||||
"snarkjs": "0.1.11",
|
"snarkjs": "0.1.9",
|
||||||
"typedarray-to-buffer": "^3.1.5",
|
|
||||||
"web3": "^1.0.0-beta.36"
|
"web3": "^1.0.0-beta.36"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"circom": "0.0.28",
|
"circom": "0.0.24",
|
||||||
"eslint-plugin-mocha": "^5.2.0",
|
"eslint-plugin-mocha": "^5.2.0",
|
||||||
"ganache-cli": "^6.2.3",
|
"ganache-cli": "^6.2.3",
|
||||||
"mocha": "^5.2.0"
|
"mocha": "^5.2.0"
|
||||||
|
|||||||
@@ -22,14 +22,8 @@ function addPoint(a,b) {
|
|||||||
const d = bigInt("168696");
|
const d = bigInt("168696");
|
||||||
|
|
||||||
const res = [];
|
const res = [];
|
||||||
|
|
||||||
/* does the equivalent of:
|
|
||||||
res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(bigInt("1") + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
res[0] = bigInt((a[0]*b[1] + b[0]*a[1]) * bigInt(bigInt("1") + d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
||||||
res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(bigInt("1") - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
res[1] = bigInt((a[1]*b[1] - cta*a[0]*b[0]) * bigInt(bigInt("1") - d*a[0]*b[0]*a[1]*b[1]).inverse(q)).affine(q);
|
||||||
*/
|
|
||||||
res[0] = bigInt((bigInt(a[0]).mul(b[1]).add(bigInt(b[0]).mul(a[1]))).mul(bigInt(bigInt("1").add(d.mul(a[0]).mul(b[0]).mul(a[1]).mul(b[1]))).inverse(q))).affine(q);
|
|
||||||
res[1] = bigInt((bigInt(a[1]).mul(b[1]).sub(cta.mul(a[0]).mul(b[0]))).mul(bigInt(bigInt("1").sub(d.mul(a[0]).mul(b[0]).mul(a[1]).mul(b[1]))).inverse(q))).affine(q);
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,9 @@ const bigInt = require("snarkjs").bigInt;
|
|||||||
const babyJub = require("./babyjub");
|
const babyJub = require("./babyjub");
|
||||||
const pedersenHash = require("./pedersenHash").hash;
|
const pedersenHash = require("./pedersenHash").hash;
|
||||||
const mimc7 = require("./mimc7");
|
const mimc7 = require("./mimc7");
|
||||||
|
const crypto = require("crypto");
|
||||||
|
|
||||||
|
exports.cratePrvKey = cratePrvKey;
|
||||||
exports.prv2pub= prv2pub;
|
exports.prv2pub= prv2pub;
|
||||||
exports.sign = sign;
|
exports.sign = sign;
|
||||||
exports.signMiMC = signMiMC;
|
exports.signMiMC = signMiMC;
|
||||||
@@ -11,9 +13,12 @@ exports.verify = verify;
|
|||||||
exports.verifyMiMC = verifyMiMC;
|
exports.verifyMiMC = verifyMiMC;
|
||||||
exports.packSignature = packSignature;
|
exports.packSignature = packSignature;
|
||||||
exports.unpackSignature = unpackSignature;
|
exports.unpackSignature = unpackSignature;
|
||||||
exports.pruneBuffer = pruneBuffer;
|
|
||||||
|
|
||||||
|
|
||||||
|
function cratePrvKey() {
|
||||||
|
return crypto.randomBytes(32);
|
||||||
|
}
|
||||||
|
|
||||||
function pruneBuffer(_buff) {
|
function pruneBuffer(_buff) {
|
||||||
const buff = Buffer.from(_buff);
|
const buff = Buffer.from(_buff);
|
||||||
buff[0] = buff[0] & 0xF8;
|
buff[0] = buff[0] & 0xF8;
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
const Web3Utils = require("web3-utils");
|
const Web3 = require("web3");
|
||||||
|
const assert = require("assert");
|
||||||
|
|
||||||
class Contract {
|
class Contract {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -38,7 +39,7 @@ class Contract {
|
|||||||
genLoadedLength = C.code.length;
|
genLoadedLength = C.code.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Web3Utils.bytesToHex(C.code.concat(this.code));
|
return Web3.utils.bytesToHex(C.code.concat(this.code));
|
||||||
}
|
}
|
||||||
|
|
||||||
stop() { this.code.push(0x00); }
|
stop() { this.code.push(0x00); }
|
||||||
@@ -127,16 +128,12 @@ class Contract {
|
|||||||
|
|
||||||
|
|
||||||
jmp(label) {
|
jmp(label) {
|
||||||
if (typeof label !== "undefined") {
|
|
||||||
this._pushLabel(label);
|
this._pushLabel(label);
|
||||||
}
|
|
||||||
this.code.push(0x56);
|
this.code.push(0x56);
|
||||||
}
|
}
|
||||||
|
|
||||||
jmpi(label) {
|
jmpi(label) {
|
||||||
if (typeof label !== "undefined") {
|
|
||||||
this._pushLabel(label);
|
this._pushLabel(label);
|
||||||
}
|
|
||||||
this.code.push(0x57);
|
this.code.push(0x57);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,9 +141,7 @@ class Contract {
|
|||||||
msize() { this.code.push(0x59); }
|
msize() { this.code.push(0x59); }
|
||||||
gas() { this.code.push(0x5a); }
|
gas() { this.code.push(0x5a); }
|
||||||
label(name) {
|
label(name) {
|
||||||
if (typeof this.labels[name] != "undefined") {
|
assert(typeof this.labels[name] == "undefined", "Label already defined");
|
||||||
throw new Error("Label already defined");
|
|
||||||
}
|
|
||||||
this.labels[name] = this.code.length;
|
this.labels[name] = this.code.length;
|
||||||
this.code.push(0x5b);
|
this.code.push(0x5b);
|
||||||
|
|
||||||
@@ -154,24 +149,21 @@ class Contract {
|
|||||||
}
|
}
|
||||||
|
|
||||||
push(data) {
|
push(data) {
|
||||||
const d = Web3Utils.hexToBytes(Web3Utils.toHex(data));
|
const d = Web3.utils.hexToBytes(Web3.utils.toHex(data));
|
||||||
if (d.length == 0 || d.length > 32) {
|
assert(d.length>0);
|
||||||
throw new Error("Assertion failed");
|
assert(d.length<=32);
|
||||||
}
|
|
||||||
this.code = this.code.concat([0x5F + d.length], d);
|
this.code = this.code.concat([0x5F + d.length], d);
|
||||||
}
|
}
|
||||||
|
|
||||||
dup(n) {
|
dup(n) {
|
||||||
if (n < 0 || n >= 16) {
|
assert(n>=0);
|
||||||
throw new Error("Assertion failed");
|
assert(n<16);
|
||||||
}
|
|
||||||
this.code.push(0x80 + n);
|
this.code.push(0x80 + n);
|
||||||
}
|
}
|
||||||
|
|
||||||
swap(n) {
|
swap(n) {
|
||||||
if (n < 1 || n > 16) {
|
assert(n>=1);
|
||||||
throw new Error("Assertion failed");
|
assert(n<=16);
|
||||||
}
|
|
||||||
this.code.push(0x8f + n);
|
this.code.push(0x8f + n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
35
src/mimc7.js
35
src/mimc7.js
@@ -1,6 +1,6 @@
|
|||||||
const bn128 = require("snarkjs").bn128;
|
const bn128 = require("snarkjs").bn128;
|
||||||
const bigInt = require("snarkjs").bigInt;
|
const bigInt = require("snarkjs").bigInt;
|
||||||
const Web3Utils = require("web3-utils");
|
const Web3 = require("web3");
|
||||||
const F = bn128.Fr;
|
const F = bn128.Fr;
|
||||||
|
|
||||||
const SEED = "mimc";
|
const SEED = "mimc";
|
||||||
@@ -8,8 +8,8 @@ const NROUNDS = 91;
|
|||||||
|
|
||||||
exports.getIV = (seed) => {
|
exports.getIV = (seed) => {
|
||||||
if (typeof seed === "undefined") seed = SEED;
|
if (typeof seed === "undefined") seed = SEED;
|
||||||
const c = Web3Utils.keccak256(seed+"_iv");
|
const c = Web3.utils.keccak256(seed+"_iv");
|
||||||
const cn = bigInt(Web3Utils.toBN(c).toString());
|
const cn = bigInt(Web3.utils.toBN(c).toString());
|
||||||
const iv = cn.mod(F.q);
|
const iv = cn.mod(F.q);
|
||||||
return iv;
|
return iv;
|
||||||
};
|
};
|
||||||
@@ -18,13 +18,13 @@ exports.getConstants = (seed, nRounds) => {
|
|||||||
if (typeof seed === "undefined") seed = SEED;
|
if (typeof seed === "undefined") seed = SEED;
|
||||||
if (typeof nRounds === "undefined") nRounds = NROUNDS;
|
if (typeof nRounds === "undefined") nRounds = NROUNDS;
|
||||||
const cts = new Array(nRounds);
|
const cts = new Array(nRounds);
|
||||||
let c = Web3Utils.keccak256(SEED);
|
let c = Web3.utils.keccak256(SEED);
|
||||||
for (let i=1; i<nRounds; i++) {
|
for (let i=1; i<nRounds; i++) {
|
||||||
c = Web3Utils.keccak256(c);
|
c = Web3.utils.keccak256(c);
|
||||||
|
|
||||||
const n1 = Web3Utils.toBN(c).mod(Web3Utils.toBN(F.q.toString()));
|
const n1 = Web3.utils.toBN(c).mod(Web3.utils.toBN(F.q.toString()));
|
||||||
const c2 = Web3Utils.padLeft(Web3Utils.toHex(n1), 64);
|
const c2 = Web3.utils.padLeft(Web3.utils.toHex(n1), 64);
|
||||||
cts[i] = bigInt(Web3Utils.toBN(c2).toString());
|
cts[i] = bigInt(Web3.utils.toBN(c2).toString());
|
||||||
}
|
}
|
||||||
cts[0] = bigInt(0);
|
cts[0] = bigInt(0);
|
||||||
return cts;
|
return cts;
|
||||||
@@ -44,21 +44,10 @@ exports.hash = (_x_in, _k) =>{
|
|||||||
return F.affine(F.add(r, k));
|
return F.affine(F.add(r, k));
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.multiHash = (arr, key) => {
|
exports.multiHash = (arr) => {
|
||||||
let r;
|
let r = exports.getIV();
|
||||||
if (typeof(key) === "undefined") {
|
|
||||||
r = F.zero;
|
|
||||||
} else {
|
|
||||||
r = key;
|
|
||||||
}
|
|
||||||
for (let i=0; i<arr.length; i++) {
|
for (let i=0; i<arr.length; i++) {
|
||||||
r = F.add(
|
r = exports.hash(r, bigInt(arr[i]));
|
||||||
F.add(
|
|
||||||
r,
|
|
||||||
arr[i]
|
|
||||||
),
|
|
||||||
exports.hash(bigInt(arr[i]), r)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return F.affine(r);
|
return r;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
// License: LGPL-3.0+
|
// License: LGPL-3.0+
|
||||||
//
|
//
|
||||||
|
|
||||||
const Web3Utils = require("web3-utils");
|
const Web3 = require("web3");
|
||||||
|
|
||||||
const Contract = require("./evmasm");
|
const Contract = require("./evmasm");
|
||||||
|
|
||||||
function createCode(seed, n) {
|
function createCode(seed, n) {
|
||||||
|
|
||||||
let ci = Web3Utils.keccak256(seed);
|
let ci = Web3.utils.keccak256(seed);
|
||||||
|
|
||||||
const C = new Contract();
|
const C = new Contract();
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ function createCode(seed, n) {
|
|||||||
C.mulmod(); // r=t^7 k q
|
C.mulmod(); // r=t^7 k q
|
||||||
|
|
||||||
for (let i=0; i<n-1; i++) {
|
for (let i=0; i<n-1; i++) {
|
||||||
ci = Web3Utils.keccak256(ci);
|
ci = Web3.utils.keccak256(ci);
|
||||||
C.dup(2); // q r k q
|
C.dup(2); // q r k q
|
||||||
C.dup(0); // q q r k q
|
C.dup(0); // q q r k q
|
||||||
C.dup(0); // q q q r k q
|
C.dup(0); // q q q r k q
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const bn128 = require("snarkjs").bn128;
|
const bn128 = require("snarkjs").bn128;
|
||||||
const bigInt = require("snarkjs").bigInt;
|
const bigInt = require("snarkjs").bigInt;
|
||||||
const babyJub = require("./babyjub");
|
const babyJub = require("./babyjub");
|
||||||
|
const assert = require("assert");
|
||||||
const createBlakeHash = require("blake-hash");
|
const createBlakeHash = require("blake-hash");
|
||||||
|
|
||||||
const GENPOINT_PREFIX = "PedersenGenerator";
|
const GENPOINT_PREFIX = "PedersenGenerator";
|
||||||
@@ -72,9 +73,7 @@ function getBasePoint(pointIdx) {
|
|||||||
|
|
||||||
const p8 = babyJub.mulPointEscalar(p, 8);
|
const p8 = babyJub.mulPointEscalar(p, 8);
|
||||||
|
|
||||||
if (!babyJub.inSubgroup(p8)) {
|
assert(babyJub.inSubgroup(p8), "Point not in curve");
|
||||||
throw new Error("Point not in curve");
|
|
||||||
}
|
|
||||||
|
|
||||||
bases[pointIdx] = p8;
|
bases[pointIdx] = p8;
|
||||||
return p8;
|
return p8;
|
||||||
|
|||||||
115
src/poseidon.js
115
src/poseidon.js
@@ -1,115 +0,0 @@
|
|||||||
const bn128 = require("snarkjs").bn128;
|
|
||||||
const bigInt = require("snarkjs").bigInt;
|
|
||||||
const createBlakeHash = require("blake-hash");
|
|
||||||
const assert = require("assert");
|
|
||||||
const F = bn128.Fr;
|
|
||||||
|
|
||||||
const SEED = "poseidon";
|
|
||||||
const NROUNDSF = 8;
|
|
||||||
const NROUNDSP = 57;
|
|
||||||
const T = 6;
|
|
||||||
|
|
||||||
function getPseudoRandom(seed, n) {
|
|
||||||
const res = [];
|
|
||||||
let h = createBlakeHash("blake256").update(seed).digest();
|
|
||||||
while (res.length<n) {
|
|
||||||
const n = F.affine(bigInt.leBuff2int(h));
|
|
||||||
res.push(n);
|
|
||||||
h = createBlakeHash("blake256").update(h).digest();
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
function allDifferent(v) {
|
|
||||||
for (let i=0; i<v.length; i++) {
|
|
||||||
if (v[i].isZero()) return false;
|
|
||||||
for (let j=i+1; j<v.length; j++) {
|
|
||||||
if (v[i].equals(v[j])) return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.getMatrix = (t, seed, nRounds) => {
|
|
||||||
if (typeof seed === "undefined") seed = SEED;
|
|
||||||
if (typeof nRounds === "undefined") nRounds = NROUNDSF + NROUNDSP;
|
|
||||||
if (typeof t === "undefined") t = T;
|
|
||||||
let nonce = "0000";
|
|
||||||
let cmatrix = getPseudoRandom(seed+"_matrix_"+nonce, t*2);
|
|
||||||
while (!allDifferent(cmatrix)) {
|
|
||||||
nonce = (Number(nonce)+1)+"";
|
|
||||||
while(nonce.length<4) nonce = "0"+nonce;
|
|
||||||
cmatrix = getPseudoRandom(seed+"_matrix_"+nonce, t*2);
|
|
||||||
}
|
|
||||||
|
|
||||||
const M = new Array(t);
|
|
||||||
for (let i=0; i<t; i++) {
|
|
||||||
M[i] = new Array(t);
|
|
||||||
for (let j=0; j<t; j++) {
|
|
||||||
M[i][j] = F.affine(F.inverse(F.sub(cmatrix[i], cmatrix[t+j])));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return M;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.getConstants = (t, seed, nRounds) => {
|
|
||||||
if (typeof seed === "undefined") seed = SEED;
|
|
||||||
if (typeof nRounds === "undefined") nRounds = NROUNDSF + NROUNDSP;
|
|
||||||
if (typeof t === "undefined") t = T;
|
|
||||||
const cts = getPseudoRandom(seed+"_constants", nRounds);
|
|
||||||
return cts;
|
|
||||||
};
|
|
||||||
|
|
||||||
function ark(state, c) {
|
|
||||||
for (let j=0; j<state.length; j++ ) {
|
|
||||||
state[j] = F.add(state[j], c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sigma(a) {
|
|
||||||
return F.mul(a, F.square(F.square(a,a)));
|
|
||||||
}
|
|
||||||
|
|
||||||
function mix(state, M) {
|
|
||||||
const newState = new Array(state.length);
|
|
||||||
for (let i=0; i<state.length; i++) {
|
|
||||||
newState[i] = F.zero;
|
|
||||||
for (let j=0; j<state.length; j++) {
|
|
||||||
newState[i] = F.add(newState[i], F.mul(M[i][j], state[j]) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i=0; i<state.length; i++) state[i] = newState[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.createHash = (t, nRoundsF, nRoundsP, seed) => {
|
|
||||||
|
|
||||||
if (typeof seed === "undefined") seed = SEED;
|
|
||||||
if (typeof nRoundsF === "undefined") nRoundsF = NROUNDSF;
|
|
||||||
if (typeof nRoundsP === "undefined") nRoundsP = NROUNDSP;
|
|
||||||
if (typeof t === "undefined") t = T;
|
|
||||||
|
|
||||||
assert(nRoundsF % 2 == 0);
|
|
||||||
const C = exports.getConstants(t, seed, nRoundsF + nRoundsP);
|
|
||||||
const M = exports.getMatrix(t, seed, nRoundsF + nRoundsP);
|
|
||||||
return function(inputs) {
|
|
||||||
let state = [];
|
|
||||||
assert(inputs.length < t);
|
|
||||||
assert(inputs.length > 0);
|
|
||||||
for (let i=0; i<inputs.length; i++) state[i] = bigInt(inputs[i]);
|
|
||||||
for (let i=inputs.length; i<t; i++) state[i] = F.zero;
|
|
||||||
|
|
||||||
for (let i=0; i< nRoundsF + nRoundsP; i++) {
|
|
||||||
ark(state, C[i]);
|
|
||||||
if ((i<nRoundsF/2) || (i >= nRoundsF/2 + nRoundsP)) {
|
|
||||||
for (let j=0; j<t; j++) state[j] = sigma(state[j]);
|
|
||||||
} else {
|
|
||||||
state[0] = sigma(state[0]);
|
|
||||||
}
|
|
||||||
mix(state, M);
|
|
||||||
}
|
|
||||||
return F.affine(state[0]);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,180 +0,0 @@
|
|||||||
// 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;
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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 +0,0 @@
|
|||||||
const poseidonGenContract = require("./poseidon_gencontract");
|
|
||||||
|
|
||||||
|
|
||||||
console.log(poseidonGenContract.createCode(6, 8, 57));
|
|
||||||
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
34
src/smt.js
34
src/smt.js
@@ -1,7 +1,7 @@
|
|||||||
const bigInt = require("snarkjs").bigInt;
|
const bigInt = require("snarkjs").bigInt;
|
||||||
|
|
||||||
const SMTMemDB = require("./smt_memdb");
|
const SMTMemDB = require("./smt_memdb");
|
||||||
const {hash0, hash1} = require("./smt_hashes_poseidon");
|
const mimc7 = require("./mimc7");
|
||||||
|
|
||||||
class SMT {
|
class SMT {
|
||||||
|
|
||||||
@@ -46,8 +46,8 @@ class SMT {
|
|||||||
const ins = [];
|
const ins = [];
|
||||||
const dels = [];
|
const dels = [];
|
||||||
|
|
||||||
let rtOld = hash1(key, resFind.foundValue);
|
let rtOld = mimc7.multiHash([1, key, resFind.foundValue]);
|
||||||
let rtNew = hash1(key, newValue);
|
let rtNew = mimc7.multiHash([1, key, newValue]);
|
||||||
ins.push([rtNew, [1, key, newValue ]]);
|
ins.push([rtNew, [1, key, newValue ]]);
|
||||||
dels.push(rtOld);
|
dels.push(rtOld);
|
||||||
|
|
||||||
@@ -59,11 +59,11 @@ class SMT {
|
|||||||
oldNode = [sibling, rtOld];
|
oldNode = [sibling, rtOld];
|
||||||
newNode = [sibling, rtNew];
|
newNode = [sibling, rtNew];
|
||||||
} else {
|
} else {
|
||||||
oldNode = [rtOld, sibling];
|
oldNode = [rtOld, sibling, ];
|
||||||
newNode = [rtNew, sibling];
|
newNode = [rtNew, sibling, ];
|
||||||
}
|
}
|
||||||
rtOld = hash0(oldNode[0], oldNode[1]);
|
rtOld = mimc7.multiHash(oldNode);
|
||||||
rtNew = hash0(newNode[0], newNode[1]);
|
rtNew = mimc7.multiHash(newNode);
|
||||||
dels.push(rtOld);
|
dels.push(rtOld);
|
||||||
ins.push([rtNew, newNode]);
|
ins.push([rtNew, newNode]);
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ class SMT {
|
|||||||
|
|
||||||
const dels = [];
|
const dels = [];
|
||||||
const ins = [];
|
const ins = [];
|
||||||
let rtOld = hash1(key, resFind.foundValue);
|
let rtOld = mimc7.multiHash([1, key, resFind.foundValue]);
|
||||||
let rtNew;
|
let rtNew;
|
||||||
dels.push(rtOld);
|
dels.push(rtOld);
|
||||||
|
|
||||||
@@ -130,9 +130,9 @@ class SMT {
|
|||||||
}
|
}
|
||||||
const oldSibling = resFind.siblings[level];
|
const oldSibling = resFind.siblings[level];
|
||||||
if (keyBits[level]) {
|
if (keyBits[level]) {
|
||||||
rtOld = hash0(oldSibling, rtOld);
|
rtOld = mimc7.multiHash([oldSibling, rtOld]);
|
||||||
} else {
|
} else {
|
||||||
rtOld = hash0(rtOld, oldSibling);
|
rtOld = mimc7.multiHash([rtOld, oldSibling]);
|
||||||
}
|
}
|
||||||
dels.push(rtOld);
|
dels.push(rtOld);
|
||||||
if (!newSibling.isZero()) {
|
if (!newSibling.isZero()) {
|
||||||
@@ -147,7 +147,7 @@ class SMT {
|
|||||||
} else {
|
} else {
|
||||||
newNode = [rtNew, newSibling];
|
newNode = [rtNew, newSibling];
|
||||||
}
|
}
|
||||||
rtNew = hash0(newNode[0], newNode[1]);
|
rtNew = mimc7.multiHash(newNode);
|
||||||
ins.push([rtNew, newNode]);
|
ins.push([rtNew, newNode]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,7 +185,7 @@ class SMT {
|
|||||||
for (let i= res.siblings.length; oldKeyits[i] == newKeyBits[i]; i++) {
|
for (let i= res.siblings.length; oldKeyits[i] == newKeyBits[i]; i++) {
|
||||||
res.siblings.push(bigInt.zero);
|
res.siblings.push(bigInt.zero);
|
||||||
}
|
}
|
||||||
rtOld = hash1(resFind.notFoundKey, resFind.notFoundValue);
|
rtOld = mimc7.multiHash([1, resFind.notFoundKey, resFind.notFoundValue]);
|
||||||
res.siblings.push(rtOld);
|
res.siblings.push(rtOld);
|
||||||
addedOne = true;
|
addedOne = true;
|
||||||
mixed = false;
|
mixed = false;
|
||||||
@@ -197,7 +197,7 @@ class SMT {
|
|||||||
const inserts = [];
|
const inserts = [];
|
||||||
const dels = [];
|
const dels = [];
|
||||||
|
|
||||||
let rt = hash1(key, value);
|
let rt = mimc7.multiHash([1, key, value]);
|
||||||
inserts.push([rt,[1, key, value]] );
|
inserts.push([rt,[1, key, value]] );
|
||||||
|
|
||||||
for (let i=res.siblings.length-1; i>=0; i--) {
|
for (let i=res.siblings.length-1; i>=0; i--) {
|
||||||
@@ -207,9 +207,9 @@ class SMT {
|
|||||||
if (mixed) {
|
if (mixed) {
|
||||||
const oldSibling = resFind.siblings[i];
|
const oldSibling = resFind.siblings[i];
|
||||||
if (newKeyBits[i]) {
|
if (newKeyBits[i]) {
|
||||||
rtOld = hash0(oldSibling, rtOld);
|
rtOld = mimc7.multiHash([oldSibling, rtOld]);
|
||||||
} else {
|
} else {
|
||||||
rtOld = hash0(rtOld, oldSibling);
|
rtOld = mimc7.multiHash([rtOld, oldSibling]);
|
||||||
}
|
}
|
||||||
dels.push(rtOld);
|
dels.push(rtOld);
|
||||||
}
|
}
|
||||||
@@ -217,10 +217,10 @@ class SMT {
|
|||||||
|
|
||||||
let newRt;
|
let newRt;
|
||||||
if (newKeyBits[i]) {
|
if (newKeyBits[i]) {
|
||||||
newRt = hash0(res.siblings[i], rt);
|
newRt = mimc7.multiHash([res.siblings[i], rt]);
|
||||||
inserts.push([newRt,[res.siblings[i], rt]] );
|
inserts.push([newRt,[res.siblings[i], rt]] );
|
||||||
} else {
|
} else {
|
||||||
newRt = hash0(rt, res.siblings[i]);
|
newRt = mimc7.multiHash([rt, res.siblings[i]]);
|
||||||
inserts.push([newRt,[rt, res.siblings[i]]] );
|
inserts.push([newRt,[rt, res.siblings[i]]] );
|
||||||
}
|
}
|
||||||
rt = newRt;
|
rt = newRt;
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
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);
|
|
||||||
};
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
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]);
|
|
||||||
};
|
|
||||||
@@ -3,12 +3,10 @@ const path = require("path");
|
|||||||
const snarkjs = require("snarkjs");
|
const snarkjs = require("snarkjs");
|
||||||
const compiler = require("circom");
|
const compiler = require("circom");
|
||||||
|
|
||||||
const createBlakeHash = require("blake-hash");
|
|
||||||
const eddsa = require("../src/eddsa.js");
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
const assert = chai.assert;
|
||||||
|
|
||||||
const bigInt = require("snarkjs").bigInt;
|
const bigInt = require("big-integer");
|
||||||
|
|
||||||
|
|
||||||
describe("Baby Jub test", function () {
|
describe("Baby Jub test", function () {
|
||||||
let circuitAdd;
|
let circuitAdd;
|
||||||
@@ -24,11 +22,6 @@ describe("Baby Jub test", function () {
|
|||||||
const cirDefTest = await compiler(path.join(__dirname, "circuits", "babycheck_test.circom"));
|
const cirDefTest = await compiler(path.join(__dirname, "circuits", "babycheck_test.circom"));
|
||||||
circuitTest = new snarkjs.Circuit(cirDefTest);
|
circuitTest = new snarkjs.Circuit(cirDefTest);
|
||||||
console.log("NConstrains BabyTest: " + circuitTest.nConstraints);
|
console.log("NConstrains BabyTest: " + circuitTest.nConstraints);
|
||||||
|
|
||||||
const cirDefPbk = await compiler(path.join(__dirname, "circuits", "babypbk_test.circom"));
|
|
||||||
circuitPbk = new snarkjs.Circuit(cirDefPbk);
|
|
||||||
console.log("NConstrains BabyPbk: " + circuitPbk.nConstraints);
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should add point (0,1) and (0,1)", async () => {
|
it("Should add point (0,1) and (0,1)", async () => {
|
||||||
@@ -104,22 +97,4 @@ describe("Baby Jub test", function () {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should extract the public key from the private one", async () => {
|
|
||||||
|
|
||||||
const rawpvk = Buffer.from("0001020304050607080900010203040506070809000102030405060708090021", "hex");
|
|
||||||
const pvk = eddsa.pruneBuffer(createBlakeHash("blake512").update(rawpvk).digest().slice(0,32));
|
|
||||||
const S = bigInt.leBuff2int(pvk).shr(3);
|
|
||||||
|
|
||||||
const A = eddsa.prv2pub(rawpvk);
|
|
||||||
|
|
||||||
const input = {
|
|
||||||
in : S,
|
|
||||||
Ax : A[0],
|
|
||||||
Ay : A[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
const w = circuitPbk.calculateWitness(input);
|
|
||||||
assert(circuitPbk.checkWitness(w));
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
include "../../circuits/babyjub.circom";
|
|
||||||
|
|
||||||
component main = BabyPbk();
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
include "../../circuits/poseidon.circom"
|
|
||||||
|
|
||||||
component main = Poseidon(2, 6, 8, 57);
|
|
||||||
@@ -2,7 +2,6 @@ const chai = require("chai");
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
const snarkjs = require("snarkjs");
|
const snarkjs = require("snarkjs");
|
||||||
const compiler = require("circom");
|
const compiler = require("circom");
|
||||||
// const crypto = require("crypto");
|
|
||||||
|
|
||||||
const eddsa = require("../src/eddsa.js");
|
const eddsa = require("../src/eddsa.js");
|
||||||
const babyJub = require("../src/babyjub.js");
|
const babyJub = require("../src/babyjub.js");
|
||||||
@@ -46,7 +45,7 @@ describe("EdDSA test", function () {
|
|||||||
it("Sign a single 10 bytes from 0 to 9", async () => {
|
it("Sign a single 10 bytes from 0 to 9", async () => {
|
||||||
const msg = Buffer.from("00010203040506070809", "hex");
|
const msg = Buffer.from("00010203040506070809", "hex");
|
||||||
|
|
||||||
// const prvKey = crypto.randomBytes(32);
|
// const prvKey = eddsa.cratePrvKey();
|
||||||
|
|
||||||
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
const prvKey = Buffer.from("0001020304050607080900010203040506070809000102030405060708090001", "hex");
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const assert = chai.assert;
|
|||||||
|
|
||||||
const bigInt = snarkjs.bigInt;
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
describe("EdDSA MiMC test", function () {
|
describe("EdDSA test", function () {
|
||||||
let circuit;
|
let circuit;
|
||||||
|
|
||||||
this.timeout(100000);
|
this.timeout(100000);
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
const chai = require("chai");
|
|
||||||
const path = require("path");
|
|
||||||
const snarkjs = require("snarkjs");
|
|
||||||
const compiler = require("circom");
|
|
||||||
|
|
||||||
const poseidon = require("../src/poseidon.js");
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
|
||||||
|
|
||||||
describe("Poseidon Circuit test", function () {
|
|
||||||
let circuit;
|
|
||||||
|
|
||||||
this.timeout(100000);
|
|
||||||
|
|
||||||
before( async () => {
|
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "poseidon_test.circom"));
|
|
||||||
|
|
||||||
circuit = new snarkjs.Circuit(cirDef);
|
|
||||||
|
|
||||||
console.log("Poseidon constraints: " + circuit.nConstraints);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Should check constrain", async () => {
|
|
||||||
const w = circuit.calculateWitness({inputs: [1, 2]});
|
|
||||||
|
|
||||||
const res = w[circuit.getSignalIdx("main.out")];
|
|
||||||
|
|
||||||
const hash = poseidon.createHash(6, 8, 57);
|
|
||||||
|
|
||||||
const res2 = hash([1,2]);
|
|
||||||
|
|
||||||
console.log(res.toString());
|
|
||||||
|
|
||||||
assert.equal(res.toString(), res2.toString());
|
|
||||||
|
|
||||||
assert(circuit.checkWitness(w));
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
const TestRPC = require("ganache-cli");
|
|
||||||
const Web3 = require("web3");
|
|
||||||
const chai = require("chai");
|
|
||||||
const poseidonGenContract = require("../src/poseidon_gencontract.js");
|
|
||||||
const Poseidon = require("../src/poseidon.js");
|
|
||||||
const bigInt = require("snarkjs").bigInt;
|
|
||||||
|
|
||||||
const assert = chai.assert;
|
|
||||||
const log = (msg) => { if (process.env.MOCHA_VERBOSE) console.log(msg); };
|
|
||||||
|
|
||||||
const SEED = "mimc";
|
|
||||||
|
|
||||||
describe("Poseidon Smart contract test", () => {
|
|
||||||
let testrpc;
|
|
||||||
let web3;
|
|
||||||
let mimc;
|
|
||||||
let accounts;
|
|
||||||
|
|
||||||
before(async () => {
|
|
||||||
testrpc = TestRPC.server({
|
|
||||||
ws: true,
|
|
||||||
gasLimit: 5800000,
|
|
||||||
total_accounts: 10,
|
|
||||||
});
|
|
||||||
|
|
||||||
testrpc.listen(8546, "127.0.0.1");
|
|
||||||
|
|
||||||
web3 = new Web3("ws://127.0.0.1:8546");
|
|
||||||
accounts = await web3.eth.getAccounts();
|
|
||||||
});
|
|
||||||
|
|
||||||
after(async () => testrpc.close());
|
|
||||||
|
|
||||||
it("Should deploy the contract", async () => {
|
|
||||||
const C = new web3.eth.Contract(poseidonGenContract.abi);
|
|
||||||
|
|
||||||
mimc = await C.deploy({
|
|
||||||
data: poseidonGenContract.createCode()
|
|
||||||
}).send({
|
|
||||||
gas: 2500000,
|
|
||||||
from: accounts[0]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Shold calculate the mimic correctly", async () => {
|
|
||||||
|
|
||||||
const res = await mimc.methods.poseidon([1,2]).call();
|
|
||||||
|
|
||||||
// console.log("Cir: " + bigInt(res.toString(16)).toString(16));
|
|
||||||
|
|
||||||
const hash = Poseidon.createHash(6, 8, 57);
|
|
||||||
|
|
||||||
const res2 = hash([1,2]);
|
|
||||||
// console.log("Ref: " + bigInt(res2).toString(16));
|
|
||||||
|
|
||||||
assert.equal(res.toString(), res2.toString());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ describe("SMT test", function () {
|
|||||||
let circuit;
|
let circuit;
|
||||||
let tree;
|
let tree;
|
||||||
|
|
||||||
this.timeout(10000000);
|
this.timeout(100000);
|
||||||
|
|
||||||
before( async () => {
|
before( async () => {
|
||||||
const cirDef = await compiler(path.join(__dirname, "circuits", "smtprocessor10_test.circom"));
|
const cirDef = await compiler(path.join(__dirname, "circuits", "smtprocessor10_test.circom"));
|
||||||
|
|||||||
231
test/smttestvectors.js
Normal file
231
test/smttestvectors.js
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
const chai = require("chai");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
|
|
||||||
|
const smt = require("../src/smt.js");
|
||||||
|
const mimcjs = require("../src/mimc7.js");
|
||||||
|
|
||||||
|
const assert = chai.assert;
|
||||||
|
const expect = chai.expect;
|
||||||
|
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
|
||||||
|
function stringifyBigInts(o) {
|
||||||
|
if ((typeof(o) == "bigint") || (o instanceof bigInt)) {
|
||||||
|
return o.toString(10);
|
||||||
|
} else if (Array.isArray(o)) {
|
||||||
|
return o.map(stringifyBigInts);
|
||||||
|
} else if (typeof o == "object") {
|
||||||
|
const res = {};
|
||||||
|
for (let k in o) {
|
||||||
|
res[k] = stringifyBigInts(o[k]);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
} else {
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function newEntryFromInts(a, b, c, d) {
|
||||||
|
return {
|
||||||
|
hi: mimcjs.hash(c, d),
|
||||||
|
hv: mimcjs.hash(a, b),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function smtHash(arr) {
|
||||||
|
let r = bigInt(0);
|
||||||
|
for (let i=0; i<arr.length; i++) {
|
||||||
|
r = mimcjs.hash(r, bigInt(arr[i]), 91 );
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("SMT Javascript test", function () {
|
||||||
|
this.timeout(100000);
|
||||||
|
before( async () => {
|
||||||
|
});
|
||||||
|
|
||||||
|
it("test MIMC7", async() => {
|
||||||
|
//const h = mimcjs.multiHash(1,2,3);
|
||||||
|
//const h = smtHash([1,2,3]);
|
||||||
|
//console.log(h.toString(10));
|
||||||
|
|
||||||
|
const mimcjs = require("../src/mimc7.js");
|
||||||
|
const snarkjs = require("snarkjs");
|
||||||
|
const bigInt = snarkjs.bigInt;
|
||||||
|
const smt = require("../src/smt.js");
|
||||||
|
|
||||||
|
h = mimcjs.hash(1,2,91);
|
||||||
|
console.log(h);
|
||||||
|
|
||||||
|
function smtHash(arr) {
|
||||||
|
let r = bigInt(0);
|
||||||
|
for (let i=0; i<arr.length; i++) {
|
||||||
|
r = mimcjs.hash(r, bigInt(arr[i]), 91 );
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(smtHash([1, 2, 3]));
|
||||||
|
// Test from old ver
|
||||||
|
});
|
||||||
|
|
||||||
|
//it("Should calculate hindex", async() => {
|
||||||
|
// const entry = newEntryFromInts(12, 45, 78, 41);
|
||||||
|
// //console.log(entry.hi.toString(16));
|
||||||
|
// expect(entry.hi.toString(16)).to.be.
|
||||||
|
// equal("114438e8321f62c4a1708f443a5a66f9c8fcb0958e7b7008332b71442610b7a0");
|
||||||
|
//});
|
||||||
|
|
||||||
|
//it("Should insert 2 elements and empty them", async () => {
|
||||||
|
// const tree = await smt.newMemEmptyTrie();
|
||||||
|
// const key1 = bigInt(111);
|
||||||
|
// const value1 = bigInt(222);
|
||||||
|
// const key2 = bigInt(333);
|
||||||
|
// const value2 = bigInt(444);
|
||||||
|
|
||||||
|
// await tree.insert(key1,value1);
|
||||||
|
// await tree.insert(key2,value2);
|
||||||
|
// await tree.delete(key2);
|
||||||
|
// await tree.delete(key1);
|
||||||
|
|
||||||
|
// assert(tree.root.isZero());
|
||||||
|
//});
|
||||||
|
|
||||||
|
//it("Should insert 3 elements in dferent order and should be the same", async () => {
|
||||||
|
// const keys = [bigInt(8), bigInt(9), bigInt(32)];
|
||||||
|
// const values = [bigInt(88), bigInt(99), bigInt(3232)];
|
||||||
|
// const tree1 = await smt.newMemEmptyTrie();
|
||||||
|
// const tree2 = await smt.newMemEmptyTrie();
|
||||||
|
// const tree3 = await smt.newMemEmptyTrie();
|
||||||
|
// const tree4 = await smt.newMemEmptyTrie();
|
||||||
|
// const tree5 = await smt.newMemEmptyTrie();
|
||||||
|
// const tree6 = await smt.newMemEmptyTrie();
|
||||||
|
|
||||||
|
// await tree1.insert(keys[0],values[0]);
|
||||||
|
// await tree1.insert(keys[1],values[1]);
|
||||||
|
// await tree1.insert(keys[2],values[2]);
|
||||||
|
|
||||||
|
// await tree2.insert(keys[0],values[0]);
|
||||||
|
// await tree2.insert(keys[2],values[2]);
|
||||||
|
// await tree2.insert(keys[1],values[1]);
|
||||||
|
|
||||||
|
// await tree3.insert(keys[1],values[1]);
|
||||||
|
// await tree3.insert(keys[0],values[0]);
|
||||||
|
// await tree3.insert(keys[2],values[2]);
|
||||||
|
|
||||||
|
// await tree4.insert(keys[1],values[1]);
|
||||||
|
// await tree4.insert(keys[2],values[2]);
|
||||||
|
// await tree4.insert(keys[0],values[0]);
|
||||||
|
|
||||||
|
// await tree5.insert(keys[2],values[2]);
|
||||||
|
// await tree5.insert(keys[0],values[0]);
|
||||||
|
// await tree5.insert(keys[1],values[1]);
|
||||||
|
|
||||||
|
// await tree6.insert(keys[2],values[2]);
|
||||||
|
// await tree6.insert(keys[1],values[1]);
|
||||||
|
// await tree6.insert(keys[0],values[0]);
|
||||||
|
|
||||||
|
// assert(tree1.root.equals(tree2.root));
|
||||||
|
// assert(tree2.root.equals(tree3.root));
|
||||||
|
// assert(tree3.root.equals(tree4.root));
|
||||||
|
// assert(tree4.root.equals(tree5.root));
|
||||||
|
// assert(tree5.root.equals(tree6.root));
|
||||||
|
|
||||||
|
// assert.equal(Object.keys(tree1.db.nodes).length, Object.keys(tree2.db.nodes).length);
|
||||||
|
// assert.equal(Object.keys(tree2.db.nodes).length, Object.keys(tree3.db.nodes).length);
|
||||||
|
// assert.equal(Object.keys(tree3.db.nodes).length, Object.keys(tree4.db.nodes).length);
|
||||||
|
// assert.equal(Object.keys(tree4.db.nodes).length, Object.keys(tree5.db.nodes).length);
|
||||||
|
// assert.equal(Object.keys(tree5.db.nodes).length, Object.keys(tree6.db.nodes).length);
|
||||||
|
|
||||||
|
// await tree1.delete(keys[0]);
|
||||||
|
// await tree1.delete(keys[1]);
|
||||||
|
// await tree2.delete(keys[1]);
|
||||||
|
// await tree2.delete(keys[0]);
|
||||||
|
// assert(tree1.root.equals(tree2.root));
|
||||||
|
|
||||||
|
// await tree3.delete(keys[0]);
|
||||||
|
// await tree3.delete(keys[2]);
|
||||||
|
// await tree4.delete(keys[2]);
|
||||||
|
// await tree4.delete(keys[0]);
|
||||||
|
// assert(tree3.root.equals(tree4.root));
|
||||||
|
|
||||||
|
// await tree5.delete(keys[1]);
|
||||||
|
// await tree5.delete(keys[2]);
|
||||||
|
// await tree6.delete(keys[2]);
|
||||||
|
// await tree6.delete(keys[1]);
|
||||||
|
// assert(tree5.root.equals(tree6.root));
|
||||||
|
|
||||||
|
// await tree1.delete(keys[2]);
|
||||||
|
// await tree2.delete(keys[2]);
|
||||||
|
// await tree3.delete(keys[1]);
|
||||||
|
// await tree4.delete(keys[1]);
|
||||||
|
// await tree5.delete(keys[0]);
|
||||||
|
// await tree6.delete(keys[0]);
|
||||||
|
|
||||||
|
// assert(tree1.root.isZero());
|
||||||
|
// assert(tree2.root.isZero());
|
||||||
|
// assert(tree3.root.isZero());
|
||||||
|
// assert(tree4.root.isZero());
|
||||||
|
// assert(tree5.root.isZero());
|
||||||
|
// assert(tree6.root.isZero());
|
||||||
|
|
||||||
|
// assert.equal(Object.keys(tree1.db.nodes).length, 0);
|
||||||
|
// assert.equal(Object.keys(tree2.db.nodes).length, 0);
|
||||||
|
// assert.equal(Object.keys(tree3.db.nodes).length, 0);
|
||||||
|
// assert.equal(Object.keys(tree4.db.nodes).length, 0);
|
||||||
|
// assert.equal(Object.keys(tree5.db.nodes).length, 0);
|
||||||
|
// assert.equal(Object.keys(tree6.db.nodes).length, 0);
|
||||||
|
//});
|
||||||
|
|
||||||
|
//it("Insert and remove 100 numbers randomly", async () => {
|
||||||
|
// function perm(a) {
|
||||||
|
// const arr = a.slice();
|
||||||
|
// const rArr = [];
|
||||||
|
// for (let i=0; i<arr.length; i++) {
|
||||||
|
// let rIdx = Math.floor(Math.random() * (arr.length - i));
|
||||||
|
// rArr.push(arr[rIdx]);
|
||||||
|
// arr[rIdx] = arr[arr.length - i - 1];
|
||||||
|
// }
|
||||||
|
// return rArr;
|
||||||
|
// }
|
||||||
|
// const tree = await smt.newMemEmptyTrie();
|
||||||
|
// const arr = [];
|
||||||
|
// const N = 100;
|
||||||
|
// for (let i=0; i<N; i++) {
|
||||||
|
// arr.push(bigInt(i));
|
||||||
|
// }
|
||||||
|
// const insArr = perm(arr);
|
||||||
|
// for (let i=0; i<N; i++) {
|
||||||
|
// await tree.insert(insArr[i], i);
|
||||||
|
// }
|
||||||
|
// const delArr = perm(insArr);
|
||||||
|
// for (let i=0; i<N; i++) {
|
||||||
|
// await tree.delete(delArr[i]);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// assert(tree.root.isZero());
|
||||||
|
// assert.equal(Object.keys(tree.db.nodes).length, 0);
|
||||||
|
//});
|
||||||
|
|
||||||
|
//it("Should test update", async () => {
|
||||||
|
// const tree1 = await smt.newMemEmptyTrie();
|
||||||
|
// const tree2 = await smt.newMemEmptyTrie();
|
||||||
|
|
||||||
|
// await tree1.insert(8,88);
|
||||||
|
// await tree1.insert(9,99,);
|
||||||
|
// await tree1.insert(32,3232);
|
||||||
|
|
||||||
|
// await tree2.insert(8,888);
|
||||||
|
// await tree2.insert(9,999);
|
||||||
|
// await tree2.insert(32,323232);
|
||||||
|
|
||||||
|
// await tree1.update(8, 888);
|
||||||
|
// await tree1.update(9, 999);
|
||||||
|
// await tree1.update(32, 323232);
|
||||||
|
|
||||||
|
// assert(tree1.root.equals(tree2.root));
|
||||||
|
//});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
Reference in New Issue
Block a user