Skip to content

Commit

Permalink
added question.min
Browse files Browse the repository at this point in the history
  • Loading branch information
benadida committed Dec 29, 2008
1 parent f7b2f24 commit 7dbf664
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 20 deletions.
3 changes: 2 additions & 1 deletion helios/templates/election_build.html
@@ -1,7 +1,7 @@
{% extends "base.html" %}

{% block content %}
<h2 class="title">{{utils.get_host}} {{election.name}} &mdash; Build <span style="font-size:0.7em;">[<a href="./view">done</a>]</span></h2>
<h2 class="title">{{election.name}} &mdash; Build <span style="font-size:0.7em;">[<a href="./view">done</a>]</span></h2>

<script language="javascript">
Helios.setup();
Expand Down Expand Up @@ -59,6 +59,7 @@ <h2 class="title">{{utils.get_host}} {{election.name}} &mdash; Build <span style
question['question'] = form['question'].value;

// integer
question['min'] = parseInt(form['min'].value);
question['max'] = parseInt(form['max'].value);

$(question.answers).each(function(i, answer) {
Expand Down
17 changes: 17 additions & 0 deletions helios/templates/vote.html
Expand Up @@ -69,6 +69,23 @@ <h3>Fingerprint: <span id="election_hash"></span></h3>
BOOTH.show($('#election_div')).processTemplate({'election' : BOOTH.election});
};

// check if the current question is ok
BOOTH.validate_question = function(question_num) {
// check if enough answers are checked
if (BOOTH.ballot.answers[question_num].length < BOOTH.election.questions[question_num].min) {
alert('You need to select at least ' + BOOTH.election.questions[question_num].min + ' answer(s).');
return false;
}

return true;
};

BOOTH.validate_and_confirm = function(question_num) {
if (BOOTH.validate_question(question_num)) {
BOOTH.show_confirm();
}
};

BOOTH.show_question = function(question_num) {
BOOTH.show_progress('1');
BOOTH.show($('#question_div')).processTemplate({'question_num' : question_num,
Expand Down
1 change: 0 additions & 1 deletion static/bigint.js
Expand Up @@ -13,7 +13,6 @@
BigInt = Class.extend({
init: function(value, radix) {
if (value == null) {
debugger;
throw "null value!";
}

Expand Down
4 changes: 3 additions & 1 deletion static/elgamal.js
Expand Up @@ -246,6 +246,7 @@ ElGamal.Ciphertext = Class.extend({
// go through all plaintexts and simulate the ones that must be simulated.
// note how the interface is as such so that the result does not reveal which is the real proof.
var self = this;

var proofs = $(list_of_plaintexts).map(function(p_num, plaintext) {
if (p_num == real_index) {
// no real proof yet
Expand All @@ -268,6 +269,7 @@ ElGamal.Ciphertext = Class.extend({
var commitments = $(proofs).map(function(proof_num, proof) {
return proof.commitment;
});

var disjunctive_challenge = challenge_generator(commitments);

// now we must subtract all of the other challenges from this challenge.
Expand All @@ -283,7 +285,7 @@ ElGamal.Ciphertext = Class.extend({

// set the real proof
proofs[real_index] = real_proof;

return new ElGamal.DisjunctiveProof(proofs);
},

Expand Down
34 changes: 23 additions & 11 deletions static/helios.js
Expand Up @@ -146,15 +146,19 @@ UTILS.open_window_with_content = function(content) {
};

// generate an array of the first few plaintexts
UTILS.generate_plaintexts = function(pk, num) {
UTILS.generate_plaintexts = function(pk, min, max) {
var last_plaintext = BigInt.ONE;

// an array of plaintexts
var plaintexts = []
var plaintexts = [];

if (min == null)
min = 0;

// questions with more than one possible answer, add to the array.
for (var i=0; i<=num; i++) {
plaintexts[i] = new ElGamal.Plaintext(last_plaintext, pk, false);
for (var i=0; i<=max; i++) {
if (i >= min)
plaintexts.push(new ElGamal.Plaintext(last_plaintext, pk, false));
last_plaintext = last_plaintext.multiply(pk.g).mod(pk.p);
}

Expand Down Expand Up @@ -191,8 +195,9 @@ HELIOS.EncryptedAnswer = Class.extend({
var individual_proofs = [];
var overall_proof = null;

// possible plaintexts [0, 1, .. , question.max]
var plaintexts = UTILS.generate_plaintexts(pk, question.max);
// possible plaintexts [question.min .. , question.max]
var plaintexts = UTILS.generate_plaintexts(pk, question.min, question.max);
var zero_one_plaintexts = UTILS.generate_plaintexts(pk, 0, 1);

// keep track of whether we need to generate new randomness
var generate_new_randomness = false;
Expand Down Expand Up @@ -220,12 +225,12 @@ HELIOS.EncryptedAnswer = Class.extend({
randomness[i] = Random.getRandomInteger(pk.q);
}

choices[i] = ElGamal.encrypt(pk, plaintexts[plaintext_index], randomness[i]);
choices[i] = ElGamal.encrypt(pk, zero_one_plaintexts[plaintext_index], randomness[i]);

// generate proof
if (generate_new_randomness) {
// generate proof that this ciphertext is a 0 or a 1
individual_proofs[i] = choices[i].generateDisjunctiveProof(plaintexts, plaintext_index, randomness[i], ElGamal.disjunctive_challenge_generator);
individual_proofs[i] = choices[i].generateDisjunctiveProof(zero_one_plaintexts, plaintext_index, randomness[i], ElGamal.disjunctive_challenge_generator);
}

if (progress)
Expand All @@ -245,7 +250,14 @@ HELIOS.EncryptedAnswer = Class.extend({

// prove that the sum is 0 or 1 (can be "blank vote" for this answer)
// num_selected_answers is 0 or 1, which is the index into the plaintext that is actually encoded
overall_proof = hom_sum.generateDisjunctiveProof(plaintexts, num_selected_answers, rand_sum, ElGamal.disjunctive_challenge_generator);
//
// now that "plaintexts" only contains the array of plaintexts that are possible starting with min
// and going to max, the num_selected_answers needs to be reduced by min to be the proper index
var overall_plaintext_index = num_selected_answers;
if (question.min)
overall_plaintext_index -= question.min;

overall_proof = hom_sum.generateDisjunctiveProof(plaintexts, overall_plaintext_index, rand_sum, ElGamal.disjunctive_challenge_generator);
if (progress)
progress.tick();
}
Expand Down Expand Up @@ -409,7 +421,7 @@ HELIOS.EncryptedVote = Class.extend({
},

verifyProofs: function(pk, outcome_callback) {
var zero_or_one = UTILS.generate_plaintexts(pk, 1);
var zero_or_one = UTILS.generate_plaintexts(pk, 0, 1);

var VALID_P = true;

Expand All @@ -431,7 +443,7 @@ HELIOS.EncryptedVote = Class.extend({
});

// possible plaintexts [0, 1, .. , question.max]
var plaintexts = UTILS.generate_plaintexts(pk, self.election.questions[ea_num].max);
var plaintexts = UTILS.generate_plaintexts(pk, self.election.questions[ea_num].min, self.election.questions[ea_num].max);

// check the proof on the overall product
var overall_check = overall_result.verifyDisjunctiveProof(plaintexts, enc_answer.overall_proof, ElGamal.disjunctive_challenge_generator);
Expand Down
17 changes: 11 additions & 6 deletions static/templates/booth/question.html
@@ -1,13 +1,18 @@

<h3 style="border-bottom: 1px solid black;">Question #{$T.question_num + 1} </h3>
<h3 style="border-bottom: 1px solid black;">Question #{$T.question_num + 1} of {$T.last_question_num + 1}</h3>

<form onsubmit="return false;" class="prettyform" id="answer_form">
<input type="hidden" name="question_num" value="{$T.question_num}" />

<p>
<em>{$T.question.question}</em>

(select {$T.question.max} answer{#if $T.question.max > 1}s{#/if})
<br />
<span style="font-size: 0.6em;">(select
{#if $T.question.min && $T.question.min > 0}
at least {$T.question.min} answer{#if $T.question.min > 1}s{#/if},
{#/if}
up to {$T.question.max} answer{#if $T.question.max > 1}s{#/if})
</span>
</p>


Expand All @@ -24,16 +29,16 @@ <h3 style="border-bottom: 1px solid black;">Question #{$T.question_num + 1} </h3
{#/for}

<div style="float: right;">
<input type="button" onclick="BOOTH.show_confirm();" value="Review all Choices" />
<input type="button" onclick="BOOTH.validate_and_confirm({$T.question_num});" value="Review all Choices" />
</div>

{#if $T.question_num != 0}
<input type="button" onclick="BOOTH.show_question({$T.question_num -1});" value="Previous" />
<input type="button" onclick="if (BOOTH.validate_question({$T.question_num})) {BOOTH.show_question({$T.question_num -1});}" value="Previous" />
&nbsp;
{#/if}

{#if $T.question_num < $T.last_question_num}
<input type="button" onclick="BOOTH.show_question({$T.question_num +1});" value="Next" />
<input type="button" onclick="if (BOOTH.validate_question({$T.question_num})) {BOOTH.show_question({$T.question_num +1});}" value="Next" />
&nbsp;
{#/if}

Expand Down
3 changes: 3 additions & 0 deletions static/templates/builder/question.html
Expand Up @@ -15,6 +15,9 @@ <h4>New Question</h4>
<label for="question">Full Question:</label>
<textarea name="question" id="question" cols="40" rows="3" wrap="soft">{$T.question.question}</textarea><br />

<label for="max">Min # of Answers:</label>
<input type="text" name="min" id="min" size="3" value="{$T.question.min || 0}" /><br />

<label for="max">Max # of Answers:</label>
<input type="text" name="max" id="max" size="3" value="{$T.question.max || 1}" /><br />
<!--<input type="hidden" name="max" id="max" value="1" />-->
Expand Down

0 comments on commit 7dbf664

Please sign in to comment.