3 ### Testing public-key crypto functionality
5 ### (c) 2019 Straylight/Edgeware
8 ###----- Licensing notice ---------------------------------------------------
10 ### This file is part of the Python interface to Catacomb.
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.
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.
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,
27 ###--------------------------------------------------------------------------
34 ###--------------------------------------------------------------------------
35 class TestDSA (U
.TestCase
):
37 def check(me
, privcls
, pubcls
, rng
, H
, G
):
38 msg
= T
.bin("A simple test message")
39 wrong
= T
.bin("This is not the message you're looking for")
40 a
= privcls(G
, rng
.range(G
.r
), hash = H
, rng
= rng
)
41 me
.assertEqual(a
.hash, H
)
42 me
.assertEqual(a
.rng
, rng
)
43 A
= pubcls(G
, a
.p
, hash = H
, rng
= rng
)
44 h
= a
.endhash(a
.beginhash().hash(msg
))
45 me
.assertEqual(h
, A
.endhash(a
.beginhash().hash(msg
)))
47 me
.assertTrue(A
.verify(h
, sig
))
48 me
.assertFalse(A
.verify(A
.endhash(A
.beginhash().hash(wrong
)), sig
))
50 me
.assertRaises(ValueError, a
.sign
, h
+ C
.bytes("00"))
51 me
.assertRaises(ValueError, a
.verify
, h
+ C
.bytes("00"), sig
)
54 me
.check(C
.DSAPriv
, C
.DSAPub
, T
.detrand("dsa"), C
.sha256
,
55 C
.primegroups
["catacomb-ll-256-3072"].group())
57 me
.check(C
.DSAPriv
, C
.DSAPub
, T
.detrand("ecdsa"), C
.sha256
,
58 C
.eccurves
["nist-p256"].group())
60 me
.check(C
.KCDSAPriv
, C
.KCDSAPub
, T
.detrand("kcdsa"), C
.has160
,
61 C
.primegroups
["catacomb-ll-160-1024"].group())
63 me
.check(C
.KCDSAPriv
, C
.KCDSAPub
, T
.detrand("eckcdsa"), C
.sha256
,
64 C
.eccurves
["nist-p256"].group())
66 ###--------------------------------------------------------------------------
67 class TestRSA (U
.TestCase
):
70 rng
= T
.detrand("rsa")
71 ev
= T
.EventRecorder()
72 msg
= T
.bin("A simple test message")
73 h
= C
.sha256().hash(msg
).done()
74 wrong
= T
.bin("This is not the message you're looking for")
75 hh
= C
.sha256().hash(wrong
).done()
77 a
= C
.RSAPriv
.generate(1536, event
= ev
, rng
= rng
)
78 A
= C
.RSAPub(n
= a
.n
, e
= a
.e
)
79 me
.assertEqual(a
.n
.nbits
, 1536)
80 me
.assertEqual(a
.rng
, None)
82 me
.assertEqual(a
.rng
, rng
)
83 me
.assertEqual(ev
.events
,
93 C
.RSAPriv(n
= a
.n
, e
= a
.e
, d
= a
.d
)
94 C
.RSAPriv(n
= a
.n
, p
= a
.p
, d
= a
.d
)
95 C
.RSAPriv(n
= a
.n
, q
= a
.q
, e
= a
.e
)
96 C
.RSAPriv(p
= a
.p
, q
= a
.q
, e
= a
.e
)
97 me
.assertRaises(ValueError, C
.RSAPriv
, p
= a
.p
, q
= a
.q
, dp
= a
.dp
)
99 me
.assertTrue(a
.p
.primep())
100 me
.assertTrue(a
.q
.primep())
101 me
.assertEqual(a
.n
, a
.p
*a
.q
)
102 me
.assertEqual(a
.dp
, a
.d
%(a
.p
- 1))
103 me
.assertEqual(a
.dq
, a
.d
%(a
.q
- 1))
104 me
.assertEqual((a
.e
*a
.dp
)%(a
.p
- 1), 1)
105 me
.assertEqual((a
.e
*a
.dq
)%(a
.q
- 1), 1)
106 me
.assertEqual((a
.q
*a
.q_inv
)%a
.p
, 1)
110 me
.assertEqual(x
, a
.pubop(y
))
111 me
.assertEqual(x
, A
.pubop(y
))
113 me
.assertEqual(z
, A
.pubop(x
))
114 me
.assertEqual(x
, a
.privop(z
))
116 pad
= C
.PKCS1Crypt(rng
= rng
)
117 ct
= A
.encrypt(msg
, pad
)
118 me
.assertEqual(a
.decrypt(ct
, pad
), msg
)
119 me
.assertRaises(ValueError, a
.decrypt
, ct ^
1, pad
)
121 pad
= C
.PKCS1Sig(ep
= C
.bytes("3031300d060960864801650304020105000420"))
123 me
.assertTrue(A
.verify(h
, sig
, pad
))
124 me
.assertFalse(A
.verify(hh
, sig
, pad
))
126 pad
= C
.OAEP(mgf
= C
.sha256_mgf
, hash = C
.sha256
, rng
= rng
)
127 ct
= A
.encrypt(msg
, pad
)
128 me
.assertEqual(a
.decrypt(ct
, pad
), msg
)
129 me
.assertRaises(ValueError, a
.decrypt
, ct ^
1, pad
)
131 pad
= C
.PSS(mgf
= C
.sha256_mgf
, hash = C
.sha256
, rng
= rng
)
133 me
.assertTrue(A
.verify(h
, sig
, pad
))
134 me
.assertFalse(A
.verify(hh
, sig
, pad
))
136 ###--------------------------------------------------------------------------
137 class TestXDH (U
.TestCase
):
139 def check(me
, privcls
, pubcls
, rng
):
140 msg
= T
.bin("A simple test message")
144 a
= privcls
.generate(rng
)
146 b
= privcls
.generate(rng
)
149 me
.assertEqual(b
.agree(A
), Z
)
150 me
.assertEqual(b
.agree(a
), Z
)
152 ct
= a
.box(B
, n
, msg
)
153 me
.assertEqual(b
.unbox(A
, n
, ct
), msg
)
154 me
.assertRaises(ValueError, b
.unbox
, A
, n1
, ct
)
157 me
.check(C
.X25519Priv
, C
.X25519Pub
, T
.detrand("x25519"))
159 me
.check(C
.X448Priv
, C
.X448Pub
, T
.detrand("x448"))
161 ###--------------------------------------------------------------------------
162 class TestEdDSA (U
.TestCase
):
164 def check(me
, privcls
, pubcls
, rng
):
165 msg
= T
.bin("A simple test message")
166 wrong
= T
.bin("This is not the message you're looking for")
167 perso
= T
.bin("Catacomb/Python test")
168 a
= privcls
.generate(rng
)
172 me
.assertTrue(a
.verify(msg
, sig
))
173 me
.assertTrue(A
.verify(msg
, sig
))
174 me
.assertFalse(A
.verify(wrong
, sig
))
176 sig
= a
.sign(msg
, perso
= perso
)
177 me
.assertTrue(a
.verify(msg
, sig
, perso
= perso
))
178 me
.assertFalse(A
.verify(msg
, sig
))
180 h
= a
.endhash(a
.beginhash().hash(msg
))
181 sig
= a
.sign(h
, phflag
= True)
182 me
.assertTrue(a
.verify(h
, sig
, phflag
= True))
183 me
.assertFalse(A
.verify(h
, sig
))
185 def test_ed25519(me
):
186 me
.check(C
.Ed25519Priv
, C
.Ed25519Pub
, T
.detrand("ed25519"))
188 me
.check(C
.Ed448Priv
, C
.Ed448Pub
, T
.detrand("ed448"))
190 ###----- That's all, folks --------------------------------------------------
192 if __name__
== "__main__": U
.main()