diff --git a/lib/salty/nif.ex b/lib/salty/nif.ex index a189fcd..4d04ceb 100644 --- a/lib/salty/nif.ex +++ b/lib/salty/nif.ex @@ -206,6 +206,8 @@ defmodule Salty.Nif do def sign_ed25519_SECRETKEYBYTES, do: :erlang.exit(:salty_nif_not_loaded) def sign_ed25519_seed_keypair(_), do: :erlang.exit(:salty_nif_not_loaded) def sign_ed25519_keypair(), do: :erlang.exit(:salty_nif_not_loaded) + def crypto_sign_ed25519_pk_to_curve25519(_), do: :erlang.exit(:salty_nif_not_loaded) + def crypto_sign_ed25519_sk_to_curve25519(_), do: :erlang.exit(:salty_nif_not_loaded) def sign_ed25519(_,_), do: :erlang.exit(:salty_nif_not_loaded) def sign_ed25519_detached(_,_), do: :erlang.exit(:salty_nif_not_loaded) def sign_ed25519_verify_detached(_,_,_), do: :erlang.exit(:salty_nif_not_loaded) diff --git a/lib/salty/sign.ex b/lib/salty/sign.ex index f2db70e..e557313 100644 --- a/lib/salty/sign.ex +++ b/lib/salty/sign.ex @@ -53,6 +53,10 @@ defmodule Salty.Sign do @callback keypair() :: {:ok, binary(), binary()} | {:error, atom()} + @callback crypto_sign_ed25519_pk_to_curve25519(binary()) :: {:ok, binary()} | {:error, atom()} + + @callback crypto_sign_ed25519_sk_to_curve25519(binary()) :: {:ok, binary()} | {:error, atom()} + @callback sign(binary(), binary()) :: {:ok, binary()} | {:error, atom()} @callback sign_detached(binary(), binary()) :: {:ok, binary()} | {:error, atom()} diff --git a/lib/salty/sign_ed25519.ex b/lib/salty/sign_ed25519.ex index 9d8ec88..9500a4e 100644 --- a/lib/salty/sign_ed25519.ex +++ b/lib/salty/sign_ed25519.ex @@ -25,6 +25,14 @@ defmodule Salty.Sign.Ed25519 do C.sign_ed25519_keypair() end + def crypto_sign_ed25519_pk_to_curve25519(data) do + C.crypto_sign_ed25519_pk_to_curve25519(data) + end + + def crypto_sign_ed25519_sk_to_curve25519(data) do + C.crypto_sign_ed25519_sk_to_curve25519(data) + end + def sign(data, sk) do C.sign_ed25519(data, sk) end diff --git a/src/salty_nif.c b/src/salty_nif.c index efe6164..a2cbb56 100644 --- a/src/salty_nif.c +++ b/src/salty_nif.c @@ -1662,6 +1662,24 @@ SALTY_FUNC(sign_ed25519_keypair, 0) DO pk.data, sk.data), pk, sk); END_OK_WITH2(pk, sk); +SALTY_FUNC(crypto_sign_ed25519_pk_to_curve25519, 1) DO + SALTY_INPUT_BIN(0, pk_ed25519, crypto_sign_ed25519_PUBLICKEYBYTES); +\ + SALTY_OUTPUT_BIN(pk_curve25519, crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES); + + SALTY_CALL2(crypto_sign_ed25519_pk_to_curve25519( + pk_curve25519.data, pk_ed25519.data), pk_ed25519, pk_curve25519); +END_OK_WITH(pk_curve25519); + +SALTY_FUNC(crypto_sign_ed25519_sk_to_curve25519, 1) DO + SALTY_INPUT_BIN(0, sk_ed25519, crypto_sign_ed25519_PUBLICKEYBYTES); +\ + SALTY_OUTPUT_BIN(sk_curve25519, crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES); + + SALTY_CALL2(crypto_sign_ed25519_sk_to_curve25519( + sk_curve25519.data, sk_ed25519.data), sk_ed25519, sk_curve25519); +END_OK_WITH(sk_curve25519); + SALTY_FUNC(sign_ed25519, 2) DO SALTY_INPUT_BIN(0, data, SALTY_BIN_NO_SIZE); SALTY_INPUT_BIN(1, sk, crypto_sign_ed25519_SECRETKEYBYTES); @@ -2194,6 +2212,8 @@ salty_exports[] = { SALTY_EXPORT_CONS(sign_ed25519_SECRETKEYBYTES, 0), SALTY_EXPORT_FUNC(sign_ed25519_seed_keypair, 1), SALTY_EXPORT_FUNC(sign_ed25519_keypair, 0), + SALTY_EXPORT_FUNC(crypto_sign_ed25519_pk_to_curve25519, 1), + SALTY_EXPORT_FUNC(crypto_sign_ed25519_sk_to_curve25519, 1), SALTY_EXPORT_FUNC(sign_ed25519, 2), SALTY_EXPORT_FUNC(sign_ed25519_detached, 2), SALTY_EXPORT_FUNC(sign_ed25519_verify_detached, 3), diff --git a/test/salty_test.exs b/test/salty_test.exs index 89b661c..3a307ae 100644 --- a/test/salty_test.exs +++ b/test/salty_test.exs @@ -130,4 +130,9 @@ defmodule SaltyTest do assert Salty.Sign.Ed25519.sk_to_pk(sk) == pk end + test "crypto_sign_ed25519_{pk,sk}_to_curve25519 works" do + {:ok, pk, sk} = Salty.Sign.Ed25519.keypair() + {:ok, _} = Salty.Sign.Ed25519.crypto_sign_ed25519_pk_to_curve25519(pk) + {:ok, _} = Salty.Sign.Ed25519.crypto_sign_ed25519_sk_to_curve25519(sk) + end end