From 695fc9ceed5559e6ee21e1ed713e0abd7cf68399 Mon Sep 17 00:00:00 2001 From: Sergey Minaev Date: Fri, 14 Oct 2022 11:17:11 +0500 Subject: [PATCH 01/11] [3392] Update tooling for BBS. Signed-off-by: Sergey Minaev --- .../third_party/kilic/bls12-381/g1_custom.go | 24 +++++-- .../kilic/bls12-381/g1_custom_test.go | 62 ++++++++++++++----- .../kilic/bls12-381/hash_to_field_custom.go | 29 +++++++-- .../bls12-381/hash_to_field_custom_test.go | 60 ++++++++++++++++++ .../third_party/kilic/bls12-381/swu_custom.go | 19 ------ .../third_party/kilic/bls12-381/swu_mod.go | 49 --------------- pkg/crypto/primitive/bbs12381g2pub/utils.go | 24 +++++++ 7 files changed, 176 insertions(+), 91 deletions(-) create mode 100644 internal/third_party/kilic/bls12-381/hash_to_field_custom_test.go delete mode 100644 internal/third_party/kilic/bls12-381/swu_custom.go delete mode 100644 internal/third_party/kilic/bls12-381/swu_mod.go diff --git a/internal/third_party/kilic/bls12-381/g1_custom.go b/internal/third_party/kilic/bls12-381/g1_custom.go index 79eadb6ea..ad92d67ce 100644 --- a/internal/third_party/kilic/bls12-381/g1_custom.go +++ b/internal/third_party/kilic/bls12-381/g1_custom.go @@ -8,17 +8,19 @@ package bls12381 import ( "hash" + + "golang.org/x/crypto/sha3" ) -func (g *G1) HashToCurveGeneric(msg, domain []byte, hashFunc func() hash.Hash) (*PointG1, error) { - hashRes, err := hashToFpXMD(hashFunc, msg, domain, 2) +func (g *G1) hashToCurveGeneric(msg, domain []byte, expand func([]byte, []byte, int) ([]byte, error)) (*PointG1, error) { + hashRes, err := hashToFpGeneric(expand, msg, domain, 2) if err != nil { return nil, err } u0, u1 := hashRes[0], hashRes[1] - x0, y0 := swuMapG1BE(u0) - x1, y1 := swuMapG1BE(u1) + x0, y0 := swuMapG1(u0) + x1, y1 := swuMapG1(u1) one := new(fe).one() p0, p1 := &PointG1{*x0, *y0, *one}, &PointG1{*x1, *y1, *one} @@ -28,3 +30,17 @@ func (g *G1) HashToCurveGeneric(msg, domain []byte, hashFunc func() hash.Hash) ( g.ClearCofactor(p0) return g.Affine(p0), nil } + +func (g *G1) HashToCurveGenericXMD(msg, domain []byte, hashFunc func() hash.Hash) (*PointG1, error) { + expand := func(msg []byte, tag []byte, outLen int) ([]byte, error) { + return expandMsgXMD(hashFunc, msg, tag, outLen) + } + return g.hashToCurveGeneric(msg, domain, expand) +} + +func (g *G1) HashToCurveGenericXOF(msg, domain []byte, hash sha3.ShakeHash) (*PointG1, error) { + expand := func(msg []byte, tag []byte, outLen int) ([]byte, error) { + return ExpandMsgXOF(hash, msg, tag, outLen) + } + return g.hashToCurveGeneric(msg, domain, expand) +} diff --git a/internal/third_party/kilic/bls12-381/g1_custom_test.go b/internal/third_party/kilic/bls12-381/g1_custom_test.go index 53a636e57..cf11ce93f 100644 --- a/internal/third_party/kilic/bls12-381/g1_custom_test.go +++ b/internal/third_party/kilic/bls12-381/g1_custom_test.go @@ -7,9 +7,12 @@ SPDX-License-Identifier: Apache-2.0 package bls12381 import ( + "crypto/sha256" + "encoding/hex" "hash" "testing" + "github.com/stretchr/testify/require" "golang.org/x/crypto/blake2b" ) @@ -37,23 +40,52 @@ func TestG1CustomSerialization(t *testing.T) { } func TestHashToCurve(t *testing.T) { - hashFunc := func() hash.Hash { - // We pass a null key so error is impossible here. - h, _ := blake2b.New512(nil) + g := NewG1() + t.Run("hello test", func(t *testing.T) { + hashFunc := func() hash.Hash { + // We pass a null key so error is impossible here. + h, _ := blake2b.New512(nil) - return h - } + return h + } - g := NewG1() + curve, err := g.HashToCurveGenericXMD([]byte("hello"), + []byte("BLS12381G1_XMD:BLAKE2B_SSWU_RO_BBS+_SIGNATURES:1_0_0"), + hashFunc) - curve, err := g.HashToCurveGeneric([]byte("hello"), - []byte("BLS12381G1_XMD:BLAKE2B_SSWU_RO_BBS+_SIGNATURES:1_0_0"), - hashFunc) - if err != nil { - t.Fatal(err) - } + require.NoError(t, err) + require.NotEqual(t, 0, len(curve)) + }) - if len(curve) == 0 { - t.Fatal("empty curve bytes") - } + t.Run("IRTF H2C draft16 J91 empty msg", func(t *testing.T) { + hashFunc := func() hash.Hash { + h := sha256.New() + return h + } + + curve, err := g.HashToCurveGenericXMD([]byte(""), + []byte("QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_"), + hashFunc) + require.NoError(t, err) + require.Equal(t, ""+ //x and y coordinates + "052926add2207b76ca4fa57a8734416c8dc95e24501772c814278700eed6d1e4e8cf62d9c09db0fac349612b759e79a1"+ + "08ba738453bfed09cb546dbb0783dbb3a5f1f566ed67bb6be0e8c67e2e81a4cc68ee29813bb7994998f3eae0c9c6a265", + hex.EncodeToString(NewG1().ToUncompressed(curve))) + }) + + t.Run("IRTF H2C draft16 J91 abc", func(t *testing.T) { + hashFunc := func() hash.Hash { + h := sha256.New() + return h + } + + curve, err := g.HashToCurveGenericXMD([]byte("abc"), + []byte("QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_"), + hashFunc) + require.NoError(t, err) + require.Equal(t, ""+ //x and y coordinates + "03567bc5ef9c690c2ab2ecdf6a96ef1c139cc0b2f284dca0a9a7943388a49a3aee664ba5379a7655d3c68900be2f6903"+ + "0b9c15f3fe6e5cf4211f346271d7b01c8f3b28be689c8429c85b67af215533311f0b8dfaaa154fa6b88176c229f2885d", + hex.EncodeToString(NewG1().ToUncompressed(curve))) + }) } diff --git a/internal/third_party/kilic/bls12-381/hash_to_field_custom.go b/internal/third_party/kilic/bls12-381/hash_to_field_custom.go index 70081373c..b549191da 100644 --- a/internal/third_party/kilic/bls12-381/hash_to_field_custom.go +++ b/internal/third_party/kilic/bls12-381/hash_to_field_custom.go @@ -14,10 +14,12 @@ package bls12381 import ( "errors" "hash" + + "golang.org/x/crypto/sha3" ) -func hashToFpXMD(f func() hash.Hash, msg []byte, domain []byte, count int) ([]*fe, error) { - randBytes, err := expandMsgXMD(f, msg, domain, count*64) +func hashToFpGeneric(expand func([]byte, []byte, int) ([]byte, error), msg []byte, domain []byte, count int) ([]*fe, error) { + randBytes, err := expand(msg, domain, count*64) if err != nil { return nil, err } @@ -36,10 +38,10 @@ func hashToFpXMD(f func() hash.Hash, msg []byte, domain []byte, count int) ([]*f func expandMsgXMD(f func() hash.Hash, msg []byte, domain []byte, outLen int) ([]byte, error) { h := f() - domainLen := uint8(len(domain)) - if domainLen > 255 { + if len(domain) > 255 { return nil, errors.New("invalid domain length") } + domainLen := uint8(len(domain)) // DST_prime = DST || I2OSP(len(DST), 1) // b_0 = H(Z_pad || msg || l_i_b_str || I2OSP(0, 1) || DST_prime) @@ -84,3 +86,22 @@ func expandMsgXMD(f func() hash.Hash, msg []byte, domain []byte, outLen int) ([] return out[:outLen], nil } + +// TODO move away? +func ExpandMsgXOF(h sha3.ShakeHash, msg []byte, dst []byte, outBytesCnt int) ([]byte, error) { + if len(dst) > 255 { + return nil, errors.New("invalid DST length") + } + dstLen := uint8(len(dst)) + + // msg || outBytesCnt || dst || dstLen + h.Write(msg) + h.Write([]byte{byte(outBytesCnt >> 8), byte(outBytesCnt & 0xFF)}) + h.Write(dst) + h.Write([]byte{byte(dstLen)}) + + out := make([]byte, outBytesCnt) + h.Read(out) + + return out, nil +} diff --git a/internal/third_party/kilic/bls12-381/hash_to_field_custom_test.go b/internal/third_party/kilic/bls12-381/hash_to_field_custom_test.go new file mode 100644 index 000000000..ed625cb5a --- /dev/null +++ b/internal/third_party/kilic/bls12-381/hash_to_field_custom_test.go @@ -0,0 +1,60 @@ +/* +SPDX-License-Identifier: Apache-2.0 +*/ + +package bls12381 + +import ( + "crypto/sha256" + "encoding/hex" + "hash" + "testing" + + "github.com/stretchr/testify/require" + "golang.org/x/crypto/sha3" +) + +func TestExpandMessageXMD(t *testing.T) { + t.Run("IRTF H2C draft16 K1 abc", func(t *testing.T) { + hashFunc := func() hash.Hash { + h := sha256.New() + return h + } + outCnt := 0x20 + out, err := expandMsgXMD(hashFunc, []byte("abc"), []byte("QUUX-V01-CS02-with-expander-SHA256-128"), outCnt) + require.NoError(t, err) + require.Equal(t, len(out), outCnt) + require.Equal(t, "d8ccab23b5985ccea865c6c97b6e5b8350e794e603b4b97902f53a8a0d605615", hex.EncodeToString(out)) + }) + + t.Run("IRTF H2C draft16 K1 abcdef0123456789", func(t *testing.T) { + hashFunc := func() hash.Hash { + h := sha256.New() + return h + } + outCnt := 0x20 + out, err := expandMsgXMD(hashFunc, []byte("abcdef0123456789"), []byte("QUUX-V01-CS02-with-expander-SHA256-128"), outCnt) + require.NoError(t, err) + require.Equal(t, len(out), outCnt) + require.Equal(t, "eff31487c770a893cfb36f912fbfcbff40d5661771ca4b2cb4eafe524333f5c1", hex.EncodeToString(out)) + }) +} + +func TestExpandMessageXOF(t *testing.T) { + dst := []byte("QUUX-V01-CS02-with-expander-SHAKE256") + t.Run("IRTF H2C draft16 K6 abc", func(t *testing.T) { + outCnt := 0x20 + out, err := ExpandMsgXOF(sha3.NewShake256(), []byte("abc"), dst, outCnt) + require.NoError(t, err) + require.Equal(t, len(out), outCnt) + require.Equal(t, "b39e493867e2767216792abce1f2676c197c0692aed061560ead251821808e07", hex.EncodeToString(out)) + }) + + t.Run("IRTF H2C draft16 K6 abcdef0123456789", func(t *testing.T) { + outCnt := 0x20 + out, err := ExpandMsgXOF(sha3.NewShake256(), []byte("abcdef0123456789"), dst, outCnt) + require.NoError(t, err) + require.Equal(t, len(out), outCnt) + require.Equal(t, "245389cf44a13f0e70af8665fe5337ec2dcd138890bb7901c4ad9cfceb054b65", hex.EncodeToString(out)) + }) +} diff --git a/internal/third_party/kilic/bls12-381/swu_custom.go b/internal/third_party/kilic/bls12-381/swu_custom.go deleted file mode 100644 index 94ee43a0a..000000000 --- a/internal/third_party/kilic/bls12-381/swu_custom.go +++ /dev/null @@ -1,19 +0,0 @@ -/* -Copyright SecureKey Technologies Inc. All Rights Reserved. - -SPDX-License-Identifier: Apache-2.0 -*/ - -package bls12381 - -// swuMapG1BE is implementation of Simplified Shallue-van de Woestijne-Ulas Method -// follows the implementation at draft-irtf-cfrg-hash-to-curve-06. -// uses big-endian variant: https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-06#section-4.1.1 -func swuMapG1BE(u *fe) (*fe, *fe) { - x, y, u := swuMapG1Pre(u) - - if y.signBE() != u.signBE() { - neg(y, y) - } - return x, y -} diff --git a/internal/third_party/kilic/bls12-381/swu_mod.go b/internal/third_party/kilic/bls12-381/swu_mod.go deleted file mode 100644 index 81b6f6af9..000000000 --- a/internal/third_party/kilic/bls12-381/swu_mod.go +++ /dev/null @@ -1,49 +0,0 @@ -package bls12381 - -// swuMapG1Pre is implementation of Simplified Shallue-van de Woestijne-Ulas Method -// follows the implementation at draft-irtf-cfrg-hash-to-curve-06. -// The swuMapG1 function is modified to perform the sign correction outside. -func swuMapG1Pre(u *fe) (*fe, *fe, *fe) { - var params = swuParamsForG1 - var tv [4]*fe - for i := 0; i < 4; i++ { - tv[i] = new(fe) - } - square(tv[0], u) - mul(tv[0], tv[0], params.z) - square(tv[1], tv[0]) - x1 := new(fe) - add(x1, tv[0], tv[1]) - inverse(x1, x1) - e1 := x1.isZero() - one := new(fe).one() - add(x1, x1, one) - if e1 { - x1.set(params.zInv) - } - mul(x1, x1, params.minusBOverA) - gx1 := new(fe) - square(gx1, x1) - add(gx1, gx1, params.a) - mul(gx1, gx1, x1) - add(gx1, gx1, params.b) - x2 := new(fe) - mul(x2, tv[0], x1) - mul(tv[1], tv[0], tv[1]) - gx2 := new(fe) - mul(gx2, gx1, tv[1]) - e2 := !isQuadraticNonResidue(gx1) - x, y2 := new(fe), new(fe) - if e2 { - x.set(x1) - y2.set(gx1) - } else { - x.set(x2) - y2.set(gx2) - } - y := new(fe) - sqrt(y, y2) - - // This function is modified to perform the sign correction outside. - return x, y, u -} \ No newline at end of file diff --git a/pkg/crypto/primitive/bbs12381g2pub/utils.go b/pkg/crypto/primitive/bbs12381g2pub/utils.go index 2b9d812f9..39aae090a 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/utils.go +++ b/pkg/crypto/primitive/bbs12381g2pub/utils.go @@ -123,3 +123,27 @@ func reverseBytes(s []byte) []byte { return s } + +func i2os2(value uint16) []byte { + bytes := make([]byte, 2) + + binary.BigEndian.PutUint16(bytes, value) + + return bytes +} + +func i2os4(value uint32) []byte { + bytes := make([]byte, 4) + + binary.BigEndian.PutUint32(bytes, value) + + return bytes +} + +func i2os8(value uint64) []byte { + bytes := make([]byte, 8) + + binary.BigEndian.PutUint64(bytes, value) + + return bytes +} From ef73954955d61f55fc4ff05421da8d7d6d080af4 Mon Sep 17 00:00:00 2001 From: Sergey Minaev Date: Fri, 14 Oct 2022 11:23:41 +0500 Subject: [PATCH 02/11] [3392] Update messaage generators calc for BBS. Signed-off-by: Sergey Minaev --- pkg/crypto/primitive/bbs12381g2pub/bbs.go | 56 ++++++++++-- pkg/crypto/primitive/bbs12381g2pub/keys.go | 90 +++++++++++++------ .../primitive/bbs12381g2pub/keys_test.go | 42 ++++++++- 3 files changed, 152 insertions(+), 36 deletions(-) diff --git a/pkg/crypto/primitive/bbs12381g2pub/bbs.go b/pkg/crypto/primitive/bbs12381g2pub/bbs.go index 7036342ad..1cc1608c4 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/bbs.go +++ b/pkg/crypto/primitive/bbs12381g2pub/bbs.go @@ -7,7 +7,7 @@ SPDX-License-Identifier: Apache-2.0 // Package bbs12381g2pub contains BBS+ signing primitives and keys. Although it can be used directly, it is recommended // to use BBS+ keys created by the kms along with the framework's Crypto service. // The default local Crypto service is found at: "github.com/hyperledger/aries-framework-go/pkg/crypto/tinkcrypto" -// while the remote Crypto service is found at: "github.com/hyperledger/aries-framework-go/pkg/crypto/webkms" +// while the remote Crypto service is found at: "github.com/hyperledger/aries-framework-go/pkg/crypto/webkms" package bbs12381g2pub import ( @@ -203,12 +203,18 @@ func (bbs *BBSG2Pub) SignWithKey(messages [][]byte, privKey *PrivateKey) ([]byte return nil, fmt.Errorf("build generators from public key: %w", err) } - messagesFr := make([]*SignatureMessage, len(messages)) - for i := range messages { - messagesFr[i] = ParseSignatureMessage(messages[i]) + es_builder := newEcnodeForHashBuilder() + es_builder.addScalar(privKey.FR) + es_builder.addScalar(pubKeyWithGenerators.domain) + + messagesFr := make([]*SignatureMessage, messagesCount) + for i, msg := range messages { + messagesFr[i] = ParseSignatureMessage(msg) + es_builder.addBytes(msg) } - e, s := createRandSignatureFr(), createRandSignatureFr() + es := Hash2scalars(es_builder.build(), 2) + e, s := es[0], es[1] exp := bls12381.NewFr().Set(privKey.FR) exp.Add(exp, e) exp.Inverse(exp) @@ -233,10 +239,11 @@ func computeB(s *bls12381.Fr, messages []*SignatureMessage, key *PublicKeyWithGe cb := newCommitmentBuilder(len(messages) + basesOffset) cb.add(g1.One(), bls12381.NewFr().One()) - cb.add(key.h0, s) + cb.add(key.Q1, s) + cb.add(key.Q2, key.domain) for i := 0; i < len(messages); i++ { - cb.add(key.h[i], messages[i].FR) + cb.add(key.H[i], messages[i].FR) } return cb.build() @@ -305,3 +312,38 @@ func ParseProofNonce(proofNonceBytes []byte) *ProofNonce { func (pn *ProofNonce) ToBytes() []byte { return frToRepr(pn.fr).ToBytes() } + +type encodeForHashBuilder struct { + bytes []byte //TODO check encoding functions per type below +} + +func newEcnodeForHashBuilder() *encodeForHashBuilder { + return &encodeForHashBuilder{ + bytes: make([]byte, 0), + } +} + +func (db *encodeForHashBuilder) addInt(value int) { + db.bytes = append(db.bytes, i2os8(uint64(value))...) +} + +func (db *encodeForHashBuilder) addPointG1(value *bls12381.PointG1) { + db.bytes = append(db.bytes, g1.ToBytes(value)...) +} + +func (db *encodeForHashBuilder) addPointG2(value *bls12381.PointG2) { + db.bytes = append(db.bytes, g2.ToBytes(value)...) +} + +func (db *encodeForHashBuilder) addScalar(value *bls12381.Fr) { + db.bytes = append(db.bytes, value.ToBytes()...) +} + +func (db *encodeForHashBuilder) addBytes(value []byte) { + db.bytes = append(db.bytes, i2os8(uint64(len(value)))...) + db.bytes = append(db.bytes, value...) +} + +func (db *encodeForHashBuilder) build() []byte { + return db.bytes +} diff --git a/pkg/crypto/primitive/bbs12381g2pub/keys.go b/pkg/crypto/primitive/bbs12381g2pub/keys.go index 8214a791a..3bb79e48b 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/keys.go +++ b/pkg/crypto/primitive/bbs12381g2pub/keys.go @@ -14,8 +14,8 @@ import ( "io" bls12381 "github.com/kilic/bls12-381" - "golang.org/x/crypto/blake2b" "golang.org/x/crypto/hkdf" + "golang.org/x/crypto/sha3" bls12381intern "github.com/hyperledger/aries-framework-go/internal/third_party/kilic/bls12-381" ) @@ -23,6 +23,13 @@ import ( const ( seedSize = frCompressedSize generateKeySalt = "BBS-SIG-KEYGEN-SALT-" + csId = "BBS_BLS12381G1_XOF:SHAKE-256_SSWU_RO_" + seedDST = csId + "SIG_GENERATOR_SEED_" + generatorDST = csId + "SIG_GENERATOR_DST_" + generatorSeed = csId + "MESSAGE_GENERATOR_SEED" + h2s_dst = csId + "H2S_" + expandLen = (384 + 128) / 8 + seedLen = ((251 + 128) + 7) / 8 ) // PublicKey defines BLS Public Key. @@ -38,48 +45,52 @@ type PrivateKey struct { // PublicKeyWithGenerators extends PublicKey with a blinding generator h0, a commitment to the secret key w, // and a generator for each message h. type PublicKeyWithGenerators struct { - h0 *bls12381.PointG1 - h []*bls12381.PointG1 + Q1 *bls12381.PointG1 + Q2 *bls12381.PointG1 + H []*bls12381.PointG1 w *bls12381.PointG2 messagesCount int + + domain *bls12381.Fr } // ToPublicKeyWithGenerators creates PublicKeyWithGenerators from the PublicKey. func (pk *PublicKey) ToPublicKeyWithGenerators(messagesCount int) (*PublicKeyWithGenerators, error) { - offset := g2UncompressedSize + 1 - - data := calcData(pk, messagesCount) - - h0, err := hashToG1(data) - if err != nil { - return nil, fmt.Errorf("create G1 point from hash") - } + genCnt := messagesCount + 2 - h := make([]*bls12381.PointG1, messagesCount) + generators := make([]*bls12381.PointG1, genCnt) - for i := 1; i <= messagesCount; i++ { - dataCopy := make([]byte, len(data)) - copy(dataCopy, data) + n := uint32(1) + v, _ := bls12381intern.ExpandMsgXOF(sha3.NewShake256(), []byte(generatorSeed), []byte(seedDST), seedLen) + for i := 0; i < genCnt; i++ { + v = append(v, i2os4(n)...) + v, _ = bls12381intern.ExpandMsgXOF(sha3.NewShake256(), v, []byte(seedDST), seedLen) + n++ - iBytes := uint32ToBytes(uint32(i)) - - for j := 0; j < len(iBytes); j++ { - dataCopy[j+offset] = iBytes[j] - } + //TODO check if candidate is uniq + generators[i], _ = hashToG1(v, []byte(generatorDST)) + } - h[i-1], err = hashToG1(dataCopy) - if err != nil { - return nil, fmt.Errorf("create G1 point from hash: %w", err) - } + domain_builder := newEcnodeForHashBuilder() + domain_builder.addPointG2(pk.PointG2) + domain_builder.addInt(messagesCount) + for _, gen := range generators { + domain_builder.addPointG1(gen) } + domain_builder.addBytes([]byte(csId)) + //TODO header ?? + + domain := Hash2scalar(domain_builder.build()) return &PublicKeyWithGenerators{ - h0: h0, - h: h, + Q1: generators[0], + Q2: generators[1], + H: generators[2:], w: pk.PointG2, messagesCount: messagesCount, + domain: domain, }, nil } @@ -214,3 +225,30 @@ func newHKDF(h func() hash.Hash, ikm, salt, info []byte, length int) ([]byte, er return result, nil } + +func Hash2scalar(message []byte) *bls12381.Fr { + return Hash2scalars(message, 1)[0] +} + +func Hash2scalars(msg []byte, cnt int) []*bls12381.Fr { + bufLen := cnt * expandLen + msgLen := len(msg) + + msgExt := make([]byte, msgLen+1+4) + copy(msgExt, msg) + copy(msgExt[msgLen+1:], i2os4(uint32(msgLen))) + + out := make([]*bls12381.Fr, cnt) + for round, completed := byte(0), false; !completed; { + msgExt[msgLen] = round + buf, _ := bls12381intern.ExpandMsgXOF(sha3.NewShake256(), msgExt, []byte(h2s_dst), bufLen) + + ok := true + for i := 0; i < cnt && ok; i++ { + out[i] = bls12381.NewFr().FromBytes(buf[i*expandLen : (i+1)*expandLen]) + ok = !out[i].IsZero() + } + completed = ok + } + return out +} diff --git a/pkg/crypto/primitive/bbs12381g2pub/keys_test.go b/pkg/crypto/primitive/bbs12381g2pub/keys_test.go index b9aa3151b..d9fa0b633 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/keys_test.go +++ b/pkg/crypto/primitive/bbs12381g2pub/keys_test.go @@ -9,9 +9,11 @@ package bbs12381g2pub_test import ( "crypto/rand" "crypto/sha256" + "encoding/hex" "testing" "github.com/btcsuite/btcutil/base58" + bls12381 "github.com/kilic/bls12-381" "github.com/stretchr/testify/require" bbs "github.com/hyperledger/aries-framework-go/pkg/crypto/primitive/bbs12381g2pub" @@ -56,10 +58,44 @@ func TestPrivateKey_Marshal(t *testing.T) { } func TestPrivateKey_PublicKey(t *testing.T) { - pubKey, privKey, err := generateKeyPairRandom() - require.NoError(t, err) + t.Run("random key pair", func(t *testing.T) { + pubKey, privKey, err := generateKeyPairRandom() + require.NoError(t, err) + + require.Equal(t, pubKey, privKey.PublicKey()) + }) + + t.Run("pre-generated key pair", func(t *testing.T) { + // original hex seed 746869732d49532d6a7573742d616e2d546573742d494b4d2d746f2d67656e65726174652d246528724074232d6b6579 + privateKeyB58 := "5qNVd4Wsp7LPC7vxrbuVMsAkAGif2dA82wm1Wte1zH4Z" + publicKeyB58 := "25pRBEBDHvG5ryqsEB5tw6eAa3Ds8bx6jMKhEtXnWjCLNg7ikYokwaNtpggZZY3MvWTxBPCidfxFBq2ZiVVTpioCh6GJLs4iESiEydJca9kmeMkEkqK6ePudqoqLHSv4NA7p" + + privateKey, err := bbs.UnmarshalPrivateKey(base58.Decode(privateKeyB58)) + require.NoError(t, err) + + publicKeyBytes, err := privateKey.PublicKey().Marshal() + require.Equal(t, publicKeyB58, base58.Encode(publicKeyBytes)) + + }) + + t.Run("generators", func(t *testing.T) { + msgCnt := 2 + _, privKey, err := generateKeyPairRandom() + require.NoError(t, err) + + pkExt, _ := privKey.PublicKey().ToPublicKeyWithGenerators(msgCnt) + + bytes := bls12381.NewG1().ToCompressed(pkExt.Q1) + require.Equal(t, "b60acd4b0dc13b580394d2d8bc6c07d452df8e2a7eff93bc9da965b57e076cae640c2858fb0c2eaf242b1bd11107d635", hex.EncodeToString(bytes)) + bytes = bls12381.NewG1().ToCompressed(pkExt.Q2) + require.Equal(t, "ad03f655b4c94f312b051aba45977c924bc5b4b1780c969534c183784c7275b70b876db641579604328c0975eaa0a137", hex.EncodeToString(bytes)) - require.Equal(t, pubKey, privKey.PublicKey()) + require.Equal(t, msgCnt, len(pkExt.H)) + bytes = bls12381.NewG1().ToCompressed(pkExt.H[0]) + require.Equal(t, "b63ae18d3edd64a2edd381290f0c68bebabaf3d37bc9dbb0bd5ad8daf03bbd2c48260255ba73f3389d2d5ad82303ac25", hex.EncodeToString(bytes)) + bytes = bls12381.NewG1().ToCompressed(pkExt.H[1]) + require.Equal(t, "b0b92b79a3e1fc59f39c6b9f78f00b873121c6a4c1814b94c07848efd172762fefbc48447a16f9ba8ed1b638e2933029", hex.EncodeToString(bytes)) + }) } func TestPublicKey_Marshal(t *testing.T) { From 514e0eedc13ac5f6faa97a46eed35381bdfd7a15 Mon Sep 17 00:00:00 2001 From: Sergey Minaev Date: Fri, 14 Oct 2022 11:25:16 +0500 Subject: [PATCH 03/11] [3392] Draft DeriveProof BBS. Signed-off-by: Sergey Minaev --- pkg/crypto/primitive/bbs12381g2pub/bbs.go | 8 +- pkg/crypto/primitive/bbs12381g2pub/keys.go | 24 +----- .../bbs12381g2pub/proof_of_knowledge.go | 83 +++++++++++-------- .../bbs12381g2pub/signature_proof.go | 48 +++++------ 4 files changed, 74 insertions(+), 89 deletions(-) diff --git a/pkg/crypto/primitive/bbs12381g2pub/bbs.go b/pkg/crypto/primitive/bbs12381g2pub/bbs.go index 1cc1608c4..29e3f9298 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/bbs.go +++ b/pkg/crypto/primitive/bbs12381g2pub/bbs.go @@ -169,13 +169,7 @@ func (bbs *BBSG2Pub) DeriveProof(messages [][]byte, sigBytes, nonce, pubKeyBytes return nil, fmt.Errorf("init proof of knowledge signature: %w", err) } - challengeBytes := pokSignature.ToBytes() - - proofNonce := ParseProofNonce(nonce) - proofNonceBytes := proofNonce.ToBytes() - challengeBytes = append(challengeBytes, proofNonceBytes...) - - proofChallenge := frFromOKM(challengeBytes) + proofChallenge := pokSignature.CalculateChallenge(publicKeyWithGenerators.domain, nonce) proof := pokSignature.GenerateProof(proofChallenge) diff --git a/pkg/crypto/primitive/bbs12381g2pub/keys.go b/pkg/crypto/primitive/bbs12381g2pub/keys.go index 3bb79e48b..243a5b72e 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/keys.go +++ b/pkg/crypto/primitive/bbs12381g2pub/keys.go @@ -94,30 +94,10 @@ func (pk *PublicKey) ToPublicKeyWithGenerators(messagesCount int) (*PublicKeyWit }, nil } -func calcData(key *PublicKey, messagesCount int) []byte { - data := g2.ToUncompressed(key.PointG2) - - data = append(data, 0, 0, 0, 0, 0, 0) - - mcBytes := uint32ToBytes(uint32(messagesCount)) - - data = append(data, mcBytes...) - - return data -} - -func hashToG1(data []byte) (*bls12381.PointG1, error) { - dstG1 := []byte("BLS12381G1_XMD:BLAKE2B_SSWU_RO_BBS+_SIGNATURES:1_0_0") - - hashFunc := func() hash.Hash { - // We pass a null key so error is impossible here. - h, _ := blake2b.New512(nil) //nolint:errcheck - return h - } - +func hashToG1(data []byte, dst []byte) (*bls12381.PointG1, error) { g := bls12381intern.NewG1() - p, err := g.HashToCurveGeneric(data, dstG1, hashFunc) + p, err := g.HashToCurveGenericXOF(data, dst, sha3.NewShake256()) if err != nil { return nil, err } diff --git a/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go b/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go index 1455912e0..c50b15396 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go +++ b/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go @@ -36,35 +36,32 @@ func NewPoKOfSignature(signature *Signature, messages []*SignatureMessage, revea } r1, r2 := createRandSignatureFr(), createRandSignatureFr() + b := computeB(signature.S, messages, pubKey) + + r3 := bls12381.NewFr() + r3.Inverse(r1) + aPrime := g1.New() g1.MulScalar(aPrime, signature.A, frToRepr(r1)) + aBar := g1.New() aBarDenom := g1.New() g1.MulScalar(aBarDenom, aPrime, frToRepr(signature.E)) - - aBar := g1.New() g1.MulScalar(aBar, b, frToRepr(r1)) g1.Sub(aBar, aBar, aBarDenom) - r2D := bls12381.NewFr() - r2D.Neg(r2) - commitmentBasesCount := 2 - cb := newCommitmentBuilder(commitmentBasesCount) - cb.add(b, r1) - cb.add(pubKey.h0, r2D) - - d := cb.build() - r3 := bls12381.NewFr() - r3.Inverse(r1) + cbD := newCommitmentBuilder(commitmentBasesCount) + cbD.add(b, r1) + cbD.add(pubKey.Q1, r2) + d := cbD.build() sPrime := bls12381.NewFr() sPrime.Mul(r2, r3) - sPrime.Neg(sPrime) sPrime.Add(sPrime, signature.S) - pokVC1, secrets1 := newVC1Signature(aPrime, pubKey.h0, signature.E, r2) + pokVC1, secrets1 := newVC1Signature(aPrime, pubKey.Q1, signature.E, r2) revealedMessages := make(map[int]*SignatureMessage, len(revealedIndexes)) @@ -91,20 +88,17 @@ func NewPoKOfSignature(signature *Signature, messages []*SignatureMessage, revea }, nil } -func newVC1Signature(aPrime *bls12381.PointG1, h0 *bls12381.PointG1, +func newVC1Signature(aPrime *bls12381.PointG1, q1 *bls12381.PointG1, e, r2 *bls12381.Fr) (*ProverCommittedG1, []*bls12381.Fr) { committing1 := NewProverCommittingG1() secrets1 := make([]*bls12381.Fr, 2) committing1.Commit(aPrime) + secrets1[0] = e - sigE := bls12381.NewFr() - sigE.Neg(e) - secrets1[0] = sigE - - committing1.Commit(h0) - + committing1.Commit(q1) secrets1[1] = r2 + pokVC1 := committing1.Finish() return pokVC1, secrets1 @@ -118,14 +112,9 @@ func newVC2Signature(d *bls12381.PointG1, r3 *bls12381.Fr, pubKey *PublicKeyWith secrets2 := make([]*bls12381.Fr, 0, baseSecretsCount+messagesCount) committing2.Commit(d) + secrets2 = append(secrets2, r3) - r3D := bls12381.NewFr() - r3D.Neg(r3) - - secrets2 = append(secrets2, r3D) - - committing2.Commit(pubKey.h0) - + committing2.Commit(pubKey.Q1) secrets2 = append(secrets2, sPrime) for i := 0; i < messagesCount; i++ { @@ -133,7 +122,7 @@ func newVC2Signature(d *bls12381.PointG1, r3 *bls12381.Fr, pubKey *PublicKeyWith continue } - committing2.Commit(pubKey.h[i]) + committing2.Commit(pubKey.H[i]) sourceFR := messages[i].FR hiddenFRCopy := bls12381.NewFr() @@ -149,9 +138,21 @@ func newVC2Signature(d *bls12381.PointG1, r3 *bls12381.Fr, pubKey *PublicKeyWith // ToBytes converts PoKOfSignature to bytes. func (pos *PoKOfSignature) ToBytes() []byte { - challengeBytes := g1.ToUncompressed(pos.aBar) - challengeBytes = append(challengeBytes, pos.pokVC1.ToBytes()...) - challengeBytes = append(challengeBytes, pos.pokVC2.ToBytes()...) + challengeBytes := g1.ToUncompressed(pos.aPrime) + challengeBytes = append(challengeBytes, g1.ToUncompressed(pos.aBar)...) + challengeBytes = append(challengeBytes, g1.ToUncompressed(pos.d)...) + challengeBytes = append(challengeBytes, g1.ToUncompressed(pos.pokVC1.commitment)...) + challengeBytes = append(challengeBytes, g1.ToUncompressed(pos.pokVC2.commitment)...) + r := len(pos.revealedMessages) + idxs := make([]byte, 8*r) + msgs := make([]byte, 0) + challengeBytes = append(challengeBytes, i2os8(uint64(r))...) + for i, m := range pos.revealedMessages { + idxs = append(idxs, i2os8(uint64(i))...) + msgs = append(msgs, m.FR.ToBytes()...) + } + challengeBytes = append(challengeBytes, idxs...) + challengeBytes = append(challengeBytes, msgs...) return challengeBytes } @@ -194,7 +195,7 @@ func (g *ProverCommittedG1) GenerateProof(challenge *bls12381.Fr, secrets []*bls c.Mul(challenge, secrets[i]) s := bls12381.NewFr() - s.Sub(g.blindingFactors[i], c) + s.Add(g.blindingFactors[i], c) responses[i] = s } @@ -235,3 +236,19 @@ func (pc *ProverCommittingG1) Finish() *ProverCommittedG1 { commitment: commitment, } } + +// Modified Finish() for case where first element should be neg +func (pc *ProverCommittingG1) FinishMod() *ProverCommittedG1 { + blindings := make([]*bls12381.Fr, 0) + copy(blindings, pc.blindingFactors) + negFirst := bls12381.NewFr() + negFirst.Neg(blindings[0]) + blindings[0] = negFirst + commitment := sumOfG1Products(pc.bases, blindings) + + return &ProverCommittedG1{ + bases: pc.bases, + blindingFactors: pc.blindingFactors, + commitment: commitment, + } +} diff --git a/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go b/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go index d4bd1f414..33144acba 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go +++ b/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go @@ -28,36 +28,30 @@ type PoKOfSignatureProof struct { // GetBytesForChallenge creates bytes for proof challenge. func (sp *PoKOfSignatureProof) GetBytesForChallenge(revealedMessages map[int]*SignatureMessage, pubKey *PublicKeyWithGenerators) []byte { - hiddenCount := pubKey.messagesCount - len(revealedMessages) - - bytesLen := (7 + hiddenCount) * g1UncompressedSize //nolint:gomnd - bytes := make([]byte, 0, bytesLen) - - bytes = append(bytes, g1.ToUncompressed(sp.aBar)...) - bytes = append(bytes, g1.ToUncompressed(sp.aPrime)...) - bytes = append(bytes, g1.ToUncompressed(pubKey.h0)...) - bytes = append(bytes, g1.ToUncompressed(sp.proofVC1.commitment)...) - bytes = append(bytes, g1.ToUncompressed(sp.d)...) - bytes = append(bytes, g1.ToUncompressed(pubKey.h0)...) - - for i := range pubKey.h { - if _, ok := revealedMessages[i]; !ok { - bytes = append(bytes, g1.ToUncompressed(pubKey.h[i])...) - } + challengeBytes := g1.ToUncompressed(sp.aPrime) + challengeBytes = append(challengeBytes, g1.ToUncompressed(sp.aBar)...) + challengeBytes = append(challengeBytes, g1.ToUncompressed(sp.d)...) + challengeBytes = append(challengeBytes, g1.ToUncompressed(sp.proofVC1.commitment)...) + challengeBytes = append(challengeBytes, g1.ToUncompressed(sp.proofVC2.commitment)...) + r := len(revealedMessages) + idxs := make([]byte, 8*r) + msgs := make([]byte, 0) + challengeBytes = append(challengeBytes, i2os8(uint64(r))...) + for i, m := range revealedMessages { + idxs = append(idxs, i2os8(uint64(i))...) + msgs = append(msgs, m.FR.ToBytes()...) } + challengeBytes = append(challengeBytes, idxs...) + challengeBytes = append(challengeBytes, msgs...) - bytes = append(bytes, g1.ToUncompressed(sp.proofVC2.commitment)...) - - return bytes + return challengeBytes } // Verify verifies PoKOfSignatureProof. func (sp *PoKOfSignatureProof) Verify(challenge *bls12381.Fr, pubKey *PublicKeyWithGenerators, revealedMessages map[int]*SignatureMessage, messages []*SignatureMessage) error { - aBar := new(bls12381.PointG1) - g1.Neg(aBar, sp.aBar) - ok := compareTwoPairings(sp.aPrime, pubKey.w, aBar, g2.One()) + ok := compareTwoPairings(sp.aPrime, pubKey.w, sp.aBar, g2.One()) if !ok { return errors.New("bad signature") } @@ -71,7 +65,7 @@ func (sp *PoKOfSignatureProof) Verify(challenge *bls12381.Fr, pubKey *PublicKeyW } func (sp *PoKOfSignatureProof) verifyVC1Proof(challenge *bls12381.Fr, pubKey *PublicKeyWithGenerators) error { - basesVC1 := []*bls12381.PointG1{sp.aPrime, pubKey.h0} + basesVC1 := []*bls12381.PointG1{sp.aPrime, pubKey.Q1, pubKey.Q2} aBarD := new(bls12381.PointG1) g1.Sub(aBarD, sp.aBar, sp.d) @@ -88,7 +82,7 @@ func (sp *PoKOfSignatureProof) verifyVC2Proof(challenge *bls12381.Fr, pubKey *Pu revealedMessagesCount := len(revealedMessages) basesVC2 := make([]*bls12381.PointG1, 0, 2+pubKey.messagesCount-revealedMessagesCount) - basesVC2 = append(basesVC2, sp.d, pubKey.h0) + basesVC2 = append(basesVC2, sp.d, pubKey.Q1, pubKey.Q2) basesDisclosed := make([]*bls12381.PointG1, 0, 1+revealedMessagesCount) exponents := make([]*bls12381.Fr, 0, 1+revealedMessagesCount) @@ -98,13 +92,13 @@ func (sp *PoKOfSignatureProof) verifyVC2Proof(challenge *bls12381.Fr, pubKey *Pu revealedMessagesInd := 0 - for i := range pubKey.h { + for i, hi := range pubKey.H { if _, ok := revealedMessages[i]; ok { - basesDisclosed = append(basesDisclosed, pubKey.h[i]) + basesDisclosed = append(basesDisclosed, hi) exponents = append(exponents, messages[revealedMessagesInd].FR) revealedMessagesInd++ } else { - basesVC2 = append(basesVC2, pubKey.h[i]) + basesVC2 = append(basesVC2, hi) } } From 857f0f6f78972f749f1737ef5ce9405cab2a64aa Mon Sep 17 00:00:00 2001 From: Sergey Minaev Date: Mon, 17 Oct 2022 12:01:24 +0500 Subject: [PATCH 04/11] [3392] Clean-up: move ParseSignatureMessage helper, minor fixes. Signed-off-by: Sergey Minaev --- pkg/crypto/primitive/bbs12381g2pub/bbs.go | 50 +++++----- pkg/crypto/primitive/bbs12381g2pub/fr.go | 10 -- pkg/crypto/primitive/bbs12381g2pub/keys.go | 94 +++++++++++++------ .../primitive/bbs12381g2pub/keys_test.go | 23 +++-- .../bbs12381g2pub/proof_of_knowledge.go | 71 ++++++-------- .../bbs12381g2pub/signature_message.go | 17 +++- .../bbs12381g2pub/signature_proof.go | 67 +++++-------- pkg/crypto/primitive/bbs12381g2pub/utils.go | 58 ++++++++---- 8 files changed, 208 insertions(+), 182 deletions(-) diff --git a/pkg/crypto/primitive/bbs12381g2pub/bbs.go b/pkg/crypto/primitive/bbs12381g2pub/bbs.go index 29e3f9298..a47eb816a 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/bbs.go +++ b/pkg/crypto/primitive/bbs12381g2pub/bbs.go @@ -43,12 +43,6 @@ const ( // Number of bytes in G1 X coordinate. g1CompressedSize = 48 - // Number of bytes in G1 X and Y coordinates. - g1UncompressedSize = 96 - - // Number of bytes in G2 X(a, b) and Y(a, b) coordinates. - g2UncompressedSize = 192 - // Number of bytes in scalar compressed form. frCompressedSize = 32 @@ -75,7 +69,7 @@ func (bbs *BBSG2Pub) Verify(messages [][]byte, sigBytes, pubKeyBytes []byte) err return fmt.Errorf("build generators from public key: %w", err) } - messagesFr := messagesToFr(messages) + messagesFr := ParseSignatureMessages(messages) return signature.Verify(messagesFr, publicKeyWithGenerators) } @@ -106,7 +100,7 @@ func (bbs *BBSG2Pub) VerifyProof(messagesBytes [][]byte, proof, nonce, pubKeyByt return fmt.Errorf("parse signature proof: %w", err) } - messages := messagesToFr(messagesBytes) + messages := ParseSignatureMessages(messagesBytes) pubKey, err := UnmarshalPublicKey(pubKeyBytes) if err != nil { @@ -127,13 +121,9 @@ func (bbs *BBSG2Pub) VerifyProof(messagesBytes [][]byte, proof, nonce, pubKeyByt revealedMessages[payload.revealed[i]] = messages[i] } - challengeBytes := signatureProof.GetBytesForChallenge(revealedMessages, publicKeyWithGenerators) - proofNonce := ParseProofNonce(nonce) - proofNonceBytes := proofNonce.ToBytes() - challengeBytes = append(challengeBytes, proofNonceBytes...) - proofChallenge := frFromOKM(challengeBytes) + challenge := signatureProof.CalculateChallenge(revealedMessages, publicKeyWithGenerators, nonce) - return signatureProof.Verify(proofChallenge, publicKeyWithGenerators, revealedMessages, messages) + return signatureProof.Verify(challenge, publicKeyWithGenerators, revealedMessages, messages) } // DeriveProof derives a proof of BBS+ signature with some messages disclosed. @@ -147,7 +137,7 @@ func (bbs *BBSG2Pub) DeriveProof(messages [][]byte, sigBytes, nonce, pubKeyBytes messagesCount := len(messages) - messagesFr := messagesToFr(messages) + messagesFr := ParseSignatureMessages(messages) pubKey, err := UnmarshalPublicKey(pubKeyBytes) if err != nil { @@ -169,7 +159,7 @@ func (bbs *BBSG2Pub) DeriveProof(messages [][]byte, sigBytes, nonce, pubKeyBytes return nil, fmt.Errorf("init proof of knowledge signature: %w", err) } - proofChallenge := pokSignature.CalculateChallenge(publicKeyWithGenerators.domain, nonce) + proofChallenge := pokSignature.CalculateChallenge(messagesCount, publicKeyWithGenerators.domain, nonce) proof := pokSignature.GenerateProof(proofChallenge) @@ -197,25 +187,24 @@ func (bbs *BBSG2Pub) SignWithKey(messages [][]byte, privKey *PrivateKey) ([]byte return nil, fmt.Errorf("build generators from public key: %w", err) } - es_builder := newEcnodeForHashBuilder() - es_builder.addScalar(privKey.FR) - es_builder.addScalar(pubKeyWithGenerators.domain) + esBuilder := newEcnodeForHashBuilder() + esBuilder.addScalar(privKey.FR) + esBuilder.addScalar(pubKeyWithGenerators.domain) - messagesFr := make([]*SignatureMessage, messagesCount) - for i, msg := range messages { - messagesFr[i] = ParseSignatureMessage(msg) - es_builder.addBytes(msg) + for _, msg := range messages { + esBuilder.addBytes(msg) } - es := Hash2scalars(es_builder.build(), 2) + es := Hash2scalars(esBuilder.build(), 2) e, s := es[0], es[1] exp := bls12381.NewFr().Set(privKey.FR) exp.Add(exp, e) exp.Inverse(exp) - sig := g1.New() + messagesFr := ParseSignatureMessages(messages) b := computeB(s, messagesFr, pubKeyWithGenerators) + sig := g1.New() g1.MulScalar(sig, b, frToRepr(exp)) signature := &Signature{ @@ -230,9 +219,12 @@ func (bbs *BBSG2Pub) SignWithKey(messages [][]byte, privKey *PrivateKey) ([]byte func computeB(s *bls12381.Fr, messages []*SignatureMessage, key *PublicKeyWithGenerators) *bls12381.PointG1 { const basesOffset = 2 + bindingBasis := g1.One() + bindingExp := bls12381.NewFr().One() + cb := newCommitmentBuilder(len(messages) + basesOffset) - cb.add(g1.One(), bls12381.NewFr().One()) + cb.add(bindingBasis, bindingExp) cb.add(key.Q1, s) cb.add(key.Q2, key.domain) @@ -308,7 +300,7 @@ func (pn *ProofNonce) ToBytes() []byte { } type encodeForHashBuilder struct { - bytes []byte //TODO check encoding functions per type below + bytes []byte // TODO check encoding functions per type below } func newEcnodeForHashBuilder() *encodeForHashBuilder { @@ -318,7 +310,7 @@ func newEcnodeForHashBuilder() *encodeForHashBuilder { } func (db *encodeForHashBuilder) addInt(value int) { - db.bytes = append(db.bytes, i2os8(uint64(value))...) + db.bytes = append(db.bytes, uint64ToBytes(uint64(value))...) } func (db *encodeForHashBuilder) addPointG1(value *bls12381.PointG1) { @@ -334,7 +326,7 @@ func (db *encodeForHashBuilder) addScalar(value *bls12381.Fr) { } func (db *encodeForHashBuilder) addBytes(value []byte) { - db.bytes = append(db.bytes, i2os8(uint64(len(value)))...) + db.bytes = append(db.bytes, uint64ToBytes(uint64(len(value)))...) db.bytes = append(db.bytes, value...) } diff --git a/pkg/crypto/primitive/bbs12381g2pub/fr.go b/pkg/crypto/primitive/bbs12381g2pub/fr.go index 1458375f2..33a6c45ff 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/fr.go +++ b/pkg/crypto/primitive/bbs12381g2pub/fr.go @@ -51,16 +51,6 @@ func frToRepr(fr *bls12381.Fr) *bls12381.Fr { return frRepr } -func messagesToFr(messages [][]byte) []*SignatureMessage { - messagesFr := make([]*SignatureMessage, len(messages)) - - for i := range messages { - messagesFr[i] = ParseSignatureMessage(messages[i]) - } - - return messagesFr -} - func createRandSignatureFr() *bls12381.Fr { fr, _ := bls12381.NewFr().Rand(rand.Reader) //nolint:errcheck diff --git a/pkg/crypto/primitive/bbs12381g2pub/keys.go b/pkg/crypto/primitive/bbs12381g2pub/keys.go index 243a5b72e..79c8ea8a0 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/keys.go +++ b/pkg/crypto/primitive/bbs12381g2pub/keys.go @@ -23,13 +23,16 @@ import ( const ( seedSize = frCompressedSize generateKeySalt = "BBS-SIG-KEYGEN-SALT-" - csId = "BBS_BLS12381G1_XOF:SHAKE-256_SSWU_RO_" - seedDST = csId + "SIG_GENERATOR_SEED_" - generatorDST = csId + "SIG_GENERATOR_DST_" - generatorSeed = csId + "MESSAGE_GENERATOR_SEED" - h2s_dst = csId + "H2S_" - expandLen = (384 + 128) / 8 - seedLen = ((251 + 128) + 7) / 8 + csID = "BBS_BLS12381G1_XOF:SHAKE-256_SSWU_RO_" + seedDST = csID + "SIG_GENERATOR_SEED_" + generatorDST = csID + "SIG_GENERATOR_DST_" + generatorSeed = csID + "MESSAGE_GENERATOR_SEED" + h2sDST = csID + "H2S_" + logP2 = 384 + logR2 = 251 + k = 128 + expandLen = (logP2 + k) / 8 + seedLen = ((logR2 + k) + 7) / 8 //nolint:gomnd ) // PublicKey defines BLS Public Key. @@ -58,31 +61,26 @@ type PublicKeyWithGenerators struct { // ToPublicKeyWithGenerators creates PublicKeyWithGenerators from the PublicKey. func (pk *PublicKey) ToPublicKeyWithGenerators(messagesCount int) (*PublicKeyWithGenerators, error) { - genCnt := messagesCount + 2 + specGenCnt := 2 + genCnt := messagesCount + specGenCnt - generators := make([]*bls12381.PointG1, genCnt) - - n := uint32(1) - v, _ := bls12381intern.ExpandMsgXOF(sha3.NewShake256(), []byte(generatorSeed), []byte(seedDST), seedLen) - for i := 0; i < genCnt; i++ { - v = append(v, i2os4(n)...) - v, _ = bls12381intern.ExpandMsgXOF(sha3.NewShake256(), v, []byte(seedDST), seedLen) - n++ - - //TODO check if candidate is uniq - generators[i], _ = hashToG1(v, []byte(generatorDST)) + generators, err := createGenerators(genCnt) + if err != nil { + return nil, err } - domain_builder := newEcnodeForHashBuilder() - domain_builder.addPointG2(pk.PointG2) - domain_builder.addInt(messagesCount) + domainBuilder := newEcnodeForHashBuilder() + domainBuilder.addPointG2(pk.PointG2) + domainBuilder.addInt(messagesCount) + for _, gen := range generators { - domain_builder.addPointG1(gen) + domainBuilder.addPointG1(gen) } - domain_builder.addBytes([]byte(csId)) - //TODO header ?? - domain := Hash2scalar(domain_builder.build()) + domainBuilder.addBytes([]byte(csID)) + // TODO use header. Probably should be a parameter to this func + + domain := Hash2scalar(domainBuilder.build()) return &PublicKeyWithGenerators{ Q1: generators[0], @@ -94,7 +92,7 @@ func (pk *PublicKey) ToPublicKeyWithGenerators(messagesCount int) (*PublicKeyWit }, nil } -func hashToG1(data []byte, dst []byte) (*bls12381.PointG1, error) { +func hashToG1(data, dst []byte) (*bls12381.PointG1, error) { g := bls12381intern.NewG1() p, err := g.HashToCurveGenericXOF(data, dst, sha3.NewShake256()) @@ -105,6 +103,35 @@ func hashToG1(data []byte, dst []byte) (*bls12381.PointG1, error) { return g1.FromBytes(g.ToBytes(p)) } +func createGenerators(cnt int) ([]*bls12381.PointG1, error) { + generators := make([]*bls12381.PointG1, cnt) + + v, err := bls12381intern.ExpandMsgXOF(sha3.NewShake256(), []byte(generatorSeed), []byte(seedDST), seedLen) + if err != nil { + return nil, err + } + + n := uint32(1) + for i := 0; i < cnt; i++ { + v = append(v, uint32ToBytes(n)...) + + v, err = bls12381intern.ExpandMsgXOF(sha3.NewShake256(), v, []byte(seedDST), seedLen) + if err != nil { + return nil, err + } + + n++ + + // TODO check if candidate is uniq + generators[i], err = hashToG1(v, []byte(generatorDST)) + if err != nil { + return nil, err + } + } + + return generators, nil +} + // UnmarshalPrivateKey unmarshals PrivateKey. func UnmarshalPrivateKey(privKeyBytes []byte) (*PrivateKey, error) { if len(privKeyBytes) != frCompressedSize { @@ -206,29 +233,36 @@ func newHKDF(h func() hash.Hash, ikm, salt, info []byte, length int) ([]byte, er return result, nil } +// Hash2scalar convert message represented in bytes to Fr. func Hash2scalar(message []byte) *bls12381.Fr { return Hash2scalars(message, 1)[0] } +// Hash2scalars convert messages represented in bytes to Fr. func Hash2scalars(msg []byte, cnt int) []*bls12381.Fr { bufLen := cnt * expandLen msgLen := len(msg) + roundSz := 1 + msgLenSz := 4 - msgExt := make([]byte, msgLen+1+4) + msgExt := make([]byte, msgLen+roundSz+msgLenSz) copy(msgExt, msg) - copy(msgExt[msgLen+1:], i2os4(uint32(msgLen))) + copy(msgExt[msgLen+1:], uint32ToBytes(uint32(msgLen))) out := make([]*bls12381.Fr, cnt) + for round, completed := byte(0), false; !completed; { msgExt[msgLen] = round - buf, _ := bls12381intern.ExpandMsgXOF(sha3.NewShake256(), msgExt, []byte(h2s_dst), bufLen) + buf, _ := bls12381intern.ExpandMsgXOF(sha3.NewShake256(), msgExt, []byte(h2sDST), bufLen) //nolint:errcheck ok := true for i := 0; i < cnt && ok; i++ { out[i] = bls12381.NewFr().FromBytes(buf[i*expandLen : (i+1)*expandLen]) ok = !out[i].IsZero() } + completed = ok } + return out } diff --git a/pkg/crypto/primitive/bbs12381g2pub/keys_test.go b/pkg/crypto/primitive/bbs12381g2pub/keys_test.go index d9fa0b633..a25c9db3f 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/keys_test.go +++ b/pkg/crypto/primitive/bbs12381g2pub/keys_test.go @@ -68,14 +68,14 @@ func TestPrivateKey_PublicKey(t *testing.T) { t.Run("pre-generated key pair", func(t *testing.T) { // original hex seed 746869732d49532d6a7573742d616e2d546573742d494b4d2d746f2d67656e65726174652d246528724074232d6b6579 privateKeyB58 := "5qNVd4Wsp7LPC7vxrbuVMsAkAGif2dA82wm1Wte1zH4Z" - publicKeyB58 := "25pRBEBDHvG5ryqsEB5tw6eAa3Ds8bx6jMKhEtXnWjCLNg7ikYokwaNtpggZZY3MvWTxBPCidfxFBq2ZiVVTpioCh6GJLs4iESiEydJca9kmeMkEkqK6ePudqoqLHSv4NA7p" + publicKeyB58 := "25pRBEBDHvG5ryqsEB5tw6eAa3Ds8bx6jMKhEtXnWjCLNg7ikYokwaNtpggZZY3MvWTxBPCidfxFBq2ZiVVTpioCh6GJLs4iESiEydJca9kmeMkEkqK6ePudqoqLHSv4NA7p" // nolint: lll privateKey, err := bbs.UnmarshalPrivateKey(base58.Decode(privateKeyB58)) require.NoError(t, err) publicKeyBytes, err := privateKey.PublicKey().Marshal() require.Equal(t, publicKeyB58, base58.Encode(publicKeyBytes)) - + require.NoError(t, err) }) t.Run("generators", func(t *testing.T) { @@ -83,18 +83,27 @@ func TestPrivateKey_PublicKey(t *testing.T) { _, privKey, err := generateKeyPairRandom() require.NoError(t, err) - pkExt, _ := privKey.PublicKey().ToPublicKeyWithGenerators(msgCnt) + pkExt, err := privKey.PublicKey().ToPublicKeyWithGenerators(msgCnt) + require.NoError(t, err) bytes := bls12381.NewG1().ToCompressed(pkExt.Q1) - require.Equal(t, "b60acd4b0dc13b580394d2d8bc6c07d452df8e2a7eff93bc9da965b57e076cae640c2858fb0c2eaf242b1bd11107d635", hex.EncodeToString(bytes)) + require.Equal(t, + "b60acd4b0dc13b580394d2d8bc6c07d452df8e2a7eff93bc9da965b57e076cae640c2858fb0c2eaf242b1bd11107d635", + hex.EncodeToString(bytes)) bytes = bls12381.NewG1().ToCompressed(pkExt.Q2) - require.Equal(t, "ad03f655b4c94f312b051aba45977c924bc5b4b1780c969534c183784c7275b70b876db641579604328c0975eaa0a137", hex.EncodeToString(bytes)) + require.Equal(t, + "ad03f655b4c94f312b051aba45977c924bc5b4b1780c969534c183784c7275b70b876db641579604328c0975eaa0a137", + hex.EncodeToString(bytes)) require.Equal(t, msgCnt, len(pkExt.H)) bytes = bls12381.NewG1().ToCompressed(pkExt.H[0]) - require.Equal(t, "b63ae18d3edd64a2edd381290f0c68bebabaf3d37bc9dbb0bd5ad8daf03bbd2c48260255ba73f3389d2d5ad82303ac25", hex.EncodeToString(bytes)) + require.Equal(t, + "b63ae18d3edd64a2edd381290f0c68bebabaf3d37bc9dbb0bd5ad8daf03bbd2c48260255ba73f3389d2d5ad82303ac25", + hex.EncodeToString(bytes)) bytes = bls12381.NewG1().ToCompressed(pkExt.H[1]) - require.Equal(t, "b0b92b79a3e1fc59f39c6b9f78f00b873121c6a4c1814b94c07848efd172762fefbc48447a16f9ba8ed1b638e2933029", hex.EncodeToString(bytes)) + require.Equal(t, + "b0b92b79a3e1fc59f39c6b9f78f00b873121c6a4c1814b94c07848efd172762fefbc48447a16f9ba8ed1b638e2933029", + hex.EncodeToString(bytes)) }) } diff --git a/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go b/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go index c50b15396..fe73ef6c9 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go +++ b/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go @@ -71,6 +71,9 @@ func NewPoKOfSignature(signature *Signature, messages []*SignatureMessage, revea } for _, ind := range revealedIndexes { + if ind >= len(messages) { + return nil, fmt.Errorf("invalid revealed index: requested index %d is larger than %d messages count", ind, len(messages)) + } revealedMessages[ind] = messages[ind] } @@ -94,13 +97,12 @@ func newVC1Signature(aPrime *bls12381.PointG1, q1 *bls12381.PointG1, secrets1 := make([]*bls12381.Fr, 2) committing1.Commit(aPrime) - secrets1[0] = e - committing1.Commit(q1) - secrets1[1] = r2 - pokVC1 := committing1.Finish() + secrets1[0] = e + secrets1[1] = r2 + return pokVC1, secrets1 } @@ -112,10 +114,9 @@ func newVC2Signature(d *bls12381.PointG1, r3 *bls12381.Fr, pubKey *PublicKeyWith secrets2 := make([]*bls12381.Fr, 0, baseSecretsCount+messagesCount) committing2.Commit(d) - secrets2 = append(secrets2, r3) - committing2.Commit(pubKey.Q1) - secrets2 = append(secrets2, sPrime) + + secrets2 = append(secrets2, r3, sPrime) for i := 0; i < messagesCount; i++ { if _, ok := revealedMessages[i]; ok { @@ -131,40 +132,30 @@ func newVC2Signature(d *bls12381.PointG1, r3 *bls12381.Fr, pubKey *PublicKeyWith secrets2 = append(secrets2, hiddenFRCopy) } - pokVC2 := committing2.Finish() + pokVC2 := committing2.FinishNegFirst() return pokVC2, secrets2 } -// ToBytes converts PoKOfSignature to bytes. -func (pos *PoKOfSignature) ToBytes() []byte { - challengeBytes := g1.ToUncompressed(pos.aPrime) - challengeBytes = append(challengeBytes, g1.ToUncompressed(pos.aBar)...) - challengeBytes = append(challengeBytes, g1.ToUncompressed(pos.d)...) - challengeBytes = append(challengeBytes, g1.ToUncompressed(pos.pokVC1.commitment)...) - challengeBytes = append(challengeBytes, g1.ToUncompressed(pos.pokVC2.commitment)...) - r := len(pos.revealedMessages) - idxs := make([]byte, 8*r) - msgs := make([]byte, 0) - challengeBytes = append(challengeBytes, i2os8(uint64(r))...) - for i, m := range pos.revealedMessages { - idxs = append(idxs, i2os8(uint64(i))...) - msgs = append(msgs, m.FR.ToBytes()...) - } - challengeBytes = append(challengeBytes, idxs...) - challengeBytes = append(challengeBytes, msgs...) - - return challengeBytes +// CalculateChallenge calculates challenge for the (PoKOfSignature, domain, nonce). +func (pos *PoKOfSignature) CalculateChallenge(msgCnt int, domain *bls12381.Fr, nonce []byte) *bls12381.Fr { + return calculateChallenge( + pos.aPrime, pos.aBar, pos.d, + pos.pokVC1.commitment, pos.pokVC2.commitment, + pos.revealedMessages, msgCnt, domain, nonce) } // GenerateProof generates PoKOfSignatureProof proof from PoKOfSignature signature. func (pos *PoKOfSignature) GenerateProof(challengeHash *bls12381.Fr) *PoKOfSignatureProof { + vc1 := pos.pokVC1.GenerateProof(challengeHash, pos.secrets1) + vc2 := pos.pokVC2.GenerateProof(challengeHash, pos.secrets2) + return &PoKOfSignatureProof{ aPrime: pos.aPrime, aBar: pos.aBar, d: pos.d, - proofVC1: pos.pokVC1.GenerateProof(challengeHash, pos.secrets1), - proofVC2: pos.pokVC2.GenerateProof(challengeHash, pos.secrets2), + proofVC1: vc1, + proofVC2: vc2, } } @@ -175,17 +166,6 @@ type ProverCommittedG1 struct { commitment *bls12381.PointG1 } -// ToBytes converts ProverCommittedG1 to bytes. -func (g *ProverCommittedG1) ToBytes() []byte { - bytes := make([]byte, 0) - - for _, base := range g.bases { - bytes = append(bytes, g1.ToUncompressed(base)...) - } - - return append(bytes, g1.ToUncompressed(g.commitment)...) -} - // GenerateProof generates proof ProofG1 for all secrets. func (g *ProverCommittedG1) GenerateProof(challenge *bls12381.Fr, secrets []*bls12381.Fr) *ProofG1 { responses := make([]*bls12381.Fr, len(g.bases)) @@ -237,11 +217,16 @@ func (pc *ProverCommittingG1) Finish() *ProverCommittedG1 { } } -// Modified Finish() for case where first element should be neg -func (pc *ProverCommittingG1) FinishMod() *ProverCommittedG1 { - blindings := make([]*bls12381.Fr, 0) +// FinishNegFirst is modified Finish() for case where first element should be neg while calc +// TODO: this is a hack to align the current impl and a draft update of BBS spec. +// As soon as the spec would be stable enough, this should be removed +// and probably some re-design of helpers and/or structures will be required. +func (pc *ProverCommittingG1) FinishNegFirst() *ProverCommittedG1 { + blindings := make([]*bls12381.Fr, len(pc.blindingFactors)) copy(blindings, pc.blindingFactors) + negFirst := bls12381.NewFr() + negFirst.Neg(blindings[0]) blindings[0] = negFirst commitment := sumOfG1Products(pc.bases, blindings) diff --git a/pkg/crypto/primitive/bbs12381g2pub/signature_message.go b/pkg/crypto/primitive/bbs12381g2pub/signature_message.go index bd25fa896..bdf99cdce 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/signature_message.go +++ b/pkg/crypto/primitive/bbs12381g2pub/signature_message.go @@ -15,11 +15,22 @@ type SignatureMessage struct { FR *bls12381.Fr } -// ParseSignatureMessage parses SignatureMessage from bytes. -func ParseSignatureMessage(message []byte) *SignatureMessage { - elm := frFromOKM(message) +// parseSignatureMessage parses SignatureMessage from bytes. +func parseSignatureMessage(message []byte) *SignatureMessage { + elm := Hash2scalar(message) return &SignatureMessage{ FR: elm, } } + +// ParseSignatureMessages parses SignatureMessages from bytes. +func ParseSignatureMessages(messages [][]byte) []*SignatureMessage { + messagesFr := make([]*SignatureMessage, len(messages)) + + for i, msg := range messages { + messagesFr[i] = parseSignatureMessage(msg) + } + + return messagesFr +} diff --git a/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go b/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go index 33144acba..de9c40026 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go +++ b/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go @@ -25,33 +25,22 @@ type PoKOfSignatureProof struct { proofVC2 *ProofG1 } -// GetBytesForChallenge creates bytes for proof challenge. -func (sp *PoKOfSignatureProof) GetBytesForChallenge(revealedMessages map[int]*SignatureMessage, - pubKey *PublicKeyWithGenerators) []byte { - challengeBytes := g1.ToUncompressed(sp.aPrime) - challengeBytes = append(challengeBytes, g1.ToUncompressed(sp.aBar)...) - challengeBytes = append(challengeBytes, g1.ToUncompressed(sp.d)...) - challengeBytes = append(challengeBytes, g1.ToUncompressed(sp.proofVC1.commitment)...) - challengeBytes = append(challengeBytes, g1.ToUncompressed(sp.proofVC2.commitment)...) - r := len(revealedMessages) - idxs := make([]byte, 8*r) - msgs := make([]byte, 0) - challengeBytes = append(challengeBytes, i2os8(uint64(r))...) - for i, m := range revealedMessages { - idxs = append(idxs, i2os8(uint64(i))...) - msgs = append(msgs, m.FR.ToBytes()...) - } - challengeBytes = append(challengeBytes, idxs...) - challengeBytes = append(challengeBytes, msgs...) - - return challengeBytes +// CalculateChallenge calculates challenge for the (PoKOfSignatureProof, domain, nonce). +func (sp *PoKOfSignatureProof) CalculateChallenge(revealedMessages map[int]*SignatureMessage, + pubKey *PublicKeyWithGenerators, nonce []byte) *bls12381.Fr { + return calculateChallenge( + sp.aPrime, sp.aBar, sp.d, + sp.proofVC1.commitment, sp.proofVC2.commitment, + revealedMessages, pubKey.messagesCount, pubKey.domain, nonce) } // Verify verifies PoKOfSignatureProof. func (sp *PoKOfSignatureProof) Verify(challenge *bls12381.Fr, pubKey *PublicKeyWithGenerators, revealedMessages map[int]*SignatureMessage, messages []*SignatureMessage) error { + aPrimeNeg := g1.New() + aPrimeNeg = g1.Neg(aPrimeNeg, sp.aPrime) - ok := compareTwoPairings(sp.aPrime, pubKey.w, sp.aBar, g2.One()) + ok := compareTwoPairings(aPrimeNeg, pubKey.w, sp.aBar, g2.One()) if !ok { return errors.New("bad signature") } @@ -65,7 +54,7 @@ func (sp *PoKOfSignatureProof) Verify(challenge *bls12381.Fr, pubKey *PublicKeyW } func (sp *PoKOfSignatureProof) verifyVC1Proof(challenge *bls12381.Fr, pubKey *PublicKeyWithGenerators) error { - basesVC1 := []*bls12381.PointG1{sp.aPrime, pubKey.Q1, pubKey.Q2} + basesVC1 := []*bls12381.PointG1{sp.aPrime, pubKey.Q1} aBarD := new(bls12381.PointG1) g1.Sub(aBarD, sp.aBar, sp.d) @@ -81,41 +70,37 @@ func (sp *PoKOfSignatureProof) verifyVC2Proof(challenge *bls12381.Fr, pubKey *Pu revealedMessages map[int]*SignatureMessage, messages []*SignatureMessage) error { revealedMessagesCount := len(revealedMessages) + negD := g1.New() + g1.Neg(negD, sp.d) + + bindingBasis := g1.One() + bindingExp := bls12381.NewFr().One() + basesVC2 := make([]*bls12381.PointG1, 0, 2+pubKey.messagesCount-revealedMessagesCount) - basesVC2 = append(basesVC2, sp.d, pubKey.Q1, pubKey.Q2) + basesVC2 = append(basesVC2, negD, pubKey.Q1) - basesDisclosed := make([]*bls12381.PointG1, 0, 1+revealedMessagesCount) - exponents := make([]*bls12381.Fr, 0, 1+revealedMessagesCount) + disclousedElementsCnt := 1 /* binding */ + 1 /* domain */ + revealedMessagesCount + basesDisclosed := make([]*bls12381.PointG1, 0, disclousedElementsCnt) + exponentsDisclosed := make([]*bls12381.Fr, 0, disclousedElementsCnt) - basesDisclosed = append(basesDisclosed, g1.One()) - exponents = append(exponents, bls12381.NewFr().One()) + basesDisclosed = append(basesDisclosed, bindingBasis, pubKey.Q2) + exponentsDisclosed = append(exponentsDisclosed, bindingExp, pubKey.domain) revealedMessagesInd := 0 for i, hi := range pubKey.H { if _, ok := revealedMessages[i]; ok { basesDisclosed = append(basesDisclosed, hi) - exponents = append(exponents, messages[revealedMessagesInd].FR) + exponentsDisclosed = append(exponentsDisclosed, messages[revealedMessagesInd].FR) revealedMessagesInd++ } else { basesVC2 = append(basesVC2, hi) } } - pr := g1.Zero() - - for i := 0; i < len(basesDisclosed); i++ { - b := basesDisclosed[i] - s := exponents[i] - - g := g1.New() - g1.MulScalar(g, b, frToRepr(s)) - g1.Add(pr, pr, g) - } - - g1.Neg(pr, pr) + t := sumOfG1Products(basesDisclosed, exponentsDisclosed) - err := sp.proofVC2.Verify(basesVC2, pr, challenge) + err := sp.proofVC2.Verify(basesVC2, t, challenge) if err != nil { return errors.New("bad signature") } diff --git a/pkg/crypto/primitive/bbs12381g2pub/utils.go b/pkg/crypto/primitive/bbs12381g2pub/utils.go index 39aae090a..21f678e6c 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/utils.go +++ b/pkg/crypto/primitive/bbs12381g2pub/utils.go @@ -9,6 +9,8 @@ package bbs12381g2pub import ( "encoding/binary" "errors" + + bls12381 "github.com/kilic/bls12-381" ) func uint32ToBytes(value uint32) []byte { @@ -19,6 +21,14 @@ func uint32ToBytes(value uint32) []byte { return bytes } +func uint64ToBytes(value uint64) []byte { + bytes := make([]byte, 8) + + binary.BigEndian.PutUint64(bytes, value) + + return bytes +} + func uint16FromBytes(bytes []byte) uint16 { return binary.BigEndian.Uint16(bytes) } @@ -124,26 +134,36 @@ func reverseBytes(s []byte) []byte { return s } -func i2os2(value uint16) []byte { - bytes := make([]byte, 2) - - binary.BigEndian.PutUint16(bytes, value) - - return bytes -} - -func i2os4(value uint32) []byte { - bytes := make([]byte, 4) - - binary.BigEndian.PutUint32(bytes, value) - - return bytes -} +func calculateChallenge(aPrime, aBar, d, c1, c2 *bls12381.PointG1, + msgsMap map[int]*SignatureMessage, msgCnt int, domain *bls12381.Fr, nonce []byte) *bls12381.Fr { + r := len(msgsMap) + idxSz := 8 + + challengeBytes := g1.ToUncompressed(aPrime) + challengeBytes = append(challengeBytes, g1.ToUncompressed(aBar)...) + challengeBytes = append(challengeBytes, g1.ToUncompressed(d)...) + challengeBytes = append(challengeBytes, g1.ToUncompressed(c1)...) + challengeBytes = append(challengeBytes, g1.ToUncompressed(c2)...) + challengeBytes = append(challengeBytes, uint64ToBytes(uint64(r))...) + + idxs := make([]byte, r*idxSz) + msgs := make([]byte, 0) + + for i := 0; i < msgCnt; i++ { + if m, ok := msgsMap[i]; ok { + idxs = append(idxs, uint64ToBytes(uint64(i))...) + msgs = append(msgs, m.FR.ToBytes()...) + } + } -func i2os8(value uint64) []byte { - bytes := make([]byte, 8) + challengeBytes = append(challengeBytes, idxs...) + challengeBytes = append(challengeBytes, msgs...) + challengeBytes = append(challengeBytes, domain.ToBytes()...) + proofNonce := ParseProofNonce(nonce) + proofNonceBytes := proofNonce.ToBytes() + challengeBytes = append(challengeBytes, proofNonceBytes...) - binary.BigEndian.PutUint64(bytes, value) + challenge := Hash2scalar(challengeBytes) - return bytes + return challenge } From 9a01fe019efe4b5e0695d7f29d9e40fc17a6dc2c Mon Sep 17 00:00:00 2001 From: Sergey Minaev Date: Thu, 20 Oct 2022 17:34:12 +0500 Subject: [PATCH 05/11] [3392] Update BBS tests. Signed-off-by: Sergey Minaev --- .../primitive/bbs12381g2pub/bbs_test.go | 147 ++++++++++-------- .../bbs12381g2pub/proof_of_knowledge.go | 11 +- 2 files changed, 86 insertions(+), 72 deletions(-) diff --git a/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go b/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go index 26101fbfc..4f00b1d30 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go +++ b/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go @@ -8,7 +8,7 @@ package bbs12381g2pub_test import ( "crypto/rand" - "encoding/base64" + "encoding/hex" "testing" "github.com/stretchr/testify/require" @@ -16,17 +16,21 @@ import ( "github.com/hyperledger/aries-framework-go/pkg/crypto/primitive/bbs12381g2pub" ) -//nolint:lll func TestBlsG2Pub_Verify(t *testing.T) { - pkBase64 := "lOpN7uGZWivVIjs0325N/V0dAhoPomrgfXVpg7pZNdRWwFwJDVxoE7TvRyOx/Qr7GMtShNuS2Px/oScD+SMf08t8eAO78QRNErPzwNpfkP4ppcSTShStFDfFbsv9L9yb" - pkBytes, err := base64.RawStdEncoding.DecodeString(pkBase64) + privateKeyBytes := hexStringToBytesTest(t, "47d2ede63ab4c329092b342ab526b1079dbc2595897d4f2ab2de4d841cbe7d56") + + privateKey, err := bbs12381g2pub.UnmarshalPrivateKey(privateKeyBytes) require.NoError(t, err) - sigBase64 := "hPbLkeMZZ6KKzkjWoTVHeMeuLJfYWjmdAU1Vg5fZ/VZnIXxxeXBB+q0/EL8XQmWkOMMwEGA/D2dCb4MDuntKZpvHEHlvaFR6l1A4bYj0t2Jd6bYwGwCwirNbmSeIoEmJeRzJ1cSvsL+jxvLixdDPnw==" - sigBytes, err := base64.StdEncoding.DecodeString(sigBase64) + pkBytes, err := privateKey.PublicKey().Marshal() require.NoError(t, err) - messagesBytes := [][]byte{[]byte("message1"), []byte("message2")} + sigBytes := hexStringToBytesTest(t, + "836370c0f9fee53a4518e3294d2cd9880e9ced5a92fd21f20af898cf76c43a1fa88b3b8a0347313b83cb2f52055c3b56"+ + "24f8ea83101ff3429b07708c790975a43a1893fa848e1ffec1ab97c61196823d"+ + "28c3baa5900943929f3b0fdf36665fa43db9ee82dd855551bb9e7aaa6cc5c764") + + messagesBytes := default10messages(t) bls := bbs12381g2pub.New() @@ -37,7 +41,9 @@ func TestBlsG2Pub_Verify(t *testing.T) { t.Run("invalid signature", func(t *testing.T) { // swap messages order - invalidMessagesBytes := [][]byte{[]byte("message2"), []byte("message1")} + invalidMessagesBytes := make([][]byte, 10) + copy(invalidMessagesBytes, messagesBytes) + invalidMessagesBytes[0] = invalidMessagesBytes[1] err = bls.Verify(invalidMessagesBytes, sigBytes, pkBytes) require.Error(t, err) @@ -128,36 +134,53 @@ func TestBBSG2Pub_Sign(t *testing.T) { require.Nil(t, signatureBytes) } -//nolint:lll -func TestBBSG2Pub_VerifyProof(t *testing.T) { - pkBase64 := "sVEbbh9jDPGSBK/oT/EeXQwFvNuC+47rgq9cxXKrwo6G7k4JOY/vEcfgZw9Vf/TpArbIdIAJCFMDyTd7l2atS5zExAKX0B/9Z3E/mgIZeQJ81iZ/1HUnUCT2Om239KFx" - pkBytes, err := base64.RawStdEncoding.DecodeString(pkBase64) +func TestBBSG2Pub_SignWithPredefinedKeys(t *testing.T) { + privateKeyBytes := hexStringToBytesTest(t, "47d2ede63ab4c329092b342ab526b1079dbc2595897d4f2ab2de4d841cbe7d56") + + // TODO "header": "11223344556677889900aabbccddeeff" + + messagesBytes := default10messages(t) + + bls := bbs12381g2pub.New() + signature, err := bls.Sign(messagesBytes, privateKeyBytes) require.NoError(t, err) - proofBase64 := "AAIBiN4EL9psRsIUlwQah7a5VROD369PPt09Z+jfzamP+/114a5RfWVMju3NCUl2Yv6ahyIdHGdEfxhC985ShlGQrRPLa+crFRiu2pfnAk+L6QMNooVMQhzJc2yYgktHen4QhsKV3IGoRRUs42zqPTP3BdqIPQeLgjDVi1d1LXEnP+WFQGEQmTKWTja4u1MsERdmAAAAdIb6HuFznhE3OByXN0Xp3E4hWQlocCdpExyNlSLh3LxK5duCI/WMM7ETTNS0Ozxe3gAAAAIuALkiwplgKW6YmvrEcllWSkG3H+uHEZzZGL6wq6Ac0SuktQ4n84tZPtMtR9vC1Rsu8f7Kwtbq1Kv4v02ct9cvj7LGcitzg3u/ZO516qLz+iitKeGeJhtFB8ggALcJOEsebPFl12cYwkieBbIHCBt4AAAAAxgEHt3iqKIyIQbTYJvtrMjGjT4zuimiZbtE3VXnqFmGaxVTeR7dh89PbPtsBI8LLMrCvFFpks9D/oTzxnw13RBmMgMlc1bcfQOmE9DZBGB7NCdwOnT7q4TVKhswOITKTQ==" - proofBytes, err := base64.StdEncoding.DecodeString(proofBase64) + expectedSignatureBytes := hexStringToBytesTest(t, + "836370c0f9fee53a4518e3294d2cd9880e9ced5a92fd21f20af898cf76c43a1fa88b3b8a0347313b83cb2f52055c3b56"+ + "24f8ea83101ff3429b07708c790975a43a1893fa848e1ffec1ab97c61196823d"+ + "28c3baa5900943929f3b0fdf36665fa43db9ee82dd855551bb9e7aaa6cc5c764") + // TODO signature defined in the spec + // "9157456791e4f9cae1130372f7cf37709ba661e43df5c23cc1c76be91abff7e2603e2ddaaa71fc42bd6f9d44bd58315b"+ + // "09ee5cc4e7614edde358f2c497b6b05c8b118fae3f71a52af482dceffccb3785"+ + // "1907573c03d2890dffbd1f660cdf89c425d4e0498bbf73dd96ff15ad9a8b581a") + + require.Equal(t, expectedSignatureBytes, signature) +} + +func TestBBSG2Pub_VerifyProof_SeveralDisclosedMessages(t *testing.T) { + privateKeyBytes := hexStringToBytesTest(t, "47d2ede63ab4c329092b342ab526b1079dbc2595897d4f2ab2de4d841cbe7d56") + + privateKey, err := bbs12381g2pub.UnmarshalPrivateKey(privateKeyBytes) require.NoError(t, err) - nonce := []byte("nonce") + pkBytes, err := privateKey.PublicKey().Marshal() + require.NoError(t, err) - messagesBytes := [][]byte{[]byte("message1"), []byte("message2")} - revealedMessagesBytes := messagesBytes[:1] + proofBytes := hexStringToBytesTest(t, "000a000589bb7f2662f787a87e205fd2f0b6b130e26040cf709359e5cb734b545f461c7fdd8cc35ef85ade32efa449d8c6712a7690f205b468dac30eae9e28da3cea5372520fac0f2a80c16aec7e420ed3c04ec5cca8cb32bfa91083fc106129a9035c3088cc8cdbe6ed083962e7e34562928734d9cec9bcb0ad9355116709f844402cbfe8ad0b542199b5b3adf5132cc96d594700000074943803ea10df094657ac0277aa9ae8738bade0898163c22bce7fd9d986ec07ae58920888026df450dfe2fe46f65ef290000000026e3bdf3df40df5885b9962cacacae6c7687f04c2c673a1f23cb73b067461ca9d646c1616afde5cd0911a752e4dc45dd493b7b0faa695688c3cf387edd3d9d48891e949783029b20e4c5a4480f64238a680f5e48dffcffd61dcd08a2e354634ac73cdc7612c2adfabfaef736f7288da1e0000000a5ed77af0675487ebbdaaa73ebc0d2235804928dd603326878aedd9714be745bb187d6188b10a42ea38da50a76d0c3308e8f101c0ea71f5caa99d0ddca929252328904bd2c92bd1ca9fdff5197c8fb66ff3323aae22180ccd672bb92086bc8b57496d36667bf9ed67a63763d75d3e71fcda6ff5e15399dda6432558238090cfea4da5c52986a874d4da93c231b78365ccb0370c3fb8cf10de36726fc283151d8954e8594209733e772226424b619d3f692236b65f244c121d8e11415d7f9e245015341d76585f3e3257304b0b894ac6fa3357c500da7c8aa15dfa3c1b7cca1da0375e63c9f6b062b02fdce1860e216b5fbd86bd5a3c5838a8cb87467b06f07c1360ba28286e40bdf07c954685c6dd2f64b9ae986fd3079834148eea0a44869b8d71421ae35157f0641db09bf7728606e7d7e6f6cf133a3e2db80940638f39be61") //nolint:lll + + // TODO "header": "11223344556677889900aabbccddeeff" + nonce := hexStringToBytesTest(t, "bed231d880675ed101ead304512e043ade9958dd0241ea70b4b3957fba941501") + + messagesBytes := default10messages(t) + revealedMessagesBytes := [][]byte{messagesBytes[0], messagesBytes[2]} bls := bbs12381g2pub.New() - t.Run("valid signature proof", func(t *testing.T) { + t.Run("valid signature", func(t *testing.T) { err = bls.VerifyProof(revealedMessagesBytes, proofBytes, nonce, pkBytes) require.NoError(t, err) }) - t.Run("test payload revealed bigger from messages", func(t *testing.T) { - wrongProofBytes, errDecode := base64.StdEncoding.DecodeString(`AAwP/4nFun/RtaXtUVTppUimMRTcEROs3gbjh9iqjGQAsvD+ne2uzME26gY4zNBcMKpvyLD4I6UGm8ATKLQI4OUiBXHNCQZI4YEM5hWI7AzhFXLEEVDFL0Gzr4S04PvcJsmV74BqST8iI1HUO2TCjdT1LkhgPabP/Zy8IpnbWUtLZO1t76NFwCV8+R1YpOozTNKRQQAAAHSpyGry6Rx3PRuOZUeqk4iGFq67iHSiBybjo6muud7aUyCxd9AW3onTlV2Nxz8AJD0AAAACB3FmuAUcklAj5cdSdw7VY57y7p4VmfPCKaEp1SSJTJRZXiE2xUqDntend+tkq+jjHhLCk56zk5GoZzr280IeuLne4WgpB2kNN7n5dqRpy4+UkS5+kiorLtKiJuWhk+OFTiB8jFlTbm0dH3O3tm5CzQAAAAIhY6I8vQ96tdSoyGy09wEMCdWzB06GElVHeQhWVw8fukq1dUAwWRXmZKT8kxDNAlp2NS7fXpEGXZ9fF7+c1IJp`) - require.NoError(t, errDecode) - err = bls.VerifyProof(revealedMessagesBytes, wrongProofBytes, nonce, pkBytes) - require.Error(t, err) - require.EqualError(t, err, "payload revealed bigger from messages") - }) - t.Run("invalid size of signature proof payload", func(t *testing.T) { err = bls.VerifyProof(revealedMessagesBytes, []byte("?"), nonce, pkBytes) require.Error(t, err) @@ -192,47 +215,15 @@ func TestBBSG2Pub_VerifyProof(t *testing.T) { }) } -//nolint:lll -func TestBBSG2Pub_VerifyProof_SeveralDisclosedMessages(t *testing.T) { - pkBase64 := "l0Wtf3gy5f140G5vCoCJw2420hwk6Xw65/DX3ycv1W7/eMky8DyExw+o1s2bmq3sEIJatkiN8f5D4k0766x0UvfbupFX+vVkeqnlOvT6o2cag2osQdMFbBQqAybOM4Gm" - pkBytes, err := base64.RawStdEncoding.DecodeString(pkBase64) - require.NoError(t, err) - - proofBase64 := "AAQFpAE2VALtmriOzSMk/oqid4uJhPQRUVUuyenL/L4w4ykdyh0jCX64EFqCdLP+n8VrkOKXhHPKPoCOdHBOMv96aM15NFg867/MToMeNN0IFzZkzhs37qk1vWWFKReMF+cRsCAmkHO6An1goNHdY/4XquSV3LwykezraWt8+8bLvVn6ciaXBVxVcYkbIXRsVjqbAAAAdIl/C/W5G1pDbLMrUrBAYdpvzGHG25gktAuUFZb/SkIyy0uhtWJk2v6A+D3zkoEBsgAAAAJY/jfJR9kpGbSY5pfz+qPkqyNOTJbs6OEpfBwYGsyC7hspvBGUOYyvuKlS8SvKAXW7hVawAhYJbvnRwzeiP6P9kbZKtLQZIkRQB+mxRSbMk/0JgE1jApHOlPtgbqI9yIouhK9xT2wVZl79qTAwifonAAAABDTDo5VtXR2gloy+au7ai0wcnnzjMJ6ztQHRI1ApV5VuOQ19TYL7SW+C90p3QSZFQ5gtl90PHaUuEAHIb+7ZgbJvh5sc1DjKfThwPx0Ao0w8+xTbLhNlxvo6VE1cfbiuME+miCAibLgHjksQ8ctl322qnblYJLXiS4lvx/jtGvA3" - proofBytes, err := base64.StdEncoding.DecodeString(proofBase64) - require.NoError(t, err) - - nonce := []byte("nonce") - - messagesBytes := [][]byte{ - []byte("message1"), - []byte("message2"), - []byte("message3"), - []byte("message4"), - } - revealedMessagesBytes := [][]byte{messagesBytes[0], messagesBytes[2]} - - bls := bbs12381g2pub.New() - - t.Run("valid signature", func(t *testing.T) { - err = bls.VerifyProof(revealedMessagesBytes, proofBytes, nonce, pkBytes) - require.NoError(t, err) - }) -} - func TestBBSG2Pub_DeriveProof(t *testing.T) { - pubKey, privKey, err := generateKeyPairRandom() - require.NoError(t, err) + privKeyBytes := hexStringToBytesTest(t, "47d2ede63ab4c329092b342ab526b1079dbc2595897d4f2ab2de4d841cbe7d56") - privKeyBytes, err := privKey.Marshal() + privKey, err := bbs12381g2pub.UnmarshalPrivateKey(privKeyBytes) require.NoError(t, err) - messagesBytes := [][]byte{ - []byte("message1"), - []byte("message2"), - []byte("message3"), - []byte("message4"), - } + pubKey := privKey.PublicKey() + + messagesBytes := default10messages(t) bls := bbs12381g2pub.New() signatureBytes, err := bls.Sign(messagesBytes, privKeyBytes) @@ -243,7 +234,7 @@ func TestBBSG2Pub_DeriveProof(t *testing.T) { require.NoError(t, bls.Verify(messagesBytes, signatureBytes, pubKeyBytes)) - nonce := []byte("nonce") + nonce := hexStringToBytesTest(t, "bed231d880675ed101ead304512e043ade9958dd0241ea70b4b3957fba941501") revealedIndexes := []int{0, 2} proofBytes, err := bls.DeriveProof(messagesBytes, signatureBytes, nonce, pubKeyBytes, revealedIndexes) require.NoError(t, err) @@ -259,7 +250,31 @@ func TestBBSG2Pub_DeriveProof(t *testing.T) { t.Run("DeriveProof with revealedIndexes larger than revealedMessages count", func(t *testing.T) { revealedIndexes = []int{0, 2, 4, 7, 9, 11} _, err = bls.DeriveProof(messagesBytes, signatureBytes, nonce, pubKeyBytes, revealedIndexes) - require.EqualError(t, err, "init proof of knowledge signature: invalid size: 6 revealed indexes is "+ - "larger than 4 messages") + require.EqualError(t, err, "init proof of knowledge signature: "+ + "invalid revealed index: requested index 11 is larger than 10 messages count") }) } + +func default10messages(t *testing.T) [][]byte { + messagesBytes := [][]byte{ + hexStringToBytesTest(t, "9872ad089e452c7b6e283dfac2a80d58e8d0ff71cc4d5e310a1debdda4a45f02"), + hexStringToBytesTest(t, "87a8bd656d49ee07b8110e1d8fd4f1dcef6fb9bc368c492d9bc8c4f98a739ac6"), + hexStringToBytesTest(t, "96012096adda3f13dd4adbe4eea481a4c4b5717932b73b00e31807d3c5894b90"), + hexStringToBytesTest(t, "ac55fb33a75909edac8994829b250779298aa75d69324a365733f16c333fa943"), + hexStringToBytesTest(t, "d183ddc6e2665aa4e2f088af9297b78c0d22b4290273db637ed33ff5cf703151"), + hexStringToBytesTest(t, "515ae153e22aae04ad16f759e07237b43022cb1ced4c176e0999c6a8ba5817cc"), + hexStringToBytesTest(t, "496694774c5604ab1b2544eababcf0f53278ff5040c1e77c811656e8220417a2"), + hexStringToBytesTest(t, "77fe97eb97a1ebe2e81e4e3597a3ee740a66e9ef2412472c23364568523f8b91"), + hexStringToBytesTest(t, "7372e9daa5ed31e6cd5c825eac1b855e84476a1d94932aa348e07b7320912416"), + hexStringToBytesTest(t, "c344136d9ab02da4dd5908bbba913ae6f58c2cc844b802a6f811f5fb075f9b80"), + } + + return messagesBytes +} + +func hexStringToBytesTest(t *testing.T, msg string) []byte { + bytes, err := hex.DecodeString(msg) + require.NoError(t, err) + + return bytes +} diff --git a/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go b/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go index fe73ef6c9..037468501 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go +++ b/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go @@ -35,18 +35,15 @@ func NewPoKOfSignature(signature *Signature, messages []*SignatureMessage, revea return nil, fmt.Errorf("verify input signature: %w", err) } - r1, r2 := createRandSignatureFr(), createRandSignatureFr() - b := computeB(signature.S, messages, pubKey) - r3 := bls12381.NewFr() + r1, r2, r3 := createRandSignatureFr(), createRandSignatureFr(), bls12381.NewFr() r3.Inverse(r1) aPrime := g1.New() g1.MulScalar(aPrime, signature.A, frToRepr(r1)) - aBar := g1.New() - aBarDenom := g1.New() + aBar, aBarDenom := g1.New(), g1.New() g1.MulScalar(aBarDenom, aPrime, frToRepr(signature.E)) g1.MulScalar(aBar, b, frToRepr(r1)) g1.Sub(aBar, aBar, aBarDenom) @@ -72,8 +69,10 @@ func NewPoKOfSignature(signature *Signature, messages []*SignatureMessage, revea for _, ind := range revealedIndexes { if ind >= len(messages) { - return nil, fmt.Errorf("invalid revealed index: requested index %d is larger than %d messages count", ind, len(messages)) + return nil, fmt.Errorf("invalid revealed index: requested index %d is larger than %d messages count", + ind, len(messages)) } + revealedMessages[ind] = messages[ind] } From 78e55c7f73df71da7854a435cf31b4f91488f4d3 Mon Sep 17 00:00:00 2001 From: Sergey Minaev Date: Thu, 20 Oct 2022 18:21:39 +0500 Subject: [PATCH 06/11] [3392] BBS update: cleanup. Signed-off-by: Sergey Minaev --- pkg/crypto/primitive/bbs12381g2pub/bbs.go | 9 ++- pkg/crypto/primitive/bbs12381g2pub/fr.go | 44 ++++++++++++ pkg/crypto/primitive/bbs12381g2pub/keys.go | 70 +++++-------------- .../primitive/bbs12381g2pub/keys_test.go | 50 +++++++------ .../bbs12381g2pub/proof_of_knowledge.go | 8 +-- .../bbs12381g2pub/signature_proof.go | 14 ++-- 6 files changed, 101 insertions(+), 94 deletions(-) diff --git a/pkg/crypto/primitive/bbs12381g2pub/bbs.go b/pkg/crypto/primitive/bbs12381g2pub/bbs.go index a47eb816a..6662bec5c 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/bbs.go +++ b/pkg/crypto/primitive/bbs12381g2pub/bbs.go @@ -48,6 +48,9 @@ const ( // Number of bytes in scalar uncompressed form. frUncompressedSize = 48 + + // Ciphersuite ID for BLS12-381 and SHAKE-256 combination. + csID = "BBS_BLS12381G1_XOF:SHAKE-256_SSWU_RO_" ) // Verify makes BLS BBS12-381 signature verification. @@ -225,11 +228,11 @@ func computeB(s *bls12381.Fr, messages []*SignatureMessage, key *PublicKeyWithGe cb := newCommitmentBuilder(len(messages) + basesOffset) cb.add(bindingBasis, bindingExp) - cb.add(key.Q1, s) - cb.add(key.Q2, key.domain) + cb.add(key.q1, s) + cb.add(key.q2, key.domain) for i := 0; i < len(messages); i++ { - cb.add(key.H[i], messages[i].FR) + cb.add(key.h[i], messages[i].FR) } return cb.build() diff --git a/pkg/crypto/primitive/bbs12381g2pub/fr.go b/pkg/crypto/primitive/bbs12381g2pub/fr.go index 33a6c45ff..adf5b9f2e 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/fr.go +++ b/pkg/crypto/primitive/bbs12381g2pub/fr.go @@ -11,6 +11,16 @@ import ( bls12381 "github.com/kilic/bls12-381" "golang.org/x/crypto/blake2b" + "golang.org/x/crypto/sha3" + + bls12381intern "github.com/hyperledger/aries-framework-go/internal/third_party/kilic/bls12-381" +) + +const ( + logP2 = 384 + k = 128 + h2sDST = csID + "H2S_" + expandLen = (logP2 + k) / 8 ) func parseFr(data []byte) *bls12381.Fr { @@ -56,3 +66,37 @@ func createRandSignatureFr() *bls12381.Fr { return frToRepr(fr) } + +// Hash2scalar convert message represented in bytes to Fr. +func Hash2scalar(message []byte) *bls12381.Fr { + return Hash2scalars(message, 1)[0] +} + +// Hash2scalars convert messages represented in bytes to Fr. +func Hash2scalars(msg []byte, cnt int) []*bls12381.Fr { + bufLen := cnt * expandLen + msgLen := len(msg) + roundSz := 1 + msgLenSz := 4 + + msgExt := make([]byte, msgLen+roundSz+msgLenSz) + copy(msgExt, msg) + copy(msgExt[msgLen+1:], uint32ToBytes(uint32(msgLen))) + + out := make([]*bls12381.Fr, cnt) + + for round, completed := byte(0), false; !completed; { + msgExt[msgLen] = round + buf, _ := bls12381intern.ExpandMsgXOF(sha3.NewShake256(), msgExt, []byte(h2sDST), bufLen) //nolint:errcheck + + ok := true + for i := 0; i < cnt && ok; i++ { + out[i] = bls12381.NewFr().FromBytes(buf[i*expandLen : (i+1)*expandLen]) + ok = !out[i].IsZero() + } + + completed = ok + } + + return out +} diff --git a/pkg/crypto/primitive/bbs12381g2pub/keys.go b/pkg/crypto/primitive/bbs12381g2pub/keys.go index 79c8ea8a0..91a1c2437 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/keys.go +++ b/pkg/crypto/primitive/bbs12381g2pub/keys.go @@ -21,18 +21,12 @@ import ( ) const ( - seedSize = frCompressedSize - generateKeySalt = "BBS-SIG-KEYGEN-SALT-" - csID = "BBS_BLS12381G1_XOF:SHAKE-256_SSWU_RO_" - seedDST = csID + "SIG_GENERATOR_SEED_" - generatorDST = csID + "SIG_GENERATOR_DST_" - generatorSeed = csID + "MESSAGE_GENERATOR_SEED" - h2sDST = csID + "H2S_" - logP2 = 384 - logR2 = 251 - k = 128 - expandLen = (logP2 + k) / 8 - seedLen = ((logR2 + k) + 7) / 8 //nolint:gomnd + seedSize = frCompressedSize + seedDST = csID + "SIG_GENERATOR_SEED_" + generatorDST = csID + "SIG_GENERATOR_DST_" + generatorSeed = csID + "MESSAGE_GENERATOR_SEED" + logR2 = 251 + seedLen = ((logR2 + k) + 7) / 8 //nolint:gomnd ) // PublicKey defines BLS Public Key. @@ -48,9 +42,9 @@ type PrivateKey struct { // PublicKeyWithGenerators extends PublicKey with a blinding generator h0, a commitment to the secret key w, // and a generator for each message h. type PublicKeyWithGenerators struct { - Q1 *bls12381.PointG1 - Q2 *bls12381.PointG1 - H []*bls12381.PointG1 + q1 *bls12381.PointG1 + q2 *bls12381.PointG1 + h []*bls12381.PointG1 w *bls12381.PointG2 @@ -64,7 +58,7 @@ func (pk *PublicKey) ToPublicKeyWithGenerators(messagesCount int) (*PublicKeyWit specGenCnt := 2 genCnt := messagesCount + specGenCnt - generators, err := createGenerators(genCnt) + generators, err := CreateGenerators(genCnt) if err != nil { return nil, err } @@ -83,9 +77,9 @@ func (pk *PublicKey) ToPublicKeyWithGenerators(messagesCount int) (*PublicKeyWit domain := Hash2scalar(domainBuilder.build()) return &PublicKeyWithGenerators{ - Q1: generators[0], - Q2: generators[1], - H: generators[2:], + q1: generators[0], + q2: generators[1], + h: generators[2:], w: pk.PointG2, messagesCount: messagesCount, domain: domain, @@ -103,7 +97,8 @@ func hashToG1(data, dst []byte) (*bls12381.PointG1, error) { return g1.FromBytes(g.ToBytes(p)) } -func createGenerators(cnt int) ([]*bls12381.PointG1, error) { +// CreateGenerators create `cnt` determenistic generators. +func CreateGenerators(cnt int) ([]*bls12381.PointG1, error) { generators := make([]*bls12381.PointG1, cnt) v, err := bls12381intern.ExpandMsgXOF(sha3.NewShake256(), []byte(generatorSeed), []byte(seedDST), seedLen) @@ -202,6 +197,7 @@ func GenerateKeyPair(h func() hash.Hash, seed []byte) (*PublicKey, *PrivateKey, } func generateOKM(ikm []byte, h func() hash.Hash) ([]byte, error) { + generateKeySalt := "BBS-SIG-KEYGEN-SALT-" salt := []byte(generateKeySalt) info := make([]byte, 2) @@ -232,37 +228,3 @@ func newHKDF(h func() hash.Hash, ikm, salt, info []byte, length int) ([]byte, er return result, nil } - -// Hash2scalar convert message represented in bytes to Fr. -func Hash2scalar(message []byte) *bls12381.Fr { - return Hash2scalars(message, 1)[0] -} - -// Hash2scalars convert messages represented in bytes to Fr. -func Hash2scalars(msg []byte, cnt int) []*bls12381.Fr { - bufLen := cnt * expandLen - msgLen := len(msg) - roundSz := 1 - msgLenSz := 4 - - msgExt := make([]byte, msgLen+roundSz+msgLenSz) - copy(msgExt, msg) - copy(msgExt[msgLen+1:], uint32ToBytes(uint32(msgLen))) - - out := make([]*bls12381.Fr, cnt) - - for round, completed := byte(0), false; !completed; { - msgExt[msgLen] = round - buf, _ := bls12381intern.ExpandMsgXOF(sha3.NewShake256(), msgExt, []byte(h2sDST), bufLen) //nolint:errcheck - - ok := true - for i := 0; i < cnt && ok; i++ { - out[i] = bls12381.NewFr().FromBytes(buf[i*expandLen : (i+1)*expandLen]) - ok = !out[i].IsZero() - } - - completed = ok - } - - return out -} diff --git a/pkg/crypto/primitive/bbs12381g2pub/keys_test.go b/pkg/crypto/primitive/bbs12381g2pub/keys_test.go index a25c9db3f..0d6264f01 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/keys_test.go +++ b/pkg/crypto/primitive/bbs12381g2pub/keys_test.go @@ -77,34 +77,32 @@ func TestPrivateKey_PublicKey(t *testing.T) { require.Equal(t, publicKeyB58, base58.Encode(publicKeyBytes)) require.NoError(t, err) }) +} - t.Run("generators", func(t *testing.T) { - msgCnt := 2 - _, privKey, err := generateKeyPairRandom() - require.NoError(t, err) - - pkExt, err := privKey.PublicKey().ToPublicKeyWithGenerators(msgCnt) - require.NoError(t, err) +func TestGenerators(t *testing.T) { + msgCnt := 2 + generators, err := bbs.CreateGenerators(msgCnt + 2) + require.NoError(t, err) - bytes := bls12381.NewG1().ToCompressed(pkExt.Q1) - require.Equal(t, - "b60acd4b0dc13b580394d2d8bc6c07d452df8e2a7eff93bc9da965b57e076cae640c2858fb0c2eaf242b1bd11107d635", - hex.EncodeToString(bytes)) - bytes = bls12381.NewG1().ToCompressed(pkExt.Q2) - require.Equal(t, - "ad03f655b4c94f312b051aba45977c924bc5b4b1780c969534c183784c7275b70b876db641579604328c0975eaa0a137", - hex.EncodeToString(bytes)) - - require.Equal(t, msgCnt, len(pkExt.H)) - bytes = bls12381.NewG1().ToCompressed(pkExt.H[0]) - require.Equal(t, - "b63ae18d3edd64a2edd381290f0c68bebabaf3d37bc9dbb0bd5ad8daf03bbd2c48260255ba73f3389d2d5ad82303ac25", - hex.EncodeToString(bytes)) - bytes = bls12381.NewG1().ToCompressed(pkExt.H[1]) - require.Equal(t, - "b0b92b79a3e1fc59f39c6b9f78f00b873121c6a4c1814b94c07848efd172762fefbc48447a16f9ba8ed1b638e2933029", - hex.EncodeToString(bytes)) - }) + bytes := bls12381.NewG1().ToCompressed(generators[0]) + require.Equal(t, + "b60acd4b0dc13b580394d2d8bc6c07d452df8e2a7eff93bc9da965b57e076cae640c2858fb0c2eaf242b1bd11107d635", + hex.EncodeToString(bytes)) + + bytes = bls12381.NewG1().ToCompressed(generators[1]) + require.Equal(t, + "ad03f655b4c94f312b051aba45977c924bc5b4b1780c969534c183784c7275b70b876db641579604328c0975eaa0a137", + hex.EncodeToString(bytes)) + + bytes = bls12381.NewG1().ToCompressed(generators[2]) + require.Equal(t, + "b63ae18d3edd64a2edd381290f0c68bebabaf3d37bc9dbb0bd5ad8daf03bbd2c48260255ba73f3389d2d5ad82303ac25", + hex.EncodeToString(bytes)) + + bytes = bls12381.NewG1().ToCompressed(generators[3]) + require.Equal(t, + "b0b92b79a3e1fc59f39c6b9f78f00b873121c6a4c1814b94c07848efd172762fefbc48447a16f9ba8ed1b638e2933029", + hex.EncodeToString(bytes)) } func TestPublicKey_Marshal(t *testing.T) { diff --git a/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go b/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go index 037468501..b164ed520 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go +++ b/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go @@ -51,14 +51,14 @@ func NewPoKOfSignature(signature *Signature, messages []*SignatureMessage, revea commitmentBasesCount := 2 cbD := newCommitmentBuilder(commitmentBasesCount) cbD.add(b, r1) - cbD.add(pubKey.Q1, r2) + cbD.add(pubKey.q1, r2) d := cbD.build() sPrime := bls12381.NewFr() sPrime.Mul(r2, r3) sPrime.Add(sPrime, signature.S) - pokVC1, secrets1 := newVC1Signature(aPrime, pubKey.Q1, signature.E, r2) + pokVC1, secrets1 := newVC1Signature(aPrime, pubKey.q1, signature.E, r2) revealedMessages := make(map[int]*SignatureMessage, len(revealedIndexes)) @@ -113,7 +113,7 @@ func newVC2Signature(d *bls12381.PointG1, r3 *bls12381.Fr, pubKey *PublicKeyWith secrets2 := make([]*bls12381.Fr, 0, baseSecretsCount+messagesCount) committing2.Commit(d) - committing2.Commit(pubKey.Q1) + committing2.Commit(pubKey.q1) secrets2 = append(secrets2, r3, sPrime) @@ -122,7 +122,7 @@ func newVC2Signature(d *bls12381.PointG1, r3 *bls12381.Fr, pubKey *PublicKeyWith continue } - committing2.Commit(pubKey.H[i]) + committing2.Commit(pubKey.h[i]) sourceFR := messages[i].FR hiddenFRCopy := bls12381.NewFr() diff --git a/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go b/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go index de9c40026..60c06be88 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go +++ b/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go @@ -37,10 +37,10 @@ func (sp *PoKOfSignatureProof) CalculateChallenge(revealedMessages map[int]*Sign // Verify verifies PoKOfSignatureProof. func (sp *PoKOfSignatureProof) Verify(challenge *bls12381.Fr, pubKey *PublicKeyWithGenerators, revealedMessages map[int]*SignatureMessage, messages []*SignatureMessage) error { - aPrimeNeg := g1.New() - aPrimeNeg = g1.Neg(aPrimeNeg, sp.aPrime) + aBar := new(bls12381.PointG1) + g1.Neg(aBar, sp.aBar) - ok := compareTwoPairings(aPrimeNeg, pubKey.w, sp.aBar, g2.One()) + ok := compareTwoPairings(sp.aPrime, pubKey.w, aBar, g2.One()) if !ok { return errors.New("bad signature") } @@ -54,7 +54,7 @@ func (sp *PoKOfSignatureProof) Verify(challenge *bls12381.Fr, pubKey *PublicKeyW } func (sp *PoKOfSignatureProof) verifyVC1Proof(challenge *bls12381.Fr, pubKey *PublicKeyWithGenerators) error { - basesVC1 := []*bls12381.PointG1{sp.aPrime, pubKey.Q1} + basesVC1 := []*bls12381.PointG1{sp.aPrime, pubKey.q1} aBarD := new(bls12381.PointG1) g1.Sub(aBarD, sp.aBar, sp.d) @@ -77,18 +77,18 @@ func (sp *PoKOfSignatureProof) verifyVC2Proof(challenge *bls12381.Fr, pubKey *Pu bindingExp := bls12381.NewFr().One() basesVC2 := make([]*bls12381.PointG1, 0, 2+pubKey.messagesCount-revealedMessagesCount) - basesVC2 = append(basesVC2, negD, pubKey.Q1) + basesVC2 = append(basesVC2, negD, pubKey.q1) disclousedElementsCnt := 1 /* binding */ + 1 /* domain */ + revealedMessagesCount basesDisclosed := make([]*bls12381.PointG1, 0, disclousedElementsCnt) exponentsDisclosed := make([]*bls12381.Fr, 0, disclousedElementsCnt) - basesDisclosed = append(basesDisclosed, bindingBasis, pubKey.Q2) + basesDisclosed = append(basesDisclosed, bindingBasis, pubKey.q2) exponentsDisclosed = append(exponentsDisclosed, bindingExp, pubKey.domain) revealedMessagesInd := 0 - for i, hi := range pubKey.H { + for i, hi := range pubKey.h { if _, ok := revealedMessages[i]; ok { basesDisclosed = append(basesDisclosed, hi) exponentsDisclosed = append(exponentsDisclosed, messages[revealedMessagesInd].FR) From 0f0246700dde59c76e038b51c93b282385aadb0f Mon Sep 17 00:00:00 2001 From: Sergey Minaev Date: Thu, 20 Oct 2022 19:14:52 +0500 Subject: [PATCH 07/11] [3392] BBS update: optimize D definition in proof gen. Signed-off-by: Sergey Minaev --- .../primitive/bbs12381g2pub/bbs_test.go | 4 ++-- .../bbs12381g2pub/proof_of_knowledge.go | 24 ++----------------- .../bbs12381g2pub/signature_proof.go | 7 ++---- 3 files changed, 6 insertions(+), 29 deletions(-) diff --git a/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go b/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go index 4f00b1d30..b28b3c0e2 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go +++ b/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go @@ -166,7 +166,7 @@ func TestBBSG2Pub_VerifyProof_SeveralDisclosedMessages(t *testing.T) { pkBytes, err := privateKey.PublicKey().Marshal() require.NoError(t, err) - proofBytes := hexStringToBytesTest(t, "000a000589bb7f2662f787a87e205fd2f0b6b130e26040cf709359e5cb734b545f461c7fdd8cc35ef85ade32efa449d8c6712a7690f205b468dac30eae9e28da3cea5372520fac0f2a80c16aec7e420ed3c04ec5cca8cb32bfa91083fc106129a9035c3088cc8cdbe6ed083962e7e34562928734d9cec9bcb0ad9355116709f844402cbfe8ad0b542199b5b3adf5132cc96d594700000074943803ea10df094657ac0277aa9ae8738bade0898163c22bce7fd9d986ec07ae58920888026df450dfe2fe46f65ef290000000026e3bdf3df40df5885b9962cacacae6c7687f04c2c673a1f23cb73b067461ca9d646c1616afde5cd0911a752e4dc45dd493b7b0faa695688c3cf387edd3d9d48891e949783029b20e4c5a4480f64238a680f5e48dffcffd61dcd08a2e354634ac73cdc7612c2adfabfaef736f7288da1e0000000a5ed77af0675487ebbdaaa73ebc0d2235804928dd603326878aedd9714be745bb187d6188b10a42ea38da50a76d0c3308e8f101c0ea71f5caa99d0ddca929252328904bd2c92bd1ca9fdff5197c8fb66ff3323aae22180ccd672bb92086bc8b57496d36667bf9ed67a63763d75d3e71fcda6ff5e15399dda6432558238090cfea4da5c52986a874d4da93c231b78365ccb0370c3fb8cf10de36726fc283151d8954e8594209733e772226424b619d3f692236b65f244c121d8e11415d7f9e245015341d76585f3e3257304b0b894ac6fa3357c500da7c8aa15dfa3c1b7cca1da0375e63c9f6b062b02fdce1860e216b5fbd86bd5a3c5838a8cb87467b06f07c1360ba28286e40bdf07c954685c6dd2f64b9ae986fd3079834148eea0a44869b8d71421ae35157f0641db09bf7728606e7d7e6f6cf133a3e2db80940638f39be61") //nolint:lll + proofBytes := hexStringToBytesTest(t, "000a0005820930990a3481f389a845ee9f81d0d32988308206fb855b8cdbc325e03b2e2d01fdd774ea83542dec75e9474b8dc4678b983f06aa58d00e88abd7bed4378eb6a909ae79f4f2ddb798a20e6467b11e1ba516fc388acb6b88462dc8311807a56b87a76929a331e2fc996d750657d2a1bfcb3df60e53775d5656d1ee62e526eb7cb6386aecd7a87d3d546f1843094ee0db00000074a9b7e161a2b32bcc48ae6ee263967cfc60980b7f18e88d2216ccebb52f2656b02de12bc0045f667b6ea50f3a58f2b895000000023392d8b8958f20d88345f666538794bcf688d3ddf9bcb53a3e7ff2b592bc2a8810fa643a1e262db5747f754687312aada9c62f86472aeab858aff948462d80b0b5a8878c9245ed2873b68f70a60a9c7d8fea9518b2a975a5cc4179a1619cdebf75c549e0a00cf1c4e38d415f46b01c250000000a23d535e387835f8550a588159608729ab8b407684eb6791bf80d0816fe14e0e62fd86bc7fd472656b18e59a4fa6db45d4e92d99753f8bdaefee58be8d8ad6e03494a77ed190b1bb31924a7e9aa1033203caa8e04df000ebd2c5cf64eeeb1a10e698e1acb9a451f7479a48d84fb7baa8338bae18aa91613ebbf9482c0346787e4521962006a1cdd032fafedcb32ff7aa697f694a903033adbedcdee0baec8953f644b3b8780623501cc7ba52ace8dc8d967be4c0e78b7d767f0b1bb9ffa8b4be16264ac5ad8d82c3500cc3bc4471ba981e7bbcab089bbe63d19a72fd28168f3d9595729254b9367435a594d4d6b750f2306f2d8dc9a8264fb8c12d8bd8eba0acb4429de451f1b53278fa312e5145783d80eaf64db2e302d935e3052fa38844259445f710a875885f184f9305f878b045384e12dda0f28cadec8912b1daec9a121") //nolint:lll // TODO "header": "11223344556677889900aabbccddeeff" nonce := hexStringToBytesTest(t, "bed231d880675ed101ead304512e043ade9958dd0241ea70b4b3957fba941501") @@ -201,7 +201,7 @@ func TestBBSG2Pub_VerifyProof_SeveralDisclosedMessages(t *testing.T) { proofBytesCopy := make([]byte, len(proofBytes)) copy(proofBytesCopy, proofBytes) - proofBytesCopy[21] = 255 - proofBytesCopy[21] + proofBytesCopy[22] = 255 - proofBytesCopy[22] err = bls.VerifyProof(revealedMessagesBytes, proofBytesCopy, nonce, pkBytes) require.Error(t, err) diff --git a/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go b/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go index b164ed520..42afe5ac2 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go +++ b/pkg/crypto/primitive/bbs12381g2pub/proof_of_knowledge.go @@ -53,6 +53,7 @@ func NewPoKOfSignature(signature *Signature, messages []*SignatureMessage, revea cbD.add(b, r1) cbD.add(pubKey.q1, r2) d := cbD.build() + g1.Neg(d, d) sPrime := bls12381.NewFr() sPrime.Mul(r2, r3) @@ -131,7 +132,7 @@ func newVC2Signature(d *bls12381.PointG1, r3 *bls12381.Fr, pubKey *PublicKeyWith secrets2 = append(secrets2, hiddenFRCopy) } - pokVC2 := committing2.FinishNegFirst() + pokVC2 := committing2.Finish() return pokVC2, secrets2 } @@ -215,24 +216,3 @@ func (pc *ProverCommittingG1) Finish() *ProverCommittedG1 { commitment: commitment, } } - -// FinishNegFirst is modified Finish() for case where first element should be neg while calc -// TODO: this is a hack to align the current impl and a draft update of BBS spec. -// As soon as the spec would be stable enough, this should be removed -// and probably some re-design of helpers and/or structures will be required. -func (pc *ProverCommittingG1) FinishNegFirst() *ProverCommittedG1 { - blindings := make([]*bls12381.Fr, len(pc.blindingFactors)) - copy(blindings, pc.blindingFactors) - - negFirst := bls12381.NewFr() - - negFirst.Neg(blindings[0]) - blindings[0] = negFirst - commitment := sumOfG1Products(pc.bases, blindings) - - return &ProverCommittedG1{ - bases: pc.bases, - blindingFactors: pc.blindingFactors, - commitment: commitment, - } -} diff --git a/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go b/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go index 60c06be88..221f9f266 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go +++ b/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go @@ -56,7 +56,7 @@ func (sp *PoKOfSignatureProof) Verify(challenge *bls12381.Fr, pubKey *PublicKeyW func (sp *PoKOfSignatureProof) verifyVC1Proof(challenge *bls12381.Fr, pubKey *PublicKeyWithGenerators) error { basesVC1 := []*bls12381.PointG1{sp.aPrime, pubKey.q1} aBarD := new(bls12381.PointG1) - g1.Sub(aBarD, sp.aBar, sp.d) + g1.Add(aBarD, sp.aBar, sp.d) err := sp.proofVC1.Verify(basesVC1, aBarD, challenge) if err != nil { @@ -70,14 +70,11 @@ func (sp *PoKOfSignatureProof) verifyVC2Proof(challenge *bls12381.Fr, pubKey *Pu revealedMessages map[int]*SignatureMessage, messages []*SignatureMessage) error { revealedMessagesCount := len(revealedMessages) - negD := g1.New() - g1.Neg(negD, sp.d) - bindingBasis := g1.One() bindingExp := bls12381.NewFr().One() basesVC2 := make([]*bls12381.PointG1, 0, 2+pubKey.messagesCount-revealedMessagesCount) - basesVC2 = append(basesVC2, negD, pubKey.q1) + basesVC2 = append(basesVC2, sp.d, pubKey.q1) disclousedElementsCnt := 1 /* binding */ + 1 /* domain */ + revealedMessagesCount basesDisclosed := make([]*bls12381.PointG1, 0, disclousedElementsCnt) From 358fcf536dd44c76dbff9431fadb8f516c4075a5 Mon Sep 17 00:00:00 2001 From: Sergey Minaev Date: Fri, 21 Oct 2022 14:16:55 +0500 Subject: [PATCH 08/11] [3392] BBS update: fix encoding. Signed-off-by: Sergey Minaev --- pkg/crypto/primitive/bbs12381g2pub/bbs.go | 12 ++++++++---- pkg/crypto/primitive/bbs12381g2pub/bbs_test.go | 4 ++-- pkg/crypto/primitive/bbs12381g2pub/keys.go | 2 +- .../primitive/bbs12381g2pub/signature_message.go | 5 ++++- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/pkg/crypto/primitive/bbs12381g2pub/bbs.go b/pkg/crypto/primitive/bbs12381g2pub/bbs.go index 6662bec5c..438bc0fa0 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/bbs.go +++ b/pkg/crypto/primitive/bbs12381g2pub/bbs.go @@ -303,7 +303,7 @@ func (pn *ProofNonce) ToBytes() []byte { } type encodeForHashBuilder struct { - bytes []byte // TODO check encoding functions per type below + bytes []byte } func newEcnodeForHashBuilder() *encodeForHashBuilder { @@ -317,11 +317,11 @@ func (db *encodeForHashBuilder) addInt(value int) { } func (db *encodeForHashBuilder) addPointG1(value *bls12381.PointG1) { - db.bytes = append(db.bytes, g1.ToBytes(value)...) + db.bytes = append(db.bytes, g1.ToCompressed(value)...) } func (db *encodeForHashBuilder) addPointG2(value *bls12381.PointG2) { - db.bytes = append(db.bytes, g2.ToBytes(value)...) + db.bytes = append(db.bytes, g2.ToCompressed(value)...) } func (db *encodeForHashBuilder) addScalar(value *bls12381.Fr) { @@ -329,10 +329,14 @@ func (db *encodeForHashBuilder) addScalar(value *bls12381.Fr) { } func (db *encodeForHashBuilder) addBytes(value []byte) { - db.bytes = append(db.bytes, uint64ToBytes(uint64(len(value)))...) + db.addInt(len(value)) db.bytes = append(db.bytes, value...) } +func (db *encodeForHashBuilder) addCsID() { + db.bytes = append(db.bytes, []byte(csID)...) +} + func (db *encodeForHashBuilder) build() []byte { return db.bytes } diff --git a/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go b/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go index b28b3c0e2..1efefdd8b 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go +++ b/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go @@ -166,7 +166,7 @@ func TestBBSG2Pub_VerifyProof_SeveralDisclosedMessages(t *testing.T) { pkBytes, err := privateKey.PublicKey().Marshal() require.NoError(t, err) - proofBytes := hexStringToBytesTest(t, "000a0005820930990a3481f389a845ee9f81d0d32988308206fb855b8cdbc325e03b2e2d01fdd774ea83542dec75e9474b8dc4678b983f06aa58d00e88abd7bed4378eb6a909ae79f4f2ddb798a20e6467b11e1ba516fc388acb6b88462dc8311807a56b87a76929a331e2fc996d750657d2a1bfcb3df60e53775d5656d1ee62e526eb7cb6386aecd7a87d3d546f1843094ee0db00000074a9b7e161a2b32bcc48ae6ee263967cfc60980b7f18e88d2216ccebb52f2656b02de12bc0045f667b6ea50f3a58f2b895000000023392d8b8958f20d88345f666538794bcf688d3ddf9bcb53a3e7ff2b592bc2a8810fa643a1e262db5747f754687312aada9c62f86472aeab858aff948462d80b0b5a8878c9245ed2873b68f70a60a9c7d8fea9518b2a975a5cc4179a1619cdebf75c549e0a00cf1c4e38d415f46b01c250000000a23d535e387835f8550a588159608729ab8b407684eb6791bf80d0816fe14e0e62fd86bc7fd472656b18e59a4fa6db45d4e92d99753f8bdaefee58be8d8ad6e03494a77ed190b1bb31924a7e9aa1033203caa8e04df000ebd2c5cf64eeeb1a10e698e1acb9a451f7479a48d84fb7baa8338bae18aa91613ebbf9482c0346787e4521962006a1cdd032fafedcb32ff7aa697f694a903033adbedcdee0baec8953f644b3b8780623501cc7ba52ace8dc8d967be4c0e78b7d767f0b1bb9ffa8b4be16264ac5ad8d82c3500cc3bc4471ba981e7bbcab089bbe63d19a72fd28168f3d9595729254b9367435a594d4d6b750f2306f2d8dc9a8264fb8c12d8bd8eba0acb4429de451f1b53278fa312e5145783d80eaf64db2e302d935e3052fa38844259445f710a875885f184f9305f878b045384e12dda0f28cadec8912b1daec9a121") //nolint:lll + proofBytes := hexStringToBytesTest(t, "000a0005b6f1890b66d4ffaaceda451c4986e36553b4db2622057e8a96b2f29e9274bb8f0249f305088269e39772ec845c267b6c84d60886cec2615e3f0b18a58b4ee97404fcaecff3889b1361df37baaf75bb4c11cb427dcbb91aac11ef32f2d4568540b1e527b52626a4f081f43182f2fcdb3f0197eb6b22d3050be87ece2c719e79b948f00be75d10b851641c6de2b84a49040000007480ce09f9513044ce742c18eb796a6cda777b836931675c7a6b76910c15debf9aa991165bc54a50d1899c00742ecd75dc000000026ae46e197c2fd0f0d7233b7eb8235b85bbbb10664c6b4c69bc645bd4e211df754f14ae46e8358107caab0e91c7a39c7b8d3bb57d6f932a2bc786877fa271bc39a8c3a8823f9246239ed8fe58da4de9bb47d4e535e27e11a764c2ae5d2d9bf5bf38db5d9e71d61d3bbc40896afc79f64f0000000a19de08e7f3ef1dca5b05363a0cf765c5c455a89fcf61513c100d9219d87f60db11ef7535cdc6f6fd6820eb8cfd8b4f89fa80321ec0121daded6257496c7ed24b4b0894a65c2abcdbfec475a10167c58f3801d3dd2563d788b6a9310ba908849135b34c5fa902e08c4f26bcd3fdd197146ee4f5d89b6bc0bd54046b68d07fcf5e42941fb950d223a508639add65e90e52380524c5cc5fef3fdca7a0f12e03f1c7559ff3467e9650230ff491699edb25daafa162c3c1dbd467d94cb2c0d63ec3305a7c022dce4952135fa1d7945af17ec131563a9d1925297945df74b46e19175f234885eea5e7b1b3b0f11aabb7f587271aeae106a6e9a4ea6662d82d5530f05d04bbe0001b8858cca3160df6dfdbcdbf4bf0dd7897f0394615026d81c4b955c13c9a99852c667c08d40de2522b138ae66de5055f9dc79df43a2a2c6522f459a1") //nolint:lll // TODO "header": "11223344556677889900aabbccddeeff" nonce := hexStringToBytesTest(t, "bed231d880675ed101ead304512e043ade9958dd0241ea70b4b3957fba941501") @@ -201,7 +201,7 @@ func TestBBSG2Pub_VerifyProof_SeveralDisclosedMessages(t *testing.T) { proofBytesCopy := make([]byte, len(proofBytes)) copy(proofBytesCopy, proofBytes) - proofBytesCopy[22] = 255 - proofBytesCopy[22] + proofBytesCopy[21] = 255 - proofBytesCopy[21] err = bls.VerifyProof(revealedMessagesBytes, proofBytesCopy, nonce, pkBytes) require.Error(t, err) diff --git a/pkg/crypto/primitive/bbs12381g2pub/keys.go b/pkg/crypto/primitive/bbs12381g2pub/keys.go index 91a1c2437..28d3e69e2 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/keys.go +++ b/pkg/crypto/primitive/bbs12381g2pub/keys.go @@ -71,7 +71,7 @@ func (pk *PublicKey) ToPublicKeyWithGenerators(messagesCount int) (*PublicKeyWit domainBuilder.addPointG1(gen) } - domainBuilder.addBytes([]byte(csID)) + domainBuilder.addCsID() // TODO use header. Probably should be a parameter to this func domain := Hash2scalar(domainBuilder.build()) diff --git a/pkg/crypto/primitive/bbs12381g2pub/signature_message.go b/pkg/crypto/primitive/bbs12381g2pub/signature_message.go index bdf99cdce..9f156d3f8 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/signature_message.go +++ b/pkg/crypto/primitive/bbs12381g2pub/signature_message.go @@ -17,7 +17,10 @@ type SignatureMessage struct { // parseSignatureMessage parses SignatureMessage from bytes. func parseSignatureMessage(message []byte) *SignatureMessage { - elm := Hash2scalar(message) + encodedForHashMsg := newEcnodeForHashBuilder() + encodedForHashMsg.addBytes(message) + + elm := Hash2scalar(encodedForHashMsg.build()) return &SignatureMessage{ FR: elm, From 1201ae8366012db93f9c661623a4abe2739225b3 Mon Sep 17 00:00:00 2001 From: Sergey Minaev Date: Fri, 21 Oct 2022 15:10:22 +0500 Subject: [PATCH 09/11] [3392] BBS update: support header in creds. Signed-off-by: Sergey Minaev --- .../command/verifiable/command_test.go | 2 +- .../rest/verifiable/operation_test.go | 2 +- pkg/crypto/primitive/bbs12381g2pub/bbs.go | 20 +++--- .../primitive/bbs12381g2pub/bbs_test.go | 70 +++++++++---------- pkg/crypto/primitive/bbs12381g2pub/keys.go | 4 +- .../primitive/bbs12381g2pub/keys_test.go | 5 +- .../primitive/bbs/subtle/bls12381g2_signer.go | 2 +- .../bbs/subtle/bls12381g2_verifier.go | 6 +- pkg/doc/presexch/definition_test.go | 2 +- .../suite/bbsblssignatureproof2020/signer.go | 2 +- .../signature/verifier/public_key_verifier.go | 4 +- pkg/doc/verifiable/credential_ldp_test.go | 2 +- pkg/doc/verifiable/example_support_test.go | 2 +- test/bbs/src/support_signer.go | 2 +- 14 files changed, 60 insertions(+), 65 deletions(-) diff --git a/pkg/controller/command/verifiable/command_test.go b/pkg/controller/command/verifiable/command_test.go index f26e83201..1571e5910 100644 --- a/pkg/controller/command/verifiable/command_test.go +++ b/pkg/controller/command/verifiable/command_test.go @@ -2934,7 +2934,7 @@ func newBBSSigner(privKey *bbs12381g2pub.PrivateKey) (*bbsSigner, error) { func (s *bbsSigner) Sign(data []byte) ([]byte, error) { msgs := s.textToLines(string(data)) - return bbs12381g2pub.New().Sign(msgs, s.privKeyBytes) + return bbs12381g2pub.New().Sign(nil, msgs, s.privKeyBytes) } func (s *bbsSigner) Alg() string { diff --git a/pkg/controller/rest/verifiable/operation_test.go b/pkg/controller/rest/verifiable/operation_test.go index 7a1f3c8a1..e30f3eebd 100644 --- a/pkg/controller/rest/verifiable/operation_test.go +++ b/pkg/controller/rest/verifiable/operation_test.go @@ -1523,7 +1523,7 @@ func newBBSSigner(privKey *bbs12381g2pub.PrivateKey) (*bbsSigner, error) { func (s *bbsSigner) Sign(data []byte) ([]byte, error) { msgs := s.textToLines(string(data)) - return bbs12381g2pub.New().Sign(msgs, s.privKeyBytes) + return bbs12381g2pub.New().Sign(nil, msgs, s.privKeyBytes) } func (s *bbsSigner) Alg() string { diff --git a/pkg/crypto/primitive/bbs12381g2pub/bbs.go b/pkg/crypto/primitive/bbs12381g2pub/bbs.go index 438bc0fa0..9144cf6a4 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/bbs.go +++ b/pkg/crypto/primitive/bbs12381g2pub/bbs.go @@ -54,7 +54,7 @@ const ( ) // Verify makes BLS BBS12-381 signature verification. -func (bbs *BBSG2Pub) Verify(messages [][]byte, sigBytes, pubKeyBytes []byte) error { +func (bbs *BBSG2Pub) Verify(header []byte, messages [][]byte, sigBytes, pubKeyBytes []byte) error { signature, err := ParseSignature(sigBytes) if err != nil { return fmt.Errorf("parse signature: %w", err) @@ -67,7 +67,7 @@ func (bbs *BBSG2Pub) Verify(messages [][]byte, sigBytes, pubKeyBytes []byte) err messagesCount := len(messages) - publicKeyWithGenerators, err := pubKey.ToPublicKeyWithGenerators(messagesCount) + publicKeyWithGenerators, err := pubKey.ToPublicKeyWithGenerators(messagesCount, header) if err != nil { return fmt.Errorf("build generators from public key: %w", err) } @@ -78,7 +78,7 @@ func (bbs *BBSG2Pub) Verify(messages [][]byte, sigBytes, pubKeyBytes []byte) err } // Sign signs the one or more messages using private key in compressed form. -func (bbs *BBSG2Pub) Sign(messages [][]byte, privKeyBytes []byte) ([]byte, error) { +func (bbs *BBSG2Pub) Sign(header []byte, messages [][]byte, privKeyBytes []byte) ([]byte, error) { privKey, err := UnmarshalPrivateKey(privKeyBytes) if err != nil { return nil, fmt.Errorf("unmarshal private key: %w", err) @@ -88,11 +88,11 @@ func (bbs *BBSG2Pub) Sign(messages [][]byte, privKeyBytes []byte) ([]byte, error return nil, errors.New("messages are not defined") } - return bbs.SignWithKey(messages, privKey) + return bbs.SignWithKey(header, messages, privKey) } // VerifyProof verifies BBS+ signature proof for one ore more revealed messages. -func (bbs *BBSG2Pub) VerifyProof(messagesBytes [][]byte, proof, nonce, pubKeyBytes []byte) error { +func (bbs *BBSG2Pub) VerifyProof(header []byte, messagesBytes [][]byte, proof, nonce, pubKeyBytes []byte) error { payload, err := parsePoKPayload(proof) if err != nil { return fmt.Errorf("parse signature proof: %w", err) @@ -110,7 +110,7 @@ func (bbs *BBSG2Pub) VerifyProof(messagesBytes [][]byte, proof, nonce, pubKeyByt return fmt.Errorf("parse public key: %w", err) } - publicKeyWithGenerators, err := pubKey.ToPublicKeyWithGenerators(payload.messagesCount) + publicKeyWithGenerators, err := pubKey.ToPublicKeyWithGenerators(payload.messagesCount, header) if err != nil { return fmt.Errorf("build generators from public key: %w", err) } @@ -130,7 +130,7 @@ func (bbs *BBSG2Pub) VerifyProof(messagesBytes [][]byte, proof, nonce, pubKeyByt } // DeriveProof derives a proof of BBS+ signature with some messages disclosed. -func (bbs *BBSG2Pub) DeriveProof(messages [][]byte, sigBytes, nonce, pubKeyBytes []byte, +func (bbs *BBSG2Pub) DeriveProof(header []byte, messages [][]byte, sigBytes, nonce, pubKeyBytes []byte, revealedIndexes []int) ([]byte, error) { if len(revealedIndexes) == 0 { return nil, errors.New("no message to reveal") @@ -147,7 +147,7 @@ func (bbs *BBSG2Pub) DeriveProof(messages [][]byte, sigBytes, nonce, pubKeyBytes return nil, fmt.Errorf("parse public key: %w", err) } - publicKeyWithGenerators, err := pubKey.ToPublicKeyWithGenerators(messagesCount) + publicKeyWithGenerators, err := pubKey.ToPublicKeyWithGenerators(messagesCount, header) if err != nil { return nil, fmt.Errorf("build generators from public key: %w", err) } @@ -179,13 +179,13 @@ func (bbs *BBSG2Pub) DeriveProof(messages [][]byte, sigBytes, nonce, pubKeyBytes } // SignWithKey signs the one or more messages using BBS+ key pair. -func (bbs *BBSG2Pub) SignWithKey(messages [][]byte, privKey *PrivateKey) ([]byte, error) { +func (bbs *BBSG2Pub) SignWithKey(header []byte, messages [][]byte, privKey *PrivateKey) ([]byte, error) { var err error pubKey := privKey.PublicKey() messagesCount := len(messages) - pubKeyWithGenerators, err := pubKey.ToPublicKeyWithGenerators(messagesCount) + pubKeyWithGenerators, err := pubKey.ToPublicKeyWithGenerators(messagesCount, header) if err != nil { return nil, fmt.Errorf("build generators from public key: %w", err) } diff --git a/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go b/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go index 1efefdd8b..373b338ae 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go +++ b/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go @@ -26,16 +26,16 @@ func TestBlsG2Pub_Verify(t *testing.T) { require.NoError(t, err) sigBytes := hexStringToBytesTest(t, - "836370c0f9fee53a4518e3294d2cd9880e9ced5a92fd21f20af898cf76c43a1fa88b3b8a0347313b83cb2f52055c3b56"+ - "24f8ea83101ff3429b07708c790975a43a1893fa848e1ffec1ab97c61196823d"+ - "28c3baa5900943929f3b0fdf36665fa43db9ee82dd855551bb9e7aaa6cc5c764") + "84d9677e651d7e039ff1bd3c6c37a6d465b23ebcc1291cf0082cd94c3971ff2ec64d8ddfd0c2f68d37429f6c751003a7"+ + "5435cae4b55250e5a3e357b7bd52589ff830820cd5e07a6125d846245efacccb"+ + "5814139b8bef5b329b3a269f576565d33bf6254916468f9e997a685ac68508a6") messagesBytes := default10messages(t) bls := bbs12381g2pub.New() t.Run("valid signature", func(t *testing.T) { - err = bls.Verify(messagesBytes, sigBytes, pkBytes) + err = bls.Verify(nil, messagesBytes, sigBytes, pkBytes) require.NoError(t, err) }) @@ -45,13 +45,13 @@ func TestBlsG2Pub_Verify(t *testing.T) { copy(invalidMessagesBytes, messagesBytes) invalidMessagesBytes[0] = invalidMessagesBytes[1] - err = bls.Verify(invalidMessagesBytes, sigBytes, pkBytes) + err = bls.Verify(nil, invalidMessagesBytes, sigBytes, pkBytes) require.Error(t, err) require.EqualError(t, err, "invalid BLS12-381 signature") }) t.Run("invalid input public key", func(t *testing.T) { - err = bls.Verify(messagesBytes, sigBytes, []byte("invalid")) + err = bls.Verify(nil, messagesBytes, sigBytes, []byte("invalid")) require.Error(t, err) require.EqualError(t, err, "parse public key: invalid size of public key") @@ -60,13 +60,13 @@ func TestBlsG2Pub_Verify(t *testing.T) { _, err = rand.Read(pkBytesInvalid) require.NoError(t, err) - err = bls.Verify(messagesBytes, sigBytes, pkBytesInvalid) + err = bls.Verify(nil, messagesBytes, sigBytes, pkBytesInvalid) require.Error(t, err) require.Contains(t, err.Error(), "parse public key: deserialize public key") }) t.Run("invalid input signature", func(t *testing.T) { - err = bls.Verify(messagesBytes, []byte("invalid"), pkBytes) + err = bls.Verify(nil, messagesBytes, []byte("invalid"), pkBytes) require.Error(t, err) require.EqualError(t, err, "parse signature: invalid size of signature") @@ -75,7 +75,7 @@ func TestBlsG2Pub_Verify(t *testing.T) { _, err = rand.Read(sigBytesInvalid) require.NoError(t, err) - err = bls.Verify(messagesBytes, sigBytesInvalid, pkBytes) + err = bls.Verify(nil, messagesBytes, sigBytesInvalid, pkBytes) require.Error(t, err) require.Contains(t, err.Error(), "parse signature: deserialize G1 compressed signature") }) @@ -89,7 +89,7 @@ func TestBBSG2Pub_SignWithKeyPair(t *testing.T) { messagesBytes := [][]byte{[]byte("message1"), []byte("message2")} - signatureBytes, err := bls.SignWithKey(messagesBytes, privKey) + signatureBytes, err := bls.SignWithKey(nil, messagesBytes, privKey) require.NoError(t, err) require.NotEmpty(t, signatureBytes) require.Len(t, signatureBytes, 112) @@ -97,7 +97,7 @@ func TestBBSG2Pub_SignWithKeyPair(t *testing.T) { pubKeyBytes, err := pubKey.Marshal() require.NoError(t, err) - require.NoError(t, bls.Verify(messagesBytes, signatureBytes, pubKeyBytes)) + require.NoError(t, bls.Verify(nil, messagesBytes, signatureBytes, pubKeyBytes)) } func TestBBSG2Pub_Sign(t *testing.T) { @@ -111,7 +111,7 @@ func TestBBSG2Pub_Sign(t *testing.T) { privKeyBytes, err := privKey.Marshal() require.NoError(t, err) - signatureBytes, err := bls.Sign(messagesBytes, privKeyBytes) + signatureBytes, err := bls.Sign(nil, messagesBytes, privKeyBytes) require.NoError(t, err) require.NotEmpty(t, signatureBytes) require.Len(t, signatureBytes, 112) @@ -119,16 +119,16 @@ func TestBBSG2Pub_Sign(t *testing.T) { pubKeyBytes, err := pubKey.Marshal() require.NoError(t, err) - require.NoError(t, bls.Verify(messagesBytes, signatureBytes, pubKeyBytes)) + require.NoError(t, bls.Verify(nil, messagesBytes, signatureBytes, pubKeyBytes)) // invalid private key bytes - signatureBytes, err = bls.Sign(messagesBytes, []byte("invalid")) + signatureBytes, err = bls.Sign(nil, messagesBytes, []byte("invalid")) require.Error(t, err) require.EqualError(t, err, "unmarshal private key: invalid size of private key") require.Nil(t, signatureBytes) // at least one message must be passed - signatureBytes, err = bls.Sign([][]byte{}, privKeyBytes) + signatureBytes, err = bls.Sign(nil, [][]byte{}, privKeyBytes) require.Error(t, err) require.EqualError(t, err, "messages are not defined") require.Nil(t, signatureBytes) @@ -136,23 +136,17 @@ func TestBBSG2Pub_Sign(t *testing.T) { func TestBBSG2Pub_SignWithPredefinedKeys(t *testing.T) { privateKeyBytes := hexStringToBytesTest(t, "47d2ede63ab4c329092b342ab526b1079dbc2595897d4f2ab2de4d841cbe7d56") - - // TODO "header": "11223344556677889900aabbccddeeff" - + header := hexStringToBytesTest(t, "11223344556677889900aabbccddeeff") messagesBytes := default10messages(t) bls := bbs12381g2pub.New() - signature, err := bls.Sign(messagesBytes, privateKeyBytes) + signature, err := bls.Sign(header, messagesBytes, privateKeyBytes) require.NoError(t, err) expectedSignatureBytes := hexStringToBytesTest(t, - "836370c0f9fee53a4518e3294d2cd9880e9ced5a92fd21f20af898cf76c43a1fa88b3b8a0347313b83cb2f52055c3b56"+ - "24f8ea83101ff3429b07708c790975a43a1893fa848e1ffec1ab97c61196823d"+ - "28c3baa5900943929f3b0fdf36665fa43db9ee82dd855551bb9e7aaa6cc5c764") - // TODO signature defined in the spec - // "9157456791e4f9cae1130372f7cf37709ba661e43df5c23cc1c76be91abff7e2603e2ddaaa71fc42bd6f9d44bd58315b"+ - // "09ee5cc4e7614edde358f2c497b6b05c8b118fae3f71a52af482dceffccb3785"+ - // "1907573c03d2890dffbd1f660cdf89c425d4e0498bbf73dd96ff15ad9a8b581a") + "9157456791e4f9cae1130372f7cf37709ba661e43df5c23cc1c76be91abff7e2603e2ddaaa71fc42bd6f9d44bd58315b"+ + "09ee5cc4e7614edde358f2c497b6b05c8b118fae3f71a52af482dceffccb3785"+ + "1907573c03d2890dffbd1f660cdf89c425d4e0498bbf73dd96ff15ad9a8b581a") require.Equal(t, expectedSignatureBytes, signature) } @@ -166,7 +160,7 @@ func TestBBSG2Pub_VerifyProof_SeveralDisclosedMessages(t *testing.T) { pkBytes, err := privateKey.PublicKey().Marshal() require.NoError(t, err) - proofBytes := hexStringToBytesTest(t, "000a0005b6f1890b66d4ffaaceda451c4986e36553b4db2622057e8a96b2f29e9274bb8f0249f305088269e39772ec845c267b6c84d60886cec2615e3f0b18a58b4ee97404fcaecff3889b1361df37baaf75bb4c11cb427dcbb91aac11ef32f2d4568540b1e527b52626a4f081f43182f2fcdb3f0197eb6b22d3050be87ece2c719e79b948f00be75d10b851641c6de2b84a49040000007480ce09f9513044ce742c18eb796a6cda777b836931675c7a6b76910c15debf9aa991165bc54a50d1899c00742ecd75dc000000026ae46e197c2fd0f0d7233b7eb8235b85bbbb10664c6b4c69bc645bd4e211df754f14ae46e8358107caab0e91c7a39c7b8d3bb57d6f932a2bc786877fa271bc39a8c3a8823f9246239ed8fe58da4de9bb47d4e535e27e11a764c2ae5d2d9bf5bf38db5d9e71d61d3bbc40896afc79f64f0000000a19de08e7f3ef1dca5b05363a0cf765c5c455a89fcf61513c100d9219d87f60db11ef7535cdc6f6fd6820eb8cfd8b4f89fa80321ec0121daded6257496c7ed24b4b0894a65c2abcdbfec475a10167c58f3801d3dd2563d788b6a9310ba908849135b34c5fa902e08c4f26bcd3fdd197146ee4f5d89b6bc0bd54046b68d07fcf5e42941fb950d223a508639add65e90e52380524c5cc5fef3fdca7a0f12e03f1c7559ff3467e9650230ff491699edb25daafa162c3c1dbd467d94cb2c0d63ec3305a7c022dce4952135fa1d7945af17ec131563a9d1925297945df74b46e19175f234885eea5e7b1b3b0f11aabb7f587271aeae106a6e9a4ea6662d82d5530f05d04bbe0001b8858cca3160df6dfdbcdbf4bf0dd7897f0394615026d81c4b955c13c9a99852c667c08d40de2522b138ae66de5055f9dc79df43a2a2c6522f459a1") //nolint:lll + proofBytes := hexStringToBytesTest(t, "000a0005ab1a7238bc9ba5065c9d1f395720f97b8d68208e89edb1fa8f1cde16c07b7771a46359ef198317ca71cfae5937200485b3e62de95b4d05a95c8d882197c56e582f74b5e6e1e4ae866a93fa13ae32690b8ea1bbbd7f1138f18a750ede1915a6d2898eec5b19028f2765585f36be4f152bd4ac2ad280743bed14ec78e0cdbf80f0547b37b1de62d71144f03e1fdec89b05000000748adcb65ca0ed38b9c6d1649bef5cd942175affdb9c7ad5212b371f0472d39228dc6c220cc80846fb2f44911b7aed2f32000000020910a8400998e7903a401b439d9a84723e46c9f0c03a9949ac9ee2d545caf72a50cd0f2f340a04a22ffbc8c4c6aa15af1ae972c18bbe6b463707836fb08d624089a4b92531729d0ce3f44ca36b47331a4c9a51af11d5b0f9bf4b55d8d09db24c8df59c6ad111ae0f9af56e16681a53df0000000a5916c0c291dc659d25699f2b182e2fbafe091bdf7a0667a4e4f047e80fa3d64214ee7f20d63f31472ec2eeac73ca01e51c2e420f3a26cda4e0cbe82e64f92a62075131c9dfde53d16e8c3e1d0b56bd6ac203f07af450cb94b019c6bb667df2465f9317c9ac178e58f638eb52751638fd54a211ab0ab3aeee8d87a69392de458f6ddb6b9f007589f6bdb5376eeffc4f64f7c7c0c426197be97f4f83a1a6f06ff74473dde98edbb444976ef4083237a859807d1a4c1e94fe68b69609fa00431e4b4622a39bd74791ce4b1f7545291b5ded098a757f680cbe1612312c8f841a8d0b077e5cf3eb5cf85f0ed9a3a061c3aa447c9a6bc87808d3ee1f293d157d1f41f14edd5cd0b1fcb5112d7e09386a276f396d4f31f1660bb65f0206eb92d669d2800f1e0f418be23895ad0cac055f973b50c38d57df54563e5493dd7910308ed9a6") //nolint:lll // TODO "header": "11223344556677889900aabbccddeeff" nonce := hexStringToBytesTest(t, "bed231d880675ed101ead304512e043ade9958dd0241ea70b4b3957fba941501") @@ -177,12 +171,12 @@ func TestBBSG2Pub_VerifyProof_SeveralDisclosedMessages(t *testing.T) { bls := bbs12381g2pub.New() t.Run("valid signature", func(t *testing.T) { - err = bls.VerifyProof(revealedMessagesBytes, proofBytes, nonce, pkBytes) + err = bls.VerifyProof(nil, revealedMessagesBytes, proofBytes, nonce, pkBytes) require.NoError(t, err) }) t.Run("invalid size of signature proof payload", func(t *testing.T) { - err = bls.VerifyProof(revealedMessagesBytes, []byte("?"), nonce, pkBytes) + err = bls.VerifyProof(nil, revealedMessagesBytes, []byte("?"), nonce, pkBytes) require.Error(t, err) require.EqualError(t, err, "parse signature proof: invalid size of PoK payload") }) @@ -192,7 +186,7 @@ func TestBBSG2Pub_VerifyProof_SeveralDisclosedMessages(t *testing.T) { copy(proofBytesCopy, proofBytes) - err = bls.VerifyProof(revealedMessagesBytes, proofBytesCopy, nonce, pkBytes) + err = bls.VerifyProof(nil, revealedMessagesBytes, proofBytesCopy, nonce, pkBytes) require.Error(t, err) require.EqualError(t, err, "parse signature proof: invalid size of signature proof") }) @@ -201,15 +195,15 @@ func TestBBSG2Pub_VerifyProof_SeveralDisclosedMessages(t *testing.T) { proofBytesCopy := make([]byte, len(proofBytes)) copy(proofBytesCopy, proofBytes) - proofBytesCopy[21] = 255 - proofBytesCopy[21] + proofBytesCopy[23] = 255 - proofBytesCopy[23] - err = bls.VerifyProof(revealedMessagesBytes, proofBytesCopy, nonce, pkBytes) + err = bls.VerifyProof(nil, revealedMessagesBytes, proofBytesCopy, nonce, pkBytes) require.Error(t, err) require.EqualError(t, err, "parse signature proof: parse G1 point: point is not on curve") }) t.Run("invalid input public key", func(t *testing.T) { - err = bls.VerifyProof(revealedMessagesBytes, proofBytes, nonce, []byte("invalid public key")) + err = bls.VerifyProof(nil, revealedMessagesBytes, proofBytes, nonce, []byte("invalid public key")) require.Error(t, err) require.EqualError(t, err, "parse public key: invalid size of public key") }) @@ -226,17 +220,17 @@ func TestBBSG2Pub_DeriveProof(t *testing.T) { messagesBytes := default10messages(t) bls := bbs12381g2pub.New() - signatureBytes, err := bls.Sign(messagesBytes, privKeyBytes) + signatureBytes, err := bls.Sign(nil, messagesBytes, privKeyBytes) require.NoError(t, err) pubKeyBytes, err := pubKey.Marshal() require.NoError(t, err) - require.NoError(t, bls.Verify(messagesBytes, signatureBytes, pubKeyBytes)) + require.NoError(t, bls.Verify(nil, messagesBytes, signatureBytes, pubKeyBytes)) nonce := hexStringToBytesTest(t, "bed231d880675ed101ead304512e043ade9958dd0241ea70b4b3957fba941501") revealedIndexes := []int{0, 2} - proofBytes, err := bls.DeriveProof(messagesBytes, signatureBytes, nonce, pubKeyBytes, revealedIndexes) + proofBytes, err := bls.DeriveProof(nil, messagesBytes, signatureBytes, nonce, pubKeyBytes, revealedIndexes) require.NoError(t, err) require.NotEmpty(t, proofBytes) @@ -245,11 +239,11 @@ func TestBBSG2Pub_DeriveProof(t *testing.T) { revealedMessages[i] = messagesBytes[ind] } - require.NoError(t, bls.VerifyProof(revealedMessages, proofBytes, nonce, pubKeyBytes)) + require.NoError(t, bls.VerifyProof(nil, revealedMessages, proofBytes, nonce, pubKeyBytes)) t.Run("DeriveProof with revealedIndexes larger than revealedMessages count", func(t *testing.T) { revealedIndexes = []int{0, 2, 4, 7, 9, 11} - _, err = bls.DeriveProof(messagesBytes, signatureBytes, nonce, pubKeyBytes, revealedIndexes) + _, err = bls.DeriveProof(nil, messagesBytes, signatureBytes, nonce, pubKeyBytes, revealedIndexes) require.EqualError(t, err, "init proof of knowledge signature: "+ "invalid revealed index: requested index 11 is larger than 10 messages count") }) diff --git a/pkg/crypto/primitive/bbs12381g2pub/keys.go b/pkg/crypto/primitive/bbs12381g2pub/keys.go index 28d3e69e2..abe595eae 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/keys.go +++ b/pkg/crypto/primitive/bbs12381g2pub/keys.go @@ -54,7 +54,7 @@ type PublicKeyWithGenerators struct { } // ToPublicKeyWithGenerators creates PublicKeyWithGenerators from the PublicKey. -func (pk *PublicKey) ToPublicKeyWithGenerators(messagesCount int) (*PublicKeyWithGenerators, error) { +func (pk *PublicKey) ToPublicKeyWithGenerators(messagesCount int, header []byte) (*PublicKeyWithGenerators, error) { specGenCnt := 2 genCnt := messagesCount + specGenCnt @@ -72,7 +72,7 @@ func (pk *PublicKey) ToPublicKeyWithGenerators(messagesCount int) (*PublicKeyWit } domainBuilder.addCsID() - // TODO use header. Probably should be a parameter to this func + domainBuilder.addBytes(header) domain := Hash2scalar(domainBuilder.build()) diff --git a/pkg/crypto/primitive/bbs12381g2pub/keys_test.go b/pkg/crypto/primitive/bbs12381g2pub/keys_test.go index 0d6264f01..6567507ae 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/keys_test.go +++ b/pkg/crypto/primitive/bbs12381g2pub/keys_test.go @@ -127,10 +127,11 @@ func TestParseMattrKeys(t *testing.T) { pubKeyBytes := base58.Decode(pubKeyB58) messagesBytes := [][]byte{[]byte("message1"), []byte("message2")} - signatureBytes, err := bbs.New().Sign(messagesBytes, privKeyBytes) + signatureBytes, err := bbs.New().Sign(nil, messagesBytes, privKeyBytes) require.NoError(t, err) - err = bbs.New().Verify(messagesBytes, signatureBytes, pubKeyBytes) + err = bbs.New().Verify(nil, + messagesBytes, signatureBytes, pubKeyBytes) require.NoError(t, err) } diff --git a/pkg/crypto/tinkcrypto/primitive/bbs/subtle/bls12381g2_signer.go b/pkg/crypto/tinkcrypto/primitive/bbs/subtle/bls12381g2_signer.go index c1d11cf9c..c01967707 100644 --- a/pkg/crypto/tinkcrypto/primitive/bbs/subtle/bls12381g2_signer.go +++ b/pkg/crypto/tinkcrypto/primitive/bbs/subtle/bls12381g2_signer.go @@ -32,5 +32,5 @@ func NewBLS12381G2Signer(privateKey []byte) *BLS12381G2Signer { // signature in []byte // error in case of errors func (s *BLS12381G2Signer) Sign(messages [][]byte) ([]byte, error) { - return s.bbsPrimitive.Sign(messages, s.privateKeyBytes) + return s.bbsPrimitive.Sign(nil, messages, s.privateKeyBytes) } diff --git a/pkg/crypto/tinkcrypto/primitive/bbs/subtle/bls12381g2_verifier.go b/pkg/crypto/tinkcrypto/primitive/bbs/subtle/bls12381g2_verifier.go index ce181dda1..2f64555fb 100644 --- a/pkg/crypto/tinkcrypto/primitive/bbs/subtle/bls12381g2_verifier.go +++ b/pkg/crypto/tinkcrypto/primitive/bbs/subtle/bls12381g2_verifier.go @@ -30,14 +30,14 @@ func NewBLS12381G2Verifier(signerPublicKey []byte) *BLS12381G2Verifier { // returns: // error in case of errors or nil if signature verification was successful func (v *BLS12381G2Verifier) Verify(messages [][]byte, signature []byte) error { - return v.bbsPrimitive.Verify(messages, signature, v.signerPubKeyBytes) + return v.bbsPrimitive.Verify(nil, messages, signature, v.signerPubKeyBytes) } // VerifyProof will verify a BBS+ signature proof (generated e.g. by DeriveProof()) with the signer's public key. // returns: // error in case of errors or nil if signature proof verification was successful func (v *BLS12381G2Verifier) VerifyProof(messages [][]byte, proof, nonce []byte) error { - return v.bbsPrimitive.VerifyProof(messages, proof, nonce, v.signerPubKeyBytes) + return v.bbsPrimitive.VerifyProof(nil, messages, proof, nonce, v.signerPubKeyBytes) } // DeriveProof will create a BBS+ signature proof for a list of revealed messages using BBS signature @@ -47,5 +47,5 @@ func (v *BLS12381G2Verifier) VerifyProof(messages [][]byte, proof, nonce []byte) // error in case of errors func (v *BLS12381G2Verifier) DeriveProof(messages [][]byte, signature, nonce []byte, revealedIndexes []int) ([]byte, error) { - return v.bbsPrimitive.DeriveProof(messages, signature, nonce, v.signerPubKeyBytes, revealedIndexes) + return v.bbsPrimitive.DeriveProof(nil, messages, signature, nonce, v.signerPubKeyBytes, revealedIndexes) } diff --git a/pkg/doc/presexch/definition_test.go b/pkg/doc/presexch/definition_test.go index 4f79cbde0..ceb756861 100644 --- a/pkg/doc/presexch/definition_test.go +++ b/pkg/doc/presexch/definition_test.go @@ -1634,7 +1634,7 @@ func newBBSSigner(key *bbs12381g2pub.PrivateKey) (*bbsSigner, error) { } func (s *bbsSigner) Sign(data []byte) ([]byte, error) { - return bbs12381g2pub.New().Sign(s.textToLines(string(data)), s.privateKey) + return bbs12381g2pub.New().Sign(nil, s.textToLines(string(data)), s.privateKey) } func (s *bbsSigner) Alg() string { diff --git a/pkg/doc/signature/suite/bbsblssignatureproof2020/signer.go b/pkg/doc/signature/suite/bbsblssignatureproof2020/signer.go index 3c736c1cb..e79e007e6 100644 --- a/pkg/doc/signature/suite/bbsblssignatureproof2020/signer.go +++ b/pkg/doc/signature/suite/bbsblssignatureproof2020/signer.go @@ -101,7 +101,7 @@ func generateSignatureProof(blsSignature map[string]interface{}, resolver keyRes return nil, fmt.Errorf("get public key and signature: %w", pErr) } - signatureProofBytes, err := bls.DeriveProof(verData.blsMessages, signatureBytes, + signatureProofBytes, err := bls.DeriveProof(nil, verData.blsMessages, signatureBytes, nonce, pubKeyBytes, verData.revealIndexes) if err != nil { return nil, fmt.Errorf("derive BBS+ proof: %w", err) diff --git a/pkg/doc/signature/verifier/public_key_verifier.go b/pkg/doc/signature/verifier/public_key_verifier.go index ca5fb424a..aedd91f6a 100644 --- a/pkg/doc/signature/verifier/public_key_verifier.go +++ b/pkg/doc/signature/verifier/public_key_verifier.go @@ -443,7 +443,7 @@ type BBSG2SignatureVerifier struct { func (v *BBSG2SignatureVerifier) Verify(pubKeyValue *PublicKey, doc, signature []byte) error { bbs := bbs12381g2pub.New() - return bbs.Verify(splitMessageIntoLines(string(doc), false), signature, pubKeyValue.Value) + return bbs.Verify(nil, splitMessageIntoLines(string(doc), false), signature, pubKeyValue.Value) } // NewBBSG2SignatureProofVerifier creates a new BBSG2SignatureProofVerifier. @@ -467,7 +467,7 @@ type BBSG2SignatureProofVerifier struct { func (v *BBSG2SignatureProofVerifier) Verify(pubKeyValue *PublicKey, doc, signature []byte) error { bbs := bbs12381g2pub.New() - return bbs.VerifyProof(splitMessageIntoLines(string(doc), true), + return bbs.VerifyProof(nil, splitMessageIntoLines(string(doc), true), signature, v.nonce, pubKeyValue.Value) } diff --git a/pkg/doc/verifiable/credential_ldp_test.go b/pkg/doc/verifiable/credential_ldp_test.go index bfa324af3..df2cbe4e6 100644 --- a/pkg/doc/verifiable/credential_ldp_test.go +++ b/pkg/doc/verifiable/credential_ldp_test.go @@ -1341,7 +1341,7 @@ func newBBSSigner(privKey *bbs12381g2pub.PrivateKey) (*bbsSigner, error) { func (s *bbsSigner) Sign(data []byte) ([]byte, error) { msgs := s.textToLines(string(data)) - return bbs12381g2pub.New().Sign(msgs, s.privKeyBytes) + return bbs12381g2pub.New().Sign(nil, msgs, s.privKeyBytes) } func (s *bbsSigner) Alg() string { diff --git a/pkg/doc/verifiable/example_support_test.go b/pkg/doc/verifiable/example_support_test.go index a39b0850f..6fbc15a06 100644 --- a/pkg/doc/verifiable/example_support_test.go +++ b/pkg/doc/verifiable/example_support_test.go @@ -72,7 +72,7 @@ func newBBSSigner(privKey *bbs12381g2pub.PrivateKey) (*bbsSigner, error) { func (s *bbsSigner) Sign(data []byte) ([]byte, error) { msgs := s.textToLines(string(data)) - return bbs12381g2pub.New().Sign(msgs, s.privKeyBytes) + return bbs12381g2pub.New().Sign(nil, msgs, s.privKeyBytes) } // Alg return alg. diff --git a/test/bbs/src/support_signer.go b/test/bbs/src/support_signer.go index c904dc279..e5199cfc7 100644 --- a/test/bbs/src/support_signer.go +++ b/test/bbs/src/support_signer.go @@ -30,7 +30,7 @@ func newBBSSigner(privKey *bbs.PrivateKey) (*bbsSigner, error) { func (s *bbsSigner) Sign(data []byte) ([]byte, error) { msgs := s.textToLines(string(data)) - return bbs.New().Sign(msgs, s.privKeyBytes) + return bbs.New().Sign(nil, msgs, s.privKeyBytes) } func (s *bbsSigner) Alg() string { From b117134fd9a762fb2194cfbc3df8549a6d93a712 Mon Sep 17 00:00:00 2001 From: Sergey Minaev Date: Mon, 24 Oct 2022 16:59:14 +0500 Subject: [PATCH 10/11] BBS Update: align impl to Signature test vector. Signed-off-by: Sergey Minaev --- pkg/crypto/primitive/bbs12381g2pub/bbs.go | 12 ++--- .../primitive/bbs12381g2pub/bbs_test.go | 54 +++++++++---------- pkg/crypto/primitive/bbs12381g2pub/fr.go | 12 +++-- pkg/crypto/primitive/bbs12381g2pub/fr_test.go | 38 +++++++++++++ pkg/crypto/primitive/bbs12381g2pub/keys.go | 32 +++++++---- .../primitive/bbs12381g2pub/keys_test.go | 10 ++-- .../bbs12381g2pub/signature_message.go | 6 ++- .../bbs12381g2pub/signature_message_test.go | 53 ++++++++++++++++++ .../bbs12381g2pub/signature_proof.go | 7 +-- 9 files changed, 165 insertions(+), 59 deletions(-) create mode 100644 pkg/crypto/primitive/bbs12381g2pub/fr_test.go create mode 100644 pkg/crypto/primitive/bbs12381g2pub/signature_message_test.go diff --git a/pkg/crypto/primitive/bbs12381g2pub/bbs.go b/pkg/crypto/primitive/bbs12381g2pub/bbs.go index 9144cf6a4..ba63ee270 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/bbs.go +++ b/pkg/crypto/primitive/bbs12381g2pub/bbs.go @@ -190,12 +190,14 @@ func (bbs *BBSG2Pub) SignWithKey(header []byte, messages [][]byte, privKey *Priv return nil, fmt.Errorf("build generators from public key: %w", err) } + messagesFr := ParseSignatureMessages(messages) + esBuilder := newEcnodeForHashBuilder() esBuilder.addScalar(privKey.FR) esBuilder.addScalar(pubKeyWithGenerators.domain) - for _, msg := range messages { - esBuilder.addBytes(msg) + for _, msgFr := range messagesFr { + esBuilder.addScalar(msgFr.FR) } es := Hash2scalars(esBuilder.build(), 2) @@ -204,7 +206,6 @@ func (bbs *BBSG2Pub) SignWithKey(header []byte, messages [][]byte, privKey *Priv exp.Add(exp, e) exp.Inverse(exp) - messagesFr := ParseSignatureMessages(messages) b := computeB(s, messagesFr, pubKeyWithGenerators) sig := g1.New() @@ -222,12 +223,9 @@ func (bbs *BBSG2Pub) SignWithKey(header []byte, messages [][]byte, privKey *Priv func computeB(s *bls12381.Fr, messages []*SignatureMessage, key *PublicKeyWithGenerators) *bls12381.PointG1 { const basesOffset = 2 - bindingBasis := g1.One() - bindingExp := bls12381.NewFr().One() - cb := newCommitmentBuilder(len(messages) + basesOffset) - cb.add(bindingBasis, bindingExp) + cb.add(key.p1, bls12381.NewFr().One()) cb.add(key.q1, s) cb.add(key.q2, key.domain) diff --git a/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go b/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go index 373b338ae..31698afe2 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go +++ b/pkg/crypto/primitive/bbs12381g2pub/bbs_test.go @@ -17,7 +17,7 @@ import ( ) func TestBlsG2Pub_Verify(t *testing.T) { - privateKeyBytes := hexStringToBytesTest(t, "47d2ede63ab4c329092b342ab526b1079dbc2595897d4f2ab2de4d841cbe7d56") + privateKeyBytes := hexToBytes(t, "47d2ede63ab4c329092b342ab526b1079dbc2595897d4f2ab2de4d841cbe7d56") privateKey, err := bbs12381g2pub.UnmarshalPrivateKey(privateKeyBytes) require.NoError(t, err) @@ -25,17 +25,17 @@ func TestBlsG2Pub_Verify(t *testing.T) { pkBytes, err := privateKey.PublicKey().Marshal() require.NoError(t, err) - sigBytes := hexStringToBytesTest(t, - "84d9677e651d7e039ff1bd3c6c37a6d465b23ebcc1291cf0082cd94c3971ff2ec64d8ddfd0c2f68d37429f6c751003a7"+ - "5435cae4b55250e5a3e357b7bd52589ff830820cd5e07a6125d846245efacccb"+ - "5814139b8bef5b329b3a269f576565d33bf6254916468f9e997a685ac68508a6") - + sigBytes := hexToBytes(t, + "9157456791e4f9cae1130372f7cf37709ba661e43df5c23cc1c76be91abff7e2603e2ddaaa71fc42bd6f9d44bd58315b"+ + "09ee5cc4e7614edde358f2c497b6b05c8b118fae3f71a52af482dceffccb3785"+ + "1907573c03d2890dffbd1f660cdf89c425d4e0498bbf73dd96ff15ad9a8b581a") + header := hexToBytes(t, "11223344556677889900aabbccddeeff") messagesBytes := default10messages(t) bls := bbs12381g2pub.New() t.Run("valid signature", func(t *testing.T) { - err = bls.Verify(nil, messagesBytes, sigBytes, pkBytes) + err = bls.Verify(header, messagesBytes, sigBytes, pkBytes) require.NoError(t, err) }) @@ -135,15 +135,15 @@ func TestBBSG2Pub_Sign(t *testing.T) { } func TestBBSG2Pub_SignWithPredefinedKeys(t *testing.T) { - privateKeyBytes := hexStringToBytesTest(t, "47d2ede63ab4c329092b342ab526b1079dbc2595897d4f2ab2de4d841cbe7d56") - header := hexStringToBytesTest(t, "11223344556677889900aabbccddeeff") + privateKeyBytes := hexToBytes(t, "47d2ede63ab4c329092b342ab526b1079dbc2595897d4f2ab2de4d841cbe7d56") + header := hexToBytes(t, "11223344556677889900aabbccddeeff") messagesBytes := default10messages(t) bls := bbs12381g2pub.New() signature, err := bls.Sign(header, messagesBytes, privateKeyBytes) require.NoError(t, err) - expectedSignatureBytes := hexStringToBytesTest(t, + expectedSignatureBytes := hexToBytes(t, "9157456791e4f9cae1130372f7cf37709ba661e43df5c23cc1c76be91abff7e2603e2ddaaa71fc42bd6f9d44bd58315b"+ "09ee5cc4e7614edde358f2c497b6b05c8b118fae3f71a52af482dceffccb3785"+ "1907573c03d2890dffbd1f660cdf89c425d4e0498bbf73dd96ff15ad9a8b581a") @@ -152,7 +152,7 @@ func TestBBSG2Pub_SignWithPredefinedKeys(t *testing.T) { } func TestBBSG2Pub_VerifyProof_SeveralDisclosedMessages(t *testing.T) { - privateKeyBytes := hexStringToBytesTest(t, "47d2ede63ab4c329092b342ab526b1079dbc2595897d4f2ab2de4d841cbe7d56") + privateKeyBytes := hexToBytes(t, "47d2ede63ab4c329092b342ab526b1079dbc2595897d4f2ab2de4d841cbe7d56") privateKey, err := bbs12381g2pub.UnmarshalPrivateKey(privateKeyBytes) require.NoError(t, err) @@ -160,10 +160,10 @@ func TestBBSG2Pub_VerifyProof_SeveralDisclosedMessages(t *testing.T) { pkBytes, err := privateKey.PublicKey().Marshal() require.NoError(t, err) - proofBytes := hexStringToBytesTest(t, "000a0005ab1a7238bc9ba5065c9d1f395720f97b8d68208e89edb1fa8f1cde16c07b7771a46359ef198317ca71cfae5937200485b3e62de95b4d05a95c8d882197c56e582f74b5e6e1e4ae866a93fa13ae32690b8ea1bbbd7f1138f18a750ede1915a6d2898eec5b19028f2765585f36be4f152bd4ac2ad280743bed14ec78e0cdbf80f0547b37b1de62d71144f03e1fdec89b05000000748adcb65ca0ed38b9c6d1649bef5cd942175affdb9c7ad5212b371f0472d39228dc6c220cc80846fb2f44911b7aed2f32000000020910a8400998e7903a401b439d9a84723e46c9f0c03a9949ac9ee2d545caf72a50cd0f2f340a04a22ffbc8c4c6aa15af1ae972c18bbe6b463707836fb08d624089a4b92531729d0ce3f44ca36b47331a4c9a51af11d5b0f9bf4b55d8d09db24c8df59c6ad111ae0f9af56e16681a53df0000000a5916c0c291dc659d25699f2b182e2fbafe091bdf7a0667a4e4f047e80fa3d64214ee7f20d63f31472ec2eeac73ca01e51c2e420f3a26cda4e0cbe82e64f92a62075131c9dfde53d16e8c3e1d0b56bd6ac203f07af450cb94b019c6bb667df2465f9317c9ac178e58f638eb52751638fd54a211ab0ab3aeee8d87a69392de458f6ddb6b9f007589f6bdb5376eeffc4f64f7c7c0c426197be97f4f83a1a6f06ff74473dde98edbb444976ef4083237a859807d1a4c1e94fe68b69609fa00431e4b4622a39bd74791ce4b1f7545291b5ded098a757f680cbe1612312c8f841a8d0b077e5cf3eb5cf85f0ed9a3a061c3aa447c9a6bc87808d3ee1f293d157d1f41f14edd5cd0b1fcb5112d7e09386a276f396d4f31f1660bb65f0206eb92d669d2800f1e0f418be23895ad0cac055f973b50c38d57df54563e5493dd7910308ed9a6") //nolint:lll + proofBytes := hexToBytes(t, "000a0005b309e66b61ed40151fe80418c2a603ac98ba5a41348daa5ff8452f8d1c3540e627d1d455cc21e416508566f2ad425ecb8e1502e60fb0b4229ea355768725f249ddd96d16aac62317932d7249cd672780518d361956cadde8113304136cba7de696a928df91d8cd4b839c4539fadfb69eaa7fb06f9383df5e71a63313f595a998052e2c5f0f8041b5fdeaa96587d8365f000000748b822f236fbe22a18573db03f7b7867925e25d765f5b3689a480ae429f7bc93b5e7705b19f03ab752d5d8f40f2179f4e0000000206b4f1e7ac8f6342a3f21fbc8f73689d9020b43749c5b59c08019c009506b3fa7293bf6163a59f207b5bddd63520c24186d294169118757f90adbd00c277f911881f03648d511521053c722b69cb4e9901b0c9e5ec1a2b8dc7effcb2cc9551d2c62e908a7906a19e252b9dc9deb435e30000000a1da464bde0b8b36051d9dafe48478fb07c66d809cb01f5ff1af65ddea5926ae25f7eeb0fc7abe707313cd88a82f338ff9bfa6e66438cb07cae7bbc2539a234fa5abde85f4157c27a5e4bb3f91f71e5ba3218ff6a442bb346a6b25cb4f22f7b346b9a713272d5b47740b12f23e8bf2c28ed396b95c94352cfdc6e217fd92d19671ab662782134a08463c3ad2fd45942f980ada1a0e507283d4c5a650c82a818f86f3260817ff2866634485ee4ca5b5ee530e40c7bfbb18165bcd558a8f8e5f8ef257c733a3f0c1eb7a5d5a7be14a6ef5dc897c77ad5e05e830a0e180608aa88fe0d4963a99d88008fe7d9ff77005ba59a3b667d9d17a95510095d631a1e61be812540857d411593c464a0d403713daa9e377d58867dfbb315d09b8eecd2aa58f72de98c306484f88a325ba57b33fd1636c713c340147c55e6c932b394afea1567") //nolint:lll // TODO "header": "11223344556677889900aabbccddeeff" - nonce := hexStringToBytesTest(t, "bed231d880675ed101ead304512e043ade9958dd0241ea70b4b3957fba941501") + nonce := hexToBytes(t, "bed231d880675ed101ead304512e043ade9958dd0241ea70b4b3957fba941501") messagesBytes := default10messages(t) revealedMessagesBytes := [][]byte{messagesBytes[0], messagesBytes[2]} @@ -195,7 +195,7 @@ func TestBBSG2Pub_VerifyProof_SeveralDisclosedMessages(t *testing.T) { proofBytesCopy := make([]byte, len(proofBytes)) copy(proofBytesCopy, proofBytes) - proofBytesCopy[23] = 255 - proofBytesCopy[23] + proofBytesCopy[21] = 255 - proofBytesCopy[21] err = bls.VerifyProof(nil, revealedMessagesBytes, proofBytesCopy, nonce, pkBytes) require.Error(t, err) @@ -210,7 +210,7 @@ func TestBBSG2Pub_VerifyProof_SeveralDisclosedMessages(t *testing.T) { } func TestBBSG2Pub_DeriveProof(t *testing.T) { - privKeyBytes := hexStringToBytesTest(t, "47d2ede63ab4c329092b342ab526b1079dbc2595897d4f2ab2de4d841cbe7d56") + privKeyBytes := hexToBytes(t, "47d2ede63ab4c329092b342ab526b1079dbc2595897d4f2ab2de4d841cbe7d56") privKey, err := bbs12381g2pub.UnmarshalPrivateKey(privKeyBytes) require.NoError(t, err) @@ -228,7 +228,7 @@ func TestBBSG2Pub_DeriveProof(t *testing.T) { require.NoError(t, bls.Verify(nil, messagesBytes, signatureBytes, pubKeyBytes)) - nonce := hexStringToBytesTest(t, "bed231d880675ed101ead304512e043ade9958dd0241ea70b4b3957fba941501") + nonce := hexToBytes(t, "bed231d880675ed101ead304512e043ade9958dd0241ea70b4b3957fba941501") revealedIndexes := []int{0, 2} proofBytes, err := bls.DeriveProof(nil, messagesBytes, signatureBytes, nonce, pubKeyBytes, revealedIndexes) require.NoError(t, err) @@ -251,22 +251,22 @@ func TestBBSG2Pub_DeriveProof(t *testing.T) { func default10messages(t *testing.T) [][]byte { messagesBytes := [][]byte{ - hexStringToBytesTest(t, "9872ad089e452c7b6e283dfac2a80d58e8d0ff71cc4d5e310a1debdda4a45f02"), - hexStringToBytesTest(t, "87a8bd656d49ee07b8110e1d8fd4f1dcef6fb9bc368c492d9bc8c4f98a739ac6"), - hexStringToBytesTest(t, "96012096adda3f13dd4adbe4eea481a4c4b5717932b73b00e31807d3c5894b90"), - hexStringToBytesTest(t, "ac55fb33a75909edac8994829b250779298aa75d69324a365733f16c333fa943"), - hexStringToBytesTest(t, "d183ddc6e2665aa4e2f088af9297b78c0d22b4290273db637ed33ff5cf703151"), - hexStringToBytesTest(t, "515ae153e22aae04ad16f759e07237b43022cb1ced4c176e0999c6a8ba5817cc"), - hexStringToBytesTest(t, "496694774c5604ab1b2544eababcf0f53278ff5040c1e77c811656e8220417a2"), - hexStringToBytesTest(t, "77fe97eb97a1ebe2e81e4e3597a3ee740a66e9ef2412472c23364568523f8b91"), - hexStringToBytesTest(t, "7372e9daa5ed31e6cd5c825eac1b855e84476a1d94932aa348e07b7320912416"), - hexStringToBytesTest(t, "c344136d9ab02da4dd5908bbba913ae6f58c2cc844b802a6f811f5fb075f9b80"), + hexToBytes(t, "9872ad089e452c7b6e283dfac2a80d58e8d0ff71cc4d5e310a1debdda4a45f02"), + hexToBytes(t, "87a8bd656d49ee07b8110e1d8fd4f1dcef6fb9bc368c492d9bc8c4f98a739ac6"), + hexToBytes(t, "96012096adda3f13dd4adbe4eea481a4c4b5717932b73b00e31807d3c5894b90"), + hexToBytes(t, "ac55fb33a75909edac8994829b250779298aa75d69324a365733f16c333fa943"), + hexToBytes(t, "d183ddc6e2665aa4e2f088af9297b78c0d22b4290273db637ed33ff5cf703151"), + hexToBytes(t, "515ae153e22aae04ad16f759e07237b43022cb1ced4c176e0999c6a8ba5817cc"), + hexToBytes(t, "496694774c5604ab1b2544eababcf0f53278ff5040c1e77c811656e8220417a2"), + hexToBytes(t, "77fe97eb97a1ebe2e81e4e3597a3ee740a66e9ef2412472c23364568523f8b91"), + hexToBytes(t, "7372e9daa5ed31e6cd5c825eac1b855e84476a1d94932aa348e07b7320912416"), + hexToBytes(t, "c344136d9ab02da4dd5908bbba913ae6f58c2cc844b802a6f811f5fb075f9b80"), } return messagesBytes } -func hexStringToBytesTest(t *testing.T, msg string) []byte { +func hexToBytes(t *testing.T, msg string) []byte { bytes, err := hex.DecodeString(msg) require.NoError(t, err) diff --git a/pkg/crypto/primitive/bbs12381g2pub/fr.go b/pkg/crypto/primitive/bbs12381g2pub/fr.go index adf5b9f2e..f725e1194 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/fr.go +++ b/pkg/crypto/primitive/bbs12381g2pub/fr.go @@ -17,10 +17,9 @@ import ( ) const ( - logP2 = 384 k = 128 h2sDST = csID + "H2S_" - expandLen = (logP2 + k) / 8 + expandLen = (logR2 + k + 7) / 8 //nolint:gomnd ) func parseFr(data []byte) *bls12381.Fr { @@ -74,20 +73,25 @@ func Hash2scalar(message []byte) *bls12381.Fr { // Hash2scalars convert messages represented in bytes to Fr. func Hash2scalars(msg []byte, cnt int) []*bls12381.Fr { + return hash2scalars(msg, []byte(h2sDST), cnt) +} + +func hash2scalars(msg, dst []byte, cnt int) []*bls12381.Fr { bufLen := cnt * expandLen msgLen := len(msg) roundSz := 1 msgLenSz := 4 msgExt := make([]byte, msgLen+roundSz+msgLenSz) + // msgExt is a concatenation of: msg || I2OSP(round, 1) || I2OSP(cnt, 4) copy(msgExt, msg) - copy(msgExt[msgLen+1:], uint32ToBytes(uint32(msgLen))) + copy(msgExt[msgLen+1:], uint32ToBytes(uint32(cnt))) out := make([]*bls12381.Fr, cnt) for round, completed := byte(0), false; !completed; { msgExt[msgLen] = round - buf, _ := bls12381intern.ExpandMsgXOF(sha3.NewShake256(), msgExt, []byte(h2sDST), bufLen) //nolint:errcheck + buf, _ := bls12381intern.ExpandMsgXOF(sha3.NewShake256(), msgExt, dst, bufLen) //nolint:errcheck ok := true for i := 0; i < cnt && ok; i++ { diff --git a/pkg/crypto/primitive/bbs12381g2pub/fr_test.go b/pkg/crypto/primitive/bbs12381g2pub/fr_test.go new file mode 100644 index 000000000..29c0f023b --- /dev/null +++ b/pkg/crypto/primitive/bbs12381g2pub/fr_test.go @@ -0,0 +1,38 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package bbs12381g2pub_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + bbs "github.com/hyperledger/aries-framework-go/pkg/crypto/primitive/bbs12381g2pub" +) + +func TestHash2Scalars(t *testing.T) { + msg := hexToBytes(t, "9872ad089e452c7b6e283dfac2a80d58e8d0ff71cc4d5e310a1debdda4a45f02") + + t.Run("single", func(t *testing.T) { + sc := bbs.Hash2scalar(msg).ToBytes() + require.Equal(t, hexToBytes(t, "260cab748e24ccc2bbd66f5b834d692622fa131f5ce898fa57217434c9ed14fa"), sc) + }) + + t.Run("multiple", func(t *testing.T) { + sc := bbs.Hash2scalars(msg, 10) + require.Equal(t, hexToBytes(t, "5c6e62607c16397ee6d9624673be9a7ddacbc7b7dd290bdb853cf4c74a34de0a"), sc[0].ToBytes()) + require.Equal(t, hexToBytes(t, "2a3524e43413a5d1b34c4c8ed119c4c5a2f9b84392ff0fea0d34e1be44ceafbc"), sc[1].ToBytes()) + require.Equal(t, hexToBytes(t, "4b649b82eed1e62117d91cd8d22438e72f3f931a0f8ad683d1ade253333c472a"), sc[2].ToBytes()) + require.Equal(t, hexToBytes(t, "64338965f1d37d17a14b6f431128c0d41a7c3924a5f484c282d20205afdfdb8f"), sc[3].ToBytes()) + require.Equal(t, hexToBytes(t, "0dfe01c01ff8654e43a611b76aaf4faec618a50d85d34f7cc89879b179bde3d5"), sc[4].ToBytes()) + require.Equal(t, hexToBytes(t, "6b6935016e64791f5d719f8206284fbe27dbb8efffb4141512c3fbfbfa861a0f"), sc[5].ToBytes()) + require.Equal(t, hexToBytes(t, "0dfe13f85a36df5ebfe0efac3759becfcc2a18b134fd22485c151db85f981342"), sc[6].ToBytes()) + require.Equal(t, hexToBytes(t, "5071751012c142046e7c3508decb0b7ba9a453d06ce7787189f4d93a821d538e"), sc[7].ToBytes()) + require.Equal(t, hexToBytes(t, "5cdae3304e745553a75134d914db5b282cc62d295e3ed176fb12f792919fd85e"), sc[8].ToBytes()) + require.Equal(t, hexToBytes(t, "32b67dfbba729831798279071a39021b66fd68ee2e68684a0f6901cd6fcb8256"), sc[9].ToBytes()) + }) +} diff --git a/pkg/crypto/primitive/bbs12381g2pub/keys.go b/pkg/crypto/primitive/bbs12381g2pub/keys.go index abe595eae..a27aec612 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/keys.go +++ b/pkg/crypto/primitive/bbs12381g2pub/keys.go @@ -21,12 +21,13 @@ import ( ) const ( - seedSize = frCompressedSize - seedDST = csID + "SIG_GENERATOR_SEED_" - generatorDST = csID + "SIG_GENERATOR_DST_" - generatorSeed = csID + "MESSAGE_GENERATOR_SEED" - logR2 = 251 - seedLen = ((logR2 + k) + 7) / 8 //nolint:gomnd + seedSize = frCompressedSize + seedDST = csID + "SIG_GENERATOR_SEED_" + generatorDST = csID + "SIG_GENERATOR_DST_" + generatorSeed = csID + "MESSAGE_GENERATOR_SEED" + generatorBPSeed = csID + "BP_MESSAGE_GENERATOR_SEED" + logR2 = 251 + seedLen = ((logR2 + k) + 7) / 8 //nolint:gomnd ) // PublicKey defines BLS Public Key. @@ -42,6 +43,7 @@ type PrivateKey struct { // PublicKeyWithGenerators extends PublicKey with a blinding generator h0, a commitment to the secret key w, // and a generator for each message h. type PublicKeyWithGenerators struct { + p1 *bls12381.PointG1 q1 *bls12381.PointG1 q2 *bls12381.PointG1 h []*bls12381.PointG1 @@ -58,7 +60,12 @@ func (pk *PublicKey) ToPublicKeyWithGenerators(messagesCount int, header []byte) specGenCnt := 2 genCnt := messagesCount + specGenCnt - generators, err := CreateGenerators(genCnt) + generators, err := CreateMessageGenerators(genCnt) + if err != nil { + return nil, err + } + + bpGenerators, err := crateGenerators(genCnt, []byte(generatorBPSeed)) if err != nil { return nil, err } @@ -77,6 +84,7 @@ func (pk *PublicKey) ToPublicKeyWithGenerators(messagesCount int, header []byte) domain := Hash2scalar(domainBuilder.build()) return &PublicKeyWithGenerators{ + p1: bpGenerators[0], q1: generators[0], q2: generators[1], h: generators[2:], @@ -97,11 +105,15 @@ func hashToG1(data, dst []byte) (*bls12381.PointG1, error) { return g1.FromBytes(g.ToBytes(p)) } -// CreateGenerators create `cnt` determenistic generators. -func CreateGenerators(cnt int) ([]*bls12381.PointG1, error) { +// CreateMessageGenerators create `cnt` determenistic generators. +func CreateMessageGenerators(cnt int) ([]*bls12381.PointG1, error) { + return crateGenerators(cnt, []byte(generatorSeed)) +} + +func crateGenerators(cnt int, seed []byte) ([]*bls12381.PointG1, error) { generators := make([]*bls12381.PointG1, cnt) - v, err := bls12381intern.ExpandMsgXOF(sha3.NewShake256(), []byte(generatorSeed), []byte(seedDST), seedLen) + v, err := bls12381intern.ExpandMsgXOF(sha3.NewShake256(), seed, []byte(seedDST), seedLen) if err != nil { return nil, err } diff --git a/pkg/crypto/primitive/bbs12381g2pub/keys_test.go b/pkg/crypto/primitive/bbs12381g2pub/keys_test.go index 6567507ae..0a6d8f32a 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/keys_test.go +++ b/pkg/crypto/primitive/bbs12381g2pub/keys_test.go @@ -67,21 +67,21 @@ func TestPrivateKey_PublicKey(t *testing.T) { t.Run("pre-generated key pair", func(t *testing.T) { // original hex seed 746869732d49532d6a7573742d616e2d546573742d494b4d2d746f2d67656e65726174652d246528724074232d6b6579 - privateKeyB58 := "5qNVd4Wsp7LPC7vxrbuVMsAkAGif2dA82wm1Wte1zH4Z" - publicKeyB58 := "25pRBEBDHvG5ryqsEB5tw6eAa3Ds8bx6jMKhEtXnWjCLNg7ikYokwaNtpggZZY3MvWTxBPCidfxFBq2ZiVVTpioCh6GJLs4iESiEydJca9kmeMkEkqK6ePudqoqLHSv4NA7p" // nolint: lll + privateKeyBytes := hexToBytes(t, "47d2ede63ab4c329092b342ab526b1079dbc2595897d4f2ab2de4d841cbe7d56") + publicKeyBytesExpeted := hexToBytes(t, "b65b7cbff4e81b723456a13936b6bcc77a078bf6291765f3ae13170072249dd7daa7ec1bd82b818ab60198030b45b8fa159c155fc3841a9ad4045e37161c9f0d9a4f361b93cfdc67d365f3be1a398e56aa173d7a55e01b4a8dd2494e7fb90da7") // nolint: lll - privateKey, err := bbs.UnmarshalPrivateKey(base58.Decode(privateKeyB58)) + privateKey, err := bbs.UnmarshalPrivateKey(privateKeyBytes) require.NoError(t, err) publicKeyBytes, err := privateKey.PublicKey().Marshal() - require.Equal(t, publicKeyB58, base58.Encode(publicKeyBytes)) + require.Equal(t, publicKeyBytesExpeted, publicKeyBytes) require.NoError(t, err) }) } func TestGenerators(t *testing.T) { msgCnt := 2 - generators, err := bbs.CreateGenerators(msgCnt + 2) + generators, err := bbs.CreateMessageGenerators(msgCnt + 2) require.NoError(t, err) bytes := bls12381.NewG1().ToCompressed(generators[0]) diff --git a/pkg/crypto/primitive/bbs12381g2pub/signature_message.go b/pkg/crypto/primitive/bbs12381g2pub/signature_message.go index 9f156d3f8..253875ff7 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/signature_message.go +++ b/pkg/crypto/primitive/bbs12381g2pub/signature_message.go @@ -10,6 +10,10 @@ import ( bls12381 "github.com/kilic/bls12-381" ) +const ( + dstMapMsg = csID + "MAP_MSG_TO_SCALAR_AS_HASH_" +) + // SignatureMessage defines a message to be used for a signature check. type SignatureMessage struct { FR *bls12381.Fr @@ -20,7 +24,7 @@ func parseSignatureMessage(message []byte) *SignatureMessage { encodedForHashMsg := newEcnodeForHashBuilder() encodedForHashMsg.addBytes(message) - elm := Hash2scalar(encodedForHashMsg.build()) + elm := hash2scalars(encodedForHashMsg.build(), []byte(dstMapMsg), 1)[0] return &SignatureMessage{ FR: elm, diff --git a/pkg/crypto/primitive/bbs12381g2pub/signature_message_test.go b/pkg/crypto/primitive/bbs12381g2pub/signature_message_test.go new file mode 100644 index 000000000..c952b4717 --- /dev/null +++ b/pkg/crypto/primitive/bbs12381g2pub/signature_message_test.go @@ -0,0 +1,53 @@ +/* +Copyright SecureKey Technologies Inc. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 +*/ + +package bbs12381g2pub_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + bbs "github.com/hyperledger/aries-framework-go/pkg/crypto/primitive/bbs12381g2pub" +) + +func TestParseSignatureMessages(t *testing.T) { + msgs := [][]byte{ + hexToBytes(t, "9872ad089e452c7b6e283dfac2a80d58e8d0ff71cc4d5e310a1debdda4a45f02"), + hexToBytes(t, "87a8bd656d49ee07b8110e1d8fd4f1dcef6fb9bc368c492d9bc8c4f98a739ac6"), + hexToBytes(t, "96012096adda3f13dd4adbe4eea481a4c4b5717932b73b00e31807d3c5894b90"), + hexToBytes(t, "ac55fb33a75909edac8994829b250779298aa75d69324a365733f16c333fa943"), + hexToBytes(t, "d183ddc6e2665aa4e2f088af9297b78c0d22b4290273db637ed33ff5cf703151"), + hexToBytes(t, "515ae153e22aae04ad16f759e07237b43022cb1ced4c176e0999c6a8ba5817cc"), + hexToBytes(t, "496694774c5604ab1b2544eababcf0f53278ff5040c1e77c811656e8220417a2"), + hexToBytes(t, "77fe97eb97a1ebe2e81e4e3597a3ee740a66e9ef2412472c23364568523f8b91"), + hexToBytes(t, "7372e9daa5ed31e6cd5c825eac1b855e84476a1d94932aa348e07b7320912416"), + hexToBytes(t, "c344136d9ab02da4dd5908bbba913ae6f58c2cc844b802a6f811f5fb075f9b80"), + } + + sc := bbs.ParseSignatureMessages(msgs) + + require.Equal(t, + hexToBytes(t, "4e67c49cf68df268bca0624880770bb57dbe8460c89883cc0ac496785b68bbe9"), sc[0].FR.ToBytes()) + require.Equal(t, + hexToBytes(t, "12d92c990f37ffab1c6ac4b0cd83378ffb8a8610259d62d3b885fc4c1bc50f7f"), sc[1].FR.ToBytes()) + require.Equal(t, + hexToBytes(t, "41a157520e8752ca100a365ffde4683fb9610bf105b40933bb98dcacbbd56ace"), sc[2].FR.ToBytes()) + require.Equal(t, + hexToBytes(t, "3344daad11febac28f0f8e3740cd2921fd6da18ebc7e9692a8287cedea5f4bf4"), sc[3].FR.ToBytes()) + require.Equal(t, + hexToBytes(t, "0407198a8ffc4640b840fc924e5308f405ca86035d05366718aafd0b688876f3"), sc[4].FR.ToBytes()) + require.Equal(t, + hexToBytes(t, "1918fa78c85628cb3ac705cc4843197d3fce88c8132d9242d87201e65a4d3743"), sc[5].FR.ToBytes()) + require.Equal(t, + hexToBytes(t, "0a272f853369d70526d7bd37281bb87d1c8db7d0975dd833812bb9d264f4b0eb"), sc[6].FR.ToBytes()) + require.Equal(t, + hexToBytes(t, "00776f91d1ecb5cc01ffe155ae05efea0b820f3d40bada5142bb852f9922b7e1"), sc[7].FR.ToBytes()) + require.Equal(t, + hexToBytes(t, "3902ced42427bca88822f818912d2f4c0d88ba1d1fc7a9b0e2321674a5d53f27"), sc[8].FR.ToBytes()) + require.Equal(t, + hexToBytes(t, "397864d9292b1f4a5fff5fa33088ed8e1a9ec52346dbd5f66ee0f978bd67595d"), sc[9].FR.ToBytes()) +} diff --git a/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go b/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go index 221f9f266..31d2186e6 100644 --- a/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go +++ b/pkg/crypto/primitive/bbs12381g2pub/signature_proof.go @@ -70,9 +70,6 @@ func (sp *PoKOfSignatureProof) verifyVC2Proof(challenge *bls12381.Fr, pubKey *Pu revealedMessages map[int]*SignatureMessage, messages []*SignatureMessage) error { revealedMessagesCount := len(revealedMessages) - bindingBasis := g1.One() - bindingExp := bls12381.NewFr().One() - basesVC2 := make([]*bls12381.PointG1, 0, 2+pubKey.messagesCount-revealedMessagesCount) basesVC2 = append(basesVC2, sp.d, pubKey.q1) @@ -80,8 +77,8 @@ func (sp *PoKOfSignatureProof) verifyVC2Proof(challenge *bls12381.Fr, pubKey *Pu basesDisclosed := make([]*bls12381.PointG1, 0, disclousedElementsCnt) exponentsDisclosed := make([]*bls12381.Fr, 0, disclousedElementsCnt) - basesDisclosed = append(basesDisclosed, bindingBasis, pubKey.q2) - exponentsDisclosed = append(exponentsDisclosed, bindingExp, pubKey.domain) + basesDisclosed = append(basesDisclosed, pubKey.p1, pubKey.q2) + exponentsDisclosed = append(exponentsDisclosed, bls12381.NewFr().One(), pubKey.domain) revealedMessagesInd := 0 From dd5e0c3945f3f1ac0bff2ba577f094885da42485 Mon Sep 17 00:00:00 2001 From: Sergey Minaev Date: Wed, 26 Oct 2022 20:43:31 +0500 Subject: [PATCH 11/11] [3392] Update affected unit tests. Signed-off-by: Sergey Minaev --- .../suite/bbsblssignature2020/public_key_verifier_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/doc/signature/suite/bbsblssignature2020/public_key_verifier_test.go b/pkg/doc/signature/suite/bbsblssignature2020/public_key_verifier_test.go index e1d3b70d4..11ed095e6 100644 --- a/pkg/doc/signature/suite/bbsblssignature2020/public_key_verifier_test.go +++ b/pkg/doc/signature/suite/bbsblssignature2020/public_key_verifier_test.go @@ -20,11 +20,11 @@ import ( func TestNewG2PublicKeyVerifier(t *testing.T) { verifier := NewG2PublicKeyVerifier() - pkBase64 := "lOpN7uGZWivVIjs0325N/V0dAhoPomrgfXVpg7pZNdRWwFwJDVxoE7TvRyOx/Qr7GMtShNuS2Px/oScD+SMf08t8eAO78QRNErPzwNpfkP4ppcSTShStFDfFbsv9L9yb" + pkBase64 := "iQp7qpSrUoYYvtYylMp61k/8/U8JgiFp+sp6AIppkByvsZ4fpbMjWqePcGkXNuKJE+pE2VqTSOs0meYy3JNj12ksKVoP0DF4ZaFgg+Q+8Gw/npZy50TcWvOBPGyHnxRC" pkBytes, err := base64.RawStdEncoding.DecodeString(pkBase64) require.NoError(t, err) - sigBase64 := "hPbLkeMZZ6KKzkjWoTVHeMeuLJfYWjmdAU1Vg5fZ/VZnIXxxeXBB+q0/EL8XQmWkOMMwEGA/D2dCb4MDuntKZpvHEHlvaFR6l1A4bYj0t2Jd6bYwGwCwirNbmSeIoEmJeRzJ1cSvsL+jxvLixdDPnw==" + sigBase64 := "gcwMuYBElR0ESVFWQqerR7Vfb4+6nJ1zF8iM4BPQ+PmSF2kXPkRSaUtkEgpS1KuFLAMwV4L/18Pu1BMWd0YBzY4MssdCwsQYerREXQNzoDJlQf0IEf91Ucdzn6MJecpEbaYvHJC8ciddUUEuVVQlVg==" sigBytes, err := base64.StdEncoding.DecodeString(sigBase64) require.NoError(t, err)