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

New curve interfaces #484

Merged
merged 50 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from 46 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
209afce
Add custom traits Field and PrimeField with a blanket implementation …
annenkov Oct 5, 2023
3324f36
Do not use PrimeField where Field is enough
annenkov Oct 5, 2023
9a2ec6d
Add curve25519 implementation stub
annenkov Oct 6, 2023
159ca8a
Implement Field/Curve traits for ed25519 (WIP)
hamiidreza Nov 9, 2023
fe5be05
curve25519 WIP
annenkov Nov 9, 2023
4eb4b0e
Curve25519 Added
hamiidreza Nov 13, 2023
45c2bc1
minor fixes
hamiidreza Nov 13, 2023
37fcf8c
Add benches
annenkov Nov 13, 2023
43d286b
Add ed25519_ng implementation; add dalek's bulletproof benchmark
annenkov Nov 14, 2023
7a2005c
msm benchmark
hamiidreza Nov 17, 2023
8610c74
Use different multiexp implementations: generic of BSL and special fo…
annenkov Nov 22, 2023
2cc21a7
Comment on msm benchmark
annenkov Nov 22, 2023
b2e6897
Change MultiExp interface a bit; GenericMultiExp::new takes window_size
annenkov Nov 24, 2023
5ccd66f
Arkworks integration WIP
annenkov Nov 27, 2023
f452d5d
Merge branch 'main' into new-curves
annenkov Nov 27, 2023
89c71bf
Fix clippy warnings
annenkov Nov 27, 2023
d6edf65
Clean-up: remove experimental code; fix imports; constants and comments
annenkov Nov 27, 2023
5b128fe
Use RistrettoMultiExpNoPrecompute as multiexp for ristretto
annenkov Nov 27, 2023
91306b5
Remove unused import and redundant comment
annenkov Nov 27, 2023
b48d1fd
Cleanup
annenkov Nov 27, 2023
cfa3b59
Update CHANGELOG
annenkov Nov 28, 2023
c732939
Cleanup; set GROUP_ELEMENT_LENGTH to 32 for curve25519
annenkov Nov 28, 2023
9de8c22
Remove ArkWorks stuff
annenkov Nov 29, 2023
8876529
Remove pprof profiling dependency; add curve25519-dalek-ng to dev dep…
annenkov Nov 29, 2023
9897928
Dependencies in Cargo.lock
annenkov Nov 29, 2023
1cca837
removed dalek range bench
hamiidreza Dec 5, 2023
78fd866
minor
hamiidreza Dec 5, 2023
23a835b
msm_bench clean-up
hamiidreza Dec 6, 2023
92be6ff
range_proof_bench clean-up
hamiidreza Dec 6, 2023
0e6b2b9
Remove todos
annenkov Dec 13, 2023
40f9132
Remove Display from Field constraints
annenkov Dec 13, 2023
1d8027f
Drive from, comment on unwrapping in into_repr()
annenkov Dec 13, 2023
e7bbf67
Apply suggestions from code review
annenkov Dec 13, 2023
6d19f44
Merge branch 'new-curves' of github.com:Concordium/concordium-base in…
annenkov Dec 13, 2023
2bea108
Remove redundant dependencies
annenkov Dec 13, 2023
287a2b8
Adding tests for ed25519
hamiidreza Dec 19, 2023
7451a6f
removing unnecessary tests
hamiidreza Dec 20, 2023
0463cd9
Apply suggestions from code review
hamiidreza Dec 20, 2023
46c9ac0
Apply suggestions from code review
hamiidreza Dec 20, 2023
5facd01
Apply suggestions from code review
hamiidreza Dec 20, 2023
c459bc3
Add tests for into_repr() and scalar_from_bytes()
annenkov Dec 21, 2023
7ecae74
Merge branch 'new-curves' of github.com:Concordium/concordium-base in…
annenkov Dec 21, 2023
a1f5187
Fix curve25519 tests
annenkov Dec 22, 2023
6da6568
Merge branch 'main' into new-curves
annenkov Dec 22, 2023
f5e5873
Add comments to curve25519 tests
annenkov Dec 22, 2023
134d1f1
Merge branch 'new-curves' of github.com:Concordium/concordium-base in…
annenkov Dec 22, 2023
f75deb8
Apply suggestions from code review
annenkov Jan 2, 2024
a85d36a
Fix comments
annenkov Jan 2, 2024
c51bdeb
Remove ff::BitIterator, use pow_vartime implementation from newer ver…
annenkov Jan 2, 2024
7d72684
Add a comment about double; remove commented out line
annenkov Jan 3, 2024
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
32 changes: 16 additions & 16 deletions mobile_wallet/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions rust-src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions rust-src/concordium_base/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
## Unreleased changes

