Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ashutosh1206
GitHub Repository: ashutosh1206/crypton
Path: blob/master/Elgamal-Encryption/example.py
1402 views
1
#!/usr/bin/env python2.7
2
3
from Crypto.Util.number import bytes_to_long, inverse, long_to_bytes
4
from Crypto.Random.random import randint
5
6
class PublicKey:
7
def __init__(self, h, p, g, q):
8
self.h = h
9
self.p = p
10
self.g = g
11
self.q = q
12
13
class PrivateKey:
14
def __init__(self, x, p, g, q):
15
self.x = x
16
self.p = p
17
self.g = g
18
self.q = q
19
20
21
def _generate_key():
22
"""
23
Generate private-public key pair.
24
For security reasons, either p should be a safe prime or g should have a
25
prime subgroup order. Otherwise it is vulnerable to Short Subgroup Attack.
26
27
:Parameters: _None_
28
29
:Variables:
30
g : int/long
31
Base point for modular exponentiation.
32
p : int/long
33
Modulus for modular exponentiation. Should be a safe prime.
34
x : int/long
35
Receiver's private key, should be kept secret.
36
h : int/long
37
Receiver's public key
38
q : int/long
39
Order of group generated by p and equals p-1
40
41
:Return: A tuple containing a Public Key object (class `PublicKey`) and
42
a Private Key object (class `PrivateKey`)
43
"""
44
# Assigning the largest 1024-bit safe prime as p
45
p = (1 << 1024) - 1093337
46
x = randint(2, p-2)
47
g = 7
48
q = p - 1
49
h = pow(g, x, p)
50
pubkey = PublicKey(h, p, g, q)
51
privkey = PrivateKey(x, p, g, q)
52
return (pubkey, privkey)
53
54
def _encrypt(message, pubkey):
55
"""
56
Encrypt message using ElGamal encryption system
57
58
:Parameters:
59
message : str
60
plaintext to be encrypted
61
pubkey : instance of `PublicKey` class
62
Alice's public key parameters used for encryption
63
64
:Variables:
65
g : int/long
66
Base point for modular exponentiation.
67
p : int/long
68
Modulus for modular exponentiation. Should be a safe prime.
69
h : int/long
70
Receiver's public key
71
q : int/long
72
Order of group generated by p and equals p-1
73
y : int/long
74
Ephemeral key generated by the sender
75
c1, c2: int/long
76
Ciphertext pair
77
s : int/long
78
Shared secret
79
80
:Return:
81
A tuple containing ciphertext pair c1, c2
82
"""
83
h = pubkey.h
84
p = pubkey.p
85
g = pubkey.g
86
q = pubkey.q
87
m = bytes_to_long(message)
88
# Generating ephemeral key: `y`
89
y = randint(2, p-2)
90
c1 = pow(g, y, p)
91
# Computing the shared secret: `s`
92
s = pow(h, y, p)
93
c2 = (m*s) % p
94
return (c1, c2)
95
96
def _decrypt(ciphertext, privkey):
97
"""
98
Decrypt ciphertext using ElGamal Encryption System
99
100
:Parameters:
101
ciphertext : int/long tuple
102
Ciphertext of ElGamal encrypted plaintext
103
privkey : instance of `PrivateKey` class
104
Receiver's private key used for decryption
105
106
:Variables:
107
g : int/long
108
Base point for modular exponentiation.
109
p : int/long
110
Modulus for modular exponentiation. Should be a safe prime.
111
q : int/long
112
Order of group generated by p and equals p-1
113
c1, c2: int/long
114
Ciphertext pair
115
x : int/long
116
Receiver's private key, should be kept secret.
117
s : int/long
118
Shared secret
119
120
"""
121
c1, c2 = ciphertext
122
g = privkey.g
123
p = privkey.p
124
x = privkey.x
125
s = pow(c1, x, p)
126
m = (c2*inverse(s, p)) % p
127
return m
128
129
if __name__ == "__main__":
130
from os import urandom
131
pubkey, privkey = _generate_key()
132
for i in range(100):
133
message = chr(1) + urandom(16)
134
ct = _encrypt(message, pubkey)
135
try:
136
assert long_to_bytes(_decrypt(ct, privkey)) == message
137
except:
138
print "[-] Something's wrong! Check the implementation!"
139
import sys
140
sys.exit()
141
142