Initial Vexta Core v0.1.0 release
This commit is contained in:
commit
25c454329d
2481 changed files with 689289 additions and 0 deletions
41
src/crypto/KeccakP-800-SnP.h
Normal file
41
src/crypto/KeccakP-800-SnP.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
|
||||
Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby
|
||||
denoted as "the implementer".
|
||||
|
||||
For more information, feedback or questions, please refer to our websites:
|
||||
http://keccak.noekeon.org/
|
||||
http://keyak.noekeon.org/
|
||||
http://ketje.noekeon.org/
|
||||
|
||||
To the extent possible under law, the implementer has waived all copyright
|
||||
and related or neighboring rights to the source code in this file.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
#ifndef _KeccakP_800_SnP_h_
|
||||
#define _KeccakP_800_SnP_h_
|
||||
|
||||
/** For the documentation, see SnP-documentation.h.
|
||||
*/
|
||||
|
||||
#define KeccakP800_implementation "32-bit reference implementation"
|
||||
#define KeccakP800_stateSizeInBytes 100
|
||||
#define KeccakP800_stateAlignment 4
|
||||
|
||||
#ifdef KeccakReference
|
||||
void KeccakP800_StaticInitialize( void );
|
||||
#else
|
||||
#define KeccakP800_StaticInitialize()
|
||||
#endif
|
||||
void KeccakP800_Initialize(void *state);
|
||||
void KeccakP800_AddByte(void *state, unsigned char data, unsigned int offset);
|
||||
void KeccakP800_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
|
||||
void KeccakP800_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length);
|
||||
void KeccakP800_OverwriteWithZeroes(void *state, unsigned int byteCount);
|
||||
void KeccakP800_Permute_12rounds(void *state);
|
||||
void KeccakP800_Permute_22rounds(void *state);
|
||||
void KeccakP800_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length);
|
||||
void KeccakP800_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length);
|
||||
|
||||
#endif
|
||||
421
src/crypto/KeccakP-800-reference.cpp
Normal file
421
src/crypto/KeccakP-800-reference.cpp
Normal file
|
|
@ -0,0 +1,421 @@
|
|||
/*
|
||||
Implementation by the Keccak Team, namely, Guido Bertoni, Joan Daemen,
|
||||
Michaël Peeters, Gilles Van Assche and Ronny Van Keer,
|
||||
hereby denoted as "the implementer".
|
||||
|
||||
For more information, feedback or questions, please refer to our website:
|
||||
https://keccak.team/
|
||||
|
||||
To the extent possible under law, the implementer has waived all copyright
|
||||
and related or neighboring rights to the source code in this file.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
---
|
||||
|
||||
This file implements Keccak-p[800] in a SnP-compatible way.
|
||||
Please refer to SnP-documentation.h for more details.
|
||||
|
||||
This implementation comes with KeccakP-800-SnP.h in the same folder.
|
||||
Please refer to LowLevel.build for the exact list of other files it must be combined with.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "brg_endian.h"
|
||||
#ifdef KeccakReference
|
||||
#include "displayIntermediateValues.h"
|
||||
#endif
|
||||
|
||||
typedef unsigned char UINT8;
|
||||
typedef unsigned int UINT32;
|
||||
typedef UINT32 tKeccakLane;
|
||||
|
||||
#define maxNrRounds 22
|
||||
#define nrLanes 25
|
||||
#define index(x, y) (((x)%5)+5*((y)%5))
|
||||
|
||||
#ifdef KeccakReference
|
||||
|
||||
static tKeccakLane KeccakRoundConstants[maxNrRounds];
|
||||
static unsigned int KeccakRhoOffsets[nrLanes];
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_InitializeRoundConstants(void);
|
||||
void KeccakP800_InitializeRhoOffsets(void);
|
||||
static int LFSR86540(UINT8 *LFSR);
|
||||
|
||||
void KeccakP800_StaticInitialize(void)
|
||||
{
|
||||
if (sizeof(tKeccakLane) != 4) {
|
||||
printf("tKeccakLane should be 32-bit wide\n");
|
||||
abort();
|
||||
}
|
||||
KeccakP800_InitializeRoundConstants();
|
||||
KeccakP800_InitializeRhoOffsets();
|
||||
}
|
||||
|
||||
void KeccakP800_InitializeRoundConstants(void)
|
||||
{
|
||||
UINT8 LFSRstate = 0x01;
|
||||
unsigned int i, j, bitPosition;
|
||||
|
||||
for(i=0; i<maxNrRounds; i++) {
|
||||
KeccakRoundConstants[i] = 0;
|
||||
for(j=0; j<7; j++) {
|
||||
bitPosition = (1<<j)-1; /* 2^j-1 */
|
||||
if (LFSR86540(&LFSRstate) && (bitPosition < (sizeof(tKeccakLane)*8)))
|
||||
KeccakRoundConstants[i] ^= (tKeccakLane)(1<<bitPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeccakP800_InitializeRhoOffsets(void)
|
||||
{
|
||||
unsigned int x, y, t, newX, newY;
|
||||
|
||||
KeccakRhoOffsets[index(0, 0)] = 0;
|
||||
x = 1;
|
||||
y = 0;
|
||||
for(t=0; t<24; t++) {
|
||||
KeccakRhoOffsets[index(x, y)] = ((t+1)*(t+2)/2) % (sizeof(tKeccakLane) * 8);
|
||||
newX = (0*x+1*y) % 5;
|
||||
newY = (2*x+3*y) % 5;
|
||||
x = newX;
|
||||
y = newY;
|
||||
}
|
||||
}
|
||||
|
||||
static int LFSR86540(UINT8 *LFSR)
|
||||
{
|
||||
int result = ((*LFSR) & 0x01) != 0;
|
||||
if (((*LFSR) & 0x80) != 0)
|
||||
/* Primitive polynomial over GF(2): x^8+x^6+x^5+x^4+1 */
|
||||
(*LFSR) = ((*LFSR) << 1) ^ 0x71;
|
||||
else
|
||||
(*LFSR) <<= 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static const tKeccakLane KeccakRoundConstants[maxNrRounds] =
|
||||
{
|
||||
0x00000001,
|
||||
0x00008082,
|
||||
0x0000808a,
|
||||
0x80008000,
|
||||
0x0000808b,
|
||||
0x80000001,
|
||||
0x80008081,
|
||||
0x00008009,
|
||||
0x0000008a,
|
||||
0x00000088,
|
||||
0x80008009,
|
||||
0x8000000a,
|
||||
0x8000808b,
|
||||
0x0000008b,
|
||||
0x00008089,
|
||||
0x00008003,
|
||||
0x00008002,
|
||||
0x00000080,
|
||||
0x0000800a,
|
||||
0x8000000a,
|
||||
0x80008081,
|
||||
0x00008080,
|
||||
};
|
||||
|
||||
static const unsigned int KeccakRhoOffsets[nrLanes] =
|
||||
{
|
||||
0, 1, 30, 28, 27, 4, 12, 6, 23, 20, 3, 10, 11, 25, 7, 9, 13, 15, 21, 8, 18, 2, 29, 24, 14
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_Initialize(void *state)
|
||||
{
|
||||
memset(state, 0, 800/8);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_AddByte(void *state, unsigned char byte, unsigned int offset)
|
||||
{
|
||||
assert(offset < 100);
|
||||
((unsigned char *)state)[offset] ^= byte;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
assert(offset < 100);
|
||||
assert(offset+length <= 100);
|
||||
for(i=0; i<length; i++)
|
||||
((unsigned char *)state)[offset+i] ^= data[i];
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_OverwriteBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length)
|
||||
{
|
||||
assert(offset < 100);
|
||||
assert(offset+length <= 100);
|
||||
memcpy((unsigned char*)state+offset, data, length);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_OverwriteWithZeroes(void *state, unsigned int byteCount)
|
||||
{
|
||||
assert(byteCount <= 100);
|
||||
memset(state, 0, byteCount);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
static void fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char *state);
|
||||
static void fromWordsToBytes(unsigned char *state, const tKeccakLane *stateAsWords);
|
||||
void KeccakP800OnWords(tKeccakLane *state, unsigned int nrRounds);
|
||||
void KeccakP800Round(tKeccakLane *state, unsigned int indexRound);
|
||||
static void theta(tKeccakLane *A);
|
||||
static void rho(tKeccakLane *A);
|
||||
static void pi(tKeccakLane *A);
|
||||
static void chi(tKeccakLane *A);
|
||||
static void iota(tKeccakLane *A, unsigned int indexRound);
|
||||
|
||||
void KeccakP800_Permute_Nrounds(void *state, unsigned int nrounds)
|
||||
{
|
||||
#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
|
||||
tKeccakLane stateAsWords[800/32];
|
||||
#endif
|
||||
|
||||
#ifdef KeccakReference
|
||||
displayStateAsBytes(1, "Input of permutation", (const unsigned char *)state, 800);
|
||||
#endif
|
||||
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
|
||||
KeccakP800OnWords((tKeccakLane*)state, nrounds);
|
||||
#else
|
||||
fromBytesToWords(stateAsWords, (const unsigned char *)state);
|
||||
KeccakP800OnWords(stateAsWords, nrounds);
|
||||
fromWordsToBytes((unsigned char *)state, stateAsWords);
|
||||
#endif
|
||||
#ifdef KeccakReference
|
||||
displayStateAsBytes(1, "State after permutation", (const unsigned char *)state, 800);
|
||||
#endif
|
||||
}
|
||||
|
||||
void KeccakP800_Permute_12rounds(void *state)
|
||||
{
|
||||
#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
|
||||
tKeccakLane stateAsWords[800/32];
|
||||
#endif
|
||||
|
||||
#ifdef KeccakReference
|
||||
displayStateAsBytes(1, "Input of permutation", (const unsigned char *)state, 800);
|
||||
#endif
|
||||
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
|
||||
KeccakP800OnWords((tKeccakLane*)state, 12);
|
||||
#else
|
||||
fromBytesToWords(stateAsWords, (const unsigned char *)state);
|
||||
KeccakP800OnWords(stateAsWords, 12);
|
||||
fromWordsToBytes((unsigned char *)state, stateAsWords);
|
||||
#endif
|
||||
#ifdef KeccakReference
|
||||
displayStateAsBytes(1, "State after permutation", (const unsigned char *)state, 800);
|
||||
#endif
|
||||
}
|
||||
|
||||
void KeccakP800_Permute_22rounds(void *state)
|
||||
{
|
||||
#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN)
|
||||
tKeccakLane stateAsWords[800/32];
|
||||
#endif
|
||||
|
||||
#ifdef KeccakReference
|
||||
displayStateAsBytes(1, "Input of permutation", (const unsigned char *)state, 800);
|
||||
#endif
|
||||
#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
|
||||
KeccakP800OnWords((tKeccakLane*)state, 22);
|
||||
#else
|
||||
fromBytesToWords(stateAsWords, (const unsigned char *)state);
|
||||
KeccakP800OnWords(stateAsWords, 22);
|
||||
fromWordsToBytes((unsigned char *)state, stateAsWords);
|
||||
#endif
|
||||
#ifdef KeccakReference
|
||||
displayStateAsBytes(1, "State after permutation", (const unsigned char *)state, 800);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char *state)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for(i=0; i<nrLanes; i++) {
|
||||
stateAsWords[i] = 0;
|
||||
for(j=0; j<sizeof(tKeccakLane); j++)
|
||||
stateAsWords[i] |= (tKeccakLane)(state[i*sizeof(tKeccakLane)+j]) << (8*j);
|
||||
}
|
||||
}
|
||||
|
||||
static void fromWordsToBytes(unsigned char *state, const tKeccakLane *stateAsWords)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for(i=0; i<nrLanes; i++)
|
||||
for(j=0; j<sizeof(tKeccakLane); j++)
|
||||
state[i*sizeof(tKeccakLane)+j] = (stateAsWords[i] >> (8*j)) & 0xFF;
|
||||
}
|
||||
|
||||
void KeccakP800OnWords(tKeccakLane *state, unsigned int nrRounds)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
#ifdef KeccakReference
|
||||
displayStateAsLanes(3, "Same, with lanes as 32-bit words", state, 800);
|
||||
#endif
|
||||
|
||||
for(i=(maxNrRounds-nrRounds); i<maxNrRounds; i++)
|
||||
KeccakP800Round(state, i);
|
||||
}
|
||||
|
||||
void KeccakP800Round(tKeccakLane *state, unsigned int indexRound)
|
||||
{
|
||||
#ifdef KeccakReference
|
||||
displayRoundNumber(3, indexRound);
|
||||
#endif
|
||||
|
||||
theta(state);
|
||||
#ifdef KeccakReference
|
||||
displayStateAsLanes(3, "After theta", state, 800);
|
||||
#endif
|
||||
|
||||
rho(state);
|
||||
#ifdef KeccakReference
|
||||
displayStateAsLanes(3, "After rho", state, 800);
|
||||
#endif
|
||||
|
||||
pi(state);
|
||||
#ifdef KeccakReference
|
||||
displayStateAsLanes(3, "After pi", state, 800);
|
||||
#endif
|
||||
|
||||
chi(state);
|
||||
#ifdef KeccakReference
|
||||
displayStateAsLanes(3, "After chi", state, 800);
|
||||
#endif
|
||||
|
||||
iota(state, indexRound);
|
||||
#ifdef KeccakReference
|
||||
displayStateAsLanes(3, "After iota", state, 800);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ROL32(a, offset) ((offset != 0) ? ((((tKeccakLane)a) << offset) ^ (((tKeccakLane)a) >> (sizeof(tKeccakLane)*8-offset))) : a)
|
||||
|
||||
static void theta(tKeccakLane *A)
|
||||
{
|
||||
unsigned int x, y;
|
||||
tKeccakLane C[5], D[5];
|
||||
|
||||
for(x=0; x<5; x++) {
|
||||
C[x] = 0;
|
||||
for(y=0; y<5; y++)
|
||||
C[x] ^= A[index(x, y)];
|
||||
}
|
||||
for(x=0; x<5; x++)
|
||||
D[x] = ROL32(C[(x+1)%5], 1) ^ C[(x+4)%5];
|
||||
for(x=0; x<5; x++)
|
||||
for(y=0; y<5; y++)
|
||||
A[index(x, y)] ^= D[x];
|
||||
}
|
||||
|
||||
static void rho(tKeccakLane *A)
|
||||
{
|
||||
unsigned int x, y;
|
||||
|
||||
for(x=0; x<5; x++) for(y=0; y<5; y++)
|
||||
A[index(x, y)] = ROL32(A[index(x, y)], KeccakRhoOffsets[index(x, y)]);
|
||||
}
|
||||
|
||||
static void pi(tKeccakLane *A)
|
||||
{
|
||||
unsigned int x, y;
|
||||
tKeccakLane tempA[25];
|
||||
|
||||
for(x=0; x<5; x++) for(y=0; y<5; y++)
|
||||
tempA[index(x, y)] = A[index(x, y)];
|
||||
for(x=0; x<5; x++) for(y=0; y<5; y++)
|
||||
A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)];
|
||||
}
|
||||
|
||||
static void chi(tKeccakLane *A)
|
||||
{
|
||||
unsigned int x, y;
|
||||
tKeccakLane C[5];
|
||||
|
||||
for(y=0; y<5; y++) {
|
||||
for(x=0; x<5; x++)
|
||||
C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]);
|
||||
for(x=0; x<5; x++)
|
||||
A[index(x, y)] = C[x];
|
||||
}
|
||||
}
|
||||
|
||||
static void iota(tKeccakLane *A, unsigned int indexRound)
|
||||
{
|
||||
A[index(0, 0)] ^= KeccakRoundConstants[indexRound];
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length)
|
||||
{
|
||||
assert(offset < 100);
|
||||
assert(offset+length <= 100);
|
||||
memcpy(data, (unsigned char*)state+offset, length);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_ExtractAndAddBytes(const void *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
assert(offset < 100);
|
||||
assert(offset+length <= 100);
|
||||
for(i=0; i<length; i++)
|
||||
output[i] = input[i] ^ ((unsigned char *)state)[offset+i];
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------- */
|
||||
|
||||
void KeccakP800_DisplayRoundConstants(FILE *f)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for(i=0; i<maxNrRounds; i++) {
|
||||
fprintf(f, "RC[%02i][0][0] = ", i);
|
||||
fprintf(f, "%08X", (unsigned int)(KeccakRoundConstants[i]));
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
||||
void KeccakP800_DisplayRhoOffsets(FILE *f)
|
||||
{
|
||||
unsigned int x, y;
|
||||
|
||||
for(y=0; y<5; y++) for(x=0; x<5; x++) {
|
||||
fprintf(f, "RhoOffset[%i][%i] = ", x, y);
|
||||
fprintf(f, "%2i", KeccakRhoOffsets[index(x, y)]);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
151
src/crypto/aes.cpp
Normal file
151
src/crypto/aes.cpp
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <crypto/aes.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <crypto/ctaes/ctaes.cpp>
|
||||
|
||||
AES256Encrypt::AES256Encrypt(const unsigned char key[32])
|
||||
{
|
||||
AES256_init(&ctx, key);
|
||||
}
|
||||
|
||||
AES256Encrypt::~AES256Encrypt()
|
||||
{
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
}
|
||||
|
||||
void AES256Encrypt::Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const
|
||||
{
|
||||
AES256_encrypt(&ctx, 1, ciphertext, plaintext);
|
||||
}
|
||||
|
||||
AES256Decrypt::AES256Decrypt(const unsigned char key[32])
|
||||
{
|
||||
AES256_init(&ctx, key);
|
||||
}
|
||||
|
||||
AES256Decrypt::~AES256Decrypt()
|
||||
{
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
}
|
||||
|
||||
void AES256Decrypt::Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const
|
||||
{
|
||||
AES256_decrypt(&ctx, 1, plaintext, ciphertext);
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
static int CBCEncrypt(const T& enc, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out)
|
||||
{
|
||||
int written = 0;
|
||||
int padsize = size % AES_BLOCKSIZE;
|
||||
unsigned char mixed[AES_BLOCKSIZE];
|
||||
|
||||
if (!data || !size || !out)
|
||||
return 0;
|
||||
|
||||
if (!pad && padsize != 0)
|
||||
return 0;
|
||||
|
||||
memcpy(mixed, iv, AES_BLOCKSIZE);
|
||||
|
||||
// Write all but the last block
|
||||
while (written + AES_BLOCKSIZE <= size) {
|
||||
for (int i = 0; i != AES_BLOCKSIZE; i++)
|
||||
mixed[i] ^= *data++;
|
||||
enc.Encrypt(out + written, mixed);
|
||||
memcpy(mixed, out + written, AES_BLOCKSIZE);
|
||||
written += AES_BLOCKSIZE;
|
||||
}
|
||||
if (pad) {
|
||||
// For all that remains, pad each byte with the value of the remaining
|
||||
// space. If there is none, pad by a full block.
|
||||
for (int i = 0; i != padsize; i++)
|
||||
mixed[i] ^= *data++;
|
||||
for (int i = padsize; i != AES_BLOCKSIZE; i++)
|
||||
mixed[i] ^= AES_BLOCKSIZE - padsize;
|
||||
enc.Encrypt(out + written, mixed);
|
||||
written += AES_BLOCKSIZE;
|
||||
}
|
||||
return written;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static int CBCDecrypt(const T& dec, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out)
|
||||
{
|
||||
int written = 0;
|
||||
bool fail = false;
|
||||
const unsigned char* prev = iv;
|
||||
|
||||
if (!data || !size || !out)
|
||||
return 0;
|
||||
|
||||
if (size % AES_BLOCKSIZE != 0)
|
||||
return 0;
|
||||
|
||||
// Decrypt all data. Padding will be checked in the output.
|
||||
while (written != size) {
|
||||
dec.Decrypt(out, data + written);
|
||||
for (int i = 0; i != AES_BLOCKSIZE; i++)
|
||||
*out++ ^= prev[i];
|
||||
prev = data + written;
|
||||
written += AES_BLOCKSIZE;
|
||||
}
|
||||
|
||||
// When decrypting padding, attempt to run in constant-time
|
||||
if (pad) {
|
||||
// If used, padding size is the value of the last decrypted byte. For
|
||||
// it to be valid, It must be between 1 and AES_BLOCKSIZE.
|
||||
unsigned char padsize = *--out;
|
||||
fail = !padsize | (padsize > AES_BLOCKSIZE);
|
||||
|
||||
// If not well-formed, treat it as though there's no padding.
|
||||
padsize *= !fail;
|
||||
|
||||
// All padding must equal the last byte otherwise it's not well-formed
|
||||
for (int i = AES_BLOCKSIZE; i != 0; i--)
|
||||
fail |= ((i > AES_BLOCKSIZE - padsize) & (*out-- != padsize));
|
||||
|
||||
written -= padsize;
|
||||
}
|
||||
return written * !fail;
|
||||
}
|
||||
|
||||
AES256CBCEncrypt::AES256CBCEncrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
|
||||
: enc(key), pad(padIn)
|
||||
{
|
||||
memcpy(iv, ivIn, AES_BLOCKSIZE);
|
||||
}
|
||||
|
||||
int AES256CBCEncrypt::Encrypt(const unsigned char* data, int size, unsigned char* out) const
|
||||
{
|
||||
return CBCEncrypt(enc, iv, data, size, pad, out);
|
||||
}
|
||||
|
||||
AES256CBCEncrypt::~AES256CBCEncrypt()
|
||||
{
|
||||
memset(iv, 0, sizeof(iv));
|
||||
}
|
||||
|
||||
AES256CBCDecrypt::AES256CBCDecrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
|
||||
: dec(key), pad(padIn)
|
||||
{
|
||||
memcpy(iv, ivIn, AES_BLOCKSIZE);
|
||||
}
|
||||
|
||||
|
||||
int AES256CBCDecrypt::Decrypt(const unsigned char* data, int size, unsigned char* out) const
|
||||
{
|
||||
return CBCDecrypt(dec, iv, data, size, pad, out);
|
||||
}
|
||||
|
||||
AES256CBCDecrypt::~AES256CBCDecrypt()
|
||||
{
|
||||
memset(iv, 0, sizeof(iv));
|
||||
}
|
||||
68
src/crypto/aes.h
Normal file
68
src/crypto/aes.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
//
|
||||
// C++ wrapper around ctaes, a constant-time AES implementation
|
||||
|
||||
#ifndef DIGIBYTE_CRYPTO_AES_H
|
||||
#define DIGIBYTE_CRYPTO_AES_H
|
||||
|
||||
extern "C" {
|
||||
#include <crypto/ctaes/ctaes.h>
|
||||
}
|
||||
|
||||
static const int AES_BLOCKSIZE = 16;
|
||||
static const int AES256_KEYSIZE = 32;
|
||||
|
||||
/** An encryption class for AES-256. */
|
||||
class AES256Encrypt
|
||||
{
|
||||
private:
|
||||
AES256_ctx ctx;
|
||||
|
||||
public:
|
||||
explicit AES256Encrypt(const unsigned char key[32]);
|
||||
~AES256Encrypt();
|
||||
void Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const;
|
||||
};
|
||||
|
||||
/** A decryption class for AES-256. */
|
||||
class AES256Decrypt
|
||||
{
|
||||
private:
|
||||
AES256_ctx ctx;
|
||||
|
||||
public:
|
||||
explicit AES256Decrypt(const unsigned char key[32]);
|
||||
~AES256Decrypt();
|
||||
void Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const;
|
||||
};
|
||||
|
||||
class AES256CBCEncrypt
|
||||
{
|
||||
public:
|
||||
AES256CBCEncrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn);
|
||||
~AES256CBCEncrypt();
|
||||
int Encrypt(const unsigned char* data, int size, unsigned char* out) const;
|
||||
|
||||
private:
|
||||
const AES256Encrypt enc;
|
||||
const bool pad;
|
||||
unsigned char iv[AES_BLOCKSIZE];
|
||||
};
|
||||
|
||||
class AES256CBCDecrypt
|
||||
{
|
||||
public:
|
||||
AES256CBCDecrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn);
|
||||
~AES256CBCDecrypt();
|
||||
int Decrypt(const unsigned char* data, int size, unsigned char* out) const;
|
||||
|
||||
private:
|
||||
const AES256Decrypt dec;
|
||||
const bool pad;
|
||||
unsigned char iv[AES_BLOCKSIZE];
|
||||
};
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_AES_H
|
||||
392
src/crypto/aes_helper.cpp
Normal file
392
src/crypto/aes_helper.cpp
Normal file
|
|
@ -0,0 +1,392 @@
|
|||
/* $Id: aes_helper.c 220 2010-06-09 09:21:50Z tp $ */
|
||||
/*
|
||||
* AES tables. This file is not meant to be compiled by itself; it
|
||||
* is included by some hash function implementations. It contains
|
||||
* the precomputed tables and helper macros for evaluating an AES
|
||||
* round, optionally with a final XOR with a subkey.
|
||||
*
|
||||
* By default, this file defines the tables and macros for little-endian
|
||||
* processing (i.e. it is assumed that the input bytes have been read
|
||||
* from memory and assembled with the little-endian convention). If
|
||||
* the 'AES_BIG_ENDIAN' macro is defined (to a non-zero integer value)
|
||||
* when this file is included, then the tables and macros for big-endian
|
||||
* processing are defined instead. The big-endian tables and macros have
|
||||
* names distinct from the little-endian tables and macros, hence it is
|
||||
* possible to have both simultaneously, by including this file twice
|
||||
* (with and without the AES_BIG_ENDIAN macro).
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#include "sph_types.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
#if AES_BIG_ENDIAN
|
||||
|
||||
#define AESx(x) ( ((SPH_C32(x) >> 24) & SPH_C32(0x000000FF)) \
|
||||
| ((SPH_C32(x) >> 8) & SPH_C32(0x0000FF00)) \
|
||||
| ((SPH_C32(x) << 8) & SPH_C32(0x00FF0000)) \
|
||||
| ((SPH_C32(x) << 24) & SPH_C32(0xFF000000)))
|
||||
|
||||
#define AES0 AES0_BE
|
||||
#define AES1 AES1_BE
|
||||
#define AES2 AES2_BE
|
||||
#define AES3 AES3_BE
|
||||
|
||||
#define AES_ROUND_BE(X0, X1, X2, X3, K0, K1, K2, K3, Y0, Y1, Y2, Y3) do { \
|
||||
(Y0) = AES0[((X0) >> 24) & 0xFF] \
|
||||
^ AES1[((X1) >> 16) & 0xFF] \
|
||||
^ AES2[((X2) >> 8) & 0xFF] \
|
||||
^ AES3[(X3) & 0xFF] ^ (K0); \
|
||||
(Y1) = AES0[((X1) >> 24) & 0xFF] \
|
||||
^ AES1[((X2) >> 16) & 0xFF] \
|
||||
^ AES2[((X3) >> 8) & 0xFF] \
|
||||
^ AES3[(X0) & 0xFF] ^ (K1); \
|
||||
(Y2) = AES0[((X2) >> 24) & 0xFF] \
|
||||
^ AES1[((X3) >> 16) & 0xFF] \
|
||||
^ AES2[((X0) >> 8) & 0xFF] \
|
||||
^ AES3[(X1) & 0xFF] ^ (K2); \
|
||||
(Y3) = AES0[((X3) >> 24) & 0xFF] \
|
||||
^ AES1[((X0) >> 16) & 0xFF] \
|
||||
^ AES2[((X1) >> 8) & 0xFF] \
|
||||
^ AES3[(X2) & 0xFF] ^ (K3); \
|
||||
} while (0)
|
||||
|
||||
#define AES_ROUND_NOKEY_BE(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
|
||||
AES_ROUND_BE(X0, X1, X2, X3, 0, 0, 0, 0, Y0, Y1, Y2, Y3)
|
||||
|
||||
#else
|
||||
|
||||
#define AESx(x) SPH_C32(x)
|
||||
#define AES0 AES0_LE
|
||||
#define AES1 AES1_LE
|
||||
#define AES2 AES2_LE
|
||||
#define AES3 AES3_LE
|
||||
|
||||
#define AES_ROUND_LE(X0, X1, X2, X3, K0, K1, K2, K3, Y0, Y1, Y2, Y3) do { \
|
||||
(Y0) = AES0[(X0) & 0xFF] \
|
||||
^ AES1[((X1) >> 8) & 0xFF] \
|
||||
^ AES2[((X2) >> 16) & 0xFF] \
|
||||
^ AES3[((X3) >> 24) & 0xFF] ^ (K0); \
|
||||
(Y1) = AES0[(X1) & 0xFF] \
|
||||
^ AES1[((X2) >> 8) & 0xFF] \
|
||||
^ AES2[((X3) >> 16) & 0xFF] \
|
||||
^ AES3[((X0) >> 24) & 0xFF] ^ (K1); \
|
||||
(Y2) = AES0[(X2) & 0xFF] \
|
||||
^ AES1[((X3) >> 8) & 0xFF] \
|
||||
^ AES2[((X0) >> 16) & 0xFF] \
|
||||
^ AES3[((X1) >> 24) & 0xFF] ^ (K2); \
|
||||
(Y3) = AES0[(X3) & 0xFF] \
|
||||
^ AES1[((X0) >> 8) & 0xFF] \
|
||||
^ AES2[((X1) >> 16) & 0xFF] \
|
||||
^ AES3[((X2) >> 24) & 0xFF] ^ (K3); \
|
||||
} while (0)
|
||||
|
||||
#define AES_ROUND_NOKEY_LE(X0, X1, X2, X3, Y0, Y1, Y2, Y3) \
|
||||
AES_ROUND_LE(X0, X1, X2, X3, 0, 0, 0, 0, Y0, Y1, Y2, Y3)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The AES*[] tables allow us to perform a fast evaluation of an AES
|
||||
* round; table AESi[] combines SubBytes for a byte at row i, and
|
||||
* MixColumns for the column where that byte goes after ShiftRows.
|
||||
*/
|
||||
|
||||
static const sph_u32 AES0[256] = {
|
||||
AESx(0xA56363C6), AESx(0x847C7CF8), AESx(0x997777EE), AESx(0x8D7B7BF6),
|
||||
AESx(0x0DF2F2FF), AESx(0xBD6B6BD6), AESx(0xB16F6FDE), AESx(0x54C5C591),
|
||||
AESx(0x50303060), AESx(0x03010102), AESx(0xA96767CE), AESx(0x7D2B2B56),
|
||||
AESx(0x19FEFEE7), AESx(0x62D7D7B5), AESx(0xE6ABAB4D), AESx(0x9A7676EC),
|
||||
AESx(0x45CACA8F), AESx(0x9D82821F), AESx(0x40C9C989), AESx(0x877D7DFA),
|
||||
AESx(0x15FAFAEF), AESx(0xEB5959B2), AESx(0xC947478E), AESx(0x0BF0F0FB),
|
||||
AESx(0xECADAD41), AESx(0x67D4D4B3), AESx(0xFDA2A25F), AESx(0xEAAFAF45),
|
||||
AESx(0xBF9C9C23), AESx(0xF7A4A453), AESx(0x967272E4), AESx(0x5BC0C09B),
|
||||
AESx(0xC2B7B775), AESx(0x1CFDFDE1), AESx(0xAE93933D), AESx(0x6A26264C),
|
||||
AESx(0x5A36366C), AESx(0x413F3F7E), AESx(0x02F7F7F5), AESx(0x4FCCCC83),
|
||||
AESx(0x5C343468), AESx(0xF4A5A551), AESx(0x34E5E5D1), AESx(0x08F1F1F9),
|
||||
AESx(0x937171E2), AESx(0x73D8D8AB), AESx(0x53313162), AESx(0x3F15152A),
|
||||
AESx(0x0C040408), AESx(0x52C7C795), AESx(0x65232346), AESx(0x5EC3C39D),
|
||||
AESx(0x28181830), AESx(0xA1969637), AESx(0x0F05050A), AESx(0xB59A9A2F),
|
||||
AESx(0x0907070E), AESx(0x36121224), AESx(0x9B80801B), AESx(0x3DE2E2DF),
|
||||
AESx(0x26EBEBCD), AESx(0x6927274E), AESx(0xCDB2B27F), AESx(0x9F7575EA),
|
||||
AESx(0x1B090912), AESx(0x9E83831D), AESx(0x742C2C58), AESx(0x2E1A1A34),
|
||||
AESx(0x2D1B1B36), AESx(0xB26E6EDC), AESx(0xEE5A5AB4), AESx(0xFBA0A05B),
|
||||
AESx(0xF65252A4), AESx(0x4D3B3B76), AESx(0x61D6D6B7), AESx(0xCEB3B37D),
|
||||
AESx(0x7B292952), AESx(0x3EE3E3DD), AESx(0x712F2F5E), AESx(0x97848413),
|
||||
AESx(0xF55353A6), AESx(0x68D1D1B9), AESx(0x00000000), AESx(0x2CEDEDC1),
|
||||
AESx(0x60202040), AESx(0x1FFCFCE3), AESx(0xC8B1B179), AESx(0xED5B5BB6),
|
||||
AESx(0xBE6A6AD4), AESx(0x46CBCB8D), AESx(0xD9BEBE67), AESx(0x4B393972),
|
||||
AESx(0xDE4A4A94), AESx(0xD44C4C98), AESx(0xE85858B0), AESx(0x4ACFCF85),
|
||||
AESx(0x6BD0D0BB), AESx(0x2AEFEFC5), AESx(0xE5AAAA4F), AESx(0x16FBFBED),
|
||||
AESx(0xC5434386), AESx(0xD74D4D9A), AESx(0x55333366), AESx(0x94858511),
|
||||
AESx(0xCF45458A), AESx(0x10F9F9E9), AESx(0x06020204), AESx(0x817F7FFE),
|
||||
AESx(0xF05050A0), AESx(0x443C3C78), AESx(0xBA9F9F25), AESx(0xE3A8A84B),
|
||||
AESx(0xF35151A2), AESx(0xFEA3A35D), AESx(0xC0404080), AESx(0x8A8F8F05),
|
||||
AESx(0xAD92923F), AESx(0xBC9D9D21), AESx(0x48383870), AESx(0x04F5F5F1),
|
||||
AESx(0xDFBCBC63), AESx(0xC1B6B677), AESx(0x75DADAAF), AESx(0x63212142),
|
||||
AESx(0x30101020), AESx(0x1AFFFFE5), AESx(0x0EF3F3FD), AESx(0x6DD2D2BF),
|
||||
AESx(0x4CCDCD81), AESx(0x140C0C18), AESx(0x35131326), AESx(0x2FECECC3),
|
||||
AESx(0xE15F5FBE), AESx(0xA2979735), AESx(0xCC444488), AESx(0x3917172E),
|
||||
AESx(0x57C4C493), AESx(0xF2A7A755), AESx(0x827E7EFC), AESx(0x473D3D7A),
|
||||
AESx(0xAC6464C8), AESx(0xE75D5DBA), AESx(0x2B191932), AESx(0x957373E6),
|
||||
AESx(0xA06060C0), AESx(0x98818119), AESx(0xD14F4F9E), AESx(0x7FDCDCA3),
|
||||
AESx(0x66222244), AESx(0x7E2A2A54), AESx(0xAB90903B), AESx(0x8388880B),
|
||||
AESx(0xCA46468C), AESx(0x29EEEEC7), AESx(0xD3B8B86B), AESx(0x3C141428),
|
||||
AESx(0x79DEDEA7), AESx(0xE25E5EBC), AESx(0x1D0B0B16), AESx(0x76DBDBAD),
|
||||
AESx(0x3BE0E0DB), AESx(0x56323264), AESx(0x4E3A3A74), AESx(0x1E0A0A14),
|
||||
AESx(0xDB494992), AESx(0x0A06060C), AESx(0x6C242448), AESx(0xE45C5CB8),
|
||||
AESx(0x5DC2C29F), AESx(0x6ED3D3BD), AESx(0xEFACAC43), AESx(0xA66262C4),
|
||||
AESx(0xA8919139), AESx(0xA4959531), AESx(0x37E4E4D3), AESx(0x8B7979F2),
|
||||
AESx(0x32E7E7D5), AESx(0x43C8C88B), AESx(0x5937376E), AESx(0xB76D6DDA),
|
||||
AESx(0x8C8D8D01), AESx(0x64D5D5B1), AESx(0xD24E4E9C), AESx(0xE0A9A949),
|
||||
AESx(0xB46C6CD8), AESx(0xFA5656AC), AESx(0x07F4F4F3), AESx(0x25EAEACF),
|
||||
AESx(0xAF6565CA), AESx(0x8E7A7AF4), AESx(0xE9AEAE47), AESx(0x18080810),
|
||||
AESx(0xD5BABA6F), AESx(0x887878F0), AESx(0x6F25254A), AESx(0x722E2E5C),
|
||||
AESx(0x241C1C38), AESx(0xF1A6A657), AESx(0xC7B4B473), AESx(0x51C6C697),
|
||||
AESx(0x23E8E8CB), AESx(0x7CDDDDA1), AESx(0x9C7474E8), AESx(0x211F1F3E),
|
||||
AESx(0xDD4B4B96), AESx(0xDCBDBD61), AESx(0x868B8B0D), AESx(0x858A8A0F),
|
||||
AESx(0x907070E0), AESx(0x423E3E7C), AESx(0xC4B5B571), AESx(0xAA6666CC),
|
||||
AESx(0xD8484890), AESx(0x05030306), AESx(0x01F6F6F7), AESx(0x120E0E1C),
|
||||
AESx(0xA36161C2), AESx(0x5F35356A), AESx(0xF95757AE), AESx(0xD0B9B969),
|
||||
AESx(0x91868617), AESx(0x58C1C199), AESx(0x271D1D3A), AESx(0xB99E9E27),
|
||||
AESx(0x38E1E1D9), AESx(0x13F8F8EB), AESx(0xB398982B), AESx(0x33111122),
|
||||
AESx(0xBB6969D2), AESx(0x70D9D9A9), AESx(0x898E8E07), AESx(0xA7949433),
|
||||
AESx(0xB69B9B2D), AESx(0x221E1E3C), AESx(0x92878715), AESx(0x20E9E9C9),
|
||||
AESx(0x49CECE87), AESx(0xFF5555AA), AESx(0x78282850), AESx(0x7ADFDFA5),
|
||||
AESx(0x8F8C8C03), AESx(0xF8A1A159), AESx(0x80898909), AESx(0x170D0D1A),
|
||||
AESx(0xDABFBF65), AESx(0x31E6E6D7), AESx(0xC6424284), AESx(0xB86868D0),
|
||||
AESx(0xC3414182), AESx(0xB0999929), AESx(0x772D2D5A), AESx(0x110F0F1E),
|
||||
AESx(0xCBB0B07B), AESx(0xFC5454A8), AESx(0xD6BBBB6D), AESx(0x3A16162C)
|
||||
};
|
||||
|
||||
static const sph_u32 AES1[256] = {
|
||||
AESx(0x6363C6A5), AESx(0x7C7CF884), AESx(0x7777EE99), AESx(0x7B7BF68D),
|
||||
AESx(0xF2F2FF0D), AESx(0x6B6BD6BD), AESx(0x6F6FDEB1), AESx(0xC5C59154),
|
||||
AESx(0x30306050), AESx(0x01010203), AESx(0x6767CEA9), AESx(0x2B2B567D),
|
||||
AESx(0xFEFEE719), AESx(0xD7D7B562), AESx(0xABAB4DE6), AESx(0x7676EC9A),
|
||||
AESx(0xCACA8F45), AESx(0x82821F9D), AESx(0xC9C98940), AESx(0x7D7DFA87),
|
||||
AESx(0xFAFAEF15), AESx(0x5959B2EB), AESx(0x47478EC9), AESx(0xF0F0FB0B),
|
||||
AESx(0xADAD41EC), AESx(0xD4D4B367), AESx(0xA2A25FFD), AESx(0xAFAF45EA),
|
||||
AESx(0x9C9C23BF), AESx(0xA4A453F7), AESx(0x7272E496), AESx(0xC0C09B5B),
|
||||
AESx(0xB7B775C2), AESx(0xFDFDE11C), AESx(0x93933DAE), AESx(0x26264C6A),
|
||||
AESx(0x36366C5A), AESx(0x3F3F7E41), AESx(0xF7F7F502), AESx(0xCCCC834F),
|
||||
AESx(0x3434685C), AESx(0xA5A551F4), AESx(0xE5E5D134), AESx(0xF1F1F908),
|
||||
AESx(0x7171E293), AESx(0xD8D8AB73), AESx(0x31316253), AESx(0x15152A3F),
|
||||
AESx(0x0404080C), AESx(0xC7C79552), AESx(0x23234665), AESx(0xC3C39D5E),
|
||||
AESx(0x18183028), AESx(0x969637A1), AESx(0x05050A0F), AESx(0x9A9A2FB5),
|
||||
AESx(0x07070E09), AESx(0x12122436), AESx(0x80801B9B), AESx(0xE2E2DF3D),
|
||||
AESx(0xEBEBCD26), AESx(0x27274E69), AESx(0xB2B27FCD), AESx(0x7575EA9F),
|
||||
AESx(0x0909121B), AESx(0x83831D9E), AESx(0x2C2C5874), AESx(0x1A1A342E),
|
||||
AESx(0x1B1B362D), AESx(0x6E6EDCB2), AESx(0x5A5AB4EE), AESx(0xA0A05BFB),
|
||||
AESx(0x5252A4F6), AESx(0x3B3B764D), AESx(0xD6D6B761), AESx(0xB3B37DCE),
|
||||
AESx(0x2929527B), AESx(0xE3E3DD3E), AESx(0x2F2F5E71), AESx(0x84841397),
|
||||
AESx(0x5353A6F5), AESx(0xD1D1B968), AESx(0x00000000), AESx(0xEDEDC12C),
|
||||
AESx(0x20204060), AESx(0xFCFCE31F), AESx(0xB1B179C8), AESx(0x5B5BB6ED),
|
||||
AESx(0x6A6AD4BE), AESx(0xCBCB8D46), AESx(0xBEBE67D9), AESx(0x3939724B),
|
||||
AESx(0x4A4A94DE), AESx(0x4C4C98D4), AESx(0x5858B0E8), AESx(0xCFCF854A),
|
||||
AESx(0xD0D0BB6B), AESx(0xEFEFC52A), AESx(0xAAAA4FE5), AESx(0xFBFBED16),
|
||||
AESx(0x434386C5), AESx(0x4D4D9AD7), AESx(0x33336655), AESx(0x85851194),
|
||||
AESx(0x45458ACF), AESx(0xF9F9E910), AESx(0x02020406), AESx(0x7F7FFE81),
|
||||
AESx(0x5050A0F0), AESx(0x3C3C7844), AESx(0x9F9F25BA), AESx(0xA8A84BE3),
|
||||
AESx(0x5151A2F3), AESx(0xA3A35DFE), AESx(0x404080C0), AESx(0x8F8F058A),
|
||||
AESx(0x92923FAD), AESx(0x9D9D21BC), AESx(0x38387048), AESx(0xF5F5F104),
|
||||
AESx(0xBCBC63DF), AESx(0xB6B677C1), AESx(0xDADAAF75), AESx(0x21214263),
|
||||
AESx(0x10102030), AESx(0xFFFFE51A), AESx(0xF3F3FD0E), AESx(0xD2D2BF6D),
|
||||
AESx(0xCDCD814C), AESx(0x0C0C1814), AESx(0x13132635), AESx(0xECECC32F),
|
||||
AESx(0x5F5FBEE1), AESx(0x979735A2), AESx(0x444488CC), AESx(0x17172E39),
|
||||
AESx(0xC4C49357), AESx(0xA7A755F2), AESx(0x7E7EFC82), AESx(0x3D3D7A47),
|
||||
AESx(0x6464C8AC), AESx(0x5D5DBAE7), AESx(0x1919322B), AESx(0x7373E695),
|
||||
AESx(0x6060C0A0), AESx(0x81811998), AESx(0x4F4F9ED1), AESx(0xDCDCA37F),
|
||||
AESx(0x22224466), AESx(0x2A2A547E), AESx(0x90903BAB), AESx(0x88880B83),
|
||||
AESx(0x46468CCA), AESx(0xEEEEC729), AESx(0xB8B86BD3), AESx(0x1414283C),
|
||||
AESx(0xDEDEA779), AESx(0x5E5EBCE2), AESx(0x0B0B161D), AESx(0xDBDBAD76),
|
||||
AESx(0xE0E0DB3B), AESx(0x32326456), AESx(0x3A3A744E), AESx(0x0A0A141E),
|
||||
AESx(0x494992DB), AESx(0x06060C0A), AESx(0x2424486C), AESx(0x5C5CB8E4),
|
||||
AESx(0xC2C29F5D), AESx(0xD3D3BD6E), AESx(0xACAC43EF), AESx(0x6262C4A6),
|
||||
AESx(0x919139A8), AESx(0x959531A4), AESx(0xE4E4D337), AESx(0x7979F28B),
|
||||
AESx(0xE7E7D532), AESx(0xC8C88B43), AESx(0x37376E59), AESx(0x6D6DDAB7),
|
||||
AESx(0x8D8D018C), AESx(0xD5D5B164), AESx(0x4E4E9CD2), AESx(0xA9A949E0),
|
||||
AESx(0x6C6CD8B4), AESx(0x5656ACFA), AESx(0xF4F4F307), AESx(0xEAEACF25),
|
||||
AESx(0x6565CAAF), AESx(0x7A7AF48E), AESx(0xAEAE47E9), AESx(0x08081018),
|
||||
AESx(0xBABA6FD5), AESx(0x7878F088), AESx(0x25254A6F), AESx(0x2E2E5C72),
|
||||
AESx(0x1C1C3824), AESx(0xA6A657F1), AESx(0xB4B473C7), AESx(0xC6C69751),
|
||||
AESx(0xE8E8CB23), AESx(0xDDDDA17C), AESx(0x7474E89C), AESx(0x1F1F3E21),
|
||||
AESx(0x4B4B96DD), AESx(0xBDBD61DC), AESx(0x8B8B0D86), AESx(0x8A8A0F85),
|
||||
AESx(0x7070E090), AESx(0x3E3E7C42), AESx(0xB5B571C4), AESx(0x6666CCAA),
|
||||
AESx(0x484890D8), AESx(0x03030605), AESx(0xF6F6F701), AESx(0x0E0E1C12),
|
||||
AESx(0x6161C2A3), AESx(0x35356A5F), AESx(0x5757AEF9), AESx(0xB9B969D0),
|
||||
AESx(0x86861791), AESx(0xC1C19958), AESx(0x1D1D3A27), AESx(0x9E9E27B9),
|
||||
AESx(0xE1E1D938), AESx(0xF8F8EB13), AESx(0x98982BB3), AESx(0x11112233),
|
||||
AESx(0x6969D2BB), AESx(0xD9D9A970), AESx(0x8E8E0789), AESx(0x949433A7),
|
||||
AESx(0x9B9B2DB6), AESx(0x1E1E3C22), AESx(0x87871592), AESx(0xE9E9C920),
|
||||
AESx(0xCECE8749), AESx(0x5555AAFF), AESx(0x28285078), AESx(0xDFDFA57A),
|
||||
AESx(0x8C8C038F), AESx(0xA1A159F8), AESx(0x89890980), AESx(0x0D0D1A17),
|
||||
AESx(0xBFBF65DA), AESx(0xE6E6D731), AESx(0x424284C6), AESx(0x6868D0B8),
|
||||
AESx(0x414182C3), AESx(0x999929B0), AESx(0x2D2D5A77), AESx(0x0F0F1E11),
|
||||
AESx(0xB0B07BCB), AESx(0x5454A8FC), AESx(0xBBBB6DD6), AESx(0x16162C3A)
|
||||
};
|
||||
|
||||
static const sph_u32 AES2[256] = {
|
||||
AESx(0x63C6A563), AESx(0x7CF8847C), AESx(0x77EE9977), AESx(0x7BF68D7B),
|
||||
AESx(0xF2FF0DF2), AESx(0x6BD6BD6B), AESx(0x6FDEB16F), AESx(0xC59154C5),
|
||||
AESx(0x30605030), AESx(0x01020301), AESx(0x67CEA967), AESx(0x2B567D2B),
|
||||
AESx(0xFEE719FE), AESx(0xD7B562D7), AESx(0xAB4DE6AB), AESx(0x76EC9A76),
|
||||
AESx(0xCA8F45CA), AESx(0x821F9D82), AESx(0xC98940C9), AESx(0x7DFA877D),
|
||||
AESx(0xFAEF15FA), AESx(0x59B2EB59), AESx(0x478EC947), AESx(0xF0FB0BF0),
|
||||
AESx(0xAD41ECAD), AESx(0xD4B367D4), AESx(0xA25FFDA2), AESx(0xAF45EAAF),
|
||||
AESx(0x9C23BF9C), AESx(0xA453F7A4), AESx(0x72E49672), AESx(0xC09B5BC0),
|
||||
AESx(0xB775C2B7), AESx(0xFDE11CFD), AESx(0x933DAE93), AESx(0x264C6A26),
|
||||
AESx(0x366C5A36), AESx(0x3F7E413F), AESx(0xF7F502F7), AESx(0xCC834FCC),
|
||||
AESx(0x34685C34), AESx(0xA551F4A5), AESx(0xE5D134E5), AESx(0xF1F908F1),
|
||||
AESx(0x71E29371), AESx(0xD8AB73D8), AESx(0x31625331), AESx(0x152A3F15),
|
||||
AESx(0x04080C04), AESx(0xC79552C7), AESx(0x23466523), AESx(0xC39D5EC3),
|
||||
AESx(0x18302818), AESx(0x9637A196), AESx(0x050A0F05), AESx(0x9A2FB59A),
|
||||
AESx(0x070E0907), AESx(0x12243612), AESx(0x801B9B80), AESx(0xE2DF3DE2),
|
||||
AESx(0xEBCD26EB), AESx(0x274E6927), AESx(0xB27FCDB2), AESx(0x75EA9F75),
|
||||
AESx(0x09121B09), AESx(0x831D9E83), AESx(0x2C58742C), AESx(0x1A342E1A),
|
||||
AESx(0x1B362D1B), AESx(0x6EDCB26E), AESx(0x5AB4EE5A), AESx(0xA05BFBA0),
|
||||
AESx(0x52A4F652), AESx(0x3B764D3B), AESx(0xD6B761D6), AESx(0xB37DCEB3),
|
||||
AESx(0x29527B29), AESx(0xE3DD3EE3), AESx(0x2F5E712F), AESx(0x84139784),
|
||||
AESx(0x53A6F553), AESx(0xD1B968D1), AESx(0x00000000), AESx(0xEDC12CED),
|
||||
AESx(0x20406020), AESx(0xFCE31FFC), AESx(0xB179C8B1), AESx(0x5BB6ED5B),
|
||||
AESx(0x6AD4BE6A), AESx(0xCB8D46CB), AESx(0xBE67D9BE), AESx(0x39724B39),
|
||||
AESx(0x4A94DE4A), AESx(0x4C98D44C), AESx(0x58B0E858), AESx(0xCF854ACF),
|
||||
AESx(0xD0BB6BD0), AESx(0xEFC52AEF), AESx(0xAA4FE5AA), AESx(0xFBED16FB),
|
||||
AESx(0x4386C543), AESx(0x4D9AD74D), AESx(0x33665533), AESx(0x85119485),
|
||||
AESx(0x458ACF45), AESx(0xF9E910F9), AESx(0x02040602), AESx(0x7FFE817F),
|
||||
AESx(0x50A0F050), AESx(0x3C78443C), AESx(0x9F25BA9F), AESx(0xA84BE3A8),
|
||||
AESx(0x51A2F351), AESx(0xA35DFEA3), AESx(0x4080C040), AESx(0x8F058A8F),
|
||||
AESx(0x923FAD92), AESx(0x9D21BC9D), AESx(0x38704838), AESx(0xF5F104F5),
|
||||
AESx(0xBC63DFBC), AESx(0xB677C1B6), AESx(0xDAAF75DA), AESx(0x21426321),
|
||||
AESx(0x10203010), AESx(0xFFE51AFF), AESx(0xF3FD0EF3), AESx(0xD2BF6DD2),
|
||||
AESx(0xCD814CCD), AESx(0x0C18140C), AESx(0x13263513), AESx(0xECC32FEC),
|
||||
AESx(0x5FBEE15F), AESx(0x9735A297), AESx(0x4488CC44), AESx(0x172E3917),
|
||||
AESx(0xC49357C4), AESx(0xA755F2A7), AESx(0x7EFC827E), AESx(0x3D7A473D),
|
||||
AESx(0x64C8AC64), AESx(0x5DBAE75D), AESx(0x19322B19), AESx(0x73E69573),
|
||||
AESx(0x60C0A060), AESx(0x81199881), AESx(0x4F9ED14F), AESx(0xDCA37FDC),
|
||||
AESx(0x22446622), AESx(0x2A547E2A), AESx(0x903BAB90), AESx(0x880B8388),
|
||||
AESx(0x468CCA46), AESx(0xEEC729EE), AESx(0xB86BD3B8), AESx(0x14283C14),
|
||||
AESx(0xDEA779DE), AESx(0x5EBCE25E), AESx(0x0B161D0B), AESx(0xDBAD76DB),
|
||||
AESx(0xE0DB3BE0), AESx(0x32645632), AESx(0x3A744E3A), AESx(0x0A141E0A),
|
||||
AESx(0x4992DB49), AESx(0x060C0A06), AESx(0x24486C24), AESx(0x5CB8E45C),
|
||||
AESx(0xC29F5DC2), AESx(0xD3BD6ED3), AESx(0xAC43EFAC), AESx(0x62C4A662),
|
||||
AESx(0x9139A891), AESx(0x9531A495), AESx(0xE4D337E4), AESx(0x79F28B79),
|
||||
AESx(0xE7D532E7), AESx(0xC88B43C8), AESx(0x376E5937), AESx(0x6DDAB76D),
|
||||
AESx(0x8D018C8D), AESx(0xD5B164D5), AESx(0x4E9CD24E), AESx(0xA949E0A9),
|
||||
AESx(0x6CD8B46C), AESx(0x56ACFA56), AESx(0xF4F307F4), AESx(0xEACF25EA),
|
||||
AESx(0x65CAAF65), AESx(0x7AF48E7A), AESx(0xAE47E9AE), AESx(0x08101808),
|
||||
AESx(0xBA6FD5BA), AESx(0x78F08878), AESx(0x254A6F25), AESx(0x2E5C722E),
|
||||
AESx(0x1C38241C), AESx(0xA657F1A6), AESx(0xB473C7B4), AESx(0xC69751C6),
|
||||
AESx(0xE8CB23E8), AESx(0xDDA17CDD), AESx(0x74E89C74), AESx(0x1F3E211F),
|
||||
AESx(0x4B96DD4B), AESx(0xBD61DCBD), AESx(0x8B0D868B), AESx(0x8A0F858A),
|
||||
AESx(0x70E09070), AESx(0x3E7C423E), AESx(0xB571C4B5), AESx(0x66CCAA66),
|
||||
AESx(0x4890D848), AESx(0x03060503), AESx(0xF6F701F6), AESx(0x0E1C120E),
|
||||
AESx(0x61C2A361), AESx(0x356A5F35), AESx(0x57AEF957), AESx(0xB969D0B9),
|
||||
AESx(0x86179186), AESx(0xC19958C1), AESx(0x1D3A271D), AESx(0x9E27B99E),
|
||||
AESx(0xE1D938E1), AESx(0xF8EB13F8), AESx(0x982BB398), AESx(0x11223311),
|
||||
AESx(0x69D2BB69), AESx(0xD9A970D9), AESx(0x8E07898E), AESx(0x9433A794),
|
||||
AESx(0x9B2DB69B), AESx(0x1E3C221E), AESx(0x87159287), AESx(0xE9C920E9),
|
||||
AESx(0xCE8749CE), AESx(0x55AAFF55), AESx(0x28507828), AESx(0xDFA57ADF),
|
||||
AESx(0x8C038F8C), AESx(0xA159F8A1), AESx(0x89098089), AESx(0x0D1A170D),
|
||||
AESx(0xBF65DABF), AESx(0xE6D731E6), AESx(0x4284C642), AESx(0x68D0B868),
|
||||
AESx(0x4182C341), AESx(0x9929B099), AESx(0x2D5A772D), AESx(0x0F1E110F),
|
||||
AESx(0xB07BCBB0), AESx(0x54A8FC54), AESx(0xBB6DD6BB), AESx(0x162C3A16)
|
||||
};
|
||||
|
||||
static const sph_u32 AES3[256] = {
|
||||
AESx(0xC6A56363), AESx(0xF8847C7C), AESx(0xEE997777), AESx(0xF68D7B7B),
|
||||
AESx(0xFF0DF2F2), AESx(0xD6BD6B6B), AESx(0xDEB16F6F), AESx(0x9154C5C5),
|
||||
AESx(0x60503030), AESx(0x02030101), AESx(0xCEA96767), AESx(0x567D2B2B),
|
||||
AESx(0xE719FEFE), AESx(0xB562D7D7), AESx(0x4DE6ABAB), AESx(0xEC9A7676),
|
||||
AESx(0x8F45CACA), AESx(0x1F9D8282), AESx(0x8940C9C9), AESx(0xFA877D7D),
|
||||
AESx(0xEF15FAFA), AESx(0xB2EB5959), AESx(0x8EC94747), AESx(0xFB0BF0F0),
|
||||
AESx(0x41ECADAD), AESx(0xB367D4D4), AESx(0x5FFDA2A2), AESx(0x45EAAFAF),
|
||||
AESx(0x23BF9C9C), AESx(0x53F7A4A4), AESx(0xE4967272), AESx(0x9B5BC0C0),
|
||||
AESx(0x75C2B7B7), AESx(0xE11CFDFD), AESx(0x3DAE9393), AESx(0x4C6A2626),
|
||||
AESx(0x6C5A3636), AESx(0x7E413F3F), AESx(0xF502F7F7), AESx(0x834FCCCC),
|
||||
AESx(0x685C3434), AESx(0x51F4A5A5), AESx(0xD134E5E5), AESx(0xF908F1F1),
|
||||
AESx(0xE2937171), AESx(0xAB73D8D8), AESx(0x62533131), AESx(0x2A3F1515),
|
||||
AESx(0x080C0404), AESx(0x9552C7C7), AESx(0x46652323), AESx(0x9D5EC3C3),
|
||||
AESx(0x30281818), AESx(0x37A19696), AESx(0x0A0F0505), AESx(0x2FB59A9A),
|
||||
AESx(0x0E090707), AESx(0x24361212), AESx(0x1B9B8080), AESx(0xDF3DE2E2),
|
||||
AESx(0xCD26EBEB), AESx(0x4E692727), AESx(0x7FCDB2B2), AESx(0xEA9F7575),
|
||||
AESx(0x121B0909), AESx(0x1D9E8383), AESx(0x58742C2C), AESx(0x342E1A1A),
|
||||
AESx(0x362D1B1B), AESx(0xDCB26E6E), AESx(0xB4EE5A5A), AESx(0x5BFBA0A0),
|
||||
AESx(0xA4F65252), AESx(0x764D3B3B), AESx(0xB761D6D6), AESx(0x7DCEB3B3),
|
||||
AESx(0x527B2929), AESx(0xDD3EE3E3), AESx(0x5E712F2F), AESx(0x13978484),
|
||||
AESx(0xA6F55353), AESx(0xB968D1D1), AESx(0x00000000), AESx(0xC12CEDED),
|
||||
AESx(0x40602020), AESx(0xE31FFCFC), AESx(0x79C8B1B1), AESx(0xB6ED5B5B),
|
||||
AESx(0xD4BE6A6A), AESx(0x8D46CBCB), AESx(0x67D9BEBE), AESx(0x724B3939),
|
||||
AESx(0x94DE4A4A), AESx(0x98D44C4C), AESx(0xB0E85858), AESx(0x854ACFCF),
|
||||
AESx(0xBB6BD0D0), AESx(0xC52AEFEF), AESx(0x4FE5AAAA), AESx(0xED16FBFB),
|
||||
AESx(0x86C54343), AESx(0x9AD74D4D), AESx(0x66553333), AESx(0x11948585),
|
||||
AESx(0x8ACF4545), AESx(0xE910F9F9), AESx(0x04060202), AESx(0xFE817F7F),
|
||||
AESx(0xA0F05050), AESx(0x78443C3C), AESx(0x25BA9F9F), AESx(0x4BE3A8A8),
|
||||
AESx(0xA2F35151), AESx(0x5DFEA3A3), AESx(0x80C04040), AESx(0x058A8F8F),
|
||||
AESx(0x3FAD9292), AESx(0x21BC9D9D), AESx(0x70483838), AESx(0xF104F5F5),
|
||||
AESx(0x63DFBCBC), AESx(0x77C1B6B6), AESx(0xAF75DADA), AESx(0x42632121),
|
||||
AESx(0x20301010), AESx(0xE51AFFFF), AESx(0xFD0EF3F3), AESx(0xBF6DD2D2),
|
||||
AESx(0x814CCDCD), AESx(0x18140C0C), AESx(0x26351313), AESx(0xC32FECEC),
|
||||
AESx(0xBEE15F5F), AESx(0x35A29797), AESx(0x88CC4444), AESx(0x2E391717),
|
||||
AESx(0x9357C4C4), AESx(0x55F2A7A7), AESx(0xFC827E7E), AESx(0x7A473D3D),
|
||||
AESx(0xC8AC6464), AESx(0xBAE75D5D), AESx(0x322B1919), AESx(0xE6957373),
|
||||
AESx(0xC0A06060), AESx(0x19988181), AESx(0x9ED14F4F), AESx(0xA37FDCDC),
|
||||
AESx(0x44662222), AESx(0x547E2A2A), AESx(0x3BAB9090), AESx(0x0B838888),
|
||||
AESx(0x8CCA4646), AESx(0xC729EEEE), AESx(0x6BD3B8B8), AESx(0x283C1414),
|
||||
AESx(0xA779DEDE), AESx(0xBCE25E5E), AESx(0x161D0B0B), AESx(0xAD76DBDB),
|
||||
AESx(0xDB3BE0E0), AESx(0x64563232), AESx(0x744E3A3A), AESx(0x141E0A0A),
|
||||
AESx(0x92DB4949), AESx(0x0C0A0606), AESx(0x486C2424), AESx(0xB8E45C5C),
|
||||
AESx(0x9F5DC2C2), AESx(0xBD6ED3D3), AESx(0x43EFACAC), AESx(0xC4A66262),
|
||||
AESx(0x39A89191), AESx(0x31A49595), AESx(0xD337E4E4), AESx(0xF28B7979),
|
||||
AESx(0xD532E7E7), AESx(0x8B43C8C8), AESx(0x6E593737), AESx(0xDAB76D6D),
|
||||
AESx(0x018C8D8D), AESx(0xB164D5D5), AESx(0x9CD24E4E), AESx(0x49E0A9A9),
|
||||
AESx(0xD8B46C6C), AESx(0xACFA5656), AESx(0xF307F4F4), AESx(0xCF25EAEA),
|
||||
AESx(0xCAAF6565), AESx(0xF48E7A7A), AESx(0x47E9AEAE), AESx(0x10180808),
|
||||
AESx(0x6FD5BABA), AESx(0xF0887878), AESx(0x4A6F2525), AESx(0x5C722E2E),
|
||||
AESx(0x38241C1C), AESx(0x57F1A6A6), AESx(0x73C7B4B4), AESx(0x9751C6C6),
|
||||
AESx(0xCB23E8E8), AESx(0xA17CDDDD), AESx(0xE89C7474), AESx(0x3E211F1F),
|
||||
AESx(0x96DD4B4B), AESx(0x61DCBDBD), AESx(0x0D868B8B), AESx(0x0F858A8A),
|
||||
AESx(0xE0907070), AESx(0x7C423E3E), AESx(0x71C4B5B5), AESx(0xCCAA6666),
|
||||
AESx(0x90D84848), AESx(0x06050303), AESx(0xF701F6F6), AESx(0x1C120E0E),
|
||||
AESx(0xC2A36161), AESx(0x6A5F3535), AESx(0xAEF95757), AESx(0x69D0B9B9),
|
||||
AESx(0x17918686), AESx(0x9958C1C1), AESx(0x3A271D1D), AESx(0x27B99E9E),
|
||||
AESx(0xD938E1E1), AESx(0xEB13F8F8), AESx(0x2BB39898), AESx(0x22331111),
|
||||
AESx(0xD2BB6969), AESx(0xA970D9D9), AESx(0x07898E8E), AESx(0x33A79494),
|
||||
AESx(0x2DB69B9B), AESx(0x3C221E1E), AESx(0x15928787), AESx(0xC920E9E9),
|
||||
AESx(0x8749CECE), AESx(0xAAFF5555), AESx(0x50782828), AESx(0xA57ADFDF),
|
||||
AESx(0x038F8C8C), AESx(0x59F8A1A1), AESx(0x09808989), AESx(0x1A170D0D),
|
||||
AESx(0x65DABFBF), AESx(0xD731E6E6), AESx(0x84C64242), AESx(0xD0B86868),
|
||||
AESx(0x82C34141), AESx(0x29B09999), AESx(0x5A772D2D), AESx(0x1E110F0F),
|
||||
AESx(0x7BCBB0B0), AESx(0xA8FC5454), AESx(0x6DD6BBBB), AESx(0x2C3A1616)
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
1120
src/crypto/blake.cpp
Normal file
1120
src/crypto/blake.cpp
Normal file
File diff suppressed because it is too large
Load diff
965
src/crypto/bmw.cpp
Normal file
965
src/crypto/bmw.cpp
Normal file
|
|
@ -0,0 +1,965 @@
|
|||
/* $Id: bmw.c 227 2010-06-16 17:28:38Z tp $ */
|
||||
/*
|
||||
* BMW implementation.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include "crypto/sph_bmw.h"
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_BMW
|
||||
#define SPH_SMALL_FOOTPRINT_BMW 1
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4146)
|
||||
#endif
|
||||
|
||||
static const sph_u32 IV224[] = {
|
||||
SPH_C32(0x00010203), SPH_C32(0x04050607),
|
||||
SPH_C32(0x08090A0B), SPH_C32(0x0C0D0E0F),
|
||||
SPH_C32(0x10111213), SPH_C32(0x14151617),
|
||||
SPH_C32(0x18191A1B), SPH_C32(0x1C1D1E1F),
|
||||
SPH_C32(0x20212223), SPH_C32(0x24252627),
|
||||
SPH_C32(0x28292A2B), SPH_C32(0x2C2D2E2F),
|
||||
SPH_C32(0x30313233), SPH_C32(0x34353637),
|
||||
SPH_C32(0x38393A3B), SPH_C32(0x3C3D3E3F)
|
||||
};
|
||||
|
||||
static const sph_u32 IV256[] = {
|
||||
SPH_C32(0x40414243), SPH_C32(0x44454647),
|
||||
SPH_C32(0x48494A4B), SPH_C32(0x4C4D4E4F),
|
||||
SPH_C32(0x50515253), SPH_C32(0x54555657),
|
||||
SPH_C32(0x58595A5B), SPH_C32(0x5C5D5E5F),
|
||||
SPH_C32(0x60616263), SPH_C32(0x64656667),
|
||||
SPH_C32(0x68696A6B), SPH_C32(0x6C6D6E6F),
|
||||
SPH_C32(0x70717273), SPH_C32(0x74757677),
|
||||
SPH_C32(0x78797A7B), SPH_C32(0x7C7D7E7F)
|
||||
};
|
||||
|
||||
#if SPH_64
|
||||
|
||||
static const sph_u64 IV384[] = {
|
||||
SPH_C64(0x0001020304050607), SPH_C64(0x08090A0B0C0D0E0F),
|
||||
SPH_C64(0x1011121314151617), SPH_C64(0x18191A1B1C1D1E1F),
|
||||
SPH_C64(0x2021222324252627), SPH_C64(0x28292A2B2C2D2E2F),
|
||||
SPH_C64(0x3031323334353637), SPH_C64(0x38393A3B3C3D3E3F),
|
||||
SPH_C64(0x4041424344454647), SPH_C64(0x48494A4B4C4D4E4F),
|
||||
SPH_C64(0x5051525354555657), SPH_C64(0x58595A5B5C5D5E5F),
|
||||
SPH_C64(0x6061626364656667), SPH_C64(0x68696A6B6C6D6E6F),
|
||||
SPH_C64(0x7071727374757677), SPH_C64(0x78797A7B7C7D7E7F)
|
||||
};
|
||||
|
||||
static const sph_u64 IV512[] = {
|
||||
SPH_C64(0x8081828384858687), SPH_C64(0x88898A8B8C8D8E8F),
|
||||
SPH_C64(0x9091929394959697), SPH_C64(0x98999A9B9C9D9E9F),
|
||||
SPH_C64(0xA0A1A2A3A4A5A6A7), SPH_C64(0xA8A9AAABACADAEAF),
|
||||
SPH_C64(0xB0B1B2B3B4B5B6B7), SPH_C64(0xB8B9BABBBCBDBEBF),
|
||||
SPH_C64(0xC0C1C2C3C4C5C6C7), SPH_C64(0xC8C9CACBCCCDCECF),
|
||||
SPH_C64(0xD0D1D2D3D4D5D6D7), SPH_C64(0xD8D9DADBDCDDDEDF),
|
||||
SPH_C64(0xE0E1E2E3E4E5E6E7), SPH_C64(0xE8E9EAEBECEDEEEF),
|
||||
SPH_C64(0xF0F1F2F3F4F5F6F7), SPH_C64(0xF8F9FAFBFCFDFEFF)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#define XCAT(x, y) XCAT_(x, y)
|
||||
#define XCAT_(x, y) x ## y
|
||||
|
||||
#define LPAR (
|
||||
|
||||
#define I16_16 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
|
||||
#define I16_17 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
|
||||
#define I16_18 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17
|
||||
#define I16_19 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18
|
||||
#define I16_20 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
|
||||
#define I16_21 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
|
||||
#define I16_22 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21
|
||||
#define I16_23 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22
|
||||
#define I16_24 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23
|
||||
#define I16_25 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24
|
||||
#define I16_26 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25
|
||||
#define I16_27 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26
|
||||
#define I16_28 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27
|
||||
#define I16_29 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28
|
||||
#define I16_30 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29
|
||||
#define I16_31 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30
|
||||
|
||||
#define M16_16 0, 1, 3, 4, 7, 10, 11
|
||||
#define M16_17 1, 2, 4, 5, 8, 11, 12
|
||||
#define M16_18 2, 3, 5, 6, 9, 12, 13
|
||||
#define M16_19 3, 4, 6, 7, 10, 13, 14
|
||||
#define M16_20 4, 5, 7, 8, 11, 14, 15
|
||||
#define M16_21 5, 6, 8, 9, 12, 15, 16
|
||||
#define M16_22 6, 7, 9, 10, 13, 0, 1
|
||||
#define M16_23 7, 8, 10, 11, 14, 1, 2
|
||||
#define M16_24 8, 9, 11, 12, 15, 2, 3
|
||||
#define M16_25 9, 10, 12, 13, 0, 3, 4
|
||||
#define M16_26 10, 11, 13, 14, 1, 4, 5
|
||||
#define M16_27 11, 12, 14, 15, 2, 5, 6
|
||||
#define M16_28 12, 13, 15, 16, 3, 6, 7
|
||||
#define M16_29 13, 14, 0, 1, 4, 7, 8
|
||||
#define M16_30 14, 15, 1, 2, 5, 8, 9
|
||||
#define M16_31 15, 16, 2, 3, 6, 9, 10
|
||||
|
||||
#define ss0(x) (((x) >> 1) ^ SPH_T32((x) << 3) \
|
||||
^ SPH_ROTL32(x, 4) ^ SPH_ROTL32(x, 19))
|
||||
#define ss1(x) (((x) >> 1) ^ SPH_T32((x) << 2) \
|
||||
^ SPH_ROTL32(x, 8) ^ SPH_ROTL32(x, 23))
|
||||
#define ss2(x) (((x) >> 2) ^ SPH_T32((x) << 1) \
|
||||
^ SPH_ROTL32(x, 12) ^ SPH_ROTL32(x, 25))
|
||||
#define ss3(x) (((x) >> 2) ^ SPH_T32((x) << 2) \
|
||||
^ SPH_ROTL32(x, 15) ^ SPH_ROTL32(x, 29))
|
||||
#define ss4(x) (((x) >> 1) ^ (x))
|
||||
#define ss5(x) (((x) >> 2) ^ (x))
|
||||
#define rs1(x) SPH_ROTL32(x, 3)
|
||||
#define rs2(x) SPH_ROTL32(x, 7)
|
||||
#define rs3(x) SPH_ROTL32(x, 13)
|
||||
#define rs4(x) SPH_ROTL32(x, 16)
|
||||
#define rs5(x) SPH_ROTL32(x, 19)
|
||||
#define rs6(x) SPH_ROTL32(x, 23)
|
||||
#define rs7(x) SPH_ROTL32(x, 27)
|
||||
|
||||
#define Ks(j) SPH_T32((sph_u32)(j) * SPH_C32(0x05555555))
|
||||
|
||||
#define add_elt_s(mf, hf, j0m, j1m, j3m, j4m, j7m, j10m, j11m, j16) \
|
||||
(SPH_T32(SPH_ROTL32(mf(j0m), j1m) + SPH_ROTL32(mf(j3m), j4m) \
|
||||
- SPH_ROTL32(mf(j10m), j11m) + Ks(j16)) ^ hf(j7m))
|
||||
|
||||
#define expand1s_inner(qf, mf, hf, i16, \
|
||||
i0, i1, i2, i3, i4, i5, i6, i7, i8, \
|
||||
i9, i10, i11, i12, i13, i14, i15, \
|
||||
i0m, i1m, i3m, i4m, i7m, i10m, i11m) \
|
||||
SPH_T32(ss1(qf(i0)) + ss2(qf(i1)) + ss3(qf(i2)) + ss0(qf(i3)) \
|
||||
+ ss1(qf(i4)) + ss2(qf(i5)) + ss3(qf(i6)) + ss0(qf(i7)) \
|
||||
+ ss1(qf(i8)) + ss2(qf(i9)) + ss3(qf(i10)) + ss0(qf(i11)) \
|
||||
+ ss1(qf(i12)) + ss2(qf(i13)) + ss3(qf(i14)) + ss0(qf(i15)) \
|
||||
+ add_elt_s(mf, hf, i0m, i1m, i3m, i4m, i7m, i10m, i11m, i16))
|
||||
|
||||
#define expand1s(qf, mf, hf, i16) \
|
||||
expand1s_(qf, mf, hf, i16, I16_ ## i16, M16_ ## i16)
|
||||
#define expand1s_(qf, mf, hf, i16, ix, iy) \
|
||||
expand1s_inner LPAR qf, mf, hf, i16, ix, iy)
|
||||
|
||||
#define expand2s_inner(qf, mf, hf, i16, \
|
||||
i0, i1, i2, i3, i4, i5, i6, i7, i8, \
|
||||
i9, i10, i11, i12, i13, i14, i15, \
|
||||
i0m, i1m, i3m, i4m, i7m, i10m, i11m) \
|
||||
SPH_T32(qf(i0) + rs1(qf(i1)) + qf(i2) + rs2(qf(i3)) \
|
||||
+ qf(i4) + rs3(qf(i5)) + qf(i6) + rs4(qf(i7)) \
|
||||
+ qf(i8) + rs5(qf(i9)) + qf(i10) + rs6(qf(i11)) \
|
||||
+ qf(i12) + rs7(qf(i13)) + ss4(qf(i14)) + ss5(qf(i15)) \
|
||||
+ add_elt_s(mf, hf, i0m, i1m, i3m, i4m, i7m, i10m, i11m, i16))
|
||||
|
||||
#define expand2s(qf, mf, hf, i16) \
|
||||
expand2s_(qf, mf, hf, i16, I16_ ## i16, M16_ ## i16)
|
||||
#define expand2s_(qf, mf, hf, i16, ix, iy) \
|
||||
expand2s_inner LPAR qf, mf, hf, i16, ix, iy)
|
||||
|
||||
#if SPH_64
|
||||
|
||||
#define sb0(x) (((x) >> 1) ^ SPH_T64((x) << 3) \
|
||||
^ SPH_ROTL64(x, 4) ^ SPH_ROTL64(x, 37))
|
||||
#define sb1(x) (((x) >> 1) ^ SPH_T64((x) << 2) \
|
||||
^ SPH_ROTL64(x, 13) ^ SPH_ROTL64(x, 43))
|
||||
#define sb2(x) (((x) >> 2) ^ SPH_T64((x) << 1) \
|
||||
^ SPH_ROTL64(x, 19) ^ SPH_ROTL64(x, 53))
|
||||
#define sb3(x) (((x) >> 2) ^ SPH_T64((x) << 2) \
|
||||
^ SPH_ROTL64(x, 28) ^ SPH_ROTL64(x, 59))
|
||||
#define sb4(x) (((x) >> 1) ^ (x))
|
||||
#define sb5(x) (((x) >> 2) ^ (x))
|
||||
#define rb1(x) SPH_ROTL64(x, 5)
|
||||
#define rb2(x) SPH_ROTL64(x, 11)
|
||||
#define rb3(x) SPH_ROTL64(x, 27)
|
||||
#define rb4(x) SPH_ROTL64(x, 32)
|
||||
#define rb5(x) SPH_ROTL64(x, 37)
|
||||
#define rb6(x) SPH_ROTL64(x, 43)
|
||||
#define rb7(x) SPH_ROTL64(x, 53)
|
||||
|
||||
#define Kb(j) SPH_T64((sph_u64)(j) * SPH_C64(0x0555555555555555))
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT_BMW
|
||||
|
||||
static const sph_u64 Kb_tab[] = {
|
||||
Kb(16), Kb(17), Kb(18), Kb(19), Kb(20), Kb(21), Kb(22), Kb(23),
|
||||
Kb(24), Kb(25), Kb(26), Kb(27), Kb(28), Kb(29), Kb(30), Kb(31)
|
||||
};
|
||||
|
||||
#define rol_off(mf, j, off) \
|
||||
SPH_ROTL64(mf(((j) + (off)) & 15), (((j) + (off)) & 15) + 1)
|
||||
|
||||
#define add_elt_b(mf, hf, j) \
|
||||
(SPH_T64(rol_off(mf, j, 0) + rol_off(mf, j, 3) \
|
||||
- rol_off(mf, j, 10) + Kb_tab[j]) ^ hf(((j) + 7) & 15))
|
||||
|
||||
#define expand1b(qf, mf, hf, i) \
|
||||
SPH_T64(sb1(qf((i) - 16)) + sb2(qf((i) - 15)) \
|
||||
+ sb3(qf((i) - 14)) + sb0(qf((i) - 13)) \
|
||||
+ sb1(qf((i) - 12)) + sb2(qf((i) - 11)) \
|
||||
+ sb3(qf((i) - 10)) + sb0(qf((i) - 9)) \
|
||||
+ sb1(qf((i) - 8)) + sb2(qf((i) - 7)) \
|
||||
+ sb3(qf((i) - 6)) + sb0(qf((i) - 5)) \
|
||||
+ sb1(qf((i) - 4)) + sb2(qf((i) - 3)) \
|
||||
+ sb3(qf((i) - 2)) + sb0(qf((i) - 1)) \
|
||||
+ add_elt_b(mf, hf, (i) - 16))
|
||||
|
||||
#define expand2b(qf, mf, hf, i) \
|
||||
SPH_T64(qf((i) - 16) + rb1(qf((i) - 15)) \
|
||||
+ qf((i) - 14) + rb2(qf((i) - 13)) \
|
||||
+ qf((i) - 12) + rb3(qf((i) - 11)) \
|
||||
+ qf((i) - 10) + rb4(qf((i) - 9)) \
|
||||
+ qf((i) - 8) + rb5(qf((i) - 7)) \
|
||||
+ qf((i) - 6) + rb6(qf((i) - 5)) \
|
||||
+ qf((i) - 4) + rb7(qf((i) - 3)) \
|
||||
+ sb4(qf((i) - 2)) + sb5(qf((i) - 1)) \
|
||||
+ add_elt_b(mf, hf, (i) - 16))
|
||||
|
||||
#else
|
||||
|
||||
#define add_elt_b(mf, hf, j0m, j1m, j3m, j4m, j7m, j10m, j11m, j16) \
|
||||
(SPH_T64(SPH_ROTL64(mf(j0m), j1m) + SPH_ROTL64(mf(j3m), j4m) \
|
||||
- SPH_ROTL64(mf(j10m), j11m) + Kb(j16)) ^ hf(j7m))
|
||||
|
||||
#define expand1b_inner(qf, mf, hf, i16, \
|
||||
i0, i1, i2, i3, i4, i5, i6, i7, i8, \
|
||||
i9, i10, i11, i12, i13, i14, i15, \
|
||||
i0m, i1m, i3m, i4m, i7m, i10m, i11m) \
|
||||
SPH_T64(sb1(qf(i0)) + sb2(qf(i1)) + sb3(qf(i2)) + sb0(qf(i3)) \
|
||||
+ sb1(qf(i4)) + sb2(qf(i5)) + sb3(qf(i6)) + sb0(qf(i7)) \
|
||||
+ sb1(qf(i8)) + sb2(qf(i9)) + sb3(qf(i10)) + sb0(qf(i11)) \
|
||||
+ sb1(qf(i12)) + sb2(qf(i13)) + sb3(qf(i14)) + sb0(qf(i15)) \
|
||||
+ add_elt_b(mf, hf, i0m, i1m, i3m, i4m, i7m, i10m, i11m, i16))
|
||||
|
||||
#define expand1b(qf, mf, hf, i16) \
|
||||
expand1b_(qf, mf, hf, i16, I16_ ## i16, M16_ ## i16)
|
||||
#define expand1b_(qf, mf, hf, i16, ix, iy) \
|
||||
expand1b_inner LPAR qf, mf, hf, i16, ix, iy)
|
||||
|
||||
#define expand2b_inner(qf, mf, hf, i16, \
|
||||
i0, i1, i2, i3, i4, i5, i6, i7, i8, \
|
||||
i9, i10, i11, i12, i13, i14, i15, \
|
||||
i0m, i1m, i3m, i4m, i7m, i10m, i11m) \
|
||||
SPH_T64(qf(i0) + rb1(qf(i1)) + qf(i2) + rb2(qf(i3)) \
|
||||
+ qf(i4) + rb3(qf(i5)) + qf(i6) + rb4(qf(i7)) \
|
||||
+ qf(i8) + rb5(qf(i9)) + qf(i10) + rb6(qf(i11)) \
|
||||
+ qf(i12) + rb7(qf(i13)) + sb4(qf(i14)) + sb5(qf(i15)) \
|
||||
+ add_elt_b(mf, hf, i0m, i1m, i3m, i4m, i7m, i10m, i11m, i16))
|
||||
|
||||
#define expand2b(qf, mf, hf, i16) \
|
||||
expand2b_(qf, mf, hf, i16, I16_ ## i16, M16_ ## i16)
|
||||
#define expand2b_(qf, mf, hf, i16, ix, iy) \
|
||||
expand2b_inner LPAR qf, mf, hf, i16, ix, iy)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define MAKE_W(tt, i0, op01, i1, op12, i2, op23, i3, op34, i4) \
|
||||
tt((M(i0) ^ H(i0)) op01 (M(i1) ^ H(i1)) op12 (M(i2) ^ H(i2)) \
|
||||
op23 (M(i3) ^ H(i3)) op34 (M(i4) ^ H(i4)))
|
||||
|
||||
#define Ws0 MAKE_W(SPH_T32, 5, -, 7, +, 10, +, 13, +, 14)
|
||||
#define Ws1 MAKE_W(SPH_T32, 6, -, 8, +, 11, +, 14, -, 15)
|
||||
#define Ws2 MAKE_W(SPH_T32, 0, +, 7, +, 9, -, 12, +, 15)
|
||||
#define Ws3 MAKE_W(SPH_T32, 0, -, 1, +, 8, -, 10, +, 13)
|
||||
#define Ws4 MAKE_W(SPH_T32, 1, +, 2, +, 9, -, 11, -, 14)
|
||||
#define Ws5 MAKE_W(SPH_T32, 3, -, 2, +, 10, -, 12, +, 15)
|
||||
#define Ws6 MAKE_W(SPH_T32, 4, -, 0, -, 3, -, 11, +, 13)
|
||||
#define Ws7 MAKE_W(SPH_T32, 1, -, 4, -, 5, -, 12, -, 14)
|
||||
#define Ws8 MAKE_W(SPH_T32, 2, -, 5, -, 6, +, 13, -, 15)
|
||||
#define Ws9 MAKE_W(SPH_T32, 0, -, 3, +, 6, -, 7, +, 14)
|
||||
#define Ws10 MAKE_W(SPH_T32, 8, -, 1, -, 4, -, 7, +, 15)
|
||||
#define Ws11 MAKE_W(SPH_T32, 8, -, 0, -, 2, -, 5, +, 9)
|
||||
#define Ws12 MAKE_W(SPH_T32, 1, +, 3, -, 6, -, 9, +, 10)
|
||||
#define Ws13 MAKE_W(SPH_T32, 2, +, 4, +, 7, +, 10, +, 11)
|
||||
#define Ws14 MAKE_W(SPH_T32, 3, -, 5, +, 8, -, 11, -, 12)
|
||||
#define Ws15 MAKE_W(SPH_T32, 12, -, 4, -, 6, -, 9, +, 13)
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT_BMW
|
||||
|
||||
#define MAKE_Qas do { \
|
||||
unsigned u; \
|
||||
sph_u32 Ws[16]; \
|
||||
Ws[ 0] = Ws0; \
|
||||
Ws[ 1] = Ws1; \
|
||||
Ws[ 2] = Ws2; \
|
||||
Ws[ 3] = Ws3; \
|
||||
Ws[ 4] = Ws4; \
|
||||
Ws[ 5] = Ws5; \
|
||||
Ws[ 6] = Ws6; \
|
||||
Ws[ 7] = Ws7; \
|
||||
Ws[ 8] = Ws8; \
|
||||
Ws[ 9] = Ws9; \
|
||||
Ws[10] = Ws10; \
|
||||
Ws[11] = Ws11; \
|
||||
Ws[12] = Ws12; \
|
||||
Ws[13] = Ws13; \
|
||||
Ws[14] = Ws14; \
|
||||
Ws[15] = Ws15; \
|
||||
for (u = 0; u < 15; u += 5) { \
|
||||
qt[u + 0] = SPH_T32(ss0(Ws[u + 0]) + H(u + 1)); \
|
||||
qt[u + 1] = SPH_T32(ss1(Ws[u + 1]) + H(u + 2)); \
|
||||
qt[u + 2] = SPH_T32(ss2(Ws[u + 2]) + H(u + 3)); \
|
||||
qt[u + 3] = SPH_T32(ss3(Ws[u + 3]) + H(u + 4)); \
|
||||
qt[u + 4] = SPH_T32(ss4(Ws[u + 4]) + H(u + 5)); \
|
||||
} \
|
||||
qt[15] = SPH_T32(ss0(Ws[15]) + H(0)); \
|
||||
} while (0)
|
||||
|
||||
#define MAKE_Qbs do { \
|
||||
qt[16] = expand1s(Qs, M, H, 16); \
|
||||
qt[17] = expand1s(Qs, M, H, 17); \
|
||||
qt[18] = expand2s(Qs, M, H, 18); \
|
||||
qt[19] = expand2s(Qs, M, H, 19); \
|
||||
qt[20] = expand2s(Qs, M, H, 20); \
|
||||
qt[21] = expand2s(Qs, M, H, 21); \
|
||||
qt[22] = expand2s(Qs, M, H, 22); \
|
||||
qt[23] = expand2s(Qs, M, H, 23); \
|
||||
qt[24] = expand2s(Qs, M, H, 24); \
|
||||
qt[25] = expand2s(Qs, M, H, 25); \
|
||||
qt[26] = expand2s(Qs, M, H, 26); \
|
||||
qt[27] = expand2s(Qs, M, H, 27); \
|
||||
qt[28] = expand2s(Qs, M, H, 28); \
|
||||
qt[29] = expand2s(Qs, M, H, 29); \
|
||||
qt[30] = expand2s(Qs, M, H, 30); \
|
||||
qt[31] = expand2s(Qs, M, H, 31); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define MAKE_Qas do { \
|
||||
qt[ 0] = SPH_T32(ss0(Ws0 ) + H( 1)); \
|
||||
qt[ 1] = SPH_T32(ss1(Ws1 ) + H( 2)); \
|
||||
qt[ 2] = SPH_T32(ss2(Ws2 ) + H( 3)); \
|
||||
qt[ 3] = SPH_T32(ss3(Ws3 ) + H( 4)); \
|
||||
qt[ 4] = SPH_T32(ss4(Ws4 ) + H( 5)); \
|
||||
qt[ 5] = SPH_T32(ss0(Ws5 ) + H( 6)); \
|
||||
qt[ 6] = SPH_T32(ss1(Ws6 ) + H( 7)); \
|
||||
qt[ 7] = SPH_T32(ss2(Ws7 ) + H( 8)); \
|
||||
qt[ 8] = SPH_T32(ss3(Ws8 ) + H( 9)); \
|
||||
qt[ 9] = SPH_T32(ss4(Ws9 ) + H(10)); \
|
||||
qt[10] = SPH_T32(ss0(Ws10) + H(11)); \
|
||||
qt[11] = SPH_T32(ss1(Ws11) + H(12)); \
|
||||
qt[12] = SPH_T32(ss2(Ws12) + H(13)); \
|
||||
qt[13] = SPH_T32(ss3(Ws13) + H(14)); \
|
||||
qt[14] = SPH_T32(ss4(Ws14) + H(15)); \
|
||||
qt[15] = SPH_T32(ss0(Ws15) + H( 0)); \
|
||||
} while (0)
|
||||
|
||||
#define MAKE_Qbs do { \
|
||||
qt[16] = expand1s(Qs, M, H, 16); \
|
||||
qt[17] = expand1s(Qs, M, H, 17); \
|
||||
qt[18] = expand2s(Qs, M, H, 18); \
|
||||
qt[19] = expand2s(Qs, M, H, 19); \
|
||||
qt[20] = expand2s(Qs, M, H, 20); \
|
||||
qt[21] = expand2s(Qs, M, H, 21); \
|
||||
qt[22] = expand2s(Qs, M, H, 22); \
|
||||
qt[23] = expand2s(Qs, M, H, 23); \
|
||||
qt[24] = expand2s(Qs, M, H, 24); \
|
||||
qt[25] = expand2s(Qs, M, H, 25); \
|
||||
qt[26] = expand2s(Qs, M, H, 26); \
|
||||
qt[27] = expand2s(Qs, M, H, 27); \
|
||||
qt[28] = expand2s(Qs, M, H, 28); \
|
||||
qt[29] = expand2s(Qs, M, H, 29); \
|
||||
qt[30] = expand2s(Qs, M, H, 30); \
|
||||
qt[31] = expand2s(Qs, M, H, 31); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#define MAKE_Qs do { \
|
||||
MAKE_Qas; \
|
||||
MAKE_Qbs; \
|
||||
} while (0)
|
||||
|
||||
#define Qs(j) (qt[j])
|
||||
|
||||
#if SPH_64
|
||||
|
||||
#define Wb0 MAKE_W(SPH_T64, 5, -, 7, +, 10, +, 13, +, 14)
|
||||
#define Wb1 MAKE_W(SPH_T64, 6, -, 8, +, 11, +, 14, -, 15)
|
||||
#define Wb2 MAKE_W(SPH_T64, 0, +, 7, +, 9, -, 12, +, 15)
|
||||
#define Wb3 MAKE_W(SPH_T64, 0, -, 1, +, 8, -, 10, +, 13)
|
||||
#define Wb4 MAKE_W(SPH_T64, 1, +, 2, +, 9, -, 11, -, 14)
|
||||
#define Wb5 MAKE_W(SPH_T64, 3, -, 2, +, 10, -, 12, +, 15)
|
||||
#define Wb6 MAKE_W(SPH_T64, 4, -, 0, -, 3, -, 11, +, 13)
|
||||
#define Wb7 MAKE_W(SPH_T64, 1, -, 4, -, 5, -, 12, -, 14)
|
||||
#define Wb8 MAKE_W(SPH_T64, 2, -, 5, -, 6, +, 13, -, 15)
|
||||
#define Wb9 MAKE_W(SPH_T64, 0, -, 3, +, 6, -, 7, +, 14)
|
||||
#define Wb10 MAKE_W(SPH_T64, 8, -, 1, -, 4, -, 7, +, 15)
|
||||
#define Wb11 MAKE_W(SPH_T64, 8, -, 0, -, 2, -, 5, +, 9)
|
||||
#define Wb12 MAKE_W(SPH_T64, 1, +, 3, -, 6, -, 9, +, 10)
|
||||
#define Wb13 MAKE_W(SPH_T64, 2, +, 4, +, 7, +, 10, +, 11)
|
||||
#define Wb14 MAKE_W(SPH_T64, 3, -, 5, +, 8, -, 11, -, 12)
|
||||
#define Wb15 MAKE_W(SPH_T64, 12, -, 4, -, 6, -, 9, +, 13)
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT_BMW
|
||||
|
||||
#define MAKE_Qab do { \
|
||||
unsigned u; \
|
||||
sph_u64 Wb[16]; \
|
||||
Wb[ 0] = Wb0; \
|
||||
Wb[ 1] = Wb1; \
|
||||
Wb[ 2] = Wb2; \
|
||||
Wb[ 3] = Wb3; \
|
||||
Wb[ 4] = Wb4; \
|
||||
Wb[ 5] = Wb5; \
|
||||
Wb[ 6] = Wb6; \
|
||||
Wb[ 7] = Wb7; \
|
||||
Wb[ 8] = Wb8; \
|
||||
Wb[ 9] = Wb9; \
|
||||
Wb[10] = Wb10; \
|
||||
Wb[11] = Wb11; \
|
||||
Wb[12] = Wb12; \
|
||||
Wb[13] = Wb13; \
|
||||
Wb[14] = Wb14; \
|
||||
Wb[15] = Wb15; \
|
||||
for (u = 0; u < 15; u += 5) { \
|
||||
qt[u + 0] = SPH_T64(sb0(Wb[u + 0]) + H(u + 1)); \
|
||||
qt[u + 1] = SPH_T64(sb1(Wb[u + 1]) + H(u + 2)); \
|
||||
qt[u + 2] = SPH_T64(sb2(Wb[u + 2]) + H(u + 3)); \
|
||||
qt[u + 3] = SPH_T64(sb3(Wb[u + 3]) + H(u + 4)); \
|
||||
qt[u + 4] = SPH_T64(sb4(Wb[u + 4]) + H(u + 5)); \
|
||||
} \
|
||||
qt[15] = SPH_T64(sb0(Wb[15]) + H(0)); \
|
||||
} while (0)
|
||||
|
||||
#define MAKE_Qbb do { \
|
||||
unsigned u; \
|
||||
for (u = 16; u < 18; u ++) \
|
||||
qt[u] = expand1b(Qb, M, H, u); \
|
||||
for (u = 18; u < 32; u ++) \
|
||||
qt[u] = expand2b(Qb, M, H, u); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define MAKE_Qab do { \
|
||||
qt[ 0] = SPH_T64(sb0(Wb0 ) + H( 1)); \
|
||||
qt[ 1] = SPH_T64(sb1(Wb1 ) + H( 2)); \
|
||||
qt[ 2] = SPH_T64(sb2(Wb2 ) + H( 3)); \
|
||||
qt[ 3] = SPH_T64(sb3(Wb3 ) + H( 4)); \
|
||||
qt[ 4] = SPH_T64(sb4(Wb4 ) + H( 5)); \
|
||||
qt[ 5] = SPH_T64(sb0(Wb5 ) + H( 6)); \
|
||||
qt[ 6] = SPH_T64(sb1(Wb6 ) + H( 7)); \
|
||||
qt[ 7] = SPH_T64(sb2(Wb7 ) + H( 8)); \
|
||||
qt[ 8] = SPH_T64(sb3(Wb8 ) + H( 9)); \
|
||||
qt[ 9] = SPH_T64(sb4(Wb9 ) + H(10)); \
|
||||
qt[10] = SPH_T64(sb0(Wb10) + H(11)); \
|
||||
qt[11] = SPH_T64(sb1(Wb11) + H(12)); \
|
||||
qt[12] = SPH_T64(sb2(Wb12) + H(13)); \
|
||||
qt[13] = SPH_T64(sb3(Wb13) + H(14)); \
|
||||
qt[14] = SPH_T64(sb4(Wb14) + H(15)); \
|
||||
qt[15] = SPH_T64(sb0(Wb15) + H( 0)); \
|
||||
} while (0)
|
||||
|
||||
#define MAKE_Qbb do { \
|
||||
qt[16] = expand1b(Qb, M, H, 16); \
|
||||
qt[17] = expand1b(Qb, M, H, 17); \
|
||||
qt[18] = expand2b(Qb, M, H, 18); \
|
||||
qt[19] = expand2b(Qb, M, H, 19); \
|
||||
qt[20] = expand2b(Qb, M, H, 20); \
|
||||
qt[21] = expand2b(Qb, M, H, 21); \
|
||||
qt[22] = expand2b(Qb, M, H, 22); \
|
||||
qt[23] = expand2b(Qb, M, H, 23); \
|
||||
qt[24] = expand2b(Qb, M, H, 24); \
|
||||
qt[25] = expand2b(Qb, M, H, 25); \
|
||||
qt[26] = expand2b(Qb, M, H, 26); \
|
||||
qt[27] = expand2b(Qb, M, H, 27); \
|
||||
qt[28] = expand2b(Qb, M, H, 28); \
|
||||
qt[29] = expand2b(Qb, M, H, 29); \
|
||||
qt[30] = expand2b(Qb, M, H, 30); \
|
||||
qt[31] = expand2b(Qb, M, H, 31); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#define MAKE_Qb do { \
|
||||
MAKE_Qab; \
|
||||
MAKE_Qbb; \
|
||||
} while (0)
|
||||
|
||||
#define Qb(j) (qt[j])
|
||||
|
||||
#endif
|
||||
|
||||
#define FOLD(type, mkQ, tt, rol, mf, qf, dhf) do { \
|
||||
type qt[32], xl, xh; \
|
||||
mkQ; \
|
||||
xl = qf(16) ^ qf(17) ^ qf(18) ^ qf(19) \
|
||||
^ qf(20) ^ qf(21) ^ qf(22) ^ qf(23); \
|
||||
xh = xl ^ qf(24) ^ qf(25) ^ qf(26) ^ qf(27) \
|
||||
^ qf(28) ^ qf(29) ^ qf(30) ^ qf(31); \
|
||||
dhf( 0) = tt(((xh << 5) ^ (qf(16) >> 5) ^ mf( 0)) \
|
||||
+ (xl ^ qf(24) ^ qf( 0))); \
|
||||
dhf( 1) = tt(((xh >> 7) ^ (qf(17) << 8) ^ mf( 1)) \
|
||||
+ (xl ^ qf(25) ^ qf( 1))); \
|
||||
dhf( 2) = tt(((xh >> 5) ^ (qf(18) << 5) ^ mf( 2)) \
|
||||
+ (xl ^ qf(26) ^ qf( 2))); \
|
||||
dhf( 3) = tt(((xh >> 1) ^ (qf(19) << 5) ^ mf( 3)) \
|
||||
+ (xl ^ qf(27) ^ qf( 3))); \
|
||||
dhf( 4) = tt(((xh >> 3) ^ (qf(20) << 0) ^ mf( 4)) \
|
||||
+ (xl ^ qf(28) ^ qf( 4))); \
|
||||
dhf( 5) = tt(((xh << 6) ^ (qf(21) >> 6) ^ mf( 5)) \
|
||||
+ (xl ^ qf(29) ^ qf( 5))); \
|
||||
dhf( 6) = tt(((xh >> 4) ^ (qf(22) << 6) ^ mf( 6)) \
|
||||
+ (xl ^ qf(30) ^ qf( 6))); \
|
||||
dhf( 7) = tt(((xh >> 11) ^ (qf(23) << 2) ^ mf( 7)) \
|
||||
+ (xl ^ qf(31) ^ qf( 7))); \
|
||||
dhf( 8) = tt(rol(dhf(4), 9) + (xh ^ qf(24) ^ mf( 8)) \
|
||||
+ ((xl << 8) ^ qf(23) ^ qf( 8))); \
|
||||
dhf( 9) = tt(rol(dhf(5), 10) + (xh ^ qf(25) ^ mf( 9)) \
|
||||
+ ((xl >> 6) ^ qf(16) ^ qf( 9))); \
|
||||
dhf(10) = tt(rol(dhf(6), 11) + (xh ^ qf(26) ^ mf(10)) \
|
||||
+ ((xl << 6) ^ qf(17) ^ qf(10))); \
|
||||
dhf(11) = tt(rol(dhf(7), 12) + (xh ^ qf(27) ^ mf(11)) \
|
||||
+ ((xl << 4) ^ qf(18) ^ qf(11))); \
|
||||
dhf(12) = tt(rol(dhf(0), 13) + (xh ^ qf(28) ^ mf(12)) \
|
||||
+ ((xl >> 3) ^ qf(19) ^ qf(12))); \
|
||||
dhf(13) = tt(rol(dhf(1), 14) + (xh ^ qf(29) ^ mf(13)) \
|
||||
+ ((xl >> 4) ^ qf(20) ^ qf(13))); \
|
||||
dhf(14) = tt(rol(dhf(2), 15) + (xh ^ qf(30) ^ mf(14)) \
|
||||
+ ((xl >> 7) ^ qf(21) ^ qf(14))); \
|
||||
dhf(15) = tt(rol(dhf(3), 16) + (xh ^ qf(31) ^ mf(15)) \
|
||||
+ ((xl >> 2) ^ qf(22) ^ qf(15))); \
|
||||
} while (0)
|
||||
|
||||
#define FOLDs FOLD(sph_u32, MAKE_Qs, SPH_T32, SPH_ROTL32, M, Qs, dH)
|
||||
|
||||
#if SPH_64
|
||||
|
||||
#define FOLDb FOLD(sph_u64, MAKE_Qb, SPH_T64, SPH_ROTL64, M, Qb, dH)
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
compress_small(const unsigned char *data, const sph_u32 h[16], sph_u32 dh[16])
|
||||
{
|
||||
#if SPH_LITTLE_FAST
|
||||
#define M(x) sph_dec32le_aligned(data + 4 * (x))
|
||||
#else
|
||||
sph_u32 mv[16];
|
||||
|
||||
mv[ 0] = sph_dec32le_aligned(data + 0);
|
||||
mv[ 1] = sph_dec32le_aligned(data + 4);
|
||||
mv[ 2] = sph_dec32le_aligned(data + 8);
|
||||
mv[ 3] = sph_dec32le_aligned(data + 12);
|
||||
mv[ 4] = sph_dec32le_aligned(data + 16);
|
||||
mv[ 5] = sph_dec32le_aligned(data + 20);
|
||||
mv[ 6] = sph_dec32le_aligned(data + 24);
|
||||
mv[ 7] = sph_dec32le_aligned(data + 28);
|
||||
mv[ 8] = sph_dec32le_aligned(data + 32);
|
||||
mv[ 9] = sph_dec32le_aligned(data + 36);
|
||||
mv[10] = sph_dec32le_aligned(data + 40);
|
||||
mv[11] = sph_dec32le_aligned(data + 44);
|
||||
mv[12] = sph_dec32le_aligned(data + 48);
|
||||
mv[13] = sph_dec32le_aligned(data + 52);
|
||||
mv[14] = sph_dec32le_aligned(data + 56);
|
||||
mv[15] = sph_dec32le_aligned(data + 60);
|
||||
#define M(x) (mv[x])
|
||||
#endif
|
||||
#define H(x) (h[x])
|
||||
#define dH(x) (dh[x])
|
||||
|
||||
FOLDs;
|
||||
|
||||
#undef M
|
||||
#undef H
|
||||
#undef dH
|
||||
}
|
||||
|
||||
static const sph_u32 final_s[16] = {
|
||||
SPH_C32(0xaaaaaaa0), SPH_C32(0xaaaaaaa1), SPH_C32(0xaaaaaaa2),
|
||||
SPH_C32(0xaaaaaaa3), SPH_C32(0xaaaaaaa4), SPH_C32(0xaaaaaaa5),
|
||||
SPH_C32(0xaaaaaaa6), SPH_C32(0xaaaaaaa7), SPH_C32(0xaaaaaaa8),
|
||||
SPH_C32(0xaaaaaaa9), SPH_C32(0xaaaaaaaa), SPH_C32(0xaaaaaaab),
|
||||
SPH_C32(0xaaaaaaac), SPH_C32(0xaaaaaaad), SPH_C32(0xaaaaaaae),
|
||||
SPH_C32(0xaaaaaaaf)
|
||||
};
|
||||
|
||||
static void
|
||||
bmw32_init(sph_bmw_small_context *sc, const sph_u32 *iv)
|
||||
{
|
||||
memcpy(sc->H, iv, sizeof sc->H);
|
||||
sc->ptr = 0;
|
||||
#if SPH_64
|
||||
sc->bit_count = 0;
|
||||
#else
|
||||
sc->bit_count_high = 0;
|
||||
sc->bit_count_low = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
bmw32(sph_bmw_small_context *sc, const void *data, size_t len)
|
||||
{
|
||||
unsigned char *buf;
|
||||
size_t ptr;
|
||||
sph_u32 htmp[16];
|
||||
sph_u32 *h1, *h2;
|
||||
#if !SPH_64
|
||||
sph_u32 tmp;
|
||||
#endif
|
||||
|
||||
#if SPH_64
|
||||
sc->bit_count += (sph_u64)len << 3;
|
||||
#else
|
||||
tmp = sc->bit_count_low;
|
||||
sc->bit_count_low = SPH_T32(tmp + ((sph_u32)len << 3));
|
||||
if (sc->bit_count_low < tmp)
|
||||
sc->bit_count_high ++;
|
||||
sc->bit_count_high += len >> 29;
|
||||
#endif
|
||||
buf = sc->buf;
|
||||
ptr = sc->ptr;
|
||||
h1 = sc->H;
|
||||
h2 = htmp;
|
||||
while (len > 0) {
|
||||
size_t clen;
|
||||
|
||||
clen = (sizeof sc->buf) - ptr;
|
||||
if (clen > len)
|
||||
clen = len;
|
||||
memcpy(buf + ptr, data, clen);
|
||||
data = (const unsigned char *)data + clen;
|
||||
len -= clen;
|
||||
ptr += clen;
|
||||
if (ptr == sizeof sc->buf) {
|
||||
sph_u32 *ht;
|
||||
|
||||
compress_small(buf, h1, h2);
|
||||
ht = h1;
|
||||
h1 = h2;
|
||||
h2 = ht;
|
||||
ptr = 0;
|
||||
}
|
||||
}
|
||||
sc->ptr = ptr;
|
||||
if (h1 != sc->H)
|
||||
memcpy(sc->H, h1, sizeof sc->H);
|
||||
}
|
||||
|
||||
static void
|
||||
bmw32_close(sph_bmw_small_context *sc, unsigned ub, unsigned n,
|
||||
void *dst, size_t out_size_w32)
|
||||
{
|
||||
unsigned char *buf, *out;
|
||||
size_t ptr, u, v;
|
||||
unsigned z;
|
||||
sph_u32 h1[16], h2[16], *h;
|
||||
|
||||
buf = sc->buf;
|
||||
ptr = sc->ptr;
|
||||
z = 0x80 >> n;
|
||||
buf[ptr ++] = ((ub & -z) | z) & 0xFF;
|
||||
h = sc->H;
|
||||
if (ptr > (sizeof sc->buf) - 8) {
|
||||
memset(buf + ptr, 0, (sizeof sc->buf) - ptr);
|
||||
compress_small(buf, h, h1);
|
||||
ptr = 0;
|
||||
h = h1;
|
||||
}
|
||||
memset(buf + ptr, 0, (sizeof sc->buf) - 8 - ptr);
|
||||
#if SPH_64
|
||||
sph_enc64le_aligned(buf + (sizeof sc->buf) - 8,
|
||||
SPH_T64(sc->bit_count + n));
|
||||
#else
|
||||
sph_enc32le_aligned(buf + (sizeof sc->buf) - 8,
|
||||
sc->bit_count_low + n);
|
||||
sph_enc32le_aligned(buf + (sizeof sc->buf) - 4,
|
||||
SPH_T32(sc->bit_count_high));
|
||||
#endif
|
||||
compress_small(buf, h, h2);
|
||||
for (u = 0; u < 16; u ++)
|
||||
sph_enc32le_aligned(buf + 4 * u, h2[u]);
|
||||
compress_small(buf, final_s, h1);
|
||||
out = (unsigned char*) dst;
|
||||
for (u = 0, v = 16 - out_size_w32; u < out_size_w32; u ++, v ++)
|
||||
sph_enc32le(out + 4 * u, h1[v]);
|
||||
}
|
||||
|
||||
#if SPH_64
|
||||
|
||||
static void
|
||||
compress_big(const unsigned char *data, const sph_u64 h[16], sph_u64 dh[16])
|
||||
{
|
||||
#if SPH_LITTLE_FAST
|
||||
#define M(x) sph_dec64le_aligned(data + 8 * (x))
|
||||
#else
|
||||
sph_u64 mv[16];
|
||||
|
||||
mv[ 0] = sph_dec64le_aligned(data + 0);
|
||||
mv[ 1] = sph_dec64le_aligned(data + 8);
|
||||
mv[ 2] = sph_dec64le_aligned(data + 16);
|
||||
mv[ 3] = sph_dec64le_aligned(data + 24);
|
||||
mv[ 4] = sph_dec64le_aligned(data + 32);
|
||||
mv[ 5] = sph_dec64le_aligned(data + 40);
|
||||
mv[ 6] = sph_dec64le_aligned(data + 48);
|
||||
mv[ 7] = sph_dec64le_aligned(data + 56);
|
||||
mv[ 8] = sph_dec64le_aligned(data + 64);
|
||||
mv[ 9] = sph_dec64le_aligned(data + 72);
|
||||
mv[10] = sph_dec64le_aligned(data + 80);
|
||||
mv[11] = sph_dec64le_aligned(data + 88);
|
||||
mv[12] = sph_dec64le_aligned(data + 96);
|
||||
mv[13] = sph_dec64le_aligned(data + 104);
|
||||
mv[14] = sph_dec64le_aligned(data + 112);
|
||||
mv[15] = sph_dec64le_aligned(data + 120);
|
||||
#define M(x) (mv[x])
|
||||
#endif
|
||||
#define H(x) (h[x])
|
||||
#define dH(x) (dh[x])
|
||||
|
||||
FOLDb;
|
||||
|
||||
#undef M
|
||||
#undef H
|
||||
#undef dH
|
||||
}
|
||||
|
||||
static const sph_u64 final_b[16] = {
|
||||
SPH_C64(0xaaaaaaaaaaaaaaa0), SPH_C64(0xaaaaaaaaaaaaaaa1),
|
||||
SPH_C64(0xaaaaaaaaaaaaaaa2), SPH_C64(0xaaaaaaaaaaaaaaa3),
|
||||
SPH_C64(0xaaaaaaaaaaaaaaa4), SPH_C64(0xaaaaaaaaaaaaaaa5),
|
||||
SPH_C64(0xaaaaaaaaaaaaaaa6), SPH_C64(0xaaaaaaaaaaaaaaa7),
|
||||
SPH_C64(0xaaaaaaaaaaaaaaa8), SPH_C64(0xaaaaaaaaaaaaaaa9),
|
||||
SPH_C64(0xaaaaaaaaaaaaaaaa), SPH_C64(0xaaaaaaaaaaaaaaab),
|
||||
SPH_C64(0xaaaaaaaaaaaaaaac), SPH_C64(0xaaaaaaaaaaaaaaad),
|
||||
SPH_C64(0xaaaaaaaaaaaaaaae), SPH_C64(0xaaaaaaaaaaaaaaaf)
|
||||
};
|
||||
|
||||
static void
|
||||
bmw64_init(sph_bmw_big_context *sc, const sph_u64 *iv)
|
||||
{
|
||||
memcpy(sc->H, iv, sizeof sc->H);
|
||||
sc->ptr = 0;
|
||||
sc->bit_count = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
bmw64(sph_bmw_big_context *sc, const void *data, size_t len)
|
||||
{
|
||||
unsigned char *buf;
|
||||
size_t ptr;
|
||||
sph_u64 htmp[16];
|
||||
sph_u64 *h1, *h2;
|
||||
|
||||
sc->bit_count += (sph_u64)len << 3;
|
||||
buf = sc->buf;
|
||||
ptr = sc->ptr;
|
||||
h1 = sc->H;
|
||||
h2 = htmp;
|
||||
while (len > 0) {
|
||||
size_t clen;
|
||||
|
||||
clen = (sizeof sc->buf) - ptr;
|
||||
if (clen > len)
|
||||
clen = len;
|
||||
memcpy(buf + ptr, data, clen);
|
||||
data = (const unsigned char *)data + clen;
|
||||
len -= clen;
|
||||
ptr += clen;
|
||||
if (ptr == sizeof sc->buf) {
|
||||
sph_u64 *ht;
|
||||
|
||||
compress_big(buf, h1, h2);
|
||||
ht = h1;
|
||||
h1 = h2;
|
||||
h2 = ht;
|
||||
ptr = 0;
|
||||
}
|
||||
}
|
||||
sc->ptr = ptr;
|
||||
if (h1 != sc->H)
|
||||
memcpy(sc->H, h1, sizeof sc->H);
|
||||
}
|
||||
|
||||
static void
|
||||
bmw64_close(sph_bmw_big_context *sc, unsigned ub, unsigned n,
|
||||
void *dst, size_t out_size_w64)
|
||||
{
|
||||
unsigned char *buf, *out;
|
||||
size_t ptr, u, v;
|
||||
unsigned z;
|
||||
sph_u64 h1[16], h2[16], *h;
|
||||
|
||||
buf = sc->buf;
|
||||
ptr = sc->ptr;
|
||||
z = 0x80 >> n;
|
||||
buf[ptr ++] = ((ub & -z) | z) & 0xFF;
|
||||
h = sc->H;
|
||||
if (ptr > (sizeof sc->buf) - 8) {
|
||||
memset(buf + ptr, 0, (sizeof sc->buf) - ptr);
|
||||
compress_big(buf, h, h1);
|
||||
ptr = 0;
|
||||
h = h1;
|
||||
}
|
||||
memset(buf + ptr, 0, (sizeof sc->buf) - 8 - ptr);
|
||||
sph_enc64le_aligned(buf + (sizeof sc->buf) - 8,
|
||||
SPH_T64(sc->bit_count + n));
|
||||
compress_big(buf, h, h2);
|
||||
for (u = 0; u < 16; u ++)
|
||||
sph_enc64le_aligned(buf + 8 * u, h2[u]);
|
||||
compress_big(buf, final_b, h1);
|
||||
out = (unsigned char*) dst;
|
||||
for (u = 0, v = 16 - out_size_w64; u < out_size_w64; u ++, v ++)
|
||||
sph_enc64le(out + 8 * u, h1[v]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw224_init(void *cc)
|
||||
{
|
||||
bmw32_init((sph_bmw_small_context*) cc, IV224);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw224(void *cc, const void *data, size_t len)
|
||||
{
|
||||
bmw32((sph_bmw_small_context*) cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw224_close(void *cc, void *dst)
|
||||
{
|
||||
sph_bmw224_addbits_and_close((sph_bmw_small_context*) cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
bmw32_close((sph_bmw_small_context*) cc, ub, n, dst, 7);
|
||||
sph_bmw224_init(cc);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw256_init(void *cc)
|
||||
{
|
||||
bmw32_init((sph_bmw_small_context*) cc, IV256);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw256(void *cc, const void *data, size_t len)
|
||||
{
|
||||
bmw32((sph_bmw_small_context*) cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw256_close(void *cc, void *dst)
|
||||
{
|
||||
sph_bmw256_addbits_and_close((sph_bmw_small_context*) cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
bmw32_close((sph_bmw_small_context*) cc, ub, n, dst, 8);
|
||||
sph_bmw256_init(cc);
|
||||
}
|
||||
|
||||
#if SPH_64
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw384_init(void *cc)
|
||||
{
|
||||
bmw64_init((sph_bmw_big_context*) cc, IV384);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw384(void *cc, const void *data, size_t len)
|
||||
{
|
||||
bmw64((sph_bmw_big_context*) cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw384_close(void *cc, void *dst)
|
||||
{
|
||||
sph_bmw384_addbits_and_close((sph_bmw_big_context*) cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
bmw64_close((sph_bmw_big_context*) cc, ub, n, dst, 6);
|
||||
sph_bmw384_init(cc);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw512_init(void *cc)
|
||||
{
|
||||
bmw64_init((sph_bmw_big_context*) cc, IV512);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw512(void *cc, const void *data, size_t len)
|
||||
{
|
||||
bmw64((sph_bmw_big_context*) cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw512_close(void *cc, void *dst)
|
||||
{
|
||||
sph_bmw512_addbits_and_close((sph_bmw_big_context*) cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_bmw.h */
|
||||
void
|
||||
sph_bmw512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
bmw64_close((sph_bmw_big_context*) cc, ub, n, dst, 8);
|
||||
sph_bmw512_init(cc);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
142
src/crypto/brg_endian.h
Normal file
142
src/crypto/brg_endian.h
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
LICENSE TERMS
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
1. source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
2. binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation;
|
||||
|
||||
3. the name of the copyright holder is not used to endorse products
|
||||
built using this software without specific written permission.
|
||||
|
||||
DISCLAIMER
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its properties, including, but not limited to, correctness
|
||||
and/or fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
Changes for ARM 9/9/2010
|
||||
*/
|
||||
|
||||
#ifndef _BRG_ENDIAN_H
|
||||
#define _BRG_ENDIAN_H
|
||||
|
||||
#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */
|
||||
#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */
|
||||
|
||||
#if 0
|
||||
/* Include files where endian defines and byteswap functions may reside */
|
||||
#if defined( __sun )
|
||||
# include <sys/isa_defs.h>
|
||||
#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
|
||||
# include <sys/endian.h>
|
||||
#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \
|
||||
defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )
|
||||
# include <machine/endian.h>
|
||||
#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
|
||||
# if !defined( __MINGW32__ ) && !defined( _AIX )
|
||||
# include <endian.h>
|
||||
# if !defined( __BEOS__ )
|
||||
# include <byteswap.h>
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Now attempt to set the define for platform byte order using any */
|
||||
/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */
|
||||
/* seem to encompass most endian symbol definitions */
|
||||
|
||||
#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN )
|
||||
# if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( BIG_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( LITTLE_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN )
|
||||
# if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( _BIG_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( _LITTLE_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN )
|
||||
# if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( __BIG_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( __LITTLE_ENDIAN )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ )
|
||||
# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif defined( __BIG_ENDIAN__ )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#elif defined( __LITTLE_ENDIAN__ )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
/* if the platform byte order could not be determined, then try to */
|
||||
/* set this define using common machine defines */
|
||||
#if !defined(PLATFORM_BYTE_ORDER)
|
||||
|
||||
#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \
|
||||
defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \
|
||||
defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \
|
||||
defined( vax ) || defined( vms ) || defined( VMS ) || \
|
||||
defined( __VMS ) || defined( _M_X64 )
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
|
||||
#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \
|
||||
defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \
|
||||
defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \
|
||||
defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \
|
||||
defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \
|
||||
defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \
|
||||
defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
|
||||
#elif defined(__arm__)
|
||||
# ifdef __BIG_ENDIAN
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
# else
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
# endif
|
||||
#elif 1 /* **** EDIT HERE IF NECESSARY **** */
|
||||
# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
|
||||
#elif 0 /* **** EDIT HERE IF NECESSARY **** */
|
||||
# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
|
||||
#else
|
||||
# error Please edit lines 132 or 134 in brg_endian.h to set the platform byte order
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
311
src/crypto/chacha20.cpp
Normal file
311
src/crypto/chacha20.cpp
Normal file
|
|
@ -0,0 +1,311 @@
|
|||
// Copyright (c) 2017-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2017-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
// Based on the public domain implementation 'merged' by D. J. Bernstein
|
||||
// See https://cr.yp.to/chacha.html.
|
||||
|
||||
#include <crypto/common.h>
|
||||
#include <crypto/chacha20.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
constexpr static inline uint32_t rotl32(uint32_t v, int c) { return (v << c) | (v >> (32 - c)); }
|
||||
|
||||
#define QUARTERROUND(a,b,c,d) \
|
||||
a += b; d = rotl32(d ^ a, 16); \
|
||||
c += d; b = rotl32(b ^ c, 12); \
|
||||
a += b; d = rotl32(d ^ a, 8); \
|
||||
c += d; b = rotl32(b ^ c, 7);
|
||||
|
||||
static const unsigned char sigma[] = "expand 32-byte k";
|
||||
static const unsigned char tau[] = "expand 16-byte k";
|
||||
|
||||
void ChaCha20::SetKey(const unsigned char* k, size_t keylen)
|
||||
{
|
||||
const unsigned char *constants;
|
||||
|
||||
input[4] = ReadLE32(k + 0);
|
||||
input[5] = ReadLE32(k + 4);
|
||||
input[6] = ReadLE32(k + 8);
|
||||
input[7] = ReadLE32(k + 12);
|
||||
if (keylen == 32) { /* recommended */
|
||||
k += 16;
|
||||
constants = sigma;
|
||||
} else { /* keylen == 16 */
|
||||
constants = tau;
|
||||
}
|
||||
input[8] = ReadLE32(k + 0);
|
||||
input[9] = ReadLE32(k + 4);
|
||||
input[10] = ReadLE32(k + 8);
|
||||
input[11] = ReadLE32(k + 12);
|
||||
input[0] = ReadLE32(constants + 0);
|
||||
input[1] = ReadLE32(constants + 4);
|
||||
input[2] = ReadLE32(constants + 8);
|
||||
input[3] = ReadLE32(constants + 12);
|
||||
input[12] = 0;
|
||||
input[13] = 0;
|
||||
input[14] = 0;
|
||||
input[15] = 0;
|
||||
}
|
||||
|
||||
ChaCha20::ChaCha20()
|
||||
{
|
||||
memset(input, 0, sizeof(input));
|
||||
}
|
||||
|
||||
ChaCha20::ChaCha20(const unsigned char* k, size_t keylen)
|
||||
{
|
||||
SetKey(k, keylen);
|
||||
}
|
||||
|
||||
void ChaCha20::SetIV(uint64_t iv)
|
||||
{
|
||||
input[14] = iv;
|
||||
input[15] = iv >> 32;
|
||||
}
|
||||
|
||||
void ChaCha20::Seek(uint64_t pos)
|
||||
{
|
||||
input[12] = pos;
|
||||
input[13] = pos >> 32;
|
||||
}
|
||||
|
||||
void ChaCha20::Keystream(unsigned char* c, size_t bytes)
|
||||
{
|
||||
uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
|
||||
uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
|
||||
unsigned char *ctarget = nullptr;
|
||||
unsigned char tmp[64];
|
||||
unsigned int i;
|
||||
|
||||
if (!bytes) return;
|
||||
|
||||
j0 = input[0];
|
||||
j1 = input[1];
|
||||
j2 = input[2];
|
||||
j3 = input[3];
|
||||
j4 = input[4];
|
||||
j5 = input[5];
|
||||
j6 = input[6];
|
||||
j7 = input[7];
|
||||
j8 = input[8];
|
||||
j9 = input[9];
|
||||
j10 = input[10];
|
||||
j11 = input[11];
|
||||
j12 = input[12];
|
||||
j13 = input[13];
|
||||
j14 = input[14];
|
||||
j15 = input[15];
|
||||
|
||||
for (;;) {
|
||||
if (bytes < 64) {
|
||||
ctarget = c;
|
||||
c = tmp;
|
||||
}
|
||||
x0 = j0;
|
||||
x1 = j1;
|
||||
x2 = j2;
|
||||
x3 = j3;
|
||||
x4 = j4;
|
||||
x5 = j5;
|
||||
x6 = j6;
|
||||
x7 = j7;
|
||||
x8 = j8;
|
||||
x9 = j9;
|
||||
x10 = j10;
|
||||
x11 = j11;
|
||||
x12 = j12;
|
||||
x13 = j13;
|
||||
x14 = j14;
|
||||
x15 = j15;
|
||||
for (i = 20;i > 0;i -= 2) {
|
||||
QUARTERROUND( x0, x4, x8,x12)
|
||||
QUARTERROUND( x1, x5, x9,x13)
|
||||
QUARTERROUND( x2, x6,x10,x14)
|
||||
QUARTERROUND( x3, x7,x11,x15)
|
||||
QUARTERROUND( x0, x5,x10,x15)
|
||||
QUARTERROUND( x1, x6,x11,x12)
|
||||
QUARTERROUND( x2, x7, x8,x13)
|
||||
QUARTERROUND( x3, x4, x9,x14)
|
||||
}
|
||||
x0 += j0;
|
||||
x1 += j1;
|
||||
x2 += j2;
|
||||
x3 += j3;
|
||||
x4 += j4;
|
||||
x5 += j5;
|
||||
x6 += j6;
|
||||
x7 += j7;
|
||||
x8 += j8;
|
||||
x9 += j9;
|
||||
x10 += j10;
|
||||
x11 += j11;
|
||||
x12 += j12;
|
||||
x13 += j13;
|
||||
x14 += j14;
|
||||
x15 += j15;
|
||||
|
||||
++j12;
|
||||
if (!j12) ++j13;
|
||||
|
||||
WriteLE32(c + 0, x0);
|
||||
WriteLE32(c + 4, x1);
|
||||
WriteLE32(c + 8, x2);
|
||||
WriteLE32(c + 12, x3);
|
||||
WriteLE32(c + 16, x4);
|
||||
WriteLE32(c + 20, x5);
|
||||
WriteLE32(c + 24, x6);
|
||||
WriteLE32(c + 28, x7);
|
||||
WriteLE32(c + 32, x8);
|
||||
WriteLE32(c + 36, x9);
|
||||
WriteLE32(c + 40, x10);
|
||||
WriteLE32(c + 44, x11);
|
||||
WriteLE32(c + 48, x12);
|
||||
WriteLE32(c + 52, x13);
|
||||
WriteLE32(c + 56, x14);
|
||||
WriteLE32(c + 60, x15);
|
||||
|
||||
if (bytes <= 64) {
|
||||
if (bytes < 64) {
|
||||
for (i = 0;i < bytes;++i) ctarget[i] = c[i];
|
||||
}
|
||||
input[12] = j12;
|
||||
input[13] = j13;
|
||||
return;
|
||||
}
|
||||
bytes -= 64;
|
||||
c += 64;
|
||||
}
|
||||
}
|
||||
|
||||
void ChaCha20::Crypt(const unsigned char* m, unsigned char* c, size_t bytes)
|
||||
{
|
||||
uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
|
||||
uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
|
||||
unsigned char *ctarget = nullptr;
|
||||
unsigned char tmp[64];
|
||||
unsigned int i;
|
||||
|
||||
if (!bytes) return;
|
||||
|
||||
j0 = input[0];
|
||||
j1 = input[1];
|
||||
j2 = input[2];
|
||||
j3 = input[3];
|
||||
j4 = input[4];
|
||||
j5 = input[5];
|
||||
j6 = input[6];
|
||||
j7 = input[7];
|
||||
j8 = input[8];
|
||||
j9 = input[9];
|
||||
j10 = input[10];
|
||||
j11 = input[11];
|
||||
j12 = input[12];
|
||||
j13 = input[13];
|
||||
j14 = input[14];
|
||||
j15 = input[15];
|
||||
|
||||
for (;;) {
|
||||
if (bytes < 64) {
|
||||
// if m has fewer than 64 bytes available, copy m to tmp and
|
||||
// read from tmp instead
|
||||
for (i = 0;i < bytes;++i) tmp[i] = m[i];
|
||||
m = tmp;
|
||||
ctarget = c;
|
||||
c = tmp;
|
||||
}
|
||||
x0 = j0;
|
||||
x1 = j1;
|
||||
x2 = j2;
|
||||
x3 = j3;
|
||||
x4 = j4;
|
||||
x5 = j5;
|
||||
x6 = j6;
|
||||
x7 = j7;
|
||||
x8 = j8;
|
||||
x9 = j9;
|
||||
x10 = j10;
|
||||
x11 = j11;
|
||||
x12 = j12;
|
||||
x13 = j13;
|
||||
x14 = j14;
|
||||
x15 = j15;
|
||||
for (i = 20;i > 0;i -= 2) {
|
||||
QUARTERROUND( x0, x4, x8,x12)
|
||||
QUARTERROUND( x1, x5, x9,x13)
|
||||
QUARTERROUND( x2, x6,x10,x14)
|
||||
QUARTERROUND( x3, x7,x11,x15)
|
||||
QUARTERROUND( x0, x5,x10,x15)
|
||||
QUARTERROUND( x1, x6,x11,x12)
|
||||
QUARTERROUND( x2, x7, x8,x13)
|
||||
QUARTERROUND( x3, x4, x9,x14)
|
||||
}
|
||||
x0 += j0;
|
||||
x1 += j1;
|
||||
x2 += j2;
|
||||
x3 += j3;
|
||||
x4 += j4;
|
||||
x5 += j5;
|
||||
x6 += j6;
|
||||
x7 += j7;
|
||||
x8 += j8;
|
||||
x9 += j9;
|
||||
x10 += j10;
|
||||
x11 += j11;
|
||||
x12 += j12;
|
||||
x13 += j13;
|
||||
x14 += j14;
|
||||
x15 += j15;
|
||||
|
||||
x0 ^= ReadLE32(m + 0);
|
||||
x1 ^= ReadLE32(m + 4);
|
||||
x2 ^= ReadLE32(m + 8);
|
||||
x3 ^= ReadLE32(m + 12);
|
||||
x4 ^= ReadLE32(m + 16);
|
||||
x5 ^= ReadLE32(m + 20);
|
||||
x6 ^= ReadLE32(m + 24);
|
||||
x7 ^= ReadLE32(m + 28);
|
||||
x8 ^= ReadLE32(m + 32);
|
||||
x9 ^= ReadLE32(m + 36);
|
||||
x10 ^= ReadLE32(m + 40);
|
||||
x11 ^= ReadLE32(m + 44);
|
||||
x12 ^= ReadLE32(m + 48);
|
||||
x13 ^= ReadLE32(m + 52);
|
||||
x14 ^= ReadLE32(m + 56);
|
||||
x15 ^= ReadLE32(m + 60);
|
||||
|
||||
++j12;
|
||||
if (!j12) ++j13;
|
||||
|
||||
WriteLE32(c + 0, x0);
|
||||
WriteLE32(c + 4, x1);
|
||||
WriteLE32(c + 8, x2);
|
||||
WriteLE32(c + 12, x3);
|
||||
WriteLE32(c + 16, x4);
|
||||
WriteLE32(c + 20, x5);
|
||||
WriteLE32(c + 24, x6);
|
||||
WriteLE32(c + 28, x7);
|
||||
WriteLE32(c + 32, x8);
|
||||
WriteLE32(c + 36, x9);
|
||||
WriteLE32(c + 40, x10);
|
||||
WriteLE32(c + 44, x11);
|
||||
WriteLE32(c + 48, x12);
|
||||
WriteLE32(c + 52, x13);
|
||||
WriteLE32(c + 56, x14);
|
||||
WriteLE32(c + 60, x15);
|
||||
|
||||
if (bytes <= 64) {
|
||||
if (bytes < 64) {
|
||||
for (i = 0;i < bytes;++i) ctarget[i] = c[i];
|
||||
}
|
||||
input[12] = j12;
|
||||
input[13] = j13;
|
||||
return;
|
||||
}
|
||||
bytes -= 64;
|
||||
c += 64;
|
||||
m += 64;
|
||||
}
|
||||
}
|
||||
35
src/crypto/chacha20.h
Normal file
35
src/crypto/chacha20.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2017-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2017-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef DIGIBYTE_CRYPTO_CHACHA20_H
|
||||
#define DIGIBYTE_CRYPTO_CHACHA20_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** A class for ChaCha20 256-bit stream cipher developed by Daniel J. Bernstein
|
||||
https://cr.yp.to/chacha/chacha-20080128.pdf */
|
||||
class ChaCha20
|
||||
{
|
||||
private:
|
||||
uint32_t input[16];
|
||||
|
||||
public:
|
||||
ChaCha20();
|
||||
ChaCha20(const unsigned char* key, size_t keylen);
|
||||
void SetKey(const unsigned char* key, size_t keylen); //!< set key with flexible keylength; 256bit recommended */
|
||||
void SetIV(uint64_t iv); // set the 64bit nonce
|
||||
void Seek(uint64_t pos); // set the 64bit block counter
|
||||
|
||||
/** outputs the keystream of size <bytes> into <c> */
|
||||
void Keystream(unsigned char* c, size_t bytes);
|
||||
|
||||
/** enciphers the message <input> of length <bytes> and write the enciphered representation into <output>
|
||||
* Used for encryption and decryption (XOR)
|
||||
*/
|
||||
void Crypt(const unsigned char* input, unsigned char* output, size_t bytes);
|
||||
};
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_CHACHA20_H
|
||||
125
src/crypto/chacha_poly_aead.cpp
Normal file
125
src/crypto/chacha_poly_aead.cpp
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
// Copyright (c) 2019 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <crypto/chacha_poly_aead.h>
|
||||
|
||||
#include <crypto/poly1305.h>
|
||||
#include <support/cleanse.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
|
||||
#ifndef HAVE_TIMINGSAFE_BCMP
|
||||
|
||||
int timingsafe_bcmp(const unsigned char* b1, const unsigned char* b2, size_t n)
|
||||
{
|
||||
const unsigned char *p1 = b1, *p2 = b2;
|
||||
int ret = 0;
|
||||
|
||||
for (; n > 0; n--)
|
||||
ret |= *p1++ ^ *p2++;
|
||||
return (ret != 0);
|
||||
}
|
||||
|
||||
#endif // TIMINGSAFE_BCMP
|
||||
|
||||
ChaCha20Poly1305AEAD::ChaCha20Poly1305AEAD(const unsigned char* K_1, size_t K_1_len, const unsigned char* K_2, size_t K_2_len)
|
||||
{
|
||||
assert(K_1_len == CHACHA20_POLY1305_AEAD_KEY_LEN);
|
||||
assert(K_2_len == CHACHA20_POLY1305_AEAD_KEY_LEN);
|
||||
m_chacha_main.SetKey(K_1, CHACHA20_POLY1305_AEAD_KEY_LEN);
|
||||
m_chacha_header.SetKey(K_2, CHACHA20_POLY1305_AEAD_KEY_LEN);
|
||||
|
||||
// set the cached sequence number to uint64 max which hints for an unset cache.
|
||||
// we can't hit uint64 max since the rekey rule (which resets the sequence number) is 1GB
|
||||
m_cached_aad_seqnr = std::numeric_limits<uint64_t>::max();
|
||||
}
|
||||
|
||||
bool ChaCha20Poly1305AEAD::Crypt(uint64_t seqnr_payload, uint64_t seqnr_aad, int aad_pos, unsigned char* dest, size_t dest_len /* length of the output buffer for sanity checks */, const unsigned char* src, size_t src_len, bool is_encrypt)
|
||||
{
|
||||
// check buffer boundaries
|
||||
if (
|
||||
// if we encrypt, make sure the source contains at least the expected AAD and the destination has at least space for the source + MAC
|
||||
(is_encrypt && (src_len < CHACHA20_POLY1305_AEAD_AAD_LEN || dest_len < src_len + POLY1305_TAGLEN)) ||
|
||||
// if we decrypt, make sure the source contains at least the expected AAD+MAC and the destination has at least space for the source - MAC
|
||||
(!is_encrypt && (src_len < CHACHA20_POLY1305_AEAD_AAD_LEN + POLY1305_TAGLEN || dest_len < src_len - POLY1305_TAGLEN))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];
|
||||
memset(poly_key, 0, sizeof(poly_key));
|
||||
m_chacha_main.SetIV(seqnr_payload);
|
||||
|
||||
// block counter 0 for the poly1305 key
|
||||
// use lower 32bytes for the poly1305 key
|
||||
// (throws away 32 unused bytes (upper 32) from this ChaCha20 round)
|
||||
m_chacha_main.Seek(0);
|
||||
m_chacha_main.Crypt(poly_key, poly_key, sizeof(poly_key));
|
||||
|
||||
// if decrypting, verify the tag prior to decryption
|
||||
if (!is_encrypt) {
|
||||
const unsigned char* tag = src + src_len - POLY1305_TAGLEN;
|
||||
poly1305_auth(expected_tag, src, src_len - POLY1305_TAGLEN, poly_key);
|
||||
|
||||
// constant time compare the calculated MAC with the provided MAC
|
||||
if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) {
|
||||
memory_cleanse(expected_tag, sizeof(expected_tag));
|
||||
memory_cleanse(poly_key, sizeof(poly_key));
|
||||
return false;
|
||||
}
|
||||
memory_cleanse(expected_tag, sizeof(expected_tag));
|
||||
// MAC has been successfully verified, make sure we don't covert it in decryption
|
||||
src_len -= POLY1305_TAGLEN;
|
||||
}
|
||||
|
||||
// calculate and cache the next 64byte keystream block if requested sequence number is not yet the cache
|
||||
if (m_cached_aad_seqnr != seqnr_aad) {
|
||||
m_cached_aad_seqnr = seqnr_aad;
|
||||
m_chacha_header.SetIV(seqnr_aad);
|
||||
m_chacha_header.Seek(0);
|
||||
m_chacha_header.Keystream(m_aad_keystream_buffer, CHACHA20_ROUND_OUTPUT);
|
||||
}
|
||||
// crypt the AAD (3 bytes message length) with given position in AAD cipher instance keystream
|
||||
dest[0] = src[0] ^ m_aad_keystream_buffer[aad_pos];
|
||||
dest[1] = src[1] ^ m_aad_keystream_buffer[aad_pos + 1];
|
||||
dest[2] = src[2] ^ m_aad_keystream_buffer[aad_pos + 2];
|
||||
|
||||
// Set the playload ChaCha instance block counter to 1 and crypt the payload
|
||||
m_chacha_main.Seek(1);
|
||||
m_chacha_main.Crypt(src + CHACHA20_POLY1305_AEAD_AAD_LEN, dest + CHACHA20_POLY1305_AEAD_AAD_LEN, src_len - CHACHA20_POLY1305_AEAD_AAD_LEN);
|
||||
|
||||
// If encrypting, calculate and append tag
|
||||
if (is_encrypt) {
|
||||
// the poly1305 tag expands over the AAD (3 bytes length) & encrypted payload
|
||||
poly1305_auth(dest + src_len, dest, src_len, poly_key);
|
||||
}
|
||||
|
||||
// cleanse no longer required MAC and polykey
|
||||
memory_cleanse(poly_key, sizeof(poly_key));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChaCha20Poly1305AEAD::GetLength(uint32_t* len24_out, uint64_t seqnr_aad, int aad_pos, const uint8_t* ciphertext)
|
||||
{
|
||||
// enforce valid aad position to avoid accessing outside of the 64byte keystream cache
|
||||
// (there is space for 21 times 3 bytes)
|
||||
assert(aad_pos >= 0 && aad_pos < CHACHA20_ROUND_OUTPUT - CHACHA20_POLY1305_AEAD_AAD_LEN);
|
||||
if (m_cached_aad_seqnr != seqnr_aad) {
|
||||
// we need to calculate the 64 keystream bytes since we reached a new aad sequence number
|
||||
m_cached_aad_seqnr = seqnr_aad;
|
||||
m_chacha_header.SetIV(seqnr_aad); // use LE for the nonce
|
||||
m_chacha_header.Seek(0); // block counter 0
|
||||
m_chacha_header.Keystream(m_aad_keystream_buffer, CHACHA20_ROUND_OUTPUT); // write keystream to the cache
|
||||
}
|
||||
|
||||
// decrypt the ciphertext length by XORing the right position of the 64byte keystream cache with the ciphertext
|
||||
*len24_out = (ciphertext[0] ^ m_aad_keystream_buffer[aad_pos + 0]) |
|
||||
(ciphertext[1] ^ m_aad_keystream_buffer[aad_pos + 1]) << 8 |
|
||||
(ciphertext[2] ^ m_aad_keystream_buffer[aad_pos + 2]) << 16;
|
||||
|
||||
return true;
|
||||
}
|
||||
146
src/crypto/chacha_poly_aead.h
Normal file
146
src/crypto/chacha_poly_aead.h
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
// Copyright (c) 2019 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef DIGIBYTE_CRYPTO_CHACHA_POLY_AEAD_H
|
||||
#define DIGIBYTE_CRYPTO_CHACHA_POLY_AEAD_H
|
||||
|
||||
#include <crypto/chacha20.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
static constexpr int CHACHA20_POLY1305_AEAD_KEY_LEN = 32;
|
||||
static constexpr int CHACHA20_POLY1305_AEAD_AAD_LEN = 3; /* 3 bytes length */
|
||||
static constexpr int CHACHA20_ROUND_OUTPUT = 64; /* 64 bytes per round */
|
||||
static constexpr int AAD_PACKAGES_PER_ROUND = 21; /* 64 / 3 round down*/
|
||||
|
||||
/* A AEAD class for ChaCha20-Poly1305@digibyte.
|
||||
*
|
||||
* ChaCha20 is a stream cipher designed by Daniel Bernstein and described in
|
||||
* <ref>[https://cr.yp.to/chacha/chacha-20080128.pdf ChaCha20]</ref>. It operates
|
||||
* by permuting 128 fixed bits, 128 or 256 bits of key, a 64 bit nonce and a 64
|
||||
* bit counter into 64 bytes of output. This output is used as a keystream, with
|
||||
* any unused bytes simply discarded.
|
||||
*
|
||||
* Poly1305 <ref>[https://cr.yp.to/mac/poly1305-20050329.pdf Poly1305]</ref>, also
|
||||
* by Daniel Bernstein, is a one-time Carter-Wegman MAC that computes a 128 bit
|
||||
* integrity tag given a message and a single-use 256 bit secret key.
|
||||
*
|
||||
* The chacha20-poly1305@digibyte combines these two primitives into an
|
||||
* authenticated encryption mode. The construction used is based on that proposed
|
||||
* for TLS by Adam Langley in
|
||||
* <ref>[http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03 "ChaCha20
|
||||
* and Poly1305 based Cipher Suites for TLS", Adam Langley]</ref>, but differs in
|
||||
* the layout of data passed to the MAC and in the addition of encryption of the
|
||||
* packet lengths.
|
||||
*
|
||||
* ==== Detailed Construction ====
|
||||
*
|
||||
* The chacha20-poly1305@digibyte cipher requires two 256 bits of key material as
|
||||
* output from the key exchange. Each key (K_1 and K_2) are used by two separate
|
||||
* instances of chacha20.
|
||||
*
|
||||
* The instance keyed by K_1 is a stream cipher that is used only to encrypt the 3
|
||||
* byte packet length field and has its own sequence number. The second instance,
|
||||
* keyed by K_2, is used in conjunction with poly1305 to build an AEAD
|
||||
* (Authenticated Encryption with Associated Data) that is used to encrypt and
|
||||
* authenticate the entire packet.
|
||||
*
|
||||
* Two separate cipher instances are used here so as to keep the packet lengths
|
||||
* confidential but not create an oracle for the packet payload cipher by
|
||||
* decrypting and using the packet length prior to checking the MAC. By using an
|
||||
* independently-keyed cipher instance to encrypt the length, an active attacker
|
||||
* seeking to exploit the packet input handling as a decryption oracle can learn
|
||||
* nothing about the payload contents or its MAC (assuming key derivation,
|
||||
* ChaCha20 and Poly1305 are secure).
|
||||
*
|
||||
* The AEAD is constructed as follows: for each packet, generate a Poly1305 key by
|
||||
* taking the first 256 bits of ChaCha20 stream output generated using K_2, an IV
|
||||
* consisting of the packet sequence number encoded as an LE uint64 and a ChaCha20
|
||||
* block counter of zero. The K_2 ChaCha20 block counter is then set to the
|
||||
* little-endian encoding of 1 (i.e. {1, 0, 0, 0, 0, 0, 0, 0}) and this instance
|
||||
* is used for encryption of the packet payload.
|
||||
*
|
||||
* ==== Packet Handling ====
|
||||
*
|
||||
* When receiving a packet, the length must be decrypted first. When 3 bytes of
|
||||
* ciphertext length have been received, they may be decrypted.
|
||||
*
|
||||
* A ChaCha20 round always calculates 64bytes which is sufficient to crypt 21
|
||||
* times a 3 bytes length field (21*3 = 63). The length field sequence number can
|
||||
* thus be used 21 times (keystream caching).
|
||||
*
|
||||
* The length field must be enc-/decrypted with the ChaCha20 keystream keyed with
|
||||
* K_1 defined by block counter 0, the length field sequence number in little
|
||||
* endian and a keystream position from 0 to 60.
|
||||
*
|
||||
* Once the entire packet has been received, the MAC MUST be checked before
|
||||
* decryption. A per-packet Poly1305 key is generated as described above and the
|
||||
* MAC tag calculated using Poly1305 with this key over the ciphertext of the
|
||||
* packet length and the payload together. The calculated MAC is then compared in
|
||||
* constant time with the one appended to the packet and the packet decrypted
|
||||
* using ChaCha20 as described above (with K_2, the packet sequence number as
|
||||
* nonce and a starting block counter of 1).
|
||||
*
|
||||
* Detection of an invalid MAC MUST lead to immediate connection termination.
|
||||
*
|
||||
* To send a packet, first encode the 3 byte length and encrypt it using K_1 as
|
||||
* described above. Encrypt the packet payload (using K_2) and append it to the
|
||||
* encrypted length. Finally, calculate a MAC tag and append it.
|
||||
*
|
||||
* The initiating peer MUST use <code>K_1_A, K_2_A</code> to encrypt messages on
|
||||
* the send channel, <code>K_1_B, K_2_B</code> MUST be used to decrypt messages on
|
||||
* the receive channel.
|
||||
*
|
||||
* The responding peer MUST use <code>K_1_A, K_2_A</code> to decrypt messages on
|
||||
* the receive channel, <code>K_1_B, K_2_B</code> MUST be used to encrypt messages
|
||||
* on the send channel.
|
||||
*
|
||||
* Optimized implementations of ChaCha20-Poly1305@digibyte are relatively fast in
|
||||
* general, therefore it is very likely that encrypted messages require not more
|
||||
* CPU cycles per bytes then the current unencrypted p2p message format
|
||||
* (ChaCha20/Poly1305 versus double SHA256).
|
||||
*
|
||||
* The initial packet sequence numbers are 0.
|
||||
*
|
||||
* K_2 ChaCha20 cipher instance (payload) must never reuse a {key, nonce} for
|
||||
* encryption nor may it be used to encrypt more than 2^70 bytes under the same
|
||||
* {key, nonce}.
|
||||
*
|
||||
* K_1 ChaCha20 cipher instance (length field/AAD) must never reuse a {key, nonce,
|
||||
* position-in-keystream} for encryption nor may it be used to encrypt more than
|
||||
* 2^70 bytes under the same {key, nonce}.
|
||||
*
|
||||
* We use message sequence numbers for both communication directions.
|
||||
*/
|
||||
|
||||
class ChaCha20Poly1305AEAD
|
||||
{
|
||||
private:
|
||||
ChaCha20 m_chacha_main; // payload and poly1305 key-derivation cipher instance
|
||||
ChaCha20 m_chacha_header; // AAD cipher instance (encrypted length)
|
||||
unsigned char m_aad_keystream_buffer[CHACHA20_ROUND_OUTPUT]; // aad keystream cache
|
||||
uint64_t m_cached_aad_seqnr; // aad keystream cache hint
|
||||
|
||||
public:
|
||||
ChaCha20Poly1305AEAD(const unsigned char* K_1, size_t K_1_len, const unsigned char* K_2, size_t K_2_len);
|
||||
|
||||
explicit ChaCha20Poly1305AEAD(const ChaCha20Poly1305AEAD&) = delete;
|
||||
|
||||
/** Encrypts/decrypts a packet
|
||||
seqnr_payload, the message sequence number
|
||||
seqnr_aad, the messages AAD sequence number which allows reuse of the AAD keystream
|
||||
aad_pos, position to use in the AAD keystream to encrypt the AAD
|
||||
dest, output buffer, must be of a size equal or larger then CHACHA20_POLY1305_AEAD_AAD_LEN + payload (+ POLY1305_TAG_LEN in encryption) bytes
|
||||
destlen, length of the destination buffer
|
||||
src, the AAD+payload to encrypt or the AAD+payload+MAC to decrypt
|
||||
src_len, the length of the source buffer
|
||||
is_encrypt, set to true if we encrypt (creates and appends the MAC instead of verifying it)
|
||||
*/
|
||||
bool Crypt(uint64_t seqnr_payload, uint64_t seqnr_aad, int aad_pos, unsigned char* dest, size_t dest_len, const unsigned char* src, size_t src_len, bool is_encrypt);
|
||||
|
||||
/** decrypts the 3 bytes AAD data and decodes it into a uint32_t field */
|
||||
bool GetLength(uint32_t* len24_out, uint64_t seqnr_aad, int aad_pos, const uint8_t* ciphertext);
|
||||
};
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_CHACHA_POLY_AEAD_H
|
||||
111
src/crypto/common.h
Normal file
111
src/crypto/common.h
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef DIGIBYTE_CRYPTO_COMMON_H
|
||||
#define DIGIBYTE_CRYPTO_COMMON_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config/vexta-config.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <compat/endian.h>
|
||||
|
||||
uint16_t static inline ReadLE16(const unsigned char* ptr)
|
||||
{
|
||||
uint16_t x;
|
||||
memcpy((char*)&x, ptr, 2);
|
||||
return le16toh(x);
|
||||
}
|
||||
|
||||
uint32_t static inline ReadLE32(const unsigned char* ptr)
|
||||
{
|
||||
uint32_t x;
|
||||
memcpy((char*)&x, ptr, 4);
|
||||
return le32toh(x);
|
||||
}
|
||||
|
||||
uint64_t static inline ReadLE64(const unsigned char* ptr)
|
||||
{
|
||||
uint64_t x;
|
||||
memcpy((char*)&x, ptr, 8);
|
||||
return le64toh(x);
|
||||
}
|
||||
|
||||
void static inline WriteLE16(unsigned char* ptr, uint16_t x)
|
||||
{
|
||||
uint16_t v = htole16(x);
|
||||
memcpy(ptr, (char*)&v, 2);
|
||||
}
|
||||
|
||||
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
|
||||
{
|
||||
uint32_t v = htole32(x);
|
||||
memcpy(ptr, (char*)&v, 4);
|
||||
}
|
||||
|
||||
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
|
||||
{
|
||||
uint64_t v = htole64(x);
|
||||
memcpy(ptr, (char*)&v, 8);
|
||||
}
|
||||
|
||||
uint16_t static inline ReadBE16(const unsigned char* ptr)
|
||||
{
|
||||
uint16_t x;
|
||||
memcpy((char*)&x, ptr, 2);
|
||||
return be16toh(x);
|
||||
}
|
||||
|
||||
uint32_t static inline ReadBE32(const unsigned char* ptr)
|
||||
{
|
||||
uint32_t x;
|
||||
memcpy((char*)&x, ptr, 4);
|
||||
return be32toh(x);
|
||||
}
|
||||
|
||||
uint64_t static inline ReadBE64(const unsigned char* ptr)
|
||||
{
|
||||
uint64_t x;
|
||||
memcpy((char*)&x, ptr, 8);
|
||||
return be64toh(x);
|
||||
}
|
||||
|
||||
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
|
||||
{
|
||||
uint32_t v = htobe32(x);
|
||||
memcpy(ptr, (char*)&v, 4);
|
||||
}
|
||||
|
||||
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
|
||||
{
|
||||
uint64_t v = htobe64(x);
|
||||
memcpy(ptr, (char*)&v, 8);
|
||||
}
|
||||
|
||||
/** Return the smallest number n such that (x >> n) == 0 (or 64 if the highest bit in x is set. */
|
||||
uint64_t static inline CountBits(uint64_t x)
|
||||
{
|
||||
#if HAVE_BUILTIN_CLZL
|
||||
if (sizeof(unsigned long) >= sizeof(uint64_t)) {
|
||||
return x ? 8 * sizeof(unsigned long) - __builtin_clzl(x) : 0;
|
||||
}
|
||||
#endif
|
||||
#if HAVE_BUILTIN_CLZLL
|
||||
if (sizeof(unsigned long long) >= sizeof(uint64_t)) {
|
||||
return x ? 8 * sizeof(unsigned long long) - __builtin_clzll(x) : 0;
|
||||
}
|
||||
#endif
|
||||
int ret = 0;
|
||||
while (x) {
|
||||
x >>= 1;
|
||||
++ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_COMMON_H
|
||||
21
src/crypto/ctaes/COPYING
Normal file
21
src/crypto/ctaes/COPYING
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Pieter Wuille
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
41
src/crypto/ctaes/README.md
Normal file
41
src/crypto/ctaes/README.md
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
ctaes
|
||||
=====
|
||||
|
||||
Simple C module for constant-time AES encryption and decryption.
|
||||
|
||||
Features:
|
||||
* Simple, pure C code without any dependencies.
|
||||
* No tables or data-dependent branches whatsoever, but using bit sliced approach from https://eprint.iacr.org/2009/129.pdf.
|
||||
* Very small object code: slightly over 4k of executable code when compiled with -Os.
|
||||
* Slower than implementations based on precomputed tables or specialized instructions, but can do ~15 MB/s on modern CPUs.
|
||||
|
||||
Performance
|
||||
-----------
|
||||
|
||||
Compiled with GCC 5.3.1 with -O3, on an Intel(R) Core(TM) i7-4800MQ CPU, numbers in CPU cycles:
|
||||
|
||||
| Algorithm | Key schedule | Encryption per byte | Decryption per byte |
|
||||
| --------- | ------------:| -------------------:| -------------------:|
|
||||
| AES-128 | 2.8k | 154 | 161 |
|
||||
| AES-192 | 3.1k | 169 | 181 |
|
||||
| AES-256 | 4.0k | 191 | 203 |
|
||||
|
||||
Build steps
|
||||
-----------
|
||||
|
||||
Object code:
|
||||
|
||||
$ gcc -O3 ctaes.c -c -o ctaes.o
|
||||
|
||||
Tests:
|
||||
|
||||
$ gcc -O3 ctaes.c test.c -o test
|
||||
|
||||
Benchmark:
|
||||
|
||||
$ gcc -O3 ctaes.c bench.c -o bench
|
||||
|
||||
Review
|
||||
------
|
||||
|
||||
Results of a formal review of the code can be found in http://digibyte.sipa.be/ctaes/review.zip
|
||||
170
src/crypto/ctaes/bench.c
Normal file
170
src/crypto/ctaes/bench.c
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "sys/time.h"
|
||||
|
||||
#include "ctaes.h"
|
||||
|
||||
static double gettimedouble(void) {
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return tv.tv_usec * 0.000001 + tv.tv_sec;
|
||||
}
|
||||
|
||||
static void print_number(double x) {
|
||||
double y = x;
|
||||
int c = 0;
|
||||
if (y < 0.0) {
|
||||
y = -y;
|
||||
}
|
||||
while (y < 100.0) {
|
||||
y *= 10.0;
|
||||
c++;
|
||||
}
|
||||
printf("%.*f", c, x);
|
||||
}
|
||||
|
||||
static void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) {
|
||||
int i;
|
||||
double min = HUGE_VAL;
|
||||
double sum = 0.0;
|
||||
double max = 0.0;
|
||||
for (i = 0; i < count; i++) {
|
||||
double begin, total;
|
||||
if (setup != NULL) {
|
||||
setup(data);
|
||||
}
|
||||
begin = gettimedouble();
|
||||
benchmark(data);
|
||||
total = gettimedouble() - begin;
|
||||
if (teardown != NULL) {
|
||||
teardown(data);
|
||||
}
|
||||
if (total < min) {
|
||||
min = total;
|
||||
}
|
||||
if (total > max) {
|
||||
max = total;
|
||||
}
|
||||
sum += total;
|
||||
}
|
||||
printf("%s: min ", name);
|
||||
print_number(min * 1000000000.0 / iter);
|
||||
printf("ns / avg ");
|
||||
print_number((sum / count) * 1000000000.0 / iter);
|
||||
printf("ns / max ");
|
||||
print_number(max * 1000000000.0 / iter);
|
||||
printf("ns\n");
|
||||
}
|
||||
|
||||
static void bench_AES128_init(void* data) {
|
||||
AES128_ctx* ctx = (AES128_ctx*)data;
|
||||
int i;
|
||||
for (i = 0; i < 50000; i++) {
|
||||
AES128_init(ctx, (unsigned char*)ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void bench_AES128_encrypt_setup(void* data) {
|
||||
AES128_ctx* ctx = (AES128_ctx*)data;
|
||||
static const unsigned char key[16] = {0};
|
||||
AES128_init(ctx, key);
|
||||
}
|
||||
|
||||
static void bench_AES128_encrypt(void* data) {
|
||||
const AES128_ctx* ctx = (const AES128_ctx*)data;
|
||||
unsigned char scratch[16] = {0};
|
||||
int i;
|
||||
for (i = 0; i < 4000000 / 16; i++) {
|
||||
AES128_encrypt(ctx, 1, scratch, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
static void bench_AES128_decrypt(void* data) {
|
||||
const AES128_ctx* ctx = (const AES128_ctx*)data;
|
||||
unsigned char scratch[16] = {0};
|
||||
int i;
|
||||
for (i = 0; i < 4000000 / 16; i++) {
|
||||
AES128_decrypt(ctx, 1, scratch, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
static void bench_AES192_init(void* data) {
|
||||
AES192_ctx* ctx = (AES192_ctx*)data;
|
||||
int i;
|
||||
for (i = 0; i < 50000; i++) {
|
||||
AES192_init(ctx, (unsigned char*)ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void bench_AES192_encrypt_setup(void* data) {
|
||||
AES192_ctx* ctx = (AES192_ctx*)data;
|
||||
static const unsigned char key[16] = {0};
|
||||
AES192_init(ctx, key);
|
||||
}
|
||||
|
||||
static void bench_AES192_encrypt(void* data) {
|
||||
const AES192_ctx* ctx = (const AES192_ctx*)data;
|
||||
unsigned char scratch[16] = {0};
|
||||
int i;
|
||||
for (i = 0; i < 4000000 / 16; i++) {
|
||||
AES192_encrypt(ctx, 1, scratch, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
static void bench_AES192_decrypt(void* data) {
|
||||
const AES192_ctx* ctx = (const AES192_ctx*)data;
|
||||
unsigned char scratch[16] = {0};
|
||||
int i;
|
||||
for (i = 0; i < 4000000 / 16; i++) {
|
||||
AES192_decrypt(ctx, 1, scratch, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
static void bench_AES256_init(void* data) {
|
||||
AES256_ctx* ctx = (AES256_ctx*)data;
|
||||
int i;
|
||||
for (i = 0; i < 50000; i++) {
|
||||
AES256_init(ctx, (unsigned char*)ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void bench_AES256_encrypt_setup(void* data) {
|
||||
AES256_ctx* ctx = (AES256_ctx*)data;
|
||||
static const unsigned char key[16] = {0};
|
||||
AES256_init(ctx, key);
|
||||
}
|
||||
|
||||
static void bench_AES256_encrypt(void* data) {
|
||||
const AES256_ctx* ctx = (const AES256_ctx*)data;
|
||||
unsigned char scratch[16] = {0};
|
||||
int i;
|
||||
for (i = 0; i < 4000000 / 16; i++) {
|
||||
AES256_encrypt(ctx, 1, scratch, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
static void bench_AES256_decrypt(void* data) {
|
||||
const AES256_ctx* ctx = (const AES256_ctx*)data;
|
||||
unsigned char scratch[16] = {0};
|
||||
int i;
|
||||
for (i = 0; i < 4000000 / 16; i++) {
|
||||
AES256_decrypt(ctx, 1, scratch, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
AES128_ctx ctx128;
|
||||
AES192_ctx ctx192;
|
||||
AES256_ctx ctx256;
|
||||
run_benchmark("aes128_init", bench_AES128_init, NULL, NULL, &ctx128, 20, 50000);
|
||||
run_benchmark("aes128_encrypt_byte", bench_AES128_encrypt, bench_AES128_encrypt_setup, NULL, &ctx128, 20, 4000000);
|
||||
run_benchmark("aes128_decrypt_byte", bench_AES128_decrypt, bench_AES128_encrypt_setup, NULL, &ctx128, 20, 4000000);
|
||||
run_benchmark("aes192_init", bench_AES192_init, NULL, NULL, &ctx192, 20, 50000);
|
||||
run_benchmark("aes192_encrypt_byte", bench_AES192_encrypt, bench_AES192_encrypt_setup, NULL, &ctx192, 20, 4000000);
|
||||
run_benchmark("aes192_decrypt_byte", bench_AES192_decrypt, bench_AES192_encrypt_setup, NULL, &ctx192, 20, 4000000);
|
||||
run_benchmark("aes256_init", bench_AES256_init, NULL, NULL, &ctx256, 20, 50000);
|
||||
run_benchmark("aes256_encrypt_byte", bench_AES256_encrypt, bench_AES256_encrypt_setup, NULL, &ctx256, 20, 4000000);
|
||||
run_benchmark("aes256_decrypt_byte", bench_AES256_decrypt, bench_AES256_encrypt_setup, NULL, &ctx256, 20, 4000000);
|
||||
return 0;
|
||||
}
|
||||
556
src/crypto/ctaes/ctaes.cpp
Normal file
556
src/crypto/ctaes/ctaes.cpp
Normal file
|
|
@ -0,0 +1,556 @@
|
|||
/*********************************************************************
|
||||
* Copyright (c) 2016 Pieter Wuille *
|
||||
* Distributed under the MIT software license, see the accompanying *
|
||||
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
|
||||
**********************************************************************/
|
||||
|
||||
/* Constant time, unoptimized, concise, plain C, AES implementation
|
||||
* Based On:
|
||||
* Emilia Kasper and Peter Schwabe, Faster and Timing-Attack Resistant AES-GCM
|
||||
* http://www.iacr.org/archive/ches2009/57470001/57470001.pdf
|
||||
* But using 8 16-bit integers representing a single AES state rather than 8 128-bit
|
||||
* integers representing 8 AES states.
|
||||
*/
|
||||
|
||||
#include "ctaes.h"
|
||||
|
||||
/* Slice variable slice_i contains the i'th bit of the 16 state variables in this order:
|
||||
* 0 1 2 3
|
||||
* 4 5 6 7
|
||||
* 8 9 10 11
|
||||
* 12 13 14 15
|
||||
*/
|
||||
|
||||
/** Convert a byte to sliced form, storing it corresponding to given row and column in s */
|
||||
static void LoadByte(AES_state* s, unsigned char byte, int r, int c) {
|
||||
int i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
s->slice[i] |= (byte & 1) << (r * 4 + c);
|
||||
byte >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
/** Load 16 bytes of data into 8 sliced integers */
|
||||
static void LoadBytes(AES_state *s, const unsigned char* data16) {
|
||||
int c;
|
||||
for (c = 0; c < 4; c++) {
|
||||
int r;
|
||||
for (r = 0; r < 4; r++) {
|
||||
LoadByte(s, *(data16++), r, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Convert 8 sliced integers into 16 bytes of data */
|
||||
static void SaveBytes(unsigned char* data16, const AES_state *s) {
|
||||
int c;
|
||||
for (c = 0; c < 4; c++) {
|
||||
int r;
|
||||
for (r = 0; r < 4; r++) {
|
||||
int b;
|
||||
uint8_t v = 0;
|
||||
for (b = 0; b < 8; b++) {
|
||||
v |= ((s->slice[b] >> (r * 4 + c)) & 1) << b;
|
||||
}
|
||||
*(data16++) = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* S-box implementation based on the gate logic from:
|
||||
* Joan Boyar and Rene Peralta, A depth-16 circuit for the AES S-box.
|
||||
* https://eprint.iacr.org/2011/332.pdf
|
||||
*/
|
||||
static void SubBytes(AES_state *s, int inv) {
|
||||
/* Load the bit slices */
|
||||
uint16_t U0 = s->slice[7], U1 = s->slice[6], U2 = s->slice[5], U3 = s->slice[4];
|
||||
uint16_t U4 = s->slice[3], U5 = s->slice[2], U6 = s->slice[1], U7 = s->slice[0];
|
||||
|
||||
uint16_t T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16;
|
||||
uint16_t T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, D;
|
||||
uint16_t M1, M6, M11, M13, M15, M20, M21, M22, M23, M25, M37, M38, M39, M40;
|
||||
uint16_t M41, M42, M43, M44, M45, M46, M47, M48, M49, M50, M51, M52, M53, M54;
|
||||
uint16_t M55, M56, M57, M58, M59, M60, M61, M62, M63;
|
||||
|
||||
if (inv) {
|
||||
uint16_t R5, R13, R17, R18, R19;
|
||||
/* Undo linear postprocessing */
|
||||
T23 = U0 ^ U3;
|
||||
T22 = ~(U1 ^ U3);
|
||||
T2 = ~(U0 ^ U1);
|
||||
T1 = U3 ^ U4;
|
||||
T24 = ~(U4 ^ U7);
|
||||
R5 = U6 ^ U7;
|
||||
T8 = ~(U1 ^ T23);
|
||||
T19 = T22 ^ R5;
|
||||
T9 = ~(U7 ^ T1);
|
||||
T10 = T2 ^ T24;
|
||||
T13 = T2 ^ R5;
|
||||
T3 = T1 ^ R5;
|
||||
T25 = ~(U2 ^ T1);
|
||||
R13 = U1 ^ U6;
|
||||
T17 = ~(U2 ^ T19);
|
||||
T20 = T24 ^ R13;
|
||||
T4 = U4 ^ T8;
|
||||
R17 = ~(U2 ^ U5);
|
||||
R18 = ~(U5 ^ U6);
|
||||
R19 = ~(U2 ^ U4);
|
||||
D = U0 ^ R17;
|
||||
T6 = T22 ^ R17;
|
||||
T16 = R13 ^ R19;
|
||||
T27 = T1 ^ R18;
|
||||
T15 = T10 ^ T27;
|
||||
T14 = T10 ^ R18;
|
||||
T26 = T3 ^ T16;
|
||||
} else {
|
||||
/* Linear preprocessing. */
|
||||
T1 = U0 ^ U3;
|
||||
T2 = U0 ^ U5;
|
||||
T3 = U0 ^ U6;
|
||||
T4 = U3 ^ U5;
|
||||
T5 = U4 ^ U6;
|
||||
T6 = T1 ^ T5;
|
||||
T7 = U1 ^ U2;
|
||||
T8 = U7 ^ T6;
|
||||
T9 = U7 ^ T7;
|
||||
T10 = T6 ^ T7;
|
||||
T11 = U1 ^ U5;
|
||||
T12 = U2 ^ U5;
|
||||
T13 = T3 ^ T4;
|
||||
T14 = T6 ^ T11;
|
||||
T15 = T5 ^ T11;
|
||||
T16 = T5 ^ T12;
|
||||
T17 = T9 ^ T16;
|
||||
T18 = U3 ^ U7;
|
||||
T19 = T7 ^ T18;
|
||||
T20 = T1 ^ T19;
|
||||
T21 = U6 ^ U7;
|
||||
T22 = T7 ^ T21;
|
||||
T23 = T2 ^ T22;
|
||||
T24 = T2 ^ T10;
|
||||
T25 = T20 ^ T17;
|
||||
T26 = T3 ^ T16;
|
||||
T27 = T1 ^ T12;
|
||||
D = U7;
|
||||
}
|
||||
|
||||
/* Non-linear transformation (shared between the forward and backward case) */
|
||||
M1 = T13 & T6;
|
||||
M6 = T3 & T16;
|
||||
M11 = T1 & T15;
|
||||
M13 = (T4 & T27) ^ M11;
|
||||
M15 = (T2 & T10) ^ M11;
|
||||
M20 = T14 ^ M1 ^ (T23 & T8) ^ M13;
|
||||
M21 = (T19 & D) ^ M1 ^ T24 ^ M15;
|
||||
M22 = T26 ^ M6 ^ (T22 & T9) ^ M13;
|
||||
M23 = (T20 & T17) ^ M6 ^ M15 ^ T25;
|
||||
M25 = M22 & M20;
|
||||
M37 = M21 ^ ((M20 ^ M21) & (M23 ^ M25));
|
||||
M38 = M20 ^ M25 ^ (M21 | (M20 & M23));
|
||||
M39 = M23 ^ ((M22 ^ M23) & (M21 ^ M25));
|
||||
M40 = M22 ^ M25 ^ (M23 | (M21 & M22));
|
||||
M41 = M38 ^ M40;
|
||||
M42 = M37 ^ M39;
|
||||
M43 = M37 ^ M38;
|
||||
M44 = M39 ^ M40;
|
||||
M45 = M42 ^ M41;
|
||||
M46 = M44 & T6;
|
||||
M47 = M40 & T8;
|
||||
M48 = M39 & D;
|
||||
M49 = M43 & T16;
|
||||
M50 = M38 & T9;
|
||||
M51 = M37 & T17;
|
||||
M52 = M42 & T15;
|
||||
M53 = M45 & T27;
|
||||
M54 = M41 & T10;
|
||||
M55 = M44 & T13;
|
||||
M56 = M40 & T23;
|
||||
M57 = M39 & T19;
|
||||
M58 = M43 & T3;
|
||||
M59 = M38 & T22;
|
||||
M60 = M37 & T20;
|
||||
M61 = M42 & T1;
|
||||
M62 = M45 & T4;
|
||||
M63 = M41 & T2;
|
||||
|
||||
if (inv){
|
||||
/* Undo linear preprocessing */
|
||||
uint16_t P0 = M52 ^ M61;
|
||||
uint16_t P1 = M58 ^ M59;
|
||||
uint16_t P2 = M54 ^ M62;
|
||||
uint16_t P3 = M47 ^ M50;
|
||||
uint16_t P4 = M48 ^ M56;
|
||||
uint16_t P5 = M46 ^ M51;
|
||||
uint16_t P6 = M49 ^ M60;
|
||||
uint16_t P7 = P0 ^ P1;
|
||||
uint16_t P8 = M50 ^ M53;
|
||||
uint16_t P9 = M55 ^ M63;
|
||||
uint16_t P10 = M57 ^ P4;
|
||||
uint16_t P11 = P0 ^ P3;
|
||||
uint16_t P12 = M46 ^ M48;
|
||||
uint16_t P13 = M49 ^ M51;
|
||||
uint16_t P14 = M49 ^ M62;
|
||||
uint16_t P15 = M54 ^ M59;
|
||||
uint16_t P16 = M57 ^ M61;
|
||||
uint16_t P17 = M58 ^ P2;
|
||||
uint16_t P18 = M63 ^ P5;
|
||||
uint16_t P19 = P2 ^ P3;
|
||||
uint16_t P20 = P4 ^ P6;
|
||||
uint16_t P22 = P2 ^ P7;
|
||||
uint16_t P23 = P7 ^ P8;
|
||||
uint16_t P24 = P5 ^ P7;
|
||||
uint16_t P25 = P6 ^ P10;
|
||||
uint16_t P26 = P9 ^ P11;
|
||||
uint16_t P27 = P10 ^ P18;
|
||||
uint16_t P28 = P11 ^ P25;
|
||||
uint16_t P29 = P15 ^ P20;
|
||||
s->slice[7] = P13 ^ P22;
|
||||
s->slice[6] = P26 ^ P29;
|
||||
s->slice[5] = P17 ^ P28;
|
||||
s->slice[4] = P12 ^ P22;
|
||||
s->slice[3] = P23 ^ P27;
|
||||
s->slice[2] = P19 ^ P24;
|
||||
s->slice[1] = P14 ^ P23;
|
||||
s->slice[0] = P9 ^ P16;
|
||||
} else {
|
||||
/* Linear postprocessing */
|
||||
uint16_t L0 = M61 ^ M62;
|
||||
uint16_t L1 = M50 ^ M56;
|
||||
uint16_t L2 = M46 ^ M48;
|
||||
uint16_t L3 = M47 ^ M55;
|
||||
uint16_t L4 = M54 ^ M58;
|
||||
uint16_t L5 = M49 ^ M61;
|
||||
uint16_t L6 = M62 ^ L5;
|
||||
uint16_t L7 = M46 ^ L3;
|
||||
uint16_t L8 = M51 ^ M59;
|
||||
uint16_t L9 = M52 ^ M53;
|
||||
uint16_t L10 = M53 ^ L4;
|
||||
uint16_t L11 = M60 ^ L2;
|
||||
uint16_t L12 = M48 ^ M51;
|
||||
uint16_t L13 = M50 ^ L0;
|
||||
uint16_t L14 = M52 ^ M61;
|
||||
uint16_t L15 = M55 ^ L1;
|
||||
uint16_t L16 = M56 ^ L0;
|
||||
uint16_t L17 = M57 ^ L1;
|
||||
uint16_t L18 = M58 ^ L8;
|
||||
uint16_t L19 = M63 ^ L4;
|
||||
uint16_t L20 = L0 ^ L1;
|
||||
uint16_t L21 = L1 ^ L7;
|
||||
uint16_t L22 = L3 ^ L12;
|
||||
uint16_t L23 = L18 ^ L2;
|
||||
uint16_t L24 = L15 ^ L9;
|
||||
uint16_t L25 = L6 ^ L10;
|
||||
uint16_t L26 = L7 ^ L9;
|
||||
uint16_t L27 = L8 ^ L10;
|
||||
uint16_t L28 = L11 ^ L14;
|
||||
uint16_t L29 = L11 ^ L17;
|
||||
s->slice[7] = L6 ^ L24;
|
||||
s->slice[6] = ~(L16 ^ L26);
|
||||
s->slice[5] = ~(L19 ^ L28);
|
||||
s->slice[4] = L6 ^ L21;
|
||||
s->slice[3] = L20 ^ L22;
|
||||
s->slice[2] = L25 ^ L29;
|
||||
s->slice[1] = ~(L13 ^ L27);
|
||||
s->slice[0] = ~(L6 ^ L23);
|
||||
}
|
||||
}
|
||||
|
||||
#define BIT_RANGE(from,to) (((1 << ((to) - (from))) - 1) << (from))
|
||||
|
||||
#define BIT_RANGE_LEFT(x,from,to,shift) (((x) & BIT_RANGE((from), (to))) << (shift))
|
||||
#define BIT_RANGE_RIGHT(x,from,to,shift) (((x) & BIT_RANGE((from), (to))) >> (shift))
|
||||
|
||||
static void ShiftRows(AES_state* s) {
|
||||
int i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
uint16_t v = s->slice[i];
|
||||
s->slice[i] =
|
||||
(v & BIT_RANGE(0, 4)) |
|
||||
BIT_RANGE_LEFT(v, 4, 5, 3) | BIT_RANGE_RIGHT(v, 5, 8, 1) |
|
||||
BIT_RANGE_LEFT(v, 8, 10, 2) | BIT_RANGE_RIGHT(v, 10, 12, 2) |
|
||||
BIT_RANGE_LEFT(v, 12, 15, 1) | BIT_RANGE_RIGHT(v, 15, 16, 3);
|
||||
}
|
||||
}
|
||||
|
||||
static void InvShiftRows(AES_state* s) {
|
||||
int i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
uint16_t v = s->slice[i];
|
||||
s->slice[i] =
|
||||
(v & BIT_RANGE(0, 4)) |
|
||||
BIT_RANGE_LEFT(v, 4, 7, 1) | BIT_RANGE_RIGHT(v, 7, 8, 3) |
|
||||
BIT_RANGE_LEFT(v, 8, 10, 2) | BIT_RANGE_RIGHT(v, 10, 12, 2) |
|
||||
BIT_RANGE_LEFT(v, 12, 13, 3) | BIT_RANGE_RIGHT(v, 13, 16, 1);
|
||||
}
|
||||
}
|
||||
|
||||
#define ROT(x,b) (((x) >> ((b) * 4)) | ((x) << ((4-(b)) * 4)))
|
||||
|
||||
static void MixColumns(AES_state* s, int inv) {
|
||||
/* The MixColumns transform treats the bytes of the columns of the state as
|
||||
* coefficients of a 3rd degree polynomial over GF(2^8) and multiplies them
|
||||
* by the fixed polynomial a(x) = {03}x^3 + {01}x^2 + {01}x + {02}, modulo
|
||||
* x^4 + {01}.
|
||||
*
|
||||
* In the inverse transform, we multiply by the inverse of a(x),
|
||||
* a^-1(x) = {0b}x^3 + {0d}x^2 + {09}x + {0e}. This is equal to
|
||||
* a(x) * ({04}x^2 + {05}), so we can reuse the forward transform's code
|
||||
* (found in OpenSSL's bsaes-x86_64.pl, attributed to Jussi Kivilinna)
|
||||
*
|
||||
* In the bitsliced representation, a multiplication of every column by x
|
||||
* mod x^4 + 1 is simply a right rotation.
|
||||
*/
|
||||
|
||||
/* Shared for both directions is a multiplication by a(x), which can be
|
||||
* rewritten as (x^3 + x^2 + x) + {02}*(x^3 + {01}).
|
||||
*
|
||||
* First compute s into the s? variables, (x^3 + {01}) * s into the s?_01
|
||||
* variables and (x^3 + x^2 + x)*s into the s?_123 variables.
|
||||
*/
|
||||
uint16_t s0 = s->slice[0], s1 = s->slice[1], s2 = s->slice[2], s3 = s->slice[3];
|
||||
uint16_t s4 = s->slice[4], s5 = s->slice[5], s6 = s->slice[6], s7 = s->slice[7];
|
||||
uint16_t s0_01 = s0 ^ ROT(s0, 1), s0_123 = ROT(s0_01, 1) ^ ROT(s0, 3);
|
||||
uint16_t s1_01 = s1 ^ ROT(s1, 1), s1_123 = ROT(s1_01, 1) ^ ROT(s1, 3);
|
||||
uint16_t s2_01 = s2 ^ ROT(s2, 1), s2_123 = ROT(s2_01, 1) ^ ROT(s2, 3);
|
||||
uint16_t s3_01 = s3 ^ ROT(s3, 1), s3_123 = ROT(s3_01, 1) ^ ROT(s3, 3);
|
||||
uint16_t s4_01 = s4 ^ ROT(s4, 1), s4_123 = ROT(s4_01, 1) ^ ROT(s4, 3);
|
||||
uint16_t s5_01 = s5 ^ ROT(s5, 1), s5_123 = ROT(s5_01, 1) ^ ROT(s5, 3);
|
||||
uint16_t s6_01 = s6 ^ ROT(s6, 1), s6_123 = ROT(s6_01, 1) ^ ROT(s6, 3);
|
||||
uint16_t s7_01 = s7 ^ ROT(s7, 1), s7_123 = ROT(s7_01, 1) ^ ROT(s7, 3);
|
||||
/* Now compute s = s?_123 + {02} * s?_01. */
|
||||
s->slice[0] = s7_01 ^ s0_123;
|
||||
s->slice[1] = s7_01 ^ s0_01 ^ s1_123;
|
||||
s->slice[2] = s1_01 ^ s2_123;
|
||||
s->slice[3] = s7_01 ^ s2_01 ^ s3_123;
|
||||
s->slice[4] = s7_01 ^ s3_01 ^ s4_123;
|
||||
s->slice[5] = s4_01 ^ s5_123;
|
||||
s->slice[6] = s5_01 ^ s6_123;
|
||||
s->slice[7] = s6_01 ^ s7_123;
|
||||
if (inv) {
|
||||
/* In the reverse direction, we further need to multiply by
|
||||
* {04}x^2 + {05}, which can be written as {04} * (x^2 + {01}) + {01}.
|
||||
*
|
||||
* First compute (x^2 + {01}) * s into the t?_02 variables: */
|
||||
uint16_t t0_02 = s->slice[0] ^ ROT(s->slice[0], 2);
|
||||
uint16_t t1_02 = s->slice[1] ^ ROT(s->slice[1], 2);
|
||||
uint16_t t2_02 = s->slice[2] ^ ROT(s->slice[2], 2);
|
||||
uint16_t t3_02 = s->slice[3] ^ ROT(s->slice[3], 2);
|
||||
uint16_t t4_02 = s->slice[4] ^ ROT(s->slice[4], 2);
|
||||
uint16_t t5_02 = s->slice[5] ^ ROT(s->slice[5], 2);
|
||||
uint16_t t6_02 = s->slice[6] ^ ROT(s->slice[6], 2);
|
||||
uint16_t t7_02 = s->slice[7] ^ ROT(s->slice[7], 2);
|
||||
/* And then update s += {04} * t?_02 */
|
||||
s->slice[0] ^= t6_02;
|
||||
s->slice[1] ^= t6_02 ^ t7_02;
|
||||
s->slice[2] ^= t0_02 ^ t7_02;
|
||||
s->slice[3] ^= t1_02 ^ t6_02;
|
||||
s->slice[4] ^= t2_02 ^ t6_02 ^ t7_02;
|
||||
s->slice[5] ^= t3_02 ^ t7_02;
|
||||
s->slice[6] ^= t4_02;
|
||||
s->slice[7] ^= t5_02;
|
||||
}
|
||||
}
|
||||
|
||||
static void AddRoundKey(AES_state* s, const AES_state* round) {
|
||||
int b;
|
||||
for (b = 0; b < 8; b++) {
|
||||
s->slice[b] ^= round->slice[b];
|
||||
}
|
||||
}
|
||||
|
||||
/** column_0(s) = column_c(a) */
|
||||
static void GetOneColumn(AES_state* s, const AES_state* a, int c) {
|
||||
int b;
|
||||
for (b = 0; b < 8; b++) {
|
||||
s->slice[b] = (a->slice[b] >> c) & 0x1111;
|
||||
}
|
||||
}
|
||||
|
||||
/** column_c1(r) |= (column_0(s) ^= column_c2(a)) */
|
||||
static void KeySetupColumnMix(AES_state* s, AES_state* r, const AES_state* a, int c1, int c2) {
|
||||
int b;
|
||||
for (b = 0; b < 8; b++) {
|
||||
r->slice[b] |= ((s->slice[b] ^= ((a->slice[b] >> c2) & 0x1111)) & 0x1111) << c1;
|
||||
}
|
||||
}
|
||||
|
||||
/** Rotate the rows in s one position upwards, and xor in r */
|
||||
static void KeySetupTransform(AES_state* s, const AES_state* r) {
|
||||
int b;
|
||||
for (b = 0; b < 8; b++) {
|
||||
s->slice[b] = ((s->slice[b] >> 4) | (s->slice[b] << 12)) ^ r->slice[b];
|
||||
}
|
||||
}
|
||||
|
||||
/* Multiply the cells in s by x, as polynomials over GF(2) mod x^8 + x^4 + x^3 + x + 1 */
|
||||
static void MultX(AES_state* s) {
|
||||
uint16_t top = s->slice[7];
|
||||
s->slice[7] = s->slice[6];
|
||||
s->slice[6] = s->slice[5];
|
||||
s->slice[5] = s->slice[4];
|
||||
s->slice[4] = s->slice[3] ^ top;
|
||||
s->slice[3] = s->slice[2] ^ top;
|
||||
s->slice[2] = s->slice[1];
|
||||
s->slice[1] = s->slice[0] ^ top;
|
||||
s->slice[0] = top;
|
||||
}
|
||||
|
||||
/** Expand the cipher key into the key schedule.
|
||||
*
|
||||
* state must be a pointer to an array of size nrounds + 1.
|
||||
* key must be a pointer to 4 * nkeywords bytes.
|
||||
*
|
||||
* AES128 uses nkeywords = 4, nrounds = 10
|
||||
* AES192 uses nkeywords = 6, nrounds = 12
|
||||
* AES256 uses nkeywords = 8, nrounds = 14
|
||||
*/
|
||||
static void AES_setup(AES_state* rounds, const uint8_t* key, int nkeywords, int nrounds)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* The one-byte round constant */
|
||||
AES_state rcon = {{1,0,0,0,0,0,0,0}};
|
||||
/* The number of the word being generated, modulo nkeywords */
|
||||
int pos = 0;
|
||||
/* The column representing the word currently being processed */
|
||||
AES_state column;
|
||||
|
||||
for (i = 0; i < nrounds + 1; i++) {
|
||||
int b;
|
||||
for (b = 0; b < 8; b++) {
|
||||
rounds[i].slice[b] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* The first nkeywords round columns are just taken from the key directly. */
|
||||
for (i = 0; i < nkeywords; i++) {
|
||||
int r;
|
||||
for (r = 0; r < 4; r++) {
|
||||
LoadByte(&rounds[i >> 2], *(key++), r, i & 3);
|
||||
}
|
||||
}
|
||||
|
||||
GetOneColumn(&column, &rounds[(nkeywords - 1) >> 2], (nkeywords - 1) & 3);
|
||||
|
||||
for (i = nkeywords; i < 4 * (nrounds + 1); i++) {
|
||||
/* Transform column */
|
||||
if (pos == 0) {
|
||||
SubBytes(&column, 0);
|
||||
KeySetupTransform(&column, &rcon);
|
||||
MultX(&rcon);
|
||||
} else if (nkeywords > 6 && pos == 4) {
|
||||
SubBytes(&column, 0);
|
||||
}
|
||||
if (++pos == nkeywords) pos = 0;
|
||||
KeySetupColumnMix(&column, &rounds[i >> 2], &rounds[(i - nkeywords) >> 2], i & 3, (i - nkeywords) & 3);
|
||||
}
|
||||
}
|
||||
|
||||
static void AES_encrypt(const AES_state* rounds, int nrounds, unsigned char* cipher16, const unsigned char* plain16) {
|
||||
AES_state s = {{0}};
|
||||
int round;
|
||||
|
||||
LoadBytes(&s, plain16);
|
||||
AddRoundKey(&s, rounds++);
|
||||
|
||||
for (round = 1; round < nrounds; round++) {
|
||||
SubBytes(&s, 0);
|
||||
ShiftRows(&s);
|
||||
MixColumns(&s, 0);
|
||||
AddRoundKey(&s, rounds++);
|
||||
}
|
||||
|
||||
SubBytes(&s, 0);
|
||||
ShiftRows(&s);
|
||||
AddRoundKey(&s, rounds);
|
||||
|
||||
SaveBytes(cipher16, &s);
|
||||
}
|
||||
|
||||
static void AES_decrypt(const AES_state* rounds, int nrounds, unsigned char* plain16, const unsigned char* cipher16) {
|
||||
/* Most AES decryption implementations use the alternate scheme
|
||||
* (the Equivalent Inverse Cipher), which allows for more code reuse between
|
||||
* the encryption and decryption code, but requires separate setup for both.
|
||||
*/
|
||||
AES_state s = {{0}};
|
||||
int round;
|
||||
|
||||
rounds += nrounds;
|
||||
|
||||
LoadBytes(&s, cipher16);
|
||||
AddRoundKey(&s, rounds--);
|
||||
|
||||
for (round = 1; round < nrounds; round++) {
|
||||
InvShiftRows(&s);
|
||||
SubBytes(&s, 1);
|
||||
AddRoundKey(&s, rounds--);
|
||||
MixColumns(&s, 1);
|
||||
}
|
||||
|
||||
InvShiftRows(&s);
|
||||
SubBytes(&s, 1);
|
||||
AddRoundKey(&s, rounds);
|
||||
|
||||
SaveBytes(plain16, &s);
|
||||
}
|
||||
|
||||
void AES128_init(AES128_ctx* ctx, const unsigned char* key16) {
|
||||
AES_setup(ctx->rk, key16, 4, 10);
|
||||
}
|
||||
|
||||
void AES128_encrypt(const AES128_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16) {
|
||||
while (blocks--) {
|
||||
AES_encrypt(ctx->rk, 10, cipher16, plain16);
|
||||
cipher16 += 16;
|
||||
plain16 += 16;
|
||||
}
|
||||
}
|
||||
|
||||
void AES128_decrypt(const AES128_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16) {
|
||||
while (blocks--) {
|
||||
AES_decrypt(ctx->rk, 10, plain16, cipher16);
|
||||
cipher16 += 16;
|
||||
plain16 += 16;
|
||||
}
|
||||
}
|
||||
|
||||
void AES192_init(AES192_ctx* ctx, const unsigned char* key24) {
|
||||
AES_setup(ctx->rk, key24, 6, 12);
|
||||
}
|
||||
|
||||
void AES192_encrypt(const AES192_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16) {
|
||||
while (blocks--) {
|
||||
AES_encrypt(ctx->rk, 12, cipher16, plain16);
|
||||
cipher16 += 16;
|
||||
plain16 += 16;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AES192_decrypt(const AES192_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16) {
|
||||
while (blocks--) {
|
||||
AES_decrypt(ctx->rk, 12, plain16, cipher16);
|
||||
cipher16 += 16;
|
||||
plain16 += 16;
|
||||
}
|
||||
}
|
||||
|
||||
void AES256_init(AES256_ctx* ctx, const unsigned char* key32) {
|
||||
AES_setup(ctx->rk, key32, 8, 14);
|
||||
}
|
||||
|
||||
void AES256_encrypt(const AES256_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16) {
|
||||
while (blocks--) {
|
||||
AES_encrypt(ctx->rk, 14, cipher16, plain16);
|
||||
cipher16 += 16;
|
||||
plain16 += 16;
|
||||
}
|
||||
}
|
||||
|
||||
void AES256_decrypt(const AES256_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16) {
|
||||
while (blocks--) {
|
||||
AES_decrypt(ctx->rk, 14, plain16, cipher16);
|
||||
cipher16 += 16;
|
||||
plain16 += 16;
|
||||
}
|
||||
}
|
||||
41
src/crypto/ctaes/ctaes.h
Normal file
41
src/crypto/ctaes/ctaes.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*********************************************************************
|
||||
* Copyright (c) 2016 Pieter Wuille *
|
||||
* Distributed under the MIT software license, see the accompanying *
|
||||
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef _CTAES_H_
|
||||
#define _CTAES_H_ 1
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct {
|
||||
uint16_t slice[8];
|
||||
} AES_state;
|
||||
|
||||
typedef struct {
|
||||
AES_state rk[11];
|
||||
} AES128_ctx;
|
||||
|
||||
typedef struct {
|
||||
AES_state rk[13];
|
||||
} AES192_ctx;
|
||||
|
||||
typedef struct {
|
||||
AES_state rk[15];
|
||||
} AES256_ctx;
|
||||
|
||||
void AES128_init(AES128_ctx* ctx, const unsigned char* key16);
|
||||
void AES128_encrypt(const AES128_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16);
|
||||
void AES128_decrypt(const AES128_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16);
|
||||
|
||||
void AES192_init(AES192_ctx* ctx, const unsigned char* key24);
|
||||
void AES192_encrypt(const AES192_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16);
|
||||
void AES192_decrypt(const AES192_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16);
|
||||
|
||||
void AES256_init(AES256_ctx* ctx, const unsigned char* key32);
|
||||
void AES256_encrypt(const AES256_ctx* ctx, size_t blocks, unsigned char* cipher16, const unsigned char* plain16);
|
||||
void AES256_decrypt(const AES256_ctx* ctx, size_t blocks, unsigned char* plain16, const unsigned char* cipher16);
|
||||
|
||||
#endif
|
||||
110
src/crypto/ctaes/test.c
Normal file
110
src/crypto/ctaes/test.c
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*********************************************************************
|
||||
* Copyright (c) 2016 Pieter Wuille *
|
||||
* Distributed under the MIT software license, see the accompanying *
|
||||
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
|
||||
**********************************************************************/
|
||||
|
||||
#include "ctaes.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
typedef struct {
|
||||
int keysize;
|
||||
const char* key;
|
||||
const char* plain;
|
||||
const char* cipher;
|
||||
} ctaes_test;
|
||||
|
||||
static const ctaes_test ctaes_tests[] = {
|
||||
/* AES test vectors from FIPS 197. */
|
||||
{128, "000102030405060708090a0b0c0d0e0f", "00112233445566778899aabbccddeeff", "69c4e0d86a7b0430d8cdb78070b4c55a"},
|
||||
{192, "000102030405060708090a0b0c0d0e0f1011121314151617", "00112233445566778899aabbccddeeff", "dda97ca4864cdfe06eaf70a0ec0d7191"},
|
||||
{256, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", "00112233445566778899aabbccddeeff", "8ea2b7ca516745bfeafc49904b496089"},
|
||||
|
||||
/* AES-ECB test vectors from NIST sp800-38a. */
|
||||
{128, "2b7e151628aed2a6abf7158809cf4f3c", "6bc1bee22e409f96e93d7e117393172a", "3ad77bb40d7a3660a89ecaf32466ef97"},
|
||||
{128, "2b7e151628aed2a6abf7158809cf4f3c", "ae2d8a571e03ac9c9eb76fac45af8e51", "f5d3d58503b9699de785895a96fdbaaf"},
|
||||
{128, "2b7e151628aed2a6abf7158809cf4f3c", "30c81c46a35ce411e5fbc1191a0a52ef", "43b1cd7f598ece23881b00e3ed030688"},
|
||||
{128, "2b7e151628aed2a6abf7158809cf4f3c", "f69f2445df4f9b17ad2b417be66c3710", "7b0c785e27e8ad3f8223207104725dd4"},
|
||||
{192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "6bc1bee22e409f96e93d7e117393172a", "bd334f1d6e45f25ff712a214571fa5cc"},
|
||||
{192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "ae2d8a571e03ac9c9eb76fac45af8e51", "974104846d0ad3ad7734ecb3ecee4eef"},
|
||||
{192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "30c81c46a35ce411e5fbc1191a0a52ef", "ef7afd2270e2e60adce0ba2face6444e"},
|
||||
{192, "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b", "f69f2445df4f9b17ad2b417be66c3710", "9a4b41ba738d6c72fb16691603c18e0e"},
|
||||
{256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "6bc1bee22e409f96e93d7e117393172a", "f3eed1bdb5d2a03c064b5a7e3db181f8"},
|
||||
{256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "ae2d8a571e03ac9c9eb76fac45af8e51", "591ccb10d410ed26dc5ba74a31362870"},
|
||||
{256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "30c81c46a35ce411e5fbc1191a0a52ef", "b6ed21b99ca6f4f9f153e7b1beafed1d"},
|
||||
{256, "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4", "f69f2445df4f9b17ad2b417be66c3710", "23304b7a39f9f3ff067d8d8f9e24ecc7"}
|
||||
};
|
||||
|
||||
static void from_hex(unsigned char* data, int len, const char* hex) {
|
||||
int p;
|
||||
for (p = 0; p < len; p++) {
|
||||
int v = 0;
|
||||
int n;
|
||||
for (n = 0; n < 2; n++) {
|
||||
assert((*hex >= '0' && *hex <= '9') || (*hex >= 'a' && *hex <= 'f'));
|
||||
if (*hex >= '0' && *hex <= '9') {
|
||||
v |= (*hex - '0') << (4 * (1 - n));
|
||||
} else {
|
||||
v |= (*hex - 'a' + 10) << (4 * (1 - n));
|
||||
}
|
||||
hex++;
|
||||
}
|
||||
*(data++) = v;
|
||||
}
|
||||
assert(*hex == 0);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int i;
|
||||
int fail = 0;
|
||||
for (i = 0; i < sizeof(ctaes_tests) / sizeof(ctaes_tests[0]); i++) {
|
||||
unsigned char key[32], plain[16], cipher[16], ciphered[16], deciphered[16];
|
||||
const ctaes_test* test = &ctaes_tests[i];
|
||||
assert(test->keysize == 128 || test->keysize == 192 || test->keysize == 256);
|
||||
from_hex(plain, 16, test->plain);
|
||||
from_hex(cipher, 16, test->cipher);
|
||||
switch (test->keysize) {
|
||||
case 128: {
|
||||
AES128_ctx ctx;
|
||||
from_hex(key, 16, test->key);
|
||||
AES128_init(&ctx, key);
|
||||
AES128_encrypt(&ctx, 1, ciphered, plain);
|
||||
AES128_decrypt(&ctx, 1, deciphered, cipher);
|
||||
break;
|
||||
}
|
||||
case 192: {
|
||||
AES192_ctx ctx;
|
||||
from_hex(key, 24, test->key);
|
||||
AES192_init(&ctx, key);
|
||||
AES192_encrypt(&ctx, 1, ciphered, plain);
|
||||
AES192_decrypt(&ctx, 1, deciphered, cipher);
|
||||
break;
|
||||
}
|
||||
case 256: {
|
||||
AES256_ctx ctx;
|
||||
from_hex(key, 32, test->key);
|
||||
AES256_init(&ctx, key);
|
||||
AES256_encrypt(&ctx, 1, ciphered, plain);
|
||||
AES256_decrypt(&ctx, 1, deciphered, cipher);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (memcmp(cipher, ciphered, 16)) {
|
||||
fprintf(stderr, "E(key=\"%s\", plain=\"%s\") != \"%s\"\n", test->key, test->plain, test->cipher);
|
||||
fail++;
|
||||
}
|
||||
if (memcmp(plain, deciphered, 16)) {
|
||||
fprintf(stderr, "D(key=\"%s\", cipher=\"%s\") != \"%s\"\n", test->key, test->cipher, test->plain);
|
||||
fail++;
|
||||
}
|
||||
}
|
||||
if (fail == 0) {
|
||||
fprintf(stderr, "All tests successful\n");
|
||||
} else {
|
||||
fprintf(stderr, "%i tests failed\n", fail);
|
||||
}
|
||||
return (fail != 0);
|
||||
}
|
||||
723
src/crypto/cubehash.cpp
Normal file
723
src/crypto/cubehash.cpp
Normal file
|
|
@ -0,0 +1,723 @@
|
|||
/* $Id: cubehash.c 227 2010-06-16 17:28:38Z tp $ */
|
||||
/*
|
||||
* CubeHash implementation.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "sph_cubehash.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_CUBEHASH
|
||||
#define SPH_SMALL_FOOTPRINT_CUBEHASH 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Some tests were conducted on an Intel Core2 Q6600 (32-bit and 64-bit
|
||||
* mode), a PowerPC G3, and a MIPS-compatible CPU (Broadcom BCM3302).
|
||||
* It appears that the optimal settings are:
|
||||
* -- full unroll, no state copy on the "big" systems (x86, PowerPC)
|
||||
* -- unroll to 4 or 8, state copy on the "small" system (MIPS)
|
||||
*/
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT_CUBEHASH
|
||||
|
||||
#if !defined SPH_CUBEHASH_UNROLL
|
||||
#define SPH_CUBEHASH_UNROLL 4
|
||||
#endif
|
||||
#if !defined SPH_CUBEHASH_NOCOPY
|
||||
#define SPH_CUBEHASH_NOCOPY 1
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if !defined SPH_CUBEHASH_UNROLL
|
||||
#define SPH_CUBEHASH_UNROLL 0
|
||||
#endif
|
||||
#if !defined SPH_CUBEHASH_NOCOPY
|
||||
#define SPH_CUBEHASH_NOCOPY 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4146)
|
||||
#endif
|
||||
|
||||
static const sph_u32 IV224[] = {
|
||||
SPH_C32(0xB0FC8217), SPH_C32(0x1BEE1A90), SPH_C32(0x829E1A22),
|
||||
SPH_C32(0x6362C342), SPH_C32(0x24D91C30), SPH_C32(0x03A7AA24),
|
||||
SPH_C32(0xA63721C8), SPH_C32(0x85B0E2EF), SPH_C32(0xF35D13F3),
|
||||
SPH_C32(0x41DA807D), SPH_C32(0x21A70CA6), SPH_C32(0x1F4E9774),
|
||||
SPH_C32(0xB3E1C932), SPH_C32(0xEB0A79A8), SPH_C32(0xCDDAAA66),
|
||||
SPH_C32(0xE2F6ECAA), SPH_C32(0x0A713362), SPH_C32(0xAA3080E0),
|
||||
SPH_C32(0xD8F23A32), SPH_C32(0xCEF15E28), SPH_C32(0xDB086314),
|
||||
SPH_C32(0x7F709DF7), SPH_C32(0xACD228A4), SPH_C32(0x704D6ECE),
|
||||
SPH_C32(0xAA3EC95F), SPH_C32(0xE387C214), SPH_C32(0x3A6445FF),
|
||||
SPH_C32(0x9CAB81C3), SPH_C32(0xC73D4B98), SPH_C32(0xD277AEBE),
|
||||
SPH_C32(0xFD20151C), SPH_C32(0x00CB573E)
|
||||
};
|
||||
|
||||
static const sph_u32 IV256[] = {
|
||||
SPH_C32(0xEA2BD4B4), SPH_C32(0xCCD6F29F), SPH_C32(0x63117E71),
|
||||
SPH_C32(0x35481EAE), SPH_C32(0x22512D5B), SPH_C32(0xE5D94E63),
|
||||
SPH_C32(0x7E624131), SPH_C32(0xF4CC12BE), SPH_C32(0xC2D0B696),
|
||||
SPH_C32(0x42AF2070), SPH_C32(0xD0720C35), SPH_C32(0x3361DA8C),
|
||||
SPH_C32(0x28CCECA4), SPH_C32(0x8EF8AD83), SPH_C32(0x4680AC00),
|
||||
SPH_C32(0x40E5FBAB), SPH_C32(0xD89041C3), SPH_C32(0x6107FBD5),
|
||||
SPH_C32(0x6C859D41), SPH_C32(0xF0B26679), SPH_C32(0x09392549),
|
||||
SPH_C32(0x5FA25603), SPH_C32(0x65C892FD), SPH_C32(0x93CB6285),
|
||||
SPH_C32(0x2AF2B5AE), SPH_C32(0x9E4B4E60), SPH_C32(0x774ABFDD),
|
||||
SPH_C32(0x85254725), SPH_C32(0x15815AEB), SPH_C32(0x4AB6AAD6),
|
||||
SPH_C32(0x9CDAF8AF), SPH_C32(0xD6032C0A)
|
||||
};
|
||||
|
||||
static const sph_u32 IV384[] = {
|
||||
SPH_C32(0xE623087E), SPH_C32(0x04C00C87), SPH_C32(0x5EF46453),
|
||||
SPH_C32(0x69524B13), SPH_C32(0x1A05C7A9), SPH_C32(0x3528DF88),
|
||||
SPH_C32(0x6BDD01B5), SPH_C32(0x5057B792), SPH_C32(0x6AA7A922),
|
||||
SPH_C32(0x649C7EEE), SPH_C32(0xF426309F), SPH_C32(0xCB629052),
|
||||
SPH_C32(0xFC8E20ED), SPH_C32(0xB3482BAB), SPH_C32(0xF89E5E7E),
|
||||
SPH_C32(0xD83D4DE4), SPH_C32(0x44BFC10D), SPH_C32(0x5FC1E63D),
|
||||
SPH_C32(0x2104E6CB), SPH_C32(0x17958F7F), SPH_C32(0xDBEAEF70),
|
||||
SPH_C32(0xB4B97E1E), SPH_C32(0x32C195F6), SPH_C32(0x6184A8E4),
|
||||
SPH_C32(0x796C2543), SPH_C32(0x23DE176D), SPH_C32(0xD33BBAEC),
|
||||
SPH_C32(0x0C12E5D2), SPH_C32(0x4EB95A7B), SPH_C32(0x2D18BA01),
|
||||
SPH_C32(0x04EE475F), SPH_C32(0x1FC5F22E)
|
||||
};
|
||||
|
||||
static const sph_u32 IV512[] = {
|
||||
SPH_C32(0x2AEA2A61), SPH_C32(0x50F494D4), SPH_C32(0x2D538B8B),
|
||||
SPH_C32(0x4167D83E), SPH_C32(0x3FEE2313), SPH_C32(0xC701CF8C),
|
||||
SPH_C32(0xCC39968E), SPH_C32(0x50AC5695), SPH_C32(0x4D42C787),
|
||||
SPH_C32(0xA647A8B3), SPH_C32(0x97CF0BEF), SPH_C32(0x825B4537),
|
||||
SPH_C32(0xEEF864D2), SPH_C32(0xF22090C4), SPH_C32(0xD0E5CD33),
|
||||
SPH_C32(0xA23911AE), SPH_C32(0xFCD398D9), SPH_C32(0x148FE485),
|
||||
SPH_C32(0x1B017BEF), SPH_C32(0xB6444532), SPH_C32(0x6A536159),
|
||||
SPH_C32(0x2FF5781C), SPH_C32(0x91FA7934), SPH_C32(0x0DBADEA9),
|
||||
SPH_C32(0xD65C8A2B), SPH_C32(0xA5A70E75), SPH_C32(0xB1C62456),
|
||||
SPH_C32(0xBC796576), SPH_C32(0x1921C8F7), SPH_C32(0xE7989AF1),
|
||||
SPH_C32(0x7795D246), SPH_C32(0xD43E3B44)
|
||||
};
|
||||
|
||||
#define T32 SPH_T32
|
||||
#define ROTL32 SPH_ROTL32
|
||||
|
||||
#if SPH_CUBEHASH_NOCOPY
|
||||
|
||||
#define DECL_STATE
|
||||
#define READ_STATE(cc)
|
||||
#define WRITE_STATE(cc)
|
||||
|
||||
#define x0 ((sc)->state[ 0])
|
||||
#define x1 ((sc)->state[ 1])
|
||||
#define x2 ((sc)->state[ 2])
|
||||
#define x3 ((sc)->state[ 3])
|
||||
#define x4 ((sc)->state[ 4])
|
||||
#define x5 ((sc)->state[ 5])
|
||||
#define x6 ((sc)->state[ 6])
|
||||
#define x7 ((sc)->state[ 7])
|
||||
#define x8 ((sc)->state[ 8])
|
||||
#define x9 ((sc)->state[ 9])
|
||||
#define xa ((sc)->state[10])
|
||||
#define xb ((sc)->state[11])
|
||||
#define xc ((sc)->state[12])
|
||||
#define xd ((sc)->state[13])
|
||||
#define xe ((sc)->state[14])
|
||||
#define xf ((sc)->state[15])
|
||||
#define xg ((sc)->state[16])
|
||||
#define xh ((sc)->state[17])
|
||||
#define xi ((sc)->state[18])
|
||||
#define xj ((sc)->state[19])
|
||||
#define xk ((sc)->state[20])
|
||||
#define xl ((sc)->state[21])
|
||||
#define xm ((sc)->state[22])
|
||||
#define xn ((sc)->state[23])
|
||||
#define xo ((sc)->state[24])
|
||||
#define xp ((sc)->state[25])
|
||||
#define xq ((sc)->state[26])
|
||||
#define xr ((sc)->state[27])
|
||||
#define xs ((sc)->state[28])
|
||||
#define xt ((sc)->state[29])
|
||||
#define xu ((sc)->state[30])
|
||||
#define xv ((sc)->state[31])
|
||||
|
||||
#else
|
||||
|
||||
#define DECL_STATE \
|
||||
sph_u32 x0, x1, x2, x3, x4, x5, x6, x7; \
|
||||
sph_u32 x8, x9, xa, xb, xc, xd, xe, xf; \
|
||||
sph_u32 xg, xh, xi, xj, xk, xl, xm, xn; \
|
||||
sph_u32 xo, xp, xq, xr, xs, xt, xu, xv;
|
||||
|
||||
#define READ_STATE(cc) do { \
|
||||
x0 = (cc)->state[ 0]; \
|
||||
x1 = (cc)->state[ 1]; \
|
||||
x2 = (cc)->state[ 2]; \
|
||||
x3 = (cc)->state[ 3]; \
|
||||
x4 = (cc)->state[ 4]; \
|
||||
x5 = (cc)->state[ 5]; \
|
||||
x6 = (cc)->state[ 6]; \
|
||||
x7 = (cc)->state[ 7]; \
|
||||
x8 = (cc)->state[ 8]; \
|
||||
x9 = (cc)->state[ 9]; \
|
||||
xa = (cc)->state[10]; \
|
||||
xb = (cc)->state[11]; \
|
||||
xc = (cc)->state[12]; \
|
||||
xd = (cc)->state[13]; \
|
||||
xe = (cc)->state[14]; \
|
||||
xf = (cc)->state[15]; \
|
||||
xg = (cc)->state[16]; \
|
||||
xh = (cc)->state[17]; \
|
||||
xi = (cc)->state[18]; \
|
||||
xj = (cc)->state[19]; \
|
||||
xk = (cc)->state[20]; \
|
||||
xl = (cc)->state[21]; \
|
||||
xm = (cc)->state[22]; \
|
||||
xn = (cc)->state[23]; \
|
||||
xo = (cc)->state[24]; \
|
||||
xp = (cc)->state[25]; \
|
||||
xq = (cc)->state[26]; \
|
||||
xr = (cc)->state[27]; \
|
||||
xs = (cc)->state[28]; \
|
||||
xt = (cc)->state[29]; \
|
||||
xu = (cc)->state[30]; \
|
||||
xv = (cc)->state[31]; \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_STATE(cc) do { \
|
||||
(cc)->state[ 0] = x0; \
|
||||
(cc)->state[ 1] = x1; \
|
||||
(cc)->state[ 2] = x2; \
|
||||
(cc)->state[ 3] = x3; \
|
||||
(cc)->state[ 4] = x4; \
|
||||
(cc)->state[ 5] = x5; \
|
||||
(cc)->state[ 6] = x6; \
|
||||
(cc)->state[ 7] = x7; \
|
||||
(cc)->state[ 8] = x8; \
|
||||
(cc)->state[ 9] = x9; \
|
||||
(cc)->state[10] = xa; \
|
||||
(cc)->state[11] = xb; \
|
||||
(cc)->state[12] = xc; \
|
||||
(cc)->state[13] = xd; \
|
||||
(cc)->state[14] = xe; \
|
||||
(cc)->state[15] = xf; \
|
||||
(cc)->state[16] = xg; \
|
||||
(cc)->state[17] = xh; \
|
||||
(cc)->state[18] = xi; \
|
||||
(cc)->state[19] = xj; \
|
||||
(cc)->state[20] = xk; \
|
||||
(cc)->state[21] = xl; \
|
||||
(cc)->state[22] = xm; \
|
||||
(cc)->state[23] = xn; \
|
||||
(cc)->state[24] = xo; \
|
||||
(cc)->state[25] = xp; \
|
||||
(cc)->state[26] = xq; \
|
||||
(cc)->state[27] = xr; \
|
||||
(cc)->state[28] = xs; \
|
||||
(cc)->state[29] = xt; \
|
||||
(cc)->state[30] = xu; \
|
||||
(cc)->state[31] = xv; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#define INPUT_BLOCK do { \
|
||||
x0 ^= sph_dec32le_aligned(buf + 0); \
|
||||
x1 ^= sph_dec32le_aligned(buf + 4); \
|
||||
x2 ^= sph_dec32le_aligned(buf + 8); \
|
||||
x3 ^= sph_dec32le_aligned(buf + 12); \
|
||||
x4 ^= sph_dec32le_aligned(buf + 16); \
|
||||
x5 ^= sph_dec32le_aligned(buf + 20); \
|
||||
x6 ^= sph_dec32le_aligned(buf + 24); \
|
||||
x7 ^= sph_dec32le_aligned(buf + 28); \
|
||||
} while (0)
|
||||
|
||||
#define ROUND_EVEN do { \
|
||||
xg = T32(x0 + xg); \
|
||||
x0 = ROTL32(x0, 7); \
|
||||
xh = T32(x1 + xh); \
|
||||
x1 = ROTL32(x1, 7); \
|
||||
xi = T32(x2 + xi); \
|
||||
x2 = ROTL32(x2, 7); \
|
||||
xj = T32(x3 + xj); \
|
||||
x3 = ROTL32(x3, 7); \
|
||||
xk = T32(x4 + xk); \
|
||||
x4 = ROTL32(x4, 7); \
|
||||
xl = T32(x5 + xl); \
|
||||
x5 = ROTL32(x5, 7); \
|
||||
xm = T32(x6 + xm); \
|
||||
x6 = ROTL32(x6, 7); \
|
||||
xn = T32(x7 + xn); \
|
||||
x7 = ROTL32(x7, 7); \
|
||||
xo = T32(x8 + xo); \
|
||||
x8 = ROTL32(x8, 7); \
|
||||
xp = T32(x9 + xp); \
|
||||
x9 = ROTL32(x9, 7); \
|
||||
xq = T32(xa + xq); \
|
||||
xa = ROTL32(xa, 7); \
|
||||
xr = T32(xb + xr); \
|
||||
xb = ROTL32(xb, 7); \
|
||||
xs = T32(xc + xs); \
|
||||
xc = ROTL32(xc, 7); \
|
||||
xt = T32(xd + xt); \
|
||||
xd = ROTL32(xd, 7); \
|
||||
xu = T32(xe + xu); \
|
||||
xe = ROTL32(xe, 7); \
|
||||
xv = T32(xf + xv); \
|
||||
xf = ROTL32(xf, 7); \
|
||||
x8 ^= xg; \
|
||||
x9 ^= xh; \
|
||||
xa ^= xi; \
|
||||
xb ^= xj; \
|
||||
xc ^= xk; \
|
||||
xd ^= xl; \
|
||||
xe ^= xm; \
|
||||
xf ^= xn; \
|
||||
x0 ^= xo; \
|
||||
x1 ^= xp; \
|
||||
x2 ^= xq; \
|
||||
x3 ^= xr; \
|
||||
x4 ^= xs; \
|
||||
x5 ^= xt; \
|
||||
x6 ^= xu; \
|
||||
x7 ^= xv; \
|
||||
xi = T32(x8 + xi); \
|
||||
x8 = ROTL32(x8, 11); \
|
||||
xj = T32(x9 + xj); \
|
||||
x9 = ROTL32(x9, 11); \
|
||||
xg = T32(xa + xg); \
|
||||
xa = ROTL32(xa, 11); \
|
||||
xh = T32(xb + xh); \
|
||||
xb = ROTL32(xb, 11); \
|
||||
xm = T32(xc + xm); \
|
||||
xc = ROTL32(xc, 11); \
|
||||
xn = T32(xd + xn); \
|
||||
xd = ROTL32(xd, 11); \
|
||||
xk = T32(xe + xk); \
|
||||
xe = ROTL32(xe, 11); \
|
||||
xl = T32(xf + xl); \
|
||||
xf = ROTL32(xf, 11); \
|
||||
xq = T32(x0 + xq); \
|
||||
x0 = ROTL32(x0, 11); \
|
||||
xr = T32(x1 + xr); \
|
||||
x1 = ROTL32(x1, 11); \
|
||||
xo = T32(x2 + xo); \
|
||||
x2 = ROTL32(x2, 11); \
|
||||
xp = T32(x3 + xp); \
|
||||
x3 = ROTL32(x3, 11); \
|
||||
xu = T32(x4 + xu); \
|
||||
x4 = ROTL32(x4, 11); \
|
||||
xv = T32(x5 + xv); \
|
||||
x5 = ROTL32(x5, 11); \
|
||||
xs = T32(x6 + xs); \
|
||||
x6 = ROTL32(x6, 11); \
|
||||
xt = T32(x7 + xt); \
|
||||
x7 = ROTL32(x7, 11); \
|
||||
xc ^= xi; \
|
||||
xd ^= xj; \
|
||||
xe ^= xg; \
|
||||
xf ^= xh; \
|
||||
x8 ^= xm; \
|
||||
x9 ^= xn; \
|
||||
xa ^= xk; \
|
||||
xb ^= xl; \
|
||||
x4 ^= xq; \
|
||||
x5 ^= xr; \
|
||||
x6 ^= xo; \
|
||||
x7 ^= xp; \
|
||||
x0 ^= xu; \
|
||||
x1 ^= xv; \
|
||||
x2 ^= xs; \
|
||||
x3 ^= xt; \
|
||||
} while (0)
|
||||
|
||||
#define ROUND_ODD do { \
|
||||
xj = T32(xc + xj); \
|
||||
xc = ROTL32(xc, 7); \
|
||||
xi = T32(xd + xi); \
|
||||
xd = ROTL32(xd, 7); \
|
||||
xh = T32(xe + xh); \
|
||||
xe = ROTL32(xe, 7); \
|
||||
xg = T32(xf + xg); \
|
||||
xf = ROTL32(xf, 7); \
|
||||
xn = T32(x8 + xn); \
|
||||
x8 = ROTL32(x8, 7); \
|
||||
xm = T32(x9 + xm); \
|
||||
x9 = ROTL32(x9, 7); \
|
||||
xl = T32(xa + xl); \
|
||||
xa = ROTL32(xa, 7); \
|
||||
xk = T32(xb + xk); \
|
||||
xb = ROTL32(xb, 7); \
|
||||
xr = T32(x4 + xr); \
|
||||
x4 = ROTL32(x4, 7); \
|
||||
xq = T32(x5 + xq); \
|
||||
x5 = ROTL32(x5, 7); \
|
||||
xp = T32(x6 + xp); \
|
||||
x6 = ROTL32(x6, 7); \
|
||||
xo = T32(x7 + xo); \
|
||||
x7 = ROTL32(x7, 7); \
|
||||
xv = T32(x0 + xv); \
|
||||
x0 = ROTL32(x0, 7); \
|
||||
xu = T32(x1 + xu); \
|
||||
x1 = ROTL32(x1, 7); \
|
||||
xt = T32(x2 + xt); \
|
||||
x2 = ROTL32(x2, 7); \
|
||||
xs = T32(x3 + xs); \
|
||||
x3 = ROTL32(x3, 7); \
|
||||
x4 ^= xj; \
|
||||
x5 ^= xi; \
|
||||
x6 ^= xh; \
|
||||
x7 ^= xg; \
|
||||
x0 ^= xn; \
|
||||
x1 ^= xm; \
|
||||
x2 ^= xl; \
|
||||
x3 ^= xk; \
|
||||
xc ^= xr; \
|
||||
xd ^= xq; \
|
||||
xe ^= xp; \
|
||||
xf ^= xo; \
|
||||
x8 ^= xv; \
|
||||
x9 ^= xu; \
|
||||
xa ^= xt; \
|
||||
xb ^= xs; \
|
||||
xh = T32(x4 + xh); \
|
||||
x4 = ROTL32(x4, 11); \
|
||||
xg = T32(x5 + xg); \
|
||||
x5 = ROTL32(x5, 11); \
|
||||
xj = T32(x6 + xj); \
|
||||
x6 = ROTL32(x6, 11); \
|
||||
xi = T32(x7 + xi); \
|
||||
x7 = ROTL32(x7, 11); \
|
||||
xl = T32(x0 + xl); \
|
||||
x0 = ROTL32(x0, 11); \
|
||||
xk = T32(x1 + xk); \
|
||||
x1 = ROTL32(x1, 11); \
|
||||
xn = T32(x2 + xn); \
|
||||
x2 = ROTL32(x2, 11); \
|
||||
xm = T32(x3 + xm); \
|
||||
x3 = ROTL32(x3, 11); \
|
||||
xp = T32(xc + xp); \
|
||||
xc = ROTL32(xc, 11); \
|
||||
xo = T32(xd + xo); \
|
||||
xd = ROTL32(xd, 11); \
|
||||
xr = T32(xe + xr); \
|
||||
xe = ROTL32(xe, 11); \
|
||||
xq = T32(xf + xq); \
|
||||
xf = ROTL32(xf, 11); \
|
||||
xt = T32(x8 + xt); \
|
||||
x8 = ROTL32(x8, 11); \
|
||||
xs = T32(x9 + xs); \
|
||||
x9 = ROTL32(x9, 11); \
|
||||
xv = T32(xa + xv); \
|
||||
xa = ROTL32(xa, 11); \
|
||||
xu = T32(xb + xu); \
|
||||
xb = ROTL32(xb, 11); \
|
||||
x0 ^= xh; \
|
||||
x1 ^= xg; \
|
||||
x2 ^= xj; \
|
||||
x3 ^= xi; \
|
||||
x4 ^= xl; \
|
||||
x5 ^= xk; \
|
||||
x6 ^= xn; \
|
||||
x7 ^= xm; \
|
||||
x8 ^= xp; \
|
||||
x9 ^= xo; \
|
||||
xa ^= xr; \
|
||||
xb ^= xq; \
|
||||
xc ^= xt; \
|
||||
xd ^= xs; \
|
||||
xe ^= xv; \
|
||||
xf ^= xu; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* There is no need to unroll all 16 rounds. The word-swapping permutation
|
||||
* is an involution, so we need to unroll an even number of rounds. On
|
||||
* "big" systems, unrolling 4 rounds yields about 97% of the speed
|
||||
* achieved with full unrolling; and it keeps the code more compact
|
||||
* for small architectures.
|
||||
*/
|
||||
|
||||
#if SPH_CUBEHASH_UNROLL == 2
|
||||
|
||||
#define SIXTEEN_ROUNDS do { \
|
||||
int j; \
|
||||
for (j = 0; j < 8; j ++) { \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#elif SPH_CUBEHASH_UNROLL == 4
|
||||
|
||||
#define SIXTEEN_ROUNDS do { \
|
||||
int j; \
|
||||
for (j = 0; j < 4; j ++) { \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#elif SPH_CUBEHASH_UNROLL == 8
|
||||
|
||||
#define SIXTEEN_ROUNDS do { \
|
||||
int j; \
|
||||
for (j = 0; j < 2; j ++) { \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define SIXTEEN_ROUNDS do { \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
ROUND_EVEN; \
|
||||
ROUND_ODD; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
static void
|
||||
cubehash_init(sph_cubehash_context *sc, const sph_u32 *iv)
|
||||
{
|
||||
memcpy(sc->state, iv, sizeof sc->state);
|
||||
sc->ptr = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cubehash_core(sph_cubehash_context *sc, const void *data, size_t len)
|
||||
{
|
||||
unsigned char *buf;
|
||||
size_t ptr;
|
||||
DECL_STATE
|
||||
|
||||
buf = sc->buf;
|
||||
ptr = sc->ptr;
|
||||
if (len < (sizeof sc->buf) - ptr) {
|
||||
memcpy(buf + ptr, data, len);
|
||||
ptr += len;
|
||||
sc->ptr = ptr;
|
||||
return;
|
||||
}
|
||||
|
||||
READ_STATE(sc);
|
||||
while (len > 0) {
|
||||
size_t clen;
|
||||
|
||||
clen = (sizeof sc->buf) - ptr;
|
||||
if (clen > len)
|
||||
clen = len;
|
||||
memcpy(buf + ptr, data, clen);
|
||||
ptr += clen;
|
||||
data = (const unsigned char *)data + clen;
|
||||
len -= clen;
|
||||
if (ptr == sizeof sc->buf) {
|
||||
INPUT_BLOCK;
|
||||
SIXTEEN_ROUNDS;
|
||||
ptr = 0;
|
||||
}
|
||||
}
|
||||
WRITE_STATE(sc);
|
||||
sc->ptr = ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
cubehash_close(sph_cubehash_context *sc, unsigned ub, unsigned n,
|
||||
void *dst, size_t out_size_w32)
|
||||
{
|
||||
unsigned char *buf, *out;
|
||||
size_t ptr;
|
||||
unsigned z;
|
||||
int i;
|
||||
DECL_STATE
|
||||
|
||||
buf = sc->buf;
|
||||
ptr = sc->ptr;
|
||||
z = 0x80 >> n;
|
||||
buf[ptr ++] = ((ub & -z) | z) & 0xFF;
|
||||
memset(buf + ptr, 0, (sizeof sc->buf) - ptr);
|
||||
READ_STATE(sc);
|
||||
INPUT_BLOCK;
|
||||
for (i = 0; i < 11; i ++) {
|
||||
SIXTEEN_ROUNDS;
|
||||
if (i == 0)
|
||||
xv ^= SPH_C32(1);
|
||||
}
|
||||
WRITE_STATE(sc);
|
||||
out = (unsigned char*) dst;
|
||||
for (z = 0; z < out_size_w32; z ++)
|
||||
sph_enc32le(out + (z << 2), sc->state[z]);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash224_init(void *cc)
|
||||
{
|
||||
cubehash_init((sph_cubehash_context*) cc, IV224);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash224(void *cc, const void *data, size_t len)
|
||||
{
|
||||
cubehash_core((sph_cubehash_context*) cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash224_close(void *cc, void *dst)
|
||||
{
|
||||
sph_cubehash224_addbits_and_close((sph_cubehash_context*) cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
cubehash_close((sph_cubehash_context*) cc, ub, n, dst, 7);
|
||||
sph_cubehash224_init(cc);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash256_init(void *cc)
|
||||
{
|
||||
cubehash_init((sph_cubehash_context*) cc, IV256);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash256(void *cc, const void *data, size_t len)
|
||||
{
|
||||
cubehash_core((sph_cubehash_context*) cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash256_close(void *cc, void *dst)
|
||||
{
|
||||
sph_cubehash256_addbits_and_close((sph_cubehash_context*) cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
cubehash_close((sph_cubehash_context*) cc, ub, n, dst, 8);
|
||||
sph_cubehash256_init(cc);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash384_init(void *cc)
|
||||
{
|
||||
cubehash_init((sph_cubehash_context*) cc, IV384);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash384(void *cc, const void *data, size_t len)
|
||||
{
|
||||
cubehash_core((sph_cubehash_context*) cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash384_close(void *cc, void *dst)
|
||||
{
|
||||
sph_cubehash384_addbits_and_close((sph_cubehash_context*) cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
cubehash_close((sph_cubehash_context*) cc, ub, n, dst, 12);
|
||||
sph_cubehash384_init(cc);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash512_init(void *cc)
|
||||
{
|
||||
cubehash_init((sph_cubehash_context*) cc, IV512);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash512(void *cc, const void *data, size_t len)
|
||||
{
|
||||
cubehash_core((sph_cubehash_context*) cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash512_close(void *cc, void *dst)
|
||||
{
|
||||
sph_cubehash512_addbits_and_close((sph_cubehash_context*) cc, 0, 0, dst);
|
||||
}
|
||||
|
||||
/* see sph_cubehash.h */
|
||||
void
|
||||
sph_cubehash512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
cubehash_close((sph_cubehash_context*) cc, ub, n, dst, 16);
|
||||
sph_cubehash512_init(cc);
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
1031
src/crypto/echo.cpp
Normal file
1031
src/crypto/echo.cpp
Normal file
File diff suppressed because it is too large
Load diff
21
src/crypto/hkdf_sha256_32.cpp
Normal file
21
src/crypto/hkdf_sha256_32.cpp
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) 2018-2019 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <crypto/hkdf_sha256_32.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
CHKDF_HMAC_SHA256_L32::CHKDF_HMAC_SHA256_L32(const unsigned char* ikm, size_t ikmlen, const std::string& salt)
|
||||
{
|
||||
CHMAC_SHA256((const unsigned char*)salt.data(), salt.size()).Write(ikm, ikmlen).Finalize(m_prk);
|
||||
}
|
||||
|
||||
void CHKDF_HMAC_SHA256_L32::Expand32(const std::string& info, unsigned char hash[OUTPUT_SIZE])
|
||||
{
|
||||
// expand a 32byte key (single round)
|
||||
assert(info.size() <= 128);
|
||||
static const unsigned char one[1] = {1};
|
||||
CHMAC_SHA256(m_prk, 32).Write((const unsigned char*)info.data(), info.size()).Write(one, 1).Finalize(hash);
|
||||
}
|
||||
25
src/crypto/hkdf_sha256_32.h
Normal file
25
src/crypto/hkdf_sha256_32.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) 2018 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef DIGIBYTE_CRYPTO_HKDF_SHA256_32_H
|
||||
#define DIGIBYTE_CRYPTO_HKDF_SHA256_32_H
|
||||
|
||||
#include <crypto/hmac_sha256.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** A rfc5869 HKDF implementation with HMAC_SHA256 and fixed key output length of 32 bytes (L=32) */
|
||||
class CHKDF_HMAC_SHA256_L32
|
||||
{
|
||||
private:
|
||||
unsigned char m_prk[32];
|
||||
static const size_t OUTPUT_SIZE = 32;
|
||||
|
||||
public:
|
||||
CHKDF_HMAC_SHA256_L32(const unsigned char* ikm, size_t ikmlen, const std::string& salt);
|
||||
void Expand32(const std::string& info, unsigned char hash[OUTPUT_SIZE]);
|
||||
};
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_HKDF_SHA256_32_H
|
||||
40
src/crypto/hmac_sha256.cpp
Normal file
40
src/crypto/hmac_sha256.cpp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <crypto/hmac_sha256.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
CHMAC_SHA256::CHMAC_SHA256(const unsigned char* key, size_t keylen)
|
||||
{
|
||||
unsigned char rkey[64];
|
||||
if (keylen <= 64) {
|
||||
memcpy(rkey, key, keylen);
|
||||
memset(rkey + keylen, 0, 64 - keylen);
|
||||
} else {
|
||||
CSHA256().Write(key, keylen).Finalize(rkey);
|
||||
memset(rkey + 32, 0, 32);
|
||||
}
|
||||
|
||||
for (int n = 0; n < 64; n++)
|
||||
rkey[n] ^= 0x5c;
|
||||
outer.Write(rkey, 64);
|
||||
|
||||
for (int n = 0; n < 64; n++)
|
||||
rkey[n] ^= 0x5c ^ 0x36;
|
||||
inner.Write(rkey, 64);
|
||||
}
|
||||
|
||||
void CHMAC_SHA256::Reset() {
|
||||
inner.Reset();
|
||||
outer.Reset();
|
||||
}
|
||||
|
||||
void CHMAC_SHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
|
||||
{
|
||||
unsigned char temp[32];
|
||||
inner.Finalize(temp);
|
||||
outer.Write(temp, 32).Finalize(hash);
|
||||
}
|
||||
34
src/crypto/hmac_sha256.h
Normal file
34
src/crypto/hmac_sha256.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef DIGIBYTE_CRYPTO_HMAC_SHA256_H
|
||||
#define DIGIBYTE_CRYPTO_HMAC_SHA256_H
|
||||
|
||||
#include <crypto/sha256.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** A hasher class for HMAC-SHA-256. */
|
||||
class CHMAC_SHA256
|
||||
{
|
||||
private:
|
||||
CSHA256 outer;
|
||||
CSHA256 inner;
|
||||
|
||||
public:
|
||||
static const size_t OUTPUT_SIZE = 32;
|
||||
|
||||
CHMAC_SHA256(const unsigned char* key, size_t keylen);
|
||||
CHMAC_SHA256& Write(const unsigned char* data, size_t len)
|
||||
{
|
||||
inner.Write(data, len);
|
||||
return *this;
|
||||
}
|
||||
void Reset();
|
||||
void Finalize(unsigned char hash[OUTPUT_SIZE]);
|
||||
};
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_HMAC_SHA256_H
|
||||
35
src/crypto/hmac_sha512.cpp
Normal file
35
src/crypto/hmac_sha512.cpp
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <crypto/hmac_sha512.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
CHMAC_SHA512::CHMAC_SHA512(const unsigned char* key, size_t keylen)
|
||||
{
|
||||
unsigned char rkey[128];
|
||||
if (keylen <= 128) {
|
||||
memcpy(rkey, key, keylen);
|
||||
memset(rkey + keylen, 0, 128 - keylen);
|
||||
} else {
|
||||
CSHA512().Write(key, keylen).Finalize(rkey);
|
||||
memset(rkey + 64, 0, 64);
|
||||
}
|
||||
|
||||
for (int n = 0; n < 128; n++)
|
||||
rkey[n] ^= 0x5c;
|
||||
outer.Write(rkey, 128);
|
||||
|
||||
for (int n = 0; n < 128; n++)
|
||||
rkey[n] ^= 0x5c ^ 0x36;
|
||||
inner.Write(rkey, 128);
|
||||
}
|
||||
|
||||
void CHMAC_SHA512::Finalize(unsigned char hash[OUTPUT_SIZE])
|
||||
{
|
||||
unsigned char temp[64];
|
||||
inner.Finalize(temp);
|
||||
outer.Write(temp, 64).Finalize(hash);
|
||||
}
|
||||
33
src/crypto/hmac_sha512.h
Normal file
33
src/crypto/hmac_sha512.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef DIGIBYTE_CRYPTO_HMAC_SHA512_H
|
||||
#define DIGIBYTE_CRYPTO_HMAC_SHA512_H
|
||||
|
||||
#include <crypto/sha512.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** A hasher class for HMAC-SHA-512. */
|
||||
class CHMAC_SHA512
|
||||
{
|
||||
private:
|
||||
CSHA512 outer;
|
||||
CSHA512 inner;
|
||||
|
||||
public:
|
||||
static const size_t OUTPUT_SIZE = 64;
|
||||
|
||||
CHMAC_SHA512(const unsigned char* key, size_t keylen);
|
||||
CHMAC_SHA512& Write(const unsigned char* data, size_t len)
|
||||
{
|
||||
inner.Write(data, len);
|
||||
return *this;
|
||||
}
|
||||
void Finalize(unsigned char hash[OUTPUT_SIZE]);
|
||||
};
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_HMAC_SHA512_H
|
||||
1116
src/crypto/jh.cpp
Normal file
1116
src/crypto/jh.cpp
Normal file
File diff suppressed because it is too large
Load diff
1824
src/crypto/keccak.cpp
Normal file
1824
src/crypto/keccak.cpp
Normal file
File diff suppressed because it is too large
Load diff
1428
src/crypto/luffa.cpp
Normal file
1428
src/crypto/luffa.cpp
Normal file
File diff suppressed because it is too large
Load diff
346
src/crypto/muhash.cpp
Normal file
346
src/crypto/muhash.cpp
Normal file
|
|
@ -0,0 +1,346 @@
|
|||
// Copyright (c) 2017-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <crypto/muhash.h>
|
||||
|
||||
#include <crypto/chacha20.h>
|
||||
#include <crypto/common.h>
|
||||
#include <hash.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
|
||||
namespace {
|
||||
|
||||
using limb_t = Num3072::limb_t;
|
||||
using double_limb_t = Num3072::double_limb_t;
|
||||
constexpr int LIMB_SIZE = Num3072::LIMB_SIZE;
|
||||
/** 2^3072 - 1103717, the largest 3072-bit safe prime number, is used as the modulus. */
|
||||
constexpr limb_t MAX_PRIME_DIFF = 1103717;
|
||||
|
||||
/** Extract the lowest limb of [c0,c1,c2] into n, and left shift the number by 1 limb. */
|
||||
inline void extract3(limb_t& c0, limb_t& c1, limb_t& c2, limb_t& n)
|
||||
{
|
||||
n = c0;
|
||||
c0 = c1;
|
||||
c1 = c2;
|
||||
c2 = 0;
|
||||
}
|
||||
|
||||
/** [c0,c1] = a * b */
|
||||
inline void mul(limb_t& c0, limb_t& c1, const limb_t& a, const limb_t& b)
|
||||
{
|
||||
double_limb_t t = (double_limb_t)a * b;
|
||||
c1 = t >> LIMB_SIZE;
|
||||
c0 = t;
|
||||
}
|
||||
|
||||
/* [c0,c1,c2] += n * [d0,d1,d2]. c2 is 0 initially */
|
||||
inline void mulnadd3(limb_t& c0, limb_t& c1, limb_t& c2, limb_t& d0, limb_t& d1, limb_t& d2, const limb_t& n)
|
||||
{
|
||||
double_limb_t t = (double_limb_t)d0 * n + c0;
|
||||
c0 = t;
|
||||
t >>= LIMB_SIZE;
|
||||
t += (double_limb_t)d1 * n + c1;
|
||||
c1 = t;
|
||||
t >>= LIMB_SIZE;
|
||||
c2 = t + d2 * n;
|
||||
}
|
||||
|
||||
/* [c0,c1] *= n */
|
||||
inline void muln2(limb_t& c0, limb_t& c1, const limb_t& n)
|
||||
{
|
||||
double_limb_t t = (double_limb_t)c0 * n;
|
||||
c0 = t;
|
||||
t >>= LIMB_SIZE;
|
||||
t += (double_limb_t)c1 * n;
|
||||
c1 = t;
|
||||
}
|
||||
|
||||
/** [c0,c1,c2] += a * b */
|
||||
inline void muladd3(limb_t& c0, limb_t& c1, limb_t& c2, const limb_t& a, const limb_t& b)
|
||||
{
|
||||
double_limb_t t = (double_limb_t)a * b;
|
||||
limb_t th = t >> LIMB_SIZE;
|
||||
limb_t tl = t;
|
||||
|
||||
c0 += tl;
|
||||
th += (c0 < tl) ? 1 : 0;
|
||||
c1 += th;
|
||||
c2 += (c1 < th) ? 1 : 0;
|
||||
}
|
||||
|
||||
/** [c0,c1,c2] += 2 * a * b */
|
||||
inline void muldbladd3(limb_t& c0, limb_t& c1, limb_t& c2, const limb_t& a, const limb_t& b)
|
||||
{
|
||||
double_limb_t t = (double_limb_t)a * b;
|
||||
limb_t th = t >> LIMB_SIZE;
|
||||
limb_t tl = t;
|
||||
|
||||
c0 += tl;
|
||||
limb_t tt = th + ((c0 < tl) ? 1 : 0);
|
||||
c1 += tt;
|
||||
c2 += (c1 < tt) ? 1 : 0;
|
||||
c0 += tl;
|
||||
th += (c0 < tl) ? 1 : 0;
|
||||
c1 += th;
|
||||
c2 += (c1 < th) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add limb a to [c0,c1]: [c0,c1] += a. Then extract the lowest
|
||||
* limb of [c0,c1] into n, and left shift the number by 1 limb.
|
||||
* */
|
||||
inline void addnextract2(limb_t& c0, limb_t& c1, const limb_t& a, limb_t& n)
|
||||
{
|
||||
limb_t c2 = 0;
|
||||
|
||||
// add
|
||||
c0 += a;
|
||||
if (c0 < a) {
|
||||
c1 += 1;
|
||||
|
||||
// Handle case when c1 has overflown
|
||||
if (c1 == 0)
|
||||
c2 = 1;
|
||||
}
|
||||
|
||||
// extract
|
||||
n = c0;
|
||||
c0 = c1;
|
||||
c1 = c2;
|
||||
}
|
||||
|
||||
/** in_out = in_out^(2^sq) * mul */
|
||||
inline void square_n_mul(Num3072& in_out, const int sq, const Num3072& mul)
|
||||
{
|
||||
for (int j = 0; j < sq; ++j) in_out.Square();
|
||||
in_out.Multiply(mul);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/** Indicates whether d is larger than the modulus. */
|
||||
bool Num3072::IsOverflow() const
|
||||
{
|
||||
if (this->limbs[0] <= std::numeric_limits<limb_t>::max() - MAX_PRIME_DIFF) return false;
|
||||
for (int i = 1; i < LIMBS; ++i) {
|
||||
if (this->limbs[i] != std::numeric_limits<limb_t>::max()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Num3072::FullReduce()
|
||||
{
|
||||
limb_t c0 = MAX_PRIME_DIFF;
|
||||
limb_t c1 = 0;
|
||||
for (int i = 0; i < LIMBS; ++i) {
|
||||
addnextract2(c0, c1, this->limbs[i], this->limbs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Num3072 Num3072::GetInverse() const
|
||||
{
|
||||
// For fast exponentiation a sliding window exponentiation with repunit
|
||||
// precomputation is utilized. See "Fast Point Decompression for Standard
|
||||
// Elliptic Curves" (Brumley, Järvinen, 2008).
|
||||
|
||||
Num3072 p[12]; // p[i] = a^(2^(2^i)-1)
|
||||
Num3072 out;
|
||||
|
||||
p[0] = *this;
|
||||
|
||||
for (int i = 0; i < 11; ++i) {
|
||||
p[i + 1] = p[i];
|
||||
for (int j = 0; j < (1 << i); ++j) p[i + 1].Square();
|
||||
p[i + 1].Multiply(p[i]);
|
||||
}
|
||||
|
||||
out = p[11];
|
||||
|
||||
square_n_mul(out, 512, p[9]);
|
||||
square_n_mul(out, 256, p[8]);
|
||||
square_n_mul(out, 128, p[7]);
|
||||
square_n_mul(out, 64, p[6]);
|
||||
square_n_mul(out, 32, p[5]);
|
||||
square_n_mul(out, 8, p[3]);
|
||||
square_n_mul(out, 2, p[1]);
|
||||
square_n_mul(out, 1, p[0]);
|
||||
square_n_mul(out, 5, p[2]);
|
||||
square_n_mul(out, 3, p[0]);
|
||||
square_n_mul(out, 2, p[0]);
|
||||
square_n_mul(out, 4, p[0]);
|
||||
square_n_mul(out, 4, p[1]);
|
||||
square_n_mul(out, 3, p[0]);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void Num3072::Multiply(const Num3072& a)
|
||||
{
|
||||
limb_t c0 = 0, c1 = 0, c2 = 0;
|
||||
Num3072 tmp;
|
||||
|
||||
/* Compute limbs 0..N-2 of this*a into tmp, including one reduction. */
|
||||
for (int j = 0; j < LIMBS - 1; ++j) {
|
||||
limb_t d0 = 0, d1 = 0, d2 = 0;
|
||||
mul(d0, d1, this->limbs[1 + j], a.limbs[LIMBS + j - (1 + j)]);
|
||||
for (int i = 2 + j; i < LIMBS; ++i) muladd3(d0, d1, d2, this->limbs[i], a.limbs[LIMBS + j - i]);
|
||||
mulnadd3(c0, c1, c2, d0, d1, d2, MAX_PRIME_DIFF);
|
||||
for (int i = 0; i < j + 1; ++i) muladd3(c0, c1, c2, this->limbs[i], a.limbs[j - i]);
|
||||
extract3(c0, c1, c2, tmp.limbs[j]);
|
||||
}
|
||||
|
||||
/* Compute limb N-1 of a*b into tmp. */
|
||||
assert(c2 == 0);
|
||||
for (int i = 0; i < LIMBS; ++i) muladd3(c0, c1, c2, this->limbs[i], a.limbs[LIMBS - 1 - i]);
|
||||
extract3(c0, c1, c2, tmp.limbs[LIMBS - 1]);
|
||||
|
||||
/* Perform a second reduction. */
|
||||
muln2(c0, c1, MAX_PRIME_DIFF);
|
||||
for (int j = 0; j < LIMBS; ++j) {
|
||||
addnextract2(c0, c1, tmp.limbs[j], this->limbs[j]);
|
||||
}
|
||||
|
||||
assert(c1 == 0);
|
||||
assert(c0 == 0 || c0 == 1);
|
||||
|
||||
/* Perform up to two more reductions if the internal state has already
|
||||
* overflown the MAX of Num3072 or if it is larger than the modulus or
|
||||
* if both are the case.
|
||||
* */
|
||||
if (this->IsOverflow()) this->FullReduce();
|
||||
if (c0) this->FullReduce();
|
||||
}
|
||||
|
||||
void Num3072::Square()
|
||||
{
|
||||
limb_t c0 = 0, c1 = 0, c2 = 0;
|
||||
Num3072 tmp;
|
||||
|
||||
/* Compute limbs 0..N-2 of this*this into tmp, including one reduction. */
|
||||
for (int j = 0; j < LIMBS - 1; ++j) {
|
||||
limb_t d0 = 0, d1 = 0, d2 = 0;
|
||||
for (int i = 0; i < (LIMBS - 1 - j) / 2; ++i) muldbladd3(d0, d1, d2, this->limbs[i + j + 1], this->limbs[LIMBS - 1 - i]);
|
||||
if ((j + 1) & 1) muladd3(d0, d1, d2, this->limbs[(LIMBS - 1 - j) / 2 + j + 1], this->limbs[LIMBS - 1 - (LIMBS - 1 - j) / 2]);
|
||||
mulnadd3(c0, c1, c2, d0, d1, d2, MAX_PRIME_DIFF);
|
||||
for (int i = 0; i < (j + 1) / 2; ++i) muldbladd3(c0, c1, c2, this->limbs[i], this->limbs[j - i]);
|
||||
if ((j + 1) & 1) muladd3(c0, c1, c2, this->limbs[(j + 1) / 2], this->limbs[j - (j + 1) / 2]);
|
||||
extract3(c0, c1, c2, tmp.limbs[j]);
|
||||
}
|
||||
|
||||
assert(c2 == 0);
|
||||
for (int i = 0; i < LIMBS / 2; ++i) muldbladd3(c0, c1, c2, this->limbs[i], this->limbs[LIMBS - 1 - i]);
|
||||
extract3(c0, c1, c2, tmp.limbs[LIMBS - 1]);
|
||||
|
||||
/* Perform a second reduction. */
|
||||
muln2(c0, c1, MAX_PRIME_DIFF);
|
||||
for (int j = 0; j < LIMBS; ++j) {
|
||||
addnextract2(c0, c1, tmp.limbs[j], this->limbs[j]);
|
||||
}
|
||||
|
||||
assert(c1 == 0);
|
||||
assert(c0 == 0 || c0 == 1);
|
||||
|
||||
/* Perform up to two more reductions if the internal state has already
|
||||
* overflown the MAX of Num3072 or if it is larger than the modulus or
|
||||
* if both are the case.
|
||||
* */
|
||||
if (this->IsOverflow()) this->FullReduce();
|
||||
if (c0) this->FullReduce();
|
||||
}
|
||||
|
||||
void Num3072::SetToOne()
|
||||
{
|
||||
this->limbs[0] = 1;
|
||||
for (int i = 1; i < LIMBS; ++i) this->limbs[i] = 0;
|
||||
}
|
||||
|
||||
void Num3072::Divide(const Num3072& a)
|
||||
{
|
||||
if (this->IsOverflow()) this->FullReduce();
|
||||
|
||||
Num3072 inv{};
|
||||
if (a.IsOverflow()) {
|
||||
Num3072 b = a;
|
||||
b.FullReduce();
|
||||
inv = b.GetInverse();
|
||||
} else {
|
||||
inv = a.GetInverse();
|
||||
}
|
||||
|
||||
this->Multiply(inv);
|
||||
if (this->IsOverflow()) this->FullReduce();
|
||||
}
|
||||
|
||||
Num3072::Num3072(const unsigned char (&data)[BYTE_SIZE]) {
|
||||
for (int i = 0; i < LIMBS; ++i) {
|
||||
if (sizeof(limb_t) == 4) {
|
||||
this->limbs[i] = ReadLE32(data + 4 * i);
|
||||
} else if (sizeof(limb_t) == 8) {
|
||||
this->limbs[i] = ReadLE64(data + 8 * i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Num3072::ToBytes(unsigned char (&out)[BYTE_SIZE]) {
|
||||
for (int i = 0; i < LIMBS; ++i) {
|
||||
if (sizeof(limb_t) == 4) {
|
||||
WriteLE32(out + i * 4, this->limbs[i]);
|
||||
} else if (sizeof(limb_t) == 8) {
|
||||
WriteLE64(out + i * 8, this->limbs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Num3072 MuHash3072::ToNum3072(Span<const unsigned char> in) {
|
||||
unsigned char tmp[Num3072::BYTE_SIZE];
|
||||
|
||||
uint256 hashed_in = (CHashWriter(SER_DISK, 0) << in).GetSHA256();
|
||||
ChaCha20(hashed_in.data(), hashed_in.size()).Keystream(tmp, Num3072::BYTE_SIZE);
|
||||
Num3072 out{tmp};
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
MuHash3072::MuHash3072(Span<const unsigned char> in) noexcept
|
||||
{
|
||||
m_numerator = ToNum3072(in);
|
||||
}
|
||||
|
||||
void MuHash3072::Finalize(uint256& out) noexcept
|
||||
{
|
||||
m_numerator.Divide(m_denominator);
|
||||
m_denominator.SetToOne(); // Needed to keep the MuHash object valid
|
||||
|
||||
unsigned char data[Num3072::BYTE_SIZE];
|
||||
m_numerator.ToBytes(data);
|
||||
|
||||
out = (CHashWriter(SER_DISK, 0) << data).GetSHA256();
|
||||
}
|
||||
|
||||
MuHash3072& MuHash3072::operator*=(const MuHash3072& mul) noexcept
|
||||
{
|
||||
m_numerator.Multiply(mul.m_numerator);
|
||||
m_denominator.Multiply(mul.m_denominator);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MuHash3072& MuHash3072::operator/=(const MuHash3072& div) noexcept
|
||||
{
|
||||
m_numerator.Multiply(div.m_denominator);
|
||||
m_denominator.Multiply(div.m_numerator);
|
||||
return *this;
|
||||
}
|
||||
|
||||
MuHash3072& MuHash3072::Insert(Span<const unsigned char> in) noexcept {
|
||||
m_numerator.Multiply(ToNum3072(in));
|
||||
return *this;
|
||||
}
|
||||
|
||||
MuHash3072& MuHash3072::Remove(Span<const unsigned char> in) noexcept {
|
||||
m_denominator.Multiply(ToNum3072(in));
|
||||
return *this;
|
||||
}
|
||||
131
src/crypto/muhash.h
Normal file
131
src/crypto/muhash.h
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
// Copyright (c) 2017-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef DIGIBYTE_CRYPTO_MUHASH_H
|
||||
#define DIGIBYTE_CRYPTO_MUHASH_H
|
||||
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include <config/vexta-config.h>
|
||||
#endif
|
||||
|
||||
#include <serialize.h>
|
||||
#include <uint256.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class Num3072
|
||||
{
|
||||
private:
|
||||
void FullReduce();
|
||||
bool IsOverflow() const;
|
||||
Num3072 GetInverse() const;
|
||||
|
||||
public:
|
||||
static constexpr size_t BYTE_SIZE = 384;
|
||||
|
||||
#ifdef HAVE___INT128
|
||||
typedef unsigned __int128 double_limb_t;
|
||||
typedef uint64_t limb_t;
|
||||
static constexpr int LIMBS = 48;
|
||||
static constexpr int LIMB_SIZE = 64;
|
||||
#else
|
||||
typedef uint64_t double_limb_t;
|
||||
typedef uint32_t limb_t;
|
||||
static constexpr int LIMBS = 96;
|
||||
static constexpr int LIMB_SIZE = 32;
|
||||
#endif
|
||||
limb_t limbs[LIMBS];
|
||||
|
||||
// Sanity check for Num3072 constants
|
||||
static_assert(LIMB_SIZE * LIMBS == 3072, "Num3072 isn't 3072 bits");
|
||||
static_assert(sizeof(double_limb_t) == sizeof(limb_t) * 2, "bad size for double_limb_t");
|
||||
static_assert(sizeof(limb_t) * 8 == LIMB_SIZE, "LIMB_SIZE is incorrect");
|
||||
|
||||
// Hard coded values in MuHash3072 constructor and Finalize
|
||||
static_assert(sizeof(limb_t) == 4 || sizeof(limb_t) == 8, "bad size for limb_t");
|
||||
|
||||
void Multiply(const Num3072& a);
|
||||
void Divide(const Num3072& a);
|
||||
void SetToOne();
|
||||
void Square();
|
||||
void ToBytes(unsigned char (&out)[BYTE_SIZE]);
|
||||
|
||||
Num3072() { this->SetToOne(); };
|
||||
Num3072(const unsigned char (&data)[BYTE_SIZE]);
|
||||
|
||||
SERIALIZE_METHODS(Num3072, obj)
|
||||
{
|
||||
for (auto& limb : obj.limbs) {
|
||||
READWRITE(limb);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** A class representing MuHash sets
|
||||
*
|
||||
* MuHash is a hashing algorithm that supports adding set elements in any
|
||||
* order but also deleting in any order. As a result, it can maintain a
|
||||
* running sum for a set of data as a whole, and add/remove when data
|
||||
* is added to or removed from it. A downside of MuHash is that computing
|
||||
* an inverse is relatively expensive. This is solved by representing
|
||||
* the running value as a fraction, and multiplying added elements into
|
||||
* the numerator and removed elements into the denominator. Only when the
|
||||
* final hash is desired, a single modular inverse and multiplication is
|
||||
* needed to combine the two. The combination is also run on serialization
|
||||
* to allow for space-efficient storage on disk.
|
||||
*
|
||||
* As the update operations are also associative, H(a)+H(b)+H(c)+H(d) can
|
||||
* in fact be computed as (H(a)+H(b)) + (H(c)+H(d)). This implies that
|
||||
* all of this is perfectly parallellizable: each thread can process an
|
||||
* arbitrary subset of the update operations, allowing them to be
|
||||
* efficiently combined later.
|
||||
*
|
||||
* MuHash does not support checking if an element is already part of the
|
||||
* set. That is why this class does not enforce the use of a set as the
|
||||
* data it represents because there is no efficient way to do so.
|
||||
* It is possible to add elements more than once and also to remove
|
||||
* elements that have not been added before. However, this implementation
|
||||
* is intended to represent a set of elements.
|
||||
*
|
||||
* See also https://cseweb.ucsd.edu/~mihir/papers/inchash.pdf and
|
||||
* https://lists.linuxfoundation.org/pipermail/digibyte-dev/2017-May/014337.html.
|
||||
*/
|
||||
class MuHash3072
|
||||
{
|
||||
private:
|
||||
Num3072 m_numerator;
|
||||
Num3072 m_denominator;
|
||||
|
||||
Num3072 ToNum3072(Span<const unsigned char> in);
|
||||
|
||||
public:
|
||||
/* The empty set. */
|
||||
MuHash3072() noexcept {};
|
||||
|
||||
/* A singleton with variable sized data in it. */
|
||||
explicit MuHash3072(Span<const unsigned char> in) noexcept;
|
||||
|
||||
/* Insert a single piece of data into the set. */
|
||||
MuHash3072& Insert(Span<const unsigned char> in) noexcept;
|
||||
|
||||
/* Remove a single piece of data from the set. */
|
||||
MuHash3072& Remove(Span<const unsigned char> in) noexcept;
|
||||
|
||||
/* Multiply (resulting in a hash for the union of the sets) */
|
||||
MuHash3072& operator*=(const MuHash3072& mul) noexcept;
|
||||
|
||||
/* Divide (resulting in a hash for the difference of the sets) */
|
||||
MuHash3072& operator/=(const MuHash3072& div) noexcept;
|
||||
|
||||
/* Finalize into a 32-byte hash. Does not change this object's value. */
|
||||
void Finalize(uint256& out) noexcept;
|
||||
|
||||
SERIALIZE_METHODS(MuHash3072, obj)
|
||||
{
|
||||
READWRITE(obj.m_numerator);
|
||||
READWRITE(obj.m_denominator);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_MUHASH_H
|
||||
141
src/crypto/poly1305.cpp
Normal file
141
src/crypto/poly1305.cpp
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
// Copyright (c) 2019 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
// Based on the public domain implementation by Andrew Moon
|
||||
// poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
|
||||
|
||||
#include <crypto/common.h>
|
||||
#include <crypto/poly1305.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define mul32x32_64(a,b) ((uint64_t)(a) * (b))
|
||||
|
||||
void poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) {
|
||||
uint32_t t0,t1,t2,t3;
|
||||
uint32_t h0,h1,h2,h3,h4;
|
||||
uint32_t r0,r1,r2,r3,r4;
|
||||
uint32_t s1,s2,s3,s4;
|
||||
uint32_t b, nb;
|
||||
size_t j;
|
||||
uint64_t t[5];
|
||||
uint64_t f0,f1,f2,f3;
|
||||
uint64_t g0,g1,g2,g3,g4;
|
||||
uint64_t c;
|
||||
unsigned char mp[16];
|
||||
|
||||
/* clamp key */
|
||||
t0 = ReadLE32(key+0);
|
||||
t1 = ReadLE32(key+4);
|
||||
t2 = ReadLE32(key+8);
|
||||
t3 = ReadLE32(key+12);
|
||||
|
||||
/* precompute multipliers */
|
||||
r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6;
|
||||
r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12;
|
||||
r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18;
|
||||
r3 = t2 & 0x3f03fff; t3 >>= 8;
|
||||
r4 = t3 & 0x00fffff;
|
||||
|
||||
s1 = r1 * 5;
|
||||
s2 = r2 * 5;
|
||||
s3 = r3 * 5;
|
||||
s4 = r4 * 5;
|
||||
|
||||
/* init state */
|
||||
h0 = 0;
|
||||
h1 = 0;
|
||||
h2 = 0;
|
||||
h3 = 0;
|
||||
h4 = 0;
|
||||
|
||||
/* full blocks */
|
||||
if (inlen < 16) goto poly1305_donna_atmost15bytes;
|
||||
poly1305_donna_16bytes:
|
||||
m += 16;
|
||||
inlen -= 16;
|
||||
|
||||
t0 = ReadLE32(m-16);
|
||||
t1 = ReadLE32(m-12);
|
||||
t2 = ReadLE32(m-8);
|
||||
t3 = ReadLE32(m-4);
|
||||
|
||||
h0 += t0 & 0x3ffffff;
|
||||
h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
|
||||
h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
|
||||
h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
|
||||
h4 += (t3 >> 8) | (1 << 24);
|
||||
|
||||
|
||||
poly1305_donna_mul:
|
||||
t[0] = mul32x32_64(h0,r0) + mul32x32_64(h1,s4) + mul32x32_64(h2,s3) + mul32x32_64(h3,s2) + mul32x32_64(h4,s1);
|
||||
t[1] = mul32x32_64(h0,r1) + mul32x32_64(h1,r0) + mul32x32_64(h2,s4) + mul32x32_64(h3,s3) + mul32x32_64(h4,s2);
|
||||
t[2] = mul32x32_64(h0,r2) + mul32x32_64(h1,r1) + mul32x32_64(h2,r0) + mul32x32_64(h3,s4) + mul32x32_64(h4,s3);
|
||||
t[3] = mul32x32_64(h0,r3) + mul32x32_64(h1,r2) + mul32x32_64(h2,r1) + mul32x32_64(h3,r0) + mul32x32_64(h4,s4);
|
||||
t[4] = mul32x32_64(h0,r4) + mul32x32_64(h1,r3) + mul32x32_64(h2,r2) + mul32x32_64(h3,r1) + mul32x32_64(h4,r0);
|
||||
|
||||
h0 = (uint32_t)t[0] & 0x3ffffff; c = (t[0] >> 26);
|
||||
t[1] += c; h1 = (uint32_t)t[1] & 0x3ffffff; b = (uint32_t)(t[1] >> 26);
|
||||
t[2] += b; h2 = (uint32_t)t[2] & 0x3ffffff; b = (uint32_t)(t[2] >> 26);
|
||||
t[3] += b; h3 = (uint32_t)t[3] & 0x3ffffff; b = (uint32_t)(t[3] >> 26);
|
||||
t[4] += b; h4 = (uint32_t)t[4] & 0x3ffffff; b = (uint32_t)(t[4] >> 26);
|
||||
h0 += b * 5;
|
||||
|
||||
if (inlen >= 16) goto poly1305_donna_16bytes;
|
||||
|
||||
/* final bytes */
|
||||
poly1305_donna_atmost15bytes:
|
||||
if (!inlen) goto poly1305_donna_finish;
|
||||
|
||||
for (j = 0; j < inlen; j++) mp[j] = m[j];
|
||||
mp[j++] = 1;
|
||||
for (; j < 16; j++) mp[j] = 0;
|
||||
inlen = 0;
|
||||
|
||||
t0 = ReadLE32(mp+0);
|
||||
t1 = ReadLE32(mp+4);
|
||||
t2 = ReadLE32(mp+8);
|
||||
t3 = ReadLE32(mp+12);
|
||||
|
||||
h0 += t0 & 0x3ffffff;
|
||||
h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
|
||||
h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
|
||||
h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
|
||||
h4 += (t3 >> 8);
|
||||
|
||||
goto poly1305_donna_mul;
|
||||
|
||||
poly1305_donna_finish:
|
||||
b = h0 >> 26; h0 = h0 & 0x3ffffff;
|
||||
h1 += b; b = h1 >> 26; h1 = h1 & 0x3ffffff;
|
||||
h2 += b; b = h2 >> 26; h2 = h2 & 0x3ffffff;
|
||||
h3 += b; b = h3 >> 26; h3 = h3 & 0x3ffffff;
|
||||
h4 += b; b = h4 >> 26; h4 = h4 & 0x3ffffff;
|
||||
h0 += b * 5; b = h0 >> 26; h0 = h0 & 0x3ffffff;
|
||||
h1 += b;
|
||||
|
||||
g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff;
|
||||
g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff;
|
||||
g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff;
|
||||
g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff;
|
||||
g4 = h4 + b - (1 << 26);
|
||||
|
||||
b = (g4 >> 31) - 1;
|
||||
nb = ~b;
|
||||
h0 = (h0 & nb) | (g0 & b);
|
||||
h1 = (h1 & nb) | (g1 & b);
|
||||
h2 = (h2 & nb) | (g2 & b);
|
||||
h3 = (h3 & nb) | (g3 & b);
|
||||
h4 = (h4 & nb) | (g4 & b);
|
||||
|
||||
f0 = ((h0 ) | (h1 << 26)) + (uint64_t)ReadLE32(&key[16]);
|
||||
f1 = ((h1 >> 6) | (h2 << 20)) + (uint64_t)ReadLE32(&key[20]);
|
||||
f2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t)ReadLE32(&key[24]);
|
||||
f3 = ((h3 >> 18) | (h4 << 8)) + (uint64_t)ReadLE32(&key[28]);
|
||||
|
||||
WriteLE32(&out[ 0], f0); f1 += (f0 >> 32);
|
||||
WriteLE32(&out[ 4], f1); f2 += (f1 >> 32);
|
||||
WriteLE32(&out[ 8], f2); f3 += (f2 >> 32);
|
||||
WriteLE32(&out[12], f3);
|
||||
}
|
||||
17
src/crypto/poly1305.h
Normal file
17
src/crypto/poly1305.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) 2019 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef DIGIBYTE_CRYPTO_POLY1305_H
|
||||
#define DIGIBYTE_CRYPTO_POLY1305_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define POLY1305_KEYLEN 32
|
||||
#define POLY1305_TAGLEN 16
|
||||
|
||||
void poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen,
|
||||
const unsigned char key[POLY1305_KEYLEN]);
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_POLY1305_H
|
||||
293
src/crypto/ripemd160.cpp
Normal file
293
src/crypto/ripemd160.cpp
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <crypto/ripemd160.h>
|
||||
|
||||
#include <crypto/common.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// Internal implementation code.
|
||||
namespace
|
||||
{
|
||||
/// Internal RIPEMD-160 implementation.
|
||||
namespace ripemd160
|
||||
{
|
||||
uint32_t inline f1(uint32_t x, uint32_t y, uint32_t z) { return x ^ y ^ z; }
|
||||
uint32_t inline f2(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (~x & z); }
|
||||
uint32_t inline f3(uint32_t x, uint32_t y, uint32_t z) { return (x | ~y) ^ z; }
|
||||
uint32_t inline f4(uint32_t x, uint32_t y, uint32_t z) { return (x & z) | (y & ~z); }
|
||||
uint32_t inline f5(uint32_t x, uint32_t y, uint32_t z) { return x ^ (y | ~z); }
|
||||
|
||||
/** Initialize RIPEMD-160 state. */
|
||||
void inline Initialize(uint32_t* s)
|
||||
{
|
||||
s[0] = 0x67452301ul;
|
||||
s[1] = 0xEFCDAB89ul;
|
||||
s[2] = 0x98BADCFEul;
|
||||
s[3] = 0x10325476ul;
|
||||
s[4] = 0xC3D2E1F0ul;
|
||||
}
|
||||
|
||||
uint32_t inline rol(uint32_t x, int i) { return (x << i) | (x >> (32 - i)); }
|
||||
|
||||
void inline Round(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t f, uint32_t x, uint32_t k, int r)
|
||||
{
|
||||
a = rol(a + f + x + k, r) + e;
|
||||
c = rol(c, 10);
|
||||
}
|
||||
|
||||
void inline R11(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); }
|
||||
void inline R21(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x5A827999ul, r); }
|
||||
void inline R31(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6ED9EBA1ul, r); }
|
||||
void inline R41(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x8F1BBCDCul, r); }
|
||||
void inline R51(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0xA953FD4Eul, r); }
|
||||
|
||||
void inline R12(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, c, d), x, 0x50A28BE6ul, r); }
|
||||
void inline R22(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, c, d), x, 0x5C4DD124ul, r); }
|
||||
void inline R32(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, c, d), x, 0x6D703EF3ul, r); }
|
||||
void inline R42(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, c, d), x, 0x7A6D76E9ul, r); }
|
||||
void inline R52(uint32_t& a, uint32_t b, uint32_t& c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, c, d), x, 0, r); }
|
||||
|
||||
/** Perform a RIPEMD-160 transformation, processing a 64-byte chunk. */
|
||||
void Transform(uint32_t* s, const unsigned char* chunk)
|
||||
{
|
||||
uint32_t a1 = s[0], b1 = s[1], c1 = s[2], d1 = s[3], e1 = s[4];
|
||||
uint32_t a2 = a1, b2 = b1, c2 = c1, d2 = d1, e2 = e1;
|
||||
uint32_t w0 = ReadLE32(chunk + 0), w1 = ReadLE32(chunk + 4), w2 = ReadLE32(chunk + 8), w3 = ReadLE32(chunk + 12);
|
||||
uint32_t w4 = ReadLE32(chunk + 16), w5 = ReadLE32(chunk + 20), w6 = ReadLE32(chunk + 24), w7 = ReadLE32(chunk + 28);
|
||||
uint32_t w8 = ReadLE32(chunk + 32), w9 = ReadLE32(chunk + 36), w10 = ReadLE32(chunk + 40), w11 = ReadLE32(chunk + 44);
|
||||
uint32_t w12 = ReadLE32(chunk + 48), w13 = ReadLE32(chunk + 52), w14 = ReadLE32(chunk + 56), w15 = ReadLE32(chunk + 60);
|
||||
|
||||
R11(a1, b1, c1, d1, e1, w0, 11);
|
||||
R12(a2, b2, c2, d2, e2, w5, 8);
|
||||
R11(e1, a1, b1, c1, d1, w1, 14);
|
||||
R12(e2, a2, b2, c2, d2, w14, 9);
|
||||
R11(d1, e1, a1, b1, c1, w2, 15);
|
||||
R12(d2, e2, a2, b2, c2, w7, 9);
|
||||
R11(c1, d1, e1, a1, b1, w3, 12);
|
||||
R12(c2, d2, e2, a2, b2, w0, 11);
|
||||
R11(b1, c1, d1, e1, a1, w4, 5);
|
||||
R12(b2, c2, d2, e2, a2, w9, 13);
|
||||
R11(a1, b1, c1, d1, e1, w5, 8);
|
||||
R12(a2, b2, c2, d2, e2, w2, 15);
|
||||
R11(e1, a1, b1, c1, d1, w6, 7);
|
||||
R12(e2, a2, b2, c2, d2, w11, 15);
|
||||
R11(d1, e1, a1, b1, c1, w7, 9);
|
||||
R12(d2, e2, a2, b2, c2, w4, 5);
|
||||
R11(c1, d1, e1, a1, b1, w8, 11);
|
||||
R12(c2, d2, e2, a2, b2, w13, 7);
|
||||
R11(b1, c1, d1, e1, a1, w9, 13);
|
||||
R12(b2, c2, d2, e2, a2, w6, 7);
|
||||
R11(a1, b1, c1, d1, e1, w10, 14);
|
||||
R12(a2, b2, c2, d2, e2, w15, 8);
|
||||
R11(e1, a1, b1, c1, d1, w11, 15);
|
||||
R12(e2, a2, b2, c2, d2, w8, 11);
|
||||
R11(d1, e1, a1, b1, c1, w12, 6);
|
||||
R12(d2, e2, a2, b2, c2, w1, 14);
|
||||
R11(c1, d1, e1, a1, b1, w13, 7);
|
||||
R12(c2, d2, e2, a2, b2, w10, 14);
|
||||
R11(b1, c1, d1, e1, a1, w14, 9);
|
||||
R12(b2, c2, d2, e2, a2, w3, 12);
|
||||
R11(a1, b1, c1, d1, e1, w15, 8);
|
||||
R12(a2, b2, c2, d2, e2, w12, 6);
|
||||
|
||||
R21(e1, a1, b1, c1, d1, w7, 7);
|
||||
R22(e2, a2, b2, c2, d2, w6, 9);
|
||||
R21(d1, e1, a1, b1, c1, w4, 6);
|
||||
R22(d2, e2, a2, b2, c2, w11, 13);
|
||||
R21(c1, d1, e1, a1, b1, w13, 8);
|
||||
R22(c2, d2, e2, a2, b2, w3, 15);
|
||||
R21(b1, c1, d1, e1, a1, w1, 13);
|
||||
R22(b2, c2, d2, e2, a2, w7, 7);
|
||||
R21(a1, b1, c1, d1, e1, w10, 11);
|
||||
R22(a2, b2, c2, d2, e2, w0, 12);
|
||||
R21(e1, a1, b1, c1, d1, w6, 9);
|
||||
R22(e2, a2, b2, c2, d2, w13, 8);
|
||||
R21(d1, e1, a1, b1, c1, w15, 7);
|
||||
R22(d2, e2, a2, b2, c2, w5, 9);
|
||||
R21(c1, d1, e1, a1, b1, w3, 15);
|
||||
R22(c2, d2, e2, a2, b2, w10, 11);
|
||||
R21(b1, c1, d1, e1, a1, w12, 7);
|
||||
R22(b2, c2, d2, e2, a2, w14, 7);
|
||||
R21(a1, b1, c1, d1, e1, w0, 12);
|
||||
R22(a2, b2, c2, d2, e2, w15, 7);
|
||||
R21(e1, a1, b1, c1, d1, w9, 15);
|
||||
R22(e2, a2, b2, c2, d2, w8, 12);
|
||||
R21(d1, e1, a1, b1, c1, w5, 9);
|
||||
R22(d2, e2, a2, b2, c2, w12, 7);
|
||||
R21(c1, d1, e1, a1, b1, w2, 11);
|
||||
R22(c2, d2, e2, a2, b2, w4, 6);
|
||||
R21(b1, c1, d1, e1, a1, w14, 7);
|
||||
R22(b2, c2, d2, e2, a2, w9, 15);
|
||||
R21(a1, b1, c1, d1, e1, w11, 13);
|
||||
R22(a2, b2, c2, d2, e2, w1, 13);
|
||||
R21(e1, a1, b1, c1, d1, w8, 12);
|
||||
R22(e2, a2, b2, c2, d2, w2, 11);
|
||||
|
||||
R31(d1, e1, a1, b1, c1, w3, 11);
|
||||
R32(d2, e2, a2, b2, c2, w15, 9);
|
||||
R31(c1, d1, e1, a1, b1, w10, 13);
|
||||
R32(c2, d2, e2, a2, b2, w5, 7);
|
||||
R31(b1, c1, d1, e1, a1, w14, 6);
|
||||
R32(b2, c2, d2, e2, a2, w1, 15);
|
||||
R31(a1, b1, c1, d1, e1, w4, 7);
|
||||
R32(a2, b2, c2, d2, e2, w3, 11);
|
||||
R31(e1, a1, b1, c1, d1, w9, 14);
|
||||
R32(e2, a2, b2, c2, d2, w7, 8);
|
||||
R31(d1, e1, a1, b1, c1, w15, 9);
|
||||
R32(d2, e2, a2, b2, c2, w14, 6);
|
||||
R31(c1, d1, e1, a1, b1, w8, 13);
|
||||
R32(c2, d2, e2, a2, b2, w6, 6);
|
||||
R31(b1, c1, d1, e1, a1, w1, 15);
|
||||
R32(b2, c2, d2, e2, a2, w9, 14);
|
||||
R31(a1, b1, c1, d1, e1, w2, 14);
|
||||
R32(a2, b2, c2, d2, e2, w11, 12);
|
||||
R31(e1, a1, b1, c1, d1, w7, 8);
|
||||
R32(e2, a2, b2, c2, d2, w8, 13);
|
||||
R31(d1, e1, a1, b1, c1, w0, 13);
|
||||
R32(d2, e2, a2, b2, c2, w12, 5);
|
||||
R31(c1, d1, e1, a1, b1, w6, 6);
|
||||
R32(c2, d2, e2, a2, b2, w2, 14);
|
||||
R31(b1, c1, d1, e1, a1, w13, 5);
|
||||
R32(b2, c2, d2, e2, a2, w10, 13);
|
||||
R31(a1, b1, c1, d1, e1, w11, 12);
|
||||
R32(a2, b2, c2, d2, e2, w0, 13);
|
||||
R31(e1, a1, b1, c1, d1, w5, 7);
|
||||
R32(e2, a2, b2, c2, d2, w4, 7);
|
||||
R31(d1, e1, a1, b1, c1, w12, 5);
|
||||
R32(d2, e2, a2, b2, c2, w13, 5);
|
||||
|
||||
R41(c1, d1, e1, a1, b1, w1, 11);
|
||||
R42(c2, d2, e2, a2, b2, w8, 15);
|
||||
R41(b1, c1, d1, e1, a1, w9, 12);
|
||||
R42(b2, c2, d2, e2, a2, w6, 5);
|
||||
R41(a1, b1, c1, d1, e1, w11, 14);
|
||||
R42(a2, b2, c2, d2, e2, w4, 8);
|
||||
R41(e1, a1, b1, c1, d1, w10, 15);
|
||||
R42(e2, a2, b2, c2, d2, w1, 11);
|
||||
R41(d1, e1, a1, b1, c1, w0, 14);
|
||||
R42(d2, e2, a2, b2, c2, w3, 14);
|
||||
R41(c1, d1, e1, a1, b1, w8, 15);
|
||||
R42(c2, d2, e2, a2, b2, w11, 14);
|
||||
R41(b1, c1, d1, e1, a1, w12, 9);
|
||||
R42(b2, c2, d2, e2, a2, w15, 6);
|
||||
R41(a1, b1, c1, d1, e1, w4, 8);
|
||||
R42(a2, b2, c2, d2, e2, w0, 14);
|
||||
R41(e1, a1, b1, c1, d1, w13, 9);
|
||||
R42(e2, a2, b2, c2, d2, w5, 6);
|
||||
R41(d1, e1, a1, b1, c1, w3, 14);
|
||||
R42(d2, e2, a2, b2, c2, w12, 9);
|
||||
R41(c1, d1, e1, a1, b1, w7, 5);
|
||||
R42(c2, d2, e2, a2, b2, w2, 12);
|
||||
R41(b1, c1, d1, e1, a1, w15, 6);
|
||||
R42(b2, c2, d2, e2, a2, w13, 9);
|
||||
R41(a1, b1, c1, d1, e1, w14, 8);
|
||||
R42(a2, b2, c2, d2, e2, w9, 12);
|
||||
R41(e1, a1, b1, c1, d1, w5, 6);
|
||||
R42(e2, a2, b2, c2, d2, w7, 5);
|
||||
R41(d1, e1, a1, b1, c1, w6, 5);
|
||||
R42(d2, e2, a2, b2, c2, w10, 15);
|
||||
R41(c1, d1, e1, a1, b1, w2, 12);
|
||||
R42(c2, d2, e2, a2, b2, w14, 8);
|
||||
|
||||
R51(b1, c1, d1, e1, a1, w4, 9);
|
||||
R52(b2, c2, d2, e2, a2, w12, 8);
|
||||
R51(a1, b1, c1, d1, e1, w0, 15);
|
||||
R52(a2, b2, c2, d2, e2, w15, 5);
|
||||
R51(e1, a1, b1, c1, d1, w5, 5);
|
||||
R52(e2, a2, b2, c2, d2, w10, 12);
|
||||
R51(d1, e1, a1, b1, c1, w9, 11);
|
||||
R52(d2, e2, a2, b2, c2, w4, 9);
|
||||
R51(c1, d1, e1, a1, b1, w7, 6);
|
||||
R52(c2, d2, e2, a2, b2, w1, 12);
|
||||
R51(b1, c1, d1, e1, a1, w12, 8);
|
||||
R52(b2, c2, d2, e2, a2, w5, 5);
|
||||
R51(a1, b1, c1, d1, e1, w2, 13);
|
||||
R52(a2, b2, c2, d2, e2, w8, 14);
|
||||
R51(e1, a1, b1, c1, d1, w10, 12);
|
||||
R52(e2, a2, b2, c2, d2, w7, 6);
|
||||
R51(d1, e1, a1, b1, c1, w14, 5);
|
||||
R52(d2, e2, a2, b2, c2, w6, 8);
|
||||
R51(c1, d1, e1, a1, b1, w1, 12);
|
||||
R52(c2, d2, e2, a2, b2, w2, 13);
|
||||
R51(b1, c1, d1, e1, a1, w3, 13);
|
||||
R52(b2, c2, d2, e2, a2, w13, 6);
|
||||
R51(a1, b1, c1, d1, e1, w8, 14);
|
||||
R52(a2, b2, c2, d2, e2, w14, 5);
|
||||
R51(e1, a1, b1, c1, d1, w11, 11);
|
||||
R52(e2, a2, b2, c2, d2, w0, 15);
|
||||
R51(d1, e1, a1, b1, c1, w6, 8);
|
||||
R52(d2, e2, a2, b2, c2, w3, 13);
|
||||
R51(c1, d1, e1, a1, b1, w15, 5);
|
||||
R52(c2, d2, e2, a2, b2, w9, 11);
|
||||
R51(b1, c1, d1, e1, a1, w13, 6);
|
||||
R52(b2, c2, d2, e2, a2, w11, 11);
|
||||
|
||||
uint32_t t = s[0];
|
||||
s[0] = s[1] + c1 + d2;
|
||||
s[1] = s[2] + d1 + e2;
|
||||
s[2] = s[3] + e1 + a2;
|
||||
s[3] = s[4] + a1 + b2;
|
||||
s[4] = t + b1 + c2;
|
||||
}
|
||||
|
||||
} // namespace ripemd160
|
||||
|
||||
} // namespace
|
||||
|
||||
////// RIPEMD160
|
||||
|
||||
CRIPEMD160::CRIPEMD160() : bytes(0)
|
||||
{
|
||||
ripemd160::Initialize(s);
|
||||
}
|
||||
|
||||
CRIPEMD160& CRIPEMD160::Write(const unsigned char* data, size_t len)
|
||||
{
|
||||
const unsigned char* end = data + len;
|
||||
size_t bufsize = bytes % 64;
|
||||
if (bufsize && bufsize + len >= 64) {
|
||||
// Fill the buffer, and process it.
|
||||
memcpy(buf + bufsize, data, 64 - bufsize);
|
||||
bytes += 64 - bufsize;
|
||||
data += 64 - bufsize;
|
||||
ripemd160::Transform(s, buf);
|
||||
bufsize = 0;
|
||||
}
|
||||
while (end - data >= 64) {
|
||||
// Process full chunks directly from the source.
|
||||
ripemd160::Transform(s, data);
|
||||
bytes += 64;
|
||||
data += 64;
|
||||
}
|
||||
if (end > data) {
|
||||
// Fill the buffer with what remains.
|
||||
memcpy(buf + bufsize, data, end - data);
|
||||
bytes += end - data;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CRIPEMD160::Finalize(unsigned char hash[OUTPUT_SIZE])
|
||||
{
|
||||
static const unsigned char pad[64] = {0x80};
|
||||
unsigned char sizedesc[8];
|
||||
WriteLE64(sizedesc, bytes << 3);
|
||||
Write(pad, 1 + ((119 - (bytes % 64)) % 64));
|
||||
Write(sizedesc, 8);
|
||||
WriteLE32(hash, s[0]);
|
||||
WriteLE32(hash + 4, s[1]);
|
||||
WriteLE32(hash + 8, s[2]);
|
||||
WriteLE32(hash + 12, s[3]);
|
||||
WriteLE32(hash + 16, s[4]);
|
||||
}
|
||||
|
||||
CRIPEMD160& CRIPEMD160::Reset()
|
||||
{
|
||||
bytes = 0;
|
||||
ripemd160::Initialize(s);
|
||||
return *this;
|
||||
}
|
||||
28
src/crypto/ripemd160.h
Normal file
28
src/crypto/ripemd160.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) 2014-2016 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef DIGIBYTE_CRYPTO_RIPEMD160_H
|
||||
#define DIGIBYTE_CRYPTO_RIPEMD160_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** A hasher class for RIPEMD-160. */
|
||||
class CRIPEMD160
|
||||
{
|
||||
private:
|
||||
uint32_t s[5];
|
||||
unsigned char buf[64];
|
||||
size_t bytes;
|
||||
|
||||
public:
|
||||
static const size_t OUTPUT_SIZE = 20;
|
||||
|
||||
CRIPEMD160();
|
||||
CRIPEMD160& Write(const unsigned char* data, size_t len);
|
||||
void Finalize(unsigned char hash[OUTPUT_SIZE]);
|
||||
CRIPEMD160& Reset();
|
||||
};
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_RIPEMD160_H
|
||||
200
src/crypto/sha1.cpp
Normal file
200
src/crypto/sha1.cpp
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <crypto/sha1.h>
|
||||
|
||||
#include <crypto/common.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// Internal implementation code.
|
||||
namespace
|
||||
{
|
||||
/// Internal SHA-1 implementation.
|
||||
namespace sha1
|
||||
{
|
||||
/** One round of SHA-1. */
|
||||
void inline Round(uint32_t a, uint32_t& b, uint32_t c, uint32_t d, uint32_t& e, uint32_t f, uint32_t k, uint32_t w)
|
||||
{
|
||||
e += ((a << 5) | (a >> 27)) + f + k + w;
|
||||
b = (b << 30) | (b >> 2);
|
||||
}
|
||||
|
||||
uint32_t inline f1(uint32_t b, uint32_t c, uint32_t d) { return d ^ (b & (c ^ d)); }
|
||||
uint32_t inline f2(uint32_t b, uint32_t c, uint32_t d) { return b ^ c ^ d; }
|
||||
uint32_t inline f3(uint32_t b, uint32_t c, uint32_t d) { return (b & c) | (d & (b | c)); }
|
||||
|
||||
uint32_t inline left(uint32_t x) { return (x << 1) | (x >> 31); }
|
||||
|
||||
/** Initialize SHA-1 state. */
|
||||
void inline Initialize(uint32_t* s)
|
||||
{
|
||||
s[0] = 0x67452301ul;
|
||||
s[1] = 0xEFCDAB89ul;
|
||||
s[2] = 0x98BADCFEul;
|
||||
s[3] = 0x10325476ul;
|
||||
s[4] = 0xC3D2E1F0ul;
|
||||
}
|
||||
|
||||
const uint32_t k1 = 0x5A827999ul;
|
||||
const uint32_t k2 = 0x6ED9EBA1ul;
|
||||
const uint32_t k3 = 0x8F1BBCDCul;
|
||||
const uint32_t k4 = 0xCA62C1D6ul;
|
||||
|
||||
/** Perform a SHA-1 transformation, processing a 64-byte chunk. */
|
||||
void Transform(uint32_t* s, const unsigned char* chunk)
|
||||
{
|
||||
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4];
|
||||
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
|
||||
|
||||
Round(a, b, c, d, e, f1(b, c, d), k1, w0 = ReadBE32(chunk + 0));
|
||||
Round(e, a, b, c, d, f1(a, b, c), k1, w1 = ReadBE32(chunk + 4));
|
||||
Round(d, e, a, b, c, f1(e, a, b), k1, w2 = ReadBE32(chunk + 8));
|
||||
Round(c, d, e, a, b, f1(d, e, a), k1, w3 = ReadBE32(chunk + 12));
|
||||
Round(b, c, d, e, a, f1(c, d, e), k1, w4 = ReadBE32(chunk + 16));
|
||||
Round(a, b, c, d, e, f1(b, c, d), k1, w5 = ReadBE32(chunk + 20));
|
||||
Round(e, a, b, c, d, f1(a, b, c), k1, w6 = ReadBE32(chunk + 24));
|
||||
Round(d, e, a, b, c, f1(e, a, b), k1, w7 = ReadBE32(chunk + 28));
|
||||
Round(c, d, e, a, b, f1(d, e, a), k1, w8 = ReadBE32(chunk + 32));
|
||||
Round(b, c, d, e, a, f1(c, d, e), k1, w9 = ReadBE32(chunk + 36));
|
||||
Round(a, b, c, d, e, f1(b, c, d), k1, w10 = ReadBE32(chunk + 40));
|
||||
Round(e, a, b, c, d, f1(a, b, c), k1, w11 = ReadBE32(chunk + 44));
|
||||
Round(d, e, a, b, c, f1(e, a, b), k1, w12 = ReadBE32(chunk + 48));
|
||||
Round(c, d, e, a, b, f1(d, e, a), k1, w13 = ReadBE32(chunk + 52));
|
||||
Round(b, c, d, e, a, f1(c, d, e), k1, w14 = ReadBE32(chunk + 56));
|
||||
Round(a, b, c, d, e, f1(b, c, d), k1, w15 = ReadBE32(chunk + 60));
|
||||
|
||||
Round(e, a, b, c, d, f1(a, b, c), k1, w0 = left(w0 ^ w13 ^ w8 ^ w2));
|
||||
Round(d, e, a, b, c, f1(e, a, b), k1, w1 = left(w1 ^ w14 ^ w9 ^ w3));
|
||||
Round(c, d, e, a, b, f1(d, e, a), k1, w2 = left(w2 ^ w15 ^ w10 ^ w4));
|
||||
Round(b, c, d, e, a, f1(c, d, e), k1, w3 = left(w3 ^ w0 ^ w11 ^ w5));
|
||||
Round(a, b, c, d, e, f2(b, c, d), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6));
|
||||
Round(e, a, b, c, d, f2(a, b, c), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7));
|
||||
Round(d, e, a, b, c, f2(e, a, b), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8));
|
||||
Round(c, d, e, a, b, f2(d, e, a), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9));
|
||||
Round(b, c, d, e, a, f2(c, d, e), k2, w8 = left(w8 ^ w5 ^ w0 ^ w10));
|
||||
Round(a, b, c, d, e, f2(b, c, d), k2, w9 = left(w9 ^ w6 ^ w1 ^ w11));
|
||||
Round(e, a, b, c, d, f2(a, b, c), k2, w10 = left(w10 ^ w7 ^ w2 ^ w12));
|
||||
Round(d, e, a, b, c, f2(e, a, b), k2, w11 = left(w11 ^ w8 ^ w3 ^ w13));
|
||||
Round(c, d, e, a, b, f2(d, e, a), k2, w12 = left(w12 ^ w9 ^ w4 ^ w14));
|
||||
Round(b, c, d, e, a, f2(c, d, e), k2, w13 = left(w13 ^ w10 ^ w5 ^ w15));
|
||||
Round(a, b, c, d, e, f2(b, c, d), k2, w14 = left(w14 ^ w11 ^ w6 ^ w0));
|
||||
Round(e, a, b, c, d, f2(a, b, c), k2, w15 = left(w15 ^ w12 ^ w7 ^ w1));
|
||||
|
||||
Round(d, e, a, b, c, f2(e, a, b), k2, w0 = left(w0 ^ w13 ^ w8 ^ w2));
|
||||
Round(c, d, e, a, b, f2(d, e, a), k2, w1 = left(w1 ^ w14 ^ w9 ^ w3));
|
||||
Round(b, c, d, e, a, f2(c, d, e), k2, w2 = left(w2 ^ w15 ^ w10 ^ w4));
|
||||
Round(a, b, c, d, e, f2(b, c, d), k2, w3 = left(w3 ^ w0 ^ w11 ^ w5));
|
||||
Round(e, a, b, c, d, f2(a, b, c), k2, w4 = left(w4 ^ w1 ^ w12 ^ w6));
|
||||
Round(d, e, a, b, c, f2(e, a, b), k2, w5 = left(w5 ^ w2 ^ w13 ^ w7));
|
||||
Round(c, d, e, a, b, f2(d, e, a), k2, w6 = left(w6 ^ w3 ^ w14 ^ w8));
|
||||
Round(b, c, d, e, a, f2(c, d, e), k2, w7 = left(w7 ^ w4 ^ w15 ^ w9));
|
||||
Round(a, b, c, d, e, f3(b, c, d), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10));
|
||||
Round(e, a, b, c, d, f3(a, b, c), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11));
|
||||
Round(d, e, a, b, c, f3(e, a, b), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12));
|
||||
Round(c, d, e, a, b, f3(d, e, a), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13));
|
||||
Round(b, c, d, e, a, f3(c, d, e), k3, w12 = left(w12 ^ w9 ^ w4 ^ w14));
|
||||
Round(a, b, c, d, e, f3(b, c, d), k3, w13 = left(w13 ^ w10 ^ w5 ^ w15));
|
||||
Round(e, a, b, c, d, f3(a, b, c), k3, w14 = left(w14 ^ w11 ^ w6 ^ w0));
|
||||
Round(d, e, a, b, c, f3(e, a, b), k3, w15 = left(w15 ^ w12 ^ w7 ^ w1));
|
||||
|
||||
Round(c, d, e, a, b, f3(d, e, a), k3, w0 = left(w0 ^ w13 ^ w8 ^ w2));
|
||||
Round(b, c, d, e, a, f3(c, d, e), k3, w1 = left(w1 ^ w14 ^ w9 ^ w3));
|
||||
Round(a, b, c, d, e, f3(b, c, d), k3, w2 = left(w2 ^ w15 ^ w10 ^ w4));
|
||||
Round(e, a, b, c, d, f3(a, b, c), k3, w3 = left(w3 ^ w0 ^ w11 ^ w5));
|
||||
Round(d, e, a, b, c, f3(e, a, b), k3, w4 = left(w4 ^ w1 ^ w12 ^ w6));
|
||||
Round(c, d, e, a, b, f3(d, e, a), k3, w5 = left(w5 ^ w2 ^ w13 ^ w7));
|
||||
Round(b, c, d, e, a, f3(c, d, e), k3, w6 = left(w6 ^ w3 ^ w14 ^ w8));
|
||||
Round(a, b, c, d, e, f3(b, c, d), k3, w7 = left(w7 ^ w4 ^ w15 ^ w9));
|
||||
Round(e, a, b, c, d, f3(a, b, c), k3, w8 = left(w8 ^ w5 ^ w0 ^ w10));
|
||||
Round(d, e, a, b, c, f3(e, a, b), k3, w9 = left(w9 ^ w6 ^ w1 ^ w11));
|
||||
Round(c, d, e, a, b, f3(d, e, a), k3, w10 = left(w10 ^ w7 ^ w2 ^ w12));
|
||||
Round(b, c, d, e, a, f3(c, d, e), k3, w11 = left(w11 ^ w8 ^ w3 ^ w13));
|
||||
Round(a, b, c, d, e, f2(b, c, d), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14));
|
||||
Round(e, a, b, c, d, f2(a, b, c), k4, w13 = left(w13 ^ w10 ^ w5 ^ w15));
|
||||
Round(d, e, a, b, c, f2(e, a, b), k4, w14 = left(w14 ^ w11 ^ w6 ^ w0));
|
||||
Round(c, d, e, a, b, f2(d, e, a), k4, w15 = left(w15 ^ w12 ^ w7 ^ w1));
|
||||
|
||||
Round(b, c, d, e, a, f2(c, d, e), k4, w0 = left(w0 ^ w13 ^ w8 ^ w2));
|
||||
Round(a, b, c, d, e, f2(b, c, d), k4, w1 = left(w1 ^ w14 ^ w9 ^ w3));
|
||||
Round(e, a, b, c, d, f2(a, b, c), k4, w2 = left(w2 ^ w15 ^ w10 ^ w4));
|
||||
Round(d, e, a, b, c, f2(e, a, b), k4, w3 = left(w3 ^ w0 ^ w11 ^ w5));
|
||||
Round(c, d, e, a, b, f2(d, e, a), k4, w4 = left(w4 ^ w1 ^ w12 ^ w6));
|
||||
Round(b, c, d, e, a, f2(c, d, e), k4, w5 = left(w5 ^ w2 ^ w13 ^ w7));
|
||||
Round(a, b, c, d, e, f2(b, c, d), k4, w6 = left(w6 ^ w3 ^ w14 ^ w8));
|
||||
Round(e, a, b, c, d, f2(a, b, c), k4, w7 = left(w7 ^ w4 ^ w15 ^ w9));
|
||||
Round(d, e, a, b, c, f2(e, a, b), k4, w8 = left(w8 ^ w5 ^ w0 ^ w10));
|
||||
Round(c, d, e, a, b, f2(d, e, a), k4, w9 = left(w9 ^ w6 ^ w1 ^ w11));
|
||||
Round(b, c, d, e, a, f2(c, d, e), k4, w10 = left(w10 ^ w7 ^ w2 ^ w12));
|
||||
Round(a, b, c, d, e, f2(b, c, d), k4, w11 = left(w11 ^ w8 ^ w3 ^ w13));
|
||||
Round(e, a, b, c, d, f2(a, b, c), k4, w12 = left(w12 ^ w9 ^ w4 ^ w14));
|
||||
Round(d, e, a, b, c, f2(e, a, b), k4, left(w13 ^ w10 ^ w5 ^ w15));
|
||||
Round(c, d, e, a, b, f2(d, e, a), k4, left(w14 ^ w11 ^ w6 ^ w0));
|
||||
Round(b, c, d, e, a, f2(c, d, e), k4, left(w15 ^ w12 ^ w7 ^ w1));
|
||||
|
||||
s[0] += a;
|
||||
s[1] += b;
|
||||
s[2] += c;
|
||||
s[3] += d;
|
||||
s[4] += e;
|
||||
}
|
||||
|
||||
} // namespace sha1
|
||||
|
||||
} // namespace
|
||||
|
||||
////// SHA1
|
||||
|
||||
CSHA1::CSHA1() : bytes(0)
|
||||
{
|
||||
sha1::Initialize(s);
|
||||
}
|
||||
|
||||
CSHA1& CSHA1::Write(const unsigned char* data, size_t len)
|
||||
{
|
||||
const unsigned char* end = data + len;
|
||||
size_t bufsize = bytes % 64;
|
||||
if (bufsize && bufsize + len >= 64) {
|
||||
// Fill the buffer, and process it.
|
||||
memcpy(buf + bufsize, data, 64 - bufsize);
|
||||
bytes += 64 - bufsize;
|
||||
data += 64 - bufsize;
|
||||
sha1::Transform(s, buf);
|
||||
bufsize = 0;
|
||||
}
|
||||
while (end - data >= 64) {
|
||||
// Process full chunks directly from the source.
|
||||
sha1::Transform(s, data);
|
||||
bytes += 64;
|
||||
data += 64;
|
||||
}
|
||||
if (end > data) {
|
||||
// Fill the buffer with what remains.
|
||||
memcpy(buf + bufsize, data, end - data);
|
||||
bytes += end - data;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CSHA1::Finalize(unsigned char hash[OUTPUT_SIZE])
|
||||
{
|
||||
static const unsigned char pad[64] = {0x80};
|
||||
unsigned char sizedesc[8];
|
||||
WriteBE64(sizedesc, bytes << 3);
|
||||
Write(pad, 1 + ((119 - (bytes % 64)) % 64));
|
||||
Write(sizedesc, 8);
|
||||
WriteBE32(hash, s[0]);
|
||||
WriteBE32(hash + 4, s[1]);
|
||||
WriteBE32(hash + 8, s[2]);
|
||||
WriteBE32(hash + 12, s[3]);
|
||||
WriteBE32(hash + 16, s[4]);
|
||||
}
|
||||
|
||||
CSHA1& CSHA1::Reset()
|
||||
{
|
||||
bytes = 0;
|
||||
sha1::Initialize(s);
|
||||
return *this;
|
||||
}
|
||||
28
src/crypto/sha1.h
Normal file
28
src/crypto/sha1.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) 2014-2016 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef DIGIBYTE_CRYPTO_SHA1_H
|
||||
#define DIGIBYTE_CRYPTO_SHA1_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** A hasher class for SHA1. */
|
||||
class CSHA1
|
||||
{
|
||||
private:
|
||||
uint32_t s[5];
|
||||
unsigned char buf[64];
|
||||
size_t bytes;
|
||||
|
||||
public:
|
||||
static const size_t OUTPUT_SIZE = 20;
|
||||
|
||||
CSHA1();
|
||||
CSHA1& Write(const unsigned char* data, size_t len);
|
||||
void Finalize(unsigned char hash[OUTPUT_SIZE]);
|
||||
CSHA1& Reset();
|
||||
};
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_SHA1_H
|
||||
720
src/crypto/sha256.cpp
Normal file
720
src/crypto/sha256.cpp
Normal file
|
|
@ -0,0 +1,720 @@
|
|||
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <crypto/sha256.h>
|
||||
#include <crypto/common.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <compat/cpuid.h>
|
||||
|
||||
#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
|
||||
#if defined(USE_ASM)
|
||||
namespace sha256_sse4
|
||||
{
|
||||
void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace sha256d64_sse41
|
||||
{
|
||||
void Transform_4way(unsigned char* out, const unsigned char* in);
|
||||
}
|
||||
|
||||
namespace sha256d64_avx2
|
||||
{
|
||||
void Transform_8way(unsigned char* out, const unsigned char* in);
|
||||
}
|
||||
|
||||
namespace sha256d64_shani
|
||||
{
|
||||
void Transform_2way(unsigned char* out, const unsigned char* in);
|
||||
}
|
||||
|
||||
namespace sha256_shani
|
||||
{
|
||||
void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks);
|
||||
}
|
||||
|
||||
// Internal implementation code.
|
||||
namespace
|
||||
{
|
||||
/// Internal SHA-256 implementation.
|
||||
namespace sha256
|
||||
{
|
||||
uint32_t inline Ch(uint32_t x, uint32_t y, uint32_t z) { return z ^ (x & (y ^ z)); }
|
||||
uint32_t inline Maj(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (z & (x | y)); }
|
||||
uint32_t inline Sigma0(uint32_t x) { return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); }
|
||||
uint32_t inline Sigma1(uint32_t x) { return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); }
|
||||
uint32_t inline sigma0(uint32_t x) { return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); }
|
||||
uint32_t inline sigma1(uint32_t x) { return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); }
|
||||
|
||||
/** One round of SHA-256. */
|
||||
void inline Round(uint32_t a, uint32_t b, uint32_t c, uint32_t& d, uint32_t e, uint32_t f, uint32_t g, uint32_t& h, uint32_t k)
|
||||
{
|
||||
uint32_t t1 = h + Sigma1(e) + Ch(e, f, g) + k;
|
||||
uint32_t t2 = Sigma0(a) + Maj(a, b, c);
|
||||
d += t1;
|
||||
h = t1 + t2;
|
||||
}
|
||||
|
||||
/** Initialize SHA-256 state. */
|
||||
void inline Initialize(uint32_t* s)
|
||||
{
|
||||
s[0] = 0x6a09e667ul;
|
||||
s[1] = 0xbb67ae85ul;
|
||||
s[2] = 0x3c6ef372ul;
|
||||
s[3] = 0xa54ff53aul;
|
||||
s[4] = 0x510e527ful;
|
||||
s[5] = 0x9b05688cul;
|
||||
s[6] = 0x1f83d9abul;
|
||||
s[7] = 0x5be0cd19ul;
|
||||
}
|
||||
|
||||
/** Perform a number of SHA-256 transformations, processing 64-byte chunks. */
|
||||
void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks)
|
||||
{
|
||||
while (blocks--) {
|
||||
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
|
||||
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0x428a2f98 + (w0 = ReadBE32(chunk + 0)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x71374491 + (w1 = ReadBE32(chunk + 4)));
|
||||
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcf + (w2 = ReadBE32(chunk + 8)));
|
||||
Round(f, g, h, a, b, c, d, e, 0xe9b5dba5 + (w3 = ReadBE32(chunk + 12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x3956c25b + (w4 = ReadBE32(chunk + 16)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x59f111f1 + (w5 = ReadBE32(chunk + 20)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x923f82a4 + (w6 = ReadBE32(chunk + 24)));
|
||||
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5 + (w7 = ReadBE32(chunk + 28)));
|
||||
Round(a, b, c, d, e, f, g, h, 0xd807aa98 + (w8 = ReadBE32(chunk + 32)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x12835b01 + (w9 = ReadBE32(chunk + 36)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x243185be + (w10 = ReadBE32(chunk + 40)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x550c7dc3 + (w11 = ReadBE32(chunk + 44)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x72be5d74 + (w12 = ReadBE32(chunk + 48)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x80deb1fe + (w13 = ReadBE32(chunk + 52)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x9bdc06a7 + (w14 = ReadBE32(chunk + 56)));
|
||||
Round(b, c, d, e, f, g, h, a, 0xc19bf174 + (w15 = ReadBE32(chunk + 60)));
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0xe49b69c1 + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xefbe4786 + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x0fc19dc6 + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x240ca1cc + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x2de92c6f + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x4a7484aa + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x5cb0a9dc + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x76f988da + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x983e5152 + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xa831c66d + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0xb00327c8 + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0xbf597fc7 + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0xc6e00bf3 + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xd5a79147 + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x06ca6351 + (w14 += sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x14292967 + (w15 += sigma1(w13) + w8 + sigma0(w0)));
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0x27b70a85 + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x2e1b2138 + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x53380d13 + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x650a7354 + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x766a0abb + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x81c2c92e + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x92722c85 + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1 + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xa81a664b + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0xc24b8b70 + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0xc76c51a3 + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0xd192e819 + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xd6990624 + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0xf40e3585 + (w14 += sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x106aa070 + (w15 += sigma1(w13) + w8 + sigma0(w0)));
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0x19a4c116 + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x1e376c08 + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x2748774c + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x34b0bcb5 + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x391c0cb3 + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x4ed8aa4a + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x5b9cca4f + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x682e6ff3 + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x748f82ee + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x78a5636f + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x84c87814 + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x8cc70208 + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x90befffa + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xa4506ceb + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0xbef9a3f7 + (w14 + sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0xc67178f2 + (w15 + sigma1(w13) + w8 + sigma0(w0)));
|
||||
|
||||
s[0] += a;
|
||||
s[1] += b;
|
||||
s[2] += c;
|
||||
s[3] += d;
|
||||
s[4] += e;
|
||||
s[5] += f;
|
||||
s[6] += g;
|
||||
s[7] += h;
|
||||
chunk += 64;
|
||||
}
|
||||
}
|
||||
|
||||
void TransformD64(unsigned char* out, const unsigned char* in)
|
||||
{
|
||||
// Transform 1
|
||||
uint32_t a = 0x6a09e667ul;
|
||||
uint32_t b = 0xbb67ae85ul;
|
||||
uint32_t c = 0x3c6ef372ul;
|
||||
uint32_t d = 0xa54ff53aul;
|
||||
uint32_t e = 0x510e527ful;
|
||||
uint32_t f = 0x9b05688cul;
|
||||
uint32_t g = 0x1f83d9abul;
|
||||
uint32_t h = 0x5be0cd19ul;
|
||||
|
||||
uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0x428a2f98ul + (w0 = ReadBE32(in + 0)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x71374491ul + (w1 = ReadBE32(in + 4)));
|
||||
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful + (w2 = ReadBE32(in + 8)));
|
||||
Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul + (w3 = ReadBE32(in + 12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x3956c25bul + (w4 = ReadBE32(in + 16)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x59f111f1ul + (w5 = ReadBE32(in + 20)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x923f82a4ul + (w6 = ReadBE32(in + 24)));
|
||||
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul + (w7 = ReadBE32(in + 28)));
|
||||
Round(a, b, c, d, e, f, g, h, 0xd807aa98ul + (w8 = ReadBE32(in + 32)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x12835b01ul + (w9 = ReadBE32(in + 36)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x243185beul + (w10 = ReadBE32(in + 40)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul + (w11 = ReadBE32(in + 44)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x72be5d74ul + (w12 = ReadBE32(in + 48)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x80deb1feul + (w13 = ReadBE32(in + 52)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul + (w14 = ReadBE32(in + 56)));
|
||||
Round(b, c, d, e, f, g, h, a, 0xc19bf174ul + (w15 = ReadBE32(in + 60)));
|
||||
Round(a, b, c, d, e, f, g, h, 0xe49b69c1ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xefbe4786ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x0fc19dc6ul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x240ca1ccul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x2de92c6ful + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x4a7484aaul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcul + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x76f988daul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x983e5152ul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xa831c66dul + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0xb00327c8ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0xbf597fc7ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0xc6e00bf3ul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xd5a79147ul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x06ca6351ul + (w14 += sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x14292967ul + (w15 += sigma1(w13) + w8 + sigma0(w0)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x27b70a85ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x2e1b2138ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x4d2c6dfcul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x53380d13ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x650a7354ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x766a0abbul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x81c2c92eul + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x92722c85ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1ul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xa81a664bul + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0xc24b8b70ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0xc76c51a3ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0xd192e819ul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xd6990624ul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0xf40e3585ul + (w14 += sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x106aa070ul + (w15 += sigma1(w13) + w8 + sigma0(w0)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x19a4c116ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x1e376c08ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x2748774cul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x34b0bcb5ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x391c0cb3ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x4ed8aa4aul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x5b9cca4ful + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x682e6ff3ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x748f82eeul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x78a5636ful + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x84c87814ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x8cc70208ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x90befffaul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xa4506cebul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0xbef9a3f7ul + (w14 + sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0xc67178f2ul + (w15 + sigma1(w13) + w8 + sigma0(w0)));
|
||||
|
||||
a += 0x6a09e667ul;
|
||||
b += 0xbb67ae85ul;
|
||||
c += 0x3c6ef372ul;
|
||||
d += 0xa54ff53aul;
|
||||
e += 0x510e527ful;
|
||||
f += 0x9b05688cul;
|
||||
g += 0x1f83d9abul;
|
||||
h += 0x5be0cd19ul;
|
||||
|
||||
uint32_t t0 = a, t1 = b, t2 = c, t3 = d, t4 = e, t5 = f, t6 = g, t7 = h;
|
||||
|
||||
// Transform 2
|
||||
Round(a, b, c, d, e, f, g, h, 0xc28a2f98ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0x71374491ul);
|
||||
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful);
|
||||
Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x3956c25bul);
|
||||
Round(d, e, f, g, h, a, b, c, 0x59f111f1ul);
|
||||
Round(c, d, e, f, g, h, a, b, 0x923f82a4ul);
|
||||
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul);
|
||||
Round(a, b, c, d, e, f, g, h, 0xd807aa98ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0x12835b01ul);
|
||||
Round(g, h, a, b, c, d, e, f, 0x243185beul);
|
||||
Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x72be5d74ul);
|
||||
Round(d, e, f, g, h, a, b, c, 0x80deb1feul);
|
||||
Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul);
|
||||
Round(b, c, d, e, f, g, h, a, 0xc19bf374ul);
|
||||
Round(a, b, c, d, e, f, g, h, 0x649b69c1ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0xf0fe4786ul);
|
||||
Round(g, h, a, b, c, d, e, f, 0x0fe1edc6ul);
|
||||
Round(f, g, h, a, b, c, d, e, 0x240cf254ul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x4fe9346ful);
|
||||
Round(d, e, f, g, h, a, b, c, 0x6cc984beul);
|
||||
Round(c, d, e, f, g, h, a, b, 0x61b9411eul);
|
||||
Round(b, c, d, e, f, g, h, a, 0x16f988faul);
|
||||
Round(a, b, c, d, e, f, g, h, 0xf2c65152ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0xa88e5a6dul);
|
||||
Round(g, h, a, b, c, d, e, f, 0xb019fc65ul);
|
||||
Round(f, g, h, a, b, c, d, e, 0xb9d99ec7ul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x9a1231c3ul);
|
||||
Round(d, e, f, g, h, a, b, c, 0xe70eeaa0ul);
|
||||
Round(c, d, e, f, g, h, a, b, 0xfdb1232bul);
|
||||
Round(b, c, d, e, f, g, h, a, 0xc7353eb0ul);
|
||||
Round(a, b, c, d, e, f, g, h, 0x3069bad5ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0xcb976d5ful);
|
||||
Round(g, h, a, b, c, d, e, f, 0x5a0f118ful);
|
||||
Round(f, g, h, a, b, c, d, e, 0xdc1eeefdul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x0a35b689ul);
|
||||
Round(d, e, f, g, h, a, b, c, 0xde0b7a04ul);
|
||||
Round(c, d, e, f, g, h, a, b, 0x58f4ca9dul);
|
||||
Round(b, c, d, e, f, g, h, a, 0xe15d5b16ul);
|
||||
Round(a, b, c, d, e, f, g, h, 0x007f3e86ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0x37088980ul);
|
||||
Round(g, h, a, b, c, d, e, f, 0xa507ea32ul);
|
||||
Round(f, g, h, a, b, c, d, e, 0x6fab9537ul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x17406110ul);
|
||||
Round(d, e, f, g, h, a, b, c, 0x0d8cd6f1ul);
|
||||
Round(c, d, e, f, g, h, a, b, 0xcdaa3b6dul);
|
||||
Round(b, c, d, e, f, g, h, a, 0xc0bbbe37ul);
|
||||
Round(a, b, c, d, e, f, g, h, 0x83613bdaul);
|
||||
Round(h, a, b, c, d, e, f, g, 0xdb48a363ul);
|
||||
Round(g, h, a, b, c, d, e, f, 0x0b02e931ul);
|
||||
Round(f, g, h, a, b, c, d, e, 0x6fd15ca7ul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x521afacaul);
|
||||
Round(d, e, f, g, h, a, b, c, 0x31338431ul);
|
||||
Round(c, d, e, f, g, h, a, b, 0x6ed41a95ul);
|
||||
Round(b, c, d, e, f, g, h, a, 0x6d437890ul);
|
||||
Round(a, b, c, d, e, f, g, h, 0xc39c91f2ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0x9eccabbdul);
|
||||
Round(g, h, a, b, c, d, e, f, 0xb5c9a0e6ul);
|
||||
Round(f, g, h, a, b, c, d, e, 0x532fb63cul);
|
||||
Round(e, f, g, h, a, b, c, d, 0xd2c741c6ul);
|
||||
Round(d, e, f, g, h, a, b, c, 0x07237ea3ul);
|
||||
Round(c, d, e, f, g, h, a, b, 0xa4954b68ul);
|
||||
Round(b, c, d, e, f, g, h, a, 0x4c191d76ul);
|
||||
|
||||
w0 = t0 + a;
|
||||
w1 = t1 + b;
|
||||
w2 = t2 + c;
|
||||
w3 = t3 + d;
|
||||
w4 = t4 + e;
|
||||
w5 = t5 + f;
|
||||
w6 = t6 + g;
|
||||
w7 = t7 + h;
|
||||
|
||||
// Transform 3
|
||||
a = 0x6a09e667ul;
|
||||
b = 0xbb67ae85ul;
|
||||
c = 0x3c6ef372ul;
|
||||
d = 0xa54ff53aul;
|
||||
e = 0x510e527ful;
|
||||
f = 0x9b05688cul;
|
||||
g = 0x1f83d9abul;
|
||||
h = 0x5be0cd19ul;
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0x428a2f98ul + w0);
|
||||
Round(h, a, b, c, d, e, f, g, 0x71374491ul + w1);
|
||||
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcful + w2);
|
||||
Round(f, g, h, a, b, c, d, e, 0xe9b5dba5ul + w3);
|
||||
Round(e, f, g, h, a, b, c, d, 0x3956c25bul + w4);
|
||||
Round(d, e, f, g, h, a, b, c, 0x59f111f1ul + w5);
|
||||
Round(c, d, e, f, g, h, a, b, 0x923f82a4ul + w6);
|
||||
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5ul + w7);
|
||||
Round(a, b, c, d, e, f, g, h, 0x5807aa98ul);
|
||||
Round(h, a, b, c, d, e, f, g, 0x12835b01ul);
|
||||
Round(g, h, a, b, c, d, e, f, 0x243185beul);
|
||||
Round(f, g, h, a, b, c, d, e, 0x550c7dc3ul);
|
||||
Round(e, f, g, h, a, b, c, d, 0x72be5d74ul);
|
||||
Round(d, e, f, g, h, a, b, c, 0x80deb1feul);
|
||||
Round(c, d, e, f, g, h, a, b, 0x9bdc06a7ul);
|
||||
Round(b, c, d, e, f, g, h, a, 0xc19bf274ul);
|
||||
Round(a, b, c, d, e, f, g, h, 0xe49b69c1ul + (w0 += sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xefbe4786ul + (w1 += 0xa00000ul + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x0fc19dc6ul + (w2 += sigma1(w0) + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x240ca1ccul + (w3 += sigma1(w1) + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x2de92c6ful + (w4 += sigma1(w2) + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x4a7484aaul + (w5 += sigma1(w3) + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcul + (w6 += sigma1(w4) + 0x100ul + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x76f988daul + (w7 += sigma1(w5) + w0 + 0x11002000ul));
|
||||
Round(a, b, c, d, e, f, g, h, 0x983e5152ul + (w8 = 0x80000000ul + sigma1(w6) + w1));
|
||||
Round(h, a, b, c, d, e, f, g, 0xa831c66dul + (w9 = sigma1(w7) + w2));
|
||||
Round(g, h, a, b, c, d, e, f, 0xb00327c8ul + (w10 = sigma1(w8) + w3));
|
||||
Round(f, g, h, a, b, c, d, e, 0xbf597fc7ul + (w11 = sigma1(w9) + w4));
|
||||
Round(e, f, g, h, a, b, c, d, 0xc6e00bf3ul + (w12 = sigma1(w10) + w5));
|
||||
Round(d, e, f, g, h, a, b, c, 0xd5a79147ul + (w13 = sigma1(w11) + w6));
|
||||
Round(c, d, e, f, g, h, a, b, 0x06ca6351ul + (w14 = sigma1(w12) + w7 + 0x400022ul));
|
||||
Round(b, c, d, e, f, g, h, a, 0x14292967ul + (w15 = 0x100ul + sigma1(w13) + w8 + sigma0(w0)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x27b70a85ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x2e1b2138ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x4d2c6dfcul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x53380d13ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x650a7354ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x766a0abbul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x81c2c92eul + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x92722c85ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0xa2bfe8a1ul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0xa81a664bul + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0xc24b8b70ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0xc76c51a3ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0xd192e819ul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xd6990624ul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0xf40e3585ul + (w14 += sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x106aa070ul + (w15 += sigma1(w13) + w8 + sigma0(w0)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x19a4c116ul + (w0 += sigma1(w14) + w9 + sigma0(w1)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x1e376c08ul + (w1 += sigma1(w15) + w10 + sigma0(w2)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x2748774cul + (w2 += sigma1(w0) + w11 + sigma0(w3)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x34b0bcb5ul + (w3 += sigma1(w1) + w12 + sigma0(w4)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x391c0cb3ul + (w4 += sigma1(w2) + w13 + sigma0(w5)));
|
||||
Round(d, e, f, g, h, a, b, c, 0x4ed8aa4aul + (w5 += sigma1(w3) + w14 + sigma0(w6)));
|
||||
Round(c, d, e, f, g, h, a, b, 0x5b9cca4ful + (w6 += sigma1(w4) + w15 + sigma0(w7)));
|
||||
Round(b, c, d, e, f, g, h, a, 0x682e6ff3ul + (w7 += sigma1(w5) + w0 + sigma0(w8)));
|
||||
Round(a, b, c, d, e, f, g, h, 0x748f82eeul + (w8 += sigma1(w6) + w1 + sigma0(w9)));
|
||||
Round(h, a, b, c, d, e, f, g, 0x78a5636ful + (w9 += sigma1(w7) + w2 + sigma0(w10)));
|
||||
Round(g, h, a, b, c, d, e, f, 0x84c87814ul + (w10 += sigma1(w8) + w3 + sigma0(w11)));
|
||||
Round(f, g, h, a, b, c, d, e, 0x8cc70208ul + (w11 += sigma1(w9) + w4 + sigma0(w12)));
|
||||
Round(e, f, g, h, a, b, c, d, 0x90befffaul + (w12 += sigma1(w10) + w5 + sigma0(w13)));
|
||||
Round(d, e, f, g, h, a, b, c, 0xa4506cebul + (w13 += sigma1(w11) + w6 + sigma0(w14)));
|
||||
Round(c, d, e, f, g, h, a, b, 0xbef9a3f7ul + (w14 + sigma1(w12) + w7 + sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, 0xc67178f2ul + (w15 + sigma1(w13) + w8 + sigma0(w0)));
|
||||
|
||||
// Output
|
||||
WriteBE32(out + 0, a + 0x6a09e667ul);
|
||||
WriteBE32(out + 4, b + 0xbb67ae85ul);
|
||||
WriteBE32(out + 8, c + 0x3c6ef372ul);
|
||||
WriteBE32(out + 12, d + 0xa54ff53aul);
|
||||
WriteBE32(out + 16, e + 0x510e527ful);
|
||||
WriteBE32(out + 20, f + 0x9b05688cul);
|
||||
WriteBE32(out + 24, g + 0x1f83d9abul);
|
||||
WriteBE32(out + 28, h + 0x5be0cd19ul);
|
||||
}
|
||||
|
||||
} // namespace sha256
|
||||
|
||||
typedef void (*TransformType)(uint32_t*, const unsigned char*, size_t);
|
||||
typedef void (*TransformD64Type)(unsigned char*, const unsigned char*);
|
||||
|
||||
template<TransformType tr>
|
||||
void TransformD64Wrapper(unsigned char* out, const unsigned char* in)
|
||||
{
|
||||
uint32_t s[8];
|
||||
static const unsigned char padding1[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0
|
||||
};
|
||||
unsigned char buffer2[64] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0
|
||||
};
|
||||
sha256::Initialize(s);
|
||||
tr(s, in, 1);
|
||||
tr(s, padding1, 1);
|
||||
WriteBE32(buffer2 + 0, s[0]);
|
||||
WriteBE32(buffer2 + 4, s[1]);
|
||||
WriteBE32(buffer2 + 8, s[2]);
|
||||
WriteBE32(buffer2 + 12, s[3]);
|
||||
WriteBE32(buffer2 + 16, s[4]);
|
||||
WriteBE32(buffer2 + 20, s[5]);
|
||||
WriteBE32(buffer2 + 24, s[6]);
|
||||
WriteBE32(buffer2 + 28, s[7]);
|
||||
sha256::Initialize(s);
|
||||
tr(s, buffer2, 1);
|
||||
WriteBE32(out + 0, s[0]);
|
||||
WriteBE32(out + 4, s[1]);
|
||||
WriteBE32(out + 8, s[2]);
|
||||
WriteBE32(out + 12, s[3]);
|
||||
WriteBE32(out + 16, s[4]);
|
||||
WriteBE32(out + 20, s[5]);
|
||||
WriteBE32(out + 24, s[6]);
|
||||
WriteBE32(out + 28, s[7]);
|
||||
}
|
||||
|
||||
TransformType Transform = sha256::Transform;
|
||||
TransformD64Type TransformD64 = sha256::TransformD64;
|
||||
TransformD64Type TransformD64_2way = nullptr;
|
||||
TransformD64Type TransformD64_4way = nullptr;
|
||||
TransformD64Type TransformD64_8way = nullptr;
|
||||
|
||||
bool SelfTest() {
|
||||
// Input state (equal to the initial SHA256 state)
|
||||
static const uint32_t init[8] = {
|
||||
0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul
|
||||
};
|
||||
// Some random input data to test with
|
||||
static const unsigned char data[641] = "-" // Intentionally not aligned
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
|
||||
"eiusmod tempor incididunt ut labore et dolore magna aliqua. Et m"
|
||||
"olestie ac feugiat sed lectus vestibulum mattis ullamcorper. Mor"
|
||||
"bi blandit cursus risus at ultrices mi tempus imperdiet nulla. N"
|
||||
"unc congue nisi vita suscipit tellus mauris. Imperdiet proin fer"
|
||||
"mentum leo vel orci. Massa tempor nec feugiat nisl pretium fusce"
|
||||
" id velit. Telus in metus vulputate eu scelerisque felis. Mi tem"
|
||||
"pus imperdiet nulla malesuada pellentesque. Tristique magna sit.";
|
||||
// Expected output state for hashing the i*64 first input bytes above (excluding SHA256 padding).
|
||||
static const uint32_t result[9][8] = {
|
||||
{0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul},
|
||||
{0x91f8ec6bul, 0x4da10fe3ul, 0x1c9c292cul, 0x45e18185ul, 0x435cc111ul, 0x3ca26f09ul, 0xeb954caeul, 0x402a7069ul},
|
||||
{0xcabea5acul, 0x374fb97cul, 0x182ad996ul, 0x7bd69cbful, 0x450ff900ul, 0xc1d2be8aul, 0x6a41d505ul, 0xe6212dc3ul},
|
||||
{0xbcff09d6ul, 0x3e76f36eul, 0x3ecb2501ul, 0x78866e97ul, 0xe1c1e2fdul, 0x32f4eafful, 0x8aa6c4e5ul, 0xdfc024bcul},
|
||||
{0xa08c5d94ul, 0x0a862f93ul, 0x6b7f2f40ul, 0x8f9fae76ul, 0x6d40439ful, 0x79dcee0cul, 0x3e39ff3aul, 0xdc3bdbb1ul},
|
||||
{0x216a0895ul, 0x9f1a3662ul, 0xe99946f9ul, 0x87ba4364ul, 0x0fb5db2cul, 0x12bed3d3ul, 0x6689c0c7ul, 0x292f1b04ul},
|
||||
{0xca3067f8ul, 0xbc8c2656ul, 0x37cb7e0dul, 0x9b6b8b0ful, 0x46dc380bul, 0xf1287f57ul, 0xc42e4b23ul, 0x3fefe94dul},
|
||||
{0x3e4c4039ul, 0xbb6fca8cul, 0x6f27d2f7ul, 0x301e44a4ul, 0x8352ba14ul, 0x5769ce37ul, 0x48a1155ful, 0xc0e1c4c6ul},
|
||||
{0xfe2fa9ddul, 0x69d0862bul, 0x1ae0db23ul, 0x471f9244ul, 0xf55c0145ul, 0xc30f9c3bul, 0x40a84ea0ul, 0x5b8a266cul},
|
||||
};
|
||||
// Expected output for each of the individual 8 64-byte messages under full double SHA256 (including padding).
|
||||
static const unsigned char result_d64[256] = {
|
||||
0x09, 0x3a, 0xc4, 0xd0, 0x0f, 0xf7, 0x57, 0xe1, 0x72, 0x85, 0x79, 0x42, 0xfe, 0xe7, 0xe0, 0xa0,
|
||||
0xfc, 0x52, 0xd7, 0xdb, 0x07, 0x63, 0x45, 0xfb, 0x53, 0x14, 0x7d, 0x17, 0x22, 0x86, 0xf0, 0x52,
|
||||
0x48, 0xb6, 0x11, 0x9e, 0x6e, 0x48, 0x81, 0x6d, 0xcc, 0x57, 0x1f, 0xb2, 0x97, 0xa8, 0xd5, 0x25,
|
||||
0x9b, 0x82, 0xaa, 0x89, 0xe2, 0xfd, 0x2d, 0x56, 0xe8, 0x28, 0x83, 0x0b, 0xe2, 0xfa, 0x53, 0xb7,
|
||||
0xd6, 0x6b, 0x07, 0x85, 0x83, 0xb0, 0x10, 0xa2, 0xf5, 0x51, 0x3c, 0xf9, 0x60, 0x03, 0xab, 0x45,
|
||||
0x6c, 0x15, 0x6e, 0xef, 0xb5, 0xac, 0x3e, 0x6c, 0xdf, 0xb4, 0x92, 0x22, 0x2d, 0xce, 0xbf, 0x3e,
|
||||
0xe9, 0xe5, 0xf6, 0x29, 0x0e, 0x01, 0x4f, 0xd2, 0xd4, 0x45, 0x65, 0xb3, 0xbb, 0xf2, 0x4c, 0x16,
|
||||
0x37, 0x50, 0x3c, 0x6e, 0x49, 0x8c, 0x5a, 0x89, 0x2b, 0x1b, 0xab, 0xc4, 0x37, 0xd1, 0x46, 0xe9,
|
||||
0x3d, 0x0e, 0x85, 0xa2, 0x50, 0x73, 0xa1, 0x5e, 0x54, 0x37, 0xd7, 0x94, 0x17, 0x56, 0xc2, 0xd8,
|
||||
0xe5, 0x9f, 0xed, 0x4e, 0xae, 0x15, 0x42, 0x06, 0x0d, 0x74, 0x74, 0x5e, 0x24, 0x30, 0xce, 0xd1,
|
||||
0x9e, 0x50, 0xa3, 0x9a, 0xb8, 0xf0, 0x4a, 0x57, 0x69, 0x78, 0x67, 0x12, 0x84, 0x58, 0xbe, 0xc7,
|
||||
0x36, 0xaa, 0xee, 0x7c, 0x64, 0xa3, 0x76, 0xec, 0xff, 0x55, 0x41, 0x00, 0x2a, 0x44, 0x68, 0x4d,
|
||||
0xb6, 0x53, 0x9e, 0x1c, 0x95, 0xb7, 0xca, 0xdc, 0x7f, 0x7d, 0x74, 0x27, 0x5c, 0x8e, 0xa6, 0x84,
|
||||
0xb5, 0xac, 0x87, 0xa9, 0xf3, 0xff, 0x75, 0xf2, 0x34, 0xcd, 0x1a, 0x3b, 0x82, 0x2c, 0x2b, 0x4e,
|
||||
0x6a, 0x46, 0x30, 0xa6, 0x89, 0x86, 0x23, 0xac, 0xf8, 0xa5, 0x15, 0xe9, 0x0a, 0xaa, 0x1e, 0x9a,
|
||||
0xd7, 0x93, 0x6b, 0x28, 0xe4, 0x3b, 0xfd, 0x59, 0xc6, 0xed, 0x7c, 0x5f, 0xa5, 0x41, 0xcb, 0x51
|
||||
};
|
||||
|
||||
|
||||
// Test Transform() for 0 through 8 transformations.
|
||||
for (size_t i = 0; i <= 8; ++i) {
|
||||
uint32_t state[8];
|
||||
std::copy(init, init + 8, state);
|
||||
Transform(state, data + 1, i);
|
||||
if (!std::equal(state, state + 8, result[i])) return false;
|
||||
}
|
||||
|
||||
// Test TransformD64
|
||||
unsigned char out[32];
|
||||
TransformD64(out, data + 1);
|
||||
if (!std::equal(out, out + 32, result_d64)) return false;
|
||||
|
||||
// Test TransformD64_2way, if available.
|
||||
if (TransformD64_2way) {
|
||||
unsigned char out[64];
|
||||
TransformD64_2way(out, data + 1);
|
||||
if (!std::equal(out, out + 64, result_d64)) return false;
|
||||
}
|
||||
|
||||
// Test TransformD64_4way, if available.
|
||||
if (TransformD64_4way) {
|
||||
unsigned char out[128];
|
||||
TransformD64_4way(out, data + 1);
|
||||
if (!std::equal(out, out + 128, result_d64)) return false;
|
||||
}
|
||||
|
||||
// Test TransformD64_8way, if available.
|
||||
if (TransformD64_8way) {
|
||||
unsigned char out[256];
|
||||
TransformD64_8way(out, data + 1);
|
||||
if (!std::equal(out, out + 256, result_d64)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(USE_ASM) && (defined(__x86_64__) || defined(__amd64__) || defined(__i386__))
|
||||
/** Check whether the OS has enabled AVX registers. */
|
||||
bool AVXEnabled()
|
||||
{
|
||||
uint32_t a, d;
|
||||
__asm__("xgetbv" : "=a"(a), "=d"(d) : "c"(0));
|
||||
return (a & 6) == 6;
|
||||
}
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
|
||||
std::string SHA256AutoDetect()
|
||||
{
|
||||
std::string ret = "standard";
|
||||
#if defined(USE_ASM) && defined(HAVE_GETCPUID)
|
||||
bool have_sse4 = false;
|
||||
bool have_xsave = false;
|
||||
bool have_avx = false;
|
||||
bool have_avx2 = false;
|
||||
bool have_shani = false;
|
||||
bool enabled_avx = false;
|
||||
|
||||
(void)AVXEnabled;
|
||||
(void)have_sse4;
|
||||
(void)have_avx;
|
||||
(void)have_xsave;
|
||||
(void)have_avx2;
|
||||
(void)have_shani;
|
||||
(void)enabled_avx;
|
||||
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
GetCPUID(1, 0, eax, ebx, ecx, edx);
|
||||
have_sse4 = (ecx >> 19) & 1;
|
||||
have_xsave = (ecx >> 27) & 1;
|
||||
have_avx = (ecx >> 28) & 1;
|
||||
if (have_xsave && have_avx) {
|
||||
enabled_avx = AVXEnabled();
|
||||
}
|
||||
if (have_sse4) {
|
||||
GetCPUID(7, 0, eax, ebx, ecx, edx);
|
||||
have_avx2 = (ebx >> 5) & 1;
|
||||
have_shani = (ebx >> 29) & 1;
|
||||
}
|
||||
|
||||
#if defined(ENABLE_SHANI) && !defined(BUILD_VEXTA_INTERNAL)
|
||||
if (have_shani) {
|
||||
Transform = sha256_shani::Transform;
|
||||
TransformD64 = TransformD64Wrapper<sha256_shani::Transform>;
|
||||
TransformD64_2way = sha256d64_shani::Transform_2way;
|
||||
ret = "shani(1way,2way)";
|
||||
have_sse4 = false; // Disable SSE4/AVX2;
|
||||
have_avx2 = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (have_sse4) {
|
||||
#if defined(__x86_64__) || defined(__amd64__)
|
||||
Transform = sha256_sse4::Transform;
|
||||
TransformD64 = TransformD64Wrapper<sha256_sse4::Transform>;
|
||||
ret = "sse4(1way)";
|
||||
#endif
|
||||
#if defined(ENABLE_SSE41) && !defined(BUILD_VEXTA_INTERNAL)
|
||||
TransformD64_4way = sha256d64_sse41::Transform_4way;
|
||||
ret += ",sse41(4way)";
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(ENABLE_AVX2) && !defined(BUILD_VEXTA_INTERNAL)
|
||||
if (have_avx2 && have_avx && enabled_avx) {
|
||||
TransformD64_8way = sha256d64_avx2::Transform_8way;
|
||||
ret += ",avx2(8way)";
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
assert(SelfTest());
|
||||
return ret;
|
||||
}
|
||||
|
||||
////// SHA-256
|
||||
|
||||
CSHA256::CSHA256() : bytes(0)
|
||||
{
|
||||
sha256::Initialize(s);
|
||||
}
|
||||
|
||||
CSHA256& CSHA256::Write(const unsigned char* data, size_t len)
|
||||
{
|
||||
const unsigned char* end = data + len;
|
||||
size_t bufsize = bytes % 64;
|
||||
if (bufsize && bufsize + len >= 64) {
|
||||
// Fill the buffer, and process it.
|
||||
memcpy(buf + bufsize, data, 64 - bufsize);
|
||||
bytes += 64 - bufsize;
|
||||
data += 64 - bufsize;
|
||||
Transform(s, buf, 1);
|
||||
bufsize = 0;
|
||||
}
|
||||
if (end - data >= 64) {
|
||||
size_t blocks = (end - data) / 64;
|
||||
Transform(s, data, blocks);
|
||||
data += 64 * blocks;
|
||||
bytes += 64 * blocks;
|
||||
}
|
||||
if (end > data) {
|
||||
// Fill the buffer with what remains.
|
||||
memcpy(buf + bufsize, data, end - data);
|
||||
bytes += end - data;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CSHA256::Finalize(unsigned char hash[OUTPUT_SIZE])
|
||||
{
|
||||
static const unsigned char pad[64] = {0x80};
|
||||
unsigned char sizedesc[8];
|
||||
WriteBE64(sizedesc, bytes << 3);
|
||||
Write(pad, 1 + ((119 - (bytes % 64)) % 64));
|
||||
Write(sizedesc, 8);
|
||||
WriteBE32(hash, s[0]);
|
||||
WriteBE32(hash + 4, s[1]);
|
||||
WriteBE32(hash + 8, s[2]);
|
||||
WriteBE32(hash + 12, s[3]);
|
||||
WriteBE32(hash + 16, s[4]);
|
||||
WriteBE32(hash + 20, s[5]);
|
||||
WriteBE32(hash + 24, s[6]);
|
||||
WriteBE32(hash + 28, s[7]);
|
||||
}
|
||||
|
||||
CSHA256& CSHA256::Reset()
|
||||
{
|
||||
bytes = 0;
|
||||
sha256::Initialize(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SHA256D64(unsigned char* out, const unsigned char* in, size_t blocks)
|
||||
{
|
||||
if (TransformD64_8way) {
|
||||
while (blocks >= 8) {
|
||||
TransformD64_8way(out, in);
|
||||
out += 256;
|
||||
in += 512;
|
||||
blocks -= 8;
|
||||
}
|
||||
}
|
||||
if (TransformD64_4way) {
|
||||
while (blocks >= 4) {
|
||||
TransformD64_4way(out, in);
|
||||
out += 128;
|
||||
in += 256;
|
||||
blocks -= 4;
|
||||
}
|
||||
}
|
||||
if (TransformD64_2way) {
|
||||
while (blocks >= 2) {
|
||||
TransformD64_2way(out, in);
|
||||
out += 64;
|
||||
in += 128;
|
||||
blocks -= 2;
|
||||
}
|
||||
}
|
||||
while (blocks) {
|
||||
TransformD64(out, in);
|
||||
out += 32;
|
||||
in += 64;
|
||||
--blocks;
|
||||
}
|
||||
}
|
||||
42
src/crypto/sha256.h
Normal file
42
src/crypto/sha256.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef DIGIBYTE_CRYPTO_SHA256_H
|
||||
#define DIGIBYTE_CRYPTO_SHA256_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
|
||||
/** A hasher class for SHA-256. */
|
||||
class CSHA256
|
||||
{
|
||||
private:
|
||||
uint32_t s[8];
|
||||
unsigned char buf[64];
|
||||
size_t bytes;
|
||||
|
||||
public:
|
||||
static const size_t OUTPUT_SIZE = 32;
|
||||
|
||||
CSHA256();
|
||||
CSHA256& Write(const unsigned char* data, size_t len);
|
||||
void Finalize(unsigned char hash[OUTPUT_SIZE]);
|
||||
CSHA256& Reset();
|
||||
};
|
||||
|
||||
/** Autodetect the best available SHA256 implementation.
|
||||
* Returns the name of the implementation.
|
||||
*/
|
||||
std::string SHA256AutoDetect();
|
||||
|
||||
/** Compute multiple double-SHA256's of 64-byte blobs.
|
||||
* output: pointer to a blocks*32 byte output buffer
|
||||
* input: pointer to a blocks*64 byte input buffer
|
||||
* blocks: the number of hashes to compute.
|
||||
*/
|
||||
void SHA256D64(unsigned char* output, const unsigned char* input, size_t blocks);
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_SHA256_H
|
||||
411
src/crypto/sha256_Y.cpp
Normal file
411
src/crypto/sha256_Y.cpp
Normal file
|
|
@ -0,0 +1,411 @@
|
|||
/*-
|
||||
* Copyright 2005,2007,2009 Colin Percival
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sysendian.h"
|
||||
|
||||
#include "sha256_Y.h"
|
||||
|
||||
/*
|
||||
* Encode a length len/4 vector of (uint32_t) into a length len vector of
|
||||
* (unsigned char) in big-endian form. Assumes len is a multiple of 4.
|
||||
*/
|
||||
static void
|
||||
be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len / 4; i++)
|
||||
be32enc(dst + i * 4, src[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a big-endian length len vector of (unsigned char) into a length
|
||||
* len/4 vector of (uint32_t). Assumes len is a multiple of 4.
|
||||
*/
|
||||
static void
|
||||
be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len / 4; i++)
|
||||
dst[i] = be32dec(src + i * 4);
|
||||
}
|
||||
|
||||
/* Elementary functions used by SHA256 */
|
||||
#define Ch(x, y, z) ((x & (y ^ z)) ^ z)
|
||||
#define Maj(x, y, z) ((x & (y | z)) | (y & z))
|
||||
#define SHR(x, n) (x >> n)
|
||||
#define ROTR(x, n) ((x >> n) | (x << (32 - n)))
|
||||
#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22))
|
||||
#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25))
|
||||
#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3))
|
||||
#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10))
|
||||
|
||||
/* SHA256 round function */
|
||||
#define RND(a, b, c, d, e, f, g, h, k) \
|
||||
t0 = h + S1(e) + Ch(e, f, g) + k; \
|
||||
t1 = S0(a) + Maj(a, b, c); \
|
||||
d += t0; \
|
||||
h = t0 + t1;
|
||||
|
||||
/* Adjusted round function for rotating state */
|
||||
#define RNDr(S, W, i, k) \
|
||||
RND(S[(64 - i) % 8], S[(65 - i) % 8], \
|
||||
S[(66 - i) % 8], S[(67 - i) % 8], \
|
||||
S[(68 - i) % 8], S[(69 - i) % 8], \
|
||||
S[(70 - i) % 8], S[(71 - i) % 8], \
|
||||
W[i] + k)
|
||||
|
||||
/*
|
||||
* SHA256 block compression function. The 256-bit state is transformed via
|
||||
* the 512-bit input block to produce a new state.
|
||||
*/
|
||||
static void
|
||||
SHA256_Transform(uint32_t * state, const unsigned char block[64])
|
||||
{
|
||||
uint32_t W[64];
|
||||
uint32_t S[8];
|
||||
uint32_t t0, t1;
|
||||
int i;
|
||||
|
||||
/* 1. Prepare message schedule W. */
|
||||
be32dec_vect(W, block, 64);
|
||||
for (i = 16; i < 64; i++)
|
||||
W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16];
|
||||
|
||||
/* 2. Initialize working variables. */
|
||||
memcpy(S, state, 32);
|
||||
|
||||
/* 3. Mix. */
|
||||
RNDr(S, W, 0, 0x428a2f98);
|
||||
RNDr(S, W, 1, 0x71374491);
|
||||
RNDr(S, W, 2, 0xb5c0fbcf);
|
||||
RNDr(S, W, 3, 0xe9b5dba5);
|
||||
RNDr(S, W, 4, 0x3956c25b);
|
||||
RNDr(S, W, 5, 0x59f111f1);
|
||||
RNDr(S, W, 6, 0x923f82a4);
|
||||
RNDr(S, W, 7, 0xab1c5ed5);
|
||||
RNDr(S, W, 8, 0xd807aa98);
|
||||
RNDr(S, W, 9, 0x12835b01);
|
||||
RNDr(S, W, 10, 0x243185be);
|
||||
RNDr(S, W, 11, 0x550c7dc3);
|
||||
RNDr(S, W, 12, 0x72be5d74);
|
||||
RNDr(S, W, 13, 0x80deb1fe);
|
||||
RNDr(S, W, 14, 0x9bdc06a7);
|
||||
RNDr(S, W, 15, 0xc19bf174);
|
||||
RNDr(S, W, 16, 0xe49b69c1);
|
||||
RNDr(S, W, 17, 0xefbe4786);
|
||||
RNDr(S, W, 18, 0x0fc19dc6);
|
||||
RNDr(S, W, 19, 0x240ca1cc);
|
||||
RNDr(S, W, 20, 0x2de92c6f);
|
||||
RNDr(S, W, 21, 0x4a7484aa);
|
||||
RNDr(S, W, 22, 0x5cb0a9dc);
|
||||
RNDr(S, W, 23, 0x76f988da);
|
||||
RNDr(S, W, 24, 0x983e5152);
|
||||
RNDr(S, W, 25, 0xa831c66d);
|
||||
RNDr(S, W, 26, 0xb00327c8);
|
||||
RNDr(S, W, 27, 0xbf597fc7);
|
||||
RNDr(S, W, 28, 0xc6e00bf3);
|
||||
RNDr(S, W, 29, 0xd5a79147);
|
||||
RNDr(S, W, 30, 0x06ca6351);
|
||||
RNDr(S, W, 31, 0x14292967);
|
||||
RNDr(S, W, 32, 0x27b70a85);
|
||||
RNDr(S, W, 33, 0x2e1b2138);
|
||||
RNDr(S, W, 34, 0x4d2c6dfc);
|
||||
RNDr(S, W, 35, 0x53380d13);
|
||||
RNDr(S, W, 36, 0x650a7354);
|
||||
RNDr(S, W, 37, 0x766a0abb);
|
||||
RNDr(S, W, 38, 0x81c2c92e);
|
||||
RNDr(S, W, 39, 0x92722c85);
|
||||
RNDr(S, W, 40, 0xa2bfe8a1);
|
||||
RNDr(S, W, 41, 0xa81a664b);
|
||||
RNDr(S, W, 42, 0xc24b8b70);
|
||||
RNDr(S, W, 43, 0xc76c51a3);
|
||||
RNDr(S, W, 44, 0xd192e819);
|
||||
RNDr(S, W, 45, 0xd6990624);
|
||||
RNDr(S, W, 46, 0xf40e3585);
|
||||
RNDr(S, W, 47, 0x106aa070);
|
||||
RNDr(S, W, 48, 0x19a4c116);
|
||||
RNDr(S, W, 49, 0x1e376c08);
|
||||
RNDr(S, W, 50, 0x2748774c);
|
||||
RNDr(S, W, 51, 0x34b0bcb5);
|
||||
RNDr(S, W, 52, 0x391c0cb3);
|
||||
RNDr(S, W, 53, 0x4ed8aa4a);
|
||||
RNDr(S, W, 54, 0x5b9cca4f);
|
||||
RNDr(S, W, 55, 0x682e6ff3);
|
||||
RNDr(S, W, 56, 0x748f82ee);
|
||||
RNDr(S, W, 57, 0x78a5636f);
|
||||
RNDr(S, W, 58, 0x84c87814);
|
||||
RNDr(S, W, 59, 0x8cc70208);
|
||||
RNDr(S, W, 60, 0x90befffa);
|
||||
RNDr(S, W, 61, 0xa4506ceb);
|
||||
RNDr(S, W, 62, 0xbef9a3f7);
|
||||
RNDr(S, W, 63, 0xc67178f2);
|
||||
|
||||
/* 4. Mix local working variables into global state */
|
||||
for (i = 0; i < 8; i++)
|
||||
state[i] += S[i];
|
||||
|
||||
/* Clean the stack. */
|
||||
memset(W, 0, 256);
|
||||
memset(S, 0, 32);
|
||||
t0 = t1 = 0;
|
||||
}
|
||||
|
||||
static unsigned char PAD[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* Add padding and terminating bit-count. */
|
||||
static void
|
||||
SHA256_Pad(SHA256_CTX_Y * ctx)
|
||||
{
|
||||
unsigned char len[8];
|
||||
uint32_t r, plen;
|
||||
|
||||
/*
|
||||
* Convert length to a vector of bytes -- we do this now rather
|
||||
* than later because the length will change after we pad.
|
||||
*/
|
||||
be32enc_vect(len, ctx->count, 8);
|
||||
|
||||
/* Add 1--64 bytes so that the resulting length is 56 mod 64 */
|
||||
r = (ctx->count[1] >> 3) & 0x3f;
|
||||
plen = (r < 56) ? (56 - r) : (120 - r);
|
||||
SHA256_Update_Y(ctx, PAD, (size_t)plen);
|
||||
|
||||
/* Add the terminating bit-count */
|
||||
SHA256_Update_Y(ctx, len, 8);
|
||||
}
|
||||
|
||||
/* SHA-256 initialization. Begins a SHA-256 operation. */
|
||||
void
|
||||
SHA256_Init_Y(SHA256_CTX_Y * ctx)
|
||||
{
|
||||
|
||||
/* Zero bits processed so far */
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
|
||||
/* Magic initialization constants */
|
||||
ctx->state[0] = 0x6A09E667;
|
||||
ctx->state[1] = 0xBB67AE85;
|
||||
ctx->state[2] = 0x3C6EF372;
|
||||
ctx->state[3] = 0xA54FF53A;
|
||||
ctx->state[4] = 0x510E527F;
|
||||
ctx->state[5] = 0x9B05688C;
|
||||
ctx->state[6] = 0x1F83D9AB;
|
||||
ctx->state[7] = 0x5BE0CD19;
|
||||
}
|
||||
|
||||
/* Add bytes into the hash */
|
||||
void
|
||||
SHA256_Update_Y(SHA256_CTX_Y * ctx, const void *in, size_t len)
|
||||
{
|
||||
uint32_t bitlen[2];
|
||||
uint32_t r;
|
||||
const unsigned char *src = in;
|
||||
|
||||
/* Number of bytes left in the buffer from previous updates */
|
||||
r = (ctx->count[1] >> 3) & 0x3f;
|
||||
|
||||
/* Convert the length into a number of bits */
|
||||
bitlen[1] = ((uint32_t)len) << 3;
|
||||
bitlen[0] = (uint32_t)(len >> 29);
|
||||
|
||||
/* Update number of bits */
|
||||
if ((ctx->count[1] += bitlen[1]) < bitlen[1])
|
||||
ctx->count[0]++;
|
||||
ctx->count[0] += bitlen[0];
|
||||
|
||||
/* Handle the case where we don't need to perform any transforms */
|
||||
if (len < 64 - r) {
|
||||
memcpy(&ctx->buf[r], src, len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Finish the current block */
|
||||
memcpy(&ctx->buf[r], src, 64 - r);
|
||||
SHA256_Transform(ctx->state, ctx->buf);
|
||||
src += 64 - r;
|
||||
len -= 64 - r;
|
||||
|
||||
/* Perform complete blocks */
|
||||
while (len >= 64) {
|
||||
SHA256_Transform(ctx->state, src);
|
||||
src += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Copy left over data into buffer */
|
||||
memcpy(ctx->buf, src, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* SHA-256 finalization. Pads the input data, exports the hash value,
|
||||
* and clears the context state.
|
||||
*/
|
||||
void
|
||||
SHA256_Final_Y(unsigned char digest[32], SHA256_CTX_Y * ctx)
|
||||
{
|
||||
|
||||
/* Add padding */
|
||||
SHA256_Pad(ctx);
|
||||
|
||||
/* Write the hash */
|
||||
be32enc_vect(digest, ctx->state, 32);
|
||||
|
||||
/* Clear the context state */
|
||||
memset((void *)ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
|
||||
/* Initialize an HMAC-SHA256 operation with the given key. */
|
||||
void
|
||||
HMAC_SHA256_Init_Y(HMAC_SHA256_CTX_Y * ctx, const void * _K, size_t Klen)
|
||||
{
|
||||
unsigned char pad[64];
|
||||
unsigned char khash[32];
|
||||
const unsigned char * K = _K;
|
||||
size_t i;
|
||||
|
||||
/* If Klen > 64, the key is really SHA256(K). */
|
||||
if (Klen > 64) {
|
||||
SHA256_Init_Y(&ctx->ictx);
|
||||
SHA256_Update_Y(&ctx->ictx, K, Klen);
|
||||
SHA256_Final_Y(khash, &ctx->ictx);
|
||||
K = khash;
|
||||
Klen = 32;
|
||||
}
|
||||
|
||||
/* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */
|
||||
SHA256_Init_Y(&ctx->ictx);
|
||||
memset(pad, 0x36, 64);
|
||||
for (i = 0; i < Klen; i++)
|
||||
pad[i] ^= K[i];
|
||||
SHA256_Update_Y(&ctx->ictx, pad, 64);
|
||||
|
||||
/* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */
|
||||
SHA256_Init_Y(&ctx->octx);
|
||||
memset(pad, 0x5c, 64);
|
||||
for (i = 0; i < Klen; i++)
|
||||
pad[i] ^= K[i];
|
||||
SHA256_Update_Y(&ctx->octx, pad, 64);
|
||||
|
||||
/* Clean the stack. */
|
||||
memset(khash, 0, 32);
|
||||
}
|
||||
|
||||
/* Add bytes to the HMAC-SHA256 operation. */
|
||||
void
|
||||
HMAC_SHA256_Update_Y(HMAC_SHA256_CTX_Y * ctx, const void *in, size_t len)
|
||||
{
|
||||
|
||||
/* Feed data to the inner SHA256 operation. */
|
||||
SHA256_Update_Y(&ctx->ictx, in, len);
|
||||
}
|
||||
|
||||
/* Finish an HMAC-SHA256 operation. */
|
||||
void
|
||||
HMAC_SHA256_Final_Y(unsigned char digest[32], HMAC_SHA256_CTX_Y * ctx)
|
||||
{
|
||||
unsigned char ihash[32];
|
||||
|
||||
/* Finish the inner SHA256 operation. */
|
||||
SHA256_Final_Y(ihash, &ctx->ictx);
|
||||
|
||||
/* Feed the inner hash to the outer SHA256 operation. */
|
||||
SHA256_Update_Y(&ctx->octx, ihash, 32);
|
||||
|
||||
/* Finish the outer SHA256 operation. */
|
||||
SHA256_Final_Y(digest, &ctx->octx);
|
||||
|
||||
/* Clean the stack. */
|
||||
memset(ihash, 0, 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
|
||||
* Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
|
||||
* write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
|
||||
*/
|
||||
void
|
||||
PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt,
|
||||
size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen)
|
||||
{
|
||||
HMAC_SHA256_CTX_Y PShctx, hctx;
|
||||
size_t i;
|
||||
uint8_t ivec[4];
|
||||
uint8_t U[32];
|
||||
uint8_t T[32];
|
||||
uint64_t j;
|
||||
int k;
|
||||
size_t clen;
|
||||
|
||||
/* Compute HMAC state after processing P and S. */
|
||||
HMAC_SHA256_Init_Y(&PShctx, passwd, passwdlen);
|
||||
HMAC_SHA256_Update_Y(&PShctx, salt, saltlen);
|
||||
|
||||
/* Iterate through the blocks. */
|
||||
for (i = 0; i * 32 < dkLen; i++) {
|
||||
/* Generate INT(i + 1). */
|
||||
be32enc(ivec, (uint32_t)(i + 1));
|
||||
|
||||
/* Compute U_1 = PRF(P, S || INT(i)). */
|
||||
memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX_Y));
|
||||
HMAC_SHA256_Update_Y(&hctx, ivec, 4);
|
||||
HMAC_SHA256_Final_Y(U, &hctx);
|
||||
|
||||
/* T_i = U_1 ... */
|
||||
memcpy(T, U, 32);
|
||||
|
||||
for (j = 2; j <= c; j++) {
|
||||
/* Compute U_j. */
|
||||
HMAC_SHA256_Init_Y(&hctx, passwd, passwdlen);
|
||||
HMAC_SHA256_Update_Y(&hctx, U, 32);
|
||||
HMAC_SHA256_Final_Y(U, &hctx);
|
||||
|
||||
/* ... xor U_j ... */
|
||||
for (k = 0; k < 32; k++)
|
||||
T[k] ^= U[k];
|
||||
}
|
||||
|
||||
/* Copy as many bytes as necessary into buf. */
|
||||
clen = dkLen - i * 32;
|
||||
if (clen > 32)
|
||||
clen = 32;
|
||||
memcpy(&buf[i * 32], T, clen);
|
||||
}
|
||||
|
||||
/* Clean PShctx, since we never called _Final on it. */
|
||||
memset(&PShctx, 0, sizeof(HMAC_SHA256_CTX_Y));
|
||||
}
|
||||
62
src/crypto/sha256_Y.h
Normal file
62
src/crypto/sha256_Y.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*-
|
||||
* Copyright 2005,2007,2009 Colin Percival
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: src/lib/libmd/sha256_Y.h,v 1.2 2006/01/17 15:35:56 phk Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SHA256_H_
|
||||
#define _SHA256_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct SHA256Context {
|
||||
uint32_t state[8];
|
||||
uint32_t count[2];
|
||||
unsigned char buf[64];
|
||||
} SHA256_CTX_Y;
|
||||
|
||||
typedef struct HMAC_SHA256Context {
|
||||
SHA256_CTX_Y ictx;
|
||||
SHA256_CTX_Y octx;
|
||||
} HMAC_SHA256_CTX_Y;
|
||||
|
||||
void SHA256_Init_Y(SHA256_CTX_Y *);
|
||||
void SHA256_Update_Y(SHA256_CTX_Y *, const void *, size_t);
|
||||
void SHA256_Final_Y(unsigned char [32], SHA256_CTX_Y *);
|
||||
void HMAC_SHA256_Init_Y(HMAC_SHA256_CTX_Y *, const void *, size_t);
|
||||
void HMAC_SHA256_Update_Y(HMAC_SHA256_CTX_Y *, const void *, size_t);
|
||||
void HMAC_SHA256_Final_Y(unsigned char [32], HMAC_SHA256_CTX_Y *);
|
||||
|
||||
/**
|
||||
* PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen):
|
||||
* Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and
|
||||
* write the output to buf. The value dkLen must be at most 32 * (2^32 - 1).
|
||||
*/
|
||||
void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t,
|
||||
uint64_t, uint8_t *, size_t);
|
||||
|
||||
#endif /* !_SHA256_H_ */
|
||||
328
src/crypto/sha256_avx2.cpp
Normal file
328
src/crypto/sha256_avx2.cpp
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
// Copyright (c) 2017-2019 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifdef ENABLE_AVX2
|
||||
|
||||
#include <stdint.h>
|
||||
#include <immintrin.h>
|
||||
|
||||
#include <crypto/common.h>
|
||||
|
||||
namespace sha256d64_avx2 {
|
||||
namespace {
|
||||
|
||||
__m256i inline K(uint32_t x) { return _mm256_set1_epi32(x); }
|
||||
|
||||
__m256i inline Add(__m256i x, __m256i y) { return _mm256_add_epi32(x, y); }
|
||||
__m256i inline Add(__m256i x, __m256i y, __m256i z) { return Add(Add(x, y), z); }
|
||||
__m256i inline Add(__m256i x, __m256i y, __m256i z, __m256i w) { return Add(Add(x, y), Add(z, w)); }
|
||||
__m256i inline Add(__m256i x, __m256i y, __m256i z, __m256i w, __m256i v) { return Add(Add(x, y, z), Add(w, v)); }
|
||||
__m256i inline Inc(__m256i& x, __m256i y) { x = Add(x, y); return x; }
|
||||
__m256i inline Inc(__m256i& x, __m256i y, __m256i z) { x = Add(x, y, z); return x; }
|
||||
__m256i inline Inc(__m256i& x, __m256i y, __m256i z, __m256i w) { x = Add(x, y, z, w); return x; }
|
||||
__m256i inline Xor(__m256i x, __m256i y) { return _mm256_xor_si256(x, y); }
|
||||
__m256i inline Xor(__m256i x, __m256i y, __m256i z) { return Xor(Xor(x, y), z); }
|
||||
__m256i inline Or(__m256i x, __m256i y) { return _mm256_or_si256(x, y); }
|
||||
__m256i inline And(__m256i x, __m256i y) { return _mm256_and_si256(x, y); }
|
||||
__m256i inline ShR(__m256i x, int n) { return _mm256_srli_epi32(x, n); }
|
||||
__m256i inline ShL(__m256i x, int n) { return _mm256_slli_epi32(x, n); }
|
||||
|
||||
__m256i inline Ch(__m256i x, __m256i y, __m256i z) { return Xor(z, And(x, Xor(y, z))); }
|
||||
__m256i inline Maj(__m256i x, __m256i y, __m256i z) { return Or(And(x, y), And(z, Or(x, y))); }
|
||||
__m256i inline Sigma0(__m256i x) { return Xor(Or(ShR(x, 2), ShL(x, 30)), Or(ShR(x, 13), ShL(x, 19)), Or(ShR(x, 22), ShL(x, 10))); }
|
||||
__m256i inline Sigma1(__m256i x) { return Xor(Or(ShR(x, 6), ShL(x, 26)), Or(ShR(x, 11), ShL(x, 21)), Or(ShR(x, 25), ShL(x, 7))); }
|
||||
__m256i inline sigma0(__m256i x) { return Xor(Or(ShR(x, 7), ShL(x, 25)), Or(ShR(x, 18), ShL(x, 14)), ShR(x, 3)); }
|
||||
__m256i inline sigma1(__m256i x) { return Xor(Or(ShR(x, 17), ShL(x, 15)), Or(ShR(x, 19), ShL(x, 13)), ShR(x, 10)); }
|
||||
|
||||
/** One round of SHA-256. */
|
||||
void inline __attribute__((always_inline)) Round(__m256i a, __m256i b, __m256i c, __m256i& d, __m256i e, __m256i f, __m256i g, __m256i& h, __m256i k)
|
||||
{
|
||||
__m256i t1 = Add(h, Sigma1(e), Ch(e, f, g), k);
|
||||
__m256i t2 = Add(Sigma0(a), Maj(a, b, c));
|
||||
d = Add(d, t1);
|
||||
h = Add(t1, t2);
|
||||
}
|
||||
|
||||
__m256i inline Read8(const unsigned char* chunk, int offset) {
|
||||
__m256i ret = _mm256_set_epi32(
|
||||
ReadLE32(chunk + 0 + offset),
|
||||
ReadLE32(chunk + 64 + offset),
|
||||
ReadLE32(chunk + 128 + offset),
|
||||
ReadLE32(chunk + 192 + offset),
|
||||
ReadLE32(chunk + 256 + offset),
|
||||
ReadLE32(chunk + 320 + offset),
|
||||
ReadLE32(chunk + 384 + offset),
|
||||
ReadLE32(chunk + 448 + offset)
|
||||
);
|
||||
return _mm256_shuffle_epi8(ret, _mm256_set_epi32(0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL, 0x00010203UL, 0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL, 0x00010203UL));
|
||||
}
|
||||
|
||||
void inline Write8(unsigned char* out, int offset, __m256i v) {
|
||||
v = _mm256_shuffle_epi8(v, _mm256_set_epi32(0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL, 0x00010203UL, 0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL, 0x00010203UL));
|
||||
WriteLE32(out + 0 + offset, _mm256_extract_epi32(v, 7));
|
||||
WriteLE32(out + 32 + offset, _mm256_extract_epi32(v, 6));
|
||||
WriteLE32(out + 64 + offset, _mm256_extract_epi32(v, 5));
|
||||
WriteLE32(out + 96 + offset, _mm256_extract_epi32(v, 4));
|
||||
WriteLE32(out + 128 + offset, _mm256_extract_epi32(v, 3));
|
||||
WriteLE32(out + 160 + offset, _mm256_extract_epi32(v, 2));
|
||||
WriteLE32(out + 192 + offset, _mm256_extract_epi32(v, 1));
|
||||
WriteLE32(out + 224 + offset, _mm256_extract_epi32(v, 0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Transform_8way(unsigned char* out, const unsigned char* in)
|
||||
{
|
||||
// Transform 1
|
||||
__m256i a = K(0x6a09e667ul);
|
||||
__m256i b = K(0xbb67ae85ul);
|
||||
__m256i c = K(0x3c6ef372ul);
|
||||
__m256i d = K(0xa54ff53aul);
|
||||
__m256i e = K(0x510e527ful);
|
||||
__m256i f = K(0x9b05688cul);
|
||||
__m256i g = K(0x1f83d9abul);
|
||||
__m256i h = K(0x5be0cd19ul);
|
||||
|
||||
__m256i w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x428a2f98ul), w0 = Read8(in, 0)));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x71374491ul), w1 = Read8(in, 4)));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0xb5c0fbcful), w2 = Read8(in, 8)));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0xe9b5dba5ul), w3 = Read8(in, 12)));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x3956c25bul), w4 = Read8(in, 16)));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x59f111f1ul), w5 = Read8(in, 20)));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x923f82a4ul), w6 = Read8(in, 24)));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0xab1c5ed5ul), w7 = Read8(in, 28)));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0xd807aa98ul), w8 = Read8(in, 32)));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x12835b01ul), w9 = Read8(in, 36)));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x243185beul), w10 = Read8(in, 40)));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x550c7dc3ul), w11 = Read8(in, 44)));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x72be5d74ul), w12 = Read8(in, 48)));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x80deb1feul), w13 = Read8(in, 52)));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x9bdc06a7ul), w14 = Read8(in, 56)));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0xc19bf174ul), w15 = Read8(in, 60)));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0xe49b69c1ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0xefbe4786ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x0fc19dc6ul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x240ca1ccul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x2de92c6ful), Inc(w4, sigma1(w2), w13, sigma0(w5))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x4a7484aaul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x5cb0a9dcul), Inc(w6, sigma1(w4), w15, sigma0(w7))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x76f988daul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x983e5152ul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0xa831c66dul), Inc(w9, sigma1(w7), w2, sigma0(w10))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0xb00327c8ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0xbf597fc7ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0xc6e00bf3ul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0xd5a79147ul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x06ca6351ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x14292967ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x27b70a85ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x2e1b2138ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x4d2c6dfcul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x53380d13ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x650a7354ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x766a0abbul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x81c2c92eul), Inc(w6, sigma1(w4), w15, sigma0(w7))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x92722c85ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0xa2bfe8a1ul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0xa81a664bul), Inc(w9, sigma1(w7), w2, sigma0(w10))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0xc24b8b70ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0xc76c51a3ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0xd192e819ul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0xd6990624ul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0xf40e3585ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x106aa070ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x19a4c116ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x1e376c08ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x2748774cul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x34b0bcb5ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x391c0cb3ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x4ed8aa4aul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x5b9cca4ful), Inc(w6, sigma1(w4), w15, sigma0(w7))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x682e6ff3ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x748f82eeul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x78a5636ful), Inc(w9, sigma1(w7), w2, sigma0(w10))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x84c87814ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x8cc70208ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x90befffaul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0xa4506cebul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0xbef9a3f7ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0xc67178f2ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
|
||||
|
||||
a = Add(a, K(0x6a09e667ul));
|
||||
b = Add(b, K(0xbb67ae85ul));
|
||||
c = Add(c, K(0x3c6ef372ul));
|
||||
d = Add(d, K(0xa54ff53aul));
|
||||
e = Add(e, K(0x510e527ful));
|
||||
f = Add(f, K(0x9b05688cul));
|
||||
g = Add(g, K(0x1f83d9abul));
|
||||
h = Add(h, K(0x5be0cd19ul));
|
||||
|
||||
__m256i t0 = a, t1 = b, t2 = c, t3 = d, t4 = e, t5 = f, t6 = g, t7 = h;
|
||||
|
||||
// Transform 2
|
||||
Round(a, b, c, d, e, f, g, h, K(0xc28a2f98ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0x71374491ul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0xb5c0fbcful));
|
||||
Round(f, g, h, a, b, c, d, e, K(0xe9b5dba5ul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x3956c25bul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0x59f111f1ul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0x923f82a4ul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0xab1c5ed5ul));
|
||||
Round(a, b, c, d, e, f, g, h, K(0xd807aa98ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0x12835b01ul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0x243185beul));
|
||||
Round(f, g, h, a, b, c, d, e, K(0x550c7dc3ul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x72be5d74ul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0x80deb1feul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0x9bdc06a7ul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0xc19bf374ul));
|
||||
Round(a, b, c, d, e, f, g, h, K(0x649b69c1ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0xf0fe4786ul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0x0fe1edc6ul));
|
||||
Round(f, g, h, a, b, c, d, e, K(0x240cf254ul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x4fe9346ful));
|
||||
Round(d, e, f, g, h, a, b, c, K(0x6cc984beul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0x61b9411eul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0x16f988faul));
|
||||
Round(a, b, c, d, e, f, g, h, K(0xf2c65152ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0xa88e5a6dul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0xb019fc65ul));
|
||||
Round(f, g, h, a, b, c, d, e, K(0xb9d99ec7ul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x9a1231c3ul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0xe70eeaa0ul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0xfdb1232bul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0xc7353eb0ul));
|
||||
Round(a, b, c, d, e, f, g, h, K(0x3069bad5ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0xcb976d5ful));
|
||||
Round(g, h, a, b, c, d, e, f, K(0x5a0f118ful));
|
||||
Round(f, g, h, a, b, c, d, e, K(0xdc1eeefdul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x0a35b689ul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0xde0b7a04ul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0x58f4ca9dul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0xe15d5b16ul));
|
||||
Round(a, b, c, d, e, f, g, h, K(0x007f3e86ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0x37088980ul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0xa507ea32ul));
|
||||
Round(f, g, h, a, b, c, d, e, K(0x6fab9537ul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x17406110ul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0x0d8cd6f1ul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0xcdaa3b6dul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0xc0bbbe37ul));
|
||||
Round(a, b, c, d, e, f, g, h, K(0x83613bdaul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0xdb48a363ul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0x0b02e931ul));
|
||||
Round(f, g, h, a, b, c, d, e, K(0x6fd15ca7ul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x521afacaul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0x31338431ul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0x6ed41a95ul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0x6d437890ul));
|
||||
Round(a, b, c, d, e, f, g, h, K(0xc39c91f2ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0x9eccabbdul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0xb5c9a0e6ul));
|
||||
Round(f, g, h, a, b, c, d, e, K(0x532fb63cul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0xd2c741c6ul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0x07237ea3ul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0xa4954b68ul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0x4c191d76ul));
|
||||
|
||||
w0 = Add(t0, a);
|
||||
w1 = Add(t1, b);
|
||||
w2 = Add(t2, c);
|
||||
w3 = Add(t3, d);
|
||||
w4 = Add(t4, e);
|
||||
w5 = Add(t5, f);
|
||||
w6 = Add(t6, g);
|
||||
w7 = Add(t7, h);
|
||||
|
||||
// Transform 3
|
||||
a = K(0x6a09e667ul);
|
||||
b = K(0xbb67ae85ul);
|
||||
c = K(0x3c6ef372ul);
|
||||
d = K(0xa54ff53aul);
|
||||
e = K(0x510e527ful);
|
||||
f = K(0x9b05688cul);
|
||||
g = K(0x1f83d9abul);
|
||||
h = K(0x5be0cd19ul);
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x428a2f98ul), w0));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x71374491ul), w1));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0xb5c0fbcful), w2));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0xe9b5dba5ul), w3));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x3956c25bul), w4));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x59f111f1ul), w5));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x923f82a4ul), w6));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0xab1c5ed5ul), w7));
|
||||
Round(a, b, c, d, e, f, g, h, K(0x5807aa98ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0x12835b01ul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0x243185beul));
|
||||
Round(f, g, h, a, b, c, d, e, K(0x550c7dc3ul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x72be5d74ul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0x80deb1feul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0x9bdc06a7ul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0xc19bf274ul));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0xe49b69c1ul), Inc(w0, sigma0(w1))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0xefbe4786ul), Inc(w1, K(0xa00000ul), sigma0(w2))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x0fc19dc6ul), Inc(w2, sigma1(w0), sigma0(w3))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x240ca1ccul), Inc(w3, sigma1(w1), sigma0(w4))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x2de92c6ful), Inc(w4, sigma1(w2), sigma0(w5))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x4a7484aaul), Inc(w5, sigma1(w3), sigma0(w6))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x5cb0a9dcul), Inc(w6, sigma1(w4), K(0x100ul), sigma0(w7))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x76f988daul), Inc(w7, sigma1(w5), w0, K(0x11002000ul))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x983e5152ul), w8 = Add(K(0x80000000ul), sigma1(w6), w1)));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0xa831c66dul), w9 = Add(sigma1(w7), w2)));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0xb00327c8ul), w10 = Add(sigma1(w8), w3)));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0xbf597fc7ul), w11 = Add(sigma1(w9), w4)));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0xc6e00bf3ul), w12 = Add(sigma1(w10), w5)));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0xd5a79147ul), w13 = Add(sigma1(w11), w6)));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x06ca6351ul), w14 = Add(sigma1(w12), w7, K(0x400022ul))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x14292967ul), w15 = Add(K(0x100ul), sigma1(w13), w8, sigma0(w0))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x27b70a85ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x2e1b2138ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x4d2c6dfcul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x53380d13ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x650a7354ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x766a0abbul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x81c2c92eul), Inc(w6, sigma1(w4), w15, sigma0(w7))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x92722c85ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0xa2bfe8a1ul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0xa81a664bul), Inc(w9, sigma1(w7), w2, sigma0(w10))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0xc24b8b70ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0xc76c51a3ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0xd192e819ul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0xd6990624ul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0xf40e3585ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x106aa070ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x19a4c116ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x1e376c08ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x2748774cul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x34b0bcb5ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x391c0cb3ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x4ed8aa4aul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x5b9cca4ful), Inc(w6, sigma1(w4), w15, sigma0(w7))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x682e6ff3ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x748f82eeul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x78a5636ful), Inc(w9, sigma1(w7), w2, sigma0(w10))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x84c87814ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x8cc70208ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x90befffaul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0xa4506cebul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0xbef9a3f7ul), w14, sigma1(w12), w7, sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0xc67178f2ul), w15, sigma1(w13), w8, sigma0(w0)));
|
||||
|
||||
// Output
|
||||
Write8(out, 0, Add(a, K(0x6a09e667ul)));
|
||||
Write8(out, 4, Add(b, K(0xbb67ae85ul)));
|
||||
Write8(out, 8, Add(c, K(0x3c6ef372ul)));
|
||||
Write8(out, 12, Add(d, K(0xa54ff53aul)));
|
||||
Write8(out, 16, Add(e, K(0x510e527ful)));
|
||||
Write8(out, 20, Add(f, K(0x9b05688cul)));
|
||||
Write8(out, 24, Add(g, K(0x1f83d9abul)));
|
||||
Write8(out, 28, Add(h, K(0x5be0cd19ul)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
357
src/crypto/sha256_shani.cpp
Normal file
357
src/crypto/sha256_shani.cpp
Normal file
|
|
@ -0,0 +1,357 @@
|
|||
// Copyright (c) 2018-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2018-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
//
|
||||
// Based on https://github.com/noloader/SHA-Intrinsics/blob/master/sha256-x86.c,
|
||||
// Written and placed in public domain by Jeffrey Walton.
|
||||
// Based on code from Intel, and by Sean Gulley for the miTLS project.
|
||||
|
||||
#ifdef ENABLE_SHANI
|
||||
|
||||
#include <stdint.h>
|
||||
#include <immintrin.h>
|
||||
|
||||
namespace {
|
||||
|
||||
alignas(__m128i) const uint8_t MASK[16] = {0x03, 0x02, 0x01, 0x00, 0x07, 0x06, 0x05, 0x04, 0x0b, 0x0a, 0x09, 0x08, 0x0f, 0x0e, 0x0d, 0x0c};
|
||||
alignas(__m128i) const uint8_t INIT0[16] = {0x8c, 0x68, 0x05, 0x9b, 0x7f, 0x52, 0x0e, 0x51, 0x85, 0xae, 0x67, 0xbb, 0x67, 0xe6, 0x09, 0x6a};
|
||||
alignas(__m128i) const uint8_t INIT1[16] = {0x19, 0xcd, 0xe0, 0x5b, 0xab, 0xd9, 0x83, 0x1f, 0x3a, 0xf5, 0x4f, 0xa5, 0x72, 0xf3, 0x6e, 0x3c};
|
||||
|
||||
void inline __attribute__((always_inline)) QuadRound(__m128i& state0, __m128i& state1, uint64_t k1, uint64_t k0)
|
||||
{
|
||||
const __m128i msg = _mm_set_epi64x(k1, k0);
|
||||
state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
|
||||
state0 = _mm_sha256rnds2_epu32(state0, state1, _mm_shuffle_epi32(msg, 0x0e));
|
||||
}
|
||||
|
||||
void inline __attribute__((always_inline)) QuadRound(__m128i& state0, __m128i& state1, __m128i m, uint64_t k1, uint64_t k0)
|
||||
{
|
||||
const __m128i msg = _mm_add_epi32(m, _mm_set_epi64x(k1, k0));
|
||||
state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
|
||||
state0 = _mm_sha256rnds2_epu32(state0, state1, _mm_shuffle_epi32(msg, 0x0e));
|
||||
}
|
||||
|
||||
void inline __attribute__((always_inline)) ShiftMessageA(__m128i& m0, __m128i m1)
|
||||
{
|
||||
m0 = _mm_sha256msg1_epu32(m0, m1);
|
||||
}
|
||||
|
||||
void inline __attribute__((always_inline)) ShiftMessageC(__m128i& m0, __m128i m1, __m128i& m2)
|
||||
{
|
||||
m2 = _mm_sha256msg2_epu32(_mm_add_epi32(m2, _mm_alignr_epi8(m1, m0, 4)), m1);
|
||||
}
|
||||
|
||||
void inline __attribute__((always_inline)) ShiftMessageB(__m128i& m0, __m128i m1, __m128i& m2)
|
||||
{
|
||||
ShiftMessageC(m0, m1, m2);
|
||||
ShiftMessageA(m0, m1);
|
||||
}
|
||||
|
||||
void inline __attribute__((always_inline)) Shuffle(__m128i& s0, __m128i& s1)
|
||||
{
|
||||
const __m128i t1 = _mm_shuffle_epi32(s0, 0xB1);
|
||||
const __m128i t2 = _mm_shuffle_epi32(s1, 0x1B);
|
||||
s0 = _mm_alignr_epi8(t1, t2, 0x08);
|
||||
s1 = _mm_blend_epi16(t2, t1, 0xF0);
|
||||
}
|
||||
|
||||
void inline __attribute__((always_inline)) Unshuffle(__m128i& s0, __m128i& s1)
|
||||
{
|
||||
const __m128i t1 = _mm_shuffle_epi32(s0, 0x1B);
|
||||
const __m128i t2 = _mm_shuffle_epi32(s1, 0xB1);
|
||||
s0 = _mm_blend_epi16(t1, t2, 0xF0);
|
||||
s1 = _mm_alignr_epi8(t2, t1, 0x08);
|
||||
}
|
||||
|
||||
__m128i inline __attribute__((always_inline)) Load(const unsigned char* in)
|
||||
{
|
||||
return _mm_shuffle_epi8(_mm_loadu_si128((const __m128i*)in), _mm_load_si128((const __m128i*)MASK));
|
||||
}
|
||||
|
||||
void inline __attribute__((always_inline)) Save(unsigned char* out, __m128i s)
|
||||
{
|
||||
_mm_storeu_si128((__m128i*)out, _mm_shuffle_epi8(s, _mm_load_si128((const __m128i*)MASK)));
|
||||
}
|
||||
}
|
||||
|
||||
namespace sha256_shani {
|
||||
void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks)
|
||||
{
|
||||
__m128i m0, m1, m2, m3, s0, s1, so0, so1;
|
||||
|
||||
/* Load state */
|
||||
s0 = _mm_loadu_si128((const __m128i*)s);
|
||||
s1 = _mm_loadu_si128((const __m128i*)(s + 4));
|
||||
Shuffle(s0, s1);
|
||||
|
||||
while (blocks--) {
|
||||
/* Remember old state */
|
||||
so0 = s0;
|
||||
so1 = s1;
|
||||
|
||||
/* Load data and transform */
|
||||
m0 = Load(chunk);
|
||||
QuadRound(s0, s1, m0, 0xe9b5dba5b5c0fbcfull, 0x71374491428a2f98ull);
|
||||
m1 = Load(chunk + 16);
|
||||
QuadRound(s0, s1, m1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull);
|
||||
ShiftMessageA(m0, m1);
|
||||
m2 = Load(chunk + 32);
|
||||
QuadRound(s0, s1, m2, 0x550c7dc3243185beull, 0x12835b01d807aa98ull);
|
||||
ShiftMessageA(m1, m2);
|
||||
m3 = Load(chunk + 48);
|
||||
QuadRound(s0, s1, m3, 0xc19bf1749bdc06a7ull, 0x80deb1fe72be5d74ull);
|
||||
ShiftMessageB(m2, m3, m0);
|
||||
QuadRound(s0, s1, m0, 0x240ca1cc0fc19dc6ull, 0xefbe4786E49b69c1ull);
|
||||
ShiftMessageB(m3, m0, m1);
|
||||
QuadRound(s0, s1, m1, 0x76f988da5cb0a9dcull, 0x4a7484aa2de92c6full);
|
||||
ShiftMessageB(m0, m1, m2);
|
||||
QuadRound(s0, s1, m2, 0xbf597fc7b00327c8ull, 0xa831c66d983e5152ull);
|
||||
ShiftMessageB(m1, m2, m3);
|
||||
QuadRound(s0, s1, m3, 0x1429296706ca6351ull, 0xd5a79147c6e00bf3ull);
|
||||
ShiftMessageB(m2, m3, m0);
|
||||
QuadRound(s0, s1, m0, 0x53380d134d2c6dfcull, 0x2e1b213827b70a85ull);
|
||||
ShiftMessageB(m3, m0, m1);
|
||||
QuadRound(s0, s1, m1, 0x92722c8581c2c92eull, 0x766a0abb650a7354ull);
|
||||
ShiftMessageB(m0, m1, m2);
|
||||
QuadRound(s0, s1, m2, 0xc76c51A3c24b8b70ull, 0xa81a664ba2bfe8a1ull);
|
||||
ShiftMessageB(m1, m2, m3);
|
||||
QuadRound(s0, s1, m3, 0x106aa070f40e3585ull, 0xd6990624d192e819ull);
|
||||
ShiftMessageB(m2, m3, m0);
|
||||
QuadRound(s0, s1, m0, 0x34b0bcb52748774cull, 0x1e376c0819a4c116ull);
|
||||
ShiftMessageB(m3, m0, m1);
|
||||
QuadRound(s0, s1, m1, 0x682e6ff35b9cca4full, 0x4ed8aa4a391c0cb3ull);
|
||||
ShiftMessageC(m0, m1, m2);
|
||||
QuadRound(s0, s1, m2, 0x8cc7020884c87814ull, 0x78a5636f748f82eeull);
|
||||
ShiftMessageC(m1, m2, m3);
|
||||
QuadRound(s0, s1, m3, 0xc67178f2bef9A3f7ull, 0xa4506ceb90befffaull);
|
||||
|
||||
/* Combine with old state */
|
||||
s0 = _mm_add_epi32(s0, so0);
|
||||
s1 = _mm_add_epi32(s1, so1);
|
||||
|
||||
/* Advance */
|
||||
chunk += 64;
|
||||
}
|
||||
|
||||
Unshuffle(s0, s1);
|
||||
_mm_storeu_si128((__m128i*)s, s0);
|
||||
_mm_storeu_si128((__m128i*)(s + 4), s1);
|
||||
}
|
||||
}
|
||||
|
||||
namespace sha256d64_shani {
|
||||
|
||||
void Transform_2way(unsigned char* out, const unsigned char* in)
|
||||
{
|
||||
__m128i am0, am1, am2, am3, as0, as1, aso0, aso1;
|
||||
__m128i bm0, bm1, bm2, bm3, bs0, bs1, bso0, bso1;
|
||||
|
||||
/* Transform 1 */
|
||||
bs0 = as0 = _mm_load_si128((const __m128i*)INIT0);
|
||||
bs1 = as1 = _mm_load_si128((const __m128i*)INIT1);
|
||||
am0 = Load(in);
|
||||
bm0 = Load(in + 64);
|
||||
QuadRound(as0, as1, am0, 0xe9b5dba5b5c0fbcfull, 0x71374491428a2f98ull);
|
||||
QuadRound(bs0, bs1, bm0, 0xe9b5dba5b5c0fbcfull, 0x71374491428a2f98ull);
|
||||
am1 = Load(in + 16);
|
||||
bm1 = Load(in + 80);
|
||||
QuadRound(as0, as1, am1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull);
|
||||
QuadRound(bs0, bs1, bm1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull);
|
||||
ShiftMessageA(am0, am1);
|
||||
ShiftMessageA(bm0, bm1);
|
||||
am2 = Load(in + 32);
|
||||
bm2 = Load(in + 96);
|
||||
QuadRound(as0, as1, am2, 0x550c7dc3243185beull, 0x12835b01d807aa98ull);
|
||||
QuadRound(bs0, bs1, bm2, 0x550c7dc3243185beull, 0x12835b01d807aa98ull);
|
||||
ShiftMessageA(am1, am2);
|
||||
ShiftMessageA(bm1, bm2);
|
||||
am3 = Load(in + 48);
|
||||
bm3 = Load(in + 112);
|
||||
QuadRound(as0, as1, am3, 0xc19bf1749bdc06a7ull, 0x80deb1fe72be5d74ull);
|
||||
QuadRound(bs0, bs1, bm3, 0xc19bf1749bdc06a7ull, 0x80deb1fe72be5d74ull);
|
||||
ShiftMessageB(am2, am3, am0);
|
||||
ShiftMessageB(bm2, bm3, bm0);
|
||||
QuadRound(as0, as1, am0, 0x240ca1cc0fc19dc6ull, 0xefbe4786E49b69c1ull);
|
||||
QuadRound(bs0, bs1, bm0, 0x240ca1cc0fc19dc6ull, 0xefbe4786E49b69c1ull);
|
||||
ShiftMessageB(am3, am0, am1);
|
||||
ShiftMessageB(bm3, bm0, bm1);
|
||||
QuadRound(as0, as1, am1, 0x76f988da5cb0a9dcull, 0x4a7484aa2de92c6full);
|
||||
QuadRound(bs0, bs1, bm1, 0x76f988da5cb0a9dcull, 0x4a7484aa2de92c6full);
|
||||
ShiftMessageB(am0, am1, am2);
|
||||
ShiftMessageB(bm0, bm1, bm2);
|
||||
QuadRound(as0, as1, am2, 0xbf597fc7b00327c8ull, 0xa831c66d983e5152ull);
|
||||
QuadRound(bs0, bs1, bm2, 0xbf597fc7b00327c8ull, 0xa831c66d983e5152ull);
|
||||
ShiftMessageB(am1, am2, am3);
|
||||
ShiftMessageB(bm1, bm2, bm3);
|
||||
QuadRound(as0, as1, am3, 0x1429296706ca6351ull, 0xd5a79147c6e00bf3ull);
|
||||
QuadRound(bs0, bs1, bm3, 0x1429296706ca6351ull, 0xd5a79147c6e00bf3ull);
|
||||
ShiftMessageB(am2, am3, am0);
|
||||
ShiftMessageB(bm2, bm3, bm0);
|
||||
QuadRound(as0, as1, am0, 0x53380d134d2c6dfcull, 0x2e1b213827b70a85ull);
|
||||
QuadRound(bs0, bs1, bm0, 0x53380d134d2c6dfcull, 0x2e1b213827b70a85ull);
|
||||
ShiftMessageB(am3, am0, am1);
|
||||
ShiftMessageB(bm3, bm0, bm1);
|
||||
QuadRound(as0, as1, am1, 0x92722c8581c2c92eull, 0x766a0abb650a7354ull);
|
||||
QuadRound(bs0, bs1, bm1, 0x92722c8581c2c92eull, 0x766a0abb650a7354ull);
|
||||
ShiftMessageB(am0, am1, am2);
|
||||
ShiftMessageB(bm0, bm1, bm2);
|
||||
QuadRound(as0, as1, am2, 0xc76c51A3c24b8b70ull, 0xa81a664ba2bfe8a1ull);
|
||||
QuadRound(bs0, bs1, bm2, 0xc76c51A3c24b8b70ull, 0xa81a664ba2bfe8a1ull);
|
||||
ShiftMessageB(am1, am2, am3);
|
||||
ShiftMessageB(bm1, bm2, bm3);
|
||||
QuadRound(as0, as1, am3, 0x106aa070f40e3585ull, 0xd6990624d192e819ull);
|
||||
QuadRound(bs0, bs1, bm3, 0x106aa070f40e3585ull, 0xd6990624d192e819ull);
|
||||
ShiftMessageB(am2, am3, am0);
|
||||
ShiftMessageB(bm2, bm3, bm0);
|
||||
QuadRound(as0, as1, am0, 0x34b0bcb52748774cull, 0x1e376c0819a4c116ull);
|
||||
QuadRound(bs0, bs1, bm0, 0x34b0bcb52748774cull, 0x1e376c0819a4c116ull);
|
||||
ShiftMessageB(am3, am0, am1);
|
||||
ShiftMessageB(bm3, bm0, bm1);
|
||||
QuadRound(as0, as1, am1, 0x682e6ff35b9cca4full, 0x4ed8aa4a391c0cb3ull);
|
||||
QuadRound(bs0, bs1, bm1, 0x682e6ff35b9cca4full, 0x4ed8aa4a391c0cb3ull);
|
||||
ShiftMessageC(am0, am1, am2);
|
||||
ShiftMessageC(bm0, bm1, bm2);
|
||||
QuadRound(as0, as1, am2, 0x8cc7020884c87814ull, 0x78a5636f748f82eeull);
|
||||
QuadRound(bs0, bs1, bm2, 0x8cc7020884c87814ull, 0x78a5636f748f82eeull);
|
||||
ShiftMessageC(am1, am2, am3);
|
||||
ShiftMessageC(bm1, bm2, bm3);
|
||||
QuadRound(as0, as1, am3, 0xc67178f2bef9A3f7ull, 0xa4506ceb90befffaull);
|
||||
QuadRound(bs0, bs1, bm3, 0xc67178f2bef9A3f7ull, 0xa4506ceb90befffaull);
|
||||
as0 = _mm_add_epi32(as0, _mm_load_si128((const __m128i*)INIT0));
|
||||
bs0 = _mm_add_epi32(bs0, _mm_load_si128((const __m128i*)INIT0));
|
||||
as1 = _mm_add_epi32(as1, _mm_load_si128((const __m128i*)INIT1));
|
||||
bs1 = _mm_add_epi32(bs1, _mm_load_si128((const __m128i*)INIT1));
|
||||
|
||||
/* Transform 2 */
|
||||
aso0 = as0;
|
||||
bso0 = bs0;
|
||||
aso1 = as1;
|
||||
bso1 = bs1;
|
||||
QuadRound(as0, as1, 0xe9b5dba5b5c0fbcfull, 0x71374491c28a2f98ull);
|
||||
QuadRound(bs0, bs1, 0xe9b5dba5b5c0fbcfull, 0x71374491c28a2f98ull);
|
||||
QuadRound(as0, as1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull);
|
||||
QuadRound(bs0, bs1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull);
|
||||
QuadRound(as0, as1, 0x550c7dc3243185beull, 0x12835b01d807aa98ull);
|
||||
QuadRound(bs0, bs1, 0x550c7dc3243185beull, 0x12835b01d807aa98ull);
|
||||
QuadRound(as0, as1, 0xc19bf3749bdc06a7ull, 0x80deb1fe72be5d74ull);
|
||||
QuadRound(bs0, bs1, 0xc19bf3749bdc06a7ull, 0x80deb1fe72be5d74ull);
|
||||
QuadRound(as0, as1, 0x240cf2540fe1edc6ull, 0xf0fe4786649b69c1ull);
|
||||
QuadRound(bs0, bs1, 0x240cf2540fe1edc6ull, 0xf0fe4786649b69c1ull);
|
||||
QuadRound(as0, as1, 0x16f988fa61b9411eull, 0x6cc984be4fe9346full);
|
||||
QuadRound(bs0, bs1, 0x16f988fa61b9411eull, 0x6cc984be4fe9346full);
|
||||
QuadRound(as0, as1, 0xb9d99ec7b019fc65ull, 0xa88e5a6df2c65152ull);
|
||||
QuadRound(bs0, bs1, 0xb9d99ec7b019fc65ull, 0xa88e5a6df2c65152ull);
|
||||
QuadRound(as0, as1, 0xc7353eb0fdb1232bull, 0xe70eeaa09a1231c3ull);
|
||||
QuadRound(bs0, bs1, 0xc7353eb0fdb1232bull, 0xe70eeaa09a1231c3ull);
|
||||
QuadRound(as0, as1, 0xdc1eeefd5a0f118full, 0xcb976d5f3069bad5ull);
|
||||
QuadRound(bs0, bs1, 0xdc1eeefd5a0f118full, 0xcb976d5f3069bad5ull);
|
||||
QuadRound(as0, as1, 0xe15d5b1658f4ca9dull, 0xde0b7a040a35b689ull);
|
||||
QuadRound(bs0, bs1, 0xe15d5b1658f4ca9dull, 0xde0b7a040a35b689ull);
|
||||
QuadRound(as0, as1, 0x6fab9537a507ea32ull, 0x37088980007f3e86ull);
|
||||
QuadRound(bs0, bs1, 0x6fab9537a507ea32ull, 0x37088980007f3e86ull);
|
||||
QuadRound(as0, as1, 0xc0bbbe37cdaa3b6dull, 0x0d8cd6f117406110ull);
|
||||
QuadRound(bs0, bs1, 0xc0bbbe37cdaa3b6dull, 0x0d8cd6f117406110ull);
|
||||
QuadRound(as0, as1, 0x6fd15ca70b02e931ull, 0xdb48a36383613bdaull);
|
||||
QuadRound(bs0, bs1, 0x6fd15ca70b02e931ull, 0xdb48a36383613bdaull);
|
||||
QuadRound(as0, as1, 0x6d4378906ed41a95ull, 0x31338431521afacaull);
|
||||
QuadRound(bs0, bs1, 0x6d4378906ed41a95ull, 0x31338431521afacaull);
|
||||
QuadRound(as0, as1, 0x532fb63cb5c9a0e6ull, 0x9eccabbdc39c91f2ull);
|
||||
QuadRound(bs0, bs1, 0x532fb63cb5c9a0e6ull, 0x9eccabbdc39c91f2ull);
|
||||
QuadRound(as0, as1, 0x4c191d76a4954b68ull, 0x07237ea3d2c741c6ull);
|
||||
QuadRound(bs0, bs1, 0x4c191d76a4954b68ull, 0x07237ea3d2c741c6ull);
|
||||
as0 = _mm_add_epi32(as0, aso0);
|
||||
bs0 = _mm_add_epi32(bs0, bso0);
|
||||
as1 = _mm_add_epi32(as1, aso1);
|
||||
bs1 = _mm_add_epi32(bs1, bso1);
|
||||
|
||||
/* Extract hash */
|
||||
Unshuffle(as0, as1);
|
||||
Unshuffle(bs0, bs1);
|
||||
am0 = as0;
|
||||
bm0 = bs0;
|
||||
am1 = as1;
|
||||
bm1 = bs1;
|
||||
|
||||
/* Transform 3 */
|
||||
bs0 = as0 = _mm_load_si128((const __m128i*)INIT0);
|
||||
bs1 = as1 = _mm_load_si128((const __m128i*)INIT1);
|
||||
QuadRound(as0, as1, am0, 0xe9b5dba5B5c0fbcfull, 0x71374491428a2f98ull);
|
||||
QuadRound(bs0, bs1, bm0, 0xe9b5dba5B5c0fbcfull, 0x71374491428a2f98ull);
|
||||
QuadRound(as0, as1, am1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull);
|
||||
QuadRound(bs0, bs1, bm1, 0xab1c5ed5923f82a4ull, 0x59f111f13956c25bull);
|
||||
ShiftMessageA(am0, am1);
|
||||
ShiftMessageA(bm0, bm1);
|
||||
bm2 = am2 = _mm_set_epi64x(0x0ull, 0x80000000ull);
|
||||
QuadRound(as0, as1, 0x550c7dc3243185beull, 0x12835b015807aa98ull);
|
||||
QuadRound(bs0, bs1, 0x550c7dc3243185beull, 0x12835b015807aa98ull);
|
||||
ShiftMessageA(am1, am2);
|
||||
ShiftMessageA(bm1, bm2);
|
||||
bm3 = am3 = _mm_set_epi64x(0x10000000000ull, 0x0ull);
|
||||
QuadRound(as0, as1, 0xc19bf2749bdc06a7ull, 0x80deb1fe72be5d74ull);
|
||||
QuadRound(bs0, bs1, 0xc19bf2749bdc06a7ull, 0x80deb1fe72be5d74ull);
|
||||
ShiftMessageB(am2, am3, am0);
|
||||
ShiftMessageB(bm2, bm3, bm0);
|
||||
QuadRound(as0, as1, am0, 0x240ca1cc0fc19dc6ull, 0xefbe4786e49b69c1ull);
|
||||
QuadRound(bs0, bs1, bm0, 0x240ca1cc0fc19dc6ull, 0xefbe4786e49b69c1ull);
|
||||
ShiftMessageB(am3, am0, am1);
|
||||
ShiftMessageB(bm3, bm0, bm1);
|
||||
QuadRound(as0, as1, am1, 0x76f988da5cb0a9dcull, 0x4a7484aa2de92c6full);
|
||||
QuadRound(bs0, bs1, bm1, 0x76f988da5cb0a9dcull, 0x4a7484aa2de92c6full);
|
||||
ShiftMessageB(am0, am1, am2);
|
||||
ShiftMessageB(bm0, bm1, bm2);
|
||||
QuadRound(as0, as1, am2, 0xbf597fc7b00327c8ull, 0xa831c66d983e5152ull);
|
||||
QuadRound(bs0, bs1, bm2, 0xbf597fc7b00327c8ull, 0xa831c66d983e5152ull);
|
||||
ShiftMessageB(am1, am2, am3);
|
||||
ShiftMessageB(bm1, bm2, bm3);
|
||||
QuadRound(as0, as1, am3, 0x1429296706ca6351ull, 0xd5a79147c6e00bf3ull);
|
||||
QuadRound(bs0, bs1, bm3, 0x1429296706ca6351ull, 0xd5a79147c6e00bf3ull);
|
||||
ShiftMessageB(am2, am3, am0);
|
||||
ShiftMessageB(bm2, bm3, bm0);
|
||||
QuadRound(as0, as1, am0, 0x53380d134d2c6dfcull, 0x2e1b213827b70a85ull);
|
||||
QuadRound(bs0, bs1, bm0, 0x53380d134d2c6dfcull, 0x2e1b213827b70a85ull);
|
||||
ShiftMessageB(am3, am0, am1);
|
||||
ShiftMessageB(bm3, bm0, bm1);
|
||||
QuadRound(as0, as1, am1, 0x92722c8581c2c92eull, 0x766a0abb650a7354ull);
|
||||
QuadRound(bs0, bs1, bm1, 0x92722c8581c2c92eull, 0x766a0abb650a7354ull);
|
||||
ShiftMessageB(am0, am1, am2);
|
||||
ShiftMessageB(bm0, bm1, bm2);
|
||||
QuadRound(as0, as1, am2, 0xc76c51a3c24b8b70ull, 0xa81a664ba2bfe8A1ull);
|
||||
QuadRound(bs0, bs1, bm2, 0xc76c51a3c24b8b70ull, 0xa81a664ba2bfe8A1ull);
|
||||
ShiftMessageB(am1, am2, am3);
|
||||
ShiftMessageB(bm1, bm2, bm3);
|
||||
QuadRound(as0, as1, am3, 0x106aa070f40e3585ull, 0xd6990624d192e819ull);
|
||||
QuadRound(bs0, bs1, bm3, 0x106aa070f40e3585ull, 0xd6990624d192e819ull);
|
||||
ShiftMessageB(am2, am3, am0);
|
||||
ShiftMessageB(bm2, bm3, bm0);
|
||||
QuadRound(as0, as1, am0, 0x34b0bcb52748774cull, 0x1e376c0819a4c116ull);
|
||||
QuadRound(bs0, bs1, bm0, 0x34b0bcb52748774cull, 0x1e376c0819a4c116ull);
|
||||
ShiftMessageB(am3, am0, am1);
|
||||
ShiftMessageB(bm3, bm0, bm1);
|
||||
QuadRound(as0, as1, am1, 0x682e6ff35b9cca4full, 0x4ed8aa4a391c0cb3ull);
|
||||
QuadRound(bs0, bs1, bm1, 0x682e6ff35b9cca4full, 0x4ed8aa4a391c0cb3ull);
|
||||
ShiftMessageC(am0, am1, am2);
|
||||
ShiftMessageC(bm0, bm1, bm2);
|
||||
QuadRound(as0, as1, am2, 0x8cc7020884c87814ull, 0x78a5636f748f82eeull);
|
||||
QuadRound(bs0, bs1, bm2, 0x8cc7020884c87814ull, 0x78a5636f748f82eeull);
|
||||
ShiftMessageC(am1, am2, am3);
|
||||
ShiftMessageC(bm1, bm2, bm3);
|
||||
QuadRound(as0, as1, am3, 0xc67178f2bef9a3f7ull, 0xa4506ceb90befffaull);
|
||||
QuadRound(bs0, bs1, bm3, 0xc67178f2bef9a3f7ull, 0xa4506ceb90befffaull);
|
||||
as0 = _mm_add_epi32(as0, _mm_load_si128((const __m128i*)INIT0));
|
||||
bs0 = _mm_add_epi32(bs0, _mm_load_si128((const __m128i*)INIT0));
|
||||
as1 = _mm_add_epi32(as1, _mm_load_si128((const __m128i*)INIT1));
|
||||
bs1 = _mm_add_epi32(bs1, _mm_load_si128((const __m128i*)INIT1));
|
||||
|
||||
/* Extract hash into out */
|
||||
Unshuffle(as0, as1);
|
||||
Unshuffle(bs0, bs1);
|
||||
Save(out, as0);
|
||||
Save(out + 16, as1);
|
||||
Save(out + 32, bs0);
|
||||
Save(out + 48, bs1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
1506
src/crypto/sha256_sse4.cpp
Normal file
1506
src/crypto/sha256_sse4.cpp
Normal file
File diff suppressed because it is too large
Load diff
320
src/crypto/sha256_sse41.cpp
Normal file
320
src/crypto/sha256_sse41.cpp
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
// Copyright (c) 2018-2019 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifdef ENABLE_SSE41
|
||||
|
||||
#include <stdint.h>
|
||||
#include <immintrin.h>
|
||||
|
||||
#include <crypto/common.h>
|
||||
|
||||
namespace sha256d64_sse41 {
|
||||
namespace {
|
||||
|
||||
__m128i inline K(uint32_t x) { return _mm_set1_epi32(x); }
|
||||
|
||||
__m128i inline Add(__m128i x, __m128i y) { return _mm_add_epi32(x, y); }
|
||||
__m128i inline Add(__m128i x, __m128i y, __m128i z) { return Add(Add(x, y), z); }
|
||||
__m128i inline Add(__m128i x, __m128i y, __m128i z, __m128i w) { return Add(Add(x, y), Add(z, w)); }
|
||||
__m128i inline Add(__m128i x, __m128i y, __m128i z, __m128i w, __m128i v) { return Add(Add(x, y, z), Add(w, v)); }
|
||||
__m128i inline Inc(__m128i& x, __m128i y) { x = Add(x, y); return x; }
|
||||
__m128i inline Inc(__m128i& x, __m128i y, __m128i z) { x = Add(x, y, z); return x; }
|
||||
__m128i inline Inc(__m128i& x, __m128i y, __m128i z, __m128i w) { x = Add(x, y, z, w); return x; }
|
||||
__m128i inline Xor(__m128i x, __m128i y) { return _mm_xor_si128(x, y); }
|
||||
__m128i inline Xor(__m128i x, __m128i y, __m128i z) { return Xor(Xor(x, y), z); }
|
||||
__m128i inline Or(__m128i x, __m128i y) { return _mm_or_si128(x, y); }
|
||||
__m128i inline And(__m128i x, __m128i y) { return _mm_and_si128(x, y); }
|
||||
__m128i inline ShR(__m128i x, int n) { return _mm_srli_epi32(x, n); }
|
||||
__m128i inline ShL(__m128i x, int n) { return _mm_slli_epi32(x, n); }
|
||||
|
||||
__m128i inline Ch(__m128i x, __m128i y, __m128i z) { return Xor(z, And(x, Xor(y, z))); }
|
||||
__m128i inline Maj(__m128i x, __m128i y, __m128i z) { return Or(And(x, y), And(z, Or(x, y))); }
|
||||
__m128i inline Sigma0(__m128i x) { return Xor(Or(ShR(x, 2), ShL(x, 30)), Or(ShR(x, 13), ShL(x, 19)), Or(ShR(x, 22), ShL(x, 10))); }
|
||||
__m128i inline Sigma1(__m128i x) { return Xor(Or(ShR(x, 6), ShL(x, 26)), Or(ShR(x, 11), ShL(x, 21)), Or(ShR(x, 25), ShL(x, 7))); }
|
||||
__m128i inline sigma0(__m128i x) { return Xor(Or(ShR(x, 7), ShL(x, 25)), Or(ShR(x, 18), ShL(x, 14)), ShR(x, 3)); }
|
||||
__m128i inline sigma1(__m128i x) { return Xor(Or(ShR(x, 17), ShL(x, 15)), Or(ShR(x, 19), ShL(x, 13)), ShR(x, 10)); }
|
||||
|
||||
/** One round of SHA-256. */
|
||||
void inline __attribute__((always_inline)) Round(__m128i a, __m128i b, __m128i c, __m128i& d, __m128i e, __m128i f, __m128i g, __m128i& h, __m128i k)
|
||||
{
|
||||
__m128i t1 = Add(h, Sigma1(e), Ch(e, f, g), k);
|
||||
__m128i t2 = Add(Sigma0(a), Maj(a, b, c));
|
||||
d = Add(d, t1);
|
||||
h = Add(t1, t2);
|
||||
}
|
||||
|
||||
__m128i inline Read4(const unsigned char* chunk, int offset) {
|
||||
__m128i ret = _mm_set_epi32(
|
||||
ReadLE32(chunk + 0 + offset),
|
||||
ReadLE32(chunk + 64 + offset),
|
||||
ReadLE32(chunk + 128 + offset),
|
||||
ReadLE32(chunk + 192 + offset)
|
||||
);
|
||||
return _mm_shuffle_epi8(ret, _mm_set_epi32(0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL, 0x00010203UL));
|
||||
}
|
||||
|
||||
void inline Write4(unsigned char* out, int offset, __m128i v) {
|
||||
v = _mm_shuffle_epi8(v, _mm_set_epi32(0x0C0D0E0FUL, 0x08090A0BUL, 0x04050607UL, 0x00010203UL));
|
||||
WriteLE32(out + 0 + offset, _mm_extract_epi32(v, 3));
|
||||
WriteLE32(out + 32 + offset, _mm_extract_epi32(v, 2));
|
||||
WriteLE32(out + 64 + offset, _mm_extract_epi32(v, 1));
|
||||
WriteLE32(out + 96 + offset, _mm_extract_epi32(v, 0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Transform_4way(unsigned char* out, const unsigned char* in)
|
||||
{
|
||||
// Transform 1
|
||||
__m128i a = K(0x6a09e667ul);
|
||||
__m128i b = K(0xbb67ae85ul);
|
||||
__m128i c = K(0x3c6ef372ul);
|
||||
__m128i d = K(0xa54ff53aul);
|
||||
__m128i e = K(0x510e527ful);
|
||||
__m128i f = K(0x9b05688cul);
|
||||
__m128i g = K(0x1f83d9abul);
|
||||
__m128i h = K(0x5be0cd19ul);
|
||||
|
||||
__m128i w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x428a2f98ul), w0 = Read4(in, 0)));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x71374491ul), w1 = Read4(in, 4)));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0xb5c0fbcful), w2 = Read4(in, 8)));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0xe9b5dba5ul), w3 = Read4(in, 12)));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x3956c25bul), w4 = Read4(in, 16)));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x59f111f1ul), w5 = Read4(in, 20)));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x923f82a4ul), w6 = Read4(in, 24)));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0xab1c5ed5ul), w7 = Read4(in, 28)));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0xd807aa98ul), w8 = Read4(in, 32)));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x12835b01ul), w9 = Read4(in, 36)));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x243185beul), w10 = Read4(in, 40)));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x550c7dc3ul), w11 = Read4(in, 44)));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x72be5d74ul), w12 = Read4(in, 48)));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x80deb1feul), w13 = Read4(in, 52)));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x9bdc06a7ul), w14 = Read4(in, 56)));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0xc19bf174ul), w15 = Read4(in, 60)));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0xe49b69c1ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0xefbe4786ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x0fc19dc6ul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x240ca1ccul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x2de92c6ful), Inc(w4, sigma1(w2), w13, sigma0(w5))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x4a7484aaul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x5cb0a9dcul), Inc(w6, sigma1(w4), w15, sigma0(w7))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x76f988daul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x983e5152ul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0xa831c66dul), Inc(w9, sigma1(w7), w2, sigma0(w10))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0xb00327c8ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0xbf597fc7ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0xc6e00bf3ul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0xd5a79147ul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x06ca6351ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x14292967ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x27b70a85ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x2e1b2138ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x4d2c6dfcul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x53380d13ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x650a7354ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x766a0abbul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x81c2c92eul), Inc(w6, sigma1(w4), w15, sigma0(w7))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x92722c85ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0xa2bfe8a1ul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0xa81a664bul), Inc(w9, sigma1(w7), w2, sigma0(w10))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0xc24b8b70ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0xc76c51a3ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0xd192e819ul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0xd6990624ul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0xf40e3585ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x106aa070ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x19a4c116ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x1e376c08ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x2748774cul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x34b0bcb5ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x391c0cb3ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x4ed8aa4aul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x5b9cca4ful), Inc(w6, sigma1(w4), w15, sigma0(w7))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x682e6ff3ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x748f82eeul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x78a5636ful), Inc(w9, sigma1(w7), w2, sigma0(w10))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x84c87814ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x8cc70208ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x90befffaul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0xa4506cebul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0xbef9a3f7ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0xc67178f2ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
|
||||
|
||||
a = Add(a, K(0x6a09e667ul));
|
||||
b = Add(b, K(0xbb67ae85ul));
|
||||
c = Add(c, K(0x3c6ef372ul));
|
||||
d = Add(d, K(0xa54ff53aul));
|
||||
e = Add(e, K(0x510e527ful));
|
||||
f = Add(f, K(0x9b05688cul));
|
||||
g = Add(g, K(0x1f83d9abul));
|
||||
h = Add(h, K(0x5be0cd19ul));
|
||||
|
||||
__m128i t0 = a, t1 = b, t2 = c, t3 = d, t4 = e, t5 = f, t6 = g, t7 = h;
|
||||
|
||||
// Transform 2
|
||||
Round(a, b, c, d, e, f, g, h, K(0xc28a2f98ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0x71374491ul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0xb5c0fbcful));
|
||||
Round(f, g, h, a, b, c, d, e, K(0xe9b5dba5ul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x3956c25bul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0x59f111f1ul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0x923f82a4ul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0xab1c5ed5ul));
|
||||
Round(a, b, c, d, e, f, g, h, K(0xd807aa98ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0x12835b01ul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0x243185beul));
|
||||
Round(f, g, h, a, b, c, d, e, K(0x550c7dc3ul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x72be5d74ul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0x80deb1feul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0x9bdc06a7ul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0xc19bf374ul));
|
||||
Round(a, b, c, d, e, f, g, h, K(0x649b69c1ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0xf0fe4786ul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0x0fe1edc6ul));
|
||||
Round(f, g, h, a, b, c, d, e, K(0x240cf254ul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x4fe9346ful));
|
||||
Round(d, e, f, g, h, a, b, c, K(0x6cc984beul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0x61b9411eul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0x16f988faul));
|
||||
Round(a, b, c, d, e, f, g, h, K(0xf2c65152ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0xa88e5a6dul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0xb019fc65ul));
|
||||
Round(f, g, h, a, b, c, d, e, K(0xb9d99ec7ul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x9a1231c3ul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0xe70eeaa0ul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0xfdb1232bul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0xc7353eb0ul));
|
||||
Round(a, b, c, d, e, f, g, h, K(0x3069bad5ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0xcb976d5ful));
|
||||
Round(g, h, a, b, c, d, e, f, K(0x5a0f118ful));
|
||||
Round(f, g, h, a, b, c, d, e, K(0xdc1eeefdul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x0a35b689ul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0xde0b7a04ul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0x58f4ca9dul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0xe15d5b16ul));
|
||||
Round(a, b, c, d, e, f, g, h, K(0x007f3e86ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0x37088980ul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0xa507ea32ul));
|
||||
Round(f, g, h, a, b, c, d, e, K(0x6fab9537ul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x17406110ul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0x0d8cd6f1ul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0xcdaa3b6dul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0xc0bbbe37ul));
|
||||
Round(a, b, c, d, e, f, g, h, K(0x83613bdaul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0xdb48a363ul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0x0b02e931ul));
|
||||
Round(f, g, h, a, b, c, d, e, K(0x6fd15ca7ul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x521afacaul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0x31338431ul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0x6ed41a95ul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0x6d437890ul));
|
||||
Round(a, b, c, d, e, f, g, h, K(0xc39c91f2ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0x9eccabbdul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0xb5c9a0e6ul));
|
||||
Round(f, g, h, a, b, c, d, e, K(0x532fb63cul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0xd2c741c6ul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0x07237ea3ul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0xa4954b68ul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0x4c191d76ul));
|
||||
|
||||
w0 = Add(t0, a);
|
||||
w1 = Add(t1, b);
|
||||
w2 = Add(t2, c);
|
||||
w3 = Add(t3, d);
|
||||
w4 = Add(t4, e);
|
||||
w5 = Add(t5, f);
|
||||
w6 = Add(t6, g);
|
||||
w7 = Add(t7, h);
|
||||
|
||||
// Transform 3
|
||||
a = K(0x6a09e667ul);
|
||||
b = K(0xbb67ae85ul);
|
||||
c = K(0x3c6ef372ul);
|
||||
d = K(0xa54ff53aul);
|
||||
e = K(0x510e527ful);
|
||||
f = K(0x9b05688cul);
|
||||
g = K(0x1f83d9abul);
|
||||
h = K(0x5be0cd19ul);
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x428a2f98ul), w0));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x71374491ul), w1));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0xb5c0fbcful), w2));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0xe9b5dba5ul), w3));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x3956c25bul), w4));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x59f111f1ul), w5));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x923f82a4ul), w6));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0xab1c5ed5ul), w7));
|
||||
Round(a, b, c, d, e, f, g, h, K(0x5807aa98ul));
|
||||
Round(h, a, b, c, d, e, f, g, K(0x12835b01ul));
|
||||
Round(g, h, a, b, c, d, e, f, K(0x243185beul));
|
||||
Round(f, g, h, a, b, c, d, e, K(0x550c7dc3ul));
|
||||
Round(e, f, g, h, a, b, c, d, K(0x72be5d74ul));
|
||||
Round(d, e, f, g, h, a, b, c, K(0x80deb1feul));
|
||||
Round(c, d, e, f, g, h, a, b, K(0x9bdc06a7ul));
|
||||
Round(b, c, d, e, f, g, h, a, K(0xc19bf274ul));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0xe49b69c1ul), Inc(w0, sigma0(w1))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0xefbe4786ul), Inc(w1, K(0xa00000ul), sigma0(w2))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x0fc19dc6ul), Inc(w2, sigma1(w0), sigma0(w3))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x240ca1ccul), Inc(w3, sigma1(w1), sigma0(w4))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x2de92c6ful), Inc(w4, sigma1(w2), sigma0(w5))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x4a7484aaul), Inc(w5, sigma1(w3), sigma0(w6))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x5cb0a9dcul), Inc(w6, sigma1(w4), K(0x100ul), sigma0(w7))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x76f988daul), Inc(w7, sigma1(w5), w0, K(0x11002000ul))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x983e5152ul), w8 = Add(K(0x80000000ul), sigma1(w6), w1)));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0xa831c66dul), w9 = Add(sigma1(w7), w2)));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0xb00327c8ul), w10 = Add(sigma1(w8), w3)));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0xbf597fc7ul), w11 = Add(sigma1(w9), w4)));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0xc6e00bf3ul), w12 = Add(sigma1(w10), w5)));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0xd5a79147ul), w13 = Add(sigma1(w11), w6)));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x06ca6351ul), w14 = Add(sigma1(w12), w7, K(0x400022ul))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x14292967ul), w15 = Add(K(0x100ul), sigma1(w13), w8, sigma0(w0))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x27b70a85ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x2e1b2138ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x4d2c6dfcul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x53380d13ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x650a7354ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x766a0abbul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x81c2c92eul), Inc(w6, sigma1(w4), w15, sigma0(w7))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x92722c85ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0xa2bfe8a1ul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0xa81a664bul), Inc(w9, sigma1(w7), w2, sigma0(w10))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0xc24b8b70ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0xc76c51a3ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0xd192e819ul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0xd6990624ul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0xf40e3585ul), Inc(w14, sigma1(w12), w7, sigma0(w15))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x106aa070ul), Inc(w15, sigma1(w13), w8, sigma0(w0))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x19a4c116ul), Inc(w0, sigma1(w14), w9, sigma0(w1))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x1e376c08ul), Inc(w1, sigma1(w15), w10, sigma0(w2))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x2748774cul), Inc(w2, sigma1(w0), w11, sigma0(w3))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x34b0bcb5ul), Inc(w3, sigma1(w1), w12, sigma0(w4))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x391c0cb3ul), Inc(w4, sigma1(w2), w13, sigma0(w5))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0x4ed8aa4aul), Inc(w5, sigma1(w3), w14, sigma0(w6))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0x5b9cca4ful), Inc(w6, sigma1(w4), w15, sigma0(w7))));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0x682e6ff3ul), Inc(w7, sigma1(w5), w0, sigma0(w8))));
|
||||
Round(a, b, c, d, e, f, g, h, Add(K(0x748f82eeul), Inc(w8, sigma1(w6), w1, sigma0(w9))));
|
||||
Round(h, a, b, c, d, e, f, g, Add(K(0x78a5636ful), Inc(w9, sigma1(w7), w2, sigma0(w10))));
|
||||
Round(g, h, a, b, c, d, e, f, Add(K(0x84c87814ul), Inc(w10, sigma1(w8), w3, sigma0(w11))));
|
||||
Round(f, g, h, a, b, c, d, e, Add(K(0x8cc70208ul), Inc(w11, sigma1(w9), w4, sigma0(w12))));
|
||||
Round(e, f, g, h, a, b, c, d, Add(K(0x90befffaul), Inc(w12, sigma1(w10), w5, sigma0(w13))));
|
||||
Round(d, e, f, g, h, a, b, c, Add(K(0xa4506cebul), Inc(w13, sigma1(w11), w6, sigma0(w14))));
|
||||
Round(c, d, e, f, g, h, a, b, Add(K(0xbef9a3f7ul), w14, sigma1(w12), w7, sigma0(w15)));
|
||||
Round(b, c, d, e, f, g, h, a, Add(K(0xc67178f2ul), w15, sigma1(w13), w8, sigma0(w0)));
|
||||
|
||||
// Output
|
||||
Write4(out, 0, Add(a, K(0x6a09e667ul)));
|
||||
Write4(out, 4, Add(b, K(0xbb67ae85ul)));
|
||||
Write4(out, 8, Add(c, K(0x3c6ef372ul)));
|
||||
Write4(out, 12, Add(d, K(0xa54ff53aul)));
|
||||
Write4(out, 16, Add(e, K(0x510e527ful)));
|
||||
Write4(out, 20, Add(f, K(0x9b05688cul)));
|
||||
Write4(out, 24, Add(g, K(0x1f83d9abul)));
|
||||
Write4(out, 28, Add(h, K(0x5be0cd19ul)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
161
src/crypto/sha3.cpp
Normal file
161
src/crypto/sha3.cpp
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
// Copyright (c) 2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
// Based on https://github.com/mjosaarinen/tiny_sha3/blob/master/sha3.c
|
||||
// by Markku-Juhani O. Saarinen <mjos@iki.fi>
|
||||
|
||||
#include <crypto/sha3.h>
|
||||
#include <crypto/common.h>
|
||||
#include <span.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array> // For std::begin and std::end.
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Internal implementation code.
|
||||
namespace
|
||||
{
|
||||
uint64_t Rotl(uint64_t x, int n) { return (x << n) | (x >> (64 - n)); }
|
||||
} // namespace
|
||||
|
||||
void KeccakF(uint64_t (&st)[25])
|
||||
{
|
||||
static constexpr uint64_t RNDC[24] = {
|
||||
0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,
|
||||
0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
|
||||
0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
|
||||
0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,
|
||||
0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
|
||||
0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008
|
||||
};
|
||||
static constexpr int ROUNDS = 24;
|
||||
|
||||
for (int round = 0; round < ROUNDS; ++round) {
|
||||
uint64_t bc0, bc1, bc2, bc3, bc4, t;
|
||||
|
||||
// Theta
|
||||
bc0 = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20];
|
||||
bc1 = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21];
|
||||
bc2 = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22];
|
||||
bc3 = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23];
|
||||
bc4 = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24];
|
||||
t = bc4 ^ Rotl(bc1, 1); st[0] ^= t; st[5] ^= t; st[10] ^= t; st[15] ^= t; st[20] ^= t;
|
||||
t = bc0 ^ Rotl(bc2, 1); st[1] ^= t; st[6] ^= t; st[11] ^= t; st[16] ^= t; st[21] ^= t;
|
||||
t = bc1 ^ Rotl(bc3, 1); st[2] ^= t; st[7] ^= t; st[12] ^= t; st[17] ^= t; st[22] ^= t;
|
||||
t = bc2 ^ Rotl(bc4, 1); st[3] ^= t; st[8] ^= t; st[13] ^= t; st[18] ^= t; st[23] ^= t;
|
||||
t = bc3 ^ Rotl(bc0, 1); st[4] ^= t; st[9] ^= t; st[14] ^= t; st[19] ^= t; st[24] ^= t;
|
||||
|
||||
// Rho Pi
|
||||
t = st[1];
|
||||
bc0 = st[10]; st[10] = Rotl(t, 1); t = bc0;
|
||||
bc0 = st[7]; st[7] = Rotl(t, 3); t = bc0;
|
||||
bc0 = st[11]; st[11] = Rotl(t, 6); t = bc0;
|
||||
bc0 = st[17]; st[17] = Rotl(t, 10); t = bc0;
|
||||
bc0 = st[18]; st[18] = Rotl(t, 15); t = bc0;
|
||||
bc0 = st[3]; st[3] = Rotl(t, 21); t = bc0;
|
||||
bc0 = st[5]; st[5] = Rotl(t, 28); t = bc0;
|
||||
bc0 = st[16]; st[16] = Rotl(t, 36); t = bc0;
|
||||
bc0 = st[8]; st[8] = Rotl(t, 45); t = bc0;
|
||||
bc0 = st[21]; st[21] = Rotl(t, 55); t = bc0;
|
||||
bc0 = st[24]; st[24] = Rotl(t, 2); t = bc0;
|
||||
bc0 = st[4]; st[4] = Rotl(t, 14); t = bc0;
|
||||
bc0 = st[15]; st[15] = Rotl(t, 27); t = bc0;
|
||||
bc0 = st[23]; st[23] = Rotl(t, 41); t = bc0;
|
||||
bc0 = st[19]; st[19] = Rotl(t, 56); t = bc0;
|
||||
bc0 = st[13]; st[13] = Rotl(t, 8); t = bc0;
|
||||
bc0 = st[12]; st[12] = Rotl(t, 25); t = bc0;
|
||||
bc0 = st[2]; st[2] = Rotl(t, 43); t = bc0;
|
||||
bc0 = st[20]; st[20] = Rotl(t, 62); t = bc0;
|
||||
bc0 = st[14]; st[14] = Rotl(t, 18); t = bc0;
|
||||
bc0 = st[22]; st[22] = Rotl(t, 39); t = bc0;
|
||||
bc0 = st[9]; st[9] = Rotl(t, 61); t = bc0;
|
||||
bc0 = st[6]; st[6] = Rotl(t, 20); t = bc0;
|
||||
st[1] = Rotl(t, 44);
|
||||
|
||||
// Chi Iota
|
||||
bc0 = st[0]; bc1 = st[1]; bc2 = st[2]; bc3 = st[3]; bc4 = st[4];
|
||||
st[0] = bc0 ^ (~bc1 & bc2) ^ RNDC[round];
|
||||
st[1] = bc1 ^ (~bc2 & bc3);
|
||||
st[2] = bc2 ^ (~bc3 & bc4);
|
||||
st[3] = bc3 ^ (~bc4 & bc0);
|
||||
st[4] = bc4 ^ (~bc0 & bc1);
|
||||
bc0 = st[5]; bc1 = st[6]; bc2 = st[7]; bc3 = st[8]; bc4 = st[9];
|
||||
st[5] = bc0 ^ (~bc1 & bc2);
|
||||
st[6] = bc1 ^ (~bc2 & bc3);
|
||||
st[7] = bc2 ^ (~bc3 & bc4);
|
||||
st[8] = bc3 ^ (~bc4 & bc0);
|
||||
st[9] = bc4 ^ (~bc0 & bc1);
|
||||
bc0 = st[10]; bc1 = st[11]; bc2 = st[12]; bc3 = st[13]; bc4 = st[14];
|
||||
st[10] = bc0 ^ (~bc1 & bc2);
|
||||
st[11] = bc1 ^ (~bc2 & bc3);
|
||||
st[12] = bc2 ^ (~bc3 & bc4);
|
||||
st[13] = bc3 ^ (~bc4 & bc0);
|
||||
st[14] = bc4 ^ (~bc0 & bc1);
|
||||
bc0 = st[15]; bc1 = st[16]; bc2 = st[17]; bc3 = st[18]; bc4 = st[19];
|
||||
st[15] = bc0 ^ (~bc1 & bc2);
|
||||
st[16] = bc1 ^ (~bc2 & bc3);
|
||||
st[17] = bc2 ^ (~bc3 & bc4);
|
||||
st[18] = bc3 ^ (~bc4 & bc0);
|
||||
st[19] = bc4 ^ (~bc0 & bc1);
|
||||
bc0 = st[20]; bc1 = st[21]; bc2 = st[22]; bc3 = st[23]; bc4 = st[24];
|
||||
st[20] = bc0 ^ (~bc1 & bc2);
|
||||
st[21] = bc1 ^ (~bc2 & bc3);
|
||||
st[22] = bc2 ^ (~bc3 & bc4);
|
||||
st[23] = bc3 ^ (~bc4 & bc0);
|
||||
st[24] = bc4 ^ (~bc0 & bc1);
|
||||
}
|
||||
}
|
||||
|
||||
SHA3_256& SHA3_256::Write(Span<const unsigned char> data)
|
||||
{
|
||||
if (m_bufsize && m_bufsize + data.size() >= sizeof(m_buffer)) {
|
||||
// Fill the buffer and process it.
|
||||
std::copy(data.begin(), data.begin() + sizeof(m_buffer) - m_bufsize, m_buffer + m_bufsize);
|
||||
data = data.subspan(sizeof(m_buffer) - m_bufsize);
|
||||
m_state[m_pos++] ^= ReadLE64(m_buffer);
|
||||
m_bufsize = 0;
|
||||
if (m_pos == RATE_BUFFERS) {
|
||||
KeccakF(m_state);
|
||||
m_pos = 0;
|
||||
}
|
||||
}
|
||||
while (data.size() >= sizeof(m_buffer)) {
|
||||
// Process chunks directly from the buffer.
|
||||
m_state[m_pos++] ^= ReadLE64(data.data());
|
||||
data = data.subspan(8);
|
||||
if (m_pos == RATE_BUFFERS) {
|
||||
KeccakF(m_state);
|
||||
m_pos = 0;
|
||||
}
|
||||
}
|
||||
if (data.size()) {
|
||||
// Keep the remainder in the buffer.
|
||||
std::copy(data.begin(), data.end(), m_buffer + m_bufsize);
|
||||
m_bufsize += data.size();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
SHA3_256& SHA3_256::Finalize(Span<unsigned char> output)
|
||||
{
|
||||
assert(output.size() == OUTPUT_SIZE);
|
||||
std::fill(m_buffer + m_bufsize, m_buffer + sizeof(m_buffer), 0);
|
||||
m_buffer[m_bufsize] ^= 0x06;
|
||||
m_state[m_pos] ^= ReadLE64(m_buffer);
|
||||
m_state[RATE_BUFFERS - 1] ^= 0x8000000000000000;
|
||||
KeccakF(m_state);
|
||||
for (unsigned i = 0; i < 4; ++i) {
|
||||
WriteLE64(output.data() + 8 * i, m_state[i]);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
SHA3_256& SHA3_256::Reset()
|
||||
{
|
||||
m_bufsize = 0;
|
||||
m_pos = 0;
|
||||
std::fill(std::begin(m_state), std::end(m_state), 0);
|
||||
return *this;
|
||||
}
|
||||
41
src/crypto/sha3.h
Normal file
41
src/crypto/sha3.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright (c) 2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef DIGIBYTE_CRYPTO_SHA3_H
|
||||
#define DIGIBYTE_CRYPTO_SHA3_H
|
||||
|
||||
#include <span.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//! The Keccak-f[1600] transform.
|
||||
void KeccakF(uint64_t (&st)[25]);
|
||||
|
||||
class SHA3_256
|
||||
{
|
||||
private:
|
||||
uint64_t m_state[25] = {0};
|
||||
unsigned char m_buffer[8];
|
||||
unsigned m_bufsize = 0;
|
||||
unsigned m_pos = 0;
|
||||
|
||||
//! Sponge rate in bits.
|
||||
static constexpr unsigned RATE_BITS = 1088;
|
||||
|
||||
//! Sponge rate expressed as a multiple of the buffer size.
|
||||
static constexpr unsigned RATE_BUFFERS = RATE_BITS / (8 * sizeof(m_buffer));
|
||||
|
||||
static_assert(RATE_BITS % (8 * sizeof(m_buffer)) == 0, "Rate must be a multiple of 8 bytes");
|
||||
|
||||
public:
|
||||
static constexpr size_t OUTPUT_SIZE = 32;
|
||||
|
||||
SHA3_256() {}
|
||||
SHA3_256& Write(Span<const unsigned char> data);
|
||||
SHA3_256& Finalize(Span<unsigned char> output);
|
||||
SHA3_256& Reset();
|
||||
};
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_SHA3_H
|
||||
208
src/crypto/sha512.cpp
Normal file
208
src/crypto/sha512.cpp
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
// Copyright (c) 2009-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <crypto/sha512.h>
|
||||
|
||||
#include <crypto/common.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
// Internal implementation code.
|
||||
namespace
|
||||
{
|
||||
/// Internal SHA-512 implementation.
|
||||
namespace sha512
|
||||
{
|
||||
uint64_t inline Ch(uint64_t x, uint64_t y, uint64_t z) { return z ^ (x & (y ^ z)); }
|
||||
uint64_t inline Maj(uint64_t x, uint64_t y, uint64_t z) { return (x & y) | (z & (x | y)); }
|
||||
uint64_t inline Sigma0(uint64_t x) { return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25); }
|
||||
uint64_t inline Sigma1(uint64_t x) { return (x >> 14 | x << 50) ^ (x >> 18 | x << 46) ^ (x >> 41 | x << 23); }
|
||||
uint64_t inline sigma0(uint64_t x) { return (x >> 1 | x << 63) ^ (x >> 8 | x << 56) ^ (x >> 7); }
|
||||
uint64_t inline sigma1(uint64_t x) { return (x >> 19 | x << 45) ^ (x >> 61 | x << 3) ^ (x >> 6); }
|
||||
|
||||
/** One round of SHA-512. */
|
||||
void inline Round(uint64_t a, uint64_t b, uint64_t c, uint64_t& d, uint64_t e, uint64_t f, uint64_t g, uint64_t& h, uint64_t k, uint64_t w)
|
||||
{
|
||||
uint64_t t1 = h + Sigma1(e) + Ch(e, f, g) + k + w;
|
||||
uint64_t t2 = Sigma0(a) + Maj(a, b, c);
|
||||
d += t1;
|
||||
h = t1 + t2;
|
||||
}
|
||||
|
||||
/** Initialize SHA-256 state. */
|
||||
void inline Initialize(uint64_t* s)
|
||||
{
|
||||
s[0] = 0x6a09e667f3bcc908ull;
|
||||
s[1] = 0xbb67ae8584caa73bull;
|
||||
s[2] = 0x3c6ef372fe94f82bull;
|
||||
s[3] = 0xa54ff53a5f1d36f1ull;
|
||||
s[4] = 0x510e527fade682d1ull;
|
||||
s[5] = 0x9b05688c2b3e6c1full;
|
||||
s[6] = 0x1f83d9abfb41bd6bull;
|
||||
s[7] = 0x5be0cd19137e2179ull;
|
||||
}
|
||||
|
||||
/** Perform one SHA-512 transformation, processing a 128-byte chunk. */
|
||||
void Transform(uint64_t* s, const unsigned char* chunk)
|
||||
{
|
||||
uint64_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
|
||||
uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0x428a2f98d728ae22ull, w0 = ReadBE64(chunk + 0));
|
||||
Round(h, a, b, c, d, e, f, g, 0x7137449123ef65cdull, w1 = ReadBE64(chunk + 8));
|
||||
Round(g, h, a, b, c, d, e, f, 0xb5c0fbcfec4d3b2full, w2 = ReadBE64(chunk + 16));
|
||||
Round(f, g, h, a, b, c, d, e, 0xe9b5dba58189dbbcull, w3 = ReadBE64(chunk + 24));
|
||||
Round(e, f, g, h, a, b, c, d, 0x3956c25bf348b538ull, w4 = ReadBE64(chunk + 32));
|
||||
Round(d, e, f, g, h, a, b, c, 0x59f111f1b605d019ull, w5 = ReadBE64(chunk + 40));
|
||||
Round(c, d, e, f, g, h, a, b, 0x923f82a4af194f9bull, w6 = ReadBE64(chunk + 48));
|
||||
Round(b, c, d, e, f, g, h, a, 0xab1c5ed5da6d8118ull, w7 = ReadBE64(chunk + 56));
|
||||
Round(a, b, c, d, e, f, g, h, 0xd807aa98a3030242ull, w8 = ReadBE64(chunk + 64));
|
||||
Round(h, a, b, c, d, e, f, g, 0x12835b0145706fbeull, w9 = ReadBE64(chunk + 72));
|
||||
Round(g, h, a, b, c, d, e, f, 0x243185be4ee4b28cull, w10 = ReadBE64(chunk + 80));
|
||||
Round(f, g, h, a, b, c, d, e, 0x550c7dc3d5ffb4e2ull, w11 = ReadBE64(chunk + 88));
|
||||
Round(e, f, g, h, a, b, c, d, 0x72be5d74f27b896full, w12 = ReadBE64(chunk + 96));
|
||||
Round(d, e, f, g, h, a, b, c, 0x80deb1fe3b1696b1ull, w13 = ReadBE64(chunk + 104));
|
||||
Round(c, d, e, f, g, h, a, b, 0x9bdc06a725c71235ull, w14 = ReadBE64(chunk + 112));
|
||||
Round(b, c, d, e, f, g, h, a, 0xc19bf174cf692694ull, w15 = ReadBE64(chunk + 120));
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0xe49b69c19ef14ad2ull, w0 += sigma1(w14) + w9 + sigma0(w1));
|
||||
Round(h, a, b, c, d, e, f, g, 0xefbe4786384f25e3ull, w1 += sigma1(w15) + w10 + sigma0(w2));
|
||||
Round(g, h, a, b, c, d, e, f, 0x0fc19dc68b8cd5b5ull, w2 += sigma1(w0) + w11 + sigma0(w3));
|
||||
Round(f, g, h, a, b, c, d, e, 0x240ca1cc77ac9c65ull, w3 += sigma1(w1) + w12 + sigma0(w4));
|
||||
Round(e, f, g, h, a, b, c, d, 0x2de92c6f592b0275ull, w4 += sigma1(w2) + w13 + sigma0(w5));
|
||||
Round(d, e, f, g, h, a, b, c, 0x4a7484aa6ea6e483ull, w5 += sigma1(w3) + w14 + sigma0(w6));
|
||||
Round(c, d, e, f, g, h, a, b, 0x5cb0a9dcbd41fbd4ull, w6 += sigma1(w4) + w15 + sigma0(w7));
|
||||
Round(b, c, d, e, f, g, h, a, 0x76f988da831153b5ull, w7 += sigma1(w5) + w0 + sigma0(w8));
|
||||
Round(a, b, c, d, e, f, g, h, 0x983e5152ee66dfabull, w8 += sigma1(w6) + w1 + sigma0(w9));
|
||||
Round(h, a, b, c, d, e, f, g, 0xa831c66d2db43210ull, w9 += sigma1(w7) + w2 + sigma0(w10));
|
||||
Round(g, h, a, b, c, d, e, f, 0xb00327c898fb213full, w10 += sigma1(w8) + w3 + sigma0(w11));
|
||||
Round(f, g, h, a, b, c, d, e, 0xbf597fc7beef0ee4ull, w11 += sigma1(w9) + w4 + sigma0(w12));
|
||||
Round(e, f, g, h, a, b, c, d, 0xc6e00bf33da88fc2ull, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||
Round(d, e, f, g, h, a, b, c, 0xd5a79147930aa725ull, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||
Round(c, d, e, f, g, h, a, b, 0x06ca6351e003826full, w14 += sigma1(w12) + w7 + sigma0(w15));
|
||||
Round(b, c, d, e, f, g, h, a, 0x142929670a0e6e70ull, w15 += sigma1(w13) + w8 + sigma0(w0));
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0x27b70a8546d22ffcull, w0 += sigma1(w14) + w9 + sigma0(w1));
|
||||
Round(h, a, b, c, d, e, f, g, 0x2e1b21385c26c926ull, w1 += sigma1(w15) + w10 + sigma0(w2));
|
||||
Round(g, h, a, b, c, d, e, f, 0x4d2c6dfc5ac42aedull, w2 += sigma1(w0) + w11 + sigma0(w3));
|
||||
Round(f, g, h, a, b, c, d, e, 0x53380d139d95b3dfull, w3 += sigma1(w1) + w12 + sigma0(w4));
|
||||
Round(e, f, g, h, a, b, c, d, 0x650a73548baf63deull, w4 += sigma1(w2) + w13 + sigma0(w5));
|
||||
Round(d, e, f, g, h, a, b, c, 0x766a0abb3c77b2a8ull, w5 += sigma1(w3) + w14 + sigma0(w6));
|
||||
Round(c, d, e, f, g, h, a, b, 0x81c2c92e47edaee6ull, w6 += sigma1(w4) + w15 + sigma0(w7));
|
||||
Round(b, c, d, e, f, g, h, a, 0x92722c851482353bull, w7 += sigma1(w5) + w0 + sigma0(w8));
|
||||
Round(a, b, c, d, e, f, g, h, 0xa2bfe8a14cf10364ull, w8 += sigma1(w6) + w1 + sigma0(w9));
|
||||
Round(h, a, b, c, d, e, f, g, 0xa81a664bbc423001ull, w9 += sigma1(w7) + w2 + sigma0(w10));
|
||||
Round(g, h, a, b, c, d, e, f, 0xc24b8b70d0f89791ull, w10 += sigma1(w8) + w3 + sigma0(w11));
|
||||
Round(f, g, h, a, b, c, d, e, 0xc76c51a30654be30ull, w11 += sigma1(w9) + w4 + sigma0(w12));
|
||||
Round(e, f, g, h, a, b, c, d, 0xd192e819d6ef5218ull, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||
Round(d, e, f, g, h, a, b, c, 0xd69906245565a910ull, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||
Round(c, d, e, f, g, h, a, b, 0xf40e35855771202aull, w14 += sigma1(w12) + w7 + sigma0(w15));
|
||||
Round(b, c, d, e, f, g, h, a, 0x106aa07032bbd1b8ull, w15 += sigma1(w13) + w8 + sigma0(w0));
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0x19a4c116b8d2d0c8ull, w0 += sigma1(w14) + w9 + sigma0(w1));
|
||||
Round(h, a, b, c, d, e, f, g, 0x1e376c085141ab53ull, w1 += sigma1(w15) + w10 + sigma0(w2));
|
||||
Round(g, h, a, b, c, d, e, f, 0x2748774cdf8eeb99ull, w2 += sigma1(w0) + w11 + sigma0(w3));
|
||||
Round(f, g, h, a, b, c, d, e, 0x34b0bcb5e19b48a8ull, w3 += sigma1(w1) + w12 + sigma0(w4));
|
||||
Round(e, f, g, h, a, b, c, d, 0x391c0cb3c5c95a63ull, w4 += sigma1(w2) + w13 + sigma0(w5));
|
||||
Round(d, e, f, g, h, a, b, c, 0x4ed8aa4ae3418acbull, w5 += sigma1(w3) + w14 + sigma0(w6));
|
||||
Round(c, d, e, f, g, h, a, b, 0x5b9cca4f7763e373ull, w6 += sigma1(w4) + w15 + sigma0(w7));
|
||||
Round(b, c, d, e, f, g, h, a, 0x682e6ff3d6b2b8a3ull, w7 += sigma1(w5) + w0 + sigma0(w8));
|
||||
Round(a, b, c, d, e, f, g, h, 0x748f82ee5defb2fcull, w8 += sigma1(w6) + w1 + sigma0(w9));
|
||||
Round(h, a, b, c, d, e, f, g, 0x78a5636f43172f60ull, w9 += sigma1(w7) + w2 + sigma0(w10));
|
||||
Round(g, h, a, b, c, d, e, f, 0x84c87814a1f0ab72ull, w10 += sigma1(w8) + w3 + sigma0(w11));
|
||||
Round(f, g, h, a, b, c, d, e, 0x8cc702081a6439ecull, w11 += sigma1(w9) + w4 + sigma0(w12));
|
||||
Round(e, f, g, h, a, b, c, d, 0x90befffa23631e28ull, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||
Round(d, e, f, g, h, a, b, c, 0xa4506cebde82bde9ull, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||
Round(c, d, e, f, g, h, a, b, 0xbef9a3f7b2c67915ull, w14 += sigma1(w12) + w7 + sigma0(w15));
|
||||
Round(b, c, d, e, f, g, h, a, 0xc67178f2e372532bull, w15 += sigma1(w13) + w8 + sigma0(w0));
|
||||
|
||||
Round(a, b, c, d, e, f, g, h, 0xca273eceea26619cull, w0 += sigma1(w14) + w9 + sigma0(w1));
|
||||
Round(h, a, b, c, d, e, f, g, 0xd186b8c721c0c207ull, w1 += sigma1(w15) + w10 + sigma0(w2));
|
||||
Round(g, h, a, b, c, d, e, f, 0xeada7dd6cde0eb1eull, w2 += sigma1(w0) + w11 + sigma0(w3));
|
||||
Round(f, g, h, a, b, c, d, e, 0xf57d4f7fee6ed178ull, w3 += sigma1(w1) + w12 + sigma0(w4));
|
||||
Round(e, f, g, h, a, b, c, d, 0x06f067aa72176fbaull, w4 += sigma1(w2) + w13 + sigma0(w5));
|
||||
Round(d, e, f, g, h, a, b, c, 0x0a637dc5a2c898a6ull, w5 += sigma1(w3) + w14 + sigma0(w6));
|
||||
Round(c, d, e, f, g, h, a, b, 0x113f9804bef90daeull, w6 += sigma1(w4) + w15 + sigma0(w7));
|
||||
Round(b, c, d, e, f, g, h, a, 0x1b710b35131c471bull, w7 += sigma1(w5) + w0 + sigma0(w8));
|
||||
Round(a, b, c, d, e, f, g, h, 0x28db77f523047d84ull, w8 += sigma1(w6) + w1 + sigma0(w9));
|
||||
Round(h, a, b, c, d, e, f, g, 0x32caab7b40c72493ull, w9 += sigma1(w7) + w2 + sigma0(w10));
|
||||
Round(g, h, a, b, c, d, e, f, 0x3c9ebe0a15c9bebcull, w10 += sigma1(w8) + w3 + sigma0(w11));
|
||||
Round(f, g, h, a, b, c, d, e, 0x431d67c49c100d4cull, w11 += sigma1(w9) + w4 + sigma0(w12));
|
||||
Round(e, f, g, h, a, b, c, d, 0x4cc5d4becb3e42b6ull, w12 += sigma1(w10) + w5 + sigma0(w13));
|
||||
Round(d, e, f, g, h, a, b, c, 0x597f299cfc657e2aull, w13 += sigma1(w11) + w6 + sigma0(w14));
|
||||
Round(c, d, e, f, g, h, a, b, 0x5fcb6fab3ad6faecull, w14 + sigma1(w12) + w7 + sigma0(w15));
|
||||
Round(b, c, d, e, f, g, h, a, 0x6c44198c4a475817ull, w15 + sigma1(w13) + w8 + sigma0(w0));
|
||||
|
||||
s[0] += a;
|
||||
s[1] += b;
|
||||
s[2] += c;
|
||||
s[3] += d;
|
||||
s[4] += e;
|
||||
s[5] += f;
|
||||
s[6] += g;
|
||||
s[7] += h;
|
||||
}
|
||||
|
||||
} // namespace sha512
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
////// SHA-512
|
||||
|
||||
CSHA512::CSHA512() : bytes(0)
|
||||
{
|
||||
sha512::Initialize(s);
|
||||
}
|
||||
|
||||
CSHA512& CSHA512::Write(const unsigned char* data, size_t len)
|
||||
{
|
||||
const unsigned char* end = data + len;
|
||||
size_t bufsize = bytes % 128;
|
||||
if (bufsize && bufsize + len >= 128) {
|
||||
// Fill the buffer, and process it.
|
||||
memcpy(buf + bufsize, data, 128 - bufsize);
|
||||
bytes += 128 - bufsize;
|
||||
data += 128 - bufsize;
|
||||
sha512::Transform(s, buf);
|
||||
bufsize = 0;
|
||||
}
|
||||
while (end - data >= 128) {
|
||||
// Process full chunks directly from the source.
|
||||
sha512::Transform(s, data);
|
||||
data += 128;
|
||||
bytes += 128;
|
||||
}
|
||||
if (end > data) {
|
||||
// Fill the buffer with what remains.
|
||||
memcpy(buf + bufsize, data, end - data);
|
||||
bytes += end - data;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CSHA512::Finalize(unsigned char hash[OUTPUT_SIZE])
|
||||
{
|
||||
static const unsigned char pad[128] = {0x80};
|
||||
unsigned char sizedesc[16] = {0x00};
|
||||
WriteBE64(sizedesc + 8, bytes << 3);
|
||||
Write(pad, 1 + ((239 - (bytes % 128)) % 128));
|
||||
Write(sizedesc, 16);
|
||||
WriteBE64(hash, s[0]);
|
||||
WriteBE64(hash + 8, s[1]);
|
||||
WriteBE64(hash + 16, s[2]);
|
||||
WriteBE64(hash + 24, s[3]);
|
||||
WriteBE64(hash + 32, s[4]);
|
||||
WriteBE64(hash + 40, s[5]);
|
||||
WriteBE64(hash + 48, s[6]);
|
||||
WriteBE64(hash + 56, s[7]);
|
||||
}
|
||||
|
||||
CSHA512& CSHA512::Reset()
|
||||
{
|
||||
bytes = 0;
|
||||
sha512::Initialize(s);
|
||||
return *this;
|
||||
}
|
||||
30
src/crypto/sha512.h
Normal file
30
src/crypto/sha512.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) 2014-2020 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef DIGIBYTE_CRYPTO_SHA512_H
|
||||
#define DIGIBYTE_CRYPTO_SHA512_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/** A hasher class for SHA-512. */
|
||||
class CSHA512
|
||||
{
|
||||
private:
|
||||
uint64_t s[8];
|
||||
unsigned char buf[128];
|
||||
size_t bytes;
|
||||
|
||||
public:
|
||||
static constexpr size_t OUTPUT_SIZE = 64;
|
||||
|
||||
CSHA512();
|
||||
CSHA512& Write(const unsigned char* data, size_t len);
|
||||
void Finalize(unsigned char hash[OUTPUT_SIZE]);
|
||||
CSHA512& Reset();
|
||||
uint64_t Size() const { return bytes; }
|
||||
};
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_SHA512_H
|
||||
1764
src/crypto/shavite.cpp
Normal file
1764
src/crypto/shavite.cpp
Normal file
File diff suppressed because it is too large
Load diff
1799
src/crypto/simd.cpp
Normal file
1799
src/crypto/simd.cpp
Normal file
File diff suppressed because it is too large
Load diff
173
src/crypto/siphash.cpp
Normal file
173
src/crypto/siphash.cpp
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
// Copyright (c) 2016-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <crypto/siphash.h>
|
||||
|
||||
#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
|
||||
|
||||
#define SIPROUND do { \
|
||||
v0 += v1; v1 = ROTL(v1, 13); v1 ^= v0; \
|
||||
v0 = ROTL(v0, 32); \
|
||||
v2 += v3; v3 = ROTL(v3, 16); v3 ^= v2; \
|
||||
v0 += v3; v3 = ROTL(v3, 21); v3 ^= v0; \
|
||||
v2 += v1; v1 = ROTL(v1, 17); v1 ^= v2; \
|
||||
v2 = ROTL(v2, 32); \
|
||||
} while (0)
|
||||
|
||||
CSipHasher::CSipHasher(uint64_t k0, uint64_t k1)
|
||||
{
|
||||
v[0] = 0x736f6d6570736575ULL ^ k0;
|
||||
v[1] = 0x646f72616e646f6dULL ^ k1;
|
||||
v[2] = 0x6c7967656e657261ULL ^ k0;
|
||||
v[3] = 0x7465646279746573ULL ^ k1;
|
||||
count = 0;
|
||||
tmp = 0;
|
||||
}
|
||||
|
||||
CSipHasher& CSipHasher::Write(uint64_t data)
|
||||
{
|
||||
uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
|
||||
|
||||
assert(count % 8 == 0);
|
||||
|
||||
v3 ^= data;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
v0 ^= data;
|
||||
|
||||
v[0] = v0;
|
||||
v[1] = v1;
|
||||
v[2] = v2;
|
||||
v[3] = v3;
|
||||
|
||||
count += 8;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CSipHasher& CSipHasher::Write(const unsigned char* data, size_t size)
|
||||
{
|
||||
uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
|
||||
uint64_t t = tmp;
|
||||
uint8_t c = count;
|
||||
|
||||
while (size--) {
|
||||
t |= ((uint64_t)(*(data++))) << (8 * (c % 8));
|
||||
c++;
|
||||
if ((c & 7) == 0) {
|
||||
v3 ^= t;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
v0 ^= t;
|
||||
t = 0;
|
||||
}
|
||||
}
|
||||
|
||||
v[0] = v0;
|
||||
v[1] = v1;
|
||||
v[2] = v2;
|
||||
v[3] = v3;
|
||||
count = c;
|
||||
tmp = t;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
uint64_t CSipHasher::Finalize() const
|
||||
{
|
||||
uint64_t v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
|
||||
|
||||
uint64_t t = tmp | (((uint64_t)count) << 56);
|
||||
|
||||
v3 ^= t;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
v0 ^= t;
|
||||
v2 ^= 0xFF;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
return v0 ^ v1 ^ v2 ^ v3;
|
||||
}
|
||||
|
||||
uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256& val)
|
||||
{
|
||||
/* Specialized implementation for efficiency */
|
||||
uint64_t d = val.GetUint64(0);
|
||||
|
||||
uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
|
||||
uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
|
||||
uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
|
||||
uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;
|
||||
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
v0 ^= d;
|
||||
d = val.GetUint64(1);
|
||||
v3 ^= d;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
v0 ^= d;
|
||||
d = val.GetUint64(2);
|
||||
v3 ^= d;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
v0 ^= d;
|
||||
d = val.GetUint64(3);
|
||||
v3 ^= d;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
v0 ^= d;
|
||||
v3 ^= ((uint64_t)4) << 59;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
v0 ^= ((uint64_t)4) << 59;
|
||||
v2 ^= 0xFF;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
return v0 ^ v1 ^ v2 ^ v3;
|
||||
}
|
||||
|
||||
uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256& val, uint32_t extra)
|
||||
{
|
||||
/* Specialized implementation for efficiency */
|
||||
uint64_t d = val.GetUint64(0);
|
||||
|
||||
uint64_t v0 = 0x736f6d6570736575ULL ^ k0;
|
||||
uint64_t v1 = 0x646f72616e646f6dULL ^ k1;
|
||||
uint64_t v2 = 0x6c7967656e657261ULL ^ k0;
|
||||
uint64_t v3 = 0x7465646279746573ULL ^ k1 ^ d;
|
||||
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
v0 ^= d;
|
||||
d = val.GetUint64(1);
|
||||
v3 ^= d;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
v0 ^= d;
|
||||
d = val.GetUint64(2);
|
||||
v3 ^= d;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
v0 ^= d;
|
||||
d = val.GetUint64(3);
|
||||
v3 ^= d;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
v0 ^= d;
|
||||
d = (((uint64_t)36) << 56) | extra;
|
||||
v3 ^= d;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
v0 ^= d;
|
||||
v2 ^= 0xFF;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
SIPROUND;
|
||||
return v0 ^ v1 ^ v2 ^ v3;
|
||||
}
|
||||
47
src/crypto/siphash.h
Normal file
47
src/crypto/siphash.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright (c) 2016-2020 The DigiByte Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef DIGIBYTE_CRYPTO_SIPHASH_H
|
||||
#define DIGIBYTE_CRYPTO_SIPHASH_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <uint256.h>
|
||||
|
||||
/** SipHash-2-4 */
|
||||
class CSipHasher
|
||||
{
|
||||
private:
|
||||
uint64_t v[4];
|
||||
uint64_t tmp;
|
||||
uint8_t count; // Only the low 8 bits of the input size matter.
|
||||
|
||||
public:
|
||||
/** Construct a SipHash calculator initialized with 128-bit key (k0, k1) */
|
||||
CSipHasher(uint64_t k0, uint64_t k1);
|
||||
/** Hash a 64-bit integer worth of data
|
||||
* It is treated as if this was the little-endian interpretation of 8 bytes.
|
||||
* This function can only be used when a multiple of 8 bytes have been written so far.
|
||||
*/
|
||||
CSipHasher& Write(uint64_t data);
|
||||
/** Hash arbitrary bytes. */
|
||||
CSipHasher& Write(const unsigned char* data, size_t size);
|
||||
/** Compute the 64-bit SipHash-2-4 of the data written so far. The object remains untouched. */
|
||||
uint64_t Finalize() const;
|
||||
};
|
||||
|
||||
/** Optimized SipHash-2-4 implementation for uint256.
|
||||
*
|
||||
* It is identical to:
|
||||
* SipHasher(k0, k1)
|
||||
* .Write(val.GetUint64(0))
|
||||
* .Write(val.GetUint64(1))
|
||||
* .Write(val.GetUint64(2))
|
||||
* .Write(val.GetUint64(3))
|
||||
* .Finalize()
|
||||
*/
|
||||
uint64_t SipHashUint256(uint64_t k0, uint64_t k1, const uint256& val);
|
||||
uint64_t SipHashUint256Extra(uint64_t k0, uint64_t k1, const uint256& val, uint32_t extra);
|
||||
|
||||
#endif // DIGIBYTE_CRYPTO_SIPHASH_H
|
||||
327
src/crypto/sph_blake.h
Normal file
327
src/crypto/sph_blake.h
Normal file
|
|
@ -0,0 +1,327 @@
|
|||
/* $Id: sph_blake.h 252 2011-06-07 17:55:14Z tp $ */
|
||||
/**
|
||||
* BLAKE interface. BLAKE is a family of functions which differ by their
|
||||
* output size; this implementation defines BLAKE for output sizes 224,
|
||||
* 256, 384 and 512 bits. This implementation conforms to the "third
|
||||
* round" specification.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_blake.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_BLAKE_H__
|
||||
#define SPH_BLAKE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BLAKE-224.
|
||||
*/
|
||||
#define SPH_SIZE_blake224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BLAKE-256.
|
||||
*/
|
||||
#define SPH_SIZE_blake256 256
|
||||
|
||||
#if SPH_64
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BLAKE-384.
|
||||
*/
|
||||
#define SPH_SIZE_blake384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BLAKE-512.
|
||||
*/
|
||||
#define SPH_SIZE_blake512 512
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This structure is a context for BLAKE-224 and BLAKE-256 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a BLAKE computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running BLAKE
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[64]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 H[8];
|
||||
sph_u32 S[4];
|
||||
sph_u32 T0, T1;
|
||||
#endif
|
||||
} sph_blake_small_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BLAKE-224 computations. It is
|
||||
* identical to the common <code>sph_blake_small_context</code>.
|
||||
*/
|
||||
typedef sph_blake_small_context sph_blake224_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BLAKE-256 computations. It is
|
||||
* identical to the common <code>sph_blake_small_context</code>.
|
||||
*/
|
||||
typedef sph_blake_small_context sph_blake256_context;
|
||||
|
||||
#if SPH_64
|
||||
|
||||
/**
|
||||
* This structure is a context for BLAKE-384 and BLAKE-512 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a BLAKE computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running BLAKE
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[128]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u64 H[8];
|
||||
sph_u64 S[4];
|
||||
sph_u64 T0, T1;
|
||||
#endif
|
||||
} sph_blake_big_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BLAKE-384 computations. It is
|
||||
* identical to the common <code>sph_blake_small_context</code>.
|
||||
*/
|
||||
typedef sph_blake_big_context sph_blake384_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BLAKE-512 computations. It is
|
||||
* identical to the common <code>sph_blake_small_context</code>.
|
||||
*/
|
||||
typedef sph_blake_big_context sph_blake512_context;
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize a BLAKE-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BLAKE-224 context (pointer to a
|
||||
* <code>sph_blake224_context</code>)
|
||||
*/
|
||||
void sph_blake224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BLAKE-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_blake224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BLAKE-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a BLAKE-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BLAKE-256 context (pointer to a
|
||||
* <code>sph_blake256_context</code>)
|
||||
*/
|
||||
void sph_blake256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BLAKE-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_blake256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BLAKE-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#if SPH_64
|
||||
|
||||
/**
|
||||
* Initialize a BLAKE-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BLAKE-384 context (pointer to a
|
||||
* <code>sph_blake384_context</code>)
|
||||
*/
|
||||
void sph_blake384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BLAKE-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_blake384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BLAKE-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a BLAKE-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BLAKE-512 context (pointer to a
|
||||
* <code>sph_blake512_context</code>)
|
||||
*/
|
||||
void sph_blake512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BLAKE-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_blake512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BLAKE-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BLAKE-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_blake512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
328
src/crypto/sph_bmw.h
Normal file
328
src/crypto/sph_bmw.h
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
/* $Id: sph_bmw.h 216 2010-06-08 09:46:57Z tp $ */
|
||||
/**
|
||||
* BMW interface. BMW (aka "Blue Midnight Wish") is a family of
|
||||
* functions which differ by their output size; this implementation
|
||||
* defines BMW for output sizes 224, 256, 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_bmw.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_BMW_H__
|
||||
#define SPH_BMW_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BMW-224.
|
||||
*/
|
||||
#define SPH_SIZE_bmw224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BMW-256.
|
||||
*/
|
||||
#define SPH_SIZE_bmw256 256
|
||||
|
||||
#if SPH_64
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BMW-384.
|
||||
*/
|
||||
#define SPH_SIZE_bmw384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for BMW-512.
|
||||
*/
|
||||
#define SPH_SIZE_bmw512 512
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This structure is a context for BMW-224 and BMW-256 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a BMW computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running BMW
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[64]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 H[16];
|
||||
#if SPH_64
|
||||
sph_u64 bit_count;
|
||||
#else
|
||||
sph_u32 bit_count_high, bit_count_low;
|
||||
#endif
|
||||
#endif
|
||||
} sph_bmw_small_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BMW-224 computations. It is
|
||||
* identical to the common <code>sph_bmw_small_context</code>.
|
||||
*/
|
||||
typedef sph_bmw_small_context sph_bmw224_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BMW-256 computations. It is
|
||||
* identical to the common <code>sph_bmw_small_context</code>.
|
||||
*/
|
||||
typedef sph_bmw_small_context sph_bmw256_context;
|
||||
|
||||
#if SPH_64
|
||||
|
||||
/**
|
||||
* This structure is a context for BMW-384 and BMW-512 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a BMW computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running BMW
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[128]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u64 H[16];
|
||||
sph_u64 bit_count;
|
||||
#endif
|
||||
} sph_bmw_big_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BMW-384 computations. It is
|
||||
* identical to the common <code>sph_bmw_small_context</code>.
|
||||
*/
|
||||
typedef sph_bmw_big_context sph_bmw384_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for BMW-512 computations. It is
|
||||
* identical to the common <code>sph_bmw_small_context</code>.
|
||||
*/
|
||||
typedef sph_bmw_big_context sph_bmw512_context;
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize a BMW-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BMW-224 context (pointer to a
|
||||
* <code>sph_bmw224_context</code>)
|
||||
*/
|
||||
void sph_bmw224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BMW-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_bmw224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BMW-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BMW-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BMW-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a BMW-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BMW-256 context (pointer to a
|
||||
* <code>sph_bmw256_context</code>)
|
||||
*/
|
||||
void sph_bmw256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BMW-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_bmw256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BMW-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BMW-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BMW-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#if SPH_64
|
||||
|
||||
/**
|
||||
* Initialize a BMW-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BMW-384 context (pointer to a
|
||||
* <code>sph_bmw384_context</code>)
|
||||
*/
|
||||
void sph_bmw384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BMW-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_bmw384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BMW-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BMW-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BMW-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a BMW-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the BMW-512 context (pointer to a
|
||||
* <code>sph_bmw512_context</code>)
|
||||
*/
|
||||
void sph_bmw512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the BMW-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_bmw512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current BMW-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the BMW-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the BMW-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_bmw512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
292
src/crypto/sph_cubehash.h
Normal file
292
src/crypto/sph_cubehash.h
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
/* $Id: sph_cubehash.h 180 2010-05-08 02:29:25Z tp $ */
|
||||
/**
|
||||
* CubeHash interface. CubeHash is a family of functions which differ by
|
||||
* their output size; this implementation defines CubeHash for output
|
||||
* sizes 224, 256, 384 and 512 bits, with the "standard parameters"
|
||||
* (CubeHash16/32 with the CubeHash specification notations).
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_cubehash.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_CUBEHASH_H__
|
||||
#define SPH_CUBEHASH_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for CubeHash-224.
|
||||
*/
|
||||
#define SPH_SIZE_cubehash224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for CubeHash-256.
|
||||
*/
|
||||
#define SPH_SIZE_cubehash256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for CubeHash-384.
|
||||
*/
|
||||
#define SPH_SIZE_cubehash384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for CubeHash-512.
|
||||
*/
|
||||
#define SPH_SIZE_cubehash512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for CubeHash computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once
|
||||
* a CubeHash computation has been performed, the context can be reused for
|
||||
* another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running CubeHash computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[32]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 state[32];
|
||||
#endif
|
||||
} sph_cubehash_context;
|
||||
|
||||
/**
|
||||
* Type for a CubeHash-224 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_cubehash_context sph_cubehash224_context;
|
||||
|
||||
/**
|
||||
* Type for a CubeHash-256 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_cubehash_context sph_cubehash256_context;
|
||||
|
||||
/**
|
||||
* Type for a CubeHash-384 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_cubehash_context sph_cubehash384_context;
|
||||
|
||||
/**
|
||||
* Type for a CubeHash-512 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_cubehash_context sph_cubehash512_context;
|
||||
|
||||
/**
|
||||
* Initialize a CubeHash-224 context. This process performs no memory
|
||||
* allocation.
|
||||
*
|
||||
* @param cc the CubeHash-224 context (pointer to a
|
||||
* <code>sph_cubehash224_context</code>)
|
||||
*/
|
||||
void sph_cubehash224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the CubeHash-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_cubehash224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current CubeHash-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a CubeHash-256 context. This process performs no memory
|
||||
* allocation.
|
||||
*
|
||||
* @param cc the CubeHash-256 context (pointer to a
|
||||
* <code>sph_cubehash256_context</code>)
|
||||
*/
|
||||
void sph_cubehash256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the CubeHash-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_cubehash256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current CubeHash-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a CubeHash-384 context. This process performs no memory
|
||||
* allocation.
|
||||
*
|
||||
* @param cc the CubeHash-384 context (pointer to a
|
||||
* <code>sph_cubehash384_context</code>)
|
||||
*/
|
||||
void sph_cubehash384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the CubeHash-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_cubehash384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current CubeHash-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a CubeHash-512 context. This process performs no memory
|
||||
* allocation.
|
||||
*
|
||||
* @param cc the CubeHash-512 context (pointer to a
|
||||
* <code>sph_cubehash512_context</code>)
|
||||
*/
|
||||
void sph_cubehash512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the CubeHash-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_cubehash512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current CubeHash-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the CubeHash-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_cubehash512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
320
src/crypto/sph_echo.h
Normal file
320
src/crypto/sph_echo.h
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
/* $Id: sph_echo.h 216 2010-06-08 09:46:57Z tp $ */
|
||||
/**
|
||||
* ECHO interface. ECHO is a family of functions which differ by
|
||||
* their output size; this implementation defines ECHO for output
|
||||
* sizes 224, 256, 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_echo.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_ECHO_H__
|
||||
#define SPH_ECHO_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for ECHO-224.
|
||||
*/
|
||||
#define SPH_SIZE_echo224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for ECHO-256.
|
||||
*/
|
||||
#define SPH_SIZE_echo256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for ECHO-384.
|
||||
*/
|
||||
#define SPH_SIZE_echo384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for ECHO-512.
|
||||
*/
|
||||
#define SPH_SIZE_echo512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for ECHO computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once
|
||||
* an ECHO computation has been performed, the context can be reused for
|
||||
* another computation. This specific structure is used for ECHO-224
|
||||
* and ECHO-256.
|
||||
*
|
||||
* The contents of this structure are private. A running ECHO computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[192]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
union {
|
||||
sph_u32 Vs[4][4];
|
||||
#if SPH_64
|
||||
sph_u64 Vb[4][2];
|
||||
#endif
|
||||
} u;
|
||||
sph_u32 C0, C1, C2, C3;
|
||||
#endif
|
||||
} sph_echo_small_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for ECHO computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once
|
||||
* an ECHO computation has been performed, the context can be reused for
|
||||
* another computation. This specific structure is used for ECHO-384
|
||||
* and ECHO-512.
|
||||
*
|
||||
* The contents of this structure are private. A running ECHO computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[128]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
union {
|
||||
sph_u32 Vs[8][4];
|
||||
#if SPH_64
|
||||
sph_u64 Vb[8][2];
|
||||
#endif
|
||||
} u;
|
||||
sph_u32 C0, C1, C2, C3;
|
||||
#endif
|
||||
} sph_echo_big_context;
|
||||
|
||||
/**
|
||||
* Type for a ECHO-224 context (identical to the common "small" context).
|
||||
*/
|
||||
typedef sph_echo_small_context sph_echo224_context;
|
||||
|
||||
/**
|
||||
* Type for a ECHO-256 context (identical to the common "small" context).
|
||||
*/
|
||||
typedef sph_echo_small_context sph_echo256_context;
|
||||
|
||||
/**
|
||||
* Type for a ECHO-384 context (identical to the common "big" context).
|
||||
*/
|
||||
typedef sph_echo_big_context sph_echo384_context;
|
||||
|
||||
/**
|
||||
* Type for a ECHO-512 context (identical to the common "big" context).
|
||||
*/
|
||||
typedef sph_echo_big_context sph_echo512_context;
|
||||
|
||||
/**
|
||||
* Initialize an ECHO-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the ECHO-224 context (pointer to a
|
||||
* <code>sph_echo224_context</code>)
|
||||
*/
|
||||
void sph_echo224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the ECHO-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_echo224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current ECHO-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize an ECHO-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the ECHO-256 context (pointer to a
|
||||
* <code>sph_echo256_context</code>)
|
||||
*/
|
||||
void sph_echo256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the ECHO-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_echo256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current ECHO-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize an ECHO-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the ECHO-384 context (pointer to a
|
||||
* <code>sph_echo384_context</code>)
|
||||
*/
|
||||
void sph_echo384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the ECHO-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_echo384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current ECHO-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize an ECHO-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the ECHO-512 context (pointer to a
|
||||
* <code>sph_echo512_context</code>)
|
||||
*/
|
||||
void sph_echo512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the ECHO-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_echo512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current ECHO-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the ECHO-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_echo512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
298
src/crypto/sph_jh.h
Normal file
298
src/crypto/sph_jh.h
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
/* $Id: sph_jh.h 216 2010-06-08 09:46:57Z tp $ */
|
||||
/**
|
||||
* JH interface. JH is a family of functions which differ by
|
||||
* their output size; this implementation defines JH for output
|
||||
* sizes 224, 256, 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_jh.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_JH_H__
|
||||
#define SPH_JH_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for JH-224.
|
||||
*/
|
||||
#define SPH_SIZE_jh224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for JH-256.
|
||||
*/
|
||||
#define SPH_SIZE_jh256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for JH-384.
|
||||
*/
|
||||
#define SPH_SIZE_jh384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for JH-512.
|
||||
*/
|
||||
#define SPH_SIZE_jh512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for JH computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once
|
||||
* a JH computation has been performed, the context can be reused for
|
||||
* another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running JH computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[64]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
union {
|
||||
#if SPH_64
|
||||
sph_u64 wide[16];
|
||||
#endif
|
||||
sph_u32 narrow[32];
|
||||
} H;
|
||||
#if SPH_64
|
||||
sph_u64 block_count;
|
||||
#else
|
||||
sph_u32 block_count_high, block_count_low;
|
||||
#endif
|
||||
#endif
|
||||
} sph_jh_context;
|
||||
|
||||
/**
|
||||
* Type for a JH-224 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_jh_context sph_jh224_context;
|
||||
|
||||
/**
|
||||
* Type for a JH-256 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_jh_context sph_jh256_context;
|
||||
|
||||
/**
|
||||
* Type for a JH-384 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_jh_context sph_jh384_context;
|
||||
|
||||
/**
|
||||
* Type for a JH-512 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_jh_context sph_jh512_context;
|
||||
|
||||
/**
|
||||
* Initialize a JH-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the JH-224 context (pointer to a
|
||||
* <code>sph_jh224_context</code>)
|
||||
*/
|
||||
void sph_jh224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the JH-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_jh224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current JH-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the JH-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the JH-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a JH-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the JH-256 context (pointer to a
|
||||
* <code>sph_jh256_context</code>)
|
||||
*/
|
||||
void sph_jh256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the JH-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_jh256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current JH-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the JH-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the JH-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a JH-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the JH-384 context (pointer to a
|
||||
* <code>sph_jh384_context</code>)
|
||||
*/
|
||||
void sph_jh384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the JH-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_jh384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current JH-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the JH-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the JH-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a JH-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the JH-512 context (pointer to a
|
||||
* <code>sph_jh512_context</code>)
|
||||
*/
|
||||
void sph_jh512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the JH-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_jh512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current JH-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the JH-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the JH-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_jh512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
293
src/crypto/sph_keccak.h
Normal file
293
src/crypto/sph_keccak.h
Normal file
|
|
@ -0,0 +1,293 @@
|
|||
/* $Id: sph_keccak.h 216 2010-06-08 09:46:57Z tp $ */
|
||||
/**
|
||||
* Keccak interface. This is the interface for Keccak with the
|
||||
* recommended parameters for SHA-3, with output lengths 224, 256,
|
||||
* 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_keccak.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_KECCAK_H__
|
||||
#define SPH_KECCAK_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Keccak-224.
|
||||
*/
|
||||
#define SPH_SIZE_keccak224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Keccak-256.
|
||||
*/
|
||||
#define SPH_SIZE_keccak256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Keccak-384.
|
||||
*/
|
||||
#define SPH_SIZE_keccak384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Keccak-512.
|
||||
*/
|
||||
#define SPH_SIZE_keccak512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for Keccak computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once a
|
||||
* Keccak computation has been performed, the context can be reused for
|
||||
* another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running Keccak computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[144]; /* first field, for alignment */
|
||||
size_t ptr, lim;
|
||||
union {
|
||||
#if SPH_64
|
||||
sph_u64 wide[25];
|
||||
#endif
|
||||
sph_u32 narrow[50];
|
||||
} u;
|
||||
#endif
|
||||
} sph_keccak_context;
|
||||
|
||||
/**
|
||||
* Type for a Keccak-224 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_keccak_context sph_keccak224_context;
|
||||
|
||||
/**
|
||||
* Type for a Keccak-256 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_keccak_context sph_keccak256_context;
|
||||
|
||||
/**
|
||||
* Type for a Keccak-384 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_keccak_context sph_keccak384_context;
|
||||
|
||||
/**
|
||||
* Type for a Keccak-512 context (identical to the common context).
|
||||
*/
|
||||
typedef sph_keccak_context sph_keccak512_context;
|
||||
|
||||
/**
|
||||
* Initialize a Keccak-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Keccak-224 context (pointer to a
|
||||
* <code>sph_keccak224_context</code>)
|
||||
*/
|
||||
void sph_keccak224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Keccak-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_keccak224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Keccak-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Keccak-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Keccak-256 context (pointer to a
|
||||
* <code>sph_keccak256_context</code>)
|
||||
*/
|
||||
void sph_keccak256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Keccak-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_keccak256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Keccak-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Keccak-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Keccak-384 context (pointer to a
|
||||
* <code>sph_keccak384_context</code>)
|
||||
*/
|
||||
void sph_keccak384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Keccak-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_keccak384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Keccak-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Keccak-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Keccak-512 context (pointer to a
|
||||
* <code>sph_keccak512_context</code>)
|
||||
*/
|
||||
void sph_keccak512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Keccak-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_keccak512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Keccak-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Keccak-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_keccak512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
296
src/crypto/sph_luffa.h
Normal file
296
src/crypto/sph_luffa.h
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
/* $Id: sph_luffa.h 154 2010-04-26 17:00:24Z tp $ */
|
||||
/**
|
||||
* Luffa interface. Luffa is a family of functions which differ by
|
||||
* their output size; this implementation defines Luffa for output
|
||||
* sizes 224, 256, 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_luffa.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_LUFFA_H__
|
||||
#define SPH_LUFFA_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Luffa-224.
|
||||
*/
|
||||
#define SPH_SIZE_luffa224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Luffa-256.
|
||||
*/
|
||||
#define SPH_SIZE_luffa256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Luffa-384.
|
||||
*/
|
||||
#define SPH_SIZE_luffa384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Luffa-512.
|
||||
*/
|
||||
#define SPH_SIZE_luffa512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for Luffa-224 computations: it contains
|
||||
* the intermediate values and some data from the last entered block.
|
||||
* Once a Luffa computation has been performed, the context can be
|
||||
* reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running Luffa
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[32]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 V[3][8];
|
||||
#endif
|
||||
} sph_luffa224_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Luffa-256 computations. It is
|
||||
* identical to <code>sph_luffa224_context</code>.
|
||||
*/
|
||||
typedef sph_luffa224_context sph_luffa256_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Luffa-384 computations.
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[32]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 V[4][8];
|
||||
#endif
|
||||
} sph_luffa384_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Luffa-512 computations.
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[32]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 V[5][8];
|
||||
#endif
|
||||
} sph_luffa512_context;
|
||||
|
||||
/**
|
||||
* Initialize a Luffa-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Luffa-224 context (pointer to a
|
||||
* <code>sph_luffa224_context</code>)
|
||||
*/
|
||||
void sph_luffa224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Luffa-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_luffa224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Luffa-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Luffa-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Luffa-256 context (pointer to a
|
||||
* <code>sph_luffa256_context</code>)
|
||||
*/
|
||||
void sph_luffa256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Luffa-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_luffa256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Luffa-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Luffa-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Luffa-384 context (pointer to a
|
||||
* <code>sph_luffa384_context</code>)
|
||||
*/
|
||||
void sph_luffa384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Luffa-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_luffa384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Luffa-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Luffa-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Luffa-512 context (pointer to a
|
||||
* <code>sph_luffa512_context</code>)
|
||||
*/
|
||||
void sph_luffa512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the Luffa-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_luffa512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Luffa-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the Luffa-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_luffa512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
314
src/crypto/sph_shavite.h
Normal file
314
src/crypto/sph_shavite.h
Normal file
|
|
@ -0,0 +1,314 @@
|
|||
/* $Id: sph_shavite.h 208 2010-06-02 20:33:00Z tp $ */
|
||||
/**
|
||||
* SHAvite-3 interface. This code implements SHAvite-3 with the
|
||||
* recommended parameters for SHA-3, with outputs of 224, 256, 384 and
|
||||
* 512 bits. In the following, we call the function "SHAvite" (without
|
||||
* the "-3" suffix), thus "SHAvite-224" is "SHAvite-3 with a 224-bit
|
||||
* output".
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_shavite.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_SHAVITE_H__
|
||||
#define SPH_SHAVITE_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SHAvite-224.
|
||||
*/
|
||||
#define SPH_SIZE_shavite224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SHAvite-256.
|
||||
*/
|
||||
#define SPH_SIZE_shavite256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SHAvite-384.
|
||||
*/
|
||||
#define SPH_SIZE_shavite384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SHAvite-512.
|
||||
*/
|
||||
#define SPH_SIZE_shavite512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-224 and SHAvite-256 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a SHAvite computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running SHAvite
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[64]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 h[8];
|
||||
sph_u32 count0, count1;
|
||||
#endif
|
||||
} sph_shavite_small_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-224 computations. It is
|
||||
* identical to the common <code>sph_shavite_small_context</code>.
|
||||
*/
|
||||
typedef sph_shavite_small_context sph_shavite224_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-256 computations. It is
|
||||
* identical to the common <code>sph_shavite_small_context</code>.
|
||||
*/
|
||||
typedef sph_shavite_small_context sph_shavite256_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-384 and SHAvite-512 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a SHAvite computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running SHAvite
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[128]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 h[16];
|
||||
sph_u32 count0, count1, count2, count3;
|
||||
#endif
|
||||
} sph_shavite_big_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-384 computations. It is
|
||||
* identical to the common <code>sph_shavite_small_context</code>.
|
||||
*/
|
||||
typedef sph_shavite_big_context sph_shavite384_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SHAvite-512 computations. It is
|
||||
* identical to the common <code>sph_shavite_small_context</code>.
|
||||
*/
|
||||
typedef sph_shavite_big_context sph_shavite512_context;
|
||||
|
||||
/**
|
||||
* Initialize a SHAvite-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SHAvite-224 context (pointer to a
|
||||
* <code>sph_shavite224_context</code>)
|
||||
*/
|
||||
void sph_shavite224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SHAvite-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_shavite224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SHAvite-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a SHAvite-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SHAvite-256 context (pointer to a
|
||||
* <code>sph_shavite256_context</code>)
|
||||
*/
|
||||
void sph_shavite256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SHAvite-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_shavite256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SHAvite-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a SHAvite-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SHAvite-384 context (pointer to a
|
||||
* <code>sph_shavite384_context</code>)
|
||||
*/
|
||||
void sph_shavite384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SHAvite-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_shavite384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SHAvite-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a SHAvite-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SHAvite-512 context (pointer to a
|
||||
* <code>sph_shavite512_context</code>)
|
||||
*/
|
||||
void sph_shavite512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SHAvite-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_shavite512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SHAvite-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SHAvite-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_shavite512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
309
src/crypto/sph_simd.h
Normal file
309
src/crypto/sph_simd.h
Normal file
|
|
@ -0,0 +1,309 @@
|
|||
/* $Id: sph_simd.h 154 2010-04-26 17:00:24Z tp $ */
|
||||
/**
|
||||
* SIMD interface. SIMD is a family of functions which differ by
|
||||
* their output size; this implementation defines SIMD for output
|
||||
* sizes 224, 256, 384 and 512 bits.
|
||||
*
|
||||
* ==========================(LICENSE BEGIN)============================
|
||||
*
|
||||
* Copyright (c) 2007-2010 Projet RNRT SAPHIR
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* ===========================(LICENSE END)=============================
|
||||
*
|
||||
* @file sph_simd.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_SIMD_H__
|
||||
#define SPH_SIMD_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SIMD-224.
|
||||
*/
|
||||
#define SPH_SIZE_simd224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SIMD-256.
|
||||
*/
|
||||
#define SPH_SIZE_simd256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SIMD-384.
|
||||
*/
|
||||
#define SPH_SIZE_simd384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for SIMD-512.
|
||||
*/
|
||||
#define SPH_SIZE_simd512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for SIMD computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once
|
||||
* an SIMD computation has been performed, the context can be reused for
|
||||
* another computation. This specific structure is used for SIMD-224
|
||||
* and SIMD-256.
|
||||
*
|
||||
* The contents of this structure are private. A running SIMD computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[64]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 state[16];
|
||||
sph_u32 count_low, count_high;
|
||||
#endif
|
||||
} sph_simd_small_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for SIMD computations: it contains the
|
||||
* intermediate values and some data from the last entered block. Once
|
||||
* an SIMD computation has been performed, the context can be reused for
|
||||
* another computation. This specific structure is used for SIMD-384
|
||||
* and SIMD-512.
|
||||
*
|
||||
* The contents of this structure are private. A running SIMD computation
|
||||
* can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char buf[128]; /* first field, for alignment */
|
||||
size_t ptr;
|
||||
sph_u32 state[32];
|
||||
sph_u32 count_low, count_high;
|
||||
#endif
|
||||
} sph_simd_big_context;
|
||||
|
||||
/**
|
||||
* Type for a SIMD-224 context (identical to the common "small" context).
|
||||
*/
|
||||
typedef sph_simd_small_context sph_simd224_context;
|
||||
|
||||
/**
|
||||
* Type for a SIMD-256 context (identical to the common "small" context).
|
||||
*/
|
||||
typedef sph_simd_small_context sph_simd256_context;
|
||||
|
||||
/**
|
||||
* Type for a SIMD-384 context (identical to the common "big" context).
|
||||
*/
|
||||
typedef sph_simd_big_context sph_simd384_context;
|
||||
|
||||
/**
|
||||
* Type for a SIMD-512 context (identical to the common "big" context).
|
||||
*/
|
||||
typedef sph_simd_big_context sph_simd512_context;
|
||||
|
||||
/**
|
||||
* Initialize an SIMD-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SIMD-224 context (pointer to a
|
||||
* <code>sph_simd224_context</code>)
|
||||
*/
|
||||
void sph_simd224_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SIMD-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_simd224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SIMD-224 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (28 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd224_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (28 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize an SIMD-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SIMD-256 context (pointer to a
|
||||
* <code>sph_simd256_context</code>)
|
||||
*/
|
||||
void sph_simd256_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SIMD-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_simd256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SIMD-256 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (32 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd256_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (32 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize an SIMD-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SIMD-384 context (pointer to a
|
||||
* <code>sph_simd384_context</code>)
|
||||
*/
|
||||
void sph_simd384_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SIMD-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_simd384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SIMD-384 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (48 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd384_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (48 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize an SIMD-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the SIMD-512 context (pointer to a
|
||||
* <code>sph_simd512_context</code>)
|
||||
*/
|
||||
void sph_simd512_init(void *cc);
|
||||
|
||||
/**
|
||||
* Process some data bytes. It is acceptable that <code>len</code> is zero
|
||||
* (in which case this function does nothing).
|
||||
*
|
||||
* @param cc the SIMD-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_simd512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current SIMD-512 computation and output the result into
|
||||
* the provided buffer. The destination buffer must be wide enough to
|
||||
* accomodate the result (64 bytes). The context is automatically
|
||||
* reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd512_close(void *cc, void *dst);
|
||||
|
||||
/**
|
||||
* Add a few additional bits (0 to 7) to the current computation, then
|
||||
* terminate it and output the result in the provided buffer, which must
|
||||
* be wide enough to accomodate the result (64 bytes). If bit number i
|
||||
* in <code>ub</code> has value 2^i, then the extra bits are those
|
||||
* numbered 7 downto 8-n (this is the big-endian convention at the byte
|
||||
* level). The context is automatically reinitialized.
|
||||
*
|
||||
* @param cc the SIMD-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_simd512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1976
src/crypto/sph_types.h
Normal file
1976
src/crypto/sph_types.h
Normal file
File diff suppressed because it is too large
Load diff
138
src/crypto/sysendian.h
Normal file
138
src/crypto/sysendian.h
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*-
|
||||
* Copyright 2007-2009 Colin Percival
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file was originally written by Colin Percival as part of the Tarsnap
|
||||
* online backup system.
|
||||
*/
|
||||
#ifndef _SYSENDIAN_H_
|
||||
#define _SYSENDIAN_H_
|
||||
|
||||
/* If we don't have be64enc, the <sys/endian.h> we have isn't usable. */
|
||||
#if !HAVE_DECL_BE64ENC
|
||||
#undef HAVE_SYS_ENDIAN_H
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_ENDIAN_H
|
||||
|
||||
#include <sys/endian.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
static inline uint32_t
|
||||
be32dec(const void *pp)
|
||||
{
|
||||
const uint8_t *p = (uint8_t const *)pp;
|
||||
|
||||
return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) +
|
||||
((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24));
|
||||
}
|
||||
|
||||
static inline void
|
||||
be32enc(void *pp, uint32_t x)
|
||||
{
|
||||
uint8_t * p = (uint8_t *)pp;
|
||||
|
||||
p[3] = x & 0xff;
|
||||
p[2] = (x >> 8) & 0xff;
|
||||
p[1] = (x >> 16) & 0xff;
|
||||
p[0] = (x >> 24) & 0xff;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
be64dec(const void *pp)
|
||||
{
|
||||
const uint8_t *p = (uint8_t const *)pp;
|
||||
|
||||
return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) +
|
||||
((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) +
|
||||
((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) +
|
||||
((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56));
|
||||
}
|
||||
|
||||
static inline void
|
||||
be64enc(void *pp, uint64_t x)
|
||||
{
|
||||
uint8_t * p = (uint8_t *)pp;
|
||||
|
||||
p[7] = x & 0xff;
|
||||
p[6] = (x >> 8) & 0xff;
|
||||
p[5] = (x >> 16) & 0xff;
|
||||
p[4] = (x >> 24) & 0xff;
|
||||
p[3] = (x >> 32) & 0xff;
|
||||
p[2] = (x >> 40) & 0xff;
|
||||
p[1] = (x >> 48) & 0xff;
|
||||
p[0] = (x >> 56) & 0xff;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
le32dec(const void *pp)
|
||||
{
|
||||
const uint8_t *p = (uint8_t const *)pp;
|
||||
|
||||
return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) +
|
||||
((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24));
|
||||
}
|
||||
|
||||
static inline void
|
||||
le32enc(void *pp, uint32_t x)
|
||||
{
|
||||
uint8_t * p = (uint8_t *)pp;
|
||||
|
||||
p[0] = x & 0xff;
|
||||
p[1] = (x >> 8) & 0xff;
|
||||
p[2] = (x >> 16) & 0xff;
|
||||
p[3] = (x >> 24) & 0xff;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
le64dec(const void *pp)
|
||||
{
|
||||
const uint8_t *p = (uint8_t const *)pp;
|
||||
|
||||
return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) +
|
||||
((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) +
|
||||
((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) +
|
||||
((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56));
|
||||
}
|
||||
|
||||
static inline void
|
||||
le64enc(void *pp, uint64_t x)
|
||||
{
|
||||
uint8_t * p = (uint8_t *)pp;
|
||||
|
||||
p[0] = x & 0xff;
|
||||
p[1] = (x >> 8) & 0xff;
|
||||
p[2] = (x >> 16) & 0xff;
|
||||
p[3] = (x >> 24) & 0xff;
|
||||
p[4] = (x >> 32) & 0xff;
|
||||
p[5] = (x >> 40) & 0xff;
|
||||
p[6] = (x >> 48) & 0xff;
|
||||
p[7] = (x >> 56) & 0xff;
|
||||
}
|
||||
#endif /* !HAVE_SYS_ENDIAN_H */
|
||||
|
||||
#endif /* !_SYSENDIAN_H_ */
|
||||
Loading…
Reference in a new issue