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))
|
||||
}
|
||||
|
||||
/// Serialize the Bulletproof(+) to a Vec<u8>.
|
||||
/// Serialize the Bulletproof(+) to a `Vec<u8>`.
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
let mut serialized = vec![];
|
||||
self.write(&mut serialized).unwrap();
|
||||
|
||||
@@ -10,7 +10,7 @@ use curve25519_dalek::{
|
||||
};
|
||||
|
||||
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;
|
||||
@@ -94,15 +94,20 @@ pub(crate) fn commitment_mask(shared_key: Scalar) -> Scalar {
|
||||
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();
|
||||
amount_mask.extend(key.to_bytes());
|
||||
(amount ^ u64::from_le_bytes(hash(&amount_mask)[.. 8].try_into().unwrap())).to_le_bytes()
|
||||
}
|
||||
|
||||
// TODO: Move this under EncryptedAmount?
|
||||
fn amount_decryption(amount: &EncryptedAmount, key: Scalar) -> (Scalar, u64) {
|
||||
match amount {
|
||||
impl EncryptedAmount {
|
||||
/// Decrypt an EncryptedAmount into the Commitment it encrypts.
|
||||
///
|
||||
/// 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 } => {
|
||||
let mask_shared_sec = hash(key.as_bytes());
|
||||
let mask =
|
||||
@@ -114,14 +119,15 @@ fn amount_decryption(amount: &EncryptedAmount, key: Scalar) -> (Scalar, u64) {
|
||||
// d2b from rctTypes.cpp
|
||||
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),
|
||||
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.
|
||||
#[derive(Clone, Zeroize, ZeroizeOnDrop)]
|
||||
|
||||
@@ -17,9 +17,7 @@ use crate::{
|
||||
transaction::{Input, Timelock, Transaction},
|
||||
block::Block,
|
||||
rpc::{RpcError, RpcConnection, Rpc},
|
||||
wallet::{
|
||||
PaymentId, Extra, address::SubaddressIndex, Scanner, uniqueness, shared_key, amount_decryption,
|
||||
},
|
||||
wallet::{PaymentId, Extra, address::SubaddressIndex, Scanner, uniqueness, shared_key},
|
||||
};
|
||||
|
||||
/// An absolute output ID, defined as its transaction hash and output index.
|
||||
@@ -427,15 +425,13 @@ impl Scanner {
|
||||
commitment.amount = amount;
|
||||
// Regular transaction
|
||||
} else {
|
||||
let (mask, amount) = match tx.rct_signatures.base.encrypted_amounts.get(o) {
|
||||
Some(amount) => amount_decryption(amount, shared_key),
|
||||
commitment = match tx.rct_signatures.base.encrypted_amounts.get(o) {
|
||||
Some(amount) => amount.decrypt(shared_key),
|
||||
// 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
|
||||
None => break,
|
||||
};
|
||||
|
||||
// Rebuild the commitment to verify it
|
||||
commitment = Commitment::new(mask, amount);
|
||||
// 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
|
||||
if Some(&commitment.calculate()) != tx.rct_signatures.base.commitments.get(o) {
|
||||
|
||||
@@ -39,7 +39,7 @@ use crate::{
|
||||
wallet::{
|
||||
address::{Network, AddressSpec, MoneroAddress},
|
||||
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},
|
||||
},
|
||||
};
|
||||
@@ -92,7 +92,7 @@ impl SendOutput {
|
||||
view_tag,
|
||||
dest: ((&shared_key * ED25519_BASEPOINT_TABLE) + output.0.spend),
|
||||
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,
|
||||
)
|
||||
@@ -936,7 +936,7 @@ impl Eventuality {
|
||||
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!(
|
||||
rct_type.compact_encrypted_amounts(),
|
||||
"created an Eventuality for a very old RctType we don't support proving for"
|
||||
|
||||
Reference in New Issue
Block a user