Add benchmarks

This commit is contained in:
aniampio
2022-04-19 22:46:58 +03:00
parent a1887356dc
commit 2eed9fd247
21 changed files with 406 additions and 113 deletions
Generated
+16 -16
View File
@@ -2934,22 +2934,6 @@ dependencies = [
"websocket-requests",
]
[[package]]
name = "nym-compact-ecash"
version = "0.1.0"
dependencies = [
"bls12_381",
"bs58",
"criterion",
"digest 0.9.0",
"ff 0.10.1",
"group 0.10.0",
"itertools",
"rand 0.8.5",
"sha2",
"thiserror",
]
[[package]]
name = "nym-divisible-ecash"
version = "0.1.0"
@@ -3150,6 +3134,22 @@ dependencies = [
"version-checker",
]
[[package]]
name = "nym_compact_ecash"
version = "0.1.0"
dependencies = [
"bls12_381",
"bs58",
"criterion",
"digest 0.9.0",
"ff 0.10.1",
"group 0.10.0",
"itertools",
"rand 0.8.5",
"sha2",
"thiserror",
]
[[package]]
name = "nymcoconut"
version = "0.5.0"
+1 -1
View File
@@ -33,7 +33,7 @@ members = [
"common/network-defaults",
"common/nonexhaustive-delayqueue",
"common/nymcoconut",
"common/nym-compact-ecash",
"common/nym_compact_ecash",
"common/nym-divisible-ecash",
"common/nymsphinx",
"common/nymsphinx/acknowledgements",
@@ -1,5 +1,5 @@
[package]
name = "nym-compact-ecash"
name = "nym_compact_ecash"
version = "0.1.0"
authors = ["Ania Piotrowska <ania@nymtech.net>"]
edition = "2021"
@@ -24,4 +24,8 @@ default-features = false
[dependencies.group]
version = "0.10"
default-features = false
default-features = false
[[bench]]
name = "benchmarks"
harness = false
@@ -0,0 +1,274 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use std::ops::Neg;
use std::time::Duration;
use bls12_381::{G1Affine, G2Affine, G2Prepared, multi_miller_loop, Scalar};
use criterion::{Criterion, criterion_group, criterion_main};
use ff::Field;
use group::{Curve, Group};
use itertools::izip;
use rand::seq::SliceRandom;
use nym_compact_ecash::{aggregate_verification_keys, aggregate_wallets, generate_keypair_user, issue_verify, issue_wallet, PartialWallet, PayInfo, ttp_keygen, VerificationKeyAuth, withdrawal_request};
use nym_compact_ecash::setup::setup;
#[allow(unused)]
fn double_pairing(g11: &G1Affine, g21: &G2Affine, g12: &G1Affine, g22: &G2Affine) {
let gt1 = bls12_381::pairing(g11, g21);
let gt2 = bls12_381::pairing(g12, g22);
assert_eq!(gt1, gt2)
}
#[allow(unused)]
fn multi_miller_pairing_affine(g11: &G1Affine, g21: &G2Affine, g12: &G1Affine, g22: &G2Affine) {
let miller_loop_result = multi_miller_loop(&[
(g11, &G2Prepared::from(*g21)),
(&g12.neg(), &G2Prepared::from(*g22)),
]);
assert!(bool::from(
miller_loop_result.final_exponentiation().is_identity()
))
}
#[allow(unused)]
fn multi_miller_pairing_with_prepared(
g11: &G1Affine,
g21: &G2Prepared,
g12: &G1Affine,
g22: &G2Prepared,
) {
let miller_loop_result = multi_miller_loop(&[(g11, g21), (&g12.neg(), g22)]);
assert!(bool::from(
miller_loop_result.final_exponentiation().is_identity()
))
}
// the case of being able to prepare G2 generator
#[allow(unused)]
fn multi_miller_pairing_with_semi_prepared(
g11: &G1Affine,
g21: &G2Affine,
g12: &G1Affine,
g22: &G2Prepared,
) {
let miller_loop_result =
multi_miller_loop(&[(g11, &G2Prepared::from(*g21)), (&g12.neg(), g22)]);
assert!(bool::from(
miller_loop_result.final_exponentiation().is_identity()
))
}
#[allow(unused)]
fn bench_pairings(c: &mut Criterion) {
let mut rng = rand::thread_rng();
let g1 = G1Affine::generator();
let g2 = G2Affine::generator();
let r = Scalar::random(&mut rng);
let s = Scalar::random(&mut rng);
let g11 = (g1 * r).to_affine();
let g21 = (g2 * s).to_affine();
let g21_prep = G2Prepared::from(g21);
let g12 = (g1 * s).to_affine();
let g22 = (g2 * r).to_affine();
let g22_prep = G2Prepared::from(g22);
c.bench_function("double pairing", |b| {
b.iter(|| double_pairing(&g11, &g21, &g12, &g22))
});
c.bench_function("multi miller in affine", |b| {
b.iter(|| multi_miller_pairing_affine(&g11, &g21, &g12, &g22))
});
c.bench_function("multi miller with prepared g2", |b| {
b.iter(|| multi_miller_pairing_with_prepared(&g11, &g21_prep, &g12, &g22_prep))
});
c.bench_function("multi miller with semi-prepared g2", |b| {
b.iter(|| multi_miller_pairing_with_semi_prepared(&g11, &g21, &g12, &g22_prep))
});
}
struct BenchCase {
num_authorities: u64,
threshold_p: f32,
L: u64,
}
fn bench_compact_ecash(c: &mut Criterion) {
let mut group = c.benchmark_group("benchmark-compact-ecash");
group.measurement_time(Duration::from_secs(200));
let case = BenchCase {
num_authorities: 100,
threshold_p: 0.7,
L: 100,
};
let params = setup(case.L);
let grparams = params.grp();
let user_keypair = generate_keypair_user(&grparams);
let authorities_keypairs = ttp_keygen(&grparams, 2, 3).unwrap();
let verification_keys_auth: Vec<VerificationKeyAuth> = authorities_keypairs
.iter()
.map(|keypair| keypair.verification_key())
.collect();
let verification_key = aggregate_verification_keys(&verification_keys_auth, Some(&[1, 2, 3])).unwrap();
// ISSUANCE PHASE
let (req, req_info) = withdrawal_request(grparams, &user_keypair.secret_key()).unwrap();
// CLIENT BENCHMARK: Prepare a single withdrawal request, i.e.,
// a data needed to ask for a withdrawal of a wallet
// group.bench_function(
// &format!(
// "[Client] withdrawal_request_{}_authorities_{}_L_{}_threshold",
// case.num_authorities,
// case.L,
// case.threshold_p,
// ),
// |b| {
// b.iter(|| withdrawal_request(grparams, &user_keypair.secret_key()).unwrap())
// },
// );
// ISSUING AUTHRORITY BENCHMARK: Benchmark the issue_wallet function
// called by an authority to issue a blind signature on a partial wallet
let mut rng = rand::thread_rng();
let keypair = authorities_keypairs.choose(&mut rng).unwrap();
// group.bench_function(
// &format!(
// "[Issuing Authority] issue_partial_wallet_with_L_{}",
// case.L,
// ),
// |b| {
// b.iter(|| {
// issue_wallet(
// &grparams,
// keypair.secret_key(),
// user_keypair.public_key(),
// &req,
// )
// })
// },
// );
let mut wallet_blinded_signatures = Vec::new();
for auth_keypair in authorities_keypairs {
let blind_signature = issue_wallet(
&grparams,
auth_keypair.secret_key(),
user_keypair.public_key(),
&req,
);
wallet_blinded_signatures.push(blind_signature.unwrap());
}
// CLIENT BENCHMARK: verify the issued partial wallet
let w = wallet_blinded_signatures.get(0).clone().unwrap();
let vk = verification_keys_auth.get(0).clone().unwrap();
// group.bench_function(
// &format!(
// "[Client] issue_verify_of_a_partial_wallet_with_L_{}",
// case.L,
// ),
// |b| {
// b.iter(|| {
// issue_verify(&grparams, vk, &user_keypair.secret_key(), w, &req_info)
// })
// },
// );
let unblinded_wallet_shares: Vec<PartialWallet> = izip!(
wallet_blinded_signatures.iter(),
verification_keys_auth.iter()
)
.map(|(w, vk)| issue_verify(&grparams, vk, &user_keypair.secret_key(), w, &req_info).unwrap())
.collect();
// // CLIENT BENCHMARK: aggregating all partial wallets
// group.bench_function(
// &format!(
// "[Client] aggregate_wallets_with_L_{}_threshold_{}",
// case.L,
// case.threshold_p,
// ),
// |b| {
// b.iter(|| {
// aggregate_wallets(
// &grparams,
// &verification_key,
// &user_keypair.secret_key(),
// &unblinded_wallet_shares,
// &req_info,
// ).unwrap()
// })
// },
// );
// Aggregate partial wallets
let aggr_wallet = aggregate_wallets(
&grparams,
&verification_key,
&user_keypair.secret_key(),
&unblinded_wallet_shares,
&req_info,
).unwrap();
// SPENDING PHASE
let pay_info = PayInfo { info: [6u8; 32] };
// CLIENT BENCHMARK: spend a single coin from the wallet
group.bench_function(
&format!(
"[Client] spend_a_single_coin_L_{}_threshold_{}",
case.L,
case.threshold_p,
),
|b| {
b.iter(|| {
aggr_wallet.spend(
&params,
&verification_key,
&user_keypair.secret_key(),
&pay_info,
true,
).unwrap()
})
},
);
let (payment, upd_wallet) = aggr_wallet.spend(
&params,
&verification_key,
&user_keypair.secret_key(),
&pay_info,
false,
).unwrap();
// MERCHANT BENCHMARK: verify whether the submitted payment is legit
group.bench_function(
&format!(
"[Merchant] spend_verify_of_a_single_payment_L_{}_threshold_{}",
case.L,
case.threshold_p,
),
|b| {
b.iter(|| {
payment
.spend_verify(&params, &verification_key, &pay_info)
.unwrap()
})
},
);
}
criterion_group!(benches, bench_compact_ecash);
criterion_main!(benches);
@@ -0,0 +1 @@
pub const MAX_COIN_VALUE: u64 = 32;
@@ -2,6 +2,17 @@ use std::convert::TryInto;
use bls12_381::Scalar;
pub use scheme::aggregation::aggregate_verification_keys;
pub use scheme::aggregation::aggregate_wallets;
pub use scheme::keygen::generate_keypair_user;
pub use scheme::keygen::ttp_keygen;
pub use scheme::keygen::VerificationKeyAuth;
pub use scheme::PartialWallet;
pub use scheme::PayInfo;
pub use scheme::setup;
pub use scheme::withdrawal::issue_verify;
pub use scheme::withdrawal::issue_wallet;
pub use scheme::withdrawal::withdrawal_request;
pub use traits::Base58;
use crate::error::CompactEcashError;
@@ -14,6 +25,7 @@ mod scheme;
mod tests;
mod traits;
mod utils;
mod constants;
pub type Attribute = Scalar;
@@ -5,7 +5,7 @@ use bls12_381::{G1Projective, G2Projective, Scalar};
use group::{Curve, Group, GroupEncoding};
use crate::error::{CompactEcashError, Result};
use crate::proofs::{compute_challenge, produce_response, produce_responses, ChallengeDigest};
use crate::proofs::{ChallengeDigest, compute_challenge, produce_response, produce_responses};
use crate::scheme::keygen::{SecretKeyUser, VerificationKeyAuth};
use crate::scheme::setup::{GroupParameters, Parameters};
use crate::utils::{try_deserialize_g1_projective, try_deserialize_g2_projective};
@@ -167,10 +167,10 @@ impl SpendProof {
let zkcm_kappa = grparams.gen2() * r_r
+ verification_key.alpha
+ r_attributes
.iter()
.zip(verification_key.beta_g2.iter())
.map(|(attr, beta_i)| beta_i * attr)
.sum::<G2Projective>();
.iter()
.zip(verification_key.beta_g2.iter())
.map(|(attr, beta_i)| beta_i * attr)
.sum::<G2Projective>();
let zkcm_aa = g1 * r_o_a + gamma1 * r_l;
let zkcm_cc = g1 * r_o_c + gamma1 * r_v;
@@ -257,11 +257,11 @@ impl SpendProof {
+ grparams.gen2() * self.response_r
+ verification_key.alpha * (Scalar::one() - self.challenge)
+ self
.response_attributes
.iter()
.zip(verification_key.beta_g2.iter())
.map(|(attr, beta_i)| beta_i * attr)
.sum::<G2Projective>();
.response_attributes
.iter()
.zip(verification_key.beta_g2.iter())
.map(|(attr, beta_i)| beta_i * attr)
.sum::<G2Projective>();
let zkcm_aa =
g1 * self.response_o_a + gamma1 * self.response_l + instance.aa * self.challenge;
@@ -317,20 +317,21 @@ impl SpendProof {
mod tests {
use bls12_381::{G1Projective, G2Projective, Scalar};
use group::Curve;
use rand::{thread_rng, Rng};
use rand::{Rng, thread_rng};
use crate::constants::MAX_COIN_VALUE;
use crate::proofs::proof_spend::{SpendInstance, SpendProof, SpendWitness};
use crate::scheme::aggregation::aggregate_verification_keys;
use crate::scheme::keygen::{ttp_keygen, PublicKeyUser, VerificationKeyAuth};
use crate::scheme::setup::{setup, GroupParameters};
use crate::scheme::PayInfo;
use crate::scheme::{pseudorandom_fgt, pseudorandom_fgv};
use crate::scheme::aggregation::aggregate_verification_keys;
use crate::scheme::keygen::{PublicKeyUser, ttp_keygen, VerificationKeyAuth};
use crate::scheme::PayInfo;
use crate::scheme::setup::{GroupParameters, setup};
use crate::utils::hash_to_scalar;
#[test]
fn spend_proof_construct_and_verify() {
let rng = thread_rng();
let params = setup();
let params = setup(MAX_COIN_VALUE);
let grparams = params.grp();
let sk = grparams.random_scalar();
let pk_user = PublicKeyUser {
@@ -357,10 +358,10 @@ mod tests {
let kappa = grparams.gen2() * r
+ verification_key.alpha
+ attributes
.iter()
.zip(verification_key.beta_g2.iter())
.map(|(priv_attr, beta_i)| beta_i * priv_attr)
.sum::<G2Projective>();
.iter()
.zip(verification_key.beta_g2.iter())
.map(|(priv_attr, beta_i)| beta_i * priv_attr)
.sum::<G2Projective>();
let o_a = grparams.random_scalar();
let o_c = grparams.random_scalar();
@@ -420,3 +421,4 @@ mod tests {
assert!(zk_proof.verify(&params, &instance, &verification_key, rr))
}
}
@@ -5,14 +5,14 @@ use std::convert::TryInto;
use bls12_381::{G1Projective, G2Prepared, G2Projective, Scalar};
use group::{Curve, Group};
use crate::Attribute;
use crate::error::{CompactEcashError, Result};
use crate::proofs::proof_spend::{SpendInstance, SpendProof, SpendWitness};
use crate::scheme::keygen::{SecretKeyUser, VerificationKeyAuth};
use crate::scheme::setup::{GroupParameters, Parameters};
use crate::utils::{
check_bilinear_pairing, hash_to_scalar, try_deserialize_g1_projective, Signature, SignerIndex,
check_bilinear_pairing, hash_to_scalar, Signature, SignerIndex, try_deserialize_g1_projective,
};
use crate::Attribute;
pub mod aggregation;
pub mod identify;
@@ -73,6 +73,7 @@ impl Wallet {
verification_key: &VerificationKeyAuth,
sk_user: &SecretKeyUser,
pay_info: &PayInfo,
bench_flag: bool,
) -> Result<(Payment, &Self)> {
if self.l() > params.L() {
return Err(CompactEcashError::Spend(
@@ -176,7 +177,9 @@ impl Wallet {
zk_proof,
};
self.up();
if !bench_flag {
self.up();
}
Ok((pay, self))
}
@@ -201,14 +204,14 @@ pub fn compute_kappa(
params.gen2() * blinding_factor
+ verification_key.alpha
+ attributes
.iter()
.zip(verification_key.beta_g2.iter())
.map(|(priv_attr, beta_i)| beta_i * priv_attr)
.sum::<G2Projective>()
.iter()
.zip(verification_key.beta_g2.iter())
.map(|(priv_attr, beta_i)| beta_i * priv_attr)
.sum::<G2Projective>()
}
pub struct PayInfo {
pub(crate) info: [u8; 32],
pub info: [u8; 32],
}
#[derive(Debug, Clone)]
@@ -9,7 +9,6 @@ use crate::error::{CompactEcashError, Result};
use crate::utils::{hash_g1, Signature};
const ATTRIBUTES_LEN: usize = 3;
const MAX_COIN_VALUE: u64 = 32;
pub struct GroupParameters {
/// Generator of the G1 group
@@ -134,14 +133,14 @@ impl Parameters {
}
}
pub fn setup() -> Parameters {
pub fn setup(L: u64) -> Parameters {
let grp = GroupParameters::new().unwrap();
let x = grp.random_scalar();
let y = grp.random_scalar();
let skRP = SecretKeyRP { x, y };
let pkRP = skRP.public_key(&grp);
let mut signs = HashMap::new();
for l in 0..MAX_COIN_VALUE {
for l in 0..L {
let r = grp.random_scalar();
let h = grp.gen1() * r;
signs.insert(
@@ -155,7 +154,7 @@ pub fn setup() -> Parameters {
Parameters {
grp,
pkRP,
L: MAX_COIN_VALUE,
L,
signs,
}
}
@@ -1,22 +1,23 @@
use itertools::izip;
use crate::constants::MAX_COIN_VALUE;
use crate::error::CompactEcashError;
use crate::scheme::{PartialWallet, Payment, pseudorandom_fgt};
use crate::scheme::aggregation::{
aggregate_signature_shares, aggregate_verification_keys, aggregate_wallets,
};
use crate::scheme::identify::identify;
use crate::scheme::keygen::{
generate_keypair_user, ttp_keygen, PublicKeyUser, SecretKeyUser, VerificationKeyAuth,
generate_keypair_user, PublicKeyUser, SecretKeyUser, ttp_keygen, VerificationKeyAuth,
};
use crate::scheme::setup::{setup, GroupParameters, Parameters};
use crate::scheme::withdrawal::{issue_verify, issue_wallet, withdrawal_request};
use crate::scheme::PayInfo;
use crate::scheme::{pseudorandom_fgt, PartialWallet, Payment};
use crate::scheme::setup::{GroupParameters, Parameters, setup};
use crate::scheme::withdrawal::{issue_verify, issue_wallet, withdrawal_request};
use crate::utils::{hash_to_scalar, SignatureShare};
#[test]
fn main() -> Result<(), CompactEcashError> {
let params = setup();
let params = setup(MAX_COIN_VALUE);
let grparams = params.grp();
let user_keypair = generate_keypair_user(&grparams);
@@ -45,8 +46,8 @@ fn main() -> Result<(), CompactEcashError> {
wallet_blinded_signatures.iter(),
verification_keys_auth.iter()
)
.map(|(w, vk)| issue_verify(&grparams, vk, &user_keypair.secret_key(), w, &req_info).unwrap())
.collect();
.map(|(w, vk)| issue_verify(&grparams, vk, &user_keypair.secret_key(), w, &req_info).unwrap())
.collect();
// Aggregate partial wallets
let aggr_wallet = aggregate_wallets(
@@ -60,12 +61,7 @@ fn main() -> Result<(), CompactEcashError> {
// Let's try to spend some coins
let pay_info = PayInfo { info: [6u8; 32] };
let (payment, upd_wallet) = aggr_wallet.spend(
&params,
&verification_key,
&user_keypair.secret_key(),
&pay_info,
)?;
let (payment, upd_wallet) = aggr_wallet.spend(&params, &verification_key, &user_keypair.secret_key(), &pay_info, false)?;
assert!(payment
.spend_verify(&params, &verification_key, &pay_info)
+51 -49
View File
@@ -1,19 +1,21 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use bls12_381::{multi_miller_loop, G1Affine, G1Projective, G2Affine, G2Prepared, Scalar};
use criterion::{criterion_group, criterion_main, Criterion};
use ff::Field;
use group::{Curve, Group};
use nymcoconut::{
aggregate_signature_shares, aggregate_verification_keys, blind_sign, elgamal_keygen,
prepare_blind_sign, prove_bandwidth_credential, setup, ttp_keygen, verify_credential,
Attribute, BlindedSignature, Parameters, Signature, SignatureShare, VerificationKey,
};
use rand::seq::SliceRandom;
use std::ops::Neg;
use std::time::Duration;
use bls12_381::{G1Affine, G1Projective, G2Affine, G2Prepared, multi_miller_loop, Scalar};
use criterion::{Criterion, criterion_group, criterion_main};
use ff::Field;
use group::{Curve, Group};
use rand::seq::SliceRandom;
use nymcoconut::{
aggregate_signature_shares, aggregate_verification_keys, Attribute, blind_sign,
BlindedSignature, elgamal_keygen, Parameters, prepare_blind_sign, prove_bandwidth_credential,
setup, Signature, SignatureShare, ttp_keygen, VerificationKey, verify_credential,
};
#[allow(unused)]
fn double_pairing(g11: &G1Affine, g21: &G2Affine, g12: &G1Affine, g22: &G2Affine) {
let gt1 = bls12_381::pairing(g11, g21);
@@ -32,6 +34,40 @@ fn multi_miller_pairing_affine(g11: &G1Affine, g21: &G2Affine, g12: &G1Affine, g
))
}
#[allow(unused)]
fn bench_pairings(c: &mut Criterion) {
let mut rng = rand::thread_rng();
let g1 = G1Affine::generator();
let g2 = G2Affine::generator();
let r = Scalar::random(&mut rng);
let s = Scalar::random(&mut rng);
let g11 = (g1 * r).to_affine();
let g21 = (g2 * s).to_affine();
let g21_prep = G2Prepared::from(g21);
let g12 = (g1 * s).to_affine();
let g22 = (g2 * r).to_affine();
let g22_prep = G2Prepared::from(g22);
c.bench_function("double pairing", |b| {
b.iter(|| double_pairing(&g11, &g21, &g12, &g22))
});
c.bench_function("multi miller in affine", |b| {
b.iter(|| multi_miller_pairing_affine(&g11, &g21, &g12, &g22))
});
c.bench_function("multi miller with prepared g2", |b| {
b.iter(|| multi_miller_pairing_with_prepared(&g11, &g21_prep, &g12, &g22_prep))
});
c.bench_function("multi miller with semi-prepared g2", |b| {
b.iter(|| multi_miller_pairing_with_semi_prepared(&g11, &g21, &g12, &g22_prep))
});
}
#[allow(unused)]
fn multi_miller_pairing_with_prepared(
g11: &G1Affine,
@@ -104,7 +140,7 @@ fn unblind_and_aggregate(
&attributes,
&unblinded_signature_shares,
)
.unwrap()
.unwrap()
}
struct BenchCase {
@@ -124,40 +160,6 @@ impl BenchCase {
}
}
#[allow(unused)]
fn bench_pairings(c: &mut Criterion) {
let mut rng = rand::thread_rng();
let g1 = G1Affine::generator();
let g2 = G2Affine::generator();
let r = Scalar::random(&mut rng);
let s = Scalar::random(&mut rng);
let g11 = (g1 * r).to_affine();
let g21 = (g2 * s).to_affine();
let g21_prep = G2Prepared::from(g21);
let g12 = (g1 * s).to_affine();
let g22 = (g2 * r).to_affine();
let g22_prep = G2Prepared::from(g22);
c.bench_function("double pairing", |b| {
b.iter(|| double_pairing(&g11, &g21, &g12, &g22))
});
c.bench_function("multi miller in affine", |b| {
b.iter(|| multi_miller_pairing_affine(&g11, &g21, &g12, &g22))
});
c.bench_function("multi miller with prepared g2", |b| {
b.iter(|| multi_miller_pairing_with_prepared(&g11, &g21_prep, &g12, &g22_prep))
});
c.bench_function("multi miller with semi-prepared g2", |b| {
b.iter(|| multi_miller_pairing_with_semi_prepared(&g11, &g21, &g12, &g22_prep))
});
}
fn bench_coconut(c: &mut Criterion) {
let mut group = c.benchmark_group("benchmark-coconut");
group.measurement_time(Duration::from_secs(100));
@@ -218,7 +220,7 @@ fn bench_coconut(c: &mut Criterion) {
&blind_sign_request,
&public_attributes,
)
.unwrap()
.unwrap()
})
},
);
@@ -233,7 +235,7 @@ fn bench_coconut(c: &mut Criterion) {
&blind_sign_request,
&public_attributes,
)
.unwrap();
.unwrap();
blinded_signatures.push(blinded_signature)
}
@@ -291,7 +293,7 @@ fn bench_coconut(c: &mut Criterion) {
serial_number,
binding_number,
)
.unwrap();
.unwrap();
// CLIENT BENCHMARK
group.bench_function(
@@ -310,7 +312,7 @@ fn bench_coconut(c: &mut Criterion) {
serial_number,
binding_number,
)
.unwrap()
.unwrap()
})
},
);