github.com/prysmaticlabs/prysm@v1.4.4/shared/bls/blst/public_key.go (about)

     1  // +build linux,amd64 linux,arm64 darwin,amd64 windows,amd64
     2  // +build !blst_disabled
     3  
     4  package blst
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/dgraph-io/ristretto"
    10  	"github.com/pkg/errors"
    11  	"github.com/prysmaticlabs/prysm/shared/bls/common"
    12  	"github.com/prysmaticlabs/prysm/shared/featureconfig"
    13  	"github.com/prysmaticlabs/prysm/shared/params"
    14  )
    15  
    16  var maxKeys = int64(1000000)
    17  var pubkeyCache, _ = ristretto.NewCache(&ristretto.Config{
    18  	NumCounters: maxKeys,
    19  	MaxCost:     1 << 26, // ~64mb is cache max size
    20  	BufferItems: 64,
    21  })
    22  
    23  // PublicKey used in the BLS signature scheme.
    24  type PublicKey struct {
    25  	p *blstPublicKey
    26  }
    27  
    28  // PublicKeyFromBytes creates a BLS public key from a  BigEndian byte slice.
    29  func PublicKeyFromBytes(pubKey []byte) (common.PublicKey, error) {
    30  	if featureconfig.Get().SkipBLSVerify {
    31  		return &PublicKey{}, nil
    32  	}
    33  	if len(pubKey) != params.BeaconConfig().BLSPubkeyLength {
    34  		return nil, fmt.Errorf("public key must be %d bytes", params.BeaconConfig().BLSPubkeyLength)
    35  	}
    36  	if cv, ok := pubkeyCache.Get(string(pubKey)); ok {
    37  		return cv.(*PublicKey).Copy(), nil
    38  	}
    39  	// Subgroup check NOT done when decompressing pubkey.
    40  	p := new(blstPublicKey).Uncompress(pubKey)
    41  	if p == nil {
    42  		return nil, errors.New("could not unmarshal bytes into public key")
    43  	}
    44  	// Subgroup and infinity check
    45  	if !p.KeyValidate() {
    46  		// NOTE: the error is not quite accurate since it includes group check
    47  		return nil, common.ErrInfinitePubKey
    48  	}
    49  	pubKeyObj := &PublicKey{p: p}
    50  	copiedKey := pubKeyObj.Copy()
    51  	pubkeyCache.Set(string(pubKey), copiedKey, 48)
    52  	return pubKeyObj, nil
    53  }
    54  
    55  // AggregatePublicKeys aggregates the provided raw public keys into a single key.
    56  func AggregatePublicKeys(pubs [][]byte) (common.PublicKey, error) {
    57  	if featureconfig.Get().SkipBLSVerify {
    58  		return &PublicKey{}, nil
    59  	}
    60  	if pubs == nil || len(pubs) == 0 {
    61  		return nil, errors.New("nil or empty public keys")
    62  	}
    63  	agg := new(blstAggregatePublicKey)
    64  	mulP1 := make([]*blstPublicKey, 0, len(pubs))
    65  	for _, pubkey := range pubs {
    66  		pubKeyObj, err := PublicKeyFromBytes(pubkey)
    67  		if err != nil {
    68  			return nil, err
    69  		}
    70  		mulP1 = append(mulP1, pubKeyObj.(*PublicKey).p)
    71  	}
    72  	// No group check needed here since it is done in PublicKeyFromBytes
    73  	// Note the checks could be moved from PublicKeyFromBytes into Aggregate
    74  	// and take advantage of multi-threading.
    75  	agg.Aggregate(mulP1, false)
    76  	return &PublicKey{p: agg.ToAffine()}, nil
    77  }
    78  
    79  // Marshal a public key into a LittleEndian byte slice.
    80  func (p *PublicKey) Marshal() []byte {
    81  	return p.p.Compress()
    82  }
    83  
    84  // Copy the public key to a new pointer reference.
    85  func (p *PublicKey) Copy() common.PublicKey {
    86  	np := *p.p
    87  	return &PublicKey{p: &np}
    88  }
    89  
    90  // IsInfinite checks if the public key is infinite.
    91  func (p *PublicKey) IsInfinite() bool {
    92  	zeroKey := new(blstPublicKey)
    93  	return p.p.Equals(zeroKey)
    94  }
    95  
    96  // Aggregate two public keys.
    97  func (p *PublicKey) Aggregate(p2 common.PublicKey) common.PublicKey {
    98  	if featureconfig.Get().SkipBLSVerify {
    99  		return p
   100  	}
   101  
   102  	agg := new(blstAggregatePublicKey)
   103  	// No group check here since it is checked at decompression time
   104  	agg.Add(p.p, false)
   105  	agg.Add(p2.(*PublicKey).p, false)
   106  	p.p = agg.ToAffine()
   107  
   108  	return p
   109  }