github.com/koko1123/flow-go-1@v0.29.6/consensus/hotstuff/signature/randombeacon_reconstructor.go (about) 1 package signature 2 3 import ( 4 "fmt" 5 6 "github.com/koko1123/flow-go-1/consensus/hotstuff" 7 "github.com/koko1123/flow-go-1/consensus/hotstuff/model" 8 "github.com/koko1123/flow-go-1/model/flow" 9 "github.com/koko1123/flow-go-1/state/protocol" 10 "github.com/onflow/flow-go/crypto" 11 ) 12 13 // RandomBeaconReconstructor implements hotstuff.RandomBeaconReconstructor. 14 // The implementation wraps the hotstuff.RandomBeaconInspector and translates the signer identity into signer index. 15 // It has knowledge about DKG to be able to map signerID to signerIndex 16 type RandomBeaconReconstructor struct { 17 hotstuff.RandomBeaconInspector // a stateful object for this epoch. It's used for both verifying all sig shares and reconstructing the threshold signature. 18 dkg hotstuff.DKG // to lookup signer index by signer ID 19 } 20 21 var _ hotstuff.RandomBeaconReconstructor = (*RandomBeaconReconstructor)(nil) 22 23 func NewRandomBeaconReconstructor(dkg hotstuff.DKG, randomBeaconInspector hotstuff.RandomBeaconInspector) *RandomBeaconReconstructor { 24 return &RandomBeaconReconstructor{ 25 RandomBeaconInspector: randomBeaconInspector, 26 dkg: dkg, 27 } 28 } 29 30 // Verify verifies the signature share under the signer's public key and the message agreed upon. 31 // The function is thread-safe and wait-free (i.e. allowing arbitrary many routines to 32 // execute the business logic, without interfering with each other). 33 // It allows concurrent verification of the given signature. 34 // Returns : 35 // - model.InvalidSignerError if signerID is invalid 36 // - model.ErrInvalidSignature if signerID is valid but signature is cryptographically invalid 37 // - other error if there is an unexpected exception. 38 func (r *RandomBeaconReconstructor) Verify(signerID flow.Identifier, sig crypto.Signature) error { 39 signerIndex, err := r.dkg.Index(signerID) 40 if err != nil { 41 if protocol.IsIdentityNotFound(err) { 42 return model.NewInvalidSignerErrorf("signer %v is not a valid random beacon participant: %w", signerID, err) 43 } 44 return fmt.Errorf("internal error retrieving DKG index for %v: %w", signerID, err) 45 } 46 return r.RandomBeaconInspector.Verify(int(signerIndex), sig) 47 } 48 49 // TrustedAdd adds a share to the internal signature shares store. 50 // There is no pre-check of the signature's validity _before_ adding it. 51 // It is the caller's responsibility to make sure the signature was previously verified. 52 // Nevertheless, the implementation guarantees safety (only correct threshold signatures 53 // are returned) through a post-check (verifying the threshold signature 54 // _after_ reconstruction before returning it). 55 // The function is thread-safe but locks its internal state, thereby permitting only 56 // one routine at a time to add a signature. 57 // Returns: 58 // - (true, nil) if the signature has been added, and enough shares have been collected. 59 // - (false, nil) if the signature has been added, but not enough shares were collected. 60 // 61 // The following errors are expected during normal operations: 62 // - model.InvalidSignerError if signerIndex is invalid (out of the valid range) 63 // - model.DuplicatedSignerError if the signer has been already added 64 // - other error if there is an unexpected exception. 65 func (r *RandomBeaconReconstructor) TrustedAdd(signerID flow.Identifier, sig crypto.Signature) (bool, error) { 66 signerIndex, err := r.dkg.Index(signerID) 67 if err != nil { 68 if protocol.IsIdentityNotFound(err) { 69 return false, model.NewInvalidSignerErrorf("signer %v is not a valid random beacon participant: %w", signerID, err) 70 } 71 return false, fmt.Errorf("internal error retrieving DKG index for %v: %w", signerID, err) 72 } 73 return r.RandomBeaconInspector.TrustedAdd(int(signerIndex), sig) 74 }