Compare commits

...

7 Commits

Author SHA1 Message Date
a_bennassar
674e8a6739 Fix value sql interface 2020-08-14 12:32:15 +02:00
a_bennassar
a86308cb0b Add scanner/valuer interface to PublicKey 2020-08-13 12:43:48 +02:00
a_bennassar
d91a4261f1 Add scanner/valuer interface to signature 2020-08-12 15:52:10 +02:00
Eduard S
327a8175d6 Merge pull request #26 from iden3/feature/pointfromsigny
Babyjubjub separate PointFromSignAndY from p.Decompress
2020-08-06 13:50:47 +02:00
arnaucube
833f68a614 Babyjubjub separate PointFromSignAndY from p.Decompress 2020-08-06 13:34:36 +02:00
Eduard S
29a66457f0 Merge pull request #25 from iden3/feature/poseidon-update
Update Poseidon Hash function names, rm HashBytes
2020-07-23 10:24:57 +02:00
arnaucube
f22be3cdee Update Poseidon Hash function names, rm HashBytes
Since Poseidon Hash is used because of compatibility in zkSNARK circuits, due
circuit constraints number, the hash method of [T]*big.Int is the one directly
compatible with the circuits, is the method which have the `Hash` name on it.
The method that can take arbitrary length of []*big.Int putting them in chunks
of [T]*big.Int and iterating, is called `HashSlice`. The `HashBytes` has been
removed, as is a method that will not be used in zkSNARK circuits due high
constraints number.

For zkSNARK circuits, should be used `poseidon.Hash([poseidon.T]*big.Int)`.
2020-07-23 07:59:59 +02:00
8 changed files with 148 additions and 59 deletions

View File

@@ -181,6 +181,14 @@ func (p *Point) Decompress(leBuf [32]byte) (*Point, error) {
leBuf[31] = leBuf[31] & 0x7F leBuf[31] = leBuf[31] & 0x7F
} }
utils.SetBigIntFromLEBytes(p.Y, leBuf[:]) utils.SetBigIntFromLEBytes(p.Y, leBuf[:])
return PointFromSignAndY(sign, p.Y)
}
// PointFromSignAndY returns a Point from a Sign and the Y coordinate
func PointFromSignAndY(sign bool, y *big.Int) (*Point, error) {
var p Point
p.X = big.NewInt(0)
p.Y = y
if p.Y.Cmp(constants.Q) >= 0 { if p.Y.Cmp(constants.Q) >= 0 {
return nil, fmt.Errorf("p.y >= Q") return nil, fmt.Errorf("p.y >= Q")
} }
@@ -209,5 +217,5 @@ func (p *Point) Decompress(leBuf [32]byte) (*Point, error) {
} }
p.X.Mod(p.X, constants.Q) p.X.Mod(p.X, constants.Q)
return p, nil return &p, nil
} }

View File

