add function comments and throw on unmatched decode attempts
This commit is contained in:
parent
7c92c57ed2
commit
0f1827f24b
@ -1,21 +1,10 @@
|
||||
defmodule SsbBfe do
|
||||
@moduledoc """
|
||||
Documentation for `SsbBfe`.
|
||||
Binary Field Encodings (BFE) for Secure Scuttlebutt (SSB).
|
||||
|
||||
Encode and decode TFD values.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Hello world.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> SsbBfe.hello()
|
||||
:world
|
||||
|
||||
"""
|
||||
def hello do
|
||||
:world
|
||||
end
|
||||
|
||||
# ENCODE
|
||||
|
||||
def encode(value) when is_list(value) do
|
||||
@ -89,8 +78,8 @@ defmodule SsbBfe do
|
||||
6 == first_byte ->
|
||||
SsbBfe.Decoder.decode_generic(value)
|
||||
|
||||
nil ->
|
||||
true
|
||||
true ->
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1,75 +1,118 @@
|
||||
defmodule SsbBfe.Decoder do
|
||||
# Split the TF tag from the data bytes and base64 encode them.
|
||||
defp extract_base64_data(bin, tf_tag) do
|
||||
[_, base64_data] = :binary.split(bin, tf_tag)
|
||||
Base.encode64(base64_data)
|
||||
end
|
||||
|
||||
def decode_blob(blob) do
|
||||
encoded_base64_data = extract_base64_data(blob, <<2, 0>>)
|
||||
@doc """
|
||||
Take a blob ID as an encoded binary, extract and encode the base64 data and return the dedoded string representing the TFD.
|
||||
"""
|
||||
def decode_blob(blob_id) do
|
||||
encoded_base64_data = extract_base64_data(blob_id, <<2, 0>>)
|
||||
"&" <> encoded_base64_data <> ".sha256"
|
||||
end
|
||||
|
||||
@doc """
|
||||
Take an encrypted box as an encoded binary, extract the TF tag and call the appropriate decoder.
|
||||
"""
|
||||
def decode_box(box) do
|
||||
tf_tag = binary_part(box, 0, 2)
|
||||
decode_box(box, tf_tag)
|
||||
end
|
||||
|
||||
# Matches box.
|
||||
@doc """
|
||||
Take an encrypted box as an encoded binary and the TF tag of a box, extract and encode the base64 data and return the dedoded string representing the TFD.
|
||||
"""
|
||||
def decode_box(box, <<5, 0>>) do
|
||||
encoded_base64_data = extract_base64_data(box, <<5, 0>>)
|
||||
encoded_base64_data <> ".box"
|
||||
end
|
||||
|
||||
# Matches box2.
|
||||
@doc """
|
||||
Take an encrypted box as an encoded binary and the TF tag of a box2, extract and encode the base64 data and return the dedoded string representing the TFD.
|
||||
"""
|
||||
def decode_box(box, <<5, 1>>) do
|
||||
encoded_base64_data = extract_base64_data(box, <<5, 1>>)
|
||||
encoded_base64_data <> ".box2"
|
||||
end
|
||||
|
||||
def decode_feed(feed) do
|
||||
tf_tag = binary_part(feed, 0, 2)
|
||||
decode_feed(feed, tf_tag)
|
||||
@doc """
|
||||
Take a feed ID as an encoded binary, extract the TF tag and call the appropriate decoder.
|
||||
"""
|
||||
def decode_feed(feed_id) do
|
||||
tf_tag = binary_part(feed_id, 0, 2)
|
||||
decode_feed(feed_id, tf_tag)
|
||||
end
|
||||
|
||||
# Matches classic feed.
|
||||
def decode_feed(feed, <<0, 0>>) do
|
||||
encoded_base64_data = extract_base64_data(feed, <<0, 0>>)
|
||||
@doc """
|
||||
Take a feed ID as an encoded binary and the TF tag of a classic feed, extract and encode the base64 data and return the dedoded string representing the TFD.
|
||||
"""
|
||||
def decode_feed(feed_id, <<0, 0>>) do
|
||||
encoded_base64_data = extract_base64_data(feed_id, <<0, 0>>)
|
||||
"@" <> encoded_base64_data <> ".ed25519"
|
||||
end
|
||||
|
||||
@doc """
|
||||
Take a boolean `true` value as an encoded binary and return `true`.
|
||||
"""
|
||||
def decode_generic(<<6, 1, 1>>), do: true
|
||||
|
||||
@doc """
|
||||
Take a boolean `false` value as an encoded binary and return `false`.
|
||||
"""
|
||||
def decode_generic(<<6, 1, 0>>), do: false
|
||||
|
||||
@doc """
|
||||
Take a `nil` value as an encoded binary and return `nil`.
|
||||
"""
|
||||
def decode_generic(<<6, 2>>), do: nil
|
||||
|
||||
@doc """
|
||||
Take a generic value as an encoded binary, extract the TF tag and call the appropriate decoder.
|
||||
"""
|
||||
def decode_generic(generic) do
|
||||
tf_tag = binary_part(generic, 0, 2)
|
||||
decode_generic(generic, tf_tag)
|
||||
end
|
||||
|
||||
# Matches generic string.
|
||||
@doc """
|
||||
Take a generic string as an encoded binary and the TF tag of a generic string, extract the bytes representing the string data and return the decoded string.
|
||||
"""
|
||||
def decode_generic(str, <<6, 0>>) do
|
||||
[_, str_data] = :binary.split(str, <<6, 0>>)
|
||||
str_data
|
||||
end
|
||||
|
||||
# Matches generic bytes.
|
||||
def decode_generic(bytes, <<6, 3>>), do: bytes
|
||||
|
||||
def decode_msg(msg) do
|
||||
tf_tag = binary_part(msg, 0, 2)
|
||||
decode_msg(msg, tf_tag)
|
||||
@doc """
|
||||
Take generic bytes as an encoded binary and the TF tag of generic bytes, extract the bytes representing the data and return them.
|
||||
"""
|
||||
def decode_generic(bytes, <<6, 3>>) do
|
||||
[_, bytes] = :binary.split(bytes, <<6, 3>>)
|
||||
bytes
|
||||
end
|
||||
|
||||
# Matches classic message.
|
||||
def decode_msg(msg, <<1, 0>>) do
|
||||
encoded_base64_data = extract_base64_data(msg, <<1, 0>>)
|
||||
@doc """
|
||||
Take a message ID as an encoded binary, extract the TF tag and call the appropriate decoder.
|
||||
"""
|
||||
def decode_msg(msg_id) do
|
||||
tf_tag = binary_part(msg_id, 0, 2)
|
||||
decode_msg(msg_id, tf_tag)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Take a message ID as an encoded binary and the TF tag of a classic message, extract and encode the base64 data and return the dedoded string representing the TFD.
|
||||
"""
|
||||
def decode_msg(msg_id, <<1, 0>>) do
|
||||
encoded_base64_data = extract_base64_data(msg_id, <<1, 0>>)
|
||||
"%" <> encoded_base64_data <> ".sha256"
|
||||
end
|
||||
|
||||
def decode_sig(sig) do
|
||||
encoded_base64_data = extract_base64_data(sig, <<4, 0>>)
|
||||
@doc """
|
||||
Take a signature ID as an encoded binary, extract and encode the base64 data and return the dedoded string representing the TFD.
|
||||
"""
|
||||
def decode_sig(sig_id) do
|
||||
encoded_base64_data = extract_base64_data(sig_id, <<4, 0>>)
|
||||
encoded_base64_data <> ".sig.ed25519"
|
||||
end
|
||||
end
|
||||
|
@ -11,42 +11,68 @@ defmodule SsbBfe.Encoder do
|
||||
Base.decode64(base64_data)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Take a blob ID as a string, match on the type-format tag, extract and decode the base64 data and return the encoded bytes representing the TFD.
|
||||
"""
|
||||
def encode_blob(blob_id) do
|
||||
blob_tf_tag = SsbBfe.Types.get_blob_type(blob_id)
|
||||
{:ok, decoded_base64_data} = extract_base64_data(blob_id)
|
||||
blob_tf_tag <> decoded_base64_data
|
||||
end
|
||||
|
||||
@doc """
|
||||
Take a boolean `true` value and return the encoded bytes representing the TFD.
|
||||
"""
|
||||
def encode_bool(true), do: <<6, 1, 1>>
|
||||
|
||||
@doc """
|
||||
Take a boolean `false` value and return the encoded bytes representing the TFD.
|
||||
"""
|
||||
def encode_bool(false), do: <<6, 1, 0>>
|
||||
|
||||
@doc """
|
||||
Take an encrypted box as a string, match on the type-format tag, extract and decode the base64 data and return the encoded bytes representing the TFD.
|
||||
"""
|
||||
def encode_box(box_str) do
|
||||
box_tf_tag = SsbBfe.Types.get_box_type(box_str)
|
||||
{:ok, decoded_base64_data} = extract_base64_data(box_str, ".")
|
||||
box_tf_tag <> decoded_base64_data
|
||||
end
|
||||
|
||||
@doc """
|
||||
Take a feed ID as a string, match on the type-format tag, extract and decode the base64 data and return the encoded bytes representing the TFD.
|
||||
"""
|
||||
def encode_feed(feed_id) do
|
||||
feed_tf_tag = SsbBfe.Types.get_feed_type(feed_id)
|
||||
{:ok, decoded_base64_data} = extract_base64_data(feed_id)
|
||||
feed_tf_tag <> decoded_base64_data
|
||||
end
|
||||
|
||||
@doc """
|
||||
Take a message ID as a string, match on the type-format tag, extract and decode the base64 data and return the encoded bytes representing the TFD.
|
||||
"""
|
||||
def encode_msg(msg_id) do
|
||||
msg_tf_tag = SsbBfe.Types.get_msg_type(msg_id)
|
||||
{:ok, decoded_base64_data} = extract_base64_data(msg_id)
|
||||
msg_tf_tag <> decoded_base64_data
|
||||
end
|
||||
|
||||
@doc """
|
||||
Take a `nil` value and return the encoded bytes representing the TFD.
|
||||
"""
|
||||
def encode_nil(), do: <<6, 2>>
|
||||
|
||||
def encode_sig(sig) do
|
||||
{:ok, decoded_base64_data} = extract_base64_data(sig, ".sig.ed25519")
|
||||
<<4, 0>> <> decoded_base64_data
|
||||
@doc """
|
||||
Take a signature ID as a string, match on the type-format tag, extract and decode the base64 data and return the encoded bytes representing the TFD.
|
||||
"""
|
||||
def encode_sig(sig_id) do
|
||||
sig_tf_tag = SsbBfe.Types.get_sig_type(sig_id)
|
||||
{:ok, decoded_base64_data} = extract_base64_data(sig_id, ".sig.ed25519")
|
||||
sig_tf_tag <> decoded_base64_data
|
||||
end
|
||||
|
||||
def encode_str(str), do: <<6, 0>> <> str
|
||||
|
||||
# def encode_uri(uri)
|
||||
@doc """
|
||||
Take a string value and return the encoded bytes representing the TFD.
|
||||
"""
|
||||
def encode_str(str), do: <<6, 0>> <> str
|
||||
end
|
||||
|
@ -1,17 +1,21 @@
|
||||
defmodule SsbBfe.Types do
|
||||
@doc ~S"""
|
||||
@doc """
|
||||
Take a blob ID as a string and return the encoded bytes representing the blob
|
||||
type-format. Return `nil` if the ID does not end with `.sha256`.
|
||||
type-format. Throw an error if the ID does not end with `.sha256`.
|
||||
"""
|
||||
def get_blob_type(blob_id) do
|
||||
if String.ends_with?(blob_id, ".sha256") do
|
||||
<<2, 0>>
|
||||
cond do
|
||||
String.ends_with?(blob_id, ".sha256") ->
|
||||
<<2, 0>>
|
||||
|
||||
true ->
|
||||
throw({:unknown_format, blob_id})
|
||||
end
|
||||
end
|
||||
|
||||
@doc ~S"""
|
||||
@doc """
|
||||
Take a box as a string and return the encoded bytes representing the box
|
||||
type-format. Return `nil` if the ID does not end with `.box` or `.box2`.
|
||||
type-format. Throw an error if the ID does not end with `.box` or `.box2`.
|
||||
"""
|
||||
def get_box_type(boxed_str) do
|
||||
cond do
|
||||
@ -22,23 +26,27 @@ defmodule SsbBfe.Types do
|
||||
<<5, 1>>
|
||||
|
||||
true ->
|
||||
nil
|
||||
throw({:unknown_format, boxed_str})
|
||||
end
|
||||
end
|
||||
|
||||
@doc ~S"""
|
||||
@doc """
|
||||
Take a feed ID (key) as a string and return the encoded bytes representing
|
||||
the feed type-format. Return `nil` if the ID does not end with `.ed25519`.
|
||||
the feed type-format. Throw an error if the ID does not end with `.ed25519`.
|
||||
"""
|
||||
def get_feed_type(feed_id) do
|
||||
if String.ends_with?(feed_id, ".ed25519") do
|
||||
<<0, 0>>
|
||||
cond do
|
||||
String.ends_with?(feed_id, ".ed25519") ->
|
||||
<<0, 0>>
|
||||
|
||||
true ->
|
||||
throw({:unknown_format, feed_id})
|
||||
end
|
||||
end
|
||||
|
||||
@doc ~S"""
|
||||
@doc """
|
||||
Take a message ID as a string and return the encoded bytes representing
|
||||
the message type-format. Return `nil` if the ID does not end with `.sha256`
|
||||
the message type-format. Throw an error if the ID does not end with `.sha256`
|
||||
or `.cloaked`.
|
||||
"""
|
||||
def get_msg_type(msg_id) do
|
||||
@ -50,7 +58,21 @@ defmodule SsbBfe.Types do
|
||||
<<1, 2>>
|
||||
|
||||
true ->
|
||||
nil
|
||||
throw({:unknown_format, msg_id})
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Take a signature ID as a string and return the encoded bytes representing
|
||||
the signature type-format. Throw an error if the ID does not end with `.sig.ed25519`.
|
||||
"""
|
||||
def get_sig_type(sig_id) do
|
||||
cond do
|
||||
String.ends_with?(sig_id, ".sig.ed25519") ->
|
||||
<<4, 0>>
|
||||
|
||||
true ->
|
||||
throw({:unknown_format, sig_id})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user