Run cargo fmt

This commit is contained in:
aniampio
2021-10-20 17:05:00 +01:00
parent 9110a8eefd
commit 0eaad032f6
18 changed files with 434 additions and 234 deletions
+10 -8
View File
@@ -22,8 +22,10 @@ use client_core::client::topology_control::{
TopologyAccessor, TopologyRefresher, TopologyRefresherConfig,
};
use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder;
use coconut_interface::{Credential, hash_to_scalar, Parameters};
use credentials::bandwidth::{prepare_for_spending, BandwidthVoucherAttributes, BANDWIDTH_VALUE, TOTAL_ATTRIBUTES};
use coconut_interface::{hash_to_scalar, Credential, Parameters};
use credentials::bandwidth::{
prepare_for_spending, BandwidthVoucherAttributes, BANDWIDTH_VALUE, TOTAL_ATTRIBUTES,
};
use credentials::obtain_aggregate_verification_key;
use crypto::asymmetric::identity;
use futures::channel::mpsc;
@@ -174,15 +176,15 @@ impl NymClient {
.expect("could not obtain aggregate verification key of validators");
let params = Parameters::new(TOTAL_ATTRIBUTES).unwrap();
let bandwidth_credential_attributes = BandwidthVoucherAttributes{
serial_number : params.random_scalar(),
binding_number : params.random_scalar(),
voucher_value : hash_to_scalar(BANDWIDTH_VALUE.to_be_bytes()),
voucher_info : hash_to_scalar(String::from("BandwidthVoucher").as_bytes()),
let bandwidth_credential_attributes = BandwidthVoucherAttributes {
serial_number: params.random_scalar(),
binding_number: params.random_scalar(),
voucher_value: hash_to_scalar(BANDWIDTH_VALUE.to_be_bytes()),
voucher_info: hash_to_scalar(String::from("BandwidthVoucher").as_bytes()),
};
let bandwidth_credential = credentials::bandwidth::obtain_signature(
&params,
&params,
&bandwidth_credential_attributes,
&self.config.get_base().get_validator_api_endpoints(),
&verification_key,
+24 -12
View File
@@ -6,9 +6,11 @@ use crate::commands::override_config;
use clap::{App, Arg, ArgMatches};
use client_core::client::key_manager::KeyManager;
use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder;
use coconut_interface::{Credential, hash_to_scalar, Parameters};
use coconut_interface::{hash_to_scalar, Credential, Parameters};
use config::NymConfig;
use credentials::bandwidth::{prepare_for_spending, BandwidthVoucherAttributes, BANDWIDTH_VALUE, TOTAL_ATTRIBUTES};
use credentials::bandwidth::{
prepare_for_spending, BandwidthVoucherAttributes, BANDWIDTH_VALUE, TOTAL_ATTRIBUTES,
};
use credentials::obtain_aggregate_verification_key;
use crypto::asymmetric::{encryption, identity};
use gateway_client::GatewayClient;
@@ -68,19 +70,29 @@ async fn prepare_temporary_credential(validators: &[Url], raw_identity: &[u8]) -
.expect("could not obtain aggregate verification key of validators");
let params = Parameters::new(TOTAL_ATTRIBUTES).unwrap();
let bandwidth_credential_attributes = BandwidthVoucherAttributes{
serial_number : params.random_scalar(),
binding_number : params.random_scalar(),
voucher_value : hash_to_scalar(BANDWIDTH_VALUE.to_be_bytes()),
voucher_info : hash_to_scalar(String::from("BandwidthVoucher").as_bytes()),
let bandwidth_credential_attributes = BandwidthVoucherAttributes {
serial_number: params.random_scalar(),
binding_number: params.random_scalar(),
voucher_value: hash_to_scalar(BANDWIDTH_VALUE.to_be_bytes()),
voucher_info: hash_to_scalar(String::from("BandwidthVoucher").as_bytes()),
};
let bandwidth_credential = credentials::bandwidth::obtain_signature(&params, &bandwidth_credential_attributes, validators, &verification_key)
.await
.expect("could not obtain bandwidth credential");
let bandwidth_credential = credentials::bandwidth::obtain_signature(
&params,
&bandwidth_credential_attributes,
validators,
&verification_key,
)
.await
.expect("could not obtain bandwidth credential");
prepare_for_spending(raw_identity, &bandwidth_credential, &bandwidth_credential_attributes, &verification_key)
.expect("could not prepare out bandwidth credential for spending")
prepare_for_spending(
raw_identity,
&bandwidth_credential,
&bandwidth_credential_attributes,
&verification_key,
)
.expect("could not prepare out bandwidth credential for spending")
}
async fn register_with_gateway(
+9 -7
View File
@@ -23,8 +23,10 @@ use client_core::client::topology_control::{
TopologyAccessor, TopologyRefresher, TopologyRefresherConfig,
};
use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder;
use coconut_interface::{Credential, hash_to_scalar, Parameters};
use credentials::bandwidth::{prepare_for_spending, BandwidthVoucherAttributes, BANDWIDTH_VALUE, TOTAL_ATTRIBUTES};
use coconut_interface::{hash_to_scalar, Credential, Parameters};
use credentials::bandwidth::{
prepare_for_spending, BandwidthVoucherAttributes, BANDWIDTH_VALUE, TOTAL_ATTRIBUTES,
};
use credentials::obtain_aggregate_verification_key;
use crypto::asymmetric::identity;
use futures::channel::mpsc;
@@ -162,11 +164,11 @@ impl NymClient {
.expect("could not obtain aggregate verification key of validators");
let params = Parameters::new(TOTAL_ATTRIBUTES).unwrap();
let bandwidth_credential_attributes = BandwidthVoucherAttributes{
serial_number : params.random_scalar(),
binding_number : params.random_scalar(),
voucher_value : hash_to_scalar(BANDWIDTH_VALUE.to_be_bytes()),
voucher_info : hash_to_scalar(String::from("BandwidthVoucher").as_bytes()),
let bandwidth_credential_attributes = BandwidthVoucherAttributes {
serial_number: params.random_scalar(),
binding_number: params.random_scalar(),
voucher_value: hash_to_scalar(BANDWIDTH_VALUE.to_be_bytes()),
voucher_info: hash_to_scalar(String::from("BandwidthVoucher").as_bytes()),
};
let bandwidth_credential = credentials::bandwidth::obtain_signature(
+24 -12
View File
@@ -6,9 +6,11 @@ use crate::commands::override_config;
use clap::{App, Arg, ArgMatches};
use client_core::client::key_manager::KeyManager;
use client_core::config::persistence::key_pathfinder::ClientKeyPathfinder;
use coconut_interface::{Credential, hash_to_scalar, Parameters};
use coconut_interface::{hash_to_scalar, Credential, Parameters};
use config::NymConfig;
use credentials::bandwidth::{prepare_for_spending, BandwidthVoucherAttributes, BANDWIDTH_VALUE, TOTAL_ATTRIBUTES};
use credentials::bandwidth::{
prepare_for_spending, BandwidthVoucherAttributes, BANDWIDTH_VALUE, TOTAL_ATTRIBUTES,
};
use credentials::obtain_aggregate_verification_key;
use crypto::asymmetric::{encryption, identity};
use gateway_client::GatewayClient;
@@ -68,19 +70,29 @@ async fn prepare_temporary_credential(validators: &[Url], raw_identity: &[u8]) -
.expect("could not obtain aggregate verification key of validators");
let params = Parameters::new(TOTAL_ATTRIBUTES).unwrap();
let bandwidth_credential_attributes = BandwidthVoucherAttributes{
serial_number : params.random_scalar(),
binding_number : params.random_scalar(),
voucher_value : hash_to_scalar(BANDWIDTH_VALUE.to_be_bytes()),
voucher_info : hash_to_scalar(String::from("BandwidthVoucher").as_bytes()),
let bandwidth_credential_attributes = BandwidthVoucherAttributes {
serial_number: params.random_scalar(),
binding_number: params.random_scalar(),
voucher_value: hash_to_scalar(BANDWIDTH_VALUE.to_be_bytes()),
voucher_info: hash_to_scalar(String::from("BandwidthVoucher").as_bytes()),
};
let bandwidth_credential = credentials::bandwidth::obtain_signature(&params, &bandwidth_credential_attributes, validators, &verification_key)
.await
.expect("could not obtain bandwidth credential");
let bandwidth_credential = credentials::bandwidth::obtain_signature(
&params,
&bandwidth_credential_attributes,
validators,
&verification_key,
)
.await
.expect("could not obtain bandwidth credential");
prepare_for_spending(raw_identity, &bandwidth_credential, &bandwidth_credential_attributes, &verification_key)
.expect("could not prepare out bandwidth credential for spending")
prepare_for_spending(
raw_identity,
&bandwidth_credential,
&bandwidth_credential_attributes,
&verification_key,
)
.expect("could not prepare out bandwidth credential for spending")
}
async fn register_with_gateway(
+22 -10
View File
@@ -10,7 +10,10 @@ use url::Url;
use crate::error::Error;
use crate::utils::{obtain_aggregate_signature, prepare_credential_for_spending, ValidatorInfo};
use coconut_interface::{hash_to_scalar, Credential, Parameters, Signature, VerificationKey, Attribute, PrivateAttribute, PublicAttribute};
use coconut_interface::{
hash_to_scalar, Attribute, Credential, Parameters, PrivateAttribute, PublicAttribute,
Signature, VerificationKey,
};
pub const BANDWIDTH_VALUE: u64 = 10 * 1024 * 1024 * 1024; // 10 GB
@@ -22,16 +25,14 @@ pub const SERIAL_NUMBER_LEN: usize = 47;
pub const BINDING_NUMBER_LEN: usize = 47;
pub const VOUCHER_INFO_LEN: usize = 47;
pub struct BandwidthVoucherAttributes {
pub serial_number : PrivateAttribute,
pub binding_number : PrivateAttribute,
pub voucher_value : PublicAttribute,
pub voucher_info : PublicAttribute,
pub serial_number: PrivateAttribute,
pub binding_number: PrivateAttribute,
pub voucher_value: PublicAttribute,
pub voucher_info: PublicAttribute,
}
impl BandwidthVoucherAttributes {
pub fn get_public_attributes(&self) -> Vec<PublicAttribute> {
let mut pub_attributes = Vec::with_capacity(PUBLIC_ATTRIBUTES as usize);
pub_attributes.push(self.voucher_value);
@@ -48,12 +49,23 @@ impl BandwidthVoucherAttributes {
}
// TODO: this definitely has to be moved somewhere else. It's just a temporary solution
pub async fn obtain_signature(params: &Parameters, attributes: &BandwidthVoucherAttributes, validators: &[Url], verification_key: &VerificationKey) -> Result<Signature, Error> {
pub async fn obtain_signature(
params: &Parameters,
attributes: &BandwidthVoucherAttributes,
validators: &[Url],
verification_key: &VerificationKey,
) -> Result<Signature, Error> {
let public_attributes = attributes.get_public_attributes();
let private_attributes = attributes.get_private_attributes();
obtain_aggregate_signature(&params, &public_attributes, &private_attributes, validators, verification_key).await
obtain_aggregate_signature(
&params,
&public_attributes,
&private_attributes,
validators,
verification_key,
)
.await
}
pub fn prepare_for_spending(
+43 -13
View File
@@ -7,8 +7,8 @@ use coconut_interface::{
prove_credential, Attribute, BlindSignRequestBody, Credential, Parameters, Signature,
SignatureShare, VerificationKey,
};
use url::Url;
use std::borrow::Borrow;
use url::Url;
/// Contacts all provided validators and then aggregate their verification keys.
///
@@ -64,7 +64,7 @@ async fn obtain_partial_credential(
public_attributes: &[Attribute],
private_attributes: &[Attribute],
client: &validator_client::ApiClient,
validator_vk : &VerificationKey,
validator_vk: &VerificationKey,
) -> Result<Signature, Error> {
let elgamal_keypair = coconut_interface::elgamal_keygen(params);
let blind_sign_request = prepare_blind_sign(
@@ -85,12 +85,21 @@ async fn obtain_partial_credential(
.blind_sign(&blind_sign_request_body)
.await?
.blinded_signature;
Ok(blinded_signature.unblind(&params, elgamal_keypair.private_key(), validator_vk , &private_attributes, &public_attributes, &blind_sign_request.commitment_hash).unwrap())
Ok(blinded_signature
.unblind(
&params,
elgamal_keypair.private_key(),
validator_vk,
&private_attributes,
&public_attributes,
&blind_sign_request.commitment_hash,
)
.unwrap())
}
pub struct ValidatorInfo {
url : Url,
verification_key : VerificationKey,
url: Url,
verification_key: VerificationKey,
}
pub async fn obtain_aggregate_signature(
@@ -109,16 +118,27 @@ pub async fn obtain_aggregate_signature(
let mut client = validator_client::ApiClient::new(validators[0].clone());
let validator_partial_vk = client.get_coconut_verification_key().await?;
let first =
obtain_partial_credential(params, public_attributes, private_attributes, &client, &validator_partial_vk.key).await?;
let first = obtain_partial_credential(
params,
public_attributes,
private_attributes,
&client,
&validator_partial_vk.key,
)
.await?;
shares.push(SignatureShare::new(first, 0));
for (id, validator_url) in validators.iter().enumerate().skip(1) {
client.change_validator_api(validator_url.clone());
let validator_partial_vk = client.get_coconut_verification_key().await?;
let signature =
obtain_partial_credential(params, public_attributes, private_attributes, &client, &validator_partial_vk.key)
.await?;
let signature = obtain_partial_credential(
params,
public_attributes,
private_attributes,
&client,
&validator_partial_vk.key,
)
.await?;
let share = SignatureShare::new(signature, id as u64);
shares.push(share)
}
@@ -127,7 +147,12 @@ pub async fn obtain_aggregate_signature(
attributes.extend_from_slice(&private_attributes);
attributes.extend_from_slice(&public_attributes);
Ok(aggregate_signature_shares(&params, verification_key, &attributes, &shares)?)
Ok(aggregate_signature_shares(
&params,
verification_key,
&attributes,
&shares,
)?)
}
// TODO: better type flow
@@ -139,8 +164,13 @@ pub fn prepare_credential_for_spending(
signature: &Signature,
verification_key: &VerificationKey,
) -> Result<Credential, Error> {
let theta = prove_credential(params, verification_key, signature, serial_number, binding_number)?;
let theta = prove_credential(
params,
verification_key,
signature,
serial_number,
binding_number,
)?;
Ok(Credential::new(
(public_attributes.len() + 2) as u32,
+3 -3
View File
@@ -112,7 +112,7 @@ impl PrivateKey {
.to_string(),
),
)
.map(PrivateKey)
.map(PrivateKey)
}
}
@@ -183,7 +183,7 @@ impl TryFrom<&[u8]> for PublicKey {
"Failed to deserialize compressed ElGamal public key".to_string(),
),
)
.map(PublicKey)
.map(PublicKey)
}
}
@@ -326,7 +326,7 @@ mod tests {
ciphertext.0.to_affine().to_compressed(),
ciphertext.1.to_affine().to_compressed(),
]
.concat();
.concat();
assert_eq!(expected_bytes, bytes);
assert_eq!(ciphertext, Ciphertext::try_from(&bytes[..]).unwrap())
}
+3 -3
View File
@@ -38,9 +38,9 @@ pub enum CoconutError {
#[error("Deserialization error: {0}")]
Deserialization(String),
#[error(
"Deserailization error, expected at least {} bytes, got {}",
min,
actual
"Deserailization error, expected at least {} bytes, got {}",
min,
actual
)]
DeserializationMinLength { min: usize, actual: usize },
#[error("Tried to deserialize {object} with bytes of invalid length. Expected {actual} < {} or {modulus_target} % {modulus} == 0")]
-1
View File
@@ -53,7 +53,6 @@ pub type Attribute = Scalar;
pub type PrivateAttribute = Attribute;
pub type PublicAttribute = Attribute;
impl Bytable for Attribute {
fn to_byte_vec(&self) -> Vec<u8> {
self.to_bytes().to_vec()
+37 -39
View File
@@ -18,18 +18,18 @@ use std::borrow::Borrow;
use std::convert::TryInto;
use bls12_381::{G1Projective, G2Projective, Scalar};
use digest::Digest;
use digest::generic_array::typenum::Unsigned;
use digest::Digest;
use group::GroupEncoding;
use itertools::izip;
use sha2::Sha256;
use crate::{Attribute, elgamal, ElGamalKeyPair, PublicKey};
use crate::elgamal::Ciphertext;
use crate::error::{CoconutError, Result};
use crate::scheme::{Signature, VerificationKey};
use crate::scheme::setup::Parameters;
use crate::scheme::{Signature, VerificationKey};
use crate::utils::{hash_g1, try_deserialize_scalar, try_deserialize_scalar_vec};
use crate::{elgamal, Attribute, ElGamalKeyPair, PublicKey};
// as per the reference python implementation
type ChallengeDigest = Sha256;
@@ -51,10 +51,10 @@ pub struct ProofCmCs {
// and as per the bls12-381 library all elements are using big-endian form
/// Generates a Scalar [or Fp] challenge by hashing a number of elliptic curve points.
fn compute_challenge<D, I, B>(iter: I) -> Scalar
where
D: Digest,
I: Iterator<Item=B>,
B: AsRef<[u8]>,
where
D: Digest,
I: Iterator<Item = B>,
B: AsRef<[u8]>,
{
let mut h = D::new();
for point_representation in iter {
@@ -76,15 +76,14 @@ fn compute_challenge<D, I, B>(iter: I) -> Scalar
Scalar::from_bytes_wide(&bytes)
}
fn produce_response(witness: &Scalar, challenge: &Scalar, secret: &Scalar) -> Scalar
{
fn produce_response(witness: &Scalar, challenge: &Scalar, secret: &Scalar) -> Scalar {
witness - challenge * secret
}
// note: it's caller's responsibility to ensure witnesses.len() = secrets.len()
fn produce_responses<S>(witnesses: &[Scalar], challenge: &Scalar, secrets: &[S]) -> Vec<Scalar>
where
S: Borrow<Scalar>,
where
S: Borrow<Scalar>,
{
debug_assert_eq!(witnesses.len(), secrets.len());
@@ -151,10 +150,10 @@ impl ProofCmCs {
// Ccm = (wr * g1) + (wm[0] * hs[0]) + ... + (wm[i] * hs[i])
let commitment_attributes = g1 * witness_commitment_opening
+ witness_attributes
.iter()
.zip(params.gen_hs().iter())
.map(|(wm_i, hs_i)| hs_i * wm_i)
.sum::<G1Projective>();
.iter()
.zip(params.gen_hs().iter())
.map(|(wm_i, hs_i)| hs_i * wm_i)
.sum::<G1Projective>();
let ciphertexts_bytes = priv_attributes_ciphertexts
.iter()
@@ -245,19 +244,19 @@ impl ProofCmCs {
self.response_keys.iter(),
self.response_attributes.iter()
)
.map(|(c2, res_key, res_attr)| c2 * self.challenge + pub_key * res_key + h * res_attr)
.map(|witness| witness.to_bytes())
.collect::<Vec<_>>();
.map(|(c2, res_key, res_attr)| c2 * self.challenge + pub_key * res_key + h * res_attr)
.map(|witness| witness.to_bytes())
.collect::<Vec<_>>();
// Cw = (cm * c) + (rr * g1) + (rm[0] * hs[0]) + ... + (rm[n] * hs[n])
let commitment_attributes = commitment * self.challenge
+ g1 * self.response_opening
+ self
.response_attributes
.iter()
.zip(params.gen_hs().iter())
.map(|(res_attr, hs)| hs * res_attr)
.sum::<G1Projective>();
.response_attributes
.iter()
.zip(params.gen_hs().iter())
.map(|(res_attr, hs)| hs * res_attr)
.sum::<G1Projective>();
let ciphertexts_bytes = attributes_ciphertexts
.iter()
@@ -414,10 +413,10 @@ impl ProofKappaNu {
let commitment_kappa = params.gen2() * witness_blinder
+ verification_key.alpha
+ witness_attributes
.iter()
.zip(verification_key.beta.iter())
.map(|(wm_i, beta_i)| beta_i * wm_i)
.sum::<G2Projective>();
.iter()
.zip(verification_key.beta.iter())
.map(|(wm_i, beta_i)| beta_i * wm_i)
.sum::<G2Projective>();
// zeta is the public value associated with the serial number
let commitment_zeta = params.gen2() * witness_serial_number;
@@ -433,8 +432,10 @@ impl ProofKappaNu {
// responses
let response_blinder = produce_response(&witness_blinder, &challenge, &blinding_factor);
let response_serial_number = produce_response(&witness_serial_number, &challenge, &serial_number);
let response_binding_number = produce_response(&witness_binding_number, &challenge, &binding_number);
let response_serial_number =
produce_response(&witness_serial_number, &challenge, &serial_number);
let response_binding_number =
produce_response(&witness_binding_number, &challenge, &binding_number);
ProofKappaNu {
challenge,
@@ -468,15 +469,13 @@ impl ProofKappaNu {
+ params.gen2() * self.response_blinder
+ verification_key.alpha * (Scalar::one() - self.challenge)
+ response_attributes
.iter()
.zip(verification_key.beta.iter())
.map(|(priv_attr, beta_i)| beta_i * priv_attr)
.sum::<G2Projective>();
.iter()
.zip(verification_key.beta.iter())
.map(|(priv_attr, beta_i)| beta_i * priv_attr)
.sum::<G2Projective>();
// zeta is the public value associated with the serial number
let commitment_zeta = zeta * self.challenge
+ params.gen2() * self.response_serial_number;
let commitment_zeta = zeta * self.challenge + params.gen2() * self.response_serial_number;
// compute the challenge
let challenge = compute_challenge::<ChallengeDigest, _, _>(
@@ -501,7 +500,6 @@ impl ProofKappaNu {
bytes.extend_from_slice(&self.response_serial_number.to_bytes());
bytes.extend_from_slice(&self.response_binding_number.to_bytes());
// bytes.extend_from_slice(&attributes_len.to_le_bytes());
// for rm in &self.response_attributes {
// bytes.extend_from_slice(&rm.to_bytes());
@@ -669,7 +667,7 @@ mod tests {
&binding_number,
&r,
&kappa,
&zeta
&zeta,
);
let bytes = pi_v.to_bytes();
@@ -689,7 +687,7 @@ mod tests {
&binding_number,
&r,
&kappa,
&zeta
&zeta,
);
let bytes = pi_v.to_bytes();
+95 -25
View File
@@ -19,11 +19,11 @@ use bls12_381::{G2Prepared, G2Projective, Scalar};
use group::Curve;
use itertools::Itertools;
use crate::{Attribute, Parameters};
use crate::error::{CoconutError, Result};
use crate::scheme::{PartialSignature, Signature, SignatureShare, SignerIndex, VerificationKey};
use crate::scheme::verification::check_bilinear_pairing;
use crate::scheme::{PartialSignature, Signature, SignatureShare, SignerIndex, VerificationKey};
use crate::utils::perform_lagrangian_interpolation_at_origin;
use crate::{Attribute, Parameters};
pub(crate) trait Aggregatable: Sized {
fn aggregate(aggregatable: &[Self], indices: Option<&[SignerIndex]>) -> Result<Self>;
@@ -36,10 +36,10 @@ pub(crate) trait Aggregatable: Sized {
// includes `VerificationKey`
impl<T> Aggregatable for T
where
T: Sum,
for<'a> T: Sum<&'a T>,
for<'a> &'a T: Mul<Scalar, Output=T>,
where
T: Sum,
for<'a> T: Sum<&'a T>,
for<'a> &'a T: Mul<Scalar, Output = T>,
{
fn aggregate(aggregatable: &[T], indices: Option<&[u64]>) -> Result<T> {
if aggregatable.is_empty() {
@@ -101,17 +101,15 @@ pub fn aggregate_signatures(
let signature = match Aggregatable::aggregate(signatures, indices) {
Ok(res) => res,
Err(err) => return Err(err)
Err(err) => return Err(err),
};
// Verify the signature
let alpha = verification_key.alpha;
let tmp = attributes.iter()
.zip(
verification_key
.beta
.iter())
let tmp = attributes
.iter()
.zip(verification_key.beta.iter())
.map(|(attr, beta_i)| beta_i * attr)
.sum::<G2Projective>();
@@ -128,13 +126,24 @@ pub fn aggregate_signatures(
Ok(signature)
}
pub fn aggregate_signature_shares(params: &Parameters, verification_key: &VerificationKey, attributes: &[Attribute], shares: &[SignatureShare]) -> Result<Signature> {
pub fn aggregate_signature_shares(
params: &Parameters,
verification_key: &VerificationKey,
attributes: &[Attribute],
shares: &[SignatureShare],
) -> Result<Signature> {
let (signatures, indices): (Vec<_>, Vec<_>) = shares
.iter()
.map(|share| (*share.signature(), share.index()))
.unzip();
aggregate_signatures(&params, &verification_key, &attributes, &signatures, Some(&indices))
aggregate_signatures(
&params,
&verification_key,
&attributes,
&signatures,
Some(&indices),
)
}
#[cfg(test)]
@@ -229,10 +238,24 @@ mod tests {
// aggregating (any) threshold works
let aggr_vk_1 = aggregate_verification_keys(&vks[..3], Some(&[1, 2, 3])).unwrap();
let aggr_sig1 = aggregate_signatures(&params, &aggr_vk_1, &attributes, &sigs[..3], Some(&[1, 2, 3])).unwrap();
let aggr_sig1 = aggregate_signatures(
&params,
&aggr_vk_1,
&attributes,
&sigs[..3],
Some(&[1, 2, 3]),
)
.unwrap();
let aggr_vk_2 = aggregate_verification_keys(&vks[2..], Some(&[3, 4, 5])).unwrap();
let aggr_sig2 = aggregate_signatures(&params, &aggr_vk_1, &attributes, &sigs[2..], Some(&[3, 4, 5])).unwrap();
let aggr_sig2 = aggregate_signatures(
&params,
&aggr_vk_1,
&attributes,
&sigs[2..],
Some(&[3, 4, 5]),
)
.unwrap();
assert_eq!(aggr_sig1, aggr_sig2);
// verify credential for good measure
@@ -240,22 +263,50 @@ mod tests {
// aggregating threshold+1 works
let aggr_vk_more = aggregate_verification_keys(&vks[1..], Some(&[2, 3, 4, 5])).unwrap();
let aggr_more = aggregate_signatures(&params, &aggr_vk_more, &attributes, &sigs[1..], Some(&[2, 3, 4, 5])).unwrap();
let aggr_more = aggregate_signatures(
&params,
&aggr_vk_more,
&attributes,
&sigs[1..],
Some(&[2, 3, 4, 5]),
)
.unwrap();
assert_eq!(aggr_sig1, aggr_more);
// aggregating all
let aggr_vk_all = aggregate_verification_keys(&vks, Some(&[1, 2, 3, 4, 5])).unwrap();
let aggr_all = aggregate_signatures(&params, &aggr_vk_all, &attributes, &sigs, Some(&[1, 2, 3, 4, 5])).unwrap();
let aggr_all = aggregate_signatures(
&params,
&aggr_vk_all,
&attributes,
&sigs,
Some(&[1, 2, 3, 4, 5]),
)
.unwrap();
assert_eq!(aggr_all, aggr_sig1);
// not taking enough points (threshold was 3) should fail
let aggr_vk_not_enough = aggregate_verification_keys(&vks[..2], Some(&[1, 2, ])).unwrap();
let aggr_not_enough = aggregate_signatures(&params, &aggr_vk_not_enough, &attributes, &sigs[..2], Some(&[1, 2])).unwrap();
let aggr_vk_not_enough = aggregate_verification_keys(&vks[..2], Some(&[1, 2])).unwrap();
let aggr_not_enough = aggregate_signatures(
&params,
&aggr_vk_not_enough,
&attributes,
&sigs[..2],
Some(&[1, 2]),
)
.unwrap();
assert_ne!(aggr_not_enough, aggr_sig1);
// taking wrong index should fail
let aggr_vk_bad = aggregate_verification_keys(&vks[2..], Some(&[1, 2, 3])).unwrap();
assert!(aggregate_signatures(&params, &aggr_vk_bad, &attributes, &sigs[2..], Some(&[42, 123, 100])).is_err());
assert!(aggregate_signatures(
&params,
&aggr_vk_bad,
&attributes,
&sigs[2..],
Some(&[42, 123, 100])
)
.is_err());
}
fn random_signature() -> Signature {
@@ -279,7 +330,9 @@ mod tests {
.unzip();
let aggr_vk_all = aggregate_verification_keys(&vks, None).unwrap();
assert!(aggregate_signatures(&params, &aggr_vk_all, &attributes, &signatures, None).is_err());
assert!(
aggregate_signatures(&params, &aggr_vk_all, &attributes, &signatures, None).is_err()
);
}
#[test]
@@ -294,8 +347,18 @@ mod tests {
.unzip();
let aggr_vk_all = aggregate_verification_keys(&vks, None).unwrap();
assert!(aggregate_signatures(&params, &aggr_vk_all, &attributes, &signatures, Some(&[])).is_err());
assert!(aggregate_signatures(&params, &aggr_vk_all, &attributes, &signatures, Some(&[1, 2])).is_err());
assert!(
aggregate_signatures(&params, &aggr_vk_all, &attributes, &signatures, Some(&[]))
.is_err()
);
assert!(aggregate_signatures(
&params,
&aggr_vk_all,
&attributes,
&signatures,
Some(&[1, 2])
)
.is_err());
}
#[test]
@@ -310,7 +373,14 @@ mod tests {
.unzip();
let aggr_vk_all = aggregate_verification_keys(&vks, None).unwrap();
assert!(aggregate_signatures(&params, &aggr_vk_all, &attributes, &signatures, Some(&[1, 1])).is_err());
assert!(aggregate_signatures(
&params,
&aggr_vk_all,
&attributes,
&signatures,
Some(&[1, 1])
)
.is_err());
}
// TODO: test for aggregating non-threshold keys
+21 -13
View File
@@ -18,21 +18,21 @@ use std::convert::TryInto;
use bls12_381::{G1Affine, G1Projective, Scalar};
use group::{Curve, GroupEncoding};
use crate::{Attribute, elgamal, ElGamalKeyPair, VerificationKey};
use crate::elgamal::{Ciphertext, EphemeralKey};
use crate::error::{CoconutError, Result};
use crate::proofs::ProofCmCs;
use crate::scheme::setup::Parameters;
use crate::scheme::BlindedSignature;
use crate::scheme::SecretKey;
use crate::scheme::setup::Parameters;
use crate::{elgamal, Attribute, ElGamalKeyPair, VerificationKey};
// TODO: possibly completely remove those two functions.
// They only exist to have a simpler and smaller code snippets to test
// basic functionalities.
use crate::traits::{Base58, Bytable};
use crate::utils::{hash_g1, try_deserialize_g1_projective};
/// Creates a Coconut Signature under a given secret key on a set of public attributes only.
#[cfg(test)]
use crate::Signature;
use crate::traits::{Base58, Bytable};
use crate::utils::{hash_g1, try_deserialize_g1_projective};
// TODO NAMING: double check this one
// Lambda
@@ -160,7 +160,6 @@ impl BlindSignRequest {
}
}
pub fn compute_private_attributes_commitment(
params: &Parameters,
private_attributes: &[Attribute],
@@ -171,7 +170,10 @@ pub fn compute_private_attributes_commitment(
// Produces h0 ^ m0 * h1^m1 * .... * hn^mn
// where m0, m1, ...., mn are private attributes
let attr_cm = private_attributes
.iter().zip(hs).map(|(&m, h)| h * m).sum::<G1Projective>();
.iter()
.zip(hs)
.map(|(&m, h)| h * m)
.sum::<G1Projective>();
// Produces g1^r * h0 ^ m0 * h1^m1 * .... * hn^mn
let commitment = params.gen1() * commitment_opening + attr_cm;
@@ -222,7 +224,13 @@ pub fn prepare_blind_sign(
// Compute the challenge as the commitment hash
let commitment_hash = compute_commitment_hash(commitment);
// build ElGamal encryption
let (private_attributes_ciphertexts, ephemeral_keys): (Vec<_>, Vec<_>) = compute_attribute_encryption(params, private_attributes, elgamal_keypair.public_key(), commitment_hash);
let (private_attributes_ciphertexts, ephemeral_keys): (Vec<_>, Vec<_>) =
compute_attribute_encryption(
params,
private_attributes,
elgamal_keypair.public_key(),
commitment_hash,
);
let pi_s = ProofCmCs::construct(
params,
@@ -330,10 +338,10 @@ pub fn sign(
// x + m0 * y0 + m1 * y1 + ... mn * yn
let exponent = secret_key.x
+ public_attributes
.iter()
.zip(secret_key.ys.iter())
.map(|(m_i, y_i)| m_i * y_i)
.sum::<Scalar>();
.iter()
.zip(secret_key.ys.iter())
.map(|(m_i, y_i)| m_i * y_i)
.sum::<Scalar>();
let sig2 = h * exponent;
Ok(Signature(h, sig2))
@@ -356,7 +364,7 @@ mod tests {
&private_attributes,
&public_attributes,
)
.unwrap();
.unwrap();
let bytes = lambda.to_bytes();
println!("{:?}", bytes.len());
@@ -374,7 +382,7 @@ mod tests {
&private_attributes,
&public_attributes,
)
.unwrap();
.unwrap();
let bytes = lambda.to_bytes();
assert_eq!(
+6 -6
View File
@@ -22,15 +22,15 @@ use bls12_381::{G2Projective, Scalar};
use group::Curve;
use serde_derive::{Deserialize, Serialize};
use crate::Base58;
use crate::error::{CoconutError, Result};
use crate::scheme::aggregation::aggregate_verification_keys;
use crate::scheme::setup::Parameters;
use crate::scheme::SignerIndex;
use crate::traits::Bytable;
use crate::utils::{
Polynomial, try_deserialize_g2_projective, try_deserialize_scalar, try_deserialize_scalar_vec,
try_deserialize_g2_projective, try_deserialize_scalar, try_deserialize_scalar_vec, Polynomial,
};
use crate::Base58;
#[derive(Debug, Clone)]
#[cfg_attr(test, derive(PartialEq))]
@@ -220,13 +220,13 @@ impl<'a> Mul<Scalar> for &'a VerificationKey {
}
impl<T> Sum<T> for VerificationKey
where
T: Borrow<VerificationKey>,
where
T: Borrow<VerificationKey>,
{
#[inline]
fn sum<I>(iter: I) -> Self
where
I: Iterator<Item=T>,
where
I: Iterator<Item = T>,
{
let mut peekable = iter.peekable();
let head_attributes = match peekable.peek() {
+79 -46
View File
@@ -22,7 +22,6 @@ use group::Curve;
pub use keygen::{SecretKey, VerificationKey};
use crate::{Attribute, elgamal};
use crate::elgamal::Ciphertext;
use crate::error::{CoconutError, Result};
use crate::scheme::aggregation::{aggregate_signature_shares, aggregate_signatures};
@@ -30,6 +29,7 @@ use crate::scheme::setup::Parameters;
use crate::scheme::verification::check_bilinear_pairing;
use crate::traits::{Base58, Bytable};
use crate::utils::try_deserialize_g1_projective;
use crate::{elgamal, Attribute};
pub mod aggregation;
pub mod issuance;
@@ -155,13 +155,15 @@ impl TryFrom<&[u8]> for BlindedSignature {
}
impl BlindedSignature {
pub fn unblind(&self,
params: &Parameters,
private_key: &elgamal::PrivateKey,
partial_verification_key: &VerificationKey,
private_attributes: &[Attribute],
public_attributes: &[Attribute],
commitment_hash: &G1Projective) -> Result<Signature> {
pub fn unblind(
&self,
params: &Parameters,
private_key: &elgamal::PrivateKey,
partial_verification_key: &VerificationKey,
private_attributes: &[Attribute],
public_attributes: &[Attribute],
commitment_hash: &G1Projective,
) -> Result<Signature> {
// parse the signature
let h = &self.0;
let c = &self.1;
@@ -179,10 +181,7 @@ impl BlindedSignature {
let tmp = private_attributes
.iter()
.chain(public_attributes.iter())
.zip(
partial_verification_key
.beta
.iter())
.zip(partial_verification_key.beta.iter())
.map(|(attr, beta_i)| beta_i * attr)
.sum::<G2Projective>();
@@ -255,13 +254,8 @@ mod tests {
let keypair1 = keygen(&mut params);
let keypair2 = keygen(&mut params);
let lambda = prepare_blind_sign(
&mut params,
&elgamal_keypair,
&private_attributes,
&[],
)
.unwrap();
let lambda =
prepare_blind_sign(&mut params, &elgamal_keypair, &private_attributes, &[]).unwrap();
let sig1 = blind_sign(
&mut params,
@@ -270,9 +264,16 @@ mod tests {
&lambda,
&[],
)
.unwrap()
.unblind(&params, elgamal_keypair.private_key(), &keypair1.verification_key(), &private_attributes, &[], lambda.commitment_hash).
unwrap();
.unwrap()
.unblind(
&params,
elgamal_keypair.private_key(),
&keypair1.verification_key(),
&private_attributes,
&[],
lambda.commitment_hash,
)
.unwrap();
let sig2 = blind_sign(
&mut params,
@@ -281,9 +282,16 @@ mod tests {
&lambda,
&[],
)
.unwrap()
.unblind(&params, elgamal_keypair.private_key(), &keypair2.verification_key(), &private_attributes, &[], lambda.commitment_hash)
.unwrap();
.unwrap()
.unblind(
&params,
elgamal_keypair.private_key(),
&keypair2.verification_key(),
&private_attributes,
&[],
lambda.commitment_hash,
)
.unwrap();
let theta1 = prove_credential(
&mut params,
@@ -291,7 +299,7 @@ mod tests {
&sig1,
&private_attributes,
)
.unwrap();
.unwrap();
let theta2 = prove_credential(
&mut params,
@@ -299,7 +307,7 @@ mod tests {
&sig2,
&private_attributes,
)
.unwrap();
.unwrap();
assert!(verify_credential(
&params,
@@ -371,7 +379,7 @@ mod tests {
&private_attributes,
&public_attributes,
)
.unwrap();
.unwrap();
let sig1 = blind_sign(
&mut params,
@@ -380,9 +388,16 @@ mod tests {
&lambda,
&public_attributes,
)
.unwrap()
.unblind(&params, elgamal_keypair.private_key(), &keypair1.verification_key(), &private_attributes, &public_attributes, lambda.commitment_hash)
.unwrap();
.unwrap()
.unblind(
&params,
elgamal_keypair.private_key(),
&keypair1.verification_key(),
&private_attributes,
&public_attributes,
lambda.commitment_hash,
)
.unwrap();
let sig2 = blind_sign(
&mut params,
@@ -391,9 +406,16 @@ mod tests {
&lambda,
&public_attributes,
)
.unwrap()
.unblind(&params, elgamal_keypair.private_key(), &keypair2.verification_key(), &private_attributes, &public_attributes, lambda.commitment_hash)
.unwrap();
.unwrap()
.unblind(
&params,
elgamal_keypair.private_key(),
&keypair2.verification_key(),
&private_attributes,
&public_attributes,
lambda.commitment_hash,
)
.unwrap();
let theta1 = prove_credential(
&mut params,
@@ -401,7 +423,7 @@ mod tests {
&sig1,
&private_attributes,
)
.unwrap();
.unwrap();
let theta2 = prove_credential(
&mut params,
@@ -409,7 +431,7 @@ mod tests {
&sig2,
&private_attributes,
)
.unwrap();
.unwrap();
assert!(verify_credential(
&params,
@@ -448,7 +470,7 @@ mod tests {
&private_attributes,
&public_attributes,
)
.unwrap();
.unwrap();
let sigs = keypairs
.iter()
@@ -460,9 +482,16 @@ mod tests {
&lambda,
&public_attributes,
)
.unwrap()
.unblind(&params, elgamal_keypair.private_key(), &keypair.verification_key(), &private_attributes, &public_attributes, lambda.commitment_hash)
.unwrap()
.unwrap()
.unblind(
&params,
elgamal_keypair.private_key(),
&keypair.verification_key(),
&private_attributes,
&public_attributes,
lambda.commitment_hash,
)
.unwrap()
})
.collect::<Vec<_>>();
@@ -476,7 +505,9 @@ mod tests {
attributes.extend_from_slice(&public_attributes);
let aggr_vk = aggregate_verification_keys(&vks[..2], Some(&[1, 2])).unwrap();
let aggr_sig = aggregate_signatures(&params, &aggr_vk, &attributes, &sigs[..2], Some(&[1, 2])).unwrap();
let aggr_sig =
aggregate_signatures(&params, &aggr_vk, &attributes, &sigs[..2], Some(&[1, 2]))
.unwrap();
let theta =
prove_credential(&mut params, &aggr_vk, &aggr_sig, &private_attributes).unwrap();
@@ -490,7 +521,9 @@ mod tests {
// taking different subset of keys and credentials
let aggr_vk = aggregate_verification_keys(&vks[1..], Some(&[2, 3])).unwrap();
let aggr_sig = aggregate_signatures(&params, &aggr_vk, &attributes, &sigs[1..], Some(&[2, 3])).unwrap();
let aggr_sig =
aggregate_signatures(&params, &aggr_vk, &attributes, &sigs[1..], Some(&[2, 3]))
.unwrap();
let theta =
prove_credential(&mut params, &aggr_vk, &aggr_sig, &private_attributes).unwrap();
@@ -516,7 +549,7 @@ mod tests {
signature.0.to_affine().to_compressed(),
signature.1.to_affine().to_compressed(),
]
.concat();
.concat();
assert_eq!(expected_bytes, bytes);
assert_eq!(signature, Signature::try_from(&bytes[..]).unwrap())
}
@@ -536,10 +569,10 @@ mod tests {
// also make sure it is equivalent to the internal g1 compressed bytes concatenated
let expected_bytes = [
blinded_sig.0.to_affine().to_compressed(),
blinded_sig.1.0.to_affine().to_compressed(),
blinded_sig.1.1.to_affine().to_compressed(),
blinded_sig.1 .0.to_affine().to_compressed(),
blinded_sig.1 .1.to_affine().to_compressed(),
]
.concat();
.concat();
assert_eq!(expected_bytes, bytes);
assert_eq!(blinded_sig, BlindedSignature::try_from(&bytes[..]).unwrap())
}
+20 -16
View File
@@ -16,10 +16,9 @@ use core::ops::Neg;
use std::convert::TryFrom;
use std::convert::TryInto;
use bls12_381::{G1Affine, G1Projective, G2Prepared, G2Projective, multi_miller_loop, Scalar};
use bls12_381::{multi_miller_loop, G1Affine, G1Projective, G2Prepared, G2Projective, Scalar};
use group::{Curve, Group};
use crate::Attribute;
use crate::error::{CoconutError, Result};
use crate::proofs::ProofKappaNu;
use crate::scheme::setup::Parameters;
@@ -27,6 +26,7 @@ use crate::scheme::Signature;
use crate::scheme::VerificationKey;
use crate::traits::{Base58, Bytable};
use crate::utils::{try_deserialize_g1_projective, try_deserialize_g2_projective};
use crate::Attribute;
// TODO NAMING: this whole thing
// Theta
@@ -36,7 +36,7 @@ pub struct Theta {
// blinded_message (kappa)
pub blinded_message: G2Projective,
// blinded serial number (zeta)
pub blinded_serial_number : G2Projective,
pub blinded_serial_number: G2Projective,
// sigma
pub credential: Signature,
// pi_v
@@ -133,10 +133,10 @@ pub fn compute_kappa(
params.gen2() * blinding_factor
+ verification_key.alpha
+ private_attributes
.iter()
.zip(verification_key.beta.iter())
.map(|(priv_attr, beta_i)| beta_i * priv_attr)
.sum::<G2Projective>()
.iter()
.zip(verification_key.beta.iter())
.map(|(priv_attr, beta_i)| beta_i * priv_attr)
.sum::<G2Projective>()
}
pub fn compute_zeta(params: &Parameters, serial_number: Attribute) -> G2Projective {
@@ -150,8 +150,7 @@ pub fn prove_credential(
serial_number: Attribute,
binding_number: Attribute,
) -> Result<Theta> {
if verification_key.beta.len() < 2{
if verification_key.beta.len() < 2 {
return Err(
CoconutError::Verification(
format!("Tried to prove a credential for higher than supported by the provided verification key number of attributes (max: {}, requested: 2)",
@@ -170,7 +169,12 @@ pub fn prove_credential(
// kappa is computed on m as input, but thanks to the use or random value r,
// it does not reveal any information about m.
let private_attributes = vec![serial_number, binding_number];
let blinded_message = compute_kappa(params, verification_key, &private_attributes, sign_blinding_factor);
let blinded_message = compute_kappa(
params,
verification_key,
&private_attributes,
sign_blinding_factor,
);
// zeta is a commitment to the serial number (i.e., a public value associated with the serial number)
let blinded_serial_number = compute_zeta(params, serial_number);
@@ -255,11 +259,11 @@ pub fn verify(
) -> bool {
let kappa = (verification_key.alpha
+ public_attributes
.iter()
.zip(verification_key.beta.iter())
.map(|(m_i, b_i)| b_i * m_i)
.sum::<G2Projective>())
.to_affine();
.iter()
.zip(verification_key.beta.iter())
.map(|(m_i, b_i)| b_i * m_i)
.sum::<G2Projective>())
.to_affine();
check_bilinear_pairing(
&sig.0.to_affine(),
@@ -295,7 +299,7 @@ mod tests {
serial_number,
binding_number,
)
.unwrap();
.unwrap();
let bytes = theta.to_bytes();
assert_eq!(Theta::try_from(bytes.as_slice()).unwrap(), theta);
+17 -5
View File
@@ -1,7 +1,7 @@
use crate::{
aggregate_signature_shares, aggregate_verification_keys, blind_sign, CoconutError,
elgamal_keygen, prepare_blind_sign, prove_credential, setup, Signature, SignatureShare,
ttp_keygen, VerificationKey, verify_credential,
aggregate_signature_shares, aggregate_verification_keys, blind_sign, elgamal_keygen,
prepare_blind_sign, prove_credential, setup, ttp_keygen, verify_credential, CoconutError,
Signature, SignatureShare, VerificationKey,
};
#[test]
@@ -51,7 +51,18 @@ fn main() -> Result<(), CoconutError> {
let unblinded_signatures: Vec<Signature> = blinded_signatures
.into_iter()
.zip(verification_keys.iter())
.map(|(signature, verification_key)| signature.unblind(&params, &elgamal_keypair.private_key(), &verification_key, &private_attributes, &public_attributes, blind_sign_request.commitment_hash).unwrap())
.map(|(signature, verification_key)| {
signature
.unblind(
&params,
&elgamal_keypair.private_key(),
&verification_key,
&private_attributes,
&public_attributes,
blind_sign_request.commitment_hash,
)
.unwrap()
})
.collect();
// Aggregate signatures
@@ -67,7 +78,8 @@ fn main() -> Result<(), CoconutError> {
attributes.extend_from_slice(&public_attributes);
// Randomize credentials and generate any cryptographic material to verify them
let signature = aggregate_signature_shares(&params, &verification_key, &attributes, &signature_shares)?;
let signature =
aggregate_signature_shares(&params, &verification_key, &attributes, &signature_shares)?;
// Generate cryptographic material to verify them
+4 -4
View File
@@ -16,8 +16,8 @@ use core::iter::Sum;
use core::ops::Mul;
use std::convert::TryInto;
use bls12_381::{G1Affine, G1Projective, G2Affine, G2Projective, Scalar};
use bls12_381::hash_to_curve::{ExpandMsgXmd, HashToCurve, HashToField};
use bls12_381::{G1Affine, G1Projective, G2Affine, G2Projective, Scalar};
use ff::Field;
use crate::error::{CoconutError, Result};
@@ -92,9 +92,9 @@ pub(crate) fn perform_lagrangian_interpolation_at_origin<T>(
points: &[SignerIndex],
values: &[T],
) -> Result<T>
where
T: Sum,
for<'a> &'a T: Mul<Scalar, Output=T>,
where
T: Sum,
for<'a> &'a T: Mul<Scalar, Output = T>,
{
if points.is_empty() || values.is_empty() {
return Err(CoconutError::Interpolation(
+17 -11
View File
@@ -15,8 +15,10 @@ use crate::network_monitor::monitor::summary_producer::SummaryProducer;
use crate::network_monitor::monitor::Monitor;
use crate::network_monitor::tested_network::TestedNetwork;
use crate::storage::NodeStatusStorage;
use coconut_interface::{Credential, hash_to_scalar, Parameters};
use credentials::bandwidth::{prepare_for_spending, BandwidthVoucherAttributes, BANDWIDTH_VALUE, TOTAL_ATTRIBUTES};
use coconut_interface::{hash_to_scalar, Credential, Parameters};
use credentials::bandwidth::{
prepare_for_spending, BandwidthVoucherAttributes, BANDWIDTH_VALUE, TOTAL_ATTRIBUTES,
};
use credentials::obtain_aggregate_verification_key;
use crypto::asymmetric::{encryption, identity};
use futures::channel::mpsc;
@@ -176,17 +178,21 @@ async fn TEMPORARY_obtain_bandwidth_credential(
.expect("could not obtain aggregate verification key of ALL validators");
let params = Parameters::new(TOTAL_ATTRIBUTES).unwrap();
let bandwidth_credential_attributes = BandwidthVoucherAttributes{
serial_number : params.random_scalar(),
binding_number : params.random_scalar(),
voucher_value : hash_to_scalar(BANDWIDTH_VALUE.to_be_bytes()),
voucher_info : hash_to_scalar(String::from("BandwidthVoucher").as_bytes()),
let bandwidth_credential_attributes = BandwidthVoucherAttributes {
serial_number: params.random_scalar(),
binding_number: params.random_scalar(),
voucher_value: hash_to_scalar(BANDWIDTH_VALUE.to_be_bytes()),
voucher_info: hash_to_scalar(String::from("BandwidthVoucher").as_bytes()),
};
let bandwidth_credential =
credentials::bandwidth::obtain_signature(&params, &bandwidth_credential_attributes, &validators, &verification_key)
.await
.expect("failed to obtain bandwidth credential!");
let bandwidth_credential = credentials::bandwidth::obtain_signature(
&params,
&bandwidth_credential_attributes,
&validators,
&verification_key,
)
.await
.expect("failed to obtain bandwidth credential!");
prepare_for_spending(
&identity.to_bytes(),