Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge contents of upstream zkcrypto/bls12_381 #116

Merged
merged 3 commits into from
Jun 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions .github/workflows/dusk_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,11 @@ jobs:
test_nightly_std:
name: Nightly tests std
uses: dusk-network/.github/.github/workflows/run-tests.yml@main
with:
test_flags: --all-features

test_nightly_no_std:
name: Nightly tests no_std
uses: dusk-network/.github/.github/workflows/run-tests.yml@main
with:
test_flags: --no-default-features

test_nightly_serde:
name: Nightly tests serde
uses: dusk-network/.github/.github/workflows/run-tests.yml@main
with:
test_flags: --features serde_req
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Align crate with upstream `zkcrypto/bls12_381` [#117]

### Removed

- Remove scalar field generator [#100]
- Remove canonical and canonical_derive dependency [#108]

### Changed

- Rename `serde_req` feature to `serde` [#117]
- Separate Dusk's additions from the original crate [#109]

## [0.11.3] - 2023-05-17
Expand Down Expand Up @@ -190,6 +195,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Rename `S` to `TWO_ADACITY` and export it

<!-- Issues -->
[#117]: (https://github.com/dusk-network/bls12_381/issues/117)
[#109]: (https://github.com/dusk-network/bls12_381/issues/109)
[#108]: (https://github.com/dusk-network/bls12_381/issues/108)
[#100]: (https://github.com/dusk-network/bls12_381/issues/100)
Expand Down
119 changes: 87 additions & 32 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
[package]
authors = ["Sean Bowe <ewillbefull@gmail.com>, CPerezz <carlos@dusk.network>"]
authors = [
"Sean Bowe <ewillbefull@gmail.com>",
"Jack Grigg <thestr4d@gmail.com>",
"CPerezz <carlos@dusk.network>",
]
description = "Fork of the implementation of the BLS12-381 pairing-friendly elliptic curve construction with some extra tooling needed by the Dusk team"
documentation = "https://docs.rs/dusk-bls12_381/"
homepage = "https://github.com/dusk-network/bls12_381"
license = "MIT/Apache-2.0"
license = "MIT/Apache-2.0/MPL-2.0"
name = "dusk-bls12_381"
repository = "https://github.com/dusk-network/bls12_381"
version = "0.11.3"
edition = "2021"

keywords = ["cryptography", "bls12_381", "zk-snarks", "ecc", "elliptic-curve"]
categories =["algorithms", "cryptography", "development-tools"]
edition = "2021"
exclude = [".github/workflows/ci.yml",
".gitignore",
exclude = [
".github/workflows/ci.yml",
".gitignore",
]

[dependencies]
byteorder = {version = "1.0", default-features = false, optional = true}
rayon = {version = "1.3", optional = true}
serde = {version = "1.0", optional = true}
rand_core = {version = "0.6", default-features = false}
rkyv = {version = "0.7", optional = true, default-features = false}
bytecheck = {version = "0.6", optional = true, default-features = false}
dusk-bytes = "0.1"

[package.metadata.docs.rs]
rustdoc-args = [ "--html-in-header", "katex-header.html" ]

[dev-dependencies]
criterion = "0.2.11"
csv = ">= 1.0, < 1.2" # csv 1.2 has MSRV 1.60
criterion = "0.3"
hex = "0.4"
rand_xorshift = "0.3"
sha2 = "0.9"
sha3 = "0.9"
# Dev-dependencies added by Dusk
bincode = "1"
rkyv = {version = "0.7", default-features = false, features = ["size_32"]}

Expand All @@ -35,26 +39,77 @@ name = "groups"
harness = false
required-features = ["groups"]

[[bench]]
name = "hash_to_curve"
harness = false
required-features = ["experimental"]

[dependencies.digest]
version = "0.9"
optional = true

[dependencies.ff]
version = "0.13"
default-features = false

[dependencies.group]
version = "0.13"
default-features = false
optional = true

[dependencies.pairing]
version = "0.23"
optional = true

[dependencies.rand_core]
version = "0.6"
default-features = false

[dependencies.subtle]
version = "2.0"
version = "2"
default-features = false

[dependencies.zeroize]
version = "1"
default-features = false
optional = true

# Start of dependencies added by Dusk
[dependencies.byteorder]
version = "1"
default-features = false
optional = true

[dependencies.rayon]
version = "1"
optional = true

[dependencies.serde]
version = "1"
optional = true

[dependencies.rkyv]
version = "0.7"
default-features = false
optional = true

[dependencies.bytecheck]
version = "0.6"
default-features = false
optional = true

[dependencies.dusk-bytes]
version = "0.1"
# End

[features]
default = ["std"]
std = [
"alloc",
"parallel",
"groups",
"pairings",
"endo",
"byteorder",
"rand_core/std"
]
groups = []
parallel = ["rayon"]
pairings = ["groups"]
alloc = []
default = ["groups", "pairings", "alloc", "bits", "parallel", "byteorder"]
bits = ["ff/bits"]
groups = ["group"]
pairings = ["groups", "pairing"]
alloc = ["group/alloc"]
experimental = ["digest"]
nightly = ["subtle/nightly"]
# Features added by Dusk
parallel = ["rayon"]
rkyv-impl = ["rkyv", "rkyv/alloc", "bytecheck"]
serde_req = ["serde", "std"]
endo = []
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
[![Repository](https://img.shields.io/badge/github-dusk--bls12_381-blueviolet?logo=github)](https://github.com/dusk-network/bls12_381)
[![Documentation](https://img.shields.io/badge/docs-dusk--bls12_381-blue?logo=rust)](https://docs.rs/dusk-bls12_381/)


**THIS CRATE IS A FORK OF [https://github.com/zkcrypto/bls12_381](https://github.com/zkcrypto/bls12_381/) where the Dusk-Network team has added a variety of tools required by other libraries built on the top of this one.
The 99% of the library stills being done by @ebfull and you SHOULD NOT use this one unless you need a specific tool that we've
implemented and it's not on the original library.**
Expand All @@ -23,18 +22,20 @@ implemented and it's not on the original library.**
This crate provides an implementation of the BLS12-381 pairing-friendly elliptic curve construction.

* **This implementation has not been reviewed or audited. Use at your own risk.**
* This implementation targets Rust `1.36` or later.
* This implementation targets Rust `1.56` or later.
* This implementation does not require the Rust standard library.
* All operations are constant time unless explicitly noted.

## Features

* `bits` (on by default): Enables APIs for obtaining bit iterators for scalars.
* `groups` (on by default): Enables APIs for performing group arithmetic with G1, G2, and GT.
* `pairings` (on by default): Enables some APIs for performing pairings.
* `alloc` (on by default): Enables APIs that require an allocator; these include pairing optimizations.
* `nightly`: Enables `subtle/nightly` which tries to prevent compiler optimizations that could jeopardize constant time operations. Requires the nightly Rust compiler.
* `endo`: Enables optimizations that leverage curve endomorphisms, which may run foul of patents US7110538B2 and US7995752B2 set to expire in September 2020.
* `parallel` (on by default): Enables `rayon` usage for higly parallelizable ops such as multiscalar multiplication.
* `experimental`: Enables experimental features. These features have no backwards-compatibility guarantees and may change at any time; users that depend on specific behaviour should pin an exact version of this crate. The current list of experimental features:
* Hashing to curves ([Internet Draft v12](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-12))
* `parallel` (on by default): Enables `rayon` usage for highly parallelizable ops such as multiscalar multiplication.

## [Documentation](https://docs.rs/dusk-bls12_381)

Expand Down
68 changes: 68 additions & 0 deletions benches/hash_to_curve.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#[macro_use]
extern crate criterion;

extern crate dusk_bls12_381;
use dusk_bls12_381::hash_to_curve::*;
use dusk_bls12_381::*;

use criterion::{black_box, Criterion};

fn criterion_benchmark(c: &mut Criterion) {
// G1Projective
{
let name = "G1Projective";

let message: &[u8] = b"test message";
let dst: &[u8] = b"test DST";

c.bench_function(
&format!("{} encode_to_curve SSWU SHA-256", name),
move |b| {
b.iter(|| {
<G1Projective as HashToCurve<ExpandMsgXmd<sha2::Sha256>>>::encode_to_curve(
black_box(message),
black_box(dst),
)
})
},
);
c.bench_function(&format!("{} hash_to_curve SSWU SHA-256", name), move |b| {
b.iter(|| {
<G1Projective as HashToCurve<ExpandMsgXmd<sha2::Sha256>>>::hash_to_curve(
black_box(message),
black_box(dst),
)
})
});
}
// G2Projective
{
let name = "G2Projective";

let message: &[u8] = b"test message";
let dst: &[u8] = b"test DST";

c.bench_function(
&format!("{} encode_to_curve SSWU SHA-256", name),
move |b| {
b.iter(|| {
<G2Projective as HashToCurve<ExpandMsgXmd<sha2::Sha256>>>::encode_to_curve(
black_box(message),
black_box(dst),
)
})
},
);
c.bench_function(&format!("{} hash_to_curve SSWU SHA-256", name), move |b| {
b.iter(|| {
<G2Projective as HashToCurve<ExpandMsgXmd<sha2::Sha256>>>::hash_to_curve(
black_box(message),
black_box(dst),
)
})
});
}
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
2 changes: 1 addition & 1 deletion rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[toolchain]
channel = "nightly"
components = ["rustfmt", "clippy"]
components = ["clippy", "rustfmt"]
11 changes: 7 additions & 4 deletions src/dusk/choice.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use core::convert::Infallible;

use dusk_bytes::{HexDebug, Serializable};
use dusk_bytes::Serializable;
use subtle::ConditionallySelectable;

#[cfg(feature = "rkyv-impl")]
Expand All @@ -9,9 +9,12 @@ use bytecheck::CheckBytes;
use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};

/// Wrapper for a [`subtle::Choice`]
#[derive(Copy, Clone, HexDebug)]
#[cfg_attr(feature = "rkyv-impl", derive(Archive, RkyvSerialize, RkyvDeserialize))]
#[cfg_attr(feature = "rkyv-impl", archive_attr(derive(CheckBytes)))]
#[derive(Copy, Clone, Debug)]
#[cfg_attr(
feature = "rkyv-impl",
derive(Archive, RkyvSerialize, RkyvDeserialize),
archive_attr(derive(CheckBytes))
)]
pub struct Choice(u8);

impl Choice {
Expand Down
15 changes: 6 additions & 9 deletions src/dusk/multiscalar_mul.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ use crate::{
g1::{G1Affine, G1Projective},
scalar::Scalar,
};
use dusk_bytes::Serializable;

use alloc::vec::*;

#[cfg(feature = "std")]
/// Performs multiscalar multiplication reliying on Pippenger's algorithm.
/// This method was taken from `curve25519-dalek` and was originally made by
/// Oleg Andreev <oleganza@gmail.com>.
#[cfg(feature = "byteorder")]
pub fn pippenger<P, I>(points: P, scalars: I) -> G1Projective
where
P: Iterator<Item = G1Projective>,
Expand Down Expand Up @@ -91,8 +90,8 @@ where
columns.fold(hi_column, |total, p| mul_by_pow_2(&total, w as u32) + p)
}

#[cfg(feature = "std")]
/// Compute \\([2\^k] P \\) by successive doublings. Requires \\( k > 0 \\).
#[cfg(feature = "byteorder")]
pub(crate) fn mul_by_pow_2(point: &G1Projective, k: u32) -> G1Projective {
debug_assert!(k > 0);
let mut r: G1Projective;
Expand All @@ -105,9 +104,9 @@ pub(crate) fn mul_by_pow_2(point: &G1Projective, k: u32) -> G1Projective {
s.double()
}

#[cfg(feature = "std")]
/// Returns a size hint indicating how many entries of the return
/// value of `to_radix_2w` are nonzero.
#[cfg(feature = "byteorder")]
fn to_radix_2w_size_hint(w: usize) -> usize {
debug_assert!(w >= 6);
debug_assert!(w <= 8);
Expand All @@ -124,7 +123,7 @@ fn to_radix_2w_size_hint(w: usize) -> usize {
digits_count
}

#[cfg(feature = "std")]
#[cfg(feature = "byteorder")]
fn to_radix_2w(scalar: &Scalar, w: usize) -> [i8; 43] {
debug_assert!(w >= 6);
debug_assert!(w <= 8);
Expand Down Expand Up @@ -286,6 +285,7 @@ mod tests {
#[allow(unused_imports)]
use super::*;

#[cfg(feature = "byteorder")]
#[test]
fn pippenger_test() {
// Reuse points across different tests
Expand All @@ -307,10 +307,7 @@ mod tests {
let scalars = &scalars[0..n];
let points = &points[0..n];
let control: G1Projective = premultiplied[0..n].iter().sum();
let subject = pippenger(
points.to_owned().into_iter(),
scalars.to_owned().into_iter(),
);
let subject = pippenger(points.to_vec().into_iter(), scalars.to_vec().into_iter());
assert_eq!(subject, control);
n = n / 2;
}
Expand Down
Loading