github.com/MetalBlockchain/metalgo@v1.11.9/utils/crypto/bls/public.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 "errors" 8 9 blst "github.com/supranational/blst/bindings/go" 10 ) 11 12 const PublicKeyLen = blst.BLST_P1_COMPRESS_BYTES 13 14 var ( 15 ErrNoPublicKeys = errors.New("no public keys") 16 ErrFailedPublicKeyDecompress = errors.New("couldn't decompress public key") 17 errInvalidPublicKey = errors.New("invalid public key") 18 errFailedPublicKeyAggregation = errors.New("couldn't aggregate public keys") 19 ) 20 21 type ( 22 PublicKey = blst.P1Affine 23 AggregatePublicKey = blst.P1Aggregate 24 ) 25 26 // PublicKeyToCompressedBytes returns the compressed big-endian format of the 27 // public key. 28 func PublicKeyToCompressedBytes(pk *PublicKey) []byte { 29 return pk.Compress() 30 } 31 32 // PublicKeyFromCompressedBytes parses the compressed big-endian format of the 33 // public key into a public key. 34 func PublicKeyFromCompressedBytes(pkBytes []byte) (*PublicKey, error) { 35 pk := new(PublicKey).Uncompress(pkBytes) 36 if pk == nil { 37 return nil, ErrFailedPublicKeyDecompress 38 } 39 if !pk.KeyValidate() { 40 return nil, errInvalidPublicKey 41 } 42 return pk, nil 43 } 44 45 // PublicKeyToUncompressedBytes returns the uncompressed big-endian format of 46 // the public key. 47 func PublicKeyToUncompressedBytes(key *PublicKey) []byte { 48 return key.Serialize() 49 } 50 51 // PublicKeyFromValidUncompressedBytes parses the uncompressed big-endian format 52 // of the public key into a public key. It is assumed that the provided bytes 53 // are valid. 54 func PublicKeyFromValidUncompressedBytes(pkBytes []byte) *PublicKey { 55 return new(PublicKey).Deserialize(pkBytes) 56 } 57 58 // AggregatePublicKeys aggregates a non-zero number of public keys into a single 59 // aggregated public key. 60 // Invariant: all [pks] have been validated. 61 func AggregatePublicKeys(pks []*PublicKey) (*PublicKey, error) { 62 if len(pks) == 0 { 63 return nil, ErrNoPublicKeys 64 } 65 66 var agg AggregatePublicKey 67 if !agg.Aggregate(pks, false) { 68 return nil, errFailedPublicKeyAggregation 69 } 70 return agg.ToAffine(), nil 71 } 72 73 // Verify the [sig] of [msg] against the [pk]. 74 // The [sig] and [pk] may have been an aggregation of other signatures and keys. 75 // Invariant: [pk] and [sig] have both been validated. 76 func Verify(pk *PublicKey, sig *Signature, msg []byte) bool { 77 return sig.Verify(false, pk, false, msg, ciphersuiteSignature) 78 } 79 80 // Verify the possession of the secret pre-image of [sk] by verifying a [sig] of 81 // [msg] against the [pk]. 82 // The [sig] and [pk] may have been an aggregation of other signatures and keys. 83 // Invariant: [pk] and [sig] have both been validated. 84 func VerifyProofOfPossession(pk *PublicKey, sig *Signature, msg []byte) bool { 85 return sig.Verify(false, pk, false, msg, ciphersuiteProofOfPossession) 86 }