mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-11 21:49:26 +00:00
Move amount_decryption into EncryptedAmount::decrypt
This commit is contained in:
@@ -189,7 +189,7 @@ impl Bulletproof {
|
|||||||
self.write_core(w, |points, w| write_vec(write_point, points, w))
|
self.write_core(w, |points, w| write_vec(write_point, points, w))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Serialize the Bulletproof(+) to a Vec<u8>.
|
/// Serialize the Bulletproof(+) to a `Vec<u8>`.
|
||||||
pub fn serialize(&self) -> Vec<u8> {
|
pub fn serialize(&self) -> Vec<u8> {
|
||||||
let mut serialized = vec![];
|
let mut serialized = vec![];
|
||||||
self.write(&mut serialized).unwrap();
|
self.write(&mut serialized).unwrap();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use curve25519_dalek::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
hash, hash_to_scalar, serialize::write_varint, ringct::EncryptedAmount, transaction::Input,
|
hash, hash_to_scalar, serialize::write_varint, Commitment, ringct::EncryptedAmount, transaction::Input,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod extra;
|
pub mod extra;
|
||||||
@@ -94,15 +94,20 @@ pub(crate) fn commitment_mask(shared_key: Scalar) -> Scalar {
|
|||||||
hash_to_scalar(&mask)
|
hash_to_scalar(&mask)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn amount_encryption(amount: u64, key: Scalar) -> [u8; 8] {
|
pub(crate) fn compact_amount_encryption(amount: u64, key: Scalar) -> [u8; 8] {
|
||||||
let mut amount_mask = b"amount".to_vec();
|
let mut amount_mask = b"amount".to_vec();
|
||||||
amount_mask.extend(key.to_bytes());
|
amount_mask.extend(key.to_bytes());
|
||||||
(amount ^ u64::from_le_bytes(hash(&amount_mask)[.. 8].try_into().unwrap())).to_le_bytes()
|
(amount ^ u64::from_le_bytes(hash(&amount_mask)[.. 8].try_into().unwrap())).to_le_bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move this under EncryptedAmount?
|
impl EncryptedAmount {
|
||||||
fn amount_decryption(amount: &EncryptedAmount, key: Scalar) -> (Scalar, u64) {
|
/// Decrypt an EncryptedAmount into the Commitment it encrypts.
|
||||||
match amount {
|
///
|
||||||
|
/// The caller must verify the decrypted Commitment matches with the actual Commitment used
|
||||||
|
/// within in the Monero protocol.
|
||||||
|
pub fn decrypt(&self, key: Scalar) -> Commitment {
|
||||||
|
match self {
|
||||||
|
// TODO: Add a test vector for this
|
||||||
EncryptedAmount::Original { mask, amount } => {
|
EncryptedAmount::Original { mask, amount } => {
|
||||||
let mask_shared_sec = hash(key.as_bytes());
|
let mask_shared_sec = hash(key.as_bytes());
|
||||||
let mask =
|
let mask =
|
||||||
@@ -114,14 +119,15 @@ fn amount_decryption(amount: &EncryptedAmount, key: Scalar) -> (Scalar, u64) {
|
|||||||
// d2b from rctTypes.cpp
|
// d2b from rctTypes.cpp
|
||||||
let amount = u64::from_le_bytes(amount_scalar.to_bytes()[0 .. 8].try_into().unwrap());
|
let amount = u64::from_le_bytes(amount_scalar.to_bytes()[0 .. 8].try_into().unwrap());
|
||||||
|
|
||||||
(mask, amount)
|
Commitment::new(mask, amount)
|
||||||
}
|
}
|
||||||
EncryptedAmount::Compact { amount } => (
|
EncryptedAmount::Compact { amount } => Commitment::new(
|
||||||
commitment_mask(key),
|
commitment_mask(key),
|
||||||
u64::from_le_bytes(amount_encryption(u64::from_le_bytes(*amount), key)),
|
u64::from_le_bytes(compact_amount_encryption(u64::from_le_bytes(*amount), key)),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The private view key and public spend key, enabling scanning transactions.
|
/// The private view key and public spend key, enabling scanning transactions.
|
||||||
#[derive(Clone, Zeroize, ZeroizeOnDrop)]
|
#[derive(Clone, Zeroize, ZeroizeOnDrop)]
|
||||||
|
|||||||
@@ -17,9 +17,7 @@ use crate::{
|
|||||||
transaction::{Input, Timelock, Transaction},
|
transaction::{Input, Timelock, Transaction},
|
||||||
block::Block,
|
block::Block,
|
||||||
rpc::{RpcError, RpcConnection, Rpc},
|
rpc::{RpcError, RpcConnection, Rpc},
|
||||||
wallet::{
|
wallet::{PaymentId, Extra, address::SubaddressIndex, Scanner, uniqueness, shared_key},
|
||||||
PaymentId, Extra, address::SubaddressIndex, Scanner, uniqueness, shared_key, amount_decryption,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An absolute output ID, defined as its transaction hash and output index.
|
/// An absolute output ID, defined as its transaction hash and output index.
|
||||||
@@ -427,15 +425,13 @@ impl Scanner {
|
|||||||
commitment.amount = amount;
|
commitment.amount = amount;
|
||||||
// Regular transaction
|
// Regular transaction
|
||||||
} else {
|
} else {
|
||||||
let (mask, amount) = match tx.rct_signatures.base.encrypted_amounts.get(o) {
|
commitment = match tx.rct_signatures.base.encrypted_amounts.get(o) {
|
||||||
Some(amount) => amount_decryption(amount, shared_key),
|
Some(amount) => amount.decrypt(shared_key),
|
||||||
// This should never happen, yet it may be possible with miner transactions?
|
// This should never happen, yet it may be possible with miner transactions?
|
||||||
// Using get just decreases the possibility of a panic and lets us move on in that case
|
// Using get just decreases the possibility of a panic and lets us move on in that case
|
||||||
None => break,
|
None => break,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Rebuild the commitment to verify it
|
|
||||||
commitment = Commitment::new(mask, amount);
|
|
||||||
// If this is a malicious commitment, move to the next output
|
// If this is a malicious commitment, move to the next output
|
||||||
// Any other R value will calculate to a different spend key and are therefore ignorable
|
// Any other R value will calculate to a different spend key and are therefore ignorable
|
||||||
if Some(&commitment.calculate()) != tx.rct_signatures.base.commitments.get(o) {
|
if Some(&commitment.calculate()) != tx.rct_signatures.base.commitments.get(o) {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ use crate::{
|
|||||||
wallet::{
|
wallet::{
|
||||||
address::{Network, AddressSpec, MoneroAddress},
|
address::{Network, AddressSpec, MoneroAddress},
|
||||||
ViewPair, SpendableOutput, Decoys, PaymentId, ExtraField, Extra, key_image_sort, uniqueness,
|
ViewPair, SpendableOutput, Decoys, PaymentId, ExtraField, Extra, key_image_sort, uniqueness,
|
||||||
shared_key, commitment_mask, amount_encryption,
|
shared_key, commitment_mask, compact_amount_encryption,
|
||||||
extra::{ARBITRARY_DATA_MARKER, MAX_ARBITRARY_DATA_SIZE},
|
extra::{ARBITRARY_DATA_MARKER, MAX_ARBITRARY_DATA_SIZE},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -92,7 +92,7 @@ impl SendOutput {
|
|||||||
view_tag,
|
view_tag,
|
||||||
dest: ((&shared_key * ED25519_BASEPOINT_TABLE) + output.0.spend),
|
dest: ((&shared_key * ED25519_BASEPOINT_TABLE) + output.0.spend),
|
||||||
commitment: Commitment::new(commitment_mask(shared_key), output.1),
|
commitment: Commitment::new(commitment_mask(shared_key), output.1),
|
||||||
amount: amount_encryption(output.1, shared_key),
|
amount: compact_amount_encryption(output.1, shared_key),
|
||||||
},
|
},
|
||||||
payment_id,
|
payment_id,
|
||||||
)
|
)
|
||||||
@@ -936,7 +936,7 @@ impl Eventuality {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove this when the following for loop is updated
|
// TODO: Remove this if/when the following for loop is updated to support older TXs
|
||||||
assert!(
|
assert!(
|
||||||
rct_type.compact_encrypted_amounts(),
|
rct_type.compact_encrypted_amounts(),
|
||||||
"created an Eventuality for a very old RctType we don't support proving for"
|
"created an Eventuality for a very old RctType we don't support proving for"
|
||||||
|
|||||||
Reference in New Issue
Block a user