You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_rng.py 3.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. ###############################################################################
  2. #
  3. # The MIT License (MIT)
  4. #
  5. # Copyright (c) Crossbar.io Technologies GmbH
  6. #
  7. # Permission is hereby granted, free of charge, to any person obtaining a copy
  8. # of this software and associated documentation files (the "Software"), to deal
  9. # in the Software without restriction, including without limitation the rights
  10. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. # copies of the Software, and to permit persons to whom the Software is
  12. # furnished to do so, subject to the following conditions:
  13. #
  14. # The above copyright notice and this permission notice shall be included in
  15. # all copies or substantial portions of the Software.
  16. #
  17. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. # THE SOFTWARE.
  24. #
  25. ###############################################################################
  26. from __future__ import absolute_import
  27. import sys
  28. import unittest
  29. import uuid
  30. import random
  31. from nacl import utils, public
  32. from autobahn import util
  33. @unittest.skipIf(not sys.platform.startswith('linux'), 'entropy depletion tests only available on Linux')
  34. class TestEntropy(unittest.TestCase):
  35. def test_non_depleting(self):
  36. res = {}
  37. with open('/dev/urandom', 'rb') as rng:
  38. for i in range(1000):
  39. for j in range(100):
  40. # "reseed" (seems pointless, but ..)
  41. random.seed()
  42. # random UUIDs
  43. v1 = uuid.uuid4() # noqa
  44. # stdlib random
  45. v2 = random.random() # noqa
  46. v3 = random.getrandbits(32) # noqa
  47. v4 = random.randint(0, 9007199254740992) # noqa
  48. v5 = random.normalvariate(10, 100) # noqa
  49. v6 = random.choice(range(100)) # noqa
  50. # PyNaCl
  51. v7 = utils.random(public.Box.NONCE_SIZE) # noqa
  52. # Autobahn utils
  53. v8 = util.generate_token(4, 4) # noqa
  54. v9 = util.id() # noqa
  55. v10 = util.rid() # noqa
  56. v11 = util.newid() # noqa
  57. # direct procfs access to PRNG
  58. d = rng.read(1000) # noqa
  59. # check available entropy
  60. with open('/proc/sys/kernel/random/entropy_avail', 'r') as ent:
  61. ea = int(ent.read()) // 100
  62. if ea not in res:
  63. res[ea] = 0
  64. res[ea] += 1
  65. skeys = sorted(res.keys())
  66. print('\nsystem entropy depletion stats:')
  67. for k in skeys:
  68. print('{}: {}'.format(k, res[k]))
  69. self.assertTrue(skeys[0] > 10)
  70. def test_depleting(self):
  71. res = {}
  72. with open('/dev/random', 'rb') as rng:
  73. for i in range(10000):
  74. # direct procfs access to "real" RNG
  75. d = rng.read(1000) # noqa
  76. # check available entropy
  77. with open('/proc/sys/kernel/random/entropy_avail', 'r') as ent:
  78. ea = int(ent.read()) // 100
  79. if ea not in res:
  80. res[ea] = 0
  81. res[ea] += 1
  82. skeys = sorted(res.keys())
  83. print('\nsystem entropy depletion stats:')
  84. for k in skeys:
  85. print('{}: {}'.format(k, res[k]))
  86. self.assertTrue(skeys[0] == 0)