def decrypt(K, s): """AES decryption of s given key schedule K.""" Nr = len(K) - 1 # Nr is 10 or 14 for i in range(Nr, 0, -1): s = mpc.matrix_add(s, K[i]) if i < Nr: s = mpc.matrix_prod(C1, s) s = [s[j][-j:] + s[j][:-j] for j in range(4)] s = [[sbox1(x) for x in _] for _ in s] s = mpc.matrix_add(s, K[0]) return s
def encrypt(K, s): """AES encryption of s given key schedule K.""" Nr = len(K) - 1 # Nr is 10 or 14 s = mpc.matrix_add(s, K[0]) for i in range(1, Nr + 1): s = [[sbox(x) for x in _] for _ in s] s = [s[j][j:] + s[j][:j] for j in range(4)] if i < Nr: s = mpc.matrix_prod(C, s) s = mpc.matrix_add(s, K[i]) return s
async def convolvetensor(x, W, b): logging.info('- - - - - - - - conv2d - - - - - - -') # 2D convolutions on m*n sized images from X with s*s sized filters from W. # b is of dimension v k, r, m, n = dim(x) x = x.tolist() v, r, s, s = dim(W) W = W.tolist() stype = type(x[0][0][0][0]) await mpc.returnType(stype, k, v, m, n) x, W = await mpc.gather(x, W) Y = [[[[b[j]] * m for _ in range(n)] for j in range(v)] for _ in range(k)] counter = 0 for i in range(k): for j in range(v): for l in range(r): counter += 1 if counter % 500 == 0: await mpc.barrier() Y[i][j] = mpc.matrix_add(Y[i][j], inprod2D(x[i][l], W[j][l])) Y = await mpc.gather(Y) for i in range(k): for j in range(v): for im in range(m): Y[i][j][im] = mpc._reshare(Y[i][j][im]) Y = await mpc.gather(Y) if stype.field.frac_length > 0: l = stype.bit_length Y = [[[mpc.trunc(y, l=l) for y in _] for _ in _] for _ in Y] Y = await mpc.gather(Y) return Y
def sharpen_img(image, kernels): """ If we use unpadded_correlation we need to reduce the size of the image """ new_image = image[1:99, 1:99] for kernel in kernels: new_image = mpc.matrix_add(new_image, unpadded_correlation(image, kernel)) new_image = np.array(new_image).flatten() return new_image
async def main(): parser = argparse.ArgumentParser() parser.add_argument('-k', '--order', type=int, metavar='K', help='order K of hash chain, length n=2**K') parser.add_argument('--recursive', action='store_true', help='use recursive pebbler') parser.add_argument('--no-one-way', action='store_true', default=False, help='use dummy one-way function') parser.add_argument('--no-random-seed', action='store_true', default=False, help='use fixed seed') parser.set_defaults(order=1) args = parser.parse_args() await mpc.start() if args.recursive: Pebbler = P else: Pebbler = p IV = [[aes.secfld(3)] * 4] * 4 # IV as 4x4 array of GF(256) elements global f if args.no_one_way: D = aes.circulant_matrix([3, 0, 0, 0]) f = lambda x: mpc.matrix_prod(D, x) else: K = aes.key_expansion(IV) f = lambda x: mpc.matrix_add(aes.encrypt(K, x), x) if args.no_random_seed: x0 = IV else: x0 = [[mpc.random.getrandbits(aes.secfld, 8) for _ in range(4)] for _ in range(4)] k = args.order print(f'Hash chain of length {2**k}:') r = 1 for v in Pebbler(k, x0): if v is None: # initial stage print(f'{r:4}', '-') await mpc.throttler(0.1 ) # raise barrier roughly every 10 AES calls else: # output stage await aes.xprint(f'{r:4} x{2**(k+1) - 1 - r:<4} =', v) r += 1 await mpc.shutdown()
async def main(): global secint parser = argparse.ArgumentParser() parser.add_argument('-b', '--batch-size', type=int, metavar='B', help='number of images to classify') parser.add_argument( '-o', '--offset', type=int, metavar='O', help='offset for batch (otherwise random in [0,10000-B])') parser.add_argument( '-d', '--d-k-star', type=int, metavar='D', help='k=D=0,1,2 for Legendre-based comparison using d_k^*') parser.add_argument('--no-legendre', action='store_true', help='disable Legendre-based comparison') parser.add_argument('--no-vectorization', action='store_true', help='disable vectorization of comparisons') parser.set_defaults(batch_size=1, offset=-1, d_k_star=1) args = parser.parse_args() batch_size = args.batch_size offset = args.offset if args.no_legendre: secint = mpc.SecInt(14) # using vectorized MPyC integer comparison else: if args.d_k_star == 0: secint = mpc.SecInt( 14, p=3546374752298322551) # Legendre-0 range [-134, 134] bsgn = bsgn_0 vector_bsgn = vector_bsgn_0 elif args.d_k_star == 1: secint = mpc.SecInt( 14, p=9409569905028393239) # Legendre-1 range [-383, 383] bsgn = bsgn_1 vector_bsgn = vector_bsgn_1 else: secint = mpc.SecInt( 14, p=15569949805843283171) # Legendre-2 range [-594, 594] bsgn = bsgn_2 vector_bsgn = vector_bsgn_2 one_by_one = args.no_vectorization await mpc.start() if offset < 0: offset = random.randrange(10001 - batch_size) if mpc.pid == 0 else None offset = await mpc.transfer(offset, senders=0) logging.info('--------------- INPUT -------------') print( f'Type = {secint.__name__}, range = ({offset}, {offset + batch_size})') # read batch_size labels and images at given offset df = gzip.open(os.path.join('data', 'cnn', 't10k-labels-idx1-ubyte.gz')) d = df.read()[8 + offset:8 + offset + batch_size] labels = list(map(int, d)) print('Labels:', labels) df = gzip.open(os.path.join('data', 'cnn', 't10k-images-idx3-ubyte.gz')) d = df.read()[16 + offset * 28**2:16 + (offset + batch_size) * 28**2] L = np.array(list(d)).reshape(batch_size, 28**2) if batch_size == 1: x = np.array(L[0]).reshape(28, 28) print( np.array2string(np.vectorize(lambda a: int(bool((a / 255))))(x), separator='')) L = np.vectorize(lambda a: secint(int(a)))(L).tolist() logging.info('--------------- LAYER 1 -------------') logging.info('- - - - - - - - fc - - - - - - -') L = mpc.matrix_prod(L, load_W('fc1')) L = mpc.matrix_add(L, [load_b('fc1')] * len(L)) logging.info('- - - - - - - - bsgn - - - - - - -') if one_by_one: L = np.vectorize(lambda a: (a >= 0) * 2 - 1)(L).tolist() else: L = [vector_sge(_) for _ in L] await mpc.barrier() logging.info('--------------- LAYER 2 -------------') logging.info('- - - - - - - - fc - - - - - - -') L = mpc.matrix_prod(L, load_W('fc2')) L = mpc.matrix_add(L, [load_b('fc2')] * len(L)) await mpc.barrier() logging.info('- - - - - - - - bsgn - - - - - - -') if args.no_legendre: secint.bit_length = 10 if one_by_one: activate = np.vectorize(lambda a: (a >= 0) * 2 - 1) L = activate(L).tolist() else: L = [vector_sge(_) for _ in L] else: if one_by_one: activate = np.vectorize(bsgn) L = activate(L).tolist() else: L = [vector_bsgn(_) for _ in L] await mpc.barrier() logging.info('--------------- LAYER 3 -------------') logging.info('- - - - - - - - fc - - - - - - -') L = mpc.matrix_prod(L, load_W('fc3')) L = mpc.matrix_add(L, [load_b('fc3')] * len(L)) await mpc.barrier() logging.info('- - - - - - - - bsgn - - - - - - -') if args.no_legendre: secint.bit_length = 10 if one_by_one: activate = np.vectorize(lambda a: (a >= 0) * 2 - 1) L = activate(L).tolist() else: L = [vector_sge(_) for _ in L] else: if one_by_one: activate = np.vectorize(bsgn) L = activate(L).tolist() else: L = [vector_bsgn(_) for _ in L] await mpc.barrier() logging.info('--------------- LAYER 4 -------------') logging.info('- - - - - - - - fc - - - - - - -') L = mpc.matrix_prod(L, load_W('fc4')) L = mpc.matrix_add(L, [load_b('fc4')] * len(L)) await mpc.barrier() logging.info('--------------- OUTPUT -------------') if args.no_legendre: secint.bit_length = 14 for i in range(batch_size): prediction = await mpc.output(mpc.argmax(L[i])[0]) error = '******* ERROR *******' if prediction != labels[i] else '' print( f'Image #{offset+i} with label {labels[i]}: {prediction} predicted. {error}' ) print(await mpc.output(L[i])) await mpc.shutdown()