Integrated Encryption Scheme (IES) - Discrete logs[ECIES Home][Home]
Integrated Encryption Scheme (IES) is a hybrid encryption scheme which allows Alice to get Bob's public key, and then generate an encryption key based on this public key and her private key. Initially Bob and Alice agree on a generator value (\(g\)) and a prime number (\(p\)). If Bob has a private key of \(b\), he can share his public key of \(B=g^b\). Alice receives this public key (\(B\)), and generates a private key (\(a\)). Alice then computes \(Key=B^a \pmod p\) and which is \(Key=g^{ab} \pmod p\). She will then take a message (\(m\)) and encrypt with this key, and send to Bob with her public key (\(A=g^b \pmod p\)). Bob can then construct this key with \(Key=A^b \pmod p\), and can then decrypt the message [Hybrid (Discrete logs)][Hybrid (Elliptic Curve)].
|
Theory
The Integrated Encryption Scheme (IES) is a hybrid encryption scheme which allows Alice to get Bob's public key, and then generate an encryption key based on this public key and her private key. Initially Bob and Alice agree on a generate value (\(g\)) and a prime number (\(p\)). If Bob has a private key of \(b\), he can share his public key of:
\(B=g^b \pmod p\)
Alice receives this public key, and generates a private key (\(a\)). Alice then computes:
\(Key=B^a \pmod p\)
and which is:
\(Key=g^{ab} \pmod p\)
She will then take a message (\(m\)) and encrypt with this key, and send to Bob with her public key:
\(A=g^a \pmod p\)
Bob can then construct this key with:
\(Key=KDF(A^b \pmod p)\)
and can then decrypt the message. In the following example we use PBKDF2 as the Key Derivation Function (KDF).
Coding
The following is the code:
import sys import random import Padding import binascii from Crypto.Util.number import getPrime from Crypto.Random import get_random_bytes from Crypto.Protocol.KDF import PBKDF2 from Crypto.Hash import SHA256 from Crypto.Cipher import AES primebits=64 msg = "Hello123" def encrypt(plaintext,key, mode): encobj = AES.new(key,mode) return(encobj.encrypt(plaintext)) def decrypt(ciphertext,key, mode): encobj = AES.new(key,mode) return(encobj.decrypt(ciphertext)) if (len(sys.argv)>2): primebits=int(sys.argv[2]) if (len(sys.argv)>2): msg=(sys.argv[1]) p = getPrime(primebits, randfunc=get_random_bytes) g=3 a = random.randint(0, p-1) b = random.randint(0, p-1) A = pow(g,a,p) B = pow(g,b,p) Key=pow(B,a,p) salt = get_random_bytes(16) key = PBKDF2(str(Key), salt, 32, count=1000, hmac_hash_module=SHA256) plaintext = Padding.appendPadding(msg,blocksize=Padding.AES_blocksize,mode=0) ciphertext = encrypt(plaintext.encode(),key,AES.MODE_ECB) print ("Prime: ",p) print ("g: ",g) print ("\nBob's private (b): ",b) print ("Bob's public B (g^b mod p): ",B) print ("\nAlice private (a): ",a) print ("Alice public A (g^a mod p): ",A) print ("\nMessage: ",msg) print ("Key: KDF(g^{ab}) ",binascii.hexlify(bytearray(key)).decode()) print ("Ciphertext: ",binascii.hexlify(bytearray(ciphertext)).decode()) plaintext = decrypt(ciphertext,key,AES.MODE_ECB) plaintext = Padding.removePadding(plaintext.decode(),mode=0) print ("\nBob computes plaintext: ",plaintext)
And a sample run:
Prime: 8416478506687054991102209043232527279335758847975538292195117491567195312725319134563640953333329360142705851747113206242177426116248529707875011852278199 g: 3 Bob's private (b): 6699584622415965947537283709253744817495683102417168746967532742027937753809185333796701050955426326286356161480050736529344284909076840621563104787728349 Bob's public B (g^b mod p): 3768178837015555886507885507893372126914487884847399652285032502857660450270723507666418753164980630598492186176001152503910458321394478211534478263220082 Alice private (a): 5470739281051810814512512335841627840803474931459249369015684012926827768872989239380996381432100280212380466568179218753070408955187854714762085616917428 Alice public A (g^a mod p): 3384022938591466480809728318548388343778881806887436186151966683799645697603324909174016583615809818161251197747511272930973501489135539408911913106649100 Message: Buzz Lightyear Key: KDF(g^{ab}) af772eaa371b7fdea5d2f6686ba50390561de1fa552777e49a7bffe4f1774168 Ciphertext: 911108d83905c93548e2d01061655913 Bob computes plaintext: Buzz Lightyear