mirror of
https://github.com/serai-dex/serai.git
synced 2025-03-12 09:26:51 +00:00
Error when the wrong spend key is used to sign a transaction
Moves decoy selection to being the last step in the multisig process so the RPC is only polled to continue valid transactions.
This commit is contained in:
parent
27751d8d98
commit
d611300adb
2 changed files with 33 additions and 20 deletions
coins/monero/src/wallet/send
|
@ -87,6 +87,8 @@ pub enum TransactionError {
|
||||||
NotEnoughFunds(u64, u64),
|
NotEnoughFunds(u64, u64),
|
||||||
#[error("invalid address")]
|
#[error("invalid address")]
|
||||||
InvalidAddress,
|
InvalidAddress,
|
||||||
|
#[error("wrong spend private key")]
|
||||||
|
WrongPrivateKey,
|
||||||
#[error("rpc error ({0})")]
|
#[error("rpc error ({0})")]
|
||||||
RpcError(RpcError),
|
RpcError(RpcError),
|
||||||
#[error("clsag error ({0})")]
|
#[error("clsag error ({0})")]
|
||||||
|
@ -282,7 +284,12 @@ impl SignableTransaction {
|
||||||
) -> Result<Transaction, TransactionError> {
|
) -> Result<Transaction, TransactionError> {
|
||||||
let mut images = Vec::with_capacity(self.inputs.len());
|
let mut images = Vec::with_capacity(self.inputs.len());
|
||||||
for input in &self.inputs {
|
for input in &self.inputs {
|
||||||
images.push(generate_key_image(&(spend + input.key_offset)));
|
let offset = spend + input.key_offset;
|
||||||
|
if (&offset * &ED25519_BASEPOINT_TABLE) != input.key {
|
||||||
|
Err(TransactionError::WrongPrivateKey)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
images.push(generate_key_image(&offset));
|
||||||
}
|
}
|
||||||
images.sort_by(key_image_sort);
|
images.sort_by(key_image_sort);
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,31 @@ impl SignableTransaction {
|
||||||
}
|
}
|
||||||
transcript.append_message(b"change", &self.change.as_bytes());
|
transcript.append_message(b"change", &self.change.as_bytes());
|
||||||
|
|
||||||
|
// Sort included before cloning it around
|
||||||
|
included.sort_unstable();
|
||||||
|
|
||||||
|
for (i, input) in self.inputs.iter().enumerate() {
|
||||||
|
// Check this the right set of keys
|
||||||
|
let offset = keys.offset(dalek_ff_group::Scalar(input.key_offset));
|
||||||
|
if offset.group_key().0 != input.key {
|
||||||
|
Err(TransactionError::WrongPrivateKey)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
clsags.push(
|
||||||
|
AlgorithmMachine::new(
|
||||||
|
ClsagMultisig::new(
|
||||||
|
transcript.clone(),
|
||||||
|
inputs[i].clone()
|
||||||
|
).map_err(|e| TransactionError::MultisigError(e))?,
|
||||||
|
Arc::new(offset),
|
||||||
|
&included
|
||||||
|
).map_err(|e| TransactionError::FrostError(e))?
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify these outputs by a dummy prep
|
||||||
|
self.prepare_outputs(rng, [0; 32])?;
|
||||||
|
|
||||||
// Select decoys
|
// Select decoys
|
||||||
// Ideally, this would be done post entropy, instead of now, yet doing so would require sign
|
// Ideally, this would be done post entropy, instead of now, yet doing so would require sign
|
||||||
// to be async which isn't preferable. This should be suitably competent though
|
// to be async which isn't preferable. This should be suitably competent though
|
||||||
|
@ -97,25 +122,6 @@ impl SignableTransaction {
|
||||||
&self.inputs
|
&self.inputs
|
||||||
).await.map_err(|e| TransactionError::RpcError(e))?;
|
).await.map_err(|e| TransactionError::RpcError(e))?;
|
||||||
|
|
||||||
// Sort included before cloning it around
|
|
||||||
included.sort_unstable();
|
|
||||||
|
|
||||||
for (i, input) in self.inputs.iter().enumerate() {
|
|
||||||
clsags.push(
|
|
||||||
AlgorithmMachine::new(
|
|
||||||
ClsagMultisig::new(
|
|
||||||
transcript.clone(),
|
|
||||||
inputs[i].clone()
|
|
||||||
).map_err(|e| TransactionError::MultisigError(e))?,
|
|
||||||
Arc::new(keys.offset(dalek_ff_group::Scalar(input.key_offset))),
|
|
||||||
&included
|
|
||||||
).map_err(|e| TransactionError::FrostError(e))?
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify these outputs by a dummy prep
|
|
||||||
self.prepare_outputs(rng, [0; 32])?;
|
|
||||||
|
|
||||||
Ok(TransactionMachine {
|
Ok(TransactionMachine {
|
||||||
signable: self,
|
signable: self,
|
||||||
i: keys.params().i(),
|
i: keys.params().i(),
|
||||||
|
|
Loading…
Reference in a new issue