Skip to content

Commit 129f847

Browse files
authored
Merge pull request #30 from onflow/tarak/threshold-comments
More clarity in threshold sign comments
2 parents 676d89a + f9e9656 commit 129f847

2 files changed

Lines changed: 176 additions & 144 deletions

File tree

bls_thresholdsign.go

Lines changed: 92 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ func NewBLSThresholdSignatureInspector(
208208

209209
// SignShare generates a signature share using the current private key share.
210210
//
211-
// The function does not add the share to the internal pool of shares and do
211+
// The function does not add the share to the internal pool of shares and does
212212
// not update the internal state.
213213
// This function is thread safe and non-blocking
214214
//
@@ -256,20 +256,22 @@ func (s *blsThresholdSignatureInspector) VerifyShare(orig int, share Signature)
256256
// message and stored group public key.
257257
//
258258
// This function does not update the internal state and is thread-safe.
259+
//
259260
// Returns:
260-
// - (true, nil) if the signature is valid
261-
// - (false, nil) if signature is invalid
262-
// - (false, error) for all other unexpected errors
261+
// - (true, nil): if the signature is valid
262+
// - (false, nil): if the signature is invalid
263+
// - (false, error): for all other unexpected errors
263264
func (s *blsThresholdSignatureInspector) VerifyThresholdSignature(thresholdSignature Signature) (bool, error) {
264265
return s.groupPublicKey.Verify(thresholdSignature, s.message, s.hasher)
265266
}
266267

267-
// EnoughShares indicates whether enough shares have been accumulated in order to reconstruct
268+
// EnoughShares indicates whether enough shares have been accumulated to reconstruct
268269
// a group signature.
269270
//
270-
// This function is thread safe.
271+
// This function is thread-safe.
272+
//
271273
// Returns:
272-
// - true if and only if at least (threshold+1) shares were added
274+
// - true: if and only if at least (threshold+1) shares were added
273275
func (s *blsThresholdSignatureInspector) EnoughShares() bool {
274276
s.lock.RLock()
275277
defer s.lock.RUnlock()
@@ -284,11 +286,12 @@ func (s *blsThresholdSignatureInspector) enoughShares() bool {
284286
}
285287

286288
// HasShare checks whether the internal map contains the share of the given index.
287-
// This function is thread safe and locks the internal state.
288-
// The function returns:
289-
// - (false, invalidInputsError) if the index is invalid
290-
// - (false, nil) if index is valid and share is not in the map
291-
// - (true, nil) if index is valid and share is in the map
289+
// This function is thread-safe and locks the internal state.
290+
//
291+
// Returns:
292+
// - (false, invalidInputsError): if the index is invalid
293+
// - (false, nil): if index is valid and share is not in the map
294+
// - (true, nil): if index is valid and share is in the map
292295
func (s *blsThresholdSignatureInspector) HasShare(orig int) (bool, error) {
293296
// validate index
294297
if err := s.validIndex(orig); err != nil {
@@ -309,15 +312,20 @@ func (s *blsThresholdSignatureInspector) hasShare(orig index) bool {
309312

310313
// TrustedAdd adds a signature share to the internal pool of shares
311314
// without verifying the signature against the message and the participant's
312-
// public key. This function is thread safe and locks the internal state.
315+
// public key. Adding an invalid signature share is not considered an error and does
316+
// not compromise the protocol security. However, the reconstruction of the threshold signature
317+
// fails if at least one invalid signature share was added. `VerifyShare` can be used to verify
318+
// the signature share before adding it to the internal pool through `TrustedAdd`.
319+
// This function is thread-safe and locks the internal state.
313320
//
314321
// The share is only added if the signer index is valid and has not been
315322
// added yet. Moreover, the share is added only if not enough shares were collected.
316-
// The function returns:
317-
// - (true, nil) if enough signature shares were already collected and no error occurred
318-
// - (false, nil) if not enough shares were collected and no error occurred
319-
// - (false, invalidInputsError) if index is invalid
320-
// - (false, duplicatedSignerError) if a signature for the index was previously added
323+
//
324+
// Returns:
325+
// - (true, nil): if enough signature shares were already collected and no error occurred
326+
// - (false, nil): if not enough shares were collected and no error occurred
327+
// - (false, invalidInputsError): if index is invalid
328+
// - (false, duplicatedSignerError): if a signature for the index was previously added
321329
func (s *blsThresholdSignatureInspector) TrustedAdd(orig int, share Signature) (bool, error) {
322330
// validate index
323331
if err := s.validIndex(orig); err != nil {
@@ -339,21 +347,22 @@ func (s *blsThresholdSignatureInspector) TrustedAdd(orig int, share Signature) (
339347
}
340348

341349
// VerifyAndAdd verifies a signature share (same as `VerifyShare`),
342-
// and may or may not add the share to the local pool of shares.
343-
// This function is thread safe and locks the internal state.
350+
// and attempts to add the share to the local pool of shares.
351+
// This function is thread-safe and locks the internal state.
344352
//
345-
// The share is only added if the signature is valid, the signer index is valid and has not been
346-
// added yet. Moreover, the share is added only if not enough shares were collected.
347-
// Boolean returns:
348-
// - First boolean output is true if the share is valid and no error is returned, and false otherwise.
349-
// - Second boolean output is true if enough shares were collected and no error is returned, and false otherwise.
353+
// The share is only added if the signature is valid, the signer index is valid,
354+
// and has not been added yet. Moreover, the share is not added if enough shares were already collected.
350355
//
351-
// Error returns:
352-
// - invalidInputsError if input index is invalid. A signature that doesn't verify against the signer's
356+
// Returns:
357+
// - First boolean: true if the share is valid and no error is returned, false otherwise.
358+
// - Second boolean: true if enough shares were collected and no error is returned, false otherwise.
359+
// - Error:
360+
// - invalidInputsError: if input index is invalid. A signature that doesn't verify against the signer's
353361
// public key is not considered an invalid input.
354-
// - duplicatedSignerError if signer was already added.
355-
// - other errors if an unexpected exception occurred.
356-
func (s *blsThresholdSignatureInspector) VerifyAndAdd(orig int, share Signature) (bool, bool, error) {
362+
// - duplicatedSignerError: if signer was already added.
363+
// - other errors: if an unexpected exception occurred.
364+
func (s *blsThresholdSignatureInspector) VerifyAndAdd(orig int, share Signature) (
365+
shareIsValid bool, enoughSharesCollected bool, err error) {
357366
// validate index
358367
if err := s.validIndex(orig); err != nil {
359368
return false, false, err
@@ -381,16 +390,20 @@ func (s *blsThresholdSignatureInspector) VerifyAndAdd(orig int, share Signature)
381390
}
382391

383392
// ThresholdSignature returns the threshold signature if the threshold was reached.
384-
// The threshold signature is reconstructed only once is cached for subsequent calls.
393+
// For safety, the function attempts the reconstruction and only returns a signature that is valid against the group public key.
394+
// This is done by first reconstructing the signature and then validating it against the group public key.
395+
// The reconstructed may fail the validation if at least one signature share added via `TrustedAdd` is invalid.
396+
// The valid threshold signature is reconstructed only once and is cached for subsequent calls.
385397
//
386398
// The function is thread-safe.
399+
//
387400
// Returns:
388-
// - (signature, nil) if no error occurred
389-
// - (nil, notEnoughSharesError) if not enough shares were collected
390-
// - (nil, errInvalidSignature) if at least one collected share does not serialize to a valid BLS signature.
391-
// - (nil, invalidInputsError) if the constructed signature failed to verify against the group public key and stored
392-
// message. This post-verification is required for safety, as `TrustedAdd` allows adding invalid signatures.
393-
// - (nil, error) for any other unexpected error.
401+
// - (signature, nil): if no error occurred
402+
// - (nil, notEnoughSharesError): if not enough shares were collected
403+
// - (nil, errInvalidSignature): if at least one collected share does not serialize to a valid BLS signature.
404+
// - (nil, invalidInputsError): if the constructed signature failed to verify against the group public key and stored
405+
// message. This post-verification is required for safety, as `TrustedAdd` allows adding invalid signatures.
406+
// - (nil, error): for any other unexpected error.
394407
func (s *blsThresholdSignatureInspector) ThresholdSignature() (Signature, error) {
395408
s.lock.Lock()
396409
defer s.lock.Unlock()
@@ -410,12 +423,15 @@ func (s *blsThresholdSignatureInspector) ThresholdSignature() (Signature, error)
410423
}
411424

412425
// reconstructThresholdSignature reconstructs the threshold signature from at least (t+1) shares.
426+
// The function attempts the reconstruction and only returns a signature that is valid against the group public key.
427+
// This is done by first reconstructing the signature and then validating it against the group public key.
428+
//
413429
// Returns:
414-
// - (signature, nil) if no error occurred
415-
// - (nil, notEnoughSharesError) if not enough shares were collected
416-
// - (nil, errInvalidSignature) if at least one collected share does not serialize to a valid BLS signature.
417-
// - (nil, invalidInputsError) if the constructed signature failed to verify against the group public key and stored message.
418-
// - (nil, error) for any other unexpected error.
430+
// - (signature, nil): if no error occurred
431+
// - (nil, notEnoughSharesError): if not enough shares were collected
432+
// - (nil, errInvalidSignature): if at least one collected share does not serialize to a valid BLS signature.
433+
// - (nil, invalidInputsError): if the constructed signature failed to verify against the group public key and stored message.
434+
// - (nil, error): for any other unexpected error.
419435
func (s *blsThresholdSignatureInspector) reconstructThresholdSignature() (Signature, error) {
420436

421437
if !s.enoughShares() {
@@ -455,26 +471,31 @@ func (s *blsThresholdSignatureInspector) reconstructThresholdSignature() (Signat
455471
return thresholdSignature, nil
456472
}
457473

458-
// BLSReconstructThresholdSignature is a stateless BLS api that takes a list of
474+
// BLSReconstructThresholdSignature is a stateless BLS API that takes a list of
459475
// BLS signatures and their signers' indices and returns the threshold signature.
460476
//
461-
// size is the number of participants, it must be in the range [ThresholdSignMinSize..ThresholdSignMaxSize].
462-
// threshold is the threshold value, it must be in the range [MinimumThreshold..size-1].
463-
// The function does not accept any input public key. Therefore, it does not check the validity of the
464-
// shares against individual public keys, and does not check the validity of the resulting signature
477+
// size is the number of participants. It must be in the range [ThresholdSignMinSize, ThresholdSignMaxSize].
478+
// threshold is the threshold value. It must be in the range [MinimumThreshold, size-1].
479+
// The function does not use or require input public keys. Therefore, it does not check the validity of the
480+
// shares against individual public keys, nor does it check the validity of the resulting signature
465481
// against the group public key.
466-
// BLSReconstructThresholdSignature returns:
467-
// - (nil, invalidInputsError) if :
468-
// -- numbers of shares does not match the number of signers
469-
// -- the inputs are not in the correct range.
470-
// - (nil, notEnoughSharesError) if the threshold is not reached.
471-
// - (nil, duplicatedSignerError) if input signers are not distinct.
472-
// - (nil, errInvalidSignature) if at least one of the first (threshold+1) signatures.
473-
// does not serialize to a valid E1 point.
474-
// - (threshold_sig, nil) otherwise.
482+
// Passing an invalid signature share is not considered an error and does
483+
// not compromise the protocol security, but if any invalid share is included, the reconstructed group
484+
// signature will be invalid.
485+
// The reconstruction is guaranteed to return a valid signature if only valid shares are passed to the
486+
// function.
475487
//
476488
// If the number of shares reaches the required threshold, only the first threshold+1 shares
477-
// are considered to reconstruct the signature.
489+
// are used to reconstruct the signature.
490+
//
491+
// Returns:
492+
// - (nil, invalidInputsError): if
493+
// -- number of shares does not match the number of signers
494+
// -- the inputs are not in the correct range
495+
// - (nil, notEnoughSharesError): if the threshold is not reached
496+
// - (nil, duplicatedSignerError): if input signers are not distinct
497+
// - (nil, errInvalidSignature): if at least one of the first (threshold+1) signatures does not serialize to a valid E1 point
498+
// - (threshold_sig, nil): otherwise
478499
func BLSReconstructThresholdSignature(size int, threshold int,
479500
shares []Signature, signers []int) (Signature, error) {
480501

@@ -536,13 +557,13 @@ func BLSReconstructThresholdSignature(size int, threshold int,
536557
}
537558

538559
// EnoughShares is a stateless function that takes the value of the threshold
539-
// and a shares number and returns true if the shares number is enough
560+
// and a number of shares, and returns true if the number of shares is enough
540561
// to reconstruct a threshold signature.
541562
//
542-
// The function returns:
543-
// - (false, invalidInputsErrorf) if input threshold is less than 1
544-
// - (false, nil) if threshold is valid but shares are not enough.
545-
// - (true, nil) if the threshold is valid but shares are enough.
563+
// Returns:
564+
// - (false, invalidInputsErrorf): if input threshold is less than 1
565+
// - (false, nil): if threshold is valid but shares are not enough
566+
// - (true, nil): if the threshold is valid and shares are enough
546567
func EnoughShares(threshold int, sharesNumber int) (bool, error) {
547568
if threshold < MinimumThreshold {
548569
return false, invalidInputsErrorf(
@@ -552,24 +573,24 @@ func EnoughShares(threshold int, sharesNumber int) (bool, error) {
552573
return sharesNumber > threshold, nil
553574
}
554575

555-
// BLSThresholdKeyGen is a key generation for a BLS-based
576+
// BLSThresholdKeyGen is a key generation function for a BLS-based
556577
// threshold signature scheme with a trusted dealer.
557578
//
558-
// The generation takes the group size `n` as an input and assigns
559-
// participants to the public indices `[0,n-1]`.
579+
// The generation takes the group size `n` as input and assigns
580+
// participants to the public indices `[0, n-1]`.
560581
//
561-
// The secret key is not returned, the function returns the corresponding
562-
// public key, the private key shares, and their corresponding public key
582+
// The group secret key is not returned. The function returns the corresponding
583+
// group public key, the private key shares, and their corresponding public key
563584
// shares. The key shares are ordered arrays following the public index: a participant
564585
// assigned to index `i` uses the private key share at index `i`, corresponding
565586
// to the public key share at index `i`.
566587
//
567-
// The function returns:
568-
// - (nil, nil, nil, invalidInputsErrorf) if:
588+
// Returns:
589+
// - (nil, nil, nil, invalidInputsErrorf): if
569590
// - `seed` is too short
570-
// - `size` is not in `[`ThresholdSignMinSize`, `ThresholdSignMaxSize`]`
591+
// - `size` is not in [`ThresholdSignMinSize`, `ThresholdSignMaxSize`]
571592
// - `threshold` value is not in interval `[1, size-1]`
572-
// - ([]privKeyShares, []pubKeyShares, groupPubKey, nil) otherwise
593+
// - ([]privKeyShares, []pubKeyShares, groupPubKey, nil): otherwise
573594
func BLSThresholdKeyGen(size int, threshold int, seed []byte) ([]PrivateKey,
574595
[]PublicKey, PublicKey, error) {
575596

0 commit comments

Comments
 (0)