Add secp256k1
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
{registered, []},
|
||||
{applications, [kernel, stdlib]},
|
||||
{env,[]},
|
||||
{modules, []},
|
||||
{modules, [ecu_secp256k1, ecu_misc]},
|
||||
{licenses, ["MIT"]},
|
||||
{links, []}
|
||||
]}.
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
%%% File : ecu_misc.erl
|
||||
%%% Author : Hans Svensson
|
||||
%%% Description : Misc. functionality
|
||||
%%% Created : 13 Jan 2022 by Hans Svensson
|
||||
-module(ecu_misc).
|
||||
|
||||
-export([eea/2]).
|
||||
|
||||
%% Extended Euclidean Algorithm
|
||||
eea(A, B) when ((A < 1) or (B < 1)) ->
|
||||
undefined;
|
||||
eea(A, B) ->
|
||||
eea(A, 1, 0, B, 0, 1).
|
||||
|
||||
eea(G, S, T, 0, _, _) ->
|
||||
{G, S, T};
|
||||
eea(G0, S0, T0, G1, S1, T1) ->
|
||||
Q = G0 div G1,
|
||||
eea(G1, S1, T1, G0 - (Q * G1), S0 - (Q * S1), T0 - (Q * T1)).
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
%%% File : ecu_secp256k1.erl
|
||||
%%% Author : Hans Svensson
|
||||
%%% Description : Trying to whip together a pure Erlang secp256k1
|
||||
%%% Just for usage when speed isn't crucial...
|
||||
%%% Created : 22 Dec 2021 by Hans Svensson
|
||||
-module(ecu_secp256k1).
|
||||
|
||||
-define(P, 16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F).
|
||||
-define(A, 16#00).
|
||||
-define(B, 16#07).
|
||||
-define(X, 16#79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798).
|
||||
-define(Y, 16#483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8).
|
||||
-define(N, 16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141).
|
||||
-define(E, 16#7AE96A2B657C07106E64479EAC3434E99CF0497512F58995C1396C28719501EE).
|
||||
|
||||
-define(ADD(A, B), ((A + B) rem ?P)).
|
||||
-define(MUL(A, B), ((A * B) rem ?P)).
|
||||
-define(SUB(A, B), ((A - B + ?P) rem ?P)).
|
||||
-define(DIV(A, B), f_div(A, B)).
|
||||
|
||||
-export([on_curve/1, p/0, n/0,
|
||||
scalar_mul/2, scalar_mul_base/1, p_add/2, p_neg/1,
|
||||
compress/1, decompress/1,
|
||||
f_add/2, f_mul/2, f_sub/2, f_div/2, f_inv/1,
|
||||
s_add/2, s_mul/2, s_sub/2, s_div/2, s_inv/1]).
|
||||
|
||||
-ifdef(TEST).
|
||||
-compile([export_all, nowarn_export_all]).
|
||||
-endif.
|
||||
|
||||
on_curve({X, Y}) ->
|
||||
%% y^2 = x^3 + 7
|
||||
X3 = ?MUL(?MUL(X, X), X),
|
||||
Y2 = ?MUL(Y, Y),
|
||||
Y2 == ?ADD(X3, ?B).
|
||||
|
||||
p() -> ?P.
|
||||
|
||||
n() -> ?N.
|
||||
|
||||
scalar_mul_base(K) ->
|
||||
scalar_mul(K, {?X, ?Y}).
|
||||
|
||||
scalar_mul(0, _P) ->
|
||||
{0, 0};
|
||||
scalar_mul(1, P) ->
|
||||
P;
|
||||
scalar_mul(K, P) ->
|
||||
case K rem 2 == 0 of
|
||||
true -> scalar_mul(K div 2, p_add(P, P));
|
||||
false -> p_add(P, scalar_mul(K - 1, P))
|
||||
end.
|
||||
|
||||
compress({X, Y}) when Y rem 2 == 0 -> <<2:8, X:256>>;
|
||||
compress({X, _}) -> <<3:8, X:256>>;
|
||||
compress(<<4:8, X:256, Y:256>>) -> compress({X, Y}).
|
||||
|
||||
decompress(<<N:8, X:256>>) ->
|
||||
Y0 = ?B + ?MUL(X, ?MUL(X, X)),
|
||||
Y1 = pow(Y0, (?P + 1) div 4),
|
||||
case Y1 rem 2 == N rem 2 of
|
||||
true -> {X, Y1};
|
||||
false -> {X, ?P - Y1}
|
||||
end.
|
||||
|
||||
p_neg({X, Y}) -> {X, ?P - Y}.
|
||||
|
||||
p_add(P1, {0, 0}) -> P1;
|
||||
p_add({0, 0}, P2) -> P2;
|
||||
p_add({X, Y1}, {X, Y2}) when Y1 /= Y2 -> {0, 0};
|
||||
p_add(P = {X1, Y1}, P) ->
|
||||
M = ?DIV(?MUL(3, ?MUL(X1, X1)), ?MUL(2, Y1)),
|
||||
X3 = ?SUB(?MUL(M, M), ?MUL(2, X1)),
|
||||
Y3 = ?SUB(?MUL(M, ?SUB(X1, X3)), Y1),
|
||||
{X3, Y3};
|
||||
p_add({X1, Y1}, {X2, Y2}) ->
|
||||
M = ?DIV(?SUB(Y2, Y1), ?SUB(X2, X1)),
|
||||
X3 = ?SUB(?MUL(M, M), ?ADD(X1, X2)),
|
||||
Y3 = ?SUB(?MUL(M, ?SUB(X1, X3)), Y1),
|
||||
{X3, Y3}.
|
||||
|
||||
pow(_, 0) -> 1;
|
||||
pow(A, 1) -> A;
|
||||
pow(A, B) -> pow(A, B, 1).
|
||||
|
||||
pow(_, 0, R) -> R;
|
||||
pow(A, B, R) when B rem 2 == 0 -> pow(A * A, B bsr 1, R);
|
||||
pow(A, B, R) -> pow(?MUL(A, A), B bsr 1, ?MUL(R, A)).
|
||||
|
||||
%% Arithmetics in prime field P
|
||||
f_add(A, B) -> (A + B) rem ?P.
|
||||
f_mul(A, B) -> (A * B) rem ?P.
|
||||
f_sub(A, B) -> (A - B + ?P) rem ?P.
|
||||
f_div(A, B) -> f_mul(A, f_inv(B)).
|
||||
|
||||
f_inv(A) ->
|
||||
{1, S, _T} = ecu_misc:eea(A, ?P),
|
||||
(S + ?P) rem ?P.
|
||||
|
||||
%% Arithmetics in curve group order N
|
||||
s_add(A, B) -> (A + B) rem ?N.
|
||||
s_mul(A, B) -> (A * B) rem ?N.
|
||||
s_sub(A, B) -> (A - B + ?N) rem ?N.
|
||||
s_div(A, B) -> s_mul(A, s_inv(B)).
|
||||
|
||||
s_inv(A) ->
|
||||
{1, S, _T} = ecu_misc:eea(A, ?N),
|
||||
(S + ?N) rem ?N.
|
||||
|
||||
%% curve() ->
|
||||
%% #{ p => 16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F,
|
||||
%% a => 16#00, b => 16#07,
|
||||
%% x => 16#79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
|
||||
%% y => 16#483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8,
|
||||
%% n => 16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141,
|
||||
%% e => 16#7AE96A2B657C07106E64479EAC3434E99CF0497512F58995C1396C28719501EE
|
||||
%% }.
|
||||
Reference in New Issue
Block a user