Skip to content

Commit

Permalink
fix proofs for revealed only
Browse files Browse the repository at this point in the history
  • Loading branch information
sdbondi committed Jul 24, 2024
1 parent c2daa70 commit 63cbf08
Show file tree
Hide file tree
Showing 14 changed files with 131 additions and 81 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 11 additions & 6 deletions applications/tari_dan_wallet_daemon/src/handlers/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,17 +363,21 @@ pub async fn handle_reveal_funds(
sender_public_nonce: public_nonce,
minimum_value_promise: 0,
encrypted_data,
reveal_amount: amount_to_reveal,
resource_view_key: None,
};

let inputs = sdk
.confidential_outputs_api()
.resolve_output_masks(inputs, key_manager::TRANSACTION_BRANCH)?;

let reveal_proof =
sdk.confidential_crypto_api()
.generate_withdraw_proof(&inputs, Amount::zero(), &output_statement, None)?;
let reveal_proof = sdk.confidential_crypto_api().generate_withdraw_proof(
&inputs,
Amount::zero(),
Some(&output_statement),
amount_to_reveal,
None,
Amount::zero(),
)?;

info!(
target: LOG_TARGET,
Expand Down Expand Up @@ -590,15 +594,16 @@ pub async fn handle_claim_burn(
sender_public_nonce: output_public_nonce,
minimum_value_promise: 0,
encrypted_data,
reveal_amount: max_fee,
resource_view_key: None,
};

let reveal_proof = sdk.confidential_crypto_api().generate_withdraw_proof(
&[unmasked_output],
Amount::zero(),
&output_statement,
Some(&output_statement).filter(|o| !o.amount.is_zero()),
max_fee,
None,
Amount::zero(),
)?;

let instructions = vec![Instruction::ClaimBurn {
Expand Down
11 changes: 6 additions & 5 deletions applications/tari_dan_wallet_daemon/src/handlers/confidential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ pub async fn handle_create_transfer_proof(
sender_public_nonce: public_nonce,
minimum_value_promise: 0,
encrypted_data,
reveal_amount: req.reveal_amount,
resource_view_key: resource_view_key.clone(),
};

Expand Down Expand Up @@ -155,7 +154,6 @@ pub async fn handle_create_transfer_proof(
sender_public_nonce: public_nonce,
encrypted_data,
minimum_value_promise: 0,
reveal_amount: Amount::zero(),
resource_view_key,
})
} else {
Expand All @@ -170,8 +168,10 @@ pub async fn handle_create_transfer_proof(
&inputs,
// TODO: support for using revealed funds as input for proof generation
Amount::zero(),
&output_statement,
Some(&output_statement).filter(|o| !o.amount.is_zero()),
req.reveal_amount,
maybe_change_statement.as_ref(),
Amount::zero(),
)?;

Ok(ProofsGenerateResponse { proof_id, proof })
Expand Down Expand Up @@ -230,11 +230,12 @@ pub async fn handle_create_output_proof(
sender_public_nonce: public_nonce,
minimum_value_promise: 0,
encrypted_data,
reveal_amount: Amount::zero(),
// TODO: the request must include the resource address so that we can fetch the view key
resource_view_key: None,
};
let proof = sdk.confidential_crypto_api().generate_output_proof(&statement)?;
let proof = sdk
.confidential_crypto_api()
.generate_output_proof(&statement, Amount::zero())?;
Ok(ConfidentialCreateOutputProofResponse { proof })
}

Expand Down
1 change: 1 addition & 0 deletions dan_layer/engine_types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ serde = { workspace = true, default-features = true }
serde_json = { workspace = true }
thiserror = { workspace = true }
ts-rs = { workspace = true, optional = true }
log = { workspace = true }

[features]
default = []
Expand Down
10 changes: 8 additions & 2 deletions dan_layer/engine_types/src/confidential/withdraw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,20 @@ pub(crate) fn validate_confidential_withdraw<'a, I: IntoIterator<Item = &'a Comm
.map(|output| output.commitment.as_public_key())
.unwrap_or(&PublicKey::default());

let message = challenges::confidential_withdraw64(
const LOG_TARGET: &str = "tari::dan::engine::confidential::withdraw";
log::error!(target: LOG_TARGET, "🐞public_excess: {public_excess}");
log::error!(target: LOG_TARGET, "🐞public_nonce: {}", balance_proof.get_public_nonce());
log::error!(target: LOG_TARGET, "🐞input_revealed_amount: {input_revealed_amount}");
log::error!(target: LOG_TARGET, "🐞total_output_revealed_amount: {total_output_revealed_amount}");

let challenge = challenges::confidential_withdraw64(
&public_excess,
balance_proof.get_public_nonce(),
input_revealed_amount,
total_output_revealed_amount,
);

if !balance_proof.verify_raw_uniform(&public_excess, &message) {
if !balance_proof.verify_raw_uniform(&public_excess, &challenge) {
return Err(ResourceError::InvalidBalanceProof {
details: "Balance proof was invalid".to_string(),
});
Expand Down
18 changes: 10 additions & 8 deletions dan_layer/template_test_tooling/src/support/confidential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ fn generate_confidential_proof_internal(
sender_public_nonce: Default::default(),
minimum_value_promise: 0,
encrypted_data: Default::default(),
reveal_amount: Default::default(),
resource_view_key: view_key.clone(),
};

Expand All @@ -49,13 +48,16 @@ fn generate_confidential_proof_internal(
sender_public_nonce: Default::default(),
minimum_value_promise: 0,
encrypted_data: Default::default(),
reveal_amount: Default::default(),
resource_view_key: view_key,
});

let proof =
tari_dan_wallet_crypto::create_confidential_output_statement(&output_statement, change_statement.as_ref())
.unwrap();
let proof = tari_dan_wallet_crypto::create_confidential_output_statement(
Some(&output_statement),
Amount::zero(),
change_statement.as_ref(),
Amount::zero(),
)
.unwrap();
(proof, mask, change.map(|_| change_mask))
}

Expand Down Expand Up @@ -147,7 +149,6 @@ fn generate_withdraw_proof_internal(
sender_public_nonce: Default::default(),
minimum_value_promise: 0,
encrypted_data: Default::default(),
reveal_amount: revealed_output_amount,
resource_view_key: view_key.clone(),
};
let change_proof = change_amount.map(|amount| ConfidentialProofStatement {
Expand All @@ -156,7 +157,6 @@ fn generate_withdraw_proof_internal(
sender_public_nonce: Default::default(),
minimum_value_promise: 0,
encrypted_data: Default::default(),
reveal_amount: Default::default(),
resource_view_key: view_key,
});

Expand All @@ -169,8 +169,10 @@ fn generate_withdraw_proof_internal(
})
.collect::<Vec<_>>(),
input_revealed_amount,
&output_proof,
Some(&output_proof),
revealed_output_amount,
change_proof.as_ref(),
Amount::zero(),
)
.unwrap();

Expand Down
1 change: 1 addition & 0 deletions dan_layer/wallet/crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ digest = { workspace = true }
rand = { workspace = true }
thiserror = { workspace = true }
zeroize = { workspace = true }
log = { workspace = true }

[dev-dependencies]
tari_template_test_tooling = { workspace = true }
32 changes: 25 additions & 7 deletions dan_layer/wallet/crypto/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,17 @@ use crate::{
pub fn create_withdraw_proof(
inputs: &[ConfidentialOutputMaskAndValue],
input_revealed_amount: Amount,
output_statement: &ConfidentialProofStatement,
output_statement: Option<&ConfidentialProofStatement>,
output_revealed_amount: Amount,
change_statement: Option<&ConfidentialProofStatement>,
change_revealed_amount: Amount,
) -> Result<ConfidentialWithdrawProof, WalletCryptoError> {
let output_proof = create_confidential_output_statement(output_statement, change_statement)?;
let output_proof = create_confidential_output_statement(
output_statement,
output_revealed_amount,
change_statement,
change_revealed_amount,
)?;
let (input_commitments, agg_input_mask) = inputs.iter().fold(
(Vec::with_capacity(inputs.len()), RistrettoSecretKey::default()),
|(mut commitments, agg_input), input| {
Expand All @@ -44,7 +51,7 @@ pub fn create_withdraw_proof(
let balance_proof = generate_balance_proof(
&agg_input_mask,
input_revealed_amount,
&output_statement.mask,
output_statement.as_ref().map(|o| &o.mask),
change_statement.as_ref().map(|ch| &ch.mask),
output_revealed_amount,
);
Expand Down Expand Up @@ -139,17 +146,28 @@ fn create_commitment(mask: &RistrettoSecretKey, value: u64) -> PedersenCommitmen
fn generate_balance_proof(
input_mask: &RistrettoSecretKey,
input_revealed_amount: Amount,
output_mask: &RistrettoSecretKey,
output_mask: Option<&RistrettoSecretKey>,
change_mask: Option<&RistrettoSecretKey>,
output_reveal_amount: Amount,
) -> BalanceProofSignature {
let secret_excess = input_mask - output_mask - change_mask.unwrap_or(&RistrettoSecretKey::default());
let secret_excess = input_mask -
output_mask.unwrap_or(&RistrettoSecretKey::default()) -
change_mask.unwrap_or(&RistrettoSecretKey::default());
if secret_excess == RistrettoSecretKey::default() {
// This is a revealed only proof
return BalanceProofSignature::zero();
}
let excess = RistrettoPublicKey::from_secret_key(&secret_excess);
let (nonce, public_nonce) = RistrettoPublicKey::random_keypair(&mut OsRng);
let challenge =
const LOG_TARGET: &str = "tari::dan::wallet::confidential::withdraw";
log::error!(target: LOG_TARGET, "🐞W public_excess: {excess}");
log::error!(target: LOG_TARGET, "🐞W public_nonce: {}", public_nonce);
log::error!(target: LOG_TARGET, "🐞W input_revealed_amount: {input_revealed_amount}");
log::error!(target: LOG_TARGET, "🐞W output_revealed_amount: {output_reveal_amount}");
let message =
challenges::confidential_withdraw64(&excess, &public_nonce, input_revealed_amount, output_reveal_amount);

let sig = RistrettoSchnorr::sign_raw_uniform(&secret_excess, nonce, &challenge).unwrap();
let sig = RistrettoSchnorr::sign_raw_uniform(&secret_excess, nonce, &message).unwrap();
BalanceProofSignature::try_from_parts(sig.get_public_nonce().as_bytes(), sig.get_signature().as_bytes()).unwrap()
}

Expand Down
1 change: 0 additions & 1 deletion dan_layer/wallet/crypto/src/confidential_statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ pub struct ConfidentialProofStatement {
pub sender_public_nonce: RistrettoPublicKey,
pub minimum_value_promise: u64,
pub encrypted_data: EncryptedData,
pub reveal_amount: Amount,
pub resource_view_key: Option<RistrettoPublicKey>,
}

Expand Down
48 changes: 24 additions & 24 deletions dan_layer/wallet/crypto/src/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use tari_hashing::TransactionSecureNonceKdfDomain;
use tari_template_lib::{
crypto::RistrettoPublicKeyBytes,
models::{
Amount,
ConfidentialOutputStatement,
ConfidentialStatement,
EncryptedData,
Expand All @@ -54,8 +55,10 @@ use crate::{
};

pub fn create_confidential_output_statement(
output_statement: &ConfidentialProofStatement,
output_statement: Option<&ConfidentialProofStatement>,
output_revealed_amount: Amount,
change_statement: Option<&ConfidentialProofStatement>,
change_revealed_amount: Amount,
) -> Result<ConfidentialOutputStatement, ConfidentialProofError> {
let proof_change_statement = change_statement
.as_ref()
Expand All @@ -78,38 +81,34 @@ pub fn create_confidential_output_statement(
})
})
.transpose()?;

let confidential_output_value = output_statement
.amount
.as_ref()
.map(|o| o.amount)
.unwrap_or_default()
.as_u64_checked()
.ok_or(ConfidentialProofError::NegativeAmount)?;

let proof_output_statement = if confidential_output_value == 0 {
None
} else {
let commitment = output_statement.to_commitment();
let statement = Some(ConfidentialStatement {
let proof_output_statement = output_statement.as_ref().map(|stmt| {
let commitment = stmt.to_commitment();
ConfidentialStatement {
commitment: copy_fixed(commitment.as_bytes()),
sender_public_nonce: copy_fixed(output_statement.sender_public_nonce.as_bytes()),
encrypted_data: output_statement.encrypted_data.clone(),
minimum_value_promise: output_statement.minimum_value_promise,
viewable_balance_proof: output_statement.resource_view_key.as_ref().map(|view_key| {
create_viewable_balance_proof(&output_statement.mask, confidential_output_value, &commitment, view_key)
sender_public_nonce: copy_fixed(stmt.sender_public_nonce.as_bytes()),
encrypted_data: stmt.encrypted_data.clone(),
minimum_value_promise: stmt.minimum_value_promise,
viewable_balance_proof: stmt.resource_view_key.as_ref().map(|view_key| {
create_viewable_balance_proof(&stmt.mask, confidential_output_value, &commitment, view_key)
}),
});

statement
};
}
});

let output_range_proof =
generate_extended_bullet_proof(Some(output_statement).filter(|s| !s.amount.is_zero()), change_statement)?;
let output_range_proof = generate_extended_bullet_proof(output_statement, change_statement)?;

Ok(ConfidentialOutputStatement {
output_statement: proof_output_statement,
change_statement: proof_change_statement,
range_proof: output_range_proof,
output_revealed_amount: output_statement.reveal_amount,
change_revealed_amount: change_statement.map(|stmt| stmt.reveal_amount).unwrap_or_default(),
output_revealed_amount,
change_revealed_amount,
})
}

Expand Down Expand Up @@ -314,16 +313,17 @@ mod tests {
fn create_valid_proof(amount: Amount, minimum_value_promise: u64) -> ConfidentialOutputStatement {
let mask = RistrettoSecretKey::random(&mut OsRng);
create_confidential_output_statement(
&ConfidentialProofStatement {
Some(&ConfidentialProofStatement {
amount,
minimum_value_promise,
mask,
sender_public_nonce: Default::default(),
reveal_amount: Default::default(),
encrypted_data: EncryptedData([0u8; EncryptedData::size()]),
resource_view_key: None,
},
}),
Default::default(),
None,
Default::default(),
)
.unwrap()
}
Expand Down
12 changes: 12 additions & 0 deletions dan_layer/wallet/crypto/tests/output_statement.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright 2024 The Tari Project
// SPDX-License-Identifier: BSD-3-Clause

use tari_dan_wallet_crypto::create_withdraw_proof;
use tari_template_lib::models::Amount;

#[test]
fn it_create_a_valid_revealed_only_proof() {
let proof = create_withdraw_proof(&[], Amount(123), None, Amount(123), None, Amount(0)).unwrap();

assert!(proof.is_revealed_only());
}
Loading

0 comments on commit 63cbf08

Please sign in to comment.