1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// The original source code is from:
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// http://src.chromium.org/viewvc/chrome/trunk/src/base/md5.cc?revision=94203
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// The original file was copied from sqlite, and was in the public domain.
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/*
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * This code implements the MD5 message-digest algorithm.
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * The algorithm is due to Ron Rivest.  This code was
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * written by Colin Plumb in 1993, no copyright is claimed.
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * This code is in the public domain; do with it what you wish.
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) *
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * Equivalent code is available from RSA Data Security, Inc.
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * This code has been tested against that, and is equivalent,
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * except that you don't need to include two pages of legalese
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * with every copy.
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) *
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * To compute the message digest of a chunk of bytes, declare an
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * MD5Context structure, pass it to MD5Init, call MD5Update as
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * needed on buffers full of bytes, and then call MD5Final, which
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * will fill a supplied 16-byte array with the digest.
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) */
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "md5.h"
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <libaddressinput/util/basictypes.h>
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <string>
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace {
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)struct Context {
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  uint32 buf[4];
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  uint32 bits[2];
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  unsigned char in[64];
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)};
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/*
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * Note: this code is harmless on little-endian machines.
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) */
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void byteReverse(unsigned char *buf, unsigned longs) {
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        uint32 t;
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        do {
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            ((unsigned)buf[1]<<8 | buf[0]);
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                *(uint32 *)buf = t;
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                buf += 4;
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        } while (--longs);
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/* The four core functions - F1 is optimized somewhat */
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/* #define F1(x, y, z) (x & y | ~x & z) */
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define F1(x, y, z) (z ^ (x & (y ^ z)))
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define F2(x, y, z) F1(z, x, y)
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define F3(x, y, z) (x ^ y ^ z)
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define F4(x, y, z) (y ^ (x | ~z))
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/* This is the central step in the MD5 algorithm. */
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define MD5STEP(f, w, x, y, z, data, s) \
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/*
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * The core of the MD5 algorithm, this alters an existing MD5 hash to
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * reflect the addition of 16 longwords of new data.  MD5Update blocks
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * the data and converts bytes into longwords for this routine.
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) */
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MD5Transform(uint32 buf[4], const uint32 in[16]) {
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        register uint32 a, b, c, d;
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        a = buf[0];
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        b = buf[1];
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        c = buf[2];
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        d = buf[3];
78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        buf[0] += a;
148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        buf[1] += b;
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        buf[2] += c;
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        buf[3] += d;
151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace i18n {
156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace addressinput {
157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/*
159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * initialization constants.
161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) */
162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MD5Init(MD5Context* context) {
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        struct Context *ctx = (struct Context *)context;
164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ctx->buf[0] = 0x67452301;
165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ctx->buf[1] = 0xefcdab89;
166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ctx->buf[2] = 0x98badcfe;
167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ctx->buf[3] = 0x10325476;
168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ctx->bits[0] = 0;
169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ctx->bits[1] = 0;
170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/*
173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * Update context to reflect the concatenation of another buffer full
174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * of bytes.
175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) */
176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MD5Update(MD5Context* context, const std::string& data) {
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        const unsigned char* inbuf = (const unsigned char*)data.data();
178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        size_t len = data.size();
179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        struct Context *ctx = (struct Context *)context;
180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        const unsigned char* buf = (const unsigned char*)inbuf;
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        uint32 t;
182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        /* Update bitcount */
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        t = ctx->bits[0];
186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                ctx->bits[1]++; /* Carry from low to high */
188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ctx->bits[1] += static_cast<uint32>(len >> 29);
189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */
191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        /* Handle any leading odd-sized chunks */
193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        if (t) {
195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                unsigned char *p = (unsigned char *)ctx->in + t;
196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                t = 64-t;
198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                if (len < t) {
199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        memcpy(p, buf, len);
200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                        return;
201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                }
202a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                memcpy(p, buf, t);
203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                byteReverse(ctx->in, 16);
204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                MD5Transform(ctx->buf, (uint32 *)ctx->in);
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                buf += t;
206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                len -= t;
207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        }
208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
209a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        /* Process data in 64-byte chunks */
210a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        while (len >= 64) {
212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                memcpy(ctx->in, buf, 64);
213a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                byteReverse(ctx->in, 16);
214a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                MD5Transform(ctx->buf, (uint32 *)ctx->in);
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                buf += 64;
216a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                len -= 64;
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        }
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        /* Handle any remaining bytes of data. */
220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        memcpy(ctx->in, buf, len);
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/*
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * Final wrapup - pad to 64-byte boundary with the bit pattern
226a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * 1 0* (64-bit count of bits processed, MSB-first)
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) */
228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MD5Final(MD5Digest* digest, MD5Context* context) {
229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        struct Context *ctx = (struct Context *)context;
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        unsigned count;
231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        unsigned char *p;
232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        /* Compute number of bytes mod 64 */
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        count = (ctx->bits[0] >> 3) & 0x3F;
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        /* Set the first char of padding to 0x80.  This is safe since there is
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)           always at least one byte free */
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        p = ctx->in + count;
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        *p++ = 0x80;
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        /* Bytes of padding needed to make 64 bytes */
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        count = 64 - 1 - count;
243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        /* Pad out to 56 mod 64 */
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        if (count < 8) {
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                /* Two lots of padding:  Pad the first block to 64 bytes */
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                memset(p, 0, count);
248a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                byteReverse(ctx->in, 16);
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                MD5Transform(ctx->buf, (uint32 *)ctx->in);
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                /* Now fill the next block with 56 bytes */
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                memset(ctx->in, 0, 56);
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        } else {
254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                /* Pad block to 56 bytes */
255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                memset(p, 0, count-8);
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        }
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        byteReverse(ctx->in, 14);
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        /* Append length in bits and transform */
260a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];
262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        MD5Transform(ctx->buf, (uint32 *)ctx->in);
264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        byteReverse((unsigned char *)ctx->buf, 4);
265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        memcpy(digest->a, ctx->buf, 16);
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        memset(ctx, 0, sizeof(*ctx));    /* In case it's sensitive */
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)std::string MD5DigestToBase16(const MD5Digest& digest) {
270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static char const zEncode[] = "0123456789abcdef";
271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string ret;
273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ret.resize(32);
274a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
275a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int j = 0;
276a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  for (int i = 0; i < 16; i ++) {
277a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    int a = digest.a[i];
278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ret[j++] = zEncode[(a>>4)&0xf];
279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ret[j++] = zEncode[a & 0xf];
280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
281a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return ret;
282a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
283a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
284a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void MD5Sum(const void* data, size_t length, MD5Digest* digest) {
285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MD5Context ctx;
286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MD5Init(&ctx);
287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MD5Update(&ctx,
288a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            std::string(reinterpret_cast<const char*>(data), length));
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MD5Final(digest, &ctx);
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)std::string MD5String(const std::string& str) {
293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MD5Digest digest;
294a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  MD5Sum(str.data(), str.length(), &digest);
295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return MD5DigestToBase16(digest);
296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
297a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
298a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace addressinput
299a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace i18n
300