use ootle_byte_type::ToByteType;
use tari_crypto::{ristretto::RistrettoPublicKey, tari_utilities::ByteArray};
use tari_ootle_transaction::{TransactionSignature, UnsignedTransactionV1};
use tari_template_lib_types::crypto::RistrettoPublicKeyBytes;
use crate::error::OotleWasmError;
pub fn hash_unsigned_transaction(
transaction: &UnsignedTransactionV1,
seal_signer_public_key: &[u8],
) -> Result<Vec<u8>, OotleWasmError> {
let seal_signer = public_key_bytes_from_bytes(seal_signer_public_key)?;
let hash = TransactionSignature::create_message_v1(&seal_signer, transaction);
Ok(hash.to_vec())
}
pub fn hash_unsigned_transaction_json(
unsigned_tx_json: &str,
seal_signer_public_key: &[u8],
) -> Result<Vec<u8>, OotleWasmError> {
let tx: UnsignedTransactionV1 = serde_json::from_str(unsigned_tx_json)?;
hash_unsigned_transaction(&tx, seal_signer_public_key)
}
pub(crate) fn public_key_bytes_from_bytes(bytes: &[u8]) -> Result<RistrettoPublicKeyBytes, OotleWasmError> {
let pk =
RistrettoPublicKey::from_canonical_bytes(bytes).map_err(|e| OotleWasmError::InvalidPublicKey(e.to_string()))?;
Ok(pk.to_byte_type())
}
#[cfg(test)]
mod tests {
use ootle_byte_type::ToByteType;
use rand::rngs::OsRng;
use tari_crypto::{
keys::{PublicKey, SecretKey},
ristretto::{RistrettoPublicKey, RistrettoSecretKey},
tari_utilities::ByteArray,
};
use tari_ootle_transaction::UnsignedTransactionV1;
use super::*;
#[test]
fn hash_matches_transaction_crate() {
let secret = RistrettoSecretKey::random(&mut OsRng);
let public_key = RistrettoPublicKey::from_secret_key(&secret);
let public_key_bytes = public_key.as_bytes().to_vec();
let seal_signer_bytes: RistrettoPublicKeyBytes = public_key.to_byte_type();
let tx = UnsignedTransactionV1::new(0u8, vec![], vec![], Default::default(), None, None, false);
let our_hash = hash_unsigned_transaction(&tx, &public_key_bytes).unwrap();
let expected = TransactionSignature::create_message_v1(&seal_signer_bytes, &tx);
assert_eq!(our_hash, expected.to_vec());
}
#[test]
fn hash_from_json_round_trip() {
let secret = RistrettoSecretKey::random(&mut OsRng);
let public_key = RistrettoPublicKey::from_secret_key(&secret);
let public_key_bytes = public_key.as_bytes().to_vec();
let tx = UnsignedTransactionV1::new(0u8, vec![], vec![], Default::default(), None, None, false);
let json = serde_json::to_string(&tx).unwrap();
let hash_from_struct = hash_unsigned_transaction(&tx, &public_key_bytes).unwrap();
let hash_from_json = hash_unsigned_transaction_json(&json, &public_key_bytes).unwrap();
assert_eq!(hash_from_struct, hash_from_json);
}
}