Skip to content

Commit

Permalink
Merge branch 'main' into sql-atomicity
Browse files Browse the repository at this point in the history
  • Loading branch information
jimthematrix committed Sep 20, 2024
2 parents b1a4d3b + b3713ab commit 6532fdb
Show file tree
Hide file tree
Showing 26 changed files with 2,371 additions and 68 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.DS_Store
.vscode
20 changes: 8 additions & 12 deletions go-sdk/integration-test/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,13 +301,11 @@ func (s *E2ETestSuite) TestZeto_3_SuccessfulProving() {
assert.NoError(s.T(), err)
err = mt.AddLeaf(n2)
assert.NoError(s.T(), err)
proof1, _, err := mt.GenerateProof(input1, nil)
proofs, _, err := mt.GenerateProofs([]*big.Int{input1, input2}, nil)
assert.NoError(s.T(), err)
circomProof1, err := proof1.ToCircomVerifierProof(input1, input1, mt.Root(), MAX_HEIGHT)
circomProof1, err := proofs[0].ToCircomVerifierProof(input1, input1, mt.Root(), MAX_HEIGHT)
assert.NoError(s.T(), err)
proof2, _, err := mt.GenerateProof(input2, nil)
assert.NoError(s.T(), err)
circomProof2, err := proof2.ToCircomVerifierProof(input2, input2, mt.Root(), MAX_HEIGHT)
circomProof2, err := proofs[1].ToCircomVerifierProof(input2, input2, mt.Root(), MAX_HEIGHT)
assert.NoError(s.T(), err)

salt3 := crypto.NewSalt()
Expand Down Expand Up @@ -387,13 +385,11 @@ func (s *E2ETestSuite) TestZeto_4_SuccessfulProving() {
assert.NoError(s.T(), err)
err = mt.AddLeaf(n2)
assert.NoError(s.T(), err)
proof1, _, err := mt.GenerateProof(input1, nil)
assert.NoError(s.T(), err)
circomProof1, err := proof1.ToCircomVerifierProof(input1, input1, mt.Root(), MAX_HEIGHT)
proofs, _, err := mt.GenerateProofs([]*big.Int{input1, input2}, nil)
assert.NoError(s.T(), err)
proof2, _, err := mt.GenerateProof(input2, nil)
circomProof1, err := proofs[0].ToCircomVerifierProof(input1, input1, mt.Root(), MAX_HEIGHT)
assert.NoError(s.T(), err)
circomProof2, err := proof2.ToCircomVerifierProof(input2, input2, mt.Root(), MAX_HEIGHT)
circomProof2, err := proofs[1].ToCircomVerifierProof(input2, input2, mt.Root(), MAX_HEIGHT)
assert.NoError(s.T(), err)

salt3 := crypto.NewSalt()
Expand Down Expand Up @@ -527,9 +523,9 @@ func (s *E2ETestSuite) TestZeto_6_SuccessfulProving() {
assert.NoError(s.T(), err)
err = mt.AddLeaf(n1)
assert.NoError(s.T(), err)
proof1, _, err := mt.GenerateProof(input1, nil)
proofs, _, err := mt.GenerateProofs([]*big.Int{input1}, nil)
assert.NoError(s.T(), err)
circomProof1, err := proof1.ToCircomVerifierProof(input1, input1, mt.Root(), MAX_HEIGHT)
circomProof1, err := proofs[0].ToCircomVerifierProof(input1, input1, mt.Root(), MAX_HEIGHT)
assert.NoError(s.T(), err)
proof1Siblings := make([]*big.Int, len(circomProof1.Siblings)-1)
for i, s := range circomProof1.Siblings[0 : len(circomProof1.Siblings)-1] {
Expand Down
27 changes: 21 additions & 6 deletions go-sdk/internal/sparse-merkle-tree/smt/merkletree.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,32 @@ func (mt *sparseMerkleTree) GetNode(key core.NodeIndex) (core.Node, error) {
return mt.getNode(key)
}

// GenerateProof generates the proof of existence (or non-existence) of a leaf node
// for a Merkle Tree given the root. It uses the node's index to represent the node.
// If the rootKey is nil, the current merkletree root is used
func (mt *sparseMerkleTree) GenerateProof(k *big.Int, rootKey core.NodeIndex) (core.Proof, *big.Int, error) {
// GenerateProofs generates a list of proofs of existence (or non-existence) of the provided
// leaf nodes that are represented by their indexes. An optional Merkle tree root can be provided.
// If rootKey is not provided, the current Merkle tree root is used
func (mt *sparseMerkleTree) GenerateProofs(keys []*big.Int, rootKey core.NodeIndex) ([]core.Proof, []*big.Int, error) {
mt.RLock()
defer mt.RUnlock()

merkleProofs := make([]core.Proof, len(keys))
foundValues := make([]*big.Int, len(keys))
for i, key := range keys {
proof, value, err := mt.generateProof(key, rootKey)
if err != nil {
return nil, nil, err
}
merkleProofs[i] = proof
foundValues[i] = value
}

return merkleProofs, foundValues, nil
}

func (mt *sparseMerkleTree) generateProof(key *big.Int, rootKey core.NodeIndex) (core.Proof, *big.Int, error) {
p := &proof{}
var siblingKey core.NodeIndex

kHash, err := node.NewNodeIndexFromBigInt(k)
kHash, err := node.NewNodeIndexFromBigInt(key)
if err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -177,7 +192,7 @@ func (mt *sparseMerkleTree) GenerateProof(k *big.Int, rootKey core.NodeIndex) (c
p.siblings = append(p.siblings, siblingKey)
}
}
return nil, nil, ErrKeyNotFound
return nil, nil, ErrReachedMaxLevel
}

// must be called from inside a read lock
Expand Down
16 changes: 8 additions & 8 deletions go-sdk/internal/sparse-merkle-tree/smt/proof.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,10 @@ func (p *proof) ExistingNode() core.Node {
}

func (p *proof) MarkNonEmptySibling(level uint) {
desiredLength := (level + 7) / 8
if desiredLength == 0 {
desiredLength = 1
}
if len(p.nonEmptySiblings) <= int(desiredLength) {
newBytes := make([]byte, desiredLength)
desiredByteLength := level/8 + 1
if len(p.nonEmptySiblings) <= int(desiredByteLength) {
// the bitmap is not big enough, resize it
newBytes := make([]byte, desiredByteLength)
if len(p.nonEmptySiblings) == 0 {
p.nonEmptySiblings = newBytes
} else {
Expand Down Expand Up @@ -186,10 +184,12 @@ func calculateRootFromProof(proof *proof, leafNode core.Node) (core.NodeIndex, e

// isBitOnBigEndian tests whether the bit n in bitmap is 1, in Big Endian.
func isBitOnBigEndian(bitmap []byte, n uint) bool {
return bitmap[uint(len(bitmap))-n/8-1]&(1<<(n%8)) != 0
byteIdxToCheck := n / 8
return bitmap[byteIdxToCheck]&(1<<(n%8)) != 0
}

// setBitBigEndian sets the bit n in the bitmap to 1, in Big Endian.
func setBitBigEndian(bitmap []byte, n uint) {
bitmap[uint(len(bitmap))-n/8-1] |= 1 << (n % 8)
byteIdxToSet := n / 8
bitmap[byteIdxToSet] |= 1 << (n % 8)
}
68 changes: 68 additions & 0 deletions go-sdk/internal/sparse-merkle-tree/smt/proof_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright © 2024 Kaleido, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package smt

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestMarkNonEmptySibling(t *testing.T) {
p := &proof{}
for i := 0; i < 256; i++ {
p.MarkNonEmptySibling(uint(i))
}
expected := make([]byte, 32)
for i := 0; i < 32; i++ {
expected[i] = 0xff
}
assert.Equal(t, p.nonEmptySiblings, expected)
}

func TestIsBitOnBigEndian(t *testing.T) {
p := &proof{}
expected := make([]byte, 32)
for i := 0; i < 32; i++ {
expected[i] = 0xff
}
p.nonEmptySiblings = expected
for i := 0; i < 256; i++ {
assert.True(t, isBitOnBigEndian(p.nonEmptySiblings, uint(i)))
}
}

func TestMarkAndCheck(t *testing.T) {
p := &proof{}
p.MarkNonEmptySibling(0)
p.MarkNonEmptySibling(10)
p.MarkNonEmptySibling(136)
assert.True(t, p.IsNonEmptySibling(0))
assert.False(t, p.IsNonEmptySibling(1))
assert.False(t, p.IsNonEmptySibling(2))
assert.False(t, p.IsNonEmptySibling(3))
assert.False(t, p.IsNonEmptySibling(4))
assert.False(t, p.IsNonEmptySibling(5))
assert.False(t, p.IsNonEmptySibling(6))
assert.False(t, p.IsNonEmptySibling(7))
assert.False(t, p.IsNonEmptySibling(8))
assert.False(t, p.IsNonEmptySibling(9))
assert.True(t, p.IsNonEmptySibling(10))
assert.False(t, p.IsNonEmptySibling(55))
assert.True(t, p.IsNonEmptySibling(136))
assert.False(t, p.IsNonEmptySibling(137))
}
22 changes: 10 additions & 12 deletions go-sdk/internal/sparse-merkle-tree/smt/smt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,22 +205,20 @@ func (s *MerkleTreeTestSuite) TestGenerateProof() {
assert.NoError(s.T(), err)

target1 := node1.Index().BigInt()
proof1, foundValue1, err := mt.GenerateProof(target1, mt.Root())
assert.NoError(s.T(), err)
assert.Equal(s.T(), target1, foundValue1)
assert.True(s.T(), proof1.(*proof).existence)
valid := VerifyProof(mt.Root(), proof1, node1)
assert.True(s.T(), valid)

utxo3 := node.NewFungible(big.NewInt(10), alice.PublicKey, big.NewInt(12347))
node3, err := node.NewLeafNode(utxo3)
assert.NoError(s.T(), err)
target2 := node3.Index().BigInt()
proof2, _, err := mt.GenerateProof(target2, mt.Root())
proofs, foundValues, err := mt.GenerateProofs([]*big.Int{target1, target2}, mt.Root())
assert.NoError(s.T(), err)
assert.False(s.T(), proof2.(*proof).existence)
assert.Equal(s.T(), target1, foundValues[0])
assert.True(s.T(), proofs[0].(*proof).existence)
valid := VerifyProof(mt.Root(), proofs[0], node1)
assert.True(s.T(), valid)
assert.False(s.T(), proofs[1].(*proof).existence)

proof3, err := proof1.ToCircomVerifierProof(target1, foundValue1, mt.Root(), levels)
proof3, err := proofs[0].ToCircomVerifierProof(target1, foundValues[0], mt.Root(), levels)
assert.NoError(s.T(), err)
assert.False(s.T(), proof3.IsOld0)
}
Expand Down Expand Up @@ -254,11 +252,11 @@ func (s *MerkleTreeTestSuite) TestVerifyProof() {

target := n.Index().BigInt()
root := mt.Root()
p, _, err := mt.GenerateProof(target, root)
p, _, err := mt.GenerateProofs([]*big.Int{target}, root)
assert.NoError(s.T(), err)
assert.True(s.T(), p.(*proof).existence)
assert.True(s.T(), p[0].(*proof).existence)

valid := VerifyProof(root, p, n)
valid := VerifyProof(root, p[0], n)
assert.True(s.T(), valid)
}()

Expand Down
6 changes: 3 additions & 3 deletions go-sdk/pkg/sparse-merkle-tree/core/merkletree.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ type SparseMerkleTree interface {
// Root returns the root hash of the tree
Root() NodeIndex
// AddLeaf adds a key-value pair to the tree
AddLeaf(Node) error
AddLeaf(leaf Node) error
// GetNode returns the node at the given reference hash
GetNode(NodeIndex) (Node, error)
GetNode(node NodeIndex) (Node, error)
// GetnerateProof generates a proof of existence (or non-existence) of a leaf node
GenerateProof(*big.Int, NodeIndex) (Proof, *big.Int, error)
GenerateProofs(nodeIndexes []*big.Int, root NodeIndex) ([]Proof, []*big.Int, error)
}
16 changes: 8 additions & 8 deletions solidity/contracts/lib/verifier_anon_enc.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ contract Groth16Verifier_AnonEnc {
uint256 constant IC0x = 5696326670703652601376328914723856805804139150397636629981154943267586835846;
uint256 constant IC0y = 17913431813079674015620165360736989993822627917830194405007674349883405519566;

uint256 constant IC1x = 15825765194464726182776026234639522157004618110842020817264286413596445235307;
uint256 constant IC1y = 2401477487480347699703028792091325200698394178743640467196981936283298710021;
uint256 constant IC1x = 2102562587253616254650248571898720579563063454685611900201869023012028011038;
uint256 constant IC1y = 858837120372047227699859025595943051604219338012183710955972141361344096680;

uint256 constant IC2x = 17823254154132200329306690888156067227498822342519393685861534093309766001383;
uint256 constant IC2y = 14804040920166770014088667887230353137747938842993092323563528559936821334324;
uint256 constant IC2x = 19871902121561448541783335513612822391415363559792595451397804594141318386828;
uint256 constant IC2y = 14203964380144242038882743638980469366132880555873818345914201687170773944754;

uint256 constant IC3x = 18619661077507789630281262029605339062675871751807780618791872378570042056116;
uint256 constant IC3y = 18692831968495678168274986594838227336308377551834418943816657968243321416157;
uint256 constant IC3x = 4534338244167504974683945726615729215678954323916000129150608047181600075942;
uint256 constant IC3y = 9004530693581096650487103914238080672423858350236817229254519649589395343912;

uint256 constant IC4x = 8481249797936633465645328566302395583826148290507195864467073391607936154307;
uint256 constant IC4y = 4631061052012679777402506942756063974564041904906197227863591152456358430540;
uint256 constant IC4x = 16926200767829183396766074136228821955738540059328214039731068817771880630127;
uint256 constant IC4y = 15535238050385142389806452090946716626530242126040333805866336792975972380578;

uint256 constant IC5x = 269115022971501175992618085182824077406065858697651888560831707201556157978;
uint256 constant IC5y = 19699073094724988754117299114476621695804537148277402334737306097425629024180;
Expand Down
16 changes: 8 additions & 8 deletions solidity/contracts/lib/verifier_anon_enc_nullifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ contract Groth16Verifier_AnonEncNullifier {
uint256 constant IC0x = 19712575420668268335634440622054263372704657131549679423053748840610444649065;
uint256 constant IC0y = 21552018618280422667464008645151951952543569291144282502207358485399703168568;

uint256 constant IC1x = 8879640517323472103773105774693203238739849734532829129136892239475022333668;
uint256 constant IC1y = 8763769862439095053692831300380880413523736171679197931386220812298104316000;
uint256 constant IC1x = 21152648367462137565411101477610760889415992049938974004172633386627195379833;
uint256 constant IC1y = 17526913059347331839566720566403027766484314611214702153099182458740108823;

uint256 constant IC2x = 938844563415264744387226778430871504680270942210685580230120080929277918399;
uint256 constant IC2y = 9128906501228717785843913573881993155178978243801248472013755207523145161265;
uint256 constant IC2x = 5554249810657633166990745736699774333938659965451342592982728994998805456417;
uint256 constant IC2y = 9730676046857216859008721613182313555756289801254042508531677626774346999622;

uint256 constant IC3x = 15866014959526954538183423799071681422553639776348384721828133108069370471390;
uint256 constant IC3y = 17150051530085128616371619156987380853738195686559145384648523741607899076676;
uint256 constant IC3x = 16411770669872316544841615427270736472060848758458781353444450000872952405569;
uint256 constant IC3y = 3883712029134278704236321509155602434293779347341551692030084302663589933567;

uint256 constant IC4x = 16628587721511911382464102713531591331106282985537150732913149203131020489047;
uint256 constant IC4y = 15415751731187982732941102993178329101138735638465538195218064540808443483176;
uint256 constant IC4x = 7689756896440471053876099704125828625789315755353261183292592808881136591701;
uint256 constant IC4y = 8154637307804119872460314948142196702392444351248969101164117581937044926170;

uint256 constant IC5x = 12299330364713292827284970278663419727424821736280679334696618553775046366194;
uint256 constant IC5y = 21075649501958706881669057145213727696785798949405955661717827102964559861134;
Expand Down
Loading

0 comments on commit 6532fdb

Please sign in to comment.