Source code for mixnet.views

from django.conf import settings
from django.shortcuts import get_object_or_404
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework.views import APIView

from .serializers import MixnetSerializer
from .models import Auth, Mixnet, Key
from base.serializers import KeySerializer, AuthSerializer


[docs]class MixnetViewSet(viewsets.ModelViewSet): """ API endpoint that allows mixnets to be viewed or edited. """ queryset = Mixnet.objects.all() serializer_class = MixnetSerializer
[docs] def create(self, request): """ This create a new mixnet and public key * auths: [ {"name": str, "url": str} ] * voting: id * position: int / nullable * key: { "p": int, "g": int } / nullable """ auths = request.data.get("auths") voting = request.data.get("voting") key = request.data.get("key", {"p": 0, "g": 0}) position = request.data.get("position", 0) p, g = int(key["p"]), int(key["g"]) dbauths = [] for auth in auths: isme = auth["url"] == settings.BASEURL a, _ = Auth.objects.get_or_create(name=auth["name"], url=auth["url"], me=isme) dbauths.append(a) mn = Mixnet(voting_id=voting, auth_position=position) mn.save() for a in dbauths: mn.auths.add(a) mn.gen_key(p, g) data = {"key": {"p": mn.key.p, "g": mn.key.g}} # chained call to the next auth to gen the key resp = mn.chain_call("/", data) if resp: y = (resp["y"] * mn.key.y) % mn.key.p else: y = mn.key.y pubkey = Key(p=mn.key.p, g=mn.key.g, y=y) pubkey.save() mn.pubkey = pubkey mn.save() return Response(KeySerializer(pubkey, many=False).data)
[docs]class Shuffle(APIView):
[docs] def post(self, request, voting_id): """ * voting_id: id * msgs: [ [int, int] ] * pk: { "p": int, "g": int, "y": int } / nullable * position: int / nullable """ position = request.data.get("position", 0) mn = get_object_or_404( Mixnet, voting_id=voting_id, auth_position=position) msgs = request.data.get("msgs", []) pk = request.data.get("pk", None) if pk: p, g, y = pk["p"], pk["g"], pk["y"] else: p, g, y = mn.key.p, mn.key.g, mn.key.y msgs = mn.shuffle(msgs, (p, g, y)) data = { "msgs": msgs, "pk": {"p": p, "g": g, "y": y}, } # chained call to the next auth to gen the key resp = mn.chain_call("/shuffle/{}/".format(voting_id), data) if resp: msgs = resp return Response(msgs)
[docs]class Decrypt(APIView):
[docs] def post(self, request, voting_id): """ * voting_id: id * msgs: [ [int, int] ] * pk: { "p": int, "g": int, "y": int } / nullable * position: int / nullable """ position = request.data.get("position", 0) mn = get_object_or_404( Mixnet, voting_id=voting_id, auth_position=position) msgs = request.data.get("msgs", []) pk = request.data.get("pk", None) if pk: p, g, y = pk["p"], pk["g"], pk["y"] else: p, g, y = mn.key.p, mn.key.g, mn.key.y next_auths = mn.next_auths() last = next_auths.count() == 0 # useful for tests only, to override the last value last = request.data.get("force-last", last) msgs = mn.decrypt(msgs, (p, g, y), last=last) data = { "msgs": msgs, "pk": {"p": p, "g": g, "y": y}, } # chained call to the next auth to gen the key resp = mn.chain_call("/decrypt/{}/".format(voting_id), data) if resp: msgs = resp return Response(msgs)