lotus/lib/sigs/bls/init.go

87 lines
2.0 KiB
Go

package bls
import (
"crypto/rand"
"fmt"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/crypto"
ffi "github.com/filecoin-project/filecoin-ffi"
"github.com/filecoin-project/lotus/lib/sigs"
)
const DST = string("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_")
type SecretKey = ffi.PrivateKey
type PublicKey = ffi.PublicKey
type Signature = ffi.Signature
type AggregateSignature = ffi.Signature
type blsSigner struct{}
func (blsSigner) GenPrivate() ([]byte, error) {
// Generate 32 bytes of randomness
var ikm [32]byte
_, err := rand.Read(ikm[:])
if err != nil {
return nil, fmt.Errorf("bls signature error generating random data")
}
// Note private keys seem to be serialized little-endian!
sk := ffi.PrivateKeyGenerateWithSeed(ikm)
return ([]byte)(sk[:]), nil
}
func (blsSigner) ToPublic(priv []byte) ([]byte, error) {
if priv == nil || len(priv) != ffi.PrivateKeyBytes {
return nil, fmt.Errorf("bls signature invalid private key")
}
sk := new(SecretKey)
copy(sk[:], priv[:ffi.PrivateKeyBytes])
pubkey := ffi.PrivateKeyPublicKey(*sk)
return ([]byte)(pubkey[:]), nil
}
func (blsSigner) Sign(p []byte, msg []byte) ([]byte, error) {
if p == nil || len(p) != ffi.PrivateKeyBytes {
return nil, fmt.Errorf("bls signature invalid private key")
}
sk := new(SecretKey)
copy(sk[:], p[:ffi.PrivateKeyBytes])
sig := ffi.PrivateKeySign(*sk, msg)
return ([]byte)(sig[:]), nil
}
func (blsSigner) Verify(sig []byte, a address.Address, msg []byte) error {
payload := a.Payload()
if sig == nil || len(sig) != ffi.SignatureBytes || len(payload) != ffi.PublicKeyBytes {
return fmt.Errorf("bls signature failed to verify")
}
pk := new(PublicKey)
copy(pk[:], payload[:ffi.PublicKeyBytes])
sigS := new(Signature)
copy(sigS[:], sig[:ffi.SignatureBytes])
msgs := [1]ffi.Message{msg}
pks := [1]PublicKey{*pk}
if !ffi.HashVerify(sigS, msgs[:], pks[:]) {
return fmt.Errorf("bls signature failed to verify")
}
return nil
}
func init() {
sigs.RegisterSignature(crypto.SigTypeBLS, blsSigner{})
}