Initial x13 support
parent
eae9eb7cce
commit
04b2edf740
|
@ -18,6 +18,7 @@
|
|||
"hefty1.c",
|
||||
"shavite3.c",
|
||||
"cryptonight.c",
|
||||
"x13.c",
|
||||
"sha3/sph_hefty1.c",
|
||||
"sha3/sph_fugue.c",
|
||||
"sha3/aes_helper.c",
|
||||
|
@ -32,6 +33,7 @@
|
|||
"sha3/sph_shavite.c",
|
||||
"sha3/sph_simd.c",
|
||||
"sha3/sph_skein.c",
|
||||
"sha3/hamsi.c",
|
||||
"crypto/oaes_lib.c",
|
||||
"crypto/c_keccak.c",
|
||||
"crypto/c_groestl.c",
|
||||
|
|
|
@ -18,6 +18,7 @@ extern "C" {
|
|||
#include "hefty1.h"
|
||||
#include "shavite3.h"
|
||||
#include "cryptonight.h"
|
||||
#include "x13.h"
|
||||
}
|
||||
|
||||
using namespace node;
|
||||
|
@ -422,6 +423,28 @@ Handle<Value> cryptonight(const Arguments& args) {
|
|||
return scope.Close(buff->handle_);
|
||||
}
|
||||
|
||||
Handle<Value> x13(const Arguments& args) {
|
||||
HandleScope scope;
|
||||
|
||||
if (args.Length() < 1)
|
||||
return except("You must provide one argument.");
|
||||
|
||||
Local<Object> target = args[0]->ToObject();
|
||||
|
||||
if(!Buffer::HasInstance(target))
|
||||
return except("Argument should be a buffer object.");
|
||||
|
||||
char * input = Buffer::Data(target);
|
||||
char output[32];
|
||||
|
||||
uint32_t input_len = Buffer::Length(target);
|
||||
|
||||
x13_hash(input, output, input_len);
|
||||
|
||||
Buffer* buff = Buffer::New(output, 32);
|
||||
return scope.Close(buff->handle_);
|
||||
}
|
||||
|
||||
void init(Handle<Object> exports) {
|
||||
exports->Set(String::NewSymbol("quark"), FunctionTemplate::New(quark)->GetFunction());
|
||||
exports->Set(String::NewSymbol("x11"), FunctionTemplate::New(x11)->GetFunction());
|
||||
|
@ -439,6 +462,7 @@ void init(Handle<Object> exports) {
|
|||
exports->Set(String::NewSymbol("hefty1"), FunctionTemplate::New(hefty1)->GetFunction());
|
||||
exports->Set(String::NewSymbol("shavite3"), FunctionTemplate::New(shavite3)->GetFunction());
|
||||
exports->Set(String::NewSymbol("cryptonight"), FunctionTemplate::New(cryptonight)->GetFunction());
|
||||
exports->Set(String::NewSymbol("x13"), FunctionTemplate::New(x13)->GetFunction());
|
||||
}
|
||||
|
||||
NODE_MODULE(multihashing, init)
|
||||
|
|
|
@ -0,0 +1,867 @@
|
|||
/* $Id: hamsi.c 251 2010-10-19 14:31:51Z tp $ */
|
||||
/*
|
||||
* Hamsi 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 "sph_hamsi.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT && !defined SPH_SMALL_FOOTPRINT_HAMSI
|
||||
#define SPH_SMALL_FOOTPRINT_HAMSI 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The SPH_HAMSI_EXPAND_* define how many input bits we handle in one
|
||||
* table lookup during message expansion (1 to 8, inclusive). If we note
|
||||
* w the number of bits per message word (w=32 for Hamsi-224/256, w=64
|
||||
* for Hamsi-384/512), r the size of a "row" in 32-bit words (r=8 for
|
||||
* Hamsi-224/256, r=16 for Hamsi-384/512), and n the expansion level,
|
||||
* then we will get t tables (where t=ceil(w/n)) of individual size
|
||||
* 2^n*r*4 (in bytes). The last table may be shorter (e.g. with w=32 and
|
||||
* n=5, there are 7 tables, but the last one uses only two bits on
|
||||
* input, not five).
|
||||
*
|
||||
* Also, we read t rows of r words from RAM. Words in a given row are
|
||||
* concatenated in RAM in that order, so most of the cost is about
|
||||
* reading the first row word; comparatively, cache misses are thus
|
||||
* less expensive with Hamsi-512 (r=16) than with Hamsi-256 (r=8).
|
||||
*
|
||||
* When n=1, tables are "special" in that we omit the first entry of
|
||||
* each table (which always contains 0), so that total table size is
|
||||
* halved.
|
||||
*
|
||||
* We thus have the following (size1 is the cumulative table size of
|
||||
* Hamsi-224/256; size2 is for Hamsi-384/512; similarly, t1 and t2
|
||||
* are for Hamsi-224/256 and Hamsi-384/512, respectively).
|
||||
*
|
||||
* n size1 size2 t1 t2
|
||||
* ---------------------------------------
|
||||
* 1 1024 4096 32 64
|
||||
* 2 2048 8192 16 32
|
||||
* 3 2688 10880 11 22
|
||||
* 4 4096 16384 8 16
|
||||
* 5 6272 25600 7 13
|
||||
* 6 10368 41984 6 11
|
||||
* 7 16896 73856 5 10
|
||||
* 8 32768 131072 4 8
|
||||
*
|
||||
* So there is a trade-off: a lower n makes the tables fit better in
|
||||
* L1 cache, but increases the number of memory accesses. The optimal
|
||||
* value depends on the amount of available L1 cache and the relative
|
||||
* impact of a cache miss.
|
||||
*
|
||||
* Experimentally, in ideal benchmark conditions (which are not necessarily
|
||||
* realistic with regards to L1 cache contention), it seems that n=8 is
|
||||
* the best value on "big" architectures (those with 32 kB or more of L1
|
||||
* cache), while n=4 is better on "small" architectures. This was tested
|
||||
* on an Intel Core2 Q6600 (both 32-bit and 64-bit mode), a PowerPC G3
|
||||
* (32 kB L1 cache, hence "big"), and a MIPS-compatible Broadcom BCM3302
|
||||
* (8 kB L1 cache).
|
||||
*
|
||||
* Note: with n=1, the 32 tables (actually implemented as one big table)
|
||||
* are read entirely and sequentially, regardless of the input data,
|
||||
* thus avoiding any data-dependent table access pattern.
|
||||
*/
|
||||
|
||||
#if !defined SPH_HAMSI_EXPAND_SMALL
|
||||
#if SPH_SMALL_FOOTPRINT_HAMSI
|
||||
#define SPH_HAMSI_EXPAND_SMALL 4
|
||||
#else
|
||||
#define SPH_HAMSI_EXPAND_SMALL 8
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined SPH_HAMSI_EXPAND_BIG
|
||||
#define SPH_HAMSI_EXPAND_BIG 8
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4146)
|
||||
#endif
|
||||
|
||||
#include "hamsi_helper.c"
|
||||
|
||||
static const sph_u32 IV224[] = {
|
||||
SPH_C32(0xc3967a67), SPH_C32(0xc3bc6c20), SPH_C32(0x4bc3bcc3),
|
||||
SPH_C32(0xa7c3bc6b), SPH_C32(0x2c204b61), SPH_C32(0x74686f6c),
|
||||
SPH_C32(0x69656b65), SPH_C32(0x20556e69)
|
||||
};
|
||||
|
||||
/*
|
||||
* This version is the one used in the Hamsi submission package for
|
||||
* round 2 of the SHA-3 competition; the UTF-8 encoding is wrong and
|
||||
* shall soon be corrected in the official Hamsi specification.
|
||||
*
|
||||
static const sph_u32 IV224[] = {
|
||||
SPH_C32(0x3c967a67), SPH_C32(0x3cbc6c20), SPH_C32(0xb4c343c3),
|
||||
SPH_C32(0xa73cbc6b), SPH_C32(0x2c204b61), SPH_C32(0x74686f6c),
|
||||
SPH_C32(0x69656b65), SPH_C32(0x20556e69)
|
||||
};
|
||||
*/
|
||||
|
||||
static const sph_u32 IV256[] = {
|
||||
SPH_C32(0x76657273), SPH_C32(0x69746569), SPH_C32(0x74204c65),
|
||||
SPH_C32(0x7576656e), SPH_C32(0x2c204465), SPH_C32(0x70617274),
|
||||
SPH_C32(0x656d656e), SPH_C32(0x7420456c)
|
||||
};
|
||||
|
||||
static const sph_u32 IV384[] = {
|
||||
SPH_C32(0x656b7472), SPH_C32(0x6f746563), SPH_C32(0x686e6965),
|
||||
SPH_C32(0x6b2c2043), SPH_C32(0x6f6d7075), SPH_C32(0x74657220),
|
||||
SPH_C32(0x53656375), SPH_C32(0x72697479), SPH_C32(0x20616e64),
|
||||
SPH_C32(0x20496e64), SPH_C32(0x75737472), SPH_C32(0x69616c20),
|
||||
SPH_C32(0x43727970), SPH_C32(0x746f6772), SPH_C32(0x61706879),
|
||||
SPH_C32(0x2c204b61)
|
||||
};
|
||||
|
||||
static const sph_u32 IV512[] = {
|
||||
SPH_C32(0x73746565), SPH_C32(0x6c706172), SPH_C32(0x6b204172),
|
||||
SPH_C32(0x656e6265), SPH_C32(0x72672031), SPH_C32(0x302c2062),
|
||||
SPH_C32(0x75732032), SPH_C32(0x3434362c), SPH_C32(0x20422d33),
|
||||
SPH_C32(0x30303120), SPH_C32(0x4c657576), SPH_C32(0x656e2d48),
|
||||
SPH_C32(0x65766572), SPH_C32(0x6c65652c), SPH_C32(0x2042656c),
|
||||
SPH_C32(0x6769756d)
|
||||
};
|
||||
|
||||
static const sph_u32 alpha_n[] = {
|
||||
SPH_C32(0xff00f0f0), SPH_C32(0xccccaaaa), SPH_C32(0xf0f0cccc),
|
||||
SPH_C32(0xff00aaaa), SPH_C32(0xccccaaaa), SPH_C32(0xf0f0ff00),
|
||||
SPH_C32(0xaaaacccc), SPH_C32(0xf0f0ff00), SPH_C32(0xf0f0cccc),
|
||||
SPH_C32(0xaaaaff00), SPH_C32(0xccccff00), SPH_C32(0xaaaaf0f0),
|
||||
SPH_C32(0xaaaaf0f0), SPH_C32(0xff00cccc), SPH_C32(0xccccf0f0),
|
||||
SPH_C32(0xff00aaaa), SPH_C32(0xccccaaaa), SPH_C32(0xff00f0f0),
|
||||
SPH_C32(0xff00aaaa), SPH_C32(0xf0f0cccc), SPH_C32(0xf0f0ff00),
|
||||
SPH_C32(0xccccaaaa), SPH_C32(0xf0f0ff00), SPH_C32(0xaaaacccc),
|
||||
SPH_C32(0xaaaaff00), SPH_C32(0xf0f0cccc), SPH_C32(0xaaaaf0f0),
|
||||
SPH_C32(0xccccff00), SPH_C32(0xff00cccc), SPH_C32(0xaaaaf0f0),
|
||||
SPH_C32(0xff00aaaa), SPH_C32(0xccccf0f0)
|
||||
};
|
||||
|
||||
static const sph_u32 alpha_f[] = {
|
||||
SPH_C32(0xcaf9639c), SPH_C32(0x0ff0f9c0), SPH_C32(0x639c0ff0),
|
||||
SPH_C32(0xcaf9f9c0), SPH_C32(0x0ff0f9c0), SPH_C32(0x639ccaf9),
|
||||
SPH_C32(0xf9c00ff0), SPH_C32(0x639ccaf9), SPH_C32(0x639c0ff0),
|
||||
SPH_C32(0xf9c0caf9), SPH_C32(0x0ff0caf9), SPH_C32(0xf9c0639c),
|
||||
SPH_C32(0xf9c0639c), SPH_C32(0xcaf90ff0), SPH_C32(0x0ff0639c),
|
||||
SPH_C32(0xcaf9f9c0), SPH_C32(0x0ff0f9c0), SPH_C32(0xcaf9639c),
|
||||
SPH_C32(0xcaf9f9c0), SPH_C32(0x639c0ff0), SPH_C32(0x639ccaf9),
|
||||
SPH_C32(0x0ff0f9c0), SPH_C32(0x639ccaf9), SPH_C32(0xf9c00ff0),
|
||||
SPH_C32(0xf9c0caf9), SPH_C32(0x639c0ff0), SPH_C32(0xf9c0639c),
|
||||
SPH_C32(0x0ff0caf9), SPH_C32(0xcaf90ff0), SPH_C32(0xf9c0639c),
|
||||
SPH_C32(0xcaf9f9c0), SPH_C32(0x0ff0639c)
|
||||
};
|
||||
|
||||
#define DECL_STATE_SMALL \
|
||||
sph_u32 c0, c1, c2, c3, c4, c5, c6, c7;
|
||||
|
||||
#define READ_STATE_SMALL(sc) do { \
|
||||
c0 = sc->h[0x0]; \
|
||||
c1 = sc->h[0x1]; \
|
||||
c2 = sc->h[0x2]; \
|
||||
c3 = sc->h[0x3]; \
|
||||
c4 = sc->h[0x4]; \
|
||||
c5 = sc->h[0x5]; \
|
||||
c6 = sc->h[0x6]; \
|
||||
c7 = sc->h[0x7]; \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_STATE_SMALL(sc) do { \
|
||||
sc->h[0x0] = c0; \
|
||||
sc->h[0x1] = c1; \
|
||||
sc->h[0x2] = c2; \
|
||||
sc->h[0x3] = c3; \
|
||||
sc->h[0x4] = c4; \
|
||||
sc->h[0x5] = c5; \
|
||||
sc->h[0x6] = c6; \
|
||||
sc->h[0x7] = c7; \
|
||||
} while (0)
|
||||
|
||||
#define s0 m0
|
||||
#define s1 m1
|
||||
#define s2 c0
|
||||
#define s3 c1
|
||||
#define s4 c2
|
||||
#define s5 c3
|
||||
#define s6 m2
|
||||
#define s7 m3
|
||||
#define s8 m4
|
||||
#define s9 m5
|
||||
#define sA c4
|
||||
#define sB c5
|
||||
#define sC c6
|
||||
#define sD c7
|
||||
#define sE m6
|
||||
#define sF m7
|
||||
|
||||
#define SBOX(a, b, c, d) do { \
|
||||
sph_u32 t; \
|
||||
t = (a); \
|
||||
(a) &= (c); \
|
||||
(a) ^= (d); \
|
||||
(c) ^= (b); \
|
||||
(c) ^= (a); \
|
||||
(d) |= t; \
|
||||
(d) ^= (b); \
|
||||
t ^= (c); \
|
||||
(b) = (d); \
|
||||
(d) |= t; \
|
||||
(d) ^= (a); \
|
||||
(a) &= (b); \
|
||||
t ^= (a); \
|
||||
(b) ^= (d); \
|
||||
(b) ^= t; \
|
||||
(a) = (c); \
|
||||
(c) = (b); \
|
||||
(b) = (d); \
|
||||
(d) = SPH_T32(~t); \
|
||||
} while (0)
|
||||
|
||||
#define L(a, b, c, d) do { \
|
||||
(a) = SPH_ROTL32(a, 13); \
|
||||
(c) = SPH_ROTL32(c, 3); \
|
||||
(b) ^= (a) ^ (c); \
|
||||
(d) ^= (c) ^ SPH_T32((a) << 3); \
|
||||
(b) = SPH_ROTL32(b, 1); \
|
||||
(d) = SPH_ROTL32(d, 7); \
|
||||
(a) ^= (b) ^ (d); \
|
||||
(c) ^= (d) ^ SPH_T32((b) << 7); \
|
||||
(a) = SPH_ROTL32(a, 5); \
|
||||
(c) = SPH_ROTL32(c, 22); \
|
||||
} while (0)
|
||||
|
||||
#define ROUND_SMALL(rc, alpha) do { \
|
||||
s0 ^= alpha[0x00]; \
|
||||
s1 ^= alpha[0x01] ^ (sph_u32)(rc); \
|
||||
s2 ^= alpha[0x02]; \
|
||||
s3 ^= alpha[0x03]; \
|
||||
s4 ^= alpha[0x08]; \
|
||||
s5 ^= alpha[0x09]; \
|
||||
s6 ^= alpha[0x0A]; \
|
||||
s7 ^= alpha[0x0B]; \
|
||||
s8 ^= alpha[0x10]; \
|
||||
s9 ^= alpha[0x11]; \
|
||||
sA ^= alpha[0x12]; \
|
||||
sB ^= alpha[0x13]; \
|
||||
sC ^= alpha[0x18]; \
|
||||
sD ^= alpha[0x19]; \
|
||||
sE ^= alpha[0x1A]; \
|
||||
sF ^= alpha[0x1B]; \
|
||||
SBOX(s0, s4, s8, sC); \
|
||||
SBOX(s1, s5, s9, sD); \
|
||||
SBOX(s2, s6, sA, sE); \
|
||||
SBOX(s3, s7, sB, sF); \
|
||||
L(s0, s5, sA, sF); \
|
||||
L(s1, s6, sB, sC); \
|
||||
L(s2, s7, s8, sD); \
|
||||
L(s3, s4, s9, sE); \
|
||||
} while (0)
|
||||
|
||||
#define P_SMALL do { \
|
||||
ROUND_SMALL(0, alpha_n); \
|
||||
ROUND_SMALL(1, alpha_n); \
|
||||
ROUND_SMALL(2, alpha_n); \
|
||||
} while (0)
|
||||
|
||||
#define PF_SMALL do { \
|
||||
ROUND_SMALL(0, alpha_f); \
|
||||
ROUND_SMALL(1, alpha_f); \
|
||||
ROUND_SMALL(2, alpha_f); \
|
||||
ROUND_SMALL(3, alpha_f); \
|
||||
ROUND_SMALL(4, alpha_f); \
|
||||
ROUND_SMALL(5, alpha_f); \
|
||||
} while (0)
|
||||
|
||||
#define T_SMALL do { \
|
||||
/* order is important */ \
|
||||
c7 = (sc->h[7] ^= sB); \
|
||||
c6 = (sc->h[6] ^= sA); \
|
||||
c5 = (sc->h[5] ^= s9); \
|
||||
c4 = (sc->h[4] ^= s8); \
|
||||
c3 = (sc->h[3] ^= s3); \
|
||||
c2 = (sc->h[2] ^= s2); \
|
||||
c1 = (sc->h[1] ^= s1); \
|
||||
c0 = (sc->h[0] ^= s0); \
|
||||
} while (0)
|
||||
|
||||
static void
|
||||
hamsi_small(sph_hamsi_small_context *sc, const unsigned char *buf, size_t num)
|
||||
{
|
||||
DECL_STATE_SMALL
|
||||
#if !SPH_64
|
||||
sph_u32 tmp;
|
||||
#endif
|
||||
|
||||
#if SPH_64
|
||||
sc->count += (sph_u64)num << 5;
|
||||
#else
|
||||
tmp = SPH_T32((sph_u32)num << 5);
|
||||
sc->count_low = SPH_T32(sc->count_low + tmp);
|
||||
sc->count_high += (sph_u32)((num >> 13) >> 14);
|
||||
if (sc->count_low < tmp)
|
||||
sc->count_high ++;
|
||||
#endif
|
||||
READ_STATE_SMALL(sc);
|
||||
while (num -- > 0) {
|
||||
sph_u32 m0, m1, m2, m3, m4, m5, m6, m7;
|
||||
|
||||
INPUT_SMALL;
|
||||
P_SMALL;
|
||||
T_SMALL;
|
||||
buf += 4;
|
||||
}
|
||||
WRITE_STATE_SMALL(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
hamsi_small_final(sph_hamsi_small_context *sc, const unsigned char *buf)
|
||||
{
|
||||
sph_u32 m0, m1, m2, m3, m4, m5, m6, m7;
|
||||
DECL_STATE_SMALL
|
||||
|
||||
READ_STATE_SMALL(sc);
|
||||
INPUT_SMALL;
|
||||
PF_SMALL;
|
||||
T_SMALL;
|
||||
WRITE_STATE_SMALL(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
hamsi_small_init(sph_hamsi_small_context *sc, const sph_u32 *iv)
|
||||
{
|
||||
sc->partial_len = 0;
|
||||
memcpy(sc->h, iv, sizeof sc->h);
|
||||
#if SPH_64
|
||||
sc->count = 0;
|
||||
#else
|
||||
sc->count_high = sc->count_low = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
hamsi_small_core(sph_hamsi_small_context *sc, const void *data, size_t len)
|
||||
{
|
||||
if (sc->partial_len != 0) {
|
||||
size_t mlen;
|
||||
|
||||
mlen = 4 - sc->partial_len;
|
||||
if (len < mlen) {
|
||||
memcpy(sc->partial + sc->partial_len, data, len);
|
||||
sc->partial_len += len;
|
||||
return;
|
||||
} else {
|
||||
memcpy(sc->partial + sc->partial_len, data, mlen);
|
||||
len -= mlen;
|
||||
data = (const unsigned char *)data + mlen;
|
||||
hamsi_small(sc, sc->partial, 1);
|
||||
sc->partial_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
hamsi_small(sc, data, (len >> 2));
|
||||
data = (const unsigned char *)data + (len & ~(size_t)3);
|
||||
len &= (size_t)3;
|
||||
memcpy(sc->partial, data, len);
|
||||
sc->partial_len = len;
|
||||
}
|
||||
|
||||
static void
|
||||
hamsi_small_close(sph_hamsi_small_context *sc,
|
||||
unsigned ub, unsigned n, void *dst, size_t out_size_w32)
|
||||
{
|
||||
unsigned char pad[12];
|
||||
size_t ptr, u;
|
||||
unsigned z;
|
||||
unsigned char *out;
|
||||
|
||||
ptr = sc->partial_len;
|
||||
memcpy(pad, sc->partial, ptr);
|
||||
#if SPH_64
|
||||
sph_enc64be(pad + 4, sc->count + (ptr << 3) + n);
|
||||
#else
|
||||
sph_enc32be(pad + 4, sc->count_high);
|
||||
sph_enc32be(pad + 8, sc->count_low + (ptr << 3) + n);
|
||||
#endif
|
||||
z = 0x80 >> n;
|
||||
pad[ptr ++] = ((ub & -z) | z) & 0xFF;
|
||||
while (ptr < 4)
|
||||
pad[ptr ++] = 0;
|
||||
hamsi_small(sc, pad, 2);
|
||||
hamsi_small_final(sc, pad + 8);
|
||||
out = dst;
|
||||
for (u = 0; u < out_size_w32; u ++)
|
||||
sph_enc32be(out + (u << 2), sc->h[u]);
|
||||
}
|
||||
|
||||
#define DECL_STATE_BIG \
|
||||
sph_u32 c0, c1, c2, c3, c4, c5, c6, c7; \
|
||||
sph_u32 c8, c9, cA, cB, cC, cD, cE, cF;
|
||||
|
||||
#define READ_STATE_BIG(sc) do { \
|
||||
c0 = sc->h[0x0]; \
|
||||
c1 = sc->h[0x1]; \
|
||||
c2 = sc->h[0x2]; \
|
||||
c3 = sc->h[0x3]; \
|
||||
c4 = sc->h[0x4]; \
|
||||
c5 = sc->h[0x5]; \
|
||||
c6 = sc->h[0x6]; \
|
||||
c7 = sc->h[0x7]; \
|
||||
c8 = sc->h[0x8]; \
|
||||
c9 = sc->h[0x9]; \
|
||||
cA = sc->h[0xA]; \
|
||||
cB = sc->h[0xB]; \
|
||||
cC = sc->h[0xC]; \
|
||||
cD = sc->h[0xD]; \
|
||||
cE = sc->h[0xE]; \
|
||||
cF = sc->h[0xF]; \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_STATE_BIG(sc) do { \
|
||||
sc->h[0x0] = c0; \
|
||||
sc->h[0x1] = c1; \
|
||||
sc->h[0x2] = c2; \
|
||||
sc->h[0x3] = c3; \
|
||||
sc->h[0x4] = c4; \
|
||||
sc->h[0x5] = c5; \
|
||||
sc->h[0x6] = c6; \
|
||||
sc->h[0x7] = c7; \
|
||||
sc->h[0x8] = c8; \
|
||||
sc->h[0x9] = c9; \
|
||||
sc->h[0xA] = cA; \
|
||||
sc->h[0xB] = cB; \
|
||||
sc->h[0xC] = cC; \
|
||||
sc->h[0xD] = cD; \
|
||||
sc->h[0xE] = cE; \
|
||||
sc->h[0xF] = cF; \
|
||||
} while (0)
|
||||
|
||||
#define s00 m0
|
||||
#define s01 m1
|
||||
#define s02 c0
|
||||
#define s03 c1
|
||||
#define s04 m2
|
||||
#define s05 m3
|
||||
#define s06 c2
|
||||
#define s07 c3
|
||||
#define s08 c4
|
||||
#define s09 c5
|
||||
#define s0A m4
|
||||
#define s0B m5
|
||||
#define s0C c6
|
||||
#define s0D c7
|
||||
#define s0E m6
|
||||
#define s0F m7
|
||||
#define s10 m8
|
||||
#define s11 m9
|
||||
#define s12 c8
|
||||
#define s13 c9
|
||||
#define s14 mA
|
||||
#define s15 mB
|
||||
#define s16 cA
|
||||
#define s17 cB
|
||||
#define s18 cC
|
||||
#define s19 cD
|
||||
#define s1A mC
|
||||
#define s1B mD
|
||||
#define s1C cE
|
||||
#define s1D cF
|
||||
#define s1E mE
|
||||
#define s1F mF
|
||||
|
||||
#define ROUND_BIG(rc, alpha) do { \
|
||||
s00 ^= alpha[0x00]; \
|
||||
s01 ^= alpha[0x01] ^ (sph_u32)(rc); \
|
||||
s02 ^= alpha[0x02]; \
|
||||
s03 ^= alpha[0x03]; \
|
||||
s04 ^= alpha[0x04]; \
|
||||
s05 ^= alpha[0x05]; \
|
||||
s06 ^= alpha[0x06]; \
|
||||
s07 ^= alpha[0x07]; \
|
||||
s08 ^= alpha[0x08]; \
|
||||
s09 ^= alpha[0x09]; \
|
||||
s0A ^= alpha[0x0A]; \
|
||||
s0B ^= alpha[0x0B]; \
|
||||
s0C ^= alpha[0x0C]; \
|
||||
s0D ^= alpha[0x0D]; \
|
||||
s0E ^= alpha[0x0E]; \
|
||||
s0F ^= alpha[0x0F]; \
|
||||
s10 ^= alpha[0x10]; \
|
||||
s11 ^= alpha[0x11]; \
|
||||
s12 ^= alpha[0x12]; \
|
||||
s13 ^= alpha[0x13]; \
|
||||
s14 ^= alpha[0x14]; \
|
||||
s15 ^= alpha[0x15]; \
|
||||
s16 ^= alpha[0x16]; \
|
||||
s17 ^= alpha[0x17]; \
|
||||
s18 ^= alpha[0x18]; \
|
||||
s19 ^= alpha[0x19]; \
|
||||
s1A ^= alpha[0x1A]; \
|
||||
s1B ^= alpha[0x1B]; \
|
||||
s1C ^= alpha[0x1C]; \
|
||||
s1D ^= alpha[0x1D]; \
|
||||
s1E ^= alpha[0x1E]; \
|
||||
s1F ^= alpha[0x1F]; \
|
||||
SBOX(s00, s08, s10, s18); \
|
||||
SBOX(s01, s09, s11, s19); \
|
||||
SBOX(s02, s0A, s12, s1A); \
|
||||
SBOX(s03, s0B, s13, s1B); \
|
||||
SBOX(s04, s0C, s14, s1C); \
|
||||
SBOX(s05, s0D, s15, s1D); \
|
||||
SBOX(s06, s0E, s16, s1E); \
|
||||
SBOX(s07, s0F, s17, s1F); \
|
||||
L(s00, s09, s12, s1B); \
|
||||
L(s01, s0A, s13, s1C); \
|
||||
L(s02, s0B, s14, s1D); \
|
||||
L(s03, s0C, s15, s1E); \
|
||||
L(s04, s0D, s16, s1F); \
|
||||
L(s05, s0E, s17, s18); \
|
||||
L(s06, s0F, s10, s19); \
|
||||
L(s07, s08, s11, s1A); \
|
||||
L(s00, s02, s05, s07); \
|
||||
L(s10, s13, s15, s16); \
|
||||
L(s09, s0B, s0C, s0E); \
|
||||
L(s19, s1A, s1C, s1F); \
|
||||
} while (0)
|
||||
|
||||
#if SPH_SMALL_FOOTPRINT_HAMSI
|
||||
|
||||
#define P_BIG do { \
|
||||
unsigned r; \
|
||||
for (r = 0; r < 6; r ++) \
|
||||
ROUND_BIG(r, alpha_n); \
|
||||
} while (0)
|
||||
|
||||
#define PF_BIG do { \
|
||||
unsigned r; \
|
||||
for (r = 0; r < 12; r ++) \
|
||||
ROUND_BIG(r, alpha_f); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define P_BIG do { \
|
||||
ROUND_BIG(0, alpha_n); \
|
||||
ROUND_BIG(1, alpha_n); \
|
||||
ROUND_BIG(2, alpha_n); \
|
||||
ROUND_BIG(3, alpha_n); \
|
||||
ROUND_BIG(4, alpha_n); \
|
||||
ROUND_BIG(5, alpha_n); \
|
||||
} while (0)
|
||||
|
||||
#define PF_BIG do { \
|
||||
ROUND_BIG(0, alpha_f); \
|
||||
ROUND_BIG(1, alpha_f); \
|
||||
ROUND_BIG(2, alpha_f); \
|
||||
ROUND_BIG(3, alpha_f); \
|
||||
ROUND_BIG(4, alpha_f); \
|
||||
ROUND_BIG(5, alpha_f); \
|
||||
ROUND_BIG(6, alpha_f); \
|
||||
ROUND_BIG(7, alpha_f); \
|
||||
ROUND_BIG(8, alpha_f); \
|
||||
ROUND_BIG(9, alpha_f); \
|
||||
ROUND_BIG(10, alpha_f); \
|
||||
ROUND_BIG(11, alpha_f); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#define T_BIG do { \
|
||||
/* order is important */ \
|
||||
cF = (sc->h[0xF] ^= s17); \
|
||||
cE = (sc->h[0xE] ^= s16); \
|
||||
cD = (sc->h[0xD] ^= s15); \
|
||||
cC = (sc->h[0xC] ^= s14); \
|
||||
cB = (sc->h[0xB] ^= s13); \
|
||||
cA = (sc->h[0xA] ^= s12); \
|
||||
c9 = (sc->h[0x9] ^= s11); \
|
||||
c8 = (sc->h[0x8] ^= s10); \
|
||||
c7 = (sc->h[0x7] ^= s07); \
|
||||
c6 = (sc->h[0x6] ^= s06); \
|
||||
c5 = (sc->h[0x5] ^= s05); \
|
||||
c4 = (sc->h[0x4] ^= s04); \
|
||||
c3 = (sc->h[0x3] ^= s03); \
|
||||
c2 = (sc->h[0x2] ^= s02); \
|
||||
c1 = (sc->h[0x1] ^= s01); \
|
||||
c0 = (sc->h[0x0] ^= s00); \
|
||||
} while (0)
|
||||
|
||||
static void
|
||||
hamsi_big(sph_hamsi_big_context *sc, const unsigned char *buf, size_t num)
|
||||
{
|
||||
DECL_STATE_BIG
|
||||
#if !SPH_64
|
||||
sph_u32 tmp;
|
||||
#endif
|
||||
|
||||
#if SPH_64
|
||||
sc->count += (sph_u64)num << 6;
|
||||
#else
|
||||
tmp = SPH_T32((sph_u32)num << 6);
|
||||
sc->count_low = SPH_T32(sc->count_low + tmp);
|
||||
sc->count_high += (sph_u32)((num >> 13) >> 13);
|
||||
if (sc->count_low < tmp)
|
||||
sc->count_high ++;
|
||||
#endif
|
||||
READ_STATE_BIG(sc);
|
||||
while (num -- > 0) {
|
||||
sph_u32 m0, m1, m2, m3, m4, m5, m6, m7;
|
||||
sph_u32 m8, m9, mA, mB, mC, mD, mE, mF;
|
||||
|
||||
INPUT_BIG;
|
||||
P_BIG;
|
||||
T_BIG;
|
||||
buf += 8;
|
||||
}
|
||||
WRITE_STATE_BIG(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
hamsi_big_final(sph_hamsi_big_context *sc, const unsigned char *buf)
|
||||
{
|
||||
sph_u32 m0, m1, m2, m3, m4, m5, m6, m7;
|
||||
sph_u32 m8, m9, mA, mB, mC, mD, mE, mF;
|
||||
DECL_STATE_BIG
|
||||
|
||||
READ_STATE_BIG(sc);
|
||||
INPUT_BIG;
|
||||
PF_BIG;
|
||||
T_BIG;
|
||||
WRITE_STATE_BIG(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
hamsi_big_init(sph_hamsi_big_context *sc, const sph_u32 *iv)
|
||||
{
|
||||
sc->partial_len = 0;
|
||||
memcpy(sc->h, iv, sizeof sc->h);
|
||||
#if SPH_64
|
||||
sc->count = 0;
|
||||
#else
|
||||
sc->count_high = sc->count_low = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
hamsi_big_core(sph_hamsi_big_context *sc, const void *data, size_t len)
|
||||
{
|
||||
if (sc->partial_len != 0) {
|
||||
size_t mlen;
|
||||
|
||||
mlen = 8 - sc->partial_len;
|
||||
if (len < mlen) {
|
||||
memcpy(sc->partial + sc->partial_len, data, len);
|
||||
sc->partial_len += len;
|
||||
return;
|
||||
} else {
|
||||
memcpy(sc->partial + sc->partial_len, data, mlen);
|
||||
len -= mlen;
|
||||
data = (const unsigned char *)data + mlen;
|
||||
hamsi_big(sc, sc->partial, 1);
|
||||
sc->partial_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
hamsi_big(sc, data, (len >> 3));
|
||||
data = (const unsigned char *)data + (len & ~(size_t)7);
|
||||
len &= (size_t)7;
|
||||
memcpy(sc->partial, data, len);
|
||||
sc->partial_len = len;
|
||||
}
|
||||
|
||||
static void
|
||||
hamsi_big_close(sph_hamsi_big_context *sc,
|
||||
unsigned ub, unsigned n, void *dst, size_t out_size_w32)
|
||||
{
|
||||
unsigned char pad[8];
|
||||
size_t ptr, u;
|
||||
unsigned z;
|
||||
unsigned char *out;
|
||||
|
||||
ptr = sc->partial_len;
|
||||
#if SPH_64
|
||||
sph_enc64be(pad, sc->count + (ptr << 3) + n);
|
||||
#else
|
||||
sph_enc32be(pad, sc->count_high);
|
||||
sph_enc32be(pad + 4, sc->count_low + (ptr << 3) + n);
|
||||
#endif
|
||||
z = 0x80 >> n;
|
||||
sc->partial[ptr ++] = ((ub & -z) | z) & 0xFF;
|
||||
while (ptr < 8)
|
||||
sc->partial[ptr ++] = 0;
|
||||
hamsi_big(sc, sc->partial, 1);
|
||||
hamsi_big_final(sc, pad);
|
||||
out = dst;
|
||||
if (out_size_w32 == 12) {
|
||||
sph_enc32be(out + 0, sc->h[ 0]);
|
||||
sph_enc32be(out + 4, sc->h[ 1]);
|
||||
sph_enc32be(out + 8, sc->h[ 3]);
|
||||
sph_enc32be(out + 12, sc->h[ 4]);
|
||||
sph_enc32be(out + 16, sc->h[ 5]);
|
||||
sph_enc32be(out + 20, sc->h[ 6]);
|
||||
sph_enc32be(out + 24, sc->h[ 8]);
|
||||
sph_enc32be(out + 28, sc->h[ 9]);
|
||||
sph_enc32be(out + 32, sc->h[10]);
|
||||
sph_enc32be(out + 36, sc->h[12]);
|
||||
sph_enc32be(out + 40, sc->h[13]);
|
||||
sph_enc32be(out + 44, sc->h[15]);
|
||||
} else {
|
||||
for (u = 0; u < 16; u ++)
|
||||
sph_enc32be(out + (u << 2), sc->h[u]);
|
||||
}
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi224_init(void *cc)
|
||||
{
|
||||
hamsi_small_init(cc, IV224);
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi224(void *cc, const void *data, size_t len)
|
||||
{
|
||||
hamsi_small_core(cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi224_close(void *cc, void *dst)
|
||||
{
|
||||
hamsi_small_close(cc, 0, 0, dst, 7);
|
||||
hamsi_small_init(cc, IV224);
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi224_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
hamsi_small_close(cc, ub, n, dst, 7);
|
||||
hamsi_small_init(cc, IV224);
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi256_init(void *cc)
|
||||
{
|
||||
hamsi_small_init(cc, IV256);
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi256(void *cc, const void *data, size_t len)
|
||||
{
|
||||
hamsi_small_core(cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi256_close(void *cc, void *dst)
|
||||
{
|
||||
hamsi_small_close(cc, 0, 0, dst, 8);
|
||||
hamsi_small_init(cc, IV256);
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi256_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
hamsi_small_close(cc, ub, n, dst, 8);
|
||||
hamsi_small_init(cc, IV256);
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi384_init(void *cc)
|
||||
{
|
||||
hamsi_big_init(cc, IV384);
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi384(void *cc, const void *data, size_t len)
|
||||
{
|
||||
hamsi_big_core(cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi384_close(void *cc, void *dst)
|
||||
{
|
||||
hamsi_big_close(cc, 0, 0, dst, 12);
|
||||
hamsi_big_init(cc, IV384);
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi384_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
hamsi_big_close(cc, ub, n, dst, 12);
|
||||
hamsi_big_init(cc, IV384);
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi512_init(void *cc)
|
||||
{
|
||||
hamsi_big_init(cc, IV512);
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi512(void *cc, const void *data, size_t len)
|
||||
{
|
||||
hamsi_big_core(cc, data, len);
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi512_close(void *cc, void *dst)
|
||||
{
|
||||
hamsi_big_close(cc, 0, 0, dst, 16);
|
||||
hamsi_big_init(cc, IV512);
|
||||
}
|
||||
|
||||
/* see sph_hamsi.h */
|
||||
void
|
||||
sph_hamsi512_addbits_and_close(void *cc, unsigned ub, unsigned n, void *dst)
|
||||
{
|
||||
hamsi_big_close(cc, ub, n, dst, 16);
|
||||
hamsi_big_init(cc, IV512);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,321 @@
|
|||
/* $Id: sph_hamsi.h 216 2010-06-08 09:46:57Z tp $ */
|
||||
/**
|
||||
* Hamsi interface. This code implements Hamsi with the recommended
|
||||
* parameters for SHA-3, with outputs of 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_hamsi.h
|
||||
* @author Thomas Pornin <thomas.pornin@cryptolog.com>
|
||||
*/
|
||||
|
||||
#ifndef SPH_HAMSI_H__
|
||||
#define SPH_HAMSI_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include "sph_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Hamsi-224.
|
||||
*/
|
||||
#define SPH_SIZE_hamsi224 224
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Hamsi-256.
|
||||
*/
|
||||
#define SPH_SIZE_hamsi256 256
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Hamsi-384.
|
||||
*/
|
||||
#define SPH_SIZE_hamsi384 384
|
||||
|
||||
/**
|
||||
* Output size (in bits) for Hamsi-512.
|
||||
*/
|
||||
#define SPH_SIZE_hamsi512 512
|
||||
|
||||
/**
|
||||
* This structure is a context for Hamsi-224 and Hamsi-256 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a Hamsi computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running Hamsi
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char partial[4];
|
||||
size_t partial_len;
|
||||
sph_u32 h[8];
|
||||
#if SPH_64
|
||||
sph_u64 count;
|
||||
#else
|
||||
sph_u32 count_high, count_low;
|
||||
#endif
|
||||
#endif
|
||||
} sph_hamsi_small_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Hamsi-224 computations. It is
|
||||
* identical to the common <code>sph_hamsi_small_context</code>.
|
||||
*/
|
||||
typedef sph_hamsi_small_context sph_hamsi224_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Hamsi-256 computations. It is
|
||||
* identical to the common <code>sph_hamsi_small_context</code>.
|
||||
*/
|
||||
typedef sph_hamsi_small_context sph_hamsi256_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Hamsi-384 and Hamsi-512 computations:
|
||||
* it contains the intermediate values and some data from the last
|
||||
* entered block. Once a Hamsi computation has been performed, the
|
||||
* context can be reused for another computation.
|
||||
*
|
||||
* The contents of this structure are private. A running Hamsi
|
||||
* computation can be cloned by copying the context (e.g. with a simple
|
||||
* <code>memcpy()</code>).
|
||||
*/
|
||||
typedef struct {
|
||||
#ifndef DOXYGEN_IGNORE
|
||||
unsigned char partial[8];
|
||||
size_t partial_len;
|
||||
sph_u32 h[16];
|
||||
#if SPH_64
|
||||
sph_u64 count;
|
||||
#else
|
||||
sph_u32 count_high, count_low;
|
||||
#endif
|
||||
#endif
|
||||
} sph_hamsi_big_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Hamsi-384 computations. It is
|
||||
* identical to the common <code>sph_hamsi_small_context</code>.
|
||||
*/
|
||||
typedef sph_hamsi_big_context sph_hamsi384_context;
|
||||
|
||||
/**
|
||||
* This structure is a context for Hamsi-512 computations. It is
|
||||
* identical to the common <code>sph_hamsi_small_context</code>.
|
||||
*/
|
||||
typedef sph_hamsi_big_context sph_hamsi512_context;
|
||||
|
||||
/**
|
||||
* Initialize a Hamsi-224 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Hamsi-224 context (pointer to a
|
||||
* <code>sph_hamsi224_context</code>)
|
||||
*/
|
||||
void sph_hamsi224_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 Hamsi-224 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_hamsi224(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Hamsi-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 Hamsi-224 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_hamsi224_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 Hamsi-224 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_hamsi224_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Hamsi-256 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Hamsi-256 context (pointer to a
|
||||
* <code>sph_hamsi256_context</code>)
|
||||
*/
|
||||
void sph_hamsi256_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 Hamsi-256 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_hamsi256(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Hamsi-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 Hamsi-256 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_hamsi256_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 Hamsi-256 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_hamsi256_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Hamsi-384 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Hamsi-384 context (pointer to a
|
||||
* <code>sph_hamsi384_context</code>)
|
||||
*/
|
||||
void sph_hamsi384_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 Hamsi-384 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_hamsi384(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Hamsi-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 Hamsi-384 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_hamsi384_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 Hamsi-384 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_hamsi384_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
/**
|
||||
* Initialize a Hamsi-512 context. This process performs no memory allocation.
|
||||
*
|
||||
* @param cc the Hamsi-512 context (pointer to a
|
||||
* <code>sph_hamsi512_context</code>)
|
||||
*/
|
||||
void sph_hamsi512_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 Hamsi-512 context
|
||||
* @param data the input data
|
||||
* @param len the input data length (in bytes)
|
||||
*/
|
||||
void sph_hamsi512(void *cc, const void *data, size_t len);
|
||||
|
||||
/**
|
||||
* Terminate the current Hamsi-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 Hamsi-512 context
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_hamsi512_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 Hamsi-512 context
|
||||
* @param ub the extra bits
|
||||
* @param n the number of extra bits (0 to 7)
|
||||
* @param dst the destination buffer
|
||||
*/
|
||||
void sph_hamsi512_addbits_and_close(
|
||||
void *cc, unsigned ub, unsigned n, void *dst);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,97 @@
|
|||
#include "x13.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "sha3/sph_blake.h"
|
||||
#include "sha3/sph_bmw.h"
|
||||
#include "sha3/sph_groestl.h"
|
||||
#include "sha3/sph_jh.h"
|
||||
#include "sha3/sph_keccak.h"
|
||||
#include "sha3/sph_skein.h"
|
||||
#include "sha3/sph_luffa.h"
|
||||
#include "sha3/sph_cubehash.h"
|
||||
#include "sha3/sph_shavite.h"
|
||||
#include "sha3/sph_simd.h"
|
||||
#include "sha3/sph_echo.h"
|
||||
#include "sha3/sph_hamsi.h"
|
||||
#include "sha3/sph_fugue.h"
|
||||
|
||||
|
||||
void x13_hash(const char* input, char* output, uint32_t len)
|
||||
{
|
||||
sph_blake512_context ctx_blake;
|
||||
sph_bmw512_context ctx_bmw;
|
||||
sph_groestl512_context ctx_groestl;
|
||||
sph_skein512_context ctx_skein;
|
||||
sph_jh512_context ctx_jh;
|
||||
sph_keccak512_context ctx_keccak;
|
||||
sph_luffa512_context ctx_luffa1;
|
||||
sph_cubehash512_context ctx_cubehash1;
|
||||
sph_shavite512_context ctx_shavite1;
|
||||
sph_simd512_context ctx_simd1;
|
||||
sph_echo512_context ctx_echo1;
|
||||
sph_hamsi512_context ctx_hamsi1;
|
||||
sph_fugue512_context ctx_fugue1;
|
||||
|
||||
//these uint512 in the c++ source of the client are backed by an array of uint32
|
||||
uint32_t hashA[16], hashB[16];
|
||||
|
||||
sph_blake512_init(&ctx_blake);
|
||||
sph_blake512 (&ctx_blake, input, len);
|
||||
sph_blake512_close (&ctx_blake, hashA);
|
||||
|
||||
sph_bmw512_init(&ctx_bmw);
|
||||
sph_bmw512 (&ctx_bmw, hashA, 64);
|
||||
sph_bmw512_close(&ctx_bmw, hashB);
|
||||
|
||||
sph_groestl512_init(&ctx_groestl);
|
||||
sph_groestl512 (&ctx_groestl, hashB, 64);
|
||||
sph_groestl512_close(&ctx_groestl, hashA);
|
||||
|
||||
sph_skein512_init(&ctx_skein);
|
||||
sph_skein512 (&ctx_skein, hashA, 64);
|
||||
sph_skein512_close (&ctx_skein, hashB);
|
||||
|
||||
sph_jh512_init(&ctx_jh);
|
||||
sph_jh512 (&ctx_jh, hashB, 64);
|
||||
sph_jh512_close(&ctx_jh, hashA);
|
||||
|
||||
sph_keccak512_init(&ctx_keccak);
|
||||
sph_keccak512 (&ctx_keccak, hashA, 64);
|
||||
sph_keccak512_close(&ctx_keccak, hashB);
|
||||
|
||||
sph_luffa512_init (&ctx_luffa1);
|
||||
sph_luffa512 (&ctx_luffa1, hashB, 64);
|
||||
sph_luffa512_close (&ctx_luffa1, hashA);
|
||||
|
||||
sph_cubehash512_init (&ctx_cubehash1);
|
||||
sph_cubehash512 (&ctx_cubehash1, hashA, 64);
|
||||
sph_cubehash512_close(&ctx_cubehash1, hashB);
|
||||
|
||||
sph_shavite512_init (&ctx_shavite1);
|
||||
sph_shavite512 (&ctx_shavite1, hashB, 64);
|
||||
sph_shavite512_close(&ctx_shavite1, hashA);
|
||||
|
||||
sph_simd512_init (&ctx_simd1);
|
||||
sph_simd512 (&ctx_simd1, hashA, 64);
|
||||
sph_simd512_close(&ctx_simd1, hashB);
|
||||
|
||||
sph_echo512_init (&ctx_echo1);
|
||||
sph_echo512 (&ctx_echo1, hashB, 64);
|
||||
sph_echo512_close(&ctx_echo1, hashA);
|
||||
|
||||
sph_hamsi512_init (&ctx_hamsi1);
|
||||
sph_hamsi512 (&ctx_hamsi1, hashA, 64);
|
||||
sph_hamsi512_close(&ctx_hamsi1, hashB);
|
||||
|
||||
sph_fugue512_init (&ctx_fugue1);
|
||||
sph_fugue512 (&ctx_fugue1, hashB, 64);
|
||||
sph_fugue512_close(&ctx_fugue1, hashA);
|
||||
|
||||
|
||||
|
||||
memcpy(output, hashA, 32);
|
||||
|
||||
}
|
Loading…
Reference in New Issue