sha2test.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #!/usr/bin/env python3
  2. #
  3. # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
  4. # Copyright (C)2013-2019 The MMGen Project <mmgen@tuta.io>
  5. #
  6. # This program is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. """
  19. test/sha2test.py: Test MMGen's SHA256 and SHA512 implementations
  20. """
  21. import sys,os
  22. from binascii import hexlify
  23. from mmgen.sha2 import Sha256,Sha512
  24. from mmgen.util import die
  25. assert len(sys.argv) in (2,3),"Test takes 1 or 2 arguments: test name, plus optional rounds count"
  26. test = sys.argv[1].capitalize()
  27. assert test in ('Sha256','Sha512'), "Valid choices for test are 'sha256' or 'sha512'"
  28. random_rounds = int(sys.argv[2]) if len(sys.argv) == 3 else 500
  29. def msg(s): sys.stderr.write(s)
  30. def green(s): return '\033[32;1m' + s + '\033[0m'
  31. class TestSha2(object):
  32. def test_constants(self):
  33. msg('Testing generated constants: ')
  34. h = self.t_cls(b'foo')
  35. if h.H_init != self.H_ref:
  36. m = 'Generated constants H[] differ from reference value:\nReference:\n{}\nGenerated:\n{}'
  37. die(3,m.format([hex(n) for n in self.H_ref],[hex(n) for n in h.H_init]))
  38. if h.K != self.K_ref:
  39. m = 'Generated constants K[] differ from reference value:\nReference:\n{}\nGenerated:\n{}'
  40. die(3,m.format([hex(n) for n in self.K_ref],[hex(n) for n in h.K]))
  41. msg('OK\n')
  42. def compare_hashes(self,dlen,data):
  43. import hashlib
  44. sha2 = getattr(hashlib,self.desc)(data).hexdigest().encode()
  45. my_sha2 = self.t_cls(data).hexdigest()
  46. if my_sha2 != sha2:
  47. die(3,'Hashes do not match!\nmy_sha2: {}\nsha2: {}\n'.format(my_sha2,sha2))
  48. def test_ref(self,input_n=None):
  49. inputs = (
  50. '','x','xa','the','7_chars''8charmsg' '9_charmsg','10_charmsg'
  51. '8charmsg' * 8,
  52. '8charmsg' * 7 + '7_chars',
  53. '8charmsg' * 7 + '9_charmsg',
  54. '\x00','\x00\x00','\x00'*256,
  55. '\x0f','\x0f\x0f','\x0f'*256,
  56. '\x0f\x0d','\x0e\x0e'*256,
  57. '\x00'*511,'\x00'*512,'\x00'*513,
  58. '\x0f'*512,'\x0f'*511,'\x0f'*513,
  59. '\x00\x0f'*512,'\x0e\x0f'*511,'\x0a\x0d'*513,
  60. '\x00\x0f'*1024,'\x0e\x0f'*1023,'\x0a\x0d'*1025 )
  61. for i,data in enumerate([inputs[input_n]] if input_n is not None else inputs):
  62. msg('\rTesting reference input data: {:4}/{} '.format(i+1,len(inputs)))
  63. self.compare_hashes(len(data),data.encode())
  64. msg('OK\n')
  65. def test_random(self,rounds):
  66. for i in range(rounds):
  67. if i+1 in (1,rounds) or not (i+1) % 10:
  68. msg('\rTesting random input data: {:4}/{} '.format(i+1,rounds))
  69. dlen = int(hexlify(os.urandom(4)),16) >> 18
  70. self.compare_hashes(dlen,os.urandom(dlen))
  71. msg('OK\n')
  72. class TestSha512(TestSha2):
  73. desc = 'sha512'
  74. t_cls = Sha512
  75. H_ref = (
  76. 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
  77. 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179 )
  78. K_ref = (
  79. 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538,
  80. 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe,
  81. 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
  82. 0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
  83. 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab,
  84. 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
  85. 0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed,
  86. 0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
  87. 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
  88. 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
  89. 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373,
  90. 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
  91. 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c,
  92. 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6,
  93. 0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
  94. 0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 )
  95. class TestSha256(TestSha2):
  96. desc = 'sha256'
  97. t_cls = Sha256
  98. H_ref = (
  99. 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 )
  100. K_ref = (
  101. 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
  102. 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
  103. 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
  104. 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
  105. 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
  106. 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
  107. 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
  108. 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 )
  109. msg(green('Testing MMGen implementation of {}\n'.format(test)))
  110. t = globals()['Test'+test]()
  111. t.test_constants()
  112. t.test_ref()
  113. t.test_random(random_rounds)