package module
Version: v0.0.7 Latest Latest

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

Go to latest
Published: Jan 22, 2020 License: GPL-3.0 Imports: 11 Imported by: 5


Threshold Cryptography Eliptic Curve Digital Signature Algorithm

Go Report Card Build Status GoDoc

Implementation of Threshold Cryptography Eliptic Curve Digital Signature Algorithm proposed on the paper Using Level-1 Homomorphic Encryption To Improve Threshold DSA Signatures For Bitcoin Wallet Security.

This implementation is loosely based on the extension of Paillier Toolbox to use Level-2 Homomorphic Encryption from Princeton CITP. That code is the working example of the work in the paper mentioned earlier.

This code also implements the level-2 homomorphic encryption protocol from Dario Catalano et al, Boosting Linearly-Homomorphic Encryption to Evaluate Degree-2 Functions on Encrypted Data.


The only requirement for this library is our [Threshold Paillier Implementation] ( It will be downloaded automatically if the module is used with Go Modules

Using the library

To use the library with a module-enabled go project, you must write the following line on a terminal on the root file of the project.

go get


To run the tests you just need to use go test:

go test




This section is empty.


View Source
var CurveNameToCurve = map[string]elliptic.Curve{
	"P-224": elliptic.P224(),
	"P-256": elliptic.P256(),
	"P-384": elliptic.P384(),
	"P-521": elliptic.P521(),


func HashToInt

func HashToInt(hash []byte, c elliptic.Curve) *big.Int

HashToInt converts a hash value to an integer. There is some disagreement about how this is done. [NSA] suggests that this is done in the obvious manner, but [SECG] truncates the hash to the bit-length of the curve order first. We follow [SECG] because that'S what OpenSSL does. Additionally, OpenSSL right shifts excess bits from the number if the hash is too large and we mirror that too. This function was borrowed from crypto/ecdsa package, and was copied because it was not exported, but it is used on ecdsa signatures in Go.

func MarshalSignature added in v0.0.3

func MarshalSignature(r, s *big.Int) ([]byte, error)

func NewKey

func NewKey(l, k uint8, curveName string, params *NewKeyParams) (keyShares []*KeyShare, keyMeta *KeyMeta, err error)

NewKey returns a new distributed key share list, using the specified l (total number of nodes), k (threshold), curveName (elliptic curve name, between those Go supports by default) and params (additional params) If the params are nil, it creates them.

func RandomFieldElement

func RandomFieldElement(c elliptic.Curve) (k *big.Int, err error)

RandomFieldElement returns A random element of the field underlying the given curve using the procedure given in [NSA] A.2.1. Taken from Golang ECDSA implementation

func RandomInRange

func RandomInRange(min, max *big.Int) (r *big.Int, err error)

RandomInRange returns a number between an interval [min, max).

func UnmarshalSignature added in v0.0.3

func UnmarshalSignature(sigByte []byte) (r, s *big.Int, err error)


type KeyGenZKProof

type KeyGenZKProof struct {
	U1         *Point
	U2, U3     *big.Int
	S1, S2, S3 *big.Int
	E          *big.Int
	Z          *big.Int

KeyGenZKProof represents the parameters for the Key Generation ZKProof.

func (*KeyGenZKProof) Verify

func (p *KeyGenZKProof) Verify(meta *KeyMeta, vals ...interface{}) error

Verify verifies a ZKProof of KeyGenZKProof type. It receives the key metainfo and 2 arguments, representing the public key share (a point), and the encrypted private key share.

type KeyInitMessage

type KeyInitMessage struct {
	AlphaI *l2fhe.EncryptedL1 // Encrypted private key share by the node
	Yi     *Point             // Public key share by the node
	Proof  *KeyGenZKProof     // ZKProof that the value in AlphaI is a valid private key share

KeyInitMessage defines a message sent on key generation

type KeyInitMessageList

type KeyInitMessageList []*KeyInitMessage

KeyInitMessageList represents a list of KeyInitMessage

func (KeyInitMessageList) Join

func (msgs KeyInitMessageList) Join(meta *KeyMeta) (alpha *l2fhe.EncryptedL1, y *Point, err error)

Join joins a list of KeyInitMessages and returns the encrypted public key and private keys.

type KeyMeta

type KeyMeta struct {
	*l2fhe.PubKey // L2FHE Public Key
	*ZKProofMeta  // Parameters used by ZK Proofs

	CurveName string
	// contains filtered or unexported fields

KeyMeta represents a set of parameters that are used by every key share.

func (*KeyMeta) Curve

func (meta *KeyMeta) Curve() elliptic.Curve

func (*KeyMeta) G

func (meta *KeyMeta) G() *Point

G returns the base point of the curve, as a *Point.

func (*KeyMeta) GetPublicKey

func (meta *KeyMeta) GetPublicKey(msgs KeyInitMessageList) (pk *ecdsa.PublicKey, err error)

GetPublicKey parses the key init messages and returns the public key of the Signature scheme.

func (*KeyMeta) Q

func (meta *KeyMeta) Q() *big.Int

Q returns curve Subfield bitlength (referred internally as N, but as Q on papers).

type KeyShare

type KeyShare struct {
	Index         uint8                // Participant Index
	Alpha         *l2fhe.EncryptedL1   // Encrypted private Key
	Y             *Point               // Public Key
	PaillierShare *tcpaillier.KeyShare // Paillier Key share, used for partial decryption

KeyShare represents a "piece" of the key held by a participant of the distributed protocol.

func (*KeyShare) Init

func (p *KeyShare) Init(meta *KeyMeta) (msg *KeyInitMessage, err error)

Init generates the needed initial parameters and creates the KeyInitMessage that needs to be broadcasted to other participants.

func (*KeyShare) NewSigSession

func (p *KeyShare) NewSigSession(meta *KeyMeta, h []byte) (state *SigSession, err error)

NewSigSession creates a new signing session, related to a specific non-empty document. It returns the new signing session and the hashed document, using the hash function defined in keyMeta. The error returned on this function could only be related to the hash encryption.

func (*KeyShare) SetKey

func (p *KeyShare) SetKey(meta *KeyMeta, msgs KeyInitMessageList) error

SetKey sets the key to a keyshare based on the messages of other nodes. It defines the Alpha (encrypted private key) and Y (public key) values. It returns an error if it cannot join the signatures.

type NewKeyParams

type NewKeyParams struct {
	PaillierFixed *tcpaillier.FixedParams // Paillier Fixed Params.

NewKeyParams represents a group of params that the metod NewKey can use.

type Point

type Point struct{ X, Y *big.Int }

Point represents a point in a discrete elliptic curve.

func NewPoint

func NewPoint(x, y *big.Int) *Point

NewPoint returns a new point centered in (x, y)

func NewZero

func NewZero() *Point

NewZero returns a new point centered in (0,0)

func (*Point) Add

func (p *Point) Add(curve elliptic.Curve, pList ...*Point) *Point

Add adds a point with another, using a given elliptic curve.

func (*Point) BaseMul

func (p *Point) BaseMul(curve elliptic.Curve, k *big.Int) *Point

BaseMul multiplies the curve base point by a scalar, using a given elliptic curve.

func (*Point) Bytes

func (p *Point) Bytes(curve elliptic.Curve) []byte

Bytes transforms the point in a unique byte representation, based in Gob.Encode.

func (*Point) Clone

func (p *Point) Clone() *Point

Clone copies the x and y coordinates of a point.

func (*Point) Cmp

func (p *Point) Cmp(p2 *Point) int

Cmp returns -1 if the first point is smaller than the second one (comparing x, then y coordinates), 0 if they are equal and 1 if the second point is smaller than the first one.

func (*Point) Mul

func (p *Point) Mul(curve elliptic.Curve, p1 *Point, k *big.Int) *Point

Mul multiplies a point by a scalar, using a given elliptic curve.

func (*Point) Neg

func (p *Point) Neg(p2 *Point) *Point

Neg negates a point, inverting its y coordinate.

func (*Point) SetBytes

func (p *Point) SetBytes(curve elliptic.Curve, b []byte) (p2 *Point, err error)

SetBytes transforms a byte array into a point, using elliptic.UnmarshalSignature method.

func (*Point) String

func (p *Point) String() string

String returns the string representation of the point.

type Round1Message

type Round1Message struct {
	Ri         *Point             // Random point related to the signing process
	Ui, Vi, Wi *l2fhe.EncryptedL1 // Encrypted u, V and W shares
	Proof      *SigZKProof        // ZLProof that the values encrypted are valid

Round1Message defines a message sent on Signature Initialization (Round1 on this implementation)

type Round1MessageList

type Round1MessageList []*Round1Message

Round1MessageList represents a list of Round1Message

func (Round1MessageList) Join

func (msgs Round1MessageList) Join(meta *KeyMeta) (R *Point, u, v, w *l2fhe.EncryptedL1, err error)

Join joins a list of Round1Messages and returns the values R, u, v and w.

type Round2Message

type Round2Message struct {
	PDZ   *l2fhe.DecryptedShareL2   // Z Decrypt share.
	Proof *l2fhe.DecryptedShareL2ZK // Proof that PDZ is a partial decryption of Z

Round2Message defines a message sent on Round 2

type Round2MessageList

type Round2MessageList []*Round2Message

Round2MessageList represents a list of Round2Message

func (Round2MessageList) Join

func (msgs Round2MessageList) Join(meta *KeyMeta, z *l2fhe.EncryptedL2) (nu *big.Int, err error)

Join joins a list of Round2Messages and returns the value nu. The Z value required is to check the ZKProofs.

type Round3Message

type Round3Message struct {
	PDSigma *l2fhe.DecryptedShareL2   // sigma Decrypt share.
	Proof   *l2fhe.DecryptedShareL2ZK // Proof that PDSigma is a partial decryption of sigma

Round3Message defines a message sent on Round 3

type Round3MessageList

type Round3MessageList []*Round3Message

Round3MessageList represents a list of Round3Message

func (Round3MessageList) Join

func (msgs Round3MessageList) Join(meta *KeyMeta, sigma *l2fhe.EncryptedL2) (s *big.Int, err error)

Join joins a list of Round3Messages and returns the value S. the sigma value required is to check the ZKProofs.

type SigSession

type SigSession struct {
	// contains filtered or unexported fields

SigSession represents a set of values saved and used by the participants to generate an specific Signature. It is an ephimeral structure and it lives only while the Signature is being created.

func (*SigSession) GetSignature

func (state *SigSession) GetSignature(msgs Round3MessageList) (r, s *big.Int, err error)

GetSignature joins the last values and returns the Signature. It is described in the paper as the joining process of partially decrypted values.

func (*SigSession) Round1

func (state *SigSession) Round1() (msg *Round1Message, err error)

Round1 starts the signing process generating a set of random values and the ZKProof of them. It represents Round 1 and Round 2 in paper, because our implementation doesn't consider the usage of commits.

func (*SigSession) Round2

func (state *SigSession) Round2(msgs Round1MessageList) (msg *Round2Message, err error)

Round2 uses the values generated in Round1 to generate R and u, a value that is needed for GetSignature It is Round 3 in paper.

func (*SigSession) Round3

func (state *SigSession) Round3(msgs Round2MessageList) (msg *Round3Message, err error)

Round3 joins the partially decrypted Z of the last round and generates a partial decryption of sigma. It is Round 4 in paper

type SigZKProof

type SigZKProof struct {
	U1                     *Point
	U2, U3, U4             *big.Int
	Z1, Z2, Z3             *big.Int
	V1, V2, V3             *big.Int
	S1, S3, S4, S5, S6, S7 *big.Int
	T1, T2, T3             *big.Int
	E                      *big.Int

SigZKProof represents the parameters for the Signature ZKProof.

func NewSigZKProof

func NewSigZKProof(meta *KeyMeta, p *SigZKProofParams) (proof *SigZKProof, err error)

NewSigZKProof creates the SigZKProof used by the protocol. This implementation is based on the original one by the authors of the paper.

func (*SigZKProof) Verify

func (p *SigZKProof) Verify(meta *KeyMeta, vals ...interface{}) error

Verify verifies a ZKProof of SigZKProof type. It receives the key metainfo and 4 arguments, representing a random point share used in the signing process, and a three random values encrypted and used as shares of other values of the protocol.

type SigZKProofParams

type SigZKProofParams struct {
	Ri                     *Point
	Eta1, Eta2, Eta3       *big.Int
	RandVi, RandUi, RandWi *big.Int
	EncVi, EncUi, EncWi    *l2fhe.EncryptedL1

SigZKProofParams groups all the params used on Signing ZKProof.

type Signature added in v0.0.6

type Signature struct {
	R, S *big.Int

type Status

type Status uint8

Status represents the current state of a SigSession

const (
	NotInited Status = iota // Session was created.
	Round1                  // Session has passed Round 1.
	Round2                  // Session has passed Round 2.
	Round3                  // Session has passed Round 3.
	Finished                // Session is finished.
	Undefined Status = iota // Undefined status.

The following consts represent the different status a session could be.

type ZKProofMeta

type ZKProofMeta struct {
	NTilde *big.Int // Used in ZK Proofs
	H1     *big.Int // Used in ZK Proofs
	H2     *big.Int // Used in ZK Proofs

ZKProofMeta contains the RSA parameters required to create ZKProofs.


Path Synopsis
Package l2fhe represents a homomorphic encryption scheme based on Catalano-Fiore and Paillier Cryptosystem.
Package l2fhe represents a homomorphic encryption scheme based on Catalano-Fiore and Paillier Cryptosystem.

Jump to

Keyboard shortcuts

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