You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
1.6 KiB

package bls
import (
"crypto/rand"
"crypto/sha256"
"math/big"
"github.com/arnaucube/go-snark/bn128"
)
// this BLS implementation uses the Go implementation of the BN128 pairing github.com/arnaucube/go-snark/bn128
const bits = 2048
// BLS is the data structure of the BLS signature scheme, including the BN128 pairing curve
type BLS struct {
Bn bn128.Bn128
PrivK *big.Int
PubK [3]*big.Int
}
// NewKeys generate new Private Key and Public Key
func NewKeys() (BLS, error) {
bn, err := bn128.NewBn128()
if err != nil {
return BLS{}, err
}
bls := BLS{}
bls.Bn = bn
bls.PrivK, err = rand.Prime(rand.Reader, bits)
if err != nil {
return BLS{}, err
}
// pubK = pk * G
bls.PubK = bls.Bn.G1.MulScalar(bls.Bn.G1.G, bls.PrivK)
return bls, nil
}
// Hash hashes a message m
func (bls BLS) Hash(m []byte) [3][2]*big.Int {
h := sha256.New()
h.Write(m)
hash := h.Sum(nil)
r := new(big.Int).SetBytes(hash)
// get point over the curve
point := bls.Bn.G2.MulScalar(bls.Bn.G2.G, r)
return point
}
// Sign performs the BLS signature of a message m
func (bls BLS) Sign(m []byte) [3][2]*big.Int {
// s = pk * H(m)
h := bls.Hash(m)
sig := bls.Bn.G2.MulScalar(h, bls.PrivK)
return sig
}
// Verify checks the signature of a message m with the given Public Key
func (bls BLS) Verify(m []byte, sig [3][2]*big.Int, pubK [3]*big.Int) bool {
// checks e(P, G) == e(G, s)
p1, err := bls.Bn.Pairing(bls.PubK, bls.Hash(m))
if err != nil {
return false
}
p2, err := bls.Bn.Pairing(bls.Bn.G1.G, sig)
if err != nil {
return false
}
return bls.Bn.Fq12.Equal(p1, p2)
}