Skip to content

Commit

Permalink
GH#90. New ElGamal generators were not square residues.
Browse files Browse the repository at this point in the history
  • Loading branch information
Legrandin committed Feb 2, 2018
1 parent d110046 commit 99c27a3
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 19 deletions.
10 changes: 10 additions & 0 deletions Changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
Changelog
=========

3.4.10 (2 February 2018)
++++++++++++++++++++++++

Resolved issues
---------------

* When creating ElGamal keys, the generator wasn't a square residue:
ElGamal encryption was not secure under the DDH assumption.
Thanks to Weikeng Chen.

3.4.9 (1 February 2018)
+++++++++++++++++++++++

Expand Down
3 changes: 2 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ All the code can be downloaded from `GitHub`_.
News
----

* **1 Feb 2018 (NEW)**. Bugfix release 3.4.9.
* **2 Feb 2018 (NEW)**. Bugfix release 3.4.10.
* 1 Feb 2018. Bugfix release 3.4.9.
* 27 Jan 2018. Bugfix release 3.4.8.
* 26 Aug 2017. Bugfix release 3.4.7.
* 17 May 2017. Bugfix release 3.4.6.
Expand Down
34 changes: 17 additions & 17 deletions lib/Crypto/PublicKey/ElGamal.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,33 +58,33 @@ def generate(bits, randfunc):
q = (obj.p - 1) >> 1

# Generate generator g
# See Algorithm 4.80 in Handbook of Applied Cryptography
# Note that the order of the group is n=p-1=2q, where q is prime
while 1:
# Choose a square residue; it will generate a cyclic group of order q.
obj.g = pow(Integer.random_range(min_inclusive=2,
max_exclusive=obj.p,
randfunc=randfunc), 2, obj.p)

# We must avoid g=2 because of Bleichenbacher's attack described
# in "Generating ElGamal signatures without knowning the secret key",
# 1996
#
obj.g = Integer.random_range(min_inclusive=3,
max_exclusive=obj.p,
randfunc=randfunc)
safe = 1
if pow(obj.g, 2, obj.p)==1:
safe=0
if safe and pow(obj.g, q, obj.p)==1:
safe=0
if obj.g in (1, 2):
continue

# Discard g if it divides p-1 because of the attack described
# in Note 11.67 (iii) in HAC
if safe and (obj.p-1) % obj.g == 0:
safe=0
if (obj.p - 1) % obj.g == 0:
continue

# g^{-1} must not divide p-1 because of Khadir's attack
# described in "Conditions of the generator for forging ElGamal
# signature", 2011
ginv = obj.g.inverse(obj.p)
if safe and (obj.p-1) % ginv == 0:
safe=0
if safe:
break
if (obj.p - 1) % ginv == 0:
continue

# Found
break

# Generate private key x
obj.x = Integer.random_range(min_inclusive=2,
max_exclusive=obj.p-1,
Expand Down
2 changes: 1 addition & 1 deletion lib/Crypto/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__all__ = ['Cipher', 'Hash', 'Protocol', 'PublicKey', 'Util', 'Signature',
'IO', 'Math']

version_info = (3, 4, 9)
version_info = (3, 4, 10)

0 comments on commit 99c27a3

Please # to comment.