Documentation ¶
Index ¶
- Constants
- func DecodeDoubleSig(sigData []byte) (crypto.Signature, crypto.Signature, error)
- func DecodeSingleSig(sigData []byte) (hotstuff.SigType, crypto.Signature, error)
- func EncodeDoubleSig(stakingSig crypto.Signature, beaconSig crypto.Signature) []byte
- func EncodeSingleSig(sigType hotstuff.SigType, sig crypto.Signature) []byte
- func NewRandomBeaconInspector(groupPublicKey crypto.PublicKey, publicKeyShares []crypto.PublicKey, ...) (*randomBeaconInspector, error)
- type ConsensusSigDataPacker
- type EpochAwareRandomBeaconKeyStore
- type RandomBeaconReconstructor
- type StaticRandomBeaconSignerStore
- type WeightedSignatureAggregator
- func (w *WeightedSignatureAggregator) Aggregate() ([]flow.Identifier, []byte, error)
- func (w *WeightedSignatureAggregator) TotalWeight() uint64
- func (w *WeightedSignatureAggregator) TrustedAdd(signerID flow.Identifier, sig crypto.Signature) (uint64, error)
- func (w *WeightedSignatureAggregator) Verify(signerID flow.Identifier, sig crypto.Signature) error
Constants ¶
const SigLen = crypto.SignatureLenBLSBLS12381
Variables ¶
This section is empty.
Functions ¶
func DecodeDoubleSig ¶
TODO: to be removed in V3, replace by packer's unpack method DecodeDoubleSig decodes the signature data into a staking signature and an optional random beacon signature. The decoding assumes BLS with BLS12-381 is used. Cryptographic validity of signatures is _not_ checked. Decomposition of the sigData is purely done based on length. It returns:
- staking signature, random beacon signature, nil: if sigData is twice the size of a BLS signature bytes long, we use the leading half as staking signature and the tailing half random beacon sig
- staking signature, nil, nil: if sigData is the size of a BLS signature, we interpret sigData entirely as staking signature
- nil, nil, ErrInvalidFormat if the sig type is invalid (covers nil or empty sigData)
func DecodeSingleSig ¶
DecodeSingleSig decodes the signature data into a cryptographic signature and a type as required by the consensus design. Cryptographic validity of signatures is _not_ checked. It returns:
- 0, nil, ErrInvalidFormat if the sig type is invalid (covers nil or empty sigData)
- sigType, signature, nil if the sig type is valid and the decoding is done successfully.
func EncodeDoubleSig ¶
TODO: to be removed in V3, replace by packer's pack method EncodeDoubleSig encodes both the staking signature and random beacon signature into one sigData.
func EncodeSingleSig ¶
EncodeSingleSig encodes a single signature into signature data as required by the consensus design.
func NewRandomBeaconInspector ¶
func NewRandomBeaconInspector( groupPublicKey crypto.PublicKey, publicKeyShares []crypto.PublicKey, threshold int, message []byte, ) (*randomBeaconInspector, error)
NewRandomBeaconInspector instantiates a new randomBeaconInspector. The constructor errors with a `model.ConfigurationError` in any of the following cases
- n is not between `ThresholdSignMinSize` and `ThresholdSignMaxSize`, for n the number of participants `n := len(publicKeyShares)`
- threshold value is not in interval [1, n-1]
- any input public key is not a BLS key
Types ¶
type ConsensusSigDataPacker ¶
type ConsensusSigDataPacker struct { packer.SigDataPacker // contains filtered or unexported fields }
ConsensusSigDataPacker implements the hotstuff.Packer interface. The encoding method is RLP.
func NewConsensusSigDataPacker ¶
func NewConsensusSigDataPacker(committees hotstuff.Committee) *ConsensusSigDataPacker
func (*ConsensusSigDataPacker) Pack ¶
func (p *ConsensusSigDataPacker) Pack(blockID flow.Identifier, sig *hotstuff.BlockSignatureData) ([]flow.Identifier, []byte, error)
Pack serializes the block signature data into raw bytes, suitable to creat a QC. To pack the block signature data, we first build a compact data type, and then encode it into bytes. Expected error returns during normal operations:
- none; all errors are symptoms of inconsistent input data or corrupted internal state.
func (*ConsensusSigDataPacker) Unpack ¶
func (p *ConsensusSigDataPacker) Unpack(blockID flow.Identifier, signerIDs []flow.Identifier, sigData []byte) (*hotstuff.BlockSignatureData, error)
Unpack de-serializes the provided signature data. blockID is the block that the aggregated sig is signed for sig is the aggregated signature data It returns:
- (sigData, nil) if successfully unpacked the signature data
- (nil, model.ErrInvalidFormat) if failed to unpack the signature data
type EpochAwareRandomBeaconKeyStore ¶
type EpochAwareRandomBeaconKeyStore struct {
// contains filtered or unexported fields
}
EpochAwareRandomBeaconKeyStore provides an abstraction to query random beacon private key for a given view. Internally it indexes and caches the private keys by epoch.
func NewEpochAwareRandomBeaconKeyStore ¶
func NewEpochAwareRandomBeaconKeyStore(epochLookup module.EpochLookup, keys storage.SafeBeaconKeys) *EpochAwareRandomBeaconKeyStore
func (*EpochAwareRandomBeaconKeyStore) ByView ¶
func (s *EpochAwareRandomBeaconKeyStore) ByView(view uint64) (crypto.PrivateKey, error)
ByView returns the random beacon signer for signing objects at a given view. The view determines the epoch, which determines the DKG private key underlying the signer. It returns:
- (signer, nil) if DKG succeeded locally in the epoch of the view, signer is not nil
- (nil, protocol.ErrEpochNotCommitted) if no epoch found for given view
- (nil, DKGFailError) if DKG failed locally in the epoch of the view
- (nil, error) if there is any exception
type RandomBeaconReconstructor ¶
type RandomBeaconReconstructor struct { hotstuff.RandomBeaconInspector // a stateful object for this epoch. It's used for both verifying all sig shares and reconstructing the threshold signature. // contains filtered or unexported fields }
RandomBeaconReconstructor implements hotstuff.RandomBeaconReconstructor. The implementation wraps the hotstuff.RandomBeaconInspector and translates the signer identity into signer index. It has knowledge about DKG to be able to map signerID to signerIndex
func NewRandomBeaconReconstructor ¶
func NewRandomBeaconReconstructor(dkg hotstuff.DKG, randomBeaconInspector hotstuff.RandomBeaconInspector) *RandomBeaconReconstructor
func (*RandomBeaconReconstructor) TrustedAdd ¶
func (r *RandomBeaconReconstructor) TrustedAdd(signerID flow.Identifier, sig crypto.Signature) (bool, error)
TrustedAdd adds a share to the internal signature shares store. There is no pre-check of the signature's validity _before_ adding it. It is the caller's responsibility to make sure the signature was previously verified. Nevertheless, the implementation guarantees safety (only correct threshold signatures are returned) through a post-check (verifying the threshold signature _after_ reconstruction before returning it). The function is thread-safe but locks its internal state, thereby permitting only one routine at a time to add a signature. Returns:
- (true, nil) if the signature has been added, and enough shares have been collected.
- (false, nil) if the signature has been added, but not enough shares were collected.
- (false, error) if there is any exception adding the signature share.
- model.InvalidSignerError if signerIndex is invalid (out of the valid range)
- model.DuplicatedSignerError if the signer has been already added
- other error if there is an unexpected exception.
func (*RandomBeaconReconstructor) Verify ¶
func (r *RandomBeaconReconstructor) Verify(signerID flow.Identifier, sig crypto.Signature) error
Verify verifies the signature share under the signer's public key and the message agreed upon. The function is thread-safe and wait-free (i.e. allowing arbitrary many routines to execute the business logic, without interfering with each other). It allows concurrent verification of the given signature. Returns :
- model.InvalidSignerError if signerID is invalid
- model.ErrInvalidSignature if signerID is valid but signature is cryptographically invalid
- other error if there is an unexpected exception.
type StaticRandomBeaconSignerStore ¶
type StaticRandomBeaconSignerStore struct {
// contains filtered or unexported fields
}
StaticRandomBeaconSignerStore is a simple implementation of module.RandomBeaconKeyStore that returns same key for each view. This structure was implemented for bootstrap process and should be used only for it.
func NewStaticRandomBeaconSignerStore ¶
func NewStaticRandomBeaconSignerStore(beaconKey crypto.PrivateKey) *StaticRandomBeaconSignerStore
func (*StaticRandomBeaconSignerStore) ByView ¶
func (s *StaticRandomBeaconSignerStore) ByView(_ uint64) (crypto.PrivateKey, error)
type WeightedSignatureAggregator ¶
type WeightedSignatureAggregator struct {
// contains filtered or unexported fields
}
WeightedSignatureAggregator implements consensus/hotstuff.WeightedSignatureAggregator. It is a wrapper around signature.SignatureAggregatorSameMessage, which implements a mapping from node IDs (as used by HotStuff) to index-based addressing of authorized signers (as used by SignatureAggregatorSameMessage).
func NewWeightedSignatureAggregator ¶
func NewWeightedSignatureAggregator( ids flow.IdentityList, pks []crypto.PublicKey, message []byte, dsTag string, ) (*WeightedSignatureAggregator, error)
NewWeightedSignatureAggregator returns a weighted aggregator initialized with a list of flow identities, their respective public keys, a message and a domain separation tag. The identities represent the list of all possible signers. The constructor errors if: - the list of identities is empty - if the length of keys does not match the length of identities - if one of the keys is not a valid public key.
A weighted aggregator is used for one aggregation only. A new instance should be used for each signature aggregation task in the protocol.
func (*WeightedSignatureAggregator) Aggregate ¶
func (w *WeightedSignatureAggregator) Aggregate() ([]flow.Identifier, []byte, error)
Aggregate aggregates the signatures and returns the aggregated signature. The function performs a final verification and errors if the aggregated signature is not valid. This is required for the function safety since "TrustedAdd" allows adding invalid signatures. The function errors with:
- model.InsufficientSignaturesError if no signatures have been added yet
- model.InvalidSignatureIncludedError if some signature(s), included via TrustedAdd, are invalid
The function is thread-safe.
TODO : When compacting the list of signers, update the return from []flow.Identifier
to a compact bit vector.
func (*WeightedSignatureAggregator) TotalWeight ¶
func (w *WeightedSignatureAggregator) TotalWeight() uint64
TotalWeight returns the total weight presented by the collected signatures. The function is thread-safe
func (*WeightedSignatureAggregator) TrustedAdd ¶
func (w *WeightedSignatureAggregator) TrustedAdd(signerID flow.Identifier, sig crypto.Signature) (uint64, error)
TrustedAdd adds a signature to the internal set of signatures and adds the signer's weight to the total collected weight, iff the signature is _not_ a duplicate.
The total weight of all collected signatures (excluding duplicates) is returned regardless of any returned error. The function errors with:
- model.InvalidSignerError if signerID is invalid (not a consensus participant)
- model.DuplicatedSignerError if the signer has been already added
The function is thread-safe.
func (*WeightedSignatureAggregator) Verify ¶
func (w *WeightedSignatureAggregator) Verify(signerID flow.Identifier, sig crypto.Signature) error
Verify verifies the signature under the stored public keys and message. Expected errors during normal operations:
- model.InvalidSignerError if signerID is invalid (not a consensus participant)
- model.ErrInvalidSignature if signerID is valid but signature is cryptographically invalid
The function is thread-safe.