Source code for pksig_waters05

'''David Naccache based Identity-Based Encryption
 
| From: "David Naccache Secure and Practical Identity-Based Encryption Section 4"
| Available from: http://eprint.iacr.org/2005/369.pdf

* type:			encryption (identity-based)
* setting:		bilinear groups (asymmetric)

:Authors:	Gary Belvin
:Date:		06/2011

:Improved by: Fan Zhang(zfwise@gwu.edu), supported by GWU computer science department
:Date: 3/2013
:Notes:
1. e(g1,g2) is pre-calculated as part of public parameters.
2. g1 and g2 have been swapped. In the original scheme, signature happens in G2
but now, it happens in G1.
3. I stored U_z and u as part of mk. This will speed up the sign() a lot.
The trick is that, instead of doing exponential operation and then multiply
all together, I compute the exponent first and then do one exponential operation
''' 

from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair
from charm.toolbox.PKSig import PKSig
from charm.toolbox.enum import Enum
from charm.toolbox.hash_module import Waters
import math

debug = False
[docs]class IBE_N04_Sig(PKSig): """ >>> from charm.toolbox.pairinggroup import PairingGroup >>> group = PairingGroup('SS512') >>> waters = Waters(group) >>> ibe = IBE_N04_Sig(group) >>> (public_key, secret_key) = ibe.keygen() >>> ID = "bob@example.com" >>> msg = waters.hash("This is a test.") >>> signature = ibe.sign(public_key, secret_key, msg) >>> ibe.verify(public_key, msg, signature) True """ """Implementation of David Naccahe Identity Based Encryption""" def __init__(self, groupObj): PKSig.__init__(self) #PKSig.setProperty(self, secdef='IND_ID_CPA', assumption='DBDH', secmodel='Standard') #, other={'id':ZR} #message_space=[GT, 'KEM'] global group group = groupObj
[docs] def keygen(self, l=32): """l is the security parameter with l = 32, and the hash function at 256 bits = n * l with n = 8""" global waters g = group.random(G2) # generator for group G of prime order p #hLen = sha1_len * 8 #int(math.floor(hLen / l)) sha2_byte_len = 32 hLen = sha2_byte_len * 8 n = int(math.floor(hLen / l)) waters = Waters(group, n, l, 'sha256') alpha = group.random(ZR) #from Zp g2 = g ** alpha g1 = group.random(G1) u = group.random(ZR) uprime = g ** u U_z = [group.random(ZR) for x in range(n)] U = [g ** x for x in U_z] pk = {'g':g, 'g1':g1, 'g2': g2, 'uPrime':uprime, 'U': U, 'n':n, 'l':l, 'egg': pair(g1, g2) } mk = {'g1^alpha':g1 ** alpha, 'U_z':U_z, 'u':u} #master secret if debug: print(mk) return (pk, mk)
[docs] def sign(self, pk, sk, m): """v = (v1, .., vn) is an identity""" r = group.random(ZR) u = sk['u'] for i in range(pk['n']): u += sk['U_z'][i] * m[i] d1 = sk['g1^alpha'] * (pk['g1'] ** (u * r)) d2 = pk['g1'] ** r return {'d1': d1, 'd2':d2}
[docs] def verify(self, pk, msg, sig): c3 = pk['uPrime'] for i in range(pk['n']): c3 *= pk['U'][i] ** msg[i] return pk['egg'] == (pair(sig['d1'], pk['g']) / pair(sig['d2'], c3))
[docs]def main(): groupObj = PairingGroup('SS512') ibe = IBE_N04_Sig(groupObj) waters = Waters(group) (pk, sk) = ibe.keygen() # represents public identity M = "bob@example.com" msg = waters.hash("This is a test.") sig = ibe.sign(pk, sk, msg) if debug: print("original msg => '%s'" % M) print("msg => '%s'" % msg) print("sig => '%s'" % sig) assert ibe.verify(pk, msg, sig), "Failed verification!" if debug: print("Successful Verification!!! msg => '%s'" % msg)
if __name__ == '__main__': debug = True main()