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