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 }