Skip to content

Commit

Permalink
Add serialization (#8)
Browse files Browse the repository at this point in the history
* add serialize and deserialize functions, untested WIP

* minor change from maps:map to maps:fold for serializing

* fix deserialization to use single element for dkg and vss
  • Loading branch information
vihu committed Aug 8, 2018
1 parent e4ce5b1 commit b8ea59c
Show file tree
Hide file tree
Showing 4 changed files with 320 additions and 82 deletions.
55 changes: 45 additions & 10 deletions src/dkg_commitment.erl
Original file line number Diff line number Diff line change
@@ -1,13 +1,5 @@
-module(dkg_commitment).

-record(commitment, {
matrix :: dkg_commitmentmatrix:matrix(),
generator :: erlang_pbc:element(),
nodes = [] :: [pos_integer()],
echoes= #{} :: map(),
readies=#{} :: map()
}).

-export([new/3,
cmp/2,
mul/2,
Expand All @@ -20,12 +12,31 @@
num_echoes/1,
num_readies/1,
matrix/1,
set_matrix/2
set_matrix/2,
serialize/1,
deserialize/2
]).

-record(commitment, {
matrix :: dkg_commitmentmatrix:matrix(),
generator :: erlang_pbc:element(),
nodes = [] :: [pos_integer()],
echoes = #{} :: map(),
readies =#{} :: map()
}).

-record(serialized_commitment, {
matrix :: dkg_commitmentmatrix:serialized_matrix(),
generator :: binary(),
nodes = [] :: [pos_integer()],
echoes = #{} :: map(),
readies = #{} :: map()
}).

-type commitment() :: #commitment{}.
-type serialized_commitment() :: #serialized_commitment{}.

-export_type([commitment/0]).
-export_type([commitment/0, serialized_commitment/0]).

-spec new([pos_integer(),...], erlang_pbc:element(), integer() | dkg_bipolynomial:bipolynomial()) -> commitment().
new(NodeIDs, Generator, Degree) when is_integer(Degree) ->
Expand Down Expand Up @@ -111,3 +122,27 @@ matrix(#commitment{matrix=Matrix}) ->
-spec set_matrix(commitment(), dkg_commitmentmatrix:matrix()) -> commitment().
set_matrix(C = #commitment{}, Matrix) ->
C#commitment{matrix=Matrix}.

-spec serialize(commitment()) -> serialized_commitment().
serialize(#commitment{matrix=Matrix,
generator=Generator,
nodes=Nodes,
echoes=Echoes,
readies=Readies}) ->
#serialized_commitment{matrix=dkg_commitmentmatrix:serialize(Matrix),
generator=erlang_pbc:element_to_binary(Generator),
nodes=Nodes,
echoes=Echoes,
readies=Readies}.

-spec deserialize(serialized_commitment(), erlang_pbc:element()) -> commitment().
deserialize(#serialized_commitment{matrix=SerializedMatrix,
generator=SerializedGenerator,
nodes=Nodes,
echoes=Echoes,
readies=Readies}, U) ->
#commitment{matrix=dkg_commitmentmatrix:deserialize(SerializedMatrix, U),
generator=erlang_pbc:binary_to_element(U, SerializedGenerator),
nodes=Nodes,
echoes=Echoes,
readies=Readies}.
2 changes: 1 addition & 1 deletion src/dkg_commitmentmatrix.erl
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ serialize(Matrix) ->
insert([I, J], Acc, erlang_pbc:element_to_binary(lookup([I,J], Acc)))
end, Matrix, iter(Matrix)).

