Skip to content

Commit

Permalink
Merge pull request #45 from hyperledger-labs/encrypt
Browse files Browse the repository at this point in the history
  • Loading branch information
Chengxuan authored Aug 26, 2024
2 parents 3b7a354 + 930499e commit e015cdc
Show file tree
Hide file tree
Showing 35 changed files with 891 additions and 332 deletions.
8 changes: 4 additions & 4 deletions go-sdk/integration-test/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ func TestZeto_2_SuccessfulProving(t *testing.T) {
output2, _ := poseidon.Hash([]*big.Int{outputValues[1], salt4, sender.PublicKey.X, sender.PublicKey.Y})
outputCommitments := []*big.Int{output1, output2}

encryptionNonce := utxo.NewSalt()
encryptionNonce := utxo.NewEncryptionNonce()

witnessInputs := map[string]interface{}{
"inputCommitments": inputCommitments,
Expand All @@ -223,7 +223,7 @@ func TestZeto_2_SuccessfulProving(t *testing.T) {
assert.Equal(t, 3, len(proof.Proof.A))
assert.Equal(t, 3, len(proof.Proof.B))
assert.Equal(t, 3, len(proof.Proof.C))
assert.Equal(t, 7, len(proof.PubSignals))
assert.Equal(t, 9, len(proof.PubSignals))
}

func TestZeto_3_SuccessfulProving(t *testing.T) {
Expand Down Expand Up @@ -360,7 +360,7 @@ func TestZeto_4_SuccessfulProving(t *testing.T) {
output2, _ := poseidon.Hash([]*big.Int{outputValues[1], salt4, sender.PublicKey.X, sender.PublicKey.Y})
outputCommitments := []*big.Int{output1, output2}

encryptionNonce := utxo.NewSalt()
encryptionNonce := utxo.NewEncryptionNonce()

proof1Siblings := make([]*big.Int, len(circomProof1.Siblings)-1)
for i, s := range circomProof1.Siblings[0 : len(circomProof1.Siblings)-1] {
Expand Down Expand Up @@ -398,7 +398,7 @@ func TestZeto_4_SuccessfulProving(t *testing.T) {
assert.Equal(t, 3, len(proof.Proof.A))
assert.Equal(t, 3, len(proof.Proof.B))
assert.Equal(t, 3, len(proof.Proof.C))
assert.Equal(t, 10, len(proof.PubSignals))
assert.Equal(t, 12, len(proof.PubSignals))
}

func TestZeto_5_SuccessfulProving(t *testing.T) {
Expand Down
79 changes: 79 additions & 0 deletions go-sdk/internal/sparse-merkle-tree/storage/memory_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// 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 storage

import (
"math/big"
"testing"

"github.com/hyperledger-labs/zeto/go-sdk/pkg/sparse-merkle-tree/core"
"github.com/stretchr/testify/assert"
)

type mockNodeIndex struct{}

func (ni *mockNodeIndex) BigInt() *big.Int { return big.NewInt(0) }
func (ni *mockNodeIndex) Hex() string { return "0" }
func (ni *mockNodeIndex) IsZero() bool { return true }
func (ni *mockNodeIndex) Equal(n core.NodeIndex) bool { return true }
func (ni *mockNodeIndex) IsBitOn(uint) bool { return false }
func (ni *mockNodeIndex) ToPath(int) []bool { return []bool{true, false} }

type mockNode struct {
idx core.NodeIndex
ref core.NodeIndex
lc core.NodeIndex
rc core.NodeIndex
}

func (n *mockNode) Type() core.NodeType { return core.NodeTypeLeaf }
func (n *mockNode) Index() core.NodeIndex { return n.idx }
func (n *mockNode) Ref() core.NodeIndex { return n.ref }
func (n *mockNode) Value() core.Indexable { return nil }
func (n *mockNode) LeftChild() core.NodeIndex { return n.lc }
func (n *mockNode) RightChild() core.NodeIndex { return n.rc }

func TestNewMemoryStorage(t *testing.T) {
s := NewMemoryStorage()
assert.Nil(t, s.root)
assert.NotNil(t, s.nodes)
assert.Empty(t, s.nodes)

_, err := s.GetRootNodeIndex()
assert.Equal(t, ErrNotFound, err)

err = s.UpsertRootNodeIndex(&mockNodeIndex{})
assert.NoError(t, err)

ni, err := s.GetRootNodeIndex()
assert.NoError(t, err)
assert.NotNil(t, ni)

idx1 := &mockNodeIndex{}
_, err = s.GetNode(idx1)
assert.Equal(t, ErrNotFound, err)

idx2 := &mockNodeIndex{}
n1 := &mockNode{idx: idx1, ref: idx2}
err = s.InsertNode(n1)
assert.NoError(t, err)

found, err := s.GetNode(idx1)
assert.NoError(t, err)
assert.NotNil(t, found)
assert.Equal(t, n1, found)
}
16 changes: 16 additions & 0 deletions go-sdk/internal/sparse-merkle-tree/storage/sql_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
// 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 storage

import (
Expand Down
56 changes: 56 additions & 0 deletions go-sdk/internal/utxo/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// 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 utxo

import (
"crypto/rand"
"fmt"
"math/big"

"github.com/iden3/go-iden3-crypto/constants"
)

// NewSalt generates a new random salt in the range of [0, MAX) where MAX is the order of the BabyJub curve.
// This ensures that the salt is a valid scalar for the curve.
func NewSalt() *big.Int {
// ensure that the salt fits inside the field of SNARKs
max := constants.Q
return newRandomNumberInRange(max)
}

const TWO_POW_128 = "340282366920938463463374607431768211456"

func NewEncryptionNonce() *big.Int {
// per https://drive.google.com/file/d/1EVrP3DzoGbmzkRmYnyEDcIQcXVU7GlOd/view
// the encrpition nonce should be in the range [0, 2^128)
max, _ := new(big.Int).SetString(TWO_POW_128, 10)
return newRandomNumberInRange(max)
}

func newRandomNumberInRange(max *big.Int) *big.Int {
// ensure that the salt fits inside the field of SNARKs
maxRounds := 10
var e error
for rounds := 0; rounds < maxRounds; rounds++ {
randInt, err := rand.Int(rand.Reader, max)
if err == nil {
return randInt
}
e = err
}
panic(fmt.Sprintf("failed to generate a random number in [0, %d) after trying %d times: %v", max, maxRounds, e))
}
39 changes: 39 additions & 0 deletions go-sdk/internal/utxo/utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// 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 utxo

import (
"math/big"
"testing"

"github.com/iden3/go-iden3-crypto/constants"
"github.com/stretchr/testify/assert"
)

func TestNewSalt(t *testing.T) {
salt := NewSalt()
assert.NotNil(t, salt)
max := constants.Q
assert.Less(t, salt.Cmp(max), 0)
}

func TestNewEncryptionNonce(t *testing.T) {
nonce := NewEncryptionNonce()
assert.NotNil(t, nonce)
max, _ := new(big.Int).SetString("340282366920938463463374607431768211456", 10)
assert.Less(t, nonce.Cmp(max), 0)
}
20 changes: 5 additions & 15 deletions go-sdk/pkg/utxo/utxo.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,11 @@
package utxo

import (
"crypto/rand"
"fmt"
"math/big"

"github.com/hyperledger-labs/zeto/go-sdk/internal/utxo"
"github.com/hyperledger-labs/zeto/go-sdk/pkg/utxo/core"
"github.com/iden3/go-iden3-crypto/babyjub"
"github.com/iden3/go-iden3-crypto/constants"
)

func NewFungible(amount *big.Int, owner *babyjub.PublicKey, salt *big.Int) core.UTXO {
Expand All @@ -50,16 +47,9 @@ func HashTokenUri(tokenUri string) (*big.Int, error) {
// NewSalt generates a new random salt in the range of [0, MAX) where MAX is the order of the BabyJub curve.
// This ensures that the salt is a valid scalar for the curve.
func NewSalt() *big.Int {
// ensure that the salt fits inside the field of SNARKs
max := constants.Q
maxRounds := 10
var e error
for rounds := 0; rounds < maxRounds; rounds++ {
randInt, err := rand.Int(rand.Reader, max)
if err == nil {
return randInt
}
e = err
}
panic(fmt.Sprintf("failed to generate a random salt after trying %d times: %v", maxRounds, e))
return utxo.NewSalt()
}

func NewEncryptionNonce() *big.Int {
return utxo.NewEncryptionNonce()
}
48 changes: 31 additions & 17 deletions solidity/contracts/lib/verifier_anon_enc.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,29 +43,35 @@ contract Groth16Verifier_AnonEnc {
uint256 constant deltay2 = 8495653923123431417604973247489272438418190587263600148770280649306958101930;


uint256 constant IC0x = 18159435826572343316676467109138200544943506442097308527447923988975990426374;
uint256 constant IC0y = 1708436670699643498315227279136315907735604591474632572875195515766865806751;
uint256 constant IC0x = 5696326670703652601376328914723856805804139150397636629981154943267586835846;
uint256 constant IC0y = 17913431813079674015620165360736989993822627917830194405007674349883405519566;

uint256 constant IC1x = 17725877415538066118429971377738049873939903267931239594678406232288476165865;
uint256 constant IC1y = 8360990294279167582836230205949026092505324676058165340999779063723292604615;
uint256 constant IC1x = 15825765194464726182776026234639522157004618110842020817264286413596445235307;
uint256 constant IC1y = 2401477487480347699703028792091325200698394178743640467196981936283298710021;

uint256 constant IC2x = 20052210699075023943196176633671323851550731090320249283011717077355771944721;
uint256 constant IC2y = 9923948506681921144353284990883464079686495068896868136143887818658688090586;
uint256 constant IC2x = 17823254154132200329306690888156067227498822342519393685861534093309766001383;
uint256 constant IC2y = 14804040920166770014088667887230353137747938842993092323563528559936821334324;

uint256 constant IC3x = 11506762257210632430778225493929306500374896561471436639612427093321561997997;
uint256 constant IC3y = 13703812577370397963540025801142135323431413739269861508775560666648024299575;
uint256 constant IC3x = 18619661077507789630281262029605339062675871751807780618791872378570042056116;
uint256 constant IC3y = 18692831968495678168274986594838227336308377551834418943816657968243321416157;

uint256 constant IC4x = 13555286548241762297389208813175424328721053664995237847337042175538225042854;
uint256 constant IC4y = 11020759506489823314465857208817866543025680973749071015072275736454425856152;
uint256 constant IC4x = 8481249797936633465645328566302395583826148290507195864467073391607936154307;
uint256 constant IC4y = 4631061052012679777402506942756063974564041904906197227863591152456358430540;

uint256 constant IC5x = 10592105017977731818845169116197332337694758364154880177846794837509112906612;
uint256 constant IC5y = 15138187076136268432825710693371558357486628971763783848698245264698459791263;
uint256 constant IC5x = 269115022971501175992618085182824077406065858697651888560831707201556157978;
uint256 constant IC5y = 19699073094724988754117299114476621695804537148277402334737306097425629024180;

uint256 constant IC6x = 20013117829926056222388758503082080889300946913142248120330207480557791362629;
uint256 constant IC6y = 9121113480497568733675534607829607958708961634501005922640134796845204415712;
uint256 constant IC6x = 1913049492538130220079715288227546492513434304091272666779551189559174650055;
uint256 constant IC6y = 8026674512639726678535471254304139996984356128094657497323442787106936741295;

uint256 constant IC7x = 4676102677804116290659127850479953191135140832404902056705090232978863910100;
uint256 constant IC7y = 9174728765241605210581079962059830862005853514793197924748953049262445558330;
uint256 constant IC7x = 19540350047697937581651886063231839834190225823779317423395632407508094676034;
uint256 constant IC7y = 11509057717377452054369845075648430924127395960184841862468027451544630252263;

uint256 constant IC8x = 20424145427206879140473289312774507494632015321325422705294860020477582644926;
uint256 constant IC8y = 7679128631893396357290525051865682086413798390080076016853338090494897502827;

uint256 constant IC9x = 1473626294810953820540987430623254549322665071695014303081451346851945206320;
uint256 constant IC9y = 11106503043437375969357683402411680940320268283974144474358260758792518561470;


// Memory data
Expand All @@ -74,7 +80,7 @@ contract Groth16Verifier_AnonEnc {

uint16 constant pLastMem = 896;

function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[7] calldata _pubSignals) public view returns (bool) {
function verifyProof(uint[2] calldata _pA, uint[2][2] calldata _pB, uint[2] calldata _pC, uint[9] calldata _pubSignals) public view returns (bool) {
assembly {
function checkField(v) {
if iszero(lt(v, q)) {
Expand Down Expand Up @@ -132,6 +138,10 @@ contract Groth16Verifier_AnonEnc {

g1_mulAccC(_pVk, IC7x, IC7y, calldataload(add(pubSignals, 192)))

g1_mulAccC(_pVk, IC8x, IC8y, calldataload(add(pubSignals, 224)))

g1_mulAccC(_pVk, IC9x, IC9y, calldataload(add(pubSignals, 256)))


// -A
mstore(_pPairing, calldataload(pA))
Expand Down Expand Up @@ -201,6 +211,10 @@ contract Groth16Verifier_AnonEnc {

checkField(calldataload(add(_pubSignals, 224)))

checkField(calldataload(add(_pubSignals, 256)))

checkField(calldataload(add(_pubSignals, 288)))


// Validate all evaluations
let isValid := checkPairing(_pA, _pB, _pC, _pubSignals, pMem)
Expand Down
Loading

0 comments on commit e015cdc

Please sign in to comment.