Commit bfc51251 authored by Stephane Glondu's avatar Stephane Glondu

Implement check_result

parent 8a29dbc8
......@@ -211,13 +211,22 @@ module MakeHomomorphicElection (P : Crypto_sigs.ELECTION_PARAMS) = struct
alpha **~ x,
fs_prove [| g; alpha |] x hash
let check_ciphertext c =
Array.fforall (fun {alpha; beta} -> G.check alpha && G.check beta) c
let compute_factor c x =
let res = Array.mmap (eg_factor x) c in
let decryption_factors, decryption_proofs = Array.ssplit res in
{decryption_factors; decryption_proofs}
if check_ciphertext c then (
let res = Array.mmap (eg_factor x) c in
let decryption_factors, decryption_proofs = Array.ssplit res in
{decryption_factors; decryption_proofs}
) else (
invalid_arg "Invalid ciphertext"
)
let check_factor c y f =
Array.fforall3 (fun {alpha; _} f {challenge; response} ->
check_modulo q challenge &&
check_modulo q response &&
let commitments =
[|
g **~ response / (y **~ challenge);
......@@ -233,13 +242,13 @@ module MakeHomomorphicElection (P : Crypto_sigs.ELECTION_PARAMS) = struct
let factors = Array.fold_left (fun a b ->
Array.mmap2 ( *~ ) a b.decryption_factors
) dummy partial_decryptions in
let exp_results = Array.mmap2 (fun {beta; _} f ->
let results = Array.mmap2 (fun {beta; _} f ->
beta / f
) encrypted_tally factors in
let log =
let module GMap = Map.Make(G) in
let rec loop i cur accu =
if i < nb_tallied
if i <= nb_tallied
then loop (succ i) (cur *~ g) (GMap.add cur i accu)
else accu
in
......@@ -250,10 +259,21 @@ module MakeHomomorphicElection (P : Crypto_sigs.ELECTION_PARAMS) = struct
with Not_found ->
invalid_arg "Cannot compute result"
in
let result = Array.mmap log exp_results in
let result = Array.mmap log results in
{nb_tallied; encrypted_tally; partial_decryptions; result}
let check_result r = assert false
let check_result ys r =
let {encrypted_tally; partial_decryptions; result; nb_tallied} = r in
check_ciphertext encrypted_tally &&
Array.forall2 (check_factor encrypted_tally) ys partial_decryptions &&
let dummy = Array.mmap (fun _ -> G.one) encrypted_tally in
let factors = Array.fold_left (fun a b ->
Array.mmap2 ( *~ ) a b.decryption_factors
) dummy partial_decryptions in
let results = Array.mmap2 (fun {beta; _} f ->
beta / f
) encrypted_tally factors in
Array.fforall2 (fun r1 r2 -> r1 =~ g **~ Z.of_int r2) results r.result
let extract_tally r = r.result
end
......@@ -132,7 +132,7 @@ module type HOMOMORPHIC = sig
produce the election result. The first argument is the number of
tallied ballots. May raise [Invalid_argument]. *)
val check_result : result -> bool
val check_result : public_key array -> result -> bool
val extract_tally : result -> plaintext
(** Extract the plaintext result of the election. *)
......
......@@ -25,6 +25,36 @@ module Array = struct
else true
in loop (pred (Array.length x))
let fforall f xs =
let rec loop_outer i =
if i >= 0 then
let x = xs.(i) in
let n = Array.length x in
let rec loop_inner j =
if j >= 0 then f x.(j) && loop_inner (pred j)
else true
in loop_inner (pred n)
else true
in
let n = Array.length xs in
loop_outer (pred n)
let fforall2 f xs ys =
let rec loop_outer i =
if i >= 0 then
let x = xs.(i) and y = ys.(i) in
let n = Array.length x in
n = Array.length y &&
let rec loop_inner j =
if j >= 0 then f x.(j) y.(j) && loop_inner (pred j)
else true
in loop_inner (pred n)
else true
in
let n = Array.length xs in
n = Array.length ys &&
loop_outer (pred n)
let fforall3 f xs ys zs =
let rec loop_outer i =
if i >= 0 then
......
......@@ -11,6 +11,9 @@ module Array : sig
val forall : ('a -> bool) -> 'a array -> bool
val forall2 : ('a -> 'b -> bool) -> 'a array -> 'b array -> bool
val foralli : (int -> 'a -> bool) -> 'a array -> bool
val fforall : ('a -> bool) -> 'a array array -> bool
val fforall2 : ('a -> 'b -> bool) ->
'a array array -> 'b array array -> bool
val fforall3 : ('a -> 'b -> 'c -> bool) ->
'a array array -> 'b array array -> 'c array array -> bool
val map2 : ('a -> 'b -> 'c) -> 'a array -> 'b array -> 'c array
......
......@@ -272,3 +272,15 @@ assert (g **~ x =% y);;
let test_factor = Election.compute_factor tally x;;
assert (Election.check_factor tally y test_factor);;
assert (Serializable_t.(test_factor.decryption_factors) = result.partial_decryptions.(0).decryption_factors);;
let nresult = Serializable_compat.of_result result;;
let () =
let open Serializable_t in
let nresult' = Election.combine_factors
nresult.nb_tallied nresult.encrypted_tally nresult.partial_decryptions
in
assert (nresult'.result = nresult.result);
assert (Election.check_result ys nresult');
;;
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