cosi

package
v0.0.0-...-ffb7191 Latest Latest
Warning

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

Go to latest
Published: Jan 25, 2019 License: MPL-2.0 Imports: 3 Imported by: 0

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.

Index

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

func AggregateMasks(a, b []byte) ([]byte, error)

AggregateMasks computes the bitwise OR of the two given participation masks.

func AggregateResponses

func AggregateResponses(suite Suite, responses []kyber.Scalar) (kyber.Scalar, error)

AggregateResponses returns the sum of given responses.

func Challenge

func Challenge(suite Suite, commitment, public kyber.Point, message []byte) (kyber.Scalar, error)

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

func Response(suite Suite, private, random, challenge kyber.Scalar) (kyber.Scalar, error)

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.

func Sign

func Sign(suite Suite, commitment kyber.Point, response kyber.Scalar, mask *Mask) ([]byte, error)

Sign returns the collective signature from the given (aggregate) commitment V, (aggregate) response r, and participation bitmask Z using the EdDSA format, i.e., the signature is V || r || Z.

func Verify

func Verify(suite Suite, publics []kyber.Point, message, sig []byte, policy Policy) error

Verify checks the given cosignature on the provided message using the list of public keys and cosigning policy.

Types

type CompletePolicy

type CompletePolicy struct {
}

CompletePolicy is the default policy requiring that all participants have cosigned to make a collective signature valid.

func (CompletePolicy) Check

func (p CompletePolicy) Check(m *Mask) 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

func NewMask(suite Suite, publics []kyber.Point, myKey kyber.Point) (*Mask, error)

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

func (m *Mask) CountEnabled() int

CountEnabled returns the number of enabled nodes in the CoSi participation mask.

func (*Mask) CountTotal

func (m *Mask) CountTotal() int

CountTotal returns the total number of nodes this CoSi instance knows.

func (*Mask) IndexEnabled

func (m *Mask) IndexEnabled(i int) (bool, error)

IndexEnabled checks whether the given index is enabled in the mask or not.

func (*Mask) KeyEnabled

func (m *Mask) KeyEnabled(public kyber.Point) (bool, error)

KeyEnabled checks whether the index, corresponding to the given key, is enabled in the mask or not.

func (*Mask) Len

func (m *Mask) Len() int

Len returns the mask length in bytes.

func (*Mask) Mask

func (m *Mask) Mask() []byte

Mask returns a copy of the participation bitmask.

func (*Mask) SetBit

func (m *Mask) SetBit(i int, enable bool) error

SetBit enables (enable: true) or disables (enable: false) the bit in the participation mask of the given cosigner.

func (*Mask) SetMask

func (m *Mask) SetMask(mask []byte) error

SetMask sets the participation bitmask according to the given byte slice interpreted in little-endian order, i.e., bits 0-7 of byte 0 correspond to cosigners 0-7, bits 0-7 of byte 1 correspond to cosigners 8-15, etc.

type Policy

type Policy interface {
	Check(m *Mask) 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.

type Suite

type Suite interface {
	kyber.Group
	kyber.HashFactory
	kyber.Random
}

Suite specifies the cryptographic building blocks required for the cosi package.

type ThresholdPolicy

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.

func NewThresholdPolicy

func NewThresholdPolicy(thold int) *ThresholdPolicy

NewThresholdPolicy returns a new ThresholdPolicy with the given threshold.

func (ThresholdPolicy) Check

func (p ThresholdPolicy) Check(m *Mask) bool

Check verifies that at least a threshold number of participants have contributed to a collective signature.

Jump to

Keyboard shortcuts

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