Compare commits

..

10 Commits

Author SHA1 Message Date
arnaucube
590573a0af Update Poseidon last changes of the reference impl
Update Poseidon to last changes of the reference implementation from
26ddaa91db

Compatible with update at circomlib
(cf853c1cc9)
2021-03-08 14:59:42 +01:00
Eduard S
58e589b6eb Merge pull request #35 from iden3/feature/comp-point-test
Update and add test for PackSignY & UnpackSignY
2020-12-21 17:03:44 +01:00
arnaucube
2318fd7044 Update and add test for PackSignY & UnpackSignY
- Update PackSignY & UnpackSignY interface and description
- Add test for UnpackSignY & PackPoint
2020-12-21 16:58:13 +01:00
Eduard S
a0722b9e8f Merge pull request #34 from iden3/feature/exp-comppoint-signy
Abstract & expose CompressedPointToSignAndY
2020-12-21 16:21:27 +01:00
arnaucube
71dbddb5f1 Abstract & expose CompressedPointToSignAndY 2020-12-21 16:12:49 +01:00
Eduard S
0a5c6acba3 Merge pull request #33 from iden3/feature/pkcomp-scanvalue
Add scanner/valuer interface to babyjub.PublicKeyComp
2020-12-21 10:31:37 +01:00
arnaucube
a366175021 Add scanner/valuer interface to babyjub.PublicKeyComp 2020-12-18 20:44:29 +01:00
Eduard S
a2015adb2f Merge pull request #32 from iden3/feature/upgrade-linters
Upgrade linters
2020-12-18 12:11:45 +01:00
arnaucube
6d75396b4b Upgrade linters 2020-12-16 15:07:19 +01:00
Eduard S
821a601d20 Merge pull request #31 from iden3/feature/update-bbjjeddsa
Update BabyJubJub EdDSA to last circomlib version
2020-12-03 10:52:29 +01:00
14 changed files with 287 additions and 131 deletions

View File

@@ -1,5 +1,5 @@
on: [ push, pull_request ]
name: Lint name: Lint
on: [ push, pull_request ]
jobs: jobs:
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -12,5 +12,5 @@ jobs:
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Lint - name: Lint
run: | run: |
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.24.0 curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.30.0
$(go env GOPATH)/bin/golangci-lint run $(go env GOPATH)/bin/golangci-lint run --timeout=5m -c .golangci.yml

17
.golangci.yml Normal file
View File

@@ -0,0 +1,17 @@
issues:
max-same-issues: 0
exclude-use-default: false
linters:
enable:
- whitespace
- gosec
- gci
- misspell
- gomnd
- gofmt
- goimports
- lll
- golint
linters-settings:
lll:
line-length: 100

View File

