dkg

package
v5.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 17, 2022 License: MPL-2.0 Imports: 11 Imported by: 0

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) For an example how to use it please have a look at examples/dkg_test.go

Index

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

	// Share to refresh. It must be nil for a new node wishing to
	// 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

func (d *Deal) MarshalBinary() ([]byte, error)

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) (*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) 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.

func (*DistKeyGenerator) Verifiers

func (d *DistKeyGenerator) Verifiers() map[uint32]*vss.Verifier

Verifiers returns the verifiers keeping state of each deals

type DistKeyShare

type DistKeyShare struct {
	// Coefficients of the public polynomial holding the public key.
	Commits []kyber.Point
	// Share of the distributed secret which is private information.
	Share *share.PriShare
	// Coefficients of the private polynomial generated by the node holding the
	// share. The final distributed polynomial is the sum of all these
	// individual polynomials, but it is never computed.
	PrivatePoly []kyber.Scalar
}

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.

type Response

type Response struct {
	// Index of the Dealer for which this response is for
	Index uint32
	// Response issued from another participant
	Response *vss.Response
}

Response holds the Response from another participant as well as the index of the target Dealer.

type Suite

type Suite vss.Suite

Suite wraps the functionalities needed by the dkg package

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL