BLS12-381 cryptography using Apache Milagro

Overview

BLS12-381 Aggregate Signatures in Rust using Apache Milagro

Build Status Gitter

WARNING: This library is a work in progress and has not been audited. Do NOT consider the cryptography safe!

Uses the The Apache Milagro Cryptographic Library.

This crate is heavily based upon work by @lovesh.

Presently this library only supports features required for Ethereum 2.0 signature validation. The aggregation methods here are vulnerable to the rouge-key attack.

There has been no public audit or scrutiny placed upon this crate. If you're a cryptographer I would love to have your input.

This library uses a Proof of Possession (PoP) variant as protection against rogue key attacks. A public key can be PoP verified by signing a hash of the public key. This must be done before a PublicKey may be used in any aggregate signatures.

Subgroup checks are performed for signatures during verification and public keys during deserialisation.

BLS Standard

Current implementation of the BLS Standard aligns with bls-signatures-v04 and hash-to-curve-v09.

Usage

Single Signatures

Perform signing and verification of non-aggregate BLS signatures. Supports serializing and de-serializing both public and secret keys.

let sk_bytes = vec![
	78, 252, 122, 126, 32, 0, 75, 89, 252, 31, 42, 130, 254, 88, 6, 90, 138, 202, 135, 194,
	233, 117, 181, 75, 96, 238, 79, 100, 237, 59, 140, 111,
];

// Load some keys from a serialized secret key.
let sk = SecretKey::from_bytes(&sk_bytes).unwrap();
let pk = PublicKey::from_secret_key(&sk);

// Sign a message
let message = "cats".as_bytes();
let signature = Signature::new(&message, &sk);
assert!(signature.verify(&message, &pk));

// Serialize then de-serialize, just 'cause we can.
let pk_bytes = pk.as_bytes();
let pk = PublicKey::from_bytes(&pk_bytes).unwrap();

// Verify the message
assert!(signature.verify(&message, &pk));

Generate new "random" secret keys (see SecretKey docs for information on entropy sources).

// Generate a random key pair.
let sk = SecretKey::random(&mut rand::thread_rng());
let pk = PublicKey::from_secret_key(&sk);

// Sign and verify a message.
let message = "cats".as_bytes();
let signature = Signature::new(&message, &sk);
assert!(signature.verify(&message, &pk));

Aggregate Signatures

Aggregate signatures and public keys. Supports serializing and de-serializing both AggregateSignatures and AggregatePublicKeys.

let signing_secret_key_bytes = vec![
		vec![
				98, 161, 50, 32, 254, 87, 16, 25, 167, 79, 192, 116, 176, 74, 164, 217, 40, 57,
				179, 15, 19, 21, 240, 100, 70, 127, 111, 170, 129, 137, 42, 53,
		],
		vec![
				53, 72, 211, 104, 184, 68, 142, 208, 115, 22, 156, 97, 28, 216, 228, 102, 4, 218,
				116, 226, 166, 131, 67, 7, 40, 55, 157, 167, 157, 127, 143, 13,
		],
];

// Load the key pairs from our serialized secret keys,
let signing_keypairs: Vec<Keypair> = signing_secret_key_bytes
		.iter()
		.map(|bytes| {
				let sk = SecretKey::from_bytes(&bytes).unwrap();
				let pk = PublicKey::from_secret_key(&sk);
				Keypair { sk, pk }
		})
		.collect();

let message = "cats".as_bytes();

// Create an aggregate signature over some message, also generating an
// aggregate public key at the same time.
let mut agg_sig = AggregateSignature::new();
let mut public_keys = vec![];
for keypair in &signing_keypairs {
		let sig = Signature::new(&message, &keypair.sk);
		agg_sig.add(&sig);
		public_keys.push(keypair.pk.clone());
}
let agg_pub_key = AggregatePublicKey::into_aggregate(&public_keys).unwrap();

// Serialize and de-serialize the aggregates, just 'cause we can.
let agg_sig_bytes = agg_sig.as_bytes();
let agg_sig = AggregateSignature::from_bytes(&agg_sig_bytes).unwrap();

// Verify the AggregateSignature against the AggregatePublicKey
assert!(agg_sig.fast_aggregate_verify_pre_aggregated(&message, &agg_pub_key));
}

How to Run Benchmarks

cargo bench --features "bench"
Comments
  • Change license to Apache-2.0

    Change license to Apache-2.0

    This repository was previously licensed as MIT/Apache-2.0. Given that the AMCL library is Apache 2.0, I don't think is it permitted to add the MIT license.

    I will seek @lovesh's input on this, as I assume he did the initial MIT/Apache-2.0 licensing.

    opened by paulhauner 7
  • Check the input of SecretKey.from_bytes to be non zero

    Check the input of SecretKey.from_bytes to be non zero

    Hi @kirk-baird,

    In the recent release, the standard disallows zero secret key. Should we also add a non-zero check in the SecretKey.from_bytes method? Or do we intentionally don't do so?

    https://github.com/sigp/milagro_bls/blob/515201c5d165f1e08bca93e24cad4044eeed6e21/src/keys.rs#L73-L77

    opened by ChihChengLiang 4
  • Should we validate the pubkeys parameters of `fast_aggregate_verify`?

    Should we validate the pubkeys parameters of `fast_aggregate_verify`?

    Hi Kirk,

    Currently, the fast_aggregate_verify returns true if the aggregate_public_key is an identity key because we don't run key_validate checks for the input public keys.

    The IETF spec defines the behavior of FastAggregateVerify when the preconditions are met. But whether to check those preconditions are left for implementors to decide.

    Here are some options:

    • In Eth2's test cases, the validation is expected. It might be safer if all the client teams implement the same behavior.
    • The nim-blscurve implements two versions, one with the check and one without.
    opened by ChihChengLiang 2
  • BLS Sig standard 02

    BLS Sig standard 02

    Issue

    #20

    Proposed changes

    ToDo

    • Align BLS signing and verifying functions with bls signatures version 2
    • Subgroup check for public keys
    • Subgroup check for secret keys

    Additional Comments

    • Relies on #17
    • This is NOT yet part of Eth Specs as at v0.11.1
    opened by kirk-baird 2
  • Secret Key Size / Value

    Secret Key Size / Value

    Secret Key should be between values 1 < sk < r - 1 as defined here, where r is a little less than 32 bytes. This check should be added to from_bytes() . Furthermore we should also then change SecretKey.x to private to prevent modification to the secret key to be larger than r.

    This could also be a good time to change SecretKey::from_bytes() to take a bytes which are less than 48 bytes. I would recommend allowing any bytes less than 48 bytes and appending the necessary number of zero bytes such the input length is 48 bytes and can be deserialised using the Big::frombytes() function.

    opened by kirk-baird 2
  • Optimisation: Improve final exponentiation in Signature::verify

    Optimisation: Improve final exponentiation in Signature::verify

    What is the issue

    Currently we do two separate pairings in signature verification which will be slower

    Steps to resolve

    Use an ate double pairing with a single fexp() and check the resultant value is 1.

    opened by kirk-baird 2
  • Convert amcl to a submodule

    Convert amcl to a submodule

    Previously it seems the amcl files had been copied directly from the old Apache Milagro repo which has since been deleted. This PR would instead use a SigP fork of the new Repo as a submodule.

    It will make it far easier to pull changes and make changes to the AMCL repo.

    I could not see any major changes to the files other than the director structures and running cargo fmt.

    opened by kirk-baird 2
  • Decompress a PublicKey 500%  performance regression in v1.4.0

    Decompress a PublicKey 500% performance regression in v1.4.0

    What's wrong

    The performance of decompressing a PublicKey is significant slow in v1.4.0. Cropped benchmark result:

    compression/Decompress a PublicKey                                                                            
                            time:   [364.46 us 372.29 us 383.01 us]
                            change: [+497.89% +518.88% +547.26%] (p = 0.00 < 0.05)
                            Performance has regressed.
    Found 11 outliers among 100 measurements (11.00%)
      7 (7.00%) high mild
      4 (4.00%) high severe
    

    Steps to reproduce

    git checkout v1.3.0 
    git submodule update
    rm -rf target/
    cargo bench --features "bench"
    git checkout v1.4.0
    git submodule update 
    cargo bench --features "bench"
    

    Logs:

    v1.4.0

    Running target/release/deps/bls381_benches-21ec5f2d00d66323

    signing/Create a Signature                                                                            
                            time:   [2.2649 ms 2.4643 ms 2.8161 ms]
                            change: [-4.1061% +2.3568% +11.914%] (p = 0.72 > 0.05)
                            No change in performance detected.
    Found 1 outliers among 10 measurements (10.00%)
      1 (10.00%) high severe
    
    signing/Verify a Signature                                                                           
                            time:   [7.6921 ms 8.3690 ms 9.3884 ms]
                            change: [-6.8269% +2.0599% +13.337%] (p = 0.70 > 0.05)
                            No change in performance detected.
    
    Benchmarking multiple-signatures-verification-30/Verification of multiple aggregate signatures with optimizations: Collecting 10 samples in estimated 8.6845 s                                                                                                                                                                multiple-signatures-verification-30/Verification of multiple aggregate signatures with optimizations                        
                            time:   [81.784 ms 89.208 ms 96.381 ms]
                            change: [+3.7598% +9.7247% +18.196%] (p = 0.01 < 0.05)
                            Performance has regressed.
    Found 1 outliers among 10 measurements (10.00%)
      1 (10.00%) high mild
    
    aggregation/Verifying aggregate of 128 signatures                                                                            
                            time:   [7.6322 ms 7.7766 ms 7.9435 ms]
                            change: [+2.2044% +4.3055% +6.3692%] (p = 0.00 < 0.05)
                            Performance has regressed.
    Found 6 outliers among 100 measurements (6.00%)
      2 (2.00%) high mild
      4 (4.00%) high severe
    
    aggregation/Aggregate a PublicKey                                                                             
                            time:   [2.1013 us 2.1592 us 2.2340 us]
                            change: [+54.977% +78.314% +105.88%] (p = 0.00 < 0.05)
                            Performance has regressed.
    Found 11 outliers among 100 measurements (11.00%)
      4 (4.00%) high mild
      7 (7.00%) high severe
    
    aggregation/Aggregate a Signature                                                                             
                            time:   [5.1918 us 5.3296 us 5.4961 us]
                            change: [+7.5565% +11.184% +14.766%] (p = 0.00 < 0.05)
                            Performance has regressed.
    Found 12 outliers among 100 measurements (12.00%)
      2 (2.00%) high mild
      10 (10.00%) high severe
    
    compression/Decompress a Signature                                                                            
                            time:   [198.73 us 200.60 us 202.77 us]
                            change: [+6.7434% +9.5261% +13.081%] (p = 0.00 < 0.05)
                            Performance has regressed.
    Found 6 outliers among 100 measurements (6.00%)
      2 (2.00%) high mild
      4 (4.00%) high severe
    
    compression/Compress a Signature                                                                            
                            time:   [1.4246 us 1.4627 us 1.5011 us]
                            change: [-5.3093% +1.8072% +7.8935%] (p = 0.65 > 0.05)
                            No change in performance detected.
    
    compression/Decompress a PublicKey                                                                            
                            time:   [364.46 us 372.29 us 383.01 us]
                            change: [+497.89% +518.88% +547.26%] (p = 0.00 < 0.05)
                            Performance has regressed.
    Found 11 outliers among 100 measurements (11.00%)
      7 (7.00%) high mild
      4 (4.00%) high severe
    
    compression/Compress a PublicKey                                                                            
                            time:   [1.4288 us 1.4490 us 1.4937 us]
                            change: [-10.385% -0.2387% +10.038%] (p = 0.97 > 0.05)
                            No change in performance detected.
    Found 1 outliers among 10 measurements (10.00%)
      1 (10.00%) high severe
    
    compression/Decompress a PublicKey from Bigs                                                                             
                            time:   [1.7494 us 1.7913 us 1.8458 us]
                            change: [+6.5483% +8.9457% +11.375%] (p = 0.00 < 0.05)
                            Performance has regressed.
    Found 8 outliers among 100 measurements (8.00%)
      3 (3.00%) high mild
      5 (5.00%) high severe
    
    compression/Compress a PublicKey to Bigs                                                                            
                            time:   [1.0970 us 1.1233 us 1.1606 us]
                            change: [+5.9204% +10.128% +16.469%] (p = 0.00 < 0.05)
                            Performance has regressed.
    Found 1 outliers among 10 measurements (10.00%)
      1 (10.00%) high severe
    
    key generation/Generate random keypair                                                                            
                            time:   [389.87 us 400.86 us 414.20 us]
                            change: [+8.9707% +11.088% +13.485%] (p = 0.00 < 0.05)
                            Performance has regressed.
    Found 12 outliers among 100 measurements (12.00%)
      2 (2.00%) high mild
      10 (10.00%) high severe
    
    key generation/Generate keypair from known string                                                                            
                            time:   [419.51 us 431.32 us 445.95 us]
                            change: [+4.7468% +12.559% +19.381%] (p = 0.00 < 0.05)
                            Performance has regressed.
    Found 10 outliers among 100 measurements (10.00%)
      3 (3.00%) high mild
      7 (7.00%) high severe
    

    v1.3.0

    Running target/release/deps/bls381_benches-fe64a3c500672cce
    signing/Create a Signature                                                                            
                            time:   [2.2934 ms 2.3310 ms 2.3758 ms]
    Found 1 outliers among 10 measurements (10.00%)
      1 (10.00%) high mild
    
    signing/Verify a Signature                                                                           
                            time:   [7.5973 ms 7.8653 ms 8.3068 ms]
    
    Benchmarking multiple-signatures-verification-30/Verification of multiple aggregate signatures with optimizations: Collecting 10 samples in estimated 8.5392 s                                                                                                                                                                multiple-signatures-verification-30/Verification of multiple aggregate signatures with optimizations                        
                            time:   [75.792 ms 77.780 ms 80.390 ms]
    Found 1 outliers among 10 measurements (10.00%)
      1 (10.00%) high severe
    
    aggregation/Verifying aggregate of 128 signatures                                                                            
                            time:   [7.4041 ms 7.4556 ms 7.5082 ms]
    Found 1 outliers among 100 measurements (1.00%)
      1 (1.00%) high mild
    
    aggregation/Aggregate a PublicKey                                                                             
                            time:   [1.6946 us 1.7270 us 1.7770 us]
    Found 6 outliers among 100 measurements (6.00%)
      3 (3.00%) high mild
      3 (3.00%) high severe
    
    aggregation/Aggregate a Signature                                                                             
                            time:   [4.9031 us 5.0449 us 5.2287 us]
    Found 4 outliers among 100 measurements (4.00%)
      1 (1.00%) high mild
      3 (3.00%) high severe
    
    compression/Decompress a Signature                                                                            
                            time:   [189.00 us 190.42 us 192.16 us]
    Found 6 outliers among 100 measurements (6.00%)
      4 (4.00%) high mild
      2 (2.00%) high severe
    
    compression/Compress a Signature                                                                            
                            time:   [1.3475 us 1.4022 us 1.4885 us]
    Found 1 outliers among 10 measurements (10.00%)
      1 (10.00%) high severe
    
    compression/Decompress a PublicKey                                                                            
                            time:   [62.944 us 63.413 us 63.958 us]
    Found 2 outliers among 100 measurements (2.00%)
      2 (2.00%) high mild
    
    compression/Compress a PublicKey                                                                            
                            time:   [1.4373 us 1.5601 us 1.7437 us]
    Found 1 outliers among 10 measurements (10.00%)
      1 (10.00%) high mild
    
    compression/Decompress a PublicKey from Bigs                                                                             
                            time:   [1.6095 us 1.6231 us 1.6474 us]
    Found 10 outliers among 100 measurements (10.00%)
      3 (3.00%) high mild
      7 (7.00%) high severe
    
    compression/Compress a PublicKey to Bigs                                                                            
                            time:   [1.0481 us 1.0510 us 1.0547 us]
    
    key generation/Generate random keypair                                                                            
                            time:   [351.54 us 352.96 us 354.64 us]
    Found 3 outliers among 100 measurements (3.00%)
      3 (3.00%) high mild
    
    key generation/Generate keypair from known string                                                                            
                            time:   [389.64 us 410.85 us 440.89 us]
    Found 7 outliers among 100 measurements (7.00%)
      2 (2.00%) high mild
      5 (5.00%) high severe
    
    opened by ChihChengLiang 1
  • Check that IKM is > 32B in KeyGen

    Check that IKM is > 32B in KeyGen

    IKM should be checked to be at least 32 bytes in

    https://github.com/sigp/milagro_bls/blob/c5e6c5e2dc0b9ca757b90141b807683ce98aac23/src/keys.rs#L42-L45

    as per https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04#section-2.3.

    opened by veorq 1
  • Optimise subgroup checks

    Optimise subgroup checks

    Issue

    Subgroup checks are somewhat time consuming. They can be optimised by methods described in this paper.

    See functions:

    • subgroup_check_g1()
    • subgroup_check_g2()

    Update

    Subgroup checks can be improved by using the pair::g1mul() and pair::g2mul() functions in amcl these will improve multiplication times significantly.

    opened by kirk-baird 1
  • BLS to Eth2 v0.10

    BLS to Eth2 v0.10

    Proposed changes

    • Updating to Eth2.0 v0.10.0
    • Removes domain
    • Changes hash_to_g2 to match BLS Standard
    • Add subgroup check #16
    • Update test vectors

    Items Complete

    • Remove domain

    Items ToDo

    • Update hash_to_g2
    • Add Subgroup check
    • Update test vectors

    Notes

    Most of these changes will be made from inside the apache repo

    Signed-off-by: Kirk Baird [email protected]

    opened by kirk-baird 1
  • no-std not compiling

    no-std not compiling

    I am trying to use this crate with the Substrate framework, which requires the no-std feature. It looks like this crate supports running in no-std environments, if I look at Cargo.toml. However, when I try to compile the crate I get the following compiler errors:

    error[E0433]: failed to resolve: could not find `prelude` in `alloc`
      --> src/lib.rs:15:20
       |
    15 |     pub use alloc::prelude::v1::*;
       |                    ^^^^^^^ could not find `prelude` in `alloc`
    
    error[E0433]: failed to resolve: use of undeclared type `Vec`
      --> src/keys.rs:58:27
       |
    58 |             let mut prk = Vec::<u8>::with_capacity(1 + ikm.len());
       |                           ^^^ not found in this scope
       |
    help: consider importing this struct
       |
    5  | use alloc::vec::Vec;
       |
    

    I will try to fix these in a forked version, but just wanted to get your input in case I might be missing something.

    Is the crate only supported for nightly builds?

    error[E0554]: `#![feature]` may not be used on the stable release channel
     --> src/lib.rs:4:5
      |
    4 |     feature(alloc),
      |     ^^^^^^^^^^^^^^
    
    error[E0554]: `#![feature]` may not be used on the stable release channel
     --> src/lib.rs:5:5
      |
    5 |     feature(alloc_prelude),
      |     ^^^^^^^^^^^^^^^^^^^^^^
    
    error[E0554]: `#![feature]` may not be used on the stable release channel
     --> src/lib.rs:6:5
      |
    6 |     feature(prelude_import)
      |     ^^^^^^^^^^^^^^^^^^^^^^^
    
    opened by claravanstaden 1
  • Zeroize all secret data

    Zeroize all secret data

    What is the issue

    All secrets need to be zeroed before the memory is freed.

    This includes SecretKey generation and signing and any subroutines used by these.

    Similarly for the underlying apache library, https://github.com/apache/incubator-milagro-crypto-rust/issues/33

    opened by kirk-baird 0
Releases(v1.5.1)
Owner
Sigma Prime
Blockchain & Information Security Services
Sigma Prime
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
Baek-Zheng threshold cryptosystem on top of BLS12-381

bzte A rust implementation of the Baek-Zhang threshold cryptosystem on top of BLS12-381 using arkworks Why threshold encrypt? The advantage of thresho

null 4 Jun 28, 2022
Example implementation for Biscuit tokens cryptography

example implementation for Biscuit token cryptography To aid in the implementation of Biscuit tokens in various languages, this repository contains an

Clever Cloud 6 May 25, 2021
Mundane is a Rust cryptography library backed by BoringSSL that is difficult to misuse, ergonomic, and performant (in that order).

Mundane Mundane is a Rust cryptography library backed by BoringSSL that is difficult to misuse, ergonomic, and performant (in that order). Issues and

Google 1.1k Jan 3, 2023
Manage secret values in-repo via public key cryptography

amber Manage secret values in-repo via public key cryptography. See the announcement blog post for more motivation. Amber provides the ability to secu

FP Complete 82 Nov 10, 2022
Cryptography-related format encoders/decoders: PKCS, PKIX

RustCrypto: Formats Cryptography-related format encoders/decoders: PKCS, PKIX. Crates Name crates.io Docs Description base64ct Constant-time encoder a

Rust Crypto 112 Dec 20, 2022
Implementation of the Web Cryptography specification in Rust.

[wip] webcrypto Implementation of the Web Cryptography specification in Rust. This crate hopes to ease interoperability between WASM and native target

Divy Srivastava 5 Mar 7, 2022
Cryptography-oriented big integer library with constant-time, stack-allocated (no_std-friendly) implementations of modern formulas

RustCrypto: Cryptographic Big Integers Pure Rust implementation of a big integer library which has been designed from the ground-up for use in cryptog

Rust Crypto 88 Dec 31, 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

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
Ursa - Hyperledger Ursa is a shared cryptography library

HYPERLEDGER URSA Introduction Features Libursa Libzmix Dependencies Building from source Contributing Introduction Ursa was created because people in

Hyperledger 307 Dec 20, 2022
Traits - Collection of cryptography-related traits

RustCrypto: Traits Collection of traits which describe functionality of cryptographic primitives. Crates Name Algorithm Crates.io Docs MSRV aead Authe

Rust Crypto 401 Dec 27, 2022
Collect libraries and packages about cryptography in Rust.

Awesome Cryptography Rust Collect libraries and packages about cryptography in Rust. Collection Library Symmetric Public-key / Asymmetric One-way Hash

Rust Cryptography Community 282 Dec 25, 2022
A general solution for commonly used crypt in rust, collection of cryptography-related traits and algorithms.

