Add keypair encoding, fix seckey size checks
Gajumaru Serialization Tests / tests (push) Successful in -2m51s
Gajumaru Serialization Tests / tests (push) Successful in -2m51s
This commit is contained in:
@@ -13,8 +13,15 @@
|
||||
safe_decode/2,
|
||||
byte_size_for_type/1]).
|
||||
|
||||
-export([encode_keypair/1,
|
||||
safe_decode_keypair/1]).
|
||||
|
||||
-ifdef(TEST).
|
||||
-export([encode_/2]). %% Encode without size checks
|
||||
-endif.
|
||||
|
||||
-export_type([encoded/0,
|
||||
known_type/0]).
|
||||
known_type/0]).
|
||||
|
||||
-type known_type() :: key_block_hash
|
||||
| micro_block_hash
|
||||
@@ -53,14 +60,66 @@
|
||||
-type payload() :: binary().
|
||||
-type encoded() :: binary().
|
||||
|
||||
-type keypair() :: #{public := <<_:(32*8)>>, secret := <<_:(64*8)>>}.
|
||||
-type encoded_keypair() :: #{binary() => binary()}.
|
||||
|
||||
-export_type([ keypair/0
|
||||
, encoded_keypair/0 ]).
|
||||
|
||||
-define(BASE58, 1).
|
||||
-define(BASE64, 2).
|
||||
|
||||
-spec encode_keypair(keypair()) -> encoded_keypair().
|
||||
encode_keypair(#{public := Pub, secret := Sec}) ->
|
||||
case Sec of
|
||||
<<Seed:32/binary, Pub1:32/binary>> when Pub1 =:= Pub ->
|
||||
#{ <<"pub">> => encode(account_pubkey, Pub)
|
||||
, <<"priv">> => encode(account_seckey, Seed) };
|
||||
_ ->
|
||||
erlang:error(invalid_keypair)
|
||||
end.
|
||||
|
||||
-spec safe_decode_keypair(encoded_keypair()) -> {'ok', keypair()} | {'error', atom()}.
|
||||
safe_decode_keypair(#{<<"pub">> := EncPub, <<"priv">> := EncPriv}) ->
|
||||
case safe_decode(account_pubkey, EncPub) of
|
||||
{ok, Pub} ->
|
||||
case safe_decode(account_seckey, EncPriv) of
|
||||
{ok, Seed} when byte_size(Seed) =:= 32 ->
|
||||
case enacl:sign_seed_keypair(Seed) of
|
||||
#{public := Pub, secret := _} = KP ->
|
||||
{ok, KP};
|
||||
_ ->
|
||||
{error, illegal_encoding}
|
||||
end;
|
||||
{ok, <<Seed:32/binary, Pub:32/binary>>} ->
|
||||
case enacl:sign_seed_keypair(Seed) of
|
||||
#{public := Pub} = KP ->
|
||||
{ok, KP};
|
||||
_ ->
|
||||
{error, illegal_encoding}
|
||||
end;
|
||||
{ok, _} ->
|
||||
{error, illegal_encoding};
|
||||
{error, _} = Error1 ->
|
||||
Error1
|
||||
end;
|
||||
Error ->
|
||||
Error
|
||||
end.
|
||||
|
||||
-spec encode(known_type(), payload() | gmser_id:id()) -> encoded().
|
||||
encode(id_hash, Payload) ->
|
||||
{IdType, Val} = gmser_id:specialize(Payload),
|
||||
encode(id2type(IdType), Val);
|
||||
encode(Type, Payload) ->
|
||||
case type_size_check(Type, Payload) of
|
||||
ok ->
|
||||
encode_(Type, Payload);
|
||||
{error, Reason} ->
|
||||
erlang:error(Reason)
|
||||
end.
|
||||
|
||||
encode_(Type, Payload) ->
|
||||
Pfx = type2pfx(Type),
|
||||
Enc = case type2enc(Type) of
|
||||
?BASE58 -> base58_check(Payload);
|
||||
@@ -68,6 +127,7 @@ encode(Type, Payload) ->
|
||||
end,
|
||||
<<Pfx/binary, "_", Enc/binary>>.
|
||||
|
||||
|
||||
-spec decode(binary()) -> {known_type(), payload()}.
|
||||
decode(Bin0) ->
|
||||
case split(Bin0) of
|
||||
@@ -83,6 +143,13 @@ decode(Bin0) ->
|
||||
erlang:error(missing_prefix)
|
||||
end.
|
||||
|
||||
type_size_check(account_seckey, Bin) ->
|
||||
case byte_size(Bin) of
|
||||
Sz when Sz =:= 32; Sz =:= 64 ->
|
||||
ok;
|
||||
_ ->
|
||||
{error, incorrect_size}
|
||||
end;
|
||||
type_size_check(Type, Bin) ->
|
||||
case byte_size_for_type(Type) of
|
||||
not_applicable -> ok;
|
||||
|
||||
Reference in New Issue
Block a user