Skip to content

Commit 0e464f2

Browse files
authored
Merge pull request #223 from tomato42/small-curves
Add support for small curves
2 parents bbe3679 + 4bd1d1c commit 0e464f2

File tree

13 files changed

+356
-79
lines changed

13 files changed

+356
-79
lines changed

.travis.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ matrix:
1717
include:
1818
- python: 2.7
1919
env: INSTRUMENTAL=yes
20+
dist: bionic
21+
sudo: true
2022
- python: 2.6
2123
env: TOX_ENV=py26
2224
- python: 2.7
@@ -117,17 +119,16 @@ script:
117119
- |
118120
if [[ $INSTRUMENTAL && $TRAVIS_PULL_REQUEST != "false" ]]; then
119121
git checkout $PR_FIRST^
120-
files="$(ls src/ecdsa/test*.py)"
121-
instrumental -t ecdsa -i 'test.*|.*_version|.*_compat' `which pytest` $files
122+
instrumental -t ecdsa -i 'test.*|.*_version|.*_compat' `which pytest` src/ecdsa/test*.py
122123
instrumental -f .instrumental.cov -s
123124
instrumental -f .instrumental.cov -s | python diff-instrumental.py --save .diff-instrumental
124125
git checkout $BRANCH
125-
instrumental -t ecdsa -i 'test.*|.*_version' `which pytest` src/ecdsa
126+
instrumental -t ecdsa -i 'test.*|.*_version|.*_compat' `which pytest` src/ecdsa/test*.py
126127
instrumental -f .instrumental.cov -sr
127128
fi
128129
- |
129130
if [[ $INSTRUMENTAL && $TRAVIS_PULL_REQUEST == "false" ]]; then
130-
instrumental -t ecdsa -i 'test.*|.*_version' `which pytest` src/ecdsa
131+
instrumental -t ecdsa -i 'test.*|.*_version|.*_compat' `which pytest` src/ecdsa
131132
instrumental -f .instrumental.cov -s
132133
# just log the values when merging
133134
instrumental -f .instrumental.cov -s | python diff-instrumental.py

src/ecdsa/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
BRAINPOOLP320r1,
2020
BRAINPOOLP384r1,
2121
BRAINPOOLP512r1,
22+
SECP112r1,
23+
SECP112r2,
24+
SECP128r1,
25+
SECP160r1,
2226
)
2327
from .ecdh import (
2428
ECDH,
@@ -72,5 +76,9 @@
7276
BRAINPOOLP320r1,
7377
BRAINPOOLP384r1,
7478
BRAINPOOLP512r1,
79+
SECP112r1,
80+
SECP112r2,
81+
SECP128r1,
82+
SECP160r1,
7583
]
7684
del _hush_pyflakes

src/ecdsa/curves.py

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
"UnknownCurveError",
1111
"orderlen",
1212
"Curve",
13+
"SECP112r1",
14+
"SECP112r2",
15+
"SECP128r1",
16+
"SECP160r1",
1317
"NIST192p",
1418
"NIST224p",
1519
"NIST256p",
@@ -40,7 +44,7 @@ def __init__(self, name, curve, generator, oid, openssl_name=None):
4044
self.generator = generator
4145
self.order = generator.order()
4246
self.baselen = orderlen(self.order)
43-
self.verifying_key_length = 2 * self.baselen
47+
self.verifying_key_length = 2 * orderlen(curve.p())
4448
self.signature_length = 2 * self.baselen
4549
self.oid = oid
4650
self.encoded_oid = der.encode_oid(*oid)
@@ -49,6 +53,43 @@ def __repr__(self):
4953
return self.name
5054

5155

56+
# the SEC curves
57+
SECP112r1 = Curve(
58+
"SECP112r1",
59+
ecdsa.curve_112r1,
60+
ecdsa.generator_112r1,
61+
(1, 3, 132, 0, 6),
62+
"secp112r1",
63+
)
64+
65+
66+
SECP112r2 = Curve(
67+
"SECP112r2",
68+
ecdsa.curve_112r2,
69+
ecdsa.generator_112r2,
70+
(1, 3, 132, 0, 7),
71+
"secp112r2",
72+
)
73+
74+
75+
SECP128r1 = Curve(
76+
"SECP128r1",
77+
ecdsa.curve_128r1,
78+
ecdsa.generator_128r1,
79+
(1, 3, 132, 0, 28),
80+
"secp128r1",
81+
)
82+
83+
84+
SECP160r1 = Curve(
85+
"SECP160r1",
86+
ecdsa.curve_160r1,
87+
ecdsa.generator_160r1,
88+
(1, 3, 132, 0, 8),
89+
"secp160r1",
90+
)
91+
92+
5293
# the NIST curves
5394
NIST192p = Curve(
5495
"NIST192p",
@@ -167,6 +208,7 @@ def __repr__(self):
167208
)
168209

169210

211+
# no order in particular, but keep previously added curves first
170212
curves = [
171213
NIST192p,
172214
NIST224p,
@@ -181,6 +223,10 @@ def __repr__(self):
181223
BRAINPOOLP320r1,
182224
BRAINPOOLP384r1,
183225
BRAINPOOLP512r1,
226+
SECP112r1,
227+
SECP112r2,
228+
SECP128r1,
229+
SECP160r1,
184230
]
185231

