Skip to content

Commit

Permalink
refactor: add keyset_id to blinded_message
Browse files Browse the repository at this point in the history
stop mint from signing if keyset in
blinded_message is not the active keyset
  • Loading branch information
thesimplekid committed Nov 25, 2023
1 parent 6e80a1d commit 2d8c682
Show file tree
Hide file tree
Showing 11 changed files with 61 additions and 29 deletions.
6 changes: 3 additions & 3 deletions bindings/cashu-ffi/src/cashu.udl
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ interface SecretKey {
};

interface BlindedMessage {
constructor(Amount amount, PublicKey b);
constructor(Id keyset_id, Amount amount, PublicKey b);
Amount amount();
PublicKey b();
};
Expand Down Expand Up @@ -100,9 +100,9 @@ interface Token {

interface BlindedMessages {
[Throws=CashuError, Name=random]
constructor(Amount amount);
constructor(Id keyset_id, Amount amount);
[Throws=CashuError, Name=blank]
constructor(Amount fee_reserve);
constructor(Id keyset_id, Amount amount);
sequence<BlindedMessage> blinded_messages();
sequence<Secret> secrets();
sequence<SecretKey> rs();
Expand Down
5 changes: 3 additions & 2 deletions bindings/cashu-ffi/src/nuts/nut00/blinded_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::sync::Arc;
use cashu::nuts::BlindedMessage as BlindedMessageSdk;

use crate::nuts::nut01::public_key::PublicKey;
use crate::Amount;
use crate::{Amount, Id};

pub struct BlindedMessage {
inner: BlindedMessageSdk,
Expand All @@ -18,9 +18,10 @@ impl Deref for BlindedMessage {
}

impl BlindedMessage {
pub fn new(amount: Arc<Amount>, b: Arc<PublicKey>) -> Self {
pub fn new(keyset_id: Arc<Id>, amount: Arc<Amount>, b: Arc<PublicKey>) -> Self {
Self {
inner: BlindedMessageSdk {
keyset_id: *keyset_id.as_ref().deref(),
amount: *amount.as_ref().deref(),
b: b.as_ref().into(),
},
Expand Down
16 changes: 11 additions & 5 deletions bindings/cashu-ffi/src/nuts/nut00/blinded_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::sync::Arc;
use cashu::nuts::nut00::wallet::BlindedMessages as BlindedMessagesSdk;

use crate::error::Result;
use crate::{Amount, BlindedMessage, Secret, SecretKey};
use crate::{Amount, BlindedMessage, Id, Secret, SecretKey};

pub struct BlindedMessages {
inner: BlindedMessagesSdk,
Expand All @@ -18,15 +18,21 @@ impl Deref for BlindedMessages {
}

impl BlindedMessages {
pub fn random(amount: Arc<Amount>) -> Result<Self> {
pub fn random(keyset_id: Arc<Id>, amount: Arc<Amount>) -> Result<Self> {
Ok(Self {
inner: BlindedMessagesSdk::random(*amount.as_ref().deref())?,
inner: BlindedMessagesSdk::random(
*keyset_id.as_ref().deref(),
*amount.as_ref().deref(),
)?,
})
}

pub fn blank(fee_reserve: Arc<Amount>) -> Result<Self> {
pub fn blank(keyset_id: Arc<Id>, fee_reserve: Arc<Amount>) -> Result<Self> {
Ok(Self {
inner: BlindedMessagesSdk::blank(*fee_reserve.as_ref().deref())?,
inner: BlindedMessagesSdk::blank(
*keyset_id.as_ref().deref(),
*fee_reserve.as_ref().deref(),
)?,
})
}

Expand Down
4 changes: 3 additions & 1 deletion bindings/cashu-js/src/nuts/nut00/blinded_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use cashu::nuts::nut00::BlindedMessage;
use wasm_bindgen::prelude::*;

use crate::nuts::nut01::JsPublicKey;
use crate::nuts::nut02::JsId;
use crate::types::amount::JsAmount;

#[wasm_bindgen(js_name = BlindedMessage)]
Expand All @@ -28,9 +29,10 @@ impl From<BlindedMessage> for JsBlindedMessage {
impl JsBlindedMessage {
#[allow(clippy::new_without_default)]
#[wasm_bindgen(constructor)]
pub fn new(amount: JsAmount, b: JsPublicKey) -> Self {
pub fn new(keyset_id: JsId, amount: JsAmount, b: JsPublicKey) -> Self {
Self {
inner: BlindedMessage {
keyset_id: *keyset_id.deref(),
amount: *amount.deref(),
b: b.deref().clone(),
},
Expand Down
11 changes: 7 additions & 4 deletions bindings/cashu-js/src/nuts/nut00/blinded_messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use cashu::nuts::nut00::wallet::BlindedMessages;
use wasm_bindgen::prelude::*;

use crate::error::{into_err, Result};
use crate::nuts::nut02::JsId;
use crate::types::JsAmount;

#[wasm_bindgen(js_name = BlindedMessages)]
Expand All @@ -21,16 +22,18 @@ impl Deref for JsBlindedMessages {
#[wasm_bindgen(js_class = BlindedMessages)]
impl JsBlindedMessages {
#[wasm_bindgen(js_name = random)]
pub fn random(amount: JsAmount) -> Result<JsBlindedMessages> {
pub fn random(keyset_id: JsId, amount: JsAmount) -> Result<JsBlindedMessages> {
Ok(JsBlindedMessages {
inner: BlindedMessages::random(*amount.deref()).map_err(into_err)?,
inner: BlindedMessages::random(*keyset_id.deref(), *amount.deref())
.map_err(into_err)?,
})
}

#[wasm_bindgen(js_name = blank)]
pub fn blank(fee_reserve: JsAmount) -> Result<JsBlindedMessages> {
pub fn blank(keyset_id: JsId, fee_reserve: JsAmount) -> Result<JsBlindedMessages> {
Ok(JsBlindedMessages {
inner: BlindedMessages::blank(*fee_reserve.deref()).map_err(into_err)?,
inner: BlindedMessages::blank(*keyset_id.deref(), *fee_reserve.deref())
.map_err(into_err)?,
})
}

Expand Down
6 changes: 3 additions & 3 deletions bindings/cashu-sdk-ffi/src/cashu_sdk.udl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ interface SecretKey {
};

interface BlindedMessage {
constructor(Amount amount, PublicKey b);
constructor(Id keyset_id, Amount amount, PublicKey b);
Amount amount();
PublicKey b();
};
Expand Down Expand Up @@ -103,9 +103,9 @@ interface Token {

interface BlindedMessages {
[Throws=CashuError, Name=random]
constructor(Amount amount);
constructor(Id keyset_id, Amount amount);
[Throws=CashuError, Name=blank]
constructor(Amount fee_reserve);
constructor(Id keyset_id, Amount amount);
sequence<BlindedMessage> blinded_messages();
sequence<Secret> secrets();
sequence<SecretKey> rs();
Expand Down
10 changes: 9 additions & 1 deletion crates/cashu-sdk/src/mint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,15 @@ impl Mint {
}

fn blind_sign(&self, blinded_message: &BlindedMessage) -> Result<BlindedSignature, Error> {
let BlindedMessage { amount, b } = blinded_message;
let BlindedMessage {
amount,
b,
keyset_id,
} = blinded_message;

if self.active_keyset.id.ne(keyset_id) {
return Err(Error::InactiveKeyset);
}

let Some(key_pair) = self.active_keyset.keys.0.get(amount) else {
// No key for amount
Expand Down
6 changes: 3 additions & 3 deletions crates/cashu-sdk/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl<C: Client> Wallet<C> {

/// Mint Proofs
pub async fn mint(&self, amount: Amount, hash: &str) -> Result<Proofs, Error> {
let blinded_messages = BlindedMessages::random(amount)?;
let blinded_messages = BlindedMessages::random((&self.mint_keys).into(), amount)?;

let mint_res = self
.client
Expand Down Expand Up @@ -173,7 +173,7 @@ impl<C: Client> Wallet<C> {
fn create_split(&self, proofs: Proofs) -> Result<SplitPayload, Error> {
let value = proofs.iter().map(|p| p.amount).sum();

let blinded_messages = BlindedMessages::random(value)?;
let blinded_messages = BlindedMessages::random((&self.mint_keys).into(), value)?;

let split_payload = SplitRequest::new(proofs, blinded_messages.blinded_messages.clone());

Expand Down Expand Up @@ -294,7 +294,7 @@ impl<C: Client> Wallet<C> {
proofs: Proofs,
fee_reserve: Amount,
) -> Result<Melted, Error> {
let blinded = BlindedMessages::blank(fee_reserve)?;
let blinded = BlindedMessages::blank((&self.mint_keys).into(), fee_reserve)?;
let melt_response = self
.client
.post_melt(
Expand Down
3 changes: 3 additions & 0 deletions crates/cashu/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ pub mod mint {
/// Duplicate Proofs sent in request
#[error("Duplicate proofs")]
DuplicateProofs,
/// Keyset id not active
#[error("Keyset id is not active")]
InactiveKeyset,
#[error("`{0}`")]
CustomError(String),
}
Expand Down
21 changes: 15 additions & 6 deletions crates/cashu/src/nuts/nut00.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ pub struct BlindedMessage {
/// encrypted secret message (B_)
#[serde(rename = "B_")]
pub b: PublicKey,
#[serde(rename = "id")]
pub keyset_id: Id,
}

#[cfg(feature = "wallet")]
Expand All @@ -30,7 +32,7 @@ pub mod wallet {
use super::MintProofs;
use crate::dhke::blind_message;
use crate::error::wallet;
use crate::nuts::{BlindedMessage, Proofs, SecretKey};
use crate::nuts::{BlindedMessage, Id, Proofs, SecretKey};
use crate::secret::Secret;
use crate::url::UncheckedUrl;
use crate::{error, Amount};
Expand All @@ -50,14 +52,18 @@ pub mod wallet {

impl BlindedMessages {
/// Outputs for speceifed amount with random secret
pub fn random(amount: Amount) -> Result<Self, wallet::Error> {
pub fn random(keyset_id: Id, amount: Amount) -> Result<Self, wallet::Error> {
let mut blinded_messages = BlindedMessages::default();

for amount in amount.split() {
let secret = Secret::new();
let (blinded, r) = blind_message(secret.as_bytes(), None)?;

let blinded_message = BlindedMessage { amount, b: blinded };
let blinded_message = BlindedMessage {
amount,
b: blinded,
keyset_id,
};

blinded_messages.secrets.push(secret);
blinded_messages.blinded_messages.push(blinded_message);
Expand All @@ -69,7 +75,7 @@ pub mod wallet {
}

/// Blank Outputs used for NUT-08 change
pub fn blank(fee_reserve: Amount) -> Result<Self, wallet::Error> {
pub fn blank(keyset_id: Id, fee_reserve: Amount) -> Result<Self, wallet::Error> {
let mut blinded_messages = BlindedMessages::default();

let fee_reserve = bitcoin::Amount::from_sat(fee_reserve.to_sat());
Expand All @@ -87,6 +93,7 @@ pub mod wallet {
let blinded_message = BlindedMessage {
amount: Amount::ZERO,
b: blinded,
keyset_id,
};

blinded_messages.secrets.push(secret);
Expand Down Expand Up @@ -303,10 +310,12 @@ mod tests {

#[test]
fn test_blank_blinded_messages() {
let b = BlindedMessages::blank(Amount::from_sat(1000)).unwrap();
// TODO: Need to update id to new type in proof
let b = BlindedMessages::blank(Id::from_str("").unwrap(), Amount::from_sat(1000)).unwrap();
assert_eq!(b.blinded_messages.len(), 10);

let b = BlindedMessages::blank(Amount::from_sat(1)).unwrap();
// TODO: Need to update id to new type in proof
let b = BlindedMessages::blank(Id::from_str("").unwrap(), Amount::from_sat(1)).unwrap();
assert_eq!(b.blinded_messages.len(), 1);
}
}
2 changes: 1 addition & 1 deletion crates/cashu/src/nuts/nut02.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl std::fmt::Display for Id {
f.write_str(&format!(
"{}{}",
self.version,
String::from_utf8(self.id.to_vec()).map_err(|_| fmt::Error::default())?
String::from_utf8(self.id.to_vec()).map_err(|_| fmt::Error)?
))
}
}
Expand Down

0 comments on commit 2d8c682

Please sign in to comment.