From 0bac1c84ba5e126ad7c6b4939c2658a8e1ca76a3 Mon Sep 17 00:00:00 2001 From: arnaucube Date: Thu, 29 Aug 2019 17:52:30 +0200 Subject: [PATCH] add babyjub-eddsa Poseidon sign & verify --- babyjub/babyjub.go | 5 +---- babyjub/eddsa.go | 43 ++++++++++++++++++++++++++++++++++++ babyjub/eddsa_test.go | 51 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 91 insertions(+), 8 deletions(-) diff --git a/babyjub/babyjub.go b/babyjub/babyjub.go index 3aab2d5..b53d148 100644 --- a/babyjub/babyjub.go +++ b/babyjub/babyjub.go @@ -171,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 // little endian and the sign of the x coordinate. func (p *Point) Compress() [32]byte { - sign := false - if PointCoordSign(p.X) { - sign = true - } + sign := PointCoordSign(p.X) return PackPoint(p.Y, sign) } diff --git a/babyjub/eddsa.go b/babyjub/eddsa.go index 3274b07..f855b0f 100644 --- a/babyjub/eddsa.go +++ b/babyjub/eddsa.go @@ -4,6 +4,7 @@ import ( "crypto/rand" "github.com/iden3/go-iden3-crypto/mimc7" + "github.com/iden3/go-iden3-crypto/poseidon" "github.com/iden3/go-iden3-crypto/utils" "math/big" @@ -208,3 +209,45 @@ func (p *PublicKey) VerifyMimc7(msg *big.Int, sig *Signature) bool { 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 { + 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) +} diff --git a/babyjub/eddsa_test.go b/babyjub/eddsa_test.go index 3342fee..547ca76 100644 --- a/babyjub/eddsa_test.go +++ b/babyjub/eddsa_test.go @@ -4,13 +4,12 @@ import ( "crypto/rand" "encoding/hex" "fmt" + "math/big" + "testing" "github.com/iden3/go-iden3-crypto/constants" "github.com/iden3/go-iden3-crypto/utils" "github.com/stretchr/testify/assert" - - "math/big" - "testing" ) func genInputs() (*PrivateKey, *big.Int) { @@ -26,7 +25,7 @@ func genInputs() (*PrivateKey, *big.Int) { return &k, msg } -func TestSignVerify1(t *testing.T) { +func TestSignVerifyMimc7(t *testing.T) { var k PrivateKey hex.Decode(k[:], []byte("0001020304050607080900010203040506070809000102030405060708090001")) msgBuf, err := hex.DecodeString("00010203040506070809") @@ -70,6 +69,50 @@ func TestSignVerify1(t *testing.T) { 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) { var k PrivateKey hex.Decode(k[:], []byte("0001020304050607080900010203040506070809000102030405060708090001"))