Identity-based encryption (IBE) was proposed by Adi Shamir in 1984. It is a public-key encryption method where the public key of the user is created using something about their identity, such as their email address. The sender then just has to use that ID to encrypt a message. When receiver the receives the encrypted message they request the decryption key from a trusted central authority. The method used on this page uses pairing-based cryptography with elliptic curves.
ID Encryption |
Theory
Identity-based Encryption (IBE) is an alternative to PKI, and involves generating the encryption key from a piece of identity for the recipitant. For example we could use the email address of the recipitant to generate the key for a destination. For this we have some shared parameters with a trust center that both Bob and Alice trust. If Alice wants to send Bob an email, she takes the parameters from the trust center, and then uses Bob's email address to generate his public key:
When Bob receives the encrypted email, he contacts the trust center and the center generates the private key required to decrypt the email.
Sample run
In the following we take a message of "Hello." and an ID of "[email protected]":
Message: Hello. ID: [email protected] =========================== Public key: Point (34948770870628343857730784459510722101823143645748018547762161050838515596400343778471192164598169160970201577400824570775121371087519194096365870741733594L : 20852140910542551246951800819600960420715346532013273249100728197849570495965469272059329693495325399071544721402807210142026757834887406389387578678556354L : 1L) on Elliptic Curve y^2 = x^3 + 1 over ExtendedFiniteField(50179444633418995760428215518943816084543378339277274339557962861710992916021522142514248292890927025958085436246349332698880745359574857376419559953437557, "x^2+x+1") Secret key: Point (4447444203156231213802545815379408013278003916727118146304600863579533566862208795922873376224684883260713128854799748934825403966898861207420846364984841L : 24816774155329071826716875081512356965317091266257636898884585056343081143081569997147710901810890068953096835741042892580223411499554691724944580165121314L : 1L) on Elliptic Curve y^2 = x^3 + 1 over ExtendedFiniteField(50179444633418995760428215518943816084543378339277274339557962861710992916021522142514248292890927025958085436246349332698880745359574857376419559953437557, "x^2+x+1") =========================== Encrypted Message: eJzNlE1u2zAQhfe8iLMK5p8zB0iAAkYXzQGMRlENF64t2AqQ3L6PTrtqV13VgC2JIjlvvvfou2k6L++7y7xv+JnOp+t6eZ3W86Ut3O6meVre778d5uPL9f7hbZ1PL/PL4+F0WOfHMdj+MvZwnH/Mp7Ut0qbd7vn1cFwPp92unZ+/zxOGtX1evyzW7l4Wb0+b903b0rZdnzZvuBNN7xFK0cmtyMQ6R2SwpRFleXoouzMrCYc6q2m5JFukJsasLIVVs2tFSI/CVbtnlEklu45Laqh5RwV164I7lEYRiQgr6RgqD85kqYrs7jeNl8Npv2lLtP0/0mlLb/sPBDkQFBDMH8R20/Hr9YrdmdpeRrUFRJy4l5mFqnFWAQ+ooEMwyDKIDkpzU+2pelPe8VCOlkIArjNVSWEa1gj4iOOLTkuyCAtotJqU2CMEdaxUJYAoqZsrXnaDK9rDGNtCApADSL8RWTft003s6b8X+wyVN7cGY277xNDwEbB/WcIyPGH9I5eqpDUKB5Nyd6hAHjPQGkN1IY9Io49STBEuUCM2ZqcrmZMmNBpad9wUI6OZoIRkJpEhamgUTQVomNqIHymOgGJmVBfGLBHBGrTFeK1mYxl2gMZ93JrZ/25qqw51DEKC9I6s49R4qVSQdzZsoMGoR/hoBM6IEMM3HZ5BdlcmYkcNgBRIAH1x7QojANTJSbBlonF3RZHA+WJBp/CDoC7gc4dfOF4M/zFzzCHBY7E5jO0MjcIljCMnKOO9c8dBU05JMoaJCaEBregZqeoOn4HIaSyGDKhg7Iju8I9wi01BOtAAFCACDnLWR7wQs0FjnGQ40hElhkHF5IMLA1VpbNt6/xNuGDCO =========================== Decrypted Message: Hello.
Coding
The code is based on [here]:
from ecpy import EllipticCurve, ExtendedFiniteField, symmetric_tate_pairing import hashlib import random import cPickle # PKI secret secret = 0xdeadbeef global P, sP, l p = int("501794446334189957604282155189438160845433783392772743395579628617109" "929160215221425142482928909270259580854362463493326988807453595748573" "76419559953437557") l = (p + 1) / 6 F = ExtendedFiniteField(p, "x^2+x+1") E = EllipticCurve(F, 0, 1) P = E(3, int("1418077311270457886139292292020587683642898636677353664354101171" "7684401801069777797699258667061922178009879315047772033936311133" "535564812495329881887557081")) sP = E(int("129862491850266001914601437161941818413833907050695770313188660767" "152646233571458109764766382285470424230719843324368007925375351295" "39576510740045312772012"), int("452543250979361708074026409576755302296698208397782707067096515523" "033579018123253402743775747767548650767928190884624134827869137911" "24188897792458334596297")) def H(x): return x.x * x.field.p + x.y def get_user_public(E, P, id, l): v = int(hashlib.sha512(id).hexdigest().encode("hex"), 16) return P * v def get_user_secret(E, pubkey, l): global secret return pubkey * secret def encrypt(E, P, sP, pubkey, m, l): assert isinstance(m, (int, long)) # r = rand() r = random.randint(2**30, 2**31) # r*P, m xor e_l(secret * P, Q)^r = e_l(P, Q) ^ (secret * r) return (r * P, m ^ H(E.field(symmetric_tate_pairing(E, sP, pubkey, l) ** r))) def decrypt(E, K, c, l): # c1, c2 = r*P, m xor e_l(secret * P, Q) ^ r = e_l(P, Q) ^ (secret * r) # a = e_l(c1, K) = e_l(r*P, secret * Q) = e_l(P, Q) ^ (secret * r) return c[1] ^ H(E.field(symmetric_tate_pairing(E, c[0], K, l))) msg="hello" ID="fred@home" import sys if (len(sys.argv)>1): msg=str(sys.argv[1]) if (len(sys.argv)>2): ID=str(sys.argv[2]) Q = get_user_public(E, P, ID, l) sQ = get_user_secret(E, Q, l) m = int(msg.strip().encode("hex"), 16) C = encrypt(E, P, sP, Q, m, l) t = tuple(C[0]) c = cPickle.dumps((t[0], t[1], C[1])).encode("zlib").encode("base64") c = c.replace("\n", "") print "Message:\t",msg print "ID:\t",ID print "===========================" print "Encrypted Message: %s" % c print "===========================" d = c.decode("base64").decode("zlib") x, y, c = cPickle.loads(d) C1 = E(x, y) C2 = c C = (C1, C2) m = decrypt(E, sQ, C, l) m = hex(m)[2:-1] if len(m) % 2 == 1: m = "0" + m m = m.decode("hex") print "Decrypted message:", m