@@ -192,6 +192,20 @@ func TestInSubGroup2(t *testing.T) {
assert.Equal(t, true, p.InSubGroup()) assert.Equal(t, true, p.InSubGroup())
} }
func TestPointFromSignAndy(t *testing.T) {
x := utils.NewIntFromString(
"17777552123799933955779906779655732241715742912184938656739573121738514868268")
y := utils.NewIntFromString(
"2626589144620713026669568689430873010625803728049924121243784502389097019475")
p := &Point{X: x, Y: y}
sign := PointCoordSign(p.X)
p2, err := PointFromSignAndY(sign, p.Y)
assert.Equal(t, nil, err)
assert.Equal(t, p.X.String(), p2.X.String())
assert.Equal(t, p.Y.String(), p2.Y.String())
}
func TestCompressDecompress1(t *testing.T) { func TestCompressDecompress1(t *testing.T) {
x := utils.NewIntFromString( x := utils.NewIntFromString(
"17777552123799933955779906779655732241715742912184938656739573121738514868268") "17777552123799933955779906779655732241715742912184938656739573121738514868268")

View File

@@ -2,6 +2,8 @@ package babyjub
import ( import (
"crypto/rand" "crypto/rand"
"database/sql/driver"
"fmt"
"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/poseidon"
@@ -175,6 +177,27 @@ func (s *SignatureComp) Decompress() (*Signature, error) {
return new(Signature).Decompress(*s) return new(Signature).Decompress(*s)
} }
// Scan implements Scanner for database/sql.
func (s *Signature) Scan(src interface{}) error {
srcB, ok := src.([]byte)
if !ok {
return fmt.Errorf("can't scan %T into Signature", src)
}
if len(srcB) != 64 {
return fmt.Errorf("can't scan []byte of len %d into Signature, want %d", len(srcB), 64)
}
buf := [64]byte{}
copy(buf[:], srcB[:])
_, err := s.Decompress(buf)
return err
}
// Value implements valuer for database/sql.
func (s Signature) Value() (driver.Value, error) {
comp := s.Compress()
return comp[:], nil
}
// SignMimc7 signs a message encoded as a big.Int in Zq using blake-512 hash // SignMimc7 signs a message encoded as a big.Int in Zq using blake-512 hash
// for buffer hashing and mimc7 for big.Int hashing. // for buffer hashing and mimc7 for big.Int hashing.
func (k *PrivateKey) SignMimc7(msg *big.Int) *Signature { func (k *PrivateKey) SignMimc7(msg *big.Int) *Signature {
@@ -231,7 +254,7 @@ func (k *PrivateKey) SignPoseidon(msg *big.Int) *Signature {
A := k.Public().Point() A := k.Public().Point()
hmInput := [poseidon.T]*big.Int{R8.X, R8.Y, A.X, A.Y, msg, big.NewInt(int64(0))} hmInput := [poseidon.T]*big.Int{R8.X, R8.Y, A.X, A.Y, msg, big.NewInt(int64(0))}
hm, err := poseidon.PoseidonHash(hmInput) // hm = H1(8*R.x, 8*R.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 { if err != nil {
panic(err) panic(err)
} }
@@ -248,7 +271,7 @@ func (k *PrivateKey) SignPoseidon(msg *big.Int) *Signature {
// using blake-512 hash for buffer hashing and Poseidon for big.Int hashing. // using blake-512 hash for buffer hashing and Poseidon for big.Int hashing.
func (p *PublicKey) VerifyPoseidon(msg *big.Int, sig *Signature) bool { func (p *PublicKey) VerifyPoseidon(msg *big.Int, sig *Signature) bool {
hmInput := [poseidon.T]*big.Int{sig.R8.X, sig.R8.Y, p.X, p.Y, msg, big.NewInt(int64(0))} hmInput := [poseidon.T]*big.Int{sig.R8.X, sig.R8.Y, p.X, p.Y, msg, big.NewInt(int64(0))}
hm, err := poseidon.PoseidonHash(hmInput) // hm = H1(8*R.x, 8*R.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 { if err != nil {
panic(err) panic(err)
} }
@@ -260,3 +283,28 @@ func (p *PublicKey) VerifyPoseidon(msg *big.Int, sig *Signature) bool {
right.Add(sig.R8, right) // right = 8 * R + 8 * hm * A right.Add(sig.R8, right) // right = 8 * R + 8 * hm * A
return (left.X.Cmp(right.X) == 0) && (left.Y.Cmp(right.Y) == 0) return (left.X.Cmp(right.X) == 0) && (left.Y.Cmp(right.Y) == 0)
} }
// Scan implements Scanner for database/sql.
func (p *PublicKey) Scan(src interface{}) error {
srcB, ok := src.([]byte)
if !ok {
return fmt.Errorf("can't scan %T into PublicKey", src)
}
if len(srcB) != 32 {
return fmt.Errorf("can't scan []byte of len %d into PublicKey, want %d", len(srcB), 32)
}
var comp PublicKeyComp
copy(comp[:], srcB)
decomp, err := comp.Decompress()
if err != nil {
return err
}
*p = *decomp
return nil
}
// Value implements valuer for database/sql.
func (p PublicKey) Value() (driver.Value, error) {
comp := p.Compress()
return comp[:], nil
}

View File

@@ -6,6 +6,9 @@ import (
"math/big" "math/big"
"testing" "testing"
"database/sql"
"database/sql/driver"
"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"
@@ -132,6 +135,33 @@ func TestCompressDecompress(t *testing.T) {
} }
} }
func TestSignatureScannerValuer(t *testing.T) {
privK := NewRandPrivKey()
var value driver.Valuer
var scan sql.Scanner
value = privK.SignPoseidon(big.NewInt(674238462))
scan = privK.SignPoseidon(big.NewInt(1))
fromDB, err := value.Value()
assert.NoError(t, err)
assert.NoError(t, scan.Scan(fromDB))
assert.Equal(t, value, scan)
}
func TestPubKeyScannerValuer(t *testing.T) {
privKValue := NewRandPrivKey()
pubKValue := privKValue.Public()
privKScan := NewRandPrivKey()
pubKScan := privKScan.Public()
var value driver.Valuer
var scan sql.Scanner
value = pubKValue
scan = pubKScan
fromDB, err := value.Value()
assert.NoError(t, err)
assert.NoError(t, scan.Scan(fromDB))
assert.Equal(t, value, scan)
}
func BenchmarkBabyjubEddsa(b *testing.B) { func BenchmarkBabyjubEddsa(b *testing.B) {
var k PrivateKey var k PrivateKey
_, err := hex.Decode(k[:], []byte("0001020304050607080900010203040506070809000102030405060708090001")) _, err := hex.Decode(k[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))

1
go.mod
View File

@@ -7,4 +7,5 @@ require (
github.com/ethereum/go-ethereum v1.9.12 github.com/ethereum/go-ethereum v1.9.12
github.com/stretchr/testify v1.4.0 github.com/stretchr/testify v1.4.0
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd // indirect
) )

10
go.sum
View File

@@ -50,8 +50,6 @@ github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87/go.mod h1:Mw6PkjjMXWbT
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa h1:XKAhUk/dtp+CV0VO6mhG2V7jA9vbcGcnYF/Ay9NjZrY= github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa h1:XKAhUk/dtp+CV0VO6mhG2V7jA9vbcGcnYF/Ay9NjZrY=
github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs= github.com/elastic/gosigar v0.8.1-0.20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
github.com/ethereum/go-ethereum v1.8.27 h1:d+gkiLaBDk5fn3Pe/xNVaMrB/ozI+AUB2IlVBp29IrY=
github.com/ethereum/go-ethereum v1.8.27/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
github.com/ethereum/go-ethereum v1.9.12 h1:EPtimwsp/KGDSiXcNunzsI4kefdsMHZGJntKx3fvbaI= github.com/ethereum/go-ethereum v1.9.12 h1:EPtimwsp/KGDSiXcNunzsI4kefdsMHZGJntKx3fvbaI=
github.com/ethereum/go-ethereum v1.9.12/go.mod h1:PvsVkQmhZFx92Y+h2ylythYlheEDt/uBgFbl61Js/jo= github.com/ethereum/go-ethereum v1.9.12/go.mod h1:PvsVkQmhZFx92Y+h2ylythYlheEDt/uBgFbl61Js/jo=
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
@@ -76,15 +74,16 @@ github.com/graph-gophers/graphql-go v0.0.0-20191115155744-f33e81362277/go.mod h1
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag= github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag=
github.com/iden3/go-iden3 v0.0.5 h1:NV6HXnLmp+1YmKd2FmymzU6OAP77q1WWDcB/B+BUL9g=
github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
@@ -138,8 +137,6 @@ github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:s
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4 h1:ydJNl0ENAG67pFbB+9tfhiL2pYqLhfoaZFw/cjLhY4A=
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 h1:QmwruyY+bKbDDL0BaglrbZABEali68eoMFhTZpCjYVA= golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 h1:QmwruyY+bKbDDL0BaglrbZABEali68eoMFhTZpCjYVA=
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -154,12 +151,15 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=

View File

@@ -120,8 +120,8 @@ func mix(state [T]*ff.Element, newState [T]*ff.Element, m [T][T]*ff.Element) {
} }
} }
// PoseidonHash computes the Poseidon hash for the given inputs // Hash computes the Poseidon hash for the given inputs
func PoseidonHash(inpBI [T]*big.Int) (*big.Int, error) { func Hash(inpBI [T]*big.Int) (*big.Int, error) {
if !utils.CheckBigIntArrayInField(inpBI[:]) { if !utils.CheckBigIntArrayInField(inpBI[:]) {
return nil, errors.New("inputs values not inside Finite Field") return nil, errors.New("inputs values not inside Finite Field")
} }
@@ -148,9 +148,9 @@ func PoseidonHash(inpBI [T]*big.Int) (*big.Int, error) {
return r, nil return r, nil
} }
// Hash performs the Poseidon hash over a ff.Element array // HashSlice performs the Poseidon hash over a ff.Element array
// in chunks of 5 elements // in chunks of 5 elements
func Hash(arr []*big.Int) (*big.Int, error) { func HashSlice(arr []*big.Int) (*big.Int, error) {
r := big.NewInt(int64(1)) r := big.NewInt(int64(1))
for i := 0; i < len(arr); i = i + T - 1 { for i := 0; i < len(arr); i = i + T - 1 {
var toHash [T]*big.Int var toHash [T]*big.Int
@@ -167,7 +167,7 @@ func Hash(arr []*big.Int) (*big.Int, error) {
toHash[j] = big.NewInt(0) toHash[j] = big.NewInt(0)
} }
ph, err := PoseidonHash(toHash) ph, err := Hash(toHash)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -176,26 +176,3 @@ func Hash(arr []*big.Int) (*big.Int, error) {
return r, nil return r, nil
} }
// HashBytes hashes a msg byte slice by blocks of 31 bytes encoded as
// little-endian
func HashBytes(b []byte) *big.Int {
n := 31
bElems := make([]*big.Int, 0, len(b)/n+1)
for i := 0; i < len(b)/n; i++ {
v := big.NewInt(int64(0))
utils.SetBigIntFromLEBytes(v, b[n*i:n*(i+1)])
bElems = append(bElems, v)
}
if len(b)%n != 0 {
v := big.NewInt(int64(0))
utils.SetBigIntFromLEBytes(v, b[(len(b)/n)*n:])
bElems = append(bElems, v)
}
h, err := Hash(bElems)
if err != nil {
panic(err)
}
return h
}

View File

@@ -15,16 +15,31 @@ func TestBlake2bVersion(t *testing.T) {
assert.Equal(t, "e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1", hex.EncodeToString(h[:])) assert.Equal(t, "e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1", hex.EncodeToString(h[:]))
} }
func TestPoseidon(t *testing.T) { func TestPoseidonHash(t *testing.T) {
b0 := big.NewInt(0)
b1 := big.NewInt(1) b1 := big.NewInt(1)
b2 := big.NewInt(2) b2 := big.NewInt(2)
h, err := Hash([]*big.Int{b1, b2}) h, err := Hash([T]*big.Int{b1, b2, b0, b0, b0, b0})
assert.Nil(t, err)
assert.Equal(t, "12242166908188651009877250812424843524687801523336557272219921456462821518061", h.String())
b3 := big.NewInt(3)
b4 := big.NewInt(4)
h, err = Hash([T]*big.Int{b3, b4, b0, b0, b0, b0})
assert.Nil(t, err)
assert.Equal(t, "17185195740979599334254027721507328033796809509313949281114643312710535000993", h.String())
}
func TestPoseidonHashArbitraryLen(t *testing.T) {
b1 := big.NewInt(1)
b2 := big.NewInt(2)
h, err := HashSlice([]*big.Int{b1, b2})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "4932297968297298434239270129193057052722409868268166443802652458940273154855", h.String()) assert.Equal(t, "4932297968297298434239270129193057052722409868268166443802652458940273154855", h.String())
b3 := big.NewInt(3) b3 := big.NewInt(3)
b4 := big.NewInt(4) b4 := big.NewInt(4)
h, err = Hash([]*big.Int{b3, b4}) h, err = HashSlice([]*big.Int{b3, b4})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "4635491972858758537477743930622086396911540895966845494943021655521913507504", h.String()) assert.Equal(t, "4635491972858758537477743930622086396911540895966845494943021655521913507504", h.String())
@@ -36,7 +51,7 @@ func TestPoseidon(t *testing.T) {
b10 := big.NewInt(10) b10 := big.NewInt(10)
b11 := big.NewInt(11) b11 := big.NewInt(11)
b12 := big.NewInt(12) b12 := big.NewInt(12)
h, err = Hash([]*big.Int{b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12}) h, err = HashSlice([]*big.Int{b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "15278801138972282646981503374384603641625274360649669926363020545395022098027", h.String()) assert.Equal(t, "15278801138972282646981503374384603641625274360649669926363020545395022098027", h.String())
@@ -53,7 +68,7 @@ func TestPoseidon(t *testing.T) {
utils.SetBigIntFromLEBytes(v, msg[(len(msg)/n)*n:]) utils.SetBigIntFromLEBytes(v, msg[(len(msg)/n)*n:])
msgElems = append(msgElems, v) msgElems = append(msgElems, v)
} }
hmsg, err := Hash(msgElems) hmsg, err := HashSlice(msgElems)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "16019700159595764790637132363672701294192939959594423814006267756172551741065", hmsg.String()) assert.Equal(t, "16019700159595764790637132363672701294192939959594423814006267756172551741065", hmsg.String())
@@ -69,33 +84,30 @@ func TestPoseidon(t *testing.T) {
utils.SetBigIntFromLEBytes(v, msg2[(len(msg2)/n)*n:]) utils.SetBigIntFromLEBytes(v, msg2[(len(msg2)/n)*n:])
msg2Elems = append(msg2Elems, v) msg2Elems = append(msg2Elems, v)
} }
hmsg2, err := Hash(msg2Elems) hmsg2, err := HashSlice(msg2Elems)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "2978613163687734485261639854325792381691890647104372645321246092227111432722", hmsg2.String()) assert.Equal(t, "2978613163687734485261639854325792381691890647104372645321246092227111432722", hmsg2.String())
hmsg2 = HashBytes(msg2)
assert.Equal(t, "2978613163687734485261639854325792381691890647104372645321246092227111432722", hmsg2.String())
} }
func TestPoseidonBrokenChunks(t *testing.T) { func TestPoseidonHashArbitraryLenBrokenChunks(t *testing.T) {
h1, err := Hash([]*big.Int{big.NewInt(0), big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4), h1, err := HashSlice([]*big.Int{big.NewInt(0), big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4),
big.NewInt(5), big.NewInt(6), big.NewInt(7), big.NewInt(8), big.NewInt(9)}) big.NewInt(5), big.NewInt(6), big.NewInt(7), big.NewInt(8), big.NewInt(9)})
assert.Nil(t, err) assert.Nil(t, err)
h2, err := Hash([]*big.Int{big.NewInt(5), big.NewInt(6), big.NewInt(7), big.NewInt(8), big.NewInt(9), h2, err := HashSlice([]*big.Int{big.NewInt(5), big.NewInt(6), big.NewInt(7), big.NewInt(8), big.NewInt(9),
big.NewInt(0), big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4)}) big.NewInt(0), big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4)})
assert.Nil(t, err) assert.Nil(t, err)
assert.NotEqual(t, h1, h2) assert.NotEqual(t, h1, h2)
} }
func TestPoseidonBrokenPadding(t *testing.T) { func TestPoseidonHashArbitraryLenBrokenPadding(t *testing.T) {
h1, err := Hash([]*big.Int{big.NewInt(int64(1))}) h1, err := HashSlice([]*big.Int{big.NewInt(int64(1))})
assert.Nil(t, err) assert.Nil(t, err)
h2, err := Hash([]*big.Int{big.NewInt(int64(1)), big.NewInt(int64(0))}) h2, err := HashSlice([]*big.Int{big.NewInt(int64(1)), big.NewInt(int64(0))})
assert.Nil(t, err) assert.Nil(t, err)
assert.NotEqual(t, h1, h2) assert.NotEqual(t, h1, h2)
} }
func BenchmarkPoseidon(b *testing.B) { func BenchmarkPoseidonHashSmallValues(b *testing.B) {
b12 := big.NewInt(int64(12)) b12 := big.NewInt(int64(12))
b45 := big.NewInt(int64(45)) b45 := big.NewInt(int64(45))
b78 := big.NewInt(int64(78)) b78 := big.NewInt(int64(78))
@@ -103,17 +115,16 @@ func BenchmarkPoseidon(b *testing.B) {
bigArray4 := []*big.Int{b12, b45, b78, b41} bigArray4 := []*big.Int{b12, b45, b78, b41}
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Hash(bigArray4) //nolint:errcheck HashSlice(bigArray4) //nolint:errcheck
} }
} }
func BenchmarkPoseidonLarge(b *testing.B) { func BenchmarkPoseidonHash(b *testing.B) {
b12 := utils.NewIntFromString("11384336176656855268977457483345535180380036354188103142384839473266348197733") b0 := big.NewInt(0)
b45 := utils.NewIntFromString("11384336176656855268977457483345535180380036354188103142384839473266348197733") b1 := utils.NewIntFromString("12242166908188651009877250812424843524687801523336557272219921456462821518061")
b78 := utils.NewIntFromString("11384336176656855268977457483345535180380036354188103142384839473266348197733") b2 := utils.NewIntFromString("12242166908188651009877250812424843524687801523336557272219921456462821518061")
b41 := utils.NewIntFromString("11384336176656855268977457483345535180380036354188103142384839473266348197733")
bigArray4 := []*big.Int{b12, b45, b78, b41} bigArray4 := [T]*big.Int{b1, b2, b0, b0, b0, b0}
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
Hash(bigArray4) //nolint:errcheck Hash(bigArray4) //nolint:errcheck