github.com/koko1123/flow-go-1@v0.29.6/consensus/hotstuff/signature.go (about)

     1  package hotstuff
     2  
     3  import (
     4  	"github.com/koko1123/flow-go-1/model/flow"
     5  	"github.com/onflow/flow-go/crypto"
     6  )
     7  
     8  // RandomBeaconReconstructor encapsulates all methods needed by a Hotstuff leader to validate the
     9  // beacon votes and reconstruct a beacon signature.
    10  // The random beacon methods are based on a threshold signature scheme.
    11  type RandomBeaconReconstructor interface {
    12  	// Verify verifies the signature share under the signer's public key and the message agreed upon.
    13  	// The function is thread-safe and wait-free (i.e. allowing arbitrary many routines to
    14  	// execute the business logic, without interfering with each other).
    15  	// It allows concurrent verification of the given signature.
    16  	// Returns :
    17  	//  - model.InvalidSignerError if signerIndex is invalid
    18  	//  - model.ErrInvalidSignature if signerID is valid but signature is cryptographically invalid
    19  	//  - other error if there is an unexpected exception.
    20  	Verify(signerID flow.Identifier, sig crypto.Signature) error
    21  
    22  	// TrustedAdd adds a share to the internal signature shares store.
    23  	// There is no pre-check of the signature's validity _before_ adding it.
    24  	// It is the caller's responsibility to make sure the signature was previously verified.
    25  	// Nevertheless, the implementation guarantees safety (only correct threshold signatures
    26  	// are returned) through a post-check (verifying the threshold signature
    27  	// _after_ reconstruction before returning it).
    28  	// The function is thread-safe but locks its internal state, thereby permitting only
    29  	// one routine at a time to add a signature.
    30  	// Returns:
    31  	//  - (true, nil) if the signature has been added, and enough shares have been collected.
    32  	//  - (false, nil) if the signature has been added, but not enough shares were collected.
    33  	//  - (false, error) if there is any exception adding the signature share.
    34  	//      - model.InvalidSignerError if signerIndex is invalid (out of the valid range)
    35  	//  	- model.DuplicatedSignerError if the signer has been already added
    36  	//      - other error if there is an unexpected exception.
    37  	TrustedAdd(signerID flow.Identifier, sig crypto.Signature) (EnoughShares bool, err error)
    38  
    39  	// EnoughShares indicates whether enough shares have been accumulated in order to reconstruct
    40  	// a group signature. The function is thread-safe.
    41  	EnoughShares() bool
    42  
    43  	// Reconstruct reconstructs the group signature. The function is thread-safe but locks
    44  	// its internal state, thereby permitting only one routine at a time.
    45  	//
    46  	// Returns:
    47  	// - (signature, nil) if no error occurred
    48  	// - (nil, model.InsufficientSignaturesError) if not enough shares were collected
    49  	// - (nil, model.InvalidSignatureIncluded) if at least one collected share does not serialize to a valid BLS signature,
    50  	//    or if the constructed signature failed to verify against the group public key and stored message. This post-verification
    51  	//    is required  for safety, as `TrustedAdd` allows adding invalid signatures.
    52  	// - (nil, error) for any other unexpected error.
    53  	Reconstruct() (crypto.Signature, error)
    54  }
    55  
    56  // WeightedSignatureAggregator aggregates signatures of the same signature scheme and the
    57  // same message from different signers. The public keys and message are agreed upon upfront.
    58  // It is also recommended to only aggregate signatures generated with keys representing
    59  // equivalent security-bit level.
    60  // Furthermore, a weight [unsigned int64] is assigned to each signer ID. The
    61  // WeightedSignatureAggregator internally tracks the total weight of all collected signatures.
    62  // Implementations must be concurrency safe.
    63  type WeightedSignatureAggregator interface {
    64  	// Verify verifies the signature under the stored public keys and message.
    65  	// Expected errors during normal operations:
    66  	//  - model.InvalidSignerError if signerID is invalid (not a consensus participant)
    67  	//  - model.ErrInvalidSignature if signerID is valid but signature is cryptographically invalid
    68  	Verify(signerID flow.Identifier, sig crypto.Signature) error
    69  
    70  	// TrustedAdd adds a signature to the internal set of signatures and adds the signer's
    71  	// weight to the total collected weight, iff the signature is _not_ a duplicate. The
    72  	// total weight of all collected signatures (excluding duplicates) is returned regardless
    73  	// of any returned error.
    74  	// Expected errors during normal operations:
    75  	//  - model.InvalidSignerError if signerID is invalid (not a consensus participant)
    76  	//  - model.DuplicatedSignerError if the signer has been already added
    77  	TrustedAdd(signerID flow.Identifier, sig crypto.Signature) (totalWeight uint64, exception error)
    78  
    79  	// TotalWeight returns the total weight presented by the collected signatures.
    80  	TotalWeight() uint64
    81  
    82  	// Aggregate aggregates the signatures and returns the aggregated signature.
    83  	// The function performs a final verification and errors if the aggregated
    84  	// signature is not valid. This is required for the function safety since
    85  	// `TrustedAdd` allows adding invalid signatures.
    86  	// Expected errors during normal operations:
    87  	//  - model.InsufficientSignaturesError if no signatures have been added yet
    88  	//  - model.InvalidSignatureIncludedError if some signature(s), included via TrustedAdd, are invalid
    89  	Aggregate() (flow.IdentifierList, []byte, error)
    90  }
    91  
    92  // BlockSignatureData is an intermediate struct for Packer to pack the
    93  // aggregated signature data into raw bytes or unpack from raw bytes.
    94  type BlockSignatureData struct {
    95  	StakingSigners               flow.IdentifierList
    96  	RandomBeaconSigners          flow.IdentifierList
    97  	AggregatedStakingSig         []byte // if BLS is used, this is equivalent to crypto.Signature
    98  	AggregatedRandomBeaconSig    []byte // if BLS is used, this is equivalent to crypto.Signature
    99  	ReconstructedRandomBeaconSig crypto.Signature
   100  }
   101  
   102  // Packer packs aggregated signature data into raw bytes to be used in block header.
   103  type Packer interface {
   104  	// Pack serializes the provided BlockSignatureData into a precursor format of a QC.
   105  	// blockID is the block that the aggregated signature is for.
   106  	// sig is the aggregated signature data.
   107  	// Expected error returns during normal operations:
   108  	//  * none; all errors are symptoms of inconsistent input data or corrupted internal state.
   109  	Pack(blockID flow.Identifier, sig *BlockSignatureData) (signerIndices []byte, sigData []byte, err error)
   110  
   111  	// Unpack de-serializes the provided signature data.
   112  	// sig is the aggregated signature data
   113  	// It returns:
   114  	//  - (sigData, nil) if successfully unpacked the signature data
   115  	//  - (nil, model.InvalidFormatError) if failed to unpack the signature data
   116  	Unpack(signerIdentities flow.IdentityList, sigData []byte) (*BlockSignatureData, error)
   117  }