1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
| // SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.10;
library MD5 {
function T() internal pure returns (uint32[64] memory t) { t[0] = 0xd76aa478; t[1] = 0xe8c7b756; t[2] = 0x242070db; t[3] = 0xc1bdceee; t[4] = 0xf57c0faf; t[5] = 0x4787c62a; t[6] = 0xa8304613; t[7] = 0xfd469501; t[8] = 0x698098d8; t[9] = 0x8b44f7af; t[10] = 0xffff5bb1; t[11] = 0x895cd7be; t[12] = 0x6b901122; t[13] = 0xfd987193; t[14] = 0xa679438e; t[15] = 0x49b40821; t[16] = 0xf61e2562; t[17] = 0xc040b340; t[18] = 0x265e5a51; t[19] = 0xe9b6c7aa; t[20] = 0xd62f105d; t[21] = 0x02441453; t[22] = 0xd8a1e681; t[23] = 0xe7d3fbc8; t[24] = 0x21e1cde6; t[25] = 0xc33707d6; t[26] = 0xf4d50d87; t[27] = 0x455a14ed; t[28] = 0xa9e3e905; t[29] = 0xfcefa3f8; t[30] = 0x676f02d9; t[31] = 0x8d2a4c8a; t[32] = 0xfffa3942; t[33] = 0x8771f681; t[34] = 0x6d9d6122; t[35] = 0xfde5380c; t[36] = 0xa4beea44; t[37] = 0x4bdecfa9; t[38] = 0xf6bb4b60; t[39] = 0xbebfbc70; t[40] = 0x289b7ec6; t[41] = 0xeaa127fa; t[42] = 0xd4ef3085; t[43] = 0x04881d05; t[44] = 0xd9d4d039; t[45] = 0xe6db99e5; t[46] = 0x1fa27cf8; t[47] = 0xc4ac5665; t[48] = 0xf4292244; t[49] = 0x432aff97; t[50] = 0xab9423a7; t[51] = 0xfc93a039; t[52] = 0x655b59c3; t[53] = 0x8f0ccc92; t[54] = 0xffeff47d; t[55] = 0x85845dd1; t[56] = 0x6fa87e4f; t[57] = 0xfe2ce6e0; t[58] = 0xa3014314; t[59] = 0x4e0811a1; t[60] = 0xf7537e82; t[61] = 0xbd3af235; t[62] = 0x2ad7d2bb; t[63] = 0xeb86d391; }
function rotl(uint32 x, uint8 n) private pure returns (uint32) { unchecked { return (x << n) | (x >> (32 - n)); } }
function hash(string memory input) internal pure returns (bytes16) { bytes memory data = bytes(input); uint256 len = data.length;
bytes memory block64 = new bytes(64);
for (uint256 i = 0; i < len; i++) { block64[i] = data[i]; } block64[len] = 0x80; uint64 bitLen = uint64(len) * 8; unchecked { block64[56] = bytes1(uint8(bitLen)); block64[57] = bytes1(uint8(bitLen >> 8)); block64[58] = bytes1(uint8(bitLen >> 16)); block64[59] = bytes1(uint8(bitLen >> 24)); }
uint32[16] memory M; unchecked { for (uint256 i = 0; i < 16; i++) { uint256 off = i * 4; M[i] = uint32(uint8(block64[off])) | (uint32(uint8(block64[off + 1])) << 8) | (uint32(uint8(block64[off + 2])) << 16) | (uint32(uint8(block64[off + 3])) << 24); } }
uint32 a = 0x67452301; uint32 b = 0xefcdab89; uint32 c = 0x98badcfe; uint32 d = 0x10325476;
uint32[64] memory t = T();
// Round 1: F(x,y,z) = (x&y) | (~x&z) unchecked { a = b + rotl(a + ((b & c) | (~b & d)) + M[0] + t[0], 7); d = a + rotl(d + ((a & b) | (~a & c)) + M[1] + t[1], 12); c = d + rotl(c + ((d & a) | (~d & b)) + M[2] + t[2], 17); b = c + rotl(b + ((c & d) | (~c & a)) + M[3] + t[3], 22); a = b + rotl(a + ((b & c) | (~b & d)) + M[4] + t[4], 7); d = a + rotl(d + ((a & b) | (~a & c)) + M[5] + t[5], 12); c = d + rotl(c + ((d & a) | (~d & b)) + M[6] + t[6], 17); b = c + rotl(b + ((c & d) | (~c & a)) + M[7] + t[7], 22); a = b + rotl(a + ((b & c) | (~b & d)) + M[8] + t[8], 7); d = a + rotl(d + ((a & b) | (~a & c)) + M[9] + t[9], 12); c = d + rotl(c + ((d & a) | (~d & b)) + M[10] + t[10], 17); b = c + rotl(b + ((c & d) | (~c & a)) + M[11] + t[11], 22); a = b + rotl(a + ((b & c) | (~b & d)) + M[12] + t[12], 7); d = a + rotl(d + ((a & b) | (~a & c)) + M[13] + t[13], 12); c = d + rotl(c + ((d & a) | (~d & b)) + M[14] + t[14], 17); b = c + rotl(b + ((c & d) | (~c & a)) + M[15] + t[15], 22); }
// Round 2: G(x,y,z) = (x&z) | (y&~z) unchecked { a = b + rotl(a + ((b & d) | (c & ~d)) + M[1] + t[16], 5); d = a + rotl(d + ((a & c) | (b & ~c)) + M[6] + t[17], 9); c = d + rotl(c + ((d & b) | (a & ~b)) + M[11] + t[18], 14); b = c + rotl(b + ((c & a) | (d & ~a)) + M[0] + t[19], 20); a = b + rotl(a + ((b & d) | (c & ~d)) + M[5] + t[20], 5); d = a + rotl(d + ((a & c) | (b & ~c)) + M[10] + t[21], 9); c = d + rotl(c + ((d & b) | (a & ~b)) + M[15] + t[22], 14); b = c + rotl(b + ((c & a) | (d & ~a)) + M[4] + t[23], 20); a = b + rotl(a + ((b & d) | (c & ~d)) + M[9] + t[24], 5); d = a + rotl(d + ((a & c) | (b & ~c)) + M[14] + t[25], 9); c = d + rotl(c + ((d & b) | (a & ~b)) + M[3] + t[26], 14); b = c + rotl(b + ((c & a) | (d & ~a)) + M[8] + t[27], 20); a = b + rotl(a + ((b & d) | (c & ~d)) + M[13] + t[28], 5); d = a + rotl(d + ((a & c) | (b & ~c)) + M[2] + t[29], 9); c = d + rotl(c + ((d & b) | (a & ~b)) + M[7] + t[30], 14); b = c + rotl(b + ((c & a) | (d & ~a)) + M[12] + t[31], 20); }
// Round 3: H(x,y,z) = x ^ y ^ z unchecked { a = b + rotl(a + (b ^ c ^ d) + M[5] + t[32], 4); d = a + rotl(d + (a ^ b ^ c) + M[8] + t[33], 11); c = d + rotl(c + (d ^ a ^ b) + M[11] + t[34], 16); b = c + rotl(b + (c ^ d ^ a) + M[14] + t[35], 23); a = b + rotl(a + (b ^ c ^ d) + M[1] + t[36], 4); d = a + rotl(d + (a ^ b ^ c) + M[4] + t[37], 11); c = d + rotl(c + (d ^ a ^ b) + M[7] + t[38], 16); b = c + rotl(b + (c ^ d ^ a) + M[10] + t[39], 23); a = b + rotl(a + (b ^ c ^ d) + M[13] + t[40], 4); d = a + rotl(d + (a ^ b ^ c) + M[0] + t[41], 11); c = d + rotl(c + (d ^ a ^ b) + M[3] + t[42], 16); b = c + rotl(b + (c ^ d ^ a) + M[6] + t[43], 23); a = b + rotl(a + (b ^ c ^ d) + M[9] + t[44], 4); d = a + rotl(d + (a ^ b ^ c) + M[12] + t[45], 11); c = d + rotl(c + (d ^ a ^ b) + M[15] + t[46], 16); b = c + rotl(b + (c ^ d ^ a) + M[2] + t[47], 23); }
// Round 4: I(x,y,z) = y ^ (x | ~z) unchecked { a = b + rotl(a + (c ^ (b | ~d)) + M[0] + t[48], 6); d = a + rotl(d + (b ^ (a | ~c)) + M[7] + t[49], 10); c = d + rotl(c + (a ^ (d | ~b)) + M[14] + t[50], 15); b = c + rotl(b + (d ^ (c | ~a)) + M[5] + t[51], 21); a = b + rotl(a + (c ^ (b | ~d)) + M[12] + t[52], 6); d = a + rotl(d + (b ^ (a | ~c)) + M[3] + t[53], 10); c = d + rotl(c + (a ^ (d | ~b)) + M[10] + t[54], 15); b = c + rotl(b + (d ^ (c | ~a)) + M[1] + t[55], 21); a = b + rotl(a + (c ^ (b | ~d)) + M[8] + t[56], 6); d = a + rotl(d + (b ^ (a | ~c)) + M[15] + t[57], 10); c = d + rotl(c + (a ^ (d | ~b)) + M[6] + t[58], 15); b = c + rotl(b + (d ^ (c | ~a)) + M[13] + t[59], 21); a = b + rotl(a + (c ^ (b | ~d)) + M[4] + t[60], 6); d = a + rotl(d + (b ^ (a | ~c)) + M[11] + t[61], 10); c = d + rotl(c + (a ^ (d | ~b)) + M[2] + t[62], 15); b = c + rotl(b + (d ^ (c | ~a)) + M[9] + t[63], 21); }
unchecked { a += 0x67452301; b += 0xefcdab89; c += 0x98badcfe; d += 0x10325476; }
unchecked { uint32 ra = (a >> 24) | ((a >> 8) & 0x0000FF00) | ((a << 8) & 0x00FF0000) | (a << 24); uint32 rb = (b >> 24) | ((b >> 8) & 0x0000FF00) | ((b << 8) & 0x00FF0000) | (b << 24); uint32 rc = (c >> 24) | ((c >> 8) & 0x0000FF00) | ((c << 8) & 0x00FF0000) | (c << 24); uint32 rd = (d >> 24) | ((d >> 8) & 0x0000FF00) | ((d << 8) & 0x00FF0000) | (d << 24); return bytes16( (bytes32(uint256(ra)) << 224) | (bytes32(uint256(rb)) << 192) | (bytes32(uint256(rc)) << 160) | (bytes32(uint256(rd)) << 128) ); } } }
|