Crypto-rs A general solution for commonly used crypt in rust, collection of cryptography-related traits and algorithms. This is a Rust implementation

houseme 4 Nov 28, 2022
A down-to-the-metal ongoing cryptography challenge designed by Radical Semiconductor.

woodpecker ?? [NOTE: scoreboard will now be updated weekends, starting the weekend of 12/10/2022--sorry for delays! I'll also be merging in pull reque

Radical Semiconductor 16 Dec 15, 2022
Elliptic curve cryptography on Soroban.

Elliptic Curve Cryptography on Soroban Contract examples and reusable primitives. Groth 16 verifier. This crate provides a SorobanGroth16Verifier obje

Xycloo Labs 5 Feb 10, 2023
Go to Rust calls with Apache Arrow datatypes.

?? Overview alloy is a standalone Go module that enables calls to Rust code with Apache Arrow datatypes through its defined C data interface. The over

Firelink Data 3 Nov 14, 2023
Safe, fast, small crypto using Rust

THE SOFTWARE IS PROVIDED "AS IS" AND BRIAN SMITH AND THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES

Brian Smith 3k Jan 2, 2023
X25519 elliptic curve Diffie-Hellman key exchange in pure-Rust, using curve25519-dalek.

x25519-dalek A pure-Rust implementation of x25519 elliptic curve Diffie-Hellman key exchange, with curve operations provided by curve25519-dalek. This

dalek cryptography 252 Dec 26, 2022