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}