Skip to content

Commit

Permalink
#6 Command to multiply encrypted number with unencrypted number and t…
Browse files Browse the repository at this point in the history
…est.

Currently will fail due to result having more negative exponent after the multiplication is carried out.
  • Loading branch information
hardbyte committed Jan 11, 2016
1 parent b456515 commit 86b0e9b
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 6 deletions.
32 changes: 31 additions & 1 deletion phe/command_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,41 @@ def add_encrypted_to_plaintext(public, encrypted, plaintext, output):
num = float(plaintext)

log("Adding")

enc_result = enc + num
serialised_result = serialise_encrypted(enc_result)
print(serialised_result, file=output)


@cli.command("multiply")
@click.argument('public', type=click.File('r'))
@click.argument('encrypted', type=click.File('r'))
@click.argument('plaintext', type=str)
@click.option('--output', type=click.File('w'),
help="Save to file instead of stdout")
def multiply_encrypted_to_plaintext(public, encrypted, plaintext, output):
"""Multiply an encrypted number to a non encrypted number.
"""
log("Loading public key")
publickeydata = json.load(public)
pub = load_public_key(publickeydata)

log("Loading encrypted number")
enc = load_encrypted_number(encrypted, pub)

log("Loading unencrypted number")
num = float(plaintext)

encoded_number = phe.EncodedNumber.encode(pub, num, max_exponent=-32)

assert encoded_number.exponent == -32

log("Multiplying")
enc_result = enc * encoded_number
assert enc_result.exponent == -32
serialised_result = serialise_encrypted(enc_result)
print(serialised_result, file=output)


if __name__ == "__main__":
cli()
61 changes: 56 additions & 5 deletions phe/tests/cli_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
import random
import unittest
from unittest import TestCase
import tempfile

Expand Down Expand Up @@ -222,12 +223,19 @@ def encrypt_and_add(self, a, b):
out = outfile.read()
return float(out)

def encrypt_a_and_add_b(self, a, b):
def _a_b_encrypt_helper(self, a, b, operation):
self.runner.invoke(cli,
['encrypt', self.public_keyfile.name, '--output', self.enc_a_file.name, '--', str(a)])
[
'encrypt',
self.public_keyfile.name,
'--output',
self.enc_a_file.name,
'--',
str(a)
])

result = self.runner.invoke(cli, [
'add',
operation,
'--output',
self.enc_result_file.name,
self.public_keyfile.name,
Expand All @@ -236,7 +244,7 @@ def encrypt_a_and_add_b(self, a, b):
str(b)
])

assert result.exit_code == 0
assert result.exit_code == 0, "Problem carrying out the {} operation".format(operation)

with tempfile.NamedTemporaryFile() as outfile:
result = self.runner.invoke(cli, [
Expand All @@ -247,6 +255,12 @@ def encrypt_a_and_add_b(self, a, b):
out = outfile.read()
return float(out)

def encrypt_a_and_add_b(self, a, b):
return self._a_b_encrypt_helper(a, b, 'add')

def encrypt_a_and_multiply_b(self, a, b):
return self._a_b_encrypt_helper(a, b, 'multiply')


class TestConsoleAddition(TestConsoleHelpers):

Expand All @@ -267,7 +281,6 @@ def test_addenc_large_ints(self):
out = self.encrypt_and_add(a, b)
self.assertAlmostEqual(float(a + b), float(out))


def test_add_large_ints(self):
"""Test adding large integers.
"""
Expand Down Expand Up @@ -311,6 +324,31 @@ def test_add_large_floats(self):
self.assertAlmostEqual(float(a + b), float(out))


class TestConsoleMultiplication(TestConsoleHelpers):
"""
Expected to fail until we decide if encrypted numbers with different
exponents are allowed for this CLI...
"""

@unittest.expectedFailure
def test_multiply_floats(self):
a, b = 1.2345, 0.6
out = self.encrypt_a_and_multiply_b(a, b)
self.assertAlmostEqual(float(a * b), float(out))

@unittest.expectedFailure
def test_multiply_random_ints(self):
"""
"""
MAX = 10000
MIN = -MAX

for _ in range(20):
a, b = random.randrange(MIN, MAX), random.randrange(MIN, MAX)
out = self.encrypt_a_and_multiply_b(a, b)
self.assertAlmostEqual(float(a * b), float(out))


class TestFuzz(TestConsoleHelpers):

def test_addenc_random_ints(self):
Expand Down Expand Up @@ -352,3 +390,16 @@ def test_add_random_floats(self):
self.assertAlmostEqual(float(a + b), float(out))


@unittest.expectedFailure
def test_multiply_random_ints(self):
"""
"""
MAX = 10000
MIN = -MAX

for _ in range(20):
a, b = random.randrange(MIN, MAX), random.randrange(MIN, MAX)
out = self.encrypt_a_and_multiply_b(a, b)
self.assertAlmostEqual(float(a * b), float(out))


0 comments on commit 86b0e9b

Please sign in to comment.