crhash: sha1: add test vectors
[crhash.git] / hash-sha1.c
blobd37a1f72f02c780e5e53495637aa619bdb6441e7
1 #include <endian.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4 #include <string.h>
6 #include "hash-sha1.h"
8 static inline uint32_t rol32(const uint32_t x, const unsigned int n)
10 return (x << n) | (x >> (32 - n));
13 static inline uint32_t F(const uint32_t X, const uint32_t Y, const uint32_t Z)
15 return (X & Y) | (~X & Z);
18 static inline uint32_t G(const uint32_t X, const uint32_t Y, const uint32_t Z)
20 return X ^ Y ^ Z;
23 static inline uint32_t H(const uint32_t X, const uint32_t Y, const uint32_t Z)
25 return (X & Y) ^ (X & Z) ^ (Y & Z);
28 struct sha1_context {
29 uint32_t A, B, C, D, E;
30 uint64_t len; /* in bits */
31 uint8_t m[64];
32 unsigned int m_len;
35 static void __sha1_update(void *_ctx, const uint8_t *m)
37 struct sha1_context *ctx = _ctx;
38 uint32_t A, B, C, D, E;
39 uint32_t W[80];
40 int i;
42 A = ctx->A;
43 B = ctx->B;
44 C = ctx->C;
45 D = ctx->D;
46 E = ctx->E;
48 for (i = 0; i < 16; i++)
49 W[i] = be32toh(*(uint32_t *)(m + i * sizeof(uint32_t)));
50 for (i = 16; i < 80; i++)
51 W[i] = rol32(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
53 for (i = 0; i <= 19; i++) {
54 uint32_t T;
56 T = rol32(A, 5) + F(B, C, D) + E + 0x5a827999 + W[i];
57 E = D;
58 D = C;
59 C = rol32(B, 30);
60 B = A;
61 A = T;
63 for (i = 20; i <= 39; i++) {
64 uint32_t T;
66 T = rol32(A, 5) + G(B, C, D) + E + 0x6ed9eba1 + W[i];
67 E = D;
68 D = C;
69 C = rol32(B, 30);
70 B = A;
71 A = T;
73 for (i = 40; i <= 59; i++) {
74 uint32_t T;
76 T = rol32(A, 5) + H(B, C, D) + E + 0x8f1bbcdc + W[i];
77 E = D;
78 D = C;
79 C = rol32(B, 30);
80 B = A;
81 A = T;
83 for (i = 60; i <= 79; i++) {
84 uint32_t T;
86 T = rol32(A, 5) + G(B, C, D) + E + 0xca62c1d6 + W[i];
87 E = D;
88 D = C;
89 C = rol32(B, 30);
90 B = A;
91 A = T;
94 ctx->A += A;
95 ctx->B += B;
96 ctx->C += C;
97 ctx->D += D;
98 ctx->E += E;
101 void sha1_update(void *_ctx, const uint8_t *m)
103 struct sha1_context *ctx = _ctx;
105 __sha1_update(ctx, m);
106 ctx->len += 512;
109 void _sha1_update(void *_ctx, const uint8_t *m, unsigned int len)
111 struct sha1_context *ctx = _ctx;
113 while (len > 0) {
114 ctx->m[ctx->m_len] = *m;
115 ctx->m_len++;
116 m++;
117 len--;
118 ctx->len += 8;
120 if (ctx->m_len == 64) {
121 __sha1_update(ctx, ctx->m);
122 ctx->m_len = 0;
127 void *sha1_init_context(void)
129 struct sha1_context *ctx;
131 ctx = malloc(sizeof(struct sha1_context));
132 if (!ctx)
133 return NULL;
135 ctx->A = 0x67452301;
136 ctx->B = 0xefcdab89;
137 ctx->C = 0x98badcfe;
138 ctx->D = 0x10325476;
139 ctx->E = 0xc3d2e1f0;
140 ctx->len = 0;
142 memset(ctx->m, 0, 64);
143 ctx->m_len = 0;
145 return ctx;
148 void sha1_fini_context(void *_ctx)
150 struct sha1_context *ctx = _ctx;
152 memset(ctx, 0, sizeof(struct sha1_context));
153 free(ctx);
156 void sha1_fini(void *_ctx)
158 struct sha1_context *ctx = _ctx;
160 ctx->m[ctx->m_len] = 0x80;
161 ctx->m_len++;
162 if (ctx->m_len <= 64 - 8) {
163 while (ctx->m_len <= 64 - 8) {
164 ctx->m[ctx->m_len] = 0;
165 ctx->m_len++;
167 } else {
168 while (ctx->m_len < 64) {
169 ctx->m[ctx->m_len] = 0;
170 ctx->m_len++;
172 __sha1_update(ctx, ctx->m);
173 memset(ctx->m, 0, 64 - 8);
175 *(uint64_t *)&ctx->m[64 - 8] = htobe64(ctx->len);
176 __sha1_update(ctx, ctx->m);
179 void sha1_digest(void *_ctx, uint8_t *digest)
181 struct sha1_context *ctx = _ctx;
183 *(uint32_t *)&digest[0] = htobe32(ctx->A);
184 *(uint32_t *)&digest[4] = htobe32(ctx->B);
185 *(uint32_t *)&digest[8] = htobe32(ctx->C);
186 *(uint32_t *)&digest[12] = htobe32(ctx->D);
187 *(uint32_t *)&digest[16] = htobe32(ctx->E);