Skip to content

Commit

Permalink
util: move zk.BigToFF and zk.BytesToArboStr to util package
Browse files Browse the repository at this point in the history
this avoids an import cycle in upcoming refactor of circuit package
  • Loading branch information
altergui committed Dec 5, 2023
1 parent 4cf19dd commit bbe3c81
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 61 deletions.
12 changes: 6 additions & 6 deletions crypto/ethereum/vocdoni_sik.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (
"math/big"

"github.com/iden3/go-iden3-crypto/poseidon"
"go.vocdoni.io/dvote/crypto/zk"
"go.vocdoni.io/dvote/tree/arbo"
"go.vocdoni.io/dvote/util"
)

// SIKsignature signs the default vocdoni sik payload. It envolves the
Expand Down Expand Up @@ -38,8 +38,8 @@ func (k *SignKeys) AccountSIK(secret []byte) ([]byte, error) {
}
seed := []*big.Int{
arbo.BytesToBigInt(k.Address().Bytes()),
zk.BigToFF(new(big.Int).SetBytes(secret)),
zk.BigToFF(new(big.Int).SetBytes(sign)),
util.BigToFF(new(big.Int).SetBytes(secret)),
util.BigToFF(new(big.Int).SetBytes(sign)),
}
hash, err := poseidon.Hash(seed)
if err != nil {
Expand All @@ -58,14 +58,14 @@ func (k *SignKeys) AccountSIKnullifier(electionID, secret []byte) ([]byte, error
}
// get the representation of the signature on the finite field and repeat
// the same with the secret if it is provided, if not add a zero
seed := []*big.Int{zk.BigToFF(new(big.Int).SetBytes(sign))}
seed := []*big.Int{util.BigToFF(new(big.Int).SetBytes(sign))}
if secret != nil {
seed = append(seed, zk.BigToFF(new(big.Int).SetBytes(secret)))
seed = append(seed, util.BigToFF(new(big.Int).SetBytes(secret)))
} else {
seed = append(seed, big.NewInt(0))
}
// encode the election id for circom and include it into the nullifier
seed = append(seed, zk.BytesToArbo(electionID)...)
seed = append(seed, util.BytesToArbo(electionID)...)
// calculate the poseidon image --> H(signature + secret + electionId)
hash, err := poseidon.Hash(seed)
if err != nil {
Expand Down
10 changes: 5 additions & 5 deletions crypto/zk/circuit/inputs.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"math/big"

"go.vocdoni.io/dvote/crypto/ethereum"
"go.vocdoni.io/dvote/crypto/zk"
"go.vocdoni.io/dvote/tree/arbo"
"go.vocdoni.io/dvote/util"
)

// CircuitInputs wraps all the necessary circuit parameters. They must all be
Expand Down Expand Up @@ -71,23 +71,23 @@ func GenerateCircuitInput(p CircuitInputsParameters) (*CircuitInputs, error) {
}
ffPassword := new(big.Int)
if p.Password != nil {
ffPassword = zk.BigToFF(new(big.Int).SetBytes(p.Password))
ffPassword = util.BigToFF(new(big.Int).SetBytes(p.Password))
}
signature, err := p.Account.SIKsignature()
if err != nil {
return nil, err
}
return &CircuitInputs{
ElectionId: zk.BytesToArboStr(p.ElectionId),
ElectionId: util.BytesToArboStr(p.ElectionId),
Nullifier: new(big.Int).SetBytes(nullifier).String(),
AvailableWeight: p.AvailableWeight.String(),
VoteHash: zk.BytesToArboStr(p.AvailableWeight.Bytes()),
VoteHash: util.BytesToArboStr(p.AvailableWeight.Bytes()),
SIKRoot: arbo.BytesToBigInt(p.SIKRoot).String(),
CensusRoot: arbo.BytesToBigInt(p.CensusRoot).String(),

Address: arbo.BytesToBigInt(p.Account.Address().Bytes()).String(),
Password: ffPassword.String(),
Signature: zk.BigToFF(new(big.Int).SetBytes(signature)).String(),
Signature: util.BigToFF(new(big.Int).SetBytes(signature)).String(),

VoteWeight: p.VoteWeight.String(),
CensusSiblings: p.CensusSiblings,
Expand Down
6 changes: 3 additions & 3 deletions crypto/zk/circuit/inputs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"testing"

"go.vocdoni.io/dvote/crypto/ethereum"
"go.vocdoni.io/dvote/crypto/zk"
"go.vocdoni.io/dvote/tree/arbo"
"go.vocdoni.io/dvote/util"

qt "github.com/frankban/quicktest"
)
Expand All @@ -33,7 +33,7 @@ func TestGenerateCircuitInput(t *testing.T) {
// mock the availableWeight
availableWeight := new(big.Int).SetUint64(10)
// calc vote hash
voteHash := zk.BytesToArboStr(availableWeight.Bytes())
voteHash := util.BytesToArboStr(availableWeight.Bytes())
// decode the test root
hexTestRoot, err := hex.DecodeString(testRoot)
c.Assert(err, qt.IsNil)
Expand All @@ -51,7 +51,7 @@ func TestGenerateCircuitInput(t *testing.T) {

Address: arbo.BytesToBigInt(acc.Address().Bytes()).String(),
Password: "0",
Signature: zk.BigToFF(new(big.Int).SetBytes(signature)).String(),
Signature: util.BigToFF(new(big.Int).SetBytes(signature)).String(),

VoteWeight: availableWeight.String(),
CensusSiblings: testSiblings,
Expand Down
35 changes: 0 additions & 35 deletions crypto/zk/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ const (
publicSigLen = 8
)

// bn254BaseField contains the Base Field of the twisted Edwards curve, whose
// base field os the scalar field on the curve BN254. It helps to represent
// a scalar number into the field.
var bn254BaseField, _ = new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)

// ProtobufZKProofToProverProof parses the provided protobuf ready proof struct
// into a prover ready proof struct.
func ProtobufZKProofToProverProof(p *models.ProofZkSNARK) (*prover.Proof, error) {
Expand Down Expand Up @@ -137,36 +132,6 @@ func LittleEndianToNBytes(num *big.Int, n int) *big.Int {
return new(big.Int).SetBytes(numBytes[m:])
}

// 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(bn254BaseField); c == 0 {
return z
} else if c != 1 && iv.Cmp(z) != -1 {
return iv
}
return z.Mod(iv, bn254BaseField)
}

// BytesToArbo calculates the sha256 hash (32 bytes) of the slice of bytes
// provided. Then, splits the hash into a two parts of 16 bytes, swap the
// endianess of that parts and encodes they into a two big.Int's.
func BytesToArbo(input []byte) []*big.Int {
hash := sha256.Sum256(input)
return []*big.Int{
new(big.Int).SetBytes(arbo.SwapEndianness(hash[:16])),
new(big.Int).SetBytes(arbo.SwapEndianness(hash[16:])),
}
}

// BytesToArboStr function wraps BytesToArbo to return the input as []string.
func BytesToArboStr(input []byte) []string {
arboBytes := BytesToArbo(input)
return []string{arboBytes[0].String(), arboBytes[1].String()}
}

// ProofToCircomSiblings function decodes the provided proof (or packaged
// siblings) and and encodes any contained siblings for use in a Circom circuit.
func ProofToCircomSiblings(proof []byte) ([]string, error) {
Expand Down
12 changes: 0 additions & 12 deletions crypto/zk/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,3 @@ func TestLittleEndianToNBytes(t *testing.T) {
expected, _ = new(big.Int).SetString("873432238408170128747103711248787244651366455432", 10)
c.Assert(LittleEndianToNBytes(input, 20).Bytes(), qt.DeepEquals, expected.Bytes())
}

func TestBytesToArboStr(t *testing.T) {
c := qt.New(t)

input := new(big.Int).SetInt64(1233)
encoded := BytesToArboStr(input.Bytes())
expected := []string{
"145749485520268040037154566173721592631",
"243838562910071029186006881148627719363",
}
c.Assert(encoded, qt.DeepEquals, expected)
}
43 changes: 43 additions & 0 deletions util/zk.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package util

import (
"crypto/sha256"
"math/big"

"go.vocdoni.io/dvote/tree/arbo"
)

// bn254BaseField contains the Base Field of the twisted Edwards curve, whose
// base field os the scalar field on the curve BN254. It helps to represent
// a scalar number into the field.
var bn254BaseField, _ = new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 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(bn254BaseField); c == 0 {
return z
} else if c != 1 && iv.Cmp(z) != -1 {
return iv
}
return z.Mod(iv, bn254BaseField)
}

// BytesToArbo calculates the sha256 hash (32 bytes) of the slice of bytes
// provided. Then, splits the hash into a two parts of 16 bytes, swap the
// endianess of that parts and encodes they into a two big.Int's.
func BytesToArbo(input []byte) []*big.Int {
hash := sha256.Sum256(input)
return []*big.Int{
new(big.Int).SetBytes(arbo.SwapEndianness(hash[:16])),
new(big.Int).SetBytes(arbo.SwapEndianness(hash[16:])),
}
}

// BytesToArboStr function wraps BytesToArbo to return the input as []string.
func BytesToArboStr(input []byte) []string {
arboBytes := BytesToArbo(input)
return []string{arboBytes[0].String(), arboBytes[1].String()}
}
20 changes: 20 additions & 0 deletions util/zk_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package util

import (
"math/big"
"testing"

qt "github.com/frankban/quicktest"
)

func TestBytesToArboStr(t *testing.T) {
c := qt.New(t)

input := new(big.Int).SetInt64(1233)
encoded := BytesToArboStr(input.Bytes())
expected := []string{
"145749485520268040037154566173721592631",
"243838562910071029186006881148627719363",
}
c.Assert(encoded, qt.DeepEquals, expected)
}

0 comments on commit bbe3c81

Please sign in to comment.