A pairing-based threshold cryptosystem for collaborative decryption and signatures used in HoneybadgerBFT implementation

Overview

threshold_crypto

crates.io Documentation Build Status

A pairing-based threshold cryptosystem for collaborative decryption and signatures.

The threshold_crypto crate provides cryptographic keys with methods for signing and encrypting messages, as well as key sets for threshold signatures and threshold encryption.

The threshold signature scheme is described in Threshold Signatures, Multisignatures and Blind Signatures Based on the Gap-Diffie-Hellman-Group Signature Scheme by Alexandra Boldyreva. This paper extends Boneh-Lynn-Shacham signatures to the threshold setting. Message encryption uses the scheme by Baek and Zhang. Our implementation is based on the pairing elliptic curve library.

In a network environment, messages are signed and encrypted, and key and signature shares are distributed to network participants. A message can be decrypted and authenticated only with cooperation from at least threshold + 1 nodes.

Security Audit

An official security audit has been completed on threshold_crypto by Jean-Philippe Aumasson. No exploitable security issues were found, and potential improvements have been addressed. Outdated dependencies mentioned in the audit were updated in commit 54026f5.

Usage

Cargo.toml:

[dependencies]
threshold_crypto = { version = "0.4", git = "https://github.com/poanetwork/threshold_crypto" }

main.rs:

extern crate rand;
extern crate threshold_crypto;

use threshold_crypto::SecretKey;

/// Very basic secret key usage.
fn main() {
    let sk0 = SecretKey::random();
    let sk1 = SecretKey::random();

    let pk0 = sk0.public_key();

    let msg0 = b"Real news";
    let msg1 = b"Fake news";

    assert!(pk0.verify(&sk0.sign(msg0), msg0));
    assert!(!pk0.verify(&sk1.sign(msg0), msg0)); // Wrong key.
    assert!(!pk0.verify(&sk0.sign(msg1), msg0)); // Wrong message.
}

Testing

Run tests with:

$ cargo test

Examples

Run examples from the examples directory using:

$ cargo run --example <example name>

Also see the distributed_key_generation test.

Application Details

The basic usage outline is:

  • choose a threshold value t
  • create a key set
  • distribute N secret key shares among the participants
  • publish the public master key

A third party can now encrypt a message to the public master key and any set of t + 1 participants (but no fewer!) can collaborate to decrypt it. Also, any set of t + 1 participants can collaborate to sign a message, producing a signature that is verifiable with the public master key.

In this system, a signature is unique and independent of the set of participants that produced it. If S1 and S2 are signatures for the same message, produced by two different sets of t + 1 secret key share holders, both signatures will be valid AND equal. This is useful in some applications, for example a message signature can serve as a pseudorandom number unknown to anyone until t + 1 participants agree to reveal it.

In its simplest form, threshold_crypto requires a trusted dealer to produce and distribute the secret key shares. However, keys can be produced so that only the corresponding participant knows their secret in the end. This crate includes the basic tools to implement such a Distributed Key Generation scheme.

A major application for this library is within a distributed network that must tolerate up to t adversarial (malicious or faulty) nodes. Because t + 1 nodes are required to sign or reveal information, messages can be trusted by third-parties as representing the consensus of the network.

Documentation

Performance

Benchmarking functionality is kept in the benches directory. You can run the benchmarks with the following command:

$ RUSTFLAGS="-C target_cpu=native" cargo bench

We use the criterion benchmarking library.

Mock cryptography

To speed up automatic tests of crates depending on threshold_crypto, the use-insecure-test-only-mock-crypto feature is available. Activating this feature will effectively disable encryption and should only be used during tests! Essentially, the underlying elliptic curves will be replaced by small finite fields, yielding a 10-200X speed-up in execution. The resulting ciphers can be trivially broken in a number of ways and should never be used in production.

License

Licensed under either of:

at your option.

Contributing

