Compare commits

..

3 Commits

5 changed files with 143 additions and 141 deletions

View File

@@ -2,9 +2,10 @@ package babyjub
import ( import (
"fmt" "fmt"
"math/big"
"github.com/iden3/go-iden3-crypto/constants" "github.com/iden3/go-iden3-crypto/constants"
"github.com/iden3/go-iden3-crypto/utils" "github.com/iden3/go-iden3-crypto/utils"
"math/big"
) )
// A is one of the babyjub constants. // A is one of the babyjub constants.
@@ -35,9 +36,9 @@ func init() {
B8 = NewPoint() B8 = NewPoint()
B8.X = utils.NewIntFromString( B8.X = utils.NewIntFromString(
"17777552123799933955779906779655732241715742912184938656739573121738514868268") "5299619240641551281634865583518297030282874472190772894086521144482721001553")
B8.Y = utils.NewIntFromString( B8.Y = utils.NewIntFromString(
"2626589144620713026669568689430873010625803728049924121243784502389097019475") "16950150798460657717958625567821834550301663161624707787222815936182638968203")
} }
// Point represents a point of the babyjub curve. // Point represents a point of the babyjub curve.
@@ -74,7 +75,7 @@ func (res *Point) Add(a *Point, b *Point) *Point {
x2.Mod(x2, constants.Q) x2.Mod(x2, constants.Q)
x2.ModInverse(x2, constants.Q) // x2 = (1 + D * a.x * b.x * a.y * b.y)^-1 x2.ModInverse(x2, constants.Q) // x2 = (1 + D * a.x * b.x * a.y * b.y)^-1
// y = (a.y * b.y + A * a.x * a.x) * (1 - D * a.x * b.x * a.y * b.y)^-1 mod q // y = (a.y * b.y - A * a.x * b.x) * (1 - D * a.x * b.x * a.y * b.y)^-1 mod q
y1a := new(big.Int).Mul(a.Y, b.Y) y1a := new(big.Int).Mul(a.Y, b.Y)
y1b := new(big.Int).Set(A) y1b := new(big.Int).Set(A)
y1b.Mul(y1b, a.X) y1b.Mul(y1b, a.X)
@@ -170,10 +171,7 @@ func PackPoint(ay *big.Int, sign bool) [32]byte {
// Compress the point into a 32 byte array that contains the y coordinate in // Compress the point into a 32 byte array that contains the y coordinate in
// little endian and the sign of the x coordinate. // little endian and the sign of the x coordinate.
func (p *Point) Compress() [32]byte { func (p *Point) Compress() [32]byte {
sign := false sign := PointCoordSign(p.X)
if PointCoordSign(p.X) {
sign = true
}
return PackPoint(p.Y, sign) return PackPoint(p.Y, sign)
} }

View File

@@ -4,6 +4,7 @@ import (
"crypto/rand" "crypto/rand"
"github.com/iden3/go-iden3-crypto/mimc7" "github.com/iden3/go-iden3-crypto/mimc7"
"github.com/iden3/go-iden3-crypto/poseidon"
"github.com/iden3/go-iden3-crypto/utils" "github.com/iden3/go-iden3-crypto/utils"
"math/big" "math/big"
@@ -179,11 +180,11 @@ func (k *PrivateKey) SignMimc7(msg *big.Int) *Signature {
r.Mod(r, SubOrder) r.Mod(r, SubOrder)
R8 := NewPoint().Mul(r, B8) // R8 = r * 8 * B R8 := NewPoint().Mul(r, B8) // R8 = r * 8 * B
A := k.Public().Point() A := k.Public().Point()
hmInput, err := mimc7.BigIntsToRElems([]*big.Int{R8.X, R8.Y, A.X, A.Y, msg}) hmInput := []*big.Int{R8.X, R8.Y, A.X, A.Y, msg}
hm, err := mimc7.Hash(hmInput, nil) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
if err != nil { if err != nil {
panic(err) panic(err)
} }
hm := mimc7.Hash(hmInput, nil) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
S := new(big.Int).Lsh(k.Scalar().BigInt(), 3) S := new(big.Int).Lsh(k.Scalar().BigInt(), 3)
S = S.Mul(hm, S) S = S.Mul(hm, S)
S.Add(r, S) S.Add(r, S)
@@ -195,11 +196,53 @@ func (k *PrivateKey) SignMimc7(msg *big.Int) *Signature {
// VerifyMimc7 verifies the signature of a message encoded as a big.Int in Zq // VerifyMimc7 verifies the signature of a message encoded as a big.Int in Zq
// using blake-512 hash for buffer hashing and mimc7 for big.Int hashing. // using blake-512 hash for buffer hashing and mimc7 for big.Int hashing.
func (p *PublicKey) VerifyMimc7(msg *big.Int, sig *Signature) bool { func (p *PublicKey) VerifyMimc7(msg *big.Int, sig *Signature) bool {
hmInput, err := mimc7.BigIntsToRElems([]*big.Int{sig.R8.X, sig.R8.Y, p.X, p.Y, msg}) hmInput := []*big.Int{sig.R8.X, sig.R8.Y, p.X, p.Y, msg}
hm, err := mimc7.Hash(hmInput, nil) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
if err != nil {
panic(err)
}
left := NewPoint().Mul(sig.S, B8) // left = s * 8 * B
r1 := big.NewInt(8)
r1.Mul(r1, hm)
right := NewPoint().Mul(r1, p.Point())
right.Add(sig.R8, right) // right = 8 * R + 8 * hm * A
return (left.X.Cmp(right.X) == 0) && (left.Y.Cmp(right.Y) == 0)
}
// SignPoseidon signs a message encoded as a big.Int in Zq using blake-512 hash
// for buffer hashing and Poseidon for big.Int hashing.
func (k *PrivateKey) SignPoseidon(msg *big.Int) *Signature {
h1 := Blake512(k[:])
msgBuf := utils.BigIntLEBytes(msg)
msgBuf32 := [32]byte{}
copy(msgBuf32[:], msgBuf[:])
rBuf := Blake512(append(h1[32:], msgBuf32[:]...))
r := utils.SetBigIntFromLEBytes(new(big.Int), rBuf) // r = H(H_{32..63}(k), msg)
r.Mod(r, SubOrder)
R8 := NewPoint().Mul(r, B8) // R8 = r * 8 * B
A := k.Public().Point()
hmInput := []*big.Int{R8.X, R8.Y, A.X, A.Y, msg}
hm, err := poseidon.Hash(hmInput) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
if err != nil {
panic(err)
}
S := new(big.Int).Lsh(k.Scalar().BigInt(), 3)
S = S.Mul(hm, S)
S.Add(r, S)
S.Mod(S, SubOrder) // S = r + hm * 8 * s
return &Signature{R8: R8, S: S}
}
// VerifyPoseidon verifies the signature of a message encoded as a big.Int in Zq
// using blake-512 hash for buffer hashing and Poseidon for big.Int hashing.
func (p *PublicKey) VerifyPoseidon(msg *big.Int, sig *Signature) bool {
hmInput := []*big.Int{sig.R8.X, sig.R8.Y, p.X, p.Y, msg}
hm, err := poseidon.Hash(hmInput) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
if err != nil { if err != nil {
panic(err) panic(err)
} }
hm := mimc7.Hash(hmInput, nil) // hm = H1(8*R.x, 8*R.y, A.x, A.y, msg)
left := NewPoint().Mul(sig.S, B8) // left = s * 8 * B left := NewPoint().Mul(sig.S, B8) // left = s * 8 * B
r1 := big.NewInt(8) r1 := big.NewInt(8)

View File

@@ -4,13 +4,12 @@ import (
"crypto/rand" "crypto/rand"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"math/big"
"testing"
"github.com/iden3/go-iden3-crypto/constants" "github.com/iden3/go-iden3-crypto/constants"
"github.com/iden3/go-iden3-crypto/utils" "github.com/iden3/go-iden3-crypto/utils"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"math/big"
"testing"
) )
func genInputs() (*PrivateKey, *big.Int) { func genInputs() (*PrivateKey, *big.Int) {
@@ -26,7 +25,7 @@ func genInputs() (*PrivateKey, *big.Int) {
return &k, msg return &k, msg
} }
func TestSignVerify1(t *testing.T) { func TestSignVerifyMimc7(t *testing.T) {
var k PrivateKey var k PrivateKey
hex.Decode(k[:], []byte("0001020304050607080900010203040506070809000102030405060708090001")) hex.Decode(k[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
msgBuf, err := hex.DecodeString("00010203040506070809") msgBuf, err := hex.DecodeString("00010203040506070809")
@@ -37,21 +36,21 @@ func TestSignVerify1(t *testing.T) {
pk := k.Public() pk := k.Public()
assert.Equal(t, assert.Equal(t,
"2610057752638682202795145288373380503107623443963127956230801721756904484787", "13277427435165878497778222415993513565335242147425444199013288855685581939618",
pk.X.String()) pk.X.String())
assert.Equal(t, assert.Equal(t,
"16617171478497210597712478520507818259149717466230047843969353176573634386897", "13622229784656158136036771217484571176836296686641868549125388198837476602820",
pk.Y.String()) pk.Y.String())
sig := k.SignMimc7(msg) sig := k.SignMimc7(msg)
assert.Equal(t, assert.Equal(t,
"4974729414807584049518234760796200867685098748448054182902488636762478901554", "11384336176656855268977457483345535180380036354188103142384839473266348197733",
sig.R8.X.String()) sig.R8.X.String())
assert.Equal(t, assert.Equal(t,
"18714049394522540751536514815950425694461287643205706667341348804546050128733", "15383486972088797283337779941324724402501462225528836549661220478783371668959",
sig.R8.Y.String()) sig.R8.Y.String())
assert.Equal(t, assert.Equal(t,
"2171284143457722024136077617757713039502332290425057126942676527240038689549", "2523202440825208709475937830811065542425109372212752003460238913256192595070",
sig.S.String()) sig.S.String())
ok := pk.VerifyMimc7(msg, sig) ok := pk.VerifyMimc7(msg, sig)
@@ -62,14 +61,58 @@ func TestSignVerify1(t *testing.T) {
assert.Equal(t, nil, err) assert.Equal(t, nil, err)
assert.Equal(t, ""+ assert.Equal(t, ""+
"5dfb6f843c023fe3e52548ccf22e55c81b426f7af81b4f51f7152f2fcfc65f29"+ "dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+
"0dab19c5a0a75973cd75a54780de0c3a41ede6f57396fe99b5307fff3ce7cc04", "7ed40dab29bf993c928e789d007387998901a24913d44fddb64b1f21fc149405",
hex.EncodeToString(sigBuf[:])) hex.EncodeToString(sigBuf[:]))
ok = pk.VerifyMimc7(msg, sig2) ok = pk.VerifyMimc7(msg, sig2)
assert.Equal(t, true, ok) assert.Equal(t, true, ok)
} }
func TestSignVerifyPoseidon(t *testing.T) {
var k PrivateKey
hex.Decode(k[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))
msgBuf, err := hex.DecodeString("00010203040506070809")
if err != nil {
panic(err)
}
msg := utils.SetBigIntFromLEBytes(new(big.Int), msgBuf)
pk := k.Public()
assert.Equal(t,
"13277427435165878497778222415993513565335242147425444199013288855685581939618",
pk.X.String())
assert.Equal(t,
"13622229784656158136036771217484571176836296686641868549125388198837476602820",
pk.Y.String())
sig := k.SignPoseidon(msg)
assert.Equal(t,
"11384336176656855268977457483345535180380036354188103142384839473266348197733",
sig.R8.X.String())
assert.Equal(t,
"15383486972088797283337779941324724402501462225528836549661220478783371668959",
sig.R8.Y.String())
assert.Equal(t,
"248298168863866362217836334079793350221620631973732197668910946177382043688",
sig.S.String())
ok := pk.VerifyPoseidon(msg, sig)
assert.Equal(t, true, ok)
sigBuf := sig.Compress()
sig2, err := new(Signature).Decompress(sigBuf)
assert.Equal(t, nil, err)
assert.Equal(t, ""+
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+
"28506bce274aa1b3f7e7c2fd7e4fe09bff8f9aa37a42def7994e98f322888c00",
hex.EncodeToString(sigBuf[:]))
ok = pk.VerifyPoseidon(msg, sig2)
assert.Equal(t, true, ok)
}
func TestCompressDecompress(t *testing.T) { func TestCompressDecompress(t *testing.T) {
var k PrivateKey var k PrivateKey
hex.Decode(k[:], []byte("0001020304050607080900010203040506070809000102030405060708090001")) hex.Decode(k[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))

View File

@@ -2,19 +2,16 @@ package mimc7
import ( import (
"errors" "errors"
"fmt"
"math/big" "math/big"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
_constants "github.com/iden3/go-iden3-crypto/constants" _constants "github.com/iden3/go-iden3-crypto/constants"
"github.com/iden3/go-iden3-crypto/field" "github.com/iden3/go-iden3-crypto/field"
"github.com/iden3/go-iden3-crypto/utils"
) )
const SEED = "mimc" const SEED = "mimc"
// RElem is a big.Int of maximum 253 bits
type RElem *big.Int
var constants = generateConstantsData() var constants = generateConstantsData()
type constantsData struct { type constantsData struct {
@@ -26,9 +23,6 @@ type constantsData struct {
cts []*big.Int cts []*big.Int
} }
func getIV(seed string) {
}
func generateConstantsData() constantsData { func generateConstantsData() constantsData {
var constants constantsData var constants constantsData
@@ -43,45 +37,12 @@ func generateConstantsData() constantsData {
constants.iv = new(big.Int).Mod(c, constants.maxFieldVal) constants.iv = new(big.Int).Mod(c, constants.maxFieldVal)
constants.nRounds = 91 constants.nRounds = 91
cts, err := getConstants(constants.fqR, SEED, constants.nRounds) cts := getConstants(constants.fqR, SEED, constants.nRounds)
if err != nil {
panic(err)
}
constants.cts = cts constants.cts = cts
return constants return constants
} }
// BigIntToRElem checks if given big.Int fits in a Field R element, and returns the RElem type func getConstants(fqR field.Fq, seed string, nRounds int) []*big.Int {
func BigIntToRElem(a *big.Int) (RElem, error) {
if a.Cmp(constants.maxFieldVal) != -1 {
return RElem(a), errors.New("Given big.Int don't fits in the Finite Field over R")
}
return RElem(a), nil
}
//BigIntsToRElems converts from array of *big.Int to array of RElem
func BigIntsToRElems(arr []*big.Int) ([]RElem, error) {
o := make([]RElem, len(arr))
for i, a := range arr {
e, err := BigIntToRElem(a)
if err != nil {
return o, fmt.Errorf("element in position %v don't fits in Finite Field over R", i)
}
o[i] = e
}
return o, nil
}
// RElemsToBigInts converts from array of RElem to array of *big.Int
func RElemsToBigInts(arr []RElem) []*big.Int {
o := make([]*big.Int, len(arr))
for i, a := range arr {
o[i] = a
}
return o
}
func getConstants(fqR field.Fq, seed string, nRounds int) ([]*big.Int, error) {
cts := make([]*big.Int, nRounds) cts := make([]*big.Int, nRounds)
cts[0] = big.NewInt(int64(0)) cts[0] = big.NewInt(int64(0))
c := new(big.Int).SetBytes(crypto.Keccak256([]byte(SEED))) c := new(big.Int).SetBytes(crypto.Keccak256([]byte(SEED)))
@@ -91,15 +52,12 @@ func getConstants(fqR field.Fq, seed string, nRounds int) ([]*big.Int, error) {
n := fqR.Affine(c) n := fqR.Affine(c)
cts[i] = n cts[i] = n
} }
return cts, nil return cts
} }
// MIMC7HashGeneric performs the MIMC7 hash over a RElem, in a generic way, where it can be specified the Finite Field over R, and the number of rounds // MIMC7HashGeneric performs the MIMC7 hash over a *big.Int, in a generic way, where it can be specified the Finite Field over R, and the number of rounds
func MIMC7HashGeneric(fqR field.Fq, xIn, k *big.Int, nRounds int) (*big.Int, error) { func MIMC7HashGeneric(fqR field.Fq, xIn, k *big.Int, nRounds int) *big.Int {
cts, err := getConstants(fqR, SEED, nRounds) cts := getConstants(fqR, SEED, nRounds)
if err != nil {
return &big.Int{}, err
}
var r *big.Int var r *big.Int
for i := 0; i < nRounds; i++ { for i := 0; i < nRounds; i++ {
var t *big.Int var t *big.Int
@@ -112,24 +70,26 @@ func MIMC7HashGeneric(fqR field.Fq, xIn, k *big.Int, nRounds int) (*big.Int, err
t4 := fqR.Square(t2) t4 := fqR.Square(t2)
r = fqR.Mul(fqR.Mul(t4, t2), t) r = fqR.Mul(fqR.Mul(t4, t2), t)
} }
return fqR.Affine(fqR.Add(r, k)), nil return fqR.Affine(fqR.Add(r, k))
} }
// HashGeneric performs the MIMC7 hash over a RElem array, in a generic way, where it can be specified the Finite Field over R, and the number of rounds // HashGeneric performs the MIMC7 hash over a *big.Int array, in a generic way, where it can be specified the Finite Field over R, and the number of rounds
func HashGeneric(iv *big.Int, arrEl []RElem, fqR field.Fq, nRounds int) (RElem, error) { func HashGeneric(iv *big.Int, arr []*big.Int, fqR field.Fq, nRounds int) (*big.Int, error) {
arr := RElemsToBigInts(arrEl) if !utils.CheckBigIntArrayInField(arr, constants.fqR.Q) {
return nil, errors.New("inputs values not inside Finite Field")
}
r := iv r := iv
var err error var err error
for i := 0; i < len(arr); i++ { for i := 0; i < len(arr); i++ {
r, err = MIMC7HashGeneric(fqR, r, arr[i], nRounds) r = MIMC7HashGeneric(fqR, r, arr[i], nRounds)
if err != nil { if err != nil {
return r, err return r, err
} }
} }
return RElem(r), nil return r, nil
} }
// MIMC7Hash performs the MIMC7 hash over a RElem, using the Finite Field over R and the number of rounds setted in the `constants` variable // MIMC7Hash performs the MIMC7 hash over a *big.Int, using the Finite Field over R and the number of rounds setted in the `constants` variable
func MIMC7Hash(xIn, k *big.Int) *big.Int { func MIMC7Hash(xIn, k *big.Int) *big.Int {
var r *big.Int var r *big.Int
for i := 0; i < constants.nRounds; i++ { for i := 0; i < constants.nRounds; i++ {
@@ -146,16 +106,17 @@ func MIMC7Hash(xIn, k *big.Int) *big.Int {
return constants.fqR.Affine(constants.fqR.Add(r, k)) return constants.fqR.Affine(constants.fqR.Add(r, k))
} }
// Hash performs the MIMC7 hash over a RElem array // Hash performs the MIMC7 hash over a *big.Int array
func Hash(arrEl []RElem, key *big.Int) RElem { func Hash(arr []*big.Int, key *big.Int) (*big.Int, error) {
arr := RElemsToBigInts(arrEl) if !utils.CheckBigIntArrayInField(arr, constants.fqR.Q) {
return nil, errors.New("inputs values not inside Finite Field")
}
var r *big.Int var r *big.Int
if key == nil { if key == nil {
r = constants.fqR.Zero() r = constants.fqR.Zero()
} else { } else {
r = key r = key
} }
// r := constants.iv
for i := 0; i < len(arr); i++ { for i := 0; i < len(arr); i++ {
r = constants.fqR.Add( r = constants.fqR.Add(
constants.fqR.Add( constants.fqR.Add(
@@ -164,5 +125,5 @@ func Hash(arrEl []RElem, key *big.Int) RElem {
), ),
MIMC7Hash(arr[i], r)) MIMC7Hash(arr[i], r))
} }
return RElem(r) return r, nil
} }

View File

@@ -5,42 +5,16 @@ import (
"math/big" "math/big"
"testing" "testing"
"github.com/ethereum/go-ethereum/crypto"
"github.com/iden3/go-iden3-crypto/field" "github.com/iden3/go-iden3-crypto/field"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestUtils(t *testing.T) { func TestKeccak256(t *testing.T) {
b1 := big.NewInt(int64(1)) res := crypto.Keccak256([]byte(SEED))
b2 := big.NewInt(int64(2)) assert.Equal(t, "b6e489e6b37224a50bebfddbe7d89fa8fdcaa84304a70bd13f79b5d9f7951e9e", hex.EncodeToString(res))
b3 := big.NewInt(int64(3)) c := new(big.Int).SetBytes(crypto.Keccak256([]byte(SEED)))
arrBigInt := []*big.Int{b1, b2, b3} assert.Equal(t, "82724731331859054037315113496710413141112897654334566532528783843265082629790", c.String())
// *big.Int array to RElem array
rElems, err := BigIntsToRElems(arrBigInt)
assert.Nil(t, err)
// RElem array to *big.Int array
bElems := RElemsToBigInts(rElems)
assert.Equal(t, arrBigInt, bElems)
r, ok := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495617", 10)
assert.True(t, ok)
// greater or equal than R will give error when passing bigInts to RElems, to fit in the R Finite Field
overR, ok := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495618", 10)
assert.True(t, ok)
_, err = BigIntsToRElems([]*big.Int{b1, overR, b2})
assert.True(t, err != nil)
_, err = BigIntsToRElems([]*big.Int{b1, r, b2})
assert.True(t, err != nil)
// smaller than R will not give error when passing bigInts to RElems, to fit in the R Finite Field
underR, ok := new(big.Int).SetString("21888242871839275222246405745257275088548364400416034343698204186575808495616", 10)
assert.True(t, ok)
_, err = BigIntsToRElems([]*big.Int{b1, underR, b2})
assert.Nil(t, err)
} }
func TestMIMC7Generic(t *testing.T) { func TestMIMC7Generic(t *testing.T) {
@@ -53,14 +27,11 @@ func TestMIMC7Generic(t *testing.T) {
fqR := field.NewFq(r) fqR := field.NewFq(r)
bigArray := []*big.Int{b1, b2, b3} bigArray := []*big.Int{b1, b2, b3}
elementsArray, err := BigIntsToRElems(bigArray)
assert.Nil(t, err)
// Generic Hash // Generic Hash
mhg, err := MIMC7HashGeneric(fqR, b1, b2, 91) mhg := MIMC7HashGeneric(fqR, b1, b2, 91)
assert.Nil(t, err)
assert.Equal(t, "10594780656576967754230020536574539122676596303354946869887184401991294982664", mhg.String()) assert.Equal(t, "10594780656576967754230020536574539122676596303354946869887184401991294982664", mhg.String())
hg, err := HashGeneric(fqR.Zero(), elementsArray, fqR, 91) hg, err := HashGeneric(fqR.Zero(), bigArray, fqR, 91)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "6464402164086696096195815557694604139393321133243036833927490113253119343397", (*big.Int)(hg).String()) assert.Equal(t, "6464402164086696096195815557694604139393321133243036833927490113253119343397", (*big.Int)(hg).String())
} }
@@ -73,48 +44,36 @@ func TestMIMC7(t *testing.T) {
// h1, hash of 1 elements // h1, hash of 1 elements
bigArray1 := []*big.Int{b12} bigArray1 := []*big.Int{b12}
elementsArray1, err := BigIntsToRElems(bigArray1)
assert.Nil(t, err)
h1 := Hash(elementsArray1, nil) h1, err := Hash(bigArray1, nil)
assert.Nil(t, err) assert.Nil(t, err)
// same hash value than the iden3js and circomlib tests: // same hash value than the iden3js and circomlib tests:
assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(h1).Bytes()), "0x237c92644dbddb86d8a259e0e923aaab65a93f1ec5758b8799988894ac0958fd") assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(h1).Bytes()), "0x237c92644dbddb86d8a259e0e923aaab65a93f1ec5758b8799988894ac0958fd")
// h2a, hash of 2 elements // h2a, hash of 2 elements
bigArray2a := []*big.Int{b78, b41} bigArray2a := []*big.Int{b78, b41}
elementsArray2a, err := BigIntsToRElems(bigArray2a)
assert.Nil(t, err)
mh2a := MIMC7Hash(b12, b45) h2a, err := Hash(bigArray2a, nil)
assert.Nil(t, err)
assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(mh2a).Bytes()), "0x2ba7ebad3c6b6f5a20bdecba2333c63173ca1a5f2f49d958081d9fa7179c44e4")
h2a := Hash(elementsArray2a, nil)
assert.Nil(t, err) assert.Nil(t, err)
// same hash value than the iden3js and circomlib tests: // same hash value than the iden3js and circomlib tests:
assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(h2a).Bytes()), "0x067f3202335ea256ae6e6aadcd2d5f7f4b06a00b2d1e0de903980d5ab552dc70") assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(h2a).Bytes()), "0x067f3202335ea256ae6e6aadcd2d5f7f4b06a00b2d1e0de903980d5ab552dc70")
// h2b, hash of 2 elements // h2b, hash of 2 elements
bigArray2b := []*big.Int{b12, b45} bigArray2b := []*big.Int{b12, b45}
elementsArray2b, err := BigIntsToRElems(bigArray2b)
assert.Nil(t, err)
mh2b := MIMC7Hash(b12, b45) mh2b := MIMC7Hash(b12, b45)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(mh2b).Bytes()), "0x2ba7ebad3c6b6f5a20bdecba2333c63173ca1a5f2f49d958081d9fa7179c44e4") assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(mh2b).Bytes()), "0x2ba7ebad3c6b6f5a20bdecba2333c63173ca1a5f2f49d958081d9fa7179c44e4")
h2b := Hash(elementsArray2b, nil) h2b, err := Hash(bigArray2b, nil)
assert.Nil(t, err) assert.Nil(t, err)
// same hash value than the iden3js and circomlib tests: // same hash value than the iden3js and circomlib tests:
assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(h2b).Bytes()), "0x15ff7fe9793346a17c3150804bcb36d161c8662b110c50f55ccb7113948d8879") assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(h2b).Bytes()), "0x15ff7fe9793346a17c3150804bcb36d161c8662b110c50f55ccb7113948d8879")
// h4, hash of 4 elements // h4, hash of 4 elements
bigArray4 := []*big.Int{b12, b45, b78, b41} bigArray4 := []*big.Int{b12, b45, b78, b41}
elementsArray4, err := BigIntsToRElems(bigArray4)
assert.Nil(t, err)
h4 := Hash(elementsArray4, nil) h4, err := Hash(bigArray4, nil)
assert.Nil(t, err) assert.Nil(t, err)
// same hash value than the iden3js and circomlib tests: // same hash value than the iden3js and circomlib tests:
assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(h4).Bytes()), "0x284bc1f34f335933a23a433b6ff3ee179d682cd5e5e2fcdd2d964afa85104beb") assert.Equal(t, "0x"+hex.EncodeToString((*big.Int)(h4).Bytes()), "0x284bc1f34f335933a23a433b6ff3ee179d682cd5e5e2fcdd2d964afa85104beb")
@@ -126,12 +85,10 @@ func BenchmarkMIMC7(b *testing.B) {
b78 := big.NewInt(int64(78)) b78 := big.NewInt(int64(78))
b41 := big.NewInt(int64(41)) b41 := big.NewInt(int64(41))
bigArray4 := []*big.Int{b12, b45, b78, b41} bigArray4 := []*big.Int{b12, b45, b78, b41}
elementsArray4, err := BigIntsToRElems(bigArray4)
assert.Nil(b, err)
var h4 RElem var h4 *big.Int
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
h4 = Hash(elementsArray4, nil) h4, _ = Hash(bigArray4, nil)
} }
println(h4) println(h4)
} }