1261287Sdes/* $OpenBSD: blocks.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
2261287Sdes
3261287Sdes/*
4261287Sdes * Public Domain, Author: Daniel J. Bernstein
5261287Sdes * Copied from nacl-20110221/crypto_hashblocks/sha512/ref/blocks.c
6261287Sdes */
7261287Sdes
8261287Sdes#include "includes.h"
9261287Sdes
10261287Sdes#include "crypto_api.h"
11261287Sdes
12261287Sdestypedef unsigned long long uint64;
13261287Sdes
14261287Sdesstatic uint64 load_bigendian(const unsigned char *x)
15261287Sdes{
16261287Sdes  return
17261287Sdes      (uint64) (x[7]) \
18261287Sdes  | (((uint64) (x[6])) << 8) \
19261287Sdes  | (((uint64) (x[5])) << 16) \
20261287Sdes  | (((uint64) (x[4])) << 24) \
21261287Sdes  | (((uint64) (x[3])) << 32) \
22261287Sdes  | (((uint64) (x[2])) << 40) \
23261287Sdes  | (((uint64) (x[1])) << 48) \
24261287Sdes  | (((uint64) (x[0])) << 56)
25261287Sdes  ;
26261287Sdes}
27261287Sdes
28261287Sdesstatic void store_bigendian(unsigned char *x,uint64 u)
29261287Sdes{
30261287Sdes  x[7] = u; u >>= 8;
31261287Sdes  x[6] = u; u >>= 8;
32261287Sdes  x[5] = u; u >>= 8;
33261287Sdes  x[4] = u; u >>= 8;
34261287Sdes  x[3] = u; u >>= 8;
35261287Sdes  x[2] = u; u >>= 8;
36261287Sdes  x[1] = u; u >>= 8;
37261287Sdes  x[0] = u;
38261287Sdes}
39261287Sdes
40261287Sdes#define SHR(x,c) ((x) >> (c))
41261287Sdes#define ROTR(x,c) (((x) >> (c)) | ((x) << (64 - (c))))
42261287Sdes
43261287Sdes#define Ch(x,y,z) ((x & y) ^ (~x & z))
44261287Sdes#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
45261287Sdes#define Sigma0(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39))
46261287Sdes#define Sigma1(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41))
47261287Sdes#define sigma0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x,7))
48261287Sdes#define sigma1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x,6))
49261287Sdes
50261287Sdes#define M(w0,w14,w9,w1) w0 = sigma1(w14) + w9 + sigma0(w1) + w0;
51261287Sdes
52261287Sdes#define EXPAND \
53261287Sdes  M(w0 ,w14,w9 ,w1 ) \
54261287Sdes  M(w1 ,w15,w10,w2 ) \
55261287Sdes  M(w2 ,w0 ,w11,w3 ) \
56261287Sdes  M(w3 ,w1 ,w12,w4 ) \
57261287Sdes  M(w4 ,w2 ,w13,w5 ) \
58261287Sdes  M(w5 ,w3 ,w14,w6 ) \
59261287Sdes  M(w6 ,w4 ,w15,w7 ) \
60261287Sdes  M(w7 ,w5 ,w0 ,w8 ) \
61261287Sdes  M(w8 ,w6 ,w1 ,w9 ) \
62261287Sdes  M(w9 ,w7 ,w2 ,w10) \
63261287Sdes  M(w10,w8 ,w3 ,w11) \
64261287Sdes  M(w11,w9 ,w4 ,w12) \
65261287Sdes  M(w12,w10,w5 ,w13) \
66261287Sdes  M(w13,w11,w6 ,w14) \
67261287Sdes  M(w14,w12,w7 ,w15) \
68261287Sdes  M(w15,w13,w8 ,w0 )
69261287Sdes
70261287Sdes#define F(w,k) \
71261287Sdes  T1 = h + Sigma1(e) + Ch(e,f,g) + k + w; \
72261287Sdes  T2 = Sigma0(a) + Maj(a,b,c); \
73261287Sdes  h = g; \
74261287Sdes  g = f; \
75261287Sdes  f = e; \
76261287Sdes  e = d + T1; \
77261287Sdes  d = c; \
78261287Sdes  c = b; \
79261287Sdes  b = a; \
80261287Sdes  a = T1 + T2;
81261287Sdes
82261287Sdesint crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen)
83261287Sdes{
84261287Sdes  uint64 state[8];
85261287Sdes  uint64 a;
86261287Sdes  uint64 b;
87261287Sdes  uint64 c;
88261287Sdes  uint64 d;
89261287Sdes  uint64 e;
90261287Sdes  uint64 f;
91261287Sdes  uint64 g;
92261287Sdes  uint64 h;
93261287Sdes  uint64 T1;
94261287Sdes  uint64 T2;
95261287Sdes
96261287Sdes  a = load_bigendian(statebytes +  0); state[0] = a;
97261287Sdes  b = load_bigendian(statebytes +  8); state[1] = b;
98261287Sdes  c = load_bigendian(statebytes + 16); state[2] = c;
99261287Sdes  d = load_bigendian(statebytes + 24); state[3] = d;
100261287Sdes  e = load_bigendian(statebytes + 32); state[4] = e;
101261287Sdes  f = load_bigendian(statebytes + 40); state[5] = f;
102261287Sdes  g = load_bigendian(statebytes + 48); state[6] = g;
103261287Sdes  h = load_bigendian(statebytes + 56); state[7] = h;
104261287Sdes
105261287Sdes  while (inlen >= 128) {
106261287Sdes    uint64 w0  = load_bigendian(in +   0);
107261287Sdes    uint64 w1  = load_bigendian(in +   8);
108261287Sdes    uint64 w2  = load_bigendian(in +  16);
109261287Sdes    uint64 w3  = load_bigendian(in +  24);
110261287Sdes    uint64 w4  = load_bigendian(in +  32);
111261287Sdes    uint64 w5  = load_bigendian(in +  40);
112261287Sdes    uint64 w6  = load_bigendian(in +  48);
113261287Sdes    uint64 w7  = load_bigendian(in +  56);
114261287Sdes    uint64 w8  = load_bigendian(in +  64);
115261287Sdes    uint64 w9  = load_bigendian(in +  72);
116261287Sdes    uint64 w10 = load_bigendian(in +  80);
117261287Sdes    uint64 w11 = load_bigendian(in +  88);
118261287Sdes    uint64 w12 = load_bigendian(in +  96);
119261287Sdes    uint64 w13 = load_bigendian(in + 104);
120261287Sdes    uint64 w14 = load_bigendian(in + 112);
121261287Sdes    uint64 w15 = load_bigendian(in + 120);
122261287Sdes
123261287Sdes    F(w0 ,0x428a2f98d728ae22ULL)
124261287Sdes    F(w1 ,0x7137449123ef65cdULL)
125261287Sdes    F(w2 ,0xb5c0fbcfec4d3b2fULL)
126261287Sdes    F(w3 ,0xe9b5dba58189dbbcULL)
127261287Sdes    F(w4 ,0x3956c25bf348b538ULL)
128261287Sdes    F(w5 ,0x59f111f1b605d019ULL)
129261287Sdes    F(w6 ,0x923f82a4af194f9bULL)
130261287Sdes    F(w7 ,0xab1c5ed5da6d8118ULL)
131261287Sdes    F(w8 ,0xd807aa98a3030242ULL)
132261287Sdes    F(w9 ,0x12835b0145706fbeULL)
133261287Sdes    F(w10,0x243185be4ee4b28cULL)
134261287Sdes    F(w11,0x550c7dc3d5ffb4e2ULL)
135261287Sdes    F(w12,0x72be5d74f27b896fULL)
136261287Sdes    F(w13,0x80deb1fe3b1696b1ULL)
137261287Sdes    F(w14,0x9bdc06a725c71235ULL)
138261287Sdes    F(w15,0xc19bf174cf692694ULL)
139261287Sdes
140261287Sdes    EXPAND
141261287Sdes
142261287Sdes    F(w0 ,0xe49b69c19ef14ad2ULL)
143261287Sdes    F(w1 ,0xefbe4786384f25e3ULL)
144261287Sdes    F(w2 ,0x0fc19dc68b8cd5b5ULL)
145261287Sdes    F(w3 ,0x240ca1cc77ac9c65ULL)
146261287Sdes    F(w4 ,0x2de92c6f592b0275ULL)
147261287Sdes    F(w5 ,0x4a7484aa6ea6e483ULL)
148261287Sdes    F(w6 ,0x5cb0a9dcbd41fbd4ULL)
149261287Sdes    F(w7 ,0x76f988da831153b5ULL)
150261287Sdes    F(w8 ,0x983e5152ee66dfabULL)
151261287Sdes    F(w9 ,0xa831c66d2db43210ULL)
152261287Sdes    F(w10,0xb00327c898fb213fULL)
153261287Sdes    F(w11,0xbf597fc7beef0ee4ULL)
154261287Sdes    F(w12,0xc6e00bf33da88fc2ULL)
155261287Sdes    F(w13,0xd5a79147930aa725ULL)
156261287Sdes    F(w14,0x06ca6351e003826fULL)
157261287Sdes    F(w15,0x142929670a0e6e70ULL)
158261287Sdes
159261287Sdes    EXPAND
160261287Sdes
161261287Sdes    F(w0 ,0x27b70a8546d22ffcULL)
162261287Sdes    F(w1 ,0x2e1b21385c26c926ULL)
163261287Sdes    F(w2 ,0x4d2c6dfc5ac42aedULL)
164261287Sdes    F(w3 ,0x53380d139d95b3dfULL)
165261287Sdes    F(w4 ,0x650a73548baf63deULL)
166261287Sdes    F(w5 ,0x766a0abb3c77b2a8ULL)
167261287Sdes    F(w6 ,0x81c2c92e47edaee6ULL)
168261287Sdes    F(w7 ,0x92722c851482353bULL)
169261287Sdes    F(w8 ,0xa2bfe8a14cf10364ULL)
170261287Sdes    F(w9 ,0xa81a664bbc423001ULL)
171261287Sdes    F(w10,0xc24b8b70d0f89791ULL)
172261287Sdes    F(w11,0xc76c51a30654be30ULL)
173261287Sdes    F(w12,0xd192e819d6ef5218ULL)
174261287Sdes    F(w13,0xd69906245565a910ULL)
175261287Sdes    F(w14,0xf40e35855771202aULL)
176261287Sdes    F(w15,0x106aa07032bbd1b8ULL)
177261287Sdes
178261287Sdes    EXPAND
179261287Sdes
180261287Sdes    F(w0 ,0x19a4c116b8d2d0c8ULL)
181261287Sdes    F(w1 ,0x1e376c085141ab53ULL)
182261287Sdes    F(w2 ,0x2748774cdf8eeb99ULL)
183261287Sdes    F(w3 ,0x34b0bcb5e19b48a8ULL)
184261287Sdes    F(w4 ,0x391c0cb3c5c95a63ULL)
185261287Sdes    F(w5 ,0x4ed8aa4ae3418acbULL)
186261287Sdes    F(w6 ,0x5b9cca4f7763e373ULL)
187261287Sdes    F(w7 ,0x682e6ff3d6b2b8a3ULL)
188261287Sdes    F(w8 ,0x748f82ee5defb2fcULL)
189261287Sdes    F(w9 ,0x78a5636f43172f60ULL)
190261287Sdes    F(w10,0x84c87814a1f0ab72ULL)
191261287Sdes    F(w11,0x8cc702081a6439ecULL)
192261287Sdes    F(w12,0x90befffa23631e28ULL)
193261287Sdes    F(w13,0xa4506cebde82bde9ULL)
194261287Sdes    F(w14,0xbef9a3f7b2c67915ULL)
195261287Sdes    F(w15,0xc67178f2e372532bULL)
196261287Sdes
197261287Sdes    EXPAND
198261287Sdes
199261287Sdes    F(w0 ,0xca273eceea26619cULL)
200261287Sdes    F(w1 ,0xd186b8c721c0c207ULL)
201261287Sdes    F(w2 ,0xeada7dd6cde0eb1eULL)
202261287Sdes    F(w3 ,0xf57d4f7fee6ed178ULL)
203261287Sdes    F(w4 ,0x06f067aa72176fbaULL)
204261287Sdes    F(w5 ,0x0a637dc5a2c898a6ULL)
205261287Sdes    F(w6 ,0x113f9804bef90daeULL)
206261287Sdes    F(w7 ,0x1b710b35131c471bULL)
207261287Sdes    F(w8 ,0x28db77f523047d84ULL)
208261287Sdes    F(w9 ,0x32caab7b40c72493ULL)
209261287Sdes    F(w10,0x3c9ebe0a15c9bebcULL)
210261287Sdes    F(w11,0x431d67c49c100d4cULL)
211261287Sdes    F(w12,0x4cc5d4becb3e42b6ULL)
212261287Sdes    F(w13,0x597f299cfc657e2aULL)
213261287Sdes    F(w14,0x5fcb6fab3ad6faecULL)
214261287Sdes    F(w15,0x6c44198c4a475817ULL)
215261287Sdes
216261287Sdes    a += state[0];
217261287Sdes    b += state[1];
218261287Sdes    c += state[2];
219261287Sdes    d += state[3];
220261287Sdes    e += state[4];
221261287Sdes    f += state[5];
222261287Sdes    g += state[6];
223261287Sdes    h += state[7];
224261287Sdes
225261287Sdes    state[0] = a;
226261287Sdes    state[1] = b;
227261287Sdes    state[2] = c;
228261287Sdes    state[3] = d;
229261287Sdes    state[4] = e;
230261287Sdes    state[5] = f;
231261287Sdes    state[6] = g;
232261287Sdes    state[7] = h;
233261287Sdes
234261287Sdes    in += 128;
235261287Sdes    inlen -= 128;
236261287Sdes  }
237261287Sdes
238261287Sdes  store_bigendian(statebytes +  0,state[0]);
239261287Sdes  store_bigendian(statebytes +  8,state[1]);
240261287Sdes  store_bigendian(statebytes + 16,state[2]);
241261287Sdes  store_bigendian(statebytes + 24,state[3]);
242261287Sdes  store_bigendian(statebytes + 32,state[4]);
243261287Sdes  store_bigendian(statebytes + 40,state[5]);
244261287Sdes  store_bigendian(statebytes + 48,state[6]);
245261287Sdes  store_bigendian(statebytes + 56,state[7]);
246261287Sdes
247261287Sdes  return inlen;
248261287Sdes}
249