See the CONTRIBUTING document for contribution, testing and pull request protocol.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Comments
  • Add additional benchmarks

    Add additional benchmarks

    Here's a few additional benchmarks. I put in a Makefile to make running tests/benches a bit easier, but I can do that in a separate commit if you want (or remove it). I ran rustfmt per the contributing guide, but it decided several more files needed reformatting. =) Would you prefer that in a separate commit?

    opened by fhaynes 10
  • Added 'MlockManager' to prevent early 'munlock'ing

    Added 'MlockManager' to prevent early 'munlock'ing

    • Added MlockManager to secrets module.
    • Prevents unnecessary/duplicate calls to mlock for a page in memory, stops pages from being unlocked when they still contain secret values.
    • Added dependency page_size.

    Closes issue #31

    opened by DrPeterVanNostrand 8
  • TODO: Add a basic Readme

    TODO: Add a basic Readme

    @vkomenda I've been told you may already be handling this or at least you have an example you want to use already but I'm happy to help if you can show me which example you want to use.

    Or I'll just make something up :P

    opened by c0gent 8
  • Add benchmark for combining signatures

    Add benchmark for combining signatures

    This benchmark is based on how the test_threshold_sig uses the combine_signatures. Let me know if this benchmarks it correctly.

    Is it worth adding in testing different thresholds?

    opened by fhaynes 7
  • Add benchmarks.

    Add benchmarks.

    Our implementation still uses naive and probably slow algorithms in several places, especially for polynomials and commitments, and we should look into optimizing them. Whether #13 leads anywhere or not, the first step is adding benchmarks. I'm mainly thinking of polynomial multiplication and interpolation, but the more we cover, the better.

    good first issue 
    opened by afck 7
  • Change the license to MIT/Apache-2.0 by popular vote

    Change the license to MIT/Apache-2.0 by popular vote

    The provisional GNU GPL license is too strong for this library and should be replaced with a more permissive one. MIT/Apache-2.0 has been chosen as a suitable candidate.

    opened by vkomenda 7
  • Key serialization and deserialization

    Key serialization and deserialization

    You already have some internal serde implementations for field elements (FieldWrap) and functions for converting Fr to a string and parsing it again. I think it would be nice to also have serde impls for secret/public keys and key shares (e.g. for config files of HBBFT nodes). Are you interested in PRs adding this functionality?

    Or is the lack of these impls intentional and I should just define newtypes? I could imagine that to be the case because reliable memory zeroing is probably harder if you impl serde traits.

    EDIT: I'm currently implementing serde for SecretKeyShares and haven't looked into the other key types yet, maybe they have serde impls. But at least for SecretKeyShare it's missing.

    opened by sgeisler 5
  • Implement serde for secret keys

    Implement serde for secret keys

    Fixes #73 . This implements a wrapper struct for secret keys SerdeSecret that enables these to be serialized and deserialized. I only intend to implement this for the non-mocked crypto because I didn't find a good generic interface to ser/de the underlying Fr struct, so I'm currently just taking the pub [u64, 4] out of the FrRepr.

    • [x] impl for SecretKey
    • [x] impl for SecretKeyShare
    • [ ] think about how to erase all stack copies of key material
    opened by sgeisler 4
  • Added a bit iterator for signatures

    Added a bit iterator for signatures

    This was supposed to be a pair PR with the matching hbbft branch to add a random_value optimization in Binary Agreement. However it can have other uses, e.g., emulating random coin flips given a signature.

    opened by vkomenda 3
  • Change license, flesh out README a bit.

    Change license, flesh out README a bit.

    • Expand readme
    • Change license

    Closes https://github.com/poanetwork/threshold_crypto/issues/7 and https://github.com/poanetwork/threshold_crypto/issues/2

    @andogro, I'll hand this off to you to refine the language in a separate PR as you see fit.

    Many of the tests use private types or types with private constructors. I'll leave it to @vkomenda, @afck, and @DrPeterVanNostrand to build on the example and decide what you may want to make public for those purposes.

    For now this is probably ready to merge.

    opened by c0gent 3
  • Question: Any plans for updating pairing?

    Question: Any plans for updating pairing?

    Hello, I was wondering if the maintainers have any plans for updating pairing and bls12-381 libraries for this repository. The reason I ask is because I'm having a bit of tough time implementing Aggregate Signatures using the primitives defined here.

    The authors of pairing and bls12-381 have separated the codebase of those two repos, and pairing now is just a collection of types and traits whereas bls12-381 has the curve definition.

    Here's my broken aggregate signature work if anyone is interested, I'm basically stuck on trying to find the right methods to calculate identity element in Gt and doing the subsequent operations to do core_aggregate_verify as mentioned in the IETF specification.

    opened by vihu 2
  • Ring signature example?

    Ring signature example?

    Anyone know where I can find a Ring Signatures example or can provide one?

    eg as described in:

    • https://crypto.stanford.edu/~dabo/pubs/papers/aggreg.pdf
    • http://isrc.ccs.asia.edu.tw/~vdoi/upload/JID190002/2020/1816-3548-2020-00015.pdf
    opened by dan-da 2
  • Include DKG example

    Include DKG example

    Would it be very difficult to add an example that does the key-setup using a DKG? Like replacing the following code in the examples:

            let mut rng = rand::thread_rng();
            let sk_set = SecretKeySet::random(threshold, &mut rng);
            let pk_set = sk_set.public_keys();
    
            let actors = (0..n_actors)
                .map(|id| {
                    let sk_share = sk_set.secret_key_share(id);
                    let pk_share = pk_set.public_key_share(id);
                    Actor::new(id, sk_share, pk_share)
                })
                .collect();
    

    With something where the dealer does not know the secret key!

    opened by ineiti 3
  • Compatibility with other bls12-381 libraries

    Compatibility with other bls12-381 libraries

    Compatibility between bls12-381 libraries might be useful. For example, etherum2, zcash, chia.net, algorand, dfinity are all using or plan to use bls12-381.

    There's a simple single-key signature verification in this test which does not pass with threshold_crypto. The secret key can be imported to threshold_crypto and it gives the same public key as in the test, but the signature does not verify.

    skbytes = [74,53,59,227,218,192,145,160,167,230,64,98,3,114,245,225,226,228,64,23,23,193,231,156,172,111,251,168,246,144,86,4]
    pkbytes = [133,105,95,203,192,108,196,196,201,69,31,77,206,33,203,248,222,62,90,19,191,72,244,76,219,177,142,32,56,186,123,139,177,99,45,121,17,239,30,46,8,116,155,221,191,22,83,82]
    msgbytes = [7,8,9]
    sigbytes = [184,250,166,214,163,136,28,159,219,173,128,59,23,13,112,202,92,191,30,107,165,165,134,38,45,243,104,199,90,205,29,31,250,58,182,238,33,199,31,132,68,148,101,152,120,245,235,35,12,149,141,213,118,176,139,133,100,170,210,238,9,146,232,90,30,86,95,41,156,213,58,40,93,231,41,147,127,112,220,23,106,31,1,67,33,41,187,43,148,211,213,3,31,128,101,161]
    

    However the test signature does verify with

    javascript noble-bls12-381

    c++ chia-network/bls-signatures

    c supranational/blst

    Is there a chance that threshold_crypto will be compatible with these other bls12-381 libraries? Or am I missing something particular about the way those libraries differ from this one?

    A few notes:

    These libraries all seem to be using sha2_256 (see this discussion) but threshold_crypto is using sha3_256 (see utils.rs). I tried changing threshold_crypto to sha2 but that change alone did not lead to the test passing.

    All these libraries have a DST parameter set to "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_" but I can't see any reference to this in threshold_crypto nor in any bls12-381 specs or docs, eg IETF and hackmd.io. So I'm definitely out of my depth and am hoping with this issue to understand whether threshold_crypto will aim to be compatible with the broader cryptocurrency bls12-381 implementations or not.

    I realize this is more of a support request than a bug or feature request, but I feel there's some small potential that this may lead to a change in this library so I figured better to raise it and learn something than leave it and never understand it.

    opened by iancoleman 3
  • Add reveal to commitment and bivarcommitment

    Add reveal to commitment and bivarcommitment

    These reveal functions are not necessary but I find them slightly helpful to debug, I figured if the polynomial and bivariate polynomial have it, I'll add it to the other structs for completeness sake. Leaving it to the maintainers if you want to land this.

    opened by vihu 0
Releases(0.1.0)
Owner
We focus on the tools and infrastructure that matter most to blockchain users and developers.
null
Implementation of the BLS12-381 pairing-friendly elliptic curve group

bls12_381 This crate provides an implementation of the BLS12-381 pairing-friendly elliptic curve construction. This implementation has not been review

Zero-knowledge Cryptography in Rust 183 Dec 27, 2022
A cryptosystem 💿

こま A cryptosystem ?? 何? ?? こま (also called Komatta) is an utility / library which implements a fast (yet to be tested) cryptosystem: encryption, integ

Oskar 2 Sep 5, 2022
Chargo is a tool for file encryption/decryption. It's based on Argon2 and ChaCha20Poly1305 algorithms.

| Documentation Chargo is a tool for file encryption/decryption with password. It's based on Argon2 and ChaCha20Poly1305 algorithms. From arg2u with ♥

Airat Galiullin 7 Jan 1, 2023
Pairing cryptography library in Rust

bn This is a pairing cryptography library written in pure Rust. It makes use of the Barreto-Naehrig (BN) curve construction from [BCTV2015] to provide

Electric Coin Company Prototypes and Experiments 139 Dec 15, 2022
Pairing cryptography library in Rust

bn This is a pairing cryptography library written in pure Rust. It makes use of the Barreto-Naehrig (BN) curve construction from [BCTV2015] to provide

Parity Technologies 23 Apr 22, 2022
An infrastructure for peer-to-peer, decentralized, and collaborative software.

karyon An infrastructure for peer-to-peer, decentralized, and collaborative software. In molecular biology, a Karyon is essentially "a part of the cel

karyons 14 Dec 2, 2023
A pure-Rust implementation of various threshold secret sharing schemes

Threshold Secret Sharing Efficient pure-Rust library for secret sharing, offering efficient share generation and reconstruction for both traditional S

Snips 137 Dec 29, 2022
Rust implementation of {t,n}-threshold ECDSA (elliptic curve digital signature algorithm).

Multi-party ECDSA This project is a Rust implementation of {t,n}-threshold ECDSA (elliptic curve digital signature algorithm). Threshold ECDSA include

[ZenGo X] 706 Jan 5, 2023
Multi Party Key Management System (KMS) for Secp256k1 Elliptic curve based digital signatures.

Key Management System (KMS) for curve Secp256k1 Multi Party Key Management System (KMS) for Secp256k1 Elliptic curve based digital signatures. Introdu

[ZenGo X] 61 Dec 28, 2022
Rust implementation of multi-party Schnorr signatures over elliptic curves.

Multi Party Schnorr Signatures This library contains several Rust implementations of multi-signature Schnorr schemes. Generally speaking, these scheme

[ZenGo X] 148 Dec 15, 2022
Schnorr VRFs and signatures on the Ristretto group

schnorrkel Schnorrkel implements Schnorr signature on Ristretto compressed Ed25519 points, as well as related protocols like HDKD, MuSig, and a verifi

Web3 Foundation 252 Dec 21, 2022
Multy-party threshold ECDSA Substrate node

Webb DKG ??️ The Webb DKG ??‍✈️ ⚠️ Beta Software ⚠️ Running the DKG Currently the easiest way to run the DKG is to use a 3-node local testnet using dk

webb 42 Dec 19, 2022
🔑 Threshold Shamir's secret sharing in Rust

Rusty Secrets Rusty Secrets is an implementation of a threshold Shamir's secret sharing scheme. Documentation (latest) Documentation (master) Design g

Spin Research 233 Dec 17, 2022
An ECDSA threshold signature algorithm implemented in Rust.

Open TSS This project is a Rust implementation of multi-party {t,n}-threshold signature scheme(TSS). The current version of this library supports ECDS

LatticeX Foundation 64 Dec 17, 2022
Gentle reminders to commit when your inserts/deletes cross a threshold

DiffDing It's easy to get lost in what you're doing. Diff ding counts the changes in your repo and reminds you to commit your changes once you exceed

Trevor Coleman 4 Dec 2, 2022
Rust library for practical time-lock encryption using `drand` threshold network

tlock-rs: Practical Timelock Encryption/Decryption in Rust This repo contains pure Rust implementation of drand/tlock scheme. It provides time-based e

Timofey 32 Jan 8, 2023
NIST P-256 signatures for Cortex-M4 microcontrollers

nisty NIST P256 signatures for Cortex-M4 microcontrollers What is this? Sometimes NIST P256 signatures need to be used. This is an attempt to create a

null 13 Mar 14, 2021
BLS Signatures in Rust

BLS Signatures Implementation of BLS signatures in pure Rust. Development BLST Portability To enable the portable feature when building blst dependenc

Filecoin 50 Dec 25, 2022
Generates Solidity code to verify EIP-712 style signatures

eip712 Generates Solidity code to verify EIP-712 style signatures. Usage First, create an abstract contract implementing the functionality you want: /

Sam Wilson 11 Dec 22, 2022