Tidy up monero-serai as a meta crate

This commit is contained in:
Luke Parker
2024-06-16 12:26:14 -04:00
parent 3e82ee60b3
commit 3a1c6c7247
16 changed files with 68 additions and 112 deletions

View File

@@ -8,7 +8,7 @@ mod binaries {
pub(crate) use serde_json::json;
pub(crate) use monero_serai::{
Commitment,
primitives::Commitment,
ringct::{RctPrunable, bulletproofs::BatchVerifier},
transaction::{Input, Transaction},
block::Block,

View File

@@ -4,9 +4,9 @@ use std_shims::{
};
use crate::{
hash,
io::*,
primitives::keccak256,
merkle::merkle_root,
serialize::*,
transaction::{Input, Transaction},
};
@@ -99,7 +99,7 @@ impl Block {
write_varint(&u64::try_from(hashable.len()).unwrap(), &mut hashing_blob).unwrap();
hashing_blob.append(&mut hashable);
let hash = hash(&hashing_blob);
let hash = keccak256(hashing_blob);
if hash == CORRECT_BLOCK_HASH_202612 {
return EXISTING_BLOCK_HASH_202612;
};

View File

@@ -2,21 +2,13 @@
#![doc = include_str!("../README.md")]
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(not(feature = "std"))]
#[macro_use]
extern crate alloc;
use std_shims::io;
use std_shims::io as stdio;
use zeroize::Zeroize;
use sha3::{Digest, Keccak256};
use curve25519_dalek::scalar::Scalar;
pub use monero_io::decompress_point;
pub use monero_generators::H;
pub use monero_primitives::INV_EIGHT;
pub use monero_io as io;
pub use monero_generators as generators;
pub use monero_primitives as primitives;
mod merkle;
@@ -114,7 +106,7 @@ impl Protocol {
}
}
pub(crate) fn write<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
pub(crate) fn write<W: stdio::Write>(&self, w: &mut W) -> stdio::Result<()> {
match self {
Protocol::v14 => w.write_all(&[0, 14]),
Protocol::v16 => w.write_all(&[0, 16]),
@@ -130,13 +122,13 @@ impl Protocol {
}
}
pub(crate) fn read<R: io::Read>(r: &mut R) -> io::Result<Protocol> {
pub(crate) fn read<R: stdio::Read>(r: &mut R) -> stdio::Result<Protocol> {
Ok(match read_byte(r)? {
// Monero protocol
0 => match read_byte(r)? {
14 => Protocol::v14,
16 => Protocol::v16,
_ => Err(io::Error::other("unrecognized monero protocol"))?,
_ => Err(stdio::Error::other("unrecognized monero protocol"))?,
},
// Custom
1 => match read_byte(r)? {
@@ -145,41 +137,24 @@ impl Protocol {
bp_plus: match read_byte(r)? {
0 => false,
1 => true,
_ => Err(io::Error::other("invalid bool serialization"))?,
_ => Err(stdio::Error::other("invalid bool serialization"))?,
},
optimal_rct_type: RctType::from_byte(read_byte(r)?)
.ok_or_else(|| io::Error::other("invalid RctType serialization"))?,
.ok_or_else(|| stdio::Error::other("invalid RctType serialization"))?,
view_tags: match read_byte(r)? {
0 => false,
1 => true,
_ => Err(io::Error::other("invalid bool serialization"))?,
_ => Err(stdio::Error::other("invalid bool serialization"))?,
},
v16_fee: match read_byte(r)? {
0 => false,
1 => true,
_ => Err(io::Error::other("invalid bool serialization"))?,
_ => Err(stdio::Error::other("invalid bool serialization"))?,
},
},
_ => Err(io::Error::other("unrecognized custom protocol serialization"))?,
_ => Err(stdio::Error::other("unrecognized custom protocol serialization"))?,
},
_ => Err(io::Error::other("unrecognized protocol serialization"))?,
_ => Err(stdio::Error::other("unrecognized protocol serialization"))?,
})
}
}
pub use monero_primitives::Commitment;
pub(crate) fn hash(data: &[u8]) -> [u8; 32] {
Keccak256::digest(data).into()
}
/// Hash the provided data to a scalar via keccak256(data) % l.
pub fn hash_to_scalar(data: &[u8]) -> Scalar {
let scalar = Scalar::from_bytes_mod_order(hash(data));
// Monero will explicitly error in this case
// This library acknowledges its practical impossibility of it occurring, and doesn't bother to
// code in logic to handle it. That said, if it ever occurs, something must happen in order to
// not generate/verify a proof we believe to be valid when it isn't
assert!(scalar != Scalar::ZERO, "ZERO HASH: {data:?}");
scalar
}

View File

@@ -1,11 +1,11 @@
use std_shims::vec::Vec;
use crate::hash;
use crate::primitives::keccak256;
pub(crate) fn merkle_root(root: [u8; 32], leafs: &[[u8; 32]]) -> [u8; 32] {
match leafs.len() {
0 => root,
1 => hash(&[root, leafs[0]].concat()),
1 => keccak256([root, leafs[0]].concat()),
_ => {
let mut hashes = Vec::with_capacity(1 + leafs.len());
hashes.push(root);
@@ -29,7 +29,7 @@ pub(crate) fn merkle_root(root: [u8; 32], leafs: &[[u8; 32]]) -> [u8; 32] {
let mut paired_hashes = Vec::with_capacity(overage);
while let Some(left) = rightmost.next() {
let right = rightmost.next().unwrap();
paired_hashes.push(hash(&[left.as_ref(), &right].concat()));
paired_hashes.push(keccak256([left.as_ref(), &right].concat()));
}
drop(rightmost);
@@ -42,7 +42,7 @@ pub(crate) fn merkle_root(root: [u8; 32], leafs: &[[u8; 32]]) -> [u8; 32] {
while hashes.len() > 1 {
let mut i = 0;
while i < hashes.len() {
new_hashes.push(hash(&[hashes[i], hashes[i + 1]].concat()));
new_hashes.push(keccak256([hashes[i], hashes[i + 1]].concat()));
i += 2;
}

View File

@@ -7,9 +7,7 @@ use zeroize::Zeroize;
use curve25519_dalek::{EdwardsPoint, Scalar};
use monero_generators::hash_to_point;
use crate::{serialize::*, hash_to_scalar};
use crate::{io::*, generators::hash_to_point, primitives::keccak256_to_scalar};
#[derive(Clone, PartialEq, Eq, Debug, Zeroize)]
pub struct Signature {
@@ -67,6 +65,6 @@ impl RingSignature {
sum += sig.c;
}
sum == hash_to_scalar(&buf)
sum == keccak256_to_scalar(buf)
}
}

View File

@@ -8,27 +8,21 @@ use zeroize::{Zeroize, Zeroizing};
use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar, edwards::EdwardsPoint};
pub(crate) mod hash_to_point;
pub use hash_to_point::{raw_hash_to_point, hash_to_point};
/// MLSAG struct, along with verifying functionality.
pub use monero_mlsag as mlsag;
/// CLSAG struct, along with signing and verifying functionality.
pub use monero_clsag as clsag;
/// BorromeanRange struct, along with verifying functionality.
pub use monero_borromean as borromean;
/// Bulletproofs(+) structs, along with proving and verifying functionality.
pub use monero_bulletproofs as bulletproofs;
use crate::{
Protocol,
serialize::*,
io::*,
generators::hash_to_point,
ringct::{mlsag::Mlsag, clsag::Clsag, borromean::BorromeanRange, bulletproofs::Bulletproof},
Protocol,
};
/// Generate a key image for a given key. Defined as `x * hash_to_point(xG)`.
pub fn generate_key_image(secret: &Zeroizing<Scalar>) -> EdwardsPoint {
hash_to_point(&(ED25519_BASEPOINT_TABLE * secret.deref())) * secret.deref()
hash_to_point((ED25519_BASEPOINT_TABLE * secret.deref()).compress().to_bytes()) * secret.deref()
}
/// An encrypted amount.

View File

@@ -1,8 +0,0 @@
use curve25519_dalek::edwards::EdwardsPoint;
pub use monero_generators::{hash_to_point as raw_hash_to_point};
/// Monero's hash to point function, as named `ge_fromfe_frombytes_vartime`.
pub fn hash_to_point(key: &EdwardsPoint) -> EdwardsPoint {
raw_hash_to_point(key.compress().to_bytes())
}

View File

@@ -4,13 +4,12 @@ use rand_core::OsRng;
use curve25519_dalek::scalar::Scalar;
use crate::{
hash,
wallet::seed::{
Seed, SeedType, SeedError,
classic::{self, trim_by_lang},
polyseed,
},
use monero_primitives::keccak256;
use crate::wallet::seed::{
Seed, SeedType, SeedError,
classic::{self, trim_by_lang},
polyseed,
};
#[test]
@@ -217,7 +216,7 @@ fn test_classic_seed() {
let view: [u8; 32] = hex::decode(vector.view).unwrap().try_into().unwrap();
// Monero then derives the view key as H(spend)
assert_eq!(
Scalar::from_bytes_mod_order(hash(&spend)),
Scalar::from_bytes_mod_order(keccak256(spend)),
Scalar::from_canonical_bytes(view).unwrap()
);

View File

@@ -9,10 +9,11 @@ use zeroize::Zeroize;
use curve25519_dalek::edwards::{EdwardsPoint, CompressedEdwardsY};
use crate::{
Protocol, hash,
serialize::*,
io::*,
primitives::keccak256,
ring_signatures::RingSignature,
ringct::{bulletproofs::Bulletproof, RctType, RctBase, RctPrunable, RctSignatures},
Protocol,
};
#[derive(Clone, PartialEq, Eq, Debug)]
@@ -240,7 +241,7 @@ impl TransactionPrefix {
}
pub fn hash(&self) -> [u8; 32] {
hash(&self.serialize())
keccak256(self.serialize())
}
}
@@ -352,25 +353,25 @@ impl Transaction {
let mut buf = Vec::with_capacity(2048);
if self.prefix.version == 1 {
self.write(&mut buf).unwrap();
hash(&buf)
keccak256(buf)
} else {
let mut hashes = Vec::with_capacity(96);
hashes.extend(self.prefix.hash());
self.rct_signatures.base.write(&mut buf, self.rct_signatures.rct_type()).unwrap();
hashes.extend(hash(&buf));
hashes.extend(keccak256(&buf));
buf.clear();
hashes.extend(&match self.rct_signatures.prunable {
RctPrunable::Null => [0; 32],
_ => {
self.rct_signatures.prunable.write(&mut buf, self.rct_signatures.rct_type()).unwrap();
hash(&buf)
keccak256(buf)
}
});
hash(&hashes)
keccak256(hashes)
}
}
@@ -386,13 +387,13 @@ impl Transaction {
sig_hash.extend(self.prefix.hash());
self.rct_signatures.base.write(&mut buf, self.rct_signatures.rct_type()).unwrap();
sig_hash.extend(hash(&buf));
sig_hash.extend(keccak256(&buf));
buf.clear();
self.rct_signatures.prunable.signature_write(&mut buf).unwrap();
sig_hash.extend(hash(&buf));
sig_hash.extend(keccak256(buf));
hash(&sig_hash)
keccak256(sig_hash)
}
fn is_rct_bulletproof(&self) -> bool {

View File

@@ -5,7 +5,7 @@ use zeroize::Zeroize;
use curve25519_dalek::edwards::EdwardsPoint;
use monero_io::decompress_point;
use crate::io::decompress_point;
use base58_monero::base58::{encode_check, decode_check};

View File

@@ -8,10 +8,7 @@ use zeroize::Zeroize;
use curve25519_dalek::edwards::EdwardsPoint;
use crate::serialize::{
varint_len, read_byte, read_bytes, read_varint, read_point, read_vec, write_byte, write_varint,
write_point, write_vec,
};
use crate::io::*;
pub const MAX_TX_EXTRA_PADDING_COUNT: usize = 255;
pub const MAX_TX_EXTRA_NONCE_SIZE: usize = 255;

View File

@@ -10,7 +10,9 @@ use curve25519_dalek::{
};
use crate::{
hash, hash_to_scalar, serialize::write_varint, Commitment, ringct::EncryptedAmount,
io::write_varint,
primitives::{Commitment, keccak256, keccak256_to_scalar},
ringct::EncryptedAmount,
transaction::Input,
};
@@ -62,7 +64,7 @@ pub(crate) fn uniqueness(inputs: &[Input]) -> [u8; 32] {
Input::ToKey { key_image, .. } => u.extend(key_image.compress().to_bytes()),
}
}
hash(&u)
keccak256(u)
}
// Hs("view_tag" || 8Ra || o), Hs(8Ra || o), and H(8Ra || 0x8d) with uniqueness inclusion in the
@@ -78,12 +80,12 @@ pub(crate) fn shared_key(
let mut payment_id_xor = [0; 8];
payment_id_xor
.copy_from_slice(&hash(&[output_derivation.as_ref(), [0x8d].as_ref()].concat())[.. 8]);
.copy_from_slice(&keccak256([output_derivation.as_ref(), [0x8d].as_ref()].concat())[.. 8]);
// || o
write_varint(&o, &mut output_derivation).unwrap();
let view_tag = hash(&[b"view_tag".as_ref(), &output_derivation].concat())[0];
let view_tag = keccak256([b"view_tag".as_ref(), &output_derivation].concat())[0];
// uniqueness ||
let shared_key = if let Some(uniqueness) = uniqueness {
@@ -92,19 +94,19 @@ pub(crate) fn shared_key(
output_derivation
};
(view_tag, hash_to_scalar(&shared_key), payment_id_xor)
(view_tag, keccak256_to_scalar(shared_key), payment_id_xor)
}
pub(crate) fn commitment_mask(shared_key: Scalar) -> Scalar {
let mut mask = b"commitment_mask".to_vec();
mask.extend(shared_key.to_bytes());
hash_to_scalar(&mask)
keccak256_to_scalar(mask)
}
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()
(amount ^ u64::from_le_bytes(keccak256(amount_mask)[.. 8].try_into().unwrap())).to_le_bytes()
}
impl EncryptedAmount {
@@ -116,11 +118,11 @@ impl EncryptedAmount {
match self {
// TODO: Add a test vector for this
EncryptedAmount::Original { mask, amount } => {
let mask_shared_sec = hash(key.as_bytes());
let mask_shared_sec = keccak256(key.as_bytes());
let mask =
Scalar::from_bytes_mod_order(*mask) - Scalar::from_bytes_mod_order(mask_shared_sec);
let amount_shared_sec = hash(&mask_shared_sec);
let amount_shared_sec = keccak256(mask_shared_sec);
let amount_scalar =
Scalar::from_bytes_mod_order(*amount) - Scalar::from_bytes_mod_order(amount_shared_sec);
// d2b from rctTypes.cpp
@@ -157,7 +159,7 @@ impl ViewPair {
}
fn subaddress_derivation(&self, index: SubaddressIndex) -> Scalar {
hash_to_scalar(&Zeroizing::new(
keccak256_to_scalar(Zeroizing::new(
[
b"SubAddr\0".as_ref(),
Zeroizing::new(self.view.to_bytes()).as_ref(),

View File

@@ -12,8 +12,8 @@ use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar, edwar
use monero_io::decompress_point;
use crate::{
Commitment,
serialize::{read_byte, read_u32, read_u64, read_bytes, read_scalar, read_point, read_raw_vec},
io::*,
primitives::Commitment,
transaction::{Input, Timelock, Transaction},
block::Block,
rpc::{RpcError, RpcConnection, Rpc},

View File

@@ -25,11 +25,9 @@ use frost::FrostError;
use monero_io::varint_len;
use crate::{
Protocol, Commitment, hash,
serialize::{
read_byte, read_bytes, read_u64, read_scalar, read_point, read_vec, write_byte, write_scalar,
write_point, write_raw_vec, write_vec,
},
io::*,
primitives::{Commitment, keccak256},
Protocol,
ringct::{
generate_key_image,
clsag::{ClsagError, ClsagContext, Clsag},
@@ -628,8 +626,8 @@ impl SignableTransaction {
for input in inputs {
r_uniqueness.extend(input.compress().to_bytes());
}
ChaCha20Rng::from_seed(hash(
&[b"monero-serai_outputs".as_ref(), seed.as_ref(), &r_uniqueness].concat(),
ChaCha20Rng::from_seed(keccak256(
[b"monero-serai_outputs".as_ref(), seed.as_ref(), &r_uniqueness].concat(),
))
};

View File

@@ -352,7 +352,7 @@ async fn mint_and_burn_test() {
ViewPair, Scanner, DecoySelection, Decoys, Change, FeePriority, SignableTransaction,
address::{Network, AddressType, AddressMeta, MoneroAddress},
},
decompress_point,
io::decompress_point,
};
// Grab the first output on the chain

View File

@@ -444,7 +444,7 @@ impl Wallet {
SignableTransaction,
},
rpc::HttpRpc,
decompress_point,
io::decompress_point,
};
use processor::{additional_key, networks::Monero};