arnaucube
arnaucube/cryptofunPublic Self-hosted repository
cryptofun/bls/bls.go
bls/bls.goRaw
  1package bls
  2
  3import (
  4	"crypto/rand"
  5	"crypto/sha256"
  6	"fmt"
  7	"math/big"
  8
  9	"github.com/arnaucube/go-snark/bn128"
 10)
 11
 12// this BLS implementation uses the Go implementation of the BN128 pairing github.com/arnaucube/go-snark/bn128
 13
 14const bits = 2048
 15
 16// BLS is the data structure of the BLS signature scheme, including the BN128 pairing curve
 17type BLS struct {
 18	Bn bn128.Bn128
 19}
 20type BLSKeys struct {
 21	PrivK *big.Int
 22	PubK  [3]*big.Int
 23}
 24
 25// NewBLS generates a new BLS scheme
 26func NewBLS() (BLS, error) {
 27	bn, err := bn128.NewBn128()
 28	if err != nil {
 29		return BLS{}, err
 30	}
 31	bls := BLS{}
 32	bls.Bn = bn
 33	return bls, nil
 34}
 35
 36// NewKeys generate new Private Key and Public Key
 37func (bls BLS) NewKeys() (BLSKeys, error) {
 38	var err error
 39	k := BLSKeys{}
 40	k.PrivK, err = rand.Prime(rand.Reader, bits)
 41	if err != nil {
 42		return BLSKeys{}, err
 43	}
 44
 45	// pubK = pk * G
 46	k.PubK = bls.Bn.G1.MulScalar(bls.Bn.G1.G, k.PrivK)
 47	return k, nil
 48}
 49
 50// Hash hashes a message m
 51func (bls BLS) Hash(m []byte) [3][2]*big.Int {
 52	h := sha256.New()
 53	h.Write(m)
 54	hash := h.Sum(nil)
 55	r := new(big.Int).SetBytes(hash)
 56	// get point over the curve
 57	point := bls.Bn.G2.MulScalar(bls.Bn.G2.G, r)
 58	return point
 59}
 60
 61// Sign performs the BLS signature of a message m
 62func (bls BLS) Sign(privK *big.Int, m []byte) [3][2]*big.Int {
 63	// s = pk * H(m)
 64	h := bls.Hash(m)
 65	sig := bls.Bn.G2.MulScalar(h, privK)
 66	return sig
 67}
 68
 69// Verify checks the signature of a message m with the given Public Key
 70func (bls BLS) Verify(m []byte, sig [3][2]*big.Int, pubK [3]*big.Int) bool {
 71	// checks e(P, G) == e(G, s)
 72	p1, err := bls.Bn.Pairing(pubK, bls.Hash(m))
 73	if err != nil {
 74		return false
 75	}
 76	p2, err := bls.Bn.Pairing(bls.Bn.G1.G, sig)
 77	if err != nil {
 78		return false
 79	}
 80
 81	return bls.Bn.Fq12.Equal(p1, p2)
 82}
 83
 84func (bls BLS) AggregateSignatures(signatures ...[3][2]*big.Int) [3][2]*big.Int {
 85	aggr := signatures[0]
 86	for _, sig := range signatures {
 87		aggr = bls.Bn.G2.Add(aggr, sig)
 88	}
 89	return aggr
 90}
 91func (bls BLS) VerifyAggregatedSignatures(aggrsig [3][2]*big.Int, pubKArray [][3]*big.Int, mArray [][]byte) bool {
 92	if len(pubKArray) != len(mArray) {
 93		fmt.Println("pubK array and msg array not with the same number of elements")
 94		return false
 95	}
 96	pairingGS, err := bls.Bn.Pairing(bls.Bn.G1.G, aggrsig)
 97	if err != nil {
 98		return false
 99	}
100	pairingsMul, err := bls.Bn.Pairing(pubKArray[0], bls.Hash(mArray[0]))
101	if err != nil {
102		return false
103	}
104
105	for i := 1; i < len(pubKArray); i++ {
106		e, err := bls.Bn.Pairing(pubKArray[i], bls.Hash(mArray[i]))
107		if err != nil {
108			return false
109		}
110		pairingsMul = bls.Bn.Fq12.Mul(pairingsMul, e)
111	}
112	if !bls.Bn.Fq12.Equal(pairingGS, pairingsMul) {
113		return false
114	}
115	return true
116}