ecash issuance api side
This commit is contained in:
@@ -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 }
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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(
|
||||
¶ms,
|
||||
@@ -123,6 +123,7 @@ mod test {
|
||||
&encryption::KeyPair::new(&mut rng).private_key().to_bytes(),
|
||||
)
|
||||
.unwrap(),
|
||||
generate_keypair_user(¶ms),
|
||||
);
|
||||
let (_, blind_sign_req) = prepare_blind_sign(
|
||||
¶ms,
|
||||
|
||||
@@ -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
@@ -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(
|
||||
¶ms,
|
||||
&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);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user