Source code for pksig_waters

""" 
Waters - Identity-based signatures

| From: "B. Waters - Efficient identity-based encryption without random oracles"
| Published in: EUROCRYPT 2005
| Available from: Vol 3494 of LNCS, pages 320-329
| Notes: 

* type:           signature (ID-based)
* setting:        bilinear groups (asymmetric)

:Authors:    J. Ayo Akinyele
:Date:       11/2011
"""
from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,pair
from charm.toolbox.iterate import dotprod
from charm.toolbox.hash_module import Waters

debug = False
[docs]class WatersSig: """ >>> from charm.toolbox.pairinggroup import PairingGroup >>> group = PairingGroup('SS512') >>> water = WatersSig(group) >>> (master_public_key, master_secret_key) = water.setup(5) >>> ID = 'janedoe@email.com' >>> secret_key = water.keygen(master_public_key, master_secret_key, ID) >>> msg = 'please sign this new message!' >>> signature = water.sign(master_public_key, secret_key, msg) >>> water.verify(master_public_key, ID, msg, signature) True """ def __init__(self, groupObj): global group,lam_func group = groupObj lam_func = lambda i,a,b: a[i] ** b[i]
[docs] def setup(self, z, l=32): global waters waters = Waters(group, z, l) alpha, h = group.random(ZR), group.random(G1) g1, g2 = group.random(G1), group.random(G2) A = pair(h, g2) ** alpha y = [group.random(ZR) for i in range(z)] y1t,y2t = group.random(ZR), group.random(ZR) u1t = g1 ** y1t; u2t = g1 ** y2t u = [g1 ** y[i] for i in range(z)] u1b = g2 ** y1t; u2b = g2 ** y2t ub =[g2 ** y[i] for i in range(z)] msk = h ** alpha mpk = {'g1':g1, 'g2':g2, 'A':A, 'u1t':u1t, 'u2t':u2t, 'u':u, 'u1b':u1b, 'u2b':u2b, 'ub':ub, 'z':z, 'l':l } return (mpk, msk)
[docs] def keygen(self, mpk, msk, ID): if debug: print("Keygen alg...") k = waters.hash(ID) # return list from k1,...,kz if debug: print("k =>", k) r = group.random(ZR) k1 = msk * ((mpk['u1t'] * dotprod(1, -1, mpk['z'], lam_func, mpk['u'], k)) ** r) k2 = mpk['g1'] ** -r return (k1, k2)
[docs] def sign(self, mpk, sk, M): if debug: print("Sign alg...") m = waters.hash(M) # return list from m1,...,mz if debug: print("m =>", m) (k1, k2) = sk s = group.random(ZR) S1 = k1 * ((mpk['u2t'] * dotprod(1, -1, mpk['z'], lam_func, mpk['u'], m)) ** s) S2 = k2 S3 = mpk['g1'] ** -s return {'S1':S1, 'S2':S2, 'S3':S3}
[docs] def verify(self, mpk, ID, M, sig): if debug: print("Verify...") k = waters.hash(ID) m = waters.hash(M) (S1, S2, S3) = sig['S1'], sig['S2'], sig['S3'] A, g2 = mpk['A'], mpk['g2'] comp1 = dotprod(1, -1, mpk['z'], lam_func, mpk['ub'], k) comp2 = dotprod(1, -1, mpk['z'], lam_func, mpk['ub'], m) lhs = (pair(S1, g2) * pair(S2, mpk['u1b'] * comp1) * pair(S3, mpk['u2b'] * comp2)) #if ((pair(S1, g2) * pair(S2, mpk['u1b'] * comp1) * pair(S3, mpk['u2b'] * comp2)) == A): if lhs == A: return True return False
[docs]def main(): groupObj = PairingGroup('SS512') wat = WatersSig(groupObj) (master_public_key, master_secret_key) = wat.setup(5) ID = 'janedoe@email.com' secret_key = wat.keygen(master_public_key, master_secret_key, ID) msg = 'please sign this new message!' sig = wat.sign(master_public_key, secret_key, msg) assert wat.verify(master_public_key, ID, msg, sig), "invalid signature" if debug: print("Successful Verification!")
if __name__ == "__main__": debug = True main()