Documentation ¶
Overview ¶
Package tcrsa implements the cryptographic algorithms of Victor Shoup's paper Practical Threshold Signatures, in the Golang programming language. You can find the paper defining the algorithms in http://www.iacr.org/archive/eurocrypt2000/1807/18070209-new.pdf.
Example ¶
package main import ( "crypto" "crypto/rsa" "crypto/sha256" "fmt" "github.com/niclabs/tcrsa" ) const exampleK = 3 const exampleL = 5 const exampleHashType = crypto.SHA256 const exampleSize = 2048 const exampleMessage = "Hello world" func main() { // First we need to get the values of K and L from somewhere. k := uint16(exampleK) l := uint16(exampleL) // Generate keys provides to us with a list of keyShares and the key metainformation. keyShares, keyMeta, err := tcrsa.NewKey(exampleSize, uint16(k), uint16(l), nil) if err != nil { panic(fmt.Sprintf("%v", err)) } // Then we need to prepare the document we want to sign, so we hash it and pad it using PKCS v1.15. docHash := sha256.Sum256([]byte(exampleMessage)) docPKCS1, err := tcrsa.PrepareDocumentHash(keyMeta.PublicKey.Size(), crypto.SHA256, docHash[:]) if err != nil { panic(fmt.Sprintf("%v", err)) } sigShares := make(tcrsa.SigShareList, l) var i uint16 // Now we sign with at least k nodes and check immediately the signature share for consistency. for i = 0; i < l; i++ { sigShares[i], err = keyShares[i].Sign(docPKCS1, exampleHashType, keyMeta) if err != nil { panic(fmt.Sprintf("%v", err)) } if err := sigShares[i].Verify(docPKCS1, keyMeta); err != nil { panic(fmt.Sprintf("%v", err)) } } // Having all the signature shares we needed, we join them to create a real signature. signature, err := sigShares.Join(docPKCS1, keyMeta) if err != nil { panic(fmt.Sprintf("%v", err)) } // Finally we check the signature with Golang's crypto/rsa PKCSv1.15 verification routine. if err := rsa.VerifyPKCS1v15(keyMeta.PublicKey, crypto.SHA256, docHash[:], signature); err != nil { panic(fmt.Sprintf("%v", err)) } fmt.Println("ok") }
Output: ok
Index ¶
- func NewKey(bitSize int, k, l uint16, args *KeyMetaArgs) (shares KeyShareList, meta *KeyMeta, err error)
- func PrepareDocumentHash(privateKeySize int, hashType crypto.Hash, digest []byte) ([]byte, error)
- type KeyMeta
- type KeyMetaArgs
- type KeyShare
- type KeyShareList
- type SigShare
- type SigShareList
- type Signature
- type VerificationKey
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewKey ¶
func NewKey(bitSize int, k, l uint16, args *KeyMetaArgs) (shares KeyShareList, meta *KeyMeta, err error)
NewKey creates l key shares for a k-threshold signing scheme. The bit_size parameter is used to generate key shares with a security level equivalent to a RSA private of that size. The generated key shares have a threshold parameter of k. This means that k valid signatures are needed to sign. On success, it returns the meta information common to all the keys, and an array with all the key shares. On failure, it returns an error and invalid pointers to shares and meta information.
func PrepareDocumentHash ¶
PrepareDocumentHash receives a document hash and encodes it in PKCS v1.15 for its signing. This method was copied from SignPKCS15 function from crypto/rsa on https://golang.org/pkg/crypto/rsa/
Types ¶
type KeyMeta ¶
type KeyMeta struct { PublicKey *rsa.PublicKey // RSA Public key used to verify signatures K uint16 // Threshold L uint16 // Total number of participants VerificationKey *VerificationKey // Verification Key associated to a Key Generation. }
KeyMeta stores the meta information of a distributed key generation. It stores the RSA public key, the threshold value k and the total shares value l. It also has stored the verification keys for each signed share.
type KeyMetaArgs ¶
type KeyMetaArgs struct { E int // Public exponent. This value should be prime. P *big.Int // A prime, it should have the half of the bitsize. Q *big.Int // Another prime, it should have the other half of the bitsize. R *big.Int // A random prime but it must be coprime with P*Q. U *big.Int // An arbitrary random value. }
KeyMetaArgs defines the initialization values for key generation. It allows to load previously computed keys. Useful for testing. Completely forbidden for production use.
type KeyShare ¶
type KeyShare struct {}
KeyShare stores the Si value of a node and an unique incremental ID for the node. It's used to generate a signature share.
func (KeyShare) EqualsSi ¶
EqualsSi compares two key share S_i values and returns true if they are equal.
func (KeyShare) Sign ¶
func (keyShare KeyShare) Sign(doc []byte, hashType crypto.Hash, info *KeyMeta) (sigShare *SigShare, err error)
Sign generates a signature share using a key share. A standard RSA signature is generated using several signature shares. The document to be signed should be prepared (hashed and padded) before using this function. It returns a SigShare with the signature of this node, or an error if the signing process failed.
type SigShare ¶
type SigShare struct {}
SigShare represents a signature share for a document. It can be joined with other k signatures and generate a standard RSA signature.
type SigShareList ¶
type SigShareList []*SigShare
SigShareList is a list of sigShares ready to be joined.
func (SigShareList) Join ¶
func (sigShareList SigShareList) Join(document []byte, info *KeyMeta) (signature Signature, err error)
Join generates a standard RSA signature using the signature shares of the document provided. The number of signatures should be at least the number of threshold defined at key creation. It returns the RSA signature generated, or an error if the process fails.
type Signature ¶
type Signature []byte
Signature is the completed signature of a document, created after joining k signature shares.
type VerificationKey ¶
type VerificationKey struct { V []byte // Verification value. U []byte // Verification value. I [][]byte // An array of the verification values for the shares the nodes create when sign a document. }
VerificationKey represents the data that is needed to verify a Key Share. It groups all the verification values for all the nodes in I property.
func NewVerificationKey ¶
func NewVerificationKey(l uint16) *VerificationKey
NewVerificationKey generates an empty Verification Key structure, allocating space for l verification values in I.