1
0
mirror of https://github.com/biergaizi/codecrypt synced 2024-06-25 16:28:15 +00:00
codecrypt/src/cubehash_impl.h

141 lines
3.4 KiB
C
Raw Normal View History

2013-09-29 17:52:46 +00:00
/*
* This file is part of Codecrypt.
*
2016-04-17 13:47:47 +00:00
* Copyright (C) 2013-2016 Mirek Kratochvil <exa.exa@gmail.com>
*
2013-09-29 17:52:46 +00:00
* Codecrypt is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Codecrypt is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Codecrypt. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ccr_cubehash_impl_h_
#define _ccr_cubehash_impl_h_
#include "types.h"
#include <cassert>
2013-09-29 17:52:46 +00:00
#include <stdint.h>
#define ROT(a,b,n) (((a) << (b)) | ((a) >> (n - b)))
#define i16(cmd) for(i=0;i<16;++i) cmd;
template < int I, //initialization rounds
2015-10-31 21:58:17 +00:00
int R, //rounds
int B, //input block size, less or equal 128
int F, //finalization rounds
int H > //output hash size in *bytes*, not bits! less or equal 128.
2013-09-29 17:52:46 +00:00
class cubehash_state
{
uint32_t X[32]; //the state
inline void rounds (uint n) {
int i;
uint32_t T[16];
for (; n; --n) {
i16 (X[i + 16] += X[i]);
i16 (T[i ^ 8] = X[i]);
2015-10-31 21:58:17 +00:00
i16 (X[i] = ROT (T[i], 7, 32));
2013-09-29 17:52:46 +00:00
i16 (X[i] ^= X[i + 16]);
i16 (T[i ^ 2] = X[i + 16]);
i16 (X[i + 16] = T[i]);
i16 (X[i + 16] += X[i]);
i16 (T[i ^ 4] = X[i]);
2015-10-31 21:58:17 +00:00
i16 (X[i] = ROT (T[i], 11, 32));
2013-09-29 17:52:46 +00:00
i16 (X[i] ^= X[i + 16]);
i16 (T[i ^ 1] = X[i + 16]);
i16 (X[i + 16] = T[i]);
}
}
public:
inline void init() {
2013-09-30 05:21:36 +00:00
static bool iv_init = false;
static uint32_t IV[32];
int i;
if (iv_init) {
for (i = 0; i < 32; ++i) X[i] = IV[i];
return;
}
2013-09-29 17:52:46 +00:00
X[0] = H;
X[1] = B;
X[2] = R;
2013-09-30 05:21:36 +00:00
for (i = 3; i < 32; ++i) X[i] = 0;
2013-09-29 17:52:46 +00:00
rounds (I);
2013-09-30 05:21:36 +00:00
for (i = 0; i < 32; ++i) IV[i] = X[i];
iv_init = true;
2013-09-29 17:52:46 +00:00
}
void process_block (const byte*data) {
2013-09-30 05:21:36 +00:00
int i;
for (i = 0; i + 4 <= B; i += 4)
#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ //allow a small speedup for LE architectures
2013-09-30 05:21:36 +00:00
X[i / 4] ^= * (uint32_t*) &data[i];
#else
X[i / 4] ^= (uint32_t) data[i]
| ( (uint32_t) data[i + 1]) << 8
| ( (uint32_t) data[i + 2]) << 16
| ( (uint32_t) data[i + 3]) << 24;
#endif
2013-09-30 05:21:36 +00:00
for (; i < B; ++i)
2015-10-31 21:58:17 +00:00
X[i / 4] ^= ( (uint32_t) (data[i])) << ( (i % 4) * 8);
2013-09-29 17:52:46 +00:00
rounds (R);
}
2013-09-30 05:21:36 +00:00
void process_final_incomplete_block (const byte*data, int n) {
2013-09-29 17:52:46 +00:00
2013-09-30 05:21:36 +00:00
int i;
if (data == NULL && n == 0) {
//empty block, finalize
X[31] ^= 1;
rounds (F);
return;
}
assert(data != NULL && n != 0); // if only one is NULL/0, it's a bug
2013-09-29 17:52:46 +00:00
2013-09-30 05:21:36 +00:00
for (i = 0; i + 4 <= n; i += 4)
#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
2013-09-30 05:21:36 +00:00
X[i / 4] ^= * (uint32_t*) &data[i];
#else
X[i / 4] ^= (uint32_t) data[i]
| ( (uint32_t) data[i + 1]) << 8
| ( (uint32_t) data[i + 2]) << 16
| ( (uint32_t) data[i + 3]) << 24;
#endif
2013-09-29 17:52:46 +00:00
2013-09-30 05:21:36 +00:00
for (; i < n; ++i)
2015-10-31 21:58:17 +00:00
X[i / 4] ^= ( (uint32_t) (data[i])) << ( (i % 4) * 8);
2013-09-29 17:52:46 +00:00
//i==n, n<128 (!)
X[i / 4] ^= ( (uint32_t) 0x80) << ( (i % 4) * 8);
2013-09-29 17:52:46 +00:00
2013-09-30 05:21:36 +00:00
rounds (R);
2013-09-29 17:52:46 +00:00
//finalize
X[31] ^= 1;
rounds (F);
}
void get_hash (byte*out) {
for (int i = 0; i < H; ++i)
2015-10-31 21:58:17 +00:00
out[i] = (X[i / 4] >> ( (i % 4) * 8)) & 0xff;
2013-09-29 17:52:46 +00:00
}
};
#endif