Commit 4b4cec75 authored by Stephane Glondu's avatar Stephane Glondu

Put shuffles in result.json

parent 671bfbce
Pipeline #74246 passed with stages
in 16 minutes and 26 seconds
......@@ -89,6 +89,7 @@ mv partial_decryptions.tmp partial_decryptions.jsons
header "Finalize tally"
belenios-tool validate
rm -f shuffles.jsons
header "Perform final verification"
......
......@@ -257,7 +257,7 @@ module Make (W : ELECTION_DATA) (M : RANDOM) = struct
type combinator = factor list -> elt shape
let compute_result num_tallied encrypted_tally partial_decryptions combinator =
let compute_result ?shuffles num_tallied encrypted_tally partial_decryptions combinator =
let factors = combinator partial_decryptions in
let results = Shape.map2 (fun {beta; _} f ->
beta / f
......@@ -269,7 +269,7 @@ module Make (W : ELECTION_DATA) (M : RANDOM) = struct
| SArray xs ->
SArray (Array.map2 (Q.compute_result ~num_tallied) election.e_params.e_questions xs)
in
{num_tallied; encrypted_tally; partial_decryptions; result}
{num_tallied; encrypted_tally; shuffles; partial_decryptions; result}
let check_result combinator r =
let {encrypted_tally; partial_decryptions; result; _} = r in
......
......@@ -114,11 +114,17 @@ type 'a shuffle_proof =
type 'a shuffle_proofs = 'a shuffle_proof list <ocaml repr="array">
type 'a shuffle = {
ciphertexts : 'a nh_ciphertexts;
proofs : 'a shuffle_proofs;
} <ocaml field_prefix="shuffle_">
(** {2 Election result} *)
type 'a election_result = {
num_tallied : int;
encrypted_tally : 'a encrypted_tally;
?shuffles : 'a shuffle list option;
partial_decryptions : 'a partial_decryption list;
result : int shape;
}
......
......@@ -130,7 +130,7 @@ module type ELECTION = sig
type combinator = factor list -> elt shape
val compute_result : int -> elt Serializable_t.ciphertext shape -> factor list -> combinator -> result
val compute_result : ?shuffles:elt shuffle list -> int -> elt Serializable_t.ciphertext shape -> factor list -> combinator -> result
(** Combine the encrypted tally and the factors from all trustees to
produce the election result. The first argument is the number of
tallied ballots. May raise [Invalid_argument]. *)
......
......@@ -318,9 +318,11 @@ module Election : CMDLINER_MODULE = struct
let get_shuffles () =
let file = "shuffles.jsons" in
Printf.eprintf "I: loading %s...\n%!" file;
try Some (lines_of_file (X.dir / file))
with _ -> None
if Sys.file_exists (X.dir / file) then (
Printf.eprintf "I: loading %s...\n%!" file;
try Some (lines_of_file (X.dir / file))
with _ -> None
) else None
let get_result () =
load_from_file (fun x -> x) (X.dir/"result.json") |> function
......@@ -399,8 +401,9 @@ module Election : CMDLINER_MODULE = struct
| Some factors -> factors
| None -> failwith "cannot load partial decryptions"
in
let result = X.validate factors in
let oc = open_out (dir/"result.json") in
output_string oc (X.validate factors);
output_string oc result;
output_char oc '\n';
close_out oc
| `Shuffle ->
......
......@@ -154,22 +154,42 @@ module Make (P : PARSED_PARAMS) : S = struct
Array.length ballots
)
let result =
lazy (
get_result ()
|> Option.map (election_result_of_string G.read)
)
let shuffles =
lazy (
get_shuffles ()
|> Option.map (fun s ->
let shuffles = ref [] and shuffle_proofs = ref [] in
let rec loop () =
if (try Stream.empty s; true with Stream.Failure -> false) then
!shuffles, !shuffle_proofs
else (
shuffle_proofs := (shuffle_proofs_of_string G.read (Stream.next s)) :: !shuffle_proofs;
shuffles := (nh_ciphertexts_of_string G.read (Stream.next s)) :: !shuffles;
loop ()
)
in
match Lazy.force result, get_shuffles () with
| Some _, Some _ -> failwith "both shuffles.jsons and result.json exist"
| None, None -> None
| Some result, None ->
result.shuffles
|> Option.map (fun s ->
let ciphertexts = ref [] and proofs = ref [] in
let rec loop = function
| [] -> !ciphertexts, !proofs
| {shuffle_ciphertexts; shuffle_proofs} :: xs ->
ciphertexts := shuffle_ciphertexts :: !ciphertexts;
proofs := shuffle_proofs :: !proofs;
loop xs
in
loop s
)
| None, Some s ->
let shuffles = ref [] and shuffle_proofs = ref [] in
let rec loop () =
if (try Stream.empty s; true with Stream.Failure -> false) then
Some (!shuffles, !shuffle_proofs)
else (
shuffle_proofs := (shuffle_proofs_of_string G.read (Stream.next s)) :: !shuffle_proofs;
shuffles := (nh_ciphertexts_of_string G.read (Stream.next s)) :: !shuffles;
loop ()
)
in
loop ()
)
let shuffles_check =
......@@ -250,7 +270,17 @@ module Make (P : PARSED_PARAMS) : S = struct
KG.combine_factors checker (Lazy.force pks)
| Some t -> KP.combine_factors checker t
in
let result = E.compute_result nballots tally factors combinator in
let shuffles = match Lazy.force shuffles with
| None -> None
| Some (ciphertexts, proofs) ->
let shuffles =
List.rev_map (fun (shuffle_ciphertexts, shuffle_proofs) ->
{shuffle_ciphertexts; shuffle_proofs}
) (List.combine ciphertexts proofs)
in
Some shuffles
in
let result = E.compute_result ?shuffles nballots tally factors combinator in
assert (E.check_result combinator result);
string_of_election_result G.write result
......@@ -265,9 +295,8 @@ module Make (P : PARSED_PARAMS) : S = struct
| Some () -> assert (Lazy.force shuffles_check)
| None -> print_msg "W: no ballots to check"
);
(match get_result () with
(match Lazy.force result with
| Some result ->
let result = election_result_of_string G.read result in
assert (fst (Lazy.force encrypted_tally) = result.encrypted_tally);
let checker = E.check_factor result.encrypted_tally in
let combinator = match threshold with
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment