iuna

iuna

iuna - experimental mainnet-candidate protocol
git clone https://getiuna.org/git/iuna.git
Log | Files | Refs | README | LICENSE

transaction_v2.rs (1452B)


      1 #![no_main]
      2 
      3 use iuna::domain::{TransactionV2, fuzz_verify_ml_dsa44};
      4 use libfuzzer_sys::fuzz_target;
      5 
      6 const PUBLIC_KEY_BYTES: usize = 1_312;
      7 const SIGNATURE_BYTES: usize = 2_420;
      8 const MAX_INPUT_BYTES: usize = 2 * 1024 * 1024;
      9 
     10 fuzz_target!(|data: &[u8]| {
     11     if data.len() > MAX_INPUT_BYTES {
     12         return;
     13     }
     14 
     15     exercise(data);
     16     if let Some(hex) = data.strip_prefix(b"hex:") {
     17         if let Some(decoded) = decode_hex(hex) {
     18             exercise(&decoded);
     19         }
     20     }
     21 });
     22 
     23 fn exercise(data: &[u8]) {
     24     if let Ok((domain, transaction)) = TransactionV2::decode(data) {
     25         let _ = transaction.verify_authorizations(&domain);
     26         let _ = transaction.encode(&domain);
     27     }
     28 
     29     if let Some((public_key, rest)) = data.split_at_checked(PUBLIC_KEY_BYTES)
     30         && let Some((signature, payload)) = rest.split_at_checked(SIGNATURE_BYTES)
     31     {
     32         fuzz_verify_ml_dsa44(public_key, payload, signature);
     33     }
     34 }
     35 
     36 fn decode_hex(encoded: &[u8]) -> Option<Vec<u8>> {
     37     if encoded.len() % 2 != 0 || encoded.len() / 2 > MAX_INPUT_BYTES {
     38         return None;
     39     }
     40     encoded
     41         .chunks_exact(2)
     42         .map(|pair| Some(decode_nibble(pair[0])? << 4 | decode_nibble(pair[1])?))
     43         .collect()
     44 }
     45 
     46 fn decode_nibble(byte: u8) -> Option<u8> {
     47     match byte {
     48         b'0'..=b'9' => Some(byte - b'0'),
     49         b'a'..=b'f' => Some(byte - b'a' + 10),
     50         b'A'..=b'F' => Some(byte - b'A' + 10),
     51         _ => None,
     52     }
     53 }