pynacl

Python wrapper for http://nacl.cace-project.eu/
git clone https://code.literati.org/pynacl.git
Log | Files | Refs | README

test.py (8982B)


      1 #!/usr/bin/env python
      2 import binascii
      3 import unittest
      4 
      5 import nacl
      6 
      7 if bytes([65]) == b"A": # py3
      8     def bchr(c):
      9         return bytes([c])
     10 else: # py2
     11     def bchr(c):
     12         return chr(c)
     13 
     14 def perturb(s):
     15     return s[:-1] + bchr((ord(s[-1:]) + 1) % 256)
     16 
     17 
     18 class RandomTestCase(unittest.TestCase):
     19     def test_random_10(self):
     20         r = nacl.randombytes(10)
     21         self.assertEqual(len(r), 10)
     22         s = nacl.randombytes(10)
     23         self.assertNotEqual(r, s)
     24 
     25     def test_random_1000(self):
     26         r = nacl.randombytes(1000)
     27         self.assertEqual(len(r), 1000)
     28 
     29 
     30 class HashTestCase(unittest.TestCase):
     31     fox = b"The quick brown fox jumps over the lazy dog."
     32     def check_hash(self, func, s, h):
     33         f = getattr(nacl, func)
     34         r = f(s)
     35         self.assertEqual(binascii.b2a_hex(r).decode("ascii"), h)
     36 
     37     def test_sha256_empty(self):
     38         self.check_hash("crypto_hash_sha256", b"",
     39                         "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca4959"
     40                         "91b7852b855")
     41 
     42     def test_sha256_fox(self):
     43         self.check_hash("crypto_hash_sha256", self.fox,
     44                         "ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b7654"
     45                         "48c8635fb6c")
     46 
     47     def test_sha512_empty(self):
     48         self.check_hash("crypto_hash_sha512", b"",
     49                         "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a"
     50                         "921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47"
     51                         "417a81a538327af927da3e")
     52 
     53     def test_sha512_fox(self):
     54         self.check_hash("crypto_hash_sha512", self.fox,
     55                         "91ea1245f20d46ae9a037a989f54f1f790f0a47607eeb8a14d128"
     56                         "90cea77a1bbc6c7ed9cf205e67b7f2b8fd4c7dfd3a7a8617e45f3"
     57                         "c463d481c7e586c39ac1ed")
     58 
     59 
     60 class BoxTestCase(unittest.TestCase):
     61     msg = b"The quick brown fox jumps over the lazy dog."
     62 
     63     def nonce(self):
     64         return nacl.randombytes(nacl.crypto_box_NONCEBYTES)
     65 
     66     def setUp(self):
     67         self.pk1, self.sk1 = nacl.crypto_box_keypair()
     68         self.pk2, self.sk2 = nacl.crypto_box_keypair()
     69 
     70     def test_key_sizes(self):
     71         self.assertEqual(len(self.pk1), nacl.crypto_box_PUBLICKEYBYTES)
     72         self.assertEqual(len(self.sk1), nacl.crypto_box_SECRETKEYBYTES)
     73 
     74     def test_box(self):
     75         nonce = self.nonce()
     76         c = nacl.crypto_box(self.msg, nonce, self.pk2, self.sk1)
     77         m = nacl.crypto_box_open(c, nonce, self.pk1, self.sk2)
     78         self.assertEqual(m, self.msg)
     79 
     80     def test_box_badsig(self):
     81         nonce = self.nonce()
     82         c = nacl.crypto_box(self.msg, nonce, self.pk1, self.sk2)
     83         c1 = perturb(c)
     84         self.assertRaises(ValueError, nacl.crypto_box_open, c1, nonce, self.pk2,
     85                           self.sk1)
     86 
     87     def test_box_badskey(self):
     88         nonce = self.nonce()
     89         c = nacl.crypto_box(self.msg, nonce, self.pk2, perturb(self.sk1))
     90         self.assertRaises(ValueError, nacl.crypto_box_open, c, nonce, self.pk1,
     91                           self.sk2)
     92 
     93     def test_box_badpkey(self):
     94         nonce = self.nonce()
     95         c = nacl.crypto_box(self.msg, nonce, perturb(self.pk1), self.sk2)
     96         self.assertRaises(ValueError, nacl.crypto_box_open, c, nonce, self.pk2,
     97                           self.sk1)
     98 
     99 
    100 class ScalarMultTestCase(unittest.TestCase):
    101     def setUp(self):
    102         self.sk1 = nacl.randombytes(nacl.crypto_scalarmult_curve25519_BYTES)
    103         self.pk1 = nacl.crypto_scalarmult_curve25519_base(self.sk1)
    104         self.sk2 = nacl.randombytes(nacl.crypto_scalarmult_curve25519_BYTES)
    105         self.pk2 = nacl.crypto_scalarmult_curve25519_base(self.sk2)
    106 
    107     def test_dh(self):
    108         """Check that both shared secrets are the same."""
    109         s1 = nacl.crypto_scalarmult_curve25519(self.sk1, self.pk2)
    110         s2 = nacl.crypto_scalarmult_curve25519(self.sk2, self.pk1)
    111         self.assertEqual(s1, s2)
    112 
    113     def test_dh_badkey(self):
    114         s1 = nacl.crypto_scalarmult_curve25519(self.sk1, self.pk2)
    115         s2 = nacl.crypto_scalarmult_curve25519(perturb(self.sk2), self.pk1)
    116         self.assertNotEqual(s1, s2)
    117 
    118     def test_sharedkey(self):
    119         dh_a = nacl.crypto_box_keypair()
    120         dh_b = nacl.crypto_box_keypair()
    121         shk_a = nacl.crypto_scalarmult_curve25519(dh_a[1], dh_b[0])
    122         shk_b = nacl.crypto_scalarmult_curve25519(dh_b[1], dh_a[0])
    123         self.assertEqual(shk_a, shk_b)
    124 
    125     def test_known(self):
    126         sk3 = binascii.a2b_hex("5305ca1802ea41cd48f904e85d97868c"
    127                                "c0f30819473cd07727d7c44974bc8e58")
    128         pk3 = nacl.crypto_scalarmult_curve25519_base(sk3)
    129         sk4 = binascii.a2b_hex("fba6870b71790aa6ca40ca1fe29533a4"
    130                                "ab09d401b3b2c624ad15d615454ba27a")
    131         pk4 = nacl.crypto_scalarmult_curve25519_base(sk4)
    132 
    133         s1 = nacl.crypto_scalarmult_curve25519(sk3, pk4)
    134         s2 = nacl.crypto_scalarmult_curve25519(sk4, pk3)
    135         expected = ("63b564b8218367b7d8d700cdc0d2e23a"
    136                     "65ef73905606f9c2e23b00d818c16a7e")
    137         self.assertEqual(binascii.b2a_hex(s1), expected)
    138         self.assertEqual(binascii.b2a_hex(s2), expected)
    139 
    140 class SignTestCase(unittest.TestCase):
    141     msg = b"The quick brown fox jumps over the lazy dog."
    142 
    143     def setUp(self):
    144         self.pk, self.sk = nacl.crypto_sign_keypair()
    145         self.pk1, self.sk1 = nacl.crypto_sign_keypair_fromseed(b"hello world")
    146 
    147     def test_keys_different(self):
    148         self.assertNotEqual(self.pk, self.pk1)
    149         self.assertNotEqual(self.sk, self.sk1)
    150         self.assertNotEqual(self.pk, self.sk)
    151         self.assertNotEqual(self.pk1, self.sk1)
    152 
    153     def test_key_length(self):
    154         self.assertEqual(len(self.pk), nacl.crypto_sign_PUBLICKEYBYTES)
    155         self.assertEqual(len(self.sk), nacl.crypto_sign_SECRETKEYBYTES)
    156 
    157     def test_seed(self):
    158         self.assertEqual(binascii.b2a_hex(self.pk1).decode("ascii"),
    159                          "683d8d0458ef6ec4cfef25157f5d88ce7a0bba334fd102fafc7e"
    160                          "2751410d5718")
    161         self.assertEqual(binascii.b2a_hex(self.sk1).decode("ascii"),
    162                          "309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd"
    163                          "3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f"
    164                          "605dcf7dc5542e93ae9cd76f")
    165 
    166     def test_signature(self):
    167         sm = nacl.crypto_sign(self.msg, self.sk)
    168         r = nacl.crypto_sign_open(sm, self.pk)
    169         self.assertEqual(r, self.msg)
    170 
    171     def test_failed_signature(self):
    172         sm = nacl.crypto_sign(self.msg, self.sk)
    173         self.assertRaises(ValueError, nacl.crypto_sign_open, sm, self.pk1)
    174 
    175 
    176 class SecretBoxTestCase(unittest.TestCase):
    177     msg = b"The quick brown fox jumps over the lazy dog."
    178     def setUp(self):
    179         self.k = nacl.randombytes(nacl.crypto_secretbox_KEYBYTES)
    180 
    181     def test_secretbox(self):
    182         nonce = nacl.randombytes(nacl.crypto_secretbox_NONCEBYTES)
    183         c = nacl.crypto_secretbox(self.msg, nonce, self.k)
    184         m = nacl.crypto_secretbox_open(c, nonce, self.k)
    185         self.assertEqual(m, self.msg)
    186 
    187     def test_secretbox_badsig(self):
    188         nonce = nacl.randombytes(nacl.crypto_secretbox_NONCEBYTES)
    189         c = nacl.crypto_secretbox(self.msg, nonce, self.k)
    190         c1 = c[:-1] + bchr((ord(c[-1:]) + 1) % 256)
    191         self.assertRaises(ValueError, nacl.crypto_secretbox_open, c1, nonce,
    192                           self.k)
    193 
    194 
    195 class StreamTestCase(unittest.TestCase):
    196     msg = b"The quick brown fox jumps over the lazy dog."
    197     def setUp(self):
    198         self.k = nacl.randombytes(nacl.crypto_stream_KEYBYTES)
    199 
    200     def test_stream(self):
    201         nonce = nacl.randombytes(nacl.crypto_stream_NONCEBYTES)
    202         c = nacl.crypto_stream(1000, nonce, self.k)
    203         self.assertEqual(len(c), 1000)
    204 
    205     def test_stream_xor(self):
    206         nonce = nacl.randombytes(nacl.crypto_stream_NONCEBYTES)
    207         c = nacl.crypto_stream_xor(self.msg, nonce, self.k)
    208         m = nacl.crypto_stream_xor(c, nonce, self.k)
    209         self.assertEqual(m, self.msg)
    210 
    211 
    212 class AuthTestCaseMixin(object):
    213     msg = b"The quick brown fox jumps over the lazy dog."
    214     def attr(self, a):
    215         return getattr(nacl, 'crypto_{0}{1}'.format(self.name, a))
    216 
    217     def setUp(self):
    218         self.k = nacl.randombytes(self.attr('_KEYBYTES'))
    219         self.auth = self.attr('')
    220         self.verify = self.attr('_verify')
    221 
    222     def test_auth(self):
    223         a = self.auth(self.msg, self.k)
    224         self.assertTrue(self.verify(a, self.msg, self.k))
    225 
    226     def test_badkey(self):
    227         a = self.auth(self.msg, perturb(self.k))
    228         self.assertFalse(self.verify(a, self.msg, self.k))
    229 
    230     def test_badmsg(self):
    231         a = self.auth(self.msg, self.k)
    232         self.assertFalse(self.verify(perturb(a), self.msg, self.k))
    233 
    234 
    235 class AuthTestCase(AuthTestCaseMixin, unittest.TestCase):
    236     name = 'auth'
    237 
    238 
    239 class OneTimeAuthTestCase(AuthTestCaseMixin, unittest.TestCase):
    240     name = 'onetimeauth'
    241 
    242 
    243 if __name__ == '__main__':
    244     unittest.main()