chiark / gitweb /
cmd-cgi.py: Don't allow caching of the `list' page.
[chopwood] / crypto.py
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 --------------------------------------------------