Add some EcDSA functionality

This commit is contained in:
Hans Svensson
2022-01-13 16:13:35 +01:00
parent 247f726f0d
commit 06f0f0aa79
4 changed files with 87 additions and 2 deletions
+53
View File
@@ -0,0 +1,53 @@
%%% File : ecu_ecdsa.erl
%%% Author : Hans Svensson
%%% Description : ecdsa functionality
%%% Created : 13 Jan 2022 by Hans Svensson
-module(ecu_ecdsa).
-export([sign/3, verify/4,
sign_secp256k1/2,
private_to_public/2]).
private_to_public(secp256k1, <<PrivateKey:256>>) ->
ecu_secp256k1:compress(ecu_secp256k1:scalar_mul_base(PrivateKey)).
sign(secp256k1, MsgHash = <<_:32/bytes>>, PrivateKey = <<_:32/bytes>>) ->
{Sig, _YVal} = sign_secp256k1(MsgHash, PrivateKey),
Sig.
verify(secp256k1, MsgHash = <<_:32/bytes>>, PubKey = <<_:33/bytes>>, Sig = <<_:64/bytes>>) ->
verify(secp256k1, MsgHash, ecu_secp256k1:decompress(PubKey), Sig);
verify(secp256k1, MsgHash = <<_:32/bytes>>, PubKey = {_, _}, Sig = <<_:64/bytes>>) ->
<<E:256>> = MsgHash,
<<R:256, S:256>> = Sig,
Z = E rem ecu_secp256k1:n(),
W = ecu_secp256k1:s_inv(S),
[P1, P2] = ecu_misc:pcomp(
[fun() -> ecu_secp256k1:scalar_mul_base(ecu_secp256k1:s_mul(Z, W)) end,
fun() -> ecu_secp256k1:scalar_mul(ecu_secp256k1:s_mul(R, W), PubKey) end]),
{X, _Y} = ecu_secp256k1:p_add(P1, P2),
R == (X rem ecu_secp256k1:n()).
sign_secp256k1(MsgHash = <<_:32/bytes>>, PrivateKey = <<_:32/bytes>>) ->
<<E:256>> = MsgHash,
<<D:256>> = PrivateKey,
Z = E rem ecu_secp256k1:n(),
K = pick_k(secp256k1),
{X, Y} = ecu_secp256k1:scalar_mul_base(K),
R = X rem ecu_secp256k1:n(),
S = ecu_secp256k1:s_mul(ecu_secp256k1:s_inv(K),
ecu_secp256k1:s_add(Z, ecu_secp256k1:s_mul(R, D))),
if R == 0 orelse S == 0 ->
sign(secp256k1, MsgHash, PrivateKey);
true ->
{<<R:256, S:256>>, Y}
end.
%% --- internal functions
pick_k(secp256k1) ->
<<K:256>> = crypto:strong_rand_bytes(32),
case K == 0 orelse K >= ecu_secp256k1:n() of
true -> pick_k(secp256k1);
false -> K
end.
+6 -2
View File
@@ -4,7 +4,7 @@
%%% Created : 13 Jan 2022 by Hans Svensson
-module(ecu_misc).
-export([eea/2]).
-export([eea/2, pcomp/1]).
%% Extended Euclidean Algorithm
eea(A, B) when ((A < 1) or (B < 1)) ->
@@ -18,4 +18,8 @@ eea(G0, S0, T0, G1, S1, T1) ->
Q = G0 div G1,
eea(G1, S1, T1, G0 - (Q * G1), S0 - (Q * S1), T0 - (Q * T1)).
%% Very rudimentary parallel computation...
pcomp(Fs) ->
Parent = self(),
Pids = [ spawn(fun() -> Parent ! {self(), F()} end) || F <- Fs ],
[ receive {Pid, X} -> X after 500 -> error(timeout) end || Pid <- Pids ].