Skip to main content

ma_core/
multiformat.rs

1use unsigned_varint::{decode, encode};
2
3use crate::error::{MaError, MaResult as Result};
4
5// Well-known multicodec codec identifiers for payload encoding.
6// Key/signature codecs live in key.rs.
7// Source: https://github.com/multiformats/multicodec/blob/master/table.csv
8pub const CODEC_IDENTITY: u64 = 0x00;
9pub const CODEC_RAW: u64 = 0x55;
10pub const CODEC_CBOR: u64 = 0x51;
11pub const CODEC_DAG_CBOR: u64 = 0x71;
12pub const CODEC_DAG_JSON: u64 = 0x0129;
13pub const CODEC_JSON: u64 = 0x0200;
14
15pub fn multibase_encode(data: &[u8]) -> String {
16    multibase::encode(multibase::Base::Base58Btc, data)
17}
18
19pub fn multibase_decode(input: &str) -> Result<Vec<u8>> {
20    multibase::decode(input)
21        .map(|(_, data)| data)
22        .map_err(|_| MaError::InvalidPublicKeyMultibase)
23}
24
25pub fn multicodec_encode(codec: u64, payload: &[u8]) -> Vec<u8> {
26    let mut buffer = encode::u64_buffer();
27    let prefix = encode::u64(codec, &mut buffer);
28    let mut out = prefix.to_vec();
29    out.extend_from_slice(payload);
30    out
31}
32
33pub fn multicodec_decode(encoded: &[u8]) -> Result<(u64, Vec<u8>)> {
34    let (codec, remainder) =
35        decode::u64(encoded).map_err(|_| MaError::InvalidPublicKeyMultibase)?;
36    if remainder.is_empty() {
37        return Err(MaError::InvalidPublicKeyMultibase);
38    }
39    Ok((codec, remainder.to_vec()))
40}
41
42pub fn public_key_multibase_encode(codec: u64, public_key: &[u8]) -> String {
43    multibase_encode(&multicodec_encode(codec, public_key))
44}
45
46pub fn public_key_multibase_decode(input: &str) -> Result<(u64, Vec<u8>)> {
47    let decoded = multibase_decode(input)?;
48    multicodec_decode(&decoded)
49}
50
51pub fn signature_multibase_encode(codec: u64, signature: &[u8]) -> String {
52    multibase_encode(&multicodec_encode(codec, signature))
53}
54
55pub fn signature_multibase_decode(input: &str) -> Result<(u64, Vec<u8>)> {
56    let decoded = multibase_decode(input)?;
57    multicodec_decode(&decoded)
58}