diff --git a/Cargo.lock b/Cargo.lock index 468a7c6790..eb1d3f96cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4945,7 +4945,6 @@ dependencies = [ "nym-coconut", "nym-coconut-bandwidth-contract-common", "nym-coconut-dkg-common", - "nym-coconut-interface", "nym-config", "nym-contracts-common", "nym-credential-storage", @@ -5000,7 +4999,7 @@ dependencies = [ "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "getset", - "nym-coconut-interface", + "nym-credentials-interface", "nym-crypto", "nym-mixnet-contract-common", "nym-node-requests", @@ -5016,9 +5015,10 @@ version = "0.1.0" dependencies = [ "bip39", "log", - "nym-coconut-interface", + "nym-coconut", "nym-credential-storage", "nym-credentials", + "nym-credentials-interface", "nym-crypto", "nym-network-defaults", "nym-validator-client", @@ -5156,7 +5156,6 @@ dependencies = [ "nym-bin-common", "nym-client-core", "nym-client-websocket-requests", - "nym-coconut-interface", "nym-config", "nym-credential-storage", "nym-credentials", @@ -5309,17 +5308,6 @@ dependencies = [ "nym-multisig-contract-common", ] -[[package]] -name = "nym-coconut-interface" -version = "0.1.0" -dependencies = [ - "bs58 0.4.0", - "getset", - "nym-coconut", - "serde", - "thiserror", -] - [[package]] name = "nym-config" version = "0.1.0" @@ -5364,6 +5352,7 @@ dependencies = [ "log", "nym-bandwidth-controller", "nym-client-core", + "nym-coconut", "nym-config", "nym-credential-storage", "nym-credentials", @@ -5381,7 +5370,7 @@ dependencies = [ "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "log", "nym-api-requests", - "nym-coconut-interface", + "nym-credentials-interface", "nym-crypto", "nym-validator-client", "rand 0.7.3", @@ -5391,6 +5380,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-credentials-interface" +version = "0.1.0" +dependencies = [ + "bls12_381", + "nym-coconut", + "serde", +] + [[package]] name = "nym-crypto" version = "0.4.0" @@ -5518,9 +5516,9 @@ dependencies = [ "log", "nym-api-requests", "nym-bin-common", - "nym-coconut-interface", "nym-config", "nym-credentials", + "nym-credentials-interface", "nym-crypto", "nym-gateway-requests", "nym-ip-packet-router", @@ -5594,8 +5592,8 @@ dependencies = [ "futures", "generic-array 0.14.7", "log", - "nym-coconut-interface", "nym-credentials", + "nym-credentials-interface", "nym-crypto", "nym-pemstore", "nym-sphinx", @@ -6138,7 +6136,6 @@ dependencies = [ "log", "nym-bin-common", "nym-client-core", - "nym-coconut-interface", "nym-config", "nym-credential-storage", "nym-credentials", @@ -6484,7 +6481,6 @@ dependencies = [ "hmac 0.12.1", "itertools 0.11.0", "log", - "nym-coconut-interface", "nym-config", "nym-crypto", "nym-mixnet-contract-common", @@ -6526,9 +6522,9 @@ dependencies = [ "itertools 0.10.5", "log", "nym-api-requests", + "nym-coconut", "nym-coconut-bandwidth-contract-common", "nym-coconut-dkg-common", - "nym-coconut-interface", "nym-config", "nym-contracts-common", "nym-ephemera-common", diff --git a/Cargo.toml b/Cargo.toml index 305be5b37b..c92723a54c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,6 @@ members = [ "common/client-libs/gateway-client", "common/client-libs/mixnet-client", "common/client-libs/validator-client", - "common/coconut-interface", "common/commands", "common/config", "common/cosmwasm-smart-contracts/coconut-bandwidth-contract", @@ -43,6 +42,7 @@ members = [ "common/credential-storage", "common/credentials", "common/credential-utils", + "common/credentials-interface", "common/crypto", "common/dkg", "common/execute", diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 0c5d4b5fd1..076b7128c8 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -38,7 +38,6 @@ tokio-tungstenite = { workspace = true } nym-bandwidth-controller = { path = "../../common/bandwidth-controller" } nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] } nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage", "cli"] } -nym-coconut-interface = { path = "../../common/coconut-interface" } nym-config = { path = "../../common/config" } nym-credential-storage = { path = "../../common/credential-storage" } nym-credentials = { path = "../../common/credentials" } diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index 72a94c4c2d..89edffb4fc 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -23,7 +23,6 @@ url = { workspace = true } # internal nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] } nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage", "cli"] } -nym-coconut-interface = { path = "../../common/coconut-interface" } nym-config = { path = "../../common/config" } nym-credentials = { path = "../../common/credentials" } nym-crypto = { path = "../../common/crypto" } diff --git a/common/bandwidth-controller/Cargo.toml b/common/bandwidth-controller/Cargo.toml index 116f8d20c4..284ccbfc77 100644 --- a/common/bandwidth-controller/Cargo.toml +++ b/common/bandwidth-controller/Cargo.toml @@ -14,9 +14,10 @@ thiserror = { workspace = true } url = { workspace = true } zeroize = { workspace = true } -nym-coconut-interface = { path = "../coconut-interface" } +nym-coconut = { path = "../nymcoconut" } nym-credential-storage = { path = "../credential-storage" } nym-credentials = { path = "../credentials" } +nym-credentials-interface = { path = "../credentials-interface" } nym-crypto = { path = "../crypto", features = ["rand", "asymmetric", "symmetric", "aes", "hashing"] } nym-network-defaults = { path = "../network-defaults" } nym-validator-client = { path = "../client-libs/validator-client", default-features = false } diff --git a/common/bandwidth-controller/src/acquire/mod.rs b/common/bandwidth-controller/src/acquire/mod.rs index 9bf1f371a3..5b842fc775 100644 --- a/common/bandwidth-controller/src/acquire/mod.rs +++ b/common/bandwidth-controller/src/acquire/mod.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::BandwidthControllerError; -use nym_coconut_interface::Base58; +use nym_coconut::Base58; use nym_credential_storage::storage::Storage; -use nym_credentials::coconut::bandwidth::{IssuanceBandwidthCredential, VOUCHER_INFO_TYPE}; +use nym_credentials::coconut::bandwidth::{CredentialType, IssuanceBandwidthCredential}; use nym_credentials::coconut::utils::obtain_aggregate_signature; use nym_crypto::asymmetric::{encryption, identity}; use nym_validator_client::coconut::all_coconut_api_clients; @@ -27,7 +27,7 @@ where let tx_hash = client .deposit( amount.clone(), - VOUCHER_INFO_TYPE.to_string(), + CredentialType::Voucher.to_string(), signing_key.public_key().to_base58_string(), encryption_key.public_key().to_base58_string(), None, @@ -73,7 +73,7 @@ where storage .insert_coconut_credential( voucher_value, - VOUCHER_INFO_TYPE.to_string(), + CredentialType::Voucher.to_string(), state.voucher.get_private_attributes()[0].to_bs58(), state.voucher.get_private_attributes()[1].to_bs58(), signature.to_bs58(), diff --git a/common/bandwidth-controller/src/error.rs b/common/bandwidth-controller/src/error.rs index 5f464c82e5..7b4e787cb5 100644 --- a/common/bandwidth-controller/src/error.rs +++ b/common/bandwidth-controller/src/error.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use nym_coconut_interface::CoconutError; +use nym_coconut::CoconutError; use nym_credential_storage::error::StorageError; use nym_credentials::error::Error as CredentialsError; use nym_crypto::asymmetric::encryption::KeyRecoveryError; diff --git a/common/bandwidth-controller/src/lib.rs b/common/bandwidth-controller/src/lib.rs index 6d78bd7401..2902d93451 100644 --- a/common/bandwidth-controller/src/lib.rs +++ b/common/bandwidth-controller/src/lib.rs @@ -4,11 +4,11 @@ use crate::error::BandwidthControllerError; use crate::utils::stored_credential_to_issued_bandwidth; use log::{error, warn}; -use nym_coconut_interface::VerificationKey; use nym_credential_storage::error::StorageError; use nym_credential_storage::storage::Storage; use nym_credentials::coconut::bandwidth::CredentialSpendingData; use nym_credentials::coconut::utils::obtain_aggregate_verification_key; +use nym_credentials_interface::VerificationKey; use nym_validator_client::coconut::all_coconut_api_clients; use nym_validator_client::nym_api::EpochId; use nym_validator_client::nyxd::contract_traits::DkgQueryClient; diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index 5325428da2..3a0b2340d9 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -32,7 +32,7 @@ url = { workspace = true, features = ["serde"] } tokio = { workspace = true, features = ["sync", "time"] } futures = { workspace = true } -nym-coconut-interface = { path = "../../coconut-interface" } +nym-coconut = { path = "../../nymcoconut" } nym-network-defaults = { path = "../../network-defaults" } nym-api-requests = { path = "../../../nym-api/nym-api-requests" } diff --git a/common/client-libs/validator-client/src/coconut/mod.rs b/common/client-libs/validator-client/src/coconut/mod.rs index 97ac95cad7..66f5d0e05a 100644 --- a/common/client-libs/validator-client/src/coconut/mod.rs +++ b/common/client-libs/validator-client/src/coconut/mod.rs @@ -4,9 +4,9 @@ use crate::nyxd::contract_traits::{DkgQueryClient, PagedDkgQueryClient}; use crate::nyxd::error::NyxdError; use crate::NymApiClient; +use nym_coconut::{Base58, CoconutError, VerificationKey}; use nym_coconut_dkg_common::types::{EpochId, NodeIndex}; use nym_coconut_dkg_common::verification_key::ContractVKShare; -use nym_coconut_interface::{Base58, CoconutError, VerificationKey}; use thiserror::Error; use url::Url; diff --git a/common/client-libs/validator-client/src/nyxd/error.rs b/common/client-libs/validator-client/src/nyxd/error.rs index e247dff6a1..905d484b72 100644 --- a/common/client-libs/validator-client/src/nyxd/error.rs +++ b/common/client-libs/validator-client/src/nyxd/error.rs @@ -140,9 +140,6 @@ pub enum NyxdError { #[error("Cosmwasm std error: {0}")] CosmwasmStdError(#[from] cosmwasm_std::StdError), - #[error("Coconut interface error: {0}")] - CoconutInterfaceError(#[from] nym_coconut_interface::error::CoconutInterfaceError), - #[error("Account had an unexpected bech32 prefix. Expected: {expected}, got: {got}")] UnexpectedBech32Prefix { got: String, expected: String }, } diff --git a/common/coconut-interface/Cargo.toml b/common/coconut-interface/Cargo.toml deleted file mode 100644 index a85115d95f..0000000000 --- a/common/coconut-interface/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "nym-coconut-interface" -version = "0.1.0" -edition = "2021" -description = "Crutch library until there is proper SerDe support for coconut structs" -license.workspace = true - -[dependencies] -bs58 = "0.4.0" -getset = "0.1.1" -serde = { workspace = true, features = ["derive"] } -thiserror = { workspace = true } - -nym-coconut = { path = "../nymcoconut" } diff --git a/common/coconut-interface/src/error.rs b/common/coconut-interface/src/error.rs deleted file mode 100644 index e096ee34f8..0000000000 --- a/common/coconut-interface/src/error.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2021 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use nym_coconut::CoconutError; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum CoconutInterfaceError { - #[error("not enough bytes: {0} received, minimum {1} required")] - InvalidByteLength(usize, usize), - - #[error("Could not decode base 58 string - {0}")] - MalformedString(#[from] bs58::decode::Error), - - #[error("Coconut error - {0}")] - CoconutError(#[from] CoconutError), -} diff --git a/common/coconut-interface/src/lib.rs b/common/coconut-interface/src/lib.rs deleted file mode 100644 index 4ac0706463..0000000000 --- a/common/coconut-interface/src/lib.rs +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2021-2024 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use error::CoconutInterfaceError; -use getset::{CopyGetters, Getters}; -use serde::{Deserialize, Serialize}; - -pub mod error; - -// We list these explicity instead of glob export due to shadowing warnings with the pub tests -// module. -pub use nym_coconut::{ - aggregate_signature_shares, aggregate_verification_keys, blind_sign, hash_to_scalar, - prepare_blind_sign, prove_bandwidth_credential, verify_credential, Attribute, Base58, - BlindSignRequest, BlindedSignature, Bytable, CoconutError, KeyPair, Parameters, - PrivateAttribute, PublicAttribute, SecretKey, Signature, SignatureShare, VerificationKey, - VerifyCredentialRequest, -}; - -// TODO: maybe just remove this sucker? -#[deprecated] -#[derive(Debug, Serialize, Deserialize, Getters, CopyGetters, Clone, PartialEq, Eq)] -pub struct Credential { - #[getset(get = "pub")] - n_params: u32, - - #[getset(get = "pub")] - theta: VerifyCredentialRequest, - - voucher_value: u64, - - voucher_info: String, - - #[getset(get = "pub")] - epoch_id: u64, -} - -impl Credential { - pub fn new( - n_params: u32, - theta: VerifyCredentialRequest, - voucher_value: u64, - voucher_info: String, - epoch_id: u64, - ) -> Credential { - Credential { - n_params, - theta, - voucher_value, - voucher_info, - epoch_id, - } - } - - pub fn blinded_serial_number(&self) -> String { - self.theta.blinded_serial_number_bs58() - } - - pub fn has_blinded_serial_number( - &self, - blinded_serial_number_bs58: &str, - ) -> Result { - Ok(self - .theta - .has_blinded_serial_number(blinded_serial_number_bs58)?) - } - - pub fn voucher_value(&self) -> u64 { - self.voucher_value - } - - pub fn verify(&self, verification_key: &VerificationKey) -> bool { - let params = Parameters::new(self.n_params).unwrap(); - - let hashed_value = hash_to_scalar(self.voucher_value.to_string()); - let hashed_info = hash_to_scalar(&self.voucher_info); - let public_attributes = &[&hashed_value, &hashed_info]; - - nym_coconut::verify_credential(¶ms, verification_key, &self.theta, public_attributes) - } - - pub fn as_bytes(&self) -> Vec { - let n_params_bytes = self.n_params.to_be_bytes(); - let theta_bytes = self.theta.to_bytes(); - let theta_bytes_len = theta_bytes.len(); - let voucher_value_bytes = self.voucher_value.to_be_bytes(); - let epoch_id_bytes = self.epoch_id.to_be_bytes(); - let voucher_info_bytes = self.voucher_info.as_bytes(); - let voucher_info_len = voucher_info_bytes.len(); - - let mut bytes = Vec::with_capacity(28 + theta_bytes_len + voucher_info_len); - bytes.extend_from_slice(&n_params_bytes); - bytes.extend_from_slice(&(theta_bytes_len as u64).to_be_bytes()); - bytes.extend_from_slice(&theta_bytes); - bytes.extend_from_slice(&voucher_value_bytes); - bytes.extend_from_slice(&epoch_id_bytes); - bytes.extend_from_slice(voucher_info_bytes); - - bytes - } - - pub fn from_bytes(bytes: &[u8]) -> Result { - if bytes.len() < 28 { - return Err(CoconutError::Deserialization(String::from( - "To few bytes in credential", - ))); - } - let mut four_byte = [0u8; 4]; - let mut eight_byte = [0u8; 8]; - - four_byte.copy_from_slice(&bytes[..4]); - let n_params = u32::from_be_bytes(four_byte); - eight_byte.copy_from_slice(&bytes[4..12]); - let theta_len = u64::from_be_bytes(eight_byte); - if bytes.len() < 28 + theta_len as usize { - return Err(CoconutError::Deserialization(String::from( - "To few bytes in credential", - ))); - } - let theta = VerifyCredentialRequest::from_bytes(&bytes[12..12 + theta_len as usize]) - .map_err(|e| CoconutError::Deserialization(e.to_string()))?; - eight_byte.copy_from_slice(&bytes[12 + theta_len as usize..20 + theta_len as usize]); - let voucher_value = u64::from_be_bytes(eight_byte); - eight_byte.copy_from_slice(&bytes[20 + theta_len as usize..28 + theta_len as usize]); - let epoch_id = u64::from_be_bytes(eight_byte); - let voucher_info = String::from_utf8(bytes[28 + theta_len as usize..].to_vec()) - .map_err(|e| CoconutError::Deserialization(e.to_string()))?; - - Ok(Credential { - n_params, - theta, - voucher_value, - voucher_info, - epoch_id, - }) - } -} - -impl Bytable for Credential { - fn to_byte_vec(&self) -> Vec { - self.as_bytes() - } - - fn try_from_byte_slice(slice: &[u8]) -> Result { - Credential::from_bytes(slice) - } -} - -impl Base58 for Credential {} - -#[cfg(test)] -mod tests { - use nym_coconut::{prove_bandwidth_credential, Signature}; - - use super::*; - - #[test] - fn serde_coconut_credential() { - let voucher_value = 1000000u64; - let voucher_info = String::from("BandwidthVoucher"); - let serial_number = - Attribute::try_from_bs58("7Rp3imcuNX3w9se9wm5th8gSvc2czsnMrGsdt5HsrycA").unwrap(); - let binding_number = - Attribute::try_from_bs58("Auf8yVEgyEAWNHaXUZmimS4n9g5YiYnNYqp6F9BtBe9E").unwrap(); - let signature = Signature::try_from_bs58( - "ta3pM9ffj5T6YGbwjSBp2W118rcwyP9PXStc\ - 7ssb91g5GQYMQHhuTNajbdZcjxUFBFL5rhED8EHpRzE8r432ss3qbPBfpNev4CdkfMkQ3wepyM7hy7q1W6Rn9WmFoZL\ - ZR9j", - ) - .unwrap(); - let params = Parameters::new(4).unwrap(); - let verification_key = VerificationKey::try_from_bs58("8CFtVVXdwLy4WHMQPE4\ - woe89q3DRHoNxBSchftrEjSBPWA4r4xZv4Y9qSvS5x5bMmFtp7BX6ikECAnuXr5EjXWSsgjirZJmpS5XDUynVfht1cD\ - FWGDvy2XFrRCuoCMotNXi3PoF6wYqdTR9Rqcfoj3i2H5Nid422WBaLtVoC9QNobvpvaqq6vX5PbsSyPayvU8HCXFxM6\ - JjScYpbRTxQtdwefWLrk3LmXyJQBWi7c2VAhSxu9msp7VTBycqdwQNgxHETStZuwXsozxaGQ2KssVUCaaoYPR4g2RqK\ - UAvtWwA7pMiAQNcbkXcbsjCgVjWaCpMWC37XA31cLcFf3zbjHD9e5tXjAcqa4M89fbFhuvvSXxowSAZ5NoWrN32kd5d\ - wxJm1JW3Tt2h6yDDBe84oMy71462dZn7N78DVk2mFNGwBCibrZWA7oUzRBMfYxiQrksoFcou7QfLLd58zoNYmPQPt84\ - 1VpQopEBfdQ7Nf9zoXxBt3zMy7g5NsFGvzh7KTbDUyeeXrdkKJPQBs6dqaizr9sS8CPPmR4uk96vDTRh8CJ5FbSsmb8\ - nP71dRvvwRZJHGzwYirMo6SXS3ZYxFuiA3mkxYuqDHCwkTWDuRCcAaztrDYRZg7VCMo4Q446AaEso5eqpeWpHZQt53E\ - ZRpqmNYKASGwMhTeEHPSLgSmtoAAUcaRWpGRzYfd6kzEma8tdGLwyP4rLXgvSvtDLP37dU7YgF3LEXbGAz57U9ATy46\ - 6sroLpHPdaCWB8RF11wvB6Tu196JnJd2KyQBP1iUWP3rtZs3GhAF1QVcxquh8BqDZzAcpQ6wCS1P9c5GxKgww77FVF5\ - Kp83XtoxSrw3GaYVyKTGxNh3vcKPR31txCjTxPaN2fg7TaPLhoQJX4YaAroFSXqrqbbRsisuHhhCeUP2YwDjHedes9y") - .unwrap(); - let theta = prove_bandwidth_credential( - ¶ms, - &verification_key, - &signature, - &serial_number, - &binding_number, - ) - .unwrap(); - let credential = Credential::new(4, theta, voucher_value, voucher_info, 42); - - let serialized_credential = credential.as_bytes(); - let deserialized_credential = Credential::from_bytes(&serialized_credential).unwrap(); - - assert_eq!(credential, deserialized_credential); - } -} diff --git a/common/credentials-interface/Cargo.toml b/common/credentials-interface/Cargo.toml new file mode 100644 index 0000000000..789552ebff --- /dev/null +++ b/common/credentials-interface/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "nym-credentials-interface" +version = "0.1.0" +authors.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +bls12_381 = { workspace = true, default-features = false } +serde = { workspace = true, features = ["derive"] } + +nym-coconut = { path = "../nymcoconut" } diff --git a/common/credentials-interface/src/lib.rs b/common/credentials-interface/src/lib.rs new file mode 100644 index 0000000000..f962bf8c9e --- /dev/null +++ b/common/credentials-interface/src/lib.rs @@ -0,0 +1,109 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use bls12_381::Scalar; +use serde::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter}; + +pub use nym_coconut::{ + aggregate_signature_shares, aggregate_verification_keys, blind_sign, hash_to_scalar, + prepare_blind_sign, prove_bandwidth_credential, verify_credential, Attribute, Base58, + BlindSignRequest, BlindedSignature, Bytable, CoconutError, KeyPair, Parameters, + PrivateAttribute, PublicAttribute, SecretKey, Signature, SignatureShare, VerificationKey, + VerifyCredentialRequest, +}; + +pub const VOUCHER_INFO_TYPE: &str = "BandwidthVoucher"; +pub const FREE_PASS_INFO_TYPE: &str = "FreeBandwidthPass"; + +// pub trait NymCredential { +// fn prove_credential(&self) -> Result<(), ()>; +// } + +#[derive(Copy, Clone, Debug, Serialize, Deserialize)] +pub enum CredentialType { + Voucher, + FreePass, +} + +impl CredentialType { + pub fn validate(&self, type_plain: &str) -> bool { + match self { + CredentialType::Voucher => type_plain == VOUCHER_INFO_TYPE, + CredentialType::FreePass => type_plain == FREE_PASS_INFO_TYPE, + } + } + + pub fn is_free_pass(&self) -> bool { + matches!(self, CredentialType::FreePass) + } + + pub fn is_voucher(&self) -> bool { + matches!(self, CredentialType::Voucher) + } +} + +impl Display for CredentialType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + CredentialType::Voucher => VOUCHER_INFO_TYPE.fmt(f), + CredentialType::FreePass => FREE_PASS_INFO_TYPE.fmt(f), + } + } +} + +#[derive(Debug, Clone)] +pub struct CredentialSigningData { + pub pedersen_commitments_openings: Vec, + + pub blind_sign_request: BlindSignRequest, + + pub public_attributes_plain: Vec, + + pub typ: CredentialType, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct CredentialSpendingData { + pub embedded_private_attributes: usize, + + pub verify_credential_request: VerifyCredentialRequest, + + pub public_attributes_plain: Vec, + + pub typ: CredentialType, +} + +impl CredentialSpendingData { + pub fn verify(&self, params: &Parameters, verification_key: &VerificationKey) -> bool { + let hashed_public_attributes = self + .public_attributes_plain + .iter() + .map(hash_to_scalar) + .collect::>(); + + // get references to the attributes + let public_attributes = hashed_public_attributes.iter().collect::>(); + + verify_credential( + params, + verification_key, + &self.verify_credential_request, + &public_attributes, + ) + } + + pub fn validate_type_attribute(&self) -> bool { + // the first attribute is variant specific bandwidth encoding, the second one should be the type + let Some(type_plain) = self.public_attributes_plain.get(1) else { + return false; + }; + + self.typ.validate(type_plain) + } + + pub fn get_bandwidth_attribute(&self) -> Option<&String> { + // the first attribute is variant specific bandwidth encoding, the second one should be the type + self.public_attributes_plain.first() + } +} diff --git a/common/credentials/Cargo.toml b/common/credentials/Cargo.toml index 55894c3754..bc096fa5a9 100644 --- a/common/credentials/Cargo.toml +++ b/common/credentials/Cargo.toml @@ -16,7 +16,7 @@ time = { workspace = true, features = ["serde"] } zeroize = { workspace = true } # I guess temporarily until we get serde support in coconut up and running -nym-coconut-interface = { path = "../coconut-interface" } +nym-credentials-interface = { path = "../credentials-interface" } nym-crypto = { path = "../crypto", features = ["rand", "asymmetric", "serde"] } nym-api-requests = { path = "../../nym-api/nym-api-requests" } nym-validator-client = { path = "../client-libs/validator-client", default-features = false } diff --git a/common/credentials/src/coconut/bandwidth/freepass.rs b/common/credentials/src/coconut/bandwidth/freepass.rs index 5783a8c25d..67fab7197b 100644 --- a/common/credentials/src/coconut/bandwidth/freepass.rs +++ b/common/credentials/src/coconut/bandwidth/freepass.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::coconut::utils::scalar_serde_helper; -use nym_coconut_interface::{hash_to_scalar, Attribute, PublicAttribute}; +use nym_credentials_interface::{hash_to_scalar, Attribute, PublicAttribute}; use serde::{Deserialize, Serialize}; use time::{Duration, OffsetDateTime, Time}; use zeroize::{Zeroize, ZeroizeOnDrop}; diff --git a/common/credentials/src/coconut/bandwidth/issuance.rs b/common/credentials/src/coconut/bandwidth/issuance.rs index 736555bfdc..7078d358d5 100644 --- a/common/credentials/src/coconut/bandwidth/issuance.rs +++ b/common/credentials/src/coconut/bandwidth/issuance.rs @@ -9,7 +9,7 @@ use crate::coconut::bandwidth::{ }; use crate::coconut::utils::scalar_serde_helper; use crate::error::Error; -use nym_coconut_interface::{ +use nym_credentials_interface::{ aggregate_signature_shares, hash_to_scalar, prepare_blind_sign, Attribute, Parameters, PrivateAttribute, PublicAttribute, Signature, SignatureShare, VerificationKey, }; diff --git a/common/credentials/src/coconut/bandwidth/issued.rs b/common/credentials/src/coconut/bandwidth/issued.rs index d3e8807f05..8a66e36365 100644 --- a/common/credentials/src/coconut/bandwidth/issued.rs +++ b/common/credentials/src/coconut/bandwidth/issued.rs @@ -10,7 +10,7 @@ use crate::coconut::bandwidth::{ bandwidth_credential_params, CredentialSpendingData, CredentialType, }; use crate::error::Error; -use nym_coconut_interface::{ +use nym_credentials_interface::{ prove_bandwidth_credential, Parameters, PrivateAttribute, PublicAttribute, Signature, VerificationKey, }; diff --git a/common/credentials/src/coconut/bandwidth/mod.rs b/common/credentials/src/coconut/bandwidth/mod.rs index 8fe23a444b..195db20598 100644 --- a/common/credentials/src/coconut/bandwidth/mod.rs +++ b/common/credentials/src/coconut/bandwidth/mod.rs @@ -1,114 +1,21 @@ // Copyright 2021-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use bls12_381::Scalar; -use nym_coconut_interface::{ - hash_to_scalar, BlindSignRequest, Parameters, VerificationKey, VerifyCredentialRequest, -}; -use serde::{Deserialize, Serialize}; -use std::fmt::{Display, Formatter}; use std::sync::OnceLock; -use zeroize::{Zeroize, ZeroizeOnDrop}; pub use issuance::IssuanceBandwidthCredential; pub use issued::IssuedBandwidthCredential; +pub use nym_credentials_interface::{ + CredentialSigningData, CredentialSpendingData, CredentialType, Parameters, +}; pub mod freepass; pub mod issuance; pub mod issued; pub mod voucher; -pub const VOUCHER_INFO_TYPE: &str = "BandwidthVoucher"; -pub const FREE_PASS_INFO_TYPE: &str = "FreeBandwidthPass"; - // works under the assumption of having 4 attributes in the underlying credential(s) pub fn bandwidth_credential_params() -> &'static Parameters { static BANDWIDTH_CREDENTIAL_PARAMS: OnceLock = OnceLock::new(); BANDWIDTH_CREDENTIAL_PARAMS.get_or_init(IssuanceBandwidthCredential::default_parameters) } - -#[derive(Zeroize, Copy, Clone, Debug, Serialize, Deserialize)] -pub enum CredentialType { - Voucher, - FreePass, -} - -impl CredentialType { - pub fn is_free_pass(&self) -> bool { - matches!(self, CredentialType::FreePass) - } - - pub fn is_voucher(&self) -> bool { - matches!(self, CredentialType::Voucher) - } -} - -impl Display for CredentialType { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - CredentialType::Voucher => VOUCHER_INFO_TYPE.fmt(f), - CredentialType::FreePass => FREE_PASS_INFO_TYPE.fmt(f), - } - } -} - -#[derive(Debug, Clone)] -pub struct CredentialSigningData { - pub pedersen_commitments_openings: Vec, - - pub blind_sign_request: BlindSignRequest, - - pub public_attributes_plain: Vec, - - pub typ: CredentialType, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct CredentialSpendingData { - pub embedded_private_attributes: usize, - - pub verify_credential_request: VerifyCredentialRequest, - - pub public_attributes_plain: Vec, - - pub typ: CredentialType, -} - -impl CredentialSpendingData { - pub fn verify(&self, verification_key: &VerificationKey) -> bool { - let params = bandwidth_credential_params(); - - let hashed_public_attributes = self - .public_attributes_plain - .iter() - .map(hash_to_scalar) - .collect::>(); - - // get references to the attributes - let public_attributes = hashed_public_attributes.iter().collect::>(); - - nym_coconut_interface::verify_credential( - params, - verification_key, - &self.verify_credential_request, - &public_attributes, - ) - } - - pub fn validate_type_attribute(&self) -> bool { - // the first attribute is variant specific bandwidth encoding, the second one should be the type - let Some(type_plain) = self.public_attributes_plain.get(1) else { - return false; - }; - - match self.typ { - CredentialType::Voucher => type_plain == VOUCHER_INFO_TYPE, - CredentialType::FreePass => type_plain == FREE_PASS_INFO_TYPE, - } - } - - pub fn get_bandwidth_attribute(&self) -> Option<&String> { - // the first attribute is variant specific bandwidth encoding, the second one should be the type - self.public_attributes_plain.first() - } -} diff --git a/common/credentials/src/coconut/bandwidth/voucher.rs b/common/credentials/src/coconut/bandwidth/voucher.rs index 06f88d2414..6bf4e55dcb 100644 --- a/common/credentials/src/coconut/bandwidth/voucher.rs +++ b/common/credentials/src/coconut/bandwidth/voucher.rs @@ -5,7 +5,7 @@ use crate::coconut::bandwidth::CredentialSigningData; use crate::coconut::utils::scalar_serde_helper; use crate::error::Error; use nym_api_requests::coconut::BlindSignRequestBody; -use nym_coconut_interface::{ +use nym_credentials_interface::{ hash_to_scalar, Attribute, BlindSignRequest, BlindedSignature, PublicAttribute, }; use nym_crypto::asymmetric::{encryption, identity}; diff --git a/common/credentials/src/coconut/credential.rs b/common/credentials/src/coconut/credential.rs deleted file mode 100644 index 446682a398..0000000000 --- a/common/credentials/src/coconut/credential.rs +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2024 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -pub trait NymCredential { - fn prove_credential(&self) -> Result<(), ()>; -} diff --git a/common/credentials/src/coconut/mod.rs b/common/credentials/src/coconut/mod.rs index c02b932712..16d9819ab4 100644 --- a/common/credentials/src/coconut/mod.rs +++ b/common/credentials/src/coconut/mod.rs @@ -2,5 +2,4 @@ // SPDX-License-Identifier: Apache-2.0 pub mod bandwidth; -pub mod credential; pub mod utils; diff --git a/common/credentials/src/coconut/utils.rs b/common/credentials/src/coconut/utils.rs index a2014d8c1a..cf0025826c 100644 --- a/common/credentials/src/coconut/utils.rs +++ b/common/credentials/src/coconut/utils.rs @@ -4,7 +4,7 @@ use crate::coconut::bandwidth::IssuanceBandwidthCredential; use crate::error::Error; use log::{debug, warn}; -use nym_coconut_interface::{ +use nym_credentials_interface::{ aggregate_verification_keys, Signature, SignatureShare, VerificationKey, }; use nym_validator_client::client::CoconutApiClient; diff --git a/common/credentials/src/error.rs b/common/credentials/src/error.rs index c89667aad6..76c4aa068c 100644 --- a/common/credentials/src/error.rs +++ b/common/credentials/src/error.rs @@ -1,7 +1,7 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use nym_coconut_interface::CoconutError; +use nym_credentials_interface::CoconutError; use nym_crypto::asymmetric::encryption::KeyRecoveryError; use nym_validator_client::ValidatorClientError; diff --git a/common/types/Cargo.toml b/common/types/Cargo.toml index d08e435486..8b5f0c3340 100644 --- a/common/types/Cargo.toml +++ b/common/types/Cargo.toml @@ -31,7 +31,6 @@ nym-validator-client = { path = "../../common/client-libs/validator-client" } nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" } nym-vesting-contract-common = { path = "../../common/cosmwasm-smart-contracts/vesting-contract" } nym-config = { path = "../../common/config" } -nym-coconut-interface = { path = "../../common/coconut-interface" } nym-crypto = { path = "../../common/crypto", features = ["asymmetric"] } [dev-dependencies] diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index a845ba908b..ff1fb32888 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -62,9 +62,9 @@ nym-node = { path = "../nym-node" } nym-api-requests = { path = "../nym-api/nym-api-requests" } nym-bin-common = { path = "../common/bin-common", features = ["output_format"] } -nym-coconut-interface = { path = "../common/coconut-interface" } nym-config = { path = "../common/config" } nym-credentials = { path = "../common/credentials" } +nym-credentials-interface = { path = "../common/credentials-interface" } nym-crypto = { path = "../common/crypto" } nym-gateway-requests = { path = "gateway-requests" } nym-mixnet-client = { path = "../common/client-libs/mixnet-client" } diff --git a/gateway/gateway-requests/Cargo.toml b/gateway/gateway-requests/Cargo.toml index 7916fa3038..d63170628e 100644 --- a/gateway/gateway-requests/Cargo.toml +++ b/gateway/gateway-requests/Cargo.toml @@ -25,8 +25,8 @@ nym-crypto = { path = "../../common/crypto" } nym-pemstore = { path = "../../common/pemstore" } nym-sphinx = { path = "../../common/nymsphinx" } -nym-coconut-interface = { path = "../../common/coconut-interface" } nym-credentials = { path = "../../common/credentials" } +nym-credentials-interface = { path = "../../common/credentials-interface" } [dependencies.tungstenite] workspace = true diff --git a/gateway/gateway-requests/src/models.rs b/gateway/gateway-requests/src/models.rs index 43881d3ceb..4e1df1d61e 100644 --- a/gateway/gateway-requests/src/models.rs +++ b/gateway/gateway-requests/src/models.rs @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use crate::GatewayRequestsError; -use nym_coconut_interface::CoconutError; use nym_credentials::coconut::bandwidth::CredentialSpendingData; +use nym_credentials_interface::CoconutError; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] diff --git a/gateway/src/node/client_handling/bandwidth.rs b/gateway/src/node/client_handling/bandwidth.rs index d5ea02b2d2..76406360f6 100644 --- a/gateway/src/node/client_handling/bandwidth.rs +++ b/gateway/src/node/client_handling/bandwidth.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-3.0-only use log::error; -use nym_coconut_interface::Credential; use nym_credentials::coconut::bandwidth::CredentialType; use thiserror::Error; @@ -49,12 +48,12 @@ impl Bandwidth { } } -impl From for Bandwidth { - fn from(credential: Credential) -> Self { - let token_value = credential.voucher_value(); - let bandwidth_bytes = token_value * nym_network_defaults::BYTES_PER_UTOKEN; - Bandwidth { - value: bandwidth_bytes, - } - } -} +// impl From for Bandwidth { +// fn from(credential: Credential) -> Self { +// let token_value = credential.voucher_value(); +// let bandwidth_bytes = token_value * nym_network_defaults::BYTES_PER_UTOKEN; +// Bandwidth { +// value: bandwidth_bytes, +// } +// } +// } diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 548037e9d3..d5a662c2ed 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -1,28 +1,6 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use futures::{ - future::{FusedFuture, OptionFuture}, - FutureExt, StreamExt, -}; -use log::*; -use nym_gateway_requests::{ - iv::{IVConversionError, IV}, - types::{BinaryRequest, ServerResponse}, - ClientControlRequest, GatewayRequestsError, -}; -use nym_sphinx::forwarding::packet::MixPacket; -use nym_task::TaskClient; -use nym_validator_client::coconut::CoconutApiError; -use rand::{CryptoRng, Rng}; -use thiserror::Error; -use tokio::io::{AsyncRead, AsyncWrite}; -use tokio_tungstenite::tungstenite::{protocol::Message, Error as WsError}; - -use nym_coconut_interface::CoconutError; -use nym_credentials::coconut::bandwidth::CredentialType; -use std::{convert::TryFrom, process, time::Duration}; - use crate::node::client_handling::bandwidth::BandwidthError; use crate::node::{ client_handling::{ @@ -37,6 +15,26 @@ use crate::node::{ }, storage::{error::StorageError, Storage}, }; +use futures::{ + future::{FusedFuture, OptionFuture}, + FutureExt, StreamExt, +}; +use log::*; +use nym_credentials::coconut::bandwidth::{bandwidth_credential_params, CredentialType}; +use nym_credentials_interface::CoconutError; +use nym_gateway_requests::{ + iv::{IVConversionError, IV}, + types::{BinaryRequest, ServerResponse}, + ClientControlRequest, GatewayRequestsError, +}; +use nym_sphinx::forwarding::packet::MixPacket; +use nym_task::TaskClient; +use nym_validator_client::coconut::CoconutApiError; +use rand::{CryptoRng, Rng}; +use std::{convert::TryFrom, process, time::Duration}; +use thiserror::Error; +use tokio::io::{AsyncRead, AsyncWrite}; +use tokio_tungstenite::tungstenite::{protocol::Message, Error as WsError}; #[derive(Debug, Error)] pub(crate) enum RequestHandlingError { @@ -76,9 +74,6 @@ pub(crate) enum RequestHandlingError { #[error("There was a problem with the proposal id: {reason}")] ProposalIdError { reason: String }, - #[error("Coconut interface error - {0}")] - CoconutInterfaceError(#[from] nym_coconut_interface::error::CoconutInterfaceError), - #[error("coconut failure: {0}")] CoconutError(#[from] CoconutError), @@ -257,7 +252,8 @@ where let bandwidth = Bandwidth::try_from_raw_value(bandwidth_attribute, credential.data.typ)?; - if !credential.data.verify(&aggregated_verification_key) { + let params = bandwidth_credential_params(); + if !credential.data.verify(params, &aggregated_verification_key) { return Err(RequestHandlingError::InvalidBandwidthCredential( String::from("credential failed to verify on gateway"), )); diff --git a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs index e62d6afa5a..7515157b55 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs @@ -3,7 +3,7 @@ use super::authenticated::RequestHandlingError; use log::*; -use nym_coconut_interface::{Credential, VerificationKey}; +use nym_credentials_interface::VerificationKey; use nym_gateway_requests::models::CredentialSpendingWithEpoch; use nym_validator_client::coconut::all_coconut_api_clients; use nym_validator_client::nym_api::EpochId; @@ -229,7 +229,8 @@ impl CoconutVerifier { } let req = nym_api_requests::coconut::VerifyCredentialBody::new( - credential, + credential.data, + credential.epoch_id, proposal_id, self.address.clone(), ); diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 579a98d991..db80920086 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -78,7 +78,6 @@ zeroize = { workspace = true } 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-ephemera-common = { path = "../common/cosmwasm-smart-contracts/ephemera" } nym-config = { path = "../common/config" } cosmwasm-std = { workspace = true } diff --git a/nym-api/nym-api-requests/Cargo.toml b/nym-api/nym-api-requests/Cargo.toml index aaf7309fcf..1baf4d17dd 100644 --- a/nym-api/nym-api-requests/Cargo.toml +++ b/nym-api/nym-api-requests/Cargo.toml @@ -16,9 +16,7 @@ serde = { workspace = true, features = ["derive"] } ts-rs = { workspace = true, optional = true } tendermint = { workspace = true } -nym-coconut = { path = "../../common/nymcoconut" } -nym-coconut-interface = { path = "../../common/coconut-interface" } -#nym-credentials = { path = "../../common/credentials" } +nym-credentials-interface = { path = "../../common/credentials-interface" } nym-crypto = { path = "../../common/crypto", features = ["serde", "asymmetric"]} nym-mixnet-contract-common = { path= "../../common/cosmwasm-smart-contracts/mixnet-contract" } diff --git a/nym-api/nym-api-requests/src/coconut/helpers.rs b/nym-api/nym-api-requests/src/coconut/helpers.rs index 58aec3eca0..73d1a7f42f 100644 --- a/nym-api/nym-api-requests/src/coconut/helpers.rs +++ b/nym-api/nym-api-requests/src/coconut/helpers.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use nym_coconut_interface::BlindedSignature; +use nym_credentials_interface::BlindedSignature; use tendermint::hash::Hash; // recomputes plaintext on the credential nym-api has used for signing diff --git a/nym-api/nym-api-requests/src/coconut/models.rs b/nym-api/nym-api-requests/src/coconut/models.rs index 15efe1a9f6..ce58d8a05e 100644 --- a/nym-api/nym-api-requests/src/coconut/models.rs +++ b/nym-api/nym-api-requests/src/coconut/models.rs @@ -3,9 +3,9 @@ use crate::coconut::helpers::issued_credential_plaintext; use cosmrs::AccountId; -use nym_coconut::{ +use nym_credentials_interface::{ hash_to_scalar, Attribute, BlindSignRequest, BlindedSignature, Bytable, CoconutError, - Signature, VerificationKey, + CredentialSpendingData, Signature, VerificationKey, }; use nym_crypto::asymmetric::identity; use serde::{Deserialize, Serialize}; @@ -15,7 +15,7 @@ use tendermint::hash::Hash; #[derive(Serialize, Deserialize)] pub struct VerifyCredentialBody { /// The cryptographic material required for spending the underlying credential. - pub credential_data: (), + pub credential_data: CredentialSpendingData, /// The (DKG) epoch id under which the credential has been issued so that the verifier /// could use correct verification key for validation. @@ -30,7 +30,7 @@ pub struct VerifyCredentialBody { impl VerifyCredentialBody { pub fn new( - credential_data: (), + credential_data: CredentialSpendingData, epoch_id: u64, proposal_id: u64, gateway_cosmos_addr: AccountId, @@ -100,7 +100,7 @@ impl BlindSignRequestBody { } pub fn encode_commitments(&self) -> Vec { - use nym_coconut_interface::Base58; + use nym_credentials_interface::Base58; self.inner_sign_request .get_private_attributes_pedersen_commitments() diff --git a/nym-api/src/coconut/api_routes/mod.rs b/nym-api/src/coconut/api_routes/mod.rs index c8a739319d..8a276d5e2d 100644 --- a/nym-api/src/coconut/api_routes/mod.rs +++ b/nym-api/src/coconut/api_routes/mod.rs @@ -17,7 +17,9 @@ use nym_coconut_bandwidth_contract_common::spend_credential::{ funds_from_cosmos_msgs, SpendCredentialStatus, }; use nym_coconut_dkg_common::types::EpochId; -use nym_credentials::coconut::bandwidth::IssuanceBandwidthCredential; +use nym_credentials::coconut::bandwidth::{ + bandwidth_credential_params, IssuanceBandwidthCredential, +}; use nym_validator_client::nyxd::Coin; use rocket::serde::json::Json; use rocket::State as RocketState; @@ -93,15 +95,22 @@ pub async fn verify_bandwidth_credential( state: &RocketState, ) -> Result> { let proposal_id = verify_credential_body.proposal_id; - let proposal = state.client.get_proposal(proposal_id).await?; + let epoch_id = verify_credential_body.epoch_id; + let credential_data = &verify_credential_body.credential_data; + let theta = &credential_data.verify_credential_request; + + let voucher_value: u64 = if credential_data.typ.is_voucher() { + todo!() + } else { + todo!("return error here") + }; // TODO: introduce a check to make sure we haven't already voted for this proposal to prevent DDOS + let proposal = state.client.get_proposal(proposal_id).await?; + // Proposal description is the blinded serial number - if !verify_credential_body - .credential - .has_blinded_serial_number(&proposal.description)? - { + if !theta.has_blinded_serial_number(&proposal.description)? { return Err(CoconutError::IncorrectProposal { reason: String::from("incorrect blinded serial number in description"), }); @@ -113,7 +122,7 @@ pub async fn verify_bandwidth_credential( // Credential has not been spent before, and is on its way of being spent let credential_status = state .client - .get_spent_credential(verify_credential_body.credential.blinded_serial_number()) + .get_spent_credential(theta.blinded_serial_number_bs58()) .await? .spend_credential .ok_or(CoconutError::InvalidCredentialStatus { @@ -125,16 +134,12 @@ pub async fn verify_bandwidth_credential( status: format!("{:?}", credential_status), }); } - let verification_key = state - .verification_key(*verify_credential_body.credential.epoch_id()) - .await?; - let mut vote_yes = verify_credential_body.credential.verify(&verification_key); + let verification_key = state.verification_key(epoch_id).await?; + let params = bandwidth_credential_params(); + let mut vote_yes = credential_data.verify(params, &verification_key); vote_yes &= Coin::from(proposed_release_funds) - == Coin::new( - verify_credential_body.credential.voucher_value() as u128, - state.mix_denom.clone(), - ); + == Coin::new(voucher_value as u128, state.mix_denom.clone()); // Vote yes or no on the proposal based on the verification result let ret = state diff --git a/nym-api/src/coconut/comm.rs b/nym-api/src/coconut/comm.rs index 0cb84fc894..2019d99650 100644 --- a/nym-api/src/coconut/comm.rs +++ b/nym-api/src/coconut/comm.rs @@ -4,8 +4,8 @@ use crate::coconut::error::Result; use crate::nyxd; use crate::support::nyxd::ClientInner; +use nym_coconut::VerificationKey; use nym_coconut_dkg_common::types::{Epoch, EpochId}; -use nym_coconut_interface::VerificationKey; use nym_credentials::coconut::utils::obtain_aggregate_verification_key; use nym_validator_client::coconut::all_coconut_api_clients; use nym_validator_client::nyxd::contract_traits::DkgQueryClient; diff --git a/nym-api/src/coconut/dkg/key_derivation.rs b/nym-api/src/coconut/dkg/key_derivation.rs index db86ec39a5..eb6c5b7214 100644 --- a/nym-api/src/coconut/dkg/key_derivation.rs +++ b/nym-api/src/coconut/dkg/key_derivation.rs @@ -10,10 +10,10 @@ use crate::coconut::keys::KeyPairWithEpoch; use crate::coconut::state::bandwidth_credential_params; use cosmwasm_std::Addr; use log::debug; +use nym_coconut::KeyPair as CoconutKeyPair; use nym_coconut::{check_vk_pairing, Base58, SecretKey, VerificationKey}; use nym_coconut_dkg_common::event_attributes::DKG_PROPOSAL_ID; use nym_coconut_dkg_common::types::{DealingIndex, EpochId, NodeIndex}; -use nym_coconut_interface::KeyPair as CoconutKeyPair; use nym_dkg::{ bte::{self, decrypt_share}, combine_shares, try_recover_verification_keys, Dealing, diff --git a/nym-api/src/coconut/error.rs b/nym-api/src/coconut/error.rs index 423574db8d..4f464ef175 100644 --- a/nym-api/src/coconut/error.rs +++ b/nym-api/src/coconut/error.rs @@ -87,9 +87,6 @@ pub enum CoconutError { #[error("public attributes in request differ from the ones in deposit: Expected {0}, got {1}")] DifferentPublicAttributes(String, String), - #[error("error in coconut interface: {0}")] - CoconutInterfaceError(#[from] nym_coconut_interface::error::CoconutInterfaceError), - #[error("storage error: {0}")] StorageError(#[from] NymApiStorageError), diff --git a/nym-api/src/coconut/helpers.rs b/nym-api/src/coconut/helpers.rs index e5778674e6..ee55f9ff1d 100644 --- a/nym-api/src/coconut/helpers.rs +++ b/nym-api/src/coconut/helpers.rs @@ -28,7 +28,7 @@ pub(crate) fn blind_sign( let public_attributes = request.public_attributes_hashed(); let attributes_ref = public_attributes.iter().collect::>(); - Ok(nym_coconut_interface::blind_sign( + Ok(nym_coconut::blind_sign( bandwidth_credential_params(), signing_key, &request.inner_sign_request, diff --git a/nym-api/src/coconut/keys/mod.rs b/nym-api/src/coconut/keys/mod.rs index 117c512b9e..7c719c7a53 100644 --- a/nym-api/src/coconut/keys/mod.rs +++ b/nym-api/src/coconut/keys/mod.rs @@ -18,12 +18,12 @@ pub struct KeyPair { #[derive(Debug)] pub struct KeyPairWithEpoch { - pub(crate) keys: nym_coconut_interface::KeyPair, + pub(crate) keys: nym_coconut::KeyPair, pub(crate) issued_for_epoch: EpochId, } impl KeyPairWithEpoch { - pub(crate) fn new(keys: nym_coconut_interface::KeyPair, issued_for_epoch: EpochId) -> Self { + pub(crate) fn new(keys: nym_coconut::KeyPair, issued_for_epoch: EpochId) -> Self { KeyPairWithEpoch { keys, issued_for_epoch, diff --git a/nym-api/src/coconut/state.rs b/nym-api/src/coconut/state.rs index 6bf4159c2e..d92a5d6f81 100644 --- a/nym-api/src/coconut/state.rs +++ b/nym-api/src/coconut/state.rs @@ -10,8 +10,8 @@ use crate::coconut::storage::CoconutStorageExt; use crate::support::storage::NymApiStorage; use nym_api_requests::coconut::helpers::issued_credential_plaintext; use nym_api_requests::coconut::BlindSignRequestBody; +use nym_coconut::{BlindedSignature, VerificationKey}; use nym_coconut_dkg_common::types::EpochId; -use nym_coconut_interface::{BlindedSignature, VerificationKey}; use nym_crypto::asymmetric::identity; use nym_validator_client::nyxd::{Hash, TxResponse}; use std::sync::Arc; diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 555390c706..2cfd6ab068 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -3694,8 +3694,7 @@ dependencies = [ "cosmrs", "cosmwasm-std", "getset", - "nym-coconut", - "nym-coconut-interface", + "nym-credentials-interface", "nym-crypto", "nym-mixnet-contract-common", "nym-node-requests", @@ -3710,9 +3709,10 @@ version = "0.1.0" dependencies = [ "bip39", "log", - "nym-coconut-interface", + "nym-coconut", "nym-credential-storage", "nym-credentials", + "nym-credentials-interface", "nym-crypto", "nym-network-defaults", "nym-validator-client", @@ -3830,17 +3830,6 @@ dependencies = [ "nym-multisig-contract-common", ] -[[package]] -name = "nym-coconut-interface" -version = "0.1.0" -dependencies = [ - "bs58 0.4.0", - "getset", - "nym-coconut", - "serde", - "thiserror", -] - [[package]] name = "nym-config" version = "0.1.0" @@ -3937,7 +3926,7 @@ dependencies = [ "cosmrs", "log", "nym-api-requests", - "nym-coconut-interface", + "nym-credentials-interface", "nym-crypto", "nym-validator-client", "serde", @@ -3946,6 +3935,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-credentials-interface" +version = "0.1.0" +dependencies = [ + "bls12_381", + "nym-coconut", + "serde", +] + [[package]] name = "nym-crypto" version = "0.4.0" @@ -4074,8 +4072,8 @@ dependencies = [ "futures", "generic-array 0.14.7", "log", - "nym-coconut-interface", "nym-credentials", + "nym-credentials-interface", "nym-crypto", "nym-pemstore", "nym-sphinx", @@ -4505,9 +4503,9 @@ dependencies = [ "itertools", "log", "nym-api-requests", + "nym-coconut", "nym-coconut-bandwidth-contract-common", "nym-coconut-dkg-common", - "nym-coconut-interface", "nym-config", "nym-contracts-common", "nym-ephemera-common", diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index b5dfb64b97..8c3109210f 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -3098,8 +3098,7 @@ dependencies = [ "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "getset", - "nym-coconut", - "nym-coconut-interface", + "nym-credentials-interface", "nym-crypto", "nym-mixnet-contract-common", "nym-node-requests", @@ -3167,17 +3166,6 @@ dependencies = [ "nym-multisig-contract-common", ] -[[package]] -name = "nym-coconut-interface" -version = "0.1.0" -dependencies = [ - "bs58 0.4.0", - "getset", - "nym-coconut", - "serde", - "thiserror", -] - [[package]] name = "nym-config" version = "0.1.0" @@ -3203,6 +3191,15 @@ dependencies = [ "thiserror", ] +[[package]] +name = "nym-credentials-interface" +version = "0.1.0" +dependencies = [ + "bls12_381", + "nym-coconut", + "serde", +] + [[package]] name = "nym-crypto" version = "0.4.0" @@ -3401,7 +3398,6 @@ dependencies = [ "hmac 0.12.1", "itertools 0.11.0", "log", - "nym-coconut-interface", "nym-config", "nym-crypto", "nym-mixnet-contract-common", @@ -3442,9 +3438,9 @@ dependencies = [ "itertools 0.10.5", "log", "nym-api-requests", + "nym-coconut", "nym-coconut-bandwidth-contract-common", "nym-coconut-dkg-common", - "nym-coconut-interface", "nym-config", "nym-contracts-common", "nym-ephemera-common", @@ -3546,7 +3542,6 @@ dependencies = [ "itertools 0.10.5", "k256 0.13.1", "log", - "nym-coconut-interface", "nym-config", "nym-contracts-common", "nym-crypto", diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index 854aa1d57f..a9b72b234e 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -57,7 +57,6 @@ nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" } nym-vesting-contract-common = { path = "../../common/cosmwasm-smart-contracts/vesting-contract" } nym-config = { path = "../../common/config" } -nym-coconut-interface = { path = "../../common/coconut-interface" } nym-types = { path = "../../common/types" } nym-wallet-types = { path = "../nym-wallet-types" } nym-store-cipher = { path = "../../common/store-cipher", features = ["json"] }