python/TimeMPIN_ZZZ.py.in (322 lines of code) (raw):

#!/usr/bin/env python3 """ Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you 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 http://www.apache.org/licenses/LICENSE-2.0 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. """ import json import sys import timeit import warnings import mpin_ZZZ warnings.filterwarnings("ignore") def time_func(stmt, n=10, setup='from __main__ import *'): t = timeit.Timer(stmt, setup) total_time = t.timeit(n) iter_time = total_time / n iter_per_sec = n / total_time print("func:{} nIter:{} total_time:{} iter_time:{} iter_per_sec: %s".format( stmt, n, total_time, iter_time, iter_per_sec)) nIter = 100 if __name__ == "__main__": # Print hex values DEBUG = False ONE_PASS = False TIME_PERMITS = True MPIN_FULL = True PIN_ERROR = True if TIME_PERMITS: date = mpin_ZZZ.today() else: date = 0 # Seed seedHex = "b75e7857fa17498c333d3c8d42e10f8c3cb8a66f7a84d85f86cd5acb537fa211" seed = seedHex.decode("hex") # random number generator rng = mpin_ZZZ.create_csprng(seed) # Identity mpin_id = "alice@milagro.com" # Hash mpin_id hash_mpin_id = mpin_ZZZ.hash_id(mpin_ZZZ.HASH_TYPE_ZZZ, mpin_id) if DEBUG: print("mpin_id: {}".format(mpin_id.hex())) print("hash_mpin_id: {}".format(hash_mpin_id.hex())) mpin_id = mpin_id # Generate master secret for MILAGRO and Customer time_func('rtn, ms1 = mpin_ZZZ.random_generate(rng)', nIter) rtn, ms1 = mpin_ZZZ.random_generate(rng) if rtn != 0: print("random_generate(rng) Error {}".format(rtn)) rtn, ms2 = mpin_ZZZ.random_generate(rng) if rtn != 0: print("random_generate(rng) Error {}".format(rtn)) if DEBUG: print("ms1: {}".format(ms1.hex()) print("ms2: {}".format(ms2.hex()) # Generate server secret shares time_func('rtn, ss1 = mpin_ZZZ.get_server_secret(ms1)', nIter) rtn, ss1=mpin_ZZZ.get_server_secret(ms1) if rtn != 0: print("get_server_secret(ms1) Error {}".format(rtn)) rtn, ss2=mpin_ZZZ.get_server_secret(ms2) if rtn != 0: print("get_server_secret(ms2) Error {}".format(rtn)) if DEBUG: print("ss1: {}".format(ss1.hex())) print("ss2: {}".format(ss2.hex())) # Combine server secret shares time_func('rtn, server_secret = mpin_ZZZ.recombine_G2(ss1, ss2)', nIter) rtn, server_secret=mpin_ZZZ.recombine_G2(ss1, ss2) if rtn != 0: print("recombine_G2(ss1, ss2) Error {}".format(rtn)) if DEBUG: print("server_secret: {}".format(mpin_ZZZ.server_secret.hex())) # Generate client secret shares time_func('rtn, cs1 = mpin_ZZZ.get_client_secret(ms1, hash_mpin_id)', nIter) rtn, cs1=mpin_ZZZ.get_client_secret(ms1, hash_mpin_id) if rtn != 0: print("get_client_secret(ms1, hash_mpin_id) Error {}".format(rtn)) rtn, cs2=mpin_ZZZ.get_client_secret(ms2, hash_mpin_id) if rtn != 0: print("get_client_secret(ms2, hash_mpin_id) Error {}".format(rtn)) if DEBUG: print("cs1: {}".format(cs1.hex())) print("cs2: {}".format(cs2.hex())) # Combine client secret shares time_func('rtn, client_secret = mpin_ZZZ.recombine_G1(cs1, cs2)', nIter) rtn, client_secret=mpin_ZZZ.recombine_G1(cs1, cs2) if rtn != 0: print("recombine_G1(cs1, cs2) Error {}".format(rtn)) print("Client Secret: {}".format(client_secret.hex())) # Generate Time Permit shares if DEBUG: print("Date {}".format(date)) time_func( 'rtn, tp1 = mpin_ZZZ.get_client_permit(mpin_ZZZ.HASH_TYPE_ZZZ, date, ms1, hash_mpin_id)', nIter) rtn, tp1=mpin_ZZZ.get_client_permit( mpin_ZZZ.HASH_TYPE_ZZZ, date, ms1, hash_mpin_id) if rtn != 0: print("get_client_permit(mpin_ZZZ.HASH_TYPE_ZZZ, date, ms1, hash_mpin_id) Error {}".format(rtn)) rtn, tp2=mpin_ZZZ.get_client_permit( mpin_ZZZ.HASH_TYPE_ZZZ, date, ms2, hash_mpin_id) if rtn != 0: print("get_client_permit(mpin_ZZZ.HASH_TYPE_ZZZ, date, ms2, hash_mpin_id) Error {}".format(rtn)) if DEBUG: print("tp1: {}".format(tp1.hex())) print("tp2: {}".format(tp2.hex())) # Combine Time Permit shares rtn, time_permit=mpin_ZZZ.recombine_G1(tp1, tp2) if rtn != 0: print("recombine_G1(tp1, tp2) Error {}".format(rtn)) if DEBUG: print("time_permit: {}".format(time_permit.hex())) # Client extracts PIN from secret to create Token PIN=1234 time_func( 'rtn, token = mpin_ZZZ.extract_pin(mpin_ZZZ.HASH_TYPE_ZZZ, mpin_id, PIN, client_secret)', nIter) rtn, token=mpin_ZZZ.extract_pin( mpin_ZZZ.HASH_TYPE_ZZZ, mpin_id, PIN, client_secret) if rtn != 0: print( "extract_pin(mpin_ZZZ.HASH_TYPE_ZZZ, mpin_id, PIN, token) Error {}".format(rtn)) print("Token: {}".format(token.hex()) if ONE_PASS: print("M-Pin One Pass") PIN=1234 time_func('epoch_time = mpin_ZZZ.get_time()', nIter) epoch_time=mpin_ZZZ.get_time() if DEBUG: print("epoch_time {}".format(epoch_time)) # Client precomputation if MPIN_FULL: time_func( 'rtn, pc1, pc2 = mpin_ZZZ.precompute(token, hash_mpin_id)', nIter) rtn, pc1, pc2=mpin_ZZZ.precompute(token, hash_mpin_id) # Client MPIN time_func( 'rtn, x, u, ut, v, y = mpin_ZZZ.client(mpin_ZZZ.HASH_TYPE_ZZZ, date, mpin_id, rng, None, PIN, token, time_permit, None, epoch_time)', nIter) rtn, x, u, ut, v, y=mpin_ZZZ.client( mpin_ZZZ.HASH_TYPE_ZZZ, date, mpin_id, rng, None, PIN, token, time_permit, None, epoch_time) if rtn != 0: print("MPIN_CLIENT ERROR {}".format(rtn)) # Client sends Z=r.ID to Server if MPIN_FULL: time_func( 'rtn, r, Z = mpin_ZZZ.get_G1_multiple(rng, 1, None, hash_mpin_id)', nIter) rtn, r, Z=mpin_ZZZ.get_G1_multiple(rng, 1, None, hash_mpin_id) # Server MPIN time_func( 'rtn, HID, HTID, E, F, y2 = mpin_ZZZ.server(mpin_ZZZ.HASH_TYPE_ZZZ, date, server_secret, u, ut, v, mpin_id, None, epoch_time, None)', nIter) rtn, HID, HTID, E, F, y2=mpin_ZZZ.server( mpin_ZZZ.HASH_TYPE_ZZZ, date, server_secret, u, ut, v, mpin_id, None, epoch_time, None) if DEBUG: print("y2 ", y2.hex()) if rtn != 0: print("ERROR: {} is not authenticated".format(mpin_id)) if PIN_ERROR: time_func('err = mpin_ZZZ.kangaroo(E, F)', nIter) err=mpin_ZZZ.kangaroo(E, F) print("Client PIN error {} ".format(err)) raise SystemExit(0) else: print("SUCCESS: {} is authenticated".format(mpin_id)) if date: prHID=HTID else: prHID=HID ut=None # Server sends T=w.ID to client if MPIN_FULL: time_func( 'rtn, w, T = mpin_ZZZ.get_G1_multiple(rng, 0, None, prHID)', nIter) rtn, w, T=mpin_ZZZ.get_G1_multiple(rng, 0, None, prHID) if rtn != 0: print("ERROR: Generating T {}".format(rtn)) if MPIN_FULL: time_func( 'HM = mpin_ZZZ.hash_all(mpin_ZZZ.HASH_TYPE_ZZZ, hash_mpin_id, u, ut, v, y, Z, T)', nIter) HM=mpin_ZZZ.hash_all( mpin_ZZZ.HASH_TYPE_ZZZ, hash_mpin_id, u, ut, v, y, Z, T) time_func( 'rtn, client_aes_key = mpin_ZZZ.client_key(mpin_ZZZ.HASH_TYPE_ZZZ, pc1, pc2, PIN, r, x, HM, T)', nIter) rtn, client_aes_key=mpin_ZZZ.client_key( mpin_ZZZ.HASH_TYPE_ZZZ, pc1, pc2, PIN, r, x, HM, T) if rtn != 0: print("ERROR: Generating client_aes_key {}".format(rtn)) print("Client AES Key: {}".format(client_aes_key.hex())) rtn, server_aes_key=mpin_ZZZ.server_key( mpin_ZZZ.HASH_TYPE_ZZZ, Z, server_secret, w, HM, HID, u, ut) if rtn != 0: print("ERROR: Generating server_aes_key {}".format(rtn)) print("Server AES Key: {}".format(server_aes_key.hex())) else: print("M-Pin Three Pass") PIN=1234 if MPIN_FULL: time_func( 'rtn, pc1, pc2 = mpin_ZZZ.precompute(token, hash_mpin_id)', nIter) rtn, pc1, pc2=mpin_ZZZ.precompute(token, hash_mpin_id) if rtn != 0: print("precompute(token, hash_mpin_id) ERROR {}".format(rtn)) # Client first pass time_func( 'rtn, x, u, ut, sec = mpin_ZZZ.client_1(mpin_ZZZ.HASH_TYPE_ZZZ, date, mpin_id, rng, None, PIN, token, time_permit)', nIter) rtn, x, u, ut, sec=mpin_ZZZ.client_1( mpin_ZZZ.HASH_TYPE_ZZZ, date, mpin_id, rng, None, PIN, token, time_permit) if rtn != 0: print("client_1 ERROR {}".format(rtn)) if DEBUG: print("x: {}".format(x.hex())) # Server calculates H(ID) and H(T|H(ID)) (if time permits enabled), # and maps them to points on the curve HID and HTID resp. time_func( 'HID, HTID = mpin_ZZZ.server_1(mpin_ZZZ.HASH_TYPE_ZZZ, date, mpin_id)', nIter) HID, HTID=mpin_ZZZ.server_1(mpin_ZZZ.HASH_TYPE_ZZZ, date, mpin_id) # Server generates Random number y and sends it to Client time_func('rtn, y = mpin_ZZZ.random_generate(rng)', nIter) rtn, y=mpin_ZZZ.random_generate(rng) if rtn != 0: print("random_generate(rng) Error {}".format(rtn)) # Client second pass time_func('rtn, v = mpin_ZZZ.client_2(x, y, sec)', nIter) rtn, v=mpin_ZZZ.client_2(x, y, sec) if rtn != 0: print("client_2(x, y, sec) Error {}".format(rtn)) # Server second pass time_func( 'rtn, E, F = mpin_ZZZ.server_2(date, HID, HTID, y, server_secret, u, ut, v, None)', nIter) rtn, E, F=mpin_ZZZ.server_2( date, HID, HTID, y, server_secret, u, ut, v, None) if rtn != 0: print("ERROR: {} is not authenticated".format(mpin_id)) if PIN_ERROR: time_func('err = mpin_ZZZ.kangaroo(E, F)', nIter) err=mpin_ZZZ.kangaroo(E, F) print("Client PIN error {} ".format(err)) raise SystemExit(0) else: print("SUCCESS: {} is authenticated".format(mpin_id)) # Client sends Z=r.ID to Server if MPIN_FULL: rtn, r, Z=mpin_ZZZ.get_G1_multiple(rng, 1, None, hash_mpin_id) if rtn != 0: print("ERROR: Generating Z {}".format(rtn)) if date: prHID=HTID else: prHID=HID ut=None # Server sends T=w.ID to client if MPIN_FULL: time_func( 'rtn, w, T = mpin_ZZZ.get_G1_multiple(rng, 0, None, prHID)', nIter) rtn, w, T=mpin_ZZZ.get_G1_multiple(rng, 0, None, prHID) if rtn != 0: print("ERROR: Generating T {}".format(rtn)) time_func( 'HM = mpin_ZZZ.hash_all(mpin_ZZZ.HASH_TYPE_ZZZ, hash_mpin_id, u, ut, v, y, Z, T)', nIter) HM=mpin_ZZZ.hash_all( mpin_ZZZ.HASH_TYPE_ZZZ, hash_mpin_id, u, ut, v, y, Z, T) time_func( 'rtn, client_aes_key = mpin_ZZZ.client_key(mpin_ZZZ.HASH_TYPE_ZZZ, pc1, pc2, PIN, r, x, HM, T)', nIter) rtn, client_aes_key=mpin_ZZZ.client_key( mpin_ZZZ.HASH_TYPE_ZZZ, pc1, pc2, PIN, r, x, HM, T) if rtn != 0: print("ERROR: Generating client_aes_key {}".format(rtn)) print("Client AES Key: {}".format(client_aes_key.hex())) time_func( 'rtn, server_aes_key = mpin_ZZZ.server_key(mpin_ZZZ.HASH_TYPE_ZZZ, Z, server_secret, w, HM, HID, u, ut)', nIter) rtn, server_aes_key=mpin_ZZZ.server_key( mpin_ZZZ.HASH_TYPE_ZZZ, Z, server_secret, w, HM, HID, u, ut) if rtn != 0: print("ERROR: Generating server_aes_key {}".format(rtn)) print("Server AES Key: {}".format(server_aes_key.hex())) if MPIN_FULL: plaintext="A test message" print("message to encrypt: ", plaintext) header_hex="1554a69ecbf04e507eb6985a234613246206c85f8af73e61ab6e2382a26f457d" header=header_hex.decode("hex") iv_hex="2b213af6b0edf6972bf996fb" iv=iv_hex.decode("hex") time_func( 'ciphertext, tag = mpin_ZZZ.aes_gcm_encrypt(client_aes_key, iv, header, plaintext)', nIter) ciphertext, tag=mpin_ZZZ.aes_gcm_encrypt( client_aes_key, iv, header, plaintext) print("ciphertext ", ciphertext.hex()) print("tag1 ", tag.hex()) time_func( 'plaintext2, tag2 = mpin_ZZZ.aes_gcm_decrypt(server_aes_key, iv, header, ciphertext)', nIter) plaintext2, tag2=mpin_ZZZ.aes_gcm_decrypt( server_aes_key, iv, header, ciphertext) print("decrypted message: ".format(plaintext2)) print("tag2 {}".format(tag2.hex()))