From ba7db5d456e1cc13a3d4695ddfe00f1547738198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Men=C3=A9ndez?= Date: Thu, 14 Nov 2024 17:35:38 +0100 Subject: [PATCH] initial version (does not work) --- arbo/mimc_bls12_377/gnark.pprof | Bin 0 -> 6079 bytes arbo/mimc_bls12_377/verifier.go | 74 ++++++++++++ arbo/mimc_bls12_377/verifier_test.go | 134 +++++++++++++++++++++ arbo/poseidon_bn254/gnark.pprof | Bin 0 -> 4157 bytes arbo/{ => poseidon_bn254}/verifier.go | 2 +- arbo/{ => poseidon_bn254}/verifier_test.go | 0 go.mod | 3 + 7 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 arbo/mimc_bls12_377/gnark.pprof create mode 100644 arbo/mimc_bls12_377/verifier.go create mode 100644 arbo/mimc_bls12_377/verifier_test.go create mode 100644 arbo/poseidon_bn254/gnark.pprof rename arbo/{ => poseidon_bn254}/verifier.go (97%) rename arbo/{ => poseidon_bn254}/verifier_test.go (100%) diff --git a/arbo/mimc_bls12_377/gnark.pprof b/arbo/mimc_bls12_377/gnark.pprof new file mode 100644 index 0000000000000000000000000000000000000000..37a6e0a182f65f057745427dfcfbc143bc97b9a2 GIT binary patch literal 6079 zcmeI0YfMvD0LRg(u%T1OlsQCLmZ$^)5doo)8kdNamjhR%NKtu?0#|vJw%Tf#kKr1I zRB%AsIp{7>u<}+)twPEKEXbqOs%=H&QQKM`?WKj5j?5VQL6&`8((~cmoAW;>x#xH8 zJ?EF}aLvl%pJG&q(tzkB!-E+{eOYhl5Unz1G7BT88d^yhFM_AH&5`6gpEm^tmo>RR zxxD*!W+^H}@p5bpx#WS^`U2=Tw(Sd*<;=QV>qkjHzDdloljW;z=t;r^x^!~Z=jS3z zX`+iu0_cS-a}ENFF`6M~(RK2>!XMq~`4%YU5Ag*am?Rae-=((kl4hX;A9pHkq&BKC zkzeYG`ENHO2KjI!aj9d-c4JAu-*MMwFJ?l@h-;dJRIgKHmJ}36){LiQCJ?oP3jRG_ zNXy-**cYjL(%%92SgmzfSF>JvpX)~&)mhpblXX|y=)h-&k9B?5rpKU(aoMihhapq7#zZO7Uf$O(;b2LWic{E*OnWc)tdG~TD7Y_+6AaY zqQjyfP*(>aBkxnZ2N`d8aJNaaIu#uz7fB~o@DkzR;g(`B>)!SB38xqzyfUS^?N@O4 zHqv&ELWBFU3uh7fv2xt4uZhf}!Ehu-@En9K&mM`Y7Ee_+m3u}rl^#?|iU=i7)u8-g z!k%YxDkU_@u5M0gO{E|kz-Zg&{aN9NC}wk%6Il^17rkjqgigpa77@D`0!0clrmio( zzjYQ`?mg0A#Bh$sV7&;{8siPDD|@63UDr@Mw1CpQ#X}kL8!63&+0h*6(o%#$FdBcN z@6Wt}TqGp#>|V+pA)UoG!P>J4VEX`9qYa1u}g1n-3LPQEaXLdiK;V-EI!NXaj7>Kfmb01*6cO620- zLc1DIw+rlwIc^#Gl7imTC@2TIl9$o?mF-yFDxy^*J!}Egv za-p4qoW7wZ?{Lvsk(j0yrWYh8V7+j0`*#GxWm0Wp0-KEdFjRc8%adAht8v5M}&Oh$FNQXb%sC(&7oTkIODhfwtVy{+U(eP1V zc=Pmt&B70*Qtd=Ni_d5CrX_@-?$@D4!ljG|zw4mwZA^f^K?4x`pXaCGtAm z!#TVA`YJdat{q=G2^uHjmNqXQ^C9V#SO~iy_4&r1p4JC2+1@$oqDOiHF zkfh&YSbHFYz`Kjr&i!={ZJ(v>AP8_${UBX+tG*U5Lrqc#VBRdOR4P@H#)7`P76CW( z0Ij~K34`2R{jRwj-S_TPHJ8xgpcu`SKP{;&4+-cL@x`2_=mK3f!7;`U>Z{V9x#RH+ zKShE9L+`3mw{u&upaGyy*SEtAiXtNSsng{~8@Q}= 0; i-- { + // check if the sibling is valid + valid := isValid(api, siblings[i], prevSibling, currentLeaf, prevLeaf) + prevLeaf = currentLeaf + prevSibling = siblings[i] + // compute the next leaf value + currentLeaf, err = prevLevel(api, currentLeaf, path[i], valid, siblings[i]) + if err != nil { + return err + } + } + api.AssertIsEqual(currentLeaf, root) + return nil +} diff --git a/arbo/mimc_bls12_377/verifier_test.go b/arbo/mimc_bls12_377/verifier_test.go new file mode 100644 index 0000000..9f0ecd2 --- /dev/null +++ b/arbo/mimc_bls12_377/verifier_test.go @@ -0,0 +1,134 @@ +package arbo + +import ( + "fmt" + "log" + "math/big" + "os" + "testing" + "time" + + "github.com/consensys/gnark-crypto/ecc" + "github.com/consensys/gnark/backend" + "github.com/consensys/gnark/frontend" + "github.com/consensys/gnark/frontend/cs/r1cs" + "github.com/consensys/gnark/profile" + "github.com/consensys/gnark/test" + arbotree "github.com/vocdoni/arbo" + "go.vocdoni.io/dvote/db" + "go.vocdoni.io/dvote/db/pebbledb" + "go.vocdoni.io/dvote/tree/arbo" + "go.vocdoni.io/dvote/util" +) + +type testVerifierCircuit struct { + Root frontend.Variable + Key frontend.Variable + Value frontend.Variable + Siblings [160]frontend.Variable +} + +func (circuit *testVerifierCircuit) Define(api frontend.API) error { + return CheckProof(api, circuit.Key, circuit.Value, circuit.Root, circuit.Siblings[:]) +} + +func TestVerifier(t *testing.T) { + p := profile.Start() + now := time.Now() + _, _ = frontend.Compile(ecc.BLS12_377.ScalarField(), r1cs.NewBuilder, &testVerifierCircuit{}) + fmt.Println("elapsed", time.Since(now)) + p.Stop() + fmt.Println("constrains", p.NbConstraints()) + + assert := test.NewAssert(t) + + // inputs := successInputs(t, 10) + inputs, err := generateCensusProof(10, util.RandomBytes(20), big.NewInt(10).Bytes()) + if err != nil { + t.Fatal(err) + } + // binputs, _ := json.MarshalIndent(inputs, " ", " ") + // fmt.Println("inputs", string(binputs)) + assert.SolvingSucceeded(&testVerifierCircuit{}, &inputs, test.WithCurves(ecc.BLS12_377), test.WithBackends(backend.GROTH16)) +} + +var baseField, _ = new(big.Int).SetString("25825498262808887005865186224201665565126143020923472090132963926938185026661", 10) + +// BigToFF function returns the finite field representation of the big.Int +// provided. It uses Euclidean Modulus and the BN254 curve scalar field to +// represent the provided number. +func BigToFF(iv *big.Int) *big.Int { + z := big.NewInt(0) + if c := iv.Cmp(baseField); c == 0 { + return z + } else if c != 1 && iv.Cmp(z) != -1 { + return iv + } + return z.Mod(iv, baseField) +} + +func generateCensusProof(n int, k, v []byte) (testVerifierCircuit, error) { + dir := os.TempDir() + defer func() { + _ = os.RemoveAll(dir) + }() + database, err := pebbledb.New(db.Options{Path: dir}) + if err != nil { + return testVerifierCircuit{}, err + } + tree, err := arbotree.NewTree(arbotree.Config{ + Database: database, + MaxLevels: 160, + HashFunction: arbotree.HashFunctionMiMC_BLS12_377, + }) + if err != nil { + return testVerifierCircuit{}, err + } + k = BigToFF(new(big.Int).SetBytes(k)).Bytes() + // add the first key-value pair + if err = tree.Add(k, v); err != nil { + return testVerifierCircuit{}, err + } + h := tree.HashFunction() + r, _ := h.Hash(k, v, []byte{1}) + log.Println("[go] leafKey", new(big.Int).SetBytes(k)) + log.Println("[go] leafValue", new(big.Int).SetBytes(r)) + // add random addresses + for i := 1; i < n; i++ { + rk := BigToFF(new(big.Int).SetBytes(util.RandomBytes(20))).Bytes() + rv := new(big.Int).SetBytes(util.RandomBytes(8)).Bytes() + if err = tree.Add(rk, rv); err != nil { + return testVerifierCircuit{}, err + } + } + // generate the proof + _, _, siblings, exist, err := tree.GenProof(k) + if err != nil { + return testVerifierCircuit{}, err + } + if !exist { + return testVerifierCircuit{}, fmt.Errorf("error building the merkle tree: key not found") + } + unpackedSiblings, err := arbo.UnpackSiblings(arbo.HashFunctionPoseidon, siblings) + if err != nil { + return testVerifierCircuit{}, err + } + paddedSiblings := [160]frontend.Variable{} + for i := 0; i < 160; i++ { + if i < len(unpackedSiblings) { + paddedSiblings[i] = arbo.BytesLEToBigInt(unpackedSiblings[i]) + } else { + paddedSiblings[i] = big.NewInt(0) + } + } + root, err := tree.Root() + if err != nil { + return testVerifierCircuit{}, err + } + return testVerifierCircuit{ + Root: root, + Key: k, + Value: new(big.Int).SetBytes(v), + Siblings: paddedSiblings, + }, nil +} diff --git a/arbo/poseidon_bn254/gnark.pprof b/arbo/poseidon_bn254/gnark.pprof new file mode 100644 index 0000000000000000000000000000000000000000..528d18950545ed0257022d115d851a7cbd7d3f85 GIT binary patch literal 4157 zcmeI0Yg1EK6o&0+MO!qT0R@Zpd~n24!9xKBnqbBoj>UquBjN>)+5)zMfdGb(khGD0~H(AtS-zrlul~M&Ooe1QOSG9J|iQ?g;hPiakC228)StsAZB z3jF$DAX4Al7|M^-ANdIUHkut*b~tYGyD=R$9%EkzlWs?_w> zFYT+V*pp=#PxsXJE&g~mo-*bykMx&&Wc#?OeZ8IVlcpH%nU%o9B<*78C-rTxIFVBH+5xuBQ5_rwWckjkPE$YzWFfr$~jvj;&&iw{ZOEye{S+f!^Ks; zv^CuJko4`%fbguzbt~yb{+?COEnRz};o`>uyH}A*`<{u7Ar~jtRn*6IuMqyNXQwiC zYXWws^*!0RB6=yUKMHiOuZ!!x9GbjJ$iJzjj>P`?WaHN8{O?zY;8bDXGwEBQ$@lAS z2CUZM{;kZ6#Z8g<-#=Z}S`~WXOGWOhitn!YUXZV^_`0pngM4=AvqRtL^#23pVnmN( zq+e~A7iva34xWXJy1>jfpt{3UC9VDfz0)x36@!LC;)gA8YiU>+|d5NBmr4Op2F@4Gh_-z2OEK_?3v@y__$8Odrriu*aV1bs(Eti!je^2SE<@ zFitw!&MnZ$HoHE*XD=g5X>FhZM(5&9 zu6Tr0JyZ*MrqyU7RRV!QFqTHgDj6pq!3CvZv9%P}L8w=$ZkKct(qAXda9f_0hLI8& zrb==F6=9~0Pt6<3h{F+?Z6W?c6s572{2Lx0jt_zFHkkIa&g0vSwNbB?n^d6ekv2W} zIzEV!6tB+3f%6x%5r!Pctff~;p(KTA@`{V7+)C4^#q~V*diy3wNBvS%-Dc{^%chpx zr4s5k?pUEM4UvKZHy+m&OvPYlpdiXyUJ>mD~y(jS5Dqw z<%pYQlbnY|K(a}*O{E=i%a`Z`y!VQ?yRd{r&x>(2!c}?|pw;3Vv^t2;@4VtQ&@t0s zx3L0MWvLtW)ot+!+gWw;wK4@IkoXN>suvvxdi3YWUk#4t5K0g1tElVr#MTGen|P$i)72+R*j` zuZFCLWaPOUB{BT|-4%kTZ{oLtg;$q;C*Ee{MFJe@1b=tNl-|!{NTUC&I?y9PX92yM z<)7j`L_n2h;xy?Wb%@8a3;ifU>wFQw+z&7g9PmuG2xsiV!DD+wr7;QO=!9FIH_hf9 zN+~^$P-^bZAv4JYY7E~D^j%AF$h@gmj#RHV4Nb3Cs(2&c!9 b;jChmwD{?k%*%fT7*@UI+^+*~ZCLXkf| ../arbo + require ( github.com/consensys/gnark v0.11.0 github.com/consensys/gnark-crypto v0.14.0 github.com/iden3/go-iden3-crypto v0.0.17 + github.com/vocdoni/arbo v0.0.0-20241114123238-8b237b4e83fa github.com/vocdoni/vocdoni-z-sandbox v0.0.0-20241113074257-1a711ad38a6b go.vocdoni.io/dvote v1.10.2-0.20241024102542-c1ce6d744bc5 )