Documentation ¶
Overview ¶
Package cosi implements the collective signing (CoSi) algorithm as presented in the paper "Keeping Authorities 'Honest or Bust' with Decentralized Witness Cosigning" by Ewa Syta et al. See https://arxiv.org/abs/1503.08768. This package only provides the functionality for the cryptographic operations of CoSi. All network-related operations have to be handled elsewhere. Below we describe a high-level overview of the CoSi protocol (using a star communication topology). We refer to the research paper for further details on communication over trees, exception mechanisms and signature verification policies.
The CoSi protocol has four phases executed between a list of participants P having a protocol leader (index i = 0) and a list of other nodes (index i > 0). The secret key of node i is denoted by a_i and the public key by A_i = [a_i]G (where G is the base point of the underlying group and [...] denotes scalar multiplication). The aggregate public key is given as A = \sum{i ∈ P}(A_i).
1. Announcement: The leader broadcasts an announcement to the other nodes optionally including the message M to be signed. Upon receiving an announcement message, a node starts its commitment phase.
2. Commitment: Each node i (including the leader) picks a random scalar v_i, computes its commitment V_i = [v_i]G and sends V_i back to the leader. The leader waits until it has received enough commitments (according to some policy) from the other nodes or a timer has run out. Let P' be the nodes that have sent their commitments. The leader computes an aggregate commitment V from all commitments he has received, i.e., V = \sum{j ∈ P'}(V_j) and creates a participation bitmask Z. The leader then broadcasts V and Z to the other participations together with the message M if it was not sent in phase 1. Upon receiving a commitment message, a node starts the challenge phase.
3. Challenge: Each node i computes the collective challenge c = H(V || A || M) using a cryptographic hash function H (here: SHA512), computes its response r_i = v_i + c*a_i and sends it back to the leader.
4. Response: The leader waits until he has received replies from all nodes in P' or a timer has run out. If he has not enough replies he aborts. Finally, the leader computes the aggregate response r = \sum{j ∈ P'}(r_j) and publishes (V,r,Z) as the signature for the message M.
Note: This package is kept here for historical and research purposes. It should not be used in new code as it has been deprecated by the bls package, which was in turn deprecated by the bdn package. See https://eprint.iacr.org/2018/417.pdf for an attack on CoSi as implemented here.
Index ¶
- func AggregateCommitments(suite Suite, commitments []kyber.Point, masks [][]byte) (sum kyber.Point, commits []byte, err error)
- func AggregateMasks(a, b []byte) ([]byte, error)
- func AggregateResponses(suite Suite, responses []kyber.Scalar) (kyber.Scalar, error)
- func Challenge(suite Suite, commitment, public kyber.Point, message []byte) (kyber.Scalar, error)
- func Commit(suite Suite) (v kyber.Scalar, V kyber.Point)
- func Response(suite Suite, private, random, challenge kyber.Scalar) (kyber.Scalar, error)
- func Sign(suite Suite, commitment kyber.Point, response kyber.Scalar, mask *Mask) ([]byte, error)
- func Verify(suite Suite, publics []kyber.Point, message, sig []byte, policy Policy) error
- type CompletePolicydeprecated
- type Mask
- func (m *Mask) CountEnabled() int
- func (m *Mask) CountTotal() int
- func (m *Mask) IndexEnabled(i int) (bool, error)
- func (m *Mask) KeyEnabled(public kyber.Point) (bool, error)
- func (m *Mask) Len() int
- func (m *Mask) Mask() []byte
- func (m *Mask) SetBit(i int, enable bool) error
- func (m *Mask) SetMask(mask []byte) error
- type ParticipationMask
- type Policydeprecated
- type Suite
- type ThresholdPolicydeprecated
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AggregateCommitments ¶
func AggregateCommitments(suite Suite, commitments []kyber.Point, masks [][]byte) (sum kyber.Point, commits []byte, err error)
AggregateCommitments returns the sum of the given commitments and the bitwise OR of the corresponding masks.
func AggregateMasks ¶
AggregateMasks computes the bitwise OR of the two given participation masks.
func AggregateResponses ¶
AggregateResponses returns the sum of given responses.
func Challenge ¶
Challenge creates the collective challenge from the given aggregate commitment V, aggregate public key A, and message M, i.e., it returns c = H(V || A || M).
func Commit ¶
func Commit(suite Suite) (v kyber.Scalar, V kyber.Point)
Commit returns a random scalar v, generated from the given suite, and a corresponding commitment V = [v]G. If the given cipher stream is nil, a random stream is used.
func Response ¶
Response creates the response from the given random scalar v, (collective) challenge c, and private key a, i.e., it returns r = v + c*a.
Types ¶
type CompletePolicy
deprecated
type CompletePolicy struct { }
CompletePolicy is the default policy requiring that all participants have cosigned to make a collective signature valid.
Deprecated: the policy has moved to the package kyber/sign
func (CompletePolicy) Check ¶
func (p CompletePolicy) Check(m ParticipationMask) bool
Check verifies that all participants have contributed to a collective signature.
type Mask ¶
type Mask struct { AggregatePublic kyber.Point // contains filtered or unexported fields }
Mask represents a cosigning participation bitmask.
func NewMask ¶
NewMask returns a new participation bitmask for cosigning where all cosigners are disabled by default. If a public key is given it verifies that it is present in the list of keys and sets the corresponding index in the bitmask to 1 (enabled).
func (*Mask) CountEnabled ¶
CountEnabled returns the number of enabled nodes in the CoSi participation mask.
func (*Mask) CountTotal ¶
CountTotal returns the total number of nodes this CoSi instance knows.
func (*Mask) IndexEnabled ¶
IndexEnabled checks whether the given index is enabled in the mask or not.
func (*Mask) KeyEnabled ¶
KeyEnabled checks whether the index, corresponding to the given key, is enabled in the mask or not.
type ParticipationMask ¶
type ParticipationMask interface { // CountEnabled returns the number of participants CountEnabled() int // CountTotal returns the number of candidates CountTotal() int }
ParticipationMask is an interface to get the total number of candidates and the number of participants.
type Policy
deprecated
type Policy interface {
Check(m ParticipationMask) bool
}
Policy represents a fully customizable cosigning policy deciding what cosigner sets are and aren't sufficient for a collective signature to be considered acceptable to a verifier. The Check method may inspect the set of participants that cosigned by invoking cosi.Mask and/or cosi.MaskBit, and may use any other relevant contextual information (e.g., how security-critical the operation relying on the collective signature is) in determining whether the collective signature was produced by an acceptable set of cosigners.
Deprecated: the policies have moved to the package kyber/sign
type Suite ¶
type Suite interface { kyber.Group kyber.HashFactory kyber.Random }
Suite specifies the cryptographic building blocks required for the cosi package.
type ThresholdPolicy
deprecated
type ThresholdPolicy struct {
// contains filtered or unexported fields
}
ThresholdPolicy allows to specify a simple t-of-n policy requring that at least the given threshold number of participants t have cosigned to make a collective signature valid.
Deprecated: the policy has moved to the package kyber/sign
func NewThresholdPolicy
deprecated
func NewThresholdPolicy(thold int) *ThresholdPolicy
NewThresholdPolicy returns a new ThresholdPolicy with the given threshold.
Deprecated: the policy has moved to the package kyber/sign
func (ThresholdPolicy) Check ¶
func (p ThresholdPolicy) Check(m ParticipationMask) bool
Check verifies that at least a threshold number of participants have contributed to a collective signature.