parent
9fc9d08fb4
commit
c0752f71ed
@ -35,7 +35,7 @@ class Ballot(EmbeddedObject):
|
|||||||
election_id = UUIDField()
|
election_id = UUIDField()
|
||||||
election_hash = StringField()
|
election_hash = StringField()
|
||||||
|
|
||||||
answers = EmbeddedObjectListField(is_hashed=False)
|
answers = EmbeddedObjectListField(is_hashed=False) # Used for ballots to be audited
|
||||||
|
|
||||||
def deaudit(self):
|
def deaudit(self):
|
||||||
encrypted_answers_deaudit = EosList()
|
encrypted_answers_deaudit = EosList()
|
||||||
@ -118,19 +118,23 @@ class ListChoiceQuestion(Question):
|
|||||||
if len(answer.choices) == 0:
|
if len(answer.choices) == 0:
|
||||||
return '(blank votes)'
|
return '(blank votes)'
|
||||||
return ', '.join([self.choices[choice] for choice in answer.choices])
|
return ', '.join([self.choices[choice] for choice in answer.choices])
|
||||||
|
|
||||||
class ApprovalQuestion(ListChoiceQuestion):
|
def max_bits(self):
|
||||||
pass
|
answer = self.answer_type(choices=list(range(len(self.choices))))
|
||||||
|
return len(EosObject.to_json(EosObject.serialise_and_wrap(answer))) * 8
|
||||||
|
|
||||||
class ApprovalAnswer(Answer):
|
class ApprovalAnswer(Answer):
|
||||||
choices = ListField(IntField())
|
choices = ListField(IntField())
|
||||||
|
|
||||||
class PreferentialQuestion(ListChoiceQuestion):
|
class ApprovalQuestion(ListChoiceQuestion):
|
||||||
pass
|
answer_type = ApprovalAnswer
|
||||||
|
|
||||||
class PreferentialAnswer(Answer):
|
class PreferentialAnswer(Answer):
|
||||||
choices = ListField(IntField())
|
choices = ListField(IntField())
|
||||||
|
|
||||||
|
class PreferentialQuestion(ListChoiceQuestion):
|
||||||
|
answer_type = PreferentialAnswer
|
||||||
|
|
||||||
class RawResult(Result):
|
class RawResult(Result):
|
||||||
plaintexts = ListField(EmbeddedObjectListField())
|
plaintexts = ListField(EmbeddedObjectListField())
|
||||||
answers = EmbeddedObjectListField()
|
answers = EmbeddedObjectListField()
|
||||||
|
@ -60,8 +60,9 @@ class DBInfo:
|
|||||||
dbinfo = DBInfo()
|
dbinfo = DBInfo()
|
||||||
|
|
||||||
def db_connect(db_name, db_uri='mongodb://localhost:27017/', db_type='mongodb'):
|
def db_connect(db_name, db_uri='mongodb://localhost:27017/', db_type='mongodb'):
|
||||||
dbinfo.provider = eos.core.db.db_providers[db_type](db_name, db_uri)
|
if is_python:
|
||||||
dbinfo.provider.connect()
|
dbinfo.provider = eos.core.db.db_providers[db_type](db_name, db_uri)
|
||||||
|
dbinfo.provider.connect()
|
||||||
|
|
||||||
# Fields
|
# Fields
|
||||||
# ======
|
# ======
|
||||||
|
@ -111,18 +111,29 @@ class BitStream(EosObject):
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
def pad_by(self, padding_size, pad_at_end=False):
|
||||||
|
if padding_size > 0:
|
||||||
|
if pad_at_end:
|
||||||
|
# Suitable for structured data
|
||||||
|
self.seek(self.nbits)
|
||||||
|
self.write(ZERO, padding_size)
|
||||||
|
else:
|
||||||
|
# Suitable for raw numbers
|
||||||
|
self.nbits += padding_size
|
||||||
|
return self # For convenient chaining
|
||||||
|
|
||||||
|
def pad_to(self, target_size, pad_at_end=False):
|
||||||
|
if self.nbits < target_size:
|
||||||
|
diff = target_size - self.nbits
|
||||||
|
self.pad_by(diff, pad_at_end)
|
||||||
|
return self
|
||||||
|
|
||||||
# Make the size of this BitStream a multiple of the block_size
|
# Make the size of this BitStream a multiple of the block_size
|
||||||
def multiple_of(self, block_size, pad_at_end=False):
|
def multiple_of(self, block_size, pad_at_end=False):
|
||||||
if self.nbits % block_size != 0:
|
if self.nbits % block_size != 0:
|
||||||
diff = block_size - (self.nbits % block_size)
|
diff = block_size - (self.nbits % block_size)
|
||||||
if pad_at_end:
|
self.pad_by(diff, pad_at_end)
|
||||||
# Suitable for structured data
|
return self
|
||||||
self.seek(self.nbits)
|
|
||||||
self.write(ZERO, diff)
|
|
||||||
else:
|
|
||||||
# Suitable for raw numbers
|
|
||||||
self.nbits += diff
|
|
||||||
return self # For convenient chaining
|
|
||||||
|
|
||||||
def map(self, func, block_size):
|
def map(self, func, block_size):
|
||||||
if self.nbits % block_size != 0:
|
if self.nbits % block_size != 0:
|
||||||
|
@ -41,7 +41,7 @@ class CyclicGroup(EmbeddedObject):
|
|||||||
crypto_method = BigInt.crypto_random if crypto_random else BigInt.noncrypto_random
|
crypto_method = BigInt.crypto_random if crypto_random else BigInt.noncrypto_random
|
||||||
return crypto_method(ZERO, self.q - ONE)
|
return crypto_method(ZERO, self.q - ONE)
|
||||||
|
|
||||||
# RFC 3526
|
# RFC 3526, 2048-bit MODP Group
|
||||||
DEFAULT_GROUP = CyclicGroup(
|
DEFAULT_GROUP = CyclicGroup(
|
||||||
p=BigInt('FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF', 16),
|
p=BigInt('FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF', 16),
|
||||||
g=TWO
|
g=TWO
|
||||||
|
@ -27,10 +27,14 @@ class BlockEncryptedAnswer(EncryptedAnswer):
|
|||||||
blocks = EmbeddedObjectListField()
|
blocks = EmbeddedObjectListField()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def encrypt(cls, pk, obj):
|
def encrypt(cls, pk, obj, nbits=None):
|
||||||
pt = EosObject.to_json(EosObject.serialise_and_wrap(obj))
|
pt = EosObject.to_json(EosObject.serialise_and_wrap(obj))
|
||||||
bs = BitStream()
|
bs = BitStream()
|
||||||
bs.write_string(pt)
|
bs.write_string(pt)
|
||||||
|
if nbits is not None:
|
||||||
|
if bs.nbits > nbits:
|
||||||
|
raise Exception('Message is too big')
|
||||||
|
bs.pad_to(nbits, True)
|
||||||
bs.multiple_of(pk.nbits(), True)
|
bs.multiple_of(pk.nbits(), True)
|
||||||
ct = bs.map(pk.encrypt, pk.nbits())
|
ct = bs.map(pk.encrypt, pk.nbits())
|
||||||
|
|
||||||
|
@ -153,7 +153,12 @@ class BlockEGTestCase(EosTestCase):
|
|||||||
|
|
||||||
ct = BlockEncryptedAnswer.encrypt(self.sk.public_key, obj)
|
ct = BlockEncryptedAnswer.encrypt(self.sk.public_key, obj)
|
||||||
_, m = ct.decrypt(self.sk)
|
_, m = ct.decrypt(self.sk)
|
||||||
|
self.assertEqualJSON(obj, m)
|
||||||
|
|
||||||
|
# Force another block
|
||||||
|
ct2 = BlockEncryptedAnswer.encrypt(self.sk.public_key, obj, (len(ct.blocks) * self.sk.public_key.nbits()) + 1)
|
||||||
|
self.assertEqual(len(ct2.blocks), len(ct.blocks) + 1)
|
||||||
|
_, m = ct2.decrypt(self.sk)
|
||||||
self.assertEqualJSON(obj, m)
|
self.assertEqualJSON(obj, m)
|
||||||
|
|
||||||
class MixnetTestCase(EosTestCase):
|
class MixnetTestCase(EosTestCase):
|
||||||
@ -177,7 +182,7 @@ class MixnetTestCase(EosTestCase):
|
|||||||
|
|
||||||
def do_mixnet(mix_order):
|
def do_mixnet(mix_order):
|
||||||
# Set up mixnet
|
# Set up mixnet
|
||||||
mixnet = RPCMixnet(mix_order)
|
mixnet = RPCMixnet(mix_order=mix_order)
|
||||||
|
|
||||||
# Mix answers
|
# Mix answers
|
||||||
shuffled_answers, commitments = mixnet.shuffle(answers)
|
shuffled_answers, commitments = mixnet.shuffle(answers)
|
||||||
|
@ -21,9 +21,10 @@ isLibrariesLoaded = false;
|
|||||||
|
|
||||||
function generateEncryptedVote(election, answers) {
|
function generateEncryptedVote(election, answers) {
|
||||||
encrypted_answers = [];
|
encrypted_answers = [];
|
||||||
for (var answer_json of answers) {
|
for (var q_num = 0; q_num < answers.length; q_num++) {
|
||||||
|
answer_json = answers[q_num];
|
||||||
answer = eosjs.eos.core.objects.__all__.EosObject.deserialise_and_unwrap(answer_json, null);
|
answer = eosjs.eos.core.objects.__all__.EosObject.deserialise_and_unwrap(answer_json, null);
|
||||||
encrypted_answer = eosjs.eos.psr.election.__all__.BlockEncryptedAnswer.encrypt(election.public_key, answer);
|
encrypted_answer = eosjs.eos.psr.election.__all__.BlockEncryptedAnswer.encrypt(election.public_key, answer, election.questions.__getitem__(q_num).max_bits());
|
||||||
encrypted_answers.push(eosjs.eos.core.objects.__all__.EosObject.serialise_and_wrap(encrypted_answer, null));
|
encrypted_answers.push(eosjs.eos.core.objects.__all__.EosObject.serialise_and_wrap(encrypted_answer, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user