| # Elliptic Curve Hybrid Encryption Scheme |
| # |
| # COPYRIGHT (c) 2010 by Toni Mattis <solaris@live.de> |
| # |
| |
| from curves import get_curve |
| from elliptic import mulp |
| from encoding import enc_long |
| from random import SystemRandom |
| from Rabbit import Rabbit |
| |
| # important for cryptographically secure random numbers: |
| random = SystemRandom() |
| |
| # Encryption Algorithm: |
| # --------------------- |
| # Input: Message M, public key Q |
| # |
| # 0. retrieve the group from which Q was generated. |
| # 1. generate random number k between 1 and the group order. |
| # 2. compute KG = k * G (where G is the base point of the group). |
| # 3. compute SG = k * Q (where Q is the public key of the receiver). |
| # 4. symmetrically encrypt M to M' using SG's x-coordinate as key. |
| # |
| # Return: Ciphertext M', temporary key KG |
| |
| |
| def encrypt(message, qk, encrypter = Rabbit): |
| '''Encrypt a message using public key qk => (ciphertext, temp. pubkey)''' |
| bits, q = qk |
| try: |
| bits, cn, n, cp, cq, g = get_curve(bits) |
| if not n: |
| raise ValueError, "Key size %s not suitable for encryption" % bits |
| except KeyError: |
| raise ValueError, "Key size %s not implemented" % bits |
| |
| k = random.randint(1, n - 1) # temporary private key k |
| kg = mulp(cp, cq, cn, g, k) # temporary public key k*G |
| sg = mulp(cp, cq, cn, q, k) # shared secret k*Q = k*d*G |
| |
| return encrypter(enc_long(sg[0])).encrypt(message), kg |
| |
| # Decryption Algorithm: |
| # --------------------- |
| # Input: Ciphertext M', temporary key KG, private key d |
| # |
| # 0. retrieve the group from which d and KG were generated. |
| # 1. compute SG = q * KG. |
| # 2. symmetrically decrypt M' to M using SG's x-coordinate as key. |
| # |
| # Return: M |
| |
| def decrypt(message, kg, dk, decrypter = Rabbit): |
| '''Decrypt a message using temp. public key kg and private key dk''' |
| bits, d = dk |
| try: |
| bits, cn, n, cp, cq, g = get_curve(bits) |
| except KeyError: |
| raise ValueError, "Key size %s not implemented" % bits |
| |
| sg = mulp(cp, cq, cn, kg, d) # shared secret d*(k*G) = k*d*G |
| return decrypter(enc_long(sg[0])).decrypt(message) |
| |
| |