prysm-pulse/shared/bls/blst/secret_key.go
Preston Van Loon 4ddacd57c6
fix blst build tag (#7443)
* fix blst build tag

* fix fuzz build

* remove buildkite specific bazelrc line

* remove conflicting kafka gotag in CI

* fix again

Co-authored-by: prylabs-bulldozer[bot] <58059840+prylabs-bulldozer[bot]@users.noreply.github.com>
Co-authored-by: Raul Jordan <raul@prysmaticlabs.com>
2020-10-08 18:37:12 +00:00

77 lines
2.3 KiB
Go

// +build linux,amd64 linux,arm64
// +build blst_enabled
package blst
import (
"fmt"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/shared/bls/iface"
"github.com/prysmaticlabs/prysm/shared/featureconfig"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/rand"
blst "github.com/supranational/blst/bindings/go"
)
// bls12SecretKey used in the BLS signature scheme.
type bls12SecretKey struct {
p *blst.SecretKey
}
// RandKey creates a new private key using a random method provided as an io.Reader.
func RandKey() iface.SecretKey {
// Generate 32 bytes of randomness
var ikm [32]byte
_, err := rand.NewGenerator().Read(ikm[:])
if err != nil {
return nil
}
return &bls12SecretKey{blst.KeyGen(ikm[:])}
}
// SecretKeyFromBytes creates a BLS private key from a BigEndian byte slice.
func SecretKeyFromBytes(privKey []byte) (iface.SecretKey, error) {
if len(privKey) != params.BeaconConfig().BLSSecretKeyLength {
return nil, fmt.Errorf("secret key must be %d bytes", params.BeaconConfig().BLSSecretKeyLength)
}
secKey := new(blst.SecretKey).Deserialize(privKey)
if secKey == nil {
return nil, errors.New("could not unmarshal bytes into secret key")
}
return &bls12SecretKey{p: secKey}, nil
}
// PublicKey obtains the public key corresponding to the BLS secret key.
func (s *bls12SecretKey) PublicKey() iface.PublicKey {
return &PublicKey{p: new(blstPublicKey).From(s.p)}
}
// Sign a message using a secret key - in a beacon/validator client.
//
// In IETF draft BLS specification:
// Sign(SK, message) -> signature: a signing algorithm that generates
// a deterministic signature given a secret key SK and a message.
//
// In ETH2.0 specification:
// def Sign(SK: int, message: Bytes) -> BLSSignature
func (s *bls12SecretKey) Sign(msg []byte) iface.Signature {
if featureconfig.Get().SkipBLSVerify {
return &Signature{}
}
signature := new(blstSignature).Sign(s.p, msg, dst)
return &Signature{s: signature}
}
// Marshal a secret key into a LittleEndian byte slice.
func (s *bls12SecretKey) Marshal() []byte {
keyBytes := s.p.Serialize()
if len(keyBytes) < params.BeaconConfig().BLSSecretKeyLength {
emptyBytes := make([]byte, params.BeaconConfig().BLSSecretKeyLength-len(keyBytes))
keyBytes = append(emptyBytes, keyBytes...)
}
return keyBytes
}