blob: 3ab661188705f937778b09c9279f91ce390e73c9 [file] [log] [blame]
#!/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
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 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
# 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
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 = 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
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" % toHex(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: %s" % toHex(IdA)
print "HIdA: %s" % toHex(HIdA)
# Hash IdB
libamcl_core.HASH_ID(HASH_TYPE_ZZZ, IdB, HIdB)
if DEBUG:
print "IdB: %s" % toHex(IdB)
print "HIdB: %s" % toHex(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 %s", 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 %s" % rtn
if DEBUG:
print "MS1: %s" % toHex(MS1)
print "MS2: %s" % toHex(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 %s" % 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 %s" % rtn
if DEBUG:
print "A1KeyG1: %s" % toHex(A1KeyG1)
print "A2KeyG1: %s" % toHex(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 %s" % rtn
print "AKeyG1: %s" % toHex(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 %s" % 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 %s" % rtn
if DEBUG:
print "B1KeyG2: %s" % toHex(B1KeyG2)
print "B2KeyG2: %s" % toHex(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 %s" % rtn
print "BKeyG2: %s" % toHex(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 %s", rtn
if DEBUG:
print "X: %s" % toHex(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 %s", rtn
if DEBUG:
print "PaG1: %s" % toHex(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 %s", rtn
if DEBUG:
print "W: %s" % toHex(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 %s", rtn
if DEBUG:
print "PgG1: %s" % toHex(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 %s", rtn
if DEBUG:
print "Y: %s" % toHex(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 %s", rtn
if DEBUG:
print "PbG2: %s" % toHex(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: %s" % toHex(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: %s" % toHex(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 %s" % rtn
print "{0}'s AES Key: {1}".format(alice_id, toHex(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 %s" % rtn
print "{0}'s AES Key: {1}".format(bob_id, toHex(KEY2))
libamcl_core.KILL_CSPRNG(RNG)