Mixnet Module#

The Mixnet module is a crucial part of the Decide application, focusing on the mix network functionality. The following sections provide documentation for its various components.

models.py#

class mixnet.models.Mixnet[source]#

Bases: Model

Django Model representing a Mixnet entity in the context of electronic voting.

voting_id#

Identifier for the voting instance.

Type:

PositiveIntegerField

auth_position#

Position of the authorization in the mixnet.

Type:

PositiveIntegerField

auths#

Relation to multiple Auth instances.

Type:

ManyToManyField

key#

Foreign key to a Key instance, nullable.

Type:

ForeignKey

pubkey#

Foreign key to a Key instance for public key, nullable.

Type:

ForeignKey

exception DoesNotExist#

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned#

Bases: MultipleObjectsReturned

auth_position#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

auths#

Accessor to the related objects manager on the forward and reverse sides of a many-to-many relation.

In the example:

class Pizza(Model):
    toppings = ManyToManyField(Topping, related_name='pizzas')

Pizza.toppings and Topping.pizzas are ManyToManyDescriptor instances.

Most of the implementation is delegated to a dynamically defined manager class built by create_forward_many_to_many_manager() defined below.

chain_call(path, data)[source]#

Makes a chained API call to the next authorization in the mixnet.

Parameters:
  • path (str) – The API path for the call.

  • data (dict) – Data to be sent in the API call.

Returns:

The response from the API call or None.

Return type:

Response or None

decrypt(msgs, pk, last=False)[source]#

Decrypts the provided messages using the mixnet’s cryptographic settings.

Parameters:
  • msgs (list) – The messages to decrypt.

  • pk (Key) – Public key used in the decryption process.

  • last (bool) – Indicates if this is the last decryption step.

Returns:

Decrypted messages.

Return type:

list

gen_key(p=0, g=0)[source]#

Generates a cryptographic key for the mixnet.

Parameters:
  • p (int, optional) – Prime number, part of the cryptographic key.

  • g (int, optional) – Generator number, part of the cryptographic key.

id#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

key#

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

key_id#
next_auths()[source]#

Retrieves the next set of authorizations in the mixnet.

Returns:

The next set of Auth instances.

Return type:

QuerySet

objects = <django.db.models.manager.Manager object>#
pubkey#

Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

pubkey_id#
shuffle(msgs, pk)[source]#

Shuffles the provided messages using the mixnet’s cryptographic settings.

Parameters:
  • msgs (list) – The messages to shuffle.

  • pk (Key) – Public key used in the shuffling process.

Returns:

Shuffled messages.

Return type:

list

voting_id#

A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

mixcrypt.py#

>>> B = 256
>>> k1 = MixCrypt(bits=B)
>>> k2 = MixCrypt(k=k1.k, bits=B)
>>> k3 = gen_multiple_key(k1, k2)
>>> N = 4
>>> clears = [random.StrongRandom().randint(1, B) for i in range(N)]
>>> cipher = [k3.encrypt(i) for i in clears]
>>> d = multiple_decrypt_shuffle(cipher, k1, k2)
>>> clears == d
False
>>> sorted(clears) == sorted(d)
True
>>> B = 256
>>> k1 = MixCrypt(bits=B)
>>> k1.setk(167,156,89,130) 
<Crypto.PublicKey.ElGamal.ElGamalobj object at 0x...>
>>> k2 = MixCrypt(bits=B)
>>> k2.setk(167,156,53,161) 
<Crypto.PublicKey.ElGamal.ElGamalobj object at 0x...>
>>> k3 = MixCrypt(bits=B)
>>> k3.k = ElGamal.construct((167, 156, 4717))
>>> k3.k.p, k3.k.g, k3.k.y
(167, 156, 4717)
>>> N = 4
>>> clears = [2,3,6,4]
>>> cipher = [(161, 109), (17, 101), (148, 163), (71, 37)]
>>> d = multiple_decrypt_shuffle(cipher, k2, k1)
>>> clears == d
False
>>> sorted(clears) == sorted(d)
True
class mixnet.mixcrypt.MixCrypt[source]#

