DASL.CID
(dasl v0.1.0)
View Source
DASL content identifier (CID).
A CID is a self-describing content address: it encodes a version, a codec
(:raw or :drisl), and a SHA-256 digest. CIDs can be round-tripped
through their canonical multibase string form, constructed by hashing
arbitrary data with compute/2, and verified against their content with
verify?/2.
Summary
Functions
Computes a CID for an arbitrary binary, defaulting to the :raw codec.
Decodes a raw CID bytestring into its constituent fields.
Encodes a DASL.CID back to its canonical string form.
Constructs a DASL.CID from a CBOR tag 42 value.
Constructs a DASL.CID from a string-encoded CID.
Parses a string-encoded CID into raw bytes.
Converts a DASL.CID to a CBOR tag 42 value.
Returns true if data hashes to the digest recorded in cid, false otherwise.
Types
@type codec() :: :raw | :drisl
@type t() :: %DASL.CID{ bytes: binary(), codec: codec(), digest: binary(), hash_size: pos_integer(), hash_type: non_neg_integer(), version: pos_integer() }
Functions
Computes a CID for an arbitrary binary, defaulting to the :raw codec.
Examples
iex> cid = DASL.CID.compute("hello world")
iex> cid.codec
:raw
iex> cid.version
1
iex> cid.hash_size
32
iex> cid = DASL.CID.compute("hello world", :drisl)
iex> cid.codec
:drisl
Decodes a raw CID bytestring into its constituent fields.
Returns {:ok, map} on success, or {:error, message} if the bytes do not
conform to the CID spec (unsupported version, unknown codec, wrong hash
algorithm or size, truncated input).
Examples
iex> bytes = <<1, 85, 18, 32, 185, 77, 39, 185, 147, 77, 62, 8, 165, 46, 82, 215,
...> 218, 125, 171, 250, 196, 132, 239, 227, 122, 83, 128, 238, 144, 136,
...> 247, 172, 226, 239, 205, 233>>
iex> DASL.CID.decode(bytes)
{:ok, %{version: 1, codec: :raw, hash_type: 18, hash_size: 32,
digest: <<185, 77, 39, 185, 147, 77, 62, 8, 165, 46, 82, 215, 218, 125,
171, 250, 196, 132, 239, 227, 122, 83, 128, 238, 144, 136, 247,
172, 226, 239, 205, 233>>}}
iex> DASL.CID.decode(<<2, 85, 18, 32>> <> :binary.copy(<<0>>, 32))
{:error, "unsupported CID version: 2"}
iex> DASL.CID.decode(<<1, 0xAB, 18, 32>> <> :binary.copy(<<0>>, 32))
{:error, "unsupported codec: 0xAB"}
iex> DASL.CID.decode(<<1, 85, 0x11, 32>> <> :binary.copy(<<0>>, 32))
{:error, "unsupported hash type: 0x11"}
iex> DASL.CID.decode(<<1, 85, 18, 31>> <> :binary.copy(<<0>>, 32))
{:error, "invalid hash size: 31"}
Encodes a DASL.CID back to its canonical string form.
Examples
iex> {:ok, cid} = DASL.CID.new("bafkreifzjut3te2nhyekklss27nh3k72ysco7y32koao5eei66wof36n5e")
iex> DASL.CID.encode(cid)
"bafkreifzjut3te2nhyekklss27nh3k72ysco7y32koao5eei66wof36n5e"
Constructs a DASL.CID from a CBOR tag 42 value.
Examples
iex> {:ok, cid} = DASL.CID.new("bafkreifzjut3te2nhyekklss27nh3k72ysco7y32koao5eei66wof36n5e")
iex> tag = DASL.CID.to_cbor(cid)
iex> {:ok, decoded} = DASL.CID.from_cbor(tag)
iex> decoded.codec
:raw
iex> DASL.CID.from_cbor(%CBOR.Tag{tag: 1, value: "not a cid"})
{:error, "invalid CBOR CID tag"}
Constructs a DASL.CID from a string-encoded CID.
Examples
iex> {:ok, cid} = DASL.CID.new("bafkreifzjut3te2nhyekklss27nh3k72ysco7y32koao5eei66wof36n5e")
iex> cid.version
1
iex> cid.codec
:raw
iex> cid.hash_type
18
iex> cid.hash_size
32
iex> DASL.CID.new("not-a-cid")
{:error, "CID must start with 'b'"}
Parses a string-encoded CID into raw bytes.
Examples
iex> DASL.CID.parse("bafkreifzjut3te2nhyekklss27nh3k72ysco7y32koao5eei66wof36n5e")
{:ok, <<1, 85, 18, 32, 185, 77, 39, 185, 147, 77, 62, 8, 165, 46, 82, 215, 218,
125, 171, 250, 196, 132, 239, 227, 122, 83, 128, 238, 144, 136, 247, 172,
226, 239, 205, 233>>}
iex> DASL.CID.parse("zQmInvalidPrefix")
{:error, "CID must start with 'b'"}
iex> DASL.CID.parse("b!!!!notbase32")
{:error, "invalid base32 encoding"}
@spec to_cbor(t()) :: CBOR.Tag.t()
Converts a DASL.CID to a CBOR tag 42 value.
Examples
iex> {:ok, cid} = DASL.CID.new("bafkreifzjut3te2nhyekklss27nh3k72ysco7y32koao5eei66wof36n5e")
iex> DASL.CID.to_cbor(cid)
%CBOR.Tag{
tag: 42,
value: %CBOR.Tag{
tag: :bytes,
value: <<0, 1, 85, 18, 32, 185, 77, 39, 185, 147, 77, 62, 8, 165, 46, 82,
215, 218, 125, 171, 250, 196, 132, 239, 227, 122, 83, 128, 238,
144, 136, 247, 172, 226, 239, 205, 233>>
}
}
Returns true if data hashes to the digest recorded in cid, false otherwise.
Uses a constant-time comparison to avoid timing attacks.
Examples
iex> cid = DASL.CID.compute("hello world")
iex> DASL.CID.verify?(cid, "hello world")
true
iex> cid = DASL.CID.compute("hello world")
iex> DASL.CID.verify?(cid, "goodbye world")
false