summaryrefslogtreecommitdiff
path: root/src/pycryptopp/test/test_rsa.py
blob: 15294bc6c59ccd0e66ebaa8398b3e99635c02a38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/env python

import random

import unittest

global VERBOSE
VERBOSE=False

from pycryptopp.publickey import rsa

from base64 import b32encode
def ab(x): # debuggery
    if len(x) >= 3:
        return "%s:%s" % (len(x), b32encode(x[-3:]),)
    elif len(x) == 2:
        return "%s:%s" % (len(x), b32encode(x[-2:]),)
    elif len(x) == 1:
        return "%s:%s" % (len(x), b32encode(x[-1:]),)
    elif len(x) == 0:
        return "%s:%s" % (len(x), "--empty--",)

def randstr(n):
    return ''.join(map(chr, map(random.randrange, [0]*n, [256]*n)))

KEYSIZE=522 # 522 bits is far too few for actual security -- it is used only for faster unit tests

class Signer(unittest.TestCase):
    def test_generate_bad_size(self):
        try:
            rsa.generate(KEYSIZE-1)
        except rsa.Error, le:
            self.failUnless("size in bits is required to be >=" in str(le), le)
        else:
            self.fail("Should have raised error from size being too small.")
        try:
            rsa.generate(sizeinbits=KEYSIZE-1)
        except rsa.Error, le:
            self.failUnless("size in bits is required to be >=" in str(le), le)
        else:
            self.fail("Should have raised error from size being too small.")

    def test_generate(self):
        rsa.generate(KEYSIZE)
        # Hooray!  It didn't raise an exception!  We win!
        rsa.generate(sizeinbits=KEYSIZE)
        # Hooray!  It didn't raise an exception!  We win!

    def test_sign(self):
        signer = rsa.generate(KEYSIZE)
        result = signer.sign("abc")
        self.failUnlessEqual(len(result), ((KEYSIZE+7)/8))
        # TODO: test against RSAInc. test vectors.

    def test_create_from_string_invalid(self):
        try:
            rsa.create_signing_key_from_string("invalid string")
        except rsa.Error, le:
            self.failUnless("decode error" in str(le), le)
        else:
            self.fail("Should have raised error from invalid string")

        try:
            rsa.create_verifying_key_from_string("invalid string")
        except rsa.Error, le:
            self.failUnless("decode error" in str(le), le)
        else:
            self.fail("Should have raised error from invalid string")

class SignAndVerify(unittest.TestCase):
    def _help_test_sign_and_check(self, signer, verifier, msg):
        sig = signer.sign(msg)
        self.failUnlessEqual(len(sig), ((KEYSIZE+7)/8))
        self.failUnless(verifier.verify(msg, sig))

    def test_sign_and_check_a(self):
        signer = rsa.generate(KEYSIZE)
        verifier = signer.get_verifying_key()
        return self._help_test_sign_and_check(signer, verifier, "a")

    def _help_test_sign_and_check_random(self, signer, verifier):
        for i in range(3):
            l = random.randrange(0, 2**10)
            msg = randstr(l)
            self._help_test_sign_and_check(signer, verifier, msg)

    def test_sign_and_check_random(self):
        signer = rsa.generate(KEYSIZE)
        verifier = signer.get_verifying_key()
        return self._help_test_sign_and_check_random(signer, verifier)

    def _help_test_sign_and_failcheck(self, signer, verifier, msg):
        sig = signer.sign("a")
        sig = sig[:-1] + chr(ord(sig[-1])^0x01)
        self.failUnless(not verifier.verify(msg, sig))

    def test_sign_and_failcheck_a(self):
        signer = rsa.generate(KEYSIZE)
        verifier = signer.get_verifying_key()
        return self._help_test_sign_and_failcheck(signer, verifier, "a")

    def _help_test_sign_and_failcheck_random(self, signer, verifier):
        for i in range(3):
            l = random.randrange(0, 2**10)
            msg = randstr(l)
            self._help_test_sign_and_failcheck(signer, verifier, msg)

    def test_sign_and_failcheck_random(self):
        signer = rsa.generate(KEYSIZE)
        verifier = signer.get_verifying_key()
        return self._help_test_sign_and_failcheck_random(signer, verifier)

    def test_serialize_and_deserialize_verifying_key_and_test(self):
        signer = rsa.generate(KEYSIZE)
        verifier = signer.get_verifying_key()
        serstr = verifier.serialize()
        verifier = None
        newverifier = rsa.create_verifying_key_from_string(serstr)
        self._help_test_sign_and_check(signer, newverifier, "a")
        self._help_test_sign_and_check_random(signer, newverifier)
        self._help_test_sign_and_failcheck(signer, newverifier, "a")
        self._help_test_sign_and_failcheck_random(signer, newverifier)

    def test_serialize_and_deserialize_signing_key_and_test(self):
        signer = rsa.generate(KEYSIZE)
        verifier = signer.get_verifying_key()
        serstr = signer.serialize()
        signer = None
        newsigner = rsa.create_signing_key_from_string(serstr)
        self._help_test_sign_and_check(newsigner, verifier, "a")
        self._help_test_sign_and_check_random(newsigner, verifier)
        self._help_test_sign_and_failcheck(newsigner, verifier, "a")
        self._help_test_sign_and_failcheck_random(newsigner, verifier)


if __name__ == "__main__":
    unittest.main()