sha1.c - sbase - suckless unix tools | |
git clone git://git.suckless.org/sbase | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
sha1.c (2966B) | |
--- | |
1 /* public domain sha1 implementation based on rfc3174 and libtomcrypt */ | |
2 #include <stdint.h> | |
3 #include <string.h> | |
4 | |
5 #include "../sha1.h" | |
6 | |
7 static uint32_t rol(uint32_t n, int k) { return (n << k) | (n >> (32-k))… | |
8 #define F0(b,c,d) (d ^ (b & (c ^ d))) | |
9 #define F1(b,c,d) (b ^ c ^ d) | |
10 #define F2(b,c,d) ((b & c) | (d & (b | c))) | |
11 #define F3(b,c,d) (b ^ c ^ d) | |
12 #define G0(a,b,c,d,e,i) e += rol(a,5)+F0(b,c,d)+W[i]+0x5A827999; b = rol… | |
13 #define G1(a,b,c,d,e,i) e += rol(a,5)+F1(b,c,d)+W[i]+0x6ED9EBA1; b = rol… | |
14 #define G2(a,b,c,d,e,i) e += rol(a,5)+F2(b,c,d)+W[i]+0x8F1BBCDC; b = rol… | |
15 #define G3(a,b,c,d,e,i) e += rol(a,5)+F3(b,c,d)+W[i]+0xCA62C1D6; b = rol… | |
16 | |
17 static void | |
18 processblock(struct sha1 *s, const uint8_t *buf) | |
19 { | |
20 uint32_t W[80], a, b, c, d, e; | |
21 int i; | |
22 | |
23 for (i = 0; i < 16; i++) { | |
24 W[i] = (uint32_t)buf[4*i]<<24; | |
25 W[i] |= (uint32_t)buf[4*i+1]<<16; | |
26 W[i] |= (uint32_t)buf[4*i+2]<<8; | |
27 W[i] |= buf[4*i+3]; | |
28 } | |
29 for (; i < 80; i++) | |
30 W[i] = rol(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); | |
31 a = s->h[0]; | |
32 b = s->h[1]; | |
33 c = s->h[2]; | |
34 d = s->h[3]; | |
35 e = s->h[4]; | |
36 for (i = 0; i < 20; ) { | |
37 G0(a,b,c,d,e,i++); | |
38 G0(e,a,b,c,d,i++); | |
39 G0(d,e,a,b,c,i++); | |
40 G0(c,d,e,a,b,i++); | |
41 G0(b,c,d,e,a,i++); | |
42 } | |
43 while (i < 40) { | |
44 G1(a,b,c,d,e,i++); | |
45 G1(e,a,b,c,d,i++); | |
46 G1(d,e,a,b,c,i++); | |
47 G1(c,d,e,a,b,i++); | |
48 G1(b,c,d,e,a,i++); | |
49 } | |
50 while (i < 60) { | |
51 G2(a,b,c,d,e,i++); | |
52 G2(e,a,b,c,d,i++); | |
53 G2(d,e,a,b,c,i++); | |
54 G2(c,d,e,a,b,i++); | |
55 G2(b,c,d,e,a,i++); | |
56 } | |
57 while (i < 80) { | |
58 G3(a,b,c,d,e,i++); | |
59 G3(e,a,b,c,d,i++); | |
60 G3(d,e,a,b,c,i++); | |
61 G3(c,d,e,a,b,i++); | |
62 G3(b,c,d,e,a,i++); | |
63 } | |
64 s->h[0] += a; | |
65 s->h[1] += b; | |
66 s->h[2] += c; | |
67 s->h[3] += d; | |
68 s->h[4] += e; | |
69 } | |
70 | |
71 static void | |
72 pad(struct sha1 *s) | |
73 { | |
74 unsigned r = s->len % 64; | |
75 | |
76 s->buf[r++] = 0x80; | |
77 if (r > 56) { | |
78 memset(s->buf + r, 0, 64 - r); | |
79 r = 0; | |
80 processblock(s, s->buf); | |
81 } | |
82 memset(s->buf + r, 0, 56 - r); | |
83 s->len *= 8; | |
84 s->buf[56] = s->len >> 56; | |
85 s->buf[57] = s->len >> 48; | |
86 s->buf[58] = s->len >> 40; | |
87 s->buf[59] = s->len >> 32; | |
88 s->buf[60] = s->len >> 24; | |
89 s->buf[61] = s->len >> 16; | |
90 s->buf[62] = s->len >> 8; | |
91 s->buf[63] = s->len; | |
92 processblock(s, s->buf); | |
93 } | |
94 | |
95 void | |
96 sha1_init(void *ctx) | |
97 { | |
98 struct sha1 *s = ctx; | |
99 | |
100 s->len = 0; | |
101 s->h[0] = 0x67452301; | |
102 s->h[1] = 0xEFCDAB89; | |
103 s->h[2] = 0x98BADCFE; | |
104 s->h[3] = 0x10325476; | |
105 s->h[4] = 0xC3D2E1F0; | |
106 } | |
107 | |
108 void | |
109 sha1_sum(void *ctx, uint8_t md[SHA1_DIGEST_LENGTH]) | |
110 { | |
111 struct sha1 *s = ctx; | |
112 int i; | |
113 | |
114 pad(s); | |
115 for (i = 0; i < 5; i++) { | |
116 md[4*i] = s->h[i] >> 24; | |
117 md[4*i+1] = s->h[i] >> 16; | |
118 md[4*i+2] = s->h[i] >> 8; | |
119 md[4*i+3] = s->h[i]; | |
120 } | |
121 } | |
122 | |
123 void | |
124 sha1_update(void *ctx, const void *m, unsigned long len) | |
125 { | |
126 struct sha1 *s = ctx; | |
127 const uint8_t *p = m; | |
128 unsigned r = s->len % 64; | |
129 | |
130 s->len += len; | |
131 if (r) { | |
132 if (len < 64 - r) { | |
133 memcpy(s->buf + r, p, len); | |
134 return; | |
135 } | |
136 memcpy(s->buf + r, p, 64 - r); | |
137 len -= 64 - r; | |
138 p += 64 - r; | |
139 processblock(s, s->buf); | |
140 } | |
141 for (; len >= 64; len -= 64, p += 64) | |
142 processblock(s, p); | |
143 memcpy(s->buf, p, len); | |
144 } |