use AVX for HMAC

This commit is contained in:
orignal 2016-12-09 15:46:21 -05:00
parent 7386b0a523
commit dca48c7eec

View File

@ -386,44 +386,58 @@ namespace crypto
// HMAC // HMAC
const uint64_t IPAD = 0x3636363636363636; const uint64_t IPAD = 0x3636363636363636;
const uint64_t OPAD = 0x5C5C5C5C5C5C5C5C; const uint64_t OPAD = 0x5C5C5C5C5C5C5C5C;
static const uint64_t ipads[] = { IPAD, IPAD, IPAD, IPAD };
static const uint64_t opads[] = { OPAD, OPAD, OPAD, OPAD };
void HMACMD5Digest (uint8_t * msg, size_t len, const MACKey& key, uint8_t * digest) void HMACMD5Digest (uint8_t * msg, size_t len, const MACKey& key, uint8_t * digest)
// key is 32 bytes // key is 32 bytes
// digest is 16 bytes // digest is 16 bytes
// block size is 64 bytes // block size is 64 bytes
{ {
uint64_t buf[256]; uint64_t buf[256];
uint64_t hash[12]; // 96 bytes
#if defined(__AVX__) // for AVX
__asm__
(
"vmovups %[key], %%ymm0 \n"
"vmovups %[ipad], %%ymm1 \n"
"vmovups %%ymm1, 32%[buf] \n"
"vxorps %%ymm0, %%ymm1, %%ymm1 \n"
"vmovups %%ymm1, %[buf] \n"
"vmovups %[opad], %%ymm1 \n"
"vmovups %%ymm1, 32%[hash] \n"
"vxorps %%ymm0, %%ymm1, %%ymm1 \n"
"vmovups %%ymm1, %[hash] \n"
: [buf]"=m"(*buf), [hash]"=m"(*hash)
: [key]"m"(*(const uint8_t *)key), [ipad]"m"(*ipads), [opad]"m"(*opads)
: "memory", "%xmm0", "%xmm1" // should be replaced by %ymm0/1 once supported by compiler
);
#else
// ikeypad // ikeypad
buf[0] = key.GetLL ()[0] ^ IPAD; buf[0] = key.GetLL ()[0] ^ IPAD;
buf[1] = key.GetLL ()[1] ^ IPAD; buf[1] = key.GetLL ()[1] ^ IPAD;
buf[2] = key.GetLL ()[2] ^ IPAD; buf[2] = key.GetLL ()[2] ^ IPAD;
buf[3] = key.GetLL ()[3] ^ IPAD; buf[3] = key.GetLL ()[3] ^ IPAD;
buf[4] = IPAD; memcpy (buf + 4, ipads, 32);
buf[5] = IPAD; // okeypad
buf[6] = IPAD; hash[0] = key.GetLL ()[0] ^ OPAD;
buf[7] = IPAD; hash[1] = key.GetLL ()[1] ^ OPAD;
hash[2] = key.GetLL ()[2] ^ OPAD;
hash[3] = key.GetLL ()[3] ^ OPAD;
memcpy (hash + 4, opads, 32);
#endif
// concatenate with msg // concatenate with msg
memcpy (buf + 8, msg, len); memcpy (buf + 8, msg, len);
// calculate first hash // calculate first hash
uint8_t hash[16]; // MD5 MD5((uint8_t *)buf, len + 64, (uint8_t *)(hash + 8)); // 16 bytes
MD5((uint8_t *)buf, len + 64, hash);
// okeypad // fill last 16 bytes with zeros (first hash size assumed 32 bytes in I2P)
buf[0] = key.GetLL ()[0] ^ OPAD; memset (hash + 10, 0, 16);
buf[1] = key.GetLL ()[1] ^ OPAD;
buf[2] = key.GetLL ()[2] ^ OPAD;
buf[3] = key.GetLL ()[3] ^ OPAD;
buf[4] = OPAD;
buf[5] = OPAD;
buf[6] = OPAD;
buf[7] = OPAD;
// copy first hash after okeypad
memcpy (buf + 8, hash, 16);
// fill next 16 bytes with zeros (first hash size assumed 32 bytes in I2P)
memset (buf + 10, 0, 16);
// calculate digest // calculate digest
MD5((uint8_t *)buf, 96, digest); MD5((uint8_t *)hash, 96, digest);
} }
// AES // AES