diff --git a/src/ecu_ed25519.erl b/src/ecu_ed25519.erl index 4db11cb..512bd43 100644 --- a/src/ecu_ed25519.erl +++ b/src/ecu_ed25519.erl @@ -11,12 +11,12 @@ -type pt_affine() :: {non_neg_integer(), non_neg_integer()}. %% {X, Y} -type pt_hom_ext() :: {non_neg_integer(), non_neg_integer(), non_neg_integer(), non_neg_integer()}. %% {X, Y, Z, T} --type pt_compressed() :: <<_:32>>. %% Y coord + odd/even X. +-type pt_compressed() :: <<_:256>>. %% Y coord + odd/even X. -type pt() :: pt_affine() | pt_hom_ext() | pt_compressed(). %% -type fld_elem() :: 0..(?P-1). --type scalar() :: 0..(?N-1). +-type scalar() :: 0..(?N-1). -define(D, 16#52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3). -define(X, 16#216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A). @@ -33,6 +33,8 @@ -define(SUB(A, B), ((A - B + ?P) rem ?P)). -define(DIV(A, B), f_div(A, B)). +-export_type([pt/0, scalar/0]). + -export([on_curve/1, p/0, n/0, pt_eq/2, scalar_mul/2, scalar_mul_base/1, scalar_mul_noclamp/2, scalar_mul_base_noclamp/1, @@ -76,14 +78,14 @@ n() -> ?N. -define(TWO_POW_255_MINUS_1, 16#7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF). --spec compress(P :: pt()) -> <<_:32>>. +-spec compress(P :: pt()) -> pt_compressed(). compress(<<_:32/binary>> = P) -> P; compress({_, _, _, _} = P) -> compress(to_affine(P)); compress({X, Y}) -> V = (Y band ?TWO_POW_255_MINUS_1) bor ((X band 1) bsl 255), <>. --spec decompress(<<_:32>>) -> pt_hom_ext(). +-spec decompress(pt_compressed()) -> pt_hom_ext(). decompress(<>) -> X0 = Y0 bsr 255, Y = Y0 band ?TWO_POW_255_MINUS_1, diff --git a/src/ecu_eddsa.erl b/src/ecu_eddsa.erl index 4d383a5..ee85ecb 100644 --- a/src/ecu_eddsa.erl +++ b/src/ecu_eddsa.erl @@ -16,23 +16,22 @@ %% %% The keypair is returned as a map with keys 'public' and 'secret'. %% @end --spec sign_keypair() -> #{ atom() => binary() }. +-spec sign_keypair() -> #{ public => binary(), secret => binary() }. sign_keypair() -> Secret = crypto:strong_rand_bytes(32), - <> = crypto:hash(sha512, Secret), + <> = crypto:hash(sha512, Secret), - Pub = ecu_ed25519:scalar_mul_base(Seed), + Pub = ecu_ed25519:compress(ecu_ed25519:scalar_mul_base(Seed)), #{public => Pub, secret => <>}. %% @doc sign_seed_keypair/1 computes the signing keypair from a seed. %% %% The keypair is returned as a map with keys 'public' and 'secret'. %% @end --spec sign_seed_keypair(Seed :: <<_:32>>) -> #{ atom() => binary() }. +-spec sign_seed_keypair(Secret :: <<_:256>>) -> #{ public => binary(), secret => binary() }. sign_seed_keypair(Secret) -> - <> = crypto:hash(sha512, Secret), + <> = crypto:hash(sha512, Secret), Pub = ecu_ed25519:compress(ecu_ed25519:scalar_mul_base(Seed)), -%% Pub = enacl:crypto_ed25519_scalarmult_base(Seed), #{public => Pub, secret => <>}. @@ -41,7 +40,7 @@ sign_seed_keypair(Secret) -> %% Given a message `Msg' and a secret key `SK' the function will sign the %% message and return a signed message `SM'. %% @end --spec sign(Msg :: iodata(), SK :: <<_:32>> | <<_:64>>) -> SM :: binary(). +-spec sign(Msg :: iodata(), SK :: <<_:256>> | <<_:512>>) -> SM :: binary(). sign(Msg, SK) -> BinMsg = iolist_to_binary(Msg), Sig = sign_detached(Msg, SK), @@ -54,12 +53,12 @@ sign(Msg, SK) -> %% `{error, failed_verification}' depending on the correctness of the %% signature. %% @end --spec sign_open(SMsg :: binary(), PK :: <<_:32>>) -> +-spec sign_open(SMsg :: binary(), PK :: <<_:256>>) -> {ok, Msg :: binary()} | {error, failed_verification}. sign_open(<>, PK) -> - <> = Sig, + <> = Sig, - Ks0 = crypto:hash(sha512, <>), + Ks0 = crypto:hash(sha512, <>), Ks = ecu_ed25519:scalar_reduce(Ks0), LHS = ecu_ed25519:scalar_mul_base_noclamp(Ss), @@ -77,7 +76,7 @@ sign_open(<>, PK) -> %% Given a message `Msg' and a secret key `SK' the function will compute the %% digital signature `Sig'. %% @end --spec sign_detached(Msg :: iodata(), SK :: <<_:32>>) -> Sig :: binary(). +-spec sign_detached(Msg :: iodata(), SK :: <<_:256>> | <<_:512>>) -> Sig :: binary(). sign_detached(Msg, SK) -> BinMsg = iolist_to_binary(Msg), <> = SK, @@ -119,12 +118,12 @@ sign_detached(Msg, SK) -> %% function computes true iff the `Sig' is valid for `Msg' and `PK'; and, %% false otherwise. %% @end --spec sign_verify_detached(Sig :: <<_:64>>, Msg :: iodata(), PK :: <<_:32>>) -> boolean(). +-spec sign_verify_detached(Sig :: <<_:512>>, Msg :: iodata(), PK :: <<_:256>>) -> boolean(). sign_verify_detached(Sig, Msg, PK) -> BinMsg = iolist_to_binary(Msg), - <> = Sig, + <> = Sig, - Ks0 = crypto:hash(sha512, <>), + Ks0 = crypto:hash(sha512, <>), Ks = ecu_ed25519:scalar_reduce(Ks0), LHS = ecu_ed25519:scalar_mul_base_noclamp(Ss), @@ -136,5 +135,5 @@ sign_verify_detached(Sig, Msg, PK) -> %% Clamp a 32-byte little-endian integer - i.e clear the lowest three bits %% of the first byte and clear the highest and set the second highest of %% the last byte (i.e. making it divisible by 8 and -clamp(<>) -> - <<(B0 band 16#f8):8, B1_30/bytes, ((B31 band 16#7f) bor 16#40):8>>. +clamp(<>) -> + <<(B0 band 16#f8):8, B1_30/binary, ((B31 band 16#7f) bor 16#40):8>>.