├── .gitignore
├── .travis.yml
├── Aono.i
├── Aono.py
├── Aono_wrap.cxx
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── index.html
├── init.py
├── init_key_switching.py
├── init_operations_example.py
├── lib
└── he
│ ├── basic.h
│ ├── keys.h
│ ├── knuthYaoSampler.h
│ ├── main.cpp
│ ├── test.cpp
│ └── utils.h
├── setup.py
└── tests.py
/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__
2 | build
3 | *.pyc
4 | .DS_Store
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: python
2 | python:
3 | - "3.6"
4 |
5 | # install server dependencies
6 | before_install:
7 | - "sudo apt-get -y install musl-dev g++ swig make"
8 | - "wget https://pari.math.u-bordeaux.fr/pub/pari/unix/pari-2.9.3.tar.gz \
9 | && tar -xzf pari-2.9.3.tar.gz \
10 | && cd pari-2.9.3 \
11 | && ./Configure \
12 | && make all \
13 | && make bench \
14 | && sudo make install \
15 | && ls \
16 | && export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/ \
17 | && echo $LD_LIBRARY_PATH \
18 | && cd .."
19 |
20 | # install dependencies
21 | install:
22 | - "make compile"
23 | - "pip install pytest pytest--flake8"
24 |
25 | # run tests
26 | script:
27 | - make test
28 |
--------------------------------------------------------------------------------
/Aono.i:
--------------------------------------------------------------------------------
1 | %module Aono
2 | %{
3 | #include "lib/he/basic.h"
4 | %}
5 | extern void pari_init(size_t parisize, int maxprime);
6 | extern void pari_close();
7 | typedef long *GEN;
8 | %include "lib/he/basic.h"
9 | %include "lib/he/keys.h"
10 | %include "lib/he/utils.h"
11 |
12 | %pythoncode%{
13 | import atexit
14 | pari_init(2000000000, 2)
15 | atexit.register(pari_close)
16 | %}
17 |
18 | %include "carrays.i"
19 | %array_class(int, intArray);
20 | %extend pari_GEN{
21 | pari_GEN(PyObject *int_list){
22 | pari_GEN* result = new pari_GEN();
23 | if(!PyList_Check(PyList_GetItem( int_list, 0))){
24 | int *array = NULL;
25 | int nInts;
26 | if (PyList_Check( int_list ))
27 | {
28 | nInts = PyList_Size( int_list );
29 | array = (int*) malloc( nInts * sizeof(int) );
30 | for ( int ii = 0; ii < nInts; ii++ ){
31 | PyObject *oo = PyList_GetItem( int_list, ii);
32 | if ( PyInt_Check( oo ) )
33 | array[ ii ] = ( int ) PyInt_AsLong( oo );
34 | }
35 | }
36 | GEN x;
37 | x = cgetg(nInts + 1, t_VEC);
38 | for(int i = 0; i < nInts; i++)
39 | gel(x, i + 1) = stoi(array[i]);
40 | result->initialize(x);
41 | return result;
42 | }
43 | else{
44 | int *array = NULL;
45 | int **arrofarray = NULL;
46 | int nInts;
47 | int nOutInts;
48 | if (PyList_Check( int_list ))
49 | {
50 | nOutInts = PyList_Size( int_list );
51 | arrofarray = (int**) malloc( nOutInts * sizeof(int*) );
52 | for ( int jj = 0; jj < nOutInts; jj++ ){
53 | nInts = PyList_Size(PyList_GetItem( int_list, jj) );
54 | array = (int*) malloc( nInts * sizeof(int) );
55 | for ( int ii = 0; ii < nInts; ii++ ){
56 | PyObject *oo = PyList_GetItem(PyList_GetItem( int_list, jj), ii);
57 | if ( PyInt_Check( oo ) ){
58 | array[ ii ] = ( int ) PyInt_AsLong( oo );
59 | }
60 |
61 | }
62 | arrofarray[jj] = array;
63 | }
64 | }
65 | GEN x;
66 | x = zeromatcopy(nOutInts, nInts);
67 | for(int j = 0; j < nOutInts; j++){
68 | for(int i = 0; i < nInts; i++)
69 | gel(gel(x, i + 1), j + 1) = stoi(arrofarray[j][i]);
70 | }
71 | result->initialize(x);
72 | return result;
73 | }
74 |
75 | }
76 |
77 | char* __str__(){
78 | return GENtostr(self->value);
79 | }
80 |
81 | pari_GEN __getitem__(int key){
82 | pari_GEN result;
83 | result.value = gel(self->value, key + 1);
84 | return result;
85 | }
86 |
87 | pari_GEN sub_mat_array(int key_1, int key_2){
88 | pari_GEN result;
89 | result.value = cgetg(key_2 - key_1 + 1, t_VEC);
90 | int cnt = 0;
91 | for(int i = key_1; i < key_2; i++)
92 | gel(result.value, 1+cnt++) = gel(gel(self->value, i + 1), 1);
93 | return result;
94 | }
95 |
96 | pari_GEN sub_mat_array(int row_1, int row_2, int col_1, int col_2){
97 | pari_GEN result;
98 | result.value = zeromatcopy(row_2 - row_1, col_2 - col_1);
99 | for(int j = col_1; j < col_2; j++){
100 | for(int i = row_1; i < row_2; i++){
101 | gel(gel(result.value, 1+(j-col_1)), 1+(i-row_1)) = gel(gel(self->value, j + 1), i + 1);
102 | }
103 | }
104 | return result;
105 | }
106 |
107 | pari_GEN sub_array(int key_1, int key_2){
108 | pari_GEN result;
109 | result.value = cgetg(key_2 - key_1 + 1, t_VEC);
110 | for(int i = key_1; i < key_2; i++)
111 | gel(result.value, i + 1) = gel(self->value, i + 1);
112 | return result;
113 | }
114 | };
115 |
116 | %extend ciphertext{
117 | ciphertext(PyObject *int_list, public_key* pk){
118 | ciphertext* result = new ciphertext();
119 | int *array = NULL;
120 | int nInts;
121 | if (PyList_Check( int_list ))
122 | {
123 | nInts = PyList_Size( int_list );
124 | array = (int*) malloc( nInts * sizeof(int) );
125 | for ( int ii = 0; ii < nInts; ii++ ){
126 | PyObject *oo = PyList_GetItem( int_list, ii);
127 | if ( PyInt_Check( oo ) )
128 | array[ ii ] = ( int ) PyInt_AsLong( oo );
129 | }
130 | }
131 | pari_GEN pt;
132 | pt.value = cgetg(nInts + 1, t_VEC);
133 | for(int i = 0; i < nInts; i++)
134 | gel(pt.value, i + 1) = stoi(array[i]);
135 | result->packing_method(pt, pk);
136 | return result;
137 | }
138 |
139 |
140 | ciphertext __mul__(const int pt){
141 | ciphertext result;
142 | pari_GEN pt_GEN(pt);
143 | result.value = plaintext_multiplication(self->value, pt_GEN);
144 | result.params = self->params;
145 | result.pk = self->pk;
146 | return result;
147 | }
148 |
149 | ciphertext __rmul__(const int pt){
150 | ciphertext result;
151 | pari_GEN pt_GEN(pt);
152 | result.value = plaintext_multiplication(self->value, pt_GEN);
153 | result.params = self->params;
154 | result.pk = self->pk;
155 | return result;
156 | }
157 | };
158 |
--------------------------------------------------------------------------------
/Aono.py:
--------------------------------------------------------------------------------
1 | # This file was automatically generated by SWIG (http://www.swig.org).
2 | # Version 3.0.12
3 | #
4 | # Do not make changes to this file unless you know what you are doing--modify
5 | # the SWIG interface file instead.
6 |
7 | from sys import version_info as _swig_python_version_info
8 | if _swig_python_version_info >= (2, 7, 0):
9 | def swig_import_helper():
10 | import importlib
11 | pkg = __name__.rpartition('.')[0]
12 | mname = '.'.join((pkg, '_Aono')).lstrip('.')
13 | try:
14 | return importlib.import_module(mname)
15 | except ImportError:
16 | return importlib.import_module('_Aono')
17 | _Aono = swig_import_helper()
18 | del swig_import_helper
19 | elif _swig_python_version_info >= (2, 6, 0):
20 | def swig_import_helper():
21 | from os.path import dirname
22 | import imp
23 | fp = None
24 | try:
25 | fp, pathname, description = imp.find_module('_Aono', [dirname(__file__)])
26 | except ImportError:
27 | import _Aono
28 | return _Aono
29 | try:
30 | _mod = imp.load_module('_Aono', fp, pathname, description)
31 | finally:
32 | if fp is not None:
33 | fp.close()
34 | return _mod
35 | _Aono = swig_import_helper()
36 | del swig_import_helper
37 | else:
38 | import _Aono
39 | del _swig_python_version_info
40 |
41 | try:
42 | _swig_property = property
43 | except NameError:
44 | pass # Python < 2.2 doesn't have 'property'.
45 |
46 | try:
47 | import builtins as __builtin__
48 | except ImportError:
49 | import __builtin__
50 |
51 | def _swig_setattr_nondynamic(self, class_type, name, value, static=1):
52 | if (name == "thisown"):
53 | return self.this.own(value)
54 | if (name == "this"):
55 | if type(value).__name__ == 'SwigPyObject':
56 | self.__dict__[name] = value
57 | return
58 | method = class_type.__swig_setmethods__.get(name, None)
59 | if method:
60 | return method(self, value)
61 | if (not static):
62 | if _newclass:
63 | object.__setattr__(self, name, value)
64 | else:
65 | self.__dict__[name] = value
66 | else:
67 | raise AttributeError("You cannot add attributes to %s" % self)
68 |
69 |
70 | def _swig_setattr(self, class_type, name, value):
71 | return _swig_setattr_nondynamic(self, class_type, name, value, 0)
72 |
73 |
74 | def _swig_getattr(self, class_type, name):
75 | if (name == "thisown"):
76 | return self.this.own()
77 | method = class_type.__swig_getmethods__.get(name, None)
78 | if method:
79 | return method(self)
80 | raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name))
81 |
82 |
83 | def _swig_repr(self):
84 | try:
85 | strthis = "proxy of " + self.this.__repr__()
86 | except __builtin__.Exception:
87 | strthis = ""
88 | return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
89 |
90 | try:
91 | _object = object
92 | _newclass = 1
93 | except __builtin__.Exception:
94 | class _object:
95 | pass
96 | _newclass = 0
97 |
98 |
99 | def pari_init(parisize, maxprime):
100 | return _Aono.pari_init(parisize, maxprime)
101 | pari_init = _Aono.pari_init
102 |
103 | def pari_close():
104 | return _Aono.pari_close()
105 | pari_close = _Aono.pari_close
106 | class ciphertext(_object):
107 | __swig_setmethods__ = {}
108 | __setattr__ = lambda self, name, value: _swig_setattr(self, ciphertext, name, value)
109 | __swig_getmethods__ = {}
110 | __getattr__ = lambda self, name: _swig_getattr(self, ciphertext, name)
111 | __repr__ = _swig_repr
112 | __swig_setmethods__["value"] = _Aono.ciphertext_value_set
113 | __swig_getmethods__["value"] = _Aono.ciphertext_value_get
114 | if _newclass:
115 | value = _swig_property(_Aono.ciphertext_value_get, _Aono.ciphertext_value_set)
116 | __swig_setmethods__["degree"] = _Aono.ciphertext_degree_set
117 | __swig_getmethods__["degree"] = _Aono.ciphertext_degree_get
118 | if _newclass:
119 | degree = _swig_property(_Aono.ciphertext_degree_get, _Aono.ciphertext_degree_set)
120 | __swig_setmethods__["pk"] = _Aono.ciphertext_pk_set
121 | __swig_getmethods__["pk"] = _Aono.ciphertext_pk_get
122 | if _newclass:
123 | pk = _swig_property(_Aono.ciphertext_pk_get, _Aono.ciphertext_pk_set)
124 | __swig_setmethods__["params"] = _Aono.ciphertext_params_set
125 | __swig_getmethods__["params"] = _Aono.ciphertext_params_get
126 | if _newclass:
127 | params = _swig_property(_Aono.ciphertext_params_get, _Aono.ciphertext_params_set)
128 | __swig_destroy__ = _Aono.delete_ciphertext
129 | __del__ = lambda self: None
130 |
131 | def packing_method(self, m, pk):
132 | return _Aono.ciphertext_packing_method(self, m, pk)
133 |
134 | def initialize(self, *args):
135 | return _Aono.ciphertext_initialize(self, *args)
136 |
137 | def __add__(self, ct):
138 | return _Aono.ciphertext___add__(self, ct)
139 |
140 | def __sub__(self, ct):
141 | return _Aono.ciphertext___sub__(self, ct)
142 |
143 | def decrypt(self, sk):
144 | return _Aono.ciphertext_decrypt(self, sk)
145 |
146 | def __init__(self, *args):
147 | this = _Aono.new_ciphertext(*args)
148 | try:
149 | self.this.append(this)
150 | except __builtin__.Exception:
151 | self.this = this
152 |
153 | def __mul__(self, *args):
154 | return _Aono.ciphertext___mul__(self, *args)
155 |
156 | def __rmul__(self, pt):
157 | return _Aono.ciphertext___rmul__(self, pt)
158 | ciphertext_swigregister = _Aono.ciphertext_swigregister
159 | ciphertext_swigregister(ciphertext)
160 |
161 | class updation_key(_object):
162 | __swig_setmethods__ = {}
163 | __setattr__ = lambda self, name, value: _swig_setattr(self, updation_key, name, value)
164 | __swig_getmethods__ = {}
165 | __getattr__ = lambda self, name: _swig_getattr(self, updation_key, name)
166 | __repr__ = _swig_repr
167 | __swig_setmethods__["params"] = _Aono.updation_key_params_set
168 | __swig_getmethods__["params"] = _Aono.updation_key_params_get
169 | if _newclass:
170 | params = _swig_property(_Aono.updation_key_params_get, _Aono.updation_key_params_set)
171 | __swig_setmethods__["params_old"] = _Aono.updation_key_params_old_set
172 | __swig_getmethods__["params_old"] = _Aono.updation_key_params_old_get
173 | if _newclass:
174 | params_old = _swig_property(_Aono.updation_key_params_old_get, _Aono.updation_key_params_old_set)
175 | __swig_setmethods__["g"] = _Aono.updation_key_g_set
176 | __swig_getmethods__["g"] = _Aono.updation_key_g_get
177 | if _newclass:
178 | g = _swig_property(_Aono.updation_key_g_get, _Aono.updation_key_g_set)
179 |
180 | def __init__(self, *args):
181 | this = _Aono.new_updation_key(*args)
182 | try:
183 | self.this.append(this)
184 | except __builtin__.Exception:
185 | self.this = this
186 |
187 | def initialize(self, X, Y, params, params_old, g, pk):
188 | return _Aono.updation_key_initialize(self, X, Y, params, params_old, g, pk)
189 |
190 | def cipher_switch(self, ct):
191 | return _Aono.updation_key_cipher_switch(self, ct)
192 |
193 | def serialize(self):
194 | return _Aono.updation_key_serialize(self)
195 | __swig_destroy__ = _Aono.delete_updation_key
196 | __del__ = lambda self: None
197 | updation_key_swigregister = _Aono.updation_key_swigregister
198 | updation_key_swigregister(updation_key)
199 |
200 | class updation_key_gen(_object):
201 | __swig_setmethods__ = {}
202 | __setattr__ = lambda self, name, value: _swig_setattr(self, updation_key_gen, name, value)
203 | __swig_getmethods__ = {}
204 | __getattr__ = lambda self, name: _swig_getattr(self, updation_key_gen, name)
205 | __repr__ = _swig_repr
206 |
207 | def __init__(self):
208 | this = _Aono.new_updation_key_gen()
209 | try:
210 | self.this.append(this)
211 | except __builtin__.Exception:
212 | self.this = this
213 |
214 | def generate_key(self, key1, key2):
215 | return _Aono.updation_key_gen_generate_key(self, key1, key2)
216 | __swig_destroy__ = _Aono.delete_updation_key_gen
217 | __del__ = lambda self: None
218 | updation_key_gen_swigregister = _Aono.updation_key_gen_swigregister
219 | updation_key_gen_swigregister(updation_key_gen)
220 |
221 | class secret_key(_object):
222 | __swig_setmethods__ = {}
223 | __setattr__ = lambda self, name, value: _swig_setattr(self, secret_key, name, value)
224 | __swig_getmethods__ = {}
225 | __getattr__ = lambda self, name: _swig_getattr(self, secret_key, name)
226 | __repr__ = _swig_repr
227 | __swig_setmethods__["params"] = _Aono.secret_key_params_set
228 | __swig_getmethods__["params"] = _Aono.secret_key_params_get
229 | if _newclass:
230 | params = _swig_property(_Aono.secret_key_params_get, _Aono.secret_key_params_set)
231 |
232 | def __init__(self, *args):
233 | this = _Aono.new_secret_key(*args)
234 | try:
235 | self.this.append(this)
236 | except __builtin__.Exception:
237 | self.this = this
238 |
239 | def initialize(self, sk, params):
240 | return _Aono.secret_key_initialize(self, sk, params)
241 |
242 | def decrypt(self, ct):
243 | return _Aono.secret_key_decrypt(self, ct)
244 |
245 | def serialize(self):
246 | return _Aono.secret_key_serialize(self)
247 | __swig_destroy__ = _Aono.delete_secret_key
248 | __del__ = lambda self: None
249 | secret_key_swigregister = _Aono.secret_key_swigregister
250 | secret_key_swigregister(secret_key)
251 |
252 | class public_key(_object):
253 | __swig_setmethods__ = {}
254 | __setattr__ = lambda self, name, value: _swig_setattr(self, public_key, name, value)
255 | __swig_getmethods__ = {}
256 | __getattr__ = lambda self, name: _swig_getattr(self, public_key, name)
257 | __repr__ = _swig_repr
258 | __swig_setmethods__["params"] = _Aono.public_key_params_set
259 | __swig_getmethods__["params"] = _Aono.public_key_params_get
260 | if _newclass:
261 | params = _swig_property(_Aono.public_key_params_get, _Aono.public_key_params_set)
262 | __swig_setmethods__["g"] = _Aono.public_key_g_set
263 | __swig_getmethods__["g"] = _Aono.public_key_g_get
264 | if _newclass:
265 | g = _swig_property(_Aono.public_key_g_get, _Aono.public_key_g_set)
266 |
267 | def __init__(self, *args):
268 | this = _Aono.new_public_key(*args)
269 | try:
270 | self.this.append(this)
271 | except __builtin__.Exception:
272 | self.this = this
273 |
274 | def initialize(self, pk, params, g):
275 | return _Aono.public_key_initialize(self, pk, params, g)
276 |
277 | def encrypt(self, m):
278 | return _Aono.public_key_encrypt(self, m)
279 |
280 | def serialize(self):
281 | return _Aono.public_key_serialize(self)
282 | __swig_destroy__ = _Aono.delete_public_key
283 | __del__ = lambda self: None
284 | public_key_swigregister = _Aono.public_key_swigregister
285 | public_key_swigregister(public_key)
286 |
287 | class key_pair(_object):
288 | __swig_setmethods__ = {}
289 | __setattr__ = lambda self, name, value: _swig_setattr(self, key_pair, name, value)
290 | __swig_getmethods__ = {}
291 | __getattr__ = lambda self, name: _swig_getattr(self, key_pair, name)
292 | __repr__ = _swig_repr
293 | __swig_setmethods__["sk"] = _Aono.key_pair_sk_set
294 | __swig_getmethods__["sk"] = _Aono.key_pair_sk_get
295 | if _newclass:
296 | sk = _swig_property(_Aono.key_pair_sk_get, _Aono.key_pair_sk_set)
297 | __swig_setmethods__["pk"] = _Aono.key_pair_pk_set
298 | __swig_getmethods__["pk"] = _Aono.key_pair_pk_get
299 | if _newclass:
300 | pk = _swig_property(_Aono.key_pair_pk_get, _Aono.key_pair_pk_set)
301 |
302 | def __init__(self):
303 | this = _Aono.new_key_pair()
304 | try:
305 | self.this.append(this)
306 | except __builtin__.Exception:
307 | self.this = this
308 | __swig_destroy__ = _Aono.delete_key_pair
309 | __del__ = lambda self: None
310 | key_pair_swigregister = _Aono.key_pair_swigregister
311 | key_pair_swigregister(key_pair)
312 |
313 | class key_gen(_object):
314 | __swig_setmethods__ = {}
315 | __setattr__ = lambda self, name, value: _swig_setattr(self, key_gen, name, value)
316 | __swig_getmethods__ = {}
317 | __getattr__ = lambda self, name: _swig_getattr(self, key_gen, name)
318 | __repr__ = _swig_repr
319 |
320 | def __init__(self):
321 | this = _Aono.new_key_gen()
322 | try:
323 | self.this.append(this)
324 | except __builtin__.Exception:
325 | self.this = this
326 |
327 | def generate_key(self, arg2, l, n, s, sigma, degree_p):
328 | return _Aono.key_gen_generate_key(self, arg2, l, n, s, sigma, degree_p)
329 | __swig_destroy__ = _Aono.delete_key_gen
330 | __del__ = lambda self: None
331 | key_gen_swigregister = _Aono.key_gen_swigregister
332 | key_gen_swigregister(key_gen)
333 |
334 | M_PI = _Aono.M_PI
335 | precision = _Aono.precision
336 | class pari_GEN(_object):
337 | __swig_setmethods__ = {}
338 | __setattr__ = lambda self, name, value: _swig_setattr(self, pari_GEN, name, value)
339 | __swig_getmethods__ = {}
340 | __getattr__ = lambda self, name: _swig_getattr(self, pari_GEN, name)
341 | __repr__ = _swig_repr
342 | __swig_setmethods__["value"] = _Aono.pari_GEN_value_set
343 | __swig_getmethods__["value"] = _Aono.pari_GEN_value_get
344 | if _newclass:
345 | value = _swig_property(_Aono.pari_GEN_value_get, _Aono.pari_GEN_value_set)
346 |
347 | def initialize(self, x):
348 | return _Aono.pari_GEN_initialize(self, x)
349 |
350 | def __add__(self, GEN_2):
351 | return _Aono.pari_GEN___add__(self, GEN_2)
352 |
353 | def __mul__(self, GEN_2):
354 | return _Aono.pari_GEN___mul__(self, GEN_2)
355 |
356 | def __truediv__(self, *args):
357 | return _Aono.pari_GEN___truediv__(self, *args)
358 | __div__ = __truediv__
359 |
360 |
361 |
362 | def __sub__(self, GEN_2):
363 | return _Aono.pari_GEN___sub__(self, GEN_2)
364 |
365 | def __mod__(self, GEN_2):
366 | return _Aono.pari_GEN___mod__(self, GEN_2)
367 |
368 | def __eq__(self, GEN_2):
369 | return _Aono.pari_GEN___eq__(self, GEN_2)
370 |
371 | def __init__(self, *args):
372 | this = _Aono.new_pari_GEN(*args)
373 | try:
374 | self.this.append(this)
375 | except __builtin__.Exception:
376 | self.this = this
377 |
378 | def __str__(self):
379 | return _Aono.pari_GEN___str__(self)
380 |
381 | def __getitem__(self, key):
382 | return _Aono.pari_GEN___getitem__(self, key)
383 |
384 | def sub_mat_array(self, *args):
385 | return _Aono.pari_GEN_sub_mat_array(self, *args)
386 |
387 | def sub_array(self, key_1, key_2):
388 | return _Aono.pari_GEN_sub_array(self, key_1, key_2)
389 | __swig_destroy__ = _Aono.delete_pari_GEN
390 | __del__ = lambda self: None
391 | pari_GEN_swigregister = _Aono.pari_GEN_swigregister
392 | pari_GEN_swigregister(pari_GEN)
393 | cvar = _Aono.cvar
394 |
395 | class parameters(_object):
396 | __swig_setmethods__ = {}
397 | __setattr__ = lambda self, name, value: _swig_setattr(self, parameters, name, value)
398 | __swig_getmethods__ = {}
399 | __getattr__ = lambda self, name: _swig_getattr(self, parameters, name)
400 | __repr__ = _swig_repr
401 | __swig_setmethods__["q"] = _Aono.parameters_q_set
402 | __swig_getmethods__["q"] = _Aono.parameters_q_get
403 | if _newclass:
404 | q = _swig_property(_Aono.parameters_q_get, _Aono.parameters_q_set)
405 | __swig_setmethods__["p"] = _Aono.parameters_p_set
406 | __swig_getmethods__["p"] = _Aono.parameters_p_get
407 | if _newclass:
408 | p = _swig_property(_Aono.parameters_p_get, _Aono.parameters_p_set)
409 | __swig_setmethods__["_lambda"] = _Aono.parameters__lambda_set
410 | __swig_getmethods__["_lambda"] = _Aono.parameters__lambda_get
411 | if _newclass:
412 | _lambda = _swig_property(_Aono.parameters__lambda_get, _Aono.parameters__lambda_set)
413 | __swig_setmethods__["l"] = _Aono.parameters_l_set
414 | __swig_getmethods__["l"] = _Aono.parameters_l_get
415 | if _newclass:
416 | l = _swig_property(_Aono.parameters_l_get, _Aono.parameters_l_set)
417 | __swig_setmethods__["s"] = _Aono.parameters_s_set
418 | __swig_getmethods__["s"] = _Aono.parameters_s_get
419 | if _newclass:
420 | s = _swig_property(_Aono.parameters_s_get, _Aono.parameters_s_set)
421 | __swig_setmethods__["n"] = _Aono.parameters_n_set
422 | __swig_getmethods__["n"] = _Aono.parameters_n_get
423 | if _newclass:
424 | n = _swig_property(_Aono.parameters_n_get, _Aono.parameters_n_set)
425 | __swig_setmethods__["sigma"] = _Aono.parameters_sigma_set
426 | __swig_getmethods__["sigma"] = _Aono.parameters_sigma_get
427 | if _newclass:
428 | sigma = _swig_property(_Aono.parameters_sigma_get, _Aono.parameters_sigma_set)
429 |
430 | def __init__(self):
431 | this = _Aono.new_parameters()
432 | try:
433 | self.this.append(this)
434 | except __builtin__.Exception:
435 | self.this = this
436 | __swig_destroy__ = _Aono.delete_parameters
437 | __del__ = lambda self: None
438 | parameters_swigregister = _Aono.parameters_swigregister
439 | parameters_swigregister(parameters)
440 |
441 | class ProbMatrixPack(_object):
442 | __swig_setmethods__ = {}
443 | __setattr__ = lambda self, name, value: _swig_setattr(self, ProbMatrixPack, name, value)
444 | __swig_getmethods__ = {}
445 | __getattr__ = lambda self, name: _swig_getattr(self, ProbMatrixPack, name)
446 | __repr__ = _swig_repr
447 | __swig_setmethods__["P"] = _Aono.ProbMatrixPack_P_set
448 | __swig_getmethods__["P"] = _Aono.ProbMatrixPack_P_get
449 | if _newclass:
450 | P = _swig_property(_Aono.ProbMatrixPack_P_get, _Aono.ProbMatrixPack_P_set)
451 | __swig_setmethods__["startPos"] = _Aono.ProbMatrixPack_startPos_set
452 | __swig_getmethods__["startPos"] = _Aono.ProbMatrixPack_startPos_get
453 | if _newclass:
454 | startPos = _swig_property(_Aono.ProbMatrixPack_startPos_get, _Aono.ProbMatrixPack_startPos_set)
455 | __swig_setmethods__["isInitialized"] = _Aono.ProbMatrixPack_isInitialized_set
456 | __swig_getmethods__["isInitialized"] = _Aono.ProbMatrixPack_isInitialized_get
457 | if _newclass:
458 | isInitialized = _swig_property(_Aono.ProbMatrixPack_isInitialized_get, _Aono.ProbMatrixPack_isInitialized_set)
459 |
460 | def __init__(self):
461 | this = _Aono.new_ProbMatrixPack()
462 | try:
463 | self.this.append(this)
464 | except __builtin__.Exception:
465 | self.this = this
466 | __swig_destroy__ = _Aono.delete_ProbMatrixPack
467 | __del__ = lambda self: None
468 | ProbMatrixPack_swigregister = _Aono.ProbMatrixPack_swigregister
469 | ProbMatrixPack_swigregister(ProbMatrixPack)
470 |
471 | class public_key_pack(_object):
472 | __swig_setmethods__ = {}
473 | __setattr__ = lambda self, name, value: _swig_setattr(self, public_key_pack, name, value)
474 | __swig_getmethods__ = {}
475 | __getattr__ = lambda self, name: _swig_getattr(self, public_key_pack, name)
476 | __repr__ = _swig_repr
477 | __swig_setmethods__["A"] = _Aono.public_key_pack_A_set
478 | __swig_getmethods__["A"] = _Aono.public_key_pack_A_get
479 | if _newclass:
480 | A = _swig_property(_Aono.public_key_pack_A_get, _Aono.public_key_pack_A_set)
481 | __swig_setmethods__["P"] = _Aono.public_key_pack_P_set
482 | __swig_getmethods__["P"] = _Aono.public_key_pack_P_get
483 | if _newclass:
484 | P = _swig_property(_Aono.public_key_pack_P_get, _Aono.public_key_pack_P_set)
485 | __swig_setmethods__["n"] = _Aono.public_key_pack_n_set
486 | __swig_getmethods__["n"] = _Aono.public_key_pack_n_get
487 | if _newclass:
488 | n = _swig_property(_Aono.public_key_pack_n_get, _Aono.public_key_pack_n_set)
489 | __swig_setmethods__["s"] = _Aono.public_key_pack_s_set
490 | __swig_getmethods__["s"] = _Aono.public_key_pack_s_get
491 | if _newclass:
492 | s = _swig_property(_Aono.public_key_pack_s_get, _Aono.public_key_pack_s_set)
493 |
494 | def __init__(self):
495 | this = _Aono.new_public_key_pack()
496 | try:
497 | self.this.append(this)
498 | except __builtin__.Exception:
499 | self.this = this
500 | __swig_destroy__ = _Aono.delete_public_key_pack
501 | __del__ = lambda self: None
502 | public_key_pack_swigregister = _Aono.public_key_pack_swigregister
503 | public_key_pack_swigregister(public_key_pack)
504 |
505 | class globalvars(_object):
506 | __swig_setmethods__ = {}
507 | __setattr__ = lambda self, name, value: _swig_setattr(self, globalvars, name, value)
508 | __swig_getmethods__ = {}
509 | __getattr__ = lambda self, name: _swig_getattr(self, globalvars, name)
510 | __repr__ = _swig_repr
511 | __swig_setmethods__["pPack"] = _Aono.globalvars_pPack_set
512 | __swig_getmethods__["pPack"] = _Aono.globalvars_pPack_get
513 | if _newclass:
514 | pPack = _swig_property(_Aono.globalvars_pPack_get, _Aono.globalvars_pPack_set)
515 | __swig_setmethods__["errorsModulo"] = _Aono.globalvars_errorsModulo_set
516 | __swig_getmethods__["errorsModulo"] = _Aono.globalvars_errorsModulo_get
517 | if _newclass:
518 | errorsModulo = _swig_property(_Aono.globalvars_errorsModulo_get, _Aono.globalvars_errorsModulo_set)
519 |
520 | def __init__(self):
521 | this = _Aono.new_globalvars()
522 | try:
523 | self.this.append(this)
524 | except __builtin__.Exception:
525 | self.this = this
526 | __swig_destroy__ = _Aono.delete_globalvars
527 | __del__ = lambda self: None
528 | globalvars_swigregister = _Aono.globalvars_swigregister
529 | globalvars_swigregister(globalvars)
530 |
531 | class cipher_text(_object):
532 | __swig_setmethods__ = {}
533 | __setattr__ = lambda self, name, value: _swig_setattr(self, cipher_text, name, value)
534 | __swig_getmethods__ = {}
535 | __getattr__ = lambda self, name: _swig_getattr(self, cipher_text, name)
536 | __repr__ = _swig_repr
537 | __swig_setmethods__["flag"] = _Aono.cipher_text_flag_set
538 | __swig_getmethods__["flag"] = _Aono.cipher_text_flag_get
539 | if _newclass:
540 | flag = _swig_property(_Aono.cipher_text_flag_get, _Aono.cipher_text_flag_set)
541 | __swig_setmethods__["comp1"] = _Aono.cipher_text_comp1_set
542 | __swig_getmethods__["comp1"] = _Aono.cipher_text_comp1_get
543 | if _newclass:
544 | comp1 = _swig_property(_Aono.cipher_text_comp1_get, _Aono.cipher_text_comp1_set)
545 | __swig_setmethods__["comp2"] = _Aono.cipher_text_comp2_set
546 | __swig_getmethods__["comp2"] = _Aono.cipher_text_comp2_get
547 | if _newclass:
548 | comp2 = _swig_property(_Aono.cipher_text_comp2_get, _Aono.cipher_text_comp2_set)
549 |
550 | def __init__(self):
551 | this = _Aono.new_cipher_text()
552 | try:
553 | self.this.append(this)
554 | except __builtin__.Exception:
555 | self.this = this
556 | __swig_destroy__ = _Aono.delete_cipher_text
557 | __del__ = lambda self: None
558 | cipher_text_swigregister = _Aono.cipher_text_swigregister
559 | cipher_text_swigregister(cipher_text)
560 |
561 | class cipher_text_mult(_object):
562 | __swig_setmethods__ = {}
563 | __setattr__ = lambda self, name, value: _swig_setattr(self, cipher_text_mult, name, value)
564 | __swig_getmethods__ = {}
565 | __getattr__ = lambda self, name: _swig_getattr(self, cipher_text_mult, name)
566 | __repr__ = _swig_repr
567 | __swig_setmethods__["flag"] = _Aono.cipher_text_mult_flag_set
568 | __swig_getmethods__["flag"] = _Aono.cipher_text_mult_flag_get
569 | if _newclass:
570 | flag = _swig_property(_Aono.cipher_text_mult_flag_get, _Aono.cipher_text_mult_flag_set)
571 | __swig_setmethods__["c"] = _Aono.cipher_text_mult_c_set
572 | __swig_getmethods__["c"] = _Aono.cipher_text_mult_c_get
573 | if _newclass:
574 | c = _swig_property(_Aono.cipher_text_mult_c_get, _Aono.cipher_text_mult_c_set)
575 |
576 | def __init__(self):
577 | this = _Aono.new_cipher_text_mult()
578 | try:
579 | self.this.append(this)
580 | except __builtin__.Exception:
581 | self.this = this
582 | __swig_destroy__ = _Aono.delete_cipher_text_mult
583 | __del__ = lambda self: None
584 | cipher_text_mult_swigregister = _Aono.cipher_text_mult_swigregister
585 | cipher_text_mult_swigregister(cipher_text_mult)
586 |
587 |
588 | def get_element(*args):
589 | return _Aono.get_element(*args)
590 | get_element = _Aono.get_element
591 |
592 | def print_GEN(*args):
593 | return _Aono.print_GEN(*args)
594 | print_GEN = _Aono.print_GEN
595 |
596 | def create_GEN(*args):
597 | return _Aono.create_GEN(*args)
598 | create_GEN = _Aono.create_GEN
599 |
600 | def Uniform():
601 | return _Aono.Uniform()
602 | Uniform = _Aono.Uniform
603 |
604 | def Normal():
605 | return _Aono.Normal()
606 | Normal = _Aono.Normal
607 |
608 | def Gauss(mu, sigma):
609 | return _Aono.Gauss(mu, sigma)
610 | Gauss = _Aono.Gauss
611 |
612 | def Sample(n, sigma):
613 | return _Aono.Sample(n, sigma)
614 | Sample = _Aono.Sample
615 |
616 | def generate_random(bit_length):
617 | return _Aono.generate_random(bit_length)
618 | generate_random = _Aono.generate_random
619 |
620 | def getGuassProbability(point, center, params):
621 | return _Aono.getGuassProbability(point, center, params)
622 | getGuassProbability = _Aono.getGuassProbability
623 |
624 | def genProbabilityMatrix(*args):
625 | return _Aono.genProbabilityMatrix(*args)
626 | genProbabilityMatrix = _Aono.genProbabilityMatrix
627 |
628 | def SampleKnuthYao(c, params, g):
629 | return _Aono.SampleKnuthYao(c, params, g)
630 | SampleKnuthYao = _Aono.SampleKnuthYao
631 |
632 | def initialize_sampler(*args):
633 | return _Aono.initialize_sampler(*args)
634 | initialize_sampler = _Aono.initialize_sampler
635 |
636 | def getGENsize(x):
637 | return _Aono.getGENsize(x)
638 | getGENsize = _Aono.getGENsize
639 |
640 | def getGEN_MATRIXsize(x):
641 | return _Aono.getGEN_MATRIXsize(x)
642 | getGEN_MATRIXsize = _Aono.getGEN_MATRIXsize
643 |
644 | def generate_secret_key(*args):
645 | return _Aono.generate_secret_key(*args)
646 | generate_secret_key = _Aono.generate_secret_key
647 |
648 | def generate_public_key(*args):
649 | return _Aono.generate_public_key(*args)
650 | generate_public_key = _Aono.generate_public_key
651 |
652 | def set_error_modulo(g, modulo):
653 | return _Aono.set_error_modulo(g, modulo)
654 | set_error_modulo = _Aono.set_error_modulo
655 |
656 | def access_value_pk(pk, flag):
657 | return _Aono.access_value_pk(pk, flag)
658 | access_value_pk = _Aono.access_value_pk
659 |
660 | def gen_params(arg1, l, n, s, sigma, degree_p):
661 | return _Aono.gen_params(arg1, l, n, s, sigma, degree_p)
662 | gen_params = _Aono.gen_params
663 |
664 | def create_message_matrix_repeated_input(arg1, arg2):
665 | return _Aono.create_message_matrix_repeated_input(arg1, arg2)
666 | create_message_matrix_repeated_input = _Aono.create_message_matrix_repeated_input
667 |
668 | def multiplication(arg1, arg2, arg3):
669 | return _Aono.multiplication(arg1, arg2, arg3)
670 | multiplication = _Aono.multiplication
671 |
672 | def encrypt_outside_class(m, pk, params, g):
673 | return _Aono.encrypt_outside_class(m, pk, params, g)
674 | encrypt_outside_class = _Aono.encrypt_outside_class
675 |
676 | def addition(ct_1, ct_2, params, pk, g):
677 | return _Aono.addition(ct_1, ct_2, params, pk, g)
678 | addition = _Aono.addition
679 |
680 | def subtraction(ct_1, ct_2, params, pk, g):
681 | return _Aono.subtraction(ct_1, ct_2, params, pk, g)
682 | subtraction = _Aono.subtraction
683 |
684 | def create_message_matrix(*args):
685 | return _Aono.create_message_matrix(*args)
686 | create_message_matrix = _Aono.create_message_matrix
687 |
688 | def see_ciphertext(c, index):
689 | return _Aono.see_ciphertext(c, index)
690 | see_ciphertext = _Aono.see_ciphertext
691 |
692 | def power2(x, n, kappa, l, q):
693 | return _Aono.power2(x, n, kappa, l, q)
694 | power2 = _Aono.power2
695 |
696 | def appendmat(m1, m2, col1, col2, row):
697 | return _Aono.appendmat(m1, m2, col1, col2, row)
698 | appendmat = _Aono.appendmat
699 |
700 | def bits(m, kappa, n):
701 | return _Aono.bits(m, kappa, n)
702 | bits = _Aono.bits
703 |
704 | def get_updation_parameters(params_old, n, s):
705 | return _Aono.get_updation_parameters(params_old, n, s)
706 | get_updation_parameters = _Aono.get_updation_parameters
707 |
708 | def plaintext_multiplication(ct, input):
709 | return _Aono.plaintext_multiplication(ct, input)
710 | plaintext_multiplication = _Aono.plaintext_multiplication
711 |
712 | import atexit
713 | pari_init(2000000000, 2)
714 | atexit.register(pari_close)
715 |
716 | class intArray(_object):
717 | __swig_setmethods__ = {}
718 | __setattr__ = lambda self, name, value: _swig_setattr(self, intArray, name, value)
719 | __swig_getmethods__ = {}
720 | __getattr__ = lambda self, name: _swig_getattr(self, intArray, name)
721 | __repr__ = _swig_repr
722 |
723 | def __init__(self, nelements):
724 | this = _Aono.new_intArray(nelements)
725 | try:
726 | self.this.append(this)
727 | except __builtin__.Exception:
728 | self.this = this
729 | __swig_destroy__ = _Aono.delete_intArray
730 | __del__ = lambda self: None
731 |
732 | def __getitem__(self, index):
733 | return _Aono.intArray___getitem__(self, index)
734 |
735 | def __setitem__(self, index, value):
736 | return _Aono.intArray___setitem__(self, index, value)
737 |
738 | def cast(self):
739 | return _Aono.intArray_cast(self)
740 | if _newclass:
741 | frompointer = staticmethod(_Aono.intArray_frompointer)
742 | else:
743 | frompointer = _Aono.intArray_frompointer
744 | intArray_swigregister = _Aono.intArray_swigregister
745 | intArray_swigregister(intArray)
746 |
747 | def intArray_frompointer(t):
748 | return _Aono.intArray_frompointer(t)
749 | intArray_frompointer = _Aono.intArray_frompointer
750 |
751 | # This file is compatible with both classic and new-style classes.
752 |
753 |
754 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # Dockerfile to build PyAono
2 |
3 | FROM alpine:edge
4 |
5 | RUN ["apk", "add", "--no-cache", "musl-dev", "g++", "make", "python3", "python3-dev", "swig"]
6 | # Even after specifying "gmp", we see this warning:
7 | # Your GMP library is incompatible with the compiler settings.
8 | # Building without GNU MP support
9 |
10 | # https://pari.math.u-bordeaux.fr/download.html
11 | RUN wget https://pari.math.u-bordeaux.fr/pub/pari/unix/pari-2.9.3.tar.gz \
12 | && tar -xzf pari-2.9.3.tar.gz \
13 | && cd pari-2.9.3 \
14 | && ./Configure \
15 | && make install
16 |
17 | RUN ["mkdir", "/PyAono"]
18 | COPY . /PyAono
19 | WORKDIR /PyAono
20 |
21 | RUN make compile
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License, Version 2.0 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/
2 |
3 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
4 |
5 | 1. Definitions.
6 |
7 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
8 |
9 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
10 |
11 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
12 |
13 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
14 |
15 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
16 |
17 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
18 |
19 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
20 |
21 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
22 |
23 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
24 |
25 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
26 |
27 | 2. Grant of Copyright License.
28 |
29 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
30 |
31 | 3. Grant of Patent License.
32 |
33 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
34 |
35 | 4. Redistribution.
36 |
37 | You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
38 |
39 | You must give any other recipients of the Work or Derivative Works a copy of this License; and You must cause any modified files to carry prominent notices stating that You changed the files; and You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
40 |
41 | 5. Submission of Contributions.
42 |
43 | Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
44 |
45 | 6. Trademarks.
46 |
47 | This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
48 |
49 | 7. Disclaimer of Warranty.
50 |
51 | Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
52 |
53 | 8. Limitation of Liability.
54 |
55 | In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
56 |
57 | 9. Accepting Warranty or Additional Liability.
58 |
59 | While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
60 |
61 | END OF TERMS AND CONDITIONS
62 |
63 | APPENDIX: How to apply the Apache License to your work
64 |
65 | To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
66 |
67 | Copyright 2017 Open Mined contributors.
68 |
69 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
70 |
71 | http://www.apache.org/licenses/LICENSE-2.0
72 |
73 | Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
74 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: compile_and_test build run dev shell test
2 |
3 | compile:
4 | swig -c++ -python -py3 Aono.i
5 | python3 setup.py install
6 |
7 | test:
8 | python3 tests.py
9 |
10 | compile_and_test: compile
11 | make test
12 |
13 | # Build the Docker environment
14 | build:
15 | docker build -t openmined/pyaono .
16 |
17 | # Run the source code inside the Docker environment
18 | run:
19 | docker run -i -t openmined/pyaono make test
20 |
21 | # Run *my* source code with the Docker environment
22 | dev:
23 | docker run -i -t -v "$(PWD):/PyAono" openmined/pyaono make compile_and_test
24 |
25 | # Open a shell inside the Docker environment, for debugging
26 | shell:
27 | docker run -i -t -v "$(PWD):/PyAono" openmined/pyaono sh
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PyAono [](https://travis-ci.org/OpenMined/PyAono)
2 |
3 | ❗
4 | This library has been deprecated due to changes in strategy and roadmap. To actively contribute based on our current roadmap, checkout [OpenMined](https://github.com/OpenMined/OpenMined), [PySyft](https://github.com/OpenMined/PySyft), or [join our slack](https://openmined.slack.com/messages/team_pysyft)
5 | ---
6 |
7 |
8 | A Python implementation of the homomorphic encryption scheme by Yoshinori Aono et al.
9 |
10 | This scheme was first introduced in the paper - "Fast and Secure Linear Regression and Biometric Authentication with Security Update" by Yoshinori Aono et al. A really unique feature supported by this proposal is the support for key switching. All the code is written in PARI library in C++.
11 |
12 | This code also has an independent header containing a PARI implementation of the Knuth-Yao's Algorithm for sampling from a discrete Gaussian distribution. The paper followed for understanding and implementing the algorithm - High Precision Discrete Gaussian Sampling on FPGAs.
13 |
14 | NOTE : Running the homomorphic multiplication gives a  matrix as opposed to the message being . This is because after homomorphic multiplication, we don't get message but we get .
15 |
16 | ## Running
17 |
18 | 1. Install [Docker](https://www.docker.com/)
19 |
20 | * If you're on macOS and use [Homebrew](https://brew.sh), run `brew cask install docker; open -a docker`
21 |
22 | 2. Run these commands:
23 |
24 | ``` shell
25 | make build
26 | make run
27 | ```
28 |
29 | ## Development
30 |
31 | 1. Install [Docker](https://www.docker.com/)
32 |
33 | * If you're on macOS and use [Homebrew](https://brew.sh), run `brew cask install docker; open -a docker`
34 |
35 | 2. Run `make build`
36 |
37 | 3. Edit source code as you wish
38 |
39 | 4. Run `make dev`
40 |
41 | ## Notes
42 |
43 | ### What's new in the latest version?
44 | We just rolled out the support for key switching/rotation. Check it out by running `init_key_switching.py`. You can also run `init.py` to check out homomorphic operations working.
45 | This scheme has an `advantage` over other schemes that the key switching can both, increase as well as decrease the security level of the ciphertext!
46 |
47 | ### News
48 | New here? Check out our sample tutorial on YouTube recorded by Mayank. The tutorial covers a basic overview of how to use the API. More in-depth tutorials coming soon. Keep checking out YouTube channel and our GitHub repositories.
49 |
50 | ### Contribute
51 | Welcome! If you are intrigued by our work and want to contribute, then please go through the tutorial as mentioned in the `News` section and contact any of the contributors. You should also go through this introductory video by Andrew Trask, of the OpenMined platform.
52 |
53 | ### Difference between Key Rotation and Security Update
54 | `Key Rotation` means that we change ciphertext associated with the key-pair `(pk1, sk1)`, where `pk1` is used to encrypt the message and `sk1` is used to decrypt to message to another ciphertext associated with keypair `(pk2, sk2)`, without decrypting the first ciphertext.
55 | We specifically call it `Key Rotation` when the parameters have this relation ```n1 = n2```.
56 | We call it `Security Update` if the paramters have this relation ```n1 < n2```, meaning that the security of new ciphertext has been updated and increased.
57 |
58 | ### Notes regarding the use and order of homomorphic function and key switching [`Important`]
59 | The following cases of operations have been implemented. Support for other cases might require some more literature reading and will follow shortly. Please take a look at he following options which are presently supported:
60 | #### `NOTE`:
61 | The scheme only supports `ONE` homomorphic multiplication at the moment.
62 | #### `Notations`:
63 | * `normal-ciphertext` means a ciphertext which has never been refreshed via either key rotation or security update and has only been operated additively or has never undergone any operation is just fresh.
64 | * `mult-ciphertext` means a ciphertext which has undergone `ONE` multiplication no matter if it has undergone key rotation or security update before or not. Note that a `mult-ciphertext` `CANNOT` be rotated or refreshed by key rotation or security update because of it's peculiar structure. It has to be decrypted.
65 | * `rotated-ciphertext` means a ciphertext which has undergone refreshment via either key rotation or security update.
66 | #### `NOTE`:
67 | If `+` is supported it implies `-` is permitted as well.
68 | #### `Permitted operations and their outputs`:
69 | * ``` normal-ciphertext + normal-ciphertext = normal-ciphertext``` and ``` normal-ciphertext * normal-ciphertext = mult-ciphertext```
70 | * ```mult-ciphertext + mult-ciphertext = mult-ciphertext```
71 | * ```rotated-ciphertext + rotated-ciphertext = rotated-ciphertext``` and ```rotated-ciphertext * rotated-ciphertext = mult-ciphertext```
72 | * ```rotated-ciphertext + normal-ciphertext = rotated-ciphertext``` and ```rotated-ciphertext * normal-ciphertext = mult-ciphertext```
73 | * ```normal-ciphertext + rotated-ciphertext = rotated-ciphertext``` and ```normal-ciphertext * rotated-ciphertext = mult-ciphertext```
74 | * ```mult-ciphertext + normal-ciphertext = mult-ciphertext``` and ```normal-ciphertext + mult-ciphertext = mult-ciphertext```[?]
75 | * ```mult-ciphertext + rotated-ciphertext = mult-ciphertext``` and ```rotated-ciphertext + mult-ciphertext = mult-ciphertext```[?]
76 |
77 | #### `[?] Meaning`:
78 | The above bullets marked with [?] means that these operations don't exist conventionally in the actual paper. I have implemented them as my own decision given they might come in handy during the course of our project. I implemented them in this way (illustrating just one example, rest are similar to this one):
79 | ```mult-ciphertext + (normal-ciphertext-of-1s * normal-ciphertext) = mult-ciphertext```
80 | `normal-ciphertext-of-1s` mean that it is a ciphertext which is deliberately made my encrypting a vector of just all 1s, so that if it is multiplied with anything (say `x`), this `x` remains same, but since `x` is of type - `normal-ciphertext` and also this `normal-ciphertext-of-1s` is also of the type - `normal-ciphertext`, this means their homomorphic multiplication `*` will yield a ciphertext encrypting `x` of the type - `mult-ciphertext`. This makes the whole above homomorphic addition as ```mult-ciphertext + mult-ciphertext = mult-ciphertext```.
81 |
82 | --------
83 |
84 | ### Importing API
85 | The API can be imported using the command ```import Aono```. It currently supports the following functions and classes:
86 |
87 | --------
88 |
89 | ## Functions Supported:
90 | ### 1. ```pari_init(pari_size, max_prime)```
91 | ```pari_init()``` is the function that needs to be called before dealing with this API. `pari_size` defines the size of stack we'll be using, and `max_prime` defines the pre computed prime table.
92 | #### Arguments: ```pari_size (int)```, ```max_prime (int)```
93 | ### 2. ```pari_close()```
94 | ```pari_close()``` function has to be called at the end of each program to clear the memory used.
95 |
96 | --------
97 |
98 | ## Classes:
99 | ### ```pari_GEN```
100 | This class abstracts the GEN variable in C++, making it available through python interface. The class is compatible with +, *, /, -, __getitem__ , %, and print.
101 | * Class Data:
102 | 1. `value` (`GEN`)
103 |
104 | * ```__init__(self, x)```
105 | The constructor converts x to a GEN variable. Arguments: `x` (`int`)
106 |
107 | ### ```parameters```
108 | * Class Data:
109 | 1. `n`, `s`, `sigma`, `l`, `lambda` (`ints`)
110 | 2. `q`, `p` (`pari_GEN`)
111 |
112 | ### ```secret_key```
113 | * Class Data:
114 | 1. `sk` (`pari_GEN`)
115 | 2. `params` (`parameters*`)
116 |
117 | * ```__init__(self, sk = None, parmas = None)```
118 | The constructor initiates class data.
119 | Arguments: `sk` (`pari_GEN`), `params` (`parameters*`)
120 |
121 | * ```decrypt(self, ct)```
122 | ```decrypt()``` method returns the plaintext (`pari_GEN`) encrypted in ciphertext `ct`. Arguments: `ct` (`pari_GEN`)
123 |
124 | * ```serialize(self)```
125 | TO BE IMPLEMENTED
126 |
127 | ### ```public_key```
128 | * Class Data:
129 | 1. `pk` (`public_key_pack*`)
130 | 2. `params` (`parameters*`)
131 | 3. `g` (`globalvars*`)
132 |
133 | * ```__init__(self, pk = None, params = None, g = None)```
134 | The constructor initiates the class data.
135 | Arguments: `pk` (`public_key_pack*`), `params` (`parameters*`), `g` (`globalvars*`)
136 |
137 | * ```encrypt(self, pt)```
138 | ```encrypt()``` method returns the ciphertext (`GEN`) which encrypts plaintext `pt`.
139 | Arguments: `pt` (`pari_GEN`)
140 |
141 | * ```serialize(self)```
142 | TO BE IMPLEMENTED
143 |
144 | ### ```key_pair```
145 | * Class Data:
146 | 1. `sk` (`secret_key`)
147 | 2. `pk` (`public_key`)
148 |
149 | ### ```key_gen```
150 | * ```generate_key(self, lambda, l, n, s, sigma, degree_p)```
151 | ```generate_key()``` method returns the keys, which is of type `key_pair`. Here `s` defines the tailprune and `degree_p` defines the `bit_size` of `p` to be generated.
152 | Arguments: `lambda` (`int`), `l` (`int`), `n` (`int`), `s` (`int`), `sigma` (`int`), `degree_p` (`int`).
153 |
154 | * ```deserialize(self)```
155 | TO BE IMPLEMENTED
156 |
157 | ### ```ciphertext```
158 | The class is compatible with `’+’, '*', and '-' operators`
159 | * Class Data:
160 | 1. `value` (`pari_GEN`)
161 | 2. `pk` (`public_key*`)
162 | 3. `params` (`parameters*`)
163 |
164 | * ```__init__(self, plaintext = None, pk, params)```
165 | The constuctor method takes two arguments: `plaintext` (`pari_GEN` variable), `pk` (`public_key*`), `params` (`parameters*`)
166 |
167 | TODO - Remove `params`, it can be taken from `pk`.
168 |
169 | * ```decrypt(self, sk)```
170 | ```decrypt()``` method returns the decrypted `ciphertext` which is `pari_GEN` variable.
171 | Arguments: `sk` (`secret_key*`)
172 |
173 | ### ```updation_key```
174 | * Class Data:
175 | 1. `pk` (`public_key_pack*`)
176 | 2. `params` (`parameters*`)
177 | 3. `old_params` (`parameters*`)
178 | 4. `g` (`globalvars*`)
179 | 5. `XComponent` (`pari_GEN`)
180 | 6. `YComponent` (`pari_GEN`)
181 |
182 | * ```__init__(self, X, Y, params, params_old, g, pk)```
183 | The constructor initiates the class data.
184 | Arguments: `pk` (`public_key_pack*`), `params` (`parameters*`), `g` (`globalvars*`)
185 |
186 | * ```cipher_switch(self, ciphertext)```
187 | ```cipher_switch()``` method returns the ciphertext (`ciphertext`) which is obtained by switching the ciphertext passed to function with the updatation key.
188 | Arguments: `ct` (`ciphertext`)
189 |
190 | ### ```updation_key_gen```
191 |
192 | * ```generate_key(self, key_pair*, key_pair*)```
193 | ```generate_key()``` method returns the updation key (`updation_key`) which is the key that can be used to switch any ciphertext which is associated with the first (in order of arguments) `key_pair` to the ciphertext which is associated with the second `key_pair`.
194 | Arguments: `key1` (`key_pair`), `key2` (`key_pair`)
195 |
196 |
197 | --------
198 |
199 | ## TODO:
200 | - [x] Tweaks to homomorphic functions to support rotated or updated ciphertexts.
201 | - [x] Support for plaintext-ciphertext multiplication.
202 | - [x] Basic testing suite.
203 | - [x] Taking care of negative errors by mapping ciphertext to a symmteric group before decryption.
204 | - [x] Add a matrix reading support to testing suite.
205 | - [x] Add key switching tests to testing suite.
206 | - [x] Update README with pari_GEN.
207 | - [ ] Add bootstrapping support.
208 | - [ ] Serialization and Deserialization support.
209 |
210 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
15 | This example illustrates wrapping a simple C++ class to give a Python class. 16 | 17 |
23 |60 | 61 |24 | /* File : example.h */ 25 | 26 | class Shape { 27 | public: 28 | Shape() { 29 | nshapes++; 30 | } 31 | virtual ~Shape() { 32 | nshapes--; 33 | } 34 | double x, y; 35 | void move(double dx, double dy); 36 | virtual double area() = 0; 37 | virtual double perimeter() = 0; 38 | static int nshapes; 39 | }; 40 | 41 | class Circle : public Shape { 42 | private: 43 | double radius; 44 | public: 45 | Circle(double r) : radius(r) { } 46 | virtual double area(); 47 | virtual double perimeter(); 48 | }; 49 | 50 | class Square : public Shape { 51 | private: 52 | double width; 53 | public: 54 | Square(double w) : width(w) { } 55 | virtual double area(); 56 | virtual double perimeter(); 57 | }; 58 |59 |
67 |79 | 80 | Note: when creating a C++ extension, you must run SWIG with the -c++ option like this: 81 |68 | /* File : example.i */ 69 | %module example 70 | 71 | %{ 72 | #include "example.h" 73 | %} 74 | 75 | /* Let's just grab the original header file here */ 76 | %include "example.h" 77 |78 |
82 |86 | 87 |83 | % swig -c++ -python example.i 84 |85 |
97 |101 | 102 |98 | c = example.new_Circle(10.0) 99 |100 |
103 |
107 |112 | 113 |108 | c.x = 15 # Set member data 109 | x = c.x # Get member data 110 |111 |
114 |
117 |121 | 122 |118 | print "The area is ", c.area() 119 |120 |
123 |
del
on the object:
124 |
125 | 126 |130 | 131 |127 | del c # Deletes a shape 128 |129 |
132 |
135 |140 | 141 |136 | n = example.cvar.Shape_nshapes # Get a static data member 137 | example.cvar.Shapes_nshapes = 13 # Set a static data member 138 |139 |