From 34a525dd6803acf82da59fa9385cb9c9249fbf7b Mon Sep 17 00:00:00 2001 From: nikkolasg Date: Sat, 28 Dec 2019 17:31:20 +0000 Subject: [PATCH] signed and go.mod --- go.mod | 2 + go.sum | 2 + sign/bls/bls.go | 99 ++++++++++++++++++++++++++++--------------------- sign/sign.go | 23 ++++++++++++ 4 files changed, 83 insertions(+), 43 deletions(-) create mode 100644 sign/sign.go diff --git a/go.mod b/go.mod index 7ab3cdeba..fabbb5bc2 100644 --- a/go.mod +++ b/go.mod @@ -8,4 +8,6 @@ require ( golang.org/x/sys v0.0.0-20190124100055-b90733256f2e ) +replace go.dedis.ch/kyber/v3 => github.com/drand/kyber v3.0.11 + go 1.13 diff --git a/go.sum b/go.sum index dcae93e46..ae6887aa8 100644 --- a/go.sum +++ b/go.sum @@ -9,6 +9,7 @@ go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= go.dedis.ch/kyber/v3 v3.0.4 h1:FDuC/S3STkvwxZ0ooo3gcp56QkUKsN7Jy7cpzBxL+vQ= go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= +go.dedis.ch/kyber/v3 v3.0.9/go.mod h1:rhNjUUg6ahf8HEg5HUvVBYoWY4boAafX8tYxX+PS+qg= go.dedis.ch/kyber/v4 v4.0.0-pre1 h1:1f5OPESkyxK6kPaCSV3J9BlpnoysIpbGLNujX9Ov8m4= go.dedis.ch/kyber/v4 v4.0.0-pre1/go.mod h1:cFStqSeD4d3Y7mal8kCRSq7I7QPeTBA0f5cRl1pqEWA= go.dedis.ch/protobuf v1.0.5 h1:EbF1czEKICxf5KY8Tm7wMF28hcOQbB6yk4IybIFWTYE= @@ -17,6 +18,7 @@ go.dedis.ch/protobuf v1.0.7 h1:wRUEiq3u0/vBhLjcw9CmAVrol+BnDyq2M0XLukdphyI= go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4= go.dedis.ch/protobuf v1.0.10 h1:/8plWfioYRf9sBQdCvoNfLf+XHuQWF1ctC1gWzzmojk= go.dedis.ch/protobuf v1.0.10/go.mod h1:oIXBd4PkP3jxrN9t/eslifGU2tTeG9JuMUjMFrgfcEc= +go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4= golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b h1:Elez2XeF2p9uyVj0yEUDqQ56NFcDtcBNkYP7yv8YbUE= golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/sys v0.0.0-20190124100055-b90733256f2e h1:3GIlrlVLfkoipSReOMNAgApI0ajnalyLa/EZHHca/XI= diff --git a/sign/bls/bls.go b/sign/bls/bls.go index f2abb3c0a..452f1f70e 100644 --- a/sign/bls/bls.go +++ b/sign/bls/bls.go @@ -19,42 +19,79 @@ import ( "go.dedis.ch/kyber/v3" "go.dedis.ch/kyber/v3/pairing" + "go.dedis.ch/kyber/v3/sign" ) type hashablePoint interface { Hash([]byte) kyber.Point } -// NewKeyPair creates a new BLS signing key pair. The private key x is a scalar -// and the public key X is a point on curve G2. -func NewKeyPair(suite pairing.Suite, random cipher.Stream) (kyber.Scalar, kyber.Point) { - x := suite.G2().Scalar().Pick(random) - X := suite.G2().Point().Mul(x, nil) - return x, X +type scheme struct { + sigGroup kyber.Group + keyGroup kyber.Group + pairing func(signature, public, hashedPoint kyber.Point) bool } -// Sign creates a BLS signature S = x * H(m) on a message m using the private -// key x. The signature S is a point on curve G1. -func Sign(suite pairing.Suite, x kyber.Scalar, msg []byte) ([]byte, error) { - hashable, ok := suite.G1().Point().(hashablePoint) +// NewSchemeG1 returns a sign.Scheme that uses G1 for its signature space and G2 +// for its public keys +func NewSchemeOnG1(suite pairing.Suite) sign.AggregatableScheme { + sigGroup := suite.G1() + keyGroup := suite.G2() + pairing := func(public, hashedMsg, sigPoint kyber.Point) bool { + // e ( H(m) , g^x) + left := suite.Pair(hashedMsg, public) + // e ( H(m)^x , g) + right := suite.Pair(sigPoint, suite.G2().Point().Base()) + return left.Equal(right) + } + return &scheme{ + sigGroup: sigGroup, + keyGroup: keyGroup, + pairing: pairing, + } +} + +func (s *scheme) NewKeyPair(random cipher.Stream) (kyber.Scalar, kyber.Point) { + secret := s.keyGroup.Scalar().Pick(random) + public := s.keyGroup.Point().Mul(secret, nil) + return secret, public +} + +func (s *scheme) Sign(private kyber.Scalar, msg []byte) ([]byte, error) { + hashable, ok := s.sigGroup.Point().(hashablePoint) if !ok { return nil, errors.New("point needs to implement hashablePoint") } HM := hashable.Hash(msg) - xHM := HM.Mul(x, HM) + xHM := HM.Mul(private, HM) - s, err := xHM.MarshalBinary() + sig, err := xHM.MarshalBinary() if err != nil { return nil, err } - return s, nil + return sig, nil } -// AggregateSignatures combines signatures created using the Sign function -func AggregateSignatures(suite pairing.Suite, sigs ...[]byte) ([]byte, error) { - sig := suite.G1().Point() +func (s *scheme) Verify(X kyber.Point, msg, sig []byte) error { + hashable, ok := s.sigGroup.Point().(hashablePoint) + if !ok { + return errors.New("bls: point needs to implement hashablePoint") + } + HM := hashable.Hash(msg) + sigPoint := s.sigGroup.Point() + if err := sigPoint.UnmarshalBinary(sig); err != nil { + return err + } + if !s.pairing(X, HM, sigPoint) { + return errors.New("bls: invalid signature") + } + return nil +} + +func (s *scheme) AggregateSignatures(sigs ...[]byte) ([]byte, error) { + sig := s.sigGroup.Point() for _, sigBytes := range sigs { - sigToAdd := suite.G1().Point() + sigToAdd := s.sigGroup.Point() if err := sigToAdd.UnmarshalBinary(sigBytes); err != nil { return nil, err } @@ -63,10 +100,8 @@ func AggregateSignatures(suite pairing.Suite, sigs ...[]byte) ([]byte, error) { return sig.MarshalBinary() } -// AggregatePublicKeys takes a slice of public G2 points and returns -// the sum of those points. This is used to verify multisignatures. -func AggregatePublicKeys(suite pairing.Suite, Xs ...kyber.Point) kyber.Point { - aggregated := suite.G2().Point() +func (s *scheme) AggregatePublicKeys(Xs ...kyber.Point) kyber.Point { + aggregated := s.keyGroup.Point() for _, X := range Xs { aggregated.Add(aggregated, X) } @@ -112,28 +147,6 @@ func BatchVerify(suite pairing.Suite, publics []kyber.Point, msgs [][]byte, sig return nil } -// Verify checks the given BLS signature S on the message m using the public -// key X by verifying that the equality e(H(m), X) == e(H(m), x*B2) == -// e(x*H(m), B2) == e(S, B2) holds where e is the pairing operation and B2 is -// the base point from curve G2. -func Verify(suite pairing.Suite, X kyber.Point, msg, sig []byte) error { - hashable, ok := suite.G1().Point().(hashablePoint) - if !ok { - return errors.New("bls: point needs to implement hashablePoint") - } - HM := hashable.Hash(msg) - left := suite.Pair(HM, X) - s := suite.G1().Point() - if err := s.UnmarshalBinary(sig); err != nil { - return err - } - right := suite.Pair(s, suite.G2().Point().Base()) - if !left.Equal(right) { - return errors.New("bls: invalid signature") - } - return nil -} - func distinct(msgs [][]byte) bool { m := make(map[[32]byte]bool) for _, msg := range msgs { diff --git a/sign/sign.go b/sign/sign.go new file mode 100644 index 000000000..d2a4e606d --- /dev/null +++ b/sign/sign.go @@ -0,0 +1,23 @@ +package sign + +import ( + "crypto/cipher" + + "go.dedis.ch/kyber/v3" +) + +// Scheme is the minimal interface for a signature scheme. +// Implemented by BLS and TBLS +type Scheme interface { + NewKeyPair(random cipher.Stream) (kyber.Scalar, kyber.Point) + Sign(private kyber.Scalar, msg []byte) ([]byte, error) + Verify(public kyber.Point, msg, sig []byte) error +} + +// AggregatableScheme is an interface allowing to aggregate signatures and +// public keys to efficient verification. +type AggregatableScheme interface { + Scheme + AggregateSignatures(sigs ...[]byte) ([]byte, error) + AggregatePublicKeys(Xs ...kyber.Point) kyber.Point +}