166458Sdfr/* $OpenBSD: blocks.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */ 266458Sdfr 366458Sdfr/* 4139790Simp * Public Domain, Author: Daniel J. Bernstein 566458Sdfr * Copied from nacl-20110221/crypto_hashblocks/sha512/ref/blocks.c 666458Sdfr */ 766458Sdfr 866458Sdfr#include "includes.h" 966458Sdfr 1066458Sdfr#include "crypto_api.h" 1166458Sdfr 1266458Sdfrtypedef unsigned long long uint64; 1366458Sdfr 1466458Sdfrstatic uint64 load_bigendian(const unsigned char *x) 1566458Sdfr{ 1666458Sdfr return 1766458Sdfr (uint64) (x[7]) \ 1866458Sdfr | (((uint64) (x[6])) << 8) \ 1966458Sdfr | (((uint64) (x[5])) << 16) \ 2066458Sdfr | (((uint64) (x[4])) << 24) \ 2166458Sdfr | (((uint64) (x[3])) << 32) \ 2266458Sdfr | (((uint64) (x[2])) << 40) \ 2366458Sdfr | (((uint64) (x[1])) << 48) \ 2466458Sdfr | (((uint64) (x[0])) << 56) 2566458Sdfr ; 2666458Sdfr} 2766458Sdfr 2866458Sdfrstatic void store_bigendian(unsigned char *x,uint64 u) 2966458Sdfr{ 3066458Sdfr x[7] = u; u >>= 8; 3166458Sdfr x[6] = u; u >>= 8; 3266458Sdfr x[5] = u; u >>= 8; 3366458Sdfr x[4] = u; u >>= 8; 3466458Sdfr x[3] = u; u >>= 8; 3566458Sdfr x[2] = u; u >>= 8; 3666458Sdfr x[1] = u; u >>= 8; 3766458Sdfr x[0] = u; 3866458Sdfr} 3966458Sdfr 4066458Sdfr#define SHR(x,c) ((x) >> (c)) 4166458Sdfr#define ROTR(x,c) (((x) >> (c)) | ((x) << (64 - (c)))) 42196994Sphk 43196994Sphk#define Ch(x,y,z) ((x & y) ^ (~x & z)) 44196994Sphk#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z)) 4566458Sdfr#define Sigma0(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) 4666458Sdfr#define Sigma1(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) 4766458Sdfr#define sigma0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x,7)) 4870508Sdfr#define sigma1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x,6)) 49196994Sphk 5096912Smarcel#define M(w0,w14,w9,w1) w0 = sigma1(w14) + w9 + sigma0(w1) + w0; 51154128Simp 52154128Simp#define EXPAND \ 53154128Simp M(w0 ,w14,w9 ,w1 ) \ 5466458Sdfr M(w1 ,w15,w10,w2 ) \ 5566458Sdfr M(w2 ,w0 ,w11,w3 ) \ 5666458Sdfr M(w3 ,w1 ,w12,w4 ) \ 5766458Sdfr M(w4 ,w2 ,w13,w5 ) \ 5866458Sdfr M(w5 ,w3 ,w14,w6 ) \ 5966458Sdfr M(w6 ,w4 ,w15,w7 ) \ 60210369Skib M(w7 ,w5 ,w0 ,w8 ) \ 61210369Skib M(w8 ,w6 ,w1 ,w9 ) \ 62210369Skib M(w9 ,w7 ,w2 ,w10) \ 6366458Sdfr M(w10,w8 ,w3 ,w11) \ 64177661Sjb M(w11,w9 ,w4 ,w12) \ 65224207Sattilio M(w12,w10,w5 ,w13) \ 66224217Sattilio M(w13,w11,w6 ,w14) \ 67224207Sattilio M(w14,w12,w7 ,w15) \ 6874733Sjhb M(w15,w13,w8 ,w0 ) 6974733Sjhb 7074733Sjhb#define F(w,k) \ 7166458Sdfr T1 = h + Sigma1(e) + Ch(e,f,g) + k + w; \ 72250338Sattilio T2 = Sigma0(a) + Maj(a,b,c); \ 73250338Sattilio h = g; \ 74250338Sattilio g = f; \ 75250338Sattilio f = e; \ 76195376Ssam e = d + T1; \ 77195376Ssam d = c; \ 7866458Sdfr c = b; \ 7966458Sdfr b = a; \ 8066458Sdfr a = T1 + T2; 8166458Sdfr 8266458Sdfrint crypto_hashblocks_sha512(unsigned char *statebytes,const unsigned char *in,unsigned long long inlen) 8366458Sdfr{ 84195376Ssam uint64 state[8]; 8566458Sdfr uint64 a; 86191278Srwatson uint64 b; 87191278Srwatson uint64 c; 88191278Srwatson uint64 d; 89191278Srwatson uint64 e; 90191309Srwatson uint64 f; 91191276Srwatson uint64 g; 92191276Srwatson uint64 h; 93119347Smarcel uint64 T1; 94119347Smarcel uint64 T2; 9583198Sdfr 96119347Smarcel a = load_bigendian(statebytes + 0); state[0] = a; 97119347Smarcel b = load_bigendian(statebytes + 8); state[1] = b; 9866458Sdfr c = load_bigendian(statebytes + 16); state[2] = c; 9966458Sdfr d = load_bigendian(statebytes + 24); state[3] = d; 10066458Sdfr e = load_bigendian(statebytes + 32); state[4] = e; 101197316Salc f = load_bigendian(statebytes + 40); state[5] = f; 102197316Salc g = load_bigendian(statebytes + 48); state[6] = g; 103118239Speter h = load_bigendian(statebytes + 56); state[7] = h; 104199719Smarcel 105118239Speter while (inlen >= 128) { 106116355Salc uint64 w0 = load_bigendian(in + 0); 10766458Sdfr uint64 w1 = load_bigendian(in + 8); 108261985Smarcel uint64 w2 = load_bigendian(in + 16); 109261985Smarcel uint64 w3 = load_bigendian(in + 24); 110261985Smarcel uint64 w4 = load_bigendian(in + 32); 111261985Smarcel uint64 w5 = load_bigendian(in + 40); 112261985Smarcel uint64 w6 = load_bigendian(in + 48); 11366458Sdfr uint64 w7 = load_bigendian(in + 56); 11466458Sdfr uint64 w8 = load_bigendian(in + 64); 11566458Sdfr uint64 w9 = load_bigendian(in + 72); 11666458Sdfr uint64 w10 = load_bigendian(in + 80); 11766458Sdfr uint64 w11 = load_bigendian(in + 88); 11866458Sdfr uint64 w12 = load_bigendian(in + 96); 11966458Sdfr uint64 w13 = load_bigendian(in + 104); 12066458Sdfr uint64 w14 = load_bigendian(in + 112); 12166458Sdfr uint64 w15 = load_bigendian(in + 120); 12266458Sdfr 12396912Smarcel F(w0 ,0x428a2f98d728ae22ULL) 124274648Skib F(w1 ,0x7137449123ef65cdULL) 125274648Skib F(w2 ,0xb5c0fbcfec4d3b2fULL) 126274648Skib F(w3 ,0xe9b5dba58189dbbcULL) 127274648Skib F(w4 ,0x3956c25bf348b538ULL) 128196994Sphk 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