Documentation ¶
Index ¶
- Constants
- Variables
- func GetNonce() []byte
- func MinimumT(n int) int
- func VerifyPacketSignature(c *Config, p Packet) error
- type BitSet
- type Board
- type Config
- type Deal
- type DealBundle
- type DistKeyGenerator
- func (d *DistKeyGenerator) Deals() (*DealBundle, error)
- func (d *DistKeyGenerator) Error(keyvals ...interface{})
- func (d *DistKeyGenerator) ExpectedResponsesFastSync() int
- func (d *DistKeyGenerator) Info(keyvals ...interface{})
- func (d *DistKeyGenerator) ProcessDeals(bundles []*DealBundle) (*ResponseBundle, error)
- func (d *DistKeyGenerator) ProcessJustifications(bundles []*JustificationBundle) (*Result, error)
- func (d *DistKeyGenerator) ProcessResponses(bundles []*ResponseBundle) (res *Result, jb *JustificationBundle, err error)
- type DistKeyShare
- type Index
- type Justification
- type JustificationBundle
- type Logger
- type Node
- type OptionResult
- type Packet
- type Phase
- type Phaser
- type Protocol
- type Response
- type ResponseBundle
- type Result
- type StatusMatrix
- func (s *StatusMatrix) AllTrue(dealer uint32) bool
- func (s *StatusMatrix) CompleteSuccess() bool
- func (s *StatusMatrix) Get(dealer, share uint32) bool
- func (s *StatusMatrix) Set(dealer, share uint32, status bool)
- func (s *StatusMatrix) SetAll(dealer uint32, status bool)
- func (s *StatusMatrix) StatusesForShare(shareIndex uint32) BitSet
- func (s *StatusMatrix) StatusesOfDealer(dealerIndex uint32) BitSet
- func (s *StatusMatrix) String() string
- type Suite
- type TimePhaser
Constants ¶
const ( Success = true Complaint = false )
const NonceLength = 32
NonceLength is the length of the nonce
Variables ¶
var ErrEvicted = errors.New("our node is evicted from list of qualified participants")
Functions ¶
func GetNonce ¶ added in v1.1.0
func GetNonce() []byte
GetNonce returns a suitable nonce to feed in the DKG config.
func VerifyPacketSignature ¶ added in v1.1.2
VerifyPacketSignature returns an error if the packet has an invalid signature. The signature is verified via the information contained in the config, namely the old and new nodes public keys.
Types ¶
type BitSet ¶
func (BitSet) LengthComplaints ¶ added in v1.1.1
type Board ¶
type Board interface { PushDeals(*DealBundle) IncomingDeal() <-chan DealBundle PushResponses(*ResponseBundle) IncomingResponse() <-chan ResponseBundle PushJustifications(*JustificationBundle) IncomingJustification() <-chan JustificationBundle }
Board is the interface between the dkg protocol and the external world. It consists in pushing packets out to other nodes and receiving in packets from the other nodes. A common board would use the network as the underlying communication mechanism but one can also use a smart contract based approach.
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 []Node // 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 []Node // 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 // FastSync is a mode where nodes sends pre-emptively responses indicating // that the shares they received are good. If a share is invalid, a // complaint is still sent as usual. This has two consequences: // - In the event all shares are good, nodes don't need to wait for the // timeout; they can already finish the protocol at the point. // - However, it requires nodes to send more messages on the network. We // pass from a O(f) where f is the number of faults to a O(n^2). Note that // the responses messages are small. FastSync bool // Nonce is required to avoid replay attacks from previous runs of a DKG / // resharing. The required property of the Nonce is that it must be unique // accross runs. A Nonce must be of length 32 bytes. User can get a secure // nonce by calling `GetNonce()`. Nonce []byte // Auth is the scheme to use to authentify the packets sent and received // during the protocol. Auth sign.Scheme // Log enables the DKG logic and protocol to log important events (mostly // errors). from participants. Errors don't mean the protocol should be // stopped, so logging is the best way to communicate information to the // application layer. It can be nil. Log Logger }
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.
func (*Config) CheckForDuplicates ¶ added in v1.1.8
CheckForDuplicates looks at the lits of node indices in the OldNodes and NewNodes list. It returns an error if there is a duplicate in either list. NOTE: It only looks at indices because it is plausible that one party may have multiple indices for the protocol, i.e. a higher "weight".
type DealBundle ¶
type DealBundle struct { DealerIndex uint32 Deals []Deal // Public coefficients of the public polynomial used to create the shares Public []kyber.Point // SessionID of the current run SessionID []byte // Signature over the hash of the whole bundle Signature []byte }
DealBundle is the struct sent out by dealers that contains all the deals and the public polynomial.
func (*DealBundle) Hash ¶
func (d *DealBundle) Hash() []byte
Hash hashes the index, public coefficients and deals
func (*DealBundle) Index ¶ added in v1.1.0
func (d *DealBundle) Index() Index
func (*DealBundle) Sig ¶ added in v1.1.2
func (d *DealBundle) Sig() []byte
type DistKeyGenerator ¶
type DistKeyGenerator struct {
// contains filtered or unexported fields
}
DistKeyGenerator is the struct that runs the 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) Deals ¶
func (d *DistKeyGenerator) Deals() (*DealBundle, error)
func (*DistKeyGenerator) Error ¶ added in v1.1.9
func (d *DistKeyGenerator) Error(keyvals ...interface{})
func (*DistKeyGenerator) ExpectedResponsesFastSync ¶
func (d *DistKeyGenerator) ExpectedResponsesFastSync() int
func (*DistKeyGenerator) Info ¶ added in v1.1.9
func (d *DistKeyGenerator) Info(keyvals ...interface{})
func (*DistKeyGenerator) ProcessDeals ¶
func (d *DistKeyGenerator) ProcessDeals(bundles []*DealBundle) (*ResponseBundle, error)
ProcessDeals process the deals from all the nodes. Each deal for this node is decrypted and stored. It returns a response bundle if there is any invalid or missing deals. It returns an error if the node is not in the right state, or if there is not enough valid shares, i.e. the dkg is failing already.
func (*DistKeyGenerator) ProcessJustifications ¶
func (d *DistKeyGenerator) ProcessJustifications(bundles []*JustificationBundle) (*Result, error)
ProcessJustifications takes the justifications of the nodes and returns the results if there is enough QUALified nodes, or an error otherwise. Note that this method returns "nil,nil" if this node is a node only present in the old group of the dkg: indeed a node leaving the group don't need to process justifications, and can simply leave the protocol.
func (*DistKeyGenerator) ProcessResponses ¶
func (d *DistKeyGenerator) ProcessResponses(bundles []*ResponseBundle) (res *Result, jb *JustificationBundle, err error)
ProcessResponses takes the response from all nodes if any and returns a triplet: - the result if there is no complaint. If not nil, the DKG is finished. - the justification bundle if this node must produce at least one. If nil, this node must still wait on the justification phase. - error if the dkg must stop now, an unrecoverable failure.
type DistKeyShare ¶
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.
type Index ¶
type Index = uint32
Index is an alias to designate the index of a node. The index is used to evaluate the share of a node, and is thereafter fixed. A node will use the same index for generating a partial signature afterwards for example.
type Justification ¶
type Justification struct {}
type JustificationBundle ¶
type JustificationBundle struct { DealerIndex uint32 Justifications []Justification // SessionID of the current run SessionID []byte // Signature over the hash of the whole bundle Signature []byte }
JustificationBundle is the struct that contains all justifications for each complaint in the precedent phase.
func (*JustificationBundle) Hash ¶
func (j *JustificationBundle) Hash() []byte
func (*JustificationBundle) Index ¶ added in v1.1.0
func (j *JustificationBundle) Index() Index
func (*JustificationBundle) Sig ¶ added in v1.1.2
func (j *JustificationBundle) Sig() []byte
type Logger ¶ added in v1.1.8
type Logger interface { Info(keyvals ...interface{}) Error(keyvals ...interface{}) }
Logger is a simpler key value logger interface
type Node ¶
Node represents the public key and its index amongt the list of participants. For a fresh DKG, the index can be anything but we usually take the index that corresponds to the position in the list of participants. For a resharing, if that node is a node that has already ran the DKG, we need to use the same index as it was given in the previous DKG in the list of OldNodes, in the DKG config.
type OptionResult ¶
type Packet ¶ added in v1.1.2
Packet is the interface that implements the three messages that this implementation uses during the different phases. This interface allows to verify a DKG packet without knowing its specific type.
type Phase ¶
type Phase int
Phase is a type that represents the different stages of the DKG protocol.
type Phaser ¶
type Phaser interface {
NextPhase() chan Phase
}
Phaser must signal on its channel when the protocol should move to a next phase. Phase must be sequential: DealPhase (start), ResponsePhase, JustifPhase and then FinishPhase. Note that if the dkg protocol finishes before the phaser sends the FinishPhase, the protocol will not listen on the channel anymore. This can happen if there is no complaints, or if using the "FastSync" mode. Most of the times, user should use the TimePhaser when using the network, but if one wants to use a smart contract as a board, then the phaser can tick at certain blocks, or when the smart contract tells it.
type Protocol ¶
type Protocol struct {
// contains filtered or unexported fields
}
Protocol contains the logic to run a DKG protocol over a generic broadcast channel, called Board. It handles the receival of packets, ordering of the phases and the termination. A protocol can be ran over a network, a smart contract, or anything else that is implemented via the Board interface.
func NewProtocol ¶
func (*Protocol) WaitEnd ¶
func (p *Protocol) WaitEnd() <-chan OptionResult
type Response ¶
type Response struct { // Index of the Dealer for which this response is for DealerIndex uint32 Status bool }
Response holds the Response from another participant as well as the index of the target Dealer.
type ResponseBundle ¶
type ResponseBundle struct { // Index of the share holder for which these reponses are for Responses []Response // SessionID of the current run SessionID []byte // Signature over the hash of the whole bundle Signature []byte }
ResponseBundle is the struct sent out by share holder containing the status for the deals received in the first phase.
func (*ResponseBundle) Hash ¶
func (r *ResponseBundle) Hash() []byte
Hash hashes the share index and responses
func (*ResponseBundle) Index ¶ added in v1.1.0
func (b *ResponseBundle) Index() Index
func (*ResponseBundle) Sig ¶ added in v1.1.2
func (b *ResponseBundle) Sig() []byte
func (*ResponseBundle) String ¶
func (b *ResponseBundle) String() string
type Result ¶
type Result struct { QUAL []Node Key *DistKeyShare }
Result is the struct that is outputted by the DKG protocol after it finishes. It contains both the list of nodes that successfully ran the protocol and the share of the node.
func (*Result) PublicEqual ¶
type StatusMatrix ¶
func NewStatusMatrix ¶
func NewStatusMatrix(dealers []Node, shareHolders []Node, status bool) *StatusMatrix
func (*StatusMatrix) AllTrue ¶
func (s *StatusMatrix) AllTrue(dealer uint32) bool
func (*StatusMatrix) CompleteSuccess ¶
func (s *StatusMatrix) CompleteSuccess() bool
func (*StatusMatrix) Get ¶
func (s *StatusMatrix) Get(dealer, share uint32) bool
can panic if indexes are not from the original list of nodes
func (*StatusMatrix) Set ¶
func (s *StatusMatrix) Set(dealer, share uint32, status bool)
can panic if indexes are not from the original list of nodes
func (*StatusMatrix) SetAll ¶
func (s *StatusMatrix) SetAll(dealer uint32, status bool)
func (*StatusMatrix) StatusesForShare ¶
func (s *StatusMatrix) StatusesForShare(shareIndex uint32) BitSet
func (*StatusMatrix) StatusesOfDealer ¶
func (s *StatusMatrix) StatusesOfDealer(dealerIndex uint32) BitSet
func (*StatusMatrix) String ¶
func (s *StatusMatrix) String() string
type Suite ¶
type Suite interface { kyber.Group kyber.HashFactory kyber.XOFFactory kyber.Random }
type TimePhaser ¶
type TimePhaser struct {
// contains filtered or unexported fields
}
TimePhaser is a phaser that sleeps between the different phases and send the signal over its channel.
func NewTimePhaser ¶
func NewTimePhaser(p time.Duration) *TimePhaser
func NewTimePhaserFunc ¶
func NewTimePhaserFunc(sleepPeriod func(Phase)) *TimePhaser
func (*TimePhaser) NextPhase ¶
func (t *TimePhaser) NextPhase() chan Phase
func (*TimePhaser) Start ¶
func (t *TimePhaser) Start()