[pycrypto] Test code - Random
Dwayne C. Litzenberger
dlitz at dlitz.net
Fri Nov 7 16:12:15 CST 2008
On Fri, Nov 07, 2008 at 04:06:26PM -0500, Dwayne C. Litzenberger wrote:
> class SimpleTest(unittest.TestCase):
> def runTest(self):
> """Crypto.Random.new()"""
> # Import the OSRNG module and try to use it
> from Crypto import Random
> randobj = Random.new()
> x = randobj.read(16)
> y = randobj.read(16)
> self.assertNotEqual(x, y)
> +class TestNotAlwaysEqual(unittest.TestCase):
> + def runTest(self):
> + from Crypto import Random
> + randobj = Random.new()
> + k = 10
> + DataArray = []
> + x = randobj.read(16)
> + count = 0
> + for i in range(0,k):
> + y = randobj.read(16)
> + if x == y:
> + count += 1
> + self.assertNotEqual(count,k)
I'm not sure what your proposed TestNotAlwaysEqual test offers that
SimpleTest does. Presumably the purpose of this new test is to avoid the
case where a correctly-functioning RNG returns two identical 128-bit
numbers in a row. While that may be possible, I'm really not concerned
about it, since according to my calculations*, the probability that
SimpleTest fails is 2**-128. TestNotAlwaysEqual adds another test that can
fail in the same way, but with a probability of 2**-1280. I don't see why
that would be necessary.
(* Someone please correct me if I'm wrong, since I'm still not very good at
reasoning with probability.)
> +class TestAverage(unittest.TestCase):
> + def runTest(self):
> + from Crypto import Random
> + randobj = Random.new()
> + x = randobj.read(2**15)
> + values = []
> + for i in x:
> + values.append(ord(i))
> + total = 0
> + for i in values:
> + total += i
> + average = total/len(values)
> + print average
> + self.assertEqual(average in range((256/2)-28,(256/2)+28),True)
> +
This looks like the beginning of a statistical test suite, but it seems out
of place here on its own, and I fear that it might cause more confusion
than anything else. Why did you choose the constants 2**15 and +/- 28, for
example? What's the likelihood that this fails under normal circumstances.
I don't want to end up with bug reports and confused users (or worse: users
who learn to ignore test failures) as a result of too many false positives,
for example. Also, I want to avoid adding unnecessary tests to SelfTest,
since SelfTest should be fairly quick to run.
It might be better to implement a full set of statistical tests like the
ones specified in FIPS 140-2. I would consider such a thing for a future
release. If someone were to tackle this, I would suggest adding it as a
module under Crypto.Random or Crypto.Util, and then calling it from
SelfTest. i.e. It should provide a usable, well-documented API, not just
be buried in the SelfTest module.
We definitely could use a more comprehensive set of self-tests, especially
for the random number generators.
Cheers,
- Dwayne
--
Dwayne C. Litzenberger <dlitz at dlitz.net>
Key-signing key - 19E1 1FE8 B3CF F273 ED17 4A24 928C EC13 39C2 5CF7
Annual key (2008) - 4B2A FD82 FC7D 9E38 38D9 179F 1C11 B877 E780 4B45
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 197 bytes
Desc: Digital signature
Url : http://lists.dlitz.net/pipermail/pycrypto/attachments/20081107/cc393bc9/attachment.pgp
More information about the pycrypto
mailing list