@@ -144,7 +144,6 @@ namespace electionguard
144144 this ->triple1 = move (triple1);
145145 this ->triple2 = move (triple2);
146146 this ->quad = move (quad);
147- populated = true ;
148147 }
149148
150149 TwoTriplesAndAQuadruple::TwoTriplesAndAQuadruple (const TwoTriplesAndAQuadruple &other)
@@ -204,9 +203,10 @@ namespace electionguard
204203 // This loop goes through until the queues are full but can be stopped
205204 // between generations of two triples and a quad. By full it means
206205 // we check how many quads are in the queue, to start with we will
207- // try 500 and see how that works. If the vendor wanted to pass the
206+ // try 5000 and see how that works. If the vendor wanted to pass the
208207 // queue size in we could use that.
209208 // for now we just go through the loop once
209+ int iteration_count = 0 ;
210210 do {
211211 // TODO - Can we tolerate not returning until we have finished
212212 // generating two triples and a quadruple?
@@ -220,16 +220,31 @@ namespace electionguard
220220 unique_ptr<Triple> triple2 = make_unique<Triple>(elgamalPublicKey);
221221 unique_ptr<Quadruple> quad = make_unique<Quadruple>(elgamalPublicKey);
222222
223- getInstance ().triple_queue .push (move (triple1));
224-
225- getInstance ().triple_queue .push (move (triple2));
226-
227- getInstance ().quadruple_queue .push (move (quad));
228-
223+ unique_ptr<TwoTriplesAndAQuadruple> twoTriplesAndAQuadruple =
224+ make_unique<TwoTriplesAndAQuadruple>(move (triple1), move (triple2), move (quad));
225+
226+ getInstance ().twoTriplesAndAQuadruple_queue .push (move (twoTriplesAndAQuadruple));
227+
228+ // This is very rudimentary. We can add a more complex algorithm in
229+ // the future, that would look at the queues and increase production if one
230+ // is getting lower than expected.
231+ // Every third iteration we generate two extra triples, one for use with
232+ // the contest constant chaum pedersen proof and one for hashed elgamal encryption
233+ // we need less of these because this exponentiation is done only every contest
234+ // encryption whereas the two triples and a quadruple is used every selection
235+ // encryption. The generating two triples every third iteration is a guess
236+ // on how many precomputes we will need.
237+ if ((iteration_count % 3 ) == 0 ) {
238+ unique_ptr<Triple> contest_triple1 = make_unique<Triple>(elgamalPublicKey);
239+ getInstance ().triple_queue .push (move (contest_triple1));
240+ unique_ptr<Triple> contest_triple2 = make_unique<Triple>(elgamalPublicKey);
241+ getInstance ().triple_queue .push (move (contest_triple2));
242+ }
243+ iteration_count++;
229244 } else {
230245 return ;
231246 }
232- } while (getInstance ().quadruple_queue .size () < getInstance ().max );
247+ } while (getInstance ().twoTriplesAndAQuadruple_queue .size () < getInstance ().max );
233248 }
234249
235250 void PrecomputeBufferContext::stop_populate () { getInstance ().populate_OK = false ; }
@@ -238,29 +253,36 @@ namespace electionguard
238253
239254 uint32_t PrecomputeBufferContext::get_current_queue_size ()
240255 {
241- return getInstance ().quadruple_queue .size ();
256+ return getInstance ().twoTriplesAndAQuadruple_queue .size ();
242257 }
243258
244259 std::unique_ptr<TwoTriplesAndAQuadruple> PrecomputeBufferContext::getTwoTriplesAndAQuadruple ()
245260 {
246- unique_ptr<TwoTriplesAndAQuadruple> result = make_unique<TwoTriplesAndAQuadruple>() ;
261+ unique_ptr<TwoTriplesAndAQuadruple> result = nullptr ;
247262
248263 // take a lock while we get the triples and a quadruple
249264 std::lock_guard<std::mutex> lock (queue_lock);
250265
251266 // make sure there are enough in the queues
252- if ((getInstance ().triple_queue .size () >= 2 ) &&
253- (getInstance ().quadruple_queue .size () >= 1 )) {
267+ if (!getInstance ().twoTriplesAndAQuadruple_queue .empty ()) {
268+ result = std::move (getInstance ().twoTriplesAndAQuadruple_queue .front ());
269+ getInstance ().twoTriplesAndAQuadruple_queue .pop ();
270+ }
254271
255- unique_ptr<Triple> triple1 = std::move (getInstance ().triple_queue .front ());
256- getInstance ().triple_queue .pop ();
257- unique_ptr<Triple> triple2 = std::move (getInstance ().triple_queue .front ());
258- getInstance ().triple_queue .pop ();
272+ return result;
273+ }
259274
260- unique_ptr<Quadruple> quad = std::move (getInstance ().quadruple_queue .front ());
261- getInstance ().quadruple_queue .pop ();
275+ std::unique_ptr<Triple> PrecomputeBufferContext::getTriple ()
276+ {
277+ unique_ptr<Triple> result = nullptr ;
278+
279+ // take a lock while we get the triples and a quadruple
280+ std::lock_guard<std::mutex> lock (queue_lock);
262281
263- result = make_unique<TwoTriplesAndAQuadruple>(move (triple1), move (triple2), move (quad));
282+ // make sure there are enough in the queues
283+ if (!getInstance ().triple_queue .empty ()) {
284+ result = std::move (getInstance ().triple_queue .front ());
285+ getInstance ().triple_queue .pop ();
264286 }
265287
266288 return result;
@@ -269,11 +291,13 @@ namespace electionguard
269291 void PrecomputeBufferContext::empty_queues ()
270292 {
271293 std::lock_guard<std::mutex> lock (queue_lock);
272- uint32_t size = getInstance ().quadruple_queue .size ();
273- for (int i = 0 ; i < (int )size ; i++) {
294+ uint32_t triple_size = getInstance ().triple_queue .size ();
295+ for (int i = 0 ; i < (int )triple_size ; i++) {
274296 getInstance ().triple_queue .pop ();
275- getInstance ().triple_queue .pop ();
276- getInstance ().quadruple_queue .pop ();
297+ }
298+ uint32_t twoTriplesAndAQuadruple_size = getInstance ().twoTriplesAndAQuadruple_queue .size ();
299+ for (int i = 0 ; i < (int )twoTriplesAndAQuadruple_size; i++) {
300+ getInstance ().twoTriplesAndAQuadruple_queue .pop ();
277301 }
278302 }
279303
0 commit comments