diff --git a/aries_cloudagent/utils/multiformats/multibase.py b/aries_cloudagent/utils/multiformats/multibase.py index d4b6ffb1fd..5f9ee5c0ff 100644 --- a/aries_cloudagent/utils/multiformats/multibase.py +++ b/aries_cloudagent/utils/multiformats/multibase.py @@ -36,13 +36,13 @@ def decode(self, value: str) -> bytes: """Decode a multibase encoded string.""" import base58 - return base58.b58decode(value[1:]) + return base58.b58decode(value) class Encoding(Enum): """Enum for supported encodings.""" - BASE58_BTC = Base58BtcEncoder() + base58btc = Base58BtcEncoder() # Insert additional encodings here @classmethod diff --git a/aries_cloudagent/utils/multiformats/multicodec.py b/aries_cloudagent/utils/multiformats/multicodec.py index b0de5e5672..465d5b3ea2 100644 --- a/aries_cloudagent/utils/multiformats/multicodec.py +++ b/aries_cloudagent/utils/multiformats/multicodec.py @@ -1,7 +1,7 @@ """Multicodec wrap and unwrap functions.""" from enum import Enum -from typing import Literal, NamedTuple, Union +from typing import Literal, NamedTuple, Optional, Union class Multicodec(NamedTuple): @@ -35,7 +35,7 @@ def for_data(cls, data: bytes) -> Multicodec: for codec in cls: if data.startswith(codec.value.code): return codec.value - raise ValueError(f"Unsupported multicodec: {data}") + raise ValueError("Unsupported multicodec") MulticodecStr = Literal[ @@ -65,7 +65,8 @@ def wrap(multicodec: Union[Multicodec, MulticodecStr], data: bytes) -> bytes: return multicodec.code + data -def unwrap(data: bytes) -> tuple[Multicodec, bytes]: +def unwrap(data: bytes, codec: Optional[Multicodec] = None) -> tuple[Multicodec, bytes]: """Unwrap data with multicodec prefix.""" - codec = SupportedCodecs.for_data(data) + if not codec: + codec = SupportedCodecs.for_data(data) return codec, data[len(codec.code) :] diff --git a/aries_cloudagent/utils/tests/test_multiformats.py b/aries_cloudagent/utils/tests/test_multiformats.py new file mode 100644 index 0000000000..5ef8ce4308 --- /dev/null +++ b/aries_cloudagent/utils/tests/test_multiformats.py @@ -0,0 +1,73 @@ +import pytest +from ..multiformats import multibase, multicodec + + +def test_encode_decode(): + value = b"Hello World!" + encoded = multibase.encode(value, "base58btc") + assert encoded == "z2NEpo7TZRRrLZSi2U" + decoded = multibase.decode(encoded) + assert decoded == value + + +def test_encode_decode_by_encoding(): + value = b"Hello World!" + encoded = multibase.encode(value, multibase.Encoding.base58btc) + assert encoded == "z2NEpo7TZRRrLZSi2U" + decoded = multibase.decode(encoded) + assert decoded == value + + +def test_x_unknown_encoding(): + with pytest.raises(ValueError): + multibase.encode(b"Hello World!", "fancy-encoding") + + +def test_x_unknown_character(): + with pytest.raises(ValueError): + multibase.decode("fHello World!") + + +def test_x_invalid_encoding(): + with pytest.raises(TypeError): + multibase.encode(b"Hello World!", 123) + + +def test_wrap_unwrap(): + value = b"Hello World!" + wrapped = multicodec.wrap("ed25519-pub", value) + codec, unwrapped = multicodec.unwrap(wrapped) + assert codec == multicodec.multicodec("ed25519-pub") + assert unwrapped == value + + +def test_wrap_unwrap_custom(): + value = b"Hello World!" + my_codec = multicodec.Multicodec("my-codec", b"\x00\x01") + wrapped = multicodec.wrap(my_codec, value) + codec, unwrapped = multicodec.unwrap(wrapped, my_codec) + assert codec == my_codec + assert unwrapped == value + + +def test_wrap_unwrap_by_codec(): + value = b"Hello World!" + wrapped = multicodec.wrap(multicodec.multicodec("ed25519-pub"), value) + codec, unwrapped = multicodec.unwrap(wrapped, multicodec.multicodec("ed25519-pub")) + assert codec == multicodec.multicodec("ed25519-pub") + assert unwrapped == value + + +def test_x_unknown_multicodec(): + with pytest.raises(ValueError): + multicodec.wrap("fancy-multicodec", b"Hello World!") + + +def test_x_invalid_multicodec(): + with pytest.raises(TypeError): + multicodec.wrap(123, b"Hello World!") + + +def test_x_invalid_multicodec_unwrap(): + with pytest.raises(ValueError): + multicodec.unwrap(b"Hello World!")