| 1 | ### -*-python-*- |
| 2 | ### |
| 3 | ### Cryptographic primitives |
| 4 | ### |
| 5 | ### (c) 2013 Mark Wooding |
| 6 | ### |
| 7 | |
| 8 | ###----- Licensing notice --------------------------------------------------- |
| 9 | ### |
| 10 | ### This file is part of Chopwood: a password-changing service. |
| 11 | ### |
| 12 | ### Chopwood is free software; you can redistribute it and/or modify |
| 13 | ### it under the terms of the GNU Affero General Public License as |
| 14 | ### published by the Free Software Foundation; either version 3 of the |
| 15 | ### License, or (at your option) any later version. |
| 16 | ### |
| 17 | ### Chopwood is distributed in the hope that it will be useful, |
| 18 | ### but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 19 | ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 20 | ### GNU Affero General Public License for more details. |
| 21 | ### |
| 22 | ### You should have received a copy of the GNU Affero General Public |
| 23 | ### License along with Chopwood; if not, see |
| 24 | ### <http://www.gnu.org/licenses/>. |
| 25 | |
| 26 | from struct import pack, unpack |
| 27 | |
| 28 | ###-------------------------------------------------------------------------- |
| 29 | ### The core of MD5. |
| 30 | |
| 31 | def U32(x): return x&0xffffffff |
| 32 | def FF(x, y, z): return (x&y) | (~x&z) |
| 33 | def GG(x, y, z): return (z&x) | (~z&y) |
| 34 | def HH(x, y, z): return x^y^z |
| 35 | def II(x, y, z): return y^(x|~z) |
| 36 | def rot(x, n): return U32((x << n) | (x >> 32 - n)) |
| 37 | MD5_INIT = '0123456789abcdeffedcba9876543210'.decode('hex') |
| 38 | def compress_md5(buf, st = MD5_INIT): |
| 39 | """ |
| 40 | The MD5 compression function, in pure Python. |
| 41 | |
| 42 | This is about as small as I could make it. Apply the MD5 compression |
| 43 | function to BUF, using the initial state ST (defaults to the standard |
| 44 | initialization vector); return the new state as the function value. |
| 45 | """ |
| 46 | a, b, c, d = unpack('<4L', st) |
| 47 | aa, bb, cc, dd = a, b, c, d |
| 48 | x = xx = unpack('<16L', buf) |
| 49 | for f, i, r, k in [(FF, 0, 7, 0xd76aa478), (FF, 1, 12, 0xe8c7b756), |
| 50 | (FF, 2, 17, 0x242070db), (FF, 3, 22, 0xc1bdceee), |
| 51 | (FF, 4, 7, 0xf57c0faf), (FF, 5, 12, 0x4787c62a), |
| 52 | (FF, 6, 17, 0xa8304613), (FF, 7, 22, 0xfd469501), |
| 53 | (FF, 8, 7, 0x698098d8), (FF, 9, 12, 0x8b44f7af), |
| 54 | (FF, 10, 17, 0xffff5bb1), (FF, 11, 22, 0x895cd7be), |
| 55 | (FF, 12, 7, 0x6b901122), (FF, 13, 12, 0xfd987193), |
| 56 | (FF, 14, 17, 0xa679438e), (FF, 15, 22, 0x49b40821), |
| 57 | (GG, 1, 5, 0xf61e2562), (GG, 6, 9, 0xc040b340), |
| 58 | (GG, 11, 14, 0x265e5a51), (GG, 0, 20, 0xe9b6c7aa), |
| 59 | (GG, 5, 5, 0xd62f105d), (GG, 10, 9, 0x02441453), |
| 60 | (GG, 15, 14, 0xd8a1e681), (GG, 4, 20, 0xe7d3fbc8), |
| 61 | (GG, 9, 5, 0x21e1cde6), (GG, 14, 9, 0xc33707d6), |
| 62 | (GG, 3, 14, 0xf4d50d87), (GG, 8, 20, 0x455a14ed), |
| 63 | (GG, 13, 5, 0xa9e3e905), (GG, 2, 9, 0xfcefa3f8), |
| 64 | (GG, 7, 14, 0x676f02d9), (GG, 12, 20, 0x8d2a4c8a), |
| 65 | (HH, 5, 4, 0xfffa3942), (HH, 8, 11, 0x8771f681), |
| 66 | (HH, 11, 16, 0x6d9d6122), (HH, 14, 23, 0xfde5380c), |
| 67 | (HH, 1, 4, 0xa4beea44), (HH, 4, 11, 0x4bdecfa9), |
| 68 | (HH, 7, 16, 0xf6bb4b60), (HH, 10, 23, 0xbebfbc70), |
| 69 | (HH, 13, 4, 0x289b7ec6), (HH, 0, 11, 0xeaa127fa), |
| 70 | (HH, 3, 16, 0xd4ef3085), (HH, 6, 23, 0x04881d05), |
| 71 | (HH, 9, 4, 0xd9d4d039), (HH, 12, 11, 0xe6db99e5), |
| 72 | (HH, 15, 16, 0x1fa27cf8), (HH, 2, 23, 0xc4ac5665), |
| 73 | (II, 0, 6, 0xf4292244), (II, 7, 10, 0x432aff97), |
| 74 | (II, 14, 15, 0xab9423a7), (II, 5, 21, 0xfc93a039), |
| 75 | (II, 12, 6, 0x655b59c3), (II, 3, 10, 0x8f0ccc92), |
| 76 | (II, 10, 15, 0xffeff47d), (II, 1, 21, 0x85845dd1), |
| 77 | (II, 8, 6, 0x6fa87e4f), (II, 15, 10, 0xfe2ce6e0), |
| 78 | (II, 6, 15, 0xa3014314), (II, 13, 21, 0x4e0811a1), |
| 79 | (II, 4, 6, 0xf7537e82), (II, 11, 10, 0xbd3af235), |
| 80 | (II, 2, 15, 0x2ad7d2bb), (II, 9, 21, 0xeb86d391)]: |
| 81 | b, c, d, a = U32(rot(U32(a + f(b, c, d) + x[i] + k), r) + b), b, c, d |
| 82 | return pack('<4L', U32(a + aa), U32(b + bb), U32(c + cc), U32(d + dd)) |
| 83 | |
| 84 | ###----- That's all, folks -------------------------------------------------- |