1import unittest 2from util import * 3from ctypes import create_string_buffer 4 5# NIST cases from http://www.di-mgt.com.au/sha_testvectors.html 6# SHA-256d vectors from https://www.dlitz.net/crypto/shad256-test-vectors/SHAd256_Test_Vectors.txt 7sha2_cases = { 8 'abc': 9 ['ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad', 10 'ddaf35a193617aba cc417349ae204131 12e6fa4e89a97ea2 0a9eeee64b55d39a' 11 '2192992a274fc1a8 36ba3c23a3feebbd 454d4423643ce80e 2a9ac94fa54ca49f', 12 '4f8b42c22dd3729b519ba6f68d2da7cc5b2d606d05daed5ad5128cc03e6c6358'], 13 14 '': 15 ['e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855', 16 'cf83e1357eefb8bd f1542850d66d8007 d620e4050b5715dc 83f4a921d36ce9ce' 17 '47d0d13c5d85f2b0 ff8318d2877eec2f 63b931bd47417a81 a538327af927da3e', 18 '5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456' ], 19 20 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq': 21 ['248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1', 22 '204a8fc6dda82f0a 0ced7beb8e08a416 57c16ef468b228a8 279be331a703c335' 23 '96fd15c13b1b07f9 aa1d3bea57789ca0 31ad85c7a71dd703 54ec631238ca3445', 24 '0cffe17f68954dac3a84fb1458bd5ec99209449749b2b308b7cb55812f9563af'], 25 26 'abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn' 27 'hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu': 28 ['cf5b16a7 78af8380 036ce59e 7b049237 0b249b11 e8f07a51 afac4503 7afee9d1', 29 '8e959b75dae313da 8cf4f72814fc143f 8f7779c6eb9f7fa1 7299aeadb6889018' 30 '501d289e4900f7e4 331b99dec4b5433a c7d329eeb6dd2654 5e96e55b874be909', 31 None], 32 33 'a' * 1000000: 34 ['cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0', 35 'e718483d0ce76964 4e2e42c7bc15b463 8e1f98b13b204428 5632a803afa973eb' 36 'de0ff244877ea60a 4cb0432ce577c31b eb009c5c2c49aa2e 4eadb217ad8cc09b', 37 '80d1189477563e1b5206b2749f1afe4807e5705e8bd77887a60187a712156688'], 38} 39 40hash160_cases = [ 41 # https://en.bitcoin.it/wiki/Technical_background_of_Bitcoin_addresses 42 [ '0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B235' 43 '22CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6', 44 '010966776006953D5567439E5E39F86A0D273BEE' ], 45 # Randomly generated cases from https://gobittest.appspot.com/Address 46 [ '045B3B9D153DDB9A9630C7C4F00A56212A3FCAD062E8014C3E95BF9DDBD651B37' 47 'FFC78E532BC15096F1BAF889B503228324485CCF02BA954F431D4B5BAE731070D', 48 '5CE3425A868F365E06272EA5472D344CC8D14E56' ], 49 [ '048DED2821E449EA2AD863A35972A97120074EF6A73C0D5DF97BF20538EF173EC' 50 '33E75210F7B5977BDD2939850B3EA3791049C83DF4F66296F935FDF38BD80C2AC', 51 'AFF2B47861A205E3AB67B2042C3F44F1C9283868' ], 52 [ '042125CC51DD979091CBA34E71A4B419708267566E72F68EB5891F70E90774A34' 53 '171C1C95F54DE84BC11CBC0E6BD4792D5C17C5C3A26F99A9D136AADB66463AD58', 54 '53190BD5877616554E72253D4CDD2D37E1AA0D73' ], 55] 56 57class HashTests(unittest.TestCase): 58 59 SHA256_LEN, SHA512_LEN, HASH160_LEN = 32, 64, 20 60 61 def make_outbuf(self, fn, aligned=True): 62 buf_len = self.SHA256_LEN 63 if fn == wally_sha512: 64 buf_len = self.SHA512_LEN 65 elif fn == wally_hash160: 66 buf_len = self.HASH160_LEN 67 offset = 0 if aligned else 1 68 buf = create_string_buffer(buf_len + offset) 69 return byref(buf, offset), buf_len 70 71 72 def do_hash(self, fn, hex_in, aligned=True): 73 buf, buf_len = self.make_outbuf(fn, aligned) 74 in_bytes, in_bytes_len = make_cbuffer(hex_in) 75 ret = fn(in_bytes, in_bytes_len, buf, buf_len) 76 self.assertEqual(ret, WALLY_OK) 77 ret, result = wally_hex_from_bytes(buf, buf_len) 78 self.assertEqual(ret, WALLY_OK) 79 return utf8(result) 80 81 82 def _do_test_sha_vectors(self): 83 for in_msg, values in sha2_cases.items(): 84 msg = h(utf8(in_msg)) 85 for i, fn in enumerate([wally_sha256, wally_sha512, wally_sha256d]): 86 if values[i] is not None: 87 for aligned in [True, False]: 88 result = self.do_hash(fn, msg, aligned) 89 expected = utf8(values[i].replace(' ', '')) 90 self.assertEqual(result, expected) 91 92 93 def test_sha_vectors(self): 94 self. _do_test_sha_vectors() 95 wally_init(0) # Enable optimized SHA256 and re-test 96 self. _do_test_sha_vectors() 97 98 99 def test_hash160_vectors(self): 100 for msg, expected in hash160_cases: 101 for aligned in [True, False]: 102 result = self.do_hash(wally_hash160, utf8(msg), aligned) 103 self.assertEqual(result, utf8(expected.lower())) 104 105 106 def test_invalid_args(self): 107 in_bytes, in_bytes_len = make_cbuffer(h(utf8('abc'))) 108 for fn in [wally_sha256, wally_sha512, wally_sha256d, wally_hash160]: 109 buf, buf_len = self.make_outbuf(fn) 110 for args in [(None, in_bytes_len, buf, buf_len), 111 (in_bytes, in_bytes_len, None, buf_len), 112 (in_bytes, in_bytes_len, buf, buf_len + 1)]: 113 self.assertEqual(fn(args[0], args[1], args[2], args[3]), 114 WALLY_EINVAL) 115 116 117if __name__ == '__main__': 118 unittest.main() 119