Bases: object

A class for cryptographic operations based on the ElGamal encryption scheme.

Parameters:
  • k (ElGamal key, optional) – Optional pre-existing key to initialize the MixCrypt.

  • bits (int) – Bit size for the key generation.

__init__(k=None, bits=256)[source]#
decrypt(c)[source]#

Decrypts an ElGamal encrypted message.

Parameters:

c (tuple) – The encrypted message tuple.

Returns:

The decrypted message.

Return type:

int

encrypt(m, k=None)[source]#

Encrypts a message using ElGamal encryption.

Parameters:
  • m (int) – The message to encrypt.

  • k (ElGamal key, optional) – Optional key to use for encryption. If not provided, use the instance’s key.

Returns:

The encrypted message.

Return type:

tuple

gen_perm(l)[source]#

Generates a permutation of indices for a given length.

Parameters:

l (int) – The length of the list to generate a permutation for.

Returns:

A list of permuted indices.

Return type:

list

genk()[source]#

Generates a new ElGamal key.

Returns:

The generated ElGamal key.

Return type:

ElGamal key

getk(p, g)[source]#

Constructs an ElGamal key from given parameters.

Parameters:
  • p (int) – Prime number.

  • g (int) – Generator number.

Returns:

The constructed ElGamal key.

Return type:

ElGamal key

multiple_decrypt(msgs, last=True)[source]#

Decrypts multiple messages, optionally leaving them in tuple form.

Parameters:
  • msgs (list) – List of encrypted message tuples.

  • last (bool) – If True, return the clear message; if False, return a tuple with the original ‘a’ value and the decrypted ‘b’.

Returns:

List of decrypted messages or message tuples.

Return type:

list

reencrypt(cipher, pubkey=None)[source]#

Re-encrypts an encrypted message, optionally with a new public key.

Parameters:
  • cipher (tuple) – The encrypted message to re-encrypt.

  • pubkey (tuple, optional) – Optional public key for re-encryption. If not provided, the instance’s key is used.

Returns:

The re-encrypted message.

Return type:

tuple

setk(p, g, y, x)[source]#

Sets the ElGamal key with specified parameters.

Parameters:
  • p (int) – Prime number.

  • g (int) – Generator number.

  • y (int) – Public key component.

  • x (int) – Private key component.

Returns:

The set ElGamal key.

Return type:

ElGamal key

shuffle(msgs, pubkey=None)[source]#

Re-encrypts and shuffles a list of messages.

Parameters:
  • msgs (list) – The list of messages to re-encrypt and shuffle.

  • pubkey (tuple, optional) – Optional public key for re-encryption. If not provided, the instance’s key is used.

Returns:

The shuffled and re-encrypted list of messages.

Return type:

list

shuffle_decrypt(msgs, last=True)[source]#

Shuffles and decrypts a list of encrypted messages.

Parameters:
  • msgs (list) – The list of messages to shuffle and decrypt.

  • last (bool) – If True, only the decrypted message is returned; if False, a tuple is returned with the original ‘a’ value and the decrypted ‘b’.

Returns:

The shuffled and decrypted list of messages.

Return type:

list

mixnet.mixcrypt.gen_multiple_key(*crypts)[source]#

Generates a combined MixCrypt object from multiple MixCrypt objects.

Parameters:

crypts (tuple) – Variable number of MixCrypt objects.

Returns:

A new MixCrypt object with combined properties.

Return type:

MixCrypt

mixnet.mixcrypt.multiple_decrypt(c, *crypts)[source]#

Sequentially decrypts a cipher using multiple MixCrypt objects.

Parameters:
  • c (tuple) – The cipher to decrypt.

  • crypts (tuple) – Variable number of MixCrypt objects for decryption.

Returns:

The decrypted message.

Return type:

int