- Improve performance of `multiexp*` family of functions.
- Add traits `Field` and `PrimeField` with implementations for the underlying field of the `BLS12-381`` curve.
- Add `MultiExp` trait that allows to have different `multiexp` algorithm implementations for different curves.
- Add implementations of `Field`, `PrimeField` and `Curve` for the Ristretto representation of `curve25519`.
- Support `P7` protocol version.
- The `Debug` implementation for `ContractEvent` displays the value in `hex`.
The alternate formatter (using `#`) displays it as a list of bytes.
Expand Down
28 changes: 15 additions & 13 deletions rust-src/concordium_base/benches/bulletproofs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,14 @@ use concordium_base::{
random_oracle::RandomOracle,
};
use criterion::Criterion;
use ff::Field;
use pairing::bls12_381::{Fr, G1};
use curve25519_dalek::ristretto::RistrettoPoint;
use pairing::bls12_381::G1;
use rand::*;
use std::time::Duration;

type SomeCurve = G1;
type SomeField = Fr;

pub fn prove_verify_benchmarks(c: &mut Criterion) {
let mut group = c.benchmark_group("Range Proof");
pub fn prove_verify_benchmarks<SomeCurve: Curve>(c: &mut Criterion) {
let bench_group_name = "Range Proof for ".to_owned() + std::any::type_name::<SomeCurve>();
let mut group = c.benchmark_group(bench_group_name);

let rng = &mut thread_rng();
let n: u8 = 32;
Expand Down Expand Up @@ -118,8 +116,12 @@ pub fn prove_verify_benchmarks(c: &mut Criterion) {
}

#[allow(non_snake_case)]
fn compare_inner_product_proof(c: &mut Criterion) {
let mut group = c.benchmark_group("Inner-Product Proof");
fn compare_inner_product_proof<SomeCurve: Curve>(c: &mut Criterion) {
let bench_group_name = format!(
"Inner-Product Proof for {}",
std::any::type_name::<SomeCurve>()
);
let mut group = c.benchmark_group(bench_group_name);

// Testing with n = 4
let rng = &mut thread_rng();
Expand All @@ -145,15 +147,15 @@ fn compare_inner_product_proof(c: &mut Criterion) {
let H = H_vec.clone();
let mut H_prime: Vec<SomeCurve> = Vec::with_capacity(n);
let y_inv = y.inverse().unwrap();
let mut H_prime_scalars: Vec<SomeField> = Vec::with_capacity(n);
let mut H_prime_scalars: Vec<<SomeCurve as Curve>::Scalar> = Vec::with_capacity(n);
let mut transcript = RandomOracle::empty();
let G_vec_p = G_vec.clone();
let H_vec_p = H_vec.clone();
let a_vec_p = a_vec.clone();
let b_vec_p = b_vec.clone();
group.bench_function("Naive inner product proof", move |b| {
b.iter(|| {
let mut y_inv_i = SomeField::one();
let mut y_inv_i = <SomeCurve as Curve>::Scalar::one();
for h in H.iter().take(n) {
H_prime.push(h.mul_by_scalar(&y_inv_i));
y_inv_i.mul_assign(&y_inv);
Expand All @@ -164,7 +166,7 @@ fn compare_inner_product_proof(c: &mut Criterion) {
let mut transcript = RandomOracle::empty();
group.bench_function("Better inner product proof with scalars", move |b| {
b.iter(|| {
let mut y_inv_i = SomeField::one();
let mut y_inv_i = <SomeCurve as Curve>::Scalar::one();
for _ in 0..n {
H_prime_scalars.push(y_inv_i);
y_inv_i.mul_assign(&y_inv);
Expand All @@ -185,5 +187,5 @@ fn compare_inner_product_proof(c: &mut Criterion) {
criterion_group!(
name = benchmarks;
config = Criterion::default().measurement_time(Duration::from_millis(1000)).sample_size(10);
targets = prove_verify_benchmarks, compare_inner_product_proof);
targets = prove_verify_benchmarks::<G1>, prove_verify_benchmarks::<RistrettoPoint>, compare_inner_product_proof::<G1>, compare_inner_product_proof::<RistrettoPoint>);
criterion_main!(benchmarks);
66 changes: 61 additions & 5 deletions rust-src/concordium_base/benches/multiexp_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ extern crate criterion;

use concordium_base::curve_arithmetic::*;
use criterion::Criterion;
use curve25519_dalek::ristretto::RistrettoPoint;
use pairing::bls12_381::G1;
use rand::*;
use std::time::Duration;

pub fn bench_multiexp(c: &mut Criterion) {
pub fn bench_multiexp_bls(c: &mut Criterion) {
let mut csprng = thread_rng();
let m = 3;
let ns = (1..=m).map(|x| x * x);
Expand All @@ -21,7 +23,7 @@ pub fn bench_multiexp(c: &mut Criterion) {
let gsc = gs[..i].to_vec();
let esc = es[..i].to_vec();
let mut group = c.benchmark_group(format!("Group({})", i));
group.bench_function(format!("{}: Baseline", module_path!()), move |b| {
group.bench_function(format!("{}: Baseline for BLS", module_path!()), move |b| {
b.iter(|| {
let mut a = G1::zero_point();
for (g, e) in gsc.iter().zip(esc.iter()) {
Expand All @@ -33,13 +35,67 @@ pub fn bench_multiexp(c: &mut Criterion) {
let gsc = gs[..i].to_vec();
let esc = es[..i].to_vec();
group.bench_function(
&format!("{}: Multiexp (window = {w})", module_path!()),
move |b| b.iter(|| multiexp_worker(&gsc, &esc, w)),
&format!("{}: Multiexp for BLS (window = {w})", module_path!()),
move |b| b.iter(|| GenericMultiExp::new(&gsc, w).multiexp(&esc)),
);
}
group.finish();
}
}

criterion_group!(multiexp_benchmarks, bench_multiexp);
// Benchmarking multi-exponentiation over the Ristretto curve. Note that we have
// two multiexp algorithms in our library: one that is tailor-made for the
// Ristretto curve, and one generic algorithm for other curves (e.g., BLS).
// The purpose of this benchmark is to measure the running time of the multiexp
// algorithm for the Ristretto curve.
pub fn bench_multiexp_ristretto(c: &mut Criterion) {
let mut csprng = thread_rng();
let m = 3;
let ns = (1..=m).map(|x| x * x);
let mut gs: Vec<RistrettoPoint> = Vec::with_capacity(m * m);
let mut es: Vec<<RistrettoPoint as Curve>::Scalar> = Vec::with_capacity(m * m);
for _ in 0..(m * m) {
gs.push(RistrettoPoint::generate(&mut csprng));
es.push(RistrettoPoint::generate_scalar(&mut csprng));
}

for i in ns {
let gsc = gs[..i].to_vec();
let esc = es[..i].to_vec();
let mut group = c.benchmark_group(format!("Group({})", i));
group.bench_function(
format!("{}: Baseline for Ristretto", module_path!()),
move |b| {
b.iter(|| {
let mut a = RistrettoPoint::zero_point();
for (g, e) in gsc.iter().zip(esc.iter()) {
a = a.plus_point(&g.mul_by_scalar(e))
}
})
},
);

let gsc = gs[..i].to_vec();
let esc = es[..i].to_vec();
group.bench_function(
format!("{}: Multiexp for Ristretto", module_path!()),
move |b| {
b.iter(|| {
// Create msm algorithm instance with a precomputed point table.
// For the Ristretto curve it will use the RistrettoMultiExpNoPrecompute and
// our generic implementation for the BLS curve.
let msm = RistrettoPoint::new_multiexp(&gsc);
msm.multiexp(&esc);
})
},
);

group.finish();
}
}

criterion_group!(
name = multiexp_benchmarks;
config = Criterion::default().measurement_time(Duration::from_millis(10000)).sample_size(100);
targets = bench_multiexp_bls, bench_multiexp_ristretto);
criterion_main!(multiexp_benchmarks);
3 changes: 1 addition & 2 deletions rust-src/concordium_base/src/aggregate_sig/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ mod ffi;

use crate::{
common::{SerdeBase16Serialize, Serialize, *},
curve_arithmetic::{Curve, Pairing, Value},
curve_arithmetic::{Curve, Field, Pairing, Value},
random_oracle::RandomOracle,
sigma_protocols::{common::*, dlog::*},
};
use ff::Field;
use rand::Rng;
use rayon::iter::*;
use sha2::{digest::Output, Digest, Sha512};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
//! this crate
use crate::{
common::*,
curve_arithmetic::{multiexp, Curve},
curve_arithmetic::{multiexp, Curve, Field},
random_oracle::RandomOracle,
};
use ff::Field;

/// Inner product proof
#[derive(Clone, Serialize, Debug)]
Expand Down
12 changes: 5 additions & 7 deletions rust-src/concordium_base/src/bulletproofs/range_proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
use super::{inner_product_proof::*, utils::*};
use crate::{
common::*,
curve_arithmetic::{multiexp, multiexp_table, multiexp_worker_given_table, Curve, Value},
curve_arithmetic::{multiexp, Curve, Field, MultiExp, PrimeField, Value},
id::id_proof_types::ProofVersion,
pedersen_commitment::*,
random_oracle::RandomOracle,
};
use ff::{Field, PrimeField};
use rand::*;
use std::iter::once;

Expand Down Expand Up @@ -92,7 +91,7 @@ pub fn prove_given_scalars<C: Curve, T: Rng>(
let mut v_integers = Vec::with_capacity(v_vec.len());
for &v in v_vec {
let rep = v.into_repr();
let r = rep.as_ref()[0];
let r = rep[0];
v_integers.push(r);
}

Expand Down Expand Up @@ -226,10 +225,9 @@ pub fn prove<C: Curve, T: Rng>(
.chain(once(B_tilde))
.collect();
// compute A and S comittments using multi exponentiation
let window_size = 4;
let table = multiexp_table(&GH_B_tilde, window_size);
let A = multiexp_worker_given_table(&A_scalars, &table, window_size);
let S = multiexp_worker_given_table(&S_scalars, &table, window_size);
let multiexp_alg = C::new_multiexp(&GH_B_tilde);
let A = multiexp_alg.multiexp(&A_scalars);
let S = multiexp_alg.multiexp(&S_scalars);
// append commitments A and S to transcript
transcript.append_message(b"A", &A);
transcript.append_message(b"S", &S);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
use super::{inner_product_proof::*, utils::*};
use crate::{
common::*,
curve_arithmetic::{multiexp, multiexp_table, multiexp_worker_given_table, Curve},
curve_arithmetic::{multiexp, Curve, Field, MultiExp},
id::id_proof_types::ProofVersion,
pedersen_commitment::*,
random_oracle::RandomOracle,
};
use ff::Field;
use rand::*;
use std::{convert::TryInto, iter::once};

Expand Down Expand Up @@ -169,10 +168,9 @@ pub fn prove<C: Curve, R: Rng>(
.chain(once(B_tilde))
.collect();
// compute A and S commitments using multi exponentiation
let window_size = 4;
let table = multiexp_table(&GH_B_tilde, window_size);
let A = multiexp_worker_given_table(&A_scalars, &table, window_size);
let S = multiexp_worker_given_table(&S_scalars, &table, window_size);
let mexp = C::new_multiexp(&GH_B_tilde);
let A = mexp.multiexp(&A_scalars);
let S = mexp.multiexp(&S_scalars);
// append commitments A and S to transcript
transcript.append_message(b"A", &A);
transcript.append_message(b"S", &S);
Expand Down
Loading
Loading