From c43fb6f96eaa7e2c4bc070c0518888ebb84569ba Mon Sep 17 00:00:00 2001 From: Rahul Guha <69rahul16@gmail.com> Date: Fri, 10 May 2024 16:52:19 +0530 Subject: [PATCH 1/7] added fn to lib.rs --- native/bls_nif/src/lib.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/native/bls_nif/src/lib.rs b/native/bls_nif/src/lib.rs index 57faf24df..c7ee19e9f 100644 --- a/native/bls_nif/src/lib.rs +++ b/native/bls_nif/src/lib.rs @@ -161,6 +161,14 @@ fn key_validate<'env>(public_key: Binary) -> Result { Ok(true) } +#[rustler::nif] +fn derive_pubkey<'env>(private_key:Binary) -> Binary<'env> { + let sk = match SecretKey::deserialize(private_key.as_slice()) { + Ok(sk) => sk, + Err(e) => return Err(format!("{:?}", e)), + }; + Ok(sk.public_key()) +} rustler::init!( "Elixir.Bls", @@ -172,6 +180,7 @@ rustler::init!( eth_fast_aggregate_verify, eth_aggregate_pubkeys, verify, - key_validate + key_validate, + derive_pubkey ] ); From 4128d05d2f02348860b322350f1c3d7ff44e086b Mon Sep 17 00:00:00 2001 From: Rahul Guha <69rahul16@gmail.com> Date: Fri, 10 May 2024 16:52:44 +0530 Subject: [PATCH 2/7] added elixir code and test case --- lib/bls.ex | 11 +++++++++++ lib/keystore.ex | 3 +++ test/unit/bls_test.exs | 9 +++++++++ 3 files changed, 23 insertions(+) diff --git a/lib/bls.ex b/lib/bls.ex index 426b6e6a2..d6629765e 100644 --- a/lib/bls.ex +++ b/lib/bls.ex @@ -77,4 +77,15 @@ defmodule Bls do {:error, _} -> false end end + + @doc """ + Converts private to public key + """ + @spec derive_pubkey?(privkey()) :: pubkey() + def derive_pubkey?(private_key) do + case Bls.derive_pubkey(private_key) do + {:ok, bool} -> bool + {:error, _} -> false + end + end end diff --git a/lib/keystore.ex b/lib/keystore.ex index 959d292ab..87f6dc5b1 100644 --- a/lib/keystore.ex +++ b/lib/keystore.ex @@ -25,6 +25,9 @@ defmodule Keystore do privkey = decrypt!(decoded_json["crypto"], password) # TODO: derive from privkey and validate with this pubkey pubkey = Map.fetch!(decoded_json, "pubkey") |> parse_binary!() + if Bls.derive_pubkey(privkey) == pubkey do + raise("Incorrect public key extracted") + end {pubkey, privkey} end diff --git a/test/unit/bls_test.exs b/test/unit/bls_test.exs index 3440eb4f0..ea2bf4e18 100644 --- a/test/unit/bls_test.exs +++ b/test/unit/bls_test.exs @@ -17,4 +17,13 @@ defmodule BlsTest do assert Bls.key_validate(invalid_public_key) == {:error, "BlstError(BLST_BAD_ENCODING)"} end end + + describe "Private to public key" do + test "return the correct public key for a private key" do + valid_public_key = Base.decode16!("8abb15ca57942b6225af4710bbb74ce8466e99fdc2264d9ffd3b335c7396667e45f537ff1f75ed5afa00585db274f3b6",case: :mixed) + private_key = Base.decode16!("18363054f52f3f1fdc9ae50d271de853c582c652ebe8dd0f261da3b00cd98984", case: :mixed) + assert Bls.derive_pubkey(private_key)==valid_public_key + end + end + end From 57d5eb5a72dc3e81aaac8ae277f38bc28e3c479a Mon Sep 17 00:00:00 2001 From: Rahul Guha <69rahul16@gmail.com> Date: Sun, 19 May 2024 20:55:45 +0530 Subject: [PATCH 3/7] message change --- lib/keystore.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/keystore.ex b/lib/keystore.ex index 87f6dc5b1..61c02472b 100644 --- a/lib/keystore.ex +++ b/lib/keystore.ex @@ -26,7 +26,7 @@ defmodule Keystore do # TODO: derive from privkey and validate with this pubkey pubkey = Map.fetch!(decoded_json, "pubkey") |> parse_binary!() if Bls.derive_pubkey(privkey) == pubkey do - raise("Incorrect public key extracted") + raise("Keystore secret and public keys don't form a valid pair") end {pubkey, privkey} end From 98db51f0791957579c3947fd28abf09a26286a19 Mon Sep 17 00:00:00 2001 From: Rahul Guha <69rahul16@gmail.com> Date: Sun, 19 May 2024 21:29:20 +0530 Subject: [PATCH 4/7] add derive_pubkey function to Bls module --- lib/bls.ex | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/bls.ex b/lib/bls.ex index d6629765e..6b1d93668 100644 --- a/lib/bls.ex +++ b/lib/bls.ex @@ -54,6 +54,10 @@ defmodule Bls do :erlang.nif_error(:nif_not_loaded) end + @spec derive_pubkey(privkey()) :: {:ok, pubkey()} | {:error, any()} + def derive_pubkey(private_key) do + Rustler.safe_nif_call(:derive_pubkey, [private_key]) + end ##### Helpers ##### @doc """ Same as ``Bls.verify``, but treats errors as invalid signatures. @@ -81,10 +85,10 @@ defmodule Bls do @doc """ Converts private to public key """ - @spec derive_pubkey?(privkey()) :: pubkey() + @spec derive_pubkey?(privkey()) :: {:ok, pubkey()} | {:error, any()} def derive_pubkey?(private_key) do case Bls.derive_pubkey(private_key) do - {:ok, bool} -> bool + {:ok, pubkey} -> pubkey {:error, _} -> false end end From b9a76d43f0b5133dca3d0bdf038cfcddf6031c1f Mon Sep 17 00:00:00 2001 From: Rahul Guha <69rahul16@gmail.com> Date: Sun, 19 May 2024 23:07:45 +0530 Subject: [PATCH 5/7] smol fixes --- lib/bls.ex | 4 ++-- native/bls_nif/src/lib.rs | 7 +++++-- test/unit/bls_test.exs | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/bls.ex b/lib/bls.ex index 6b1d93668..8b87706c4 100644 --- a/lib/bls.ex +++ b/lib/bls.ex @@ -55,8 +55,8 @@ defmodule Bls do end @spec derive_pubkey(privkey()) :: {:ok, pubkey()} | {:error, any()} - def derive_pubkey(private_key) do - Rustler.safe_nif_call(:derive_pubkey, [private_key]) + def derive_pubkey(_private_key) do + :erlang.nif_error(:nif_not_loaded) end ##### Helpers ##### @doc """ diff --git a/native/bls_nif/src/lib.rs b/native/bls_nif/src/lib.rs index c7ee19e9f..b34d9bc58 100644 --- a/native/bls_nif/src/lib.rs +++ b/native/bls_nif/src/lib.rs @@ -162,12 +162,15 @@ fn key_validate<'env>(public_key: Binary) -> Result { Ok(true) } #[rustler::nif] -fn derive_pubkey<'env>(private_key:Binary) -> Binary<'env> { +fn derive_pubkey<'env>(env: Env<'env>,private_key:Binary) -> Result, String> { let sk = match SecretKey::deserialize(private_key.as_slice()) { Ok(sk) => sk, Err(e) => return Err(format!("{:?}", e)), }; - Ok(sk.public_key()) + let public_key = sk.public_key(); + let public_key_bytes = public_key.serialize(); + + Ok(bytes_to_binary(env, &public_key_bytes)) } rustler::init!( diff --git a/test/unit/bls_test.exs b/test/unit/bls_test.exs index ea2bf4e18..6a76054ac 100644 --- a/test/unit/bls_test.exs +++ b/test/unit/bls_test.exs @@ -22,7 +22,7 @@ defmodule BlsTest do test "return the correct public key for a private key" do valid_public_key = Base.decode16!("8abb15ca57942b6225af4710bbb74ce8466e99fdc2264d9ffd3b335c7396667e45f537ff1f75ed5afa00585db274f3b6",case: :mixed) private_key = Base.decode16!("18363054f52f3f1fdc9ae50d271de853c582c652ebe8dd0f261da3b00cd98984", case: :mixed) - assert Bls.derive_pubkey(private_key)==valid_public_key + assert Bls.derive_pubkey(private_key)=={:ok, valid_public_key} end end From 4a4c0c5815fec35cf7e48312b4f7b1a23fdf6c62 Mon Sep 17 00:00:00 2001 From: Rahul Guha <69rahul16@gmail.com> Date: Mon, 20 May 2024 05:44:20 +0530 Subject: [PATCH 6/7] fix dialyzer issue and derive_pubkey fix --- lib/bls.ex | 12 ++++-------- lib/keystore.ex | 6 ++++-- native/bls_nif/src/lib.rs | 2 +- test/unit/bls_test.exs | 16 ++++++++++++---- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/lib/bls.ex b/lib/bls.ex index 8b87706c4..1122e0915 100644 --- a/lib/bls.ex +++ b/lib/bls.ex @@ -54,10 +54,6 @@ defmodule Bls do :erlang.nif_error(:nif_not_loaded) end - @spec derive_pubkey(privkey()) :: {:ok, pubkey()} | {:error, any()} - def derive_pubkey(_private_key) do - :erlang.nif_error(:nif_not_loaded) - end ##### Helpers ##### @doc """ Same as ``Bls.verify``, but treats errors as invalid signatures. @@ -85,11 +81,11 @@ defmodule Bls do @doc """ Converts private to public key """ - @spec derive_pubkey?(privkey()) :: {:ok, pubkey()} | {:error, any()} - def derive_pubkey?(private_key) do + @spec derive_pubkey(privkey()) :: {:ok, pubkey()} | {:error, any()} + def derive_pubkey(private_key) do case Bls.derive_pubkey(private_key) do - {:ok, pubkey} -> pubkey - {:error, _} -> false + {:ok, pubkey} -> {:ok, pubkey} + error -> error end end end diff --git a/lib/keystore.ex b/lib/keystore.ex index 61c02472b..753055e49 100644 --- a/lib/keystore.ex +++ b/lib/keystore.ex @@ -23,11 +23,13 @@ defmodule Keystore do validate_empty_path!(decoded_json["path"]) privkey = decrypt!(decoded_json["crypto"], password) - # TODO: derive from privkey and validate with this pubkey + pubkey = Map.fetch!(decoded_json, "pubkey") |> parse_binary!() - if Bls.derive_pubkey(privkey) == pubkey do + + if Bls.derive_pubkey(privkey) != {:ok, pubkey} do raise("Keystore secret and public keys don't form a valid pair") end + {pubkey, privkey} end diff --git a/native/bls_nif/src/lib.rs b/native/bls_nif/src/lib.rs index b34d9bc58..f048be374 100644 --- a/native/bls_nif/src/lib.rs +++ b/native/bls_nif/src/lib.rs @@ -162,7 +162,7 @@ fn key_validate<'env>(public_key: Binary) -> Result { Ok(true) } #[rustler::nif] -fn derive_pubkey<'env>(env: Env<'env>,private_key:Binary) -> Result, String> { +fn derive_pubkey<'env>(env: Env<'env>, private_key: Binary) -> Result, String> { let sk = match SecretKey::deserialize(private_key.as_slice()) { Ok(sk) => sk, Err(e) => return Err(format!("{:?}", e)), diff --git a/test/unit/bls_test.exs b/test/unit/bls_test.exs index 6a76054ac..fdf489bfa 100644 --- a/test/unit/bls_test.exs +++ b/test/unit/bls_test.exs @@ -20,10 +20,18 @@ defmodule BlsTest do describe "Private to public key" do test "return the correct public key for a private key" do - valid_public_key = Base.decode16!("8abb15ca57942b6225af4710bbb74ce8466e99fdc2264d9ffd3b335c7396667e45f537ff1f75ed5afa00585db274f3b6",case: :mixed) - private_key = Base.decode16!("18363054f52f3f1fdc9ae50d271de853c582c652ebe8dd0f261da3b00cd98984", case: :mixed) - assert Bls.derive_pubkey(private_key)=={:ok, valid_public_key} + valid_public_key = + Base.decode16!( + "8abb15ca57942b6225af4710bbb74ce8466e99fdc2264d9ffd3b335c7396667e45f537ff1f75ed5afa00585db274f3b6", + case: :mixed + ) + + private_key = + Base.decode16!("18363054f52f3f1fdc9ae50d271de853c582c652ebe8dd0f261da3b00cd98984", + case: :mixed + ) + + assert Bls.derive_pubkey(private_key) == {:ok, valid_public_key} end end - end From a01d5c3551e8c5063d647320c457bc86ad7c79b1 Mon Sep 17 00:00:00 2001 From: Rahul Guha <69rahul16@gmail.com> Date: Mon, 20 May 2024 23:22:27 +0530 Subject: [PATCH 7/7] fix --- lib/bls.ex | 16 +++++----------- lib/keystore.ex | 4 +++- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/lib/bls.ex b/lib/bls.ex index 1122e0915..cc6320e3e 100644 --- a/lib/bls.ex +++ b/lib/bls.ex @@ -54,6 +54,11 @@ defmodule Bls do :erlang.nif_error(:nif_not_loaded) end + @spec derive_pubkey(privkey()) :: {:ok, pubkey()} | {:error, any()} + def derive_pubkey(_private_key) do + :erlang.nif_error(:nif_not_loaded) + end + ##### Helpers ##### @doc """ Same as ``Bls.verify``, but treats errors as invalid signatures. @@ -77,15 +82,4 @@ defmodule Bls do {:error, _} -> false end end - - @doc """ - Converts private to public key - """ - @spec derive_pubkey(privkey()) :: {:ok, pubkey()} | {:error, any()} - def derive_pubkey(private_key) do - case Bls.derive_pubkey(private_key) do - {:ok, pubkey} -> {:ok, pubkey} - error -> error - end - end end diff --git a/lib/keystore.ex b/lib/keystore.ex index b35fb2a30..259a7499b 100644 --- a/lib/keystore.ex +++ b/lib/keystore.ex @@ -26,7 +26,9 @@ defmodule Keystore do pubkey = Map.fetch!(decoded_json, "pubkey") |> parse_binary!() - if Bls.derive_pubkey(privkey) != {:ok, pubkey} do + {:ok, derived_pubkey} = Bls.derive_pubkey(privkey) + + if derived_pubkey != pubkey do raise("Keystore secret and public keys don't form a valid pair") end