github.com/cloudflare/circl@v1.5.0/sign/bls/bls.go (about)

     1  // Package bls provides BLS signatures using the BLS12-381 pairing curve.
     2  //
     3  // This packages implements the IETF/CFRG draft for BLS signatures [1].
     4  // Currently only the BASIC mode (one of the three modes specified
     5  // in the draft) is supported. The pairing function is instantiated
     6  // with the BLS12-381 curve.
     7  //
     8  // # Groups
     9  //
    10  // The BLS signature scheme can be instantiated with keys in one of the
    11  // two groups: G1 or G2, which correspond to the input domain of a pairing
    12  // function e(G1,G2) -> Gt.
    13  // Thus, choosing keys in G1 implies that signature values are internally
    14  // represented in G2; or viceversa. Use the types KeyG1SigG2 or KeyG2SigG1
    15  // to express this preference.
    16  //
    17  // # Serialization
    18  //
    19  // The serialization of elements in G1 and G2 follows the recommendation
    20  // given in [2], in order to be compatible with other implementations of
    21  // BLS12-381 curve.
    22  //
    23  // # References
    24  //
    25  // [1] https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-05
    26  //
    27  // [2] https://github.com/zkcrypto/bls12_381/blob/0.7.0/src/notes/serialization.rs
    28  package bls
    29  
    30  import (
    31  	"crypto"
    32  	"crypto/sha256"
    33  	"encoding/binary"
    34  	"errors"
    35  	"io"
    36  
    37  	GG "github.com/cloudflare/circl/ecc/bls12381"
    38  	"golang.org/x/crypto/hkdf"
    39  )
    40  
    41  var (
    42  	ErrInvalid    = errors.New("bls: invalid BLS instance")
    43  	ErrInvalidKey = errors.New("bls: invalid key")
    44  	ErrKeyGen     = errors.New("bls: too many unsuccessful key generation tries")
    45  	ErrShortIKM   = errors.New("bls: IKM material shorter than 32 bytes")
    46  	ErrAggregate  = errors.New("bls: error while aggregating signatures")
    47  )
    48  
    49  const (
    50  	dstG1 = "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_"
    51  	dstG2 = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_"
    52  )
    53  
    54  type Signature = []byte
    55  
    56  type (
    57  	// G1 group used for keys defined in pairing group G1.
    58  	G1 struct{ g GG.G1 }
    59  	// G2 group used for keys defined in pairing group G2.
    60  	G2 struct{ g GG.G2 }
    61  	// KeyG1SigG2 sets the keys to G1 and signatures to G2.
    62  	KeyG1SigG2 = G1
    63  	// KeyG2SigG1 sets the keys to G2 and signatures to G1.
    64  	KeyG2SigG1 = G2
    65  )
    66  
    67  func (f *G1) setBytes(b []byte) error { return f.g.SetBytes(b) }
    68  func (f *G2) setBytes(b []byte) error { return f.g.SetBytes(b) }
    69  
    70  func (f *G1) hash(msg []byte) { f.g.Hash(msg, []byte(dstG1)) }
    71  func (f *G2) hash(msg []byte) { f.g.Hash(msg, []byte(dstG2)) }
    72  
    73  // KeyGroup determines the group used for keys, while the other
    74  // group is used for signatures.
    75  type KeyGroup interface{ G1 | G2 }
    76  
    77  type PrivateKey[K KeyGroup] struct {
    78  	key GG.Scalar
    79  	pub *PublicKey[K]
    80  }
    81  
    82  type PublicKey[K KeyGroup] struct{ key K }
    83  
    84  func (k *PrivateKey[K]) Public() crypto.PublicKey { return k.PublicKey() }
    85  
    86  // PublicKey computes the corresponding public key. The key is cached
    87  // for further invocations to this function.
    88  func (k *PrivateKey[K]) PublicKey() *PublicKey[K] {
    89  	if k.pub == nil {
    90  		k.pub = new(PublicKey[K])
    91  		switch any(k).(type) {
    92  		case *PrivateKey[G1]:
    93  			kk := any(&k.pub.key).(*G1)
    94  			kk.g.ScalarMult(&k.key, GG.G1Generator())
    95  		case *PrivateKey[G2]:
    96  			kk := any(&k.pub.key).(*G2)
    97  			kk.g.ScalarMult(&k.key, GG.G2Generator())
    98  		default:
    99  			panic(ErrInvalid)
   100  		}
   101  	}
   102  
   103  	return k.pub
   104  }
   105  
   106  func (k *PrivateKey[K]) Equal(x crypto.PrivateKey) bool {
   107  	xx, ok := x.(*PrivateKey[K])
   108  	if !ok {
   109  		return false
   110  	}
   111  
   112  	switch any(k).(type) {
   113  	case *PrivateKey[G1], *PrivateKey[G2]:
   114  		return k.key.IsEqual(&xx.key) == 1
   115  	default:
   116  		panic(ErrInvalid)
   117  	}
   118  }
   119  
   120  // Validate explicitly determines if a private key is valid.
   121  func (k *PrivateKey[K]) Validate() bool {
   122  	switch any(k).(type) {
   123  	case *PrivateKey[G1], *PrivateKey[G2]:
   124  		return k.key.IsZero() == 0
   125  	default:
   126  		panic(ErrInvalid)
   127  	}
   128  }
   129  
   130  // MarshalBinary returns a slice with the representation of
   131  // the underlying PrivateKey scalar (in big-endian order).
   132  func (k *PrivateKey[K]) MarshalBinary() ([]byte, error) {
   133  	switch any(k).(type) {
   134  	case *PrivateKey[G1], *PrivateKey[G2]:
   135  		return k.key.MarshalBinary()
   136  	default:
   137  		panic(ErrInvalid)
   138  	}
   139  }
   140  
   141  func (k *PrivateKey[K]) UnmarshalBinary(data []byte) error {
   142  	switch any(k).(type) {
   143  	case *PrivateKey[G1], *PrivateKey[G2]:
   144  		if err := k.key.UnmarshalBinary(data); err != nil {
   145  			return err
   146  		}
   147  		if !k.Validate() {
   148  			return ErrInvalidKey
   149  		}
   150  		k.pub = nil
   151  		return nil
   152  	default:
   153  		panic(ErrInvalid)
   154  	}
   155  }
   156  
   157  // Validate explicitly determines if a public key is valid.
   158  func (k *PublicKey[K]) Validate() bool {
   159  	switch any(k).(type) {
   160  	case *PublicKey[G1]:
   161  		kk := any(k.key).(G1)
   162  		return !kk.g.IsIdentity() && kk.g.IsOnG1()
   163  	case *PublicKey[G2]:
   164  		kk := any(k.key).(G2)
   165  		return !kk.g.IsIdentity() && kk.g.IsOnG2()
   166  	default:
   167  		panic(ErrInvalid)
   168  	}
   169  }
   170  
   171  func (k *PublicKey[K]) Equal(x crypto.PublicKey) bool {
   172  	xx, ok := x.(*PublicKey[K])
   173  	if !ok {
   174  		return false
   175  	}
   176  
   177  	switch any(k).(type) {
   178  	case *PublicKey[G1]:
   179  		xxx := any(xx.key).(G1)
   180  		kk := any(k.key).(G1)
   181  		return kk.g.IsEqual(&xxx.g)
   182  	case *PublicKey[G2]:
   183  		xxx := any(xx.key).(G2)
   184  		kk := any(k.key).(G2)
   185  		return kk.g.IsEqual(&xxx.g)
   186  	default:
   187  		panic(ErrInvalid)
   188  	}
   189  }
   190  
   191  // MarshalBinary returns a slice with the compressed
   192  // representation of the underlying element in G1 or G2.
   193  func (k *PublicKey[K]) MarshalBinary() ([]byte, error) {
   194  	switch any(k).(type) {
   195  	case *PublicKey[G1]:
   196  		kk := any(k.key).(G1)
   197  		return kk.g.BytesCompressed(), nil
   198  	case *PublicKey[G2]:
   199  		kk := any(k.key).(G2)
   200  		return kk.g.BytesCompressed(), nil
   201  	default:
   202  		panic(ErrInvalid)
   203  	}
   204  }
   205  
   206  func (k *PublicKey[K]) UnmarshalBinary(data []byte) error {
   207  	switch any(k).(type) {
   208  	case *PublicKey[G1]:
   209  		kk := any(&k.key).(*G1)
   210  		return kk.setBytes(data)
   211  	case *PublicKey[G2]:
   212  		kk := any(&k.key).(*G2)
   213  		return kk.setBytes(data)
   214  	default:
   215  		panic(ErrInvalid)
   216  	}
   217  }
   218  
   219  // KeyGen derives a private key for the specified group (G1 or G2).
   220  // The length of ikm material should be at least 32 bytes length.
   221  // The salt value should be either empty or a uniformly random
   222  // bytes whose length equals the output length of SHA-256.
   223  func KeyGen[K KeyGroup](ikm, salt, keyInfo []byte) (*PrivateKey[K], error) {
   224  	// Implements recommended method at:
   225  	// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-05#name-keygen
   226  	if len(ikm) < 32 {
   227  		return nil, ErrShortIKM
   228  	}
   229  
   230  	ikmZero := make([]byte, len(ikm)+1)
   231  	keyInfoTwo := make([]byte, len(keyInfo)+2)
   232  	copy(ikmZero, ikm)
   233  	copy(keyInfoTwo, keyInfo)
   234  	const L = uint16(48)
   235  	binary.BigEndian.PutUint16(keyInfoTwo[len(keyInfo):], L)
   236  	OKM := make([]byte, L)
   237  
   238  	var ss GG.Scalar
   239  	for tries := 8; tries > 0; tries-- {
   240  		rd := hkdf.New(sha256.New, ikmZero, salt, keyInfoTwo)
   241  		n, err := io.ReadFull(rd, OKM)
   242  		if n != len(OKM) || err != nil {
   243  			return nil, err
   244  		}
   245  
   246  		ss.SetBytes(OKM)
   247  
   248  		if ss.IsZero() == 1 {
   249  			digest := sha256.Sum256(salt)
   250  			salt = digest[:]
   251  		} else {
   252  			return &PrivateKey[K]{key: ss, pub: nil}, nil
   253  		}
   254  	}
   255  
   256  	return nil, ErrKeyGen
   257  }
   258  
   259  // Sign computes a signature of a message using a key (defined in
   260  // G1 or G1).
   261  func Sign[K KeyGroup](k *PrivateKey[K], msg []byte) Signature {
   262  	if !k.Validate() {
   263  		panic(ErrInvalidKey)
   264  	}
   265  
   266  	switch any(k).(type) {
   267  	case *PrivateKey[G1]:
   268  		var Q GG.G2
   269  		Q.Hash(msg, []byte(dstG2))
   270  		Q.ScalarMult(&k.key, &Q)
   271  		return Q.BytesCompressed()
   272  	case *PrivateKey[G2]:
   273  		var Q GG.G1
   274  		Q.Hash(msg, []byte(dstG1))
   275  		Q.ScalarMult(&k.key, &Q)
   276  		return Q.BytesCompressed()
   277  	default:
   278  		panic(ErrInvalid)
   279  	}
   280  }
   281  
   282  // Verify returns true if the signature of a message is valid for the
   283  // corresponding public key.
   284  func Verify[K KeyGroup](pub *PublicKey[K], msg []byte, sig Signature) bool {
   285  	var (
   286  		a, b interface {
   287  			setBytes([]byte) error
   288  			hash([]byte)
   289  		}
   290  		listG1 [2]*GG.G1
   291  		listG2 [2]*GG.G2
   292  	)
   293  
   294  	switch any(pub).(type) {
   295  	case *PublicKey[G1]:
   296  		aa, bb := new(G2), new(G2)
   297  		a, b = aa, bb
   298  		k := any(pub.key).(G1)
   299  		listG1[0], listG1[1] = &k.g, GG.G1Generator()
   300  		listG2[0], listG2[1] = &aa.g, &bb.g
   301  	case *PublicKey[G2]:
   302  		aa, bb := new(G1), new(G1)
   303  		a, b = aa, bb
   304  		k := any(pub.key).(G2)
   305  		listG2[0], listG2[1] = &k.g, GG.G2Generator()
   306  		listG1[0], listG1[1] = &aa.g, &bb.g
   307  	default:
   308  		panic(ErrInvalid)
   309  	}
   310  
   311  	err := b.setBytes(sig)
   312  	if err != nil {
   313  		return false
   314  	}
   315  	if !pub.Validate() {
   316  		return false
   317  	}
   318  	a.hash(msg)
   319  
   320  	res := GG.ProdPairFrac(listG1[:], listG2[:], []int{1, -1})
   321  	return res.IsIdentity()
   322  }
   323  
   324  // Aggregate produces a unified signature given a list of signatures.
   325  // To specify the group of keys pass either G1{} or G2{} as the first
   326  // parameter.
   327  func Aggregate[K KeyGroup](k K, sigs []Signature) (Signature, error) {
   328  	if len(sigs) == 0 {
   329  		return nil, ErrAggregate
   330  	}
   331  
   332  	switch any(k).(type) {
   333  	case G1:
   334  		var P, Q GG.G2
   335  		P.SetIdentity()
   336  		for _, sig := range sigs {
   337  			if err := Q.SetBytes(sig); err != nil {
   338  				return nil, err
   339  			}
   340  			P.Add(&P, &Q)
   341  		}
   342  		return P.BytesCompressed(), nil
   343  
   344  	case G2:
   345  		var P, Q GG.G1
   346  		P.SetIdentity()
   347  		for _, sig := range sigs {
   348  			if err := Q.SetBytes(sig); err != nil {
   349  				return nil, err
   350  			}
   351  			P.Add(&P, &Q)
   352  		}
   353  		return P.BytesCompressed(), nil
   354  
   355  	default:
   356  		panic(ErrInvalid)
   357  	}
   358  }
   359  
   360  // VerifyAggregate returns true if the aggregated signature is valid for
   361  // the list of messages and public keys provided. The slices must have
   362  // equal size and have at least one element.
   363  func VerifyAggregate[K KeyGroup](pubs []*PublicKey[K], msgs [][]byte, aggSig Signature) bool {
   364  	if len(pubs) != len(msgs) || len(pubs) == 0 {
   365  		return false
   366  	}
   367  
   368  	for _, p := range pubs {
   369  		if !p.Validate() {
   370  			return false
   371  		}
   372  	}
   373  
   374  	n := len(pubs)
   375  	listG1 := make([]*GG.G1, n+1)
   376  	listG2 := make([]*GG.G2, n+1)
   377  	listSigns := make([]int, n+1)
   378  
   379  	listG1[n] = GG.G1Generator()
   380  	listG2[n] = GG.G2Generator()
   381  	listSigns[n] = -1
   382  
   383  	switch any(pubs).(type) {
   384  	case []*PublicKey[G1]:
   385  		for i := range msgs {
   386  			listG2[i] = new(GG.G2)
   387  			listG2[i].Hash(msgs[i], []byte(dstG2))
   388  
   389  			xP := any(pubs[i].key).(G1)
   390  			listG1[i] = &xP.g
   391  			listSigns[i] = 1
   392  		}
   393  
   394  		err := listG2[n].SetBytes(aggSig)
   395  		if err != nil {
   396  			return false
   397  		}
   398  
   399  	case []*PublicKey[G2]:
   400  		for i := range msgs {
   401  			listG1[i] = new(GG.G1)
   402  			listG1[i].Hash(msgs[i], []byte(dstG1))
   403  
   404  			xP := any(pubs[i].key).(G2)
   405  			listG2[i] = &xP.g
   406  			listSigns[i] = 1
   407  		}
   408  
   409  		err := listG1[n].SetBytes(aggSig)
   410  		if err != nil {
   411  			return false
   412  		}
   413  
   414  	default:
   415  		panic(ErrInvalid)
   416  	}
   417  
   418  	C := GG.ProdPairFrac(listG1, listG2, listSigns)
   419  	return C.IsIdentity()
   420  }