keysplitting

package module
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Dec 13, 2022 License: Apache-2.0 Imports: 10 Imported by: 2

README

keysplitting

Wrapper around Go's RSA library supporting multi-party signatures and decryption

Note

We will release a stable (v1) version soon. Until then, we make no guarantees and you should not use this for production applications.

Documentation
Installation
go get github.com/bastionzero/keysplitting

Documentation

Overview

Package keysplitting implements primitives for multi-party RSA signatures using Go's crypto/rsa library

Overview

Keysplitting supports a simple and secure flow for producing multi-party signatures. First, a broker generates an ordinary RSA keypair and splits the private key into shards:

key, _ := rsa.GenerateKey(rand.Reader, 2048)
shards, err := keysplitting.SplitD(key, 2, keysplitting.Addition)
if err != nil {
    return err
}

The broker then distributes the private shards (as well as the public key) over a secure channel, destroying each shards as it is sent. If the broker will be one of the parties to the signature, it keeps one of the shards.

When it comes time to sign a message, the key shards do not need to be reassembled. Instead, each party uses its shard to generate a partial signature. It is these partial signatures, not the shards, that are combined to create the final valid signature. This can be verified against the public key in the usual way:

err = rsa.VerifyPKCS1v15(&key.PublicKey, crypto.SHA512, hash, fullSig)

The additive vs. multiplicative split schemes

Keysplitting offers two algorithms for splitting the private key, Addition and Multiplication, specified by the SplitBy type. Both methods are equally secure and applicable to most use cases. However, the following differences may lead you to choose one over the other:

  • The Multiplication algorithm supports blinding during signature (TODO: not yet implemented)
  • The Multiplication algorithm can only be used sequentially (i.e. partial signatures / decryptions are generated one at a time by parties who each have their own shard)
  • The Addition algorithm can be used sequentially. Alternatively, all parties can partially sign at once and send the results to a broker, who can combine them without using a key shard

To learn how to use each algorithm, see the examples. To learn more about how they work, see this TODO: detailed explanation published somewhere!!

Sources

[1] https://eprint.iacr.org/2001/060.pdf
[2] https://crypto.stanford.edu/semmail/mrsa.pdf

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SignFirst

func SignFirst(random io.Reader, shard *PrivateKeyShard, hashFn crypto.Hash, hashed []byte) ([]byte, error)

SignFirst uses the given key shard to perform the initial signature on a hashed message. Note that hashed must be the result of hashing the input message using the given hash function

func SignNext

func SignNext(random io.Reader, shard *PrivateKeyShard, hashFn crypto.Hash, hashed []byte, partialSig []byte) ([]byte, error)

SignNext uses the given key shard to sign a partially-signed message

If the original key was split multiplicatively, nextSig(H) <- partialSig(H)^shard (mod N), i.e. a chain of exponentiation

If the original key was split additively, nextSig(H) <- partialSig(H) * H^shard (mod N), i.e. a chain of multiplication

Note that hashed must be the result of hashing the input message using the given hash function.

Types

type PrivateKeyShard added in v0.4.0

type PrivateKeyShard struct {
	PublicKey *rsa.PublicKey // public part
	D         *big.Int       // split private exponent
	SplitBy   SplitBy        // the algorithm used to split the original key

}

A PrivateKeyShard represents one shard of a split RSA key. The public key matches that of the whole original key

func DecodePEM added in v0.3.0

func DecodePEM(encodedPks string) (*PrivateKeyShard, error)

returns key data from a PEM encoding

func SplitD

func SplitD(priv *rsa.PrivateKey, k int, splitBy SplitBy) ([]*PrivateKeyShard, error)

SplitD returns k private key shards that together compose priv.D

If SplitBy.Multiplication is used, the shards will be such that s1 * s2 * ... * sk ≡ D (mod phi(N))

If SplitBy.Addition is used, the shards will be such that s1 + s2 + ... + sk ≡ D (mod phi(N))

func (*PrivateKeyShard) EncodePEM added in v0.4.0

func (pks *PrivateKeyShard) EncodePEM() (string, error)

returns a PEM encoding of the key data

type SplitBy

type SplitBy string

SplitBy determines the algorithm used to split the private key and combine partial signatures. Either algorithm is suitable from a performance and security standpoint

const (
	Multiplication SplitBy = "Multiplication"
	Addition       SplitBy = "Addition"
)

Directories

Path Synopsis
to run these scripts, do:
to run these scripts, do:

Jump to

Keyboard shortcuts

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