Commit | Line | Data |
---|---|---|
ffad1322 MW |
1 | ### -*- mode: python, coding: utf-8 -*- |
2 | ### | |
3 | ### Testing implicit conversions | |
4 | ### | |
5 | ### (c) 2019 Straylight/Edgeware | |
6 | ### | |
7 | ||
8 | ###----- Licensing notice --------------------------------------------------- | |
9 | ### | |
10 | ### This file is part of the Python interface to Catacomb. | |
11 | ### | |
12 | ### Catacomb/Python is free software: you can redistribute it and/or | |
13 | ### modify it under the terms of the GNU General Public License as | |
14 | ### published by the Free Software Foundation; either version 2 of the | |
15 | ### License, or (at your option) any later version. | |
16 | ### | |
17 | ### Catacomb/Python is distributed in the hope that it will be useful, but | |
18 | ### WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
20 | ### General Public License for more details. | |
21 | ### | |
22 | ### You should have received a copy of the GNU General Public License | |
23 | ### along with Catacomb/Python. If not, write to the Free Software | |
24 | ### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |
25 | ### USA. | |
26 | ||
27 | ###-------------------------------------------------------------------------- | |
28 | ### Imported modules. | |
29 | ||
30 | import catacomb as C | |
31 | import sys as SYS | |
32 | import unittest as U | |
33 | import testutils as T | |
34 | ||
35 | ###-------------------------------------------------------------------------- | |
36 | class TestConvert (U.TestCase): | |
37 | """Test implicit conversions between various mathematical types.""" | |
38 | ||
39 | def test(me): | |
40 | ||
41 | k = C.PrimeField(17) | |
42 | E = k.ec(-3, 4) | |
43 | P = E(1) # order 15 | |
44 | kk = C.BinPolyField(0x13) | |
45 | EE = kk.ec(1, 2) | |
46 | PP = E(9) # order 16 | |
47 | ||
48 | ## `MP' asymmetric operations. | |
49 | me.assertEqual(pow(C.MP(5), 2), 25) | |
50 | me.assertEqual(pow(5, C.MP(2)), 25) | |
51 | me.assertEqual(pow(C.MP(5), 2, 7), 4) | |
52 | me.assertEqual(pow(5, C.MP(2), 7), 4) | |
53 | me.assertEqual(pow(5, 2, C.MP(7)), 4) | |
7032ee7c | 54 | for bad in [C.GF, k, kk, str, float, lambda x: [x]]: |
ffad1322 MW |
55 | me.assertRaises(TypeError, pow, C.MP(5), bad(2)) |
56 | me.assertRaises(TypeError, pow, C.MP(5), bad(2), 7) | |
d472b9a1 | 57 | if not (T.PY2 and T.DEBUGP): |
ffad1322 MW |
58 | ## Debug builds of Python 2 crash here, and it's not our fault. Run |
59 | ## | |
60 | ## $ python2.7-dbg -c 'pow(long(5), 2, [7])' | |
61 | ## | |
62 | ## to confirm. The `[7]' causes coercion to occur. The first and | |
63 | ## second operands are coerced first, and successfully replaced by | |
64 | ## the results: the first operand (in this case) is unchanged, but | |
65 | ## has its refcount bumped, and the second operand is replaced by the | |
66 | ## result of coercion, which now has a refcount of 1. Then the first | |
67 | ## and third operands are coerced, which fails. Python decrements | |
68 | ## the refcounts of the results of the first coercion, so the second | |
69 | ## operand is now freed and, in debug builds, clobbered. Python then | |
70 | ## tries to format an error message, quoting the types of the | |
71 | ## operands, but one of them has been lost. | |
72 | me.assertRaises(TypeError, pow, C.MP(5), 2, bad(7)) | |
73 | me.assertRaises(TypeError, T.lsl, C.MP(5), bad(2)) | |
74 | ||
75 | ## `GF' asymmetric operations. | |
76 | me.assertEqual(pow(C.GF(0x5), 2), C.GF(0x11)) | |
77 | me.assertEqual(pow(C.GF(0x5), C.MP(2)), C.GF(0x11)) | |
78 | me.assertEqual(pow(C.GF(5), 2, C.GF(0x13)), C.GF(0x2)) | |
7032ee7c | 79 | for bad in [k, kk, str, float, lambda x: [x]]: |
ffad1322 MW |
80 | me.assertRaises(TypeError, pow, C.GF(5), bad(2)) |
81 | me.assertRaises(TypeError, T.lsl, C.GF(5), bad(2)) | |
7032ee7c | 82 | for bad in [int, C.MP, k, kk, str, float, lambda x: [x]]: |
ffad1322 MW |
83 | me.assertRaises(TypeError, pow, bad(5), C.GF(2)) |
84 | me.assertRaises(TypeError, pow, bad(5), C.GF(2), bad(7)) | |
85 | me.assertRaises(TypeError, pow, bad(5), bad(2), C.GF(7)) | |
86 | me.assertRaises(TypeError, pow, C.GF(5), bad(2), bad(7)) | |
d472b9a1 | 87 | if not (T.PY2 and T.DEBUGP): |
ffad1322 MW |
88 | ## Python bug: see above. |
89 | me.assertRaises(TypeError, pow, C.GF(5), 2, bad(7)) | |
90 | ||
91 | ## `MP' and `GF'. | |
92 | me.assertEqual(C.MP(5), 5) | |
93 | me.assertEqual(5, C.MP(5)) | |
7032ee7c MW |
94 | me.assertNotEqual(C.GF(5), 5) |
95 | me.assertNotEqual(5, C.GF(5)) | |
a70a5a80 MW |
96 | me.assertNotEqual(C.MP(5), C.GF(5)) |
97 | me.assertNotEqual(C.GF(5), C.MP(5)) | |
ffad1322 MW |
98 | |
99 | me.assertEqual(C.MP(5) + 3, 8) | |
100 | me.assertEqual(3 + C.MP(5), 8) | |
7032ee7c MW |
101 | me.assertRaises(TypeError, T.add, C.GF(5), 3) |
102 | me.assertRaises(TypeError, T.add, 3, C.GF(5)) | |
ffad1322 MW |
103 | me.assertRaises(TypeError, T.add, C.MP(5), C.GF(3)) |
104 | me.assertRaises(TypeError, T.add, C.GF(3), C.MP(5)) | |
7032ee7c | 105 | if T.PY3: me.assertRaises(TypeError, T.le, C.MP(4), C.GF(5)) |
ffad1322 MW |
106 | |
107 | ## Field elements. | |
108 | me.assertEqual(k(3) + 4, 7) | |
109 | me.assertEqual(4 + k(3), 7) | |
110 | me.assertEqual(k(3) + C.MP(4), 7) | |
111 | me.assertEqual(C.MP(4) + k(3), 7) | |
112 | me.assertEqual(k(3) + 4, 7) | |
113 | me.assertEqual(C.GF(7) + kk(3), C.GF(4)) | |
114 | me.assertEqual(kk(3) + C.GF(7), C.GF(4)) | |
115 | ||
4dc1425b | 116 | me.assertRaises(TypeError, T.add, k(3), 3.0) |
7032ee7c | 117 | me.assertRaises(TypeError, T.add, k(3), "3") |
ffad1322 MW |
118 | me.assertRaises(TypeError, T.add, k(3), kk(3)) |
119 | me.assertRaises(TypeError, T.add, kk(3), k(3)) | |
4dc1425b MW |
120 | me.assertRaises(TypeError, T.add, k(3), C.GF(7)) |
121 | me.assertRaises(TypeError, T.add, C.GF(7), k(3)) | |
7032ee7c | 122 | me.assertRaises(TypeError, T.add, kk(3), 7) |
4dc1425b | 123 | me.assertRaises(TypeError, T.add, kk(3), 7.0) |
7032ee7c MW |
124 | me.assertRaises(TypeError, T.add, kk(3), "7") |
125 | me.assertRaises(TypeError, T.add, 7, kk(3)) | |
4dc1425b MW |
126 | me.assertRaises(TypeError, T.add, kk(3), C.MP(7)) |
127 | me.assertRaises(TypeError, T.add, C.MP(7), kk(3)) | |
ffad1322 MW |
128 | |
129 | ###----- That's all, folks -------------------------------------------------- | |
130 | ||
131 | if __name__ == "__main__": U.main() |