87c8b512b0
Co-authored-by: Jędrzej Stuczyński <jedrzej.stuczynski@gmail.com>
94 lines
3.0 KiB
Rust
94 lines
3.0 KiB
Rust
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// for time being assume the bandwidth credential consists of public identity of the requester
|
|
// and private (though known... just go along with it) infinite bandwidth value
|
|
// right now this has no double-spending protection, spender binding, etc
|
|
// it's the simplest possible case
|
|
|
|
use url::Url;
|
|
|
|
use coconut_interface::{
|
|
Credential, Parameters, PrivateAttribute, PublicAttribute, Signature, VerificationKey,
|
|
};
|
|
|
|
use crate::error::Error;
|
|
use crate::utils::{obtain_aggregate_signature, prepare_credential_for_spending};
|
|
|
|
pub const BANDWIDTH_VALUE: u64 = 10 * 1024 * 1024 * 1024; // 10 GB
|
|
|
|
pub const PUBLIC_ATTRIBUTES: u32 = 2;
|
|
pub const PRIVATE_ATTRIBUTES: u32 = 2;
|
|
pub const TOTAL_ATTRIBUTES: u32 = PUBLIC_ATTRIBUTES + PRIVATE_ATTRIBUTES;
|
|
|
|
pub const SERIAL_NUMBER_LEN: usize = 47;
|
|
pub const BINDING_NUMBER_LEN: usize = 47;
|
|
pub const VOUCHER_INFO_LEN: usize = 47;
|
|
|
|
pub struct BandwidthVoucherAttributes {
|
|
// a random secret value generated by the client used for double-spending detection
|
|
pub serial_number: PrivateAttribute,
|
|
// a random secret value generated by the client used to bind multiple credentials together
|
|
pub binding_number: PrivateAttribute,
|
|
// the value (e.g., bandwidth) encoded in this voucher
|
|
pub voucher_value: PublicAttribute,
|
|
// a field with public information, e.g., type of voucher, epoch etc.
|
|
pub voucher_info: PublicAttribute,
|
|
}
|
|
|
|
impl BandwidthVoucherAttributes {
|
|
pub fn get_public_attributes(&self) -> Vec<PublicAttribute> {
|
|
vec![self.voucher_value, self.voucher_info]
|
|
}
|
|
|
|
pub fn get_private_attributes(&self) -> Vec<PrivateAttribute> {
|
|
let mut priv_attributes = Vec::with_capacity(PRIVATE_ATTRIBUTES as usize);
|
|
priv_attributes.push(self.serial_number);
|
|
priv_attributes.push(self.binding_number);
|
|
priv_attributes
|
|
}
|
|
}
|
|
|
|
// 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> {
|
|
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
|
|
}
|
|
|
|
pub fn prepare_for_spending(
|
|
raw_identity: &[u8],
|
|
signature: &Signature,
|
|
attributes: &BandwidthVoucherAttributes,
|
|
verification_key: &VerificationKey,
|
|
) -> Result<Credential, Error> {
|
|
let public_attributes = vec![
|
|
raw_identity.to_vec(),
|
|
BANDWIDTH_VALUE.to_be_bytes().to_vec(),
|
|
];
|
|
|
|
let params = Parameters::new(TOTAL_ATTRIBUTES)?;
|
|
|
|
prepare_credential_for_spending(
|
|
¶ms,
|
|
public_attributes,
|
|
attributes.serial_number,
|
|
attributes.binding_number,
|
|
signature,
|
|
verification_key,
|
|
)
|
|
}
|