Documentation ¶
Overview ¶
Package dkg implements a general distributed key generation (DKG) framework. This package serves two functionalities: (1) to run a fresh new DKG from scratch and (2) to reshare old shares to a potentially distinct new set of nodes (the "resharing" protocol). The former protocol is described in "A threshold cryptosystem without a trusted party" by Torben Pryds Pedersen. https://dl.acm.org/citation.cfm?id=1754929. The latter protocol is implemented in "Verifiable Secret Redistribution for Threshold Signing Schemes", by T. Wong et al.(https://www.cs.cmu.edu/~wing/publications/Wong-Wing02b.pdf)
Index ¶
- type Config
- type Deal
- type DistKeyGenerator
- func (d *DistKeyGenerator) Certified() bool
- func (d *DistKeyGenerator) Deals() (map[int]*Deal, error)
- func (d *DistKeyGenerator) DistKeyShare() (*DistKeyShare, error)
- func (d *DistKeyGenerator) ExpectedDeals() int
- func (d *DistKeyGenerator) GetConfig() *Config
- func (d *DistKeyGenerator) GetDealer() *vss.Dealer
- func (d *DistKeyGenerator) ProcessDeal(dd *Deal) (*Response, error)
- func (d *DistKeyGenerator) ProcessJustification(j *Justification) error
- func (d *DistKeyGenerator) ProcessResponse(resp *Response) (*Justification, error)
- func (d *DistKeyGenerator) QUAL() []int
- func (d *DistKeyGenerator) QualifiedShares() []int
- func (d *DistKeyGenerator) SetTimeout()
- func (d *DistKeyGenerator) ThresholdCertified() bool
- func (d *DistKeyGenerator) Verifiers() map[uint32]*vss.Verifier
- type DistKeyShare
- type Justification
- type Response
- type Suite
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct { Suite Suite // Longterm is the longterm secret key. Longterm kyber.Scalar // Current group of share holders. It will be nil for new DKG. These nodes // will have invalid shares after the protocol has been run. To be able to issue // new shares to a new group, the group member's public key must be inside this // list and in the Share field. Keys can be disjoint or not with respect to the // NewNodes list. OldNodes []kyber.Point // PublicCoeffs are the coefficients of the distributed polynomial needed // during the resharing protocol. The first coefficient is the key. It is // required for new share holders. It should be nil for a new DKG. PublicCoeffs []kyber.Point // Expected new group of share holders. These public-key designated nodes // will be in possession of new shares after the protocol has been run. To be a // receiver of a new share, one's public key must be inside this list. Keys // can be disjoint or not with respect to the OldNodes list. NewNodes []kyber.Point // join or create a group. To be able to issue new fresh shares to a new group, // one's share must be specified here, along with the public key inside the // OldNodes field. Share *DistKeyShare // The threshold to use in order to reconstruct the secret with the produced // shares. This threshold is with respect to the number of nodes in the // NewNodes list. If unspecified, default is set to // `vss.MinimumT(len(NewNodes))`. This threshold indicates the degree of the // polynomials used to create the shares, and the minimum number of // verification required for each deal. Threshold int // OldThreshold holds the threshold value that was used in the previous // configuration. This field MUST be specified when doing resharing, but is // not needed when doing a fresh DKG. This value is required to gather a // correct number of valid deals before creating the distributed key share. // NOTE: this field is always required (instead of taking the default when // absent) when doing a resharing to avoid a downgrade attack, where a resharing // the number of deals required is less than what it is supposed to be. OldThreshold int // Reader is an optional field that can hold a user-specified entropy source. // If it is set, Reader's data will be combined with random data from crypto/rand // to create a random stream which will pick the dkg's secret coefficient. Otherwise, // the random stream will only use crypto/rand's entropy. Reader io.Reader // When UserReaderOnly it set to true, only the user-specified entropy source // Reader will be used. This should only be used in tests, allowing reproducibility. UserReaderOnly bool }
Config holds all required information to run a fresh DKG protocol or a resharing protocol. In the case of a new fresh DKG protocol, one must fill the following fields: Suite, Longterm, NewNodes, Threshold (opt). In the case of a resharing protocol, one must fill the following: Suite, Longterm, OldNodes, NewNodes. If the node using this config is creating new shares (i.e. it belongs to the current group), the Share field must be filled in with the current share of the node. If the node using this config is a new addition and thus has no current share, the PublicCoeffs field be must be filled in.
type Deal ¶
type Deal struct { // Index of the Dealer in the list of participants Index uint32 // Deal issued for another participant Deal *vss.EncryptedDeal // Signature over the whole message Signature []byte }
Deal holds the Deal for one participant as well as the index of the issuing Dealer.
func (*Deal) MarshalBinary ¶
MarshalBinary returns a binary representation of this deal, which is the message signed in a dkg deal.
type DistKeyGenerator ¶
type DistKeyGenerator struct {
// contains filtered or unexported fields
}
DistKeyGenerator is the struct that runs the DKG protocol.
func NewDistKeyGenerator ¶
func NewDistKeyGenerator(suite Suite, longterm kyber.Scalar, participants []kyber.Point, t int, reader io.Reader) (*DistKeyGenerator, error)
NewDistKeyGenerator returns a dist key generator ready to create a fresh distributed key with the regular DKG protocol.
func NewDistKeyHandler ¶
func NewDistKeyHandler(c *Config) (*DistKeyGenerator, error)
NewDistKeyHandler takes a Config and returns a DistKeyGenerator that is able to drive the DKG or resharing protocol.
func (*DistKeyGenerator) Certified ¶
func (d *DistKeyGenerator) Certified() bool
Certified returns true if *all* deals are certified. This method should be called before the timeout occurs, as to pre-emptively stop the DKG protocol if it is already finished before the timeout.
func (*DistKeyGenerator) Deals ¶
func (d *DistKeyGenerator) Deals() (map[int]*Deal, error)
Deals returns all the deals that must be broadcasted to all participants in the new list. The deal corresponding to this DKG is already added to this DKG and is ommitted from the returned map. To know which participant a deal belongs to, loop over the keys as indices in the list of new participants:
for i,dd := range distDeals { sendTo(participants[i],dd) }
If this method cannot process its own Deal, that indicates a severe problem with the configuration or implementation and results in a panic.
func (*DistKeyGenerator) DistKeyShare ¶
func (d *DistKeyGenerator) DistKeyShare() (*DistKeyShare, error)
DistKeyShare generates the distributed key relative to this receiver. It throws an error if something is wrong such as not enough deals received. The shared secret can be computed when all deals have been sent and basically consists of a public point and a share. The public point is the sum of all aggregated individual public commits of each individual secrets. The share is evaluated from the global Private Polynomial, basically SUM of fj(i) for a receiver i.
func (*DistKeyGenerator) ExpectedDeals ¶
func (d *DistKeyGenerator) ExpectedDeals() int
ExpectedDeals returns the number of deals that this node will receive from the other participants.
func (*DistKeyGenerator) GetConfig ¶
func (d *DistKeyGenerator) GetConfig() *Config
func (*DistKeyGenerator) GetDealer ¶
func (d *DistKeyGenerator) GetDealer() *vss.Dealer
func (*DistKeyGenerator) ProcessDeal ¶
func (d *DistKeyGenerator) ProcessDeal(dd *Deal) (*Response, error)
ProcessDeal takes a Deal created by Deals() and stores and verifies it. It returns a Response to broadcast to every other participant, including the old participants. It returns an error in case the deal has already been stored, or if the deal is incorrect (see vss.Verifier.ProcessEncryptedDeal).
func (*DistKeyGenerator) ProcessJustification ¶
func (d *DistKeyGenerator) ProcessJustification(j *Justification) error
ProcessJustification takes a justification and validates it. It returns an error in case the justification is wrong.
func (*DistKeyGenerator) ProcessResponse ¶
func (d *DistKeyGenerator) ProcessResponse(resp *Response) (*Justification, error)
ProcessResponse takes a response from every other peer. If the response designates the deal of another participant than this dkg, this dkg stores it and returns nil with a possible error regarding the validity of the response. If the response designates a deal this dkg has issued, then the dkg will process the response, and returns a justification.
func (*DistKeyGenerator) QUAL ¶
func (d *DistKeyGenerator) QUAL() []int
QUAL returns the index in the list of participants that forms the QUALIFIED set, i.e. the list of Certified deals. It does NOT take into account any malicious share holder which share may have been revealed, due to invalid complaint.
func (*DistKeyGenerator) QualifiedShares ¶
func (d *DistKeyGenerator) QualifiedShares() []int
QualifiedShares returns the set of shares holder index that are considered valid. In particular, it computes the list of common share holders that replied with an approval (or with a complaint later on justified) for each deal received. These indexes represent the new share holders with valid (or justified) shares from certified deals. Detailled explanation: To compute this list, we consider the scenario where a share holder replied to one share but not the other, as invalid, as the library is not currently equipped to deal with that scenario. 1. If there is a valid complaint non-justified for a deal, the deal is deemed invalid 2. if there are no response from a share holder, the share holder is removed from the list.
func (*DistKeyGenerator) SetTimeout ¶
func (d *DistKeyGenerator) SetTimeout()
SetTimeout triggers the timeout on all verifiers, and thus makes sure all verifiers have either responded, or have a StatusComplaint response.
func (*DistKeyGenerator) ThresholdCertified ¶
func (d *DistKeyGenerator) ThresholdCertified() bool
ThresholdCertified returns true if a THRESHOLD of deals are certified. To know the list of correct receiver, one can call d.QUAL() NOTE: This method should only be used after a certain timeout - mimicking the synchronous assumption of the Pedersen's protocol. One can call `Certified()` to check if the DKG is finished and stops it pre-emptively if all deals are correct. If called *before* the timeout, there may be inconsistencies in the shares produced. For example, node 1 could have aggregated shares from 1, 2, 3 and node 2 could have aggregated shares from 2, 3 and 4.
type DistKeyShare ¶
type DistKeyShare struct { kyber.Point Share *share.PriShare // share. The final distributed polynomial is the sum of all these // individual polynomials, but it is never computed. PrivatePoly []kyber.Scalar }Commits []
DistKeyShare holds the share of a distributed key for a participant.
func (*DistKeyShare) Commitments ¶
func (d *DistKeyShare) Commitments() []kyber.Point
Commitments implements the dss.DistKeyShare interface so either pedersen or rabin dkg can be used with dss.
func (*DistKeyShare) PriShare ¶
func (d *DistKeyShare) PriShare() *share.PriShare
PriShare implements the dss.DistKeyShare interface so either pedersen or rabin dkg can be used with dss.
func (*DistKeyShare) Public ¶
func (d *DistKeyShare) Public() kyber.Point
Public returns the public key associated with the distributed private key.
func (*DistKeyShare) Renew ¶
func (d *DistKeyShare) Renew(suite Suite, g *DistKeyShare) (*DistKeyShare, error)
Renew adds the new distributed key share g (with secret 0) to the distributed key share d.
type Justification ¶
type Justification struct { // Index of the Dealer who answered with this Justification Index uint32 // Justification issued from the Dealer Justification *vss.Justification }
Justification holds the Justification from a Dealer as well as the index of the Dealer in question.