1#!/usr/bin/env python3
2
3import sys
4import unittest
5import struct
6import itertools
7import functools
8import contextlib
9import hashlib
10import binascii
11import base64
12import json
13try:
14    from math import gcd
15except ImportError:
16    from fractions import gcd
17
18from eccref import *
19from testcrypt import *
20from ssh import *
21
22assert sys.version_info[:2] >= (3,0), "This is Python 3 code"
23
24try:
25    base64decode = base64.decodebytes
26except AttributeError:
27    base64decode = base64.decodestring
28
29def unhex(s):
30    return binascii.unhexlify(s.replace(" ", "").replace("\n", ""))
31
32def rsa_bare(e, n):
33    rsa = rsa_new()
34    get_rsa_ssh1_pub(ssh_uint32(nbits(n)) + ssh1_mpint(e) + ssh1_mpint(n),
35                     rsa, 'exponent_first')
36    return rsa
37
38def find_non_square_mod(p):
39    # Find a non-square mod p, using the Jacobi symbol
40    # calculation function from eccref.py.
41    return next(z for z in itertools.count(2) if jacobi(z, p) == -1)
42
43def fibonacci_scattered(n=10):
44    # Generate a list of Fibonacci numbers with power-of-2 indices
45    # (F_1, F_2, F_4, ...), to be used as test inputs of varying
46    # sizes. Also put F_0 = 0 into the list as a bonus.
47    yield 0
48    a, b, c = 0, 1, 1
49    while True:
50        yield b
51        n -= 1
52        if n <= 0:
53            break
54        a, b, c = (a**2+b**2, b*(a+c), b**2+c**2)
55
56def fibonacci(n=10):
57    # Generate the full Fibonacci sequence starting from F_0 = 0.
58    a, b = 0, 1
59    while True:
60        yield a
61        n -= 1
62        if n <= 0:
63            break
64        a, b = b, a+b
65
66def mp_mask(mp):
67    # Return the value that mp would represent if all its bits
68    # were set. Useful for masking a true mathematical output
69    # value (e.g. from an operation that can over/underflow, like
70    # mp_sub or mp_anything_into) to check it's right within the
71    # ability of that particular mp_int to represent.
72    return ((1 << mp_max_bits(mp))-1)
73
74def adjtuples(iterable, n):
75    # Return all the contiguous n-tuples of an iterable, including
76    # overlapping ones. E.g. if called on [0,1,2,3,4] with n=3 it
77    # would return (0,1,2), (1,2,3), (2,3,4) and then stop.
78    it = iter(iterable)
79    toret = [next(it) for _ in range(n-1)]
80    for element in it:
81        toret.append(element)
82        yield tuple(toret)
83        toret[:1] = []
84
85def last(iterable):
86    # Return the last element of an iterable, or None if it is empty.
87    it = iter(iterable)
88    toret = None
89    for toret in it:
90        pass
91    return toret
92
93def le_integer(x, nbits):
94    assert nbits % 8 == 0
95    return bytes([0xFF & (x >> (8*n)) for n in range(nbits//8)])
96
97@contextlib.contextmanager
98def queued_random_data(nbytes, seed):
99    hashsize = 512 // 8
100    data = b''.join(
101        hashlib.sha512("preimage:{:d}:{}".format(i, seed).encode('ascii'))
102        .digest() for i in range((nbytes + hashsize - 1) // hashsize))
103    data = data[:nbytes]
104    random_queue(data)
105    yield None
106    random_clear()
107
108@contextlib.contextmanager
109def queued_specific_random_data(data):
110    random_queue(data)
111    yield None
112    random_clear()
113
114@contextlib.contextmanager
115def random_prng(seed):
116    random_make_prng('sha256', seed)
117    yield None
118    random_clear()
119
120def hash_str(alg, message):
121    h = ssh_hash_new(alg)
122    ssh_hash_update(h, message)
123    return ssh_hash_final(h)
124
125def hash_str_iter(alg, message_iter):
126    h = ssh_hash_new(alg)
127    for string in message_iter:
128        ssh_hash_update(h, string)
129    return ssh_hash_final(h)
130
131def mac_str(alg, key, message, cipher=None):
132    m = ssh2_mac_new(alg, cipher)
133    ssh2_mac_setkey(m, key)
134    ssh2_mac_start(m)
135    ssh2_mac_update(m, "dummy")
136    # Make sure ssh_mac_start erases previous state
137    ssh2_mac_start(m)
138    ssh2_mac_update(m, message)
139    return ssh2_mac_genresult(m)
140
141def lcm(a, b):
142    return a * b // gcd(a, b)
143
144class MyTestBase(unittest.TestCase):
145    "Intermediate class that adds useful helper methods."
146    def assertEqualBin(self, x, y):
147        # Like assertEqual, but produces more legible error reports
148        # for random-looking binary data.
149        self.assertEqual(binascii.hexlify(x), binascii.hexlify(y))
150
151class mpint(MyTestBase):
152    def testCreation(self):
153        self.assertEqual(int(mp_new(128)), 0)
154        self.assertEqual(int(mp_from_bytes_be(b'ABCDEFGHIJKLMNOP')),
155                         0x4142434445464748494a4b4c4d4e4f50)
156        self.assertEqual(int(mp_from_bytes_le(b'ABCDEFGHIJKLMNOP')),
157                         0x504f4e4d4c4b4a494847464544434241)
158        self.assertEqual(int(mp_from_integer(12345)), 12345)
159        decstr = '91596559417721901505460351493238411077414937428167'
160        self.assertEqual(int(mp_from_decimal_pl(decstr)), int(decstr, 10))
161        self.assertEqual(int(mp_from_decimal(decstr)), int(decstr, 10))
162        self.assertEqual(int(mp_from_decimal("")), 0)
163        # For hex, test both upper and lower case digits
164        hexstr = 'ea7cb89f409ae845215822e37D32D0C63EC43E1381C2FF8094'
165        self.assertEqual(int(mp_from_hex_pl(hexstr)), int(hexstr, 16))
166        self.assertEqual(int(mp_from_hex(hexstr)), int(hexstr, 16))
167        self.assertEqual(int(mp_from_hex("")), 0)
168        p2 = mp_power_2(123)
169        self.assertEqual(int(p2), 1 << 123)
170        p2c = mp_copy(p2)
171        self.assertEqual(int(p2c), 1 << 123)
172        # Check mp_copy really makes a copy, not an alias (ok, that's
173        # testing the testcrypt system more than it's testing the
174        # underlying C functions)
175        mp_set_bit(p2c, 120, 1)
176        self.assertEqual(int(p2c), (1 << 123) + (1 << 120))
177        self.assertEqual(int(p2), 1 << 123)
178
179    def testBytesAndBits(self):
180        x = mp_new(128)
181        self.assertEqual(mp_get_byte(x, 2), 0)
182        mp_set_bit(x, 2*8+3, 1)
183        self.assertEqual(mp_get_byte(x, 2), 1<<3)
184        self.assertEqual(mp_get_bit(x, 2*8+3), 1)
185        mp_set_bit(x, 2*8+3, 0)
186        self.assertEqual(mp_get_byte(x, 2), 0)
187        self.assertEqual(mp_get_bit(x, 2*8+3), 0)
188        # Currently I expect 128 to be a multiple of any
189        # BIGNUM_INT_BITS value we might be running with, so these
190        # should be exact equality
191        self.assertEqual(mp_max_bytes(x), 128/8)
192        self.assertEqual(mp_max_bits(x), 128)
193
194        nb = lambda hexstr: mp_get_nbits(mp_from_hex(hexstr))
195        self.assertEqual(nb('00000000000000000000000000000000'), 0)
196        self.assertEqual(nb('00000000000000000000000000000001'), 1)
197        self.assertEqual(nb('00000000000000000000000000000002'), 2)
198        self.assertEqual(nb('00000000000000000000000000000003'), 2)
199        self.assertEqual(nb('00000000000000000000000000000004'), 3)
200        self.assertEqual(nb('000003ffffffffffffffffffffffffff'), 106)
201        self.assertEqual(nb('000003ffffffffff0000000000000000'), 106)
202        self.assertEqual(nb('80000000000000000000000000000000'), 128)
203        self.assertEqual(nb('ffffffffffffffffffffffffffffffff'), 128)
204
205    def testDecAndHex(self):
206        def checkHex(hexstr):
207            n = mp_from_hex(hexstr)
208            i = int(hexstr, 16)
209            self.assertEqual(mp_get_hex(n),
210                             "{:x}".format(i).encode('ascii'))
211            self.assertEqual(mp_get_hex_uppercase(n),
212                             "{:X}".format(i).encode('ascii'))
213        checkHex("0")
214        checkHex("f")
215        checkHex("00000000000000000000000000000000000000000000000000")
216        checkHex("d5aa1acd5a9a1f6b126ed416015390b8dc5fceee4c86afc8c2")
217        checkHex("ffffffffffffffffffffffffffffffffffffffffffffffffff")
218
219        def checkDec(hexstr):
220            n = mp_from_hex(hexstr)
221            i = int(hexstr, 16)
222            self.assertEqual(mp_get_decimal(n),
223                             "{:d}".format(i).encode('ascii'))
224        checkDec("0")
225        checkDec("f")
226        checkDec("00000000000000000000000000000000000000000000000000")
227        checkDec("d5aa1acd5a9a1f6b126ed416015390b8dc5fceee4c86afc8c2")
228        checkDec("ffffffffffffffffffffffffffffffffffffffffffffffffff")
229        checkDec("f" * 512)
230
231    def testComparison(self):
232        inputs = [
233            "0", "1", "2", "10", "314159265358979", "FFFFFFFFFFFFFFFF",
234
235            # Test over-long versions of some of the same numbers we
236            # had short forms of above
237            "0000000000000000000000000000000000000000000000000000000000000000"
238            "0000000000000000000000000000000000000000000000000000000000000000",
239
240            "0000000000000000000000000000000000000000000000000000000000000000"
241            "0000000000000000000000000000000000000000000000000000000000000001",
242
243            "0000000000000000000000000000000000000000000000000000000000000000"
244            "0000000000000000000000000000000000000000000000000000000000000002",
245
246            "0000000000000000000000000000000000000000000000000000000000000000"
247            "000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFF",
248
249            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
250            "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
251        ]
252        values = [(mp_from_hex(s), int(s, 16)) for s in inputs]
253        for am, ai in values:
254            for bm, bi in values:
255                self.assertEqual(mp_cmp_eq(am, bm) == 1, ai == bi)
256                self.assertEqual(mp_cmp_hs(am, bm) == 1, ai >= bi)
257                if (bi >> 64) == 0:
258                    self.assertEqual(mp_eq_integer(am, bi) == 1, ai == bi)
259                    self.assertEqual(mp_hs_integer(am, bi) == 1, ai >= bi)
260
261                # mp_{min,max}{,_into} is a reasonable thing to test
262                # here as well
263                self.assertEqual(int(mp_min(am, bm)), min(ai, bi))
264                self.assertEqual(int(mp_max(am, bm)), max(ai, bi))
265                am_small = mp_copy(am if ai<bi else bm)
266                mp_min_into(am_small, am, bm)
267                self.assertEqual(int(am_small), min(ai, bi))
268                am_big = mp_copy(am if ai>bi else bm)
269                mp_max_into(am_big, am, bm)
270                self.assertEqual(int(am_big), max(ai, bi))
271
272        # Test mp_{eq,hs}_integer in the case where the integer is as
273        # large as possible and the bignum contains very few words. In
274        # modes where BIGNUM_INT_BITS < 64, this used to go wrong.
275        mp10 = mp_new(4)
276        mp_copy_integer_into(mp10, 10)
277        highbit = 1 << 63
278        self.assertEqual(mp_hs_integer(mp10, highbit | 9), 0)
279        self.assertEqual(mp_hs_integer(mp10, highbit | 10), 0)
280        self.assertEqual(mp_hs_integer(mp10, highbit | 11), 0)
281        self.assertEqual(mp_eq_integer(mp10, highbit | 9), 0)
282        self.assertEqual(mp_eq_integer(mp10, highbit | 10), 0)
283        self.assertEqual(mp_eq_integer(mp10, highbit | 11), 0)
284
285    def testConditionals(self):
286        testnumbers = [(mp_copy(n),n) for n in fibonacci_scattered()]
287        for am, ai in testnumbers:
288            for bm, bi in testnumbers:
289                cm = mp_copy(am)
290                mp_select_into(cm, am, bm, 0)
291                self.assertEqual(int(cm), ai & mp_mask(am))
292                mp_select_into(cm, am, bm, 1)
293                self.assertEqual(int(cm), bi & mp_mask(am))
294
295                mp_cond_add_into(cm, am, bm, 0)
296                self.assertEqual(int(cm), ai & mp_mask(am))
297                mp_cond_add_into(cm, am, bm, 1)
298                self.assertEqual(int(cm), (ai+bi) & mp_mask(am))
299
300                mp_cond_sub_into(cm, am, bm, 0)
301                self.assertEqual(int(cm), ai & mp_mask(am))
302                mp_cond_sub_into(cm, am, bm, 1)
303                self.assertEqual(int(cm), (ai-bi) & mp_mask(am))
304
305                maxbits = max(mp_max_bits(am), mp_max_bits(bm))
306                cm = mp_new(maxbits)
307                dm = mp_new(maxbits)
308                mp_copy_into(cm, am)
309                mp_copy_into(dm, bm)
310
311                self.assertEqual(int(cm), ai)
312                self.assertEqual(int(dm), bi)
313                mp_cond_swap(cm, dm, 0)
314                self.assertEqual(int(cm), ai)
315                self.assertEqual(int(dm), bi)
316                mp_cond_swap(cm, dm, 1)
317                self.assertEqual(int(cm), bi)
318                self.assertEqual(int(dm), ai)
319
320                if bi != 0:
321                    mp_cond_clear(cm, 0)
322                    self.assertEqual(int(cm), bi)
323                    mp_cond_clear(cm, 1)
324                    self.assertEqual(int(cm), 0)
325
326    def testBasicArithmetic(self):
327        testnumbers = list(fibonacci_scattered(5))
328        testnumbers.extend([1 << (1 << i) for i in range(3,10)])
329        testnumbers.extend([(1 << (1 << i)) - 1 for i in range(3,10)])
330
331        testnumbers = [(mp_copy(n),n) for n in testnumbers]
332
333        for am, ai in testnumbers:
334            for bm, bi in testnumbers:
335                self.assertEqual(int(mp_add(am, bm)), ai + bi)
336                self.assertEqual(int(mp_mul(am, bm)), ai * bi)
337                # Cope with underflow in subtraction
338                diff = mp_sub(am, bm)
339                self.assertEqual(int(diff), (ai - bi) & mp_mask(diff))
340
341                for bits in range(64, 512, 64):
342                    cm = mp_new(bits)
343                    mp_add_into(cm, am, bm)
344                    self.assertEqual(int(cm), (ai + bi) & mp_mask(cm))
345                    mp_mul_into(cm, am, bm)
346                    self.assertEqual(int(cm), (ai * bi) & mp_mask(cm))
347                    mp_sub_into(cm, am, bm)
348                    self.assertEqual(int(cm), (ai - bi) & mp_mask(cm))
349
350        # A test cherry-picked from the old bignum test script,
351        # involving two numbers whose product has a single 1 bit miles
352        # in the air and then all 0s until a bunch of cruft at the
353        # bottom, the aim being to test that carry propagation works
354        # all the way up.
355        ai, bi = 0xb4ff6ed2c633847562087ed9354c5c17be212ac83b59c10c316250f50b7889e5b058bf6bfafd12825225ba225ede0cba583ffbd0882de88c9e62677385a6dbdedaf81959a273eb7909ebde21ae5d12e2a584501a6756fe50ccb93b93f0d6ee721b6052a0d88431e62f410d608532868cdf3a6de26886559e94cc2677eea9bd797918b70e2717e95b45918bd1f86530cb9989e68b632c496becff848aa1956cd57ed46676a65ce6dd9783f230c8796909eef5583fcfe4acbf9c8b4ea33a08ec3fd417cf7175f434025d032567a00fc329aee154ca20f799b961fbab8f841cb7351f561a44aea45746ceaf56874dad99b63a7d7af2769d2f185e2d1c656cc6630b5aba98399fa57, 0xb50a77c03ac195225021dc18d930a352f27c0404742f961ca828c972737bad3ada74b1144657ab1d15fe1b8aefde8784ad61783f3c8d4584aa5f22a4eeca619f90563ae351b5da46770df182cf348d8e23b25fda07670c6609118e916a57ce4043608752c91515708327e36f5bb5ebd92cd4cfb39424167a679870202b23593aa524bac541a3ad322c38102a01e9659b06a4335c78d50739a51027954ac2bf03e500f975c2fa4d0ab5dd84cc9334f219d2ae933946583e384ed5dbf6498f214480ca66987b867df0f69d92e4e14071e4b8545212dd5e29ff0248ed751e168d78934da7930bcbe10e9a212128a68de5d749c61f5e424cf8cf6aa329674de0cf49c6f9b4c8b8cc3
356        am = mp_copy(ai)
357        bm = mp_copy(bi)
358        self.assertEqual(int(mp_mul(am, bm)), ai * bi)
359
360        # A regression test for a bug that came up during development
361        # of mpint.c, relating to an intermediate value overflowing
362        # its container.
363        ai, bi = (2**8512 * 2 // 3), (2**4224 * 11 // 15)
364        am = mp_copy(ai)
365        bm = mp_copy(bi)
366        self.assertEqual(int(mp_mul(am, bm)), ai * bi)
367
368    def testAddInteger(self):
369        initial = mp_copy(4444444444444444444444444)
370
371        x = mp_new(mp_max_bits(initial) + 64)
372
373        # mp_{add,sub,copy}_integer_into should be able to cope with
374        # any uintmax_t. Test a number that requires more than 32 bits.
375        mp_add_integer_into(x, initial, 123123123123123)
376        self.assertEqual(int(x), 4444444444567567567567567)
377        mp_sub_integer_into(x, initial, 123123123123123)
378        self.assertEqual(int(x), 4444444444321321321321321)
379        mp_copy_integer_into(x, 123123123123123)
380        self.assertEqual(int(x), 123123123123123)
381
382        # mp_mul_integer_into only takes a uint16_t integer input
383        mp_mul_integer_into(x, initial, 10001)
384        self.assertEqual(int(x), 44448888888888888888888884444)
385
386    def testDivision(self):
387        divisors = [1, 2, 3, 2**16+1, 2**32-1, 2**32+1, 2**128-159,
388                    141421356237309504880168872420969807856967187537694807]
389        quotients = [0, 1, 2, 2**64-1, 2**64, 2**64+1, 17320508075688772935]
390        for d in divisors:
391            for q in quotients:
392                remainders = {0, 1, d-1, 2*d//3}
393                for r in sorted(remainders):
394                    if r >= d:
395                        continue # silly cases with tiny divisors
396                    n = q*d + r
397                    mq = mp_new(max(nbits(q), 1))
398                    mr = mp_new(max(nbits(r), 1))
399                    mp_divmod_into(n, d, mq, mr)
400                    self.assertEqual(int(mq), q)
401                    self.assertEqual(int(mr), r)
402                    self.assertEqual(int(mp_div(n, d)), q)
403                    self.assertEqual(int(mp_mod(n, d)), r)
404
405                    # Make sure divmod_into can handle not getting one
406                    # of its output pointers (or even both).
407                    mp_clear(mq)
408                    mp_divmod_into(n, d, mq, None)
409                    self.assertEqual(int(mq), q)
410                    mp_clear(mr)
411                    mp_divmod_into(n, d, None, mr)
412                    self.assertEqual(int(mr), r)
413                    mp_divmod_into(n, d, None, None)
414                    # No tests we can do after that last one - we just
415                    # insist that it isn't allowed to have crashed!
416
417    def testNthRoot(self):
418        roots = [1, 13, 1234567654321,
419                 57721566490153286060651209008240243104215933593992]
420        tests = []
421        tests.append((0, 2, 0, 0))
422        tests.append((0, 3, 0, 0))
423        for r in roots:
424            for n in 2, 3, 5:
425                tests.append((r**n, n, r, 0))
426                tests.append((r**n+1, n, r, 1))
427                tests.append((r**n-1, n, r-1, r**n - (r-1)**n - 1))
428        for x, n, eroot, eremainder in tests:
429            with self.subTest(x=x):
430                mx = mp_copy(x)
431                remainder = mp_copy(mx)
432                root = mp_nthroot(x, n, remainder)
433                self.assertEqual(int(root), eroot)
434                self.assertEqual(int(remainder), eremainder)
435        self.assertEqual(int(mp_nthroot(2*10**100, 2, None)),
436                         141421356237309504880168872420969807856967187537694)
437        self.assertEqual(int(mp_nthroot(3*10**150, 3, None)),
438                         144224957030740838232163831078010958839186925349935)
439
440    def testBitwise(self):
441        p = 0x3243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e
442        e = 0x2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190
443        x = mp_new(nbits(p))
444
445        mp_and_into(x, p, e)
446        self.assertEqual(int(x), p & e)
447
448        mp_or_into(x, p, e)
449        self.assertEqual(int(x), p | e)
450
451        mp_xor_into(x, p, e)
452        self.assertEqual(int(x), p ^ e)
453
454        mp_bic_into(x, p, e)
455        self.assertEqual(int(x), p & ~e)
456
457    def testInversion(self):
458        # Test mp_invert_mod_2to.
459        testnumbers = [(mp_copy(n),n) for n in fibonacci_scattered()
460                       if n & 1]
461        for power2 in [1, 2, 3, 5, 13, 32, 64, 127, 128, 129]:
462            for am, ai in testnumbers:
463                bm = mp_invert_mod_2to(am, power2)
464                bi = int(bm)
465                self.assertEqual(((ai * bi) & ((1 << power2) - 1)), 1)
466
467                # mp_reduce_mod_2to is a much simpler function, but
468                # this is as good a place as any to test it.
469                rm = mp_copy(am)
470                mp_reduce_mod_2to(rm, power2)
471                self.assertEqual(int(rm), ai & ((1 << power2) - 1))
472
473        # Test mp_invert proper.
474        moduli = [2, 3, 2**16+1, 2**32-1, 2**32+1, 2**128-159,
475                  141421356237309504880168872420969807856967187537694807,
476                  2**128-1]
477        for m in moduli:
478            # Prepare a MontyContext for the monty_invert test below
479            # (unless m is even, in which case we can't)
480            mc = monty_new(m) if m & 1 else None
481
482            to_invert = {1, 2, 3, 7, 19, m-1, 5*m//17, (m-1)//2, (m+1)//2}
483            for x in sorted(to_invert):
484                if gcd(x, m) != 1:
485                    continue # filter out non-invertible cases
486                inv = int(mp_invert(x, m))
487                assert x * inv % m == 1
488
489                # Test monty_invert too, while we're here
490                if mc is not None:
491                    self.assertEqual(
492                        int(monty_invert(mc, monty_import(mc, x))),
493                        int(monty_import(mc, inv)))
494
495    def testGCD(self):
496        powerpairs = [(0,0), (1,0), (1,1), (2,1), (2,2), (75,3), (17,23)]
497        for a2, b2 in powerpairs:
498            for a3, b3 in powerpairs:
499                for a5, b5 in powerpairs:
500                    a = 2**a2 * 3**a3 * 5**a5 * 17 * 19 * 23
501                    b = 2**b2 * 3**b3 * 5**b5 * 65423
502                    d = 2**min(a2, b2) * 3**min(a3, b3) * 5**min(a5, b5)
503
504                    ma = mp_copy(a)
505                    mb = mp_copy(b)
506
507                    self.assertEqual(int(mp_gcd(ma, mb)), d)
508
509                    md = mp_new(nbits(d))
510                    mA = mp_new(nbits(b))
511                    mB = mp_new(nbits(a))
512                    mp_gcd_into(ma, mb, md, mA, mB)
513                    self.assertEqual(int(md), d)
514                    A = int(mA)
515                    B = int(mB)
516                    self.assertEqual(a*A - b*B, d)
517                    self.assertTrue(0 <= A < b//d)
518                    self.assertTrue(0 <= B < a//d)
519
520                    self.assertEqual(mp_coprime(ma, mb), 1 if d==1 else 0)
521
522                    # Make sure gcd_into can handle not getting some
523                    # of its output pointers.
524                    mp_clear(md)
525                    mp_gcd_into(ma, mb, md, None, None)
526                    self.assertEqual(int(md), d)
527                    mp_clear(mA)
528                    mp_gcd_into(ma, mb, None, mA, None)
529                    self.assertEqual(int(mA), A)
530                    mp_clear(mB)
531                    mp_gcd_into(ma, mb, None, None, mB)
532                    self.assertEqual(int(mB), B)
533                    mp_gcd_into(ma, mb, None, None, None)
534                    # No tests we can do after that last one - we just
535                    # insist that it isn't allowed to have crashed!
536
537    def testMonty(self):
538        moduli = [5, 19, 2**16+1, 2**31-1, 2**128-159, 2**255-19,
539                  293828847201107461142630006802421204703,
540                  113064788724832491560079164581712332614996441637880086878209969852674997069759]
541
542        for m in moduli:
543            mc = monty_new(m)
544
545            # Import some numbers
546            inputs = [(monty_import(mc, n), n)
547                      for n in sorted({0, 1, 2, 3, 2*m//3, m-1})]
548
549            # Check modulus and identity
550            self.assertEqual(int(monty_modulus(mc)), m)
551            self.assertEqual(int(monty_identity(mc)), int(inputs[1][0]))
552
553            # Check that all those numbers export OK
554            for mn, n in inputs:
555                self.assertEqual(int(monty_export(mc, mn)), n)
556
557            for ma, a in inputs:
558                for mb, b in inputs:
559                    xprod = int(monty_export(mc, monty_mul(mc, ma, mb)))
560                    self.assertEqual(xprod, a*b % m)
561
562                    xsum = int(monty_export(mc, monty_add(mc, ma, mb)))
563                    self.assertEqual(xsum, (a+b) % m)
564
565                    xdiff = int(monty_export(mc, monty_sub(mc, ma, mb)))
566                    self.assertEqual(xdiff, (a-b) % m)
567
568                    # Test the ordinary mp_mod{add,sub,mul} at the
569                    # same time, even though those don't do any
570                    # montying at all
571
572                    xprod = int(mp_modmul(a, b, m))
573                    self.assertEqual(xprod, a*b % m)
574
575                    xsum = int(mp_modadd(a, b, m))
576                    self.assertEqual(xsum, (a+b) % m)
577
578                    xdiff = int(mp_modsub(a, b, m))
579                    self.assertEqual(xdiff, (a-b) % m)
580
581            for ma, a in inputs:
582                # Compute a^0, a^1, a^1, a^2, a^3, a^5, ...
583                indices = list(fibonacci())
584                powers = [int(monty_export(mc, monty_pow(mc, ma, power)))
585                          for power in indices]
586                # Check the first two make sense
587                self.assertEqual(powers[0], 1)
588                self.assertEqual(powers[1], a)
589                # Check the others using the Fibonacci identity:
590                # F_n + F_{n+1} = F_{n+2}, so a^{F_n} a^{F_{n+1}} = a^{F_{n+2}}
591                for p0, p1, p2 in adjtuples(powers, 3):
592                    self.assertEqual(p2, p0 * p1 % m)
593
594                # Test the ordinary mp_modpow here as well, while
595                # we've got the machinery available
596                for index, power in zip(indices, powers):
597                    self.assertEqual(int(mp_modpow(a, index, m)), power)
598
599        # A regression test for a bug I encountered during initial
600        # development of mpint.c, in which an incomplete reduction
601        # happened somewhere in an intermediate value.
602        b, e, m = 0x2B5B93812F253FF91F56B3B4DAD01CA2884B6A80719B0DA4E2159A230C6009EDA97C5C8FD4636B324F9594706EE3AD444831571BA5E17B1B2DFA92DEA8B7E, 0x25, 0xC8FCFD0FD7371F4FE8D0150EFC124E220581569587CCD8E50423FA8D41E0B2A0127E100E92501E5EE3228D12EA422A568C17E0AD2E5C5FCC2AE9159D2B7FB8CB
603        assert(int(mp_modpow(b, e, m)) == pow(b, e, m))
604
605        # Make sure mp_modpow can handle a base larger than the
606        # modulus, by pre-reducing it
607        assert(int(mp_modpow(1<<877, 907, 999979)) == pow(2, 877*907, 999979))
608
609    def testModsqrt(self):
610        moduli = [
611            5, 19, 2**16+1, 2**31-1, 2**128-159, 2**255-19,
612            293828847201107461142630006802421204703,
613            113064788724832491560079164581712332614996441637880086878209969852674997069759,
614            0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6FFFFFFFF00000001]
615        for p in moduli:
616            # Count the factors of 2 in the group. (That is, we want
617            # p-1 to be an odd multiple of 2^{factors_of_2}.)
618            factors_of_2 = nbits((p-1) & (1-p)) - 1
619            assert (p & ((2 << factors_of_2)-1)) == ((1 << factors_of_2)+1)
620
621            z = find_non_square_mod(p)
622
623            sc = modsqrt_new(p, z)
624
625            def ptest(x):
626                root, success = mp_modsqrt(sc, x)
627                r = int(root)
628                self.assertTrue(success)
629                self.assertEqual((r * r - x) % p, 0)
630
631            def ntest(x):
632                root, success = mp_modsqrt(sc, x)
633                self.assertFalse(success)
634
635            # Make up some more or less random values mod p to square
636            v1 = pow(3, nbits(p), p)
637            v2 = pow(5, v1, p)
638            test_roots = [0, 1, 2, 3, 4, 3*p//4, v1, v2, v1+1, 12873*v1, v1*v2]
639            known_squares = {r*r % p for r in test_roots}
640            for s in known_squares:
641                ptest(s)
642                if s != 0:
643                    ntest(z*s % p)
644
645            # Make sure we've tested a value that is in each of the
646            # subgroups of order (p-1)/2^k but not in the next one
647            # (with the exception of k=0, which just means 'have we
648            # tested a non-square?', which we have in the above loop).
649            #
650            # We do this by starting with a known non-square; then
651            # squaring it (factors_of_2) times will return values
652            # nested deeper and deeper in those subgroups.
653            vbase = z
654            for k in range(factors_of_2):
655                # Adjust vbase by an arbitrary odd power of
656                # z, so that it won't look too much like the previous
657                # value.
658                vbase = vbase * pow(z, (vbase + v1 + v2) | 1, p) % p
659
660                # Move vbase into the next smaller group by squaring
661                # it.
662                vbase = pow(vbase, 2, p)
663
664                ptest(vbase)
665
666    def testShifts(self):
667        x = ((1<<900) // 9949) | 1
668        for i in range(2049):
669            mp = mp_copy(x)
670
671            mp_lshift_fixed_into(mp, mp, i)
672            self.assertEqual(int(mp), (x << i) & mp_mask(mp))
673
674            mp_copy_into(mp, x)
675            mp_lshift_safe_into(mp, mp, i)
676            self.assertEqual(int(mp), (x << i) & mp_mask(mp))
677
678            mp_copy_into(mp, x)
679            mp_rshift_fixed_into(mp, mp, i)
680            self.assertEqual(int(mp), x >> i)
681
682            mp_copy_into(mp, x)
683            mp_rshift_safe_into(mp, mp, i)
684            self.assertEqual(int(mp), x >> i)
685
686            self.assertEqual(int(mp_rshift_fixed(x, i)), x >> i)
687
688            self.assertEqual(int(mp_rshift_safe(x, i)), x >> i)
689
690    def testRandom(self):
691        # Test random_bits to ensure it correctly masks the return
692        # value, and uses exactly as many random bytes as we expect it
693        # to.
694        for bits in range(512):
695            bytes_needed = (bits + 7) // 8
696            with queued_random_data(bytes_needed, "random_bits test"):
697                mp = mp_random_bits(bits)
698                self.assertTrue(int(mp) < (1 << bits))
699                self.assertEqual(random_queue_len(), 0)
700
701        # Test mp_random_in_range to ensure it returns things in the
702        # right range.
703        for rangesize in [2, 3, 19, 35]:
704            for lo in [0, 1, 0x10001, 1<<512]:
705                hi = lo + rangesize
706                bytes_needed = mp_max_bytes(hi) + 16
707                for trial in range(rangesize*3):
708                    with queued_random_data(
709                            bytes_needed,
710                            "random_in_range {:d}".format(trial)):
711                        v = int(mp_random_in_range(lo, hi))
712                        self.assertTrue(lo <= v < hi)
713
714class ecc(MyTestBase):
715    def testWeierstrassSimple(self):
716        # Simple tests using a Weierstrass curve I made up myself,
717        # which (unlike the ones used for serious crypto) is small
718        # enough that you can fit all the coordinates for a curve on
719        # to your retina in one go.
720
721        p = 3141592661
722        a, b = -3 % p, 12345
723        rc = WeierstrassCurve(p, a, b)
724        wc = ecc_weierstrass_curve(p, a, b, None)
725
726        def check_point(wp, rp):
727            self.assertTrue(ecc_weierstrass_point_valid(wp))
728            is_id = ecc_weierstrass_is_identity(wp)
729            x, y = ecc_weierstrass_get_affine(wp)
730            if rp.infinite:
731                self.assertEqual(is_id, 1)
732            else:
733                self.assertEqual(is_id, 0)
734                self.assertEqual(int(x), int(rp.x))
735                self.assertEqual(int(y), int(rp.y))
736
737        def make_point(x, y):
738            wp = ecc_weierstrass_point_new(wc, x, y)
739            rp = rc.point(x, y)
740            check_point(wp, rp)
741            return wp, rp
742
743        # Some sample points, including the identity and also a pair
744        # of mutual inverses.
745        wI, rI = ecc_weierstrass_point_new_identity(wc), rc.point()
746        wP, rP = make_point(102, 387427089)
747        wQ, rQ = make_point(1000, 546126574)
748        wmP, rmP = make_point(102, p - 387427089)
749
750        # Check the simple arithmetic functions.
751        check_point(ecc_weierstrass_add(wP, wQ), rP + rQ)
752        check_point(ecc_weierstrass_add(wQ, wP), rP + rQ)
753        check_point(ecc_weierstrass_double(wP), rP + rP)
754        check_point(ecc_weierstrass_double(wQ), rQ + rQ)
755
756        # Check all the special cases with add_general:
757        # Adding two finite unequal non-mutually-inverse points
758        check_point(ecc_weierstrass_add_general(wP, wQ), rP + rQ)
759        # Doubling a finite point
760        check_point(ecc_weierstrass_add_general(wP, wP), rP + rP)
761        check_point(ecc_weierstrass_add_general(wQ, wQ), rQ + rQ)
762        # Adding the identity to a point (both ways round)
763        check_point(ecc_weierstrass_add_general(wI, wP), rP)
764        check_point(ecc_weierstrass_add_general(wI, wQ), rQ)
765        check_point(ecc_weierstrass_add_general(wP, wI), rP)
766        check_point(ecc_weierstrass_add_general(wQ, wI), rQ)
767        # Doubling the identity
768        check_point(ecc_weierstrass_add_general(wI, wI), rI)
769        # Adding a point to its own inverse, giving the identity.
770        check_point(ecc_weierstrass_add_general(wmP, wP), rI)
771        check_point(ecc_weierstrass_add_general(wP, wmP), rI)
772
773        # Verify that point_valid fails if we pass it nonsense.
774        bogus = ecc_weierstrass_point_new(wc, int(rP.x), int(rP.y * 3))
775        self.assertFalse(ecc_weierstrass_point_valid(bogus))
776
777        # Re-instantiate the curve with the ability to take square
778        # roots, and check that we can reconstruct P and Q from their
779        # x coordinate and y parity only.
780        wc = ecc_weierstrass_curve(p, a, b, find_non_square_mod(p))
781
782        x, yp = int(rP.x), (int(rP.y) & 1)
783        check_point(ecc_weierstrass_point_new_from_x(wc, x, yp), rP)
784        check_point(ecc_weierstrass_point_new_from_x(wc, x, yp ^ 1), rmP)
785        x, yp = int(rQ.x), (int(rQ.y) & 1)
786        check_point(ecc_weierstrass_point_new_from_x(wc, x, yp), rQ)
787
788    def testMontgomerySimple(self):
789        p, a, b = 3141592661, 0xabc, 0xde
790
791        rc = MontgomeryCurve(p, a, b)
792        mc = ecc_montgomery_curve(p, a, b)
793
794        rP = rc.cpoint(0x1001)
795        rQ = rc.cpoint(0x20001)
796        rdiff = rP - rQ
797        rsum = rP + rQ
798
799        def make_mpoint(rp):
800            return ecc_montgomery_point_new(mc, int(rp.x))
801
802        mP = make_mpoint(rP)
803        mQ = make_mpoint(rQ)
804        mdiff = make_mpoint(rdiff)
805        msum = make_mpoint(rsum)
806
807        def check_point(mp, rp):
808            x = ecc_montgomery_get_affine(mp)
809            self.assertEqual(int(x), int(rp.x))
810
811        check_point(ecc_montgomery_diff_add(mP, mQ, mdiff), rsum)
812        check_point(ecc_montgomery_diff_add(mQ, mP, mdiff), rsum)
813        check_point(ecc_montgomery_diff_add(mP, mQ, msum), rdiff)
814        check_point(ecc_montgomery_diff_add(mQ, mP, msum), rdiff)
815        check_point(ecc_montgomery_double(mP), rP + rP)
816        check_point(ecc_montgomery_double(mQ), rQ + rQ)
817
818        zero = ecc_montgomery_point_new(mc, 0)
819        self.assertEqual(ecc_montgomery_is_identity(zero), False)
820        identity = ecc_montgomery_double(zero)
821        ecc_montgomery_get_affine(identity)
822        self.assertEqual(ecc_montgomery_is_identity(identity), True)
823
824    def testEdwardsSimple(self):
825        p, d, a = 3141592661, 2688750488, 367934288
826
827        rc = TwistedEdwardsCurve(p, d, a)
828        ec = ecc_edwards_curve(p, d, a, None)
829
830        def check_point(ep, rp):
831            x, y = ecc_edwards_get_affine(ep)
832            self.assertEqual(int(x), int(rp.x))
833            self.assertEqual(int(y), int(rp.y))
834
835        def make_point(x, y):
836            ep = ecc_edwards_point_new(ec, x, y)
837            rp = rc.point(x, y)
838            check_point(ep, rp)
839            return ep, rp
840
841        # Some sample points, including the identity and also a pair
842        # of mutual inverses.
843        eI, rI = make_point(0, 1)
844        eP, rP = make_point(196270812, 1576162644)
845        eQ, rQ = make_point(1777630975, 2717453445)
846        emP, rmP = make_point(p - 196270812, 1576162644)
847
848        # Check that the ordinary add function handles all the special
849        # cases.
850
851        # Adding two finite unequal non-mutually-inverse points
852        check_point(ecc_edwards_add(eP, eQ), rP + rQ)
853        check_point(ecc_edwards_add(eQ, eP), rP + rQ)
854        # Doubling a finite point
855        check_point(ecc_edwards_add(eP, eP), rP + rP)
856        check_point(ecc_edwards_add(eQ, eQ), rQ + rQ)
857        # Adding the identity to a point (both ways round)
858        check_point(ecc_edwards_add(eI, eP), rP)
859        check_point(ecc_edwards_add(eI, eQ), rQ)
860        check_point(ecc_edwards_add(eP, eI), rP)
861        check_point(ecc_edwards_add(eQ, eI), rQ)
862        # Doubling the identity
863        check_point(ecc_edwards_add(eI, eI), rI)
864        # Adding a point to its own inverse, giving the identity.
865        check_point(ecc_edwards_add(emP, eP), rI)
866        check_point(ecc_edwards_add(eP, emP), rI)
867
868        # Re-instantiate the curve with the ability to take square
869        # roots, and check that we can reconstruct P and Q from their
870        # y coordinate and x parity only.
871        ec = ecc_edwards_curve(p, d, a, find_non_square_mod(p))
872
873        y, xp = int(rP.y), (int(rP.x) & 1)
874        check_point(ecc_edwards_point_new_from_y(ec, y, xp), rP)
875        check_point(ecc_edwards_point_new_from_y(ec, y, xp ^ 1), rmP)
876        y, xp = int(rQ.y), (int(rQ.x) & 1)
877        check_point(ecc_edwards_point_new_from_y(ec, y, xp), rQ)
878
879    # For testing point multiplication, let's switch to the full-sized
880    # standard curves, because I want to have tested those a bit too.
881
882    def testWeierstrassMultiply(self):
883        wc = ecc_weierstrass_curve(p256.p, int(p256.a), int(p256.b), None)
884        wG = ecc_weierstrass_point_new(wc, int(p256.G.x), int(p256.G.y))
885        self.assertTrue(ecc_weierstrass_point_valid(wG))
886
887        ints = set(i % p256.p for i in fibonacci_scattered(10))
888        ints.remove(0) # the zero multiple isn't expected to work
889        for i in sorted(ints):
890            wGi = ecc_weierstrass_multiply(wG, i)
891            x, y = ecc_weierstrass_get_affine(wGi)
892            rGi = p256.G * i
893            self.assertEqual(int(x), int(rGi.x))
894            self.assertEqual(int(y), int(rGi.y))
895
896    def testMontgomeryMultiply(self):
897        mc = ecc_montgomery_curve(
898            curve25519.p, int(curve25519.a), int(curve25519.b))
899        mG = ecc_montgomery_point_new(mc, int(curve25519.G.x))
900
901        ints = set(i % p256.p for i in fibonacci_scattered(10))
902        ints.remove(0) # the zero multiple isn't expected to work
903        for i in sorted(ints):
904            mGi = ecc_montgomery_multiply(mG, i)
905            x = ecc_montgomery_get_affine(mGi)
906            rGi = curve25519.G * i
907            self.assertEqual(int(x), int(rGi.x))
908
909    def testEdwardsMultiply(self):
910        ec = ecc_edwards_curve(ed25519.p, int(ed25519.d), int(ed25519.a), None)
911        eG = ecc_edwards_point_new(ec, int(ed25519.G.x), int(ed25519.G.y))
912
913        ints = set(i % ed25519.p for i in fibonacci_scattered(10))
914        ints.remove(0) # the zero multiple isn't expected to work
915        for i in sorted(ints):
916            eGi = ecc_edwards_multiply(eG, i)
917            x, y = ecc_edwards_get_affine(eGi)
918            rGi = ed25519.G * i
919            self.assertEqual(int(x), int(rGi.x))
920            self.assertEqual(int(y), int(rGi.y))
921
922class keygen(MyTestBase):
923    def testPrimeCandidateSource(self):
924        def inspect(pcs):
925            # Returns (pcs->limit, pcs->factor, pcs->addend) as Python integers
926            return tuple(map(int, pcs_inspect(pcs)))
927
928        # Test accumulating modular congruence requirements, by
929        # inspecting the internal values computed during
930        # require_residue. We ensure that the addend satisfies all our
931        # congruences and the factor is the lcm of all the moduli
932        # (hence, the arithmetic progression defined by those
933        # parameters is precisely the set of integers satisfying the
934        # requirements); we also ensure that the limiting values
935        # (addend itself at the low end, and addend + (limit-1) *
936        # factor at the high end) are the maximal subsequence of that
937        # progression that are within the originally specified range.
938
939        def check(pcs, lo, hi, mod_res_pairs):
940            limit, factor, addend = inspect(pcs)
941
942            for mod, res in mod_res_pairs:
943                self.assertEqual(addend % mod, res % mod)
944
945            self.assertEqual(factor, functools.reduce(
946                lcm, [mod for mod, res in mod_res_pairs]))
947
948            self.assertFalse(lo <= addend +      (-1) * factor < hi)
949            self.assertTrue (lo <= addend                      < hi)
950            self.assertTrue (lo <= addend + (limit-1) * factor < hi)
951            self.assertFalse(lo <= addend +  limit    * factor < hi)
952
953        pcs = pcs_new(64)
954        check(pcs, 2**63, 2**64, [(2, 1)])
955        pcs_require_residue(pcs, 3, 2)
956        check(pcs, 2**63, 2**64, [(2, 1), (3, 2)])
957        pcs_require_residue_1(pcs, 7)
958        check(pcs, 2**63, 2**64, [(2, 1), (3, 2), (7, 1)])
959        pcs_require_residue(pcs, 16, 7)
960        check(pcs, 2**63, 2**64, [(2, 1), (3, 2), (7, 1), (16, 7)])
961        pcs_require_residue(pcs, 49, 8)
962        check(pcs, 2**63, 2**64, [(2, 1), (3, 2), (7, 1), (16, 7), (49, 8)])
963
964        # Now test-generate some actual values, and ensure they
965        # satisfy all the congruences, and also avoid one residue mod
966        # 5 that we told them to. Also, give a nontrivial range.
967        pcs = pcs_new_with_firstbits(64, 0xAB, 8)
968        pcs_require_residue(pcs, 0x100, 0xCD)
969        pcs_require_residue_1(pcs, 65537)
970        pcs_avoid_residue_small(pcs, 5, 3)
971        pcs_ready(pcs)
972        with random_prng("test seed"):
973            for i in range(100):
974                n = int(pcs_generate(pcs))
975                self.assertTrue((0xAB<<56) < n < (0xAC<<56))
976                self.assertEqual(n % 0x100, 0xCD)
977                self.assertEqual(n % 65537, 1)
978                self.assertNotEqual(n % 5, 3)
979
980                # I'm not actually testing here that the outputs of
981                # pcs_generate are non-multiples of _all_ primes up to
982                # 2^16. But checking this many for 100 turns is enough
983                # to be pretty sure. (If you take the product of
984                # (1-1/p) over all p in the list below, you find that
985                # a given random number has about a 13% chance of
986                # avoiding being a multiple of any of them. So 100
987                # trials without a mistake gives you 0.13^100 < 10^-88
988                # as the probability of it happening by chance. More
989                # likely the code is actually working :-)
990
991                for p in [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61]:
992                    self.assertNotEqual(n % p, 0)
993
994    def testPocklePositive(self):
995        def add_small(po, *ps):
996            for p in ps:
997                self.assertEqual(pockle_add_small_prime(po, p), 'POCKLE_OK')
998        def add(po, *args):
999            self.assertEqual(pockle_add_prime(po, *args), 'POCKLE_OK')
1000
1001        # Transcription of the proof that 2^130-5 is prime from
1002        # Theorem 3.1 from http://cr.yp.to/mac/poly1305-20050329.pdf
1003        po = pockle_new()
1004        p1 = (2**130 - 6) // 1517314646
1005        p2 = (p1 - 1) // 222890620702
1006        add_small(po, 37003, 221101)
1007        add(po, p2, [37003, 221101], 2)
1008        add(po, p1, [p2], 2)
1009        add(po, 2**130 - 5, [p1], 2)
1010
1011        # My own proof that 2^255-19 is prime
1012        po = pockle_new()
1013        p1 = 8574133
1014        p2 = 1919519569386763
1015        p3 = 75445702479781427272750846543864801
1016        p4 = (2**255 - 20) // (65147*12)
1017        p = 2**255 - 19
1018        add_small(po, p1)
1019        add(po, p2, [p1], 2)
1020        add(po, p3, [p2], 2)
1021        add(po, p4, [p3], 2)
1022        add(po, p, [p4], 2)
1023
1024        # And the prime used in Ed448, while I'm here
1025        po = pockle_new()
1026        p1 = 379979
1027        p2 = 1764234391
1028        p3 = 97859369123353
1029        p4 = 34741861125639557
1030        p5 = 36131535570665139281
1031        p6 = 167773885276849215533569
1032        p7 = 596242599987116128415063
1033        p = 2**448 - 2**224 - 1
1034        add_small(po, p1, p2)
1035        add(po, p3, [p1], 2)
1036        add(po, p4, [p2], 2)
1037        add(po, p5, [p4], 2)
1038        add(po, p6, [p3], 3)
1039        add(po, p7, [p5], 3)
1040        add(po, p, [p6, p7], 2)
1041
1042        p = 4095744004479977
1043        factors = [2, 79999] # just enough factors to exceed cbrt(p)
1044        po = pockle_new()
1045        for q in factors:
1046            add_small(po, q)
1047        add(po, p, factors, 3)
1048
1049        # The order of the generator in Ed25519
1050        po = pockle_new()
1051        p1a, p1b = 132667, 137849
1052        p2 = 3044861653679985063343
1053        p3 = 198211423230930754013084525763697
1054        p = 2**252 + 0x14def9dea2f79cd65812631a5cf5d3ed
1055        add_small(po, p1a, p1b)
1056        add(po, p2, [p1a, p1b], 2)
1057        add(po, p3, [p2], 2)
1058        add(po, p, [p3], 2)
1059
1060        # And the one in Ed448
1061        po = pockle_new()
1062        p1 = 766223
1063        p2 = 3009341
1064        p3 = 7156907
1065        p4 = 671065561
1066        p5 = 342682509629
1067        p6 = 6730519843040614479184435237013
1068        p = 2**446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d
1069        add_small(po, p1, p2, p3, p4)
1070        add(po, p5, [p1], 2)
1071        add(po, p6, [p3,p4], 2)
1072        add(po, p, [p2,p5,p6], 2)
1073
1074    def testPockleNegative(self):
1075        def add_small(po, p):
1076            self.assertEqual(pockle_add_small_prime(po, p), 'POCKLE_OK')
1077
1078        po = pockle_new()
1079        self.assertEqual(pockle_add_small_prime(po, 0),
1080                         'POCKLE_PRIME_SMALLER_THAN_2')
1081        self.assertEqual(pockle_add_small_prime(po, 1),
1082                         'POCKLE_PRIME_SMALLER_THAN_2')
1083        self.assertEqual(pockle_add_small_prime(po, 2**61 - 1),
1084                         'POCKLE_SMALL_PRIME_NOT_SMALL')
1085        self.assertEqual(pockle_add_small_prime(po, 4),
1086                         'POCKLE_SMALL_PRIME_NOT_PRIME')
1087
1088        po = pockle_new()
1089        self.assertEqual(pockle_add_prime(po, 1919519569386763, [8574133], 2),
1090                         'POCKLE_FACTOR_NOT_KNOWN_PRIME')
1091
1092        po = pockle_new()
1093        add_small(po, 8574133)
1094        self.assertEqual(pockle_add_prime(po, 1919519569386765, [8574133], 2),
1095                         'POCKLE_FACTOR_NOT_A_FACTOR')
1096
1097        p = 4095744004479977
1098        factors = [2, 79997] # not quite enough factors to reach cbrt(p)
1099        po = pockle_new()
1100        for q in factors:
1101            add_small(po, q)
1102        self.assertEqual(pockle_add_prime(po, p, factors, 3),
1103                         'POCKLE_PRODUCT_OF_FACTORS_TOO_SMALL')
1104
1105        p = 1999527 * 3999053
1106        factors = [999763]
1107        po = pockle_new()
1108        for q in factors:
1109            add_small(po, q)
1110        self.assertEqual(pockle_add_prime(po, p, factors, 3),
1111                         'POCKLE_DISCRIMINANT_IS_SQUARE')
1112
1113        p = 9999929 * 9999931
1114        factors = [257, 2593]
1115        po = pockle_new()
1116        for q in factors:
1117            add_small(po, q)
1118        self.assertEqual(pockle_add_prime(po, p, factors, 3),
1119                         'POCKLE_FERMAT_TEST_FAILED')
1120
1121        p = 1713000920401 # a Carmichael number
1122        po = pockle_new()
1123        add_small(po, 561787)
1124        self.assertEqual(pockle_add_prime(po, p, [561787], 2),
1125                         'POCKLE_WITNESS_POWER_IS_1')
1126
1127        p = 4294971121
1128        factors = [3, 5, 11, 17]
1129        po = pockle_new()
1130        for q in factors:
1131            add_small(po, q)
1132        self.assertEqual(pockle_add_prime(po, p, factors, 17),
1133                         'POCKLE_WITNESS_POWER_NOT_COPRIME')
1134
1135        po = pockle_new()
1136        add_small(po, 2)
1137        self.assertEqual(pockle_add_prime(po, 1, [2], 1),
1138                         'POCKLE_PRIME_SMALLER_THAN_2')
1139
1140class crypt(MyTestBase):
1141    def testSSH1Fingerprint(self):
1142        # Example key and reference fingerprint value generated by
1143        # OpenSSH 6.7 ssh-keygen
1144        rsa = rsa_bare(65537, 984185866443261798625575612408956568591522723900235822424492423996716524817102482330189709310179009158443944785704183009867662230534501187034891091310377917105259938712348098594526746211645472854839799025154390701673823298369051411)
1145        fp = rsa_ssh1_fingerprint(rsa)
1146        self.assertEqual(
1147            fp, b"768 96:12:c8:bc:e6:03:75:86:e8:c7:b9:af:d8:0c:15:75")
1148
1149    def testSSH2Fingerprints(self):
1150        # A sensible key blob that we can make sense of.
1151        sensible_blob = base64.decodebytes(
1152            b'AAAAC3NzaC1lZDI1NTE5AAAAICWiV0VAD4lQ7taUN7vZ5Rkc'
1153            b'SLJBW5ubn6ZINwCOzpn3')
1154        self.assertEqual(ssh2_fingerprint_blob(sensible_blob, "sha256"),
1155                         b'ssh-ed25519 255 SHA256:'
1156                         b'E4VmaHW0sUF7SUgSEOmMJ8WBtt0e/j3zbsKvyqfFnu4')
1157        self.assertEqual(ssh2_fingerprint_blob(sensible_blob, "md5"),
1158                         b'ssh-ed25519 255 '
1159                         b'35:73:80:df:a3:2c:1a:f2:2c:a6:5c:84:ce:48:6a:7e')
1160
1161        # A key blob with an unknown algorithm name, so that we can't
1162        # extract the bit count.
1163        silly_blob = ssh_string(b'foo') + ssh_string(b'key data')
1164        self.assertEqual(ssh2_fingerprint_blob(silly_blob, "sha256"),
1165                         b'foo SHA256:'
1166                         b'mvfJTB4PaRI7hxYaYwn0sH8G6zW1HbLkbWnZE2YIKc4')
1167        self.assertEqual(ssh2_fingerprint_blob(silly_blob, "md5"),
1168                         b'foo '
1169                         b'5f:5f:97:94:97:be:01:5c:f6:3f:e3:6e:55:46:ea:52')
1170
1171        # A key blob without even a valid algorithm-name string at the start.
1172        very_silly_blob = b'foo'
1173        self.assertEqual(ssh2_fingerprint_blob(very_silly_blob, "sha256"),
1174                         b'SHA256:'
1175                         b'LCa0a2j/xo/5m0U8HTBBNBNCLXBkg7+g+YpeiGJm564')
1176        self.assertEqual(ssh2_fingerprint_blob(very_silly_blob, "md5"),
1177                         b'ac:bd:18:db:4c:c2:f8:5c:ed:ef:65:4f:cc:c4:a4:d8')
1178
1179    def testAES(self):
1180        # My own test cases, generated by a mostly independent
1181        # reference implementation of AES in Python. ('Mostly'
1182        # independent in that it was written by me.)
1183
1184        def vector(cipher, key, iv, plaintext, ciphertext):
1185            for suffix in "hw", "sw":
1186                c = ssh_cipher_new("{}_{}".format(cipher, suffix))
1187                if c is None: return # skip test if HW AES not available
1188                ssh_cipher_setkey(c, key)
1189                ssh_cipher_setiv(c, iv)
1190                self.assertEqualBin(
1191                    ssh_cipher_encrypt(c, plaintext), ciphertext)
1192                ssh_cipher_setiv(c, iv)
1193                self.assertEqualBin(
1194                    ssh_cipher_decrypt(c, ciphertext), plaintext)
1195
1196        # Tests of CBC mode.
1197
1198        key = unhex(
1199            '98483c6eb40b6c31a448c22a66ded3b5e5e8d5119cac8327b655c8b5c4836489')
1200        iv = unhex('38f87b0b9b736160bfc0cbd8447af6ee')
1201        plaintext = unhex('''
1202        ee16271827b12d828f61d56fddccc38ccaa69601da2b36d3af1a34c51947b71a
1203        362f05e07bf5e7766c24599799b252ad2d5954353c0c6ca668c46779c2659c94
1204        8df04e4179666e335470ff042e213c8bcff57f54842237fbf9f3c7e6111620ac
1205        1c007180edd25f0e337c2a49d890a7173f6b52d61e3d2a21ddc8e41513a0e825
1206        afd5932172270940b01014b5b7fb8495946151520a126518946b44ea32f9b2a9
1207        ''')
1208
1209        vector('aes128_cbc', key[:16], iv, plaintext, unhex('''
1210        547ee90514cb6406d5bb00855c8092892c58299646edda0b4e7c044247795c8d
1211        3c3eb3d91332e401215d4d528b94a691969d27b7890d1ae42fe3421b91c989d5
1212        113fefa908921a573526259c6b4f8e4d90ea888e1d8b7747457ba3a43b5b79b9
1213        34873ebf21102d14b51836709ee85ed590b7ca618a1e884f5c57c8ea73fe3d0d
1214        6bf8c082dd602732bde28131159ed0b6e9cf67c353ffdd010a5a634815aaa963'''))
1215
1216        vector('aes192_cbc', key[:24], iv, plaintext, unhex('''
1217        e3dee5122edd3fec5fab95e7db8c784c0cb617103e2a406fba4ae3b4508dd608
1218        4ff5723a670316cc91ed86e413c11b35557c56a6f5a7a2c660fc6ee603d73814
1219        73a287645be0f297cdda97aef6c51faeb2392fec9d33adb65138d60f954babd9
1220        8ee0daab0d1decaa8d1e07007c4a3c7b726948025f9fb72dd7de41f74f2f36b4
1221        23ac6a5b4b6b39682ec74f57d9d300e547f3c3e467b77f5e4009923b2f94c903'''))
1222
1223        vector('aes256_cbc', key[:32], iv, plaintext, unhex('''
1224        088c6d4d41997bea79c408925255266f6c32c03ea465a5f607c2f076ec98e725
1225        7e0beed79609b3577c16ebdf17d7a63f8865278e72e859e2367de81b3b1fe9ab
1226        8f045e1d008388a3cfc4ff87daffedbb47807260489ad48566dbe73256ce9dd4
1227        ae1689770a883b29695928f5983f33e8d7aec4668f64722e943b0b671c365709
1228        dfa86c648d5fb00544ff11bd29121baf822d867e32da942ba3a0d26299bcee13'''))
1229
1230        # Tests of SDCTR mode, one with a random IV and one with an IV
1231        # about to wrap round. More vigorous tests of IV carry and
1232        # wraparound behaviour are in the testAESSDCTR method.
1233
1234        sdctrIVs = [
1235            unhex('38f87b0b9b736160bfc0cbd8447af6ee'),
1236            unhex('fffffffffffffffffffffffffffffffe'),
1237        ]
1238
1239        vector('aes128_ctr', key[:16], sdctrIVs[0], plaintext[:64], unhex('''
1240        d0061d7b6e8c4ef4fe5614b95683383f46cdd2766e66b6fb0b0f0b3a24520b2d
1241        15d869b06cbf685ede064bcf8fb5fb6726cfd68de7016696a126e9e84420af38'''))
1242        vector('aes128_ctr', key[:16], sdctrIVs[1], plaintext[:64], unhex('''
1243        49ac67164fd9ce8701caddbbc9a2b06ac6524d4aa0fdac95253971974b8f3bc2
1244        bb8d7c970f6bcd79b25218cc95582edf7711aae2384f6cf91d8d07c9d9b370bc'''))
1245
1246        vector('aes192_ctr', key[:24], sdctrIVs[0], plaintext[:64], unhex('''
1247        0baa86acbe8580845f0671b7ebad4856ca11b74e5108f515e34e54fa90f87a9a
1248        c6eee26686253c19156f9be64957f0dbc4f8ecd7cabb1f4e0afefe33888faeec'''))
1249        vector('aes192_ctr', key[:24], sdctrIVs[1], plaintext[:64], unhex('''
1250        2da1791250100dc0d1461afe1bbfad8fa0320253ba5d7905d837386ba0a3a41f
1251        01965c770fcfe01cf307b5316afb3981e0e4aa59a6e755f0a5784d9accdc52be'''))
1252
1253        vector('aes256_ctr', key[:32], sdctrIVs[0], plaintext[:64], unhex('''
1254        49c7b284222d408544c770137b6ef17ef770c47e24f61fa66e7e46cae4888882
1255        f980a0f2446956bf47d2aed55ebd2e0694bfc46527ed1fd33efe708fec2f8b1f'''))
1256        vector('aes256_ctr', key[:32], sdctrIVs[1], plaintext[:64], unhex('''
1257        f1d013c3913ccb4fc0091e25d165804480fb0a1d5c741bf012bba144afda6db2
1258        c512f3942018574bd7a8fdd88285a73d25ef81e621aebffb6e9b8ecc8e2549d4'''))
1259
1260    def testAESSDCTR(self):
1261        # A thorough test of the IV-incrementing component of SDCTR
1262        # mode. We set up an AES-SDCTR cipher object with the given
1263        # input IV; we encrypt two all-zero blocks, expecting the
1264        # return values to be the AES-ECB encryptions of the input IV
1265        # and the incremented version. Then we decrypt each of them by
1266        # feeding them to an AES-CBC cipher object with its IV set to
1267        # zero.
1268
1269        def increment(keylen, suffix, iv):
1270            key = b'\xab' * (keylen//8)
1271            sdctr = ssh_cipher_new("aes{}_ctr_{}".format(keylen, suffix))
1272            if sdctr is None: return # skip test if HW AES not available
1273            ssh_cipher_setkey(sdctr, key)
1274            cbc = ssh_cipher_new("aes{}_cbc_{}".format(keylen, suffix))
1275            ssh_cipher_setkey(cbc, key)
1276
1277            ssh_cipher_setiv(sdctr, iv)
1278            ec0 = ssh_cipher_encrypt(sdctr, b'\x00' * 16)
1279            ec1 = ssh_cipher_encrypt(sdctr, b'\x00' * 16)
1280            ssh_cipher_setiv(cbc, b'\x00' * 16)
1281            dc0 = ssh_cipher_decrypt(cbc, ec0)
1282            ssh_cipher_setiv(cbc, b'\x00' * 16)
1283            dc1 = ssh_cipher_decrypt(cbc, ec1)
1284            self.assertEqualBin(iv, dc0)
1285            return dc1
1286
1287        def test(keylen, suffix, ivInteger):
1288            mask = (1 << 128) - 1
1289            ivInteger &= mask
1290            ivBinary = unhex("{:032x}".format(ivInteger))
1291            ivIntegerInc = (ivInteger + 1) & mask
1292            ivBinaryInc = unhex("{:032x}".format((ivIntegerInc)))
1293            actualResult = increment(keylen, suffix, ivBinary)
1294            if actualResult is not None:
1295                self.assertEqualBin(actualResult, ivBinaryInc)
1296
1297        # Check every input IV you can make by gluing together 32-bit
1298        # pieces of the form 0, 1 or -1. This should test all the
1299        # places where carry propagation within the 128-bit integer
1300        # can go wrong.
1301        #
1302        # We also test this at all three AES key lengths, in case the
1303        # core cipher routines are written separately for each one.
1304
1305        for suffix in "hw", "sw":
1306            for keylen in [128, 192, 256]:
1307                hexTestValues = ["00000000", "00000001", "ffffffff"]
1308                for ivHexBytes in itertools.product(*([hexTestValues] * 4)):
1309                    ivInteger = int("".join(ivHexBytes), 16)
1310                    test(keylen, suffix, ivInteger)
1311
1312    def testAESParallelism(self):
1313        # Since at least one of our implementations of AES works in
1314        # parallel, here's a test that CBC decryption works the same
1315        # way no matter how the input data is divided up.
1316
1317        # A pile of conveniently available random-looking test data.
1318        test_ciphertext = ssh2_mpint(last(fibonacci_scattered(14)))
1319        test_ciphertext += b"x" * (15 & -len(test_ciphertext)) # pad to a block
1320
1321        # Test key and IV.
1322        test_key = b"foobarbazquxquuxFooBarBazQuxQuux"
1323        test_iv = b"FOOBARBAZQUXQUUX"
1324
1325        for keylen in [128, 192, 256]:
1326            decryptions = []
1327
1328            for suffix in "hw", "sw":
1329                c = ssh_cipher_new("aes{:d}_cbc_{}".format(keylen, suffix))
1330                if c is None: continue
1331                ssh_cipher_setkey(c, test_key[:keylen//8])
1332                for chunklen in range(16, 16*12, 16):
1333                    ssh_cipher_setiv(c, test_iv)
1334                    decryption = b""
1335                    for pos in range(0, len(test_ciphertext), chunklen):
1336                        chunk = test_ciphertext[pos:pos+chunklen]
1337                        decryption += ssh_cipher_decrypt(c, chunk)
1338                    decryptions.append(decryption)
1339
1340            for d in decryptions:
1341                self.assertEqualBin(d, decryptions[0])
1342
1343    def testCRC32(self):
1344        # Check the effect of every possible single-byte input to
1345        # crc32_update. In the traditional implementation with a
1346        # 256-word lookup table, this exercises every table entry; in
1347        # _any_ implementation which iterates over the input one byte
1348        # at a time, it should be a similarly exhaustive test. (But if
1349        # a more optimised implementation absorbed _more_ than 8 bits
1350        # at a time, then perhaps this test wouldn't be enough...)
1351
1352        # It would be nice if there was a functools.iterate() which
1353        # would apply a function n times. Failing that, making shift1
1354        # accept and ignore a second argument allows me to iterate it
1355        # 8 times using functools.reduce.
1356        shift1 = lambda x, dummy=None: (x >> 1) ^ (0xEDB88320 * (x & 1))
1357        shift8 = lambda x: functools.reduce(shift1, [None]*8, x)
1358
1359        # A small selection of choices for the other input to
1360        # crc32_update, just to check linearity.
1361        test_prior_values = [0, 0xFFFFFFFF, 0x45CC1F6A, 0xA0C4ADCF, 0xD482CDF1]
1362
1363        for prior in test_prior_values:
1364            prior_shifted = shift8(prior)
1365            for i in range(256):
1366                exp = shift8(i) ^ prior_shifted
1367                self.assertEqual(crc32_update(prior, struct.pack("B", i)), exp)
1368
1369                # Check linearity of the _reference_ implementation, while
1370                # we're at it!
1371                self.assertEqual(shift8(i ^ prior), exp)
1372
1373    def testCRCDA(self):
1374        def pattern(badblk, otherblks, pat):
1375            # Arrange copies of the bad block in a pattern
1376            # corresponding to the given bit string.
1377            retstr = b""
1378            while pat != 0:
1379                retstr += (badblk if pat & 1 else next(otherblks))
1380                pat >>= 1
1381            return retstr
1382
1383        def testCases(pat):
1384            badblock = b'muhahaha' # the block we'll maliciously repeat
1385
1386            # Various choices of the other blocks, including all the
1387            # same, all different, and all different but only in the
1388            # byte at one end.
1389            for otherblocks in [
1390                    itertools.repeat(b'GoodData'),
1391                    (struct.pack('>Q', i) for i in itertools.count()),
1392                    (struct.pack('<Q', i) for i in itertools.count())]:
1393                yield pattern(badblock, otherblocks, pat)
1394
1395        def positiveTest(pat):
1396            for data in testCases(pat):
1397                self.assertTrue(crcda_detect(data, ""))
1398                self.assertTrue(crcda_detect(data[8:], data[:8]))
1399
1400        def negativeTest(pat):
1401            for data in testCases(pat):
1402                self.assertFalse(crcda_detect(data, ""))
1403                self.assertFalse(crcda_detect(data[8:], data[:8]))
1404
1405        # Tests of successful attack detection, derived by taking
1406        # multiples of the CRC polynomial itself.
1407        #
1408        # (The CRC32 polynomial is usually written as 0xEDB88320.
1409        # That's in bit-reversed form, but then, that's the form we
1410        # need anyway for these patterns. But it's also missing the
1411        # leading term - really, 0xEDB88320 is the value you get by
1412        # reducing X^32 modulo the real poly, i.e. the value you put
1413        # back in to the CRC to compensate for an X^32 that's just
1414        # been shifted out. If you put that bit back on - at the
1415        # bottom, because of the bit-reversal - you get the less
1416        # familiar-looking 0x1db710641.)
1417        positiveTest(0x1db710641) # the CRC polynomial P itself
1418        positiveTest(0x26d930ac3) # (X+1) * P
1419        positiveTest(0xbdbdf21cf) # (X^3+X^2+X+1) * P
1420        positiveTest(0x3a66a39b653f6889d)
1421        positiveTest(0x170db3167dd9f782b9765214c03e71a18f685b7f3)
1422        positiveTest(0x1751997d000000000000000000000000000000001)
1423        positiveTest(0x800000000000000000000000000000000f128a2d1)
1424
1425        # Tests of non-detection.
1426        negativeTest(0x1db711a41)
1427        negativeTest(0x3a66a39b453f6889d)
1428        negativeTest(0x170db3167dd9f782b9765214c03e71b18f685b7f3)
1429        negativeTest(0x1751997d000000000000000000000001000000001)
1430        negativeTest(0x800000000000002000000000000000000f128a2d1)
1431
1432    def testAuxEncryptFns(self):
1433        # Test helper functions such as aes256_encrypt_pubkey. The
1434        # test cases are all just things I made up at random, and the
1435        # expected outputs are generated by running PuTTY's own code;
1436        # this doesn't independently check them against any other
1437        # implementation, but it at least means we're protected
1438        # against code reorganisations changing the behaviour from
1439        # what it was before.
1440
1441        p = b'three AES blocks, or six DES, of arbitrary input'
1442
1443        k = b'thirty-two-byte aes-256 test key'
1444        iv = b'\0' * 16
1445        c = unhex('7b112d00c0fc95bc13fcdacfd43281bf'
1446                  'de9389db1bbcfde79d59a303d41fd2eb'
1447                  '0955c9477ae4ee3a4d6c1fbe474c0ef6')
1448        self.assertEqualBin(aes256_encrypt_pubkey(k, iv, p), c)
1449        self.assertEqualBin(aes256_decrypt_pubkey(k, iv, c), p)
1450
1451        # same k as in the previous case
1452        iv = unhex('0102030405060708090a0b0c0d0e0f10')
1453        c = unhex('9e9c8a91b739677b834397bdd8e70c05'
1454                  'c3e2cf6cce68d376d798a59848621c6d'
1455                  '42b9e7101260a438daadd7b742875a36')
1456        self.assertEqualBin(aes256_encrypt_pubkey(k, iv, p), c)
1457        self.assertEqualBin(aes256_decrypt_pubkey(k, iv, c), p)
1458
1459        k = b'3des with keys distinct.'
1460        iv = b'randomIV'
1461        c = unhex('be81ff840d885869a54d63b03d7cd8db'
1462                  'd39ab875e5f7b9da1081f8434cb33c47'
1463                  'dee5bcd530a3f6c13a9fc73e321a843a')
1464        self.assertEqualBin(des3_encrypt_pubkey_ossh(k, iv, p), c)
1465        self.assertEqualBin(des3_decrypt_pubkey_ossh(k, iv, c), p)
1466
1467        k = b'3des, 2keys only'
1468        c = unhex('0b845650d73f615cf16ee3ed20535b5c'
1469                  'd2a8866ee628547bbdad916e2b4b9f19'
1470                  '67c15bde33c5b03ff7f403b4f8cf2364')
1471        self.assertEqualBin(des3_encrypt_pubkey(k, p), c)
1472        self.assertEqualBin(des3_decrypt_pubkey(k, c), p)
1473
1474        k = b'7 bytes'
1475        c = unhex('5cac9999cffc980a1d1184d84b71c8cb'
1476                  '313d12a1d25a7831179aeb11edaca5ad'
1477                  '9482b224105a61c27137587620edcba8')
1478        self.assertEqualBin(des_encrypt_xdmauth(k, p), c)
1479        self.assertEqualBin(des_decrypt_xdmauth(k, c), p)
1480
1481    def testSSHCiphers(self):
1482        # Test all the SSH ciphers we support, on the same principle
1483        # as testAuxCryptFns that we should have test cases to verify
1484        # that things still work the same today as they did yesterday.
1485
1486        p = b'64 bytes of test input data, enough to check any cipher mode xyz'
1487        k = b'sixty-four bytes of test key data, enough to key any cipher pqrs'
1488        iv = b'16 bytes of IV w'
1489
1490        ciphers = [
1491            ("3des_ctr",      24,    8, False, unhex('83c17a29250d3d4fa81250fc0362c54e40456936445b77709a30fccf8b983d57129a969c59070d7c2977f3d25dd7d71163687c7b3cd2edb0d07514e6c77479f5')),
1492            ("3des_ssh2",     24,    8, True,  unhex('d5f1cc25b8fbc62decc74b432344de674f7249b2e38871f764411eaae17a1097396bd97b66a1e4d49f08c219acaef2a483198ce837f75cc1ef67b37c2432da3e')),
1493            ("3des_ssh1",     24,    8, False, unhex('d5f1cc25b8fbc62de63590b9b92344adf6dd72753273ff0fb32d4dbc6af858529129f34242f3d557eed3a5c84204eb4f868474294964cf70df5d8f45dfccfc45')),
1494            ("des_cbc",        8,    8, True,  unhex('051524e77fb40e109d9fffeceacf0f28c940e2f8415ddccc117020bdd2612af5036490b12085d0e46129919b8e499f51cb82a4b341d7a1a1ea3e65201ef248f6')),
1495            ("aes256_ctr",    32,   16, False, unhex('b87b35e819f60f0f398a37b05d7bcf0b04ad4ebe570bd08e8bfa8606bafb0db2cfcd82baf2ccceae5de1a3c1ae08a8b8fdd884fdc5092031ea8ce53333e62976')),
1496            ("aes256_ctr_hw", 32,   16, False, unhex('b87b35e819f60f0f398a37b05d7bcf0b04ad4ebe570bd08e8bfa8606bafb0db2cfcd82baf2ccceae5de1a3c1ae08a8b8fdd884fdc5092031ea8ce53333e62976')),
1497            ("aes256_ctr_sw", 32,   16, False, unhex('b87b35e819f60f0f398a37b05d7bcf0b04ad4ebe570bd08e8bfa8606bafb0db2cfcd82baf2ccceae5de1a3c1ae08a8b8fdd884fdc5092031ea8ce53333e62976')),
1498            ("aes256_cbc",    32,   16, True,  unhex('381cbb2fbcc48118d0094540242bd990dd6af5b9a9890edd013d5cad2d904f34b9261c623a452f32ea60e5402919a77165df12862742f1059f8c4a862f0827c5')),
1499            ("aes256_cbc_hw", 32,   16, True,  unhex('381cbb2fbcc48118d0094540242bd990dd6af5b9a9890edd013d5cad2d904f34b9261c623a452f32ea60e5402919a77165df12862742f1059f8c4a862f0827c5')),
1500            ("aes256_cbc_sw", 32,   16, True,  unhex('381cbb2fbcc48118d0094540242bd990dd6af5b9a9890edd013d5cad2d904f34b9261c623a452f32ea60e5402919a77165df12862742f1059f8c4a862f0827c5')),
1501            ("aes192_ctr",    24,   16, False, unhex('06bcfa7ccf075d723e12b724695a571a0fad67c56287ea609c410ac12749c51bb96e27fa7e1c7ea3b14792bbbb8856efb0617ebec24a8e4a87340d820cf347b8')),
1502            ("aes192_ctr_hw", 24,   16, False, unhex('06bcfa7ccf075d723e12b724695a571a0fad67c56287ea609c410ac12749c51bb96e27fa7e1c7ea3b14792bbbb8856efb0617ebec24a8e4a87340d820cf347b8')),
1503            ("aes192_ctr_sw", 24,   16, False, unhex('06bcfa7ccf075d723e12b724695a571a0fad67c56287ea609c410ac12749c51bb96e27fa7e1c7ea3b14792bbbb8856efb0617ebec24a8e4a87340d820cf347b8')),
1504            ("aes192_cbc",    24,   16, True,  unhex('ac97f8698170f9c05341214bd7624d5d2efef8311596163dc597d9fe6c868971bd7557389974612cbf49ea4e7cc6cc302d4cc90519478dd88a4f09b530c141f3')),
1505            ("aes192_cbc_hw", 24,   16, True,  unhex('ac97f8698170f9c05341214bd7624d5d2efef8311596163dc597d9fe6c868971bd7557389974612cbf49ea4e7cc6cc302d4cc90519478dd88a4f09b530c141f3')),
1506            ("aes192_cbc_sw", 24,   16, True,  unhex('ac97f8698170f9c05341214bd7624d5d2efef8311596163dc597d9fe6c868971bd7557389974612cbf49ea4e7cc6cc302d4cc90519478dd88a4f09b530c141f3')),
1507            ("aes128_ctr",    16,   16, False, unhex('0ad4ddfd2360ec59d77dcb9a981f92109437c68c5e7f02f92017d9f424f89ab7850473ac0e19274125e740f252c84ad1f6ad138b6020a03bdaba2f3a7378ce1e')),
1508            ("aes128_ctr_hw", 16,   16, False, unhex('0ad4ddfd2360ec59d77dcb9a981f92109437c68c5e7f02f92017d9f424f89ab7850473ac0e19274125e740f252c84ad1f6ad138b6020a03bdaba2f3a7378ce1e')),
1509            ("aes128_ctr_sw", 16,   16, False, unhex('0ad4ddfd2360ec59d77dcb9a981f92109437c68c5e7f02f92017d9f424f89ab7850473ac0e19274125e740f252c84ad1f6ad138b6020a03bdaba2f3a7378ce1e')),
1510            ("aes128_cbc",    16,   16, True,  unhex('36de36917fb7955a711c8b0bf149b29120a77524f393ae3490f4ce5b1d5ca2a0d7064ce3c38e267807438d12c0e40cd0d84134647f9f4a5b11804a0cc5070e62')),
1511            ("aes128_cbc_hw", 16,   16, True,  unhex('36de36917fb7955a711c8b0bf149b29120a77524f393ae3490f4ce5b1d5ca2a0d7064ce3c38e267807438d12c0e40cd0d84134647f9f4a5b11804a0cc5070e62')),
1512            ("aes128_cbc_sw", 16,   16, True,  unhex('36de36917fb7955a711c8b0bf149b29120a77524f393ae3490f4ce5b1d5ca2a0d7064ce3c38e267807438d12c0e40cd0d84134647f9f4a5b11804a0cc5070e62')),
1513            ("blowfish_ctr",  32,    8, False, unhex('079daf0f859363ccf72e975764d709232ec48adc74f88ccd1f342683f0bfa89ca0e8dbfccc8d4d99005d6b61e9cc4e6eaa2fd2a8163271b94bf08ef212129f01')),
1514            ("blowfish_ssh2", 16,    8, True,  unhex('e986b7b01f17dfe80ee34cac81fa029b771ec0f859ae21ae3ec3df1674bc4ceb54a184c6c56c17dd2863c3e9c068e76fd9aef5673465995f0d648b0bb848017f')),
1515            ("blowfish_ssh1", 32,    8, True,  unhex('d44092a9035d895acf564ba0365d19570fbb4f125d5a4fd2a1812ee6c8a1911a51bb181fbf7d1a261253cab71ee19346eb477b3e7ecf1d95dd941e635c1a4fbf')),
1516            ("arcfour256",    32, None, False, unhex('db68db4cd9bbc1d302cce5919ff3181659272f5d38753e464b3122fc69518793fe15dd0fbdd9cd742bd86c5e8a3ae126c17ecc420bd2d5204f1a24874d00fda3')),
1517            ("arcfour128",    16, None, False, unhex('fd4af54c5642cb29629e50a15d22e4944e21ffba77d0543b27590eafffe3886686d1aefae0484afc9e67edc0e67eb176bbb5340af1919ea39adfe866d066dd05')),
1518        ]
1519
1520        for alg, keylen, ivlen, simple_cbc, c in ciphers:
1521            cipher = ssh_cipher_new(alg)
1522            if cipher is None:
1523                continue # hardware-accelerated cipher not available
1524
1525            ssh_cipher_setkey(cipher, k[:keylen])
1526            if ivlen is not None:
1527                ssh_cipher_setiv(cipher, iv[:ivlen])
1528            self.assertEqualBin(ssh_cipher_encrypt(cipher, p), c)
1529
1530            ssh_cipher_setkey(cipher, k[:keylen])
1531            if ivlen is not None:
1532                ssh_cipher_setiv(cipher, iv[:ivlen])
1533            self.assertEqualBin(ssh_cipher_decrypt(cipher, c), p)
1534
1535            if simple_cbc:
1536                # CBC ciphers (other than the three-layered CBC used
1537                # by SSH-1 3DES) have more specific semantics for
1538                # their IV than 'some kind of starting state for the
1539                # cipher mode': the IV is specifically supposed to
1540                # represent the previous block of ciphertext. So we
1541                # can check that, by supplying the IV _as_ a
1542                # ciphertext block via a call to decrypt(), and seeing
1543                # if that causes our test ciphertext to decrypt the
1544                # same way as when we provided the same IV via
1545                # setiv().
1546                ssh_cipher_setkey(cipher, k[:keylen])
1547                ssh_cipher_decrypt(cipher, iv[:ivlen])
1548                self.assertEqualBin(ssh_cipher_decrypt(cipher, c), p)
1549
1550    def testRSAKex(self):
1551        # Round-trip test of the RSA key exchange functions, plus a
1552        # hardcoded plain/ciphertext pair to guard against the
1553        # behaviour accidentally changing.
1554        def blobs(n, e, d, p, q, iqmp):
1555            # For RSA kex, the public blob is formatted exactly like
1556            # any other SSH-2 RSA public key. But there's no private
1557            # key blob format defined by the protocol, so for the
1558            # purposes of making a test RSA private key, we borrow the
1559            # function we already had that decodes one out of the wire
1560            # format used in the SSH-1 agent protocol.
1561            pubblob = ssh_string(b"ssh-rsa") + ssh2_mpint(e) + ssh2_mpint(n)
1562            privblob = (ssh_uint32(nbits(n)) + ssh1_mpint(n) + ssh1_mpint(e) +
1563                        ssh1_mpint(d) + ssh1_mpint(iqmp) +
1564                        ssh1_mpint(q) + ssh1_mpint(p))
1565            return pubblob, privblob
1566
1567        # Parameters for a test key.
1568        p = 0xf49e4d21c1ec3d1c20dc8656cc29aadb2644a12c98ed6c81a6161839d20d398d
1569        q = 0xa5f0bc464bf23c4c83cf17a2f396b15136fbe205c07cb3bb3bdb7ed357d1cd13
1570        n = p*q
1571        e = 37
1572        d = int(mp_invert(e, (p-1)*(q-1)))
1573        iqmp = int(mp_invert(q, p))
1574        assert iqmp * q % p == 1
1575        assert d * e % (p-1) == 1
1576        assert d * e % (q-1) == 1
1577
1578        pubblob, privblob = blobs(n, e, d, p, q, iqmp)
1579
1580        pubkey = ssh_rsakex_newkey(pubblob)
1581        privkey = get_rsa_ssh1_priv_agent(privblob)
1582
1583        plain = 0x123456789abcdef
1584        hashalg = 'md5'
1585        with queued_random_data(64, "rsakex encrypt test"):
1586            cipher = ssh_rsakex_encrypt(pubkey, hashalg, ssh2_mpint(plain))
1587        decoded = ssh_rsakex_decrypt(privkey, hashalg, cipher)
1588        self.assertEqual(int(decoded), plain)
1589        self.assertEqualBin(cipher, unhex(
1590            '34277d1060dc0a434d98b4239de9cec59902a4a7d17a763587cdf8c25d57f51a'
1591            '7964541892e7511798e61dd78429358f4d6a887a50d2c5ebccf0e04f48fc665c'
1592        ))
1593
1594    def testMontgomeryKexLowOrderPoints(self):
1595        # List of all the bad input values for Curve25519 which can
1596        # end up generating a zero output key. You can find the first
1597        # five (the ones in canonical representation, i.e. in
1598        # [0,2^255-19)) by running
1599        # find_montgomery_power2_order_x_values(curve25519.p, curve25519.a)
1600        # and then encoding the results little-endian.
1601        bad_keys_25519 = [
1602            "0000000000000000000000000000000000000000000000000000000000000000",
1603            "0100000000000000000000000000000000000000000000000000000000000000",
1604            "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157",
1605            "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800",
1606            "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
1607
1608            # Input values less than 2^255 are reduced mod p, so those
1609            # of the above values which are still in that range when
1610            # you add 2^255-19 to them should also be caught.
1611            "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
1612            "eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f",
1613
1614            # Input values are reduced mod 2^255 before reducing mod
1615            # p. So setting the high-order bit of any of the above 7
1616            # values should also lead to rejection, because it will be
1617            # stripped off and then the value will be recognised as
1618            # one of the above.
1619            "0000000000000000000000000000000000000000000000000000000000000080",
1620            "0100000000000000000000000000000000000000000000000000000000000080",
1621            "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f11d7",
1622            "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b880",
1623            "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1624            "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1625            "eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
1626        ]
1627
1628        # Same for Curve448, found by the analogous eccref function call
1629        # find_montgomery_power2_order_x_values(curve448.p, curve448.a)
1630        bad_keys_448 = [
1631            # The first three are the bad values in canonical
1632            # representationm. In Curve448 these are just 0, 1 and -1.
1633            '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
1634            '0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
1635            'fefffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff',
1636
1637            # As with Curve25519, we must also include values in
1638            # non-canonical representation that reduce to one of the
1639            # above mod p.
1640            'fffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffff',
1641            '00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
1642
1643            # But that's all, because Curve448 fits neatly into a
1644            # whole number of bytes, so there's no secondary reduction
1645            # mod a power of 2.
1646        ]
1647
1648        with random_prng("doesn't matter"):
1649            ecdh25519 = ssh_ecdhkex_newkey('curve25519')
1650            ecdh448 = ssh_ecdhkex_newkey('curve448')
1651        for pub in bad_keys_25519:
1652            key = ssh_ecdhkex_getkey(ecdh25519, unhex(pub))
1653            self.assertEqual(key, None)
1654        for pub in bad_keys_448:
1655            key = ssh_ecdhkex_getkey(ecdh448, unhex(pub))
1656            self.assertEqual(key, None)
1657
1658    def testPRNG(self):
1659        hashalg = 'sha256'
1660        seed = b"hello, world"
1661        entropy = b'1234567890' * 100
1662
1663        # Replicate the generation of some random numbers. to ensure
1664        # they really are the hashes of what they're supposed to be.
1665        pr = prng_new(hashalg)
1666        prng_seed_begin(pr)
1667        prng_seed_update(pr, seed)
1668        prng_seed_finish(pr)
1669        data1 = prng_read(pr, 128)
1670        data2 = prng_read(pr, 127) # a short read shouldn't confuse things
1671        prng_add_entropy(pr, 0, entropy) # forces a reseed
1672        data3 = prng_read(pr, 128)
1673
1674        le128 = lambda x: le_integer(x, 128)
1675
1676        key1 = hash_str(hashalg, b'R' + seed)
1677        expected_data1 = b''.join(
1678            hash_str(hashalg, key1 + b'G' + le128(counter))
1679            for counter in range(4))
1680        # After prng_read finishes, we expect the PRNG to have
1681        # automatically reseeded itself, so that if its internal state
1682        # is revealed then the previous output can't be reconstructed.
1683        key2 = hash_str(hashalg, key1 + b'R')
1684        expected_data2 = b''.join(
1685            hash_str(hashalg, key2 + b'G' + le128(counter))
1686            for counter in range(4,8))
1687        # There will have been another reseed after the second
1688        # prng_read, and then another due to the entropy.
1689        key3 = hash_str(hashalg, key2 + b'R')
1690        key4 = hash_str(hashalg, key3 + b'R' + hash_str(hashalg, entropy))
1691        expected_data3 = b''.join(
1692            hash_str(hashalg, key4 + b'G' + le128(counter))
1693            for counter in range(8,12))
1694
1695        self.assertEqualBin(data1, expected_data1)
1696        self.assertEqualBin(data2, expected_data2[:127])
1697        self.assertEqualBin(data3, expected_data3)
1698
1699    def testHashPadding(self):
1700        # A consistency test for hashes that use MD5/SHA-1/SHA-2 style
1701        # padding of the message into a whole number of fixed-size
1702        # blocks. We test-hash a message of every length up to twice
1703        # the block length, to make sure there's no off-by-1 error in
1704        # the code that decides how much padding to put on.
1705
1706        # Source: generated using Python hashlib as an independent
1707        # implementation. The function below will do it, called with
1708        # parameters such as (hashlib.sha256,128).
1709        #
1710        # def gen_testcase(hashclass, maxlen):
1711        #    return hashclass(b''.join(hashclass(text[:i]).digest()
1712        #             for i in range(maxlen))).hexdigest()
1713
1714        text = """
1715Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
1716eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
1717minim veniam, quis nostrud exercitation ullamco laboris nisi ut
1718aliquip ex ea commodo consequat. Duis aute irure dolor in
1719reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
1720pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
1721culpa qui officia deserunt mollit anim id est laborum.
1722        """.replace('\n', ' ').strip()
1723
1724        def test(hashname, maxlen, expected):
1725            assert len(text) >= maxlen
1726            buf = b''.join(hash_str(hashname, text[:i])
1727                           for i in range(maxlen))
1728            self.assertEqualBin(hash_str(hashname, buf), unhex(expected))
1729
1730        test('md5', 128, '8169d766cc3b8df182b3ce756ae19a15')
1731        test('sha1', 128, '3691759577deb3b70f427763a9c15acb9dfc0259')
1732        test('sha256', 128, 'ec539c4d678412c86c13ee4eb9452232'
1733             '35d4eed3368d876fdf10c9df27396640')
1734        test('sha512', 256,
1735             'cb725b4b4ec0ac1174d69427b4d97848b7db4fc01181f99a8049a4d721862578'
1736             'f91e026778bb2d389a9dd88153405189e6ba438b213c5387284103d2267fd055'
1737        )
1738
1739    def testDSA(self):
1740        p = 0xe93618c54716992ffd54e79df6e1b0edd517f7bbe4a49d64631eb3efe8105f676e8146248cfb4f05720862533210f0c2ab0f9dd61dbc0e5195200c4ebd95364b
1741        q = 0xf3533bcece2e164ca7c5ce64bc1e395e9a15bbdd
1742        g = 0x5ac9d0401c27d7abfbc5c17cdc1dc43323cd0ef18b79e1909bdace6d17af675a10d37dde8bd8b70e72a8666592216ccb00614629c27e870e4fbf393b812a9f05
1743        y = 0xac3ddeb22d65a5a2ded4a28418b2a748d8e5e544ba5e818c137d7b042ef356b0ef6d66cfca0b3ab5affa2969522e7b07bee60562fa4869829a5afce0ad0c4cd0
1744        x = 0x664f8250b7f1a5093047fe0c7fe4b58e46b73295
1745        pubblob = ssh_string(b"ssh-dss") + b"".join(map(ssh2_mpint, [p,q,g,y]))
1746        privblob = ssh2_mpint(x)
1747        pubkey = ssh_key_new_pub('dsa', pubblob)
1748        privkey = ssh_key_new_priv('dsa', pubblob, privblob)
1749
1750        sig = ssh_key_sign(privkey, b"hello, world", 0)
1751        self.assertTrue(ssh_key_verify(pubkey, sig, b"hello, world"))
1752        self.assertFalse(ssh_key_verify(pubkey, sig, b"hello, again"))
1753
1754        badsig0 = unhex('{:040x}{:040x}'.format(1, 0))
1755        badsigq = unhex('{:040x}{:040x}'.format(1, q))
1756        self.assertFalse(ssh_key_verify(pubkey, badsig0, "hello, world"))
1757        self.assertFalse(ssh_key_verify(pubkey, badsigq, "hello, world"))
1758        self.assertFalse(ssh_key_verify(pubkey, badsig0, "hello, again"))
1759        self.assertFalse(ssh_key_verify(pubkey, badsigq, "hello, again"))
1760
1761    def testBLAKE2b(self):
1762        # The standard test vectors for BLAKE2b (in the separate class
1763        # below) don't satisfy me because they only test one hash
1764        # size. These additional tests exercise BLAKE2b's configurable
1765        # output length. The expected results are derived from the
1766        # BLAKE2 reference implementation.
1767
1768        def b2_with_len(data, length):
1769            h = blake2b_new_general(length)
1770            h.update(data)
1771            return h.digest()[:length]
1772
1773        self.assertEqualBin(b2_with_len(b'hello', 1), unhex("29"))
1774        self.assertEqualBin(b2_with_len(b'hello', 2), unhex("accd"))
1775        self.assertEqualBin(b2_with_len(b'hello', 3), unhex("980032"))
1776        self.assertEqualBin(b2_with_len(b'hello', 5), unhex("9baecc38f2"))
1777        self.assertEqualBin(b2_with_len(b'hello', 8), unhex(
1778            "a7b6eda801e5347d"))
1779        self.assertEqualBin(b2_with_len(b'hello', 13), unhex(
1780            "6eedb122c6707328a66aa34a07"))
1781        self.assertEqualBin(b2_with_len(b'hello', 21), unhex(
1782            "c7f0f74a227116547b3d2788e927ee2a76c87d8797"))
1783        self.assertEqualBin(b2_with_len(b'hello', 34), unhex(
1784            "2f5fcdf2b870fa254051dd448193a1fb6e92be122efca539ba2aeac0bc6c77d0"
1785            "dadc"))
1786        self.assertEqualBin(b2_with_len(b'hello', 55), unhex(
1787            "daafcf2bd6fccf976cbc234b71cd9f4f7d56fe0eb33a40018707089a215c44a8"
1788            "4b272d0329ae6d85a0f8acc7e964dc2facb715ba472bb6"))
1789
1790    def testArgon2LongHash(self):
1791        # Unit-test the Argon2 long hash function H', which starts off
1792        # the same as BLAKE2b, but comes with its own method of
1793        # extending the output length past 64 bytes.
1794        #
1795        # I generated these test values using a test program linked
1796        # against the reference implementation's libargon2.a and
1797        # calling its blake2b_long function.
1798        preimage = b'hello, world'
1799
1800        self.assertEqualBin(argon2_long_hash(1, preimage), unhex("8b"))
1801        self.assertEqualBin(argon2_long_hash(2, preimage), unhex("1ff9"))
1802        self.assertEqualBin(argon2_long_hash(63, preimage), unhex(
1803            "e2c997721f1d64aa8c25e588fb8ab19646ce6d5c2a431fa560fcb813e55dd481"
1804            "322d2630d95ca6b1b63317b13d6b111e5816170c80c3ca7d5b4bf894096de4"))
1805        self.assertEqualBin(argon2_long_hash(64, preimage), unhex(
1806            "0c7ba7ee6d510b4bb5c9b69ac91e25e0b11aa30dd6234b8e61b0fe1537c037b8"
1807            "8ed5aa59a277e8cc07095c81aff26d08967e4dfdabd32db8b6af6ceb78cf8c47"))
1808        self.assertEqualBin(argon2_long_hash(65, preimage), unhex(
1809            "680941abbd8fc80f28c38d623e90903f08709bf76575e2775d4ce01c31b192c8"
1810            "73038d9a31af8991c8b1ad4f2b1991f4d15f73ab0f4f3add415c297a12eb9ddb"
1811            "76"))
1812        self.assertEqualBin(argon2_long_hash(95, preimage), unhex(
1813            "4be28c51850fed70d9403e1406b6ba68a83d98cf222a4ee162beef60fd3384df"
1814            "eba3fce9d95f646982eb384ac943ce5263cb03428fd8d261cc41ffdb7ba328fe"
1815            "098526f2b49593f9e7f38188598ce4693b59f4dd32db30c1be9a9d35784fa0"))
1816        self.assertEqualBin(argon2_long_hash(96, preimage), unhex(
1817            "20295ea01e822cca113f668f33e5e481ed5879bfd7de6359ea42d497da97be52"
1818            "2cdd518d34ae32c44cabd45249b4e697626b0b14b6a33a2bd138be0a4bceeaf4"
1819            "9528f93acef01b093ee84d8d871d1ee6cf7c10e83ad0619631aed19345166f03"))
1820        self.assertEqualBin(argon2_long_hash(97, preimage), unhex(
1821            "d24b31f3ac0baad168d524efc4bafee55fef743fd60b14e28b860d7523e319c7"
1822            "520e2d5457cc3d06dc1044530afdf6990fa12e38d5802eb642f8e77fcfee2c0b"
1823            "1f84a28877f2f2f049ed9299e1e0230f98af3a161185970aad21f0ea0f5184cf"
1824            "90"))
1825        self.assertEqualBin(argon2_long_hash(127, preimage), unhex(
1826            "5d1e8380450dbc985418ed1f3700b925ae0719e4486e29131c81bca7083ac6b8"
1827            "f535c3398488e34d3dc1390de44097f1eee498f10ebe85b579e99a7672023b01"
1828            "ca5c20e63c595b640e00d80f113a52e3773719889b266ab4c65269c11fb212e4"
1829            "75f2b769bb26321bb60ecc0d490821e5056d7dfc9def3cd065d3ba90360764"))
1830        self.assertEqualBin(argon2_long_hash(128, preimage), unhex(
1831            "be15b316f3483c4d0d00f71a65b974894a2025f441b79b9fe461bc740cb0b039"
1832            "c4fe914f61c05a612d63ebc50a662b2d59b1996091e5e3474340544ea46a46cb"
1833            "25c41ff700fafcd96c4f12ddc698cd2426558f960696837ea8170fd2fe284b54"
1834            "8f585f97919ef14f2b3cbb351eb98872add7ba6d08c1401232df6cc878fbeb22"))
1835        self.assertEqualBin(argon2_long_hash(129, preimage), unhex(
1836            "83da464c278dcb12c29b6685fee6d32f0b461337c155369ad0d56b58b0aa5f80"
1837            "9aa7b56bd41b664c8d768957f8f0e40999fb0178eb53cf83f31d725bf92881bc"
1838            "900774bce4cdf56b6386ad3de6891d11a0ccd4564a3431fc4c24105a02d0a6a2"
1839            "434712b9a7471f3223c72a6e64912200d0a3d149a19d06fe9dc8ec09d7ed5a48"
1840            "bb"))
1841        self.assertEqualBin(argon2_long_hash(511, preimage), unhex(
1842            "30c0c0d0467e7665368db0b40a2324a61fb569d35172de2df53a9739a8d18e60"
1843            "b4f25d521c8855604be3e24ea56302566074323d94c0bd3a33d08f185d8ba5ac"
1844            "a2bc3fb2e4c4e5ffec5778daea67c6b5913c9cac16f2e5c7b7818e757fa747b3"
1845            "69e586d616010a752762f69c604238ed8738430366fbdb7493454fa02391a76b"
1846            "30f241695b9fa8d3a3116227c6bb6f72d325cf104ab153d15f928b22767d467d"
1847            "4bf7e16176aaa7315954b7872061933c12d548f1f93a8abb9d73791661bee521"
1848            "b2ae51be373a229dfef32787234c1be5846d133563002b9a029178716ad41e70"
1849            "1539d3fad300c77607c5217701e3e485d72c980f3f71d525c8148375a2f8d22c"
1850            "a211ba165330a90b7e0e6baa6073833925c23bdd388ee904f38463c7e6b85475"
1851            "09b810aae5c9ffc5dd902c2ffe049c338e3ae2c6416d3b874d6a9d384089564c"
1852            "0d8e4dce9b6e47e1d5ec9087bf526cc9fa35aab1893a0588d31b77fea37e0799"
1853            "468deacde47629d2960a3519b3bcd4e22364a9cccd3b128cba21cac27f140d53"
1854            "f79c11e4157e4cb48272eecdf62f52084a27e5b0933bbe66ded17e2df6f8d398"
1855            "f6c479c3c716457820ad177b8bd9334cb594e03d09fcc4f82d4385e141eacd7d"
1856            "9ad1e1c4cb42788af70bac0509f0a891e662960955490abf2763373803e8c89c"
1857            "df632579cb9c647634b30df214a3d67b92fd55d283c42c63b470a48a78cd5b"))
1858        self.assertEqualBin(argon2_long_hash(512, preimage), unhex(
1859            "79a6974e29a9a6c069e0156774d35c5014a409f5ffc60013725367a7208d4929"
1860            "7d228637751768a31a59e27aa89372f1bcc095a6fa331198a5bd5ad053ba2ebb"
1861            "cbcc501ea55cf142e8d95209228c9ab60cd104d5077472f2a9ecaa071aed6ee9"
1862            "5de29e188b7399d5b6b7ed897b2bc4dd1ea745eb9974e39ca6fb983380cc537a"
1863            "c04dfe6caefe85faf206b1613092ebadf791eaa8a5b814c9a79a73a5733b0505"
1864            "a47163c10a0f7309df6663896df6079a7c88c6879bb591a40abd398c6deda792"
1865            "1cc3986435b1c840a768b2fa507446f2f77a406b1b2f739f7795db24789c8927"
1866            "24b4c84b7005445123154f8cd2ba63a7ede672af5d197f846700732025c9931d"
1867            "1c67c5493417ca394a8f68ba532645815cf7b5102af134ecb4fd9e326f53779a"
1868            "3039dbef6a0880db9e38b6b61d2f9ead969e4224c2d9c69b5897e5eeb7032e83"
1869            "334e192ff50017056ccb84d4cc8eee3ab248d2614643d0174fe18c72186dd967"
1870            "92d8545645ddf4a9b2c7a91c9a71857a399449d7154077a8e9580f1a2d20227d"
1871            "671b455ccb897cba0491e50892120d7877f7776d653cfdb176fa3f64a9e6f848"
1872            "cd681c487b488775aaf698294eec813b2cca90d68d63b5d886d61c1a8e922aaa"
1873            "330fd658ede56e34bcd288048e845eba7b8e2e7cc22ba6c91b523e48017aa878"
1874            "8ce4f91d0e6d6c6706762fb0cc7f465cee3916684fb21e337cfe1b583e0b1e92"))
1875        self.assertEqualBin(argon2_long_hash(513, preimage), unhex(
1876            "32243cfbd7eca582d60b3b8ea3ba3d93783537689c7cbcd1d1cbde46200b8c86"
1877            "617fc00e8a9ae991a1e2f91c67e07d5f0a777d982c1461d0c5474e4e164b053c"
1878            "2808559e2b8a5ac4a46a5fcbc825b1d5302c7b0611940194eb494d45ce7113a2"
1879            "3424b51c199c6a5100ab159ff323eda5feffee4da4155a028a81da9d44e4286b"
1880            "ac3dab4ffce43a80b6ce97a47ea0ac51ee16e8b4d3b68942afdc20e1c21747c4"
1881            "94859c3d3883e7dc19ea416a393a3507683d9d03e6a3a91f8f1cb8a7d5d9892e"
1882            "80c8fb0222527a73a1f59b9dd41770982f2af177a6e96093064534803edd0713"
1883            "71ede53024cedc291d768325bb4e4def9af1b5569c349b64816496c37a8787b5"
1884            "4fbe248372ebadb5ce20e03eaa935dc55ff4b8cbe5d6d844c7b71d4656fef22c"
1885            "5a49f13d75a7a8368a2dbc1e78d732b879bfc5c9467eda2bf4918f0c59037ae3"
1886            "dee7880a171409dd1a4e143c814e60301ac77237f261fa7519a04e68000530f9"
1887            "708ed9fda5609d655560a9491f80f5875ad5725e3120686b73319c6a727932e3"
1888            "20a2174422523498c38fea47aeb20d135ff9fd93c6fa6db0005e0001685d7577"
1889            "33a82a4dc9dd6556b938f7b8dafd0d670846780b9931b815063708189b17877b"
1890            "825533bcc250fb576a28be4caa107e6a3a6f7b0c60fb51b0def27008b7e272ac"
1891            "95d610bfa912339799a2e537ce543d7862dddbe31bb224fda4ae283571847a28"
1892            "54"))
1893        self.assertEqualBin(argon2_long_hash(1024, preimage), unhex(
1894            "951252f6fa152124f381266a358d9b78b88e469d08d5fc78e4ea32253c7fc26c"
1895            "3ff1c93529ab4ee6fcf00acf29bbaba934a4014ce2625e0806601c55e6ce70d7"
1896            "121fd82f0904f335c5c7ba07dc6e6adf7582c92f7f255072203ea85844b4fe54"
1897            "817476a20bb742710ffc42750361be94332d0fc721b192309acfa70da43db6ae"
1898            "1d0f0bbe8a3250966a4532b36728162073c9eb3e119ea4c1c187c775dbb25a5d"
1899            "d883e3f65706a5fca897cdc4a8aa7b68ba3f57940c72f3a3396c417e758ba071"
1900            "95be4afba325237c0e2738a74d96fd1350fb623cb2ad40ea8b1e070cf398b98c"
1901            "2865ea40225b81f031f2b405409ca01dc5d9903d3d8e1d6381fbe7ccfc8f3dab"
1902            "eadafd7c976c0ba84a936f78ff7df0f112c089ba88f82bed7f9a6e31a91e5fee"
1903            "f675755454b948de22695660b243b9eca3bcc89608f83d2baa1d73dd6b8bd4f9"
1904            "b995ed9cb0f1edc6e98a49ed841b506c1bf59b43f4b3457a376bbff116c1a4f6"
1905            "07cc62381fc5c19953c68f300c1b51198d40784d812d25810ba404862f04b680"
1906            "6039a074f612ad8b84e0941ba23c915c3e7162c225fbecffdb7dc1ab559b2b54"
1907            "32fe8a498c32e918d8e7e33254ff75077f648827705e987f4d90fba971e78e1a"
1908            "6896b4d775c7359dc950f1e964fa04621aacf3c0988969490f4c72c54caf79e8"
1909            "481053cc0a27ffcd3580aabf9ef1268d498d8a18bd70e9b8402e011753bb7dc7"
1910            "e856c00d988fca924ee7cf61979c38cda8a872e4cc4fbdc90c23a0ded71eb944"
1911            "bb816ab22d9a4380e3e9d1cec818165c2fba6c5d51dcbf452c0cb1779a384937"
1912            "64d695370e13a301eca7be68d4112d2177381514efbb36fe08fc5bc2970301b8"
1913            "06f8e5a57a780e894d5276e2025bb775b6d1861e33c54ab6e3eb72947fbe6f91"
1914            "8174ce24eb4682efbb3c4f01233dc7ce9ef44792e9e876bb03e6751b3d559047"
1915            "d045127d976aa042fc55c690c9048e200065e7b7de19d9353aa9ac9b3e7611f0"
1916            "d1c42d069a300455ca1f7420a352bace89215e705106927510c11b3b1c1486d9"
1917            "f3ab006d2de2ee2c94574f760ce8c246bca229f98c66f06042b14f1fff9a16c0"
1918            "1550237e16d108ce5597299b1eb406a9ee505a29a6e0fa526b3e6beafd336aea"
1919            "138b2f31971586f67c5ffffbd6826d1c75666038c43d0bdff4edfc294e064a49"
1920            "2eed43e2dc78d00abc4e85edcd9563b8251b66f57b0f4b6d17f5a3f35c87c488"
1921            "dbeeb84fd720286197c2dec8290eccf3a313747de285b9cd3548e90cf81b3838"
1922            "3ffcc8c2a7f582feb369d05cb96b9b224d05902b3e39e5b96536032e9dddeb9b"
1923            "9d4f40a9c8f544ca37cf8d39d7c8c6a33880e9184ed017bd642db9590759bd10"
1924            "7362048ede5c0257feecc4984584592c566f37fba8469c064015339fb4f03023"
1925            "56ece37fd3655aae2bfc989b9b4c1384efc3503c8866db901802cb36eda9fb00"))
1926
1927    def testArgon2(self):
1928        # A few tests of my own of Argon2, derived from the reference
1929        # implementation.
1930        pwd = b"password"
1931        salt = b"salt of at least 16 bytes"
1932        secret = b"secret"
1933        assoc = b"associated data"
1934
1935        # Smallest memory (8Kbyte) and parallelism (1) parameters the
1936        # reference implementation will accept, but lots of passes
1937        self.assertEqualBin(
1938            argon2('i', 8, 16, 1, 24, pwd, salt, secret, assoc), unhex(
1939                "314da280240a3ca1eedd1f1db417a76eb0741e7df64b8cdf"))
1940        self.assertEqualBin(
1941            argon2('d', 8, 16, 1, 24, pwd, salt, secret, assoc), unhex(
1942                "9cc961cf43e0f86c2d4e202b816dc5bc5b2177e68faa0b08"))
1943        self.assertEqualBin(
1944            argon2('id', 8, 16, 1, 24, pwd, salt, secret, assoc), unhex(
1945                "6cd6c490c582fa597721d772d4e3de166987792491b48c51"))
1946
1947        # Test a memory cost value that isn't a power of 2. This
1948        # checks a wraparound case during the conversion of J1 to a
1949        # block index, and is a regression test for a bug that nearly
1950        # got past me during original development.
1951        self.assertEqualBin(
1952            argon2('i', 104, 16, 2, 24, pwd, salt, secret, assoc), unhex(
1953                "a561963623f1073c9aa8caecdb600c73ffc6de677ba8d97c"))
1954        self.assertEqualBin(
1955            argon2('d', 104, 16, 2, 24, pwd, salt, secret, assoc), unhex(
1956                "a9014db7f1d468fb25b88fa7fc0deac0f2e7f27e25d2cf6e"))
1957        self.assertEqualBin(
1958            argon2('id', 104, 16, 2, 24, pwd, salt, secret, assoc), unhex(
1959                "64f3212b1e7725ffcf9ae2d1753d63e763bcd6970061a435"))
1960
1961        # Larger parameters that should exercise the pseudorandom
1962        # block indexing reasonably thoroughly. Also generate plenty
1963        # of output data.
1964        self.assertEqualBin(
1965            argon2('i', 1024, 5, 16, 77, pwd, salt, secret, assoc), unhex(
1966                "b008a685ff57730fad0e6f3ef3b9189282c0d9b05303675f43b5f3054724"
1967                "733fcbe8e2639cc2c930535b31b723339041bcd703bf2483455acf86c0e6"
1968                "9ed88c545ad40f1f2068855e4d61e99407"))
1969        self.assertEqualBin(
1970            argon2('d', 1024, 5, 16, 111, pwd, salt, secret, assoc), unhex(
1971                "399ffbcd720c47745b9deb391ed0de7d5e0ffe53aef9f8ef7a7918cfa212"
1972                "53df8cc577affbd5e0c0f8bf6d93c11b2f63973f8fc8f89dccd832fc587e"
1973                "5d61717be6e88ca33eef5d1e168c028bae632a2a723c6c83f8e755f39171"
1974                "5eda1c77c8e2fe06fbdd4e56d35262587e7df73cd7"))
1975        self.assertEqualBin(
1976            argon2('id', 1024, 5, 16, 123, pwd, salt, secret, assoc), unhex(
1977                "6636807289cb9b9c032f48dcc31ffed1de4ca6c1b97e1ce768d690486341"
1978                "2ac84b39d568a81dd01d9ee3ceec6cc23441d95e6abeb4a2024f1f540d56"
1979                "9b799277c4037ddc7195ba783c9158a901adc7d4a5df8357b34a3869e5d6"
1980                "aeae2a21201eef5e347de22c922192e8f46274b0c9d33e965155a91e7686"
1981                "9d530e"))
1982
1983    def testRSAVerify(self):
1984        def blobs(n, e, d, p, q, iqmp):
1985            pubblob = ssh_string(b"ssh-rsa") + ssh2_mpint(e) + ssh2_mpint(n)
1986            privblob = (ssh2_mpint(d) + ssh2_mpint(p) +
1987                        ssh2_mpint(q) + ssh2_mpint(iqmp))
1988            return pubblob, privblob
1989
1990        def failure_test(*args):
1991            pubblob, privblob = blobs(*args)
1992            key = ssh_key_new_priv('rsa', pubblob, privblob)
1993            self.assertEqual(key, None)
1994
1995        def success_test(*args):
1996            pubblob, privblob = blobs(*args)
1997            key = ssh_key_new_priv('rsa', pubblob, privblob)
1998            self.assertNotEqual(key, None)
1999
2000        # Parameters for a (trivially small) test key.
2001        n = 0xb5d545a2f6423eabd55ffede53e21628d5d4491541482e10676d9d6f2783b9a5
2002        e = 0x25
2003        d = 0x6733db6a546ac99fcc21ba2b28b0c077156e8a705976205a955c6d9cef98f419
2004        p = 0xe30ebd7348bf10dca72b36f2724dafa7
2005        q = 0xcd02c87a7f7c08c4e9dc80c9b9bad5d3
2006        iqmp = 0x60a129b30db9227910efe1608976c513
2007
2008        # Check the test key makes sense unmodified.
2009        success_test(n, e, d, p, q, iqmp)
2010
2011        # Try modifying the values one by one to ensure they are
2012        # rejected, except iqmp, which sshrsa.c regenerates anyway so
2013        # it won't matter at all.
2014        failure_test(n+1, e, d, p, q, iqmp)
2015        failure_test(n, e+1, d, p, q, iqmp)
2016        failure_test(n, e, d+1, p, q, iqmp)
2017        failure_test(n, e, d, p+1, q, iqmp)
2018        failure_test(n, e, d, p, q+1, iqmp)
2019        success_test(n, e, d, p, q, iqmp+1)
2020
2021        # The key should also be accepted with p,q reversed. (Again,
2022        # iqmp gets regenerated, so it won't matter if that's wrong.)
2023        success_test(n, e, d, q, p, iqmp)
2024
2025        # Replace each of p and q with 0, and with 1. These should
2026        # still fail validation (obviously), but the point is that the
2027        # validator should also avoid trying to divide by zero in the
2028        # process.
2029        failure_test(n, e, d, 0, q, iqmp)
2030        failure_test(n, e, d, p, 0, iqmp)
2031        failure_test(n, e, d, 1, q, iqmp)
2032        failure_test(n, e, d, p, 1, iqmp)
2033
2034    def testKeyMethods(self):
2035        # Exercise all the methods of the ssh_key trait on all key
2036        # types, and ensure that they're consistent with each other.
2037        # No particular test is done on the rightness of the
2038        # signatures by any objective standard, only that the output
2039        # from our signing method can be verified by the corresponding
2040        # verification method.
2041        #
2042        # However, we do include the expected signature text in each
2043        # case, which checks determinism in the sense of being
2044        # independent of any random numbers, and also in the sense of
2045        # tomorrow's change to the code not having accidentally
2046        # changed the behaviour.
2047
2048        test_message = b"Message to be signed by crypt.testKeyMethods\n"
2049
2050        test_keys = [
2051            ('ed25519', 'AAAAC3NzaC1lZDI1NTE5AAAAIM7jupzef6CD0ps2JYxJp9IlwY49oorOseV5z5JFDFKn', 'AAAAIAf4/WRtypofgdNF2vbZOUFE1h4hvjw4tkGJZyOzI7c3', 255, b'0xf4d6e7f6f4479c23f0764ef43cea1711dbfe02aa2b5a32ff925c7c1fbf0f0db,0x27520c4592cf79e5b1ce8aa23d8ec125d2a7498c25369bd283a07fde9cbae3ce', [(0, 'AAAAC3NzaC1lZDI1NTE5AAAAQN73EqfyA4WneqDhgZ98TlRj9V5Wg8zCrMxTLJN1UtyfAnPUJDtfG/U0vOsP8PrnQxd41DDDnxrAXuqJz8rOagc=')]),
2052            ('ed448', 'AAAACXNzaC1lZDQ0OAAAADnRI0CQDym5IqUidLNDcSdHe54bYEwqjpjBlab8uKGoe6FRqqejha7+5U/VAHy7BmE23+ju26O9XgA=', 'AAAAObP9klqyiJSJsdFJf+xwZQdkbZGUqXE07K6e5plfRTGjYYkyWJFUNFH4jzIn9xH1TX9z9EGycPaXAA==', 448, b'0x4bf4a2b6586c60d8cdb52c2b45b897f6d2224bc37987489c0d70febb449e8c82964ed5785827be808e44d31dd31e6ff7c99f43e49f419928,0x5ebda3dbeee8df366106bb7c00d54fe5feae85a3a7aa51a17ba8a1b8fca695c1988e2a4c601b9e7b47277143b37422a522b9290f904023d1', [(0, 'AAAACXNzaC1lZDQ0OAAAAHLkSVioGMvLesZp3Tn+Z/sSK0Hl7RHsHP4q9flLzTpZG5h6JDH3VmZBEjTJ6iOLaa0v4FoNt0ng4wAB53WrlQC4h3iAusoGXnPMAKJLmqzplKOCi8HKXk8Xl8fsXbaoyhatv1OZpwJcffmh1x+x+LSgNQA=')]),
2053            ('p256', 'AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHkYQ0sQoq5LbJI1VMWhw3bV43TSYi3WVpqIgKcBKK91TcFFlAMZgceOHQ0xAFYcSczIttLvFu+xkcLXrRd4N7Q=', 'AAAAIQCV/1VqiCsHZm/n+bq7lHEHlyy7KFgZBEbzqYaWtbx48Q==', 256, b'nistp256,0x7918434b10a2ae4b6c923554c5a1c376d5e374d2622dd6569a8880a70128af75,0x4dc14594031981c78e1d0d3100561c49ccc8b6d2ef16efb191c2d7ad177837b4', [(0, 'AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAABIAAAAIAryzHDGi/TcCnbdxZkIYR5EGR6SNYXr/HlQRF8le+/IAAAAIERfzn6eHuBbqWIop2qL8S7DWRB3lenN1iyL10xYQPKw')]),
2054            ('p384', 'AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBMYK8PUtfAlJwKaBTIGEuCzH0vqOMa4UbcjrBbTbkGVSUnfo+nuC80NCdj9JJMs1jvfF8GzKLc5z8H3nZyM741/BUFjV7rEHsQFDek4KyWvKkEgKiTlZid19VukNo1q2Hg==', 'AAAAMGsfTmdB4zHdbiQ2euTSdzM6UKEOnrVjMAWwHEYvmG5qUOcBnn62fJDRJy67L+QGdg==', 384, b'nistp384,0xc60af0f52d7c0949c0a6814c8184b82cc7d2fa8e31ae146dc8eb05b4db9065525277e8fa7b82f34342763f4924cb358e,0xf7c5f06cca2dce73f07de767233be35fc15058d5eeb107b101437a4e0ac96bca90480a89395989dd7d56e90da35ab61e', [(0, 'AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAABpAAAAMDmHrtXCADzLvkkWG/duBAHlf6B1mVvdt6F0uzXfsf8Yub8WXNUNVnYq6ovrWPzLggAAADEA9izzwoUuFcXYRJeKcRLZEGMmSDDPzUZb7oZR0UgD1jsMQXs8UfpO31Qur/FDSCRK')]),
2055            ('p521', 'AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBAFrGthlKM152vu2Ghk+R7iO9/M6e+hTehNZ6+FBwof4HPkPB2/HHXj5+w5ynWyUrWiX5TI2riuJEIrJErcRH5LglADnJDX2w4yrKZ+wDHSz9lwh9p2F+B5R952es6gX3RJRkGA+qhKpKup8gKx78RMbleX8wgRtIu+4YMUnKb1edREiRg==', 'AAAAQgFh7VNJFUljWhhyAEiL0z+UPs/QggcMTd3Vv2aKDeBdCRl5di8r+BMm39L7bRzxRMEtW5NSKlDtE8MFEGdIE9khsw==', 521, b'nistp521,0x16b1ad86528cd79dafbb61a193e47b88ef7f33a7be8537a1359ebe141c287f81cf90f076fc71d78f9fb0e729d6c94ad6897e53236ae2b89108ac912b7111f92e094,0xe72435f6c38cab299fb00c74b3f65c21f69d85f81e51f79d9eb3a817dd125190603eaa12a92aea7c80ac7bf1131b95e5fcc2046d22efb860c52729bd5e75112246', [(0, 'AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAACMAAAAQgCLgvftvwM3CUaigrW0yzmCHoYjC6GLtO+6S91itqpgMEtWPNlaTZH6QQqkgscijWdXx98dDkQao/gcAKVmOZKPXgAAAEIB1PIrsDF1y6poJ/czqujB7NSUWt31v+c2t6UA8m2gTA1ARuVJ9XBGLMdceOTB00Hi9psC2RYFLpaWREOGCeDa6ow=')]),
2056            ('dsa', 'AAAAB3NzaC1kc3MAAABhAJyWZzjVddGdyc5JPu/WPrC07vKRAmlqO6TUi49ah96iRcM7/D1aRMVAdYBepQ2mf1fsQTmvoC9KgQa79nN3kHhz0voQBKOuKI1ZAodfVOgpP4xmcXgjaA73Vjz22n4newAAABUA6l7/vIveaiA33YYv+SKcKLQaA8cAAABgbErc8QLw/WDz7mhVRZrU+9x3Tfs68j3eW+B/d7Rz1ZCqMYDk7r/F8dlBdQlYhpQvhuSBgzoFa0+qPvSSxPmutgb94wNqhHlVIUb9ZOJNloNr2lXiPP//Wu51TxXAEvAAAAAAYQCcQ9mufXtZa5RyfwT4NuLivdsidP4HRoLXdlnppfFAbNdbhxE0Us8WZt+a/443bwKnYxgif8dgxv5UROnWTngWu0jbJHpaDcTc9lRyTeSUiZZK312s/Sl7qDk3/Du7RUI=', 'AAAAFGx3ft7G8AQzFsjhle7PWardUXh3', 768, b'0x9c966738d575d19dc9ce493eefd63eb0b4eef29102696a3ba4d48b8f5a87dea245c33bfc3d5a44c54075805ea50da67f57ec4139afa02f4a8106bbf67377907873d2fa1004a3ae288d5902875f54e8293f8c66717823680ef7563cf6da7e277b,0xea5effbc8bde6a2037dd862ff9229c28b41a03c7,0x6c4adcf102f0fd60f3ee6855459ad4fbdc774dfb3af23dde5be07f77b473d590aa3180e4eebfc5f1d94175095886942f86e481833a056b4faa3ef492c4f9aeb606fde3036a8479552146fd64e24d96836bda55e23cffff5aee754f15c012f000,0x9c43d9ae7d7b596b94727f04f836e2e2bddb2274fe074682d77659e9a5f1406cd75b87113452cf1666df9aff8e376f02a76318227fc760c6fe5444e9d64e7816bb48db247a5a0dc4dcf654724de49489964adf5dacfd297ba83937fc3bbb4542', [(0, 'AAAAB3NzaC1kc3MAAAAo0T2t6dr8Qr5DK2B0ETwUa3BhxMLPjLY0ZtlOACmP/kUt3JgByLv+3g==')]),
2057            ('rsa', 'AAAAB3NzaC1yc2EAAAABJQAAAGEA2ChX9+mQD/NULFkBrxLDI8d1PHgrInC2u11U4Grqu4oVzKvnFROo6DZeCu6sKhFJE5CnIL7evAthQ9hkXVHDhQ7xGVauzqyHGdIU4/pHRScAYWBv/PZOlNMrSoP/PP91', 'AAAAYCMNdgyGvWpez2EjMLSbQj0nQ3GW8jzvru3zdYwtA3hblNUU9QpWNxDmOMOApkwCzUgsdIPsBxctIeWT2h+v8sVOH+d66LCaNmNR0lp+dQ+iXM67hcGNuxJwRdMupD9ZbQAAADEA7XMrMAb4WuHaFafoTfGrf6Jhdy9Ozjqi1fStuld7Nj9JkoZluiL2dCwIrxqOjwU5AAAAMQDpC1gYiGVSPeDRILr2oxREtXWOsW+/ZZTfZNX7lvoufnp+qvwZPqvZnXQFHyZ8qB0AAAAwQE0wx8TPgcvRVEVv8Wt+o1NFlkJZayWD5hqpe/8AqUMZbqfg/aiso5mvecDLFgfV', 768, b'0x25,0xd82857f7e9900ff3542c5901af12c323c7753c782b2270b6bb5d54e06aeabb8a15ccabe71513a8e8365e0aeeac2a11491390a720bedebc0b6143d8645d51c3850ef11956aeceac8719d214e3fa4745270061606ffcf64e94d32b4a83ff3cff75', [(0, 'AAAAB3NzaC1yc2EAAABgrLSC4635RCsH1b3en58NqLsrH7PKRZyb3YmRasOyr8xIZMSlKZyxNg+kkn9OgBzbH9vChafzarfHyVwtJE2IMt3uwxTIWjwgwH19tc16k8YmNfDzujmB6OFOArmzKJgJ'), (2, 'AAAADHJzYS1zaGEyLTI1NgAAAGAJszr04BZlVBEdRLGOv1rTJwPiid/0I6/MycSH+noahvUH2wjrRhqDuv51F4nKYF5J9vBsEotTSrSF/cnLsliCdvVkEfmvhdcn/jx2LWF2OfjqETiYSc69Dde9UFmAPds='), (4, 'AAAADHJzYS1zaGEyLTUxMgAAAGBxfZ2m+WjvZ5YV5RFm0+w84CgHQ95EPndoAha0PCMc93AUHBmoHnezsJvEGuLovUm35w/0POmUNHI7HzM9PECwXrV0rO6N/HL/oFxJuDYmeqCpjMVmN8QXka+yxs2GEtA=')]),
2058        ]
2059
2060        for alg, pubb64, privb64, bits, cachestr, siglist in test_keys:
2061            # Decode the blobs in the above test data.
2062            pubblob = base64decode(pubb64.encode('ASCII'))
2063            privblob = base64decode(privb64.encode('ASCII'))
2064
2065            # Check the method that examines a public blob directly
2066            # and returns an integer showing the key size.
2067            self.assertEqual(ssh_key_public_bits(alg, pubblob), bits)
2068
2069            # Make a public-only and a full ssh_key object.
2070            pubkey = ssh_key_new_pub(alg, pubblob)
2071            privkey = ssh_key_new_priv(alg, pubblob, privblob)
2072
2073            # Test that they re-export the public and private key
2074            # blobs unchanged.
2075            self.assertEqual(ssh_key_public_blob(pubkey), pubblob)
2076            self.assertEqual(ssh_key_public_blob(privkey), pubblob)
2077            self.assertEqual(ssh_key_private_blob(privkey), privblob)
2078
2079            # Round-trip through the OpenSSH wire encoding used by the
2080            # agent protocol (and the newer OpenSSH key file format),
2081            # and check the result still exports all the same blobs.
2082            osshblob = ssh_key_openssh_blob(privkey)
2083            privkey2 = ssh_key_new_priv_openssh(alg, osshblob)
2084            self.assertEqual(ssh_key_public_blob(privkey2), pubblob)
2085            self.assertEqual(ssh_key_private_blob(privkey2), privblob)
2086            self.assertEqual(ssh_key_openssh_blob(privkey2), osshblob)
2087
2088            # Test that the string description used in the host key
2089            # cache is as expected.
2090            for key in [pubkey, privkey, privkey2]:
2091                self.assertEqual(ssh_key_cache_str(key), cachestr)
2092
2093            # Now test signatures, separately for each provided flags
2094            # value.
2095            for flags, sigb64 in siglist:
2096                # Decode the signature blob from the test data.
2097                sigblob = base64decode(sigb64.encode('ASCII'))
2098
2099                # Sign our test message, and check it produces exactly
2100                # the expected signature blob.
2101                #
2102                # We do this with both the original private key and
2103                # the one we round-tripped through OpenSSH wire
2104                # format, just in case that round trip made some kind
2105                # of a mess that didn't show up in the re-extraction
2106                # of the blobs.
2107                for key in [privkey, privkey2]:
2108                    self.assertEqual(ssh_key_sign(
2109                        key, test_message, flags), sigblob)
2110
2111                if flags != 0:
2112                    # Currently we only support _generating_
2113                    # signatures with flags != 0, not verifying them.
2114                    continue
2115
2116                # Check the signature verifies successfully, with all
2117                # three of the key objects we have.
2118                for key in [pubkey, privkey, privkey2]:
2119                    self.assertTrue(ssh_key_verify(key, sigblob, test_message))
2120
2121                # A crude check that at least _something_ doesn't
2122                # verify successfully: flip a bit of the signature
2123                # and expect it to fail.
2124                #
2125                # We do this twice, at the 1/3 and 2/3 points along
2126                # the signature's length, so that in the case of
2127                # signatures in two parts (DSA-like) we try perturbing
2128                # both parts. Other than that, we don't do much to
2129                # make this a rigorous cryptographic test.
2130                for n, d in [(1,3),(2,3)]:
2131                    sigbytes = list(sigblob)
2132                    bit = 8 * len(sigbytes) * n // d
2133                    sigbytes[bit // 8] ^= 1 << (bit % 8)
2134                    badsig = bytes(sigbytes)
2135                    for key in [pubkey, privkey, privkey2]:
2136                        self.assertFalse(ssh_key_verify(
2137                            key, badsig, test_message))
2138
2139    def testPPKLoadSave(self):
2140        # Stability test of PPK load/save functions.
2141        input_clear_key = b"""\
2142PuTTY-User-Key-File-3: ssh-ed25519
2143Encryption: none
2144Comment: ed25519-key-20200105
2145Public-Lines: 2
2146AAAAC3NzaC1lZDI1NTE5AAAAIHJCszOHaI9X/yGLtjn22f0hO6VPMQDVtctkym6F
2147JH1W
2148Private-Lines: 1
2149AAAAIGvvIpl8jyqn8Xufkw6v3FnEGtXF3KWw55AP3/AGEBpY
2150Private-MAC: 816c84093fc4877e8411b8e5139c5ce35d8387a2630ff087214911d67417a54d
2151"""
2152        input_encrypted_key = b"""\
2153PuTTY-User-Key-File-3: ssh-ed25519
2154Encryption: aes256-cbc
2155Comment: ed25519-key-20200105
2156Public-Lines: 2
2157AAAAC3NzaC1lZDI1NTE5AAAAIHJCszOHaI9X/yGLtjn22f0hO6VPMQDVtctkym6F
2158JH1W
2159Key-Derivation: Argon2id
2160Argon2-Memory: 8192
2161Argon2-Passes: 13
2162Argon2-Parallelism: 1
2163Argon2-Salt: 37c3911bfefc8c1d11ec579627d2b3d9
2164Private-Lines: 1
2165amviz4sVUBN64jLO3gt4HGXJosUArghc4Soi7aVVLb2Tir5Baj0OQClorycuaPRd
2166Private-MAC: 6f5e588e475e55434106ec2c3569695b03f423228b44993a9e97d52ffe7be5a8
2167"""
2168        algorithm = b'ssh-ed25519'
2169        comment = b'ed25519-key-20200105'
2170        pp = b'test-passphrase'
2171        public_blob = unhex(
2172            '0000000b7373682d65643235353139000000207242b33387688f57ff218bb639'
2173            'f6d9fd213ba54f3100d5b5cb64ca6e85247d56')
2174
2175        self.assertEqual(ppk_encrypted_s(input_clear_key), (False, comment))
2176        self.assertEqual(ppk_encrypted_s(input_encrypted_key), (True, comment))
2177        self.assertEqual(ppk_encrypted_s("not a key file"), (False, None))
2178
2179        self.assertEqual(ppk_loadpub_s(input_clear_key),
2180                         (True, algorithm, public_blob, comment, None))
2181        self.assertEqual(ppk_loadpub_s(input_encrypted_key),
2182                         (True, algorithm, public_blob, comment, None))
2183        self.assertEqual(ppk_loadpub_s("not a key file"),
2184                         (False, None, b'', None,
2185                          b'not a PuTTY SSH-2 private key'))
2186
2187        k1, c, e = ppk_load_s(input_clear_key, None)
2188        self.assertEqual((c, e), (comment, None))
2189        k2, c, e = ppk_load_s(input_encrypted_key, pp)
2190        self.assertEqual((c, e), (comment, None))
2191        privblob = ssh_key_private_blob(k1)
2192        self.assertEqual(ssh_key_private_blob(k2), privblob)
2193
2194        salt = unhex('37c3911bfefc8c1d11ec579627d2b3d9')
2195        with queued_specific_random_data(salt):
2196            self.assertEqual(ppk_save_sb(k1, comment, None,
2197                                         3, 'id', 8192, 13, 1),
2198                             input_clear_key)
2199        with queued_specific_random_data(salt):
2200            self.assertEqual(ppk_save_sb(k2, comment, None,
2201                                         3, 'id', 8192, 13, 1),
2202                             input_clear_key)
2203
2204        with queued_specific_random_data(salt):
2205            self.assertEqual(ppk_save_sb(k1, comment, pp,
2206                                         3, 'id', 8192, 13, 1),
2207                             input_encrypted_key)
2208        with queued_specific_random_data(salt):
2209            self.assertEqual(ppk_save_sb(k2, comment, pp,
2210                                         3, 'id', 8192, 13, 1),
2211                             input_encrypted_key)
2212
2213        # And check we can still handle v2 key files.
2214        v2_clear_key = b"""\
2215PuTTY-User-Key-File-2: ssh-ed25519
2216Encryption: none
2217Comment: ed25519-key-20200105
2218Public-Lines: 2
2219AAAAC3NzaC1lZDI1NTE5AAAAIHJCszOHaI9X/yGLtjn22f0hO6VPMQDVtctkym6F
2220JH1W
2221Private-Lines: 1
2222AAAAIGvvIpl8jyqn8Xufkw6v3FnEGtXF3KWw55AP3/AGEBpY
2223Private-MAC: 2a629acfcfbe28488a1ba9b6948c36406bc28422
2224"""
2225        v2_encrypted_key = b"""\
2226PuTTY-User-Key-File-2: ssh-ed25519
2227Encryption: aes256-cbc
2228Comment: ed25519-key-20200105
2229Public-Lines: 2
2230AAAAC3NzaC1lZDI1NTE5AAAAIHJCszOHaI9X/yGLtjn22f0hO6VPMQDVtctkym6F
2231JH1W
2232Private-Lines: 1
22334/jKlTgC652oa9HLVGrMjHZw7tj0sKRuZaJPOuLhGTvb25Jzpcqpbi+Uf+y+uo+Z
2234Private-MAC: 5b1f6f4cc43eb0060d2c3e181bc0129343adba2b
2235"""
2236
2237        self.assertEqual(ppk_encrypted_s(v2_clear_key), (False, comment))
2238        self.assertEqual(ppk_encrypted_s(v2_encrypted_key), (True, comment))
2239        self.assertEqual(ppk_encrypted_s("not a key file"), (False, None))
2240
2241        self.assertEqual(ppk_loadpub_s(v2_clear_key),
2242                         (True, algorithm, public_blob, comment, None))
2243        self.assertEqual(ppk_loadpub_s(v2_encrypted_key),
2244                         (True, algorithm, public_blob, comment, None))
2245        self.assertEqual(ppk_loadpub_s("not a key file"),
2246                         (False, None, b'', None,
2247                          b'not a PuTTY SSH-2 private key'))
2248
2249        k1, c, e = ppk_load_s(v2_clear_key, None)
2250        self.assertEqual((c, e), (comment, None))
2251        k2, c, e = ppk_load_s(v2_encrypted_key, pp)
2252        self.assertEqual((c, e), (comment, None))
2253        self.assertEqual(ssh_key_private_blob(k1), privblob)
2254        self.assertEqual(ssh_key_private_blob(k2), privblob)
2255
2256        self.assertEqual(ppk_save_sb(k2, comment, None,
2257                                     2, 'id', 8192, 13, 1),
2258                         v2_clear_key)
2259        self.assertEqual(ppk_save_sb(k1, comment, pp,
2260                                     2, 'id', 8192, 13, 1),
2261                         v2_encrypted_key)
2262
2263    def testRSA1LoadSave(self):
2264        # Stability test of SSH-1 RSA key-file load/save functions.
2265        input_clear_key = unhex(
2266            "5353482050524956415445204B45592046494C4520464F524D415420312E310A"
2267            "000000000000000002000200BB115A85B741E84E3D940E690DF96A0CBFDC07CA"
2268            "70E51DA8234D211DE77341CEF40C214CAA5DCF68BE2127447FD6C84CCB17D057"
2269            "A74F2365B9D84A78906AEB51000625000000107273612D6B65792D3230323030"
2270            "313036208E208E0200929EE615C6FC4E4B29585E52570F984F2E97B3144AA5BD"
2271            "4C6EB2130999BB339305A21FFFA79442462A8397AF8CAC395A3A3827DE10457A"
2272            "1F1B277ABFB8C069C100FF55B1CAD69B3BD9E42456CF28B1A4B98130AFCE08B2"
2273            "8BCFFF5FFFED76C5D51E9F0100C5DE76889C62B1090A770AE68F087A19AB5126"
2274            "E60DF87710093A2AD57B3380FB0100F2068AC47ECB33BF8F13DF402BABF35EE7"
2275            "26BD32F7564E51502DF5C8F4888B2300000000")
2276        input_encrypted_key = unhex(
2277            "5353482050524956415445204b45592046494c4520464f524d415420312e310a"
2278            "000300000000000002000200bb115a85b741e84e3d940e690df96a0cbfdc07ca"
2279            "70e51da8234d211de77341cef40c214caa5dcf68be2127447fd6c84ccb17d057"
2280            "a74f2365b9d84a78906aeb51000625000000107273612d6b65792d3230323030"
2281            "3130363377f926e811a5f044c52714801ecdcf9dd572ee0a193c4f67e87ab2ce"
2282            "4569d0c5776fd6028909ed8b6d663bef15d207d3ef6307e7e21dbec56e8d8b4e"
2283            "894ded34df891bb29bae6b2b74805ac80f7304926abf01ae314dd69c64240761"
2284            "34f15d50c99f7573252993530ec9c4d5016dd1f5191730cda31a5d95d362628b"
2285            "2a26f4bb21840d01c8360e4a6ce216c4686d25b8699d45cf361663bb185e2c5e"
2286            "652012a1e0f9d6d19afbb28506f7775bfd8129")
2287
2288        comment = b'rsa-key-20200106'
2289        pp = b'test-passphrase'
2290        public_blob = unhex(
2291            "000002000006250200bb115a85b741e84e3d940e690df96a0cbfdc07ca70e51d"
2292            "a8234d211de77341cef40c214caa5dcf68be2127447fd6c84ccb17d057a74f23"
2293            "65b9d84a78906aeb51")
2294
2295        self.assertEqual(rsa1_encrypted_s(input_clear_key), (False, comment))
2296        self.assertEqual(rsa1_encrypted_s(input_encrypted_key),
2297                         (True, comment))
2298        self.assertEqual(rsa1_encrypted_s("not a key file"), (False, None))
2299
2300        self.assertEqual(rsa1_loadpub_s(input_clear_key),
2301                         (1, public_blob, comment, None))
2302        self.assertEqual(rsa1_loadpub_s(input_encrypted_key),
2303                         (1, public_blob, comment, None))
2304
2305        k1 = rsa_new()
2306        status, c, e = rsa1_load_s(input_clear_key, k1, None)
2307        self.assertEqual((status, c, e), (1, comment, None))
2308        k2 = rsa_new()
2309        status, c, e = rsa1_load_s(input_clear_key, k2, None)
2310        self.assertEqual((status, c, e), (1, comment, None))
2311
2312        with queued_specific_random_data(unhex("208e")):
2313            self.assertEqual(rsa1_save_sb(k1, comment, None), input_clear_key)
2314        with queued_specific_random_data(unhex("208e")):
2315            self.assertEqual(rsa1_save_sb(k2, comment, None), input_clear_key)
2316
2317        with queued_specific_random_data(unhex("99f3")):
2318            self.assertEqual(rsa1_save_sb(k1, comment, pp),
2319                             input_encrypted_key)
2320        with queued_specific_random_data(unhex("99f3")):
2321            self.assertEqual(rsa1_save_sb(k2, comment, pp),
2322                             input_encrypted_key)
2323
2324class standard_test_vectors(MyTestBase):
2325    def testAES(self):
2326        def vector(cipher, key, plaintext, ciphertext):
2327            for suffix in "hw", "sw":
2328                c = ssh_cipher_new("{}_{}".format(cipher, suffix))
2329                if c is None: return # skip test if HW AES not available
2330                ssh_cipher_setkey(c, key)
2331
2332                # The AES test vectors are implicitly in ECB mode,
2333                # because they're testing the cipher primitive rather
2334                # than any mode layered on top of it. We fake this by
2335                # using PuTTY's CBC setting, and clearing the IV to
2336                # all zeroes before each operation.
2337
2338                ssh_cipher_setiv(c, b'\x00' * 16)
2339                self.assertEqualBin(
2340                    ssh_cipher_encrypt(c, plaintext), ciphertext)
2341
2342                ssh_cipher_setiv(c, b'\x00' * 16)
2343                self.assertEqualBin(
2344                    ssh_cipher_decrypt(c, ciphertext), plaintext)
2345
2346        # The test vector from FIPS 197 appendix B. (This is also the
2347        # same key whose key setup phase is shown in detail in
2348        # appendix A.)
2349        vector('aes128_cbc',
2350               unhex('2b7e151628aed2a6abf7158809cf4f3c'),
2351               unhex('3243f6a8885a308d313198a2e0370734'),
2352               unhex('3925841d02dc09fbdc118597196a0b32'))
2353
2354        # The test vectors from FIPS 197 appendix C: the key bytes go
2355        # 00 01 02 03 ... for as long as needed, and the plaintext
2356        # bytes go 00 11 22 33 ... FF.
2357        fullkey = struct.pack("B"*32, *range(32))
2358        plaintext = struct.pack("B"*16, *[0x11*i for i in range(16)])
2359        vector('aes128_cbc', fullkey[:16], plaintext,
2360               unhex('69c4e0d86a7b0430d8cdb78070b4c55a'))
2361        vector('aes192_cbc', fullkey[:24], plaintext,
2362               unhex('dda97ca4864cdfe06eaf70a0ec0d7191'))
2363        vector('aes256_cbc', fullkey[:32], plaintext,
2364               unhex('8ea2b7ca516745bfeafc49904b496089'))
2365
2366    def testDES(self):
2367        c = ssh_cipher_new("des_cbc")
2368        def vector(key, plaintext, ciphertext):
2369            key = unhex(key)
2370            plaintext = unhex(plaintext)
2371            ciphertext = unhex(ciphertext)
2372
2373            # Similarly to above, we fake DES ECB by using DES CBC and
2374            # resetting the IV to zero all the time
2375            ssh_cipher_setkey(c, key)
2376            ssh_cipher_setiv(c, b'\x00' * 8)
2377            self.assertEqualBin(ssh_cipher_encrypt(c, plaintext), ciphertext)
2378            ssh_cipher_setiv(c, b'\x00' * 8)
2379            self.assertEqualBin(ssh_cipher_decrypt(c, ciphertext), plaintext)
2380
2381        # Source: FIPS SP PUB 500-20
2382
2383        # 'Initial permutation and expansion tests': key fixed at 8
2384        # copies of the byte 01, but ciphertext and plaintext in turn
2385        # run through all possible values with exactly 1 bit set.
2386        # Expected plaintexts and ciphertexts (respectively) listed in
2387        # the arrays below.
2388        ipe_key = '01' * 8
2389        ipe_plaintexts = [
2390'166B40B44ABA4BD6', '06E7EA22CE92708F', 'D2FD8867D50D2DFE', 'CC083F1E6D9E85F6',
2391'5B711BC4CEEBF2EE', '0953E2258E8E90A1', 'E07C30D7E4E26E12', '2FBC291A570DB5C4',
2392'DD7C0BBD61FAFD54', '48221B9937748A23', 'E643D78090CA4207', '8405D1ABE24FB942',
2393'CE332329248F3228', '1D1CA853AE7C0C5F', '5D86CB23639DBEA9', '1029D55E880EC2D0',
2394'8DD45A2DDF90796C', 'CAFFC6AC4542DE31', 'EA51D3975595B86B', '8B54536F2F3E64A8',
2395'866ECEDD8072BB0E', '79E90DBC98F92CCA', 'AB6A20C0620D1C6F', '25EB5FC3F8CF0621',
2396'4D49DB1532919C9F', '814EEB3B91D90726', '5E0905517BB59BCF', 'CA3A2B036DBC8502',
2397'FA0752B07D9C4AB8', 'B160E4680F6C696F', 'DF98C8276F54B04B', 'E943D7568AEC0C5C',
2398'AEB5F5EDE22D1A36', 'E428581186EC8F46', 'E1652C6B138C64A5', 'D106FF0BED5255D7',
2399'9D64555A9A10B852', 'F02B263B328E2B60', '64FEED9C724C2FAF', '750D079407521363',
2400'FBE00A8A1EF8AD72', 'A484C3AD38DC9C19', '12A9F5817FF2D65D', 'E7FCE22557D23C97',
2401'329A8ED523D71AEC', 'E19E275D846A1298', '889DE068A16F0BE6', '2B9F982F20037FA9',
2402'F356834379D165CD', 'ECBFE3BD3F591A5E', 'E6D5F82752AD63D1', 'ADD0CC8D6E5DEBA1',
2403'F15D0F286B65BD28', 'B8061B7ECD9A21E5', '424250B37C3DD951', 'D9031B0271BD5A0A',
2404'0D9F279BA5D87260', '6CC5DEFAAF04512F', '55579380D77138EF', '20B9E767B2FB1456',
2405'4BD388FF6CD81D4F', '2E8653104F3834EA', 'DD7F121CA5015619', '95F8A5E5DD31D900',
2406        ]
2407        ipe_ciphertexts = [
2408'166B40B44ABA4BD6', '06E7EA22CE92708F', 'D2FD8867D50D2DFE', 'CC083F1E6D9E85F6',
2409'5B711BC4CEEBF2EE', '0953E2258E8E90A1', 'E07C30D7E4E26E12', '2FBC291A570DB5C4',
2410'DD7C0BBD61FAFD54', '48221B9937748A23', 'E643D78090CA4207', '8405D1ABE24FB942',
2411'CE332329248F3228', '1D1CA853AE7C0C5F', '5D86CB23639DBEA9', '1029D55E880EC2D0',
2412'8DD45A2DDF90796C', 'CAFFC6AC4542DE31', 'EA51D3975595B86B', '8B54536F2F3E64A8',
2413'866ECEDD8072BB0E', '79E90DBC98F92CCA', 'AB6A20C0620D1C6F', '25EB5FC3F8CF0621',
2414'4D49DB1532919C9F', '814EEB3B91D90726', '5E0905517BB59BCF', 'CA3A2B036DBC8502',
2415'FA0752B07D9C4AB8', 'B160E4680F6C696F', 'DF98C8276F54B04B', 'E943D7568AEC0C5C',
2416'AEB5F5EDE22D1A36', 'E428581186EC8F46', 'E1652C6B138C64A5', 'D106FF0BED5255D7',
2417'9D64555A9A10B852', 'F02B263B328E2B60', '64FEED9C724C2FAF', '750D079407521363',
2418'FBE00A8A1EF8AD72', 'A484C3AD38DC9C19', '12A9F5817FF2D65D', 'E7FCE22557D23C97',
2419'329A8ED523D71AEC', 'E19E275D846A1298', '889DE068A16F0BE6', '2B9F982F20037FA9',
2420'F356834379D165CD', 'ECBFE3BD3F591A5E', 'E6D5F82752AD63D1', 'ADD0CC8D6E5DEBA1',
2421'F15D0F286B65BD28', 'B8061B7ECD9A21E5', '424250B37C3DD951', 'D9031B0271BD5A0A',
2422'0D9F279BA5D87260', '6CC5DEFAAF04512F', '55579380D77138EF', '20B9E767B2FB1456',
2423'4BD388FF6CD81D4F', '2E8653104F3834EA', 'DD7F121CA5015619', '95F8A5E5DD31D900',
2424        ]
2425        ipe_single_bits = ["{:016x}".format(1 << bit) for bit in range(64)]
2426        for plaintext, ciphertext in zip(ipe_plaintexts, ipe_single_bits):
2427            vector(ipe_key, plaintext, ciphertext)
2428        for plaintext, ciphertext in zip(ipe_single_bits, ipe_ciphertexts):
2429            vector(ipe_key, plaintext, ciphertext)
2430
2431        # 'Key permutation tests': plaintext fixed at all zeroes, key
2432        # is a succession of tweaks of the previous key made by
2433        # replacing each 01 byte in turn with one containing a
2434        # different single set bit (e.g. 01 20 01 01 01 01 01 01).
2435        # Expected ciphertexts listed.
2436        kp_ciphertexts = [
2437'95A8D72813DAA94D', '0EEC1487DD8C26D5', '7AD16FFB79C45926', 'D3746294CA6A6CF3',
2438'809F5F873C1FD761', 'C02FAFFEC989D1FC', '4615AA1D33E72F10', '2055123350C00858',
2439'DF3B99D6577397C8', '31FE17369B5288C9', 'DFDD3CC64DAE1642', '178C83CE2B399D94',
2440'50F636324A9B7F80', 'A8468EE3BC18F06D', 'A2DC9E92FD3CDE92', 'CAC09F797D031287',
2441'90BA680B22AEB525', 'CE7A24F350E280B6', '882BFF0AA01A0B87', '25610288924511C2',
2442'C71516C29C75D170', '5199C29A52C9F059', 'C22F0A294A71F29F', 'EE371483714C02EA',
2443'A81FBD448F9E522F', '4F644C92E192DFED', '1AFA9A66A6DF92AE', 'B3C1CC715CB879D8',
2444'19D032E64AB0BD8B', '3CFAA7A7DC8720DC', 'B7265F7F447AC6F3', '9DB73B3C0D163F54',
2445'8181B65BABF4A975', '93C9B64042EAA240', '5570530829705592', '8638809E878787A0',
2446'41B9A79AF79AC208', '7A9BE42F2009A892', '29038D56BA6D2745', '5495C6ABF1E5DF51',
2447'AE13DBD561488933', '024D1FFA8904E389', 'D1399712F99BF02E', '14C1D7C1CFFEC79E',
2448'1DE5279DAE3BED6F', 'E941A33F85501303', 'DA99DBBC9A03F379', 'B7FC92F91D8E92E9',
2449'AE8E5CAA3CA04E85', '9CC62DF43B6EED74', 'D863DBB5C59A91A0', 'A1AB2190545B91D7',
2450'0875041E64C570F7', '5A594528BEBEF1CC', 'FCDB3291DE21F0C0', '869EFD7F9F265A09',
2451        ]
2452        kp_key_repl_bytes = ["{:02x}".format(0x80>>i) for i in range(7)]
2453        kp_keys = ['01'*j + b + '01'*(7-j)
2454                   for j in range(8) for b in kp_key_repl_bytes]
2455        kp_plaintext = '0' * 16
2456        for key, ciphertext in zip(kp_keys, kp_ciphertexts):
2457            vector(key, kp_plaintext, ciphertext)
2458
2459        # 'Data permutation test': plaintext fixed at all zeroes,
2460        # pairs of key and expected ciphertext listed below.
2461        dp_keys_and_ciphertexts = [
2462'1046913489980131:88D55E54F54C97B4', '1007103489988020:0C0CC00C83EA48FD',
2463'10071034C8980120:83BC8EF3A6570183', '1046103489988020:DF725DCAD94EA2E9',
2464'1086911519190101:E652B53B550BE8B0', '1086911519580101:AF527120C485CBB0',
2465'5107B01519580101:0F04CE393DB926D5', '1007B01519190101:C9F00FFC74079067',
2466'3107915498080101:7CFD82A593252B4E', '3107919498080101:CB49A2F9E91363E3',
2467'10079115B9080140:00B588BE70D23F56', '3107911598080140:406A9A6AB43399AE',
2468'1007D01589980101:6CB773611DCA9ADA', '9107911589980101:67FD21C17DBB5D70',
2469'9107D01589190101:9592CB4110430787', '1007D01598980120:A6B7FF68A318DDD3',
2470'1007940498190101:4D102196C914CA16', '0107910491190401:2DFA9F4573594965',
2471'0107910491190101:B46604816C0E0774', '0107940491190401:6E7E6221A4F34E87',
2472'19079210981A0101:AA85E74643233199', '1007911998190801:2E5A19DB4D1962D6',
2473'10079119981A0801:23A866A809D30894', '1007921098190101:D812D961F017D320',
2474'100791159819010B:055605816E58608F', '1004801598190101:ABD88E8B1B7716F1',
2475'1004801598190102:537AC95BE69DA1E1', '1004801598190108:AED0F6AE3C25CDD8',
2476'1002911498100104:B3E35A5EE53E7B8D', '1002911598190104:61C79C71921A2EF8',
2477'1002911598100201:E2F5728F0995013C', '1002911698100101:1AEAC39A61F0A464',
2478        ]
2479        dp_plaintext = '0' * 16
2480        for key_and_ciphertext in dp_keys_and_ciphertexts:
2481            key, ciphertext = key_and_ciphertext.split(":")
2482            vector(key, dp_plaintext, ciphertext)
2483
2484        # Tests intended to select every entry in every S-box. Full
2485        # arbitrary triples (key, plaintext, ciphertext).
2486        sb_complete_tests = [
2487            '7CA110454A1A6E57:01A1D6D039776742:690F5B0D9A26939B',
2488            '0131D9619DC1376E:5CD54CA83DEF57DA:7A389D10354BD271',
2489            '07A1133E4A0B2686:0248D43806F67172:868EBB51CAB4599A',
2490            '3849674C2602319E:51454B582DDF440A:7178876E01F19B2A',
2491            '04B915BA43FEB5B6:42FD443059577FA2:AF37FB421F8C4095',
2492            '0113B970FD34F2CE:059B5E0851CF143A:86A560F10EC6D85B',
2493            '0170F175468FB5E6:0756D8E0774761D2:0CD3DA020021DC09',
2494            '43297FAD38E373FE:762514B829BF486A:EA676B2CB7DB2B7A',
2495            '07A7137045DA2A16:3BDD119049372802:DFD64A815CAF1A0F',
2496            '04689104C2FD3B2F:26955F6835AF609A:5C513C9C4886C088',
2497            '37D06BB516CB7546:164D5E404F275232:0A2AEEAE3FF4AB77',
2498            '1F08260D1AC2465E:6B056E18759F5CCA:EF1BF03E5DFA575A',
2499            '584023641ABA6176:004BD6EF09176062:88BF0DB6D70DEE56',
2500            '025816164629B007:480D39006EE762F2:A1F9915541020B56',
2501            '49793EBC79B3258F:437540C8698F3CFA:6FBF1CAFCFFD0556',
2502            '4FB05E1515AB73A7:072D43A077075292:2F22E49BAB7CA1AC',
2503            '49E95D6D4CA229BF:02FE55778117F12A:5A6B612CC26CCE4A',
2504            '018310DC409B26D6:1D9D5C5018F728C2:5F4C038ED12B2E41',
2505            '1C587F1C13924FEF:305532286D6F295A:63FAC0D034D9F793',
2506        ]
2507        for test in sb_complete_tests:
2508            key, plaintext, ciphertext = test.split(":")
2509            vector(key, plaintext, ciphertext)
2510
2511    def testMD5(self):
2512        MD5 = lambda s: hash_str('md5', s)
2513
2514        # The test vectors from RFC 1321 section A.5.
2515        self.assertEqualBin(MD5(""),
2516                            unhex('d41d8cd98f00b204e9800998ecf8427e'))
2517        self.assertEqualBin(MD5("a"),
2518                            unhex('0cc175b9c0f1b6a831c399e269772661'))
2519        self.assertEqualBin(MD5("abc"),
2520                            unhex('900150983cd24fb0d6963f7d28e17f72'))
2521        self.assertEqualBin(MD5("message digest"),
2522                            unhex('f96b697d7cb7938d525a2f31aaf161d0'))
2523        self.assertEqualBin(MD5("abcdefghijklmnopqrstuvwxyz"),
2524                            unhex('c3fcd3d76192e4007dfb496cca67e13b'))
2525        self.assertEqualBin(MD5("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
2526                                "abcdefghijklmnopqrstuvwxyz0123456789"),
2527                            unhex('d174ab98d277d9f5a5611c2c9f419d9f'))
2528        self.assertEqualBin(MD5("1234567890123456789012345678901234567890"
2529                                "1234567890123456789012345678901234567890"),
2530                            unhex('57edf4a22be3c955ac49da2e2107b67a'))
2531
2532    def testHmacMD5(self):
2533        # The test vectors from the RFC 2104 Appendix.
2534        self.assertEqualBin(mac_str('hmac_md5', unhex('0b'*16), "Hi There"),
2535                         unhex('9294727a3638bb1c13f48ef8158bfc9d'))
2536        self.assertEqualBin(mac_str('hmac_md5', "Jefe",
2537                                 "what do ya want for nothing?"),
2538                         unhex('750c783e6ab0b503eaa86e310a5db738'))
2539        self.assertEqualBin(mac_str('hmac_md5', unhex('aa'*16), unhex('dd'*50)),
2540                         unhex('56be34521d144c88dbb8c733f0e8b3f6'))
2541
2542    def testSHA1(self):
2543        for hashname in ['sha1_sw', 'sha1_hw']:
2544            if ssh_hash_new(hashname) is None:
2545                continue # skip testing of unavailable HW implementation
2546
2547            # Test cases from RFC 6234 section 8.5, omitting the ones
2548            # whose input is not a multiple of 8 bits
2549            self.assertEqualBin(hash_str(hashname, "abc"), unhex(
2550                "a9993e364706816aba3e25717850c26c9cd0d89d"))
2551            self.assertEqualBin(hash_str(hashname,
2552                "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"),
2553                unhex("84983e441c3bd26ebaae4aa1f95129e5e54670f1"))
2554            self.assertEqualBin(hash_str_iter(hashname,
2555                ("a" * 1000 for _ in range(1000))), unhex(
2556                "34aa973cd4c4daa4f61eeb2bdbad27316534016f"))
2557            self.assertEqualBin(hash_str(hashname,
2558                "01234567012345670123456701234567" * 20), unhex(
2559                "dea356a2cddd90c7a7ecedc5ebb563934f460452"))
2560            self.assertEqualBin(hash_str(hashname, b"\x5e"), unhex(
2561                "5e6f80a34a9798cafc6a5db96cc57ba4c4db59c2"))
2562            self.assertEqualBin(hash_str(hashname,
2563                unhex("9a7dfdf1ecead06ed646aa55fe757146")), unhex(
2564                "82abff6605dbe1c17def12a394fa22a82b544a35"))
2565            self.assertEqualBin(hash_str(hashname, unhex(
2566                "f78f92141bcd170ae89b4fba15a1d59f"
2567                "3fd84d223c9251bdacbbae61d05ed115"
2568                "a06a7ce117b7beead24421ded9c32592"
2569                "bd57edeae39c39fa1fe8946a84d0cf1f"
2570                "7beead1713e2e0959897347f67c80b04"
2571                "00c209815d6b10a683836fd5562a56ca"
2572                "b1a28e81b6576654631cf16566b86e3b"
2573                "33a108b05307c00aff14a768ed735060"
2574                "6a0f85e6a91d396f5b5cbe577f9b3880"
2575                "7c7d523d6d792f6ebc24a4ecf2b3a427"
2576                "cdbbfb")), unhex(
2577                "cb0082c8f197d260991ba6a460e76e202bad27b3"))
2578
2579    def testSHA256(self):
2580        for hashname in ['sha256_sw', 'sha256_hw']:
2581            if ssh_hash_new(hashname) is None:
2582                continue # skip testing of unavailable HW implementation
2583
2584            # Test cases from RFC 6234 section 8.5, omitting the ones
2585            # whose input is not a multiple of 8 bits
2586            self.assertEqualBin(hash_str(hashname, "abc"),
2587                                unhex("ba7816bf8f01cfea414140de5dae2223"
2588                                      "b00361a396177a9cb410ff61f20015ad"))
2589            self.assertEqualBin(hash_str(hashname,
2590                "abcdbcdecdefdefgefghfghighijhijk""ijkljklmklmnlmnomnopnopq"),
2591                                unhex("248d6a61d20638b8e5c026930c3e6039"
2592                                      "a33ce45964ff2167f6ecedd419db06c1"))
2593            self.assertEqualBin(
2594                hash_str_iter(hashname, ("a" * 1000 for _ in range(1000))),
2595                unhex("cdc76e5c9914fb9281a1c7e284d73e67"
2596                      "f1809a48a497200e046d39ccc7112cd0"))
2597            self.assertEqualBin(
2598                hash_str(hashname, "01234567012345670123456701234567" * 20),
2599                unhex("594847328451bdfa85056225462cc1d8"
2600                      "67d877fb388df0ce35f25ab5562bfbb5"))
2601            self.assertEqualBin(hash_str(hashname, b"\x19"),
2602                                unhex("68aa2e2ee5dff96e3355e6c7ee373e3d"
2603                                      "6a4e17f75f9518d843709c0c9bc3e3d4"))
2604            self.assertEqualBin(
2605                hash_str(hashname, unhex("e3d72570dcdd787ce3887ab2cd684652")),
2606                unhex("175ee69b02ba9b58e2b0a5fd13819cea"
2607                      "573f3940a94f825128cf4209beabb4e8"))
2608            self.assertEqualBin(hash_str(hashname, unhex(
2609                "8326754e2277372f4fc12b20527afef0"
2610                "4d8a056971b11ad57123a7c137760000"
2611                "d7bef6f3c1f7a9083aa39d810db31077"
2612                "7dab8b1e7f02b84a26c773325f8b2374"
2613                "de7a4b5a58cb5c5cf35bcee6fb946e5b"
2614                "d694fa593a8beb3f9d6592ecedaa66ca"
2615                "82a29d0c51bcf9336230e5d784e4c0a4"
2616                "3f8d79a30a165cbabe452b774b9c7109"
2617                "a97d138f129228966f6c0adc106aad5a"
2618                "9fdd30825769b2c671af6759df28eb39"
2619                "3d54d6")), unhex(
2620                    "97dbca7df46d62c8a422c941dd7e835b"
2621                    "8ad3361763f7e9b2d95f4f0da6e1ccbc"))
2622
2623    def testSHA384(self):
2624        for hashname in ['sha384_sw', 'sha384_hw']:
2625            if ssh_hash_new(hashname) is None:
2626                continue # skip testing of unavailable HW implementation
2627
2628            # Test cases from RFC 6234 section 8.5, omitting the ones
2629            # whose input is not a multiple of 8 bits
2630            self.assertEqualBin(hash_str('sha384', "abc"), unhex(
2631                'cb00753f45a35e8bb5a03d699ac65007272c32ab0eded163'
2632                '1a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7'))
2633            self.assertEqualBin(hash_str('sha384',
2634                "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
2635                "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"),
2636                unhex('09330c33f71147e83d192fc782cd1b4753111b173b3b05d2'
2637                      '2fa08086e3b0f712fcc7c71a557e2db966c3e9fa91746039'))
2638            self.assertEqualBin(hash_str_iter('sha384',
2639                ("a" * 1000 for _ in range(1000))), unhex(
2640                '9d0e1809716474cb086e834e310a4a1ced149e9c00f24852'
2641                '7972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985'))
2642            self.assertEqualBin(hash_str('sha384',
2643                "01234567012345670123456701234567" * 20), unhex(
2644                '2fc64a4f500ddb6828f6a3430b8dd72a368eb7f3a8322a70'
2645                'bc84275b9c0b3ab00d27a5cc3c2d224aa6b61a0d79fb4596'))
2646            self.assertEqualBin(hash_str('sha384', b"\xB9"), unhex(
2647                'bc8089a19007c0b14195f4ecc74094fec64f01f90929282c'
2648                '2fb392881578208ad466828b1c6c283d2722cf0ad1ab6938'))
2649            self.assertEqualBin(hash_str('sha384',
2650                unhex("a41c497779c0375ff10a7f4e08591739")), unhex(
2651                'c9a68443a005812256b8ec76b00516f0dbb74fab26d66591'
2652                '3f194b6ffb0e91ea9967566b58109cbc675cc208e4c823f7'))
2653            self.assertEqualBin(hash_str('sha384', unhex(
2654                "399669e28f6b9c6dbcbb6912ec10ffcf74790349b7dc8fbe4a8e7b3b5621"
2655                "db0f3e7dc87f823264bbe40d1811c9ea2061e1c84ad10a23fac1727e7202"
2656                "fc3f5042e6bf58cba8a2746e1f64f9b9ea352c711507053cf4e5339d5286"
2657                "5f25cc22b5e87784a12fc961d66cb6e89573199a2ce6565cbdf13dca4038"
2658                "32cfcb0e8b7211e83af32a11ac17929ff1c073a51cc027aaedeff85aad7c"
2659                "2b7c5a803e2404d96d2a77357bda1a6daeed17151cb9bc5125a422e941de"
2660                "0ca0fc5011c23ecffefdd09676711cf3db0a3440720e1615c1f22fbc3c72"
2661                "1de521e1b99ba1bd5577408642147ed096")), unhex(
2662                '4f440db1e6edd2899fa335f09515aa025ee177a79f4b4aaf'
2663                '38e42b5c4de660f5de8fb2a5b2fbd2a3cbffd20cff1288c0'))
2664
2665    def testSHA512(self):
2666        for hashname in ['sha512_sw', 'sha512_hw']:
2667            if ssh_hash_new(hashname) is None:
2668                continue # skip testing of unavailable HW implementation
2669
2670            # Test cases from RFC 6234 section 8.5, omitting the ones
2671            # whose input is not a multiple of 8 bits
2672            self.assertEqualBin(hash_str('sha512', "abc"), unhex(
2673                'ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55'
2674                'd39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94f'
2675                'a54ca49f'))
2676            self.assertEqualBin(hash_str('sha512',
2677                "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
2678                "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"),
2679                unhex('8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299'
2680                'aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26'
2681                '545e96e55b874be909'))
2682            self.assertEqualBin(hash_str_iter('sha512',
2683                ("a" * 1000 for _ in range(1000))), unhex(
2684                'e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa9'
2685                '73ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217'
2686                'ad8cc09b'))
2687            self.assertEqualBin(hash_str('sha512',
2688                "01234567012345670123456701234567" * 20), unhex(
2689                '89d05ba632c699c31231ded4ffc127d5a894dad412c0e024db872d1abd2b'
2690                'a8141a0f85072a9be1e2aa04cf33c765cb510813a39cd5a84c4acaa64d3f'
2691                '3fb7bae9'))
2692            self.assertEqualBin(hash_str('sha512', b"\xD0"), unhex(
2693                '9992202938e882e73e20f6b69e68a0a7149090423d93c81bab3f21678d4a'
2694                'ceeee50e4e8cafada4c85a54ea8306826c4ad6e74cece9631bfa8a549b4a'
2695                'b3fbba15'))
2696            self.assertEqualBin(hash_str('sha512',
2697                unhex("8d4e3c0e3889191491816e9d98bff0a0")), unhex(
2698                'cb0b67a4b8712cd73c9aabc0b199e9269b20844afb75acbdd1c153c98289'
2699                '24c3ddedaafe669c5fdd0bc66f630f6773988213eb1b16f517ad0de4b2f0'
2700                'c95c90f8'))
2701            self.assertEqualBin(hash_str('sha512', unhex(
2702                "a55f20c411aad132807a502d65824e31a2305432aa3d06d3e282a8d84e0d"
2703                "e1de6974bf495469fc7f338f8054d58c26c49360c3e87af56523acf6d89d"
2704                "03e56ff2f868002bc3e431edc44df2f0223d4bb3b243586e1a7d92493669"
2705                "4fcbbaf88d9519e4eb50a644f8e4f95eb0ea95bc4465c8821aacd2fe15ab"
2706                "4981164bbb6dc32f969087a145b0d9cc9c67c22b763299419cc4128be9a0"
2707                "77b3ace634064e6d99283513dc06e7515d0d73132e9a0dc6d3b1f8b246f1"
2708                "a98a3fc72941b1e3bb2098e8bf16f268d64f0b0f4707fe1ea1a1791ba2f3"
2709                "c0c758e5f551863a96c949ad47d7fb40d2")), unhex(
2710                'c665befb36da189d78822d10528cbf3b12b3eef726039909c1a16a270d48'
2711                '719377966b957a878e720584779a62825c18da26415e49a7176a894e7510'
2712                'fd1451f5'))
2713
2714    def testSHA3(self):
2715        # Source: all the SHA-3 test strings from
2716        # https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values#aHashing
2717        # which are a multiple of 8 bits long.
2718
2719        self.assertEqualBin(hash_str('sha3_224', ''), unhex("6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7"))
2720        self.assertEqualBin(hash_str('sha3_224', unhex('a3')*200), unhex("9376816aba503f72f96ce7eb65ac095deee3be4bf9bbc2a1cb7e11e0"))
2721        self.assertEqualBin(hash_str('sha3_256', ''), unhex("a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"))
2722        self.assertEqualBin(hash_str('sha3_256', unhex('a3')*200), unhex("79f38adec5c20307a98ef76e8324afbfd46cfd81b22e3973c65fa1bd9de31787"))
2723        self.assertEqualBin(hash_str('sha3_384', ''), unhex("0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004"))
2724        self.assertEqualBin(hash_str('sha3_384', unhex('a3')*200), unhex("1881de2ca7e41ef95dc4732b8f5f002b189cc1e42b74168ed1732649ce1dbcdd76197a31fd55ee989f2d7050dd473e8f"))
2725        self.assertEqualBin(hash_str('sha3_512', ''), unhex("a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26"))
2726        self.assertEqualBin(hash_str('sha3_512', unhex('a3')*200), unhex("e76dfad22084a8b1467fcf2ffa58361bec7628edf5f3fdc0e4805dc48caeeca81b7c13c30adf52a3659584739a2df46be589c51ca1a4a8416df6545a1ce8ba00"))
2727        self.assertEqualBin(hash_str('shake256_114bytes', ''), unhex("46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be141e96616fb13957692cc7edd0b45ae3dc07223c8e92937bef84bc0eab862853349ec75546f58fb7c2775c38462c5010d846"))
2728        self.assertEqualBin(hash_str('shake256_114bytes', unhex('a3')*200), unhex("cd8a920ed141aa0407a22d59288652e9d9f1a7ee0c1e7c1ca699424da84a904d2d700caae7396ece96604440577da4f3aa22aeb8857f961c4cd8e06f0ae6610b1048a7f64e1074cd629e85ad7566048efc4fb500b486a3309a8f26724c0ed628001a1099422468de726f1061d99eb9e93604"))
2729
2730    def testBLAKE2b(self):
2731        # Test case from RFC 7693 appendix A.
2732        self.assertEqualBin(hash_str('blake2b', b'abc'), unhex(
2733            "ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d1"
2734            "7d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923"))
2735
2736        # A small number of test cases from the larger test vector
2737        # set, testing multiple blocks and the empty input.
2738        self.assertEqualBin(hash_str('blake2b', b''), unhex(
2739            "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419"
2740            "d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"))
2741        self.assertEqualBin(hash_str('blake2b', unhex('00')), unhex(
2742            "2fa3f686df876995167e7c2e5d74c4c7b6e48f8068fe0e44208344d480f7904c"
2743            "36963e44115fe3eb2a3ac8694c28bcb4f5a0f3276f2e79487d8219057a506e4b"))
2744        self.assertEqualBin(hash_str('blake2b', bytes(range(255))), unhex(
2745            "5b21c5fd8868367612474fa2e70e9cfa2201ffeee8fafab5797ad58fefa17c9b"
2746            "5b107da4a3db6320baaf2c8617d5a51df914ae88da3867c2d41f0cc14fa67928"))
2747
2748        # You can get this test program to run the full version of the
2749        # test vectors by modifying the source temporarily to set this
2750        # variable to a pathname where you downloaded the JSON file
2751        # blake2-kat.json.
2752        blake2_test_vectors_path = None
2753        if blake2_test_vectors_path is not None:
2754            with open(blake2_test_vectors_path) as fh:
2755                vectors = json.load(fh)
2756            for vector in vectors:
2757                if vector['hash'] != 'blake2b':
2758                    continue
2759                if len(vector['key']) != 0:
2760                    continue
2761
2762                h = blake2b_new_general(len(vector['out']) // 2)
2763                ssh_hash_update(h, unhex(vector['in']))
2764                digest = ssh_hash_digest(h)
2765                self.assertEqualBin(digest, unhex(vector['out']))
2766
2767    def testArgon2(self):
2768        # draft-irtf-cfrg-argon2-12 section 5
2769        self.assertEqualBin(
2770            argon2('d', 32, 3, 4, 32, b'\x01' * 32, b'\x02' * 16,
2771                   b'\x03' * 8, b'\x04' * 12),
2772            unhex("512b391b6f1162975371d30919734294"
2773                  "f868e3be3984f3c1a13a4db9fabe4acb"))
2774        self.assertEqualBin(
2775            argon2('i', 32, 3, 4, 32, b'\x01' * 32, b'\x02' * 16,
2776                   b'\x03' * 8, b'\x04' * 12),
2777            unhex("c814d9d1dc7f37aa13f0d77f2494bda1"
2778                  "c8de6b016dd388d29952a4c4672b6ce8"))
2779        self.assertEqualBin(
2780            argon2('id', 32, 3, 4, 32, b'\x01' * 32, b'\x02' * 16,
2781                   b'\x03' * 8, b'\x04' * 12),
2782            unhex("0d640df58d78766c08c037a34a8b53c9"
2783                  "d01ef0452d75b65eb52520e96b01e659"))
2784
2785    def testHmacSHA(self):
2786        # Test cases from RFC 6234 section 8.5.
2787        def vector(key, message, s1=None, s256=None):
2788            if s1 is not None:
2789                self.assertEqualBin(
2790                    mac_str('hmac_sha1', key, message), unhex(s1))
2791            if s256 is not None:
2792                self.assertEqualBin(
2793                    mac_str('hmac_sha256', key, message), unhex(s256))
2794        vector(
2795            unhex("0b"*20), "Hi There",
2796            "b617318655057264e28bc0b6fb378c8ef146be00",
2797            "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7")
2798        vector(
2799            "Jefe", "what do ya want for nothing?",
2800            "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79",
2801            "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843")
2802        vector(
2803            unhex("aa"*20), unhex('dd'*50),
2804            "125d7342b9ac11cd91a39af48aa17b4f63f175d3",
2805            "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565FE")
2806        vector(
2807            unhex("0102030405060708090a0b0c0d0e0f10111213141516171819"),
2808            unhex("cd"*50),
2809            "4c9007f4026250c6bc8414f9bf50c86c2d7235da",
2810            "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b")
2811        vector(
2812            unhex("aa"*80),
2813            "Test Using Larger Than Block-Size Key - Hash Key First",
2814            s1="aa4ae5e15272d00e95705637ce8a3b55ed402112")
2815        vector(
2816            unhex("aa"*131),
2817            "Test Using Larger Than Block-Size Key - Hash Key First",
2818            s256="60e431591ee0b67f0d8a26aacbf5b77f"
2819            "8e0bc6213728c5140546040f0ee37f54")
2820        vector(
2821            unhex("aa"*80),
2822            "Test Using Larger Than Block-Size Key and "
2823            "Larger Than One Block-Size Data",
2824            s1="e8e99d0f45237d786d6bbaa7965c7808bbff1a91")
2825        vector(
2826            unhex("aa"*131),
2827            "This is a test using a larger than block-size key and a "
2828            "larger than block-size data. The key needs to be hashed "
2829            "before being used by the HMAC algorithm.",
2830            s256="9B09FFA71B942FCB27635FBCD5B0E944BFDC63644F0713938A7F51535C3A35E2")
2831
2832    def testEd25519(self):
2833        def vector(privkey, pubkey, message, signature):
2834            x, y = ecc_edwards_get_affine(eddsa_public(
2835                mp_from_bytes_le(privkey), 'ed25519'))
2836            self.assertEqual(int(y) | ((int(x) & 1) << 255),
2837                             int(mp_from_bytes_le(pubkey)))
2838            pubblob = ssh_string(b"ssh-ed25519") + ssh_string(pubkey)
2839            privblob = ssh_string(privkey)
2840            sigblob = ssh_string(b"ssh-ed25519") + ssh_string(signature)
2841            pubkey = ssh_key_new_pub('ed25519', pubblob)
2842            self.assertTrue(ssh_key_verify(pubkey, sigblob, message))
2843            privkey = ssh_key_new_priv('ed25519', pubblob, privblob)
2844            # By testing that the signature is exactly the one expected in
2845            # the test vector and not some equivalent one generated with a
2846            # different nonce, we're verifying in particular that we do
2847            # our deterministic nonce generation in the manner specified
2848            # by Ed25519. Getting that wrong would lead to no obvious
2849            # failure, but would surely turn out to be a bad idea sooner
2850            # or later...
2851            self.assertEqualBin(ssh_key_sign(privkey, message, 0), sigblob)
2852
2853        # A cherry-picked example from DJB's test vector data at
2854        # https://ed25519.cr.yp.to/python/sign.input, which is too
2855        # large to copy into here in full.
2856        privkey = unhex(
2857            'c89955e0f7741d905df0730b3dc2b0ce1a13134e44fef3d40d60c020ef19df77')
2858        pubkey = unhex(
2859            'fdb30673402faf1c8033714f3517e47cc0f91fe70cf3836d6c23636e3fd2287c')
2860        message = unhex(
2861            '507c94c8820d2a5793cbf3442b3d71936f35fe3afef316')
2862        signature = unhex(
2863            '7ef66e5e86f2360848e0014e94880ae2920ad8a3185a46b35d1e07dea8fa8ae4'
2864            'f6b843ba174d99fa7986654a0891c12a794455669375bf92af4cc2770b579e0c')
2865        vector(privkey, pubkey, message, signature)
2866
2867        # You can get this test program to run the full version of
2868        # DJB's test vectors by modifying the source temporarily to
2869        # set this variable to a pathname where you downloaded the
2870        # file.
2871        ed25519_test_vector_path = None
2872        if ed25519_test_vector_path is not None:
2873            with open(ed25519_test_vector_path) as f:
2874                for line in iter(f.readline, ""):
2875                    words = line.split(":")
2876                    # DJB's test vector input format concatenates a
2877                    # spare copy of the public key to the end of the
2878                    # private key, and a spare copy of the message to
2879                    # the end of the signature. Strip those off.
2880                    privkey = unhex(words[0])[:32]
2881                    pubkey = unhex(words[1])
2882                    message = unhex(words[2])
2883                    signature = unhex(words[3])[:64]
2884                    vector(privkey, pubkey, message, signature)
2885
2886    def testEd448(self):
2887        def vector(privkey, pubkey, message, signature):
2888            x, y = ecc_edwards_get_affine(eddsa_public(
2889                mp_from_bytes_le(privkey), 'ed448'))
2890            self.assertEqual(int(y) | ((int(x) & 1) << 455),
2891                             int(mp_from_bytes_le(pubkey)))
2892            pubblob = ssh_string(b"ssh-ed448") + ssh_string(pubkey)
2893            privblob = ssh_string(privkey)
2894            sigblob = ssh_string(b"ssh-ed448") + ssh_string(signature)
2895            pubkey = ssh_key_new_pub('ed448', pubblob)
2896            self.assertTrue(ssh_key_verify(pubkey, sigblob, message))
2897            privkey = ssh_key_new_priv('ed448', pubblob, privblob)
2898            # Deterministic signature check as in Ed25519
2899            self.assertEqualBin(ssh_key_sign(privkey, message, 0), sigblob)
2900
2901        # Source: RFC 8032 section 7.4
2902
2903        privkey = unhex('6c82a562cb808d10d632be89c8513ebf6c929f34ddfa8c9f63c9960ef6e348a3528c8a3fcc2f044e39a3fc5b94492f8f032e7549a20098f95b')
2904        pubkey = unhex('5fd7449b59b461fd2ce787ec616ad46a1da1342485a70e1f8a0ea75d80e96778edf124769b46c7061bd6783df1e50f6cd1fa1abeafe8256180')
2905        message = b''
2906        signature = unhex('533a37f6bbe457251f023c0d88f976ae2dfb504a843e34d2074fd823d41a591f2b233f034f628281f2fd7a22ddd47d7828c59bd0a21bfd3980ff0d2028d4b18a9df63e006c5d1c2d345b925d8dc00b4104852db99ac5c7cdda8530a113a0f4dbb61149f05a7363268c71d95808ff2e652600')
2907        vector(privkey, pubkey, message, signature)
2908
2909        privkey = unhex('c4eab05d357007c632f3dbb48489924d552b08fe0c353a0d4a1f00acda2c463afbea67c5e8d2877c5e3bc397a659949ef8021e954e0a12274e')
2910        pubkey = unhex('43ba28f430cdff456ae531545f7ecd0ac834a55d9358c0372bfa0c6c6798c0866aea01eb00742802b8438ea4cb82169c235160627b4c3a9480')
2911        message = unhex('03')
2912        signature = unhex('26b8f91727bd62897af15e41eb43c377efb9c610d48f2335cb0bd0087810f4352541b143c4b981b7e18f62de8ccdf633fc1bf037ab7cd779805e0dbcc0aae1cbcee1afb2e027df36bc04dcecbf154336c19f0af7e0a6472905e799f1953d2a0ff3348ab21aa4adafd1d234441cf807c03a00')
2913        vector(privkey, pubkey, message, signature)
2914
2915        privkey = unhex('cd23d24f714274e744343237b93290f511f6425f98e64459ff203e8985083ffdf60500553abc0e05cd02184bdb89c4ccd67e187951267eb328')
2916        pubkey = unhex('dcea9e78f35a1bf3499a831b10b86c90aac01cd84b67a0109b55a36e9328b1e365fce161d71ce7131a543ea4cb5f7e9f1d8b00696447001400')
2917        message = unhex('0c3e544074ec63b0265e0c')
2918        signature = unhex('1f0a8888ce25e8d458a21130879b840a9089d999aaba039eaf3e3afa090a09d389dba82c4ff2ae8ac5cdfb7c55e94d5d961a29fe0109941e00b8dbdeea6d3b051068df7254c0cdc129cbe62db2dc957dbb47b51fd3f213fb8698f064774250a5028961c9bf8ffd973fe5d5c206492b140e00')
2919        vector(privkey, pubkey, message, signature)
2920
2921        privkey = unhex('258cdd4ada32ed9c9ff54e63756ae582fb8fab2ac721f2c8e676a72768513d939f63dddb55609133f29adf86ec9929dccb52c1c5fd2ff7e21b')
2922        pubkey = unhex('3ba16da0c6f2cc1f30187740756f5e798d6bc5fc015d7c63cc9510ee3fd44adc24d8e968b6e46e6f94d19b945361726bd75e149ef09817f580')
2923        message = unhex('64a65f3cdedcdd66811e2915')
2924        signature = unhex('7eeeab7c4e50fb799b418ee5e3197ff6bf15d43a14c34389b59dd1a7b1b85b4ae90438aca634bea45e3a2695f1270f07fdcdf7c62b8efeaf00b45c2c96ba457eb1a8bf075a3db28e5c24f6b923ed4ad747c3c9e03c7079efb87cb110d3a99861e72003cbae6d6b8b827e4e6c143064ff3c00')
2925        vector(privkey, pubkey, message, signature)
2926
2927        privkey = unhex('d65df341ad13e008567688baedda8e9dcdc17dc024974ea5b4227b6530e339bff21f99e68ca6968f3cca6dfe0fb9f4fab4fa135d5542ea3f01')
2928        pubkey = unhex('df9705f58edbab802c7f8363cfe5560ab1c6132c20a9f1dd163483a26f8ac53a39d6808bf4a1dfbd261b099bb03b3fb50906cb28bd8a081f00')
2929        message = unhex('bd0f6a3747cd561bdddf4640a332461a4a30a12a434cd0bf40d766d9c6d458e5512204a30c17d1f50b5079631f64eb3112182da3005835461113718d1a5ef944')
2930        signature = unhex('554bc2480860b49eab8532d2a533b7d578ef473eeb58c98bb2d0e1ce488a98b18dfde9b9b90775e67f47d4a1c3482058efc9f40d2ca033a0801b63d45b3b722ef552bad3b4ccb667da350192b61c508cf7b6b5adadc2c8d9a446ef003fb05cba5f30e88e36ec2703b349ca229c2670833900')
2931        vector(privkey, pubkey, message, signature)
2932
2933        privkey = unhex('2ec5fe3c17045abdb136a5e6a913e32ab75ae68b53d2fc149b77e504132d37569b7e766ba74a19bd6162343a21c8590aa9cebca9014c636df5')
2934        pubkey = unhex('79756f014dcfe2079f5dd9e718be4171e2ef2486a08f25186f6bff43a9936b9bfe12402b08ae65798a3d81e22e9ec80e7690862ef3d4ed3a00')
2935        message = unhex('15777532b0bdd0d1389f636c5f6b9ba734c90af572877e2d272dd078aa1e567cfa80e12928bb542330e8409f3174504107ecd5efac61ae7504dabe2a602ede89e5cca6257a7c77e27a702b3ae39fc769fc54f2395ae6a1178cab4738e543072fc1c177fe71e92e25bf03e4ecb72f47b64d0465aaea4c7fad372536c8ba516a6039c3c2a39f0e4d832be432dfa9a706a6e5c7e19f397964ca4258002f7c0541b590316dbc5622b6b2a6fe7a4abffd96105eca76ea7b98816af0748c10df048ce012d901015a51f189f3888145c03650aa23ce894c3bd889e030d565071c59f409a9981b51878fd6fc110624dcbcde0bf7a69ccce38fabdf86f3bef6044819de11')
2936        signature = unhex('c650ddbb0601c19ca11439e1640dd931f43c518ea5bea70d3dcde5f4191fe53f00cf966546b72bcc7d58be2b9badef28743954e3a44a23f880e8d4f1cfce2d7a61452d26da05896f0a50da66a239a8a188b6d825b3305ad77b73fbac0836ecc60987fd08527c1a8e80d5823e65cafe2a3d00')
2937        vector(privkey, pubkey, message, signature)
2938
2939        privkey = unhex('872d093780f5d3730df7c212664b37b8a0f24f56810daa8382cd4fa3f77634ec44dc54f1c2ed9bea86fafb7632d8be199ea165f5ad55dd9ce8')
2940        pubkey = unhex('a81b2e8a70a5ac94ffdbcc9badfc3feb0801f258578bb114ad44ece1ec0e799da08effb81c5d685c0c56f64eecaef8cdf11cc38737838cf400')
2941        message = unhex('6ddf802e1aae4986935f7f981ba3f0351d6273c0a0c22c9c0e8339168e675412a3debfaf435ed651558007db4384b650fcc07e3b586a27a4f7a00ac8a6fec2cd86ae4bf1570c41e6a40c931db27b2faa15a8cedd52cff7362c4e6e23daec0fbc3a79b6806e316efcc7b68119bf46bc76a26067a53f296dafdbdc11c77f7777e972660cf4b6a9b369a6665f02e0cc9b6edfad136b4fabe723d2813db3136cfde9b6d044322fee2947952e031b73ab5c603349b307bdc27bc6cb8b8bbd7bd323219b8033a581b59eadebb09b3c4f3d2277d4f0343624acc817804728b25ab797172b4c5c21a22f9c7839d64300232eb66e53f31c723fa37fe387c7d3e50bdf9813a30e5bb12cf4cd930c40cfb4e1fc622592a49588794494d56d24ea4b40c89fc0596cc9ebb961c8cb10adde976a5d602b1c3f85b9b9a001ed3c6a4d3b1437f52096cd1956d042a597d561a596ecd3d1735a8d570ea0ec27225a2c4aaff26306d1526c1af3ca6d9cf5a2c98f47e1c46db9a33234cfd4d81f2c98538a09ebe76998d0d8fd25997c7d255c6d66ece6fa56f11144950f027795e653008f4bd7ca2dee85d8e90f3dc315130ce2a00375a318c7c3d97be2c8ce5b6db41a6254ff264fa6155baee3b0773c0f497c573f19bb4f4240281f0b1f4f7be857a4e59d416c06b4c50fa09e1810ddc6b1467baeac5a3668d11b6ecaa901440016f389f80acc4db977025e7f5924388c7e340a732e554440e76570f8dd71b7d640b3450d1fd5f0410a18f9a3494f707c717b79b4bf75c98400b096b21653b5d217cf3565c9597456f70703497a078763829bc01bb1cbc8fa04eadc9a6e3f6699587a9e75c94e5bab0036e0b2e711392cff0047d0d6b05bd2a588bc109718954259f1d86678a579a3120f19cfb2963f177aeb70f2d4844826262e51b80271272068ef5b3856fa8535aa2a88b2d41f2a0e2fda7624c2850272ac4a2f561f8f2f7a318bfd5caf9696149e4ac824ad3460538fdc25421beec2cc6818162d06bbed0c40a387192349db67a118bada6cd5ab0140ee273204f628aad1c135f770279a651e24d8c14d75a6059d76b96a6fd857def5e0b354b27ab937a5815d16b5fae407ff18222c6d1ed263be68c95f32d908bd895cd76207ae726487567f9a67dad79abec316f683b17f2d02bf07e0ac8b5bc6162cf94697b3c27cd1fea49b27f23ba2901871962506520c392da8b6ad0d99f7013fbc06c2c17a569500c8a7696481c1cd33e9b14e40b82e79a5f5db82571ba97bae3ad3e0479515bb0e2b0f3bfcd1fd33034efc6245eddd7ee2086ddae2600d8ca73e214e8c2b0bdb2b047c6a464a562ed77b73d2d841c4b34973551257713b753632efba348169abc90a68f42611a40126d7cb21b58695568186f7e569d2ff0f9e745d0487dd2eb997cafc5abf9dd102e62ff66cba87')
2942        signature = unhex('e301345a41a39a4d72fff8df69c98075a0cc082b802fc9b2b6bc503f926b65bddf7f4c8f1cb49f6396afc8a70abe6d8aef0db478d4c6b2970076c6a0484fe76d76b3a97625d79f1ce240e7c576750d295528286f719b413de9ada3e8eb78ed573603ce30d8bb761785dc30dbc320869e1a00')
2943        vector(privkey, pubkey, message, signature)
2944
2945    def testMontgomeryKex(self):
2946        # Unidirectional tests, consisting of an input random number
2947        # string and peer public value, giving the expected output
2948        # shared key. Source: RFC 7748 section 5.2.
2949        rfc7748s5_2 = [
2950            ('curve25519',
2951             'a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4',
2952             'e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c',
2953             0xc3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552),
2954            ('curve25519',
2955             '4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d',
2956             'e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493',
2957             0x95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957),
2958            ('curve448',
2959             '3d262fddf9ec8e88495266fea19a34d28882acef045104d0d1aae121700a779c984c24f8cdd78fbff44943eba368f54b29259a4f1c600ad3',
2960             '06fce640fa3487bfda5f6cf2d5263f8aad88334cbd07437f020f08f9814dc031ddbdc38c19c6da2583fa5429db94ada18aa7a7fb4ef8a086',
2961             0xce3e4ff95a60dc6697da1db1d85e6afbdf79b50a2412d7546d5f239fe14fbaadeb445fc66a01b0779d98223961111e21766282f73dd96b6f),
2962            ('curve448',
2963             '203d494428b8399352665ddca42f9de8fef600908e0d461cb021f8c538345dd77c3e4806e25f46d3315c44e0a5b4371282dd2c8d5be3095f',
2964             '0fbcc2f993cd56d3305b0b7d9e55d4c1a8fb5dbb52f8e9a1e9b6201b165d015894e56c4d3570bee52fe205e28a78b91cdfbde71ce8d157db',
2965             0x884a02576239ff7a2f2f63b2db6a9ff37047ac13568e1e30fe63c4a7ad1b3ee3a5700df34321d62077e63633c575c1c954514e99da7c179d),
2966        ]
2967
2968        for method, priv, pub, expected in rfc7748s5_2:
2969            with queued_specific_random_data(unhex(priv)):
2970                ecdh = ssh_ecdhkex_newkey(method)
2971            key = ssh_ecdhkex_getkey(ecdh, unhex(pub))
2972            self.assertEqual(int(key), expected)
2973
2974        # Bidirectional tests, consisting of the input random number
2975        # strings for both parties, and the expected public values and
2976        # shared key. Source: RFC 7748 section 6.
2977        rfc7748s6 = [
2978            ('curve25519', # section 6.1
2979             '77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a',
2980             '8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a',
2981             '5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb',
2982             'de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f',
2983             0x4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742),
2984            ('curve448', # section 6.2
2985             '9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28dd9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b',
2986             '9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0',
2987             '1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d',
2988             '3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b43027d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609',
2989             0x07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d),
2990        ]
2991
2992        for method, apriv, apub, bpriv, bpub, expected in rfc7748s6:
2993            with queued_specific_random_data(unhex(apriv)):
2994                alice = ssh_ecdhkex_newkey(method)
2995            with queued_specific_random_data(unhex(bpriv)):
2996                bob = ssh_ecdhkex_newkey(method)
2997            self.assertEqualBin(ssh_ecdhkex_getpublic(alice), unhex(apub))
2998            self.assertEqualBin(ssh_ecdhkex_getpublic(bob), unhex(bpub))
2999            akey = ssh_ecdhkex_getkey(alice, unhex(bpub))
3000            bkey = ssh_ecdhkex_getkey(bob, unhex(apub))
3001            self.assertEqual(int(akey), expected)
3002            self.assertEqual(int(bkey), expected)
3003
3004    def testCRC32(self):
3005        self.assertEqual(crc32_rfc1662("123456789"), 0xCBF43926)
3006        self.assertEqual(crc32_ssh1("123456789"), 0x2DFD2D88)
3007
3008        # Source:
3009        # http://reveng.sourceforge.net/crc-catalogue/17plus.htm#crc.cat.crc-32-iso-hdlc
3010        # which collected these from various sources.
3011        reveng_tests = [
3012            '000000001CDF4421',
3013            'F20183779DAB24',
3014            '0FAA005587B2C9B6',
3015            '00FF55111262A032',
3016            '332255AABBCCDDEEFF3D86AEB0',
3017            '926B559BA2DE9C',
3018            'FFFFFFFFFFFFFFFF',
3019            'C008300028CFE9521D3B08EA449900E808EA449900E8300102007E649416',
3020            '6173640ACEDE2D15',
3021        ]
3022        for vec in map(unhex, reveng_tests):
3023            # Each of these test vectors can be read two ways. One
3024            # interpretation is that the last four bytes are the
3025            # little-endian encoding of the CRC of the rest. (Because
3026            # that's how the CRC is attached to a string at the
3027            # sending end.)
3028            #
3029            # The other interpretation is that if you CRC the whole
3030            # string, _including_ the final four bytes, you expect to
3031            # get the same value for any correct string (because the
3032            # little-endian encoding matches the way the rest of the
3033            # string was interpreted as a polynomial in the first
3034            # place). That's how a receiver is intended to check
3035            # things.
3036            #
3037            # The expected output value is listed in RFC 1662, and in
3038            # the reveng.sourceforge.net catalogue, as 0xDEBB20E3. But
3039            # that's because their checking procedure omits the final
3040            # complement step that the construction procedure
3041            # includes. Our crc32_rfc1662 function does do the final
3042            # complement, so we expect the bitwise NOT of that value,
3043            # namely 0x2144DF1C.
3044            expected = struct.unpack("<L", vec[-4:])[0]
3045            self.assertEqual(crc32_rfc1662(vec[:-4]), expected)
3046            self.assertEqual(crc32_rfc1662(vec), 0x2144DF1C)
3047
3048if __name__ == "__main__":
3049    # Run the tests, suppressing automatic sys.exit and collecting the
3050    # unittest.TestProgram instance returned by unittest.main instead.
3051    testprogram = unittest.main(exit=False)
3052
3053    # If any test failed, just exit with failure status.
3054    if not testprogram.result.wasSuccessful():
3055        childprocess.wait_for_exit()
3056        sys.exit(1)
3057
3058    # But if no tests failed, we have one last check to do: look at
3059    # the subprocess's return status, so that if Leak Sanitiser
3060    # detected any memory leaks, the success return status will turn
3061    # into a failure at the last minute.
3062    childprocess.check_return_status()
3063