github.com/MetalBlockchain/metalgo@v1.11.9/utils/crypto/bls/secret.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package bls 5 6 import ( 7 "crypto/rand" 8 "errors" 9 "runtime" 10 11 blst "github.com/supranational/blst/bindings/go" 12 ) 13 14 const SecretKeyLen = blst.BLST_SCALAR_BYTES 15 16 var ( 17 errFailedSecretKeyDeserialize = errors.New("couldn't deserialize secret key") 18 19 // The ciphersuite is more commonly known as G2ProofOfPossession. 20 // There are two digests to ensure that message space for normal 21 // signatures and the proof of possession are distinct. 22 ciphersuiteSignature = []byte("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_") 23 ciphersuiteProofOfPossession = []byte("BLS_POP_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_") 24 ) 25 26 type SecretKey = blst.SecretKey 27 28 // NewSecretKey generates a new secret key from the local source of 29 // cryptographically secure randomness. 30 func NewSecretKey() (*SecretKey, error) { 31 var ikm [32]byte 32 _, err := rand.Read(ikm[:]) 33 if err != nil { 34 return nil, err 35 } 36 sk := blst.KeyGen(ikm[:]) 37 ikm = [32]byte{} // zero out the ikm 38 return sk, nil 39 } 40 41 // SecretKeyToBytes returns the big-endian format of the secret key. 42 func SecretKeyToBytes(sk *SecretKey) []byte { 43 return sk.Serialize() 44 } 45 46 // SecretKeyFromBytes parses the big-endian format of the secret key into a 47 // secret key. 48 func SecretKeyFromBytes(skBytes []byte) (*SecretKey, error) { 49 sk := new(SecretKey).Deserialize(skBytes) 50 if sk == nil { 51 return nil, errFailedSecretKeyDeserialize 52 } 53 runtime.SetFinalizer(sk, func(sk *SecretKey) { 54 sk.Zeroize() 55 }) 56 return sk, nil 57 } 58 59 // PublicFromSecretKey returns the public key that corresponds to this secret 60 // key. 61 func PublicFromSecretKey(sk *SecretKey) *PublicKey { 62 return new(PublicKey).From(sk) 63 } 64 65 // Sign [msg] to authorize this message from this [sk]. 66 func Sign(sk *SecretKey, msg []byte) *Signature { 67 return new(Signature).Sign(sk, msg, ciphersuiteSignature) 68 } 69 70 // Sign [msg] to prove the ownership of this [sk]. 71 func SignProofOfPossession(sk *SecretKey, msg []byte) *Signature { 72 return new(Signature).Sign(sk, msg, ciphersuiteProofOfPossession) 73 }