Skip to content

Commit ec4f814

Browse files
Add doctests
1 parent 0e154cb commit ec4f814

File tree

2 files changed

+67
-34
lines changed

2 files changed

+67
-34
lines changed

lib/bls_ex.ex

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,72 @@
11
defmodule BlsEx do
2+
@moduledoc """
3+
BlsEx provides utility to leverage BLS signatures through WASM
4+
"""
25
alias __MODULE__.Keystore
36

47
@doc """
5-
Creates a new BLS keystore
8+
Verifies a single BLS signature
69
710
## Examples
811
9-
iex> {:ok, pid} = BlsEx.new_keystore("myseed")
12+
iex> {:ok, pid} = BlsEx.Keystore.start_link(seed: "myseed")
1013
iex> {:ok, public_key} = BlsEx.Keystore.get_public_key(pid)
1114
iex> {:ok, signature} = BlsEx.Keystore.sign(pid, "hello")
12-
"""
13-
@spec new_keystore(binary()) :: GenServer.on_start()
14-
def new_keystore(seed) do
15-
Keystore.start_link(seed: seed)
16-
end
17-
18-
@doc """
19-
Verifies a single BLS signature
15+
iex> BlsEx.verify_signature(public_key, "hello", signature)
16+
{:ok, true}
2017
"""
2118
@spec verify_signature(public_key :: binary(), message :: binary(), signature :: binary()) ::
2219
{:ok, boolean()} | {:error, any()}
2320
defdelegate verify_signature(public_key, message, signature), to: __MODULE__.StandaloneWasm
2421

2522
@doc """
2623
Aggregate BLS signatures
24+
25+
## Examples
26+
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])
2734
"""
2835
@spec aggregate_signatures(signatures :: list(binary()), public_keys :: list(binary())) ::
2936
{:ok, binary()} | {:error, any()}
3037
defdelegate aggregate_signatures(signatures, public_keys), to: __MODULE__.StandaloneWasm
3138

3239
@doc """
3340
Aggregate BLS public keys
41+
42+
## Examples
43+
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])
3449
"""
3550
@spec aggregated_public_keys(public_keys :: list(binary())) :: {:ok, binary()} | {:error, any()}
3651
defdelegate aggregated_public_keys(public_keys), to: __MODULE__.StandaloneWasm
3752

3853
@doc """
3954
Verifies an aggregated BLS signature
55+
56+
## Examples
57+
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}
4067
"""
4168
@spec verify_aggregated_signature(list(binary()), binary(), binary()) ::
4269
{:ok, boolean()} | {:error, any()}
4370
defdelegate verify_aggregated_signature(public_keys, message, signature),
4471
to: __MODULE__.StandaloneWasm
45-
46-
def test() do
47-
{:ok, keystore1} = new_keystore("test")
48-
# {:ok, keystore2} = new_keystore("test2")
49-
# {:ok, public_key1} = Keystore.get_public_key(keystore1)
50-
# {:ok, public_key2} = Keystore.get_public_key(keystore2)
51-
# {:ok, signature1} = Keystore.sign(keystore1, "hello")
52-
# # # IO.inspect(Base.encode16(signature1))
53-
# {:ok, signature2} = Keystore.sign(keystore2, "hello")
54-
# # IO.inspect(Base.encode16(signature2))
55-
56-
# verify_signature(public_key1, "hello", signature1)
57-
# #
58-
# {:ok, agg_signature} =
59-
# aggregate_signatures([signature1, signature2], [public_key1, public_key2])
60-
61-
# # # IO.inspect(Base.encode16(agg_signature))
62-
# verify_aggregated_signature([public_key1, public_key2], "hello", agg_signature)
63-
end
6472
end

lib/bls_ex/keystore.ex

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,28 @@
11
defmodule BlsEx.Keystore do
2+
@doc """
3+
Represents a keystore holding a the wasm instance for the given private key
4+
5+
To use the keystore, you have to instanciate it with `start_link/1` and later use either `sign/2` or `get_public_key/1`
6+
7+
## Examples
8+
9+
iex> {:ok, pid} = BlsEx.Keystore.start_link(seed: "myseed")
10+
iex> {:ok, _signature} = BlsEx.Keystore.sign(pid, "hello")
11+
"""
12+
213
use GenServer
314

415
@wasm_path Application.compile_env!(:bls_ex, :wasm_path)
516

17+
@type options :: [seed: binary()]
18+
19+
@doc """
20+
Start a new keystore instance.
21+
22+
It requires to pass a keyword list options:
23+
- `seed`: The private key entropy used to generate public key and sign data
24+
"""
25+
@spec start_link(options) :: GenServer.on_start()
626
def start_link(arg \\ []) do
727
GenServer.start_link(__MODULE__, arg)
828
end
@@ -37,16 +57,21 @@ defmodule BlsEx.Keystore do
3757
}
3858

3959
{:ok, plugin} = Extism.Plugin.new(manifest)
40-
{:ok, %{plugin: plugin, seed_fn: fn -> seed end}}
60+
61+
{:ok,
62+
%{
63+
plugin: plugin,
64+
seed: seed
65+
}}
4166
end
4267

4368
defp seed_digest(seed), do: :crypto.hash(:sha512, seed)
4469

45-
def handle_call(:get_public_key, _from, state = %{plugin: plugin, seed_fn: seed_fn}) do
70+
def handle_call(:get_public_key, _from, state = %{plugin: plugin, seed: seed}) do
4671
case Extism.Plugin.call(
4772
plugin,
4873
"getPublicKey",
49-
Base.encode16(seed_fn.())
74+
Base.encode16(seed)
5075
) do
5176
{:ok, public_key_hex} ->
5277
{:reply, {:ok, Base.decode16!(public_key_hex, case: :mixed)}, state}
@@ -56,11 +81,11 @@ defmodule BlsEx.Keystore do
5681
end
5782
end
5883

59-
def handle_call({:sign, message}, _from, state = %{plugin: plugin, seed_fn: seed_fn}) do
84+
def handle_call({:sign, message}, _from, state = %{plugin: plugin, seed: seed}) do
6085
case Extism.Plugin.call(
6186
plugin,
6287
"signData",
63-
Jason.encode!(%{seed: Base.encode16(seed_fn.()), data: message})
88+
Jason.encode!(%{seed: Base.encode16(seed), data: message})
6489
) do
6590
{:ok, signature_hex} ->
6691
{:reply, {:ok, Base.decode16!(signature_hex, case: :mixed)}, state}

0 commit comments

Comments
 (0)