186232

src/ecdsa/ecdh.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ def generate_sharedsecret_bytes(self):
304304
:rtype: byte string
305305
"""
306306
return number_to_string(
307-
self.generate_sharedsecret(), self.private_key.curve.order
307+
self.generate_sharedsecret(), self.private_key.curve.curve.p()
308308
)
309309

310310
def generate_sharedsecret(self):

src/ecdsa/ecdsa.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,74 @@ def point_is_valid(generator, x, y):
294294
return True
295295

296296

297+
# secp112r1 curve
298+
_p = int(remove_whitespace("DB7C 2ABF62E3 5E668076 BEAD208B"), 16)
299+
# s = 00F50B02 8E4D696E 67687561 51752904 72783FB1
300+
_a = int(remove_whitespace("DB7C 2ABF62E3 5E668076 BEAD2088"), 16)
301+
_b = int(remove_whitespace("659E F8BA0439 16EEDE89 11702B22"), 16)
302+
_Gx = int(remove_whitespace("09487239 995A5EE7 6B55F9C2 F098"), 16)
303+
_Gy = int(remove_whitespace("A89C E5AF8724 C0A23E0E 0FF77500"), 16)
304+
_r = int(remove_whitespace("DB7C 2ABF62E3 5E7628DF AC6561C5"), 16)
305+
_h = 1
306+
curve_112r1 = ellipticcurve.CurveFp(_p, _a, _b, _h)
307+
generator_112r1 = ellipticcurve.PointJacobi(
308+
curve_112r1, _Gx, _Gy, 1, _r, generator=True
309+
)
310+
311+
312+
# secp112r2 curve
313+
_p = int(remove_whitespace("DB7C 2ABF62E3 5E668076 BEAD208B"), 16)
314+
# s = 022757A1 114D69E 67687561 51755316 C05E0BD4
315+
_a = int(remove_whitespace("6127 C24C05F3 8A0AAAF6 5C0EF02C"), 16)
316+
_b = int(remove_whitespace("51DE F1815DB5 ED74FCC3 4C85D709"), 16)
317+
_Gx = int(remove_whitespace("4BA30AB5 E892B4E1 649DD092 8643"), 16)
318+
_Gy = int(remove_whitespace("ADCD 46F5882E 3747DEF3 6E956E97"), 16)
319+
_r = int(remove_whitespace("36DF 0AAFD8B8 D7597CA1 0520D04B"), 16)
320+
_h = 4
321+
curve_112r2 = ellipticcurve.CurveFp(_p, _a, _b, _h)
322+
generator_112r2 = ellipticcurve.PointJacobi(
323+
curve_112r2, _Gx, _Gy, 1, _r, generator=True
324+
)
325+
326+
327+
# secp128r1 curve
328+
_p = int(remove_whitespace("FFFFFFFD FFFFFFFF FFFFFFFF FFFFFFFF"), 16)
329+
# S = 000E0D4D 69E6768 75615175 0CC03A44 73D03679
330+
# a and b are mod p, so a is equal to p-3, or simply -3
331+
# _a = -3
332+
_b = int(remove_whitespace("E87579C1 1079F43D D824993C 2CEE5ED3"), 16)
333+
_Gx = int(remove_whitespace("161FF752 8B899B2D 0C28607C A52C5B86"), 16)
334+
_Gy = int(remove_whitespace("CF5AC839 5BAFEB13 C02DA292 DDED7A83"), 16)
335+
_r = int(remove_whitespace("FFFFFFFE 00000000 75A30D1B 9038A115"), 16)
336+
_h = 1
337+
curve_128r1 = ellipticcurve.CurveFp(_p, -3, _b, _h)
338+
generator_128r1 = ellipticcurve.PointJacobi(
339+
curve_128r1, _Gx, _Gy, 1, _r, generator=True
340+
)
341+
342+
343+
# secp160r1
344+
_p = int(remove_whitespace("FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 7FFFFFFF"), 16)
345+
# S = 1053CDE4 2C14D696 E6768756 1517533B F3F83345
346+
# a and b are mod p, so a is equal to p-3, or simply -3
347+
# _a = -3
348+
_b = int(remove_whitespace("1C97BEFC 54BD7A8B 65ACF89F 81D4D4AD C565FA45"), 16)
349+
_Gx = int(
350+
remove_whitespace("4A96B568 8EF57328 46646989 68C38BB9 13CBFC82"), 16,
351+
)
352+
_Gy = int(
353+
remove_whitespace("23A62855 3168947D 59DCC912 04235137 7AC5FB32"), 16,
354+
)
355+
_r = int(
356+
remove_whitespace("01 00000000 00000000 0001F4C8 F927AED3 CA752257"), 16,
357+
)
358+
_h = 1
359+
curve_160r1 = ellipticcurve.CurveFp(_p, -3, _b, _h)
360+
generator_160r1 = ellipticcurve.PointJacobi(
361+
curve_160r1, _Gx, _Gy, 1, _r, generator=True
362+
)
363+
364+
297365
# NIST Curve P-192:
298366
_p = 6277101735386680763835789423207666416083908700390324961279
299367
_r = 6277101735386680763835789423176059013767194773182842284081

0 commit comments

Comments
 (0)