ecash issuance api side

This commit is contained in:
Simon Wicky
2023-10-20 13:06:03 +02:00
committed by durch
parent dd323ce493
commit ea0dbfea03
6 changed files with 73 additions and 57 deletions
+1
View File
@@ -79,6 +79,7 @@ nym-bandwidth-controller = { path = "../common/bandwidth-controller" }
nym-coconut-bandwidth-contract-common = { path = "../common/cosmwasm-smart-contracts/coconut-bandwidth-contract" }
nym-coconut-dkg-common = { path = "../common/cosmwasm-smart-contracts/coconut-dkg" }
nym-coconut-interface = { path = "../common/coconut-interface" }
nym_compact_ecash = { path = "../common/nym_offline_compact_ecash" }
nym-ephemera-common = { path = "../common/cosmwasm-smart-contracts/ephemera" }
nym-config = { path = "../common/config" }
cosmwasm-std = { workspace = true }
+1
View File
@@ -15,6 +15,7 @@ serde = { workspace = true, features = ["derive"] }
ts-rs = { workspace = true, optional = true }
nym-coconut-interface = { path = "../../common/coconut-interface" }
nym_compact_ecash = { path = "../../common/nym_offline_compact_ecash" }
nym-mixnet-contract-common = { path= "../../common/cosmwasm-smart-contracts/mixnet-contract" }
nym-node-requests = { path = "../../nym-node/nym-node-requests", default-features = false }
+27 -22
View File
@@ -3,12 +3,10 @@
use cosmrs::AccountId;
use getset::{CopyGetters, Getters};
use nym_coconut_interface::{Credential, VerificationKey};
use nym_compact_ecash::{error::CompactEcashError, scheme::withdrawal::WithdrawalRequest};
use serde::{Deserialize, Serialize};
use nym_coconut_interface::{
error::CoconutInterfaceError, Attribute, Base58, BlindSignRequest, Credential, VerificationKey,
};
#[derive(Serialize, Deserialize, Getters, CopyGetters)]
pub struct VerifyCredentialBody {
#[getset(get = "pub")]
@@ -50,12 +48,14 @@ impl VerifyCredentialResponse {
#[derive(Clone, Serialize, Deserialize, Debug, Getters, CopyGetters)]
pub struct BlindSignRequestBody {
#[getset(get = "pub")]
blind_sign_request: BlindSignRequest,
withdrawal_request: WithdrawalRequest,
#[getset(get = "pub")]
tx_hash: String,
#[getset(get = "pub")]
signature: String,
public_attributes: Vec<String>,
#[getset(get = "pub")]
ecash_pubkey: String,
//public_attributes: Vec<String>,
#[getset(get = "pub")]
public_attributes_plain: Vec<String>,
#[getset(get = "pub")]
@@ -64,32 +64,34 @@ pub struct BlindSignRequestBody {
impl BlindSignRequestBody {
pub fn new(
blind_sign_request: &BlindSignRequest,
withdrawal_request: &WithdrawalRequest,
tx_hash: String,
signature: String,
public_attributes: &[Attribute],
ecash_pubkey: String,
//public_attributes: &[Attribute],
public_attributes_plain: Vec<String>,
total_params: u32,
) -> BlindSignRequestBody {
BlindSignRequestBody {
blind_sign_request: blind_sign_request.clone(),
withdrawal_request: withdrawal_request.clone(),
tx_hash,
signature,
public_attributes: public_attributes
.iter()
.map(|attr| attr.to_bs58())
.collect(),
ecash_pubkey,
// public_attributes: public_attributes
// .iter()
// .map(|attr| attr.to_bs58())
// .collect(),
public_attributes_plain,
total_params,
}
}
pub fn public_attributes(&self) -> Vec<Attribute> {
self.public_attributes
.iter()
.map(|x| Attribute::try_from_bs58(x).unwrap())
.collect()
}
// pub fn public_attributes(&self) -> Vec<Attribute> {
// self.public_attributes
// .iter()
// .map(|x| Attribute::try_from_bs58(x).unwrap())
// .collect()
// }
}
#[derive(Debug, Serialize, Deserialize)]
@@ -110,7 +112,7 @@ impl BlindedSignatureResponse {
bs58::encode(&self.to_bytes()).into_string()
}
pub fn from_base58_string<I: AsRef<[u8]>>(val: I) -> Result<Self, CoconutInterfaceError> {
pub fn from_base58_string<I: AsRef<[u8]>>(val: I) -> Result<Self, CompactEcashError> {
let bytes = bs58::decode(val).into_vec()?;
Self::from_bytes(&bytes)
}
@@ -121,9 +123,12 @@ impl BlindedSignatureResponse {
bytes
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, CoconutInterfaceError> {
pub fn from_bytes(bytes: &[u8]) -> Result<Self, CompactEcashError> {
if bytes.len() < 32 {
return Err(CoconutInterfaceError::InvalidByteLength(bytes.len(), 32));
return Err(CompactEcashError::DeserializationMinLength {
min: 32,
actual: bytes.len(),
});
}
let mut remote_key = [0u8; 32];
remote_key.copy_from_slice(&bytes[..32]);
+10 -9
View File
@@ -6,7 +6,6 @@ use nym_coconut_bandwidth_contract_common::events::{
DEPOSITED_FUNDS_EVENT_TYPE, DEPOSIT_ENCRYPTION_KEY, DEPOSIT_IDENTITY_KEY, DEPOSIT_INFO,
DEPOSIT_VALUE,
};
use nym_credentials::coconut::bandwidth::BandwidthVoucher;
use nym_crypto::asymmetric::encryption;
use nym_crypto::asymmetric::identity::{self, Signature};
use nym_validator_client::nyxd::TxResponse;
@@ -17,16 +16,16 @@ pub async fn extract_encryption_key(
blind_sign_request_body: &BlindSignRequestBody,
tx: TxResponse,
) -> Result<encryption::PublicKey> {
let blind_sign_request = blind_sign_request_body.blind_sign_request();
let public_attributes = blind_sign_request_body.public_attributes();
let withdrawal_request = blind_sign_request_body.withdrawal_request();
//let public_attributes = blind_sign_request_body.public_attributes();
let public_attributes_plain = blind_sign_request_body.public_attributes_plain();
if !BandwidthVoucher::verify_against_plain(&public_attributes, public_attributes_plain) {
return Err(CoconutError::InconsistentPublicAttributes);
}
// if !BandwidthVoucher::verify_against_plain(&public_attributes, public_attributes_plain) {
// return Err(CoconutError::InconsistentPublicAttributes);
// }
let tx_hash_str = blind_sign_request_body.tx_hash();
let mut message = blind_sign_request.to_bytes();
let mut message = withdrawal_request.to_bytes();
message.extend_from_slice(tx_hash_str.as_bytes());
let signature = Signature::from_base58_string(blind_sign_request_body.signature())?;
@@ -93,7 +92,8 @@ pub async fn extract_encryption_key(
mod test {
use super::*;
use crate::coconut::tests::tx_entry_fixture;
use nym_coconut::{prepare_blind_sign, BlindSignRequest, Parameters};
use nym_compact_ecash::generate_keypair_user;
use nym_compact_ecash::setup::GroupParameters;
use nym_config::defaults::VOUCHER_INFO;
use nym_validator_client::nyxd::Hash;
use nym_validator_client::nyxd::{Event, EventAttribute};
@@ -106,7 +106,7 @@ mod test {
Hash::from_str("6B27412050B823E58BB38447D7870BBC8CBE3C51C905BEA89D459ACCDA80A00E")
.unwrap();
let mut tx_entry = tx_entry_fixture(&tx_hash.to_string());
let params = Parameters::new(4).unwrap();
let params = GroupParametersParameters::new().unwrap();
let mut rng = OsRng;
let voucher = BandwidthVoucher::new(
&params,
@@ -123,6 +123,7 @@ mod test {
&encryption::KeyPair::new(&mut rng).private_key().to_bytes(),
)
.unwrap(),
generate_keypair_user(&params),
);
let (_, blind_sign_req) = prepare_blind_sign(
&params,
+3
View File
@@ -48,6 +48,9 @@ pub enum CoconutError {
#[error("Coconut internal error - {0}")]
CoconutInternalError(#[from] nym_coconut::CoconutError),
#[error("Compact ecash internal error - {0}")]
CompactEcashInternalError(#[from] nym_compact_ecash::error::CompactEcashError),
#[error("Could not find a deposit event in the transaction provided")]
DepositEventNotFound,
+31 -26
View File
@@ -16,10 +16,12 @@ use nym_coconut_bandwidth_contract_common::spend_credential::{
funds_from_cosmos_msgs, SpendCredentialStatus,
};
use nym_coconut_dkg_common::types::EpochId;
use nym_coconut_interface::KeyPair as CoconutKeyPair;
use nym_coconut_interface::{
Attribute, BlindSignRequest, BlindedSignature, Parameters, VerificationKey,
};
use nym_compact_ecash::scheme::keygen::{KeyPairAuth, SecretKeyAuth};
use nym_compact_ecash::scheme::withdrawal::WithdrawalRequest;
use nym_compact_ecash::setup::GroupParameters;
use nym_compact_ecash::utils::BlindedSignature;
use nym_compact_ecash::{PublicKeyUser, VerificationKeyAuth};
use nym_config::defaults::NYM_API_VERSION;
use nym_credentials::coconut::params::{
NymApiCredentialEncryptionAlgorithm, NymApiCredentialHkdfAlgorithm,
@@ -135,7 +137,10 @@ impl State {
}
}
pub async fn verification_key(&self, epoch_id: EpochId) -> Result<VerificationKey> {
pub async fn verification_key(
&self,
epoch_id: EpochId,
) -> Result<nym_coconut_interface::VerificationKey> {
self.comm_channel
.aggregated_verification_key(epoch_id)
.await
@@ -144,25 +149,20 @@ impl State {
#[derive(Getters, CopyGetters, Debug)]
pub(crate) struct InternalSignRequest {
// Total number of parameters to generate for
#[getset(get_copy)]
total_params: u32,
#[getset(get)]
public_attributes: Vec<Attribute>,
withdrawal_request: WithdrawalRequest,
#[getset(get)]
blind_sign_request: BlindSignRequest,
ecash_pubkey: PublicKeyUser,
}
impl InternalSignRequest {
pub fn new(
total_params: u32,
public_attributes: Vec<Attribute>,
blind_sign_request: BlindSignRequest,
withdrawal_request: WithdrawalRequest,
ecash_pubkey: PublicKeyUser,
) -> InternalSignRequest {
InternalSignRequest {
total_params,
public_attributes,
blind_sign_request,
withdrawal_request,
ecash_pubkey,
}
}
@@ -188,13 +188,13 @@ impl InternalSignRequest {
}
}
fn blind_sign(request: InternalSignRequest, key_pair: &CoconutKeyPair) -> Result<BlindedSignature> {
let params = Parameters::new(request.total_params())?;
Ok(nym_coconut_interface::blind_sign(
fn blind_sign(request: InternalSignRequest, key_pair: KeyPairAuth) -> Result<BlindedSignature> {
let params = GroupParameters::new()?;
Ok(nym_compact_ecash::scheme::withdrawal::issue_wallet(
&params,
&key_pair.secret_key(),
request.blind_sign_request(),
request.public_attributes(),
key_pair.secret_key(),
request.ecash_pubkey().clone(),
request.withdrawal_request(),
)?)
}
@@ -217,12 +217,17 @@ pub async fn post_blind_sign(
.await?;
let encryption_key = extract_encryption_key(&blind_sign_request_body, tx).await?;
let internal_request = InternalSignRequest::new(
*blind_sign_request_body.total_params(),
blind_sign_request_body.public_attributes(),
blind_sign_request_body.blind_sign_request().clone(),
blind_sign_request_body.withdrawal_request().clone(),
PublicKeyUser::from_base58_string(blind_sign_request_body.ecash_pubkey())?,
);
let blinded_signature = if let Some(keypair) = state.key_pair.get().await.as_ref() {
blind_sign(internal_request, keypair)?
let secret_key_auth = SecretKeyAuth::from_bytes(&keypair.secret_key().to_bytes())?;
let verification_key_auth =
VerificationKeyAuth::from_bytes(&keypair.verification_key().to_bytes())?;
let index = keypair.index;
let keypair_auth = KeyPairAuth::new(secret_key_auth, verification_key_auth, index);
blind_sign(internal_request, keypair_auth)?
} else {
return Err(CoconutError::KeyPairNotDerivedYet);
};