Current section

Files

Jump to
bls_ex lib bls_ex.ex
Raw

lib/bls_ex.ex

defmodule BlsEx do
@moduledoc """
BlsEx provides utility to leverage BLS signatures
BLS scheme supports aggregation of public keys and aggregation of signatures.
Here an full example of aggregated signature verification
iex> seed = :crypto.hash(:sha512, "myseed")
iex> public_key1 = BlsEx.get_public_key(seed)
iex> signature1 = BlsEx.sign(seed, "hello")
iex> seed2 = :crypto.hash(:sha512, "myseed2")
iex> public_key2 = BlsEx.get_public_key(seed2)
iex> signature2 = BlsEx.sign(seed2, "hello")
iex> aggregated_signature = BlsEx.aggregate_signatures([signature1, signature2], [public_key1, public_key2])
iex> aggregated_public_key = BlsEx.aggregate_public_keys([public_key1, public_key2])
iex> BlsEx.verify_signature(aggregated_public_key, "hello", aggregated_signature)
true
"""
@version Mix.Project.config()[:version]
use RustlerPrecompiled,
otp_app: :bls_ex,
crate: "bls",
base_url: "https://github.com/archethic-foundation/bls_ex/releases/download/#{@version}",
force_build: System.get_env("BLS_EX_BUILD") in ["1", "true"],
targets:
Enum.uniq(["aarch64-unknown-linux-musl" | RustlerPrecompiled.Config.default_targets()]),
version: @version
@type secret_key :: <<_::512>>
@type signature :: <<_::96>>
@type public_key :: <<_::48>>
@doc """
Generate a public key from a secret key
"""
@spec get_public_key(secret_key :: secret_key()) :: public_key()
def get_public_key(secret_key) when is_binary(secret_key) and byte_size(secret_key) == 512,
do: :erlang.nif_error(:nif_not_loaded)
@doc """
Sign a message using the given secret key
"""
@spec sign(secret_key :: secret_key(), message :: binary()) :: signature()
def sign(secret_key, data)
when is_binary(secret_key) and byte_size(secret_key) == 512 and is_binary(data),
do: :erlang.nif_error(:nif_not_loaded)
@doc """
Verifies a single BLS signature
"""
@spec verify_signature(
public_key :: public_key(),
message :: binary(),
signature :: signature()
) ::
boolean()
def verify_signature(public_key, message, signature)
when is_binary(public_key) and byte_size(public_key) == 48 and is_binary(message) and
is_binary(signature) and byte_size(signature) == 96,
do: :erlang.nif_error(:nif_not_loaded)
@doc """
Aggregate a list of signatures
"""
@spec aggregate_signatures(list(signature()), list(public_key())) :: signature()
def aggregate_signatures(signatures, public_keys)
when is_list(signatures) and is_list(public_keys) and
length(signatures) == length(public_keys),
do: :erlang.nif_error(:nif_not_loaded)
@doc """
Aggregate a list of public keys
"""
@spec aggregate_public_keys(list(public_key())) :: public_key()
def aggregate_public_keys(public_keys) when is_list(public_keys),
do: :erlang.nif_error(:nif_not_loaded)
end