http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/pythonCFFI/TestMPINInstall.py ---------------------------------------------------------------------- diff --git a/pythonCFFI/TestMPINInstall.py b/pythonCFFI/TestMPINInstall.py deleted file mode 100755 index 3c36c55..0000000 --- a/pythonCFFI/TestMPINInstall.py +++ /dev/null @@ -1,703 +0,0 @@ -#!/usr/bin/env python - -""" -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 os -import unittest -import json -import hashlib - -from mpin import ffi, G1, G2, HASH_BYTES, IVL, libmpin, PAS, PFS, PGS, toHex - -# Master Secret Shares -MS1 = ffi.new("octet*") -MS1val = ffi.new("char []", PGS) -MS1[0].val = MS1val -MS1[0].max = PGS -MS1[0].len = PGS - -MS2 = ffi.new("octet*") -MS2val = ffi.new("char []", PGS) -MS2[0].val = MS2val -MS2[0].max = PGS -MS2[0].len = PGS - -# Client secret and shares -CS1 = ffi.new("octet*") -CS1val = ffi.new("char []", G1) -CS1[0].val = CS1val -CS1[0].max = G1 -CS1[0].len = G1 - -CS2 = ffi.new("octet*") -CS2val = ffi.new("char []", G1) -CS2[0].val = CS2val -CS2[0].max = G1 -CS2[0].len = G1 - -SEC = ffi.new("octet*") -SECval = ffi.new("char []", G1) -SEC[0].val = SECval -SEC[0].max = G1 -SEC[0].len = G1 - -# Server secret and shares -SS1 = ffi.new("octet*") -SS1val = ffi.new("char []", G2) -SS1[0].val = SS1val -SS1[0].max = G2 -SS1[0].len = G2 - -SS2 = ffi.new("octet*") -SS2val = ffi.new("char []", G2) -SS2[0].val = SS2val -SS2[0].max = G2 -SS2[0].len = G2 - -SERVER_SECRET = ffi.new("octet*") -SERVER_SECRETval = ffi.new("char []", G2) -SERVER_SECRET[0].val = SERVER_SECRETval -SERVER_SECRET[0].max = G2 -SERVER_SECRET[0].len = G2 - -# Time Permit and shares -TP1 = ffi.new("octet*") -TP1val = ffi.new("char []", G1) -TP1[0].val = TP1val -TP1[0].max = G1 -TP1[0].len = G1 - -TP2 = ffi.new("octet*") -TP2val = ffi.new("char []", G1) -TP2[0].val = TP2val -TP2[0].max = G1 -TP2[0].len = G1 - -TIME_PERMIT = ffi.new("octet*") -TIME_PERMITval = ffi.new("char []", G1) -TIME_PERMIT[0].val = TIME_PERMITval -TIME_PERMIT[0].max = G1 -TIME_PERMIT[0].len = G1 - -# Token stored on computer -TOKEN = ffi.new("octet*") -TOKENval = ffi.new("char []", G1) -TOKEN[0].val = TOKENval -TOKEN[0].max = G1 -TOKEN[0].len = G1 - -UT = ffi.new("octet*") -UTval = ffi.new("char []", G1) -UT[0].val = UTval -UT[0].max = G1 -UT[0].len = G1 - -U = ffi.new("octet*") -Uval = ffi.new("char []", G1) -U[0].val = Uval -U[0].max = G1 -U[0].len = G1 - -X = ffi.new("octet*") -Xval = ffi.new("char []", PGS) -X[0].val = Xval -X[0].max = PGS -X[0].len = PGS - -Y = ffi.new("octet*") -Yval = ffi.new("char []", PGS) -Y[0].val = Yval -Y[0].max = PGS -Y[0].len = PGS - -lenEF = 12 * PFS -E = ffi.new("octet*") -Eval = ffi.new("char []", lenEF) -E[0].val = Eval -E[0].max = lenEF -E[0].len = lenEF - -F = ffi.new("octet*") -Fval = ffi.new("char []", lenEF) -F[0].val = Fval -F[0].max = lenEF -F[0].len = lenEF - -# H(ID) -HID = ffi.new("octet*") -HIDval = ffi.new("char []", G1) -HID[0].val = HIDval -HID[0].max = G1 -HID[0].len = G1 - -# H(T|H(ID)) -HTID = ffi.new("octet*") -HTIDval = ffi.new("char []", G1) -HTID[0].val = HTIDval -HTID[0].max = G1 -HTID[0].len = G1 - - -class TestMPIN(unittest.TestCase): - """Tests M-Pin crypto code""" - - def setUp(self): - - # Form MPin ID - endUserData = { - "issued": "2013-10-19T06:12:28Z", - "userID": "[email protected]", - "mobile": 1, - "salt": "e985da112a378c222cfc2f7226097b0c" - } - mpin_id = json.dumps(endUserData) - - self.MPIN_ID = ffi.new("octet*") - self.MPIN_IDval = ffi.new("char [%s]" % len(mpin_id), mpin_id) - self.MPIN_ID[0].val = self.MPIN_IDval - self.MPIN_ID[0].max = len(mpin_id) - self.MPIN_ID[0].len = len(mpin_id) - - # Hash value of MPIN_ID - self.HASH_MPIN_ID = ffi.new("octet*") - self.HASH_MPIN_IDval = ffi.new("char []", HASH_BYTES) - self.HASH_MPIN_ID[0].val = self.HASH_MPIN_IDval - self.HASH_MPIN_ID[0].max = HASH_BYTES - self.HASH_MPIN_ID[0].len = HASH_BYTES - libmpin.MPIN_HASH_ID(self.MPIN_ID, self.HASH_MPIN_ID) - - # Assign a seed value - seedHex = "3ade3d4a5c698e8910bf92f25d97ceeb7c25ed838901a5cb5db2cf25434c1fe76c7f79b7af2e5e1e4988e4294dbd9bd9fa3960197fb7aec373609fb890d74b16a4b14b2ae7e23b75f15d36c21791272372863c4f8af39980283ae69a79cf4e48e908f9e0" - self.seed = seedHex.decode("hex") - self.RAW = ffi.new("octet*") - self.RAWval = ffi.new("char [%s]" % len(self.seed), self.seed) - self.RAW[0].val = self.RAWval - self.RAW[0].len = len(self.seed) - self.RAW[0].max = len(self.seed) - - self.date = 16238 - - def test_1(self): - """test_1 Good PIN and good token""" - PIN1 = 1234 - PIN2 = 1234 - - # random number generator - RNG = ffi.new("csprng*") - libmpin.MPIN_CREATE_CSPRNG(RNG, self.RAW) - - # Generate Client master secret share for MIRACL and Customer - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS1) - self.assertEqual(rtn, 0) - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS2) - self.assertEqual(rtn, 0) - - # Generate server secret shares - rtn = libmpin.MPIN_GET_SERVER_SECRET(MS1, SS1) - self.assertEqual(rtn, 0) - rtn = libmpin.MPIN_GET_SERVER_SECRET(MS2, SS2) - self.assertEqual(rtn, 0) - - # Combine server secret shares - rtn = libmpin.MPIN_RECOMBINE_G2(SS1, SS2, SERVER_SECRET) - self.assertEqual(rtn, 0) - - # Generate client secret shares - rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS1, self.HASH_MPIN_ID, CS1) - self.assertEqual(rtn, 0) - rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS2, self.HASH_MPIN_ID, CS2) - self.assertEqual(rtn, 0) - - # Combine client secret shares : TOKEN is the full client secret - rtn = libmpin.MPIN_RECOMBINE_G1(CS1, CS2, TOKEN) - self.assertEqual(rtn, 0) - - # Generate Time Permit shares - rtn = libmpin.MPIN_GET_CLIENT_PERMIT(self.date, MS1, self.HASH_MPIN_ID, TP1) - self.assertEqual(rtn, 0) - rtn = libmpin.MPIN_GET_CLIENT_PERMIT(self.date, MS2, self.HASH_MPIN_ID, TP2) - self.assertEqual(rtn, 0) - - # Combine Time Permit shares - rtn = libmpin.MPIN_RECOMBINE_G1(TP1, TP2, TIME_PERMIT) - self.assertEqual(rtn, 0) - - # Client extracts PIN from secret to create Token - PIN1 = 1234 - rtn = libmpin.MPIN_EXTRACT_PIN(self.MPIN_ID, PIN1, TOKEN) - self.assertEqual(rtn, 0) - - # Client first pass - rtn = libmpin.MPIN_CLIENT_1(self.date, self.MPIN_ID, RNG, X, PIN2, TOKEN, SEC, U, UT, TIME_PERMIT) - self.assertEqual(rtn, 0) - - # Server calculates H(ID) and H(T|H(ID)) - libmpin.MPIN_SERVER_1(self.date, self.MPIN_ID, HID, HTID) - - # Server generates Random number Y and sends it to Client - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, Y) - self.assertEqual(rtn, 0) - - # Client second pass - rtn = libmpin.MPIN_CLIENT_2(X, Y, SEC) - self.assertEqual(rtn, 0) - - # Server second pass - rtn = libmpin.MPIN_SERVER_2(self.date, HID, HTID, Y, SERVER_SECRET, U, UT, SEC, E, F) - self.assertEqual(rtn, 0) - - def test_2(self): - """test_2 Bad PIN and good token""" - PIN1 = 1234 - PIN2 = 2000 - - # random number generator - RNG = ffi.new("csprng*") - libmpin.MPIN_CREATE_CSPRNG(RNG, self.RAW) - - # Generate Client master secret share for MIRACL and Customer - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS1) - self.assertEqual(rtn, 0) - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS2) - self.assertEqual(rtn, 0) - - # Generate server secret shares - rtn = libmpin.MPIN_GET_SERVER_SECRET(MS1, SS1) - self.assertEqual(rtn, 0) - rtn = libmpin.MPIN_GET_SERVER_SECRET(MS2, SS2) - self.assertEqual(rtn, 0) - - # Combine server secret shares - rtn = libmpin.MPIN_RECOMBINE_G2(SS1, SS2, SERVER_SECRET) - self.assertEqual(rtn, 0) - - # Generate client secret shares - rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS1, self.HASH_MPIN_ID, CS1) - self.assertEqual(rtn, 0) - rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS2, self.HASH_MPIN_ID, CS2) - self.assertEqual(rtn, 0) - - # Combine client secret shares : TOKEN is the full client secret - rtn = libmpin.MPIN_RECOMBINE_G1(CS1, CS2, TOKEN) - self.assertEqual(rtn, 0) - - # Generate Time Permit shares - rtn = libmpin.MPIN_GET_CLIENT_PERMIT(self.date, MS1, self.HASH_MPIN_ID, TP1) - self.assertEqual(rtn, 0) - rtn = libmpin.MPIN_GET_CLIENT_PERMIT(self.date, MS2, self.HASH_MPIN_ID, TP2) - self.assertEqual(rtn, 0) - - # Combine Time Permit shares - rtn = libmpin.MPIN_RECOMBINE_G1(TP1, TP2, TIME_PERMIT) - self.assertEqual(rtn, 0) - - # Client extracts PIN from secret to create Token - PIN1 = 1234 - rtn = libmpin.MPIN_EXTRACT_PIN(self.MPIN_ID, PIN1, TOKEN) - self.assertEqual(rtn, 0) - - # Client first pass - rtn = libmpin.MPIN_CLIENT_1(self.date, self.MPIN_ID, RNG, X, PIN2, TOKEN, SEC, U, UT, TIME_PERMIT) - self.assertEqual(rtn, 0) - - # Server calculates H(ID) and H(T|H(ID)) - libmpin.MPIN_SERVER_1(self.date, self.MPIN_ID, HID, HTID) - - # Server generates Random number Y and sends it to Client - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, Y) - self.assertEqual(rtn, 0) - - # Client second pass - rtn = libmpin.MPIN_CLIENT_2(X, Y, SEC) - self.assertEqual(rtn, 0) - - # Server second pass - rtn = libmpin.MPIN_SERVER_2(self.date, HID, HTID, Y, SERVER_SECRET, U, UT, SEC, E, F) - self.assertEqual(rtn, -19) - - def test_3(self): - """test_3 Good PIN and bad token""" - PIN1 = 1234 - PIN2 = 1234 - - # random number generator - RNG = ffi.new("csprng*") - libmpin.MPIN_CREATE_CSPRNG(RNG, self.RAW) - - # Generate Client master secret share for MIRACL and Customer - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS1) - self.assertEqual(rtn, 0) - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS2) - self.assertEqual(rtn, 0) - - # Generate server secret shares - rtn = libmpin.MPIN_GET_SERVER_SECRET(MS1, SS1) - self.assertEqual(rtn, 0) - rtn = libmpin.MPIN_GET_SERVER_SECRET(MS2, SS2) - self.assertEqual(rtn, 0) - - # Combine server secret shares - rtn = libmpin.MPIN_RECOMBINE_G2(SS1, SS2, SERVER_SECRET) - self.assertEqual(rtn, 0) - - # Generate client secret shares - rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS1, self.HASH_MPIN_ID, CS1) - self.assertEqual(rtn, 0) - rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS2, self.HASH_MPIN_ID, CS2) - self.assertEqual(rtn, 0) - - # Combine client secret shares : TOKEN is the full client secret - rtn = libmpin.MPIN_RECOMBINE_G1(CS1, CS2, TOKEN) - self.assertEqual(rtn, 0) - - # Generate Time Permit shares - rtn = libmpin.MPIN_GET_CLIENT_PERMIT(self.date, MS1, self.HASH_MPIN_ID, TP1) - self.assertEqual(rtn, 0) - rtn = libmpin.MPIN_GET_CLIENT_PERMIT(self.date, MS2, self.HASH_MPIN_ID, TP2) - self.assertEqual(rtn, 0) - - # Combine Time Permit shares - rtn = libmpin.MPIN_RECOMBINE_G1(TP1, TP2, TIME_PERMIT) - self.assertEqual(rtn, 0) - - # Client extracts PIN from secret to create Token - PIN1 = 1234 - rtn = libmpin.MPIN_EXTRACT_PIN(self.MPIN_ID, PIN1, TOKEN) - self.assertEqual(rtn, 0) - - # Client first pass - rtn = libmpin.MPIN_CLIENT_1(self.date, self.MPIN_ID, RNG, X, PIN2, TOKEN, SEC, U, UT, TIME_PERMIT) - self.assertEqual(rtn, 0) - - # Server calculates H(ID) and H(T|H(ID)) - libmpin.MPIN_SERVER_1(self.date, self.MPIN_ID, HID, HTID) - - # Server generates Random number Y and sends it to Client - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, Y) - self.assertEqual(rtn, 0) - - # Client second pass - rtn = libmpin.MPIN_CLIENT_2(X, Y, SEC) - self.assertEqual(rtn, 0) - - # Server second pass - # clientSecret aka V is equal to UT to model a bad token - rtn = libmpin.MPIN_SERVER_2(self.date, HID, HTID, Y, SERVER_SECRET, U, UT, UT, E, F) - self.assertEqual(rtn, -19) - - def test_4(self): - """test_4 Test hash function""" - HASH_MPIN_ID = ffi.new("octet*") - HASH_MPIN_IDval = ffi.new("char []", HASH_BYTES) - HASH_MPIN_ID[0].val = HASH_MPIN_IDval - HASH_MPIN_ID[0].max = HASH_BYTES - HASH_MPIN_ID[0].len = HASH_BYTES - - for i in range(1, 10000): - bytesStr = os.urandom(128) - hash_object2 = hashlib.sha256(bytesStr) - digest = hash_object2.hexdigest() - MPIN_ID = ffi.new("octet*") - MPIN_IDval = ffi.new("char [%s]" % len(bytesStr), bytesStr) - MPIN_ID[0].val = MPIN_IDval - MPIN_ID[0].max = len(bytesStr) - MPIN_ID[0].len = len(bytesStr) - libmpin.MPIN_HASH_ID(MPIN_ID, HASH_MPIN_ID) - self.assertEqual(digest, toHex(HASH_MPIN_ID)) - - def test_5(self): - """test_5 Make sure all client secret are unique""" - # random number generator - RNG = ffi.new("csprng*") - libmpin.MPIN_CREATE_CSPRNG(RNG, self.RAW) - - # Generate master secret share - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS1) - self.assertEqual(rtn, 0) - - s = set() - match = 0 - for i in range(1, 1000): - rand_val = os.urandom(32) - HASH_MPIN_ID = ffi.new("octet*") - HASH_MPIN_IDval = ffi.new("char [%s]" % HASH_BYTES, rand_val) - HASH_MPIN_ID[0].val = HASH_MPIN_IDval - HASH_MPIN_ID[0].max = HASH_BYTES - HASH_MPIN_ID[0].len = HASH_BYTES - - # Generate client secret shares - rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS1, HASH_MPIN_ID, CS1) - self.assertEqual(rtn, 0) - cs1Hex = toHex(CS1) - if cs1Hex in s: - match = 1 - self.assertEqual(match, 0) - s.add(cs1Hex) - - def test_6(self): - """test_6 Make sure all one time passwords are random i.e. they should collide""" - # random number generator - RNG = ffi.new("csprng*") - libmpin.MPIN_CREATE_CSPRNG(RNG, self.RAW) - - s = set() - match = 0 - for i in range(1, 10000): - OTP = libmpin.generateOTP(RNG) - if OTP in s: - # print i - match = 1 - s.add(OTP) - self.assertEqual(match, 1) - - def test_7(self): - """test_7 Make sure all random values are random i.e. they should collide""" - # random number generator - RNG = ffi.new("csprng*") - libmpin.MPIN_CREATE_CSPRNG(RNG, self.RAW) - - # Generate 100 byte random number - RANDOMlen = 3 - RANDOM = ffi.new("octet*") - RANDOMval = ffi.new("char []", RANDOMlen) - RANDOM[0].val = RANDOMval - RANDOM[0].max = RANDOMlen - RANDOM[0].len = RANDOMlen - - s = set() - match = 0 - for i in range(1, 10000): - libmpin.generateRandom(RNG, RANDOM) - random = toHex(RANDOM) - if random in s: - # print i - match = 1 - s.add(random) - self.assertEqual(match, 1) - - def test_8(self): - """test_8 AES-GCM: Successful encryption and decryption""" - - # Generate 16 byte key - key_val = os.urandom(PAS) - AES_KEY = ffi.new("octet*") - AES_KEYval = ffi.new("char [%s]" % PAS, key_val) - AES_KEY[0].val = AES_KEYval - AES_KEY[0].max = PAS - AES_KEY[0].len = PAS - - # Generate 12 byte IV - iv_val = os.urandom(IVL) - IV = ffi.new("octet*") - IVval = ffi.new("char [%s]" % IVL, iv_val) - IV[0].val = IVval - IV[0].max = IVL - IV[0].len = IVL - - # Generate a 32 byte random header - header_val = os.urandom(32) - HEADER = ffi.new("octet*") - HEADERval = ffi.new("char [%s]" % len(header_val), header_val) - HEADER[0].val = HEADERval - HEADER[0].max = len(header_val) - HEADER[0].len = len(header_val) - - # Plaintext input - plaintext1 = "A test message" - PLAINTEXT1 = ffi.new("octet*") - PLAINTEXT1val = ffi.new("char [%s]" % len(plaintext1), plaintext1) - PLAINTEXT1[0].val = PLAINTEXT1val - PLAINTEXT1[0].max = len(plaintext1) - PLAINTEXT1[0].len = len(plaintext1) - # print "Input message: %s" % ffi.string(PLAINTEXT1[0].val, PLAINTEXT1[0].len) - - # Ciphertext - CIPHERTEXT = ffi.new("octet*") - CIPHERTEXTval = ffi.new("char []", len(plaintext1)) - CIPHERTEXT[0].val = CIPHERTEXTval - CIPHERTEXT[0].max = len(plaintext1) - - # 16 byte authentication tag - TAG1 = ffi.new("octet*") - TAG1val = ffi.new("char []", PAS) - TAG1[0].val = TAG1val - TAG1[0].max = PAS - - libmpin.MPIN_AES_GCM_ENCRYPT(AES_KEY, IV, HEADER, PLAINTEXT1, CIPHERTEXT, TAG1) - # Plaintext output - PLAINTEXT2 = ffi.new("octet*") - PLAINTEXT2val = ffi.new("char []", CIPHERTEXT[0].len) - PLAINTEXT2[0].val = PLAINTEXT2val - PLAINTEXT2[0].max = CIPHERTEXT[0].len - PLAINTEXT2[0].len = CIPHERTEXT[0].len - - # 16 byte authentication tag - TAG2 = ffi.new("octet*") - TAG2val = ffi.new("char []", PAS) - TAG2[0].val = TAG2val - TAG2[0].max = PAS - - libmpin.MPIN_AES_GCM_DECRYPT(AES_KEY, IV, HEADER, CIPHERTEXT, PLAINTEXT2, TAG2) - self.assertEqual(toHex(TAG1), toHex(TAG2)) - self.assertEqual(toHex(PLAINTEXT1), toHex(PLAINTEXT2)) - # print "Output message: %s" % ffi.string(PLAINTEXT2[0].val, PLAINTEXT2[0].len) - - def test_9(self): - """test_9 AES-GCM: Failed encryption and decryption by changing a ciphertext byte""" - - # Generate 16 byte key - key_val = os.urandom(PAS) - AES_KEY = ffi.new("octet*") - AES_KEYval = ffi.new("char [%s]" % PAS, key_val) - AES_KEY[0].val = AES_KEYval - AES_KEY[0].max = PAS - AES_KEY[0].len = PAS - - # Generate 12 byte IV - iv_val = os.urandom(IVL) - IV = ffi.new("octet*") - IVval = ffi.new("char [%s]" % IVL, iv_val) - IV[0].val = IVval - IV[0].max = IVL - IV[0].len = IVL - - # Generate a 32 byte random header - header_val = os.urandom(32) - HEADER = ffi.new("octet*") - HEADERval = ffi.new("char [%s]" % len(header_val), header_val) - HEADER[0].val = HEADERval - HEADER[0].max = len(header_val) - HEADER[0].len = len(header_val) - - # Plaintext input - plaintext1 = "A test message" - PLAINTEXT1 = ffi.new("octet*") - PLAINTEXT1val = ffi.new("char [%s]" % len(plaintext1), plaintext1) - PLAINTEXT1[0].val = PLAINTEXT1val - PLAINTEXT1[0].max = len(plaintext1) - PLAINTEXT1[0].len = len(plaintext1) - # print "Input message: %s" % ffi.string(PLAINTEXT1[0].val, PLAINTEXT1[0].len) - - # Ciphertext - CIPHERTEXT = ffi.new("octet*") - CIPHERTEXTval = ffi.new("char []", len(plaintext1)) - CIPHERTEXT[0].val = CIPHERTEXTval - CIPHERTEXT[0].max = len(plaintext1) - - # 16 byte authentication tag - TAG1 = ffi.new("octet*") - TAG1val = ffi.new("char []", PAS) - TAG1[0].val = TAG1val - TAG1[0].max = PAS - - libmpin.MPIN_AES_GCM_ENCRYPT(AES_KEY, IV, HEADER, PLAINTEXT1, CIPHERTEXT, TAG1) - - # Change one byte of ciphertext - CIPHERTEXT[0].val[0] = "\xa5" - - # Plaintext output - PLAINTEXT2 = ffi.new("octet*") - PLAINTEXT2val = ffi.new("char []", CIPHERTEXT[0].len) - PLAINTEXT2[0].val = PLAINTEXT2val - PLAINTEXT2[0].max = CIPHERTEXT[0].len - PLAINTEXT2[0].len = CIPHERTEXT[0].len - - # 16 byte authentication tag - TAG2 = ffi.new("octet*") - TAG2val = ffi.new("char []", PAS) - TAG2[0].val = TAG2val - TAG2[0].max = PAS - - libmpin.MPIN_AES_GCM_DECRYPT(AES_KEY, IV, HEADER, CIPHERTEXT, PLAINTEXT2, TAG2) - self.assertNotEqual(toHex(TAG1), toHex(TAG2)) - self.assertNotEqual(toHex(PLAINTEXT1), toHex(PLAINTEXT2)) - # print "Output message: %s" % ffi.string(PLAINTEXT2[0].val, PLAINTEXT2[0].len) - - def test_10(self): - """test_10 AES-GCM: Failed encryption and decryption by changing a header byte""" - - # Generate 16 byte key - key_val = os.urandom(PAS) - AES_KEY = ffi.new("octet*") - AES_KEYval = ffi.new("char [%s]" % PAS, key_val) - AES_KEY[0].val = AES_KEYval - AES_KEY[0].max = PAS - AES_KEY[0].len = PAS - - # Generate 12 byte IV - iv_val = os.urandom(IVL) - IV = ffi.new("octet*") - IVval = ffi.new("char [%s]" % IVL, iv_val) - IV[0].val = IVval - IV[0].max = IVL - IV[0].len = IVL - - # Generate a 32 byte random header - header_val = os.urandom(32) - HEADER = ffi.new("octet*") - HEADERval = ffi.new("char [%s]" % len(header_val), header_val) - HEADER[0].val = HEADERval - HEADER[0].max = len(header_val) - HEADER[0].len = len(header_val) - - # Plaintext input - plaintext1 = "A test message" - PLAINTEXT1 = ffi.new("octet*") - PLAINTEXT1val = ffi.new("char [%s]" % len(plaintext1), plaintext1) - PLAINTEXT1[0].val = PLAINTEXT1val - PLAINTEXT1[0].max = len(plaintext1) - PLAINTEXT1[0].len = len(plaintext1) - # print "Input message: %s" % ffi.string(PLAINTEXT1[0].val, PLAINTEXT1[0].len) - - # Ciphertext - CIPHERTEXT = ffi.new("octet*") - CIPHERTEXTval = ffi.new("char []", len(plaintext1)) - CIPHERTEXT[0].val = CIPHERTEXTval - CIPHERTEXT[0].max = len(plaintext1) - - # 16 byte authentication tag - TAG1 = ffi.new("octet*") - TAG1val = ffi.new("char []", PAS) - TAG1[0].val = TAG1val - TAG1[0].max = PAS - - libmpin.MPIN_AES_GCM_ENCRYPT(AES_KEY, IV, HEADER, PLAINTEXT1, CIPHERTEXT, TAG1) - # Plaintext output - PLAINTEXT2 = ffi.new("octet*") - PLAINTEXT2val = ffi.new("char []", CIPHERTEXT[0].len) - PLAINTEXT2[0].val = PLAINTEXT2val - PLAINTEXT2[0].max = CIPHERTEXT[0].len - PLAINTEXT2[0].len = CIPHERTEXT[0].len - - # Change one byte of header - HEADER[0].val[0] = "\xa5" - - # 16 byte authentication tag - TAG2 = ffi.new("octet*") - TAG2val = ffi.new("char []", PAS) - TAG2[0].val = TAG2val - TAG2[0].max = PAS - - libmpin.MPIN_AES_GCM_DECRYPT(AES_KEY, IV, HEADER, CIPHERTEXT, PLAINTEXT2, TAG2) - self.assertNotEqual(toHex(TAG1), toHex(TAG2)) - self.assertEqual(toHex(PLAINTEXT1), toHex(PLAINTEXT2)) - -if __name__ == '__main__': - # Run tests - unittest.main()
http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/pythonCFFI/TimeMPIN.py ---------------------------------------------------------------------- diff --git a/pythonCFFI/TimeMPIN.py b/pythonCFFI/TimeMPIN.py deleted file mode 100755 index 5273322..0000000 --- a/pythonCFFI/TimeMPIN.py +++ /dev/null @@ -1,331 +0,0 @@ -#!/usr/bin/env python - -""" -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 sys -import timeit -import warnings - -from mpin import ffi, G1, G2, HASH_BYTES, libmpin, PGS, toHex - -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:%s nIter:%s total_time:%s iter_time:%s iter_per_sec: %s" % (stmt, n, total_time, iter_time, iter_per_sec) - -if (len(sys.argv) == 2) and (sys.argv[1] == "DEBUG"): - DEBUG = True -else: - DEBUG = False - -nIter = 1000 - -if __name__ == "__main__": - # Print hex values - DEBUG = False - MULTI_PASS = False - - # Seed - seedHex = "79dd3f23c70bb529a8e3b221cf62da0dd4bd3ca35bd0c515cd9cde5ffa6a5c4d" - seed = seedHex.decode("hex") - - # Identity - identity = "[email protected]" - MPIN_ID = ffi.new("octet*") - MPIN_IDval = ffi.new("char [%s]" % len(identity), identity) - MPIN_ID[0].val = MPIN_IDval - MPIN_ID[0].max = len(identity) - MPIN_ID[0].len = len(identity) - - # Master Secret Shares - MS1 = ffi.new("octet*") - MS1val = ffi.new("char []", PGS) - MS1[0].val = MS1val - MS1[0].max = PGS - MS1[0].len = PGS - - MS2 = ffi.new("octet*") - MS2val = ffi.new("char []", PGS) - MS2[0].val = MS2val - MS2[0].max = PGS - MS2[0].len = PGS - - # Hash value of MPIN_ID - HASH_MPIN_ID = ffi.new("octet*") - HASH_MPIN_IDval = ffi.new("char []", HASH_BYTES) - HASH_MPIN_ID[0].val = HASH_MPIN_IDval - HASH_MPIN_ID[0].max = HASH_BYTES - HASH_MPIN_ID[0].len = HASH_BYTES - - # Client secret and shares - CS1 = ffi.new("octet*") - CS1val = ffi.new("char []", G1) - CS1[0].val = CS1val - CS1[0].max = G1 - CS1[0].len = G1 - - CS2 = ffi.new("octet*") - CS2val = ffi.new("char []", G1) - CS2[0].val = CS2val - CS2[0].max = G1 - CS2[0].len = G1 - - SEC = ffi.new("octet*") - SECval = ffi.new("char []", G1) - SEC[0].val = SECval - SEC[0].max = G1 - SEC[0].len = G1 - - # Server secret and shares - SS1 = ffi.new("octet*") - SS1val = ffi.new("char []", G2) - SS1[0].val = SS1val - SS1[0].max = G2 - SS1[0].len = G2 - - SS2 = ffi.new("octet*") - SS2val = ffi.new("char []", G2) - SS2[0].val = SS2val - SS2[0].max = G2 - SS2[0].len = G2 - - SERVER_SECRET = ffi.new("octet*") - SERVER_SECRETval = ffi.new("char []", G2) - SERVER_SECRET[0].val = SERVER_SECRETval - SERVER_SECRET[0].max = G2 - SERVER_SECRET[0].len = G2 - - # Time Permit and shares - TP1 = ffi.new("octet*") - TP1val = ffi.new("char []", G1) - TP1[0].val = TP1val - TP1[0].max = G1 - TP1[0].len = G1 - - TP2 = ffi.new("octet*") - TP2val = ffi.new("char []", G1) - TP2[0].val = TP2val - TP2[0].max = G1 - TP2[0].len = G1 - - TIME_PERMIT = ffi.new("octet*") - TIME_PERMITval = ffi.new("char []", G1) - TIME_PERMIT[0].val = TIME_PERMITval - TIME_PERMIT[0].max = G1 - TIME_PERMIT[0].len = G1 - - # Token stored on computer - TOKEN = ffi.new("octet*") - TOKENval = ffi.new("char []", G1) - TOKEN[0].val = TOKENval - TOKEN[0].max = G1 - TOKEN[0].len = G1 - - # H(ID) - HID = ffi.new("octet*") - HIDval = ffi.new("char []", G1) - HID[0].val = HIDval - HID[0].max = G1 - HID[0].len = G1 - - # H(T|H(ID)) - HTID = ffi.new("octet*") - HTIDval = ffi.new("char []", G1) - HTID[0].val = HTIDval - HTID[0].max = G1 - HTID[0].len = G1 - - UT = ffi.new("octet*") - UTval = ffi.new("char []", G1) - UT[0].val = UTval - UT[0].max = G1 - UT[0].len = G1 - - U = ffi.new("octet*") - Uval = ffi.new("char []", G1) - U[0].val = Uval - U[0].max = G1 - U[0].len = G1 - - X = ffi.new("octet*") - Xval = ffi.new("char []", PGS) - X[0].val = Xval - X[0].max = PGS - X[0].len = PGS - - Y = ffi.new("octet*") - Yval = ffi.new("char []", PGS) - Y[0].val = Yval - Y[0].max = PGS - Y[0].len = PGS - - E = ffi.NULL - F = ffi.NULL - - date = libmpin.MPIN_today() - if date: - HID = ffi.NULL - U = ffi.NULL - else: - HTID = ffi.NULL - UT = ffi.NULL - - # Assign a seed value - RAW = ffi.new("octet*") - RAWval = ffi.new("char [%s]" % len(seed), seed) - RAW[0].val = RAWval - RAW[0].len = len(seed) - RAW[0].max = len(seed) - if DEBUG: - print "RAW: %s" % toHex(RAW) - - # random number generator - RNG = ffi.new("csprng*") - libmpin.MPIN_CREATE_CSPRNG(RNG, RAW) - - # Hash MPIN_ID - libmpin.MPIN_HASH_ID(MPIN_ID, HASH_MPIN_ID) - if DEBUG: - print "MPIN_ID: %s" % toHex(MPIN_ID) - print "HASH_MPIN_ID: %s" % toHex(HASH_MPIN_ID) - - # Generate master secret for MIRACL and Customer - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS1) - if rtn != 0: - print "libmpin.MPIN_RANDOM_GENERATE(RNG,MS1) Error %s", rtn - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS2) - if rtn != 0: - print "libmpin.MPIN_RANDOM_GENERATE(RNG,MS2) Error %s" % rtn - if DEBUG: - print "MS1: %s" % toHex(MS1) - print "MS2: %s" % toHex(MS2) - - # Generate server secret shares - rtn = libmpin.MPIN_GET_SERVER_SECRET(MS1, SS1) - if rtn != 0: - print "libmpin.MPIN_GET_SERVER_SECRET(MS1,SS1) Error %s" % rtn - rtn = libmpin.MPIN_GET_SERVER_SECRET(MS2, SS2) - if rtn != 0: - print "libmpin.MPIN_GET_SERVER_SECRET(MS2,SS2) Error %s" % rtn - if DEBUG: - print "SS1: %s" % toHex(SS1) - print "SS2: %s" % toHex(SS2) - - # Combine server secret shares - rtn = libmpin.MPIN_RECOMBINE_G2(SS1, SS2, SERVER_SECRET) - if rtn != 0: - print "libmpin.MPIN_RECOMBINE_G2( SS1, SS2, SERVER_SECRET) Error %s" % rtn - if DEBUG: - print "SERVER_SECRET: %s" % toHex(SERVER_SECRET) - - # Generate client secret shares - rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS1, HASH_MPIN_ID, CS1) - if rtn != 0: - print "libmpin.MPIN_GET_CLIENT_SECRET(MS1,HASH_MPIN_ID,CS1) Error %s" % rtn - rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS2, HASH_MPIN_ID, CS2) - if rtn != 0: - print "libmpin.MPIN_GET_CLIENT_SECRET(MS2,HASH_MPIN_ID,CS2) Error %s" % rtn - if DEBUG: - print "CS1: %s" % toHex(CS1) - print "CS2: %s" % toHex(CS2) - - # Combine client secret shares : TOKEN is the full client secret - rtn = libmpin.MPIN_RECOMBINE_G1(CS1, CS2, TOKEN) - if rtn != 0: - print "libmpin.MPIN_RECOMBINE_G1( CS1, CS2, TOKEN) Error %s" % rtn - print "Client Secret: %s" % toHex(TOKEN) - - # Generate Time Permit shares - if DEBUG: - print "Date %s" % date - rtn = libmpin.MPIN_GET_CLIENT_PERMIT(date, MS1, HASH_MPIN_ID, TP1) - if rtn != 0: - print "libmpin.MPIN_GET_CLIENT_PERMIT(date,MS1,HASH_MPIN_ID,TP1) Error %s" % rtn - rtn = libmpin.MPIN_GET_CLIENT_PERMIT(date, MS2, HASH_MPIN_ID, TP2) - if rtn != 0: - print "libmpin.MPIN_GET_CLIENT_PERMIT(date,MS2,HASH_MPIN_ID,TP2) Error %s" % rtn - if DEBUG: - print "TP1: %s" % toHex(TP1) - print "TP2: %s" % toHex(TP2) - - # Combine Time Permit shares - rtn = libmpin.MPIN_RECOMBINE_G1(TP1, TP2, TIME_PERMIT) - if rtn != 0: - print "libmpin.MPIN_RECOMBINE_G1(TP1, TP2, TIME_PERMIT) Error %s" % rtn - if DEBUG: - print "TIME_PERMIT: %s" % toHex(TIME_PERMIT) - - # Client extracts PIN from secret to create Token - PIN = 1234 - rtn = libmpin.MPIN_EXTRACT_PIN(MPIN_ID, PIN, TOKEN) - if rtn != 0: - print "libmpin.MPIN_EXTRACT_PIN( MPIN_ID, PIN, TOKEN) Error %s" % rtn - print "Token: %s" % toHex(TOKEN) - - if MULTI_PASS: - # Client first pass - rtn = libmpin.MPIN_CLIENT_1(date, MPIN_ID, RNG, X, PIN, TOKEN, SEC, U, UT, TIME_PERMIT) - if rtn != 0: - print "MPIN_CLIENT_1 ERROR %s" % rtn - if DEBUG: - print "X: %s" % toHex(X) - - # 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. - libmpin.MPIN_SERVER_1(date, MPIN_ID, HID, HTID) - - # Server generates Random number Y and sends it to Client - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, Y) - if rtn != 0: - print "libmpin.MPIN_RANDOM_GENERATE(RNG,Y) Error %s" % rtn - if DEBUG: - print "Y: %s" % toHex(Y) - - # Client second pass - rtn = libmpin.MPIN_CLIENT_2(X, Y, SEC) - if rtn != 0: - print "libmpin.MPIN_CLIENT_2(X,Y,SEC) Error %s" % rtn - if DEBUG: - print "V: %s" % toHex(SEC) - - # Server second pass - rtn = libmpin.MPIN_SERVER_2(date, HID, HTID, Y, SERVER_SECRET, U, UT, SEC, E, F) - if rtn != 0: - print "ERROR: Multi Pass %s is not authenticated" % identity - else: - print "SUCCESS: Multi Pass %s is authenticated" % identity - else: - # Client - TimeValue = libmpin.MPIN_GET_TIME() - time_func('libmpin.MPIN_CLIENT(date, MPIN_ID, RNG, X, PIN, TOKEN, SEC, U, UT, TIME_PERMIT, ffi.NULL, TimeValue, Y)', nIter) - if DEBUG: - print "X: %s" % toHex(X) - - # Server - time_func('libmpin.MPIN_SERVER(date, HID, HTID, Y, SERVER_SECRET, U, UT, SEC, E, F, MPIN_ID, ffi.NULL, TimeValue)', nIter) - rtn = libmpin.MPIN_SERVER(date, HID, HTID, Y, SERVER_SECRET, U, UT, SEC, E, F, MPIN_ID, ffi.NULL, TimeValue) - if rtn != 0: - print "ERROR: Single Pass %s is not authenticated" % identity - else: - print "SUCCESS: Single Pass %s is authenticated" % identity http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/pythonCFFI/TimeMPINFull.py ---------------------------------------------------------------------- diff --git a/pythonCFFI/TimeMPINFull.py b/pythonCFFI/TimeMPINFull.py deleted file mode 100755 index 6ca5022..0000000 --- a/pythonCFFI/TimeMPINFull.py +++ /dev/null @@ -1,444 +0,0 @@ -#!/usr/bin/env python - -""" -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 sys -import timeit -import warnings - -from mpin import ffi, G1, G2, HASH_BYTES, libmpin, PAS, PFS, PGS, toHex - -warnings.filterwarnings("ignore") - - -def time_func(stmt, n=10, setup='from __main__ import *'): - t = timeit.Timer(stmt, setup) - exec_time = t.timeit(n) - iter_time = exec_time / n - iter_per_sec = n / exec_time - print "func:%s nIter:%s exec_time:%s iter_time:%s iter_per_sec: %s" % (stmt, n, exec_time, iter_time, iter_per_sec) - return exec_time - -if (len(sys.argv) == 2) and (sys.argv[1] == "DEBUG"): - DEBUG = True -else: - DEBUG = False - -nIter = 100 - -if __name__ == "__main__": - # Print hex values - DEBUG = False - SINGLE_PASS = True - TIME_PERMITS = True - - if TIME_PERMITS: - date = libmpin.MPIN_today() - else: - date = 0 - - # Seed - seedHex = "79dd3f23c70bb529a8e3b221cf62da0dd4bd3ca35bd0c515cd9cde5ffa6a5c4d" - seed = seedHex.decode("hex") - - # Identity - identity = "[email protected]" - MPIN_ID = ffi.new("octet*") - MPIN_IDval = ffi.new("char [%s]" % len(identity), identity) - MPIN_ID[0].val = MPIN_IDval - MPIN_ID[0].max = len(identity) - MPIN_ID[0].len = len(identity) - - # Master Secret Shares - MS1 = ffi.new("octet*") - MS1val = ffi.new("char []", PGS) - MS1[0].val = MS1val - MS1[0].max = PGS - MS1[0].len = PGS - - MS2 = ffi.new("octet*") - MS2val = ffi.new("char []", PGS) - MS2[0].val = MS2val - MS2[0].max = PGS - MS2[0].len = PGS - - # Hash value of MPIN_ID - HASH_MPIN_ID = ffi.new("octet*") - HASH_MPIN_IDval = ffi.new("char []", HASH_BYTES) - HASH_MPIN_ID[0].val = HASH_MPIN_IDval - HASH_MPIN_ID[0].max = HASH_BYTES - HASH_MPIN_ID[0].len = HASH_BYTES - - # Client secret and shares - CS1 = ffi.new("octet*") - CS1val = ffi.new("char []", G1) - CS1[0].val = CS1val - CS1[0].max = G1 - CS1[0].len = G1 - - CS2 = ffi.new("octet*") - CS2val = ffi.new("char []", G1) - CS2[0].val = CS2val - CS2[0].max = G1 - CS2[0].len = G1 - - SEC = ffi.new("octet*") - SECval = ffi.new("char []", G1) - SEC[0].val = SECval - SEC[0].max = G1 - SEC[0].len = G1 - - # Server secret and shares - SS1 = ffi.new("octet*") - SS1val = ffi.new("char []", G2) - SS1[0].val = SS1val - SS1[0].max = G2 - SS1[0].len = G2 - - SS2 = ffi.new("octet*") - SS2val = ffi.new("char []", G2) - SS2[0].val = SS2val - SS2[0].max = G2 - SS2[0].len = G2 - - SERVER_SECRET = ffi.new("octet*") - SERVER_SECRETval = ffi.new("char []", G2) - SERVER_SECRET[0].val = SERVER_SECRETval - SERVER_SECRET[0].max = G2 - SERVER_SECRET[0].len = G2 - - # Time Permit and shares - TP1 = ffi.new("octet*") - TP1val = ffi.new("char []", G1) - TP1[0].val = TP1val - TP1[0].max = G1 - TP1[0].len = G1 - - TP2 = ffi.new("octet*") - TP2val = ffi.new("char []", G1) - TP2[0].val = TP2val - TP2[0].max = G1 - TP2[0].len = G1 - - TIME_PERMIT = ffi.new("octet*") - TIME_PERMITval = ffi.new("char []", G1) - TIME_PERMIT[0].val = TIME_PERMITval - TIME_PERMIT[0].max = G1 - TIME_PERMIT[0].len = G1 - - # Token stored on computer - TOKEN = ffi.new("octet*") - TOKENval = ffi.new("char []", G1) - TOKEN[0].val = TOKENval - TOKEN[0].max = G1 - TOKEN[0].len = G1 - - # H(ID) - HID = ffi.new("octet*") - HIDval = ffi.new("char []", G1) - HID[0].val = HIDval - HID[0].max = G1 - HID[0].len = G1 - - # H(T|H(ID)) - HTID = ffi.new("octet*") - HTIDval = ffi.new("char []", G1) - HTID[0].val = HTIDval - HTID[0].max = G1 - HTID[0].len = G1 - - UT = ffi.new("octet*") - UTval = ffi.new("char []", G1) - UT[0].val = UTval - UT[0].max = G1 - UT[0].len = G1 - - U = ffi.new("octet*") - Uval = ffi.new("char []", G1) - U[0].val = Uval - U[0].max = G1 - U[0].len = G1 - - X = ffi.new("octet*") - Xval = ffi.new("char []", PGS) - X[0].val = Xval - X[0].max = PGS - X[0].len = PGS - - Y = ffi.new("octet*") - Yval = ffi.new("char []", PGS) - Y[0].val = Yval - Y[0].max = PGS - Y[0].len = PGS - - E = ffi.NULL - F = ffi.NULL - - # MPIN Full - R = ffi.new("octet*") - Rval = ffi.new("char []", PGS) - R[0].val = Rval - R[0].max = PGS - R[0].len = PGS - - W = ffi.new("octet*") - Wval = ffi.new("char []", PGS) - W[0].val = Wval - W[0].max = PGS - W[0].len = PGS - - Z = ffi.new("octet*") - Zval = ffi.new("char []", G1) - Z[0].val = Zval - Z[0].max = G1 - Z[0].len = G1 - - T = ffi.new("octet*") - Tval = ffi.new("char []", G1) - T[0].val = Tval - T[0].max = G1 - T[0].len = G1 - - TATE1 = ffi.new("octet*") - TATE1val = ffi.new("char []", 12*PFS) - TATE1[0].val = TATE1val - TATE1[0].max = 12*PFS - TATE1[0].len = 12*PFS - - TATE2 = ffi.new("octet*") - TATE2val = ffi.new("char []", 12*PFS) - TATE2[0].val = TATE2val - TATE2[0].max = 12*PFS - TATE2[0].len = 12*PFS - - SK = ffi.new("octet*") - SKval = ffi.new("char []", PAS) - SK[0].val = SKval - SK[0].max = PAS - SK[0].len = PAS - - CK = ffi.new("octet*") - CKval = ffi.new("char []", PAS) - CK[0].val = CKval - CK[0].max = PAS - CK[0].len = PAS - - if date: - HID = ffi.NULL - U = ffi.NULL - prHID = HTID - else: - HTID = ffi.NULL - UT = ffi.NULL - prHID = HID - - # Assign a seed value - RAW = ffi.new("octet*") - RAWval = ffi.new("char [%s]" % len(seed), seed) - RAW[0].val = RAWval - RAW[0].len = len(seed) - RAW[0].max = len(seed) - if DEBUG: - print "RAW: %s" % toHex(RAW) - - # random number generator - RNG = ffi.new("csprng*") - libmpin.MPIN_CREATE_CSPRNG(RNG, RAW) - - # Hash MPIN_ID - libmpin.MPIN_HASH_ID(MPIN_ID, HASH_MPIN_ID) - if DEBUG: - print "MPIN_ID: %s" % toHex(MPIN_ID) - print "HASH_MPIN_ID: %s" % toHex(HASH_MPIN_ID) - - # Generate master secret for MIRACL and Customer - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS1) - if rtn != 0: - print "libmpin.MPIN_RANDOM_GENERATE(RNG,MS1) Error %s", rtn - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS2) - if rtn != 0: - print "libmpin.MPIN_RANDOM_GENERATE(RNG,MS2) Error %s" % rtn - if DEBUG: - print "MS1: %s" % toHex(MS1) - print "MS2: %s" % toHex(MS2) - - # Generate server secret shares - rtn = libmpin.MPIN_GET_SERVER_SECRET(MS1, SS1) - if rtn != 0: - print "libmpin.MPIN_GET_SERVER_SECRET(MS1,SS1) Error %s" % rtn - rtn = libmpin.MPIN_GET_SERVER_SECRET(MS2, SS2) - if rtn != 0: - print "libmpin.MPIN_GET_SERVER_SECRET(MS2,SS2) Error %s" % rtn - if DEBUG: - print "SS1: %s" % toHex(SS1) - print "SS2: %s" % toHex(SS2) - - # Combine server secret shares - rtn = libmpin.MPIN_RECOMBINE_G2(SS1, SS2, SERVER_SECRET) - if rtn != 0: - print "libmpin.MPIN_RECOMBINE_G2( SS1, SS2, SERVER_SECRET) Error %s" % rtn - if DEBUG: - print "SERVER_SECRET: %s" % toHex(SERVER_SECRET) - - # Generate client secret shares - rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS1, HASH_MPIN_ID, CS1) - if rtn != 0: - print "libmpin.MPIN_GET_CLIENT_SECRET(MS1,HASH_MPIN_ID,CS1) Error %s" % rtn - rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS2, HASH_MPIN_ID, CS2) - if rtn != 0: - print "libmpin.MPIN_GET_CLIENT_SECRET(MS2,HASH_MPIN_ID,CS2) Error %s" % rtn - if DEBUG: - print "CS1: %s" % toHex(CS1) - print "CS2: %s" % toHex(CS2) - - # Combine client secret shares : TOKEN is the full client secret - rtn = libmpin.MPIN_RECOMBINE_G1(CS1, CS2, TOKEN) - if rtn != 0: - print "libmpin.MPIN_RECOMBINE_G1( CS1, CS2, TOKEN) Error %s" % rtn - print "Client Secret: %s" % toHex(TOKEN) - - # Generate Time Permit shares - if DEBUG: - print "Date %s" % date - rtn = libmpin.MPIN_GET_CLIENT_PERMIT(date, MS1, HASH_MPIN_ID, TP1) - if rtn != 0: - print "libmpin.MPIN_GET_CLIENT_PERMIT(date,MS1,HASH_MPIN_ID,TP1) Error %s" % rtn - rtn = libmpin.MPIN_GET_CLIENT_PERMIT(date, MS2, HASH_MPIN_ID, TP2) - if rtn != 0: - print "libmpin.MPIN_GET_CLIENT_PERMIT(date,MS2,HASH_MPIN_ID,TP2) Error %s" % rtn - if DEBUG: - print "TP1: %s" % toHex(TP1) - print "TP2: %s" % toHex(TP2) - - # Combine Time Permit shares - rtn = libmpin.MPIN_RECOMBINE_G1(TP1, TP2, TIME_PERMIT) - if rtn != 0: - print "libmpin.MPIN_RECOMBINE_G1(TP1, TP2, TIME_PERMIT) Error %s" % rtn - if DEBUG: - print "TIME_PERMIT: %s" % toHex(TIME_PERMIT) - - # Client extracts PIN from secret to create Token - PIN = 1234 - rtn = libmpin.MPIN_EXTRACT_PIN(MPIN_ID, PIN, TOKEN) - if rtn != 0: - print "libmpin.MPIN_EXTRACT_PIN( MPIN_ID, PIN, TOKEN) Error %s" % rtn - print "Token: %s" % toHex(TOKEN) - - if SINGLE_PASS: - print "M-Pin Single Pass" - clientTime = 0 - serverTime = 0 - TimeValue = libmpin.MPIN_GET_TIME() - # Client precomputation - time_func('libmpin.MPIN_PRECOMPUTE(TOKEN,HASH_MPIN_ID,TATE1,TATE2)', nIter) - - # Client MPIN - ct1 = time_func('libmpin.MPIN_CLIENT(date, MPIN_ID, RNG, X, PIN, TOKEN, SEC, U, UT, TIME_PERMIT, ffi.NULL, TimeValue, Y)', nIter) - clientTime = clientTime + ct1 - if DEBUG: - print "X: %s" % toHex(X) - - # Client sends Z=r.ID to Server - ct2 = time_func('libmpin.MPIN_GET_G1_MULTIPLE(RNG,1,R,HASH_MPIN_ID,Z)', nIter) - clientTime = clientTime + ct2 - - # Server MPIN - st1 = time_func('libmpin.MPIN_SERVER(date, HID, HTID, Y, SERVER_SECRET, U, UT, SEC, E, F, MPIN_ID, ffi.NULL, TimeValue)', nIter) - serverTime = serverTime + st1 - rtn = libmpin.MPIN_SERVER(date, HID, HTID, Y, SERVER_SECRET, U, UT, SEC, E, F, MPIN_ID, ffi.NULL, TimeValue) - if rtn != 0: - print "ERROR: Single Pass %s is not authenticated" % identity - else: - print "SUCCESS: Single Pass %s is authenticated" % identity - - # Server sends T=w.ID to client - st2 = time_func('libmpin.MPIN_GET_G1_MULTIPLE(RNG,0,W,prHID,T)', nIter) - serverTime = serverTime + st2 - print "T: %s" % toHex(T) - - ct3 = time_func('libmpin.MPIN_CLIENT_KEY(TATE1,TATE2,PIN,R,X,T,CK)', nIter) - clientTime = clientTime + ct3 - print "Client Key: %s" % toHex(CK) - - st3 = time_func('libmpin.MPIN_SERVER_KEY(Z,SERVER_SECRET,W,U,UT,SK)', nIter) - serverTime = serverTime + st3 - print "Server Key: %s" % toHex(SK) - - assert toHex(CK) == toHex(SK), "CK == SK" - - iter_time = clientTime / nIter - iter_per_sec = nIter / clientTime - print "Client nIter:%s time:%s iter_time:%s iter_per_sec: %s" % (nIter, clientTime, iter_time, iter_per_sec) - iter_time = serverTime / nIter - iter_per_sec = nIter / serverTime - print "Server nIter:%s time:%s iter_time:%s iter_per_sec: %s" % (nIter, serverTime, iter_time, iter_per_sec) - - else: - print "M-Pin Multi Pass" - rtn = libmpin.MPIN_PRECOMPUTE(TOKEN, HASH_MPIN_ID, TATE1, TATE2) - if rtn != 0: - print "MPIN_PERCOMPUTE ERROR %s" % rtn - - # Client first pass - rtn = libmpin.MPIN_CLIENT_1(date, MPIN_ID, RNG, X, PIN, TOKEN, SEC, U, UT, TIME_PERMIT) - if rtn != 0: - print "MPIN_CLIENT_1 ERROR %s" % rtn - if DEBUG: - print "X: %s" % toHex(X) - - # 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. - libmpin.MPIN_SERVER_1(date, MPIN_ID, HID, HTID) - - # Server generates Random number Y and sends it to Client - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, Y) - if rtn != 0: - print "libmpin.MPIN_RANDOM_GENERATE(RNG,Y) Error %s" % rtn - if DEBUG: - print "Y: %s" % toHex(Y) - - # Client second pass - rtn = libmpin.MPIN_CLIENT_2(X, Y, SEC) - if rtn != 0: - print "libmpin.MPIN_CLIENT_2(X,Y,SEC) Error %s" % rtn - if DEBUG: - print "V: %s" % toHex(SEC) - - # Server second pass - rtn = libmpin.MPIN_SERVER_2(date, HID, HTID, Y, SERVER_SECRET, U, UT, SEC, E, F) - if rtn != 0: - print "ERROR: Multi Pass %s is not authenticated" % identity - else: - print "SUCCESS: Multi Pass %s is authenticated" % identity - - # Server sends T=w.ID to client - libmpin.MPIN_GET_G1_MULTIPLE(RNG, 0, W, prHID, T) - - # Client sends Z=r.ID to Server - rtn = libmpin.MPIN_GET_G1_MULTIPLE(RNG, 1, R, HASH_MPIN_ID, Z) - if rtn != 0: - print "ERROR: Generating Z %s" % rtn - - libmpin.MPIN_CLIENT_KEY(TATE1, TATE2, PIN, R, X, T, CK) - print "Client Key: %s" % toHex(CK) - - libmpin.MPIN_SERVER_KEY(Z, SERVER_SECRET, W, U, UT, SK) - print "Server Key: %s" % toHex(SK) - - assert toHex(CK) == toHex(SK), "CK == SK" http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/pythonCFFI/mpin.py ---------------------------------------------------------------------- diff --git a/pythonCFFI/mpin.py b/pythonCFFI/mpin.py deleted file mode 100755 index 7032e45..0000000 --- a/pythonCFFI/mpin.py +++ /dev/null @@ -1,572 +0,0 @@ -#!/usr/bin/env python - -""" -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. -""" - - -""" -mpin - -This module use cffi to access the c functions in the mpin library. - -There is also an example usage program in this file. - -""" -import cffi -import platform - -# MPIN Group Size -PGS = 32 -# MPIN Field Size -PFS = 32 -G1 = 2*PFS + 1 -G2 = 4*PFS -# Hash Size -HASH_BYTES = 32 -# AES-GCM IV length -IVL = 12 -# MPIN Symmetric Key Size -PAS = 16 - -ffi = cffi.FFI() -ffi.cdef(""" -typedef struct { -unsigned int ira[21]; /* random number... */ -int rndptr; /* ...array & pointer */ -unsigned int borrow; -int pool_ptr; -char pool[32]; /* random pool */ -} csprng; - -typedef struct -{ - int len; - int max; - char *val; -} octet; - -extern unsigned int MPIN_GET_TIME(void); -extern void MPIN_Y(int,octet *,octet *); -extern void MPIN_HASH_ID(octet *,octet *); -extern int MPIN_EXTRACT_PIN(octet *,int,octet *); -extern int MPIN_CLIENT(int d,octet *ID,csprng *R,octet *x,int pin,octet *T,octet *V,octet *U,octet *UT,octet *TP, octet* MESSAGE, int t, octet *y); -extern int MPIN_CLIENT_1(int,octet *,csprng *,octet *,int,octet *,octet *,octet *,octet *,octet *); -extern int MPIN_RANDOM_GENERATE(csprng *,octet *); -extern int MPIN_CLIENT_2(octet *,octet *,octet *); -extern void MPIN_SERVER_1(int,octet *,octet *,octet *); -extern int MPIN_SERVER_2(int,octet *,octet *,octet *,octet *,octet *,octet *,octet *,octet *,octet *); -extern int MPIN_SERVER(int d,octet *HID,octet *HTID,octet *y,octet *SS,octet *U,octet *UT,octet *V,octet *E,octet *F,octet *ID,octet *MESSAGE, int t); -extern int MPIN_RECOMBINE_G1(octet *,octet *,octet *); -extern int MPIN_RECOMBINE_G2(octet *,octet *,octet *); -extern int MPIN_KANGAROO(octet *,octet *); - -extern int MPIN_ENCODING(csprng *,octet *); -extern int MPIN_DECODING(octet *); - -extern unsigned int MPIN_today(void); -extern void MPIN_CREATE_CSPRNG(csprng *,octet *); -extern void MPIN_KILL_CSPRNG(csprng *); -extern int MPIN_PRECOMPUTE(octet *,octet *,octet *,octet *); -extern int MPIN_SERVER_KEY(octet *Z,octet *SS,octet *w,octet *p,octet *I,octet *U,octet *UT,octet *K); -extern int MPIN_CLIENT_KEY(octet *g1,octet *g2,int pin,octet *r,octet *x,octet *p,octet *T,octet *K); -extern int MPIN_GET_G1_MULTIPLE(csprng *,int,octet *,octet *,octet *); -extern int MPIN_GET_CLIENT_SECRET(octet *,octet *,octet *); -extern int MPIN_GET_CLIENT_PERMIT(int,octet *,octet *,octet *); -extern int MPIN_GET_SERVER_SECRET(octet *,octet *); -extern int MPIN_TEST_PAIRING(octet *,octet *); -extern void hex2bytes(char *hex, char *bin); -extern void generateRandom(csprng*, octet*); -extern int generateOTP(csprng*); -extern void MPIN_AES_GCM_ENCRYPT(octet *K,octet *IV,octet *H,octet *P,octet *C,octet *T); -extern void MPIN_AES_GCM_DECRYPT(octet *K,octet *IV,octet *H,octet *C,octet *P,octet *T); -extern void MPIN_HASH_ALL(octet *I,octet *U,octet *CU,octet *V,octet *Y,octet *R,octet *W,octet *H); - -""") - -if (platform.system() == 'Windows'): - libmpin = ffi.dlopen("libmpin.dll") -elif (platform.system() == 'Darwin'): - libmpin = ffi.dlopen("libmpin.dylib") -else: - libmpin = ffi.dlopen("libmpin.so") - - -def toHex(octetValue): - """Converts an octet type into a string - - Add all the values in an octet into an array. This arrays is then - converted to a string and hex encoded. - - Args:: - - octetValue. An octet type - - Returns:: - - String - - Raises: - Exception - """ - i = 0 - val = [] - while i < octetValue[0].len: - val.append(octetValue[0].val[i]) - i = i+1 - return ''.join(val).encode("hex") - -if __name__ == "__main__": - # Print hex values - DEBUG = False - SINGLE_PASS = False - TIME_PERMITS = True - MPIN_FULL = False - PIN_ERROR = True - USE_ANONYMOUS = False - - if TIME_PERMITS: - date = libmpin.MPIN_today() - else: - date = 0 - - # Seed - seedHex = "3ade3d4a5c698e8910bf92f25d97ceeb7c25ed838901a5cb5db2cf25434c1fe76c7f79b7af2e5e1e4988e4294dbd9bd9fa3960197fb7aec373609fb890d74b16a4b14b2ae7e23b75f15d36c21791272372863c4f8af39980283ae69a79cf4e48e908f9e0" - seed = seedHex.decode("hex") - - # Identity - identity = raw_input("Please enter identity:") - MPIN_ID = ffi.new("octet*") - MPIN_IDval = ffi.new("char [%s]" % len(identity), identity) - MPIN_ID[0].val = MPIN_IDval - MPIN_ID[0].max = len(identity) - MPIN_ID[0].len = len(identity) - - # Master Secret Shares - MS1 = ffi.new("octet*") - MS1val = ffi.new("char []", PGS) - MS1[0].val = MS1val - MS1[0].max = PGS - MS1[0].len = PGS - - MS2 = ffi.new("octet*") - MS2val = ffi.new("char []", PGS) - MS2[0].val = MS2val - MS2[0].max = PGS - MS2[0].len = PGS - - # Hash value of MPIN_ID - HASH_MPIN_ID = ffi.new("octet*") - HASH_MPIN_IDval = ffi.new("char []", HASH_BYTES) - HASH_MPIN_ID[0].val = HASH_MPIN_IDval - HASH_MPIN_ID[0].max = HASH_BYTES - HASH_MPIN_ID[0].len = HASH_BYTES - - # Client secret and shares - CS1 = ffi.new("octet*") - CS1val = ffi.new("char []", G1) - CS1[0].val = CS1val - CS1[0].max = G1 - CS1[0].len = G1 - - CS2 = ffi.new("octet*") - CS2val = ffi.new("char []", G1) - CS2[0].val = CS2val - CS2[0].max = G1 - CS2[0].len = G1 - - SEC = ffi.new("octet*") - SECval = ffi.new("char []", G1) - SEC[0].val = SECval - SEC[0].max = G1 - SEC[0].len = G1 - - # Server secret and shares - SS1 = ffi.new("octet*") - SS1val = ffi.new("char []", G2) - SS1[0].val = SS1val - SS1[0].max = G2 - SS1[0].len = G2 - - SS2 = ffi.new("octet*") - SS2val = ffi.new("char []", G2) - SS2[0].val = SS2val - SS2[0].max = G2 - SS2[0].len = G2 - - SERVER_SECRET = ffi.new("octet*") - SERVER_SECRETval = ffi.new("char []", G2) - SERVER_SECRET[0].val = SERVER_SECRETval - SERVER_SECRET[0].max = G2 - SERVER_SECRET[0].len = G2 - - # Time Permit and shares - TP1 = ffi.new("octet*") - TP1val = ffi.new("char []", G1) - TP1[0].val = TP1val - TP1[0].max = G1 - TP1[0].len = G1 - - TP2 = ffi.new("octet*") - TP2val = ffi.new("char []", G1) - TP2[0].val = TP2val - TP2[0].max = G1 - TP2[0].len = G1 - - TIME_PERMIT = ffi.new("octet*") - TIME_PERMITval = ffi.new("char []", G1) - TIME_PERMIT[0].val = TIME_PERMITval - TIME_PERMIT[0].max = G1 - TIME_PERMIT[0].len = G1 - - # Token stored on computer - TOKEN = ffi.new("octet*") - TOKENval = ffi.new("char []", G1) - TOKEN[0].val = TOKENval - TOKEN[0].max = G1 - TOKEN[0].len = G1 - - # H(ID) - HID = ffi.new("octet*") - HIDval = ffi.new("char []", G1) - HID[0].val = HIDval - HID[0].max = G1 - HID[0].len = G1 - - # H(T|H(ID)) - HTID = ffi.new("octet*") - HTIDval = ffi.new("char []", G1) - HTID[0].val = HTIDval - HTID[0].max = G1 - HTID[0].len = G1 - - UT = ffi.new("octet*") - UTval = ffi.new("char []", G1) - UT[0].val = UTval - UT[0].max = G1 - UT[0].len = G1 - - U = ffi.new("octet*") - Uval = ffi.new("char []", G1) - U[0].val = Uval - U[0].max = G1 - U[0].len = G1 - - X = ffi.new("octet*") - Xval = ffi.new("char []", PGS) - X[0].val = Xval - X[0].max = PGS - X[0].len = PGS - - Y = ffi.new("octet*") - Yval = ffi.new("char []", PGS) - Y[0].val = Yval - Y[0].max = PGS - Y[0].len = PGS - - E = ffi.new("octet*") - Eval = ffi.new("char []", 12*PFS) - E[0].val = Eval - E[0].max = 12*PFS - E[0].len = 12*PFS - - F = ffi.new("octet*") - Fval = ffi.new("char []", 12*PFS) - F[0].val = Fval - F[0].max = 12*PFS - F[0].len = 12*PFS - - # MPIN Full - R = ffi.new("octet*") - Rval = ffi.new("char []", PGS) - R[0].val = Rval - R[0].max = PGS - R[0].len = PGS - - W = ffi.new("octet*") - Wval = ffi.new("char []", PGS) - W[0].val = Wval - W[0].max = PGS - W[0].len = PGS - - Z = ffi.new("octet*") - Zval = ffi.new("char []", G1) - Z[0].val = Zval - Z[0].max = G1 - Z[0].len = G1 - - T = ffi.new("octet*") - Tval = ffi.new("char []", G1) - T[0].val = Tval - T[0].max = G1 - T[0].len = G1 - - TATE1 = ffi.new("octet*") - TATE1val = ffi.new("char []", 12*PFS) - TATE1[0].val = TATE1val - TATE1[0].max = 12*PFS - TATE1[0].len = 12*PFS - - TATE2 = ffi.new("octet*") - TATE2val = ffi.new("char []", 12*PFS) - TATE2[0].val = TATE2val - TATE2[0].max = 12*PFS - TATE2[0].len = 12*PFS - - SK = ffi.new("octet*") - SKval = ffi.new("char []", PAS) - SK[0].val = SKval - SK[0].max = PAS - SK[0].len = PAS - - CK = ffi.new("octet*") - CKval = ffi.new("char []", PAS) - CK[0].val = CKval - CK[0].max = PAS - CK[0].len = PAS - - # Hash value of transmission - HM = ffi.new("octet*") - HMval = ffi.new("char []", HASH_BYTES) - HM[0].val = HMval - HM[0].max = HASH_BYTES - HM[0].len = HASH_BYTES - - if date: - prHID = HTID - if not PIN_ERROR: - U = ffi.NULL - else: - HTID = ffi.NULL - UT = ffi.NULL - prHID = HID - TIME_PERMIT = ffi.NULL - - if not PIN_ERROR: - E = ffi.NULL - F = ffi.NULL - - # Assign a seed value - RAW = ffi.new("octet*") - RAWval = ffi.new("char [%s]" % len(seed), seed) - RAW[0].val = RAWval - RAW[0].len = len(seed) - RAW[0].max = len(seed) - if DEBUG: - print "RAW: %s" % toHex(RAW) - - # random number generator - RNG = ffi.new("csprng*") - libmpin.MPIN_CREATE_CSPRNG(RNG, RAW) - - # Hash MPIN_ID - libmpin.MPIN_HASH_ID(MPIN_ID, HASH_MPIN_ID) - if DEBUG: - print "MPIN_ID: %s" % toHex(MPIN_ID) - print "HASH_MPIN_ID: %s" % toHex(HASH_MPIN_ID) - - if USE_ANONYMOUS: - pID = HASH_MPIN_ID - else: - pID = MPIN_ID - - # Generate master secret for MIRACL and Customer - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS1) - if rtn != 0: - print "libmpin.MPIN_RANDOM_GENERATE(RNG,MS1) Error %s", rtn - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, MS2) - if rtn != 0: - print "libmpin.MPIN_RANDOM_GENERATE(RNG,MS2) Error %s" % rtn - if DEBUG: - print "MS1: %s" % toHex(MS1) - print "MS2: %s" % toHex(MS2) - - # Generate server secret shares - rtn = libmpin.MPIN_GET_SERVER_SECRET(MS1, SS1) - if rtn != 0: - print "libmpin.MPIN_GET_SERVER_SECRET(MS1,SS1) Error %s" % rtn - rtn = libmpin.MPIN_GET_SERVER_SECRET(MS2, SS2) - if rtn != 0: - print "libmpin.MPIN_GET_SERVER_SECRET(MS2,SS2) Error %s" % rtn - if DEBUG: - print "SS1: %s" % toHex(SS1) - print "SS2: %s" % toHex(SS2) - - # Combine server secret shares - rtn = libmpin.MPIN_RECOMBINE_G2(SS1, SS2, SERVER_SECRET) - if rtn != 0: - print "libmpin.MPIN_RECOMBINE_G2( SS1, SS2, SERVER_SECRET) Error %s" % rtn - if DEBUG: - print "SERVER_SECRET: %s" % toHex(SERVER_SECRET) - - # Generate client secret shares - rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS1, HASH_MPIN_ID, CS1) - if rtn != 0: - print "libmpin.MPIN_GET_CLIENT_SECRET(MS1,HASH_MPIN_ID,CS1) Error %s" % rtn - rtn = libmpin.MPIN_GET_CLIENT_SECRET(MS2, HASH_MPIN_ID, CS2) - if rtn != 0: - print "libmpin.MPIN_GET_CLIENT_SECRET(MS2,HASH_MPIN_ID,CS2) Error %s" % rtn - if DEBUG: - print "CS1: %s" % toHex(CS1) - print "CS2: %s" % toHex(CS2) - - # Combine client secret shares : TOKEN is the full client secret - rtn = libmpin.MPIN_RECOMBINE_G1(CS1, CS2, TOKEN) - if rtn != 0: - print "libmpin.MPIN_RECOMBINE_G1( CS1, CS2, TOKEN) Error %s" % rtn - print "Client Secret: %s" % toHex(TOKEN) - - # Generate Time Permit shares - if DEBUG: - print "Date %s" % date - rtn = libmpin.MPIN_GET_CLIENT_PERMIT(date, MS1, HASH_MPIN_ID, TP1) - if rtn != 0: - print "libmpin.MPIN_GET_CLIENT_PERMIT(date,MS1,HASH_MPIN_ID,TP1) Error %s" % rtn - rtn = libmpin.MPIN_GET_CLIENT_PERMIT(date, MS2, HASH_MPIN_ID, TP2) - if rtn != 0: - print "libmpin.MPIN_GET_CLIENT_PERMIT(date,MS2,HASH_MPIN_ID,TP2) Error %s" % rtn - if DEBUG: - print "TP1: %s" % toHex(TP1) - print "TP2: %s" % toHex(TP2) - - # Combine Time Permit shares - rtn = libmpin.MPIN_RECOMBINE_G1(TP1, TP2, TIME_PERMIT) - if rtn != 0: - print "libmpin.MPIN_RECOMBINE_G1(TP1, TP2, TIME_PERMIT) Error %s" % rtn - if DEBUG: - print "TIME_PERMIT: %s" % toHex(TIME_PERMIT) - - # Client extracts PIN from secret to create Token - PIN = int(raw_input("Please enter four digit PIN to create M-Pin Token:")) - rtn = libmpin.MPIN_EXTRACT_PIN(MPIN_ID, PIN, TOKEN) - if rtn != 0: - print "libmpin.MPIN_EXTRACT_PIN( MPIN_ID, PIN, TOKEN) Error %s" % rtn - print "Token: %s" % toHex(TOKEN) - - if SINGLE_PASS: - print "M-Pin Single Pass" - PIN = int(raw_input("Please enter PIN to authenticate:")) - TimeValue = libmpin.MPIN_GET_TIME() - if DEBUG: - print "TimeValue %s" % TimeValue - - # Client precomputation - if MPIN_FULL: - libmpin.MPIN_PRECOMPUTE(TOKEN, HASH_MPIN_ID, TATE1, TATE2) - - # Client MPIN - rtn = libmpin.MPIN_CLIENT(date, MPIN_ID, RNG, X, PIN, TOKEN, SEC, U, UT, TIME_PERMIT, ffi.NULL, TimeValue, Y) - if rtn != 0: - print "MPIN_CLIENT ERROR %s" % rtn - if DEBUG: - print "X: %s" % toHex(X) - - # Client sends Z=r.ID to Server - if MPIN_FULL: - libmpin.MPIN_GET_G1_MULTIPLE(RNG, 1, R, HASH_MPIN_ID, Z) - - # Server MPIN - rtn = libmpin.MPIN_SERVER(date, HID, HTID, Y, SERVER_SECRET, U, UT, SEC, E, F, pID, ffi.NULL, TimeValue) - if rtn != 0: - print "ERROR: Single Pass %s is not authenticated" % identity - if PIN_ERROR: - err = libmpin.MPIN_KANGAROO(E, F) - print "Client PIN error %d " % err - else: - print "SUCCESS: Single Pass %s is authenticated" % identity - - # Server sends T=w.ID to client - if MPIN_FULL: - libmpin.MPIN_GET_G1_MULTIPLE(RNG, 0, W, prHID, T) - print "T: %s" % toHex(T) - - if MPIN_FULL: - libmpin.MPIN_HASH_ALL(prHID,U,UT,SEC,Y,Z,T,HM); - - libmpin.MPIN_CLIENT_KEY(TATE1, TATE2, PIN, R, X, HM, T, CK) - print "Client AES Key: %s" % toHex(CK) - - libmpin.MPIN_SERVER_KEY(Z, SERVER_SECRET, W, HM, HID, U, UT, SK) - print "Server AES Key: %s" % toHex(SK) - - else: - print "M-Pin Multi Pass" - PIN = int(raw_input("Please enter PIN to authenticate:")) - if MPIN_FULL: - rtn = libmpin.MPIN_PRECOMPUTE(TOKEN, HASH_MPIN_ID, TATE1, TATE2) - if rtn != 0: - print "MPIN_PERCOMPUTE ERROR %s" % rtn - - # Client first pass - rtn = libmpin.MPIN_CLIENT_1(date, MPIN_ID, RNG, X, PIN, TOKEN, SEC, U, UT, TIME_PERMIT) - if rtn != 0: - print "MPIN_CLIENT_1 ERROR %s" % rtn - if DEBUG: - print "X: %s" % toHex(X) - - # 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. - libmpin.MPIN_SERVER_1(date, pID, HID, HTID) - - # Server generates Random number Y and sends it to Client - rtn = libmpin.MPIN_RANDOM_GENERATE(RNG, Y) - if rtn != 0: - print "libmpin.MPIN_RANDOM_GENERATE(RNG,Y) Error %s" % rtn - if DEBUG: - print "Y: %s" % toHex(Y) - - # Client second pass - rtn = libmpin.MPIN_CLIENT_2(X, Y, SEC) - if rtn != 0: - print "libmpin.MPIN_CLIENT_2(X,Y,SEC) Error %s" % rtn - if DEBUG: - print "V: %s" % toHex(SEC) - - # Server second pass - rtn = libmpin.MPIN_SERVER_2(date, HID, HTID, Y, SERVER_SECRET, U, UT, SEC, E, F) - if rtn != 0: - print "ERROR: Multi Pass %s is not authenticated" % identity - if PIN_ERROR: - err = libmpin.MPIN_KANGAROO(E, F) - print "Client PIN error %d " % err - else: - print "SUCCESS: Multi Pass %s is authenticated" % identity - - # Client sends Z=r.ID to Server - if MPIN_FULL: - rtn = libmpin.MPIN_GET_G1_MULTIPLE(RNG, 1, R, HASH_MPIN_ID, Z) - if rtn != 0: - print "ERROR: Generating Z %s" % rtn - - # Server sends T=w.ID to client - if MPIN_FULL: - rtn = libmpin.MPIN_GET_G1_MULTIPLE(RNG, 0, W, prHID, T) - if rtn != 0: - print "ERROR: Generating T %s" % rtn - - libmpin.MPIN_HASH_ALL(HASH_MPIN_ID,U,UT,SEC,Y,Z,T,HM); - - rtn = libmpin.MPIN_CLIENT_KEY(TATE1, TATE2, PIN, R, X, HM, T, CK) - if rtn != 0: - print "ERROR: Generating CK %s" % rtn - print "Client AES Key: %s" % toHex(CK) - - rtn = libmpin.MPIN_SERVER_KEY(Z, SERVER_SECRET, W, HM, HID, U, UT, SK) - if rtn != 0: - print "ERROR: Generating SK %s" % rtn - print "Server AES Key: %s" % toHex(SK) http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/pythonCFFI/wcc.py ---------------------------------------------------------------------- diff --git a/pythonCFFI/wcc.py b/pythonCFFI/wcc.py deleted file mode 100755 index efd991d..0000000 --- a/pythonCFFI/wcc.py +++ /dev/null @@ -1,478 +0,0 @@ -#!/usr/bin/env python - -""" -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. -""" - - -""" -wcc - -This module use cffi to access the c functions in the WCC library. - -There is also an example usage program in this file. - -""" -import cffi -import platform - -# WCC Group Size -PGS = 32 -# WCC Field Size -PFS = 32 -G1 = 2*PFS + 1 -G2 = 4*PFS -# Length of hash -HASH_BYTES = 32 -# AES-GCM IV length -IVL = 12 -# AES Key length -PAS = 16 - -ffi = cffi.FFI() -ffi.cdef(""" -typedef struct { -unsigned int ira[21]; /* random number... */ -int rndptr; /* ...array & pointer */ -unsigned int borrow; -int pool_ptr; -char pool[32]; /* random pool */ -} csprng; - -typedef struct -{ - int len; - int max; - char *val; -} octet; - -extern int WCC_RANDOM_GENERATE(csprng *RNG,octet* S); -extern void WCC_Hq(octet *A,octet *B,octet *C,octet *D,octet *h); -extern int WCC_GET_G2_MULTIPLE(int hashDone,octet *S,octet *ID,octet *VG2); -extern int WCC_GET_G1_MULTIPLE(int hashDone,octet *S,octet *ID,octet *VG1); -extern int WCC_GET_G1_TPMULT(int date, octet *S,octet *ID,octet *VG1); -extern int WCC_GET_G2_TPMULT(int date, octet *S,octet *ID,octet *VG2); -extern int WCC_GET_G1_PERMIT(int date,octet *S,octet *HID,octet *G1TP); -extern int WCC_GET_G2_PERMIT(int date,octet *S,octet *HID,octet *G2TP); -extern int WCC_SENDER_KEY(int date, octet *xOct, octet *piaOct, octet *pibOct, octet *PbG2Oct, octet *PgG1Oct, octet *AKeyG1Oct, octet *ATPG1Oct, octet *IdBOct, octet *AESKeyOct); -extern int WCC_RECEIVER_KEY(int date, octet *yOct, octet *wOct, octet *piaOct, octet *pibOct, octet *PaG1Oct, octet *PgG1Oct, octet *BKeyG2Oct,octet *BTPG2Oct, octet *IdAOct, octet *AESKeyOct); -extern void WCC_AES_GCM_ENCRYPT(octet *K,octet *IV,octet *H,octet *P,octet *C,octet *T); -extern void WCC_AES_GCM_DECRYPT(octet *K,octet *IV,octet *H,octet *C,octet *P,octet *T); -extern void WCC_HASH_ID(octet *,octet *); -extern int WCC_RECOMBINE_G1(octet *,octet *,octet *); -extern int WCC_RECOMBINE_G2(octet *,octet *,octet *); -extern unsigned int WCC_today(void); -extern void WCC_CREATE_CSPRNG(csprng *,octet *); -extern void WCC_KILL_CSPRNG(csprng *RNG); -extern void version(char* info); - -""") - -if (platform.system() == 'Windows'): - libwcc = ffi.dlopen("libwcc.dll") -elif (platform.system() == 'Darwin'): - libwcc = ffi.dlopen("libwcc.dylib") -else: - libwcc = ffi.dlopen("libwcc.so") - - -def toHex(octetValue): - """Converts an octet type into a string - - Add all the values in an octet into an array. This arrays is then - converted to a string and hex encoded. - - Args:: - - octetValue. An octet type - - Returns:: - - String - - Raises: - Exception - """ - i = 0 - val = [] - while i < octetValue[0].len: - val.append(octetValue[0].val[i]) - i = i+1 - return ''.join(val).encode("hex") - - -if __name__ == "__main__": - # Print hex values - DEBUG = False - - build_version = ffi.new("char []", 256) - libwcc.version(build_version) - print ffi.string(build_version) - - # Seed - seedHex = "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20" - seed = seedHex.decode("hex") - - # Master Secret Shares - MS1 = ffi.new("octet*") - MS1val = ffi.new("char []", PGS) - MS1[0].val = MS1val - MS1[0].max = PGS - MS1[0].len = PGS - - MS2 = ffi.new("octet*") - MS2val = ffi.new("char []", PGS) - MS2[0].val = MS2val - MS2[0].max = PGS - MS2[0].len = PGS - - # Alice Identity - alice_id = raw_input("Please enter Alice's identity:") - IdA = ffi.new("octet*") - IdAval = ffi.new("char [%s]" % len(alice_id), alice_id) - IdA[0].val = IdAval - IdA[0].max = len(alice_id) - IdA[0].len = len(alice_id) - - # Hash value of IdA - AHV = ffi.new("octet*") - AHVval = ffi.new("char []", HASH_BYTES) - AHV[0].val = AHVval - AHV[0].max = HASH_BYTES - AHV[0].len = HASH_BYTES - - # Bob Identity - bob_id = raw_input("Please enter Bob's identity:") - IdB = ffi.new("octet*") - IdBval = ffi.new("char [%s]" % len(bob_id), bob_id) - IdB[0].val = IdBval - IdB[0].max = len(bob_id) - IdB[0].len = len(bob_id) - - # Hash value of IdB - BHV = ffi.new("octet*") - BHVval = ffi.new("char []", HASH_BYTES) - BHV[0].val = BHVval - BHV[0].max = HASH_BYTES - BHV[0].len = HASH_BYTES - - # Sender keys - A1KeyG1 = ffi.new("octet*") - A1KeyG1val = ffi.new("char []", G1) - A1KeyG1[0].val = A1KeyG1val - A1KeyG1[0].max = G1 - A1KeyG1[0].len = G1 - - A2KeyG1 = ffi.new("octet*") - A2KeyG1val = ffi.new("char []", G1) - A2KeyG1[0].val = A2KeyG1val - A2KeyG1[0].max = G1 - A2KeyG1[0].len = G1 - - AKeyG1 = ffi.new("octet*") - AKeyG1val = ffi.new("char []", G1) - AKeyG1[0].val = AKeyG1val - AKeyG1[0].max = G1 - AKeyG1[0].len = G1 - - # Receiver keys - B1KeyG2 = ffi.new("octet*") - B1KeyG2val = ffi.new("char []", G2) - B1KeyG2[0].val = B1KeyG2val - B1KeyG2[0].max = G2 - B1KeyG2[0].len = G2 - - B2KeyG2 = ffi.new("octet*") - B2KeyG2val = ffi.new("char []", G2) - B2KeyG2[0].val = B2KeyG2val - B2KeyG2[0].max = G2 - B2KeyG2[0].len = G2 - - BKeyG2 = ffi.new("octet*") - BKeyG2val = ffi.new("char []", G2) - BKeyG2[0].val = BKeyG2val - BKeyG2[0].max = G2 - BKeyG2[0].len = G2 - - # Sender time permits - A1TPG1 = ffi.new("octet*") - A1TPG1val = ffi.new("char []", G1) - A1TPG1[0].val = A1TPG1val - A1TPG1[0].max = G1 - A1TPG1[0].len = G1 - - A2TPG1 = ffi.new("octet*") - A2TPG1val = ffi.new("char []", G1) - A2TPG1[0].val = A2TPG1val - A2TPG1[0].max = G1 - A2TPG1[0].len = G1 - - ATPG1 = ffi.new("octet*") - ATPG1val = ffi.new("char []", G1) - ATPG1[0].val = ATPG1val - ATPG1[0].max = G1 - ATPG1[0].len = G1 - - # Receiver time permits - B1TPG2 = ffi.new("octet*") - B1TPG2val = ffi.new("char []", G2) - B1TPG2[0].val = B1TPG2val - B1TPG2[0].max = G2 - B1TPG2[0].len = G2 - - B2TPG2 = ffi.new("octet*") - B2TPG2val = ffi.new("char []", G2) - B2TPG2[0].val = B2TPG2val - B2TPG2[0].max = G2 - B2TPG2[0].len = G2 - - BTPG2 = ffi.new("octet*") - BTPG2val = ffi.new("char []", G2) - BTPG2[0].val = BTPG2val - BTPG2[0].max = G2 - BTPG2[0].len = G2 - - # AES Keys - KEY1 = ffi.new("octet*") - KEY1val = ffi.new("char []", PAS) - KEY1[0].val = KEY1val - KEY1[0].max = PAS - KEY1[0].len = PAS - - KEY2 = ffi.new("octet*") - KEY2val = ffi.new("char []", PAS) - KEY2[0].val = KEY2val - KEY2[0].max = PAS - KEY2[0].len = PAS - - X = ffi.new("octet*") - Xval = ffi.new("char []", PGS) - X[0].val = Xval - X[0].max = PGS - X[0].len = PGS - - Y = ffi.new("octet*") - Yval = ffi.new("char []", PGS) - Y[0].val = Yval - Y[0].max = PGS - Y[0].len = PGS - - W = ffi.new("octet*") - Wval = ffi.new("char []", PGS) - W[0].val = Wval - W[0].max = PGS - W[0].len = PGS - - PIA = ffi.new("octet*") - PIAval = ffi.new("char []", PGS) - PIA[0].val = PIAval - PIA[0].max = PGS - PIA[0].len = PGS - - PIB = ffi.new("octet*") - PIBval = ffi.new("char []", PGS) - PIB[0].val = PIBval - PIB[0].max = PGS - PIB[0].len = PGS - - PaG1 = ffi.new("octet*") - PaG1val = ffi.new("char []", G1) - PaG1[0].val = PaG1val - PaG1[0].max = G1 - PaG1[0].len = G1 - - PgG1 = ffi.new("octet*") - PgG1val = ffi.new("char []", G1) - PgG1[0].val = PgG1val - PgG1[0].max = G1 - PgG1[0].len = G1 - - PbG2 = ffi.new("octet*") - PbG2val = ffi.new("char []", G2) - PbG2[0].val = PbG2val - PbG2[0].max = G2 - PbG2[0].len = G2 - - # Assign a seed value - RAW = ffi.new("octet*") - RAWval = ffi.new("char [%s]" % len(seed), seed) - RAW[0].val = RAWval - RAW[0].len = len(seed) - RAW[0].max = len(seed) - if DEBUG: - print "RAW: %s" % toHex(RAW) - - # random number generator - RNG = ffi.new("csprng*") - libwcc.WCC_CREATE_CSPRNG(RNG, RAW) - - # Today's date in epoch days - date = libwcc.WCC_today() - if DEBUG: - print "Date %s" % date - - # Hash IdA - libwcc.WCC_HASH_ID(IdA, AHV) - if DEBUG: - print "IdA: %s" % toHex(IdA) - print "AHV: %s" % toHex(AHV) - - # Hash IdB - libwcc.WCC_HASH_ID(IdB, BHV) - if DEBUG: - print "IdB: %s" % toHex(IdB) - print "BHV: %s" % toHex(BHV) - - # Generate master secret for MIRACL and Customer - rtn = libwcc.WCC_RANDOM_GENERATE(RNG, MS1) - if rtn != 0: - print "libwcc.WCC_RANDOM_GENERATE(RNG,MS1) Error %s", rtn - rtn = libwcc.WCC_RANDOM_GENERATE(RNG, MS2) - if rtn != 0: - print "libwcc.WCC_RANDOM_GENERATE(RNG,MS2) Error %s" % rtn - if DEBUG: - print "MS1: %s" % toHex(MS1) - print "MS2: %s" % toHex(MS2) - - # Generate Alice's sender key shares - rtn = libwcc.WCC_GET_G1_MULTIPLE(1,MS1, AHV, A1KeyG1) - if rtn != 0: - print "libwcc.WCC_GET_G1_MULTIPLE(MS1,AHV,A1KeyG1) Error %s" % rtn - rtn = libwcc.WCC_GET_G1_MULTIPLE(1,MS2, AHV, A2KeyG1) - if rtn != 0: - print "libwcc.WCC_GET_G1_MULTIPLE(MS2,AHV,A2KeyG1) Error %s" % rtn - if DEBUG: - print "A1KeyG1: %s" % toHex(A1KeyG1) - print "A2KeyG1: %s" % toHex(A2KeyG1) - - # Combine Alices's sender key shares - rtn = libwcc.WCC_RECOMBINE_G1(A1KeyG1, A2KeyG1, AKeyG1) - if rtn != 0: - print "libwcc.WCC_RECOMBINE_G1(A1KeyG1, A2KeyG1, AKeyG1) Error %s" % rtn - print "AKeyG1: %s" % toHex(AKeyG1) - - # Generate Alice's sender time permit shares - rtn = libwcc.WCC_GET_G1_PERMIT(date, MS1, AHV, A1TPG1) - if rtn != 0: - print "libwcc.WCC_GET_G1_PERMIT(date,MS1,AHV,A1TPG1) Error %s" % rtn - rtn = libwcc.WCC_GET_G1_PERMIT(date, MS2, AHV, A2TPG1) - if rtn != 0: - print "libwcc.WCC_GET_G1_PERMIT(date,MS2,AHV,A2TPG1) Error %s" % rtn - if DEBUG: - print "A1TPG1: %s" % toHex(A1TPG1) - print "A2TPG1: %s" % toHex(A2TPG1) - - # Combine Alice's sender Time Permit shares - rtn = libwcc.WCC_RECOMBINE_G1(A1TPG1, A2TPG1, ATPG1) - if rtn != 0: - print "libwcc.WCC_RECOMBINE_G1(A1TPG1, A2TPG1, ATPG1) Error %s" % rtn - print "ATPG1: %s" % toHex(ATPG1) - - # Generate Bob's receiver secret key shares - rtn = libwcc.WCC_GET_G2_MULTIPLE(1,MS1, BHV, B1KeyG2) - if rtn != 0: - print "libwcc.WCC_GET_G2_MULTIPLE(MS1,BHV,B1KeyG2) Error %s" % rtn - rtn = libwcc.WCC_GET_G2_MULTIPLE(1,MS2, BHV, B2KeyG2) - if rtn != 0: - print "libwcc.WCC_GET_G2_MULTIPLE(MS2,BHV,B2KeyG2) Error %s" % rtn - if DEBUG: - print "B1KeyG2: %s" % toHex(B1KeyG2) - print "B2KeyG2: %s" % toHex(B2KeyG2) - - # Combine Bobs's receiver secret key shares - rtn = libwcc.WCC_RECOMBINE_G2(B1KeyG2, B2KeyG2, BKeyG2) - if rtn != 0: - print "libwcc.WCC_RECOMBINE_G2(B1KeyG2, B2KeyG2, BKeyG2) Error %s" % rtn - print "BKeyG2: %s" % toHex(BKeyG2) - - # Generate Bob's receiver time permit shares - rtn = libwcc.WCC_GET_G2_PERMIT(date, MS1, BHV, B1TPG2) - if rtn != 0: - print "libwcc.WCC_GET_G2_PERMIT(date,MS1,BHV,B1TPG2) Error %s" % rtn - rtn = libwcc.WCC_GET_G2_PERMIT(date, MS2, BHV, B2TPG2) - if rtn != 0: - print "libwcc.WCC_GET_G2_PERMIT(date,MS2,BHV,B2TPG2) Error %s" % rtn - if DEBUG: - print "B1TPG2: %s" % toHex(B1TPG2) - print "B2TPG2: %s" % toHex(B2TPG2) - - # Combine Bob's receiver time permit shares - rtn = libwcc.WCC_RECOMBINE_G2(B1TPG2, B2TPG2, BTPG2) - if rtn != 0: - print "libwcc.WCC_RECOMBINE_G2(B1TPG2, B2TPG2, BTPG2) Error %s" % rtn - print "BTPG2: %s" % toHex(BTPG2) - - rtn = libwcc.WCC_RANDOM_GENERATE(RNG, X) - if rtn != 0: - print "libwcc.WCC_RANDOM_GENERATE(RNG,X) Error %s", rtn - if DEBUG: - print "X: %s" % toHex(X) - - rtn = libwcc.WCC_GET_G1_TPMULT(date,X,IdA,PaG1); - if rtn != 0: - print "libwcc.WCC_GET_G1_TPMULT(date,X,IdA,PaG1) Error %s", rtn - if DEBUG: - print "PaG1: %s" % toHex(PaG1) - - rtn = libwcc.WCC_RANDOM_GENERATE(RNG, W) - if rtn != 0: - print "libwcc.WCC_RANDOM_GENERATE(RNG,W) Error %s", rtn - if DEBUG: - print "W: %s" % toHex(W) - - rtn = libwcc.WCC_GET_G1_TPMULT(date,W,IdA,PgG1); - if rtn != 0: - print "libwcc.WCC_GET_G1_TPMULT(date,W,IdA,PgG1) Error %s", rtn - if DEBUG: - print "PgG1: %s" % toHex(PgG1) - - rtn = libwcc.WCC_RANDOM_GENERATE(RNG, Y) - if rtn != 0: - print "libwcc.WCC_RANDOM_GENERATE(RNG,Y) Error %s", rtn - if DEBUG: - print "Y: %s" % toHex(Y) - - rtn = libwcc.WCC_GET_G2_TPMULT(date,Y,IdB,PbG2); - if rtn != 0: - print "libwcc.WCC_GET_G1_TPMULT(date,Y,IdB,PbG2) Error %s", rtn - if DEBUG: - print "PbG2: %s" % toHex(PbG2) - - # PIA = Hq(PaG1,PbG2,PgG1,IdB) - libwcc.WCC_Hq(PaG1,PbG2,PgG1,IdB,PIA); - if DEBUG: - print "PIA: %s" % toHex(PIA) - - # PIB = Hq(PbG2,PaG1,PgG1,IdA) - libwcc.WCC_Hq(PbG2,PaG1,PgG1,IdA,PIB); - if DEBUG: - print "PIB: %s" % toHex(PIB) - - # Alice calculates AES Key - rtn = libwcc.WCC_SENDER_KEY(date, X, PIA, PIB, PbG2, PgG1, AKeyG1, ATPG1, IdB, KEY1) - if rtn != 0: - print "libwcc.WCC_SENDER_KEY(date, X, PIA, PIB, PbG2, PgG1, AKeyG1, ATPG1, IdB, KEY1) Error %s" % rtn - print "{0}'s AES Key: {1}".format(alice_id, toHex(KEY1)) - - # Bob calculates AES Key - rtn = libwcc.WCC_RECEIVER_KEY(date, Y, W, PIA, PIB, PaG1, PgG1, BKeyG2, BTPG2, IdA, KEY2) - if rtn != 0: - print "libwcc.WCC_RECEIVER_KEY(date, Y, W, PIA, PIB, PaG1, PgG1, BKeyG2, BTPG2, IdA, KEY2) Error %s" % rtn - print "{0}'s AES Key: {1}".format(bob_id, toHex(KEY2)) - - libwcc.WCC_KILL_CSPRNG(RNG) http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/readme.txt ---------------------------------------------------------------------- diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..5469379 --- /dev/null +++ b/readme.txt @@ -0,0 +1,41 @@ +The Apache Milagro Cryptographic Library + +Note that the AMCL currently comes in two versions, version 2.2 +and version 3.1 + +AMCL v2.2 is presented in what might be called a pre-library state. + +In the various supported languages the source code is made available, +but it is not organised into rigid packages/crates/jars/whatever +It is expected that the consumer will themselves take this final step, +depending on the exact requirements of their project. + +Note that version 2.2 is no longer supported. + +AMCL v3.1 uses a standard Python 3 script to build libraries in all +supported languages. New users should use this version. + +The main improvement is that AMCL v3 can optionally simultaneously support +multiple elliptic curves and RSA key sizes within a single appliction. + +Note that AMCL is largely configured at compile time. In version 3 this +configuration is handled by the Python script. + +AMCL is available in 32-bit and 64-bit versions in most languages. Limited +support for 16-bit processors is provided by the C version. + +Now languages like to remain "standard" irrespective of the underlying +hardware. However when it comes to optimal performance, it is impossible +to remain architecture-agnostic. If a processor supports 64-bit +instructions that operate on 64-bit registers, it will be a waste not to +use them. Therefore the 64-bit language versions should always be used +on 64-bit processors. + +Version 3.1 is a major "under the hood" upgrade. Field arithmetic is +performed using ideas from http://eprint.iacr.org/2017/437 to ensure +that critical calculations are performed in constant time. This strongly +mitigates against side-channel attacks. Exception-free formulae are +now used for Weierstrass elliptic curves. A new standardised script +builds for the same set of curves across all languages. + + http://git-wip-us.apache.org/repos/asf/incubator-milagro-crypto/blob/70e3a3a3/swift/TestECDH.swift ---------------------------------------------------------------------- diff --git a/swift/TestECDH.swift b/swift/TestECDH.swift deleted file mode 100644 index 7070770..0000000 --- a/swift/TestECDH.swift +++ /dev/null @@ -1,164 +0,0 @@ -/* -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. -*/ -// -// TestECDH.swift -// -// -// Created by Michael Scott on 02/07/2015. -// Copyright (c) 2015 Michael Scott. All rights reserved. -// - -import Foundation -import clint // comment out for Xcode - -public func TestECDH() -{ - let pp=String("M0ng00se"); - - let EGS=ECDH.EGS - let EFS=ECDH.EFS - let EAS=AES.KS - - var S1=[UInt8](count:EGS,repeatedValue:0) - var W0=[UInt8](count:2*EFS+1,repeatedValue:0) - var W1=[UInt8](count:2*EFS+1,repeatedValue:0) - var Z0=[UInt8](count:EFS,repeatedValue:0) - var Z1=[UInt8](count:EFS,repeatedValue:0) - var RAW=[UInt8](count:100,repeatedValue:0) - var SALT=[UInt8](count:8,repeatedValue:0) - var P1=[UInt8](count:3,repeatedValue:0) - var P2=[UInt8](count:4,repeatedValue:0) - var V=[UInt8](count:2*EFS+1,repeatedValue:0) - var M=[UInt8](count:17,repeatedValue:0) - var T=[UInt8](count:12,repeatedValue:0) - var CS=[UInt8](count:EGS,repeatedValue:0) - var DS=[UInt8](count:EGS,repeatedValue:0) - - let rng=RAND() - - rng.clean(); - for var i=0;i<100;i++ {RAW[i]=UInt8(i&0xff)} - - rng.seed(100,RAW) - - - for var i=0;i<8;i++ {SALT[i]=UInt8(i+1)} // set Salt - - print("Alice's Passphrase= "+pp) - let PW=[UInt8](pp.utf8) - - /* private key S0 of size EGS bytes derived from Password and Salt */ - - var S0=ECDH.PBKDF2(PW,SALT,1000,EGS) - print("Alice's private key= 0x",terminator: ""); ECDH.printBinary(S0) - - /* Generate Key pair S/W */ - ECDH.KEY_PAIR_GENERATE(nil,&S0,&W0); - - print("Alice's public key= 0x",terminator: ""); ECDH.printBinary(W0) - - var res=ECDH.PUBLIC_KEY_VALIDATE(true,W0); - - if res != 0 - { - print("ECP Public Key is invalid!"); - return; - } - - /* Random private key for other party */ - ECDH.KEY_PAIR_GENERATE(rng,&S1,&W1) - - print("Servers private key= 0x",terminator: ""); ECDH.printBinary(S1) - - print("Servers public key= 0x",terminator: ""); ECDH.printBinary(W1); - - res=ECDH.PUBLIC_KEY_VALIDATE(true,W1) - if res != 0 - { - print("ECP Public Key is invalid!") - return - } - - /* Calculate common key using DH - IEEE 1363 method */ - - ECDH.ECPSVDP_DH(S0,W1,&Z0) - ECDH.ECPSVDP_DH(S1,W0,&Z1) - - var same=true - for var i=0;i<EFS;i++ - { - if Z0[i] != Z1[i] {same=false} - } - - if (!same) - { - print("*** ECPSVDP-DH Failed") - return - } - - let KEY=ECDH.KDF1(Z0,EAS) - - print("Alice's DH Key= 0x",terminator: ""); ECDH.printBinary(KEY) - print("Servers DH Key= 0x",terminator: ""); ECDH.printBinary(KEY) - - print("Testing ECIES") - - P1[0]=0x0; P1[1]=0x1; P1[2]=0x2 - P2[0]=0x0; P2[1]=0x1; P2[2]=0x2; P2[3]=0x3 - - for var i=0;i<=16;i++ {M[i]=UInt8(i&0xff)} - - let C=ECDH.ECIES_ENCRYPT(P1,P2,rng,W1,M,&V,&T) - - print("Ciphertext= ") - print("V= 0x",terminator: ""); ECDH.printBinary(V) - print("C= 0x",terminator: ""); ECDH.printBinary(C) - print("T= 0x",terminator: ""); ECDH.printBinary(T) - - M=ECDH.ECIES_DECRYPT(P1,P2,V,C,T,S1) - if M.count==0 - { - print("*** ECIES Decryption Failed\n") - return - } - else {print("Decryption succeeded")} - - print("Message is 0x"); ECDH.printBinary(M) - - print("Testing ECDSA") - - if ECDH.ECPSP_DSA(rng,S0,M,&CS,&DS) != 0 - { - print("***ECDSA Signature Failed") - return - } - print("Signature= ") - print("C= 0x",terminator: ""); ECDH.printBinary(CS) - print("D= 0x",terminator: ""); ECDH.printBinary(DS) - - if ECDH.ECPVP_DSA(W0,M,CS,DS) != 0 - { - print("***ECDSA Verification Failed") - return - } - else {print("ECDSA Signature/Verification succeeded ")} - -} - -TestECDH() // comment out for Xcode
