aph_core/crypto/
multibase.rs1const BASE58BTC_TAG: char = 'z';
14
15pub fn base58btc_encode(input: &[u8]) -> String {
17 let mut out = String::with_capacity(1 + input.len() * 2);
18 out.push(BASE58BTC_TAG);
19 out.push_str(&bs58::encode(input).into_string());
20 out
21}
22
23pub fn base58btc_decode(input: &str) -> std::result::Result<std::vec::Vec<u8>, crate::errors::AphError> {
29 let body = match input.strip_prefix(BASE58BTC_TAG) {
30 std::option::Option::Some(b) => b,
31 std::option::Option::None => {
32 return std::result::Result::Err(crate::errors::AphError::InvalidEnvelopeSignature);
33 }
34 };
35 match bs58::decode(body).into_vec() {
36 std::result::Result::Ok(bytes) => std::result::Result::Ok(bytes),
37 std::result::Result::Err(_) => {
38 std::result::Result::Err(crate::errors::AphError::InvalidEnvelopeSignature)
39 }
40 }
41}
42
43#[cfg(test)]
44mod tests {
45 #[test]
46 fn round_trip_preserves_bytes() {
47 let data = [1u8, 2, 3, 250, 255, 0, 128];
50 let encoded = super::base58btc_encode(&data);
51 std::assert!(encoded.starts_with('z'));
52 std::assert_eq!(super::base58btc_decode(&encoded).unwrap(), data.to_vec());
53 }
54
55 #[test]
56 fn leading_zero_bytes_survive() {
57 let data = [0u8, 0, 0, 42];
61 let encoded = super::base58btc_encode(&data);
62 std::assert_eq!(super::base58btc_decode(&encoded).unwrap(), data.to_vec());
63 }
64
65 #[test]
66 fn missing_multibase_tag_is_rejected() {
67 std::assert!(super::base58btc_decode("6MkfAkf").is_err());
70 }
71
72 #[test]
73 fn invalid_base58_is_rejected_not_panicking() {
74 std::assert!(super::base58btc_decode("z0OIl").is_err());
77 }
78
79 #[test]
80 fn empty_payload_round_trips() {
81 std::assert_eq!(super::base58btc_decode("z").unwrap(), std::vec::Vec::<u8>::new());
84 }
85}