Refactored + added some test vector support

This commit is contained in:
Hans Svensson
2018-03-06 10:06:03 +01:00
parent bc8ebc7ec6
commit b1d63ad3b9
11 changed files with 20033 additions and 54 deletions
+100 -8
View File
@@ -8,10 +8,13 @@
, dh/1
, from_name/1
, hash/1
, msgs/2
, pattern/1
, pre_msgs/2
, to_name/1]).
-compile(export_all).
-type noise_pattern() :: nn | xk.
-type noise_msg() :: {in | out, [enoise_hs_state:noise_token()]}.
-record(noise_protocol,
{ hs_pattern = noiseNN :: noise_pattern()
@@ -22,7 +25,7 @@
-opaque protocol() :: #noise_protocol{}.
-export_type([noise_pattern/0, protocol/0]).
-export_type([noise_msg/0, noise_pattern/0, protocol/0]).
-spec cipher(Protocol :: protocol()) -> enoise_cipher_state:noise_cipher().
cipher(#noise_protocol{ cipher = Cipher }) ->
@@ -40,11 +43,100 @@ hash(#noise_protocol{ hash = Hash }) ->
pattern(#noise_protocol{ hs_pattern = Pattern }) ->
Pattern.
to_name(_Protocol) ->
<<"Noise_XK_25519_ChaChaPoly_BLAKE2b">>.
-spec to_name(Protocol :: protocol()) -> binary().
to_name(Protocol = #noise_protocol{ hs_pattern = Pattern, dh = Dh
, cipher = Cipher, hash = Hash }) ->
case supported_pattern(Pattern) andalso supported_dh(Dh) andalso
supported_cipher(Cipher) andalso supported_hash(Hash) of
true -> to_name(Pattern, Dh, Cipher, Hash);
false -> error({protocol_not_recognized, Protocol})
end.
from_name("Noise_XK_25519_ChaChaPoly_Blake2b") ->
#noise_protocol{ hs_pattern = xk, dh = dh25519, cipher = 'ChaChaPoly', hash = blake2b };
from_name(Name) ->
error({protocol_not_implemented_yet, Name}).
-spec from_name(Name :: string() | binary()) -> protocol().
from_name(Bin) when is_binary(Bin) -> from_name(binary_to_list(Bin));
from_name(String) ->
case string:lexemes(String, "_") of
["Noise", PatStr, DhStr, CipStr, HashStr] ->
Pattern = from_name_pattern(PatStr),
Dh = from_name_dh(DhStr),
Cipher = from_name_cipher(CipStr),
Hash = from_name_hash(HashStr),
case supported_pattern(Pattern) andalso supported_dh(Dh) andalso
supported_cipher(Cipher) andalso supported_hash(Hash) of
true -> #noise_protocol{ hs_pattern = Pattern, dh = Dh
, cipher = Cipher, hash = Hash };
false -> error({name_not_recognized, String})
end;
_ ->
error({name_not_recognized, String})
end.
-spec msgs(Role :: enoise_hs_state:noise_role(), Protocol :: protocol()) -> [noise_msg()].
msgs(Role, #noise_protocol{ hs_pattern = Pattern }) ->
{_Pre, Msgs} = protocol(Pattern),
role_adapt(Role, Msgs).
-spec pre_msgs(Role :: enoise_hs_state:noise_role(), Protocol :: protocol()) -> [noise_msg()].
pre_msgs(Role, #noise_protocol{ hs_pattern = Pattern }) ->
{PreMsgs, _Msgs} = protocol(Pattern),
role_adapt(Role, PreMsgs).
role_adapt(initiator, Msgs) ->
Msgs;
role_adapt(responder, Msgs) ->
Flip = fun({in, Msg}) -> {out, Msg}; ({out, Msg}) -> {in, Msg} end,
lists:map(Flip, Msgs).
protocol(nn) ->
{[], [{out, [e]}, {in, [e, ee]}]};
protocol(kn) ->
{[{out, [s]}], [{out, [e]}, {in, [e, ee, se]}]};
protocol(nk) ->
{[{in, [s]}], [{out, [e, es]}, {in, [e, ee]}]};
protocol(xk) ->
{[{in, [s]}], [{out, [e, es]}, {in, [e, ee]}, {out, [s, se]}]}.
supported_hash(Hash) ->
lists:member(Hash, [blake2b, sha256, sha512]).
supported_cipher(Cipher) ->
lists:member(Cipher, ['ChaChaPoly', 'AESGCM']).
supported_dh(Dh) ->
lists:member(Dh, [dh25519]).
supported_pattern(P) ->
lists:member(P, [nn, kn, nk, xk]).
to_name(Pattern, Dh, Cipher, Hash) ->
list_to_binary(lists:join("_", ["Noise", to_name_pattern(Pattern), to_name_dh(Dh),
to_name_cipher(Cipher), to_name_hash(Hash)])).
to_name_pattern(Atom) ->
[Simple | Rest] = string:lexemes(atom_to_list(Atom), "_"),
string:uppercase(Simple) ++ lists:join("+", Rest).
from_name_pattern(String) ->
[Init | Mod2] = string:lexemes(String, "+"),
{Simple, Mod1} = lists:splitwith(fun(C) -> C >= $A andalso C =< $Z end, Init),
list_to_atom(string:lowercase(Simple) ++
case Mod1 of
"" -> "";
_ -> "_" ++ lists:join([Mod1 | Mod2], "_")
end).
to_name_dh(dh25519) -> "25519";
to_name_dh(dh448) -> "448".
from_name_dh(Dh) -> list_to_atom("dh" ++ Dh).
to_name_cipher(Cipher) -> atom_to_list(Cipher).
from_name_cipher(Cipher) -> list_to_atom(Cipher).
to_name_hash(sha256) -> "SHA256";
to_name_hash(sha512) -> "SHA512";
to_name_hash(blake2s) -> "BLAKE2s";
to_name_hash(blake2b) -> "BLAKE2b".
from_name_hash(Hash) -> list_to_atom(string:lowercase(Hash)).