Add rsa-internal.h to distributed headers.
[gd/nettle] / md4.c
1 /* md4.c
2
3    The MD4 hash function, described in RFC 1320.
4
5    Copyright (C) 2003 Niels Möller, Marcus Comstedt
6
7    This file is part of GNU Nettle.
8
9    GNU Nettle is free software: you can redistribute it and/or
10    modify it under the terms of either:
11
12      * the GNU Lesser General Public License as published by the Free
13        Software Foundation; either version 3 of the License, or (at your
14        option) any later version.
15
16    or
17
18      * the GNU General Public License as published by the Free
19        Software Foundation; either version 2 of the License, or (at your
20        option) any later version.
21
22    or both in parallel, as here.
23
24    GNU Nettle is distributed in the hope that it will be useful,
25    but WITHOUT ANY WARRANTY; without even the implied warranty of
26    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27    General Public License for more details.
28
29    You should have received copies of the GNU General Public License and
30    the GNU Lesser General Public License along with this program.  If
31    not, see http://www.gnu.org/licenses/.
32 */
33
34 /* Based on the public domain md5 code, and modified by Marcus
35    Comstedt */
36
37 #if HAVE_CONFIG_H
38 # include "config.h"
39 #endif
40
41 #include <assert.h>
42 #include <string.h>
43
44 #include "md4.h"
45
46 #include "macros.h"
47 #include "nettle-write.h"
48
49 /* A block, treated as a sequence of 32-bit words. */
50 #define MD4_DATA_LENGTH 16
51
52 static void
53 md4_transform(uint32_t *digest, const uint32_t *data);
54
55 static void
56 md4_compress(struct md4_ctx *ctx, const uint8_t *block);
57
58 /* FIXME: Could be an alias for md5_init */
59 void
60 md4_init(struct md4_ctx *ctx)
61 {
62   /* Same constants as for md5. */
63   const uint32_t iv[_MD4_DIGEST_LENGTH] =
64     {
65       0x67452301,
66       0xefcdab89,
67       0x98badcfe,
68       0x10325476,
69     };
70   memcpy(ctx->state, iv, sizeof(ctx->state));
71   
72   ctx->count = 0;
73   ctx->index = 0;
74 }
75
76 void
77 md4_update(struct md4_ctx *ctx,
78            size_t length,
79            const uint8_t *data)
80 {
81   MD_UPDATE(ctx, length, data, md4_compress, ctx->count++);
82 }
83
84 void
85 md4_digest(struct md4_ctx *ctx,
86            size_t length,
87            uint8_t *digest)
88 {
89   uint64_t bit_count;
90   uint32_t data[MD4_DATA_LENGTH];
91   unsigned i;
92
93   assert(length <= MD4_DIGEST_SIZE);
94
95   MD_PAD(ctx, 8, md4_compress);
96   for (i = 0; i < MD4_DATA_LENGTH - 2; i++)
97     data[i] = LE_READ_UINT32(ctx->block + 4*i);
98
99   /* There are 512 = 2^9 bits in one block 
100    * Little-endian order => Least significant word first */
101   bit_count = (ctx->count << 9) | (ctx->index << 3);
102   data[MD4_DATA_LENGTH-2] = bit_count;
103   data[MD4_DATA_LENGTH-1] = bit_count >> 32;
104   md4_transform(ctx->state, data);
105
106   _nettle_write_le32(length, digest, ctx->state);
107   md4_init(ctx);
108 }
109
110 /* MD4 functions */
111 #define F(x, y, z) (((y) & (x)) | ((z) & ~(x)))
112 #define G(x, y, z) (((y) & (x)) | ((z) & (x)) | ((y) & (z)))
113 #define H(x, y, z) ((x) ^ (y) ^ (z))
114
115 #define ROUND(f, w, x, y, z, data, s) \
116 ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s) )
117
118 /* Perform the MD4 transformation on one full block of 16 32-bit words. */
119    
120 static void
121 md4_transform(uint32_t *digest, const uint32_t *data)
122 {
123   uint32_t a, b, c, d;
124   a = digest[0];
125   b = digest[1];
126   c = digest[2];
127   d = digest[3];
128
129   ROUND(F, a, b, c, d, data[ 0], 3);
130   ROUND(F, d, a, b, c, data[ 1], 7);
131   ROUND(F, c, d, a, b, data[ 2], 11);
132   ROUND(F, b, c, d, a, data[ 3], 19);
133   ROUND(F, a, b, c, d, data[ 4], 3);
134   ROUND(F, d, a, b, c, data[ 5], 7);
135   ROUND(F, c, d, a, b, data[ 6], 11);
136   ROUND(F, b, c, d, a, data[ 7], 19);
137   ROUND(F, a, b, c, d, data[ 8], 3);
138   ROUND(F, d, a, b, c, data[ 9], 7);
139   ROUND(F, c, d, a, b, data[10], 11);
140   ROUND(F, b, c, d, a, data[11], 19);
141   ROUND(F, a, b, c, d, data[12], 3);
142   ROUND(F, d, a, b, c, data[13], 7);
143   ROUND(F, c, d, a, b, data[14], 11);
144   ROUND(F, b, c, d, a, data[15], 19);
145
146   ROUND(G, a, b, c, d, data[ 0] + 0x5a827999, 3);
147   ROUND(G, d, a, b, c, data[ 4] + 0x5a827999, 5);
148   ROUND(G, c, d, a, b, data[ 8] + 0x5a827999, 9);
149   ROUND(G, b, c, d, a, data[12] + 0x5a827999, 13);
150   ROUND(G, a, b, c, d, data[ 1] + 0x5a827999, 3);
151   ROUND(G, d, a, b, c, data[ 5] + 0x5a827999, 5);
152   ROUND(G, c, d, a, b, data[ 9] + 0x5a827999, 9);
153   ROUND(G, b, c, d, a, data[13] + 0x5a827999, 13);
154   ROUND(G, a, b, c, d, data[ 2] + 0x5a827999, 3);
155   ROUND(G, d, a, b, c, data[ 6] + 0x5a827999, 5);
156   ROUND(G, c, d, a, b, data[10] + 0x5a827999, 9);
157   ROUND(G, b, c, d, a, data[14] + 0x5a827999, 13);
158   ROUND(G, a, b, c, d, data[ 3] + 0x5a827999, 3);
159   ROUND(G, d, a, b, c, data[ 7] + 0x5a827999, 5);
160   ROUND(G, c, d, a, b, data[11] + 0x5a827999, 9);
161   ROUND(G, b, c, d, a, data[15] + 0x5a827999, 13);
162
163   ROUND(H, a, b, c, d, data[ 0] + 0x6ed9eba1, 3);
164   ROUND(H, d, a, b, c, data[ 8] + 0x6ed9eba1, 9);
165   ROUND(H, c, d, a, b, data[ 4] + 0x6ed9eba1, 11);
166   ROUND(H, b, c, d, a, data[12] + 0x6ed9eba1, 15);
167   ROUND(H, a, b, c, d, data[ 2] + 0x6ed9eba1, 3);
168   ROUND(H, d, a, b, c, data[10] + 0x6ed9eba1, 9);
169   ROUND(H, c, d, a, b, data[ 6] + 0x6ed9eba1, 11);
170   ROUND(H, b, c, d, a, data[14] + 0x6ed9eba1, 15);
171   ROUND(H, a, b, c, d, data[ 1] + 0x6ed9eba1, 3);
172   ROUND(H, d, a, b, c, data[ 9] + 0x6ed9eba1, 9);
173   ROUND(H, c, d, a, b, data[ 5] + 0x6ed9eba1, 11);
174   ROUND(H, b, c, d, a, data[13] + 0x6ed9eba1, 15);
175   ROUND(H, a, b, c, d, data[ 3] + 0x6ed9eba1, 3);
176   ROUND(H, d, a, b, c, data[11] + 0x6ed9eba1, 9);
177   ROUND(H, c, d, a, b, data[ 7] + 0x6ed9eba1, 11);
178   ROUND(H, b, c, d, a, data[15] + 0x6ed9eba1, 15);
179
180   digest[0] += a;
181   digest[1] += b;
182   digest[2] += c;
183   digest[3] += d;
184 }
185
186 static void
187 md4_compress(struct md4_ctx *ctx, const uint8_t *block)
188 {
189   uint32_t data[MD4_DATA_LENGTH];
190   unsigned i;
191   
192   /* Endian independent conversion */
193   for (i = 0; i<16; i++, block += 4)
194     data[i] = LE_READ_UINT32(block);
195
196   md4_transform(ctx->state, data);
197 }