@@ -59,7 +59,8 @@ type PointProjective struct {
// NewPointProjective creates a new Point in projective coordinates. // NewPointProjective creates a new Point in projective coordinates.
func NewPointProjective() *PointProjective { func NewPointProjective() *PointProjective {
return &PointProjective{X: ff.NewElement().SetZero(), Y: ff.NewElement().SetOne(), Z: ff.NewElement().SetOne()} return &PointProjective{X: ff.NewElement().SetZero(),
Y: ff.NewElement().SetOne(), Z: ff.NewElement().SetOne()}
} }
// Affine returns the Point from the projective representation // Affine returns the Point from the projective representation
@@ -84,19 +85,21 @@ func (p *PointProjective) Affine() *Point {
} }
} }
// Add computes the addition of two points in projective coordinates representation // Add computes the addition of two points in projective coordinates
func (res *PointProjective) Add(p *PointProjective, q *PointProjective) *PointProjective { // representation
// add-2008-bbjlp https://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html#doubling-dbl-2008-bbjlp func (p *PointProjective) Add(q *PointProjective, o *PointProjective) *PointProjective {
a := ff.NewElement().Mul(p.Z, q.Z) // add-2008-bbjlp
// https://hyperelliptic.org/EFD/g1p/auto-twisted-projective.html#doubling-dbl-2008-bbjlp
a := ff.NewElement().Mul(q.Z, o.Z)
b := ff.NewElement().Square(a) b := ff.NewElement().Square(a)
c := ff.NewElement().Mul(p.X, q.X) c := ff.NewElement().Mul(q.X, o.X)
d := ff.NewElement().Mul(p.Y, q.Y) d := ff.NewElement().Mul(q.Y, o.Y)
e := ff.NewElement().Mul(Dff, c) e := ff.NewElement().Mul(Dff, c)
e.MulAssign(d) e.MulAssign(d)
f := ff.NewElement().Sub(b, e) f := ff.NewElement().Sub(b, e)
g := ff.NewElement().Add(b, e) g := ff.NewElement().Add(b, e)
x1y1 := ff.NewElement().Add(p.X, p.Y) x1y1 := ff.NewElement().Add(q.X, q.Y)
x2y2 := ff.NewElement().Add(q.X, q.Y) x2y2 := ff.NewElement().Add(o.X, o.Y)
x3 := ff.NewElement().Mul(x1y1, x2y2) x3 := ff.NewElement().Mul(x1y1, x2y2)
x3.SubAssign(c) x3.SubAssign(c)
x3.SubAssign(d) x3.SubAssign(d)
@@ -108,10 +111,10 @@ func (res *PointProjective) Add(p *PointProjective, q *PointProjective) *PointPr
y3.MulAssign(g) y3.MulAssign(g)
z3 := ff.NewElement().Mul(f, g) z3 := ff.NewElement().Mul(f, g)
res.X = x3 p.X = x3
res.Y = y3 p.Y = y3
res.Z = z3 p.Z = z3
return res return p
} }
// Point represents a point of the babyjub curve. // Point represents a point of the babyjub curve.
@@ -141,15 +144,15 @@ func (p *Point) Projective() *PointProjective {
} }
} }
// Mul multiplies the Point p by the scalar s and stores the result in res, // Mul multiplies the Point q by the scalar s and stores the result in p,
// which is also returned. // which is also returned.
func (res *Point) Mul(s *big.Int, p *Point) *Point { func (p *Point) Mul(s *big.Int, q *Point) *Point {
resProj := &PointProjective{ resProj := &PointProjective{
X: ff.NewElement().SetZero(), X: ff.NewElement().SetZero(),
Y: ff.NewElement().SetOne(), Y: ff.NewElement().SetOne(),
Z: ff.NewElement().SetOne(), Z: ff.NewElement().SetOne(),
} }
exp := p.Projective() exp := q.Projective()
for i := 0; i < s.BitLen(); i++ { for i := 0; i < s.BitLen(); i++ {
if s.Bit(i) == 1 { if s.Bit(i) == 1 {
@@ -157,8 +160,8 @@ func (res *Point) Mul(s *big.Int, p *Point) *Point {
} }
exp = exp.Add(exp, exp) exp = exp.Add(exp, exp)
} }
res = resProj.Affine() p = resProj.Affine()
return res return p
} }
// InCurve returns true when the Point p is in the babyjub curve. // InCurve returns true when the Point p is in the babyjub curve.
@@ -200,30 +203,46 @@ func PointCoordSign(c *big.Int) bool {
return c.Cmp(new(big.Int).Rsh(constants.Q, 1)) == 1 return c.Cmp(new(big.Int).Rsh(constants.Q, 1)) == 1
} }
func PackPoint(ay *big.Int, sign bool) [32]byte { // PackSignY packs the given sign and the coordinate Y of a point into a 32
leBuf := utils.BigIntLEBytes(ay) // byte array. This method does not check that the values belong to a valid
// Point in the curve.
func PackSignY(sign bool, y *big.Int) [32]byte {
leBuf := utils.BigIntLEBytes(y)
if sign { if sign {
leBuf[31] = leBuf[31] | 0x80 leBuf[31] = leBuf[31] | 0x80 //nolint:gomnd
} }
return leBuf return leBuf
} }
// UnpackSignY returns the sign and coordinate Y from a given compressed point.
// This method does not check that the Point belongs to the BabyJubJub curve,
// thus does not return error in such case. This method is intended to obtain
// the sign and the Y coordinate without checking if the point belongs to the
// curve, if the objective is to uncompress a point, Decompress method should
// be used instead.
func UnpackSignY(leBuf [32]byte) (bool, *big.Int) {
sign := false
y := big.NewInt(0)
if (leBuf[31] & 0x80) != 0x00 { //nolint:gomnd
sign = true
leBuf[31] = leBuf[31] & 0x7F //nolint:gomnd
}
utils.SetBigIntFromLEBytes(y, leBuf[:])
return sign, y
}
// 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 := PointCoordSign(p.X) sign := PointCoordSign(p.X)
return PackPoint(p.Y, sign) return PackSignY(sign, p.Y)
} }
// Decompress a compressed Point into p, and also returns the decompressed // Decompress a compressed Point into p, and also returns the decompressed
// Point. Returns error if the compressed Point is invalid. // Point. Returns error if the compressed Point is invalid.
func (p *Point) Decompress(leBuf [32]byte) (*Point, error) { func (p *Point) Decompress(leBuf [32]byte) (*Point, error) {
sign := false var sign bool
if (leBuf[31] & 0x80) != 0x00 { sign, p.Y = UnpackSignY(leBuf)
sign = true
leBuf[31] = leBuf[31] & 0x7F
}
utils.SetBigIntFromLEBytes(p.Y, leBuf[:])
return PointFromSignAndY(sign, p.Y) return PointFromSignAndY(sign, p.Y)
} }

View File

