def test_paillier_key_generation(self): key = paillier.generate_keys(bits = 128) public = key.public() ptxt_original = 521 ctxt = paillier.encrypt(public, ptxt_original) ptxt = paillier.decrypt(key, ctxt) self.assertEqual(ptxt_original, ptxt) # test homomorphism ptxt1 = 14 ptxt2 = 19 ctxt1 = paillier.encrypt(public, ptxt1) ctxt2 = paillier.encrypt(public, ptxt2) final_ptxt = paillier.decrypt(key, ctxt1 * ctxt2) self.assertEqual(final_ptxt, ptxt1 + ptxt2) # test average ptxt3 = 12 ctxt3 = paillier.encrypt(public, ptxt3) ciphertext = [ctxt1, ctxt2, ctxt3] numerator, denominator = paillier.average(public, ciphertext) numerator = paillier.decrypt(key, numerator) denominator = paillier.decrypt(key, denominator) average = numerator/denominator self.assertAlmostEqual(average, 15)
def average(request): params = request.QUERY_PARAMS.dict() # get the paillier key modulus = params.pop('modulus', None) generator = params.pop('generator', None) if modulus is None or generator is None: raise PubKeyRequired try: modulus = int(modulus) generator = int(generator) except ValueError: raise PubKeyRequired("invalid public key") key = paillier.PublicKey(modulus, generator) packets = Packet.objects.encrypted_filter(**params) try: lengths = [int(packet.length) for packet in packets] except ValueError: raise APIException("invalid database state -- non-int packet lengths") ctxt_sum, ctxt_count = paillier.average(key, lengths) return Response({'sum': ctxt_sum, 'count': ctxt_count})