Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
hansieodendaal committed May 10, 2023
1 parent 8740fd0 commit 08e8a4b
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -258,11 +258,12 @@ mod test {
EncryptedOpenings::decrypt_openings(&encryption_key, &commitment, &encrypted_openings).unwrap();
assert_eq!(amount, decrypted_value);
assert_eq!(mask, decrypted_mask);
if let Ok((decrypted_value, decrypted_mask)) = EncryptedOpenings::decrypt_openings(&PrivateKey::random(&mut OsRng), &commitment, &encrypted_openings) {
if let Ok((decrypted_value, decrypted_mask)) =
EncryptedOpenings::decrypt_openings(&PrivateKey::random(&mut OsRng), &commitment, &encrypted_openings)
{
assert_ne!(amount, decrypted_value);
assert_ne!(mask, decrypted_mask);
}

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ pub enum TransactionError {
NonCoinbaseHasOutputFeaturesCoinbaseExtra,
#[error("Coinbase extra size is {len} but the maximum is {max}")]
InvalidOutputFeaturesCoinbaseExtraSize { len: usize, max: u32 },
#[error("Invalid revealed value : {0}")]
InvalidRevealedValue(String),
}

impl From<CovenantError> for TransactionError {
Expand Down
23 changes: 16 additions & 7 deletions base_layer/core/src/transactions/transaction_components/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,15 +444,24 @@ fn test_output_recover_openings() {
value: v,
..Default::default()
});
let output = unblinded_output
.as_transaction_output(&factories)
.unwrap();
let output = unblinded_output.as_transaction_output(&factories).unwrap();

if let Ok((value, recovered_mask)) = EncryptedOpenings::decrypt_openings(&random_key, &output.commitment, &output.encrypted_openings) {
assert!(output.verify_mask(&factories.range_proof, &recovered_mask, value.as_u64()).is_err());
if let Ok((value, recovered_mask)) =
EncryptedOpenings::decrypt_openings(&random_key, &output.commitment, &output.encrypted_openings)
{
assert!(output
.verify_mask(&factories.range_proof, &recovered_mask, value.as_u64())
.is_err());
}
let (value, recovered_mask) = EncryptedOpenings::decrypt_openings(&test_params.rewind_data.encryption_key, &output.commitment, &output.encrypted_openings).unwrap();
assert!(output.verify_mask(&factories.range_proof, &recovered_mask, value.as_u64()).is_ok());
let (value, recovered_mask) = EncryptedOpenings::decrypt_openings(
&test_params.rewind_data.encryption_key,
&output.commitment,
&output.encrypted_openings,
)
.unwrap();
assert!(output
.verify_mask(&factories.range_proof, &recovered_mask, value.as_u64())
.is_ok());
assert_eq!(recovered_mask, test_params.spend_key);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,27 +301,6 @@ impl TransactionOutput {
Ok(())
}

/// Attempt to rewind the range proof to reveal the mask (blinding factor)
pub fn recover_mask(
&self,
prover: &RangeProofService,
rewind_blinding_key: &PrivateKey,
) -> Result<BlindingFactor, TransactionError> {
let statement_private = RistrettoAggregatedPrivateStatement::init(
vec![RistrettoStatement {
commitment: self.commitment.clone(),
minimum_value_promise: self.minimum_value_promise.as_u64(),
}],
Some(rewind_blinding_key.clone()),
)?;
match prover.recover_extended_mask(&self.proof.0, &statement_private)? {
Some(extended_mask) => Ok(extended_mask.secrets()[0].clone()),
None => Err(TransactionError::RangeProofError(RangeProofError::InvalidRewind(
"Empty mask".to_string(),
))),
}
}

/// Attempt to verify a recovered mask (blinding factor) for a proof against the commitment.
pub fn verify_mask(
&self,
Expand Down Expand Up @@ -417,8 +396,9 @@ impl TransactionOutput {
covenant: &Covenant,
encrypted_openings: &EncryptedOpenings,
minimum_value_promise: MicroTari,
range_proof_type: RangeProofType,
) -> Result<ComAndPubSignature, TransactionError> {
let nonce_a = PrivateKey::random(&mut OsRng);
let nonce_a = TransactionOutput::nonce_a(range_proof_type, value, minimum_value_promise)?;
let nonce_b = PrivateKey::random(&mut OsRng);
let nonce_commitment = CommitmentFactory::default().commit(&nonce_b, &nonce_a);
let pk_value = PrivateKey::from(value.as_u64());
Expand Down Expand Up @@ -491,6 +471,26 @@ impl TransactionOutput {
)?)
}

// With RevealedValue type range proofs, the nonce is always 0 and the minimum value promise equal to the value
fn nonce_a(
range_proof_type: RangeProofType,
value: MicroTari,
minimum_value_promise: MicroTari,
) -> Result<PrivateKey, TransactionError> {
match range_proof_type {
RangeProofType::BulletProofPlus => Ok(PrivateKey::random(&mut OsRng)),
RangeProofType::RevealedValue => {
if minimum_value_promise != value {
return Err(TransactionError::InvalidRevealedValue(format!(
"Expected {}, received {}",
value, minimum_value_promise
)));
}
Ok(PrivateKey::default())
},
}
}

// Create complete commitment signature if you are both the sender and receiver
pub fn create_metadata_signature(
version: TransactionOutputVersion,
Expand All @@ -502,8 +502,9 @@ impl TransactionOutput {
covenant: &Covenant,
encrypted_openings: &EncryptedOpenings,
minimum_value_promise: MicroTari,
range_proof_type: RangeProofType,
) -> Result<ComAndPubSignature, TransactionError> {
let nonce_a = PrivateKey::random(&mut OsRng);
let nonce_a = TransactionOutput::nonce_a(range_proof_type, value, minimum_value_promise)?;
let nonce_b = PrivateKey::random(&mut OsRng);
let nonce_commitment = CommitmentFactory::default().commit(&nonce_b, &nonce_a);
let nonce_x = PrivateKey::random(&mut OsRng);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,14 @@ use tari_crypto::{
use tari_key_manager::key_manager_service::KeyManagerInterface;
use tari_script::{inputs, script, Opcode};

use crate::{
output_manager_service::{
error::{OutputManagerError, OutputManagerStorageError},
handle::RecoveredOutput,
resources::OutputManagerKeyManagerBranch,
storage::{
database::{OutputManagerBackend, OutputManagerDatabase},
models::DbUnblindedOutput,
OutputSource,
},
use crate::output_manager_service::{
error::{OutputManagerError, OutputManagerStorageError},
handle::RecoveredOutput,
resources::OutputManagerKeyManagerBranch,
storage::{
database::{OutputManagerBackend, OutputManagerDatabase},
models::DbUnblindedOutput,
OutputSource,
},
};

Expand Down
4 changes: 3 additions & 1 deletion base_layer/wallet/src/output_manager_service/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2642,7 +2642,9 @@ where

for (output, output_source, script_private_key, shared_secret) in scanned_outputs {
let encryption_key = shared_secret_to_output_encryption_key(&shared_secret)?;
if let Ok((committed_value, blinding_factor)) = EncryptedOpenings::decrypt_openings(&encryption_key, &output.commitment, &output.encrypted_openings) {
if let Ok((committed_value, blinding_factor)) =
EncryptedOpenings::decrypt_openings(&encryption_key, &output.commitment, &output.encrypted_openings)
{
if output.verify_mask(
&self.resources.factories.range_proof,
&blinding_factor,
Expand Down

0 comments on commit 08e8a4b

Please sign in to comment.