# tcecdsa

package module
Version: v0.0.7 Latest Latest

Go to latest
Published: Jan 22, 2020 License: GPL-3.0

### Threshold Cryptography Eliptic Curve Digital Signature Algorithm

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.

### Requirements

The only requirement for this library is our [Threshold Paillier Implementation] (https://github.com/niclabs/tcpaillier). 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 github.com/niclabs/tcecdsa

### Tests

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

go test github.com/niclabs/tcecdsa

## Documentation ¶

### Constants ¶

This section is empty.

### Variables ¶

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

### Functions ¶

#### 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)

### Types ¶

#### 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 (p *Point) Add(curve elliptic.Curve, pList ...*Point) *Point

#### 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.

## Directories ¶

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.