-spec deserialize(matrix(), erlang_pbc:element()) -> matrix().
-spec deserialize(serialized_matrix(), erlang_pbc:element()) -> matrix().
deserialize(Matrix, U) ->
lists:foldl(fun({I, J}, Acc) ->
insert([I, J], Acc, erlang_pbc:binary_to_element(U, lookup([I,J], Acc)))
Expand Down
166 changes: 149 additions & 17 deletions src/dkg_hybriddkg.erl
Original file line number Diff line number Diff line change
@@ -1,32 +1,43 @@
-module(dkg_hybriddkg).

-export([init/7, start/1]).
-export([init/7,
start/1,
serialize/1,
deserialize/2
]).

-export([handle_msg/3]).

-type rhat() :: [vss_ready()].
-type qset() :: [pos_integer()].
-type mbar() :: [signed_ready() | signed_echo()].
-type signed_leader_change() :: {signed_leader_change, pos_integer(), qset(), rhat() | mbar()}.
-type signed_echo() :: {signed_echo, qset()}.
-type signed_ready() :: {signed_ready, qset()}.
-type vss_ready() :: {signed_vss_ready, dkg_hybridvss:readies()}.
-type identity() :: {Leader :: pos_integer(), Q :: [pos_integer()]}.
-type echo() :: {Sender :: pos_integer(), SignedEcho :: signed_echo()}.
-type ready() :: {Sender :: pos_integer(), SignedReady :: signed_ready()}.
-type elq() :: #{identity() => [echo()]}.
-type rlq() :: #{identity() => [ready()]}.
-type lc_map() :: #{Leader :: pos_integer() => [{Sender :: pos_integer(), signed_leader_change()}]}.

-record(dkg, {
id :: pos_integer(),
n :: pos_integer(),
f :: pos_integer(),
t :: pos_integer(),
u :: erlang_pbc:element(),
u2 :: erlang_pbc:element(),
vss_map :: #{pos_integer() => dkg_hybridvss:vss()},
vss_results = #{} :: #{pos_integer() => {C :: dkg_commitment:commitment(), Si :: erlang_pbc:element()}},
vss_map = #{} :: vss_map(),
vss_results = #{} :: vss_results(),
qbar = [] :: qset(),
qhat = [] :: qset(),
rhat = [] :: rhat(),
mbar = [] :: mbar(),
elq = #{} :: elq(),
rlq = #{} :: rlq(),
lc_flag = false :: boolean(),
leader :: pos_integer(),
l_next :: pos_integer(),
lc_map = #{} :: lc_map()
}).

-record(serialized_dkg, {
id :: pos_integer(),
n :: pos_integer(),
f :: pos_integer(),
t :: pos_integer(),
u :: binary(),
u2 :: binary(),
vss_map :: #{pos_integer() => dkg_hybridvss:serialized_vss()},
vss_results = #{} :: #{pos_integer() => {C :: dkg_commitment:serialized_commitment(), Si :: binary()}},
qbar = [] :: qset(),
qhat = [] :: qset(),
rhat = [] :: rhat(),
Expand All @@ -39,7 +50,26 @@
lc_map = #{} :: lc_map()
}).

-type rhat() :: [vss_ready()].
-type qset() :: [pos_integer()].
-type mbar() :: [signed_ready() | signed_echo()].
-type signed_leader_change() :: {signed_leader_change, pos_integer(), qset(), rhat() | mbar()}.
-type signed_echo() :: {signed_echo, qset()}.
-type signed_ready() :: {signed_ready, qset()}.
-type vss_ready() :: {signed_vss_ready, dkg_hybridvss:readies()}.
-type identity() :: {Leader :: pos_integer(), Q :: [pos_integer()]}.
-type echo() :: {Sender :: pos_integer(), SignedEcho :: signed_echo()}.
-type ready() :: {Sender :: pos_integer(), SignedReady :: signed_ready()}.
-type elq() :: #{identity() => [echo()]}.
-type rlq() :: #{identity() => [ready()]}.
-type lc_map() :: #{Leader :: pos_integer() => [{Sender :: pos_integer(), signed_leader_change()}]}.
-type vss_map() :: #{pos_integer() => dkg_hybridvss:vss()}.
-type serialized_vss_map() :: #{pos_integer() => dkg_hybridvss:serialized_vss()}.
-type vss_results() :: #{pos_integer() => {C :: dkg_commitment:commitment(), Si :: erlang_pbc:element()}}.
-type serialized_vss_results() :: #{pos_integer() => {C :: dkg_commitment:serialized_commitment(), Si :: binary()}}.
-type dkg() :: #dkg{}.
-type serialized_dkg() :: #serialized_dkg{}.

-export_type([dkg/0]).

%% upon initialization:
Expand Down Expand Up @@ -383,3 +413,105 @@ store_leader_change(DKG, Sender, {signed_leader_change, Lbar, _, _}=LeaderChange
_ ->
false
end.

-spec serialize(dkg()) -> serialized_dkg().
serialize(#dkg{id=Id,
n=N,
f=F,
t=T,
u=U,
u2=U2,
vss_map=VSSMap,
vss_results=VSSResults,
qbar=Qbar,
qhat=Qhat,
rhat=Rhat,
mbar=Mbar,
elq=Elq,
rlq=Rlq,
lc_flag=LCFlag,
leader=Leader,
l_next=LNext,
lc_map=LCMap}) ->
#serialized_dkg{id=Id,
n=N,
f=F,
t=T,
u=erlang_pbc:element_to_binary(U),
u2=erlang_pbc:element_to_binary(U2),
vss_map=serialize_vss_map(VSSMap),
vss_results=serialize_vss_results(VSSResults),
qbar=Qbar,
qhat=Qhat,
rhat=Rhat,
mbar=Mbar,
elq=Elq,
rlq=Rlq,
lc_flag=LCFlag,
leader=Leader,
l_next=LNext,
lc_map=LCMap}.