mixnet.mixcrypt.multiple_decrypt_shuffle(ciphers, *crypts)[source]#

Sequentially decrypts and shuffles a list of ciphers using multiple MixCrypt objects.

Parameters:
  • ciphers (list) – The list of ciphers to decrypt and shuffle.

  • crypts (tuple) – Variable number of MixCrypt objects for decryption and shuffling.

Returns:

The list of decrypted and shuffled messages.

Return type:

list

mixnet.mixcrypt.multiple_decrypt_shuffle2(ciphers, *crypts, pubkey=None)[source]#

Decrypts and shuffles a list of ciphers using multiple MixCrypt objects.

Parameters:
  • ciphers (list) – The list of ciphers to decrypt and shuffle.

  • crypts (tuple) – Variable number of MixCrypt objects for decryption and shuffling.

  • pubkey (tuple, optional) – Optional public key used in the shuffling process.

Returns:

The list of decrypted and shuffled messages.

Return type:

list

mixnet.mixcrypt.rand(p)[source]#

Generates a random integer k where GCD(k, p-1) == 1.

Parameters:

p (int) – A prime number.

Returns:

A random integer k.

Return type:

int

views.py#

class mixnet.views.Decrypt[source]#

Bases: APIView

post(request, voting_id)[source]#
  • voting_id: id

  • msgs: [ [int, int] ]

  • pk: { “p”: int, “g”: int, “y”: int } / nullable

  • position: int / nullable

class mixnet.views.MixnetViewSet[source]#

Bases: ModelViewSet

API endpoint that allows mixnets to be viewed or edited.

create(request)[source]#

This create a new mixnet and public key

  • auths: [ {“name”: str, “url”: str} ]

  • voting: id

  • position: int / nullable

  • key: { “p”: int, “g”: int } / nullable

queryset#
serializer_class#

alias of MixnetSerializer

class mixnet.views.Shuffle[source]#

Bases: APIView

post(request, voting_id)[source]#
  • voting_id: id

  • msgs: [ [int, int] ]

  • pk: { “p”: int, “g”: int, “y”: int } / nullable

  • position: int / nullable

tests.py#

class mixnet.tests.MixnetCase[source]#

Bases: APITestCase

Test case class for Mixnet related operations.

This class contains several test methods for testing Mixnet functionalities including encryption, shuffling, and decryption in various scenarios.

encrypt_msgs(msgs, pk, bits=256)[source]#

Encrypts a list of messages using the provided public key.

Parameters:
  • msgs (list) – Messages to be encrypted.

  • pk (tuple) – Public key used for encryption.

  • bits (int) – Bit size for encryption.

Returns:

List of encrypted messages.

Return type:

list

setUp()[source]#

Set up function for test case.

Initializes the test client and applies necessary mocks.

tearDown()[source]#

Tear down function for test case.

Cleans up resources after each test method.

test_create()[source]#

Test case for creating a Mixnet instance.

Validates the creation and key types of a new Mixnet instance.

test_decrypt()[source]#

Test case for decrypting shuffled messages in Mixnet.

Validates decryption functionality and ensures decrypted messages match the original pre-shuffled messages.

test_multiple_auths()[source]#

This test emulates a two authorities shuffle and decryption.

We create two votings, one with id 1 and another one with id 2, to have this separated in the test db.

Then we compose the PublicKey of both auths.

Then we encrypt the text with the PK and shuffle two times, once with each voting/auth.

Then we decrypt with the first voting/auth and decrypt the result with the second voting/auth.

test_multiple_auths_mock()[source]#

Test case for emulating shuffle and decryption with multiple authorities using mocks.

Similar to ‘test_multiple_auths’ but uses mocked data and settings.

test_shuffle()[source]#

Test case for shuffling encrypted messages in Mixnet.

Validates the shuffling functionality and ensures the shuffled messages are different from the original.

test_shuffle2()[source]#

Second test case for shuffling encrypted messages in Mixnet.

Similar to ‘test_shuffle’ but includes additional public key parameter.