Documentation
¶
Index ¶
- Constants
- Variables
- func BLSThresholdKeyGen(size int, threshold int, seed []byte) ([]PrivateKey, []PublicKey, PublicKey, error)
- func BLSVerifyPOP(pk PublicKey, s Signature) (bool, error)
- func BatchVerifyBLSSignaturesOneMessage(pks []PublicKey, sigs []Signature, message []byte, kmac hash.Hasher) ([]bool, error)
- func EnoughShares(threshold int, sharesNumber int) (bool, error)
- func IsBLSAggregateEmptyListError(err error) bool
- func IsBLSSignatureIdentity(s Signature) bool
- func IsDKGFailureError(err error) bool
- func IsDKGInvalidStateTransitionError(err error) bool
- func IsDuplicatedSignerError(err error) bool
- func IsInvalidHasherSizeError(err error) bool
- func IsInvalidInputsError(err error) bool
- func IsInvalidSignatureError(err error) bool
- func IsNilHasherError(err error) bool
- func IsNotBLSKeyError(err error) bool
- func IsNotEnoughSharesError(err error) bool
- func NewBLSThresholdSignatureInspector(groupPublicKey PublicKey, sharePublicKeys []PublicKey, threshold int, ...) (*blsThresholdSignatureInspector, error)
- func NewBLSThresholdSignatureParticipant(groupPublicKey PublicKey, sharePublicKeys []PublicKey, threshold int, ...) (*blsThresholdSignatureParticipant, error)
- func NewExpandMsgXOFKMAC128(domainTag string) hash.Hasher
- func SPOCKVerify(pk1 PublicKey, proof1 Signature, pk2 PublicKey, proof2 Signature) (bool, error)
- func SPOCKVerifyAgainstData(pk PublicKey, proof Signature, data []byte, kmac hash.Hasher) (bool, error)
- func SignatureFormatCheck(algo SigningAlgorithm, s Signature) (bool, error)
- func TestHasherErrors(t *testing.T)
- func TestKeyGenErrors(t *testing.T)
- func VerifyBLSSignatureManyMessages(pks []PublicKey, s Signature, messages [][]byte, kmac []hash.Hasher) (bool, error)
- func VerifyBLSSignatureOneMessage(pks []PublicKey, s Signature, message []byte, kmac hash.Hasher) (bool, error)
- type DKGProcessor
- type DKGState
- func NewFeldmanVSS(size int, threshold int, myIndex int, processor DKGProcessor, dealerIndex int) (DKGState, error)
- func NewFeldmanVSSQual(size int, threshold int, myIndex int, processor DKGProcessor, dealerIndex int) (DKGState, error)
- func NewJointFeldman(size int, threshold int, myIndex int, processor DKGProcessor) (DKGState, error)
- type JointFeldmanState
- func (s *JointFeldmanState) End() (PrivateKey, PublicKey, []PublicKey, error)
- func (s *JointFeldmanState) ForceDisqualify(participant int) error
- func (s *JointFeldmanState) HandleBroadcastMsg(orig int, msg []byte) error
- func (s *JointFeldmanState) HandlePrivateMsg(orig int, msg []byte) error
- func (s *JointFeldmanState) NextTimeout() error
- func (s *JointFeldmanState) Running() bool
- func (s JointFeldmanState) Size() int
- func (s *JointFeldmanState) Start(seed []byte) error
- func (s JointFeldmanState) Threshold() int
- type PrivateKey
- type PublicKey
- func AggregateBLSPublicKeys(keys []PublicKey) (PublicKey, error)
- func DecodePublicKey(algo SigningAlgorithm, data []byte) (PublicKey, error)
- func DecodePublicKeyCompressed(algo SigningAlgorithm, data []byte) (PublicKey, error)
- func IdentityBLSPublicKey() PublicKey
- func RemoveBLSPublicKeys(aggKey PublicKey, keysToRemove []PublicKey) (PublicKey, error)
- type Signature
- func AggregateBLSSignatures(sigs []Signature) (Signature, error)
- func BLSGeneratePOP(sk PrivateKey) (Signature, error)
- func BLSInvalidSignature() Signature
- func BLSReconstructThresholdSignature(size int, threshold int, shares []Signature, signers []int) (Signature, error)
- func SPOCKProve(sk PrivateKey, data []byte, kmac hash.Hasher) (Signature, error)
- type SigningAlgorithm
- type ThresholdSignatureInspector
- type ThresholdSignatureParticipant
Constants ¶
const ( // SignatureLenBLSBLS12381 is the serialization size of a `G_1` element. SignatureLenBLSBLS12381 = g1BytesLen // PubKeyLenBLSBLS12381 is the serialization size of a `G_2` element. PubKeyLenBLSBLS12381 = g2BytesLen // PrKeyLenBLSBLS12381 is the serialization size of a `F_r` element, // where `r` is the order of `G_1` and `G_2`. PrKeyLenBLSBLS12381 = frBytesLen )
const ( // keygen seed length conditions // enforce seed to be at least double the security bits and have enough entropy. // it is still recommened that seed is generated using a secure RNG. KeyGenSeedMinLen = 2 * (securityBits / 8) KeyGenSeedMaxLen = 256 )
const ( // MinimumThreshold is the minimum value of the threshold parameter in all threshold-based protocols. MinimumThreshold = 1 // DKGMinSize is the minimum size of a group participating in threshold-based protocols. DKGMinSize int = MinimumThreshold + 1 // DKGMaxSize is the maximum size of a group participating in threshold-based protocols. DKGMaxSize int = 254 )
const ( // NIST P256 SignatureLenECDSAP256 = 64 PrKeyLenECDSAP256 = 32 // PubKeyLenECDSAP256 is the size of uncompressed points on P256 PubKeyLenECDSAP256 = 64 // SECG secp256k1 SignatureLenECDSASecp256k1 = 64 PrKeyLenECDSASecp256k1 = 32 // PubKeyLenECDSASecp256k1 is the size of uncompressed points on secp256k1 PubKeyLenECDSASecp256k1 = 64 )
const ( // ThresholdSignMinSize is the minimum size of a group participating in a threshold signature protocol ThresholdSignMinSize = MinimumThreshold + 1 // ThresholdSignMaxSize is the maximum size of a group participating in a threshold signature protocol ThresholdSignMaxSize = DKGMaxSize )
Variables ¶
var BLS12381Order = []byte{0x73, 0xED, 0xA7, 0x53, 0x29, 0x9D, 0x7D, 0x48, 0x33, 0x39,
0xD8, 0x08, 0x09, 0xA1, 0xD8, 0x05, 0x53, 0xBD, 0xA4, 0x02, 0xFF, 0xFE,
0x5B, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01}
Functions ¶
func BLSThresholdKeyGen ¶
func BLSThresholdKeyGen(size int, threshold int, seed []byte) ([]PrivateKey, []PublicKey, PublicKey, error)
BLSThresholdKeyGen is a key generation for a BLS-based threshold signature scheme with a trusted dealer.
The generation takes the group size `n` as an input and assigns participants to the public indices `[0,n-1]`.
The secret key is not returned, the function returns the corresponding public key, the private key shares, and their corresponding public key shares. The key shares are ordered arrays following the public index: a participant assigned to index `i` uses the private key share at index `i`, corresponding to the public key share at index `i`.
The function returns: - (nil, nil, nil, invalidInputsErrorf) if:
- `seed` is too short
- `size` is not in `[`ThresholdSignMinSize`, `ThresholdSignMaxSize`]`
- `threshold` value is not in interval `[1, size-1]`
- ([]privKeyShares, []pubKeyShares, groupPubKey, nil) otherwise
func BLSVerifyPOP ¶
BLSVerifyPOP verifies a proof of possession (PoP) for the receiver public key.
The function internally uses the same KMAC hasher used to generate the PoP. The hasher is guaranteed to be orthogonal to any hasher used to generate signature or SPoCK proofs on this package. Note that verifying a PoP against an idenity public key fails.
The function returns:
- (false, notBLSKeyError) if the input key is not of type BLS BLS12-381
- (validity, nil) otherwise
func BatchVerifyBLSSignaturesOneMessage ¶
func BatchVerifyBLSSignaturesOneMessage( pks []PublicKey, sigs []Signature, message []byte, kmac hash.Hasher, ) ([]bool, error)
BatchVerifyBLSSignaturesOneMessage is a batch verification of multiple BLS signatures of a single message against multiple BLS public keys that is faster than verifying the signatures one by one.
Each signature at index (i) of the input signature slice is verified against the public key of the same index (i) in the input key slice. The input hasher is the same used to generate all signatures. The returned boolean slice is of the same length of the signatures slice, where the boolean at index (i) is true if signature (i) verifies against public key (i), and false otherwise. In the case where an error occurs during the execution of the function, all the returned boolean values are `false`.
The caller must make sure the input public keys's proofs of possession have been verified prior to calling this function (or each input key is sum of public keys of which proofs of possession have been verified).
Membership checks are performed on the input signatures but are not performed on the input public keys (which are guaranteed by the package to be on the correct G2 subgroup). In order to avoid equivocation issues, any identity public key results in the corresponding signature being invalid.
The function returns:
- ([]false, nilHasherError) if a hasher is nil
- ([]false, invalidHasherSizeError) if a hasher's output size is not 128 bytes
- ([]false, notBLSKeyError) if at least one key is not of type BLS BLS12-381
- ([]false, invalidInputsError) if size of keys is not matching the size of signatures
- ([]false, blsAggregateEmptyListError) if input key slice is empty
- ([]false, error) if an unexpected error occurs
- ([]validity, nil) otherwise
func EnoughShares ¶
EnoughShares is a stateless function that takes the value of the threshold and a shares number and returns true if the shares number is enough to reconstruct a threshold signature.
The function returns:
- (false, invalidInputsErrorf) if input threshold is less than 1
- (false, nil) if threshold is valid but shares are not enough.
- (true, nil) if the threshold is valid but shares are enough.
func IsBLSAggregateEmptyListError ¶
IsBLSAggregateEmptyListError checks if err is an `blsAggregateEmptyListError`. blsAggregateEmptyListError is returned when a BLS aggregation function is called with an empty list which is not allowed in some aggregation cases to avoid signature equivocation issues.
func IsBLSSignatureIdentity ¶
IsBLSSignatureIdentity checks whether the input signature is the identity signature (point at infinity in G1).
An identity signature is always an invalid signature even when verified against the identity public key. This identity check is useful when an aggregated signature is suspected to be equal to identity, which avoids failing the aggregated signature verification.
func IsDKGFailureError ¶
IsDKGFailureError checks if the input error is of a dkgFailureError type. dkgFailureError is an error returned when a participant detects a failure in the protocol and is not able to compute output keys.
func IsDKGInvalidStateTransitionError ¶
IsDkgInvalidStateTransitionError checks if the input error is of a dkgInvalidStateTransition type. invalidStateTransition is returned when a caller triggers an invalid state transition in the local DKG instance. Such a failure can only happen if the API is misued by not respecting the state machine conditions.
func IsDuplicatedSignerError ¶
IsDuplicatedSignerError checks if the input error is a duplicatedSignerError
func IsInvalidHasherSizeError ¶
IsInvalidHasherSizeError checks if the input error is of an invalidHasherSizeError type. invalidHasherSizeError is an error returned when a crypto API is called with a hasher with an output size not suited with the cryptographic operation.
func IsInvalidInputsError ¶
IsInvalidInputsError checks if the input error is of an invalidInputsError type invalidInputsError is returned when the API is provided invalid inputs. Some specific errors are assigned specific sentinel errors for a simpler error check while the remaining input errors trigger an invalidInputsError.
func IsInvalidSignatureError ¶
IsInvalidSignatureError checks if err is an `invalidSignatureError` invalidSignatureError is returned when a signature input does not serialize to a valid element on E1 of the BLS12-381 curve (but without checking the element is on subgroup G1).
func IsNilHasherError ¶
IsNilHasherError checks if the input error wraps a nilHasherError. nilHasherError is returned when a nil hasher is used.
func IsNotBLSKeyError ¶
IsNotBLSKeyError checks if err is an `notBLSKeyError`. notBLSKeyError is returned when a private or public key used is not a BLS on BLS12 381 key.
func IsNotEnoughSharesError ¶
IsNotEnoughSharesError checks if the input error is a notEnoughSharesError
func NewBLSThresholdSignatureInspector ¶
func NewBLSThresholdSignatureInspector( groupPublicKey PublicKey, sharePublicKeys []PublicKey, threshold int, message []byte, dsTag string, ) (*blsThresholdSignatureInspector, error)
NewBLSThresholdSignatureInspector creates a new instance of the protocol follower using BLS. The returned instance implements ThresholdSignatureInspector.
A new instance is needed for each set of public keys and message. If the key set or message change, a new structure needs to be instantiated. The `n` participants are identified using their public indices in the range `[0, n-1]`, as well as their public key shares. The input `sharePublicKeys` is an array of `n` keys ordered following the public indices: a participant assigned to index `i` uses the public key `sharePublicKeys[i]`.
The function returns: - (nil, invalidInputsError) if:
- `n` is not in [`ThresholdSignMinSize`, `ThresholdSignMaxSize`]
- threshold value is not in interval `[1, n-1]`
- (nil, notBLSKeyError) at least one public key is not of type pubKeyBLSBLS12381
- (pointer, nil) otherwise
func NewBLSThresholdSignatureParticipant ¶
func NewBLSThresholdSignatureParticipant( groupPublicKey PublicKey, sharePublicKeys []PublicKey, threshold int, myIndex int, myPrivateKey PrivateKey, message []byte, dsTag string, ) (*blsThresholdSignatureParticipant, error)
NewBLSThresholdSignatureParticipant creates a new instance of a protocol participant using BLS. A participant is able to follow the protocol as well as contribute to the threshold signing. It implements the ThresholdSignatureParticipant interface.
A new instance is needed for each set of public keys and message. If the key set or message change, a new structure needs to be instantiated. The `n` participants are identified using their public indices in the range `[0, n-1]`, as well as their public key shares. The input `sharePublicKeys` is an array of `n` keys ordered following the public indices: a participant assigned to index `i` uses the public key `sharePublicKeys[i]`. The current participant is defined by `myIndex` and holds the input private key corresponding to `sharePublicKeys[myIndex]`.
The function returns: - (nil, invalidInputsError) if:
- `n` is not in [`ThresholdSignMinSize`, `ThresholdSignMaxSize`]
- threshold value is not in interval `[1, n-1]`
- input private key and public key at my index do not match
- (nil, notBLSKeyError) if the private or at least one public key is not of type BLS BLS12-381.
- (pointer, nil) otherwise
func NewExpandMsgXOFKMAC128 ¶
NewExpandMsgXOFKMAC128 returns a new expand_message_xof instance for the hash-to-curve function, hashing data to G1 on BLS12 381. This instance must only be used to generate signatures (and not PoP), because the internal ciphersuite is customized for signatures. It is guaranteed to be different than the expand_message_xof instance used to generate proofs of possession.
KMAC128 is used as the underligned extendable-output function (xof) as required by https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-14#section-5.4.4.
`domainTag` is a domain separation tag that defines the protocol and its subdomain. Such tag should be of the format: <protocol>-V<xx>-CS<yy>-with- where <protocol> is the name of the protocol, <xx> the protocol version number and <yy> the index of the ciphersuite in the protocol. The function suffixes the given `domainTag` by the BLS ciphersuite supported by the library.
The returned instance is a `Hasher` and can be used to generate BLS signatures with the `Sign` method.
func SPOCKVerify ¶
SPOCKVerify checks whether two couples of (SPoCK proof, public key) are consistent.
Two (SPoCK proof, public key) couples are consistent if there exists a message such that each proof could be generated from the message and the private key corresponding to the respective public key.
If the input proof slices have an invalid length or fail to deserialize into curve points, the function returns false without an error. The proofs membership checks in G1 are included in the verifcation.
The function does not check the public keys membership in G2 because it is guaranteed by the package. However, the caller must make sure each input public key has been verified against a proof of possession prior to calling this function.
The function returns:
- (false, notBLSKeyError) if at least one key is not a BLS key.
- (false, error) if an unexpected error occurs.
- (validity, nil) otherwise
func SPOCKVerifyAgainstData ¶
func SPOCKVerifyAgainstData(pk PublicKey, proof Signature, data []byte, kmac hash.Hasher) (bool, error)
SPOCKVerifyAgainstData verifies a SPoCK proof is generated from the given data and the prover's public key.
This is a simple BLS signature verifictaion of the proof under the input data and public key.
The function returns:
- (false, notBLSKeyError) if input key is not a BLS key
- (false, nilHasherError) if the hasher is nil
- (false, invalidHasherSiseError) if hasher's output size is not 128 bytes
- (false, error) if an unexpected error occurs
- (validity, nil) otherwise
func SignatureFormatCheck ¶
func SignatureFormatCheck(algo SigningAlgorithm, s Signature) (bool, error)
SignatureFormatCheck verifies the format of a serialized signature, regardless of messages or public keys.
This function is only defined for ECDSA algos for now.
If SignatureFormatCheck returns false then the input is not a valid signature and will fail a verification against any message and public key.
func TestHasherErrors ¶
func TestKeyGenErrors ¶
func VerifyBLSSignatureManyMessages ¶
func VerifyBLSSignatureManyMessages( pks []PublicKey, s Signature, messages [][]byte, kmac []hash.Hasher, ) (bool, error)
VerifyBLSSignatureManyMessages is a multi-signature verification that verifies a BLS signature under multiple messages and public keys.
The input signature could be generated by aggregating multiple signatures of distinct messages under distinct private keys. The verification is performed against the message at index (i) and the public key at the same index (i) of the input messages and public keys. The hasher at index (i) is used to hash the message at index (i).
Since the package only supports the Proof of Possession scheme, the function does not enforce input messages to be distinct. Thereore, the caller must make sure the input public keys's proofs of possession have been verified prior to calling this function (or each input key is sum of public keys of which proofs of possession have been verified).
The verification is optimized to compute one pairing per distinct message, or one pairing per distinct key, whatever way offers less pairings calls. If all messages are the same, the function has the same behavior as VerifyBLSSignatureOneMessage. If there is one input message and input public key, the function has the same behavior as pk.Verify. Membership check is performed on the input signature. In order to avoid equivocation issues, any identity public key results in the overall signature being invalid.
The function returns:
- (false, nilHasherError) if a hasher is nil
- (false, invalidHasherSizeError) if a hasher's output size is not 128 bytes
- (false, notBLSKeyError) if at least one key is not a BLS BLS12-381 key
- (false, invalidInputsError) if size of keys is not matching the size of messages and hashers
- (false, blsAggregateEmptyListError) if input key slice `pks` is empty
- (false, error) if an unexpected error occurs
- (validity, nil) otherwise
func VerifyBLSSignatureOneMessage ¶
func VerifyBLSSignatureOneMessage( pks []PublicKey, s Signature, message []byte, kmac hash.Hasher, ) (bool, error)
VerifyBLSSignatureOneMessage is a multi-signature verification that verifies a BLS signature of a single message against multiple BLS public keys.
The input signature could be generated by aggregating multiple signatures of the message under multiple private keys. The public keys corresponding to the signing private keys are passed as input to this function. The caller must make sure the input public keys's proofs of possession have been verified prior to calling this function (or each input key is sum of public keys of which proofs of possession have been verified).
The input hasher is the same hasher used to generate all initial signatures. The order of the public keys in the slice does not matter. Membership check is performed on the input signature but is not performed on the input public keys (membership is guaranteed by using the package functions). If the input public keys add up to the identity public key, the signature is invalid to avoid signature equivocation issues.
This is a special case function of VerifyBLSSignatureManyMessages, using a single message and hasher.
The function returns:
- (false, nilHasherError) if hasher is nil
- (false, invalidHasherSizeError) if hasher's output size is not 128 bytes
- (false, notBLSKeyError) if at least one key is not of type pubKeyBLSBLS12381
- (nil, blsAggregateEmptyListError) if input key slice is empty
- (false, error) if an unexpected error occurs
- (validity, nil) otherwise
Types ¶
type DKGProcessor ¶
type DKGProcessor interface { // PrivateSend sends a message to a destination over // a private channel. The channel must preserve the // confidentiality of the message and should authenticate // the sender. // It is recommended to use a unique private channel per // protocol instance. This can be achieved by prepending all // messages by a unique instance ID. // The message destination is specified using the destination index `dest`. PrivateSend(dest int, data []byte) // Broadcast broadcasts a message to all participants. // The function must implement a reliable broadcast // (Cachin and Poritz, Secure INtrusion-Tolerant Replication on the Internet, 2002) // to guarantee the correctness of the overall protocol. // The broadcasted message is public and not confidential. // The broadcasting channel should authenticate the sender. // It is recommended to use a unique broadcasting channel per // protocol instance. This can be achieved by prepending all // messages by a unique instance ID. Broadcast(data []byte) // Disqualify flags that the current instance detected that // another participant has misbehaved and that they got // disqualified from the protocol. Such misbehavior is // detected by all honest participants. // `log` is a string describing the disqualification reason. // The disqualified participant is referred to using its public index `index`. Disqualify(index int, log string) // FlagMisbehavior warns that the current instance detected that // another participant has misbehaved. // Such misbehavior is not necessarily detected by other participants and therefore // the participant is not disqualified from the protocol. // Other mechanisms outside DKG could be implemented to // synchronize slashing the misbehaving participant, // using the function `ForceDisqualify`. // Failing to synchronize the action properly by all honest participants // may break the protocol. // `log` is a string describing the misbehavior. // The disqualified participant is referred to using its public index `index`. FlagMisbehavior(index int, log string) }
DKGProcessor is an interface that implements the DKG actions by a DKG participant during the protocol run.
In particular, it implements the communication channels with the other participants, taking into account their pre-agreed public indices.
An instance of a DKGProcessor is needed for each participant in order to participate in a DKG protocol
type DKGState ¶
type DKGState interface { // Size returns the size of the DKG group n Size() int // Threshold returns the threshold value `t` Threshold() int // Start starts running a DKG in the current participant Start(seed []byte) error // HandleBroadcastMsg processes a new broadcasted message received by the current participant. // `orig` is the public index of the message sender. HandleBroadcastMsg(orig int, msg []byte) error // HandlePrivateMsg processes a new private message received by the current participant. // `orig` is the public index of the message sender. HandlePrivateMsg(orig int, msg []byte) error // End ends a DKG protocol in the current participant. // It returns the finalized public data and participant private key share. // - the group public key corresponding to the group secret key // - all the public key shares corresponding to the participants private // key shares // - the finalized private key which is the current participant's own private key share End() (PrivateKey, PublicKey, []PublicKey, error) // NextTimeout set the next timeout of the protocol if any timeout applies. // Some protocols could require more than one timeout NextTimeout() error // Running returns the running state of the DKG protocol Running() bool // ForceDisqualify forces a participant to get disqualified // for a reason outside of the DKG protocol. // The caller should make sure all honest participants call this function, // otherwise, the protocol can be broken. ForceDisqualify(participant int) error }
func NewFeldmanVSS ¶
func NewFeldmanVSS( size int, threshold int, myIndex int, processor DKGProcessor, dealerIndex int, ) (DKGState, error)
NewFeldmanVSS creates a new instance of Feldman VSS protocol.
An instance is run by a single participant and is usable for only one protocol run. In order to run the protocol again, a new instance needs to be created. The current participant uses the pre-agreed public index `myIndex`.
- `size` is the group size
- `threshold` is the threshold value `t`
- `myIndex` is the index of the current participant, in `[0, size-1]`
- `dealerIndex` is the index of the dealer, in `[0, size-1]`
- `processor` is an implementation of DKGProcessor (see dkg.go)
The function returns: - (nil, InvalidInputsError) if:
- `size` if not in `[DKGMinSize, DKGMaxSize]`
- `threshold` is not in `[MinimumThreshold, size-1]`
- `myIndex` is not in `[0, size-1]`
- `dealerIndex` is not in `[0, size-1]`
- (dkgInstance, nil) otherwise
func NewFeldmanVSSQual ¶
func NewFeldmanVSSQual( size int, threshold int, myIndex int, processor DKGProcessor, dealerIndex int, ) (DKGState, error)
NewFeldmanVSSQual creates a new instance of a Feldman VSS protocol with a qualification mechanism.
An instance is run by a single participant and is usable for only one protocol run. In order to run the protocol again, a new instance needs to be created. The current participant uses the pre-agreed public index `myIndex`.
- `size` is the group size
- `threshold` is the threshold value `t`
- `myIndex` is the index of the current participant, in `[0, size-1]`
- `dealerIndex` is the index of the dealer, in `[0, size-1]`
- `processor` is an implementation of DKGProcessor (see dkg.go)
The function returns: - (nil, InvalidInputsError) if:
- `size` is not in `[DKGMinSize, DKGMaxSize]`
- `threshold` is not in `[MinimumThreshold, size-1]`
- `myIndex` is not in `[0, size-1]`
- `dealerIndex` is not in `[0, size-1]`
- (dkgInstance, nil) otherwise
func NewJointFeldman ¶
func NewJointFeldman( size int, threshold int, myIndex int, processor DKGProcessor, ) (DKGState, error)
NewJointFeldman creates a new instance of a Joint Feldman protocol, used by a single participant.
An instance is run by a single participant and is usable for only one protocol run. In order to run the protocol again, a new instance needs to be created. The current participant uses the pre-agreed public index `myIndex`.
- `size` is the total number of participants `n`
- `threshold` is the threshold parameter `t`. the DKG protocol is secure in the presence of up to `t` malicious participants when `t < n/2`.
- `myIndex` is the index of the current participant, in `[0, n-1]`
- `processor` is the DKGProcessor instance required to implement
the communication channels with other participants (see dkg.go).
The function returns: - (nil, InvalidInputsError) if:
- `size` if not in `[DKGMinSize, DKGMaxSize]`
- `threshold` is not in `[MinimumThreshold, size-1]`
- `myIndex` is not in `[0, size-1]`
- `dealerIndex` is not in `[0, size-1]`
- (dkgInstance, nil) otherwise
type JointFeldmanState ¶ added in v0.25.0
type JointFeldmanState struct {
// contains filtered or unexported fields
}
Joint Feldman protocol, with complaint mechanism, implements DKGState
func (*JointFeldmanState) End ¶ added in v0.25.0
func (s *JointFeldmanState) End() (PrivateKey, PublicKey, []PublicKey, error)
End ends the protocol in the current participant It returns the finalized public data and participant private key share. - the group public key corresponding to the group secret key - all the public key shares corresponding to the participants private key shares. - the finalized private key which is the current participant's own private key share
The returned error is:
- dkgFailureError if the disqualified dealers exceeded the threshold
- dkgFailureError if the public key share or group public key is identity.
- dkgInvalidStateTransitionError Start() was not called, or NextTimeout() was not called twice
- nil otherwise.
func (*JointFeldmanState) ForceDisqualify ¶ added in v0.25.0
func (s *JointFeldmanState) ForceDisqualify(participant int) error
ForceDisqualify forces a participant to get disqualified for a reason outside of the DKG protocol The caller should make sure all honest participants call this function, otherwise, the protocol can be broken
The function returns:
- dkgInvalidStateTransitionError if the instance is not running
- invalidInputsError if `orig` is not valid (in [0, size-1])
- nil otherwise
func (*JointFeldmanState) HandleBroadcastMsg ¶ added in v0.25.0
func (s *JointFeldmanState) HandleBroadcastMsg(orig int, msg []byte) error
HandleBroadcastMsg processes a new broadcasted message received by the current participant orig is the message origin index
The function returns:
- dkgInvalidStateTransitionError if the instance is not running
- invalidInputsError if `orig` is not valid (in [0, size-1])
- nil otherwise
func (*JointFeldmanState) HandlePrivateMsg ¶ added in v0.25.0
func (s *JointFeldmanState) HandlePrivateMsg(orig int, msg []byte) error
HandlePrivateMsg processes a new private message received by the current participant orig is the message origin index
The function returns:
- dkgInvalidStateTransitionError if the instance is not running
- invalidInputsError if `orig` is not valid (in [0, size-1])
- nil otherwise
func (*JointFeldmanState) NextTimeout ¶ added in v0.25.0
func (s *JointFeldmanState) NextTimeout() error
NextTimeout sets the next timeout of the protocol if any timeout applies.
The returned error is :
- dkgInvalidStateTransitionError if the DKG instance was not running.
- dkgInvalidStateTransitionError if the DKG instance already called the 2 required timeouts.
- nil otherwise.
func (*JointFeldmanState) Running ¶ added in v0.25.0
func (s *JointFeldmanState) Running() bool
Running returns the running state of Joint Feldman protocol
func (JointFeldmanState) Size ¶ added in v0.25.0
func (s JointFeldmanState) Size() int
Size returns the size of the DKG group n
func (*JointFeldmanState) Start ¶ added in v0.25.0
func (s *JointFeldmanState) Start(seed []byte) error
Start triggers Joint Feldman protocol start for the current participant. The seed is used to generate the FVSS secret polynomial (including the instance group private key) when the current participant is the dealer.
The returned error is :
- dkgInvalidStateTransitionError if the DKG instance is already running.
- error if an unexpected exception occurs
- nil otherwise.
type PrivateKey ¶
type PrivateKey interface { // Algorithm returns the signing algorithm related to the private key. Algorithm() SigningAlgorithm // Size return the key size in bytes. Size() int // String return a hex representation of the key String() string // Sign generates a signature using the provided hasher. Sign([]byte, hash.Hasher) (Signature, error) // PublicKey returns the public key. PublicKey() PublicKey // Encode returns a bytes representation of the private key Encode() []byte // Equals returns true if the given PrivateKeys are equal. Keys are considered unequal if their algorithms are // unequal or if their encoded representations are unequal. If the encoding of either key fails, they are considered // unequal as well. Equals(PrivateKey) bool }
PrivateKey is an unspecified signature scheme private key
func AggregateBLSPrivateKeys ¶
func AggregateBLSPrivateKeys(keys []PrivateKey) (PrivateKey, error)
AggregateBLSPrivateKeys aggregates multiple BLS private keys into one.
The order of the keys in the slice does not matter since the aggregation is commutative. The slice should not be empty. No check is performed on the input private keys. Input or output private keys could be equal to the identity element (zero). Note that any signature generated by the identity key is invalid (to avoid equivocation issues).
The function returns:
- (nil, notBLSKeyError) if at least one key is not of type BLS BLS12-381
- (nil, blsAggregateEmptyListError) if no keys are provided (input slice is empty)
- (aggregated_key, nil) otherwise
func DecodePrivateKey ¶
func DecodePrivateKey(algo SigningAlgorithm, data []byte) (PrivateKey, error)
DecodePrivateKey decodes an array of bytes into a private key of the given algorithm
The function returns:
- (nil, invalidInputsErrors) if the signing algorithm is not supported
- (nil, invalidInputsErrors) if the input does not serialize a valid private key:
- ECDSA: bytes(x) where bytes() is the big-endian encoding padded to the curve order.
- BLS: bytes(x) where bytes() is the big-endian encoding padded to the order of BLS12-381. for all algorithms supported, input is big-endian encoding of a the private scalar less than the curve order and left-padded to 32 bytes
- (nil, error) if an unexpected error occurs
- (sk, nil) otherwise
func GeneratePrivateKey ¶
func GeneratePrivateKey(algo SigningAlgorithm, seed []byte) (PrivateKey, error)
GeneratePrivateKey generates a private key of the algorithm using the entropy of the given seed.
The seed minimum length is 32 bytes and it should have enough entropy. It is recommended to use a secure crypto RNG to generate the seed.
The function returns:
- (false, invalidInputsErrors) if the signing algorithm is not supported or if the seed length is not valid (less than 32 bytes or larger than 256 bytes)
- (false, error) if an unexpected error occurs
- (sk, nil) if key generation was successful
type PublicKey ¶
type PublicKey interface { // Algorithm returns the signing algorithm related to the public key. Algorithm() SigningAlgorithm // Size() return the key size in bytes. Size() int // String return a hex representation of the key String() string // Verify verifies a signature of an input message using the provided hasher. Verify(Signature, []byte, hash.Hasher) (bool, error) // Encode returns a bytes representation of the public key. Encode() []byte // EncodeCompressed returns a compressed byte representation of the public key. // The compressed serialization concept is generic to elliptic curves, // but we refer to individual curve parameters for details of the compressed format EncodeCompressed() []byte // Equals returns true if the given PublicKeys are equal. Keys are considered unequal if their algorithms are // unequal or if their encoded representations are unequal. If the encoding of either key fails, they are considered // unequal as well. Equals(PublicKey) bool }
PublicKey is an unspecified signature scheme public key.
func AggregateBLSPublicKeys ¶
AggregateBLSPublicKeys aggregate multiple BLS public keys into one.
The order of the keys in the slice does not matter since the aggregation is commutative. The slice should not be empty. No check is performed on the input public keys. The input keys are guaranteed by the package constructors to be on the G2 subgroup. Input or output keys can be equal to the identity key. Note that any signature verified against the identity key is invalid (to avoid equivocation issues).
The function returns:
- (nil, notBLSKeyError) if at least one key is not of type BLS BLS12-381
- (nil, blsAggregateEmptyListError) no keys are provided (input slice is empty)
- (aggregated_key, nil) otherwise
func DecodePublicKey ¶
func DecodePublicKey(algo SigningAlgorithm, data []byte) (PublicKey, error)
DecodePublicKey decodes an array of bytes into a public key of the given algorithm
The function returns:
- (nil, invalidInputsErrors) if the signing algorithm is not supported
- (nil, invalidInputsErrors) if the input does not serialize a valid public key:
- ECDSA: bytes(x)||bytes(y) where bytes() is the big-endian encoding padded to the field size.
- BLS: compressed serialization of a G2 point following https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-08.html#name-zcash-serialization-format-
- (nil, error) if an unexpected error occurs
- (sk, nil) otherwise
func DecodePublicKeyCompressed ¶
func DecodePublicKeyCompressed(algo SigningAlgorithm, data []byte) (PublicKey, error)
DecodePublicKeyCompressed decodes an array of bytes given in a compressed representation into a public key of the given algorithm Only ECDSA is supported (BLS uses the compressed serialzation by default).
The function returns:
- (nil, invalidInputsErrors) if the signing algorithm is not supported (is not ECDSA)
- (nil, invalidInputsErrors) if the input does not serialize a valid public key:
- ECDSA: sign_byte||bytes(x) according to X9.62 section 4.3.6.
- (nil, error) if an unexpected error occurs
- (sk, nil) otherwise
func IdentityBLSPublicKey ¶
func IdentityBLSPublicKey() PublicKey
IdentityBLSPublicKey returns an identity public key which corresponds to the point at infinity in G2 (identity element g2).
func RemoveBLSPublicKeys ¶
RemoveBLSPublicKeys removes multiple BLS public keys from a given (aggregated) public key.
The common use case assumes the aggregated public key was initially formed using the keys to be removed (directly or using other aggregated forms). However the function can still be called in different use cases. The order of the keys to be removed in the slice does not matter since the removal is commutative. The slice of keys to be removed can be empty. No check is performed on the input public keys. The input keys are guaranteed by the package constructors to be on the G2 subgroup. Input or output keys can be equal to the identity key.
The function returns:
- (nil, notBLSKeyError) if at least one input key is not of type BLS BLS12-381
- (remaining_key, nil) otherwise
type Signature ¶
type Signature []byte
Signature is a generic type, regardless of the signature scheme
func AggregateBLSSignatures ¶
AggregateBLSSignatures aggregates multiple BLS signatures into one.
Signatures could be generated from the same or distinct messages, they could also be the aggregation of other signatures. The order of the signatures in the slice does not matter since the aggregation is commutative. The slice should not be empty. No G1 membership check is performed on the input signatures.
The function returns:
- (nil, blsAggregateEmptyListError) if no signatures are provided (input slice is empty)
- (nil, invalidSignatureError) if a deserialization of at least one signature fails (input is an invalid serialization of a compressed E1 element following [zcash] https://www.ietf.org/archive/id/draft-irtf-cfrg-pairing-friendly-curves-08.html#name-zcash-serialization-format-). G1 membership is not checked.
- (nil, error) if an unexpected error occurs
- (aggregated_signature, nil) otherwise
func BLSGeneratePOP ¶
func BLSGeneratePOP(sk PrivateKey) (Signature, error)
BLSGeneratePOP returns a proof of possession (PoP) for the receiver private key.
The KMAC hasher used in the function is guaranteed to be orthogonal to all hashers used for signatures or SPoCK proofs on this package. This means a specific domain tag is used to generate PoP and is not used by any other application.
The function returns:
- (nil, notBLSKeyError) if the input key is not of type BLS BLS12-381
- (pop, nil) otherwise
func BLSInvalidSignature ¶
func BLSInvalidSignature() Signature
BLSInvalidSignature returns an invalid signature that fails when verified with any message and public key, which can be used for testing.
The signature bytes represent an invalid serialization of a point which makes the verification fail early. The verification would return (false, nil).
func BLSReconstructThresholdSignature ¶
func BLSReconstructThresholdSignature(size int, threshold int, shares []Signature, signers []int) (Signature, error)
BLSReconstructThresholdSignature is a stateless BLS api that takes a list of BLS signatures and their signers' indices and returns the threshold signature.
size is the number of participants, it must be in the range [ThresholdSignMinSize..ThresholdSignMaxSize]. threshold is the threshold value, it must be in the range [MinimumThreshold..size-1]. The function does not accept any input public key. Therefore, it does not check the validity of the shares against individual public keys, and does not check the validity of the resulting signature against the group public key. BLSReconstructThresholdSignature returns:
- (nil, invalidInputsError) if : -- numbers of shares does not match the number of signers -- the inputs are not in the correct range.
- (nil, notEnoughSharesError) if the threshold is not reached.
- (nil, duplicatedSignerError) if input signers are not distinct.
- (nil, invalidSignatureError) if at least one of the first (threshold+1) signatures. does not serialize to a valid E1 point.
- (threshold_sig, nil) otherwise.
If the number of shares reaches the required threshold, only the first threshold+1 shares are considered to reconstruct the signature.
func SPOCKProve ¶
SPOCKProve generates a spock poof for data under the private key sk.
The function returns:
- (false, nilHasherError) if the hasher is nil
- (false, invalidHasherSiseError) if hasher's output size is not 128 bytes
- (nil, notBLSKeyError) if input key is not a BLS key
- (nil, error) if an unexpected error occurs
- (proof, nil) otherwise
type SigningAlgorithm ¶
type SigningAlgorithm int
SigningAlgorithm is an identifier for a signing algorithm (and parameters if applicable)
const ( // Supported signing algorithms UnknownSigningAlgorithm SigningAlgorithm = iota // BLSBLS12381 is BLS on BLS 12-381 curve BLSBLS12381 // ECDSAP256 is ECDSA on NIST P-256 curve ECDSAP256 // ECDSASecp256k1 is ECDSA on secp256k1 curve ECDSASecp256k1 )
func (SigningAlgorithm) String ¶
func (f SigningAlgorithm) String() string
String returns the string representation of this signing algorithm.
type ThresholdSignatureInspector ¶
type ThresholdSignatureInspector interface { // key at the input index. This function does not update the internal state. // The function is thread-safe. // Returns: // - (true, nil) if the signature is valid // - (false, nil) if `index` is a valid index but the signature share is invalid // - (false, InvalidInputsError) if `index` is an invalid index value // - (false, error) for all other unexpected errors VerifyShare(index int, share Signature) (bool, error) // VerifyThresholdSignature verifies the input signature against the stored // message and stored group public key. It does not update the internal state. // The function is thread-safe. // Returns: // - (true, nil) if the signature is valid // - (false, nil) if the signature is invalid // - (false, error) for all other unexpected errors VerifyThresholdSignature(thresholdSignature Signature) (bool, error) // a group signature. This function is thread safe and locks the internal state. // Returns: // - true if and only if at least (threshold+1) shares were added EnoughShares() bool // TrustedAdd adds a signature share to the internal pool of shares // without verifying the signature against the message and the participant's // public key. This function is thread safe and locks the internal state. // // The share is only added if the signer index is valid and has not been // added yet. Moreover, the share is added only if not enough shares were collected. // The function returns: // - (true, nil) if enough signature shares were already collected and no error occurred // - (false, nil) if not enough shares were collected and no error occurred // - (false, InvalidInputsError) if index is invalid // - (false, duplicatedSignerError) if a signature for the index was previously added TrustedAdd(index int, share Signature) (bool, error) // VerifyAndAdd verifies a signature share (same as `VerifyShare`), // and may or may not add the share to the local pool of shares. // This function is thread safe and locks the internal state. // // The share is only added if the signature is valid, the signer index is valid and has not been // added yet. Moreover, the share is added only if not enough shares were collected. // Boolean returns: // - First boolean output is true if the share is valid and no error is returned, and false otherwise. // - Second boolean output is true if enough shares were collected and no error is returned, and false otherwise. // Error returns: // - invalidInputsError if input index is invalid. A signature that doesn't verify against the signer's // public key is not considered an invalid input. // - duplicatedSignerError if signer was already added. // - other errors if an unexpected exception occurred. VerifyAndAdd(index int, share Signature) (bool, bool, error) // This function is thread safe. // The function errors with InvalidInputsError if the index is invalid. HasShare(index int) (bool, error) // ThresholdSignature returns the threshold signature if the threshold was reached. // The threshold signature is reconstructed only once and is cached for subsequent calls. // // Returns: // - (signature, nil) if no error occurred // - (nil, notEnoughSharesError) if not enough shares were collected // - (nil, invalidSignatureError) if at least one collected share does not serialize to a valid BLS signature. // - (nil, invalidInputsError) if the constructed signature failed to verify against the group public key and stored message. This post-verification // is required for safety, as `TrustedAdd` allows adding invalid signatures. // - (nil, error) for any other unexpected error. ThresholdSignature() (Signature, error) }
ThresholdSignatureInspector is an inspector of the threshold signature protocol.
An inspector is not holding a private key share and does not contribute to the protocol but is able to verify and reconstruct signatures in a non-interactive manner based on the public data of the protocol.
type ThresholdSignatureParticipant ¶
type ThresholdSignatureParticipant interface { ThresholdSignatureInspector // // The function does not add the share to the internal pool of shares and do // not update the internal state. // This function is thread safe // No error is expected unless an unexpected exception occurs SignShare() (Signature, error) }
ThresholdSignatureParticipant is a participant in a threshold signature protocol. A participant holds a private key share and can contribute to group signatures, in addition to inspecting and reconstructing signatures.