|
1 |
| -from .ellipticcurve import CurveFp, INFINITY, Point |
| 1 | +import pytest |
2 | 2 | from six import print_
|
| 3 | +try: |
| 4 | + import unittest2 as unittest |
| 5 | +except ImportError: |
| 6 | + import unittest |
| 7 | +from hypothesis import given, settings |
| 8 | +import hypothesis.strategies as st |
| 9 | +try: |
| 10 | + from hypothesis import HealthCheck |
| 11 | + HC_PRESENT=True |
| 12 | +except ImportError: |
| 13 | + HC_PRESENT=False |
| 14 | +from .numbertheory import inverse_mod |
| 15 | +from .ellipticcurve import CurveFp, INFINITY, Point |
| 16 | + |
| 17 | + |
| 18 | +HYP_SETTINGS={} |
| 19 | +if HC_PRESENT: |
| 20 | + HYP_SETTINGS['suppress_health_check']=[HealthCheck.too_slow] |
| 21 | + HYP_SETTINGS['deadline'] = 5000 |
| 22 | + |
| 23 | + |
| 24 | +# NIST Curve P-192: |
| 25 | +p = 6277101735386680763835789423207666416083908700390324961279 |
| 26 | +r = 6277101735386680763835789423176059013767194773182842284081 |
| 27 | +# s = 0x3045ae6fc8422f64ed579528d38120eae12196d5 |
| 28 | +# c = 0x3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65 |
| 29 | +b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1 |
| 30 | +Gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012 |
| 31 | +Gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811 |
| 32 | + |
| 33 | + |
| 34 | +c192 = CurveFp(p, -3, b) |
| 35 | +p192 = Point(c192, Gx, Gy, r) |
| 36 | + |
| 37 | + |
| 38 | +def test_p192(): |
| 39 | + # Checking against some sample computations presented |
| 40 | + # in X9.62: |
| 41 | + d = 651056770906015076056810763456358567190100156695615665659 |
| 42 | + Q = d * p192 |
| 43 | + assert Q.x() == 0x62B12D60690CDCF330BABAB6E69763B471F994DD702D16A5 |
| 44 | + |
| 45 | + k = 6140507067065001063065065565667405560006161556565665656654 |
| 46 | + R = k * p192 |
| 47 | + assert R.x() == 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD \ |
| 48 | + and R.y() == 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835 |
| 49 | + |
| 50 | + u1 = 2563697409189434185194736134579731015366492496392189760599 |
| 51 | + u2 = 6266643813348617967186477710235785849136406323338782220568 |
| 52 | + temp = u1 * p192 + u2 * Q |
| 53 | + assert temp.x() == 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD \ |
| 54 | + and temp.y() == 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835 |
| 55 | + |
| 56 | + |
| 57 | +@settings(**HYP_SETTINGS) |
| 58 | +@given(st.integers(min_value=1, max_value=r+1)) |
| 59 | +def test_p192_mult_tests(multiple): |
| 60 | + inv_m = inverse_mod(multiple, r) |
3 | 61 |
|
4 |
| -def test_ellipticcurve(): |
| 62 | + p1 = p192 * multiple |
| 63 | + assert p1 * inv_m == p192 |
5 | 64 |
|
6 |
| - class FailedTest(Exception): |
7 |
| - pass |
8 | 65 |
|
9 |
| - def test_add(c, x1, y1, x2, y2, x3, y3): |
| 66 | +def add_n_times(point, n): |
| 67 | + ret = INFINITY |
| 68 | + i = 0 |
| 69 | + while i <= n: |
| 70 | + yield ret |
| 71 | + ret = ret + point |
| 72 | + i += 1 |
| 73 | + |
| 74 | + |
| 75 | +c_23 = CurveFp(23, 1, 1) |
| 76 | + |
| 77 | + |
| 78 | +g_23 = Point(c_23, 13, 7, 7) |
| 79 | + |
| 80 | + |
| 81 | +# Trivial tests from X9.62 B.3: |
| 82 | +@pytest.mark.parametrize( |
| 83 | + "c,x1,y1,x2,y2,x3,y3", |
| 84 | + [(c_23, 3, 10, 9, 7, 17, 20), |
| 85 | + (c_23, 3, 10, 3, 10, 7, 12)], |
| 86 | + ids=["real add", "double"]) |
| 87 | +def test_add(c, x1, y1, x2, y2, x3, y3): |
10 | 88 | """We expect that on curve c, (x1,y1) + (x2, y2 ) = (x3, y3)."""
|
11 | 89 | p1 = Point(c, x1, y1)
|
12 | 90 | p2 = Point(c, x2, y2)
|
13 | 91 | p3 = p1 + p2
|
14 |
| - print_("%s + %s = %s" % (p1, p2, p3), end=' ') |
15 |
| - if p3.x() != x3 or p3.y() != y3: |
16 |
| - raise FailedTest("Failure: should give (%d,%d)." % (x3, y3)) |
17 |
| - else: |
18 |
| - print_(" Good.") |
19 |
| - |
20 |
| - def test_double(c, x1, y1, x3, y3): |
21 |
| - """We expect that on curve c, 2*(x1,y1) = (x3, y3).""" |
| 92 | + assert p3.x() == x3 and p3.y() == y3 |
| 93 | + |
| 94 | + |
| 95 | +@pytest.mark.parametrize( |
| 96 | + "c, x1, y1, x3, y3", |
| 97 | + [(c_23, 3, 10, 7, 12)], |
| 98 | + ids=["real add"]) |
| 99 | +def test_double(c, x1, y1, x3, y3): |
22 | 100 | p1 = Point(c, x1, y1)
|
23 | 101 | p3 = p1.double()
|
24 |
| - print_("%s doubled = %s" % (p1, p3), end=' ') |
25 |
| - if p3.x() != x3 or p3.y() != y3: |
26 |
| - raise FailedTest("Failure: should give (%d,%d)." % (x3, y3)) |
27 |
| - else: |
28 |
| - print_(" Good.") |
29 |
| - |
30 |
| - def test_double_infinity(c): |
31 |
| - """We expect that on curve c, 2*INFINITY = INFINITY.""" |
| 102 | + assert p3.x() == x3 and p3.y() == y3 |
| 103 | + |
| 104 | + |
| 105 | +def test_double_infinity(): |
32 | 106 | p1 = INFINITY
|
33 | 107 | p3 = p1.double()
|
34 |
| - print_("%s doubled = %s" % (p1, p3), end=' ') |
35 |
| - if p3.x() != INFINITY.x() or p3.y() != INFINITY.y(): |
36 |
| - raise FailedTest("Failure: should give (%d,%d)." % (INFINITY.x(), INFINITY.y())) |
37 |
| - else: |
38 |
| - print_(" Good.") |
39 |
| - |
40 |
| - def test_multiply(c, x1, y1, m, x3, y3): |
41 |
| - """We expect that on curve c, m*(x1,y1) = (x3,y3).""" |
| 108 | + assert p1 == p3 |
| 109 | + assert p3.x() == p1.x() and p3.y() == p3.y() |
| 110 | + |
| 111 | + |
| 112 | +@pytest.mark.parametrize( |
| 113 | + "c, x1, y1, m, x3, y3", |
| 114 | + [(c_23, 3, 10, 2, 7, 12)], |
| 115 | + ids=["multiply by 2"]) |
| 116 | +def test_multiply(c, x1, y1, m, x3, y3): |
42 | 117 | p1 = Point(c, x1, y1)
|
43 | 118 | p3 = p1 * m
|
44 |
| - print_("%s * %d = %s" % (p1, m, p3), end=' ') |
45 |
| - if p3.x() != x3 or p3.y() != y3: |
46 |
| - raise FailedTest("Failure: should give (%d,%d)." % (x3, y3)) |
47 |
| - else: |
48 |
| - print_(" Good.") |
49 |
| - |
50 |
| - # A few tests from X9.62 B.3: |
51 |
| - |
52 |
| - c = CurveFp(23, 1, 1) |
53 |
| - test_add(c, 3, 10, 9, 7, 17, 20) |
54 |
| - test_double(c, 3, 10, 7, 12) |
55 |
| - test_add(c, 3, 10, 3, 10, 7, 12) # (Should just invoke double.) |
56 |
| - test_multiply(c, 3, 10, 2, 7, 12) |
57 |
| - |
58 |
| - test_double_infinity(c) |
59 |
| - |
60 |
| - # From X9.62 I.1 (p. 96): |
61 |
| - |
62 |
| - g = Point(c, 13, 7, 7) |
63 |
| - |
64 |
| - check = INFINITY |
65 |
| - for i in range(7 + 1): |
66 |
| - p = (i % 7) * g |
67 |
| - print_("%s * %d = %s, expected %s . . ." % (g, i, p, check), end=' ') |
68 |
| - if p == check: |
69 |
| - print_(" Good.") |
70 |
| - else: |
71 |
| - raise FailedTest("Bad.") |
72 |
| - check = check + g |
73 |
| - |
74 |
| - # NIST Curve P-192: |
75 |
| - p = 6277101735386680763835789423207666416083908700390324961279 |
76 |
| - r = 6277101735386680763835789423176059013767194773182842284081 |
77 |
| - # s = 0x3045ae6fc8422f64ed579528d38120eae12196d5L |
78 |
| - c = 0x3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65 |
79 |
| - b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1 |
80 |
| - Gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012 |
81 |
| - Gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811 |
82 |
| - |
83 |
| - c192 = CurveFp(p, -3, b) |
84 |
| - p192 = Point(c192, Gx, Gy, r) |
85 |
| - |
86 |
| - # Checking against some sample computations presented |
87 |
| - # in X9.62: |
88 |
| - |
89 |
| - d = 651056770906015076056810763456358567190100156695615665659 |
90 |
| - Q = d * p192 |
91 |
| - if Q.x() != 0x62B12D60690CDCF330BABAB6E69763B471F994DD702D16A5: |
92 |
| - raise FailedTest("p192 * d came out wrong.") |
93 |
| - else: |
94 |
| - print_("p192 * d came out right.") |
95 |
| - |
96 |
| - k = 6140507067065001063065065565667405560006161556565665656654 |
97 |
| - R = k * p192 |
98 |
| - if R.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD \ |
99 |
| - or R.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835: |
100 |
| - raise FailedTest("k * p192 came out wrong.") |
101 |
| - else: |
102 |
| - print_("k * p192 came out right.") |
103 |
| - |
104 |
| - u1 = 2563697409189434185194736134579731015366492496392189760599 |
105 |
| - u2 = 6266643813348617967186477710235785849136406323338782220568 |
106 |
| - temp = u1 * p192 + u2 * Q |
107 |
| - if temp.x() != 0x885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD \ |
108 |
| - or temp.y() != 0x9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835: |
109 |
| - raise FailedTest("u1 * p192 + u2 * Q came out wrong.") |
110 |
| - else: |
111 |
| - print_("u1 * p192 + u2 * Q came out right.") |
| 119 | + assert p3.x() == x3 and p3.y() == y3 |
| 120 | + |
| 121 | + |
| 122 | +# From X9.62 I.1 (p. 96): |
| 123 | +@pytest.mark.parametrize( |
| 124 | + "p, m, check", |
| 125 | + [(g_23, n, exp) for n, exp in enumerate(add_n_times(g_23, 8))], |
| 126 | + ids=["g_23 test with mult {0}".format(i) for i in range(9)]) |
| 127 | +def test_add_and_mult_equivalence(p, m, check): |
| 128 | + assert p * m == check |
0 commit comments