blob: 8e698c4ae046f07456ae9e9875c65642e636282b [file] [log] [blame]
Damien Miller3cccc0e2013-12-07 11:27:47 +11001/* $OpenBSD: blocks.c,v 1.2 2013/12/07 00:26:37 djm Exp $ */
Damien Miller5be9d9e2013-12-07 11:24:01 +11002
3/* Public Domain, from supercop-20130419/crypto_hashblocks/sha512/ref/blocks.c */
4
5#include "crypto_api.h"
6
7typedef unsigned long long uint64;
8
9static uint64 load_bigendian(const unsigned char *x)
10{
11 return
12 (uint64) (x[7]) \
13 | (((uint64) (x[6])) << 8) \
14 | (((uint64) (x[5])) << 16) \
15 | (((uint64) (x[4])) << 24) \
16 | (((uint64) (x[3])) << 32) \
17 | (((uint64) (x[2])) << 40) \
18 | (((uint64) (x[1])) << 48) \
19 | (((uint64) (x[0])) << 56)
20 ;
21}
22
23static void store_bigendian(unsigned char *x,uint64 u)
24{
25 x[7] = u; u >>= 8;
26 x[6] = u; u >>= 8;
27 x[5] = u; u >>= 8;
28 x[4] = u; u >>= 8;
29 x[3] = u; u >>= 8;
30 x[2] = u; u >>= 8;
31 x[1] = u; u >>= 8;
32 x[0] = u;
33}
34
35#define SHR(x,c) ((x) >> (c))
36#define ROTR(x,c) (((x) >> (c)) | ((x) << (64 - (c))))
37
38#define Ch(x,y,z) ((x & y) ^ (~x & z))
39#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
40#define Sigma0(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
41#define Sigma1(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
42#define sigma0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x,7))
43#define sigma1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x,6))
44
45#define M(w0,w14,w9,w1) w0 = sigma1(w14) + w9 + sigma0(w1) + w0;
46
47#define EXPAND \
48 M(w0 ,w14,w9 ,w1 ) \
49 M(w1 ,w15,w10,w2 ) \
50 M(w2 ,w0 ,w11,w3 ) \
51 M(w3 ,w1 ,w12,w4 ) \
52 M(w4 ,w2 ,w13,w5 ) \
53 M(w5 ,w3 ,w14,w6 ) \
54 M(w6 ,w4 ,w15,w7 ) \
55 M(w7 ,w5 ,w0 ,w8 ) \
56 M(w8 ,w6 ,w1 ,w9 ) \
57 M(w9 ,w7 ,w2 ,w10) \
58 M(w10,w8 ,w3 ,w11) \
59 M(w11,w9 ,w4 ,w12) \
60 M(w12,w10,w5 ,w13) \
61 M(w13,w11,w6 ,w14) \
62 M(w14,w12,w7 ,w15) \
63 M(w15,w13,w8 ,w0 )
64
65#define F(w,k) \
66 T1 = h + Sigma1(e) + Ch(e,f,g) + k + w; \
67 T2 = Sigma0(a) + Maj(a,b,c); \
68 h = g; \
69 g = f; \
70 f = e; \
71 e = d + T1; \
72 d = c; \
73 c = b; \
74 b = a; \
75 a = T1 + T2;
76
77int crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen)
78{
79 uint64 state[8];
80 uint64 a;
81 uint64 b;
82 uint64 c;
83 uint64 d;
84 uint64 e;
85 uint64 f;
86 uint64 g;
87 uint64 h;
88 uint64 T1;
89 uint64 T2;
90
91 a = load_bigendian(statebytes + 0); state[0] = a;
92 b = load_bigendian(statebytes + 8); state[1] = b;
93 c = load_bigendian(statebytes + 16); state[2] = c;
94 d = load_bigendian(statebytes + 24); state[3] = d;
95 e = load_bigendian(statebytes + 32); state[4] = e;
96 f = load_bigendian(statebytes + 40); state[5] = f;
97 g = load_bigendian(statebytes + 48); state[6] = g;
98 h = load_bigendian(statebytes + 56); state[7] = h;
99
100 while (inlen >= 128) {
101 uint64 w0 = load_bigendian(in + 0);
102 uint64 w1 = load_bigendian(in + 8);
103 uint64 w2 = load_bigendian(in + 16);
104 uint64 w3 = load_bigendian(in + 24);
105 uint64 w4 = load_bigendian(in + 32);
106 uint64 w5 = load_bigendian(in + 40);
107 uint64 w6 = load_bigendian(in + 48);
108 uint64 w7 = load_bigendian(in + 56);
109 uint64 w8 = load_bigendian(in + 64);
110 uint64 w9 = load_bigendian(in + 72);
111 uint64 w10 = load_bigendian(in + 80);
112 uint64 w11 = load_bigendian(in + 88);
113 uint64 w12 = load_bigendian(in + 96);
114 uint64 w13 = load_bigendian(in + 104);
115 uint64 w14 = load_bigendian(in + 112);
116 uint64 w15 = load_bigendian(in + 120);
117
118 F(w0 ,0x428a2f98d728ae22ULL)
119 F(w1 ,0x7137449123ef65cdULL)
120 F(w2 ,0xb5c0fbcfec4d3b2fULL)
121 F(w3 ,0xe9b5dba58189dbbcULL)
122 F(w4 ,0x3956c25bf348b538ULL)
123 F(w5 ,0x59f111f1b605d019ULL)
124 F(w6 ,0x923f82a4af194f9bULL)
125 F(w7 ,0xab1c5ed5da6d8118ULL)
126 F(w8 ,0xd807aa98a3030242ULL)
127 F(w9 ,0x12835b0145706fbeULL)
128 F(w10,0x243185be4ee4b28cULL)
129 F(w11,0x550c7dc3d5ffb4e2ULL)
130 F(w12,0x72be5d74f27b896fULL)
131 F(w13,0x80deb1fe3b1696b1ULL)
132 F(w14,0x9bdc06a725c71235ULL)
133 F(w15,0xc19bf174cf692694ULL)
134
135 EXPAND
136
137 F(w0 ,0xe49b69c19ef14ad2ULL)
138 F(w1 ,0xefbe4786384f25e3ULL)
139 F(w2 ,0x0fc19dc68b8cd5b5ULL)
140 F(w3 ,0x240ca1cc77ac9c65ULL)
141 F(w4 ,0x2de92c6f592b0275ULL)
142 F(w5 ,0x4a7484aa6ea6e483ULL)
143 F(w6 ,0x5cb0a9dcbd41fbd4ULL)
144 F(w7 ,0x76f988da831153b5ULL)
145 F(w8 ,0x983e5152ee66dfabULL)
146 F(w9 ,0xa831c66d2db43210ULL)
147 F(w10,0xb00327c898fb213fULL)
148 F(w11,0xbf597fc7beef0ee4ULL)
149 F(w12,0xc6e00bf33da88fc2ULL)
150 F(w13,0xd5a79147930aa725ULL)
151 F(w14,0x06ca6351e003826fULL)
152 F(w15,0x142929670a0e6e70ULL)
153
154 EXPAND
155
156 F(w0 ,0x27b70a8546d22ffcULL)
157 F(w1 ,0x2e1b21385c26c926ULL)
158 F(w2 ,0x4d2c6dfc5ac42aedULL)
159 F(w3 ,0x53380d139d95b3dfULL)
160 F(w4 ,0x650a73548baf63deULL)
161 F(w5 ,0x766a0abb3c77b2a8ULL)
162 F(w6 ,0x81c2c92e47edaee6ULL)
163 F(w7 ,0x92722c851482353bULL)
164 F(w8 ,0xa2bfe8a14cf10364ULL)
165 F(w9 ,0xa81a664bbc423001ULL)
166 F(w10,0xc24b8b70d0f89791ULL)
167 F(w11,0xc76c51a30654be30ULL)
168 F(w12,0xd192e819d6ef5218ULL)
169 F(w13,0xd69906245565a910ULL)
170 F(w14,0xf40e35855771202aULL)
171 F(w15,0x106aa07032bbd1b8ULL)
172
173 EXPAND
174
175 F(w0 ,0x19a4c116b8d2d0c8ULL)
176 F(w1 ,0x1e376c085141ab53ULL)
177 F(w2 ,0x2748774cdf8eeb99ULL)
178 F(w3 ,0x34b0bcb5e19b48a8ULL)
179 F(w4 ,0x391c0cb3c5c95a63ULL)
180 F(w5 ,0x4ed8aa4ae3418acbULL)
181 F(w6 ,0x5b9cca4f7763e373ULL)
182 F(w7 ,0x682e6ff3d6b2b8a3ULL)
183 F(w8 ,0x748f82ee5defb2fcULL)
184 F(w9 ,0x78a5636f43172f60ULL)
185 F(w10,0x84c87814a1f0ab72ULL)
186 F(w11,0x8cc702081a6439ecULL)
187 F(w12,0x90befffa23631e28ULL)
188 F(w13,0xa4506cebde82bde9ULL)
189 F(w14,0xbef9a3f7b2c67915ULL)
190 F(w15,0xc67178f2e372532bULL)
191
192 EXPAND
193
194 F(w0 ,0xca273eceea26619cULL)
195 F(w1 ,0xd186b8c721c0c207ULL)
196 F(w2 ,0xeada7dd6cde0eb1eULL)
197 F(w3 ,0xf57d4f7fee6ed178ULL)
198 F(w4 ,0x06f067aa72176fbaULL)
199 F(w5 ,0x0a637dc5a2c898a6ULL)
200 F(w6 ,0x113f9804bef90daeULL)
201 F(w7 ,0x1b710b35131c471bULL)
202 F(w8 ,0x28db77f523047d84ULL)
203 F(w9 ,0x32caab7b40c72493ULL)
204 F(w10,0x3c9ebe0a15c9bebcULL)
205 F(w11,0x431d67c49c100d4cULL)
206 F(w12,0x4cc5d4becb3e42b6ULL)
207 F(w13,0x597f299cfc657e2aULL)
208 F(w14,0x5fcb6fab3ad6faecULL)
209 F(w15,0x6c44198c4a475817ULL)
210
211 a += state[0];
212 b += state[1];
213 c += state[2];
214 d += state[3];
215 e += state[4];
216 f += state[5];
217 g += state[6];
218 h += state[7];
219
220 state[0] = a;
221 state[1] = b;
222 state[2] = c;
223 state[3] = d;
224 state[4] = e;
225 state[5] = f;
226 state[6] = g;
227 state[7] = h;
228
229 in += 128;
230 inlen -= 128;
231 }
232
233 store_bigendian(statebytes + 0,state[0]);
234 store_bigendian(statebytes + 8,state[1]);
235 store_bigendian(statebytes + 16,state[2]);
236 store_bigendian(statebytes + 24,state[3]);
237 store_bigendian(statebytes + 32,state[4]);
238 store_bigendian(statebytes + 40,state[5]);
239 store_bigendian(statebytes + 48,state[6]);
240 store_bigendian(statebytes + 56,state[7]);
241
242 return inlen;
243}