serializable_compat.ml 4.35 KB
Newer Older
Stephane Glondu's avatar
Stephane Glondu committed
1
open Util
Stephane Glondu's avatar
Stephane Glondu committed
2
3
open Serializable_compat_t

4
let question q =
Stephane Glondu's avatar
Stephane Glondu committed
5
6
7
8
9
10
11
12
  let {q_answers; q_min; q_max; q_question; _} = q in
  let q_max = match q_max with
    | Some i -> i
    | None -> Array.length q_answers
  in
  let open Serializable_t in
  {q_answers; q_min; q_max; q_question}

13
let election e =
Stephane Glondu's avatar
Stephane Glondu committed
14
15
16
17
18
19
  let {
    e_description; e_name; e_public_key;
    e_questions; e_uuid; e_short_name;
    _
  } = e in
  let e_public_key = e_public_key.y in
20
  let e_questions = Array.map question e_questions in
Stephane Glondu's avatar
Stephane Glondu committed
21
22
23
24
25
26
  let open Serializable_t in
  {
    e_description; e_name; e_public_key;
    e_questions; e_uuid; e_short_name
  }

27
let proof p =
Stephane Glondu's avatar
Stephane Glondu committed
28
29
30
31
  let {dp_challenge; dp_response; _} = p in
  let open Serializable_t in
  {challenge = dp_challenge; response = dp_response}

32
let proofs ps = Array.map proof ps
Stephane Glondu's avatar
Stephane Glondu committed
33

34
let answer a =
Stephane Glondu's avatar
Stephane Glondu committed
35
  let {choices; individual_proofs; overall_proof} = a in
36
37
  let individual_proofs = Array.map proofs individual_proofs in
  let overall_proof = proofs overall_proof in
Stephane Glondu's avatar
Stephane Glondu committed
38
39
40
  let open Serializable_t in
  {choices; individual_proofs; overall_proof}

41
let ballot b =
Stephane Glondu's avatar
Stephane Glondu committed
42
  let {answers; election_hash; election_uuid} = b in
43
  let answers = Array.map answer answers in
Stephane Glondu's avatar
Stephane Glondu committed
44
45
  let open Serializable_t in
  {answers; election_hash; election_uuid}
Stephane Glondu's avatar
Debug    
Stephane Glondu committed
46

47
let partial_decryption p =
48
  let {decryption_factors; decryption_proofs} = p in
49
  let decryption_proofs = Array.mmap proof decryption_proofs in
50
51
52
  let open Serializable_t in
  {decryption_factors; decryption_proofs}

53
let result r =
Stephane Glondu's avatar
Stephane Glondu committed
54
55
56
57
  let {encrypted_tally; partial_decryptions; result} = r in
  let nb_tallied = encrypted_tally.num_tallied in
  let encrypted_tally = encrypted_tally.tally in
  let partial_decryptions =
58
    Array.map partial_decryption partial_decryptions
Stephane Glondu's avatar
Stephane Glondu committed
59
60
61
62
  in
  let open Serializable_t in
  {nb_tallied; encrypted_tally; partial_decryptions; result}

63
module MakeCompat (P : Signatures.ELECTION_PARAMS) = struct
Stephane Glondu's avatar
Debug    
Stephane Glondu committed
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
  open Serializable_t
  open P
  open G

  (* The following duplicates parts of module Crypto, in order to
     reconstruct commitments. *)

  let dummy_ciphertext =
    {
      alpha = G.one;
      beta = G.one;
    }

  let eg_combine c1 c2 =
    {
      alpha = c1.alpha *~ c2.alpha;
      beta = c1.beta *~ c2.beta;
    }

  let dummy_proof =
    let open Serializable_compat_t in
    {
      dp_commitment = {a = G.one; b = G.one};
      dp_challenge = Z.zero;
      dp_response = Z.zero;
    }

  let y = params.e_public_key
  let ( / ) x y = x *~ invert y

  let invg = invert G.g
  let d01 = [| G.one; invg |]

  let make_d min max =
    let n = max - min + 1 in
    let d = Array.create n (invert (g **~ Z.of_int min)) in
    for i = 1 to n-1 do
      d.(i) <- d.(i-1) *~ invg
    done;
    d

  let recommit d proofs {alpha; beta} =
    let n = Array.length d in
    assert (n = Array.length proofs);
    let result = Array.create n dummy_proof in
    for i = 0 to n-1 do
      let {challenge; response} = proofs.(i) in
      let dp_commitment = {
        a = g **~ response / alpha **~ challenge;
        b = y **~ response / (beta *~ d.(i)) **~ challenge;
      } in
      let open Serializable_compat_t in
      result.(i) <- {
        dp_commitment;
        dp_challenge = challenge;
        dp_response = response;
      };
    done;
    result

124
  let answer a q =
Stephane Glondu's avatar
Debug    
Stephane Glondu committed
125
    let {choices; individual_proofs; overall_proof} = a in
126
127
128
    let individual_proofs =
      Array.map2 (recommit d01) individual_proofs choices
    in
Stephane Glondu's avatar
Debug    
Stephane Glondu committed
129
    let sumc = Array.fold_left eg_combine dummy_ciphertext choices in
130
131
132
    let overall_proof =
      recommit (make_d q.q_min q.q_max) overall_proof sumc
    in
Stephane Glondu's avatar
Debug    
Stephane Glondu committed
133
134
135
    let open Serializable_compat_t in
    {choices; individual_proofs; overall_proof}

136
  let ballot b =
Stephane Glondu's avatar
Debug    
Stephane Glondu committed
137
    let {answers; election_hash; election_uuid} = b in
138
    let answers = Array.map2 answer answers params.e_questions in
Stephane Glondu's avatar
Debug    
Stephane Glondu committed
139
140
    let open Serializable_compat_t in
    {answers; election_hash; election_uuid}
141

142
  let partial_decryption c p =
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
    let {decryption_factors; decryption_proofs} = p in
    let decryption_proofs =
      Array.mmap3 (fun {alpha; _} f {challenge; response} ->
        let open Serializable_compat_t in
        let dp_commitment = {
          a = g **~ response / (y **~ challenge);
          b = alpha **~ response / (f **~ challenge);
        } in {
          dp_commitment;
          dp_challenge = challenge;
          dp_response = response;
        }
      ) c decryption_factors decryption_proofs
    in
    let open Serializable_compat_t in
    {decryption_factors; decryption_proofs}
Stephane Glondu's avatar
Debug    
Stephane Glondu committed
159
end