pub mod dotns;
pub mod extrinsic;
pub mod identity;
pub mod statement_store;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CryptoScheme {
Ed25519,
Sr25519,
Ecdsa,
}
pub fn encode_multi_signature(sig_bytes: &[u8], scheme: CryptoScheme) -> Result<Vec<u8>, String> {
let (variant_byte, expected_len) = match scheme {
CryptoScheme::Ed25519 => (0x00u8, 64usize),
CryptoScheme::Sr25519 => (0x01u8, 64usize),
CryptoScheme::Ecdsa => (0x02u8, 65usize),
};
if sig_bytes.len() != expected_len {
return Err(format!(
"expected {} bytes for {:?} signature, got {}",
expected_len,
scheme,
sig_bytes.len(),
));
}
let mut out = Vec::with_capacity(1 + expected_len);
out.push(variant_byte);
out.extend_from_slice(sig_bytes);
Ok(out)
}
pub fn hex_encode(bytes: &[u8]) -> String {
let mut s = String::with_capacity(2 + bytes.len() * 2);
s.push_str("0x");
for b in bytes {
s.push_str(&format!("{b:02x}"));
}
s
}
pub fn hex_decode(s: &str) -> Option<Vec<u8>> {
let s = s.strip_prefix("0x").unwrap_or(s);
if !s.len().is_multiple_of(2) {
return None;
}
let mut out = Vec::with_capacity(s.len() / 2);
for i in (0..s.len()).step_by(2) {
out.push(u8::from_str_radix(&s[i..i + 2], 16).ok()?);
}
Some(out)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sr25519_multi_signature_prefix_and_length() {
let sig = [0xabu8; 64];
let out = encode_multi_signature(&sig, CryptoScheme::Sr25519).unwrap();
assert_eq!(out.len(), 65);
assert_eq!(out[0], 0x01);
assert_eq!(&out[1..], sig.as_ref());
}
#[test]
fn test_ed25519_multi_signature_prefix_and_length() {
let sig = [0xabu8; 64];
let out = encode_multi_signature(&sig, CryptoScheme::Ed25519).unwrap();
assert_eq!(out.len(), 65);
assert_eq!(out[0], 0x00);
assert_eq!(&out[1..], sig.as_ref());
}
#[test]
fn test_ecdsa_multi_signature_prefix_and_length() {
let sig = [0xabu8; 65];
let out = encode_multi_signature(&sig, CryptoScheme::Ecdsa).unwrap();
assert_eq!(out.len(), 66);
assert_eq!(out[0], 0x02);
assert_eq!(&out[1..], sig.as_ref());
}
#[test]
fn test_multi_signature_rejects_wrong_sr25519_length() {
let sig = [0x00u8; 63];
assert!(encode_multi_signature(&sig, CryptoScheme::Sr25519).is_err());
}
#[test]
fn test_multi_signature_rejects_wrong_ecdsa_length() {
let sig = [0x00u8; 64];
assert!(encode_multi_signature(&sig, CryptoScheme::Ecdsa).is_err());
}
#[test]
fn test_multi_signature_pinned_zeros() {
let sig = [0u8; 64];
let out = encode_multi_signature(&sig, CryptoScheme::Sr25519).unwrap();
assert_eq!(out.len(), 65);
assert_eq!(out[0], 0x01);
assert!(out[1..].iter().all(|&b| b == 0x00));
}
}