From 5e4e14fb6196883fca6f77dd4e9b553f44e28092 Mon Sep 17 00:00:00 2001 From: Morten Dahl Date: Tue, 16 Jul 2019 22:55:59 +0200 Subject: [PATCH 1/2] first step of more elaborate Paillier example --- examples/paillier.py | 76 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/examples/paillier.py b/examples/paillier.py index 2af05f9..c39f4ec 100644 --- a/examples/paillier.py +++ b/examples/paillier.py @@ -1,26 +1,70 @@ +import numpy as np import tensorflow as tf import tf_big +# use secure operations by default tf_big.set_secure_default(True) -p = tf_big.constant([17]) -q = tf_big.constant([19]) -n = p * q +class EncryptionKey: + def __init__(self, n, nn, g): + self.n = n + self.nn = nn + self.g = g -g = n + 1 -nn = n * n +class DecryptionKey: + def __init__(self): + # TODO what do we need? -x = tf.constant([[4]]) -# r = tf_big.random.uniform(n) -r = tf_big.constant([82]) -assert r.shape == x.shape, (r.shape, x.shape) +def keygen(modulus_bitlen): + # TODO + p = tf_big.constant(SOME PRIME) + q = tf_big.constant(SOME PRIME) + n = p * q -gx = tf_big.pow(g, x, nn, secure=True) -assert gx.shape.as_list() == [1, 1], gx.shape -rn = tf_big.pow(r, n, nn, secure=True) -assert rn.shape.as_list() == [1, 1], rn.shape -c = gx * rn #% nn + g = n + 1 + nn = n * n + + ek = EncryptionKey(n, nn, g) + dk = DecryptionKey() + return ek, dk + +def encrypt(ek, x): + r = tf_big.random.uniform(ek.n, shape=x.shape) + assert r.shape == x.shape, "Shapes are not matching: {}, {}".format(r.shape, x.shape) + + gx = tf_big.pow(ek.g, x, ek.nn) + rn = tf_big.pow(r, ek.n, ek.nn) + c = gx * rn % ek.nn + return c + +def decrypt(dk, c): + # TODO what do we need? + +def add(ek, c1, c2): + c = c1 * c2 % ek.nn + return c + +def mul(ek, c1, x2): + c = tf_big.pow(c1, x2, ek.nn) + return c + +ek, dk = keygen(2048) + +# TODO(Morten) relace with lin reg computation? + +x1 = tf.constant([[1, 2], [3, 4]]) +c1 = encrypt(ek, x1) + +x1 = tf.constant([[5, 6], [7, 8]]) +c2 = encrypt(ek, x2) + +c3 = add(ek, c1, c2) + +c4 = mul(ek, c3, tf.constant(3)) + +y = decrypt(dk, c4) with tf.Session() as sess: - res = sess.run(c) - print(res) + actual = sess.run(tf_big.convert_from_tensor(y)) + expected = (x1 + x2) * 3 + np.testing.assert_array_equal(actual, expected) From a35d6555dbcfde030af0b1dd5255bc4a81db7725 Mon Sep 17 00:00:00 2001 From: Morten Dahl Date: Mon, 26 Aug 2019 18:02:33 +0200 Subject: [PATCH 2/2] Update paillier.py --- examples/paillier.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/examples/paillier.py b/examples/paillier.py index c39f4ec..93d55cb 100644 --- a/examples/paillier.py +++ b/examples/paillier.py @@ -14,11 +14,12 @@ def __init__(self, n, nn, g): class DecryptionKey: def __init__(self): # TODO what do we need? + pass -def keygen(modulus_bitlen): - # TODO - p = tf_big.constant(SOME PRIME) - q = tf_big.constant(SOME PRIME) +def dummy_keygen(): + # TODO use fixed large primes + p = tf_big.constant([17]) + q = tf_big.constant([19]) n = p * q g = n + 1 @@ -29,7 +30,8 @@ def keygen(modulus_bitlen): return ek, dk def encrypt(ek, x): - r = tf_big.random.uniform(ek.n, shape=x.shape) + # r = tf_big.random.uniform(ek.n, shape=x.shape) + r = tf_big.convert_to_tensor(tf.constant([[123, 124], [125, 126]])) # TODO assert r.shape == x.shape, "Shapes are not matching: {}, {}".format(r.shape, x.shape) gx = tf_big.pow(ek.g, x, ek.nn) @@ -39,6 +41,7 @@ def encrypt(ek, x): def decrypt(dk, c): # TODO what do we need? + pass def add(ek, c1, c2): c = c1 * c2 % ek.nn @@ -48,7 +51,7 @@ def mul(ek, c1, x2): c = tf_big.pow(c1, x2, ek.nn) return c -ek, dk = keygen(2048) +ek, dk = dummy_keygen() # TODO(Morten) relace with lin reg computation? @@ -65,6 +68,6 @@ def mul(ek, c1, x2): y = decrypt(dk, c4) with tf.Session() as sess: - actual = sess.run(tf_big.convert_from_tensor(y)) + actual = sess.run(y) expected = (x1 + x2) * 3 np.testing.assert_array_equal(actual, expected)