@@ -44,7 +44,9 @@ func TestAdd2(t *testing.T) {
c.Y.String()) c.Y.String())
d := NewPointProjective().Add(c.Projective(), c.Projective()).Affine() d := NewPointProjective().Add(c.Projective(), c.Projective()).Affine()
assert.Equal(t, "2f6458832049e917c95867185a96621336df33e13c98e81d1ef4928cdbb77772", hex.EncodeToString(d.X.Bytes())) assert.Equal(t,
"2f6458832049e917c95867185a96621336df33e13c98e81d1ef4928cdbb77772",
hex.EncodeToString(d.X.Bytes()))
// Projective // Projective
aP := a.Projective() aP := a.Projective()
@@ -52,7 +54,6 @@ func TestAdd2(t *testing.T) {
cP := NewPointProjective().Add(aP, bP) cP := NewPointProjective().Add(aP, bP)
c2 := cP.Affine() c2 := cP.Affine()
assert.Equal(t, c, c2) assert.Equal(t, c, c2)
} }
func TestAdd3(t *testing.T) { func TestAdd3(t *testing.T) {
@@ -217,6 +218,26 @@ func TestPointFromSignAndy(t *testing.T) {
assert.Equal(t, p.Y.String(), p2.Y.String()) assert.Equal(t, p.Y.String(), p2.Y.String())
} }
func TestPackAndUnpackSignY(t *testing.T) {
x := utils.NewIntFromString(
"17777552123799933955779906779655732241715742912184938656739573121738514868268")
y := utils.NewIntFromString(
"2626589144620713026669568689430873010625803728049924121243784502389097019475")
p := &Point{X: x, Y: y}
pComp := p.Compress()
s, y := UnpackSignY(pComp)
pComp2 := PackSignY(s, y)
assert.Equal(t, pComp, pComp2)
emptyPointComp := [32]byte{}
s, y = UnpackSignY(emptyPointComp)
pComp2 = PackSignY(s, y)
assert.Equal(t, emptyPointComp, pComp2)
}
func TestCompressDecompress1(t *testing.T) { func TestCompressDecompress1(t *testing.T) {
x := utils.NewIntFromString( x := utils.NewIntFromString(
"17777552123799933955779906779655732241715742912184938656739573121738514868268") "17777552123799933955779906779655732241715742912184938656739573121738514868268")
@@ -225,7 +246,9 @@ func TestCompressDecompress1(t *testing.T) {
p := &Point{X: x, Y: y} p := &Point{X: x, Y: y}
buf := p.Compress() buf := p.Compress()
assert.Equal(t, "53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85", hex.EncodeToString(buf[:])) assert.Equal(t,
"53b81ed5bffe9545b54016234682e7b2f699bd42a5e9eae27ff4051bc698ce85",
hex.EncodeToString(buf[:]))
p2, err := NewPoint().Decompress(buf) p2, err := NewPoint().Decompress(buf)
assert.Equal(t, nil, err) assert.Equal(t, nil, err)
@@ -241,7 +264,9 @@ func TestCompressDecompress2(t *testing.T) {
p := &Point{X: x, Y: y} p := &Point{X: x, Y: y}
buf := p.Compress() buf := p.Compress()
assert.Equal(t, "e114eb17eddf794f063a68fecac515e3620e131976108555735c8b0773929709", hex.EncodeToString(buf[:])) assert.Equal(t,
"e114eb17eddf794f063a68fecac515e3620e131976108555735c8b0773929709",
hex.EncodeToString(buf[:]))
p2, err := NewPoint().Decompress(buf) p2, err := NewPoint().Decompress(buf)
assert.Equal(t, nil, err) assert.Equal(t, nil, err)
@@ -263,7 +288,7 @@ func TestCompressDecompressRnd(t *testing.T) {
func BenchmarkBabyjub(b *testing.B) { func BenchmarkBabyjub(b *testing.B) {
const n = 256 const n = 256
rnd := rand.New(rand.NewSource(42)) rnd := rand.New(rand.NewSource(42)) //nolint:gosec
var badpoints [n]*Point var badpoints [n]*Point
for i := 0; i < n; i++ { for i := 0; i < n; i++ {

View File

@@ -1,15 +1,16 @@
// Package babyjub eddsa implements the EdDSA over the BabyJubJub curve
//nolint:gomnd
package babyjub package babyjub
import ( import (
"crypto/rand" "crypto/rand"
"database/sql/driver" "database/sql/driver"
"fmt" "fmt"
"math/big"
"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"
"github.com/iden3/go-iden3-crypto/utils" "github.com/iden3/go-iden3-crypto/utils"
"math/big"
) )
// pruneBuffer prunes the buffer during key generation according to RFC 8032. // pruneBuffer prunes the buffer during key generation according to RFC 8032.
@@ -55,7 +56,7 @@ func SkToBigInt(k *PrivateKey) *big.Int {
return s return s
} }
// Pub returns the public key corresponding to a private key. // Public returns the public key corresponding to a private key.
func (k *PrivateKey) Public() *PublicKey { func (k *PrivateKey) Public() *PublicKey {
return k.Scalar().Public() return k.Scalar().Public()
} }
@@ -69,8 +70,8 @@ func NewPrivKeyScalar(s *big.Int) *PrivKeyScalar {
return &sk return &sk
} }
// Pub returns the public key corresponding to the scalar value s of a private // Public returns the public key corresponding to the scalar value s of a
// key. // private key.
func (s *PrivKeyScalar) Public() *PublicKey { func (s *PrivKeyScalar) Public() *PublicKey {
p := NewPoint().Mul((*big.Int)(s), B8) p := NewPoint().Mul((*big.Int)(s), B8)
pk := PublicKey(*p) pk := PublicKey(*p)
@@ -85,16 +86,19 @@ func (s *PrivKeyScalar) BigInt() *big.Int {
// PublicKey represents an EdDSA public key, which is a curve point. // PublicKey represents an EdDSA public key, which is a curve point.
type PublicKey Point type PublicKey Point
// MarshalText implements the marshaler for PublicKey
func (pk PublicKey) MarshalText() ([]byte, error) { func (pk PublicKey) MarshalText() ([]byte, error) {
pkc := pk.Compress() pkc := pk.Compress()
return utils.Hex(pkc[:]).MarshalText() return utils.Hex(pkc[:]).MarshalText()
} }
// String returns the string representation of the PublicKey
func (pk PublicKey) String() string { func (pk PublicKey) String() string {
pkc := pk.Compress() pkc := pk.Compress()
return utils.Hex(pkc[:]).String() return utils.Hex(pkc[:]).String()
} }
// UnmarshalText implements the unmarshaler for the PublicKey
func (pk *PublicKey) UnmarshalText(h []byte) error { func (pk *PublicKey) UnmarshalText(h []byte) error {
var pkc PublicKeyComp var pkc PublicKeyComp
if err := utils.HexDecodeInto(pkc[:], h); err != nil { if err := utils.HexDecodeInto(pkc[:], h); err != nil {
@@ -109,24 +113,35 @@ func (pk *PublicKey) UnmarshalText(h []byte) error {
} }
// Point returns the Point corresponding to a PublicKey. // Point returns the Point corresponding to a PublicKey.
func (p *PublicKey) Point() *Point { func (pk *PublicKey) Point() *Point {
return (*Point)(p) return (*Point)(pk)
} }
// PublicKeyComp represents a compressed EdDSA Public key; it's a compressed curve // PublicKeyComp represents a compressed EdDSA Public key; it's a compressed curve
// point. // point.
type PublicKeyComp [32]byte type PublicKeyComp [32]byte
func (buf PublicKeyComp) MarshalText() ([]byte, error) { return utils.Hex(buf[:]).MarshalText() } // MarshalText implements the marshaler for the PublicKeyComp
func (buf PublicKeyComp) String() string { return utils.Hex(buf[:]).String() } func (pkComp PublicKeyComp) MarshalText() ([]byte, error) {
func (buf *PublicKeyComp) UnmarshalText(h []byte) error { return utils.HexDecodeInto(buf[:], h) } return utils.Hex(pkComp[:]).MarshalText()
func (p *PublicKey) Compress() PublicKeyComp {
return PublicKeyComp((*Point)(p).Compress())
} }
func (p *PublicKeyComp) Decompress() (*PublicKey, error) { // String returns the string representation of the PublicKeyComp
point, err := NewPoint().Decompress(*p) func (pkComp PublicKeyComp) String() string { return utils.Hex(pkComp[:]).String() }
// UnmarshalText implements the unmarshaler for the PublicKeyComp
func (pkComp *PublicKeyComp) UnmarshalText(h []byte) error {
return utils.HexDecodeInto(pkComp[:], h)
}
// Compress returns the PublicKeyCompr for the given PublicKey
func (pk *PublicKey) Compress() PublicKeyComp {
return PublicKeyComp((*Point)(pk).Compress())
}
// Decompress returns the PublicKey for the given PublicKeyComp
func (pkComp *PublicKeyComp) Decompress() (*PublicKey, error) {
point, err := NewPoint().Decompress(*pkComp)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -143,9 +158,18 @@ type Signature struct {
// SignatureComp represents a compressed EdDSA signature. // SignatureComp represents a compressed EdDSA signature.
type SignatureComp [64]byte type SignatureComp [64]byte
func (buf SignatureComp) MarshalText() ([]byte, error) { return utils.Hex(buf[:]).MarshalText() } // MarshalText implements the marshaler for the SignatureComp
func (buf SignatureComp) String() string { return utils.Hex(buf[:]).String() } func (sComp SignatureComp) MarshalText() ([]byte, error) {
func (buf *SignatureComp) UnmarshalText(h []byte) error { return utils.HexDecodeInto(buf[:], h) } return utils.Hex(sComp[:]).MarshalText()
}
// String returns the string representation of the SignatureComp
func (sComp SignatureComp) String() string { return utils.Hex(sComp[:]).String() }
// UnmarshalText implements the unmarshaler for the SignatureComp
func (sComp *SignatureComp) UnmarshalText(h []byte) error {
return utils.HexDecodeInto(sComp[:], h)
}
// Compress an EdDSA signature by concatenating the compression of // Compress an EdDSA signature by concatenating the compression of
// the point R8 and the Little-Endian encoding of S. // the point R8 and the Little-Endian encoding of S.
@@ -173,12 +197,12 @@ func (s *Signature) Decompress(buf [64]byte) (*Signature, error) {
// Decompress a compressed signature. Returns error if the Point decompression // Decompress a compressed signature. Returns error if the Point decompression
// fails. // fails.
func (s *SignatureComp) Decompress() (*Signature, error) { func (sComp *SignatureComp) Decompress() (*Signature, error) {
return new(Signature).Decompress(*s) return new(Signature).Decompress(*sComp)
} }
// Scan implements Scanner for database/sql. // Scan implements Scanner for database/sql.
func (s *SignatureComp) Scan(src interface{}) error { func (sComp *SignatureComp) Scan(src interface{}) error {
srcB, ok := src.([]byte) srcB, ok := src.([]byte)
if !ok { if !ok {
return fmt.Errorf("can't scan %T into Signature", src) return fmt.Errorf("can't scan %T into Signature", src)
@@ -186,13 +210,13 @@ func (s *SignatureComp) Scan(src interface{}) error {
if len(srcB) != 64 { if len(srcB) != 64 {
return fmt.Errorf("can't scan []byte of len %d into Signature, want %d", len(srcB), 64) return fmt.Errorf("can't scan []byte of len %d into Signature, want %d", len(srcB), 64)
} }
copy(s[:], srcB[:]) copy(sComp[:], srcB[:])
return nil return nil
} }
// Value implements valuer for database/sql. // Value implements valuer for database/sql.
func (s SignatureComp) Value() (driver.Value, error) { func (sComp SignatureComp) Value() (driver.Value, error) {
return s[:], nil return sComp[:], nil
} }
// Scan implements Scanner for database/sql. // Scan implements Scanner for database/sql.
@@ -243,8 +267,8 @@ 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 (pk *PublicKey) VerifyMimc7(msg *big.Int, sig *Signature) bool {
hmInput := []*big.Int{sig.R8.X, sig.R8.Y, p.X, p.Y, msg} hmInput := []*big.Int{sig.R8.X, sig.R8.Y, pk.X, pk.Y, msg}
hm, err := mimc7.Hash(hmInput, nil) // hm = H1(8*R.x, 8*R.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 {
return false return false
@@ -253,7 +277,7 @@ func (p *PublicKey) VerifyMimc7(msg *big.Int, sig *Signature) bool {
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)
r1.Mul(r1, hm) r1.Mul(r1, hm)
right := NewPoint().Mul(r1, p.Point()) right := NewPoint().Mul(r1, pk.Point())
rightProj := right.Projective() rightProj := right.Projective()
rightProj.Add(sig.R8.Projective(), rightProj) // right = 8 * R + 8 * hm * A rightProj.Add(sig.R8.Projective(), rightProj) // right = 8 * R + 8 * hm * A
right = rightProj.Affine() right = rightProj.Affine()
@@ -289,8 +313,8 @@ func (k *PrivateKey) SignPoseidon(msg *big.Int) *Signature {
// VerifyPoseidon verifies the signature of a message encoded as a big.Int in Zq // 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. // using blake-512 hash for buffer hashing and Poseidon for big.Int hashing.
func (p *PublicKey) VerifyPoseidon(msg *big.Int, sig *Signature) bool { func (pk *PublicKey) VerifyPoseidon(msg *big.Int, sig *Signature) bool {
hmInput := []*big.Int{sig.R8.X, sig.R8.Y, p.X, p.Y, msg} hmInput := []*big.Int{sig.R8.X, sig.R8.Y, pk.X, pk.Y, msg}
hm, err := poseidon.Hash(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 {
return false return false
@@ -299,7 +323,7 @@ func (p *PublicKey) VerifyPoseidon(msg *big.Int, sig *Signature) bool {
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)
r1.Mul(r1, hm) r1.Mul(r1, hm)
right := NewPoint().Mul(r1, p.Point()) right := NewPoint().Mul(r1, pk.Point())
rightProj := right.Projective() rightProj := right.Projective()
rightProj.Add(sig.R8.Projective(), rightProj) // right = 8 * R + 8 * hm * A rightProj.Add(sig.R8.Projective(), rightProj) // right = 8 * R + 8 * hm * A
right = rightProj.Affine() right = rightProj.Affine()
@@ -307,7 +331,7 @@ func (p *PublicKey) VerifyPoseidon(msg *big.Int, sig *Signature) bool {
} }
// Scan implements Scanner for database/sql. // Scan implements Scanner for database/sql.
func (p *PublicKey) Scan(src interface{}) error { func (pk *PublicKey) Scan(src interface{}) error {
srcB, ok := src.([]byte) srcB, ok := src.([]byte)
if !ok { if !ok {
return fmt.Errorf("can't scan %T into PublicKey", src) return fmt.Errorf("can't scan %T into PublicKey", src)
@@ -321,12 +345,30 @@ func (p *PublicKey) Scan(src interface{}) error {
if err != nil { if err != nil {
return err return err
} }
*p = *decomp *pk = *decomp
return nil return nil
} }
// Value implements valuer for database/sql. // Value implements valuer for database/sql.
func (p PublicKey) Value() (driver.Value, error) { func (pk PublicKey) Value() (driver.Value, error) {
comp := p.Compress() comp := pk.Compress()
return comp[:], nil return comp[:], nil
} }
// Scan implements Scanner for database/sql.
func (pkComp *PublicKeyComp) Scan(src interface{}) error {
srcB, ok := src.([]byte)
if !ok {
return fmt.Errorf("can't scan %T into PublicKeyComp", src)
}
if len(srcB) != 32 {
return fmt.Errorf("can't scan []byte of len %d into PublicKeyComp, want %d", len(srcB), 32)
}
copy(pkComp[:], srcB)
return nil
}
// Value implements valuer for database/sql.
func (pkComp PublicKeyComp) Value() (driver.Value, error) {
return pkComp[:], nil
}

View File

@@ -1,14 +1,13 @@
package babyjub package babyjub
import ( import (
"database/sql"
"database/sql/driver"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"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"
@@ -27,7 +26,8 @@ func TestPublicKey(t *testing.T) {
func TestSignVerifyMimc7(t *testing.T) { func TestSignVerifyMimc7(t *testing.T) {
var k PrivateKey var k PrivateKey
_, err := hex.Decode(k[:], []byte("0001020304050607080900010203040506070809000102030405060708090001")) _, err := hex.Decode(k[:],
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
require.Nil(t, err) require.Nil(t, err)
msgBuf, err := hex.DecodeString("00010203040506070809") msgBuf, err := hex.DecodeString("00010203040506070809")
if err != nil { if err != nil {
@@ -72,7 +72,8 @@ func TestSignVerifyMimc7(t *testing.T) {
func TestSignVerifyPoseidon(t *testing.T) { func TestSignVerifyPoseidon(t *testing.T) {
var k PrivateKey var k PrivateKey
_, err := hex.Decode(k[:], []byte("0001020304050607080900010203040506070809000102030405060708090001")) _, err := hex.Decode(k[:],
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
require.Nil(t, err) require.Nil(t, err)
msgBuf, err := hex.DecodeString("00010203040506070809") msgBuf, err := hex.DecodeString("00010203040506070809")
if err != nil { if err != nil {
@@ -96,7 +97,7 @@ func TestSignVerifyPoseidon(t *testing.T) {
"15383486972088797283337779941324724402501462225528836549661220478783371668959", "15383486972088797283337779941324724402501462225528836549661220478783371668959",
sig.R8.Y.String()) sig.R8.Y.String())
assert.Equal(t, assert.Equal(t,
"1398758333392199195742243841591064350253744445503462896781493968760929513778", "1672775540645840396591609181675628451599263765380031905495115170613215233181",
sig.S.String()) sig.S.String())
ok := pk.VerifyPoseidon(msg, sig) ok := pk.VerifyPoseidon(msg, sig)
@@ -108,7 +109,7 @@ func TestSignVerifyPoseidon(t *testing.T) {
assert.Equal(t, ""+ assert.Equal(t, ""+
"dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+ "dfedb4315d3f2eb4de2d3c510d7a987dcab67089c8ace06308827bf5bcbe02a2"+
"32f16b0f2f4c4e1169aa59685637e1429b6581a9531d058d65f4ab224eab1703", "9d043ece562a8f82bfc0adb640c0107a7d3a27c1c7c1a6179a0da73de5c1b203",
hex.EncodeToString(sigBuf[:])) hex.EncodeToString(sigBuf[:]))
ok = pk.VerifyPoseidon(msg, sig2) ok = pk.VerifyPoseidon(msg, sig2)
@@ -117,7 +118,8 @@ func TestSignVerifyPoseidon(t *testing.T) {
func TestCompressDecompress(t *testing.T) { func TestCompressDecompress(t *testing.T) {
var k PrivateKey var k PrivateKey
_, err := hex.Decode(k[:], []byte("0001020304050607080900010203040506070809000102030405060708090001")) _, err := hex.Decode(k[:],
[]byte("0001020304050607080900010203040506070809000102030405060708090001"))
require.Nil(t, err) require.Nil(t, err)
pk := k.Public() pk := k.Public()
for i := 0; i < 64; i++ { for i := 0; i < 64; i++ {
@@ -137,7 +139,7 @@ func TestCompressDecompress(t *testing.T) {
func TestSignatureCompScannerValuer(t *testing.T) { func TestSignatureCompScannerValuer(t *testing.T) {
privK := NewRandPrivKey() privK := NewRandPrivKey()
var value driver.Valuer //nolint:gosimple this is done to ensure interface compability var value driver.Valuer //nolint:gosimple this is done to ensure interface compatibility
value = privK.SignPoseidon(big.NewInt(674238462)).Compress() value = privK.SignPoseidon(big.NewInt(674238462)).Compress()
scan := privK.SignPoseidon(big.NewInt(1)).Compress() scan := privK.SignPoseidon(big.NewInt(1)).Compress()
fromDB, err := value.Value() fromDB, err := value.Value()
@@ -158,7 +160,7 @@ func TestSignatureScannerValuer(t *testing.T) {
assert.Equal(t, value, scan) assert.Equal(t, value, scan)
} }
func TestPubKeyScannerValuer(t *testing.T) { func TestPublicKeyScannerValuer(t *testing.T) {
privKValue := NewRandPrivKey() privKValue := NewRandPrivKey()
pubKValue := privKValue.Public() pubKValue := privKValue.Public()
privKScan := NewRandPrivKey() privKScan := NewRandPrivKey()
@@ -173,9 +175,25 @@ func TestPubKeyScannerValuer(t *testing.T) {
assert.Equal(t, value, scan) assert.Equal(t, value, scan)
} }
func TestPublicKeyCompScannerValuer(t *testing.T) {
privKValue := NewRandPrivKey()
pubKCompValue := privKValue.Public().Compress()
privKScan := NewRandPrivKey()
pubKCompScan := privKScan.Public().Compress()
var value driver.Valuer
var scan sql.Scanner
value = &pubKCompValue
scan = &pubKCompScan
fromDB, err := value.Value()
assert.Nil(t, err)
assert.Nil(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"))
require.Nil(b, err) require.Nil(b, err)
pk := k.Public() pk := k.Public()

View File

@@ -1,9 +1,13 @@
package babyjub package babyjub
import ( import (
"github.com/dchest/blake512" // I have personally reviewed that this module doesn't do anything suspicious "github.com/dchest/blake512"
) )
// Note on dchest/blake512: This specific blake512 module is compatible with
// the version of Blake512 used at circomlib, and this module has been reviewed
// to don't be doing do anything suspicious.
// Blake512 performs the blake-512 hash over the buffer m. Note that this is // Blake512 performs the blake-512 hash over the buffer m. Note that this is
// the original blake from the SHA3 competition and not the new blake2 version. // the original blake from the SHA3 competition and not the new blake2 version.
func Blake512(m []byte) []byte { func Blake512(m []byte) []byte {

View File

@@ -3,13 +3,10 @@ package constants
import ( import (
"fmt" "fmt"
"math/big" "math/big"
"github.com/iden3/go-iden3-crypto/ff"
) )
// Q is the order of the integer field (Zq) that fits inside the SNARK. // Q is the order of the integer field (Zq) that fits inside the SNARK.
var Q *big.Int var Q *big.Int
var QE *ff.Element
// Zero is 0. // Zero is 0.
var Zero *big.Int var Zero *big.Int

View File

@@ -1,5 +1,6 @@
package ff package ff
// NewElement returns a new empty *Element
func NewElement() *Element { func NewElement() *Element {
return &Element{} return &Element{}
} }

View File

@@ -10,6 +10,7 @@ import (
"github.com/iden3/go-iden3-crypto/utils" "github.com/iden3/go-iden3-crypto/utils"
) )
// SEED defines the seed used to constants
const SEED = "mimc" const SEED = "mimc"
var constants = generateConstantsData() var constants = generateConstantsData()
@@ -47,8 +48,9 @@ func getConstants(seed string, nRounds int) []*ff.Element {
return cts return cts
} }
// 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 // MIMC7HashGeneric performs the MIMC7 hash over a *big.Int, in a generic way,
func MIMC7HashGeneric(xInBI, kBI *big.Int, nRounds int) *big.Int { // where it can be specified the Finite Field over R, and the number of rounds
func MIMC7HashGeneric(xInBI, kBI *big.Int, nRounds int) *big.Int { //nolint:golint
xIn := ff.NewElement().SetBigInt(xInBI) xIn := ff.NewElement().SetBigInt(xInBI)
k := ff.NewElement().SetBigInt(kBI) k := ff.NewElement().SetBigInt(kBI)
@@ -72,7 +74,8 @@ func MIMC7HashGeneric(xInBI, kBI *big.Int, nRounds int) *big.Int {
return res return res
} }
// 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 // 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, arr []*big.Int, nRounds int) (*big.Int, error) { func HashGeneric(iv *big.Int, arr []*big.Int, nRounds int) (*big.Int, error) {
if !utils.CheckBigIntArrayInField(arr) { if !utils.CheckBigIntArrayInField(arr) {
return nil, errors.New("inputs values not inside Finite Field") return nil, errors.New("inputs values not inside Finite Field")
@@ -88,8 +91,9 @@ func HashGeneric(iv *big.Int, arr []*big.Int, nRounds int) (*big.Int, error) {
return r, nil return r, nil
} }
// 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 // MIMC7Hash performs the MIMC7 hash over a *big.Int, using the Finite Field
func MIMC7Hash(xInBI, kBI *big.Int) *big.Int { // over R and the number of rounds setted in the `constants` variable
func MIMC7Hash(xInBI, kBI *big.Int) *big.Int { //nolint:golint
xIn := ff.NewElement().SetBigInt(xInBI) xIn := ff.NewElement().SetBigInt(xInBI)
k := ff.NewElement().SetBigInt(kBI) k := ff.NewElement().SetBigInt(kBI)

View File

@@ -11,9 +11,13 @@ import (
func TestKeccak256(t *testing.T) { func TestKeccak256(t *testing.T) {
res := crypto.Keccak256([]byte(SEED)) res := crypto.Keccak256([]byte(SEED))
assert.Equal(t, "b6e489e6b37224a50bebfddbe7d89fa8fdcaa84304a70bd13f79b5d9f7951e9e", hex.EncodeToString(res)) assert.Equal(t,
"b6e489e6b37224a50bebfddbe7d89fa8fdcaa84304a70bd13f79b5d9f7951e9e",
hex.EncodeToString(res))
c := new(big.Int).SetBytes(crypto.Keccak256([]byte(SEED))) c := new(big.Int).SetBytes(crypto.Keccak256([]byte(SEED)))
assert.Equal(t, "82724731331859054037315113496710413141112897654334566532528783843265082629790", c.String()) assert.Equal(t,
"82724731331859054037315113496710413141112897654334566532528783843265082629790",
c.String())
} }
func TestMIMC7Generic(t *testing.T) { func TestMIMC7Generic(t *testing.T) {
@@ -25,10 +29,14 @@ func TestMIMC7Generic(t *testing.T) {
// Generic Hash // Generic Hash
mhg := MIMC7HashGeneric(b1, b2, 91) mhg := MIMC7HashGeneric(b1, b2, 91)
assert.Equal(t, "10594780656576967754230020536574539122676596303354946869887184401991294982664", mhg.String()) assert.Equal(t,
"10594780656576967754230020536574539122676596303354946869887184401991294982664",
mhg.String())
hg, err := HashGeneric(big.NewInt(0), bigArray, 91) hg, err := HashGeneric(big.NewInt(0), bigArray, 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())
} }
func TestMIMC7(t *testing.T) { func TestMIMC7(t *testing.T) {
@@ -43,7 +51,8 @@ func TestMIMC7(t *testing.T) {
h1, err := Hash(bigArray1, 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}
@@ -51,19 +60,22 @@ func TestMIMC7(t *testing.T) {
h2a, err := Hash(bigArray2a, nil) h2a, err := Hash(bigArray2a, 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}
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, err := Hash(bigArray2b, 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}
@@ -71,11 +83,14 @@ func TestMIMC7(t *testing.T) {
h4, err := Hash(bigArray4, 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")
msg := []byte("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") msg := []byte("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.") //nolint:lll
hmsg := HashBytes(msg) hmsg := HashBytes(msg)
assert.Equal(t, "16855787120419064316734350414336285711017110414939748784029922801367685456065", hmsg.String()) assert.Equal(t,
"16855787120419064316734350414336285711017110414939748784029922801367685456065",
hmsg.String())
} }
func BenchmarkMIMC7(b *testing.B) { func BenchmarkMIMC7(b *testing.B) {
@@ -86,6 +101,6 @@ func BenchmarkMIMC7(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, nil) //nolint:errcheck Hash(bigArray4, nil) //nolint:errcheck,gosec
} }
} }

View File

@@ -9,9 +9,9 @@ import (
"github.com/iden3/go-iden3-crypto/utils" "github.com/iden3/go-iden3-crypto/utils"
) )
const NROUNDSF = 8 const NROUNDSF = 8 //nolint:golint
var NROUNDSP = []int{56, 57, 56, 60, 60, 63, 64, 63} var NROUNDSP = []int{56, 57, 56, 60, 60, 63, 64, 63} //nolint:golint
func zero() *ff.Element { func zero() *ff.Element {
return ff.NewElement() return ff.NewElement()
@@ -47,7 +47,7 @@ func mix(state []*ff.Element, newState []*ff.Element, m [][]*ff.Element) {
for i := 0; i < len(state); i++ { for i := 0; i < len(state); i++ {
newState[i].SetUint64(0) newState[i].SetUint64(0)
for j := 0; j < len(state); j++ { for j := 0; j < len(state); j++ {
mul.Mul(m[j][i], state[j]) mul.Mul(m[i][j], state[j])
newState[i].Add(newState[i], mul) newState[i].Add(newState[i], mul)
} }
} }
@@ -64,8 +64,8 @@ func Hash(inpBI []*big.Int) (*big.Int, error) {
} }
inp := utils.BigIntArrayToElementArray(inpBI[:]) inp := utils.BigIntArrayToElementArray(inpBI[:])
state := make([]*ff.Element, t) state := make([]*ff.Element, t)
copy(state[:], inp[:]) state[0] = zero()
state[len(state)-1] = zero() copy(state[1:], inp[:])
nRoundsF := NROUNDSF nRoundsF := NROUNDSF
nRoundsP := NROUNDSP[t-2] nRoundsP := NROUNDSP[t-2]
@@ -79,11 +79,9 @@ func Hash(inpBI []*big.Int) (*big.Int, error) {
for i := 0; i < nRoundsF+nRoundsP; i++ { for i := 0; i < nRoundsF+nRoundsP; i++ {
ark(state, c.c[t-2], i*t) ark(state, c.c[t-2], i*t)
sbox(nRoundsF, nRoundsP, state, i) sbox(nRoundsF, nRoundsP, state, i)
if i < nRoundsF+nRoundsP-1 {
mix(state, newState, c.m[t-2]) mix(state, newState, c.m[t-2])
state, newState = newState, state state, newState = newState, state
} }
}
rE := state[0] rE := state[0]
r := big.NewInt(0) r := big.NewInt(0)
rE.ToBigIntRegular(r) rE.ToBigIntRegular(r)

View File

@@ -12,7 +12,9 @@ import (
func TestBlake2bVersion(t *testing.T) { func TestBlake2bVersion(t *testing.T) {
h := blake2b.Sum256([]byte("poseidon_constants")) h := blake2b.Sum256([]byte("poseidon_constants"))
assert.Equal(t, "e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1", hex.EncodeToString(h[:])) assert.Equal(t,
"e57ba154fb2c47811dc1a2369b27e25a44915b4e4ece4eb8ec74850cb78e01b1",
hex.EncodeToString(h[:]))
} }
func TestPoseidonHash(t *testing.T) { func TestPoseidonHash(t *testing.T) {
@@ -22,33 +24,47 @@ func TestPoseidonHash(t *testing.T) {
h, err := Hash([]*big.Int{b1}) h, err := Hash([]*big.Int{b1})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "11043376183861534927536506085090418075369306574649619885724436265926427398571", h.String()) assert.Equal(t,
"18586133768512220936620570745912940619677854269274689475585506675881198879027",
h.String())
h, err = Hash([]*big.Int{b1, b2}) h, err = Hash([]*big.Int{b1, b2})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "17117985411748610629288516079940078114952304104811071254131751175361957805920", h.String()) assert.Equal(t,
"7853200120776062878684798364095072458815029376092732009249414926327459813530",
h.String())
h, err = Hash([]*big.Int{b1, b2, b0, b0, b0}) h, err = Hash([]*big.Int{b1, b2, b0, b0, b0})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "3975478831357328722254985704342968745327876719981393787143845259590563829094", h.String()) assert.Equal(t,
"1018317224307729531995786483840663576608797660851238720571059489595066344487",
h.String())
h, err = Hash([]*big.Int{b1, b2, b0, b0, b0, b0}) h, err = Hash([]*big.Int{b1, b2, b0, b0, b0, b0})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "19772360636270345724087386688434825760738403416279047262510528378903625000110", h.String()) assert.Equal(t,
"15336558801450556532856248569924170992202208561737609669134139141992924267169",
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, b0, b0, b0}) h, err = Hash([]*big.Int{b3, b4, b0, b0, b0})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "3181200837746671699652342497997860344148947482942465819251904554707352676086", h.String()) assert.Equal(t,
"5811595552068139067952687508729883632420015185677766880877743348592482390548",
h.String())
h, err = Hash([]*big.Int{b3, b4, b0, b0, b0, b0}) h, err = Hash([]*big.Int{b3, b4, b0, b0, b0, b0})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "8386348873272147968934270337233829407378789978142456170950021426339096575008", h.String()) assert.Equal(t,
"12263118664590987767234828103155242843640892839966517009184493198782366909018",
h.String())
b5 := big.NewInt(5) b5 := big.NewInt(5)
b6 := big.NewInt(6) b6 := big.NewInt(6)
h, err = Hash([]*big.Int{b1, b2, b3, b4, b5, b6}) h, err = Hash([]*big.Int{b1, b2, b3, b4, b5, b6})
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, "5202465217520500374834597824465244016759843635092906214933648999760272616044", h.String()) assert.Equal(t,
"20400040500897583745843009878988256314335038853985262692600694741116813247201",
h.String())
} }
func TestErrorInputs(t *testing.T) { func TestErrorInputs(t *testing.T) {
@@ -70,12 +86,12 @@ func TestErrorInputs(t *testing.T) {
func BenchmarkPoseidonHash(b *testing.B) { func BenchmarkPoseidonHash(b *testing.B) {
b0 := big.NewInt(0) b0 := big.NewInt(0)
b1 := utils.NewIntFromString("12242166908188651009877250812424843524687801523336557272219921456462821518061") b1 := utils.NewIntFromString("12242166908188651009877250812424843524687801523336557272219921456462821518061") //nolint:lll
b2 := utils.NewIntFromString("12242166908188651009877250812424843524687801523336557272219921456462821518061") b2 := utils.NewIntFromString("12242166908188651009877250812424843524687801523336557272219921456462821518061") //nolint:lll
bigArray4 := []*big.Int{b1, b2, b0, b0, b0, b0} bigArray4 := []*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,gosec
} }
} }

View File

@@ -77,7 +77,7 @@ func HexDecodeInto(dst []byte, h []byte) error {
h = h[2:] h = h[2:]
} }
if len(h)/2 != len(dst) { if len(h)/2 != len(dst) {
return fmt.Errorf("expected %v bytes in hex string, got %v", len(dst), len(h)/2) return fmt.Errorf("expected %v bytes in hex string, got %v", len(dst), len(h)/2) //nolint:gomnd
} }
n, err := hex.Decode(dst, h) n, err := hex.Decode(dst, h)
if err != nil { if err != nil {