|
1 | 1 | defmodule BlsEx do |
2 | 2 | @moduledoc """ |
3 | | - BlsEx provides utility to leverage BLS signatures through WASM |
4 | | - """ |
5 | | - alias __MODULE__.Keystore |
| 3 | + BlsEx provides utility to leverage BLS signatures |
6 | 4 |
|
7 | | - @doc """ |
8 | | - Verifies a single BLS signature |
| 5 | + BLS scheme supports aggregation of public keys and aggregation of signatures. |
9 | 6 |
|
10 | | - ## Examples |
| 7 | + Here an full example of aggregated signature verification |
11 | 8 |
|
12 | | - iex> {:ok, pid} = BlsEx.Keystore.start_link(seed: "myseed") |
13 | | - iex> {:ok, public_key} = BlsEx.Keystore.get_public_key(pid) |
14 | | - iex> {:ok, signature} = BlsEx.Keystore.sign(pid, "hello") |
15 | | - iex> BlsEx.verify_signature(public_key, "hello", signature) |
16 | | - {:ok, true} |
| 9 | + iex> seed = :crypto.hash(:sha512, "myseed") |
| 10 | + iex> public_key1 = BlsEx.get_public_key(seed) |
| 11 | + iex> signature1 = BlsEx.sign(seed, "hello") |
| 12 | + iex> seed2 = :crypto.hash(:sha512, "myseed2") |
| 13 | + iex> public_key2 = BlsEx.get_public_key(seed2) |
| 14 | + iex> signature2 = BlsEx.sign(seed2, "hello") |
| 15 | + iex> aggregated_signature = BlsEx.aggregate_signatures([signature1, signature2], [public_key1, public_key2]) |
| 16 | + iex> aggregated_public_key = BlsEx.aggregate_public_keys([public_key1, public_key2]) |
| 17 | + iex> BlsEx.verify_signature(aggregated_public_key, "hello", aggregated_signature) |
| 18 | + true |
17 | 19 | """ |
18 | | - @spec verify_signature(public_key :: binary(), message :: binary(), signature :: binary()) :: |
19 | | - {:ok, boolean()} | {:error, any()} |
20 | | - defdelegate verify_signature(public_key, message, signature), to: __MODULE__.StandaloneWasm |
21 | 20 |
|
22 | | - @doc """ |
23 | | - Aggregate BLS signatures |
| 21 | + @version Mix.Project.config()[:version] |
24 | 22 |
|
25 | | - ## Examples |
| 23 | + use RustlerPrecompiled, |
| 24 | + otp_app: :bls_ex, |
| 25 | + crate: "bls", |
| 26 | + base_url: "https://github.com/archethic-foundation/bls_ex/releases/download/#{@version}", |
| 27 | + force_build: System.get_env("BLS_EX_BUILD") in ["1", "true"], |
| 28 | + targets: |
| 29 | + Enum.uniq(["aarch64-unknown-linux-musl" | RustlerPrecompiled.Config.default_targets()]), |
| 30 | + version: @version |
26 | 31 |
|
27 | | - iex> {:ok, pid} = BlsEx.Keystore.start_link(seed: "myseed") |
28 | | - iex> {:ok, public_key1} = BlsEx.Keystore.get_public_key(pid) |
29 | | - iex> {:ok, signature1} = BlsEx.Keystore.sign(pid, "hello") |
30 | | - iex> {:ok, pid2} = BlsEx.Keystore.start_link(seed: "myseed2") |
31 | | - iex> {:ok, public_key2} = BlsEx.Keystore.get_public_key(pid2) |
32 | | - iex> {:ok, signature2} = BlsEx.Keystore.sign(pid2, "hello") |
33 | | - iex> BlsEx.aggregate_signatures([signature1, signature2], [public_key1, public_key2]) |
34 | | - """ |
35 | | - @spec aggregate_signatures(signatures :: list(binary()), public_keys :: list(binary())) :: |
36 | | - {:ok, binary()} | {:error, any()} |
37 | | - defdelegate aggregate_signatures(signatures, public_keys), to: __MODULE__.StandaloneWasm |
| 32 | + @type secret_key :: <<_::512>> |
| 33 | + @type signature :: <<_::96>> |
| 34 | + @type public_key :: <<_::48>> |
38 | 35 |
|
39 | 36 | @doc """ |
40 | | - Aggregate BLS public keys |
41 | | -
|
42 | | - ## Examples |
| 37 | + Generate a public key from a secret key |
| 38 | + """ |
| 39 | + @spec get_public_key(secret_key :: secret_key()) :: public_key() |
| 40 | + def get_public_key(secret_key) when is_binary(secret_key) and byte_size(secret_key) == 512, |
| 41 | + do: :erlang.nif_error(:nif_not_loaded) |
43 | 42 |
|
44 | | - iex> {:ok, pid} = BlsEx.Keystore.start_link(seed: "myseed") |
45 | | - iex> {:ok, public_key1} = BlsEx.Keystore.get_public_key(pid) |
46 | | - iex> {:ok, pid2} = BlsEx.Keystore.start_link(seed: "myseed2") |
47 | | - iex> {:ok, public_key2} = BlsEx.Keystore.get_public_key(pid2) |
48 | | - iex> {:ok, _aggregated_public_key} = BlsEx.aggregated_public_keys([public_key1, public_key2]) |
| 43 | + @doc """ |
| 44 | + Sign a message using the given secret key |
49 | 45 | """ |
50 | | - @spec aggregated_public_keys(public_keys :: list(binary())) :: {:ok, binary()} | {:error, any()} |
51 | | - defdelegate aggregated_public_keys(public_keys), to: __MODULE__.StandaloneWasm |
| 46 | + @spec sign(secret_key :: secret_key(), message :: binary()) :: signature() |
| 47 | + def sign(secret_key, data) |
| 48 | + when is_binary(secret_key) and byte_size(secret_key) == 512 and is_binary(data), |
| 49 | + do: :erlang.nif_error(:nif_not_loaded) |
52 | 50 |
|
53 | 51 | @doc """ |
54 | | - Verifies an aggregated BLS signature |
| 52 | + Verifies a single BLS signature |
| 53 | + """ |
| 54 | + @spec verify_signature( |
| 55 | + public_key :: public_key(), |
| 56 | + message :: binary(), |
| 57 | + signature :: signature() |
| 58 | + ) :: |
| 59 | + boolean() |
| 60 | + def verify_signature(public_key, message, signature) |
| 61 | + when is_binary(public_key) and byte_size(public_key) == 48 and is_binary(message) and |
| 62 | + is_binary(signature) and byte_size(signature) == 96, |
| 63 | + do: :erlang.nif_error(:nif_not_loaded) |
55 | 64 |
|
56 | | - ## Examples |
| 65 | + @doc """ |
| 66 | + Aggregate a list of signatures |
| 67 | + """ |
| 68 | + @spec aggregate_signatures(list(signature()), list(public_key())) :: signature() |
| 69 | + def aggregate_signatures(signatures, public_keys) |
| 70 | + when is_list(signatures) and is_list(public_keys) and |
| 71 | + length(signatures) == length(public_keys), |
| 72 | + do: :erlang.nif_error(:nif_not_loaded) |
57 | 73 |
|
58 | | - iex> {:ok, pid} = BlsEx.Keystore.start_link(seed: "myseed") |
59 | | - iex> {:ok, public_key1} = BlsEx.Keystore.get_public_key(pid) |
60 | | - iex> {:ok, signature1} = BlsEx.Keystore.sign(pid, "hello") |
61 | | - iex> {:ok, pid2} = BlsEx.Keystore.start_link(seed: "myseed2") |
62 | | - iex> {:ok, public_key2} = BlsEx.Keystore.get_public_key(pid2) |
63 | | - iex> {:ok, signature2} = BlsEx.Keystore.sign(pid2, "hello") |
64 | | - iex> {:ok, aggregated_signature} = BlsEx.aggregate_signatures([signature1, signature2], [public_key1, public_key2]) |
65 | | - iex> BlsEx.verify_aggregated_signature( [public_key1, public_key2], "hello", aggregated_signature) |
66 | | - {:ok, true} |
| 74 | + @doc """ |
| 75 | + Aggregate a list of public keys |
67 | 76 | """ |
68 | | - @spec verify_aggregated_signature(list(binary()), binary(), binary()) :: |
69 | | - {:ok, boolean()} | {:error, any()} |
70 | | - defdelegate verify_aggregated_signature(public_keys, message, signature), |
71 | | - to: __MODULE__.StandaloneWasm |
| 77 | + @spec aggregate_public_keys(list(public_key())) :: public_key() |
| 78 | + def aggregate_public_keys(public_keys) when is_list(public_keys), |
| 79 | + do: :erlang.nif_error(:nif_not_loaded) |
72 | 80 | end |
0 commit comments