| 1 | // Copyright ©2025 blackshirt. |
| 2 | // Use of this source code is governed by an MIT license |
| 3 | // that can be found in the LICENSE file. |
| 4 | // |
| 5 | module ascon |
| 6 | |
| 7 | import arrays |
| 8 | import encoding.hex |
| 9 | |
| 10 | struct HashTest { |
| 11 | count int |
| 12 | msg string |
| 13 | md string |
| 14 | } |
| 15 | |
| 16 | // This test material mostly taken and adapted from Known-Answer-Test (KAT) of reference implementation. |
| 17 | // See at https://github.com/ascon/ascon-c/blob/main/crypto_hash/asconhash256/LWC_HASH_KAT_128_256.txt |
| 18 | fn test_hash256_sum_chunked() ! { |
| 19 | item := HashTest{ |
| 20 | count: 500 |
| 21 | msg: '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2' |
| 22 | md: '8174F5E8DFC9441DBB7A183D56F431B1AEF9513E747A3878BB806BAE27655E3E' |
| 23 | } |
| 24 | msg := hex.decode(item.msg)! |
| 25 | md := hex.decode(item.md)! |
| 26 | // One shoot sum256 function |
| 27 | md0 := sum256(msg) |
| 28 | assert md0 == md |
| 29 | |
| 30 | // Digest based |
| 31 | mut h := new_hash256() |
| 32 | expected_md := h.sum(msg) |
| 33 | assert expected_md == md |
| 34 | |
| 35 | // with multistep |
| 36 | h.reset() |
| 37 | _ := h.Digest.absorb(msg) |
| 38 | h.Digest.finish() |
| 39 | mut dst := []u8{len: hash256_size} |
| 40 | h.Digest.squeeze(mut dst) |
| 41 | assert dst == md |
| 42 | |
| 43 | // with splitted message |
| 44 | msg0 := msg[0..200] |
| 45 | msg1 := msg[200..400] |
| 46 | msg2 := msg[400..] |
| 47 | h.reset() |
| 48 | _ := h.Digest.absorb(msg0) |
| 49 | _ := h.Digest.absorb(msg1) |
| 50 | _ := h.Digest.absorb(msg2) |
| 51 | h.Digest.finish() |
| 52 | h.Digest.squeeze(mut dst) |
| 53 | assert dst == md |
| 54 | |
| 55 | // with arrays chunk |
| 56 | h.reset() |
| 57 | chunks := arrays.chunk[u8](msg, 200) |
| 58 | mut n := 0 |
| 59 | for chunk in chunks { |
| 60 | n += h.Digest.absorb(chunk) |
| 61 | } |
| 62 | assert n == msg.len |
| 63 | h.Digest.finish() |
| 64 | h.Digest.squeeze(mut dst) |
| 65 | assert dst == md |
| 66 | |
| 67 | // with sum |
| 68 | h.reset() |
| 69 | for chunk in chunks { |
| 70 | n += h.write(chunk)! |
| 71 | } |
| 72 | chunked_md := h.sum([]u8{}) |
| 73 | assert chunked_md == md |
| 74 | } |
| 75 | |
| 76 | fn test_hash256_sum_kat() ! { |
| 77 | for item in ascon_hash256_test_data { |
| 78 | msg := hex.decode(item.msg)! |
| 79 | md := hex.decode(item.md)! |
| 80 | out := sum256(msg) |
| 81 | assert out == md |
| 82 | |
| 83 | // work with Digest opaque |
| 84 | mut h := new_hash256() |
| 85 | exp_md := h.sum(msg) |
| 86 | assert exp_md == md |
| 87 | |
| 88 | // Lets work in streaming-way |
| 89 | chunks := arrays.chunk[u8](msg, 7) |
| 90 | h.reset() |
| 91 | mut tot := 0 |
| 92 | for chunk in chunks { |
| 93 | n := h.write(chunk)! |
| 94 | tot += n |
| 95 | } |
| 96 | assert msg.len == tot |
| 97 | |
| 98 | chunked_md := h.sum([]u8{}) |
| 99 | assert chunked_md == md |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | const ascon_hash256_test_data = [ |
| 104 | HashTest{ |
| 105 | count: 1 |
| 106 | msg: '' |
| 107 | md: '0b3be5850f2f6b98caf29f8fdea89b64a1fa70aa249b8f839bd53baa304d92b2' |
| 108 | }, |
| 109 | HashTest{ |
| 110 | count: 2 |
| 111 | msg: '00' |
| 112 | md: '0728621035af3ed2bca03bf6fde900f9456f5330e4b5ee23e7f6a1e70291bc80' |
| 113 | }, |
| 114 | HashTest{ |
| 115 | count: 3 |
| 116 | msg: '0001' |
| 117 | md: '6115e7c9c4081c2797fc8fe1bc57a836afa1c5381e556dd583860ca2dfb48dd2' |
| 118 | }, |
| 119 | HashTest{ |
| 120 | count: 4 |
| 121 | msg: '000102' |
| 122 | md: '265ab89a609f5a05dca57e83fbba700f9a2d2c4211ba4cc9f0a1a369e17b915c' |
| 123 | }, |
| 124 | HashTest{ |
| 125 | count: 5 |
| 126 | msg: '00010203' |
| 127 | md: 'd7e4c7ed9b8a325cd08b9ef259f8877054ecd8304fe1b2d7fd847137df6727ee' |
| 128 | }, |
| 129 | HashTest{ |
| 130 | count: 6 |
| 131 | msg: '0001020304' |
| 132 | md: 'c7b28962d4f5c2211f466f83d3c57ae1504387e2a326949747a8376447a6bb51' |
| 133 | }, |
| 134 | HashTest{ |
| 135 | count: 7 |
| 136 | msg: '000102030405' |
| 137 | md: 'dc0c6748af8ffe63e1084aa3e5786a194685c88c21348b29e184fb50409703bc' |
| 138 | }, |
| 139 | HashTest{ |
| 140 | count: 8 |
| 141 | msg: '00010203040506' |
| 142 | md: '3e4d273ba69b3b9c53216107e88b75cdbeedbcbf8faf0219c3928ab62b116577' |
| 143 | }, |
| 144 | HashTest{ |
| 145 | count: 9 |
| 146 | msg: '0001020304050607' |
| 147 | md: 'b88e497ae8e6fb641b87ef622eb8f2fca0ed95383f7ffebe167acf1099ba764f' |
| 148 | }, |
| 149 | HashTest{ |
| 150 | count: 10 |
| 151 | msg: '000102030405060708' |
| 152 | md: '94269C30E0296E1EC86655041841823EFA1927F520FD58C8E9BCE6197878C1A6' |
| 153 | }, |
| 154 | HashTest{ |
| 155 | count: 500 |
| 156 | msg: '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2' |
| 157 | md: '8174F5E8DFC9441DBB7A183D56F431B1AEF9513E747A3878BB806BAE27655E3E' |
| 158 | }, |
| 159 | HashTest{ |
| 160 | count: 501 |
| 161 | msg: '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3' |
| 162 | md: 'E73D4DDB9D248BF2C0F8D49892D7455A4C3053153DE7F79BA4487C7D823F605C' |
| 163 | }, |
| 164 | HashTest{ |
| 165 | count: 502 |
| 166 | msg: '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4' |
| 167 | md: 'B73FA04079263F6A733B67466552784B436138F41F80B72C4D5D03934B72207D' |
| 168 | }, |
| 169 | ] |
| 170 | |