python/wcc_ZZZ.py.in (368 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. """ """ 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 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 void CREATE_CSPRNG(csprng *R,octet *S); extern void KILL_CSPRNG(csprng *R); extern int WCC_ZZZ_RANDOM_GENERATE(csprng *RNG,octet* S); extern void WCC_ZZZ_Hq(int sha, octet *A,octet *B,octet *C,octet *D,octet *h); extern void HASH_ID(int sha, octet *,octet *); extern int WCC_ZZZ_GET_G2_MULTIPLE(octet *S,octet *HID,octet *VG2); extern int WCC_ZZZ_GET_G1_MULTIPLE(octet *S,octet *HID,octet *VG1); extern int WCC_ZZZ_SENDER_KEY(int sha, octet *xOct, octet *piaOct, octet *pibOct, octet *PbG2Oct, octet *PgG1Oct, octet *AKeyG1Oct, octet *IdBOct, octet *AESKeyOct); extern int WCC_ZZZ_RECEIVER_KEY(int sha, octet *yOct, octet *wOct, octet *piaOct, octet *pibOct, octet *PaG1Oct, octet *PgG1Oct, octet *BKeyG2Oct, octet *IdAOct, octet *AESKeyOct); extern void AES_GCM_ENCRYPT(octet *K,octet *IV,octet *H,octet *P,octet *C,octet *T); extern void AES_GCM_DECRYPT(octet *K,octet *IV,octet *H,octet *C,octet *P,octet *T); extern int WCC_ZZZ_RECOMBINE_G1(octet *,octet *,octet *); extern int WCC_ZZZ_RECOMBINE_G2(octet *,octet *,octet *); """) if (platform.system() == 'Windows'): libamcl_wcc_ZZZ = ffi.dlopen("libamcl_wcc_ZZZ.dll") libamcl_core = ffi.dlopen("libamcl_core.dll") elif (platform.system() == 'Darwin'): libamcl_wcc_ZZZ = ffi.dlopen("libamcl_wcc_ZZZ.dylib") libamcl_core = ffi.dlopen("libamcl_core.dylib") else: libamcl_wcc_ZZZ = ffi.dlopen("libamcl_wcc_ZZZ.so") libamcl_core = ffi.dlopen("libamcl_core.so") # Group Size PGS = @NB@ # Field Size PFS = @NB@ CURVE_SECURITY = @CS@ if CURVE_SECURITY == 128: G2 = 4 * PFS HASH_TYPE_ZZZ = 32 AESKEY_ZZZ = 16 if CURVE_SECURITY == 192: G2 = 8 * PFS HASH_TYPE_ZZZ = 48 AESKEY_ZZZ = 24 if CURVE_SECURITY == 256: G2 = 16 * PFS HASH_TYPE_ZZZ = 64 AESKEY_ZZZ = 32 G1 = 2 * PFS + 1 # AES-GCM IV length IVL = 12 def to_hex(octet_value): """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:: octet_value. An octet pointer type Returns:: String Raises: Exception """ i = 0 val = [] while i < octet_value.len: val.append(octet_value.val[i]) i = i + 1 out = b'' for x in val: out = out + x return out.hex() if __name__ == "__main__": # Print hex values DEBUG = False # Seed seed_hex = "78d0fb6705ce77dee47d03eb5b9c5d30" seed = bytes.fromhex(seed_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 = input("Please enter Alice's identity:") alice_id_b = alice_id.encode("utf-8") IdA = ffi.new("octet*") IdAval = ffi.new("char [%s]" % len(alice_id_b), alice_id_b) IdA[0].val = IdAval IdA[0].max = len(alice_id_b) IdA[0].len = len(alice_id_b) # Hash value of IdA HIdA = ffi.new("octet*") HIdAval = ffi.new("char []", PFS) HIdA[0].val = HIdAval HIdA[0].max = PFS HIdA[0].len = PFS # Bob Identity bob_id = input("Please enter Bob's identity:") bob_id_b = bob_id.encode("utf-8") IdB = ffi.new("octet*") IdBval = ffi.new("char [%s]" % len(bob_id_b), bob_id_b) IdB[0].val = IdBval IdB[0].max = len(bob_id_b) IdB[0].len = len(bob_id_b) # Hash value of IdB HIdB = ffi.new("octet*") HIdBval = ffi.new("char []", PFS) HIdB[0].val = HIdBval HIdB[0].max = PFS HIdB[0].len = PFS # 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 # AES Keys KEY1 = ffi.new("octet*") KEY1val = ffi.new("char []", AESKEY_ZZZ) KEY1[0].val = KEY1val KEY1[0].max = AESKEY_ZZZ KEY1[0].len = AESKEY_ZZZ KEY2 = ffi.new("octet*") KEY2val = ffi.new("char []", AESKEY_ZZZ) KEY2[0].val = KEY2val KEY2[0].max = AESKEY_ZZZ KEY2[0].len = AESKEY_ZZZ 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 SEED = ffi.new("octet*") SEEDval = ffi.new("char [%s]" % len(seed), seed) SEED[0].val = SEEDval SEED[0].len = len(seed) SEED[0].max = len(seed) if DEBUG: print("SEED: %s" % to_hex(SEED)) # random number generator RNG = ffi.new("csprng*") libamcl_core.CREATE_CSPRNG(RNG, SEED) # Hash IdA libamcl_core.HASH_ID(HASH_TYPE_ZZZ, IdA, HIdA) if DEBUG: print("IdA: {}".format(to_hex(IdA))) print("HIdA: {}".format(to_hex(HIdA))) # Hash IdB libamcl_core.HASH_ID(HASH_TYPE_ZZZ, IdB, HIdB) if DEBUG: print("IdB: {}".format(to_hex(IdB))) print("HIdB: {}".format(to_hex(HIdB))) # Generate master secret for MILAGRO and Customer rtn = libamcl_wcc_ZZZ.WCC_ZZZ_RANDOM_GENERATE(RNG, MS1) if rtn != 0: print("libamcl_wcc_ZZZ.WCC_ZZZ_RANDOM_GENERATE(RNG,MS1) Error {}".format(rtn)) rtn = libamcl_wcc_ZZZ.WCC_ZZZ_RANDOM_GENERATE(RNG, MS2) if rtn != 0: print("libamcl_wcc_ZZZ.WCC_ZZZ_RANDOM_GENERATE(RNG,MS2) Error {}".format(rtn)) if DEBUG: print("MS1: {}".format(to_hex(MS1))) print("MS2: {}".format(to_hex(MS2))) # Generate Alice's sender key shares rtn = libamcl_wcc_ZZZ.WCC_ZZZ_GET_G1_MULTIPLE(MS1, HIdA, A1KeyG1) if rtn != 0: print( "libamcl_wcc_ZZZ.WCC_ZZZ_GET_G1_MULTIPLE(MS1,HIdA,A1KeyG1) Error {}".format(rtn)) rtn = libamcl_wcc_ZZZ.WCC_ZZZ_GET_G1_MULTIPLE(MS2, HIdA, A2KeyG1) if rtn != 0: print( "libamcl_wcc_ZZZ.WCC_ZZZ_GET_G1_MULTIPLE(MS2,HIdA,A2KeyG1) Error {}".format(rtn)) if DEBUG: print("A1KeyG1: {}".format(to_hex(A1KeyG1))) print("A2KeyG1: {}".format(to_hex(A2KeyG1))) # Combine Alices's sender key shares rtn = libamcl_wcc_ZZZ.WCC_ZZZ_RECOMBINE_G1(A1KeyG1, A2KeyG1, AKeyG1) if rtn != 0: print( "libamcl_wcc_ZZZ.WCC_ZZZ_RECOMBINE_G1(A1KeyG1, A2KeyG1, AKeyG1) Error {}".format(rtn)) print("AKeyG1: {}".format(to_hex(AKeyG1))) # Generate Bob's receiver secret key shares rtn = libamcl_wcc_ZZZ.WCC_ZZZ_GET_G2_MULTIPLE(MS1, HIdB, B1KeyG2) if rtn != 0: print( "libamcl_wcc_ZZZ.WCC_ZZZ_GET_G2_MULTIPLE(MS1,HIdB,B1KeyG2) Error {}".format(rtn)) rtn = libamcl_wcc_ZZZ.WCC_ZZZ_GET_G2_MULTIPLE(MS2, HIdB, B2KeyG2) if rtn != 0: print( "libamcl_wcc_ZZZ.WCC_ZZZ_GET_G2_MULTIPLE(MS2,HIdB,B2KeyG2) Error {}".format(rtn)) if DEBUG: print("B1KeyG2: {}".format(to_hex(B1KeyG2))) print("B2KeyG2: {}".format(to_hex(B2KeyG2))) # Combine Bobs's receiver secret key shares rtn = libamcl_wcc_ZZZ.WCC_ZZZ_RECOMBINE_G2(B1KeyG2, B2KeyG2, BKeyG2) if rtn != 0: print( "libamcl_wcc_ZZZ.WCC_ZZZ_RECOMBINE_G2(B1KeyG2, B2KeyG2, BKeyG2) Error {}".format(rtn)) print("BKeyG2: {}".format(to_hex(BKeyG2))) rtn = libamcl_wcc_ZZZ.WCC_ZZZ_RANDOM_GENERATE(RNG, X) if rtn != 0: print("libamcl_wcc_ZZZ.WCC_ZZZ_RANDOM_GENERATE(RNG,X) Error {}".format(rtn)) if DEBUG: print("X: {}".format(to_hex(X))) rtn = libamcl_wcc_ZZZ.WCC_ZZZ_GET_G1_MULTIPLE(X, HIdA, PaG1) if rtn != 0: print( "libamcl_wcc_ZZZ.WCC_ZZZ_GET_G1_MULTIPLE(X,HIdA,PaG1) Error {}".format(rtn)) if DEBUG: print("PaG1: {}".format(to_hex(PaG1))) rtn = libamcl_wcc_ZZZ.WCC_ZZZ_RANDOM_GENERATE(RNG, W) if rtn != 0: print("libamcl_wcc_ZZZ.WCC_ZZZ_RANDOM_GENERATE(RNG,W) Error {}".format(rtn)) if DEBUG: print("W: {}".format(to_hex(W))) rtn = libamcl_wcc_ZZZ.WCC_ZZZ_GET_G1_MULTIPLE(W, HIdA, PgG1) if rtn != 0: print( "libamcl_wcc_ZZZ.WCC_ZZZ_GET_G1_MULTIPLE(W, HIdA, PgG1) Error {}".format(rtn)) if DEBUG: print("PgG1: {}".format(to_hex(PgG1))) rtn = libamcl_wcc_ZZZ.WCC_ZZZ_RANDOM_GENERATE(RNG, Y) if rtn != 0: print("libamcl_wcc_ZZZ.WCC_ZZZ_RANDOM_GENERATE(RNG,Y) Error {}".format(rtn)) if DEBUG: print("Y: {}".format(to_hex(Y))) rtn = libamcl_wcc_ZZZ.WCC_ZZZ_GET_G2_MULTIPLE(Y, HIdB, PbG2) if rtn != 0: print( "libamcl_wcc_ZZZ.WCC_ZZZ_GET_G2_MULTIPLE(Y, HIdB, PbG2) Error {}".format(rtn)) if DEBUG: print("PbG2: {}".format(to_hex(PbG2))) # PIA = Hq(PaG1,PbG2,PgG1,IdB) libamcl_wcc_ZZZ.WCC_ZZZ_Hq(HASH_TYPE_ZZZ, PaG1, PbG2, PgG1, IdB, PIA) if DEBUG: print("PIA: {}".format(to_hex(PIA))) # PIB = Hq(PbG2,PaG1,PgG1,IdA) libamcl_wcc_ZZZ.WCC_ZZZ_Hq(HASH_TYPE_ZZZ, PbG2, PaG1, PgG1, IdA, PIB) if DEBUG: print("PIB: {}".format(to_hex(PIB))) # Alice calculates AES Key rtn = libamcl_wcc_ZZZ.WCC_ZZZ_SENDER_KEY( HASH_TYPE_ZZZ, X, PIA, PIB, PbG2, PgG1, AKeyG1, IdB, KEY1) if rtn != 0: print("libamcl_wcc_ZZZ.WCC_ZZZ_SENDER_KEY(HASH_TYPE_ZZZ, X, PIA, PIB, PbG2, PgG1, AKeyG1, IdB, KEY1) Error {}".format(rtn)) print("{}'s AES Key: {}".format(alice_id, to_hex(KEY1))) # Bob calculates AES Key rtn = libamcl_wcc_ZZZ.WCC_ZZZ_RECEIVER_KEY( HASH_TYPE_ZZZ, Y, W, PIA, PIB, PaG1, PgG1, BKeyG2, IdA, KEY2) if rtn != 0: print("libamcl_wcc_ZZZ.WCC_ZZZ_RECEIVER_KEY(HASH_TYPE_ZZZ, Y, W, PIA, PIB, PaG1, PgG1, BKeyG2, IdA, KEY2) Error {}".format(rtn)) print("{}'s AES Key: {}".format(bob_id, to_hex(KEY2))) libamcl_core.KILL_CSPRNG(RNG)