Source code for pkenc_cs98

'''
Cramer-Shoup Public Key Encryption Scheme (Decisional Diffie-Hellman Assumption in groups of prime order)
 
| From: "R. Cramer, V. Shoup: A practical public key cryptosystem provably secure against adaptive chosen ciphertext attack"
| Published in: CRYPTO 1998
| Available from: http://knot.kaist.ac.kr/seminar/archive/46/46.pdf
| Notes: 

* type:			encryption (public key)
* setting:		DDH-hard EC groups of prime order (F_p) or Integer Groups
* assumption:	DDH
* Name:         PKEnc_DDH_CCA_CS98

:Authors:	Matthew Green
:Date:			1/2011


'''
from charm.toolbox.ecgroup import G
from charm.toolbox.PKEnc import PKEnc

# type definitions
#pk_t = { 'g1' : G, 'g2' : G, 'c' : G, 'd' : G, 'h' : G }
#sk_t = { 'x1' : ZR, 'x2' : ZR, 'y1' : ZR, 'y2' : ZR, 'z' : ZR }
#c_t = { 'u1' : G, 'u2' : G, 'e' : G, 'v' : G }
#str_t = str

debug = False
[docs]class CS98(PKEnc): """ >>> from charm.toolbox.eccurve import prime192v1 >>> from charm.toolbox.ecgroup import ECGroup >>> groupObj = ECGroup(prime192v1) >>> pkenc = CS98(groupObj) >>> (public_key, secret_key) = pkenc.keygen() >>> msg = b"hello world!!!123456" >>> cipher_text = pkenc.encrypt(public_key, msg) >>> decrypted_msg = pkenc.decrypt(public_key, secret_key, cipher_text) >>> decrypted_msg == msg True >>> from charm.toolbox.integergroup import IntegerGroup, integer >>> p = integer(156053402631691285300957066846581395905893621007563090607988086498527791650834395958624527746916581251903190331297268907675919283232442999706619659475326192111220545726433895802392432934926242553363253333261282122117343404703514696108330984423475697798156574052962658373571332699002716083130212467463571362679) >>> q = integer(78026701315845642650478533423290697952946810503781545303994043249263895825417197979312263873458290625951595165648634453837959641616221499853309829737663096055610272863216947901196216467463121276681626666630641061058671702351757348054165492211737848899078287026481329186785666349501358041565106233731785681339) >>> groupObj = IntegerGroup() >>> pkenc = CS98(groupObj, p, q) >>> (public_key, secret_key) = pkenc.keygen(1024) >>> msg = b"hello world. test message" >>> cipher_text = pkenc.encrypt(public_key, msg) >>> decrypted_msg = pkenc.decrypt(public_key, secret_key, cipher_text) >>> decrypted_msg == msg True """ def __init__(self, groupObj, p=0, q=0): PKEnc.__init__(self) global group group = groupObj if group.groupSetting() == 'integer': group.p, group.q, group.r = p, q, 2 # @output(pk_t, sk_t)
[docs] def keygen(self, secparam=0): if group.groupSetting() == 'integer': if group.p == 0 or group.q == 0: group.paramgen(secparam) p = group.p g1, g2 = group.randomGen(), group.randomGen() elif group.groupSetting() == 'elliptic_curve': group.paramgen(secparam) g1, g2 = group.random(G), group.random(G) x1, x2, y1, y2, z = group.random(), group.random(), group.random(), group.random(), group.random() c = ((g1 ** x1) * (g2 ** x2)) d = ((g1 ** y1) * (g2 ** y2)) h = (g1 ** z) pk = { 'g1' : g1, 'g2' : g2, 'c' : c, 'd' : d, 'h' : h } sk = { 'x1' : x1, 'x2' : x2, 'y1' : y1, 'y2' : y2, 'z' : z } return (pk, sk)
# @input(pk_t, bytes) # @output(c_t)
[docs] def encrypt(self, pk, M): r = group.random() u1 = (pk['g1'] ** r) u2 = (pk['g2'] ** r) e = group.encode(M) * (pk['h'] ** r) alpha = group.hash((u1, u2, e)) v = (pk['c'] ** r) * (pk['d'] ** (r * alpha)) # Assemble the ciphertext c = { 'u1' : u1, 'u2' : u2, 'e' : e, 'v' : v } return c
# @input(pk_t, sk_t, c_t) # @output(bytes)
[docs] def decrypt(self, pk, sk, c): alpha = group.hash((c['u1'], c['u2'], c['e'])) v_prime = (c['u1'] ** (sk['x1'] + (sk['y1'] * alpha))) * (c['u2'] ** (sk['x2'] + (sk['y2'] * alpha))) if (c['v'] != v_prime): return 'ERROR' if debug: print("c['v'] => %s" % c['v']) if debug: print("v' => %s" % v_prime) return group.decode(c['e'] / (c['u1'] ** sk['z']))