arnaucube
arnaucube/cryptofunPublic Self-hosted repository
cryptofun/bls/bls.go
bls/bls.goRaw
 1package bls
 2
 3import (
 4	"crypto/rand"
 5	"crypto/sha256"
 6	"math/big"
 7
 8	"github.com/arnaucube/go-snark/bn128"
 9)
10
11// this BLS implementation uses the Go implementation of the BN128 pairing github.com/arnaucube/go-snark/bn128
12
13const bits = 2048
14
15// BLS is the data structure of the BLS signature scheme, including the BN128 pairing curve
16type BLS struct {
17	Bn    bn128.Bn128
18	PrivK *big.Int
19	PubK  [3]*big.Int
20}
21
22// NewKeys generate new Private Key and Public Key
23func NewKeys() (BLS, error) {
24	bn, err := bn128.NewBn128()
25	if err != nil {
26		return BLS{}, err
27	}
28	bls := BLS{}
29	bls.Bn = bn
30	bls.PrivK, err = rand.Prime(rand.Reader, bits)
31	if err != nil {
32		return BLS{}, err
33	}
34
35	// pubK = pk * G
36	bls.PubK = bls.Bn.G1.MulScalar(bls.Bn.G1.G, bls.PrivK)
37	return bls, nil
38}
39
40// Hash hashes a message m
41func (bls BLS) Hash(m []byte) [3][2]*big.Int {
42	h := sha256.New()
43	h.Write(m)
44	hash := h.Sum(nil)
45	r := new(big.Int).SetBytes(hash)
46	// get point over the curve
47	point := bls.Bn.G2.MulScalar(bls.Bn.G2.G, r)
48	return point
49}
50
51// Sign performs the BLS signature of a message m
52func (bls BLS) Sign(m []byte) [3][2]*big.Int {
53	// s = pk * H(m)
54	h := bls.Hash(m)
55	sig := bls.Bn.G2.MulScalar(h, bls.PrivK)
56	return sig
57}
58
59// Verify checks the signature of a message m with the given Public Key
60func (bls BLS) Verify(m []byte, sig [3][2]*big.Int, pubK [3]*big.Int) bool {
61	// checks e(P, G) == e(G, s)
62	p1, err := bls.Bn.Pairing(bls.PubK, bls.Hash(m))
63	if err != nil {
64		return false
65	}
66	p2, err := bls.Bn.Pairing(bls.Bn.G1.G, sig)
67	if err != nil {
68		return false
69	}
70
71	return bls.Bn.Fq12.Equal(p1, p2)
72}