-spec deserialize(serialized_dkg(), erlang_pbc:element()) -> dkg().
deserialize(#serialized_dkg{id=Id,
n=N,
f=F,
t=T,
u=SerializedU,
u2=SerializedU2,
vss_map=SerializedVSSMap,
vss_results=SerializedVSSResults,
qbar=Qbar,
qhat=Qhat,
rhat=Rhat,
mbar=Mbar,
elq=Elq,
rlq=Rlq,
lc_flag=LCFlag,
leader=Leader,
l_next=LNext,
%% XXX: Only one element is enough?
%% presumably we need to generate U and U2 again to deserialize? Not sure...
lc_map=LCMap}, Element) ->
#dkg{id=Id,
n=N,
f=F,
t=T,
u=erlang_pbc:binary_to_element(Element, SerializedU),
u2=erlang_pbc:binary_to_element(Element, SerializedU2),
vss_map=deserialize_vss_map(SerializedVSSMap, Element),
vss_results=deserialize_vss_results(SerializedVSSResults, Element),
qbar=Qbar,
qhat=Qhat,
rhat=Rhat,
mbar=Mbar,
elq=Elq,
rlq=Rlq,
lc_flag=LCFlag,
leader=Leader,
l_next=LNext,
lc_map=LCMap}.

-spec serialize_vss_map(vss_map()) -> serialized_vss_map().
serialize_vss_map(VSSMap) ->
maps:fold(fun(K, VSS, Acc) ->
maps:put(K, dkg_hybridvss:serialize(VSS), Acc)
end, #{}, VSSMap).

-spec deserialize_vss_map(serialized_vss_map(), erlang_pbc:element()) -> vss_map().
deserialize_vss_map(SerializedVSSMap, Element) ->
maps:fold(fun(K, VSS, Acc) ->
maps:put(K, dkg_hybridvss:deserialize(VSS, Element), Acc)
end, #{}, SerializedVSSMap).

-spec serialize_vss_results(vss_results()) -> serialized_vss_results().
serialize_vss_results(VSSResults) ->
maps:fold(fun(K, {C, Si}, Acc) ->
maps:put(K, {dkg_commitment:serialize(C), erlang_pbc:element_to_binary(Si)}, Acc)
end, #{}, VSSResults).

-spec deserialize_vss_results(serialized_vss_results(), erlang_pbc:element()) -> vss_results().
deserialize_vss_results(SerializedVSSResults, U) ->
maps:fold(fun(K, {C, Si}, Acc) ->
maps:put(K, {dkg_commitment:deserialize(C, U), erlang_pbc:binary_to_element(U, Si)}, Acc)
end, #{}, SerializedVSSResults).
Loading

0 comments on commit b8ea59c

Please sign in to comment.