-rw-r--r-- 1905 lib25519-20240321/crypto_hash/sha512/blocksplusavx/hash.c raw
#include <immintrin.h>
#include "crypto_hashblocks_sha512.h"
#include "crypto_hash.h"
#define blocks crypto_hashblocks_sha512
#define ALIGNED __attribute((aligned(32)))
static const ALIGNED unsigned char iv[64] = {
0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,
0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,
0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,
0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,
0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,
0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,
0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b,
0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79
} ;
typedef unsigned long long uint64;
#define load256(x) (_mm256_loadu_si256((void *) (x)))
#define store256(x,y) (_mm256_storeu_si256((void *) (x),y))
void crypto_hash(unsigned char *out,const unsigned char *in,long long inlen)
{
ALIGNED unsigned char h[64];
ALIGNED unsigned char padded[256];
unsigned long long i;
unsigned long long bytes = inlen;
__m256i X0,X1;
X0 = load256(iv);
X1 = load256(iv + 32);
store256(h,X0);
store256(h + 32,X1);
blocks(h,in,inlen);
in += inlen;
inlen &= 127;
in -= inlen;
X0 ^= X0;
if (inlen < 112) {
store256(padded,X0);
store256(padded + 32,X0);
store256(padded + 64,X0);
store256(padded + 96,X0);
for (i = 0;i < inlen;++i) padded[i] = in[i];
padded[inlen] = 0x80;
padded[119] = bytes >> 61;
*(uint64 *) (padded + 120) = __builtin_bswap64(bytes << 3);
blocks(h,padded,128);
} else {
store256(padded + 96,X0);
store256(padded + 128,X0);
store256(padded + 160,X0);
store256(padded + 192,X0);
store256(padded + 224,X0);
for (i = 0;i < inlen;++i) padded[i] = in[i];
padded[inlen] = 0x80;
padded[247] = bytes >> 61;
*(uint64 *) (padded + 248) = __builtin_bswap64(bytes << 3);
blocks(h,padded,256);
}
X0 = load256(h);
X1 = load256(h + 32);
store256(out,X0);
store256(out + 32,X1);
}