2
0
mirror of https://github.com/Laupetin/OpenAssetTools.git synced 2025-09-02 06:57:26 +00:00

Import code from previous AssetBuilder version

This commit is contained in:
Jan
2019-09-24 10:45:09 +02:00
parent 5609557516
commit 0d8432d4f7
919 changed files with 154412 additions and 26 deletions

29
thirdparty/libtomcrypt/LICENSE vendored Normal file
View File

@@ -0,0 +1,29 @@
LibTomCrypt is licensed under DUAL licensing terms.
Choose and use the license of your needs.
[LICENSE #1]
LibTomCrypt is public domain. As should all quality software be.
Tom St Denis
[/LICENSE #1]
[LICENSE #2]
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
[/LICENSE #2]

743
thirdparty/libtomcrypt/ciphers/aes/aes.c vendored Normal file
View File

@@ -0,0 +1,743 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/* AES implementation by Tom St Denis
*
* Derived from the Public Domain source code by
---
* rijndael-alg-fst.c
*
* @version 3.0 (December 2000)
*
* Optimised ANSI C code for the Rijndael cipher (now AES)
*
* @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
* @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
* @author Paulo Barreto <paulo.barreto@terra.com.br>
---
*/
/**
@file aes.c
Implementation of AES
*/
#include "tomcrypt.h"
#ifdef LTC_RIJNDAEL
#ifndef ENCRYPT_ONLY
#define SETUP rijndael_setup
#define ECB_ENC rijndael_ecb_encrypt
#define ECB_DEC rijndael_ecb_decrypt
#define ECB_DONE rijndael_done
#define ECB_TEST rijndael_test
#define ECB_KS rijndael_keysize
const struct ltc_cipher_descriptor rijndael_desc =
{
"rijndael",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
const struct ltc_cipher_descriptor aes_desc =
{
"aes",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#else
#define SETUP rijndael_enc_setup
#define ECB_ENC rijndael_enc_ecb_encrypt
#define ECB_KS rijndael_enc_keysize
#define ECB_DONE rijndael_enc_done
const struct ltc_cipher_descriptor rijndael_enc_desc =
{
"rijndael",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
const struct ltc_cipher_descriptor aes_enc_desc =
{
"aes",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#endif
#define __LTC_AES_TAB_C__
#include "aes_tab.c"
static ulong32 setup_mix(ulong32 temp)
{
return (Te4_3[byte(temp, 2)]) ^
(Te4_2[byte(temp, 1)]) ^
(Te4_1[byte(temp, 0)]) ^
(Te4_0[byte(temp, 3)]);
}
#ifndef ENCRYPT_ONLY
#ifdef LTC_SMALL_CODE
static ulong32 setup_mix2(ulong32 temp)
{
return Td0(255 & Te4[byte(temp, 3)]) ^
Td1(255 & Te4[byte(temp, 2)]) ^
Td2(255 & Te4[byte(temp, 1)]) ^
Td3(255 & Te4[byte(temp, 0)]);
}
#endif
#endif
/**
Initialize the AES (Rijndael) block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int i;
ulong32 temp, *rk;
#ifndef ENCRYPT_ONLY
ulong32 *rrk;
#endif
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (keylen != 16 && keylen != 24 && keylen != 32) {
return CRYPT_INVALID_KEYSIZE;
}
if (num_rounds != 0 && num_rounds != (10 + ((keylen/8)-2)*2)) {
return CRYPT_INVALID_ROUNDS;
}
skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
/* setup the forward key */
i = 0;
rk = skey->rijndael.eK;
LOAD32H(rk[0], key );
LOAD32H(rk[1], key + 4);
LOAD32H(rk[2], key + 8);
LOAD32H(rk[3], key + 12);
if (keylen == 16) {
for (;;) {
temp = rk[3];
rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
rk[7] = rk[3] ^ rk[6];
if (++i == 10) {
break;
}
rk += 4;
}
} else if (keylen == 24) {
LOAD32H(rk[4], key + 16);
LOAD32H(rk[5], key + 20);
for (;;) {
#ifdef _MSC_VER
temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5];
#else
temp = rk[5];
#endif
rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
rk[ 7] = rk[ 1] ^ rk[ 6];
rk[ 8] = rk[ 2] ^ rk[ 7];
rk[ 9] = rk[ 3] ^ rk[ 8];
if (++i == 8) {
break;
}
rk[10] = rk[ 4] ^ rk[ 9];
rk[11] = rk[ 5] ^ rk[10];
rk += 6;
}
} else if (keylen == 32) {
LOAD32H(rk[4], key + 16);
LOAD32H(rk[5], key + 20);
LOAD32H(rk[6], key + 24);
LOAD32H(rk[7], key + 28);
for (;;) {
#ifdef _MSC_VER
temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7];
#else
temp = rk[7];
#endif
rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
rk[ 9] = rk[ 1] ^ rk[ 8];
rk[10] = rk[ 2] ^ rk[ 9];
rk[11] = rk[ 3] ^ rk[10];
if (++i == 7) {
break;
}
temp = rk[11];
rk[12] = rk[ 4] ^ setup_mix(RORc(temp, 8));
rk[13] = rk[ 5] ^ rk[12];
rk[14] = rk[ 6] ^ rk[13];
rk[15] = rk[ 7] ^ rk[14];
rk += 8;
}
} else {
/* this can't happen */
/* coverity[dead_error_line] */
return CRYPT_ERROR;
}
#ifndef ENCRYPT_ONLY
/* setup the inverse key now */
rk = skey->rijndael.dK;
rrk = skey->rijndael.eK + (28 + keylen) - 4;
/* apply the inverse MixColumn transform to all round keys but the first and the last: */
/* copy first */
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk = *rrk;
rk -= 3; rrk -= 3;
for (i = 1; i < skey->rijndael.Nr; i++) {
rrk -= 4;
rk += 4;
#ifdef LTC_SMALL_CODE
temp = rrk[0];
rk[0] = setup_mix2(temp);
temp = rrk[1];
rk[1] = setup_mix2(temp);
temp = rrk[2];
rk[2] = setup_mix2(temp);
temp = rrk[3];
rk[3] = setup_mix2(temp);
#else
temp = rrk[0];
rk[0] =
Tks0[byte(temp, 3)] ^
Tks1[byte(temp, 2)] ^
Tks2[byte(temp, 1)] ^
Tks3[byte(temp, 0)];
temp = rrk[1];
rk[1] =
Tks0[byte(temp, 3)] ^
Tks1[byte(temp, 2)] ^
Tks2[byte(temp, 1)] ^
Tks3[byte(temp, 0)];
temp = rrk[2];
rk[2] =
Tks0[byte(temp, 3)] ^
Tks1[byte(temp, 2)] ^
Tks2[byte(temp, 1)] ^
Tks3[byte(temp, 0)];
temp = rrk[3];
rk[3] =
Tks0[byte(temp, 3)] ^
Tks1[byte(temp, 2)] ^
Tks2[byte(temp, 1)] ^
Tks3[byte(temp, 0)];
#endif
}
/* copy last */
rrk -= 4;
rk += 4;
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk++ = *rrk++;
*rk = *rrk;
#endif /* ENCRYPT_ONLY */
return CRYPT_OK;
}
/**
Encrypts a block of text with AES
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
int Nr, r;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
Nr = skey->rijndael.Nr;
rk = skey->rijndael.eK;
/*
* map byte array block to cipher state
* and add initial round key:
*/
LOAD32H(s0, pt ); s0 ^= rk[0];
LOAD32H(s1, pt + 4); s1 ^= rk[1];
LOAD32H(s2, pt + 8); s2 ^= rk[2];
LOAD32H(s3, pt + 12); s3 ^= rk[3];
#ifdef LTC_SMALL_CODE
for (r = 0; ; r++) {
rk += 4;
t0 =
Te0(byte(s0, 3)) ^
Te1(byte(s1, 2)) ^
Te2(byte(s2, 1)) ^
Te3(byte(s3, 0)) ^
rk[0];
t1 =
Te0(byte(s1, 3)) ^
Te1(byte(s2, 2)) ^
Te2(byte(s3, 1)) ^
Te3(byte(s0, 0)) ^
rk[1];
t2 =
Te0(byte(s2, 3)) ^
Te1(byte(s3, 2)) ^
Te2(byte(s0, 1)) ^
Te3(byte(s1, 0)) ^
rk[2];
t3 =
Te0(byte(s3, 3)) ^
Te1(byte(s0, 2)) ^
Te2(byte(s1, 1)) ^
Te3(byte(s2, 0)) ^
rk[3];
if (r == Nr-2) {
break;
}
s0 = t0; s1 = t1; s2 = t2; s3 = t3;
}
rk += 4;
#else
/*
* Nr - 1 full rounds:
*/
r = Nr >> 1;
for (;;) {
t0 =
Te0(byte(s0, 3)) ^
Te1(byte(s1, 2)) ^
Te2(byte(s2, 1)) ^
Te3(byte(s3, 0)) ^
rk[4];
t1 =
Te0(byte(s1, 3)) ^
Te1(byte(s2, 2)) ^
Te2(byte(s3, 1)) ^
Te3(byte(s0, 0)) ^
rk[5];
t2 =
Te0(byte(s2, 3)) ^
Te1(byte(s3, 2)) ^
Te2(byte(s0, 1)) ^
Te3(byte(s1, 0)) ^
rk[6];
t3 =
Te0(byte(s3, 3)) ^
Te1(byte(s0, 2)) ^
Te2(byte(s1, 1)) ^
Te3(byte(s2, 0)) ^
rk[7];
rk += 8;
if (--r == 0) {
break;
}
s0 =
Te0(byte(t0, 3)) ^
Te1(byte(t1, 2)) ^
Te2(byte(t2, 1)) ^
Te3(byte(t3, 0)) ^
rk[0];
s1 =
Te0(byte(t1, 3)) ^
Te1(byte(t2, 2)) ^
Te2(byte(t3, 1)) ^
Te3(byte(t0, 0)) ^
rk[1];
s2 =
Te0(byte(t2, 3)) ^
Te1(byte(t3, 2)) ^
Te2(byte(t0, 1)) ^
Te3(byte(t1, 0)) ^
rk[2];
s3 =
Te0(byte(t3, 3)) ^
Te1(byte(t0, 2)) ^
Te2(byte(t1, 1)) ^
Te3(byte(t2, 0)) ^
rk[3];
}
#endif
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Te4_3[byte(t0, 3)]) ^
(Te4_2[byte(t1, 2)]) ^
(Te4_1[byte(t2, 1)]) ^
(Te4_0[byte(t3, 0)]) ^
rk[0];
STORE32H(s0, ct);
s1 =
(Te4_3[byte(t1, 3)]) ^
(Te4_2[byte(t2, 2)]) ^
(Te4_1[byte(t3, 1)]) ^
(Te4_0[byte(t0, 0)]) ^
rk[1];
STORE32H(s1, ct+4);
s2 =
(Te4_3[byte(t2, 3)]) ^
(Te4_2[byte(t3, 2)]) ^
(Te4_1[byte(t0, 1)]) ^
(Te4_0[byte(t1, 0)]) ^
rk[2];
STORE32H(s2, ct+8);
s3 =
(Te4_3[byte(t3, 3)]) ^
(Te4_2[byte(t0, 2)]) ^
(Te4_1[byte(t1, 1)]) ^
(Te4_0[byte(t2, 0)]) ^
rk[3];
STORE32H(s3, ct+12);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
int err = _rijndael_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
return err;
}
#endif
#ifndef ENCRYPT_ONLY
/**
Decrypts a block of text with AES
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
int Nr, r;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
Nr = skey->rijndael.Nr;
rk = skey->rijndael.dK;
/*
* map byte array block to cipher state
* and add initial round key:
*/
LOAD32H(s0, ct ); s0 ^= rk[0];
LOAD32H(s1, ct + 4); s1 ^= rk[1];
LOAD32H(s2, ct + 8); s2 ^= rk[2];
LOAD32H(s3, ct + 12); s3 ^= rk[3];
#ifdef LTC_SMALL_CODE
for (r = 0; ; r++) {
rk += 4;
t0 =
Td0(byte(s0, 3)) ^
Td1(byte(s3, 2)) ^
Td2(byte(s2, 1)) ^
Td3(byte(s1, 0)) ^
rk[0];
t1 =
Td0(byte(s1, 3)) ^
Td1(byte(s0, 2)) ^
Td2(byte(s3, 1)) ^
Td3(byte(s2, 0)) ^
rk[1];
t2 =
Td0(byte(s2, 3)) ^
Td1(byte(s1, 2)) ^
Td2(byte(s0, 1)) ^
Td3(byte(s3, 0)) ^
rk[2];
t3 =
Td0(byte(s3, 3)) ^
Td1(byte(s2, 2)) ^
Td2(byte(s1, 1)) ^
Td3(byte(s0, 0)) ^
rk[3];
if (r == Nr-2) {
break;
}
s0 = t0; s1 = t1; s2 = t2; s3 = t3;
}
rk += 4;
#else
/*
* Nr - 1 full rounds:
*/
r = Nr >> 1;
for (;;) {
t0 =
Td0(byte(s0, 3)) ^
Td1(byte(s3, 2)) ^
Td2(byte(s2, 1)) ^
Td3(byte(s1, 0)) ^
rk[4];
t1 =
Td0(byte(s1, 3)) ^
Td1(byte(s0, 2)) ^
Td2(byte(s3, 1)) ^
Td3(byte(s2, 0)) ^
rk[5];
t2 =
Td0(byte(s2, 3)) ^
Td1(byte(s1, 2)) ^
Td2(byte(s0, 1)) ^
Td3(byte(s3, 0)) ^
rk[6];
t3 =
Td0(byte(s3, 3)) ^
Td1(byte(s2, 2)) ^
Td2(byte(s1, 1)) ^
Td3(byte(s0, 0)) ^
rk[7];
rk += 8;
if (--r == 0) {
break;
}
s0 =
Td0(byte(t0, 3)) ^
Td1(byte(t3, 2)) ^
Td2(byte(t2, 1)) ^
Td3(byte(t1, 0)) ^
rk[0];
s1 =
Td0(byte(t1, 3)) ^
Td1(byte(t0, 2)) ^
Td2(byte(t3, 1)) ^
Td3(byte(t2, 0)) ^
rk[1];
s2 =
Td0(byte(t2, 3)) ^
Td1(byte(t1, 2)) ^
Td2(byte(t0, 1)) ^
Td3(byte(t3, 0)) ^
rk[2];
s3 =
Td0(byte(t3, 3)) ^
Td1(byte(t2, 2)) ^
Td2(byte(t1, 1)) ^
Td3(byte(t0, 0)) ^
rk[3];
}
#endif
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Td4[byte(t0, 3)] & 0xff000000) ^
(Td4[byte(t3, 2)] & 0x00ff0000) ^
(Td4[byte(t2, 1)] & 0x0000ff00) ^
(Td4[byte(t1, 0)] & 0x000000ff) ^
rk[0];
STORE32H(s0, pt);
s1 =
(Td4[byte(t1, 3)] & 0xff000000) ^
(Td4[byte(t0, 2)] & 0x00ff0000) ^
(Td4[byte(t3, 1)] & 0x0000ff00) ^
(Td4[byte(t2, 0)] & 0x000000ff) ^
rk[1];
STORE32H(s1, pt+4);
s2 =
(Td4[byte(t2, 3)] & 0xff000000) ^
(Td4[byte(t1, 2)] & 0x00ff0000) ^
(Td4[byte(t0, 1)] & 0x0000ff00) ^
(Td4[byte(t3, 0)] & 0x000000ff) ^
rk[2];
STORE32H(s2, pt+8);
s3 =
(Td4[byte(t3, 3)] & 0xff000000) ^
(Td4[byte(t2, 2)] & 0x00ff0000) ^
(Td4[byte(t1, 1)] & 0x0000ff00) ^
(Td4[byte(t0, 0)] & 0x000000ff) ^
rk[3];
STORE32H(s3, pt+12);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
int err = _rijndael_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
return err;
}
#endif
/**
Performs a self-test of the AES block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int ECB_TEST(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
int err;
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
} tests[] = {
{ 16,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
}, {
24,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
}, {
32,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
}
};
symmetric_key key;
unsigned char tmp[2][16];
int i, y;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
zeromem(&key, sizeof(key));
if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
return err;
}
rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key);
rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "AES Encrypt", i) ||
compare_testvector(tmp[1], 16, tests[i].pt, 16, "AES Decrypt", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 16; y++) tmp[0][y] = 0;
for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
#endif /* ENCRYPT_ONLY */
/** Terminate the context
@param skey The scheduled key
*/
void ECB_DONE(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int ECB_KS(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 16)
return CRYPT_INVALID_KEYSIZE;
if (*keysize < 24) {
*keysize = 16;
return CRYPT_OK;
} else if (*keysize < 32) {
*keysize = 24;
return CRYPT_OK;
} else {
*keysize = 32;
return CRYPT_OK;
}
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

File diff suppressed because it is too large Load Diff

1558
thirdparty/libtomcrypt/ciphers/anubis.c vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,594 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file blowfish.c
Implementation of the Blowfish block cipher, Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_BLOWFISH
const struct ltc_cipher_descriptor blowfish_desc =
{
"blowfish",
0,
8, 56, 8, 16,
&blowfish_setup,
&blowfish_ecb_encrypt,
&blowfish_ecb_decrypt,
&blowfish_test,
&blowfish_done,
&blowfish_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static const ulong32 ORIG_P[16 + 2] = {
0x243F6A88UL, 0x85A308D3UL, 0x13198A2EUL, 0x03707344UL,
0xA4093822UL, 0x299F31D0UL, 0x082EFA98UL, 0xEC4E6C89UL,
0x452821E6UL, 0x38D01377UL, 0xBE5466CFUL, 0x34E90C6CUL,
0xC0AC29B7UL, 0xC97C50DDUL, 0x3F84D5B5UL, 0xB5470917UL,
0x9216D5D9UL, 0x8979FB1BUL
};
static const ulong32 ORIG_S[4][256] = {
{ 0xD1310BA6UL, 0x98DFB5ACUL, 0x2FFD72DBUL, 0xD01ADFB7UL,
0xB8E1AFEDUL, 0x6A267E96UL, 0xBA7C9045UL, 0xF12C7F99UL,
0x24A19947UL, 0xB3916CF7UL, 0x0801F2E2UL, 0x858EFC16UL,
0x636920D8UL, 0x71574E69UL, 0xA458FEA3UL, 0xF4933D7EUL,
0x0D95748FUL, 0x728EB658UL, 0x718BCD58UL, 0x82154AEEUL,
0x7B54A41DUL, 0xC25A59B5UL, 0x9C30D539UL, 0x2AF26013UL,
0xC5D1B023UL, 0x286085F0UL, 0xCA417918UL, 0xB8DB38EFUL,
0x8E79DCB0UL, 0x603A180EUL, 0x6C9E0E8BUL, 0xB01E8A3EUL,
0xD71577C1UL, 0xBD314B27UL, 0x78AF2FDAUL, 0x55605C60UL,
0xE65525F3UL, 0xAA55AB94UL, 0x57489862UL, 0x63E81440UL,
0x55CA396AUL, 0x2AAB10B6UL, 0xB4CC5C34UL, 0x1141E8CEUL,
0xA15486AFUL, 0x7C72E993UL, 0xB3EE1411UL, 0x636FBC2AUL,
0x2BA9C55DUL, 0x741831F6UL, 0xCE5C3E16UL, 0x9B87931EUL,
0xAFD6BA33UL, 0x6C24CF5CUL, 0x7A325381UL, 0x28958677UL,
0x3B8F4898UL, 0x6B4BB9AFUL, 0xC4BFE81BUL, 0x66282193UL,
0x61D809CCUL, 0xFB21A991UL, 0x487CAC60UL, 0x5DEC8032UL,
0xEF845D5DUL, 0xE98575B1UL, 0xDC262302UL, 0xEB651B88UL,
0x23893E81UL, 0xD396ACC5UL, 0x0F6D6FF3UL, 0x83F44239UL,
0x2E0B4482UL, 0xA4842004UL, 0x69C8F04AUL, 0x9E1F9B5EUL,
0x21C66842UL, 0xF6E96C9AUL, 0x670C9C61UL, 0xABD388F0UL,
0x6A51A0D2UL, 0xD8542F68UL, 0x960FA728UL, 0xAB5133A3UL,
0x6EEF0B6CUL, 0x137A3BE4UL, 0xBA3BF050UL, 0x7EFB2A98UL,
0xA1F1651DUL, 0x39AF0176UL, 0x66CA593EUL, 0x82430E88UL,
0x8CEE8619UL, 0x456F9FB4UL, 0x7D84A5C3UL, 0x3B8B5EBEUL,
0xE06F75D8UL, 0x85C12073UL, 0x401A449FUL, 0x56C16AA6UL,
0x4ED3AA62UL, 0x363F7706UL, 0x1BFEDF72UL, 0x429B023DUL,
0x37D0D724UL, 0xD00A1248UL, 0xDB0FEAD3UL, 0x49F1C09BUL,
0x075372C9UL, 0x80991B7BUL, 0x25D479D8UL, 0xF6E8DEF7UL,
0xE3FE501AUL, 0xB6794C3BUL, 0x976CE0BDUL, 0x04C006BAUL,
0xC1A94FB6UL, 0x409F60C4UL, 0x5E5C9EC2UL, 0x196A2463UL,
0x68FB6FAFUL, 0x3E6C53B5UL, 0x1339B2EBUL, 0x3B52EC6FUL,
0x6DFC511FUL, 0x9B30952CUL, 0xCC814544UL, 0xAF5EBD09UL,
0xBEE3D004UL, 0xDE334AFDUL, 0x660F2807UL, 0x192E4BB3UL,
0xC0CBA857UL, 0x45C8740FUL, 0xD20B5F39UL, 0xB9D3FBDBUL,
0x5579C0BDUL, 0x1A60320AUL, 0xD6A100C6UL, 0x402C7279UL,
0x679F25FEUL, 0xFB1FA3CCUL, 0x8EA5E9F8UL, 0xDB3222F8UL,
0x3C7516DFUL, 0xFD616B15UL, 0x2F501EC8UL, 0xAD0552ABUL,
0x323DB5FAUL, 0xFD238760UL, 0x53317B48UL, 0x3E00DF82UL,
0x9E5C57BBUL, 0xCA6F8CA0UL, 0x1A87562EUL, 0xDF1769DBUL,
0xD542A8F6UL, 0x287EFFC3UL, 0xAC6732C6UL, 0x8C4F5573UL,
0x695B27B0UL, 0xBBCA58C8UL, 0xE1FFA35DUL, 0xB8F011A0UL,
0x10FA3D98UL, 0xFD2183B8UL, 0x4AFCB56CUL, 0x2DD1D35BUL,
0x9A53E479UL, 0xB6F84565UL, 0xD28E49BCUL, 0x4BFB9790UL,
0xE1DDF2DAUL, 0xA4CB7E33UL, 0x62FB1341UL, 0xCEE4C6E8UL,
0xEF20CADAUL, 0x36774C01UL, 0xD07E9EFEUL, 0x2BF11FB4UL,
0x95DBDA4DUL, 0xAE909198UL, 0xEAAD8E71UL, 0x6B93D5A0UL,
0xD08ED1D0UL, 0xAFC725E0UL, 0x8E3C5B2FUL, 0x8E7594B7UL,
0x8FF6E2FBUL, 0xF2122B64UL, 0x8888B812UL, 0x900DF01CUL,
0x4FAD5EA0UL, 0x688FC31CUL, 0xD1CFF191UL, 0xB3A8C1ADUL,
0x2F2F2218UL, 0xBE0E1777UL, 0xEA752DFEUL, 0x8B021FA1UL,
0xE5A0CC0FUL, 0xB56F74E8UL, 0x18ACF3D6UL, 0xCE89E299UL,
0xB4A84FE0UL, 0xFD13E0B7UL, 0x7CC43B81UL, 0xD2ADA8D9UL,
0x165FA266UL, 0x80957705UL, 0x93CC7314UL, 0x211A1477UL,
0xE6AD2065UL, 0x77B5FA86UL, 0xC75442F5UL, 0xFB9D35CFUL,
0xEBCDAF0CUL, 0x7B3E89A0UL, 0xD6411BD3UL, 0xAE1E7E49UL,
0x00250E2DUL, 0x2071B35EUL, 0x226800BBUL, 0x57B8E0AFUL,
0x2464369BUL, 0xF009B91EUL, 0x5563911DUL, 0x59DFA6AAUL,
0x78C14389UL, 0xD95A537FUL, 0x207D5BA2UL, 0x02E5B9C5UL,
0x83260376UL, 0x6295CFA9UL, 0x11C81968UL, 0x4E734A41UL,
0xB3472DCAUL, 0x7B14A94AUL, 0x1B510052UL, 0x9A532915UL,
0xD60F573FUL, 0xBC9BC6E4UL, 0x2B60A476UL, 0x81E67400UL,
0x08BA6FB5UL, 0x571BE91FUL, 0xF296EC6BUL, 0x2A0DD915UL,
0xB6636521UL, 0xE7B9F9B6UL, 0xFF34052EUL, 0xC5855664UL,
0x53B02D5DUL, 0xA99F8FA1UL, 0x08BA4799UL, 0x6E85076AUL },
{ 0x4B7A70E9UL, 0xB5B32944UL, 0xDB75092EUL, 0xC4192623UL,
0xAD6EA6B0UL, 0x49A7DF7DUL, 0x9CEE60B8UL, 0x8FEDB266UL,
0xECAA8C71UL, 0x699A17FFUL, 0x5664526CUL, 0xC2B19EE1UL,
0x193602A5UL, 0x75094C29UL, 0xA0591340UL, 0xE4183A3EUL,
0x3F54989AUL, 0x5B429D65UL, 0x6B8FE4D6UL, 0x99F73FD6UL,
0xA1D29C07UL, 0xEFE830F5UL, 0x4D2D38E6UL, 0xF0255DC1UL,
0x4CDD2086UL, 0x8470EB26UL, 0x6382E9C6UL, 0x021ECC5EUL,
0x09686B3FUL, 0x3EBAEFC9UL, 0x3C971814UL, 0x6B6A70A1UL,
0x687F3584UL, 0x52A0E286UL, 0xB79C5305UL, 0xAA500737UL,
0x3E07841CUL, 0x7FDEAE5CUL, 0x8E7D44ECUL, 0x5716F2B8UL,
0xB03ADA37UL, 0xF0500C0DUL, 0xF01C1F04UL, 0x0200B3FFUL,
0xAE0CF51AUL, 0x3CB574B2UL, 0x25837A58UL, 0xDC0921BDUL,
0xD19113F9UL, 0x7CA92FF6UL, 0x94324773UL, 0x22F54701UL,
0x3AE5E581UL, 0x37C2DADCUL, 0xC8B57634UL, 0x9AF3DDA7UL,
0xA9446146UL, 0x0FD0030EUL, 0xECC8C73EUL, 0xA4751E41UL,
0xE238CD99UL, 0x3BEA0E2FUL, 0x3280BBA1UL, 0x183EB331UL,
0x4E548B38UL, 0x4F6DB908UL, 0x6F420D03UL, 0xF60A04BFUL,
0x2CB81290UL, 0x24977C79UL, 0x5679B072UL, 0xBCAF89AFUL,
0xDE9A771FUL, 0xD9930810UL, 0xB38BAE12UL, 0xDCCF3F2EUL,
0x5512721FUL, 0x2E6B7124UL, 0x501ADDE6UL, 0x9F84CD87UL,
0x7A584718UL, 0x7408DA17UL, 0xBC9F9ABCUL, 0xE94B7D8CUL,
0xEC7AEC3AUL, 0xDB851DFAUL, 0x63094366UL, 0xC464C3D2UL,
0xEF1C1847UL, 0x3215D908UL, 0xDD433B37UL, 0x24C2BA16UL,
0x12A14D43UL, 0x2A65C451UL, 0x50940002UL, 0x133AE4DDUL,
0x71DFF89EUL, 0x10314E55UL, 0x81AC77D6UL, 0x5F11199BUL,
0x043556F1UL, 0xD7A3C76BUL, 0x3C11183BUL, 0x5924A509UL,
0xF28FE6EDUL, 0x97F1FBFAUL, 0x9EBABF2CUL, 0x1E153C6EUL,
0x86E34570UL, 0xEAE96FB1UL, 0x860E5E0AUL, 0x5A3E2AB3UL,
0x771FE71CUL, 0x4E3D06FAUL, 0x2965DCB9UL, 0x99E71D0FUL,
0x803E89D6UL, 0x5266C825UL, 0x2E4CC978UL, 0x9C10B36AUL,
0xC6150EBAUL, 0x94E2EA78UL, 0xA5FC3C53UL, 0x1E0A2DF4UL,
0xF2F74EA7UL, 0x361D2B3DUL, 0x1939260FUL, 0x19C27960UL,
0x5223A708UL, 0xF71312B6UL, 0xEBADFE6EUL, 0xEAC31F66UL,
0xE3BC4595UL, 0xA67BC883UL, 0xB17F37D1UL, 0x018CFF28UL,
0xC332DDEFUL, 0xBE6C5AA5UL, 0x65582185UL, 0x68AB9802UL,
0xEECEA50FUL, 0xDB2F953BUL, 0x2AEF7DADUL, 0x5B6E2F84UL,
0x1521B628UL, 0x29076170UL, 0xECDD4775UL, 0x619F1510UL,
0x13CCA830UL, 0xEB61BD96UL, 0x0334FE1EUL, 0xAA0363CFUL,
0xB5735C90UL, 0x4C70A239UL, 0xD59E9E0BUL, 0xCBAADE14UL,
0xEECC86BCUL, 0x60622CA7UL, 0x9CAB5CABUL, 0xB2F3846EUL,
0x648B1EAFUL, 0x19BDF0CAUL, 0xA02369B9UL, 0x655ABB50UL,
0x40685A32UL, 0x3C2AB4B3UL, 0x319EE9D5UL, 0xC021B8F7UL,
0x9B540B19UL, 0x875FA099UL, 0x95F7997EUL, 0x623D7DA8UL,
0xF837889AUL, 0x97E32D77UL, 0x11ED935FUL, 0x16681281UL,
0x0E358829UL, 0xC7E61FD6UL, 0x96DEDFA1UL, 0x7858BA99UL,
0x57F584A5UL, 0x1B227263UL, 0x9B83C3FFUL, 0x1AC24696UL,
0xCDB30AEBUL, 0x532E3054UL, 0x8FD948E4UL, 0x6DBC3128UL,
0x58EBF2EFUL, 0x34C6FFEAUL, 0xFE28ED61UL, 0xEE7C3C73UL,
0x5D4A14D9UL, 0xE864B7E3UL, 0x42105D14UL, 0x203E13E0UL,
0x45EEE2B6UL, 0xA3AAABEAUL, 0xDB6C4F15UL, 0xFACB4FD0UL,
0xC742F442UL, 0xEF6ABBB5UL, 0x654F3B1DUL, 0x41CD2105UL,
0xD81E799EUL, 0x86854DC7UL, 0xE44B476AUL, 0x3D816250UL,
0xCF62A1F2UL, 0x5B8D2646UL, 0xFC8883A0UL, 0xC1C7B6A3UL,
0x7F1524C3UL, 0x69CB7492UL, 0x47848A0BUL, 0x5692B285UL,
0x095BBF00UL, 0xAD19489DUL, 0x1462B174UL, 0x23820E00UL,
0x58428D2AUL, 0x0C55F5EAUL, 0x1DADF43EUL, 0x233F7061UL,
0x3372F092UL, 0x8D937E41UL, 0xD65FECF1UL, 0x6C223BDBUL,
0x7CDE3759UL, 0xCBEE7460UL, 0x4085F2A7UL, 0xCE77326EUL,
0xA6078084UL, 0x19F8509EUL, 0xE8EFD855UL, 0x61D99735UL,
0xA969A7AAUL, 0xC50C06C2UL, 0x5A04ABFCUL, 0x800BCADCUL,
0x9E447A2EUL, 0xC3453484UL, 0xFDD56705UL, 0x0E1E9EC9UL,
0xDB73DBD3UL, 0x105588CDUL, 0x675FDA79UL, 0xE3674340UL,
0xC5C43465UL, 0x713E38D8UL, 0x3D28F89EUL, 0xF16DFF20UL,
0x153E21E7UL, 0x8FB03D4AUL, 0xE6E39F2BUL, 0xDB83ADF7UL },
{ 0xE93D5A68UL, 0x948140F7UL, 0xF64C261CUL, 0x94692934UL,
0x411520F7UL, 0x7602D4F7UL, 0xBCF46B2EUL, 0xD4A20068UL,
0xD4082471UL, 0x3320F46AUL, 0x43B7D4B7UL, 0x500061AFUL,
0x1E39F62EUL, 0x97244546UL, 0x14214F74UL, 0xBF8B8840UL,
0x4D95FC1DUL, 0x96B591AFUL, 0x70F4DDD3UL, 0x66A02F45UL,
0xBFBC09ECUL, 0x03BD9785UL, 0x7FAC6DD0UL, 0x31CB8504UL,
0x96EB27B3UL, 0x55FD3941UL, 0xDA2547E6UL, 0xABCA0A9AUL,
0x28507825UL, 0x530429F4UL, 0x0A2C86DAUL, 0xE9B66DFBUL,
0x68DC1462UL, 0xD7486900UL, 0x680EC0A4UL, 0x27A18DEEUL,
0x4F3FFEA2UL, 0xE887AD8CUL, 0xB58CE006UL, 0x7AF4D6B6UL,
0xAACE1E7CUL, 0xD3375FECUL, 0xCE78A399UL, 0x406B2A42UL,
0x20FE9E35UL, 0xD9F385B9UL, 0xEE39D7ABUL, 0x3B124E8BUL,
0x1DC9FAF7UL, 0x4B6D1856UL, 0x26A36631UL, 0xEAE397B2UL,
0x3A6EFA74UL, 0xDD5B4332UL, 0x6841E7F7UL, 0xCA7820FBUL,
0xFB0AF54EUL, 0xD8FEB397UL, 0x454056ACUL, 0xBA489527UL,
0x55533A3AUL, 0x20838D87UL, 0xFE6BA9B7UL, 0xD096954BUL,
0x55A867BCUL, 0xA1159A58UL, 0xCCA92963UL, 0x99E1DB33UL,
0xA62A4A56UL, 0x3F3125F9UL, 0x5EF47E1CUL, 0x9029317CUL,
0xFDF8E802UL, 0x04272F70UL, 0x80BB155CUL, 0x05282CE3UL,
0x95C11548UL, 0xE4C66D22UL, 0x48C1133FUL, 0xC70F86DCUL,
0x07F9C9EEUL, 0x41041F0FUL, 0x404779A4UL, 0x5D886E17UL,
0x325F51EBUL, 0xD59BC0D1UL, 0xF2BCC18FUL, 0x41113564UL,
0x257B7834UL, 0x602A9C60UL, 0xDFF8E8A3UL, 0x1F636C1BUL,
0x0E12B4C2UL, 0x02E1329EUL, 0xAF664FD1UL, 0xCAD18115UL,
0x6B2395E0UL, 0x333E92E1UL, 0x3B240B62UL, 0xEEBEB922UL,
0x85B2A20EUL, 0xE6BA0D99UL, 0xDE720C8CUL, 0x2DA2F728UL,
0xD0127845UL, 0x95B794FDUL, 0x647D0862UL, 0xE7CCF5F0UL,
0x5449A36FUL, 0x877D48FAUL, 0xC39DFD27UL, 0xF33E8D1EUL,
0x0A476341UL, 0x992EFF74UL, 0x3A6F6EABUL, 0xF4F8FD37UL,
0xA812DC60UL, 0xA1EBDDF8UL, 0x991BE14CUL, 0xDB6E6B0DUL,
0xC67B5510UL, 0x6D672C37UL, 0x2765D43BUL, 0xDCD0E804UL,
0xF1290DC7UL, 0xCC00FFA3UL, 0xB5390F92UL, 0x690FED0BUL,
0x667B9FFBUL, 0xCEDB7D9CUL, 0xA091CF0BUL, 0xD9155EA3UL,
0xBB132F88UL, 0x515BAD24UL, 0x7B9479BFUL, 0x763BD6EBUL,
0x37392EB3UL, 0xCC115979UL, 0x8026E297UL, 0xF42E312DUL,
0x6842ADA7UL, 0xC66A2B3BUL, 0x12754CCCUL, 0x782EF11CUL,
0x6A124237UL, 0xB79251E7UL, 0x06A1BBE6UL, 0x4BFB6350UL,
0x1A6B1018UL, 0x11CAEDFAUL, 0x3D25BDD8UL, 0xE2E1C3C9UL,
0x44421659UL, 0x0A121386UL, 0xD90CEC6EUL, 0xD5ABEA2AUL,
0x64AF674EUL, 0xDA86A85FUL, 0xBEBFE988UL, 0x64E4C3FEUL,
0x9DBC8057UL, 0xF0F7C086UL, 0x60787BF8UL, 0x6003604DUL,
0xD1FD8346UL, 0xF6381FB0UL, 0x7745AE04UL, 0xD736FCCCUL,
0x83426B33UL, 0xF01EAB71UL, 0xB0804187UL, 0x3C005E5FUL,
0x77A057BEUL, 0xBDE8AE24UL, 0x55464299UL, 0xBF582E61UL,
0x4E58F48FUL, 0xF2DDFDA2UL, 0xF474EF38UL, 0x8789BDC2UL,
0x5366F9C3UL, 0xC8B38E74UL, 0xB475F255UL, 0x46FCD9B9UL,
0x7AEB2661UL, 0x8B1DDF84UL, 0x846A0E79UL, 0x915F95E2UL,
0x466E598EUL, 0x20B45770UL, 0x8CD55591UL, 0xC902DE4CUL,
0xB90BACE1UL, 0xBB8205D0UL, 0x11A86248UL, 0x7574A99EUL,
0xB77F19B6UL, 0xE0A9DC09UL, 0x662D09A1UL, 0xC4324633UL,
0xE85A1F02UL, 0x09F0BE8CUL, 0x4A99A025UL, 0x1D6EFE10UL,
0x1AB93D1DUL, 0x0BA5A4DFUL, 0xA186F20FUL, 0x2868F169UL,
0xDCB7DA83UL, 0x573906FEUL, 0xA1E2CE9BUL, 0x4FCD7F52UL,
0x50115E01UL, 0xA70683FAUL, 0xA002B5C4UL, 0x0DE6D027UL,
0x9AF88C27UL, 0x773F8641UL, 0xC3604C06UL, 0x61A806B5UL,
0xF0177A28UL, 0xC0F586E0UL, 0x006058AAUL, 0x30DC7D62UL,
0x11E69ED7UL, 0x2338EA63UL, 0x53C2DD94UL, 0xC2C21634UL,
0xBBCBEE56UL, 0x90BCB6DEUL, 0xEBFC7DA1UL, 0xCE591D76UL,
0x6F05E409UL, 0x4B7C0188UL, 0x39720A3DUL, 0x7C927C24UL,
0x86E3725FUL, 0x724D9DB9UL, 0x1AC15BB4UL, 0xD39EB8FCUL,
0xED545578UL, 0x08FCA5B5UL, 0xD83D7CD3UL, 0x4DAD0FC4UL,
0x1E50EF5EUL, 0xB161E6F8UL, 0xA28514D9UL, 0x6C51133CUL,
0x6FD5C7E7UL, 0x56E14EC4UL, 0x362ABFCEUL, 0xDDC6C837UL,
0xD79A3234UL, 0x92638212UL, 0x670EFA8EUL, 0x406000E0UL },
{ 0x3A39CE37UL, 0xD3FAF5CFUL, 0xABC27737UL, 0x5AC52D1BUL,
0x5CB0679EUL, 0x4FA33742UL, 0xD3822740UL, 0x99BC9BBEUL,
0xD5118E9DUL, 0xBF0F7315UL, 0xD62D1C7EUL, 0xC700C47BUL,
0xB78C1B6BUL, 0x21A19045UL, 0xB26EB1BEUL, 0x6A366EB4UL,
0x5748AB2FUL, 0xBC946E79UL, 0xC6A376D2UL, 0x6549C2C8UL,
0x530FF8EEUL, 0x468DDE7DUL, 0xD5730A1DUL, 0x4CD04DC6UL,
0x2939BBDBUL, 0xA9BA4650UL, 0xAC9526E8UL, 0xBE5EE304UL,
0xA1FAD5F0UL, 0x6A2D519AUL, 0x63EF8CE2UL, 0x9A86EE22UL,
0xC089C2B8UL, 0x43242EF6UL, 0xA51E03AAUL, 0x9CF2D0A4UL,
0x83C061BAUL, 0x9BE96A4DUL, 0x8FE51550UL, 0xBA645BD6UL,
0x2826A2F9UL, 0xA73A3AE1UL, 0x4BA99586UL, 0xEF5562E9UL,
0xC72FEFD3UL, 0xF752F7DAUL, 0x3F046F69UL, 0x77FA0A59UL,
0x80E4A915UL, 0x87B08601UL, 0x9B09E6ADUL, 0x3B3EE593UL,
0xE990FD5AUL, 0x9E34D797UL, 0x2CF0B7D9UL, 0x022B8B51UL,
0x96D5AC3AUL, 0x017DA67DUL, 0xD1CF3ED6UL, 0x7C7D2D28UL,
0x1F9F25CFUL, 0xADF2B89BUL, 0x5AD6B472UL, 0x5A88F54CUL,
0xE029AC71UL, 0xE019A5E6UL, 0x47B0ACFDUL, 0xED93FA9BUL,
0xE8D3C48DUL, 0x283B57CCUL, 0xF8D56629UL, 0x79132E28UL,
0x785F0191UL, 0xED756055UL, 0xF7960E44UL, 0xE3D35E8CUL,
0x15056DD4UL, 0x88F46DBAUL, 0x03A16125UL, 0x0564F0BDUL,
0xC3EB9E15UL, 0x3C9057A2UL, 0x97271AECUL, 0xA93A072AUL,
0x1B3F6D9BUL, 0x1E6321F5UL, 0xF59C66FBUL, 0x26DCF319UL,
0x7533D928UL, 0xB155FDF5UL, 0x03563482UL, 0x8ABA3CBBUL,
0x28517711UL, 0xC20AD9F8UL, 0xABCC5167UL, 0xCCAD925FUL,
0x4DE81751UL, 0x3830DC8EUL, 0x379D5862UL, 0x9320F991UL,
0xEA7A90C2UL, 0xFB3E7BCEUL, 0x5121CE64UL, 0x774FBE32UL,
0xA8B6E37EUL, 0xC3293D46UL, 0x48DE5369UL, 0x6413E680UL,
0xA2AE0810UL, 0xDD6DB224UL, 0x69852DFDUL, 0x09072166UL,
0xB39A460AUL, 0x6445C0DDUL, 0x586CDECFUL, 0x1C20C8AEUL,
0x5BBEF7DDUL, 0x1B588D40UL, 0xCCD2017FUL, 0x6BB4E3BBUL,
0xDDA26A7EUL, 0x3A59FF45UL, 0x3E350A44UL, 0xBCB4CDD5UL,
0x72EACEA8UL, 0xFA6484BBUL, 0x8D6612AEUL, 0xBF3C6F47UL,
0xD29BE463UL, 0x542F5D9EUL, 0xAEC2771BUL, 0xF64E6370UL,
0x740E0D8DUL, 0xE75B1357UL, 0xF8721671UL, 0xAF537D5DUL,
0x4040CB08UL, 0x4EB4E2CCUL, 0x34D2466AUL, 0x0115AF84UL,
0xE1B00428UL, 0x95983A1DUL, 0x06B89FB4UL, 0xCE6EA048UL,
0x6F3F3B82UL, 0x3520AB82UL, 0x011A1D4BUL, 0x277227F8UL,
0x611560B1UL, 0xE7933FDCUL, 0xBB3A792BUL, 0x344525BDUL,
0xA08839E1UL, 0x51CE794BUL, 0x2F32C9B7UL, 0xA01FBAC9UL,
0xE01CC87EUL, 0xBCC7D1F6UL, 0xCF0111C3UL, 0xA1E8AAC7UL,
0x1A908749UL, 0xD44FBD9AUL, 0xD0DADECBUL, 0xD50ADA38UL,
0x0339C32AUL, 0xC6913667UL, 0x8DF9317CUL, 0xE0B12B4FUL,
0xF79E59B7UL, 0x43F5BB3AUL, 0xF2D519FFUL, 0x27D9459CUL,
0xBF97222CUL, 0x15E6FC2AUL, 0x0F91FC71UL, 0x9B941525UL,
0xFAE59361UL, 0xCEB69CEBUL, 0xC2A86459UL, 0x12BAA8D1UL,
0xB6C1075EUL, 0xE3056A0CUL, 0x10D25065UL, 0xCB03A442UL,
0xE0EC6E0EUL, 0x1698DB3BUL, 0x4C98A0BEUL, 0x3278E964UL,
0x9F1F9532UL, 0xE0D392DFUL, 0xD3A0342BUL, 0x8971F21EUL,
0x1B0A7441UL, 0x4BA3348CUL, 0xC5BE7120UL, 0xC37632D8UL,
0xDF359F8DUL, 0x9B992F2EUL, 0xE60B6F47UL, 0x0FE3F11DUL,
0xE54CDA54UL, 0x1EDAD891UL, 0xCE6279CFUL, 0xCD3E7E6FUL,
0x1618B166UL, 0xFD2C1D05UL, 0x848FD2C5UL, 0xF6FB2299UL,
0xF523F357UL, 0xA6327623UL, 0x93A83531UL, 0x56CCCD02UL,
0xACF08162UL, 0x5A75EBB5UL, 0x6E163697UL, 0x88D273CCUL,
0xDE966292UL, 0x81B949D0UL, 0x4C50901BUL, 0x71C65614UL,
0xE6C6C7BDUL, 0x327A140AUL, 0x45E1D006UL, 0xC3F27B9AUL,
0xC9AA53FDUL, 0x62A80F00UL, 0xBB25BFE2UL, 0x35BDD2F6UL,
0x71126905UL, 0xB2040222UL, 0xB6CBCF7CUL, 0xCD769C2BUL,
0x53113EC0UL, 0x1640E3D3UL, 0x38ABBD60UL, 0x2547ADF0UL,
0xBA38209CUL, 0xF746CE76UL, 0x77AFA1C5UL, 0x20756060UL,
0x85CBFE4EUL, 0x8AE88DD8UL, 0x7AAAF9B0UL, 0x4CF9AA7EUL,
0x1948C25CUL, 0x02FB8A8CUL, 0x01C36AE4UL, 0xD6EBE1F9UL,
0x90D4F869UL, 0xA65CDEA0UL, 0x3F09252DUL, 0xC208E69FUL,
0xB74E6132UL, 0xCE77E25BUL, 0x578FDFE3UL, 0x3AC372E6UL }
};
/**
Initialize the Blowfish block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
symmetric_key *skey)
{
ulong32 x, y, z, A;
unsigned char B[8];
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
/* check key length */
if (keylen < 8 || keylen > 56) {
return CRYPT_INVALID_KEYSIZE;
}
/* check rounds */
if (num_rounds != 0 && num_rounds != 16) {
return CRYPT_INVALID_ROUNDS;
}
/* load in key bytes (Supplied by David Hopwood) */
for (x = y = 0; x < 18; x++) {
A = 0;
for (z = 0; z < 4; z++) {
A = (A << 8) | ((ulong32)key[y++] & 255);
if (y == (ulong32)keylen) {
y = 0;
}
}
skey->blowfish.K[x] = ORIG_P[x] ^ A;
}
/* copy sboxes */
for (x = 0; x < 4; x++) {
for (y = 0; y < 256; y++) {
skey->blowfish.S[x][y] = ORIG_S[x][y];
}
}
/* encrypt K array */
for (x = 0; x < 8; x++) {
B[x] = 0;
}
for (x = 0; x < 18; x += 2) {
/* encrypt it */
blowfish_ecb_encrypt(B, B, skey);
/* copy it */
LOAD32H(skey->blowfish.K[x], &B[0]);
LOAD32H(skey->blowfish.K[x+1], &B[4]);
}
/* encrypt S array */
for (x = 0; x < 4; x++) {
for (y = 0; y < 256; y += 2) {
/* encrypt it */
blowfish_ecb_encrypt(B, B, skey);
/* copy it */
LOAD32H(skey->blowfish.S[x][y], &B[0]);
LOAD32H(skey->blowfish.S[x][y+1], &B[4]);
}
}
#ifdef LTC_CLEAN_STACK
zeromem(B, sizeof(B));
#endif
return CRYPT_OK;
}
#ifndef __GNUC__
#define F(x) ((S1[byte(x,3)] + S2[byte(x,2)]) ^ S3[byte(x,1)]) + S4[byte(x,0)]
#else
#define F(x) ((skey->blowfish.S[0][byte(x,3)] + skey->blowfish.S[1][byte(x,2)]) ^ skey->blowfish.S[2][byte(x,1)]) + skey->blowfish.S[3][byte(x,0)]
#endif
/**
Encrypts a block of text with Blowfish
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 L, R;
int r;
#ifndef __GNUC__
ulong32 *S1, *S2, *S3, *S4;
#endif
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
#ifndef __GNUC__
S1 = skey->blowfish.S[0];
S2 = skey->blowfish.S[1];
S3 = skey->blowfish.S[2];
S4 = skey->blowfish.S[3];
#endif
/* load it */
LOAD32H(L, &pt[0]);
LOAD32H(R, &pt[4]);
/* do 16 rounds */
for (r = 0; r < 16; ) {
L ^= skey->blowfish.K[r++]; R ^= F(L);
R ^= skey->blowfish.K[r++]; L ^= F(R);
L ^= skey->blowfish.K[r++]; R ^= F(L);
R ^= skey->blowfish.K[r++]; L ^= F(R);
}
/* last keying */
R ^= skey->blowfish.K[17];
L ^= skey->blowfish.K[16];
/* store */
STORE32H(R, &ct[0]);
STORE32H(L, &ct[4]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
int err = _blowfish_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(ulong32) * 2 + sizeof(int));
return err;
}
#endif
/**
Decrypts a block of text with Blowfish
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 L, R;
int r;
#ifndef __GNUC__
ulong32 *S1, *S2, *S3, *S4;
#endif
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
#ifndef __GNUC__
S1 = skey->blowfish.S[0];
S2 = skey->blowfish.S[1];
S3 = skey->blowfish.S[2];
S4 = skey->blowfish.S[3];
#endif
/* load it */
LOAD32H(R, &ct[0]);
LOAD32H(L, &ct[4]);
/* undo last keying */
R ^= skey->blowfish.K[17];
L ^= skey->blowfish.K[16];
/* do 16 rounds */
for (r = 15; r > 0; ) {
L ^= F(R); R ^= skey->blowfish.K[r--];
R ^= F(L); L ^= skey->blowfish.K[r--];
L ^= F(R); R ^= skey->blowfish.K[r--];
R ^= F(L); L ^= skey->blowfish.K[r--];
}
/* store */
STORE32H(L, &pt[0]);
STORE32H(R, &pt[4]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
int err = _blowfish_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(ulong32) * 2 + sizeof(int));
return err;
}
#endif
/**
Performs a self-test of the Blowfish block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int blowfish_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
int err;
symmetric_key key;
static const struct {
unsigned char key[8], pt[8], ct[8];
} tests[] = {
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{ 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}
},
{
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{ 0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A}
},
{
{ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
{ 0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2}
}
};
unsigned char tmp[2][8];
int x, y;
for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
/* setup key */
if ((err = blowfish_setup(tests[x].key, 8, 16, &key)) != CRYPT_OK) {
return err;
}
/* encrypt and decrypt */
blowfish_ecb_encrypt(tests[x].pt, tmp[0], &key);
blowfish_ecb_decrypt(tmp[0], tmp[1], &key);
/* compare */
if ((compare_testvector(tmp[0], 8, tests[x].ct, 8, "Blowfish Encrypt", x) != 0) ||
(compare_testvector(tmp[1], 8, tests[x].pt, 8, "Blowfish Decrypt", x) != 0)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 8; y++) tmp[0][y] = 0;
for (y = 0; y < 1000; y++) blowfish_ecb_encrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 1000; y++) blowfish_ecb_decrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
/** Terminate the context
@param skey The scheduled key
*/
void blowfish_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int blowfish_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 8) {
return CRYPT_INVALID_KEYSIZE;
} else if (*keysize > 56) {
*keysize = 56;
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,726 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file camellia.c
Implementation by Tom St Denis of Elliptic Semiconductor
*/
#include "tomcrypt.h"
#ifdef LTC_CAMELLIA
const struct ltc_cipher_descriptor camellia_desc = {
"camellia",
23,
16, 32, 16, 18,
&camellia_setup,
&camellia_ecb_encrypt,
&camellia_ecb_decrypt,
&camellia_test,
&camellia_done,
&camellia_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static const ulong32 SP1110[] = {
0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, 0xc0c0c000, 0xe5e5e500,
0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100,
0x23232300, 0xefefef00, 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100,
0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, 0x92929200, 0xbdbdbd00,
0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00,
0x3e3e3e00, 0x30303000, 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00,
0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, 0x5d5d5d00, 0x3d3d3d00,
0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00,
0x8b8b8b00, 0x0d0d0d00, 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00,
0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, 0x84848400, 0x99999900,
0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500,
0x6d6d6d00, 0xb7b7b700, 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700,
0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, 0x11111100, 0x1c1c1c00,
0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200,
0xfefefe00, 0x44444400, 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100,
0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, 0x69696900, 0x50505000,
0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700,
0x54545400, 0x5b5b5b00, 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200,
0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, 0x75757500, 0xdbdbdb00,
0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400,
0x87878700, 0x5c5c5c00, 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300,
0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, 0xbfbfbf00, 0xe2e2e200,
0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00,
0x81818100, 0x96969600, 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00,
0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, 0xbcbcbc00, 0x8e8e8e00,
0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900,
0x78787800, 0x98989800, 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00,
0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, 0x8d8d8d00, 0xfafafa00,
0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00,
0x36363600, 0x49494900, 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400,
0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100,
0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00,
};
static const ulong32 SP0222[] = {
0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, 0x00818181, 0x00cbcbcb,
0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282,
0x00464646, 0x00dfdfdf, 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242,
0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, 0x00252525, 0x007b7b7b,
0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d,
0x007c7c7c, 0x00606060, 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434,
0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, 0x00bababa, 0x007a7a7a,
0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a,
0x00171717, 0x001a1a1a, 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a,
0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, 0x00090909, 0x00333333,
0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a,
0x00dadada, 0x006f6f6f, 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf,
0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, 0x00222222, 0x00383838,
0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444,
0x00fdfdfd, 0x00888888, 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323,
0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, 0x00d2d2d2, 0x00a0a0a0,
0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f,
0x00a8a8a8, 0x00b6b6b6, 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5,
0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, 0x00eaeaea, 0x00b7b7b7,
0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929,
0x000f0f0f, 0x00b8b8b8, 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666,
0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, 0x007f7f7f, 0x00c5c5c5,
0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676,
0x00030303, 0x002d2d2d, 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c,
0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, 0x00797979, 0x001d1d1d,
0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2,
0x00f0f0f0, 0x00313131, 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575,
0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, 0x001b1b1b, 0x00f5f5f5,
0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414,
0x006c6c6c, 0x00929292, 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949,
0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, 0x00868686, 0x00838383,
0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d,
};
static const ulong32 SP3033[] = {
0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, 0x60006060, 0xf200f2f2,
0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0,
0x91009191, 0xf700f7f7, 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090,
0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, 0x49004949, 0xde00dede,
0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767,
0x1f001f1f, 0x18001818, 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d,
0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, 0xae00aeae, 0x9e009e9e,
0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6,
0xc500c5c5, 0x86008686, 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696,
0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, 0x42004242, 0xcc00cccc,
0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282,
0xb600b6b6, 0xdb00dbdb, 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb,
0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, 0x88008888, 0x0e000e0e,
0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111,
0x7f007f7f, 0x22002222, 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8,
0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, 0xb400b4b4, 0x28002828,
0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb,
0x2a002a2a, 0xad00adad, 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969,
0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, 0xba00baba, 0xed00eded,
0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a,
0xc300c3c3, 0x2e002e2e, 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999,
0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, 0xdf00dfdf, 0x71007171,
0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d,
0xc000c0c0, 0x4b004b4b, 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717,
0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, 0x5e005e5e, 0x47004747,
0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac,
0x3c003c3c, 0x4c004c4c, 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d,
0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, 0xc600c6c6, 0x7d007d7d,
0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505,
0x1b001b1b, 0xa400a4a4, 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252,
0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0,
0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f,
};
static const ulong32 SP4404[] = {
0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, 0xeaea00ea, 0xaeae00ae,
0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092,
0x86860086, 0xafaf00af, 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b,
0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, 0x51510051, 0x6c6c006c,
0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084,
0xdfdf00df, 0xcbcb00cb, 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004,
0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, 0x53530053, 0xf2f200f2,
0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069,
0xaaaa00aa, 0xa0a000a0, 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064,
0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, 0x09090009, 0xdddd00dd,
0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf,
0x52520052, 0xd8d800d8, 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063,
0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, 0x2f2f002f, 0xb4b400b4,
0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d,
0x72720072, 0xb9b900b9, 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1,
0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, 0x77770077, 0x80800080,
0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041,
0xefef00ef, 0x93930093, 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd,
0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, 0xc5c500c5, 0x1a1a001a,
0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d,
0x0d0d000d, 0x66660066, 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099,
0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, 0x17170017, 0xd7d700d7,
0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022,
0x44440044, 0xb2b200b2, 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050,
0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, 0xffff00ff, 0xd2d200d2,
0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094,
0x5c5c005c, 0x02020002, 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2,
0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, 0xbebe00be, 0x2e2e002e,
0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059,
0x98980098, 0x6a6a006a, 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa,
0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, 0x38380038, 0xa4a400a4,
0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e,
};
static const ulong64 key_sigma[] = {
CONST64(0xA09E667F3BCC908B),
CONST64(0xB67AE8584CAA73B2),
CONST64(0xC6EF372FE94F82BE),
CONST64(0x54FF53A5F1D36F1C),
CONST64(0x10E527FADE682D1D),
CONST64(0xB05688C2B3E6C1FD)
};
static ulong64 F(ulong64 x)
{
ulong32 D, U;
#define loc(i) ((8-i)*8)
D = SP1110[(x >> loc(8)) & 0xFF] ^ SP0222[(x >> loc(5)) & 0xFF] ^ SP3033[(x >> loc(6)) & 0xFF] ^ SP4404[(x >> loc(7)) & 0xFF];
U = SP1110[(x >> loc(1)) & 0xFF] ^ SP0222[(x >> loc(2)) & 0xFF] ^ SP3033[(x >> loc(3)) & 0xFF] ^ SP4404[(x >> loc(4)) & 0xFF];
D ^= U;
U = D ^ RORc(U, 8);
return ((ulong64)U) | (((ulong64)D) << CONST64(32));
}
static void rot_128(unsigned char *in, unsigned count, unsigned char *out)
{
unsigned x, w, b;
w = count >> 3;
b = count & 7;
for (x = 0; x < 16; x++) {
out[x] = (in[(x+w)&15] << b) | (in[(x+w+1)&15] >> (8 - b));
}
}
int camellia_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
unsigned char T[48], kA[16], kB[16], kR[16], kL[16];
int x;
ulong64 A, B;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
/* Valid sizes (in bytes) are 16, 24, 32 */
if (keylen != 16 && keylen != 24 && keylen != 32) {
return CRYPT_INVALID_KEYSIZE;
}
/* number of rounds */
skey->camellia.R = (keylen == 16) ? 18 : 24;
if (num_rounds != 0 && num_rounds != skey->camellia.R) {
return CRYPT_INVALID_ROUNDS;
}
/* expand key */
if (keylen == 16) {
for (x = 0; x < 16; x++) {
T[x] = key[x];
T[x + 16] = 0;
}
} else if (keylen == 24) {
for (x = 0; x < 24; x++) {
T[x] = key[x];
}
for (x = 24; x < 32; x++) {
T[x] = key[x-8] ^ 0xFF;
}
} else {
for (x = 0; x < 32; x++) {
T[x] = key[x];
}
}
for (x = 0; x < 16; x++) {
kL[x] = T[x];
kR[x] = T[x + 16];
}
for (x = 32; x < 48; x++) {
T[x] = T[x - 32] ^ T[x - 16];
}
/* first two rounds */
LOAD64H(A, T+32); LOAD64H(B, T+40);
B ^= F(A ^ key_sigma[0]);
A ^= F(B ^ key_sigma[1]);
STORE64H(A, T+32); STORE64H(B, T+40);
/* xor kL in */
for (x = 0; x < 16; x++) { T[x+32] ^= kL[x]; }
/* next two rounds */
LOAD64H(A, T+32); LOAD64H(B, T+40);
B ^= F(A ^ key_sigma[2]);
A ^= F(B ^ key_sigma[3]);
STORE64H(A, T+32); STORE64H(B, T+40);
/* grab KA */
for (x = 0; x < 16; x++) { kA[x] = T[x+32]; }
/* xor kR in */
for (x = 0; x < 16; x++) { T[x+32] ^= kR[x]; }
if (keylen == 16) {
/* grab whitening keys kw1 and kw2 */
LOAD64H(skey->camellia.kw[0], kL);
LOAD64H(skey->camellia.kw[1], kL+8);
/* k1-k2 */
LOAD64H(skey->camellia.k[0], kA);
LOAD64H(skey->camellia.k[1], kA+8);
/* rotate kL by 15, k3/k4 */
rot_128(kL, 15, T+32);
LOAD64H(skey->camellia.k[2], T+32);
LOAD64H(skey->camellia.k[3], T+40);
/* rotate kA by 15, k5/k6 */
rot_128(kA, 15, T+32);
LOAD64H(skey->camellia.k[4], T+32);
LOAD64H(skey->camellia.k[5], T+40);
/* rotate kA by 30, kl1, kl2 */
rot_128(kA, 30, T+32);
LOAD64H(skey->camellia.kl[0], T+32);
LOAD64H(skey->camellia.kl[1], T+40);
/* rotate kL by 45, k7/k8 */
rot_128(kL, 45, T+32);
LOAD64H(skey->camellia.k[6], T+32);
LOAD64H(skey->camellia.k[7], T+40);
/* rotate kA by 45, k9/k10 */
rot_128(kA, 45, T+32);
LOAD64H(skey->camellia.k[8], T+32);
rot_128(kL, 60, T+32);
LOAD64H(skey->camellia.k[9], T+40);
/* rotate kA by 60, k11/k12 */
rot_128(kA, 60, T+32);
LOAD64H(skey->camellia.k[10], T+32);
LOAD64H(skey->camellia.k[11], T+40);
/* rotate kL by 77, kl3, kl4 */
rot_128(kL, 77, T+32);
LOAD64H(skey->camellia.kl[2], T+32);
LOAD64H(skey->camellia.kl[3], T+40);
/* rotate kL by 94, k13/k14 */
rot_128(kL, 94, T+32);
LOAD64H(skey->camellia.k[12], T+32);
LOAD64H(skey->camellia.k[13], T+40);
/* rotate kA by 94, k15/k16 */
rot_128(kA, 94, T+32);
LOAD64H(skey->camellia.k[14], T+32);
LOAD64H(skey->camellia.k[15], T+40);
/* rotate kL by 111, k17/k18 */
rot_128(kL, 111, T+32);
LOAD64H(skey->camellia.k[16], T+32);
LOAD64H(skey->camellia.k[17], T+40);
/* rotate kA by 111, kw3/kw4 */
rot_128(kA, 111, T+32);
LOAD64H(skey->camellia.kw[2], T+32);
LOAD64H(skey->camellia.kw[3], T+40);
} else {
/* last two rounds */
LOAD64H(A, T+32); LOAD64H(B, T+40);
B ^= F(A ^ key_sigma[4]);
A ^= F(B ^ key_sigma[5]);
STORE64H(A, T+32); STORE64H(B, T+40);
/* grab kB */
for (x = 0; x < 16; x++) { kB[x] = T[x+32]; }
/* kw1/2 from kL*/
LOAD64H(skey->camellia.kw[0], kL);
LOAD64H(skey->camellia.kw[1], kL+8);
/* k1/k2 = kB */
LOAD64H(skey->camellia.k[0], kB);
LOAD64H(skey->camellia.k[1], kB+8);
/* k3/k4 = kR by 15 */
rot_128(kR, 15, T+32);
LOAD64H(skey->camellia.k[2], T+32);
LOAD64H(skey->camellia.k[3], T+40);
/* k5/k7 = kA by 15 */
rot_128(kA, 15, T+32);
LOAD64H(skey->camellia.k[4], T+32);
LOAD64H(skey->camellia.k[5], T+40);
/* kl1/2 = kR by 30 */
rot_128(kR, 30, T+32);
LOAD64H(skey->camellia.kl[0], T+32);
LOAD64H(skey->camellia.kl[1], T+40);
/* k7/k8 = kB by 30 */
rot_128(kB, 30, T+32);
LOAD64H(skey->camellia.k[6], T+32);
LOAD64H(skey->camellia.k[7], T+40);
/* k9/k10 = kL by 45 */
rot_128(kL, 45, T+32);
LOAD64H(skey->camellia.k[8], T+32);
LOAD64H(skey->camellia.k[9], T+40);
/* k11/k12 = kA by 45 */
rot_128(kA, 45, T+32);
LOAD64H(skey->camellia.k[10], T+32);
LOAD64H(skey->camellia.k[11], T+40);
/* kl3/4 = kL by 60 */
rot_128(kL, 60, T+32);
LOAD64H(skey->camellia.kl[2], T+32);
LOAD64H(skey->camellia.kl[3], T+40);
/* k13/k14 = kR by 60 */
rot_128(kR, 60, T+32);
LOAD64H(skey->camellia.k[12], T+32);
LOAD64H(skey->camellia.k[13], T+40);
/* k15/k16 = kB by 15 */
rot_128(kB, 60, T+32);
LOAD64H(skey->camellia.k[14], T+32);
LOAD64H(skey->camellia.k[15], T+40);
/* k17/k18 = kL by 77 */
rot_128(kL, 77, T+32);
LOAD64H(skey->camellia.k[16], T+32);
LOAD64H(skey->camellia.k[17], T+40);
/* kl5/6 = kA by 77 */
rot_128(kA, 77, T+32);
LOAD64H(skey->camellia.kl[4], T+32);
LOAD64H(skey->camellia.kl[5], T+40);
/* k19/k20 = kR by 94 */
rot_128(kR, 94, T+32);
LOAD64H(skey->camellia.k[18], T+32);
LOAD64H(skey->camellia.k[19], T+40);
/* k21/k22 = kA by 94 */
rot_128(kA, 94, T+32);
LOAD64H(skey->camellia.k[20], T+32);
LOAD64H(skey->camellia.k[21], T+40);
/* k23/k24 = kL by 111 */
rot_128(kL, 111, T+32);
LOAD64H(skey->camellia.k[22], T+32);
LOAD64H(skey->camellia.k[23], T+40);
/* kw2/kw3 = kB by 111 */
rot_128(kB, 111, T+32);
LOAD64H(skey->camellia.kw[2], T+32);
LOAD64H(skey->camellia.kw[3], T+40);
}
return CRYPT_OK;
}
int camellia_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
ulong64 L, R;
ulong32 a, b;
LOAD64H(L, pt+0); LOAD64H(R, pt+8);
L ^= skey->camellia.kw[0];
R ^= skey->camellia.kw[1];
/* first 6 rounds */
R ^= F(L ^ skey->camellia.k[0]);
L ^= F(R ^ skey->camellia.k[1]);
R ^= F(L ^ skey->camellia.k[2]);
L ^= F(R ^ skey->camellia.k[3]);
R ^= F(L ^ skey->camellia.k[4]);
L ^= F(R ^ skey->camellia.k[5]);
/* FL */
a = (ulong32)(L >> 32);
b = (ulong32)(L & 0xFFFFFFFFUL);
b ^= ROL((a & (ulong32)(skey->camellia.kl[0] >> 32)), 1);
a ^= b | (skey->camellia.kl[0] & 0xFFFFFFFFU);
L = (((ulong64)a) << 32) | b;
/* FL^-1 */
a = (ulong32)(R >> 32);
b = (ulong32)(R & 0xFFFFFFFFUL);
a ^= b | (skey->camellia.kl[1] & 0xFFFFFFFFU);
b ^= ROL((a & (ulong32)(skey->camellia.kl[1] >> 32)), 1);
R = (((ulong64)a) << 32) | b;
/* second 6 rounds */
R ^= F(L ^ skey->camellia.k[6]);
L ^= F(R ^ skey->camellia.k[7]);
R ^= F(L ^ skey->camellia.k[8]);
L ^= F(R ^ skey->camellia.k[9]);
R ^= F(L ^ skey->camellia.k[10]);
L ^= F(R ^ skey->camellia.k[11]);
/* FL */
a = (ulong32)(L >> 32);
b = (ulong32)(L & 0xFFFFFFFFUL);
b ^= ROL((a & (ulong32)(skey->camellia.kl[2] >> 32)), 1);
a ^= b | (skey->camellia.kl[2] & 0xFFFFFFFFU);
L = (((ulong64)a) << 32) | b;
/* FL^-1 */
a = (ulong32)(R >> 32);
b = (ulong32)(R & 0xFFFFFFFFUL);
a ^= b | (skey->camellia.kl[3] & 0xFFFFFFFFU);
b ^= ROL((a & (ulong32)(skey->camellia.kl[3] >> 32)), 1);
R = (((ulong64)a) << 32) | b;
/* third 6 rounds */
R ^= F(L ^ skey->camellia.k[12]);
L ^= F(R ^ skey->camellia.k[13]);
R ^= F(L ^ skey->camellia.k[14]);
L ^= F(R ^ skey->camellia.k[15]);
R ^= F(L ^ skey->camellia.k[16]);
L ^= F(R ^ skey->camellia.k[17]);
/* next FL */
if (skey->camellia.R == 24) {
/* FL */
a = (ulong32)(L >> 32);
b = (ulong32)(L & 0xFFFFFFFFUL);
b ^= ROL((a & (ulong32)(skey->camellia.kl[4] >> 32)), 1);
a ^= b | (skey->camellia.kl[4] & 0xFFFFFFFFU);
L = (((ulong64)a) << 32) | b;
/* FL^-1 */
a = (ulong32)(R >> 32);
b = (ulong32)(R & 0xFFFFFFFFUL);
a ^= b | (skey->camellia.kl[5] & 0xFFFFFFFFU);
b ^= ROL((a & (ulong32)(skey->camellia.kl[5] >> 32)), 1);
R = (((ulong64)a) << 32) | b;
/* fourth 6 rounds */
R ^= F(L ^ skey->camellia.k[18]);
L ^= F(R ^ skey->camellia.k[19]);
R ^= F(L ^ skey->camellia.k[20]);
L ^= F(R ^ skey->camellia.k[21]);
R ^= F(L ^ skey->camellia.k[22]);
L ^= F(R ^ skey->camellia.k[23]);
}
L ^= skey->camellia.kw[3];
R ^= skey->camellia.kw[2];
STORE64H(R, ct+0); STORE64H(L, ct+8);
return CRYPT_OK;
}
int camellia_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
ulong64 L, R;
ulong32 a, b;
LOAD64H(R, ct+0); LOAD64H(L, ct+8);
L ^= skey->camellia.kw[3];
R ^= skey->camellia.kw[2];
/* next FL */
if (skey->camellia.R == 24) {
/* fourth 6 rounds */
L ^= F(R ^ skey->camellia.k[23]);
R ^= F(L ^ skey->camellia.k[22]);
L ^= F(R ^ skey->camellia.k[21]);
R ^= F(L ^ skey->camellia.k[20]);
L ^= F(R ^ skey->camellia.k[19]);
R ^= F(L ^ skey->camellia.k[18]);
/* FL */
a = (ulong32)(L >> 32);
b = (ulong32)(L & 0xFFFFFFFFUL);
a ^= b | (skey->camellia.kl[4] & 0xFFFFFFFFU);
b ^= ROL((a & (ulong32)(skey->camellia.kl[4] >> 32)), 1);
L = (((ulong64)a) << 32) | b;
/* FL^-1 */
a = (ulong32)(R >> 32);
b = (ulong32)(R & 0xFFFFFFFFUL);
b ^= ROL((a & (ulong32)(skey->camellia.kl[5] >> 32)), 1);
a ^= b | (skey->camellia.kl[5] & 0xFFFFFFFFU);
R = (((ulong64)a) << 32) | b;
}
/* third 6 rounds */
L ^= F(R ^ skey->camellia.k[17]);
R ^= F(L ^ skey->camellia.k[16]);
L ^= F(R ^ skey->camellia.k[15]);
R ^= F(L ^ skey->camellia.k[14]);
L ^= F(R ^ skey->camellia.k[13]);
R ^= F(L ^ skey->camellia.k[12]);
/* FL */
a = (ulong32)(L >> 32);
b = (ulong32)(L & 0xFFFFFFFFUL);
a ^= b | (skey->camellia.kl[2] & 0xFFFFFFFFU);
b ^= ROL((a & (ulong32)(skey->camellia.kl[2] >> 32)), 1);
L = (((ulong64)a) << 32) | b;
/* FL^-1 */
a = (ulong32)(R >> 32);
b = (ulong32)(R & 0xFFFFFFFFUL);
b ^= ROL((a & (ulong32)(skey->camellia.kl[3] >> 32)), 1);
a ^= b | (skey->camellia.kl[3] & 0xFFFFFFFFU);
R = (((ulong64)a) << 32) | b;
/* second 6 rounds */
L ^= F(R ^ skey->camellia.k[11]);
R ^= F(L ^ skey->camellia.k[10]);
L ^= F(R ^ skey->camellia.k[9]);
R ^= F(L ^ skey->camellia.k[8]);
L ^= F(R ^ skey->camellia.k[7]);
R ^= F(L ^ skey->camellia.k[6]);
/* FL */
a = (ulong32)(L >> 32);
b = (ulong32)(L & 0xFFFFFFFFUL);
a ^= b | (skey->camellia.kl[0] & 0xFFFFFFFFU);
b ^= ROL((a & (ulong32)(skey->camellia.kl[0] >> 32)), 1);
L = (((ulong64)a) << 32) | b;
/* FL^-1 */
a = (ulong32)(R >> 32);
b = (ulong32)(R & 0xFFFFFFFFUL);
b ^= ROL((a & (ulong32)(skey->camellia.kl[1] >> 32)), 1);
a ^= b | (skey->camellia.kl[1] & 0xFFFFFFFFU);
R = (((ulong64)a) << 32) | b;
/* first 6 rounds */
L ^= F(R ^ skey->camellia.k[5]);
R ^= F(L ^ skey->camellia.k[4]);
L ^= F(R ^ skey->camellia.k[3]);
R ^= F(L ^ skey->camellia.k[2]);
L ^= F(R ^ skey->camellia.k[1]);
R ^= F(L ^ skey->camellia.k[0]);
R ^= skey->camellia.kw[1];
L ^= skey->camellia.kw[0];
STORE64H(R, pt+8); STORE64H(L, pt+0);
return CRYPT_OK;
}
int camellia_test(void)
{
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
} tests[] = {
{
16,
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
{ 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73,
0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 }
},
{
24,
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 },
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
{ 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8,
0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 }
},
{
32,
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 },
{ 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c,
0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 }
},
{
32,
{ 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 },
{ 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 },
{ 0x79, 0x60, 0x10, 0x9F, 0xB6, 0xDC, 0x42, 0x94,
0x7F, 0xCF, 0xE5, 0x9E, 0xA3, 0xC5, 0xEB, 0x6B }
}
};
unsigned char buf[2][16];
symmetric_key skey;
int err;
unsigned int x;
for (x = 0; x < sizeof(tests)/sizeof(tests[0]); x++) {
zeromem(&skey, sizeof(skey));
if ((err = camellia_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) {
return err;
}
if ((err = camellia_ecb_encrypt(tests[x].pt, buf[0], &skey)) != CRYPT_OK) {
camellia_done(&skey);
return err;
}
if ((err = camellia_ecb_decrypt(tests[x].ct, buf[1], &skey)) != CRYPT_OK) {
camellia_done(&skey);
return err;
}
camellia_done(&skey);
if (compare_testvector(tests[x].ct, 16, buf[0], 16, "Camellia Encrypt", x) ||
compare_testvector(tests[x].pt, 16, buf[1], 16, "Camellia Decrypt", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
}
void camellia_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
int camellia_keysize(int *keysize)
{
if (*keysize >= 32) { *keysize = 32; }
else if (*keysize >= 24) { *keysize = 24; }
else if (*keysize >= 16) { *keysize = 16; }
else return CRYPT_INVALID_KEYSIZE;
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

720
thirdparty/libtomcrypt/ciphers/cast5.c vendored Normal file
View File

@@ -0,0 +1,720 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file cast5.c
Implementation of LTC_CAST5 (RFC 2144) by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_CAST5
const struct ltc_cipher_descriptor cast5_desc = {
"cast5",
15,
5, 16, 8, 16,
&cast5_setup,
&cast5_ecb_encrypt,
&cast5_ecb_decrypt,
&cast5_test,
&cast5_done,
&cast5_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static const ulong32 S1[256] = {
0x30fb40d4UL, 0x9fa0ff0bUL, 0x6beccd2fUL, 0x3f258c7aUL, 0x1e213f2fUL, 0x9c004dd3UL,
0x6003e540UL, 0xcf9fc949UL, 0xbfd4af27UL, 0x88bbbdb5UL, 0xe2034090UL, 0x98d09675UL,
0x6e63a0e0UL, 0x15c361d2UL, 0xc2e7661dUL, 0x22d4ff8eUL, 0x28683b6fUL, 0xc07fd059UL,
0xff2379c8UL, 0x775f50e2UL, 0x43c340d3UL, 0xdf2f8656UL, 0x887ca41aUL, 0xa2d2bd2dUL,
0xa1c9e0d6UL, 0x346c4819UL, 0x61b76d87UL, 0x22540f2fUL, 0x2abe32e1UL, 0xaa54166bUL,
0x22568e3aUL, 0xa2d341d0UL, 0x66db40c8UL, 0xa784392fUL, 0x004dff2fUL, 0x2db9d2deUL,
0x97943facUL, 0x4a97c1d8UL, 0x527644b7UL, 0xb5f437a7UL, 0xb82cbaefUL, 0xd751d159UL,
0x6ff7f0edUL, 0x5a097a1fUL, 0x827b68d0UL, 0x90ecf52eUL, 0x22b0c054UL, 0xbc8e5935UL,
0x4b6d2f7fUL, 0x50bb64a2UL, 0xd2664910UL, 0xbee5812dUL, 0xb7332290UL, 0xe93b159fUL,
0xb48ee411UL, 0x4bff345dUL, 0xfd45c240UL, 0xad31973fUL, 0xc4f6d02eUL, 0x55fc8165UL,
0xd5b1caadUL, 0xa1ac2daeUL, 0xa2d4b76dUL, 0xc19b0c50UL, 0x882240f2UL, 0x0c6e4f38UL,
0xa4e4bfd7UL, 0x4f5ba272UL, 0x564c1d2fUL, 0xc59c5319UL, 0xb949e354UL, 0xb04669feUL,
0xb1b6ab8aUL, 0xc71358ddUL, 0x6385c545UL, 0x110f935dUL, 0x57538ad5UL, 0x6a390493UL,
0xe63d37e0UL, 0x2a54f6b3UL, 0x3a787d5fUL, 0x6276a0b5UL, 0x19a6fcdfUL, 0x7a42206aUL,
0x29f9d4d5UL, 0xf61b1891UL, 0xbb72275eUL, 0xaa508167UL, 0x38901091UL, 0xc6b505ebUL,
0x84c7cb8cUL, 0x2ad75a0fUL, 0x874a1427UL, 0xa2d1936bUL, 0x2ad286afUL, 0xaa56d291UL,
0xd7894360UL, 0x425c750dUL, 0x93b39e26UL, 0x187184c9UL, 0x6c00b32dUL, 0x73e2bb14UL,
0xa0bebc3cUL, 0x54623779UL, 0x64459eabUL, 0x3f328b82UL, 0x7718cf82UL, 0x59a2cea6UL,
0x04ee002eUL, 0x89fe78e6UL, 0x3fab0950UL, 0x325ff6c2UL, 0x81383f05UL, 0x6963c5c8UL,
0x76cb5ad6UL, 0xd49974c9UL, 0xca180dcfUL, 0x380782d5UL, 0xc7fa5cf6UL, 0x8ac31511UL,
0x35e79e13UL, 0x47da91d0UL, 0xf40f9086UL, 0xa7e2419eUL, 0x31366241UL, 0x051ef495UL,
0xaa573b04UL, 0x4a805d8dUL, 0x548300d0UL, 0x00322a3cUL, 0xbf64cddfUL, 0xba57a68eUL,
0x75c6372bUL, 0x50afd341UL, 0xa7c13275UL, 0x915a0bf5UL, 0x6b54bfabUL, 0x2b0b1426UL,
0xab4cc9d7UL, 0x449ccd82UL, 0xf7fbf265UL, 0xab85c5f3UL, 0x1b55db94UL, 0xaad4e324UL,
0xcfa4bd3fUL, 0x2deaa3e2UL, 0x9e204d02UL, 0xc8bd25acUL, 0xeadf55b3UL, 0xd5bd9e98UL,
0xe31231b2UL, 0x2ad5ad6cUL, 0x954329deUL, 0xadbe4528UL, 0xd8710f69UL, 0xaa51c90fUL,
0xaa786bf6UL, 0x22513f1eUL, 0xaa51a79bUL, 0x2ad344ccUL, 0x7b5a41f0UL, 0xd37cfbadUL,
0x1b069505UL, 0x41ece491UL, 0xb4c332e6UL, 0x032268d4UL, 0xc9600accUL, 0xce387e6dUL,
0xbf6bb16cUL, 0x6a70fb78UL, 0x0d03d9c9UL, 0xd4df39deUL, 0xe01063daUL, 0x4736f464UL,
0x5ad328d8UL, 0xb347cc96UL, 0x75bb0fc3UL, 0x98511bfbUL, 0x4ffbcc35UL, 0xb58bcf6aUL,
0xe11f0abcUL, 0xbfc5fe4aUL, 0xa70aec10UL, 0xac39570aUL, 0x3f04442fUL, 0x6188b153UL,
0xe0397a2eUL, 0x5727cb79UL, 0x9ceb418fUL, 0x1cacd68dUL, 0x2ad37c96UL, 0x0175cb9dUL,
0xc69dff09UL, 0xc75b65f0UL, 0xd9db40d8UL, 0xec0e7779UL, 0x4744ead4UL, 0xb11c3274UL,
0xdd24cb9eUL, 0x7e1c54bdUL, 0xf01144f9UL, 0xd2240eb1UL, 0x9675b3fdUL, 0xa3ac3755UL,
0xd47c27afUL, 0x51c85f4dUL, 0x56907596UL, 0xa5bb15e6UL, 0x580304f0UL, 0xca042cf1UL,
0x011a37eaUL, 0x8dbfaadbUL, 0x35ba3e4aUL, 0x3526ffa0UL, 0xc37b4d09UL, 0xbc306ed9UL,
0x98a52666UL, 0x5648f725UL, 0xff5e569dUL, 0x0ced63d0UL, 0x7c63b2cfUL, 0x700b45e1UL,
0xd5ea50f1UL, 0x85a92872UL, 0xaf1fbda7UL, 0xd4234870UL, 0xa7870bf3UL, 0x2d3b4d79UL,
0x42e04198UL, 0x0cd0ede7UL, 0x26470db8UL, 0xf881814cUL, 0x474d6ad7UL, 0x7c0c5e5cUL,
0xd1231959UL, 0x381b7298UL, 0xf5d2f4dbUL, 0xab838653UL, 0x6e2f1e23UL, 0x83719c9eUL,
0xbd91e046UL, 0x9a56456eUL, 0xdc39200cUL, 0x20c8c571UL, 0x962bda1cUL, 0xe1e696ffUL,
0xb141ab08UL, 0x7cca89b9UL, 0x1a69e783UL, 0x02cc4843UL, 0xa2f7c579UL, 0x429ef47dUL,
0x427b169cUL, 0x5ac9f049UL, 0xdd8f0f00UL, 0x5c8165bfUL};
static const ulong32 S2[256] = {
0x1f201094UL, 0xef0ba75bUL, 0x69e3cf7eUL, 0x393f4380UL, 0xfe61cf7aUL, 0xeec5207aUL,
0x55889c94UL, 0x72fc0651UL, 0xada7ef79UL, 0x4e1d7235UL, 0xd55a63ceUL, 0xde0436baUL,
0x99c430efUL, 0x5f0c0794UL, 0x18dcdb7dUL, 0xa1d6eff3UL, 0xa0b52f7bUL, 0x59e83605UL,
0xee15b094UL, 0xe9ffd909UL, 0xdc440086UL, 0xef944459UL, 0xba83ccb3UL, 0xe0c3cdfbUL,
0xd1da4181UL, 0x3b092ab1UL, 0xf997f1c1UL, 0xa5e6cf7bUL, 0x01420ddbUL, 0xe4e7ef5bUL,
0x25a1ff41UL, 0xe180f806UL, 0x1fc41080UL, 0x179bee7aUL, 0xd37ac6a9UL, 0xfe5830a4UL,
0x98de8b7fUL, 0x77e83f4eUL, 0x79929269UL, 0x24fa9f7bUL, 0xe113c85bUL, 0xacc40083UL,
0xd7503525UL, 0xf7ea615fUL, 0x62143154UL, 0x0d554b63UL, 0x5d681121UL, 0xc866c359UL,
0x3d63cf73UL, 0xcee234c0UL, 0xd4d87e87UL, 0x5c672b21UL, 0x071f6181UL, 0x39f7627fUL,
0x361e3084UL, 0xe4eb573bUL, 0x602f64a4UL, 0xd63acd9cUL, 0x1bbc4635UL, 0x9e81032dUL,
0x2701f50cUL, 0x99847ab4UL, 0xa0e3df79UL, 0xba6cf38cUL, 0x10843094UL, 0x2537a95eUL,
0xf46f6ffeUL, 0xa1ff3b1fUL, 0x208cfb6aUL, 0x8f458c74UL, 0xd9e0a227UL, 0x4ec73a34UL,
0xfc884f69UL, 0x3e4de8dfUL, 0xef0e0088UL, 0x3559648dUL, 0x8a45388cUL, 0x1d804366UL,
0x721d9bfdUL, 0xa58684bbUL, 0xe8256333UL, 0x844e8212UL, 0x128d8098UL, 0xfed33fb4UL,
0xce280ae1UL, 0x27e19ba5UL, 0xd5a6c252UL, 0xe49754bdUL, 0xc5d655ddUL, 0xeb667064UL,
0x77840b4dUL, 0xa1b6a801UL, 0x84db26a9UL, 0xe0b56714UL, 0x21f043b7UL, 0xe5d05860UL,
0x54f03084UL, 0x066ff472UL, 0xa31aa153UL, 0xdadc4755UL, 0xb5625dbfUL, 0x68561be6UL,
0x83ca6b94UL, 0x2d6ed23bUL, 0xeccf01dbUL, 0xa6d3d0baUL, 0xb6803d5cUL, 0xaf77a709UL,
0x33b4a34cUL, 0x397bc8d6UL, 0x5ee22b95UL, 0x5f0e5304UL, 0x81ed6f61UL, 0x20e74364UL,
0xb45e1378UL, 0xde18639bUL, 0x881ca122UL, 0xb96726d1UL, 0x8049a7e8UL, 0x22b7da7bUL,
0x5e552d25UL, 0x5272d237UL, 0x79d2951cUL, 0xc60d894cUL, 0x488cb402UL, 0x1ba4fe5bUL,
0xa4b09f6bUL, 0x1ca815cfUL, 0xa20c3005UL, 0x8871df63UL, 0xb9de2fcbUL, 0x0cc6c9e9UL,
0x0beeff53UL, 0xe3214517UL, 0xb4542835UL, 0x9f63293cUL, 0xee41e729UL, 0x6e1d2d7cUL,
0x50045286UL, 0x1e6685f3UL, 0xf33401c6UL, 0x30a22c95UL, 0x31a70850UL, 0x60930f13UL,
0x73f98417UL, 0xa1269859UL, 0xec645c44UL, 0x52c877a9UL, 0xcdff33a6UL, 0xa02b1741UL,
0x7cbad9a2UL, 0x2180036fUL, 0x50d99c08UL, 0xcb3f4861UL, 0xc26bd765UL, 0x64a3f6abUL,
0x80342676UL, 0x25a75e7bUL, 0xe4e6d1fcUL, 0x20c710e6UL, 0xcdf0b680UL, 0x17844d3bUL,
0x31eef84dUL, 0x7e0824e4UL, 0x2ccb49ebUL, 0x846a3baeUL, 0x8ff77888UL, 0xee5d60f6UL,
0x7af75673UL, 0x2fdd5cdbUL, 0xa11631c1UL, 0x30f66f43UL, 0xb3faec54UL, 0x157fd7faUL,
0xef8579ccUL, 0xd152de58UL, 0xdb2ffd5eUL, 0x8f32ce19UL, 0x306af97aUL, 0x02f03ef8UL,
0x99319ad5UL, 0xc242fa0fUL, 0xa7e3ebb0UL, 0xc68e4906UL, 0xb8da230cUL, 0x80823028UL,
0xdcdef3c8UL, 0xd35fb171UL, 0x088a1bc8UL, 0xbec0c560UL, 0x61a3c9e8UL, 0xbca8f54dUL,
0xc72feffaUL, 0x22822e99UL, 0x82c570b4UL, 0xd8d94e89UL, 0x8b1c34bcUL, 0x301e16e6UL,
0x273be979UL, 0xb0ffeaa6UL, 0x61d9b8c6UL, 0x00b24869UL, 0xb7ffce3fUL, 0x08dc283bUL,
0x43daf65aUL, 0xf7e19798UL, 0x7619b72fUL, 0x8f1c9ba4UL, 0xdc8637a0UL, 0x16a7d3b1UL,
0x9fc393b7UL, 0xa7136eebUL, 0xc6bcc63eUL, 0x1a513742UL, 0xef6828bcUL, 0x520365d6UL,
0x2d6a77abUL, 0x3527ed4bUL, 0x821fd216UL, 0x095c6e2eUL, 0xdb92f2fbUL, 0x5eea29cbUL,
0x145892f5UL, 0x91584f7fUL, 0x5483697bUL, 0x2667a8ccUL, 0x85196048UL, 0x8c4baceaUL,
0x833860d4UL, 0x0d23e0f9UL, 0x6c387e8aUL, 0x0ae6d249UL, 0xb284600cUL, 0xd835731dUL,
0xdcb1c647UL, 0xac4c56eaUL, 0x3ebd81b3UL, 0x230eabb0UL, 0x6438bc87UL, 0xf0b5b1faUL,
0x8f5ea2b3UL, 0xfc184642UL, 0x0a036b7aUL, 0x4fb089bdUL, 0x649da589UL, 0xa345415eUL,
0x5c038323UL, 0x3e5d3bb9UL, 0x43d79572UL, 0x7e6dd07cUL, 0x06dfdf1eUL, 0x6c6cc4efUL,
0x7160a539UL, 0x73bfbe70UL, 0x83877605UL, 0x4523ecf1UL};
static const ulong32 S3[256] = {
0x8defc240UL, 0x25fa5d9fUL, 0xeb903dbfUL, 0xe810c907UL, 0x47607fffUL, 0x369fe44bUL,
0x8c1fc644UL, 0xaececa90UL, 0xbeb1f9bfUL, 0xeefbcaeaUL, 0xe8cf1950UL, 0x51df07aeUL,
0x920e8806UL, 0xf0ad0548UL, 0xe13c8d83UL, 0x927010d5UL, 0x11107d9fUL, 0x07647db9UL,
0xb2e3e4d4UL, 0x3d4f285eUL, 0xb9afa820UL, 0xfade82e0UL, 0xa067268bUL, 0x8272792eUL,
0x553fb2c0UL, 0x489ae22bUL, 0xd4ef9794UL, 0x125e3fbcUL, 0x21fffceeUL, 0x825b1bfdUL,
0x9255c5edUL, 0x1257a240UL, 0x4e1a8302UL, 0xbae07fffUL, 0x528246e7UL, 0x8e57140eUL,
0x3373f7bfUL, 0x8c9f8188UL, 0xa6fc4ee8UL, 0xc982b5a5UL, 0xa8c01db7UL, 0x579fc264UL,
0x67094f31UL, 0xf2bd3f5fUL, 0x40fff7c1UL, 0x1fb78dfcUL, 0x8e6bd2c1UL, 0x437be59bUL,
0x99b03dbfUL, 0xb5dbc64bUL, 0x638dc0e6UL, 0x55819d99UL, 0xa197c81cUL, 0x4a012d6eUL,
0xc5884a28UL, 0xccc36f71UL, 0xb843c213UL, 0x6c0743f1UL, 0x8309893cUL, 0x0feddd5fUL,
0x2f7fe850UL, 0xd7c07f7eUL, 0x02507fbfUL, 0x5afb9a04UL, 0xa747d2d0UL, 0x1651192eUL,
0xaf70bf3eUL, 0x58c31380UL, 0x5f98302eUL, 0x727cc3c4UL, 0x0a0fb402UL, 0x0f7fef82UL,
0x8c96fdadUL, 0x5d2c2aaeUL, 0x8ee99a49UL, 0x50da88b8UL, 0x8427f4a0UL, 0x1eac5790UL,
0x796fb449UL, 0x8252dc15UL, 0xefbd7d9bUL, 0xa672597dUL, 0xada840d8UL, 0x45f54504UL,
0xfa5d7403UL, 0xe83ec305UL, 0x4f91751aUL, 0x925669c2UL, 0x23efe941UL, 0xa903f12eUL,
0x60270df2UL, 0x0276e4b6UL, 0x94fd6574UL, 0x927985b2UL, 0x8276dbcbUL, 0x02778176UL,
0xf8af918dUL, 0x4e48f79eUL, 0x8f616ddfUL, 0xe29d840eUL, 0x842f7d83UL, 0x340ce5c8UL,
0x96bbb682UL, 0x93b4b148UL, 0xef303cabUL, 0x984faf28UL, 0x779faf9bUL, 0x92dc560dUL,
0x224d1e20UL, 0x8437aa88UL, 0x7d29dc96UL, 0x2756d3dcUL, 0x8b907ceeUL, 0xb51fd240UL,
0xe7c07ce3UL, 0xe566b4a1UL, 0xc3e9615eUL, 0x3cf8209dUL, 0x6094d1e3UL, 0xcd9ca341UL,
0x5c76460eUL, 0x00ea983bUL, 0xd4d67881UL, 0xfd47572cUL, 0xf76cedd9UL, 0xbda8229cUL,
0x127dadaaUL, 0x438a074eUL, 0x1f97c090UL, 0x081bdb8aUL, 0x93a07ebeUL, 0xb938ca15UL,
0x97b03cffUL, 0x3dc2c0f8UL, 0x8d1ab2ecUL, 0x64380e51UL, 0x68cc7bfbUL, 0xd90f2788UL,
0x12490181UL, 0x5de5ffd4UL, 0xdd7ef86aUL, 0x76a2e214UL, 0xb9a40368UL, 0x925d958fUL,
0x4b39fffaUL, 0xba39aee9UL, 0xa4ffd30bUL, 0xfaf7933bUL, 0x6d498623UL, 0x193cbcfaUL,
0x27627545UL, 0x825cf47aUL, 0x61bd8ba0UL, 0xd11e42d1UL, 0xcead04f4UL, 0x127ea392UL,
0x10428db7UL, 0x8272a972UL, 0x9270c4a8UL, 0x127de50bUL, 0x285ba1c8UL, 0x3c62f44fUL,
0x35c0eaa5UL, 0xe805d231UL, 0x428929fbUL, 0xb4fcdf82UL, 0x4fb66a53UL, 0x0e7dc15bUL,
0x1f081fabUL, 0x108618aeUL, 0xfcfd086dUL, 0xf9ff2889UL, 0x694bcc11UL, 0x236a5caeUL,
0x12deca4dUL, 0x2c3f8cc5UL, 0xd2d02dfeUL, 0xf8ef5896UL, 0xe4cf52daUL, 0x95155b67UL,
0x494a488cUL, 0xb9b6a80cUL, 0x5c8f82bcUL, 0x89d36b45UL, 0x3a609437UL, 0xec00c9a9UL,
0x44715253UL, 0x0a874b49UL, 0xd773bc40UL, 0x7c34671cUL, 0x02717ef6UL, 0x4feb5536UL,
0xa2d02fffUL, 0xd2bf60c4UL, 0xd43f03c0UL, 0x50b4ef6dUL, 0x07478cd1UL, 0x006e1888UL,
0xa2e53f55UL, 0xb9e6d4bcUL, 0xa2048016UL, 0x97573833UL, 0xd7207d67UL, 0xde0f8f3dUL,
0x72f87b33UL, 0xabcc4f33UL, 0x7688c55dUL, 0x7b00a6b0UL, 0x947b0001UL, 0x570075d2UL,
0xf9bb88f8UL, 0x8942019eUL, 0x4264a5ffUL, 0x856302e0UL, 0x72dbd92bUL, 0xee971b69UL,
0x6ea22fdeUL, 0x5f08ae2bUL, 0xaf7a616dUL, 0xe5c98767UL, 0xcf1febd2UL, 0x61efc8c2UL,
0xf1ac2571UL, 0xcc8239c2UL, 0x67214cb8UL, 0xb1e583d1UL, 0xb7dc3e62UL, 0x7f10bdceUL,
0xf90a5c38UL, 0x0ff0443dUL, 0x606e6dc6UL, 0x60543a49UL, 0x5727c148UL, 0x2be98a1dUL,
0x8ab41738UL, 0x20e1be24UL, 0xaf96da0fUL, 0x68458425UL, 0x99833be5UL, 0x600d457dUL,
0x282f9350UL, 0x8334b362UL, 0xd91d1120UL, 0x2b6d8da0UL, 0x642b1e31UL, 0x9c305a00UL,
0x52bce688UL, 0x1b03588aUL, 0xf7baefd5UL, 0x4142ed9cUL, 0xa4315c11UL, 0x83323ec5UL,
0xdfef4636UL, 0xa133c501UL, 0xe9d3531cUL, 0xee353783UL};
static const ulong32 S4[256] = {
0x9db30420UL, 0x1fb6e9deUL, 0xa7be7befUL, 0xd273a298UL, 0x4a4f7bdbUL, 0x64ad8c57UL,
0x85510443UL, 0xfa020ed1UL, 0x7e287affUL, 0xe60fb663UL, 0x095f35a1UL, 0x79ebf120UL,
0xfd059d43UL, 0x6497b7b1UL, 0xf3641f63UL, 0x241e4adfUL, 0x28147f5fUL, 0x4fa2b8cdUL,
0xc9430040UL, 0x0cc32220UL, 0xfdd30b30UL, 0xc0a5374fUL, 0x1d2d00d9UL, 0x24147b15UL,
0xee4d111aUL, 0x0fca5167UL, 0x71ff904cUL, 0x2d195ffeUL, 0x1a05645fUL, 0x0c13fefeUL,
0x081b08caUL, 0x05170121UL, 0x80530100UL, 0xe83e5efeUL, 0xac9af4f8UL, 0x7fe72701UL,
0xd2b8ee5fUL, 0x06df4261UL, 0xbb9e9b8aUL, 0x7293ea25UL, 0xce84ffdfUL, 0xf5718801UL,
0x3dd64b04UL, 0xa26f263bUL, 0x7ed48400UL, 0x547eebe6UL, 0x446d4ca0UL, 0x6cf3d6f5UL,
0x2649abdfUL, 0xaea0c7f5UL, 0x36338cc1UL, 0x503f7e93UL, 0xd3772061UL, 0x11b638e1UL,
0x72500e03UL, 0xf80eb2bbUL, 0xabe0502eUL, 0xec8d77deUL, 0x57971e81UL, 0xe14f6746UL,
0xc9335400UL, 0x6920318fUL, 0x081dbb99UL, 0xffc304a5UL, 0x4d351805UL, 0x7f3d5ce3UL,
0xa6c866c6UL, 0x5d5bcca9UL, 0xdaec6feaUL, 0x9f926f91UL, 0x9f46222fUL, 0x3991467dUL,
0xa5bf6d8eUL, 0x1143c44fUL, 0x43958302UL, 0xd0214eebUL, 0x022083b8UL, 0x3fb6180cUL,
0x18f8931eUL, 0x281658e6UL, 0x26486e3eUL, 0x8bd78a70UL, 0x7477e4c1UL, 0xb506e07cUL,
0xf32d0a25UL, 0x79098b02UL, 0xe4eabb81UL, 0x28123b23UL, 0x69dead38UL, 0x1574ca16UL,
0xdf871b62UL, 0x211c40b7UL, 0xa51a9ef9UL, 0x0014377bUL, 0x041e8ac8UL, 0x09114003UL,
0xbd59e4d2UL, 0xe3d156d5UL, 0x4fe876d5UL, 0x2f91a340UL, 0x557be8deUL, 0x00eae4a7UL,
0x0ce5c2ecUL, 0x4db4bba6UL, 0xe756bdffUL, 0xdd3369acUL, 0xec17b035UL, 0x06572327UL,
0x99afc8b0UL, 0x56c8c391UL, 0x6b65811cUL, 0x5e146119UL, 0x6e85cb75UL, 0xbe07c002UL,
0xc2325577UL, 0x893ff4ecUL, 0x5bbfc92dUL, 0xd0ec3b25UL, 0xb7801ab7UL, 0x8d6d3b24UL,
0x20c763efUL, 0xc366a5fcUL, 0x9c382880UL, 0x0ace3205UL, 0xaac9548aUL, 0xeca1d7c7UL,
0x041afa32UL, 0x1d16625aUL, 0x6701902cUL, 0x9b757a54UL, 0x31d477f7UL, 0x9126b031UL,
0x36cc6fdbUL, 0xc70b8b46UL, 0xd9e66a48UL, 0x56e55a79UL, 0x026a4cebUL, 0x52437effUL,
0x2f8f76b4UL, 0x0df980a5UL, 0x8674cde3UL, 0xedda04ebUL, 0x17a9be04UL, 0x2c18f4dfUL,
0xb7747f9dUL, 0xab2af7b4UL, 0xefc34d20UL, 0x2e096b7cUL, 0x1741a254UL, 0xe5b6a035UL,
0x213d42f6UL, 0x2c1c7c26UL, 0x61c2f50fUL, 0x6552daf9UL, 0xd2c231f8UL, 0x25130f69UL,
0xd8167fa2UL, 0x0418f2c8UL, 0x001a96a6UL, 0x0d1526abUL, 0x63315c21UL, 0x5e0a72ecUL,
0x49bafefdUL, 0x187908d9UL, 0x8d0dbd86UL, 0x311170a7UL, 0x3e9b640cUL, 0xcc3e10d7UL,
0xd5cad3b6UL, 0x0caec388UL, 0xf73001e1UL, 0x6c728affUL, 0x71eae2a1UL, 0x1f9af36eUL,
0xcfcbd12fUL, 0xc1de8417UL, 0xac07be6bUL, 0xcb44a1d8UL, 0x8b9b0f56UL, 0x013988c3UL,
0xb1c52fcaUL, 0xb4be31cdUL, 0xd8782806UL, 0x12a3a4e2UL, 0x6f7de532UL, 0x58fd7eb6UL,
0xd01ee900UL, 0x24adffc2UL, 0xf4990fc5UL, 0x9711aac5UL, 0x001d7b95UL, 0x82e5e7d2UL,
0x109873f6UL, 0x00613096UL, 0xc32d9521UL, 0xada121ffUL, 0x29908415UL, 0x7fbb977fUL,
0xaf9eb3dbUL, 0x29c9ed2aUL, 0x5ce2a465UL, 0xa730f32cUL, 0xd0aa3fe8UL, 0x8a5cc091UL,
0xd49e2ce7UL, 0x0ce454a9UL, 0xd60acd86UL, 0x015f1919UL, 0x77079103UL, 0xdea03af6UL,
0x78a8565eUL, 0xdee356dfUL, 0x21f05cbeUL, 0x8b75e387UL, 0xb3c50651UL, 0xb8a5c3efUL,
0xd8eeb6d2UL, 0xe523be77UL, 0xc2154529UL, 0x2f69efdfUL, 0xafe67afbUL, 0xf470c4b2UL,
0xf3e0eb5bUL, 0xd6cc9876UL, 0x39e4460cUL, 0x1fda8538UL, 0x1987832fUL, 0xca007367UL,
0xa99144f8UL, 0x296b299eUL, 0x492fc295UL, 0x9266beabUL, 0xb5676e69UL, 0x9bd3dddaUL,
0xdf7e052fUL, 0xdb25701cUL, 0x1b5e51eeUL, 0xf65324e6UL, 0x6afce36cUL, 0x0316cc04UL,
0x8644213eUL, 0xb7dc59d0UL, 0x7965291fUL, 0xccd6fd43UL, 0x41823979UL, 0x932bcdf6UL,
0xb657c34dUL, 0x4edfd282UL, 0x7ae5290cUL, 0x3cb9536bUL, 0x851e20feUL, 0x9833557eUL,
0x13ecf0b0UL, 0xd3ffb372UL, 0x3f85c5c1UL, 0x0aef7ed2UL};
static const ulong32 S5[256] = {
0x7ec90c04UL, 0x2c6e74b9UL, 0x9b0e66dfUL, 0xa6337911UL, 0xb86a7fffUL, 0x1dd358f5UL,
0x44dd9d44UL, 0x1731167fUL, 0x08fbf1faUL, 0xe7f511ccUL, 0xd2051b00UL, 0x735aba00UL,
0x2ab722d8UL, 0x386381cbUL, 0xacf6243aUL, 0x69befd7aUL, 0xe6a2e77fUL, 0xf0c720cdUL,
0xc4494816UL, 0xccf5c180UL, 0x38851640UL, 0x15b0a848UL, 0xe68b18cbUL, 0x4caadeffUL,
0x5f480a01UL, 0x0412b2aaUL, 0x259814fcUL, 0x41d0efe2UL, 0x4e40b48dUL, 0x248eb6fbUL,
0x8dba1cfeUL, 0x41a99b02UL, 0x1a550a04UL, 0xba8f65cbUL, 0x7251f4e7UL, 0x95a51725UL,
0xc106ecd7UL, 0x97a5980aUL, 0xc539b9aaUL, 0x4d79fe6aUL, 0xf2f3f763UL, 0x68af8040UL,
0xed0c9e56UL, 0x11b4958bUL, 0xe1eb5a88UL, 0x8709e6b0UL, 0xd7e07156UL, 0x4e29fea7UL,
0x6366e52dUL, 0x02d1c000UL, 0xc4ac8e05UL, 0x9377f571UL, 0x0c05372aUL, 0x578535f2UL,
0x2261be02UL, 0xd642a0c9UL, 0xdf13a280UL, 0x74b55bd2UL, 0x682199c0UL, 0xd421e5ecUL,
0x53fb3ce8UL, 0xc8adedb3UL, 0x28a87fc9UL, 0x3d959981UL, 0x5c1ff900UL, 0xfe38d399UL,
0x0c4eff0bUL, 0x062407eaUL, 0xaa2f4fb1UL, 0x4fb96976UL, 0x90c79505UL, 0xb0a8a774UL,
0xef55a1ffUL, 0xe59ca2c2UL, 0xa6b62d27UL, 0xe66a4263UL, 0xdf65001fUL, 0x0ec50966UL,
0xdfdd55bcUL, 0x29de0655UL, 0x911e739aUL, 0x17af8975UL, 0x32c7911cUL, 0x89f89468UL,
0x0d01e980UL, 0x524755f4UL, 0x03b63cc9UL, 0x0cc844b2UL, 0xbcf3f0aaUL, 0x87ac36e9UL,
0xe53a7426UL, 0x01b3d82bUL, 0x1a9e7449UL, 0x64ee2d7eUL, 0xcddbb1daUL, 0x01c94910UL,
0xb868bf80UL, 0x0d26f3fdUL, 0x9342ede7UL, 0x04a5c284UL, 0x636737b6UL, 0x50f5b616UL,
0xf24766e3UL, 0x8eca36c1UL, 0x136e05dbUL, 0xfef18391UL, 0xfb887a37UL, 0xd6e7f7d4UL,
0xc7fb7dc9UL, 0x3063fcdfUL, 0xb6f589deUL, 0xec2941daUL, 0x26e46695UL, 0xb7566419UL,
0xf654efc5UL, 0xd08d58b7UL, 0x48925401UL, 0xc1bacb7fUL, 0xe5ff550fUL, 0xb6083049UL,
0x5bb5d0e8UL, 0x87d72e5aUL, 0xab6a6ee1UL, 0x223a66ceUL, 0xc62bf3cdUL, 0x9e0885f9UL,
0x68cb3e47UL, 0x086c010fUL, 0xa21de820UL, 0xd18b69deUL, 0xf3f65777UL, 0xfa02c3f6UL,
0x407edac3UL, 0xcbb3d550UL, 0x1793084dUL, 0xb0d70ebaUL, 0x0ab378d5UL, 0xd951fb0cUL,
0xded7da56UL, 0x4124bbe4UL, 0x94ca0b56UL, 0x0f5755d1UL, 0xe0e1e56eUL, 0x6184b5beUL,
0x580a249fUL, 0x94f74bc0UL, 0xe327888eUL, 0x9f7b5561UL, 0xc3dc0280UL, 0x05687715UL,
0x646c6bd7UL, 0x44904db3UL, 0x66b4f0a3UL, 0xc0f1648aUL, 0x697ed5afUL, 0x49e92ff6UL,
0x309e374fUL, 0x2cb6356aUL, 0x85808573UL, 0x4991f840UL, 0x76f0ae02UL, 0x083be84dUL,
0x28421c9aUL, 0x44489406UL, 0x736e4cb8UL, 0xc1092910UL, 0x8bc95fc6UL, 0x7d869cf4UL,
0x134f616fUL, 0x2e77118dUL, 0xb31b2be1UL, 0xaa90b472UL, 0x3ca5d717UL, 0x7d161bbaUL,
0x9cad9010UL, 0xaf462ba2UL, 0x9fe459d2UL, 0x45d34559UL, 0xd9f2da13UL, 0xdbc65487UL,
0xf3e4f94eUL, 0x176d486fUL, 0x097c13eaUL, 0x631da5c7UL, 0x445f7382UL, 0x175683f4UL,
0xcdc66a97UL, 0x70be0288UL, 0xb3cdcf72UL, 0x6e5dd2f3UL, 0x20936079UL, 0x459b80a5UL,
0xbe60e2dbUL, 0xa9c23101UL, 0xeba5315cUL, 0x224e42f2UL, 0x1c5c1572UL, 0xf6721b2cUL,
0x1ad2fff3UL, 0x8c25404eUL, 0x324ed72fUL, 0x4067b7fdUL, 0x0523138eUL, 0x5ca3bc78UL,
0xdc0fd66eUL, 0x75922283UL, 0x784d6b17UL, 0x58ebb16eUL, 0x44094f85UL, 0x3f481d87UL,
0xfcfeae7bUL, 0x77b5ff76UL, 0x8c2302bfUL, 0xaaf47556UL, 0x5f46b02aUL, 0x2b092801UL,
0x3d38f5f7UL, 0x0ca81f36UL, 0x52af4a8aUL, 0x66d5e7c0UL, 0xdf3b0874UL, 0x95055110UL,
0x1b5ad7a8UL, 0xf61ed5adUL, 0x6cf6e479UL, 0x20758184UL, 0xd0cefa65UL, 0x88f7be58UL,
0x4a046826UL, 0x0ff6f8f3UL, 0xa09c7f70UL, 0x5346aba0UL, 0x5ce96c28UL, 0xe176eda3UL,
0x6bac307fUL, 0x376829d2UL, 0x85360fa9UL, 0x17e3fe2aUL, 0x24b79767UL, 0xf5a96b20UL,
0xd6cd2595UL, 0x68ff1ebfUL, 0x7555442cUL, 0xf19f06beUL, 0xf9e0659aUL, 0xeeb9491dUL,
0x34010718UL, 0xbb30cab8UL, 0xe822fe15UL, 0x88570983UL, 0x750e6249UL, 0xda627e55UL,
0x5e76ffa8UL, 0xb1534546UL, 0x6d47de08UL, 0xefe9e7d4UL};
static const ulong32 S6[256] = {
0xf6fa8f9dUL, 0x2cac6ce1UL, 0x4ca34867UL, 0xe2337f7cUL, 0x95db08e7UL, 0x016843b4UL,
0xeced5cbcUL, 0x325553acUL, 0xbf9f0960UL, 0xdfa1e2edUL, 0x83f0579dUL, 0x63ed86b9UL,
0x1ab6a6b8UL, 0xde5ebe39UL, 0xf38ff732UL, 0x8989b138UL, 0x33f14961UL, 0xc01937bdUL,
0xf506c6daUL, 0xe4625e7eUL, 0xa308ea99UL, 0x4e23e33cUL, 0x79cbd7ccUL, 0x48a14367UL,
0xa3149619UL, 0xfec94bd5UL, 0xa114174aUL, 0xeaa01866UL, 0xa084db2dUL, 0x09a8486fUL,
0xa888614aUL, 0x2900af98UL, 0x01665991UL, 0xe1992863UL, 0xc8f30c60UL, 0x2e78ef3cUL,
0xd0d51932UL, 0xcf0fec14UL, 0xf7ca07d2UL, 0xd0a82072UL, 0xfd41197eUL, 0x9305a6b0UL,
0xe86be3daUL, 0x74bed3cdUL, 0x372da53cUL, 0x4c7f4448UL, 0xdab5d440UL, 0x6dba0ec3UL,
0x083919a7UL, 0x9fbaeed9UL, 0x49dbcfb0UL, 0x4e670c53UL, 0x5c3d9c01UL, 0x64bdb941UL,
0x2c0e636aUL, 0xba7dd9cdUL, 0xea6f7388UL, 0xe70bc762UL, 0x35f29adbUL, 0x5c4cdd8dUL,
0xf0d48d8cUL, 0xb88153e2UL, 0x08a19866UL, 0x1ae2eac8UL, 0x284caf89UL, 0xaa928223UL,
0x9334be53UL, 0x3b3a21bfUL, 0x16434be3UL, 0x9aea3906UL, 0xefe8c36eUL, 0xf890cdd9UL,
0x80226daeUL, 0xc340a4a3UL, 0xdf7e9c09UL, 0xa694a807UL, 0x5b7c5eccUL, 0x221db3a6UL,
0x9a69a02fUL, 0x68818a54UL, 0xceb2296fUL, 0x53c0843aUL, 0xfe893655UL, 0x25bfe68aUL,
0xb4628abcUL, 0xcf222ebfUL, 0x25ac6f48UL, 0xa9a99387UL, 0x53bddb65UL, 0xe76ffbe7UL,
0xe967fd78UL, 0x0ba93563UL, 0x8e342bc1UL, 0xe8a11be9UL, 0x4980740dUL, 0xc8087dfcUL,
0x8de4bf99UL, 0xa11101a0UL, 0x7fd37975UL, 0xda5a26c0UL, 0xe81f994fUL, 0x9528cd89UL,
0xfd339fedUL, 0xb87834bfUL, 0x5f04456dUL, 0x22258698UL, 0xc9c4c83bUL, 0x2dc156beUL,
0x4f628daaUL, 0x57f55ec5UL, 0xe2220abeUL, 0xd2916ebfUL, 0x4ec75b95UL, 0x24f2c3c0UL,
0x42d15d99UL, 0xcd0d7fa0UL, 0x7b6e27ffUL, 0xa8dc8af0UL, 0x7345c106UL, 0xf41e232fUL,
0x35162386UL, 0xe6ea8926UL, 0x3333b094UL, 0x157ec6f2UL, 0x372b74afUL, 0x692573e4UL,
0xe9a9d848UL, 0xf3160289UL, 0x3a62ef1dUL, 0xa787e238UL, 0xf3a5f676UL, 0x74364853UL,
0x20951063UL, 0x4576698dUL, 0xb6fad407UL, 0x592af950UL, 0x36f73523UL, 0x4cfb6e87UL,
0x7da4cec0UL, 0x6c152daaUL, 0xcb0396a8UL, 0xc50dfe5dUL, 0xfcd707abUL, 0x0921c42fUL,
0x89dff0bbUL, 0x5fe2be78UL, 0x448f4f33UL, 0x754613c9UL, 0x2b05d08dUL, 0x48b9d585UL,
0xdc049441UL, 0xc8098f9bUL, 0x7dede786UL, 0xc39a3373UL, 0x42410005UL, 0x6a091751UL,
0x0ef3c8a6UL, 0x890072d6UL, 0x28207682UL, 0xa9a9f7beUL, 0xbf32679dUL, 0xd45b5b75UL,
0xb353fd00UL, 0xcbb0e358UL, 0x830f220aUL, 0x1f8fb214UL, 0xd372cf08UL, 0xcc3c4a13UL,
0x8cf63166UL, 0x061c87beUL, 0x88c98f88UL, 0x6062e397UL, 0x47cf8e7aUL, 0xb6c85283UL,
0x3cc2acfbUL, 0x3fc06976UL, 0x4e8f0252UL, 0x64d8314dUL, 0xda3870e3UL, 0x1e665459UL,
0xc10908f0UL, 0x513021a5UL, 0x6c5b68b7UL, 0x822f8aa0UL, 0x3007cd3eUL, 0x74719eefUL,
0xdc872681UL, 0x073340d4UL, 0x7e432fd9UL, 0x0c5ec241UL, 0x8809286cUL, 0xf592d891UL,
0x08a930f6UL, 0x957ef305UL, 0xb7fbffbdUL, 0xc266e96fUL, 0x6fe4ac98UL, 0xb173ecc0UL,
0xbc60b42aUL, 0x953498daUL, 0xfba1ae12UL, 0x2d4bd736UL, 0x0f25faabUL, 0xa4f3fcebUL,
0xe2969123UL, 0x257f0c3dUL, 0x9348af49UL, 0x361400bcUL, 0xe8816f4aUL, 0x3814f200UL,
0xa3f94043UL, 0x9c7a54c2UL, 0xbc704f57UL, 0xda41e7f9UL, 0xc25ad33aUL, 0x54f4a084UL,
0xb17f5505UL, 0x59357cbeUL, 0xedbd15c8UL, 0x7f97c5abUL, 0xba5ac7b5UL, 0xb6f6deafUL,
0x3a479c3aUL, 0x5302da25UL, 0x653d7e6aUL, 0x54268d49UL, 0x51a477eaUL, 0x5017d55bUL,
0xd7d25d88UL, 0x44136c76UL, 0x0404a8c8UL, 0xb8e5a121UL, 0xb81a928aUL, 0x60ed5869UL,
0x97c55b96UL, 0xeaec991bUL, 0x29935913UL, 0x01fdb7f1UL, 0x088e8dfaUL, 0x9ab6f6f5UL,
0x3b4cbf9fUL, 0x4a5de3abUL, 0xe6051d35UL, 0xa0e1d855UL, 0xd36b4cf1UL, 0xf544edebUL,
0xb0e93524UL, 0xbebb8fbdUL, 0xa2d762cfUL, 0x49c92f54UL, 0x38b5f331UL, 0x7128a454UL,
0x48392905UL, 0xa65b1db8UL, 0x851c97bdUL, 0xd675cf2fUL};
static const ulong32 S7[256] = {
0x85e04019UL, 0x332bf567UL, 0x662dbfffUL, 0xcfc65693UL, 0x2a8d7f6fUL, 0xab9bc912UL,
0xde6008a1UL, 0x2028da1fUL, 0x0227bce7UL, 0x4d642916UL, 0x18fac300UL, 0x50f18b82UL,
0x2cb2cb11UL, 0xb232e75cUL, 0x4b3695f2UL, 0xb28707deUL, 0xa05fbcf6UL, 0xcd4181e9UL,
0xe150210cUL, 0xe24ef1bdUL, 0xb168c381UL, 0xfde4e789UL, 0x5c79b0d8UL, 0x1e8bfd43UL,
0x4d495001UL, 0x38be4341UL, 0x913cee1dUL, 0x92a79c3fUL, 0x089766beUL, 0xbaeeadf4UL,
0x1286becfUL, 0xb6eacb19UL, 0x2660c200UL, 0x7565bde4UL, 0x64241f7aUL, 0x8248dca9UL,
0xc3b3ad66UL, 0x28136086UL, 0x0bd8dfa8UL, 0x356d1cf2UL, 0x107789beUL, 0xb3b2e9ceUL,
0x0502aa8fUL, 0x0bc0351eUL, 0x166bf52aUL, 0xeb12ff82UL, 0xe3486911UL, 0xd34d7516UL,
0x4e7b3affUL, 0x5f43671bUL, 0x9cf6e037UL, 0x4981ac83UL, 0x334266ceUL, 0x8c9341b7UL,
0xd0d854c0UL, 0xcb3a6c88UL, 0x47bc2829UL, 0x4725ba37UL, 0xa66ad22bUL, 0x7ad61f1eUL,
0x0c5cbafaUL, 0x4437f107UL, 0xb6e79962UL, 0x42d2d816UL, 0x0a961288UL, 0xe1a5c06eUL,
0x13749e67UL, 0x72fc081aUL, 0xb1d139f7UL, 0xf9583745UL, 0xcf19df58UL, 0xbec3f756UL,
0xc06eba30UL, 0x07211b24UL, 0x45c28829UL, 0xc95e317fUL, 0xbc8ec511UL, 0x38bc46e9UL,
0xc6e6fa14UL, 0xbae8584aUL, 0xad4ebc46UL, 0x468f508bUL, 0x7829435fUL, 0xf124183bUL,
0x821dba9fUL, 0xaff60ff4UL, 0xea2c4e6dUL, 0x16e39264UL, 0x92544a8bUL, 0x009b4fc3UL,
0xaba68cedUL, 0x9ac96f78UL, 0x06a5b79aUL, 0xb2856e6eUL, 0x1aec3ca9UL, 0xbe838688UL,
0x0e0804e9UL, 0x55f1be56UL, 0xe7e5363bUL, 0xb3a1f25dUL, 0xf7debb85UL, 0x61fe033cUL,
0x16746233UL, 0x3c034c28UL, 0xda6d0c74UL, 0x79aac56cUL, 0x3ce4e1adUL, 0x51f0c802UL,
0x98f8f35aUL, 0x1626a49fUL, 0xeed82b29UL, 0x1d382fe3UL, 0x0c4fb99aUL, 0xbb325778UL,
0x3ec6d97bUL, 0x6e77a6a9UL, 0xcb658b5cUL, 0xd45230c7UL, 0x2bd1408bUL, 0x60c03eb7UL,
0xb9068d78UL, 0xa33754f4UL, 0xf430c87dUL, 0xc8a71302UL, 0xb96d8c32UL, 0xebd4e7beUL,
0xbe8b9d2dUL, 0x7979fb06UL, 0xe7225308UL, 0x8b75cf77UL, 0x11ef8da4UL, 0xe083c858UL,
0x8d6b786fUL, 0x5a6317a6UL, 0xfa5cf7a0UL, 0x5dda0033UL, 0xf28ebfb0UL, 0xf5b9c310UL,
0xa0eac280UL, 0x08b9767aUL, 0xa3d9d2b0UL, 0x79d34217UL, 0x021a718dUL, 0x9ac6336aUL,
0x2711fd60UL, 0x438050e3UL, 0x069908a8UL, 0x3d7fedc4UL, 0x826d2befUL, 0x4eeb8476UL,
0x488dcf25UL, 0x36c9d566UL, 0x28e74e41UL, 0xc2610acaUL, 0x3d49a9cfUL, 0xbae3b9dfUL,
0xb65f8de6UL, 0x92aeaf64UL, 0x3ac7d5e6UL, 0x9ea80509UL, 0xf22b017dUL, 0xa4173f70UL,
0xdd1e16c3UL, 0x15e0d7f9UL, 0x50b1b887UL, 0x2b9f4fd5UL, 0x625aba82UL, 0x6a017962UL,
0x2ec01b9cUL, 0x15488aa9UL, 0xd716e740UL, 0x40055a2cUL, 0x93d29a22UL, 0xe32dbf9aUL,
0x058745b9UL, 0x3453dc1eUL, 0xd699296eUL, 0x496cff6fUL, 0x1c9f4986UL, 0xdfe2ed07UL,
0xb87242d1UL, 0x19de7eaeUL, 0x053e561aUL, 0x15ad6f8cUL, 0x66626c1cUL, 0x7154c24cUL,
0xea082b2aUL, 0x93eb2939UL, 0x17dcb0f0UL, 0x58d4f2aeUL, 0x9ea294fbUL, 0x52cf564cUL,
0x9883fe66UL, 0x2ec40581UL, 0x763953c3UL, 0x01d6692eUL, 0xd3a0c108UL, 0xa1e7160eUL,
0xe4f2dfa6UL, 0x693ed285UL, 0x74904698UL, 0x4c2b0eddUL, 0x4f757656UL, 0x5d393378UL,
0xa132234fUL, 0x3d321c5dUL, 0xc3f5e194UL, 0x4b269301UL, 0xc79f022fUL, 0x3c997e7eUL,
0x5e4f9504UL, 0x3ffafbbdUL, 0x76f7ad0eUL, 0x296693f4UL, 0x3d1fce6fUL, 0xc61e45beUL,
0xd3b5ab34UL, 0xf72bf9b7UL, 0x1b0434c0UL, 0x4e72b567UL, 0x5592a33dUL, 0xb5229301UL,
0xcfd2a87fUL, 0x60aeb767UL, 0x1814386bUL, 0x30bcc33dUL, 0x38a0c07dUL, 0xfd1606f2UL,
0xc363519bUL, 0x589dd390UL, 0x5479f8e6UL, 0x1cb8d647UL, 0x97fd61a9UL, 0xea7759f4UL,
0x2d57539dUL, 0x569a58cfUL, 0xe84e63adUL, 0x462e1b78UL, 0x6580f87eUL, 0xf3817914UL,
0x91da55f4UL, 0x40a230f3UL, 0xd1988f35UL, 0xb6e318d2UL, 0x3ffa50bcUL, 0x3d40f021UL,
0xc3c0bdaeUL, 0x4958c24cUL, 0x518f36b2UL, 0x84b1d370UL, 0x0fedce83UL, 0x878ddadaUL,
0xf2a279c7UL, 0x94e01be8UL, 0x90716f4bUL, 0x954b8aa3UL};
static const ulong32 S8[256] = {
0xe216300dUL, 0xbbddfffcUL, 0xa7ebdabdUL, 0x35648095UL, 0x7789f8b7UL, 0xe6c1121bUL,
0x0e241600UL, 0x052ce8b5UL, 0x11a9cfb0UL, 0xe5952f11UL, 0xece7990aUL, 0x9386d174UL,
0x2a42931cUL, 0x76e38111UL, 0xb12def3aUL, 0x37ddddfcUL, 0xde9adeb1UL, 0x0a0cc32cUL,
0xbe197029UL, 0x84a00940UL, 0xbb243a0fUL, 0xb4d137cfUL, 0xb44e79f0UL, 0x049eedfdUL,
0x0b15a15dUL, 0x480d3168UL, 0x8bbbde5aUL, 0x669ded42UL, 0xc7ece831UL, 0x3f8f95e7UL,
0x72df191bUL, 0x7580330dUL, 0x94074251UL, 0x5c7dcdfaUL, 0xabbe6d63UL, 0xaa402164UL,
0xb301d40aUL, 0x02e7d1caUL, 0x53571daeUL, 0x7a3182a2UL, 0x12a8ddecUL, 0xfdaa335dUL,
0x176f43e8UL, 0x71fb46d4UL, 0x38129022UL, 0xce949ad4UL, 0xb84769adUL, 0x965bd862UL,
0x82f3d055UL, 0x66fb9767UL, 0x15b80b4eUL, 0x1d5b47a0UL, 0x4cfde06fUL, 0xc28ec4b8UL,
0x57e8726eUL, 0x647a78fcUL, 0x99865d44UL, 0x608bd593UL, 0x6c200e03UL, 0x39dc5ff6UL,
0x5d0b00a3UL, 0xae63aff2UL, 0x7e8bd632UL, 0x70108c0cUL, 0xbbd35049UL, 0x2998df04UL,
0x980cf42aUL, 0x9b6df491UL, 0x9e7edd53UL, 0x06918548UL, 0x58cb7e07UL, 0x3b74ef2eUL,
0x522fffb1UL, 0xd24708ccUL, 0x1c7e27cdUL, 0xa4eb215bUL, 0x3cf1d2e2UL, 0x19b47a38UL,
0x424f7618UL, 0x35856039UL, 0x9d17dee7UL, 0x27eb35e6UL, 0xc9aff67bUL, 0x36baf5b8UL,
0x09c467cdUL, 0xc18910b1UL, 0xe11dbf7bUL, 0x06cd1af8UL, 0x7170c608UL, 0x2d5e3354UL,
0xd4de495aUL, 0x64c6d006UL, 0xbcc0c62cUL, 0x3dd00db3UL, 0x708f8f34UL, 0x77d51b42UL,
0x264f620fUL, 0x24b8d2bfUL, 0x15c1b79eUL, 0x46a52564UL, 0xf8d7e54eUL, 0x3e378160UL,
0x7895cda5UL, 0x859c15a5UL, 0xe6459788UL, 0xc37bc75fUL, 0xdb07ba0cUL, 0x0676a3abUL,
0x7f229b1eUL, 0x31842e7bUL, 0x24259fd7UL, 0xf8bef472UL, 0x835ffcb8UL, 0x6df4c1f2UL,
0x96f5b195UL, 0xfd0af0fcUL, 0xb0fe134cUL, 0xe2506d3dUL, 0x4f9b12eaUL, 0xf215f225UL,
0xa223736fUL, 0x9fb4c428UL, 0x25d04979UL, 0x34c713f8UL, 0xc4618187UL, 0xea7a6e98UL,
0x7cd16efcUL, 0x1436876cUL, 0xf1544107UL, 0xbedeee14UL, 0x56e9af27UL, 0xa04aa441UL,
0x3cf7c899UL, 0x92ecbae6UL, 0xdd67016dUL, 0x151682ebUL, 0xa842eedfUL, 0xfdba60b4UL,
0xf1907b75UL, 0x20e3030fUL, 0x24d8c29eUL, 0xe139673bUL, 0xefa63fb8UL, 0x71873054UL,
0xb6f2cf3bUL, 0x9f326442UL, 0xcb15a4ccUL, 0xb01a4504UL, 0xf1e47d8dUL, 0x844a1be5UL,
0xbae7dfdcUL, 0x42cbda70UL, 0xcd7dae0aUL, 0x57e85b7aUL, 0xd53f5af6UL, 0x20cf4d8cUL,
0xcea4d428UL, 0x79d130a4UL, 0x3486ebfbUL, 0x33d3cddcUL, 0x77853b53UL, 0x37effcb5UL,
0xc5068778UL, 0xe580b3e6UL, 0x4e68b8f4UL, 0xc5c8b37eUL, 0x0d809ea2UL, 0x398feb7cUL,
0x132a4f94UL, 0x43b7950eUL, 0x2fee7d1cUL, 0x223613bdUL, 0xdd06caa2UL, 0x37df932bUL,
0xc4248289UL, 0xacf3ebc3UL, 0x5715f6b7UL, 0xef3478ddUL, 0xf267616fUL, 0xc148cbe4UL,
0x9052815eUL, 0x5e410fabUL, 0xb48a2465UL, 0x2eda7fa4UL, 0xe87b40e4UL, 0xe98ea084UL,
0x5889e9e1UL, 0xefd390fcUL, 0xdd07d35bUL, 0xdb485694UL, 0x38d7e5b2UL, 0x57720101UL,
0x730edebcUL, 0x5b643113UL, 0x94917e4fUL, 0x503c2fbaUL, 0x646f1282UL, 0x7523d24aUL,
0xe0779695UL, 0xf9c17a8fUL, 0x7a5b2121UL, 0xd187b896UL, 0x29263a4dUL, 0xba510cdfUL,
0x81f47c9fUL, 0xad1163edUL, 0xea7b5965UL, 0x1a00726eUL, 0x11403092UL, 0x00da6d77UL,
0x4a0cdd61UL, 0xad1f4603UL, 0x605bdfb0UL, 0x9eedc364UL, 0x22ebe6a8UL, 0xcee7d28aUL,
0xa0e736a0UL, 0x5564a6b9UL, 0x10853209UL, 0xc7eb8f37UL, 0x2de705caUL, 0x8951570fUL,
0xdf09822bUL, 0xbd691a6cUL, 0xaa12e4f2UL, 0x87451c0fUL, 0xe0f6a27aUL, 0x3ada4819UL,
0x4cf1764fUL, 0x0d771c2bUL, 0x67cdb156UL, 0x350d8384UL, 0x5938fa0fUL, 0x42399ef3UL,
0x36997b07UL, 0x0e84093dUL, 0x4aa93e61UL, 0x8360d87bUL, 0x1fa98b0cUL, 0x1149382cUL,
0xe97625a5UL, 0x0614d1b7UL, 0x0e25244bUL, 0x0c768347UL, 0x589e8d82UL, 0x0d2059d1UL,
0xa466bb1eUL, 0xf8da0a82UL, 0x04f19130UL, 0xba6e4ec0UL, 0x99265164UL, 0x1ee7230dUL,
0x50b2ad80UL, 0xeaee6801UL, 0x8db2a283UL, 0xea8bf59eUL};
/* returns the i'th byte of a variable */
#ifdef _MSC_VER
#define GB(x, i) ((unsigned char)((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3))))
#else
#define GB(x, i) (((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3)))&255)
#endif
/**
Initialize the LTC_CAST5 block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#else
int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#endif
{
ulong32 x[4], z[4];
unsigned char buf[16];
int y, i;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (num_rounds != 12 && num_rounds != 16 && num_rounds != 0) {
return CRYPT_INVALID_ROUNDS;
}
if (num_rounds == 12 && keylen > 10) {
return CRYPT_INVALID_ROUNDS;
}
if (keylen < 5 || keylen > 16) {
return CRYPT_INVALID_KEYSIZE;
}
/* extend the key as required */
zeromem(buf, sizeof(buf));
XMEMCPY(buf, key, (size_t)keylen);
/* load and start the awful looking network */
for (y = 0; y < 4; y++) {
LOAD32H(x[3-y],buf+4*y);
}
for (i = y = 0; y < 2; y++) {
z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)];
z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)];
z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)];
z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)];
skey->cast5.K[i++] = S5[GB(z, 0x8)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0x7)] ^ S8[GB(z, 0x6)] ^ S5[GB(z, 0x2)];
skey->cast5.K[i++] = S5[GB(z, 0xA)] ^ S6[GB(z, 0xB)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S6[GB(z, 0x6)];
skey->cast5.K[i++] = S5[GB(z, 0xC)] ^ S6[GB(z, 0xd)] ^ S7[GB(z, 0x3)] ^ S8[GB(z, 0x2)] ^ S7[GB(z, 0x9)];
skey->cast5.K[i++] = S5[GB(z, 0xE)] ^ S6[GB(z, 0xF)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x0)] ^ S8[GB(z, 0xc)];
x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)];
x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)];
x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)];
x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)];
skey->cast5.K[i++] = S5[GB(x, 0x3)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0xc)] ^ S8[GB(x, 0xd)] ^ S5[GB(x, 0x8)];
skey->cast5.K[i++] = S5[GB(x, 0x1)] ^ S6[GB(x, 0x0)] ^ S7[GB(x, 0xe)] ^ S8[GB(x, 0xf)] ^ S6[GB(x, 0xd)];
skey->cast5.K[i++] = S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x8)] ^ S8[GB(x, 0x9)] ^ S7[GB(x, 0x3)];
skey->cast5.K[i++] = S5[GB(x, 0x5)] ^ S6[GB(x, 0x4)] ^ S7[GB(x, 0xa)] ^ S8[GB(x, 0xb)] ^ S8[GB(x, 0x7)];
/* second half */
z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)];
z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)];
z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)];
z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)];
skey->cast5.K[i++] = S5[GB(z, 0x3)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0xc)] ^ S8[GB(z, 0xd)] ^ S5[GB(z, 0x9)];
skey->cast5.K[i++] = S5[GB(z, 0x1)] ^ S6[GB(z, 0x0)] ^ S7[GB(z, 0xe)] ^ S8[GB(z, 0xf)] ^ S6[GB(z, 0xc)];
skey->cast5.K[i++] = S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x8)] ^ S8[GB(z, 0x9)] ^ S7[GB(z, 0x2)];
skey->cast5.K[i++] = S5[GB(z, 0x5)] ^ S6[GB(z, 0x4)] ^ S7[GB(z, 0xa)] ^ S8[GB(z, 0xb)] ^ S8[GB(z, 0x6)];
x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)];
x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)];
x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)];
x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)];
skey->cast5.K[i++] = S5[GB(x, 0x8)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0x7)] ^ S8[GB(x, 0x6)] ^ S5[GB(x, 0x3)];
skey->cast5.K[i++] = S5[GB(x, 0xa)] ^ S6[GB(x, 0xb)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S6[GB(x, 0x7)];
skey->cast5.K[i++] = S5[GB(x, 0xc)] ^ S6[GB(x, 0xd)] ^ S7[GB(x, 0x3)] ^ S8[GB(x, 0x2)] ^ S7[GB(x, 0x8)];
skey->cast5.K[i++] = S5[GB(x, 0xe)] ^ S6[GB(x, 0xf)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x0)] ^ S8[GB(x, 0xd)];
}
skey->cast5.keylen = keylen;
#ifdef LTC_CLEAN_STACK
zeromem(buf, sizeof(buf));
zeromem(x, sizeof(x));
zeromem(z, sizeof(z));
#endif
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int z;
z = _cast5_setup(key, keylen, num_rounds, skey);
burn_stack(sizeof(ulong32)*8 + 16 + sizeof(int)*2);
return z;
}
#endif
#ifdef _MSC_VER
#define INLINE __inline
#else
#define INLINE
#endif
INLINE static ulong32 FI(ulong32 R, ulong32 Km, ulong32 Kr)
{
ulong32 I;
I = (Km + R);
I = ROL(I, Kr);
return ((S1[byte(I, 3)] ^ S2[byte(I,2)]) - S3[byte(I,1)]) + S4[byte(I,0)];
}
INLINE static ulong32 FII(ulong32 R, ulong32 Km, ulong32 Kr)
{
ulong32 I;
I = (Km ^ R);
I = ROL(I, Kr);
return ((S1[byte(I, 3)] - S2[byte(I,2)]) + S3[byte(I,1)]) ^ S4[byte(I,0)];
}
INLINE static ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr)
{
ulong32 I;
I = (Km - R);
I = ROL(I, Kr);
return ((S1[byte(I, 3)] + S2[byte(I,2)]) ^ S3[byte(I,1)]) - S4[byte(I,0)];
}
/**
Encrypts a block of text with LTC_CAST5
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
*/
#ifdef LTC_CLEAN_STACK
static int _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 R, L;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
LOAD32H(L,&pt[0]);
LOAD32H(R,&pt[4]);
L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]);
R ^= FII(L, skey->cast5.K[1], skey->cast5.K[17]);
L ^= FIII(R, skey->cast5.K[2], skey->cast5.K[18]);
R ^= FI(L, skey->cast5.K[3], skey->cast5.K[19]);
L ^= FII(R, skey->cast5.K[4], skey->cast5.K[20]);
R ^= FIII(L, skey->cast5.K[5], skey->cast5.K[21]);
L ^= FI(R, skey->cast5.K[6], skey->cast5.K[22]);
R ^= FII(L, skey->cast5.K[7], skey->cast5.K[23]);
L ^= FIII(R, skey->cast5.K[8], skey->cast5.K[24]);
R ^= FI(L, skey->cast5.K[9], skey->cast5.K[25]);
L ^= FII(R, skey->cast5.K[10], skey->cast5.K[26]);
R ^= FIII(L, skey->cast5.K[11], skey->cast5.K[27]);
if (skey->cast5.keylen > 10) {
L ^= FI(R, skey->cast5.K[12], skey->cast5.K[28]);
R ^= FII(L, skey->cast5.K[13], skey->cast5.K[29]);
L ^= FIII(R, skey->cast5.K[14], skey->cast5.K[30]);
R ^= FI(L, skey->cast5.K[15], skey->cast5.K[31]);
}
STORE32H(R,&ct[0]);
STORE32H(L,&ct[4]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
int err =_cast5_ecb_encrypt(pt,ct,skey);
burn_stack(sizeof(ulong32)*3);
return err;
}
#endif
/**
Decrypts a block of text with LTC_CAST5
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
*/
#ifdef LTC_CLEAN_STACK
static int _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 R, L;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
LOAD32H(R,&ct[0]);
LOAD32H(L,&ct[4]);
if (skey->cast5.keylen > 10) {
R ^= FI(L, skey->cast5.K[15], skey->cast5.K[31]);
L ^= FIII(R, skey->cast5.K[14], skey->cast5.K[30]);
R ^= FII(L, skey->cast5.K[13], skey->cast5.K[29]);
L ^= FI(R, skey->cast5.K[12], skey->cast5.K[28]);
}
R ^= FIII(L, skey->cast5.K[11], skey->cast5.K[27]);
L ^= FII(R, skey->cast5.K[10], skey->cast5.K[26]);
R ^= FI(L, skey->cast5.K[9], skey->cast5.K[25]);
L ^= FIII(R, skey->cast5.K[8], skey->cast5.K[24]);
R ^= FII(L, skey->cast5.K[7], skey->cast5.K[23]);
L ^= FI(R, skey->cast5.K[6], skey->cast5.K[22]);
R ^= FIII(L, skey->cast5.K[5], skey->cast5.K[21]);
L ^= FII(R, skey->cast5.K[4], skey->cast5.K[20]);
R ^= FI(L, skey->cast5.K[3], skey->cast5.K[19]);
L ^= FIII(R, skey->cast5.K[2], skey->cast5.K[18]);
R ^= FII(L, skey->cast5.K[1], skey->cast5.K[17]);
L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]);
STORE32H(L,&pt[0]);
STORE32H(R,&pt[4]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
int err = _cast5_ecb_decrypt(ct,pt,skey);
burn_stack(sizeof(ulong32)*3);
return err;
}
#endif
/**
Performs a self-test of the LTC_CAST5 block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int cast5_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen;
unsigned char key[16];
unsigned char pt[8];
unsigned char ct[8];
} tests[] = {
{ 16,
{0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A},
{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
{0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2}
},
{ 10,
{0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
{0xEB, 0x6A, 0x71, 0x1A, 0x2C, 0x02, 0x27, 0x1B},
},
{ 5,
{0x01, 0x23, 0x45, 0x67, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
{0x7A, 0xC8, 0x16, 0xD1, 0x6E, 0x9B, 0x30, 0x2E}
}
};
int i, y, err;
symmetric_key key;
unsigned char tmp[2][8];
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
if ((err = cast5_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
return err;
}
cast5_ecb_encrypt(tests[i].pt, tmp[0], &key);
cast5_ecb_decrypt(tmp[0], tmp[1], &key);
if ((compare_testvector(tmp[0], 8, tests[i].ct, 8, "CAST5 Encrypt", i) != 0) ||
(compare_testvector(tmp[1], 8, tests[i].pt, 8, "CAST5 Decrypt", i) != 0)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 8; y++) tmp[0][y] = 0;
for (y = 0; y < 1000; y++) cast5_ecb_encrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 1000; y++) cast5_ecb_decrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
/** Terminate the context
@param skey The scheduled key
*/
void cast5_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int cast5_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 5) {
return CRYPT_INVALID_KEYSIZE;
} else if (*keysize > 16) {
*keysize = 16;
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

2086
thirdparty/libtomcrypt/ciphers/des.c vendored Normal file

File diff suppressed because it is too large Load Diff

318
thirdparty/libtomcrypt/ciphers/kasumi.c vendored Normal file
View File

@@ -0,0 +1,318 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file kasumi.c
Implementation of the 3GPP Kasumi block cipher
Derived from the 3GPP standard source code
*/
#include "tomcrypt.h"
#ifdef LTC_KASUMI
typedef unsigned u16;
#define ROL16(x, y) ((((x)<<(y)) | ((x)>>(16-(y)))) & 0xFFFF)
const struct ltc_cipher_descriptor kasumi_desc = {
"kasumi",
21,
16, 16, 8, 8,
&kasumi_setup,
&kasumi_ecb_encrypt,
&kasumi_ecb_decrypt,
&kasumi_test,
&kasumi_done,
&kasumi_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static u16 FI( u16 in, u16 subkey )
{
u16 nine, seven;
static const u16 S7[128] = {
54, 50, 62, 56, 22, 34, 94, 96, 38, 6, 63, 93, 2, 18,123, 33,
55,113, 39,114, 21, 67, 65, 12, 47, 73, 46, 27, 25,111,124, 81,
53, 9,121, 79, 52, 60, 58, 48,101,127, 40,120,104, 70, 71, 43,
20,122, 72, 61, 23,109, 13,100, 77, 1, 16, 7, 82, 10,105, 98,
117,116, 76, 11, 89,106, 0,125,118, 99, 86, 69, 30, 57,126, 87,
112, 51, 17, 5, 95, 14, 90, 84, 91, 8, 35,103, 32, 97, 28, 66,
102, 31, 26, 45, 75, 4, 85, 92, 37, 74, 80, 49, 68, 29,115, 44,
64,107,108, 24,110, 83, 36, 78, 42, 19, 15, 41, 88,119, 59, 3 };
static const u16 S9[512] = {
167,239,161,379,391,334, 9,338, 38,226, 48,358,452,385, 90,397,
183,253,147,331,415,340, 51,362,306,500,262, 82,216,159,356,177,
175,241,489, 37,206, 17, 0,333, 44,254,378, 58,143,220, 81,400,
95, 3,315,245, 54,235,218,405,472,264,172,494,371,290,399, 76,
165,197,395,121,257,480,423,212,240, 28,462,176,406,507,288,223,
501,407,249,265, 89,186,221,428,164, 74,440,196,458,421,350,163,
232,158,134,354, 13,250,491,142,191, 69,193,425,152,227,366,135,
344,300,276,242,437,320,113,278, 11,243, 87,317, 36, 93,496, 27,
487,446,482, 41, 68,156,457,131,326,403,339, 20, 39,115,442,124,
475,384,508, 53,112,170,479,151,126,169, 73,268,279,321,168,364,
363,292, 46,499,393,327,324, 24,456,267,157,460,488,426,309,229,
439,506,208,271,349,401,434,236, 16,209,359, 52, 56,120,199,277,
465,416,252,287,246, 6, 83,305,420,345,153,502, 65, 61,244,282,
173,222,418, 67,386,368,261,101,476,291,195,430, 49, 79,166,330,
280,383,373,128,382,408,155,495,367,388,274,107,459,417, 62,454,
132,225,203,316,234, 14,301, 91,503,286,424,211,347,307,140,374,
35,103,125,427, 19,214,453,146,498,314,444,230,256,329,198,285,
50,116, 78,410, 10,205,510,171,231, 45,139,467, 29, 86,505, 32,
72, 26,342,150,313,490,431,238,411,325,149,473, 40,119,174,355,
185,233,389, 71,448,273,372, 55,110,178,322, 12,469,392,369,190,
1,109,375,137,181, 88, 75,308,260,484, 98,272,370,275,412,111,
336,318, 4,504,492,259,304, 77,337,435, 21,357,303,332,483, 18,
47, 85, 25,497,474,289,100,269,296,478,270,106, 31,104,433, 84,
414,486,394, 96, 99,154,511,148,413,361,409,255,162,215,302,201,
266,351,343,144,441,365,108,298,251, 34,182,509,138,210,335,133,
311,352,328,141,396,346,123,319,450,281,429,228,443,481, 92,404,
485,422,248,297, 23,213,130,466, 22,217,283, 70,294,360,419,127,
312,377, 7,468,194, 2,117,295,463,258,224,447,247,187, 80,398,
284,353,105,390,299,471,470,184, 57,200,348, 63,204,188, 33,451,
97, 30,310,219, 94,160,129,493, 64,179,263,102,189,207,114,402,
438,477,387,122,192, 42,381, 5,145,118,180,449,293,323,136,380,
43, 66, 60,455,341,445,202,432, 8,237, 15,376,436,464, 59,461};
/* The sixteen bit input is split into two unequal halves, *
* nine bits and seven bits - as is the subkey */
nine = (u16)(in>>7)&0x1FF;
seven = (u16)(in&0x7F);
/* Now run the various operations */
nine = (u16)(S9[nine] ^ seven);
seven = (u16)(S7[seven] ^ (nine & 0x7F));
seven ^= (subkey>>9);
nine ^= (subkey&0x1FF);
nine = (u16)(S9[nine] ^ seven);
seven = (u16)(S7[seven] ^ (nine & 0x7F));
return (u16)(seven<<9) + nine;
}
static ulong32 FO( ulong32 in, int round_no, symmetric_key *key)
{
u16 left, right;
/* Split the input into two 16-bit words */
left = (u16)(in>>16);
right = (u16) in&0xFFFF;
/* Now apply the same basic transformation three times */
left ^= key->kasumi.KOi1[round_no];
left = FI( left, key->kasumi.KIi1[round_no] );
left ^= right;
right ^= key->kasumi.KOi2[round_no];
right = FI( right, key->kasumi.KIi2[round_no] );
right ^= left;
left ^= key->kasumi.KOi3[round_no];
left = FI( left, key->kasumi.KIi3[round_no] );
left ^= right;
return (((ulong32)right)<<16)+left;
}
static ulong32 FL( ulong32 in, int round_no, symmetric_key *key )
{
u16 l, r, a, b;
/* split out the left and right halves */
l = (u16)(in>>16);
r = (u16)(in)&0xFFFF;
/* do the FL() operations */
a = (u16) (l & key->kasumi.KLi1[round_no]);
r ^= ROL16(a,1);
b = (u16)(r | key->kasumi.KLi2[round_no]);
l ^= ROL16(b,1);
/* put the two halves back together */
return (((ulong32)l)<<16) + r;
}
int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
ulong32 left, right, temp;
int n;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
LOAD32H(left, pt);
LOAD32H(right, pt+4);
for (n = 0; n <= 7; ) {
temp = FL(left, n, skey);
temp = FO(temp, n++, skey);
right ^= temp;
temp = FO(right, n, skey);
temp = FL(temp, n++, skey);
left ^= temp;
}
STORE32H(left, ct);
STORE32H(right, ct+4);
return CRYPT_OK;
}
int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
ulong32 left, right, temp;
int n;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
LOAD32H(left, ct);
LOAD32H(right, ct+4);
for (n = 7; n >= 0; ) {
temp = FO(right, n, skey);
temp = FL(temp, n--, skey);
left ^= temp;
temp = FL(left, n, skey);
temp = FO(temp, n--, skey);
right ^= temp;
}
STORE32H(left, pt);
STORE32H(right, pt+4);
return CRYPT_OK;
}
int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
static const u16 C[8] = { 0x0123,0x4567,0x89AB,0xCDEF, 0xFEDC,0xBA98,0x7654,0x3210 };
u16 ukey[8], Kprime[8];
int n;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (keylen != 16) {
return CRYPT_INVALID_KEYSIZE;
}
if (num_rounds != 0 && num_rounds != 8) {
return CRYPT_INVALID_ROUNDS;
}
/* Start by ensuring the subkeys are endian correct on a 16-bit basis */
for (n = 0; n < 8; n++ ) {
ukey[n] = (((u16)key[2*n]) << 8) | key[2*n+1];
}
/* Now build the K'[] keys */
for (n = 0; n < 8; n++) {
Kprime[n] = ukey[n] ^ C[n];
}
/* Finally construct the various sub keys */
for(n = 0; n < 8; n++) {
skey->kasumi.KLi1[n] = ROL16(ukey[n],1);
skey->kasumi.KLi2[n] = Kprime[(n+2)&0x7];
skey->kasumi.KOi1[n] = ROL16(ukey[(n+1)&0x7],5);
skey->kasumi.KOi2[n] = ROL16(ukey[(n+5)&0x7],8);
skey->kasumi.KOi3[n] = ROL16(ukey[(n+6)&0x7],13);
skey->kasumi.KIi1[n] = Kprime[(n+4)&0x7];
skey->kasumi.KIi2[n] = Kprime[(n+3)&0x7];
skey->kasumi.KIi3[n] = Kprime[(n+7)&0x7];
}
return CRYPT_OK;
}
void kasumi_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
int kasumi_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize >= 16) {
*keysize = 16;
return CRYPT_OK;
} else {
return CRYPT_INVALID_KEYSIZE;
}
}
int kasumi_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
unsigned char key[16], pt[8], ct[8];
} tests[] = {
{
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x4B, 0x58, 0xA7, 0x71, 0xAF, 0xC7, 0xE5, 0xE8 }
},
{
{ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x7E, 0xEF, 0x11, 0x3C, 0x95, 0xBB, 0x5A, 0x77 }
},
{
{ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x5F, 0x14, 0x06, 0x86, 0xD7, 0xAD, 0x5A, 0x39 },
},
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x2E, 0x14, 0x91, 0xCF, 0x70, 0xAA, 0x46, 0x5D }
},
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xB5, 0x45, 0x86, 0xF4, 0xAB, 0x9A, 0xE5, 0x46 }
},
};
unsigned char buf[2][8];
symmetric_key key;
int err, x;
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
if ((err = kasumi_setup(tests[x].key, 16, 0, &key)) != CRYPT_OK) {
return err;
}
if ((err = kasumi_ecb_encrypt(tests[x].pt, buf[0], &key)) != CRYPT_OK) {
return err;
}
if ((err = kasumi_ecb_decrypt(tests[x].ct, buf[1], &key)) != CRYPT_OK) {
return err;
}
if (compare_testvector(buf[1], 8, tests[x].pt, 8, "Kasumi Decrypt", x) ||
compare_testvector(buf[0], 8, tests[x].ct, 8, "Kasumi Encrypt", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

855
thirdparty/libtomcrypt/ciphers/khazad.c vendored Normal file
View File

@@ -0,0 +1,855 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file khazad.c
Khazad implementation derived from public domain source
Authors: Paulo S.L.M. Barreto and Vincent Rijmen.
*/
#ifdef LTC_KHAZAD
const struct ltc_cipher_descriptor khazad_desc = {
"khazad",
18,
16, 16, 8, 8,
&khazad_setup,
&khazad_ecb_encrypt,
&khazad_ecb_decrypt,
&khazad_test,
&khazad_done,
&khazad_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#define R 8
#define KEYSIZE 128
#define KEYSIZEB (KEYSIZE/8)
#define BLOCKSIZE 64
#define BLOCKSIZEB (BLOCKSIZE/8)
static const ulong64 T0[256] = {
CONST64(0xbad3d268bbb96a01), CONST64(0x54fc4d19e59a66b1), CONST64(0x2f71bc93e26514cd), CONST64(0x749ccdb925871b51),
CONST64(0x53f55102f7a257a4), CONST64(0xd3686bb8d0d6be03), CONST64(0xd26b6fbdd6deb504), CONST64(0x4dd72964b35285fe),
CONST64(0x50f05d0dfdba4aad), CONST64(0xace98a26cf09e063), CONST64(0x8d8a0e83091c9684), CONST64(0xbfdcc679a5914d1a),
CONST64(0x7090ddad3da7374d), CONST64(0x52f65507f1aa5ca3), CONST64(0x9ab352c87ba417e1), CONST64(0x4cd42d61b55a8ef9),
CONST64(0xea238f65460320ac), CONST64(0xd56273a6c4e68411), CONST64(0x97a466f155cc68c2), CONST64(0xd16e63b2dcc6a80d),
CONST64(0x3355ccffaa85d099), CONST64(0x51f35908fbb241aa), CONST64(0x5bed712ac7e20f9c), CONST64(0xa6f7a204f359ae55),
CONST64(0xde7f5f81febec120), CONST64(0x48d83d75ad7aa2e5), CONST64(0xa8e59a32d729cc7f), CONST64(0x99b65ec771bc0ae8),
CONST64(0xdb704b90e096e63b), CONST64(0x3256c8faac8ddb9e), CONST64(0xb7c4e65195d11522), CONST64(0xfc19d72b32b3aace),
CONST64(0xe338ab48704b7393), CONST64(0x9ebf42dc63843bfd), CONST64(0x91ae7eef41fc52d0), CONST64(0x9bb056cd7dac1ce6),
CONST64(0xe23baf4d76437894), CONST64(0xbbd0d66dbdb16106), CONST64(0x41c319589b32f1da), CONST64(0x6eb2a5cb7957e517),
CONST64(0xa5f2ae0bf941b35c), CONST64(0xcb400bc08016564b), CONST64(0x6bbdb1da677fc20c), CONST64(0x95a26efb59dc7ecc),
CONST64(0xa1febe1fe1619f40), CONST64(0xf308eb1810cbc3e3), CONST64(0xb1cefe4f81e12f30), CONST64(0x0206080a0c10160e),
CONST64(0xcc4917db922e675e), CONST64(0xc45137f3a26e3f66), CONST64(0x1d2774694ee8cf53), CONST64(0x143c504478a09c6c),
CONST64(0xc3582be8b0560e73), CONST64(0x63a591f2573f9a34), CONST64(0xda734f95e69eed3c), CONST64(0x5de76934d3d2358e),
CONST64(0x5fe1613edfc22380), CONST64(0xdc79578bf2aed72e), CONST64(0x7d87e99413cf486e), CONST64(0xcd4a13de94266c59),
CONST64(0x7f81e19e1fdf5e60), CONST64(0x5aee752fc1ea049b), CONST64(0x6cb4adc17547f319), CONST64(0x5ce46d31d5da3e89),
CONST64(0xf704fb0c08ebefff), CONST64(0x266a98bed42d47f2), CONST64(0xff1cdb2438abb7c7), CONST64(0xed2a937e543b11b9),
CONST64(0xe825876f4a1336a2), CONST64(0x9dba4ed3699c26f4), CONST64(0x6fb1a1ce7f5fee10), CONST64(0x8e8f028c03048b8d),
CONST64(0x192b647d56c8e34f), CONST64(0xa0fdba1ae7699447), CONST64(0xf00de7171ad3deea), CONST64(0x89861e97113cba98),
CONST64(0x0f113c332278692d), CONST64(0x07091c1b12383115), CONST64(0xafec8629c511fd6a), CONST64(0xfb10cb30208b9bdb),
CONST64(0x0818202830405838), CONST64(0x153f54417ea8976b), CONST64(0x0d1734392e687f23), CONST64(0x040c101418202c1c),
CONST64(0x0103040506080b07), CONST64(0x64ac8de94507ab21), CONST64(0xdf7c5b84f8b6ca27), CONST64(0x769ac5b329970d5f),
CONST64(0x798bf9800bef6472), CONST64(0xdd7a538ef4a6dc29), CONST64(0x3d47f4c98ef5b2b3), CONST64(0x163a584e74b08a62),
CONST64(0x3f41fcc382e5a4bd), CONST64(0x3759dcebb2a5fc85), CONST64(0x6db7a9c4734ff81e), CONST64(0x3848e0d890dd95a8),
CONST64(0xb9d6de67b1a17708), CONST64(0x7395d1a237bf2a44), CONST64(0xe926836a4c1b3da5), CONST64(0x355fd4e1beb5ea8b),
CONST64(0x55ff491ce3926db6), CONST64(0x7193d9a83baf3c4a), CONST64(0x7b8df18a07ff727c), CONST64(0x8c890a860f149d83),
CONST64(0x7296d5a731b72143), CONST64(0x88851a921734b19f), CONST64(0xf607ff090ee3e4f8), CONST64(0x2a7ea882fc4d33d6),
CONST64(0x3e42f8c684edafba), CONST64(0x5ee2653bd9ca2887), CONST64(0x27699cbbd2254cf5), CONST64(0x46ca0543890ac0cf),
CONST64(0x0c14303c28607424), CONST64(0x65af89ec430fa026), CONST64(0x68b8bdd56d67df05), CONST64(0x61a399f85b2f8c3a),
CONST64(0x03050c0f0a181d09), CONST64(0xc15e23e2bc46187d), CONST64(0x57f94116ef827bb8), CONST64(0xd6677fa9cefe9918),
CONST64(0xd976439aec86f035), CONST64(0x58e87d25cdfa1295), CONST64(0xd875479fea8efb32), CONST64(0x66aa85e34917bd2f),
CONST64(0xd7647bacc8f6921f), CONST64(0x3a4ee8d29ccd83a6), CONST64(0xc84507cf8a0e4b42), CONST64(0x3c44f0cc88fdb9b4),
CONST64(0xfa13cf35268390dc), CONST64(0x96a762f453c463c5), CONST64(0xa7f4a601f551a552), CONST64(0x98b55ac277b401ef),
CONST64(0xec29977b52331abe), CONST64(0xb8d5da62b7a97c0f), CONST64(0xc7543bfca876226f), CONST64(0xaeef822cc319f66d),
CONST64(0x69bbb9d06b6fd402), CONST64(0x4bdd317aa762bfec), CONST64(0xabe0963ddd31d176), CONST64(0xa9e69e37d121c778),
CONST64(0x67a981e64f1fb628), CONST64(0x0a1e28223c504e36), CONST64(0x47c901468f02cbc8), CONST64(0xf20bef1d16c3c8e4),
CONST64(0xb5c2ee5b99c1032c), CONST64(0x226688aacc0d6bee), CONST64(0xe532b356647b4981), CONST64(0xee2f9f715e230cb0),
CONST64(0xbedfc27ca399461d), CONST64(0x2b7dac87fa4538d1), CONST64(0x819e3ebf217ce2a0), CONST64(0x1236485a6c90a67e),
CONST64(0x839836b52d6cf4ae), CONST64(0x1b2d6c775ad8f541), CONST64(0x0e1238362470622a), CONST64(0x23658cafca0560e9),
CONST64(0xf502f30604fbf9f1), CONST64(0x45cf094c8312ddc6), CONST64(0x216384a5c61576e7), CONST64(0xce4f1fd19e3e7150),
CONST64(0x49db3970ab72a9e2), CONST64(0x2c74b09ce87d09c4), CONST64(0xf916c33a2c9b8dd5), CONST64(0xe637bf596e635488),
CONST64(0xb6c7e25493d91e25), CONST64(0x2878a088f05d25d8), CONST64(0x17395c4b72b88165), CONST64(0x829b32b02b64ffa9),
CONST64(0x1a2e68725cd0fe46), CONST64(0x8b80169d1d2cac96), CONST64(0xfe1fdf213ea3bcc0), CONST64(0x8a8312981b24a791),
CONST64(0x091b242d3648533f), CONST64(0xc94603ca8c064045), CONST64(0x879426a1354cd8b2), CONST64(0x4ed2256bb94a98f7),
CONST64(0xe13ea3427c5b659d), CONST64(0x2e72b896e46d1fca), CONST64(0xe431b75362734286), CONST64(0xe03da7477a536e9a),
CONST64(0xeb208b60400b2bab), CONST64(0x90ad7aea47f459d7), CONST64(0xa4f1aa0eff49b85b), CONST64(0x1e22786644f0d25a),
CONST64(0x85922eab395ccebc), CONST64(0x60a09dfd5d27873d), CONST64(0x0000000000000000), CONST64(0x256f94b1de355afb),
CONST64(0xf401f70302f3f2f6), CONST64(0xf10ee3121cdbd5ed), CONST64(0x94a16afe5fd475cb), CONST64(0x0b1d2c273a584531),
CONST64(0xe734bb5c686b5f8f), CONST64(0x759fc9bc238f1056), CONST64(0xef2c9b74582b07b7), CONST64(0x345cd0e4b8bde18c),
CONST64(0x3153c4f5a695c697), CONST64(0xd46177a3c2ee8f16), CONST64(0xd06d67b7dacea30a), CONST64(0x869722a43344d3b5),
CONST64(0x7e82e59b19d75567), CONST64(0xadea8e23c901eb64), CONST64(0xfd1ad32e34bba1c9), CONST64(0x297ba48df6552edf),
CONST64(0x3050c0f0a09dcd90), CONST64(0x3b4decd79ac588a1), CONST64(0x9fbc46d9658c30fa), CONST64(0xf815c73f2a9386d2),
CONST64(0xc6573ff9ae7e2968), CONST64(0x13354c5f6a98ad79), CONST64(0x060a181e14303a12), CONST64(0x050f14111e28271b),
CONST64(0xc55233f6a4663461), CONST64(0x113344556688bb77), CONST64(0x7799c1b62f9f0658), CONST64(0x7c84ed9115c74369),
CONST64(0x7a8ef58f01f7797b), CONST64(0x7888fd850de76f75), CONST64(0x365ad8eeb4adf782), CONST64(0x1c24706c48e0c454),
CONST64(0x394be4dd96d59eaf), CONST64(0x59eb7920cbf21992), CONST64(0x1828607850c0e848), CONST64(0x56fa4513e98a70bf),
CONST64(0xb3c8f6458df1393e), CONST64(0xb0cdfa4a87e92437), CONST64(0x246c90b4d83d51fc), CONST64(0x206080a0c01d7de0),
CONST64(0xb2cbf2408bf93239), CONST64(0x92ab72e04be44fd9), CONST64(0xa3f8b615ed71894e), CONST64(0xc05d27e7ba4e137a),
CONST64(0x44cc0d49851ad6c1), CONST64(0x62a695f751379133), CONST64(0x103040506080b070), CONST64(0xb4c1ea5e9fc9082b),
CONST64(0x84912aae3f54c5bb), CONST64(0x43c511529722e7d4), CONST64(0x93a876e54dec44de), CONST64(0xc25b2fedb65e0574),
CONST64(0x4ade357fa16ab4eb), CONST64(0xbddace73a9815b14), CONST64(0x8f8c0689050c808a), CONST64(0x2d77b499ee7502c3),
CONST64(0xbcd9ca76af895013), CONST64(0x9cb94ad66f942df3), CONST64(0x6abeb5df6177c90b), CONST64(0x40c01d5d9d3afadd),
CONST64(0xcf4c1bd498367a57), CONST64(0xa2fbb210eb798249), CONST64(0x809d3aba2774e9a7), CONST64(0x4fd1216ebf4293f0),
CONST64(0x1f217c6342f8d95d), CONST64(0xca430fc5861e5d4c), CONST64(0xaae39238db39da71), CONST64(0x42c61557912aecd3),
};
static const ulong64 T1[256] = {
CONST64(0xd3ba68d2b9bb016a), CONST64(0xfc54194d9ae5b166), CONST64(0x712f93bc65e2cd14), CONST64(0x9c74b9cd8725511b),
CONST64(0xf5530251a2f7a457), CONST64(0x68d3b86bd6d003be), CONST64(0x6bd2bd6fded604b5), CONST64(0xd74d642952b3fe85),
CONST64(0xf0500d5dbafdad4a), CONST64(0xe9ac268a09cf63e0), CONST64(0x8a8d830e1c098496), CONST64(0xdcbf79c691a51a4d),
CONST64(0x9070addda73d4d37), CONST64(0xf6520755aaf1a35c), CONST64(0xb39ac852a47be117), CONST64(0xd44c612d5ab5f98e),
CONST64(0x23ea658f0346ac20), CONST64(0x62d5a673e6c41184), CONST64(0xa497f166cc55c268), CONST64(0x6ed1b263c6dc0da8),
CONST64(0x5533ffcc85aa99d0), CONST64(0xf3510859b2fbaa41), CONST64(0xed5b2a71e2c79c0f), CONST64(0xf7a604a259f355ae),
CONST64(0x7fde815fbefe20c1), CONST64(0xd848753d7aade5a2), CONST64(0xe5a8329a29d77fcc), CONST64(0xb699c75ebc71e80a),
CONST64(0x70db904b96e03be6), CONST64(0x5632fac88dac9edb), CONST64(0xc4b751e6d1952215), CONST64(0x19fc2bd7b332ceaa),
CONST64(0x38e348ab4b709373), CONST64(0xbf9edc428463fd3b), CONST64(0xae91ef7efc41d052), CONST64(0xb09bcd56ac7de61c),
CONST64(0x3be24daf43769478), CONST64(0xd0bb6dd6b1bd0661), CONST64(0xc3415819329bdaf1), CONST64(0xb26ecba5577917e5),
CONST64(0xf2a50bae41f95cb3), CONST64(0x40cbc00b16804b56), CONST64(0xbd6bdab17f670cc2), CONST64(0xa295fb6edc59cc7e),
CONST64(0xfea11fbe61e1409f), CONST64(0x08f318ebcb10e3c3), CONST64(0xceb14ffee181302f), CONST64(0x06020a08100c0e16),
CONST64(0x49ccdb172e925e67), CONST64(0x51c4f3376ea2663f), CONST64(0x271d6974e84e53cf), CONST64(0x3c144450a0786c9c),
CONST64(0x58c3e82b56b0730e), CONST64(0xa563f2913f57349a), CONST64(0x73da954f9ee63ced), CONST64(0xe75d3469d2d38e35),
CONST64(0xe15f3e61c2df8023), CONST64(0x79dc8b57aef22ed7), CONST64(0x877d94e9cf136e48), CONST64(0x4acdde132694596c),
CONST64(0x817f9ee1df1f605e), CONST64(0xee5a2f75eac19b04), CONST64(0xb46cc1ad477519f3), CONST64(0xe45c316ddad5893e),
CONST64(0x04f70cfbeb08ffef), CONST64(0x6a26be982dd4f247), CONST64(0x1cff24dbab38c7b7), CONST64(0x2aed7e933b54b911),
CONST64(0x25e86f87134aa236), CONST64(0xba9dd34e9c69f426), CONST64(0xb16fcea15f7f10ee), CONST64(0x8f8e8c0204038d8b),
CONST64(0x2b197d64c8564fe3), CONST64(0xfda01aba69e74794), CONST64(0x0df017e7d31aeade), CONST64(0x8689971e3c1198ba),
CONST64(0x110f333c78222d69), CONST64(0x09071b1c38121531), CONST64(0xecaf298611c56afd), CONST64(0x10fb30cb8b20db9b),
CONST64(0x1808282040303858), CONST64(0x3f154154a87e6b97), CONST64(0x170d3934682e237f), CONST64(0x0c04141020181c2c),
CONST64(0x030105040806070b), CONST64(0xac64e98d074521ab), CONST64(0x7cdf845bb6f827ca), CONST64(0x9a76b3c597295f0d),
CONST64(0x8b7980f9ef0b7264), CONST64(0x7add8e53a6f429dc), CONST64(0x473dc9f4f58eb3b2), CONST64(0x3a164e58b074628a),
CONST64(0x413fc3fce582bda4), CONST64(0x5937ebdca5b285fc), CONST64(0xb76dc4a94f731ef8), CONST64(0x4838d8e0dd90a895),
CONST64(0xd6b967dea1b10877), CONST64(0x9573a2d1bf37442a), CONST64(0x26e96a831b4ca53d), CONST64(0x5f35e1d4b5be8bea),
CONST64(0xff551c4992e3b66d), CONST64(0x9371a8d9af3b4a3c), CONST64(0x8d7b8af1ff077c72), CONST64(0x898c860a140f839d),
CONST64(0x9672a7d5b7314321), CONST64(0x8588921a34179fb1), CONST64(0x07f609ffe30ef8e4), CONST64(0x7e2a82a84dfcd633),
CONST64(0x423ec6f8ed84baaf), CONST64(0xe25e3b65cad98728), CONST64(0x6927bb9c25d2f54c), CONST64(0xca4643050a89cfc0),
CONST64(0x140c3c3060282474), CONST64(0xaf65ec890f4326a0), CONST64(0xb868d5bd676d05df), CONST64(0xa361f8992f5b3a8c),
CONST64(0x05030f0c180a091d), CONST64(0x5ec1e22346bc7d18), CONST64(0xf957164182efb87b), CONST64(0x67d6a97ffece1899),
CONST64(0x76d99a4386ec35f0), CONST64(0xe858257dfacd9512), CONST64(0x75d89f478eea32fb), CONST64(0xaa66e38517492fbd),
CONST64(0x64d7ac7bf6c81f92), CONST64(0x4e3ad2e8cd9ca683), CONST64(0x45c8cf070e8a424b), CONST64(0x443cccf0fd88b4b9),
CONST64(0x13fa35cf8326dc90), CONST64(0xa796f462c453c563), CONST64(0xf4a701a651f552a5), CONST64(0xb598c25ab477ef01),
CONST64(0x29ec7b973352be1a), CONST64(0xd5b862daa9b70f7c), CONST64(0x54c7fc3b76a86f22), CONST64(0xefae2c8219c36df6),
CONST64(0xbb69d0b96f6b02d4), CONST64(0xdd4b7a3162a7ecbf), CONST64(0xe0ab3d9631dd76d1), CONST64(0xe6a9379e21d178c7),
CONST64(0xa967e6811f4f28b6), CONST64(0x1e0a2228503c364e), CONST64(0xc9474601028fc8cb), CONST64(0x0bf21defc316e4c8),
CONST64(0xc2b55beec1992c03), CONST64(0x6622aa880dccee6b), CONST64(0x32e556b37b648149), CONST64(0x2fee719f235eb00c),
CONST64(0xdfbe7cc299a31d46), CONST64(0x7d2b87ac45fad138), CONST64(0x9e81bf3e7c21a0e2), CONST64(0x36125a48906c7ea6),
CONST64(0x9883b5366c2daef4), CONST64(0x2d1b776cd85a41f5), CONST64(0x120e363870242a62), CONST64(0x6523af8c05cae960),
CONST64(0x02f506f3fb04f1f9), CONST64(0xcf454c091283c6dd), CONST64(0x6321a58415c6e776), CONST64(0x4fced11f3e9e5071),
CONST64(0xdb49703972abe2a9), CONST64(0x742c9cb07de8c409), CONST64(0x16f93ac39b2cd58d), CONST64(0x37e659bf636e8854),
CONST64(0xc7b654e2d993251e), CONST64(0x782888a05df0d825), CONST64(0x39174b5cb8726581), CONST64(0x9b82b032642ba9ff),
CONST64(0x2e1a7268d05c46fe), CONST64(0x808b9d162c1d96ac), CONST64(0x1ffe21dfa33ec0bc), CONST64(0x838a9812241b91a7),
CONST64(0x1b092d2448363f53), CONST64(0x46c9ca03068c4540), CONST64(0x9487a1264c35b2d8), CONST64(0xd24e6b254ab9f798),
CONST64(0x3ee142a35b7c9d65), CONST64(0x722e96b86de4ca1f), CONST64(0x31e453b773628642), CONST64(0x3de047a7537a9a6e),
CONST64(0x20eb608b0b40ab2b), CONST64(0xad90ea7af447d759), CONST64(0xf1a40eaa49ff5bb8), CONST64(0x221e6678f0445ad2),
CONST64(0x9285ab2e5c39bcce), CONST64(0xa060fd9d275d3d87), CONST64(0x0000000000000000), CONST64(0x6f25b19435defb5a),
CONST64(0x01f403f7f302f6f2), CONST64(0x0ef112e3db1cedd5), CONST64(0xa194fe6ad45fcb75), CONST64(0x1d0b272c583a3145),
CONST64(0x34e75cbb6b688f5f), CONST64(0x9f75bcc98f235610), CONST64(0x2cef749b2b58b707), CONST64(0x5c34e4d0bdb88ce1),
CONST64(0x5331f5c495a697c6), CONST64(0x61d4a377eec2168f), CONST64(0x6dd0b767ceda0aa3), CONST64(0x9786a4224433b5d3),
CONST64(0x827e9be5d7196755), CONST64(0xeaad238e01c964eb), CONST64(0x1afd2ed3bb34c9a1), CONST64(0x7b298da455f6df2e),
CONST64(0x5030f0c09da090cd), CONST64(0x4d3bd7ecc59aa188), CONST64(0xbc9fd9468c65fa30), CONST64(0x15f83fc7932ad286),
CONST64(0x57c6f93f7eae6829), CONST64(0x35135f4c986a79ad), CONST64(0x0a061e183014123a), CONST64(0x0f051114281e1b27),
CONST64(0x52c5f63366a46134), CONST64(0x33115544886677bb), CONST64(0x9977b6c19f2f5806), CONST64(0x847c91edc7156943),
CONST64(0x8e7a8ff5f7017b79), CONST64(0x887885fde70d756f), CONST64(0x5a36eed8adb482f7), CONST64(0x241c6c70e04854c4),
CONST64(0x4b39dde4d596af9e), CONST64(0xeb592079f2cb9219), CONST64(0x28187860c05048e8), CONST64(0xfa5613458ae9bf70),
CONST64(0xc8b345f6f18d3e39), CONST64(0xcdb04afae9873724), CONST64(0x6c24b4903dd8fc51), CONST64(0x6020a0801dc0e07d),
CONST64(0xcbb240f2f98b3932), CONST64(0xab92e072e44bd94f), CONST64(0xf8a315b671ed4e89), CONST64(0x5dc0e7274eba7a13),
CONST64(0xcc44490d1a85c1d6), CONST64(0xa662f79537513391), CONST64(0x30105040806070b0), CONST64(0xc1b45eeac99f2b08),
CONST64(0x9184ae2a543fbbc5), CONST64(0xc54352112297d4e7), CONST64(0xa893e576ec4dde44), CONST64(0x5bc2ed2f5eb67405),
CONST64(0xde4a7f356aa1ebb4), CONST64(0xdabd73ce81a9145b), CONST64(0x8c8f89060c058a80), CONST64(0x772d99b475eec302),
CONST64(0xd9bc76ca89af1350), CONST64(0xb99cd64a946ff32d), CONST64(0xbe6adfb577610bc9), CONST64(0xc0405d1d3a9dddfa),
CONST64(0x4ccfd41b3698577a), CONST64(0xfba210b279eb4982), CONST64(0x9d80ba3a7427a7e9), CONST64(0xd14f6e2142bff093),
CONST64(0x211f637cf8425dd9), CONST64(0x43cac50f1e864c5d), CONST64(0xe3aa389239db71da), CONST64(0xc64257152a91d3ec),
};
static const ulong64 T2[256] = {
CONST64(0xd268bad36a01bbb9), CONST64(0x4d1954fc66b1e59a), CONST64(0xbc932f7114cde265), CONST64(0xcdb9749c1b512587),
CONST64(0x510253f557a4f7a2), CONST64(0x6bb8d368be03d0d6), CONST64(0x6fbdd26bb504d6de), CONST64(0x29644dd785feb352),
CONST64(0x5d0d50f04aadfdba), CONST64(0x8a26ace9e063cf09), CONST64(0x0e838d8a9684091c), CONST64(0xc679bfdc4d1aa591),
CONST64(0xddad7090374d3da7), CONST64(0x550752f65ca3f1aa), CONST64(0x52c89ab317e17ba4), CONST64(0x2d614cd48ef9b55a),
CONST64(0x8f65ea2320ac4603), CONST64(0x73a6d5628411c4e6), CONST64(0x66f197a468c255cc), CONST64(0x63b2d16ea80ddcc6),
CONST64(0xccff3355d099aa85), CONST64(0x590851f341aafbb2), CONST64(0x712a5bed0f9cc7e2), CONST64(0xa204a6f7ae55f359),
CONST64(0x5f81de7fc120febe), CONST64(0x3d7548d8a2e5ad7a), CONST64(0x9a32a8e5cc7fd729), CONST64(0x5ec799b60ae871bc),
CONST64(0x4b90db70e63be096), CONST64(0xc8fa3256db9eac8d), CONST64(0xe651b7c4152295d1), CONST64(0xd72bfc19aace32b3),
CONST64(0xab48e3387393704b), CONST64(0x42dc9ebf3bfd6384), CONST64(0x7eef91ae52d041fc), CONST64(0x56cd9bb01ce67dac),
CONST64(0xaf4de23b78947643), CONST64(0xd66dbbd06106bdb1), CONST64(0x195841c3f1da9b32), CONST64(0xa5cb6eb2e5177957),
CONST64(0xae0ba5f2b35cf941), CONST64(0x0bc0cb40564b8016), CONST64(0xb1da6bbdc20c677f), CONST64(0x6efb95a27ecc59dc),
CONST64(0xbe1fa1fe9f40e161), CONST64(0xeb18f308c3e310cb), CONST64(0xfe4fb1ce2f3081e1), CONST64(0x080a0206160e0c10),
CONST64(0x17dbcc49675e922e), CONST64(0x37f3c4513f66a26e), CONST64(0x74691d27cf534ee8), CONST64(0x5044143c9c6c78a0),
CONST64(0x2be8c3580e73b056), CONST64(0x91f263a59a34573f), CONST64(0x4f95da73ed3ce69e), CONST64(0x69345de7358ed3d2),
CONST64(0x613e5fe12380dfc2), CONST64(0x578bdc79d72ef2ae), CONST64(0xe9947d87486e13cf), CONST64(0x13decd4a6c599426),
CONST64(0xe19e7f815e601fdf), CONST64(0x752f5aee049bc1ea), CONST64(0xadc16cb4f3197547), CONST64(0x6d315ce43e89d5da),
CONST64(0xfb0cf704efff08eb), CONST64(0x98be266a47f2d42d), CONST64(0xdb24ff1cb7c738ab), CONST64(0x937eed2a11b9543b),
CONST64(0x876fe82536a24a13), CONST64(0x4ed39dba26f4699c), CONST64(0xa1ce6fb1ee107f5f), CONST64(0x028c8e8f8b8d0304),
CONST64(0x647d192be34f56c8), CONST64(0xba1aa0fd9447e769), CONST64(0xe717f00ddeea1ad3), CONST64(0x1e978986ba98113c),
CONST64(0x3c330f11692d2278), CONST64(0x1c1b070931151238), CONST64(0x8629afecfd6ac511), CONST64(0xcb30fb109bdb208b),
CONST64(0x2028081858383040), CONST64(0x5441153f976b7ea8), CONST64(0x34390d177f232e68), CONST64(0x1014040c2c1c1820),
CONST64(0x040501030b070608), CONST64(0x8de964acab214507), CONST64(0x5b84df7cca27f8b6), CONST64(0xc5b3769a0d5f2997),
CONST64(0xf980798b64720bef), CONST64(0x538edd7adc29f4a6), CONST64(0xf4c93d47b2b38ef5), CONST64(0x584e163a8a6274b0),
CONST64(0xfcc33f41a4bd82e5), CONST64(0xdceb3759fc85b2a5), CONST64(0xa9c46db7f81e734f), CONST64(0xe0d8384895a890dd),
CONST64(0xde67b9d67708b1a1), CONST64(0xd1a273952a4437bf), CONST64(0x836ae9263da54c1b), CONST64(0xd4e1355fea8bbeb5),
CONST64(0x491c55ff6db6e392), CONST64(0xd9a871933c4a3baf), CONST64(0xf18a7b8d727c07ff), CONST64(0x0a868c899d830f14),
CONST64(0xd5a77296214331b7), CONST64(0x1a928885b19f1734), CONST64(0xff09f607e4f80ee3), CONST64(0xa8822a7e33d6fc4d),
CONST64(0xf8c63e42afba84ed), CONST64(0x653b5ee22887d9ca), CONST64(0x9cbb27694cf5d225), CONST64(0x054346cac0cf890a),
CONST64(0x303c0c1474242860), CONST64(0x89ec65afa026430f), CONST64(0xbdd568b8df056d67), CONST64(0x99f861a38c3a5b2f),
CONST64(0x0c0f03051d090a18), CONST64(0x23e2c15e187dbc46), CONST64(0x411657f97bb8ef82), CONST64(0x7fa9d6679918cefe),
CONST64(0x439ad976f035ec86), CONST64(0x7d2558e81295cdfa), CONST64(0x479fd875fb32ea8e), CONST64(0x85e366aabd2f4917),
CONST64(0x7bacd764921fc8f6), CONST64(0xe8d23a4e83a69ccd), CONST64(0x07cfc8454b428a0e), CONST64(0xf0cc3c44b9b488fd),
CONST64(0xcf35fa1390dc2683), CONST64(0x62f496a763c553c4), CONST64(0xa601a7f4a552f551), CONST64(0x5ac298b501ef77b4),
CONST64(0x977bec291abe5233), CONST64(0xda62b8d57c0fb7a9), CONST64(0x3bfcc754226fa876), CONST64(0x822caeeff66dc319),
CONST64(0xb9d069bbd4026b6f), CONST64(0x317a4bddbfeca762), CONST64(0x963dabe0d176dd31), CONST64(0x9e37a9e6c778d121),
CONST64(0x81e667a9b6284f1f), CONST64(0x28220a1e4e363c50), CONST64(0x014647c9cbc88f02), CONST64(0xef1df20bc8e416c3),
CONST64(0xee5bb5c2032c99c1), CONST64(0x88aa22666beecc0d), CONST64(0xb356e5324981647b), CONST64(0x9f71ee2f0cb05e23),
CONST64(0xc27cbedf461da399), CONST64(0xac872b7d38d1fa45), CONST64(0x3ebf819ee2a0217c), CONST64(0x485a1236a67e6c90),
CONST64(0x36b58398f4ae2d6c), CONST64(0x6c771b2df5415ad8), CONST64(0x38360e12622a2470), CONST64(0x8caf236560e9ca05),
CONST64(0xf306f502f9f104fb), CONST64(0x094c45cfddc68312), CONST64(0x84a5216376e7c615), CONST64(0x1fd1ce4f71509e3e),
CONST64(0x397049dba9e2ab72), CONST64(0xb09c2c7409c4e87d), CONST64(0xc33af9168dd52c9b), CONST64(0xbf59e63754886e63),
CONST64(0xe254b6c71e2593d9), CONST64(0xa088287825d8f05d), CONST64(0x5c4b1739816572b8), CONST64(0x32b0829bffa92b64),
CONST64(0x68721a2efe465cd0), CONST64(0x169d8b80ac961d2c), CONST64(0xdf21fe1fbcc03ea3), CONST64(0x12988a83a7911b24),
CONST64(0x242d091b533f3648), CONST64(0x03cac94640458c06), CONST64(0x26a18794d8b2354c), CONST64(0x256b4ed298f7b94a),
CONST64(0xa342e13e659d7c5b), CONST64(0xb8962e721fcae46d), CONST64(0xb753e43142866273), CONST64(0xa747e03d6e9a7a53),
CONST64(0x8b60eb202bab400b), CONST64(0x7aea90ad59d747f4), CONST64(0xaa0ea4f1b85bff49), CONST64(0x78661e22d25a44f0),
CONST64(0x2eab8592cebc395c), CONST64(0x9dfd60a0873d5d27), CONST64(0x0000000000000000), CONST64(0x94b1256f5afbde35),
CONST64(0xf703f401f2f602f3), CONST64(0xe312f10ed5ed1cdb), CONST64(0x6afe94a175cb5fd4), CONST64(0x2c270b1d45313a58),
CONST64(0xbb5ce7345f8f686b), CONST64(0xc9bc759f1056238f), CONST64(0x9b74ef2c07b7582b), CONST64(0xd0e4345ce18cb8bd),
CONST64(0xc4f53153c697a695), CONST64(0x77a3d4618f16c2ee), CONST64(0x67b7d06da30adace), CONST64(0x22a48697d3b53344),
CONST64(0xe59b7e82556719d7), CONST64(0x8e23adeaeb64c901), CONST64(0xd32efd1aa1c934bb), CONST64(0xa48d297b2edff655),
CONST64(0xc0f03050cd90a09d), CONST64(0xecd73b4d88a19ac5), CONST64(0x46d99fbc30fa658c), CONST64(0xc73ff81586d22a93),
CONST64(0x3ff9c6572968ae7e), CONST64(0x4c5f1335ad796a98), CONST64(0x181e060a3a121430), CONST64(0x1411050f271b1e28),
CONST64(0x33f6c5523461a466), CONST64(0x44551133bb776688), CONST64(0xc1b6779906582f9f), CONST64(0xed917c84436915c7),
CONST64(0xf58f7a8e797b01f7), CONST64(0xfd8578886f750de7), CONST64(0xd8ee365af782b4ad), CONST64(0x706c1c24c45448e0),
CONST64(0xe4dd394b9eaf96d5), CONST64(0x792059eb1992cbf2), CONST64(0x60781828e84850c0), CONST64(0x451356fa70bfe98a),
CONST64(0xf645b3c8393e8df1), CONST64(0xfa4ab0cd243787e9), CONST64(0x90b4246c51fcd83d), CONST64(0x80a020607de0c01d),
CONST64(0xf240b2cb32398bf9), CONST64(0x72e092ab4fd94be4), CONST64(0xb615a3f8894eed71), CONST64(0x27e7c05d137aba4e),
CONST64(0x0d4944ccd6c1851a), CONST64(0x95f762a691335137), CONST64(0x40501030b0706080), CONST64(0xea5eb4c1082b9fc9),
CONST64(0x2aae8491c5bb3f54), CONST64(0x115243c5e7d49722), CONST64(0x76e593a844de4dec), CONST64(0x2fedc25b0574b65e),
CONST64(0x357f4adeb4eba16a), CONST64(0xce73bdda5b14a981), CONST64(0x06898f8c808a050c), CONST64(0xb4992d7702c3ee75),
CONST64(0xca76bcd95013af89), CONST64(0x4ad69cb92df36f94), CONST64(0xb5df6abec90b6177), CONST64(0x1d5d40c0fadd9d3a),
CONST64(0x1bd4cf4c7a579836), CONST64(0xb210a2fb8249eb79), CONST64(0x3aba809de9a72774), CONST64(0x216e4fd193f0bf42),
CONST64(0x7c631f21d95d42f8), CONST64(0x0fc5ca435d4c861e), CONST64(0x9238aae3da71db39), CONST64(0x155742c6ecd3912a),
};
static const ulong64 T3[256] = {
CONST64(0x68d2d3ba016ab9bb), CONST64(0x194dfc54b1669ae5), CONST64(0x93bc712fcd1465e2), CONST64(0xb9cd9c74511b8725),
CONST64(0x0251f553a457a2f7), CONST64(0xb86b68d303bed6d0), CONST64(0xbd6f6bd204b5ded6), CONST64(0x6429d74dfe8552b3),
CONST64(0x0d5df050ad4abafd), CONST64(0x268ae9ac63e009cf), CONST64(0x830e8a8d84961c09), CONST64(0x79c6dcbf1a4d91a5),
CONST64(0xaddd90704d37a73d), CONST64(0x0755f652a35caaf1), CONST64(0xc852b39ae117a47b), CONST64(0x612dd44cf98e5ab5),
CONST64(0x658f23eaac200346), CONST64(0xa67362d51184e6c4), CONST64(0xf166a497c268cc55), CONST64(0xb2636ed10da8c6dc),
CONST64(0xffcc553399d085aa), CONST64(0x0859f351aa41b2fb), CONST64(0x2a71ed5b9c0fe2c7), CONST64(0x04a2f7a655ae59f3),
CONST64(0x815f7fde20c1befe), CONST64(0x753dd848e5a27aad), CONST64(0x329ae5a87fcc29d7), CONST64(0xc75eb699e80abc71),
CONST64(0x904b70db3be696e0), CONST64(0xfac856329edb8dac), CONST64(0x51e6c4b72215d195), CONST64(0x2bd719fcceaab332),
CONST64(0x48ab38e393734b70), CONST64(0xdc42bf9efd3b8463), CONST64(0xef7eae91d052fc41), CONST64(0xcd56b09be61cac7d),
CONST64(0x4daf3be294784376), CONST64(0x6dd6d0bb0661b1bd), CONST64(0x5819c341daf1329b), CONST64(0xcba5b26e17e55779),
CONST64(0x0baef2a55cb341f9), CONST64(0xc00b40cb4b561680), CONST64(0xdab1bd6b0cc27f67), CONST64(0xfb6ea295cc7edc59),
CONST64(0x1fbefea1409f61e1), CONST64(0x18eb08f3e3c3cb10), CONST64(0x4ffeceb1302fe181), CONST64(0x0a0806020e16100c),
CONST64(0xdb1749cc5e672e92), CONST64(0xf33751c4663f6ea2), CONST64(0x6974271d53cfe84e), CONST64(0x44503c146c9ca078),
CONST64(0xe82b58c3730e56b0), CONST64(0xf291a563349a3f57), CONST64(0x954f73da3ced9ee6), CONST64(0x3469e75d8e35d2d3),
CONST64(0x3e61e15f8023c2df), CONST64(0x8b5779dc2ed7aef2), CONST64(0x94e9877d6e48cf13), CONST64(0xde134acd596c2694),
CONST64(0x9ee1817f605edf1f), CONST64(0x2f75ee5a9b04eac1), CONST64(0xc1adb46c19f34775), CONST64(0x316de45c893edad5),
CONST64(0x0cfb04f7ffefeb08), CONST64(0xbe986a26f2472dd4), CONST64(0x24db1cffc7b7ab38), CONST64(0x7e932aedb9113b54),
CONST64(0x6f8725e8a236134a), CONST64(0xd34eba9df4269c69), CONST64(0xcea1b16f10ee5f7f), CONST64(0x8c028f8e8d8b0403),
CONST64(0x7d642b194fe3c856), CONST64(0x1abafda0479469e7), CONST64(0x17e70df0eaded31a), CONST64(0x971e868998ba3c11),
CONST64(0x333c110f2d697822), CONST64(0x1b1c090715313812), CONST64(0x2986ecaf6afd11c5), CONST64(0x30cb10fbdb9b8b20),
CONST64(0x2820180838584030), CONST64(0x41543f156b97a87e), CONST64(0x3934170d237f682e), CONST64(0x14100c041c2c2018),
CONST64(0x05040301070b0806), CONST64(0xe98dac6421ab0745), CONST64(0x845b7cdf27cab6f8), CONST64(0xb3c59a765f0d9729),
CONST64(0x80f98b797264ef0b), CONST64(0x8e537add29dca6f4), CONST64(0xc9f4473db3b2f58e), CONST64(0x4e583a16628ab074),
CONST64(0xc3fc413fbda4e582), CONST64(0xebdc593785fca5b2), CONST64(0xc4a9b76d1ef84f73), CONST64(0xd8e04838a895dd90),
CONST64(0x67ded6b90877a1b1), CONST64(0xa2d19573442abf37), CONST64(0x6a8326e9a53d1b4c), CONST64(0xe1d45f358beab5be),
CONST64(0x1c49ff55b66d92e3), CONST64(0xa8d993714a3caf3b), CONST64(0x8af18d7b7c72ff07), CONST64(0x860a898c839d140f),
CONST64(0xa7d596724321b731), CONST64(0x921a85889fb13417), CONST64(0x09ff07f6f8e4e30e), CONST64(0x82a87e2ad6334dfc),
CONST64(0xc6f8423ebaafed84), CONST64(0x3b65e25e8728cad9), CONST64(0xbb9c6927f54c25d2), CONST64(0x4305ca46cfc00a89),
CONST64(0x3c30140c24746028), CONST64(0xec89af6526a00f43), CONST64(0xd5bdb86805df676d), CONST64(0xf899a3613a8c2f5b),
CONST64(0x0f0c0503091d180a), CONST64(0xe2235ec17d1846bc), CONST64(0x1641f957b87b82ef), CONST64(0xa97f67d61899fece),
CONST64(0x9a4376d935f086ec), CONST64(0x257de8589512facd), CONST64(0x9f4775d832fb8eea), CONST64(0xe385aa662fbd1749),
CONST64(0xac7b64d71f92f6c8), CONST64(0xd2e84e3aa683cd9c), CONST64(0xcf0745c8424b0e8a), CONST64(0xccf0443cb4b9fd88),
CONST64(0x35cf13fadc908326), CONST64(0xf462a796c563c453), CONST64(0x01a6f4a752a551f5), CONST64(0xc25ab598ef01b477),
CONST64(0x7b9729ecbe1a3352), CONST64(0x62dad5b80f7ca9b7), CONST64(0xfc3b54c76f2276a8), CONST64(0x2c82efae6df619c3),
CONST64(0xd0b9bb6902d46f6b), CONST64(0x7a31dd4becbf62a7), CONST64(0x3d96e0ab76d131dd), CONST64(0x379ee6a978c721d1),
CONST64(0xe681a96728b61f4f), CONST64(0x22281e0a364e503c), CONST64(0x4601c947c8cb028f), CONST64(0x1def0bf2e4c8c316),
CONST64(0x5beec2b52c03c199), CONST64(0xaa886622ee6b0dcc), CONST64(0x56b332e581497b64), CONST64(0x719f2feeb00c235e),
CONST64(0x7cc2dfbe1d4699a3), CONST64(0x87ac7d2bd13845fa), CONST64(0xbf3e9e81a0e27c21), CONST64(0x5a4836127ea6906c),
CONST64(0xb5369883aef46c2d), CONST64(0x776c2d1b41f5d85a), CONST64(0x3638120e2a627024), CONST64(0xaf8c6523e96005ca),
CONST64(0x06f302f5f1f9fb04), CONST64(0x4c09cf45c6dd1283), CONST64(0xa5846321e77615c6), CONST64(0xd11f4fce50713e9e),
CONST64(0x7039db49e2a972ab), CONST64(0x9cb0742cc4097de8), CONST64(0x3ac316f9d58d9b2c), CONST64(0x59bf37e68854636e),
CONST64(0x54e2c7b6251ed993), CONST64(0x88a07828d8255df0), CONST64(0x4b5c39176581b872), CONST64(0xb0329b82a9ff642b),
CONST64(0x72682e1a46fed05c), CONST64(0x9d16808b96ac2c1d), CONST64(0x21df1ffec0bca33e), CONST64(0x9812838a91a7241b),
CONST64(0x2d241b093f534836), CONST64(0xca0346c94540068c), CONST64(0xa1269487b2d84c35), CONST64(0x6b25d24ef7984ab9),
CONST64(0x42a33ee19d655b7c), CONST64(0x96b8722eca1f6de4), CONST64(0x53b731e486427362), CONST64(0x47a73de09a6e537a),
CONST64(0x608b20ebab2b0b40), CONST64(0xea7aad90d759f447), CONST64(0x0eaaf1a45bb849ff), CONST64(0x6678221e5ad2f044),
CONST64(0xab2e9285bcce5c39), CONST64(0xfd9da0603d87275d), CONST64(0x0000000000000000), CONST64(0xb1946f25fb5a35de),
CONST64(0x03f701f4f6f2f302), CONST64(0x12e30ef1edd5db1c), CONST64(0xfe6aa194cb75d45f), CONST64(0x272c1d0b3145583a),
CONST64(0x5cbb34e78f5f6b68), CONST64(0xbcc99f7556108f23), CONST64(0x749b2cefb7072b58), CONST64(0xe4d05c348ce1bdb8),
CONST64(0xf5c4533197c695a6), CONST64(0xa37761d4168feec2), CONST64(0xb7676dd00aa3ceda), CONST64(0xa4229786b5d34433),
CONST64(0x9be5827e6755d719), CONST64(0x238eeaad64eb01c9), CONST64(0x2ed31afdc9a1bb34), CONST64(0x8da47b29df2e55f6),
CONST64(0xf0c0503090cd9da0), CONST64(0xd7ec4d3ba188c59a), CONST64(0xd946bc9ffa308c65), CONST64(0x3fc715f8d286932a),
CONST64(0xf93f57c668297eae), CONST64(0x5f4c351379ad986a), CONST64(0x1e180a06123a3014), CONST64(0x11140f051b27281e),
CONST64(0xf63352c5613466a4), CONST64(0x5544331177bb8866), CONST64(0xb6c1997758069f2f), CONST64(0x91ed847c6943c715),
CONST64(0x8ff58e7a7b79f701), CONST64(0x85fd8878756fe70d), CONST64(0xeed85a3682f7adb4), CONST64(0x6c70241c54c4e048),
CONST64(0xdde44b39af9ed596), CONST64(0x2079eb599219f2cb), CONST64(0x7860281848e8c050), CONST64(0x1345fa56bf708ae9),
CONST64(0x45f6c8b33e39f18d), CONST64(0x4afacdb03724e987), CONST64(0xb4906c24fc513dd8), CONST64(0xa0806020e07d1dc0),
CONST64(0x40f2cbb23932f98b), CONST64(0xe072ab92d94fe44b), CONST64(0x15b6f8a34e8971ed), CONST64(0xe7275dc07a134eba),
CONST64(0x490dcc44c1d61a85), CONST64(0xf795a66233913751), CONST64(0x5040301070b08060), CONST64(0x5eeac1b42b08c99f),
CONST64(0xae2a9184bbc5543f), CONST64(0x5211c543d4e72297), CONST64(0xe576a893de44ec4d), CONST64(0xed2f5bc274055eb6),
CONST64(0x7f35de4aebb46aa1), CONST64(0x73cedabd145b81a9), CONST64(0x89068c8f8a800c05), CONST64(0x99b4772dc30275ee),
CONST64(0x76cad9bc135089af), CONST64(0xd64ab99cf32d946f), CONST64(0xdfb5be6a0bc97761), CONST64(0x5d1dc040ddfa3a9d),
CONST64(0xd41b4ccf577a3698), CONST64(0x10b2fba2498279eb), CONST64(0xba3a9d80a7e97427), CONST64(0x6e21d14ff09342bf),
CONST64(0x637c211f5dd9f842), CONST64(0xc50f43ca4c5d1e86), CONST64(0x3892e3aa71da39db), CONST64(0x5715c642d3ec2a91),
};
static const ulong64 T4[256] = {
CONST64(0xbbb96a01bad3d268), CONST64(0xe59a66b154fc4d19), CONST64(0xe26514cd2f71bc93), CONST64(0x25871b51749ccdb9),
CONST64(0xf7a257a453f55102), CONST64(0xd0d6be03d3686bb8), CONST64(0xd6deb504d26b6fbd), CONST64(0xb35285fe4dd72964),
CONST64(0xfdba4aad50f05d0d), CONST64(0xcf09e063ace98a26), CONST64(0x091c96848d8a0e83), CONST64(0xa5914d1abfdcc679),
CONST64(0x3da7374d7090ddad), CONST64(0xf1aa5ca352f65507), CONST64(0x7ba417e19ab352c8), CONST64(0xb55a8ef94cd42d61),
CONST64(0x460320acea238f65), CONST64(0xc4e68411d56273a6), CONST64(0x55cc68c297a466f1), CONST64(0xdcc6a80dd16e63b2),
CONST64(0xaa85d0993355ccff), CONST64(0xfbb241aa51f35908), CONST64(0xc7e20f9c5bed712a), CONST64(0xf359ae55a6f7a204),
CONST64(0xfebec120de7f5f81), CONST64(0xad7aa2e548d83d75), CONST64(0xd729cc7fa8e59a32), CONST64(0x71bc0ae899b65ec7),
CONST64(0xe096e63bdb704b90), CONST64(0xac8ddb9e3256c8fa), CONST64(0x95d11522b7c4e651), CONST64(0x32b3aacefc19d72b),
CONST64(0x704b7393e338ab48), CONST64(0x63843bfd9ebf42dc), CONST64(0x41fc52d091ae7eef), CONST64(0x7dac1ce69bb056cd),
CONST64(0x76437894e23baf4d), CONST64(0xbdb16106bbd0d66d), CONST64(0x9b32f1da41c31958), CONST64(0x7957e5176eb2a5cb),
CONST64(0xf941b35ca5f2ae0b), CONST64(0x8016564bcb400bc0), CONST64(0x677fc20c6bbdb1da), CONST64(0x59dc7ecc95a26efb),
CONST64(0xe1619f40a1febe1f), CONST64(0x10cbc3e3f308eb18), CONST64(0x81e12f30b1cefe4f), CONST64(0x0c10160e0206080a),
CONST64(0x922e675ecc4917db), CONST64(0xa26e3f66c45137f3), CONST64(0x4ee8cf531d277469), CONST64(0x78a09c6c143c5044),
CONST64(0xb0560e73c3582be8), CONST64(0x573f9a3463a591f2), CONST64(0xe69eed3cda734f95), CONST64(0xd3d2358e5de76934),
CONST64(0xdfc223805fe1613e), CONST64(0xf2aed72edc79578b), CONST64(0x13cf486e7d87e994), CONST64(0x94266c59cd4a13de),
CONST64(0x1fdf5e607f81e19e), CONST64(0xc1ea049b5aee752f), CONST64(0x7547f3196cb4adc1), CONST64(0xd5da3e895ce46d31),
CONST64(0x08ebeffff704fb0c), CONST64(0xd42d47f2266a98be), CONST64(0x38abb7c7ff1cdb24), CONST64(0x543b11b9ed2a937e),
CONST64(0x4a1336a2e825876f), CONST64(0x699c26f49dba4ed3), CONST64(0x7f5fee106fb1a1ce), CONST64(0x03048b8d8e8f028c),
CONST64(0x56c8e34f192b647d), CONST64(0xe7699447a0fdba1a), CONST64(0x1ad3deeaf00de717), CONST64(0x113cba9889861e97),
CONST64(0x2278692d0f113c33), CONST64(0x1238311507091c1b), CONST64(0xc511fd6aafec8629), CONST64(0x208b9bdbfb10cb30),
CONST64(0x3040583808182028), CONST64(0x7ea8976b153f5441), CONST64(0x2e687f230d173439), CONST64(0x18202c1c040c1014),
CONST64(0x06080b0701030405), CONST64(0x4507ab2164ac8de9), CONST64(0xf8b6ca27df7c5b84), CONST64(0x29970d5f769ac5b3),
CONST64(0x0bef6472798bf980), CONST64(0xf4a6dc29dd7a538e), CONST64(0x8ef5b2b33d47f4c9), CONST64(0x74b08a62163a584e),
CONST64(0x82e5a4bd3f41fcc3), CONST64(0xb2a5fc853759dceb), CONST64(0x734ff81e6db7a9c4), CONST64(0x90dd95a83848e0d8),
CONST64(0xb1a17708b9d6de67), CONST64(0x37bf2a447395d1a2), CONST64(0x4c1b3da5e926836a), CONST64(0xbeb5ea8b355fd4e1),
CONST64(0xe3926db655ff491c), CONST64(0x3baf3c4a7193d9a8), CONST64(0x07ff727c7b8df18a), CONST64(0x0f149d838c890a86),
CONST64(0x31b721437296d5a7), CONST64(0x1734b19f88851a92), CONST64(0x0ee3e4f8f607ff09), CONST64(0xfc4d33d62a7ea882),
CONST64(0x84edafba3e42f8c6), CONST64(0xd9ca28875ee2653b), CONST64(0xd2254cf527699cbb), CONST64(0x890ac0cf46ca0543),
CONST64(0x286074240c14303c), CONST64(0x430fa02665af89ec), CONST64(0x6d67df0568b8bdd5), CONST64(0x5b2f8c3a61a399f8),
CONST64(0x0a181d0903050c0f), CONST64(0xbc46187dc15e23e2), CONST64(0xef827bb857f94116), CONST64(0xcefe9918d6677fa9),
CONST64(0xec86f035d976439a), CONST64(0xcdfa129558e87d25), CONST64(0xea8efb32d875479f), CONST64(0x4917bd2f66aa85e3),
CONST64(0xc8f6921fd7647bac), CONST64(0x9ccd83a63a4ee8d2), CONST64(0x8a0e4b42c84507cf), CONST64(0x88fdb9b43c44f0cc),
CONST64(0x268390dcfa13cf35), CONST64(0x53c463c596a762f4), CONST64(0xf551a552a7f4a601), CONST64(0x77b401ef98b55ac2),
CONST64(0x52331abeec29977b), CONST64(0xb7a97c0fb8d5da62), CONST64(0xa876226fc7543bfc), CONST64(0xc319f66daeef822c),
CONST64(0x6b6fd40269bbb9d0), CONST64(0xa762bfec4bdd317a), CONST64(0xdd31d176abe0963d), CONST64(0xd121c778a9e69e37),
CONST64(0x4f1fb62867a981e6), CONST64(0x3c504e360a1e2822), CONST64(0x8f02cbc847c90146), CONST64(0x16c3c8e4f20bef1d),
CONST64(0x99c1032cb5c2ee5b), CONST64(0xcc0d6bee226688aa), CONST64(0x647b4981e532b356), CONST64(0x5e230cb0ee2f9f71),
CONST64(0xa399461dbedfc27c), CONST64(0xfa4538d12b7dac87), CONST64(0x217ce2a0819e3ebf), CONST64(0x6c90a67e1236485a),
CONST64(0x2d6cf4ae839836b5), CONST64(0x5ad8f5411b2d6c77), CONST64(0x2470622a0e123836), CONST64(0xca0560e923658caf),
CONST64(0x04fbf9f1f502f306), CONST64(0x8312ddc645cf094c), CONST64(0xc61576e7216384a5), CONST64(0x9e3e7150ce4f1fd1),
CONST64(0xab72a9e249db3970), CONST64(0xe87d09c42c74b09c), CONST64(0x2c9b8dd5f916c33a), CONST64(0x6e635488e637bf59),
CONST64(0x93d91e25b6c7e254), CONST64(0xf05d25d82878a088), CONST64(0x72b8816517395c4b), CONST64(0x2b64ffa9829b32b0),
CONST64(0x5cd0fe461a2e6872), CONST64(0x1d2cac968b80169d), CONST64(0x3ea3bcc0fe1fdf21), CONST64(0x1b24a7918a831298),
CONST64(0x3648533f091b242d), CONST64(0x8c064045c94603ca), CONST64(0x354cd8b2879426a1), CONST64(0xb94a98f74ed2256b),
CONST64(0x7c5b659de13ea342), CONST64(0xe46d1fca2e72b896), CONST64(0x62734286e431b753), CONST64(0x7a536e9ae03da747),
CONST64(0x400b2babeb208b60), CONST64(0x47f459d790ad7aea), CONST64(0xff49b85ba4f1aa0e), CONST64(0x44f0d25a1e227866),
CONST64(0x395ccebc85922eab), CONST64(0x5d27873d60a09dfd), CONST64(0x0000000000000000), CONST64(0xde355afb256f94b1),
CONST64(0x02f3f2f6f401f703), CONST64(0x1cdbd5edf10ee312), CONST64(0x5fd475cb94a16afe), CONST64(0x3a5845310b1d2c27),
CONST64(0x686b5f8fe734bb5c), CONST64(0x238f1056759fc9bc), CONST64(0x582b07b7ef2c9b74), CONST64(0xb8bde18c345cd0e4),
CONST64(0xa695c6973153c4f5), CONST64(0xc2ee8f16d46177a3), CONST64(0xdacea30ad06d67b7), CONST64(0x3344d3b5869722a4),
CONST64(0x19d755677e82e59b), CONST64(0xc901eb64adea8e23), CONST64(0x34bba1c9fd1ad32e), CONST64(0xf6552edf297ba48d),
CONST64(0xa09dcd903050c0f0), CONST64(0x9ac588a13b4decd7), CONST64(0x658c30fa9fbc46d9), CONST64(0x2a9386d2f815c73f),
CONST64(0xae7e2968c6573ff9), CONST64(0x6a98ad7913354c5f), CONST64(0x14303a12060a181e), CONST64(0x1e28271b050f1411),
CONST64(0xa4663461c55233f6), CONST64(0x6688bb7711334455), CONST64(0x2f9f06587799c1b6), CONST64(0x15c743697c84ed91),
CONST64(0x01f7797b7a8ef58f), CONST64(0x0de76f757888fd85), CONST64(0xb4adf782365ad8ee), CONST64(0x48e0c4541c24706c),
CONST64(0x96d59eaf394be4dd), CONST64(0xcbf2199259eb7920), CONST64(0x50c0e84818286078), CONST64(0xe98a70bf56fa4513),
CONST64(0x8df1393eb3c8f645), CONST64(0x87e92437b0cdfa4a), CONST64(0xd83d51fc246c90b4), CONST64(0xc01d7de0206080a0),
CONST64(0x8bf93239b2cbf240), CONST64(0x4be44fd992ab72e0), CONST64(0xed71894ea3f8b615), CONST64(0xba4e137ac05d27e7),
CONST64(0x851ad6c144cc0d49), CONST64(0x5137913362a695f7), CONST64(0x6080b07010304050), CONST64(0x9fc9082bb4c1ea5e),
CONST64(0x3f54c5bb84912aae), CONST64(0x9722e7d443c51152), CONST64(0x4dec44de93a876e5), CONST64(0xb65e0574c25b2fed),
CONST64(0xa16ab4eb4ade357f), CONST64(0xa9815b14bddace73), CONST64(0x050c808a8f8c0689), CONST64(0xee7502c32d77b499),
CONST64(0xaf895013bcd9ca76), CONST64(0x6f942df39cb94ad6), CONST64(0x6177c90b6abeb5df), CONST64(0x9d3afadd40c01d5d),
CONST64(0x98367a57cf4c1bd4), CONST64(0xeb798249a2fbb210), CONST64(0x2774e9a7809d3aba), CONST64(0xbf4293f04fd1216e),
CONST64(0x42f8d95d1f217c63), CONST64(0x861e5d4cca430fc5), CONST64(0xdb39da71aae39238), CONST64(0x912aecd342c61557),
};
static const ulong64 T5[256] = {
CONST64(0xb9bb016ad3ba68d2), CONST64(0x9ae5b166fc54194d), CONST64(0x65e2cd14712f93bc), CONST64(0x8725511b9c74b9cd),
CONST64(0xa2f7a457f5530251), CONST64(0xd6d003be68d3b86b), CONST64(0xded604b56bd2bd6f), CONST64(0x52b3fe85d74d6429),
CONST64(0xbafdad4af0500d5d), CONST64(0x09cf63e0e9ac268a), CONST64(0x1c0984968a8d830e), CONST64(0x91a51a4ddcbf79c6),
CONST64(0xa73d4d379070addd), CONST64(0xaaf1a35cf6520755), CONST64(0xa47be117b39ac852), CONST64(0x5ab5f98ed44c612d),
CONST64(0x0346ac2023ea658f), CONST64(0xe6c4118462d5a673), CONST64(0xcc55c268a497f166), CONST64(0xc6dc0da86ed1b263),
CONST64(0x85aa99d05533ffcc), CONST64(0xb2fbaa41f3510859), CONST64(0xe2c79c0fed5b2a71), CONST64(0x59f355aef7a604a2),
CONST64(0xbefe20c17fde815f), CONST64(0x7aade5a2d848753d), CONST64(0x29d77fcce5a8329a), CONST64(0xbc71e80ab699c75e),
CONST64(0x96e03be670db904b), CONST64(0x8dac9edb5632fac8), CONST64(0xd1952215c4b751e6), CONST64(0xb332ceaa19fc2bd7),
CONST64(0x4b70937338e348ab), CONST64(0x8463fd3bbf9edc42), CONST64(0xfc41d052ae91ef7e), CONST64(0xac7de61cb09bcd56),
CONST64(0x437694783be24daf), CONST64(0xb1bd0661d0bb6dd6), CONST64(0x329bdaf1c3415819), CONST64(0x577917e5b26ecba5),
CONST64(0x41f95cb3f2a50bae), CONST64(0x16804b5640cbc00b), CONST64(0x7f670cc2bd6bdab1), CONST64(0xdc59cc7ea295fb6e),
CONST64(0x61e1409ffea11fbe), CONST64(0xcb10e3c308f318eb), CONST64(0xe181302fceb14ffe), CONST64(0x100c0e1606020a08),
CONST64(0x2e925e6749ccdb17), CONST64(0x6ea2663f51c4f337), CONST64(0xe84e53cf271d6974), CONST64(0xa0786c9c3c144450),
CONST64(0x56b0730e58c3e82b), CONST64(0x3f57349aa563f291), CONST64(0x9ee63ced73da954f), CONST64(0xd2d38e35e75d3469),
CONST64(0xc2df8023e15f3e61), CONST64(0xaef22ed779dc8b57), CONST64(0xcf136e48877d94e9), CONST64(0x2694596c4acdde13),
CONST64(0xdf1f605e817f9ee1), CONST64(0xeac19b04ee5a2f75), CONST64(0x477519f3b46cc1ad), CONST64(0xdad5893ee45c316d),
CONST64(0xeb08ffef04f70cfb), CONST64(0x2dd4f2476a26be98), CONST64(0xab38c7b71cff24db), CONST64(0x3b54b9112aed7e93),
CONST64(0x134aa23625e86f87), CONST64(0x9c69f426ba9dd34e), CONST64(0x5f7f10eeb16fcea1), CONST64(0x04038d8b8f8e8c02),
CONST64(0xc8564fe32b197d64), CONST64(0x69e74794fda01aba), CONST64(0xd31aeade0df017e7), CONST64(0x3c1198ba8689971e),
CONST64(0x78222d69110f333c), CONST64(0x3812153109071b1c), CONST64(0x11c56afdecaf2986), CONST64(0x8b20db9b10fb30cb),
CONST64(0x4030385818082820), CONST64(0xa87e6b973f154154), CONST64(0x682e237f170d3934), CONST64(0x20181c2c0c041410),
CONST64(0x0806070b03010504), CONST64(0x074521abac64e98d), CONST64(0xb6f827ca7cdf845b), CONST64(0x97295f0d9a76b3c5),
CONST64(0xef0b72648b7980f9), CONST64(0xa6f429dc7add8e53), CONST64(0xf58eb3b2473dc9f4), CONST64(0xb074628a3a164e58),
CONST64(0xe582bda4413fc3fc), CONST64(0xa5b285fc5937ebdc), CONST64(0x4f731ef8b76dc4a9), CONST64(0xdd90a8954838d8e0),
CONST64(0xa1b10877d6b967de), CONST64(0xbf37442a9573a2d1), CONST64(0x1b4ca53d26e96a83), CONST64(0xb5be8bea5f35e1d4),
CONST64(0x92e3b66dff551c49), CONST64(0xaf3b4a3c9371a8d9), CONST64(0xff077c728d7b8af1), CONST64(0x140f839d898c860a),
CONST64(0xb73143219672a7d5), CONST64(0x34179fb18588921a), CONST64(0xe30ef8e407f609ff), CONST64(0x4dfcd6337e2a82a8),
CONST64(0xed84baaf423ec6f8), CONST64(0xcad98728e25e3b65), CONST64(0x25d2f54c6927bb9c), CONST64(0x0a89cfc0ca464305),
CONST64(0x60282474140c3c30), CONST64(0x0f4326a0af65ec89), CONST64(0x676d05dfb868d5bd), CONST64(0x2f5b3a8ca361f899),
CONST64(0x180a091d05030f0c), CONST64(0x46bc7d185ec1e223), CONST64(0x82efb87bf9571641), CONST64(0xfece189967d6a97f),
CONST64(0x86ec35f076d99a43), CONST64(0xfacd9512e858257d), CONST64(0x8eea32fb75d89f47), CONST64(0x17492fbdaa66e385),
CONST64(0xf6c81f9264d7ac7b), CONST64(0xcd9ca6834e3ad2e8), CONST64(0x0e8a424b45c8cf07), CONST64(0xfd88b4b9443cccf0),
CONST64(0x8326dc9013fa35cf), CONST64(0xc453c563a796f462), CONST64(0x51f552a5f4a701a6), CONST64(0xb477ef01b598c25a),
CONST64(0x3352be1a29ec7b97), CONST64(0xa9b70f7cd5b862da), CONST64(0x76a86f2254c7fc3b), CONST64(0x19c36df6efae2c82),
CONST64(0x6f6b02d4bb69d0b9), CONST64(0x62a7ecbfdd4b7a31), CONST64(0x31dd76d1e0ab3d96), CONST64(0x21d178c7e6a9379e),
CONST64(0x1f4f28b6a967e681), CONST64(0x503c364e1e0a2228), CONST64(0x028fc8cbc9474601), CONST64(0xc316e4c80bf21def),
CONST64(0xc1992c03c2b55bee), CONST64(0x0dccee6b6622aa88), CONST64(0x7b64814932e556b3), CONST64(0x235eb00c2fee719f),
CONST64(0x99a31d46dfbe7cc2), CONST64(0x45fad1387d2b87ac), CONST64(0x7c21a0e29e81bf3e), CONST64(0x906c7ea636125a48),
CONST64(0x6c2daef49883b536), CONST64(0xd85a41f52d1b776c), CONST64(0x70242a62120e3638), CONST64(0x05cae9606523af8c),
CONST64(0xfb04f1f902f506f3), CONST64(0x1283c6ddcf454c09), CONST64(0x15c6e7766321a584), CONST64(0x3e9e50714fced11f),
CONST64(0x72abe2a9db497039), CONST64(0x7de8c409742c9cb0), CONST64(0x9b2cd58d16f93ac3), CONST64(0x636e885437e659bf),
CONST64(0xd993251ec7b654e2), CONST64(0x5df0d825782888a0), CONST64(0xb872658139174b5c), CONST64(0x642ba9ff9b82b032),
CONST64(0xd05c46fe2e1a7268), CONST64(0x2c1d96ac808b9d16), CONST64(0xa33ec0bc1ffe21df), CONST64(0x241b91a7838a9812),
CONST64(0x48363f531b092d24), CONST64(0x068c454046c9ca03), CONST64(0x4c35b2d89487a126), CONST64(0x4ab9f798d24e6b25),
CONST64(0x5b7c9d653ee142a3), CONST64(0x6de4ca1f722e96b8), CONST64(0x7362864231e453b7), CONST64(0x537a9a6e3de047a7),
CONST64(0x0b40ab2b20eb608b), CONST64(0xf447d759ad90ea7a), CONST64(0x49ff5bb8f1a40eaa), CONST64(0xf0445ad2221e6678),
CONST64(0x5c39bcce9285ab2e), CONST64(0x275d3d87a060fd9d), CONST64(0x0000000000000000), CONST64(0x35defb5a6f25b194),
CONST64(0xf302f6f201f403f7), CONST64(0xdb1cedd50ef112e3), CONST64(0xd45fcb75a194fe6a), CONST64(0x583a31451d0b272c),
CONST64(0x6b688f5f34e75cbb), CONST64(0x8f2356109f75bcc9), CONST64(0x2b58b7072cef749b), CONST64(0xbdb88ce15c34e4d0),
CONST64(0x95a697c65331f5c4), CONST64(0xeec2168f61d4a377), CONST64(0xceda0aa36dd0b767), CONST64(0x4433b5d39786a422),
CONST64(0xd7196755827e9be5), CONST64(0x01c964ebeaad238e), CONST64(0xbb34c9a11afd2ed3), CONST64(0x55f6df2e7b298da4),
CONST64(0x9da090cd5030f0c0), CONST64(0xc59aa1884d3bd7ec), CONST64(0x8c65fa30bc9fd946), CONST64(0x932ad28615f83fc7),
CONST64(0x7eae682957c6f93f), CONST64(0x986a79ad35135f4c), CONST64(0x3014123a0a061e18), CONST64(0x281e1b270f051114),
CONST64(0x66a4613452c5f633), CONST64(0x886677bb33115544), CONST64(0x9f2f58069977b6c1), CONST64(0xc7156943847c91ed),
CONST64(0xf7017b798e7a8ff5), CONST64(0xe70d756f887885fd), CONST64(0xadb482f75a36eed8), CONST64(0xe04854c4241c6c70),
CONST64(0xd596af9e4b39dde4), CONST64(0xf2cb9219eb592079), CONST64(0xc05048e828187860), CONST64(0x8ae9bf70fa561345),
CONST64(0xf18d3e39c8b345f6), CONST64(0xe9873724cdb04afa), CONST64(0x3dd8fc516c24b490), CONST64(0x1dc0e07d6020a080),
CONST64(0xf98b3932cbb240f2), CONST64(0xe44bd94fab92e072), CONST64(0x71ed4e89f8a315b6), CONST64(0x4eba7a135dc0e727),
CONST64(0x1a85c1d6cc44490d), CONST64(0x37513391a662f795), CONST64(0x806070b030105040), CONST64(0xc99f2b08c1b45eea),
CONST64(0x543fbbc59184ae2a), CONST64(0x2297d4e7c5435211), CONST64(0xec4dde44a893e576), CONST64(0x5eb674055bc2ed2f),
CONST64(0x6aa1ebb4de4a7f35), CONST64(0x81a9145bdabd73ce), CONST64(0x0c058a808c8f8906), CONST64(0x75eec302772d99b4),
CONST64(0x89af1350d9bc76ca), CONST64(0x946ff32db99cd64a), CONST64(0x77610bc9be6adfb5), CONST64(0x3a9dddfac0405d1d),
CONST64(0x3698577a4ccfd41b), CONST64(0x79eb4982fba210b2), CONST64(0x7427a7e99d80ba3a), CONST64(0x42bff093d14f6e21),
CONST64(0xf8425dd9211f637c), CONST64(0x1e864c5d43cac50f), CONST64(0x39db71dae3aa3892), CONST64(0x2a91d3ecc6425715),
};
static const ulong64 T6[256] = {
CONST64(0x6a01bbb9d268bad3), CONST64(0x66b1e59a4d1954fc), CONST64(0x14cde265bc932f71), CONST64(0x1b512587cdb9749c),
CONST64(0x57a4f7a2510253f5), CONST64(0xbe03d0d66bb8d368), CONST64(0xb504d6de6fbdd26b), CONST64(0x85feb35229644dd7),
CONST64(0x4aadfdba5d0d50f0), CONST64(0xe063cf098a26ace9), CONST64(0x9684091c0e838d8a), CONST64(0x4d1aa591c679bfdc),
CONST64(0x374d3da7ddad7090), CONST64(0x5ca3f1aa550752f6), CONST64(0x17e17ba452c89ab3), CONST64(0x8ef9b55a2d614cd4),
CONST64(0x20ac46038f65ea23), CONST64(0x8411c4e673a6d562), CONST64(0x68c255cc66f197a4), CONST64(0xa80ddcc663b2d16e),
CONST64(0xd099aa85ccff3355), CONST64(0x41aafbb2590851f3), CONST64(0x0f9cc7e2712a5bed), CONST64(0xae55f359a204a6f7),
CONST64(0xc120febe5f81de7f), CONST64(0xa2e5ad7a3d7548d8), CONST64(0xcc7fd7299a32a8e5), CONST64(0x0ae871bc5ec799b6),
CONST64(0xe63be0964b90db70), CONST64(0xdb9eac8dc8fa3256), CONST64(0x152295d1e651b7c4), CONST64(0xaace32b3d72bfc19),
CONST64(0x7393704bab48e338), CONST64(0x3bfd638442dc9ebf), CONST64(0x52d041fc7eef91ae), CONST64(0x1ce67dac56cd9bb0),
CONST64(0x78947643af4de23b), CONST64(0x6106bdb1d66dbbd0), CONST64(0xf1da9b32195841c3), CONST64(0xe5177957a5cb6eb2),
CONST64(0xb35cf941ae0ba5f2), CONST64(0x564b80160bc0cb40), CONST64(0xc20c677fb1da6bbd), CONST64(0x7ecc59dc6efb95a2),
CONST64(0x9f40e161be1fa1fe), CONST64(0xc3e310cbeb18f308), CONST64(0x2f3081e1fe4fb1ce), CONST64(0x160e0c10080a0206),
CONST64(0x675e922e17dbcc49), CONST64(0x3f66a26e37f3c451), CONST64(0xcf534ee874691d27), CONST64(0x9c6c78a05044143c),
CONST64(0x0e73b0562be8c358), CONST64(0x9a34573f91f263a5), CONST64(0xed3ce69e4f95da73), CONST64(0x358ed3d269345de7),
CONST64(0x2380dfc2613e5fe1), CONST64(0xd72ef2ae578bdc79), CONST64(0x486e13cfe9947d87), CONST64(0x6c59942613decd4a),
CONST64(0x5e601fdfe19e7f81), CONST64(0x049bc1ea752f5aee), CONST64(0xf3197547adc16cb4), CONST64(0x3e89d5da6d315ce4),
CONST64(0xefff08ebfb0cf704), CONST64(0x47f2d42d98be266a), CONST64(0xb7c738abdb24ff1c), CONST64(0x11b9543b937eed2a),
CONST64(0x36a24a13876fe825), CONST64(0x26f4699c4ed39dba), CONST64(0xee107f5fa1ce6fb1), CONST64(0x8b8d0304028c8e8f),
CONST64(0xe34f56c8647d192b), CONST64(0x9447e769ba1aa0fd), CONST64(0xdeea1ad3e717f00d), CONST64(0xba98113c1e978986),
CONST64(0x692d22783c330f11), CONST64(0x311512381c1b0709), CONST64(0xfd6ac5118629afec), CONST64(0x9bdb208bcb30fb10),
CONST64(0x5838304020280818), CONST64(0x976b7ea85441153f), CONST64(0x7f232e6834390d17), CONST64(0x2c1c18201014040c),
CONST64(0x0b07060804050103), CONST64(0xab2145078de964ac), CONST64(0xca27f8b65b84df7c), CONST64(0x0d5f2997c5b3769a),
CONST64(0x64720beff980798b), CONST64(0xdc29f4a6538edd7a), CONST64(0xb2b38ef5f4c93d47), CONST64(0x8a6274b0584e163a),
CONST64(0xa4bd82e5fcc33f41), CONST64(0xfc85b2a5dceb3759), CONST64(0xf81e734fa9c46db7), CONST64(0x95a890dde0d83848),
CONST64(0x7708b1a1de67b9d6), CONST64(0x2a4437bfd1a27395), CONST64(0x3da54c1b836ae926), CONST64(0xea8bbeb5d4e1355f),
CONST64(0x6db6e392491c55ff), CONST64(0x3c4a3bafd9a87193), CONST64(0x727c07fff18a7b8d), CONST64(0x9d830f140a868c89),
CONST64(0x214331b7d5a77296), CONST64(0xb19f17341a928885), CONST64(0xe4f80ee3ff09f607), CONST64(0x33d6fc4da8822a7e),
CONST64(0xafba84edf8c63e42), CONST64(0x2887d9ca653b5ee2), CONST64(0x4cf5d2259cbb2769), CONST64(0xc0cf890a054346ca),
CONST64(0x74242860303c0c14), CONST64(0xa026430f89ec65af), CONST64(0xdf056d67bdd568b8), CONST64(0x8c3a5b2f99f861a3),
CONST64(0x1d090a180c0f0305), CONST64(0x187dbc4623e2c15e), CONST64(0x7bb8ef82411657f9), CONST64(0x9918cefe7fa9d667),
CONST64(0xf035ec86439ad976), CONST64(0x1295cdfa7d2558e8), CONST64(0xfb32ea8e479fd875), CONST64(0xbd2f491785e366aa),
CONST64(0x921fc8f67bacd764), CONST64(0x83a69ccde8d23a4e), CONST64(0x4b428a0e07cfc845), CONST64(0xb9b488fdf0cc3c44),
CONST64(0x90dc2683cf35fa13), CONST64(0x63c553c462f496a7), CONST64(0xa552f551a601a7f4), CONST64(0x01ef77b45ac298b5),
CONST64(0x1abe5233977bec29), CONST64(0x7c0fb7a9da62b8d5), CONST64(0x226fa8763bfcc754), CONST64(0xf66dc319822caeef),
CONST64(0xd4026b6fb9d069bb), CONST64(0xbfeca762317a4bdd), CONST64(0xd176dd31963dabe0), CONST64(0xc778d1219e37a9e6),
CONST64(0xb6284f1f81e667a9), CONST64(0x4e363c5028220a1e), CONST64(0xcbc88f02014647c9), CONST64(0xc8e416c3ef1df20b),
CONST64(0x032c99c1ee5bb5c2), CONST64(0x6beecc0d88aa2266), CONST64(0x4981647bb356e532), CONST64(0x0cb05e239f71ee2f),
CONST64(0x461da399c27cbedf), CONST64(0x38d1fa45ac872b7d), CONST64(0xe2a0217c3ebf819e), CONST64(0xa67e6c90485a1236),
CONST64(0xf4ae2d6c36b58398), CONST64(0xf5415ad86c771b2d), CONST64(0x622a247038360e12), CONST64(0x60e9ca058caf2365),
CONST64(0xf9f104fbf306f502), CONST64(0xddc68312094c45cf), CONST64(0x76e7c61584a52163), CONST64(0x71509e3e1fd1ce4f),
CONST64(0xa9e2ab72397049db), CONST64(0x09c4e87db09c2c74), CONST64(0x8dd52c9bc33af916), CONST64(0x54886e63bf59e637),
CONST64(0x1e2593d9e254b6c7), CONST64(0x25d8f05da0882878), CONST64(0x816572b85c4b1739), CONST64(0xffa92b6432b0829b),
CONST64(0xfe465cd068721a2e), CONST64(0xac961d2c169d8b80), CONST64(0xbcc03ea3df21fe1f), CONST64(0xa7911b2412988a83),
CONST64(0x533f3648242d091b), CONST64(0x40458c0603cac946), CONST64(0xd8b2354c26a18794), CONST64(0x98f7b94a256b4ed2),
CONST64(0x659d7c5ba342e13e), CONST64(0x1fcae46db8962e72), CONST64(0x42866273b753e431), CONST64(0x6e9a7a53a747e03d),
CONST64(0x2bab400b8b60eb20), CONST64(0x59d747f47aea90ad), CONST64(0xb85bff49aa0ea4f1), CONST64(0xd25a44f078661e22),
CONST64(0xcebc395c2eab8592), CONST64(0x873d5d279dfd60a0), CONST64(0x0000000000000000), CONST64(0x5afbde3594b1256f),
CONST64(0xf2f602f3f703f401), CONST64(0xd5ed1cdbe312f10e), CONST64(0x75cb5fd46afe94a1), CONST64(0x45313a582c270b1d),
CONST64(0x5f8f686bbb5ce734), CONST64(0x1056238fc9bc759f), CONST64(0x07b7582b9b74ef2c), CONST64(0xe18cb8bdd0e4345c),
CONST64(0xc697a695c4f53153), CONST64(0x8f16c2ee77a3d461), CONST64(0xa30adace67b7d06d), CONST64(0xd3b5334422a48697),
CONST64(0x556719d7e59b7e82), CONST64(0xeb64c9018e23adea), CONST64(0xa1c934bbd32efd1a), CONST64(0x2edff655a48d297b),
CONST64(0xcd90a09dc0f03050), CONST64(0x88a19ac5ecd73b4d), CONST64(0x30fa658c46d99fbc), CONST64(0x86d22a93c73ff815),
CONST64(0x2968ae7e3ff9c657), CONST64(0xad796a984c5f1335), CONST64(0x3a121430181e060a), CONST64(0x271b1e281411050f),
CONST64(0x3461a46633f6c552), CONST64(0xbb77668844551133), CONST64(0x06582f9fc1b67799), CONST64(0x436915c7ed917c84),
CONST64(0x797b01f7f58f7a8e), CONST64(0x6f750de7fd857888), CONST64(0xf782b4add8ee365a), CONST64(0xc45448e0706c1c24),
CONST64(0x9eaf96d5e4dd394b), CONST64(0x1992cbf2792059eb), CONST64(0xe84850c060781828), CONST64(0x70bfe98a451356fa),
CONST64(0x393e8df1f645b3c8), CONST64(0x243787e9fa4ab0cd), CONST64(0x51fcd83d90b4246c), CONST64(0x7de0c01d80a02060),
CONST64(0x32398bf9f240b2cb), CONST64(0x4fd94be472e092ab), CONST64(0x894eed71b615a3f8), CONST64(0x137aba4e27e7c05d),
CONST64(0xd6c1851a0d4944cc), CONST64(0x9133513795f762a6), CONST64(0xb070608040501030), CONST64(0x082b9fc9ea5eb4c1),
CONST64(0xc5bb3f542aae8491), CONST64(0xe7d49722115243c5), CONST64(0x44de4dec76e593a8), CONST64(0x0574b65e2fedc25b),
CONST64(0xb4eba16a357f4ade), CONST64(0x5b14a981ce73bdda), CONST64(0x808a050c06898f8c), CONST64(0x02c3ee75b4992d77),
CONST64(0x5013af89ca76bcd9), CONST64(0x2df36f944ad69cb9), CONST64(0xc90b6177b5df6abe), CONST64(0xfadd9d3a1d5d40c0),
CONST64(0x7a5798361bd4cf4c), CONST64(0x8249eb79b210a2fb), CONST64(0xe9a727743aba809d), CONST64(0x93f0bf42216e4fd1),
CONST64(0xd95d42f87c631f21), CONST64(0x5d4c861e0fc5ca43), CONST64(0xda71db399238aae3), CONST64(0xecd3912a155742c6),
};
static const ulong64 T7[256] = {
CONST64(0x016ab9bb68d2d3ba), CONST64(0xb1669ae5194dfc54), CONST64(0xcd1465e293bc712f), CONST64(0x511b8725b9cd9c74),
CONST64(0xa457a2f70251f553), CONST64(0x03bed6d0b86b68d3), CONST64(0x04b5ded6bd6f6bd2), CONST64(0xfe8552b36429d74d),
CONST64(0xad4abafd0d5df050), CONST64(0x63e009cf268ae9ac), CONST64(0x84961c09830e8a8d), CONST64(0x1a4d91a579c6dcbf),
CONST64(0x4d37a73daddd9070), CONST64(0xa35caaf10755f652), CONST64(0xe117a47bc852b39a), CONST64(0xf98e5ab5612dd44c),
CONST64(0xac200346658f23ea), CONST64(0x1184e6c4a67362d5), CONST64(0xc268cc55f166a497), CONST64(0x0da8c6dcb2636ed1),
CONST64(0x99d085aaffcc5533), CONST64(0xaa41b2fb0859f351), CONST64(0x9c0fe2c72a71ed5b), CONST64(0x55ae59f304a2f7a6),
CONST64(0x20c1befe815f7fde), CONST64(0xe5a27aad753dd848), CONST64(0x7fcc29d7329ae5a8), CONST64(0xe80abc71c75eb699),
CONST64(0x3be696e0904b70db), CONST64(0x9edb8dacfac85632), CONST64(0x2215d19551e6c4b7), CONST64(0xceaab3322bd719fc),
CONST64(0x93734b7048ab38e3), CONST64(0xfd3b8463dc42bf9e), CONST64(0xd052fc41ef7eae91), CONST64(0xe61cac7dcd56b09b),
CONST64(0x947843764daf3be2), CONST64(0x0661b1bd6dd6d0bb), CONST64(0xdaf1329b5819c341), CONST64(0x17e55779cba5b26e),
CONST64(0x5cb341f90baef2a5), CONST64(0x4b561680c00b40cb), CONST64(0x0cc27f67dab1bd6b), CONST64(0xcc7edc59fb6ea295),
CONST64(0x409f61e11fbefea1), CONST64(0xe3c3cb1018eb08f3), CONST64(0x302fe1814ffeceb1), CONST64(0x0e16100c0a080602),
CONST64(0x5e672e92db1749cc), CONST64(0x663f6ea2f33751c4), CONST64(0x53cfe84e6974271d), CONST64(0x6c9ca07844503c14),
CONST64(0x730e56b0e82b58c3), CONST64(0x349a3f57f291a563), CONST64(0x3ced9ee6954f73da), CONST64(0x8e35d2d33469e75d),
CONST64(0x8023c2df3e61e15f), CONST64(0x2ed7aef28b5779dc), CONST64(0x6e48cf1394e9877d), CONST64(0x596c2694de134acd),
CONST64(0x605edf1f9ee1817f), CONST64(0x9b04eac12f75ee5a), CONST64(0x19f34775c1adb46c), CONST64(0x893edad5316de45c),
CONST64(0xffefeb080cfb04f7), CONST64(0xf2472dd4be986a26), CONST64(0xc7b7ab3824db1cff), CONST64(0xb9113b547e932aed),
CONST64(0xa236134a6f8725e8), CONST64(0xf4269c69d34eba9d), CONST64(0x10ee5f7fcea1b16f), CONST64(0x8d8b04038c028f8e),
CONST64(0x4fe3c8567d642b19), CONST64(0x479469e71abafda0), CONST64(0xeaded31a17e70df0), CONST64(0x98ba3c11971e8689),
CONST64(0x2d697822333c110f), CONST64(0x153138121b1c0907), CONST64(0x6afd11c52986ecaf), CONST64(0xdb9b8b2030cb10fb),
CONST64(0x3858403028201808), CONST64(0x6b97a87e41543f15), CONST64(0x237f682e3934170d), CONST64(0x1c2c201814100c04),
CONST64(0x070b080605040301), CONST64(0x21ab0745e98dac64), CONST64(0x27cab6f8845b7cdf), CONST64(0x5f0d9729b3c59a76),
CONST64(0x7264ef0b80f98b79), CONST64(0x29dca6f48e537add), CONST64(0xb3b2f58ec9f4473d), CONST64(0x628ab0744e583a16),
CONST64(0xbda4e582c3fc413f), CONST64(0x85fca5b2ebdc5937), CONST64(0x1ef84f73c4a9b76d), CONST64(0xa895dd90d8e04838),
CONST64(0x0877a1b167ded6b9), CONST64(0x442abf37a2d19573), CONST64(0xa53d1b4c6a8326e9), CONST64(0x8beab5bee1d45f35),
CONST64(0xb66d92e31c49ff55), CONST64(0x4a3caf3ba8d99371), CONST64(0x7c72ff078af18d7b), CONST64(0x839d140f860a898c),
CONST64(0x4321b731a7d59672), CONST64(0x9fb13417921a8588), CONST64(0xf8e4e30e09ff07f6), CONST64(0xd6334dfc82a87e2a),
CONST64(0xbaafed84c6f8423e), CONST64(0x8728cad93b65e25e), CONST64(0xf54c25d2bb9c6927), CONST64(0xcfc00a894305ca46),
CONST64(0x247460283c30140c), CONST64(0x26a00f43ec89af65), CONST64(0x05df676dd5bdb868), CONST64(0x3a8c2f5bf899a361),
CONST64(0x091d180a0f0c0503), CONST64(0x7d1846bce2235ec1), CONST64(0xb87b82ef1641f957), CONST64(0x1899fecea97f67d6),
CONST64(0x35f086ec9a4376d9), CONST64(0x9512facd257de858), CONST64(0x32fb8eea9f4775d8), CONST64(0x2fbd1749e385aa66),
CONST64(0x1f92f6c8ac7b64d7), CONST64(0xa683cd9cd2e84e3a), CONST64(0x424b0e8acf0745c8), CONST64(0xb4b9fd88ccf0443c),
CONST64(0xdc90832635cf13fa), CONST64(0xc563c453f462a796), CONST64(0x52a551f501a6f4a7), CONST64(0xef01b477c25ab598),
CONST64(0xbe1a33527b9729ec), CONST64(0x0f7ca9b762dad5b8), CONST64(0x6f2276a8fc3b54c7), CONST64(0x6df619c32c82efae),
CONST64(0x02d46f6bd0b9bb69), CONST64(0xecbf62a77a31dd4b), CONST64(0x76d131dd3d96e0ab), CONST64(0x78c721d1379ee6a9),
CONST64(0x28b61f4fe681a967), CONST64(0x364e503c22281e0a), CONST64(0xc8cb028f4601c947), CONST64(0xe4c8c3161def0bf2),
CONST64(0x2c03c1995beec2b5), CONST64(0xee6b0dccaa886622), CONST64(0x81497b6456b332e5), CONST64(0xb00c235e719f2fee),
CONST64(0x1d4699a37cc2dfbe), CONST64(0xd13845fa87ac7d2b), CONST64(0xa0e27c21bf3e9e81), CONST64(0x7ea6906c5a483612),
CONST64(0xaef46c2db5369883), CONST64(0x41f5d85a776c2d1b), CONST64(0x2a6270243638120e), CONST64(0xe96005caaf8c6523),
CONST64(0xf1f9fb0406f302f5), CONST64(0xc6dd12834c09cf45), CONST64(0xe77615c6a5846321), CONST64(0x50713e9ed11f4fce),
CONST64(0xe2a972ab7039db49), CONST64(0xc4097de89cb0742c), CONST64(0xd58d9b2c3ac316f9), CONST64(0x8854636e59bf37e6),
CONST64(0x251ed99354e2c7b6), CONST64(0xd8255df088a07828), CONST64(0x6581b8724b5c3917), CONST64(0xa9ff642bb0329b82),
CONST64(0x46fed05c72682e1a), CONST64(0x96ac2c1d9d16808b), CONST64(0xc0bca33e21df1ffe), CONST64(0x91a7241b9812838a),
CONST64(0x3f5348362d241b09), CONST64(0x4540068cca0346c9), CONST64(0xb2d84c35a1269487), CONST64(0xf7984ab96b25d24e),
CONST64(0x9d655b7c42a33ee1), CONST64(0xca1f6de496b8722e), CONST64(0x8642736253b731e4), CONST64(0x9a6e537a47a73de0),
CONST64(0xab2b0b40608b20eb), CONST64(0xd759f447ea7aad90), CONST64(0x5bb849ff0eaaf1a4), CONST64(0x5ad2f0446678221e),
CONST64(0xbcce5c39ab2e9285), CONST64(0x3d87275dfd9da060), CONST64(0x0000000000000000), CONST64(0xfb5a35deb1946f25),
CONST64(0xf6f2f30203f701f4), CONST64(0xedd5db1c12e30ef1), CONST64(0xcb75d45ffe6aa194), CONST64(0x3145583a272c1d0b),
CONST64(0x8f5f6b685cbb34e7), CONST64(0x56108f23bcc99f75), CONST64(0xb7072b58749b2cef), CONST64(0x8ce1bdb8e4d05c34),
CONST64(0x97c695a6f5c45331), CONST64(0x168feec2a37761d4), CONST64(0x0aa3cedab7676dd0), CONST64(0xb5d34433a4229786),
CONST64(0x6755d7199be5827e), CONST64(0x64eb01c9238eeaad), CONST64(0xc9a1bb342ed31afd), CONST64(0xdf2e55f68da47b29),
CONST64(0x90cd9da0f0c05030), CONST64(0xa188c59ad7ec4d3b), CONST64(0xfa308c65d946bc9f), CONST64(0xd286932a3fc715f8),
CONST64(0x68297eaef93f57c6), CONST64(0x79ad986a5f4c3513), CONST64(0x123a30141e180a06), CONST64(0x1b27281e11140f05),
CONST64(0x613466a4f63352c5), CONST64(0x77bb886655443311), CONST64(0x58069f2fb6c19977), CONST64(0x6943c71591ed847c),
CONST64(0x7b79f7018ff58e7a), CONST64(0x756fe70d85fd8878), CONST64(0x82f7adb4eed85a36), CONST64(0x54c4e0486c70241c),
CONST64(0xaf9ed596dde44b39), CONST64(0x9219f2cb2079eb59), CONST64(0x48e8c05078602818), CONST64(0xbf708ae91345fa56),
CONST64(0x3e39f18d45f6c8b3), CONST64(0x3724e9874afacdb0), CONST64(0xfc513dd8b4906c24), CONST64(0xe07d1dc0a0806020),
CONST64(0x3932f98b40f2cbb2), CONST64(0xd94fe44be072ab92), CONST64(0x4e8971ed15b6f8a3), CONST64(0x7a134ebae7275dc0),
CONST64(0xc1d61a85490dcc44), CONST64(0x33913751f795a662), CONST64(0x70b0806050403010), CONST64(0x2b08c99f5eeac1b4),
CONST64(0xbbc5543fae2a9184), CONST64(0xd4e722975211c543), CONST64(0xde44ec4de576a893), CONST64(0x74055eb6ed2f5bc2),
CONST64(0xebb46aa17f35de4a), CONST64(0x145b81a973cedabd), CONST64(0x8a800c0589068c8f), CONST64(0xc30275ee99b4772d),
CONST64(0x135089af76cad9bc), CONST64(0xf32d946fd64ab99c), CONST64(0x0bc97761dfb5be6a), CONST64(0xddfa3a9d5d1dc040),
CONST64(0x577a3698d41b4ccf), CONST64(0x498279eb10b2fba2), CONST64(0xa7e97427ba3a9d80), CONST64(0xf09342bf6e21d14f),
CONST64(0x5dd9f842637c211f), CONST64(0x4c5d1e86c50f43ca), CONST64(0x71da39db3892e3aa), CONST64(0xd3ec2a915715c642),
};
static const ulong64 c[R + 1] = {
CONST64(0xba542f7453d3d24d),
CONST64(0x50ac8dbf70529a4c),
CONST64(0xead597d133515ba6),
CONST64(0xde48a899db32b7fc),
CONST64(0xe39e919be2bb416e),
CONST64(0xa5cb6b95a1f3b102),
CONST64(0xccc41d14c363da5d),
CONST64(0x5fdc7dcd7f5a6c5c),
CONST64(0xf726ffede89d6f8e),
};
/**
Initialize the Khazad block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int r;
const ulong64 *S;
ulong64 K2, K1;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (keylen != 16) {
return CRYPT_INVALID_KEYSIZE;
}
if (num_rounds != 8 && num_rounds != 0) {
return CRYPT_INVALID_ROUNDS;
}
/* use 7th table */
S = T7;
/*
* map unsigned char array cipher key to initial key state (mu):
*/
K2 =
((ulong64)key[ 0] << 56) ^
((ulong64)key[ 1] << 48) ^
((ulong64)key[ 2] << 40) ^
((ulong64)key[ 3] << 32) ^
((ulong64)key[ 4] << 24) ^
((ulong64)key[ 5] << 16) ^
((ulong64)key[ 6] << 8) ^
((ulong64)key[ 7] );
K1 =
((ulong64)key[ 8] << 56) ^
((ulong64)key[ 9] << 48) ^
((ulong64)key[10] << 40) ^
((ulong64)key[11] << 32) ^
((ulong64)key[12] << 24) ^
((ulong64)key[13] << 16) ^
((ulong64)key[14] << 8) ^
((ulong64)key[15] );
/*
* compute the round keys:
*/
for (r = 0; r <= R; r++) {
/*
* K[r] = rho(c[r], K1) ^ K2;
*/
skey->khazad.roundKeyEnc[r] =
T0[(int)(K1 >> 56) ] ^
T1[(int)(K1 >> 48) & 0xff] ^
T2[(int)(K1 >> 40) & 0xff] ^
T3[(int)(K1 >> 32) & 0xff] ^
T4[(int)(K1 >> 24) & 0xff] ^
T5[(int)(K1 >> 16) & 0xff] ^
T6[(int)(K1 >> 8) & 0xff] ^
T7[(int)(K1 ) & 0xff] ^
c[r] ^ K2;
K2 = K1; K1 = skey->khazad.roundKeyEnc[r];
}
/*
* compute the inverse key schedule:
* K'^0 = K^R, K'^R = K^0, K'^r = theta(K^{R-r})
*/
skey->khazad.roundKeyDec[0] = skey->khazad.roundKeyEnc[R];
for (r = 1; r < R; r++) {
K1 = skey->khazad.roundKeyEnc[R - r];
skey->khazad.roundKeyDec[r] =
T0[(int)S[(int)(K1 >> 56) ] & 0xff] ^
T1[(int)S[(int)(K1 >> 48) & 0xff] & 0xff] ^
T2[(int)S[(int)(K1 >> 40) & 0xff] & 0xff] ^
T3[(int)S[(int)(K1 >> 32) & 0xff] & 0xff] ^
T4[(int)S[(int)(K1 >> 24) & 0xff] & 0xff] ^
T5[(int)S[(int)(K1 >> 16) & 0xff] & 0xff] ^
T6[(int)S[(int)(K1 >> 8) & 0xff] & 0xff] ^
T7[(int)S[(int)(K1 ) & 0xff] & 0xff];
}
skey->khazad.roundKeyDec[R] = skey->khazad.roundKeyEnc[0];
return CRYPT_OK;
}
static void khazad_crypt(const unsigned char *plaintext, unsigned char *ciphertext,
const ulong64 *roundKey) {
int r;
ulong64 state;
/*
* map plaintext block to cipher state (mu)
* and add initial round key (sigma[K^0]):
*/
state =
((ulong64)plaintext[0] << 56) ^
((ulong64)plaintext[1] << 48) ^
((ulong64)plaintext[2] << 40) ^
((ulong64)plaintext[3] << 32) ^
((ulong64)plaintext[4] << 24) ^
((ulong64)plaintext[5] << 16) ^
((ulong64)plaintext[6] << 8) ^
((ulong64)plaintext[7] ) ^
roundKey[0];
/*
* R - 1 full rounds:
*/
for (r = 1; r < R; r++) {
state =
T0[(int)(state >> 56) ] ^
T1[(int)(state >> 48) & 0xff] ^
T2[(int)(state >> 40) & 0xff] ^
T3[(int)(state >> 32) & 0xff] ^
T4[(int)(state >> 24) & 0xff] ^
T5[(int)(state >> 16) & 0xff] ^
T6[(int)(state >> 8) & 0xff] ^
T7[(int)(state ) & 0xff] ^
roundKey[r];
}
/*
* last round:
*/
state =
(T0[(int)(state >> 56) ] & CONST64(0xff00000000000000)) ^
(T1[(int)(state >> 48) & 0xff] & CONST64(0x00ff000000000000)) ^
(T2[(int)(state >> 40) & 0xff] & CONST64(0x0000ff0000000000)) ^
(T3[(int)(state >> 32) & 0xff] & CONST64(0x000000ff00000000)) ^
(T4[(int)(state >> 24) & 0xff] & CONST64(0x00000000ff000000)) ^
(T5[(int)(state >> 16) & 0xff] & CONST64(0x0000000000ff0000)) ^
(T6[(int)(state >> 8) & 0xff] & CONST64(0x000000000000ff00)) ^
(T7[(int)(state ) & 0xff] & CONST64(0x00000000000000ff)) ^
roundKey[R];
/*
* map cipher state to ciphertext block (mu^{-1}):
*/
ciphertext[0] = (unsigned char)(state >> 56);
ciphertext[1] = (unsigned char)(state >> 48);
ciphertext[2] = (unsigned char)(state >> 40);
ciphertext[3] = (unsigned char)(state >> 32);
ciphertext[4] = (unsigned char)(state >> 24);
ciphertext[5] = (unsigned char)(state >> 16);
ciphertext[6] = (unsigned char)(state >> 8);
ciphertext[7] = (unsigned char)(state );
}
/**
Encrypts a block of text with Khazad
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
khazad_crypt(pt, ct, skey->khazad.roundKeyEnc);
return CRYPT_OK;
}
/**
Decrypts a block of text with Khazad
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
khazad_crypt(ct, pt, skey->khazad.roundKeyDec);
return CRYPT_OK;
}
/**
Performs a self-test of the Khazad block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int khazad_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct test {
unsigned char pt[8], ct[8], key[16];
} tests[] = {
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x49, 0xA4, 0xCE, 0x32, 0xAC, 0x19, 0x0E, 0x3F },
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
}, {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x64, 0x5D, 0x77, 0x3E, 0x40, 0xAB, 0xDD, 0x53 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }
}, {
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x9E, 0x39, 0x98, 0x64, 0xF7, 0x8E, 0xCA, 0x02 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
}, {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
{ 0xA9, 0xDF, 0x3D, 0x2C, 0x64, 0xD3, 0xEA, 0x28 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
}
};
int x, y;
unsigned char buf[2][8];
symmetric_key skey;
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
khazad_setup(tests[x].key, 16, 0, &skey);
khazad_ecb_encrypt(tests[x].pt, buf[0], &skey);
khazad_ecb_decrypt(buf[0], buf[1], &skey);
if (compare_testvector(buf[0], 8, tests[x].ct, 8, "Khazad Encrypt", x) ||
compare_testvector(buf[1], 8, tests[x].pt, 8, "Khazad Decrypt", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
for (y = 0; y < 1000; y++) khazad_ecb_encrypt(buf[0], buf[0], &skey);
for (y = 0; y < 1000; y++) khazad_ecb_decrypt(buf[0], buf[0], &skey);
if (compare_testvector(buf[0], 8, tests[x].ct, 8, "Khazad 1000", 1000)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
/** Terminate the context
@param skey The scheduled key
*/
void khazad_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int khazad_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize >= 16) {
*keysize = 16;
return CRYPT_OK;
} else {
return CRYPT_INVALID_KEYSIZE;
}
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

376
thirdparty/libtomcrypt/ciphers/kseed.c vendored Normal file
View File

@@ -0,0 +1,376 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file kseed.c
seed implementation of SEED derived from RFC4269
Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_KSEED
const struct ltc_cipher_descriptor kseed_desc = {
"seed",
20,
16, 16, 16, 16,
&kseed_setup,
&kseed_ecb_encrypt,
&kseed_ecb_decrypt,
&kseed_test,
&kseed_done,
&kseed_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static const ulong32 SS0[256] = {
0x2989A1A8UL,0x05858184UL,0x16C6D2D4UL,0x13C3D3D0UL,0x14445054UL,0x1D0D111CUL,0x2C8CA0ACUL,0x25052124UL,
0x1D4D515CUL,0x03434340UL,0x18081018UL,0x1E0E121CUL,0x11415150UL,0x3CCCF0FCUL,0x0ACAC2C8UL,0x23436360UL,
0x28082028UL,0x04444044UL,0x20002020UL,0x1D8D919CUL,0x20C0E0E0UL,0x22C2E2E0UL,0x08C8C0C8UL,0x17071314UL,
0x2585A1A4UL,0x0F8F838CUL,0x03030300UL,0x3B4B7378UL,0x3B8BB3B8UL,0x13031310UL,0x12C2D2D0UL,0x2ECEE2ECUL,
0x30407070UL,0x0C8C808CUL,0x3F0F333CUL,0x2888A0A8UL,0x32023230UL,0x1DCDD1DCUL,0x36C6F2F4UL,0x34447074UL,
0x2CCCE0ECUL,0x15859194UL,0x0B0B0308UL,0x17475354UL,0x1C4C505CUL,0x1B4B5358UL,0x3D8DB1BCUL,0x01010100UL,
0x24042024UL,0x1C0C101CUL,0x33437370UL,0x18889098UL,0x10001010UL,0x0CCCC0CCUL,0x32C2F2F0UL,0x19C9D1D8UL,
0x2C0C202CUL,0x27C7E3E4UL,0x32427270UL,0x03838380UL,0x1B8B9398UL,0x11C1D1D0UL,0x06868284UL,0x09C9C1C8UL,
0x20406060UL,0x10405050UL,0x2383A3A0UL,0x2BCBE3E8UL,0x0D0D010CUL,0x3686B2B4UL,0x1E8E929CUL,0x0F4F434CUL,
0x3787B3B4UL,0x1A4A5258UL,0x06C6C2C4UL,0x38487078UL,0x2686A2A4UL,0x12021210UL,0x2F8FA3ACUL,0x15C5D1D4UL,
0x21416160UL,0x03C3C3C0UL,0x3484B0B4UL,0x01414140UL,0x12425250UL,0x3D4D717CUL,0x0D8D818CUL,0x08080008UL,
0x1F0F131CUL,0x19899198UL,0x00000000UL,0x19091118UL,0x04040004UL,0x13435350UL,0x37C7F3F4UL,0x21C1E1E0UL,
0x3DCDF1FCUL,0x36467274UL,0x2F0F232CUL,0x27072324UL,0x3080B0B0UL,0x0B8B8388UL,0x0E0E020CUL,0x2B8BA3A8UL,
0x2282A2A0UL,0x2E4E626CUL,0x13839390UL,0x0D4D414CUL,0x29496168UL,0x3C4C707CUL,0x09090108UL,0x0A0A0208UL,
0x3F8FB3BCUL,0x2FCFE3ECUL,0x33C3F3F0UL,0x05C5C1C4UL,0x07878384UL,0x14041014UL,0x3ECEF2FCUL,0x24446064UL,
0x1ECED2DCUL,0x2E0E222CUL,0x0B4B4348UL,0x1A0A1218UL,0x06060204UL,0x21012120UL,0x2B4B6368UL,0x26466264UL,
0x02020200UL,0x35C5F1F4UL,0x12829290UL,0x0A8A8288UL,0x0C0C000CUL,0x3383B3B0UL,0x3E4E727CUL,0x10C0D0D0UL,
0x3A4A7278UL,0x07474344UL,0x16869294UL,0x25C5E1E4UL,0x26062224UL,0x00808080UL,0x2D8DA1ACUL,0x1FCFD3DCUL,
0x2181A1A0UL,0x30003030UL,0x37073334UL,0x2E8EA2ACUL,0x36063234UL,0x15051114UL,0x22022220UL,0x38083038UL,
0x34C4F0F4UL,0x2787A3A4UL,0x05454144UL,0x0C4C404CUL,0x01818180UL,0x29C9E1E8UL,0x04848084UL,0x17879394UL,
0x35053134UL,0x0BCBC3C8UL,0x0ECEC2CCUL,0x3C0C303CUL,0x31417170UL,0x11011110UL,0x07C7C3C4UL,0x09898188UL,
0x35457174UL,0x3BCBF3F8UL,0x1ACAD2D8UL,0x38C8F0F8UL,0x14849094UL,0x19495158UL,0x02828280UL,0x04C4C0C4UL,
0x3FCFF3FCUL,0x09494148UL,0x39093138UL,0x27476364UL,0x00C0C0C0UL,0x0FCFC3CCUL,0x17C7D3D4UL,0x3888B0B8UL,
0x0F0F030CUL,0x0E8E828CUL,0x02424240UL,0x23032320UL,0x11819190UL,0x2C4C606CUL,0x1BCBD3D8UL,0x2484A0A4UL,
0x34043034UL,0x31C1F1F0UL,0x08484048UL,0x02C2C2C0UL,0x2F4F636CUL,0x3D0D313CUL,0x2D0D212CUL,0x00404040UL,
0x3E8EB2BCUL,0x3E0E323CUL,0x3C8CB0BCUL,0x01C1C1C0UL,0x2A8AA2A8UL,0x3A8AB2B8UL,0x0E4E424CUL,0x15455154UL,
0x3B0B3338UL,0x1CCCD0DCUL,0x28486068UL,0x3F4F737CUL,0x1C8C909CUL,0x18C8D0D8UL,0x0A4A4248UL,0x16465254UL,
0x37477374UL,0x2080A0A0UL,0x2DCDE1ECUL,0x06464244UL,0x3585B1B4UL,0x2B0B2328UL,0x25456164UL,0x3ACAF2F8UL,
0x23C3E3E0UL,0x3989B1B8UL,0x3181B1B0UL,0x1F8F939CUL,0x1E4E525CUL,0x39C9F1F8UL,0x26C6E2E4UL,0x3282B2B0UL,
0x31013130UL,0x2ACAE2E8UL,0x2D4D616CUL,0x1F4F535CUL,0x24C4E0E4UL,0x30C0F0F0UL,0x0DCDC1CCUL,0x08888088UL,
0x16061214UL,0x3A0A3238UL,0x18485058UL,0x14C4D0D4UL,0x22426260UL,0x29092128UL,0x07070304UL,0x33033330UL,
0x28C8E0E8UL,0x1B0B1318UL,0x05050104UL,0x39497178UL,0x10809090UL,0x2A4A6268UL,0x2A0A2228UL,0x1A8A9298UL
};
static const ulong32 SS1[256] = {
0x38380830UL,0xE828C8E0UL,0x2C2D0D21UL,0xA42686A2UL,0xCC0FCFC3UL,0xDC1ECED2UL,0xB03383B3UL,0xB83888B0UL,
0xAC2F8FA3UL,0x60204060UL,0x54154551UL,0xC407C7C3UL,0x44044440UL,0x6C2F4F63UL,0x682B4B63UL,0x581B4B53UL,
0xC003C3C3UL,0x60224262UL,0x30330333UL,0xB43585B1UL,0x28290921UL,0xA02080A0UL,0xE022C2E2UL,0xA42787A3UL,
0xD013C3D3UL,0x90118191UL,0x10110111UL,0x04060602UL,0x1C1C0C10UL,0xBC3C8CB0UL,0x34360632UL,0x480B4B43UL,
0xEC2FCFE3UL,0x88088880UL,0x6C2C4C60UL,0xA82888A0UL,0x14170713UL,0xC404C4C0UL,0x14160612UL,0xF434C4F0UL,
0xC002C2C2UL,0x44054541UL,0xE021C1E1UL,0xD416C6D2UL,0x3C3F0F33UL,0x3C3D0D31UL,0x8C0E8E82UL,0x98188890UL,
0x28280820UL,0x4C0E4E42UL,0xF436C6F2UL,0x3C3E0E32UL,0xA42585A1UL,0xF839C9F1UL,0x0C0D0D01UL,0xDC1FCFD3UL,
0xD818C8D0UL,0x282B0B23UL,0x64264662UL,0x783A4A72UL,0x24270723UL,0x2C2F0F23UL,0xF031C1F1UL,0x70324272UL,
0x40024242UL,0xD414C4D0UL,0x40014141UL,0xC000C0C0UL,0x70334373UL,0x64274763UL,0xAC2C8CA0UL,0x880B8B83UL,
0xF437C7F3UL,0xAC2D8DA1UL,0x80008080UL,0x1C1F0F13UL,0xC80ACAC2UL,0x2C2C0C20UL,0xA82A8AA2UL,0x34340430UL,
0xD012C2D2UL,0x080B0B03UL,0xEC2ECEE2UL,0xE829C9E1UL,0x5C1D4D51UL,0x94148490UL,0x18180810UL,0xF838C8F0UL,
0x54174753UL,0xAC2E8EA2UL,0x08080800UL,0xC405C5C1UL,0x10130313UL,0xCC0DCDC1UL,0x84068682UL,0xB83989B1UL,
0xFC3FCFF3UL,0x7C3D4D71UL,0xC001C1C1UL,0x30310131UL,0xF435C5F1UL,0x880A8A82UL,0x682A4A62UL,0xB03181B1UL,
0xD011C1D1UL,0x20200020UL,0xD417C7D3UL,0x00020202UL,0x20220222UL,0x04040400UL,0x68284860UL,0x70314171UL,
0x04070703UL,0xD81BCBD3UL,0x9C1D8D91UL,0x98198991UL,0x60214161UL,0xBC3E8EB2UL,0xE426C6E2UL,0x58194951UL,
0xDC1DCDD1UL,0x50114151UL,0x90108090UL,0xDC1CCCD0UL,0x981A8A92UL,0xA02383A3UL,0xA82B8BA3UL,0xD010C0D0UL,
0x80018181UL,0x0C0F0F03UL,0x44074743UL,0x181A0A12UL,0xE023C3E3UL,0xEC2CCCE0UL,0x8C0D8D81UL,0xBC3F8FB3UL,
0x94168692UL,0x783B4B73UL,0x5C1C4C50UL,0xA02282A2UL,0xA02181A1UL,0x60234363UL,0x20230323UL,0x4C0D4D41UL,
0xC808C8C0UL,0x9C1E8E92UL,0x9C1C8C90UL,0x383A0A32UL,0x0C0C0C00UL,0x2C2E0E22UL,0xB83A8AB2UL,0x6C2E4E62UL,
0x9C1F8F93UL,0x581A4A52UL,0xF032C2F2UL,0x90128292UL,0xF033C3F3UL,0x48094941UL,0x78384870UL,0xCC0CCCC0UL,
0x14150511UL,0xF83BCBF3UL,0x70304070UL,0x74354571UL,0x7C3F4F73UL,0x34350531UL,0x10100010UL,0x00030303UL,
0x64244460UL,0x6C2D4D61UL,0xC406C6C2UL,0x74344470UL,0xD415C5D1UL,0xB43484B0UL,0xE82ACAE2UL,0x08090901UL,
0x74364672UL,0x18190911UL,0xFC3ECEF2UL,0x40004040UL,0x10120212UL,0xE020C0E0UL,0xBC3D8DB1UL,0x04050501UL,
0xF83ACAF2UL,0x00010101UL,0xF030C0F0UL,0x282A0A22UL,0x5C1E4E52UL,0xA82989A1UL,0x54164652UL,0x40034343UL,
0x84058581UL,0x14140410UL,0x88098981UL,0x981B8B93UL,0xB03080B0UL,0xE425C5E1UL,0x48084840UL,0x78394971UL,
0x94178793UL,0xFC3CCCF0UL,0x1C1E0E12UL,0x80028282UL,0x20210121UL,0x8C0C8C80UL,0x181B0B13UL,0x5C1F4F53UL,
0x74374773UL,0x54144450UL,0xB03282B2UL,0x1C1D0D11UL,0x24250521UL,0x4C0F4F43UL,0x00000000UL,0x44064642UL,
0xEC2DCDE1UL,0x58184850UL,0x50124252UL,0xE82BCBE3UL,0x7C3E4E72UL,0xD81ACAD2UL,0xC809C9C1UL,0xFC3DCDF1UL,
0x30300030UL,0x94158591UL,0x64254561UL,0x3C3C0C30UL,0xB43686B2UL,0xE424C4E0UL,0xB83B8BB3UL,0x7C3C4C70UL,
0x0C0E0E02UL,0x50104050UL,0x38390931UL,0x24260622UL,0x30320232UL,0x84048480UL,0x68294961UL,0x90138393UL,
0x34370733UL,0xE427C7E3UL,0x24240420UL,0xA42484A0UL,0xC80BCBC3UL,0x50134353UL,0x080A0A02UL,0x84078783UL,
0xD819C9D1UL,0x4C0C4C40UL,0x80038383UL,0x8C0F8F83UL,0xCC0ECEC2UL,0x383B0B33UL,0x480A4A42UL,0xB43787B3UL
};
static const ulong32 SS2[256] = {
0xA1A82989UL,0x81840585UL,0xD2D416C6UL,0xD3D013C3UL,0x50541444UL,0x111C1D0DUL,0xA0AC2C8CUL,0x21242505UL,
0x515C1D4DUL,0x43400343UL,0x10181808UL,0x121C1E0EUL,0x51501141UL,0xF0FC3CCCUL,0xC2C80ACAUL,0x63602343UL,
0x20282808UL,0x40440444UL,0x20202000UL,0x919C1D8DUL,0xE0E020C0UL,0xE2E022C2UL,0xC0C808C8UL,0x13141707UL,
0xA1A42585UL,0x838C0F8FUL,0x03000303UL,0x73783B4BUL,0xB3B83B8BUL,0x13101303UL,0xD2D012C2UL,0xE2EC2ECEUL,
0x70703040UL,0x808C0C8CUL,0x333C3F0FUL,0xA0A82888UL,0x32303202UL,0xD1DC1DCDUL,0xF2F436C6UL,0x70743444UL,
0xE0EC2CCCUL,0x91941585UL,0x03080B0BUL,0x53541747UL,0x505C1C4CUL,0x53581B4BUL,0xB1BC3D8DUL,0x01000101UL,
0x20242404UL,0x101C1C0CUL,0x73703343UL,0x90981888UL,0x10101000UL,0xC0CC0CCCUL,0xF2F032C2UL,0xD1D819C9UL,
0x202C2C0CUL,0xE3E427C7UL,0x72703242UL,0x83800383UL,0x93981B8BUL,0xD1D011C1UL,0x82840686UL,0xC1C809C9UL,
0x60602040UL,0x50501040UL,0xA3A02383UL,0xE3E82BCBUL,0x010C0D0DUL,0xB2B43686UL,0x929C1E8EUL,0x434C0F4FUL,
0xB3B43787UL,0x52581A4AUL,0xC2C406C6UL,0x70783848UL,0xA2A42686UL,0x12101202UL,0xA3AC2F8FUL,0xD1D415C5UL,
0x61602141UL,0xC3C003C3UL,0xB0B43484UL,0x41400141UL,0x52501242UL,0x717C3D4DUL,0x818C0D8DUL,0x00080808UL,
0x131C1F0FUL,0x91981989UL,0x00000000UL,0x11181909UL,0x00040404UL,0x53501343UL,0xF3F437C7UL,0xE1E021C1UL,
0xF1FC3DCDUL,0x72743646UL,0x232C2F0FUL,0x23242707UL,0xB0B03080UL,0x83880B8BUL,0x020C0E0EUL,0xA3A82B8BUL,
0xA2A02282UL,0x626C2E4EUL,0x93901383UL,0x414C0D4DUL,0x61682949UL,0x707C3C4CUL,0x01080909UL,0x02080A0AUL,
0xB3BC3F8FUL,0xE3EC2FCFUL,0xF3F033C3UL,0xC1C405C5UL,0x83840787UL,0x10141404UL,0xF2FC3ECEUL,0x60642444UL,
0xD2DC1ECEUL,0x222C2E0EUL,0x43480B4BUL,0x12181A0AUL,0x02040606UL,0x21202101UL,0x63682B4BUL,0x62642646UL,
0x02000202UL,0xF1F435C5UL,0x92901282UL,0x82880A8AUL,0x000C0C0CUL,0xB3B03383UL,0x727C3E4EUL,0xD0D010C0UL,
0x72783A4AUL,0x43440747UL,0x92941686UL,0xE1E425C5UL,0x22242606UL,0x80800080UL,0xA1AC2D8DUL,0xD3DC1FCFUL,
0xA1A02181UL,0x30303000UL,0x33343707UL,0xA2AC2E8EUL,0x32343606UL,0x11141505UL,0x22202202UL,0x30383808UL,
0xF0F434C4UL,0xA3A42787UL,0x41440545UL,0x404C0C4CUL,0x81800181UL,0xE1E829C9UL,0x80840484UL,0x93941787UL,
0x31343505UL,0xC3C80BCBUL,0xC2CC0ECEUL,0x303C3C0CUL,0x71703141UL,0x11101101UL,0xC3C407C7UL,0x81880989UL,
0x71743545UL,0xF3F83BCBUL,0xD2D81ACAUL,0xF0F838C8UL,0x90941484UL,0x51581949UL,0x82800282UL,0xC0C404C4UL,
0xF3FC3FCFUL,0x41480949UL,0x31383909UL,0x63642747UL,0xC0C000C0UL,0xC3CC0FCFUL,0xD3D417C7UL,0xB0B83888UL,
0x030C0F0FUL,0x828C0E8EUL,0x42400242UL,0x23202303UL,0x91901181UL,0x606C2C4CUL,0xD3D81BCBUL,0xA0A42484UL,
0x30343404UL,0xF1F031C1UL,0x40480848UL,0xC2C002C2UL,0x636C2F4FUL,0x313C3D0DUL,0x212C2D0DUL,0x40400040UL,
0xB2BC3E8EUL,0x323C3E0EUL,0xB0BC3C8CUL,0xC1C001C1UL,0xA2A82A8AUL,0xB2B83A8AUL,0x424C0E4EUL,0x51541545UL,
0x33383B0BUL,0xD0DC1CCCUL,0x60682848UL,0x737C3F4FUL,0x909C1C8CUL,0xD0D818C8UL,0x42480A4AUL,0x52541646UL,
0x73743747UL,0xA0A02080UL,0xE1EC2DCDUL,0x42440646UL,0xB1B43585UL,0x23282B0BUL,0x61642545UL,0xF2F83ACAUL,
0xE3E023C3UL,0xB1B83989UL,0xB1B03181UL,0x939C1F8FUL,0x525C1E4EUL,0xF1F839C9UL,0xE2E426C6UL,0xB2B03282UL,
0x31303101UL,0xE2E82ACAUL,0x616C2D4DUL,0x535C1F4FUL,0xE0E424C4UL,0xF0F030C0UL,0xC1CC0DCDUL,0x80880888UL,
0x12141606UL,0x32383A0AUL,0x50581848UL,0xD0D414C4UL,0x62602242UL,0x21282909UL,0x03040707UL,0x33303303UL,
0xE0E828C8UL,0x13181B0BUL,0x01040505UL,0x71783949UL,0x90901080UL,0x62682A4AUL,0x22282A0AUL,0x92981A8AUL
};
static const ulong32 SS3[256] = {
0x08303838UL,0xC8E0E828UL,0x0D212C2DUL,0x86A2A426UL,0xCFC3CC0FUL,0xCED2DC1EUL,0x83B3B033UL,0x88B0B838UL,
0x8FA3AC2FUL,0x40606020UL,0x45515415UL,0xC7C3C407UL,0x44404404UL,0x4F636C2FUL,0x4B63682BUL,0x4B53581BUL,
0xC3C3C003UL,0x42626022UL,0x03333033UL,0x85B1B435UL,0x09212829UL,0x80A0A020UL,0xC2E2E022UL,0x87A3A427UL,
0xC3D3D013UL,0x81919011UL,0x01111011UL,0x06020406UL,0x0C101C1CUL,0x8CB0BC3CUL,0x06323436UL,0x4B43480BUL,
0xCFE3EC2FUL,0x88808808UL,0x4C606C2CUL,0x88A0A828UL,0x07131417UL,0xC4C0C404UL,0x06121416UL,0xC4F0F434UL,
0xC2C2C002UL,0x45414405UL,0xC1E1E021UL,0xC6D2D416UL,0x0F333C3FUL,0x0D313C3DUL,0x8E828C0EUL,0x88909818UL,
0x08202828UL,0x4E424C0EUL,0xC6F2F436UL,0x0E323C3EUL,0x85A1A425UL,0xC9F1F839UL,0x0D010C0DUL,0xCFD3DC1FUL,
0xC8D0D818UL,0x0B23282BUL,0x46626426UL,0x4A72783AUL,0x07232427UL,0x0F232C2FUL,0xC1F1F031UL,0x42727032UL,
0x42424002UL,0xC4D0D414UL,0x41414001UL,0xC0C0C000UL,0x43737033UL,0x47636427UL,0x8CA0AC2CUL,0x8B83880BUL,
0xC7F3F437UL,0x8DA1AC2DUL,0x80808000UL,0x0F131C1FUL,0xCAC2C80AUL,0x0C202C2CUL,0x8AA2A82AUL,0x04303434UL,
0xC2D2D012UL,0x0B03080BUL,0xCEE2EC2EUL,0xC9E1E829UL,0x4D515C1DUL,0x84909414UL,0x08101818UL,0xC8F0F838UL,
0x47535417UL,0x8EA2AC2EUL,0x08000808UL,0xC5C1C405UL,0x03131013UL,0xCDC1CC0DUL,0x86828406UL,0x89B1B839UL,
0xCFF3FC3FUL,0x4D717C3DUL,0xC1C1C001UL,0x01313031UL,0xC5F1F435UL,0x8A82880AUL,0x4A62682AUL,0x81B1B031UL,
0xC1D1D011UL,0x00202020UL,0xC7D3D417UL,0x02020002UL,0x02222022UL,0x04000404UL,0x48606828UL,0x41717031UL,
0x07030407UL,0xCBD3D81BUL,0x8D919C1DUL,0x89919819UL,0x41616021UL,0x8EB2BC3EUL,0xC6E2E426UL,0x49515819UL,
0xCDD1DC1DUL,0x41515011UL,0x80909010UL,0xCCD0DC1CUL,0x8A92981AUL,0x83A3A023UL,0x8BA3A82BUL,0xC0D0D010UL,
0x81818001UL,0x0F030C0FUL,0x47434407UL,0x0A12181AUL,0xC3E3E023UL,0xCCE0EC2CUL,0x8D818C0DUL,0x8FB3BC3FUL,
0x86929416UL,0x4B73783BUL,0x4C505C1CUL,0x82A2A022UL,0x81A1A021UL,0x43636023UL,0x03232023UL,0x4D414C0DUL,
0xC8C0C808UL,0x8E929C1EUL,0x8C909C1CUL,0x0A32383AUL,0x0C000C0CUL,0x0E222C2EUL,0x8AB2B83AUL,0x4E626C2EUL,
0x8F939C1FUL,0x4A52581AUL,0xC2F2F032UL,0x82929012UL,0xC3F3F033UL,0x49414809UL,0x48707838UL,0xCCC0CC0CUL,
0x05111415UL,0xCBF3F83BUL,0x40707030UL,0x45717435UL,0x4F737C3FUL,0x05313435UL,0x00101010UL,0x03030003UL,
0x44606424UL,0x4D616C2DUL,0xC6C2C406UL,0x44707434UL,0xC5D1D415UL,0x84B0B434UL,0xCAE2E82AUL,0x09010809UL,
0x46727436UL,0x09111819UL,0xCEF2FC3EUL,0x40404000UL,0x02121012UL,0xC0E0E020UL,0x8DB1BC3DUL,0x05010405UL,
0xCAF2F83AUL,0x01010001UL,0xC0F0F030UL,0x0A22282AUL,0x4E525C1EUL,0x89A1A829UL,0x46525416UL,0x43434003UL,
0x85818405UL,0x04101414UL,0x89818809UL,0x8B93981BUL,0x80B0B030UL,0xC5E1E425UL,0x48404808UL,0x49717839UL,
0x87939417UL,0xCCF0FC3CUL,0x0E121C1EUL,0x82828002UL,0x01212021UL,0x8C808C0CUL,0x0B13181BUL,0x4F535C1FUL,
0x47737437UL,0x44505414UL,0x82B2B032UL,0x0D111C1DUL,0x05212425UL,0x4F434C0FUL,0x00000000UL,0x46424406UL,
0xCDE1EC2DUL,0x48505818UL,0x42525012UL,0xCBE3E82BUL,0x4E727C3EUL,0xCAD2D81AUL,0xC9C1C809UL,0xCDF1FC3DUL,
0x00303030UL,0x85919415UL,0x45616425UL,0x0C303C3CUL,0x86B2B436UL,0xC4E0E424UL,0x8BB3B83BUL,0x4C707C3CUL,
0x0E020C0EUL,0x40505010UL,0x09313839UL,0x06222426UL,0x02323032UL,0x84808404UL,0x49616829UL,0x83939013UL,
0x07333437UL,0xC7E3E427UL,0x04202424UL,0x84A0A424UL,0xCBC3C80BUL,0x43535013UL,0x0A02080AUL,0x87838407UL,
0xC9D1D819UL,0x4C404C0CUL,0x83838003UL,0x8F838C0FUL,0xCEC2CC0EUL,0x0B33383BUL,0x4A42480AUL,0x87B3B437UL
};
static const ulong32 KCi[16] = {
0x9E3779B9,0x3C6EF373,
0x78DDE6E6,0xF1BBCDCC,
0xE3779B99,0xC6EF3733,
0x8DDE6E67,0x1BBCDCCF,
0x3779B99E,0x6EF3733C,
0xDDE6E678,0xBBCDCCF1,
0x779B99E3,0xEF3733C6,
0xDE6E678D,0xBCDCCF1B
};
#define G(x) (SS3[((x)>>24)&255] ^ SS2[((x)>>16)&255] ^ SS1[((x)>>8)&255] ^ SS0[(x)&255])
#define F(L1, L2, R1, R2, K1, K2) \
T2 = G((R1 ^ K1) ^ (R2 ^ K2)); \
T = G( G(T2 + (R1 ^ K1)) + T2); \
L2 ^= T; \
L1 ^= (T + G(T2 + (R1 ^ K1))); \
/**
Initialize the SEED block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int i;
ulong32 tmp, k1, k2, k3, k4;
if (keylen != 16) {
return CRYPT_INVALID_KEYSIZE;
}
if (num_rounds != 16 && num_rounds != 0) {
return CRYPT_INVALID_ROUNDS;
}
/* load key */
LOAD32H(k1, key);
LOAD32H(k2, key+4);
LOAD32H(k3, key+8);
LOAD32H(k4, key+12);
for (i = 0; i < 16; i++) {
skey->kseed.K[2*i+0] = G(k1 + k3 - KCi[i]);
skey->kseed.K[2*i+1] = G(k2 - k4 + KCi[i]);
if (i&1) {
tmp = k3;
k3 = ((k3 << 8) | (k4 >> 24)) & 0xFFFFFFFF;
k4 = ((k4 << 8) | (tmp >> 24)) & 0xFFFFFFFF;
} else {
tmp = k1;
k1 = ((k1 >> 8) | (k2 << 24)) & 0xFFFFFFFF;
k2 = ((k2 >> 8) | (tmp << 24)) & 0xFFFFFFFF;
}
/* reverse keys for decrypt */
skey->kseed.dK[2*(15-i)+0] = skey->kseed.K[2*i+0];
skey->kseed.dK[2*(15-i)+1] = skey->kseed.K[2*i+1];
}
return CRYPT_OK;
}
static void rounds(ulong32 *P, ulong32 *K)
{
ulong32 T, T2;
int i;
for (i = 0; i < 16; i += 2) {
F(P[0], P[1], P[2], P[3], K[0], K[1]);
F(P[2], P[3], P[0], P[1], K[2], K[3]);
K += 4;
}
}
/**
Encrypts a block of text with SEED
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
ulong32 P[4];
LOAD32H(P[0], pt);
LOAD32H(P[1], pt+4);
LOAD32H(P[2], pt+8);
LOAD32H(P[3], pt+12);
rounds(P, skey->kseed.K);
STORE32H(P[2], ct);
STORE32H(P[3], ct+4);
STORE32H(P[0], ct+8);
STORE32H(P[1], ct+12);
return CRYPT_OK;
}
/**
Decrypts a block of text with SEED
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
ulong32 P[4];
LOAD32H(P[0], ct);
LOAD32H(P[1], ct+4);
LOAD32H(P[2], ct+8);
LOAD32H(P[3], ct+12);
rounds(P, skey->kseed.dK);
STORE32H(P[2], pt);
STORE32H(P[3], pt+4);
STORE32H(P[0], pt+8);
STORE32H(P[1], pt+12);
return CRYPT_OK;
}
/** Terminate the context
@param skey The scheduled key
*/
void kseed_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Performs a self-test of the SEED block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int kseed_test(void)
{
#if !defined(LTC_TEST)
return CRYPT_NOP;
#else
static const struct test {
unsigned char pt[16], ct[16], key[16];
} tests[] = {
{
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F },
{ 0x5E,0xBA,0xC6,0xE0,0x05,0x4E,0x16,0x68,0x19,0xAF,0xF1,0xCC,0x6D,0x34,0x6C,0xDB },
{ 0 },
},
{
{ 0 },
{ 0xC1,0x1F,0x22,0xF2,0x01,0x40,0x50,0x50,0x84,0x48,0x35,0x97,0xE4,0x37,0x0F,0x43 },
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F },
},
{
{ 0x83,0xA2,0xF8,0xA2,0x88,0x64,0x1F,0xB9,0xA4,0xE9,0xA5,0xCC,0x2F,0x13,0x1C,0x7D },
{ 0xEE,0x54,0xD1,0x3E,0xBC,0xAE,0x70,0x6D,0x22,0x6B,0xC3,0x14,0x2C,0xD4,0x0D,0x4A },
{ 0x47,0x06,0x48,0x08,0x51,0xE6,0x1B,0xE8,0x5D,0x74,0xBF,0xB3,0xFD,0x95,0x61,0x85 },
},
{
{ 0xB4,0x1E,0x6B,0xE2,0xEB,0xA8,0x4A,0x14,0x8E,0x2E,0xED,0x84,0x59,0x3C,0x5E,0xC7 },
{ 0x9B,0x9B,0x7B,0xFC,0xD1,0x81,0x3C,0xB9,0x5D,0x0B,0x36,0x18,0xF4,0x0F,0x51,0x22 },
{ 0x28,0xDB,0xC3,0xBC,0x49,0xFF,0xD8,0x7D,0xCF,0xA5,0x09,0xB1,0x1D,0x42,0x2B,0xE7 },
}
};
int x;
unsigned char buf[2][16];
symmetric_key skey;
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
kseed_setup(tests[x].key, 16, 0, &skey);
kseed_ecb_encrypt(tests[x].pt, buf[0], &skey);
kseed_ecb_decrypt(buf[0], buf[1], &skey);
if (compare_testvector(buf[0], 16, tests[x].ct, 16, "KSEED Encrypt", x) ||
compare_testvector(buf[1], 16, tests[x].pt, 16, "KSEED Decrypt", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int kseed_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize >= 16) {
*keysize = 16;
} else {
return CRYPT_INVALID_KEYSIZE;
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

319
thirdparty/libtomcrypt/ciphers/multi2.c vendored Normal file
View File

@@ -0,0 +1,319 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file multi2.c
Multi-2 implementation (not public domain, hence the default disable)
*/
#include "tomcrypt.h"
#ifdef LTC_MULTI2
static void pi1(ulong32 *p)
{
p[1] ^= p[0];
}
static void pi2(ulong32 *p, ulong32 *k)
{
ulong32 t;
t = (p[1] + k[0]) & 0xFFFFFFFFUL;
t = (ROL(t, 1) + t - 1) & 0xFFFFFFFFUL;
t = (ROL(t, 4) ^ t) & 0xFFFFFFFFUL;
p[0] ^= t;
}
static void pi3(ulong32 *p, ulong32 *k)
{
ulong32 t;
t = p[0] + k[1];
t = (ROL(t, 2) + t + 1) & 0xFFFFFFFFUL;
t = (ROL(t, 8) ^ t) & 0xFFFFFFFFUL;
t = (t + k[2]) & 0xFFFFFFFFUL;
t = (ROL(t, 1) - t) & 0xFFFFFFFFUL;
t = ROL(t, 16) ^ (p[0] | t);
p[1] ^= t;
}
static void pi4(ulong32 *p, ulong32 *k)
{
ulong32 t;
t = (p[1] + k[3]) & 0xFFFFFFFFUL;
t = (ROL(t, 2) + t + 1) & 0xFFFFFFFFUL;
p[0] ^= t;
}
static void setup(ulong32 *dk, ulong32 *k, ulong32 *uk)
{
int n, t;
ulong32 p[2];
p[0] = dk[0]; p[1] = dk[1];
t = 4;
n = 0;
pi1(p);
pi2(p, k);
uk[n++] = p[0];
pi3(p, k);
uk[n++] = p[1];
pi4(p, k);
uk[n++] = p[0];
pi1(p);
uk[n++] = p[1];
pi2(p, k+t);
uk[n++] = p[0];
pi3(p, k+t);
uk[n++] = p[1];
pi4(p, k+t);
uk[n++] = p[0];
pi1(p);
uk[n++] = p[1];
}
static void encrypt(ulong32 *p, int N, ulong32 *uk)
{
int n, t;
for (t = n = 0; ; ) {
pi1(p); if (++n == N) break;
pi2(p, uk+t); if (++n == N) break;
pi3(p, uk+t); if (++n == N) break;
pi4(p, uk+t); if (++n == N) break;
t ^= 4;
}
}
static void decrypt(ulong32 *p, int N, ulong32 *uk)
{
int n, t;
for (t = 4*(((N-1)>>2)&1), n = N; ; ) {
switch (n<=4 ? n : ((n-1)%4)+1) {
case 4: pi4(p, uk+t); --n; /* FALLTHROUGH */
case 3: pi3(p, uk+t); --n; /* FALLTHROUGH */
case 2: pi2(p, uk+t); --n; /* FALLTHROUGH */
case 1: pi1(p); --n; break;
case 0: return;
}
t ^= 4;
}
}
const struct ltc_cipher_descriptor multi2_desc = {
"multi2",
22,
40, 40, 8, 128,
&multi2_setup,
&multi2_ecb_encrypt,
&multi2_ecb_decrypt,
&multi2_test,
&multi2_done,
&multi2_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
ulong32 sk[8], dk[2];
int x;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (keylen != 40) return CRYPT_INVALID_KEYSIZE;
if (num_rounds == 0) num_rounds = 128;
skey->multi2.N = num_rounds;
for (x = 0; x < 8; x++) {
LOAD32H(sk[x], key + x*4);
}
LOAD32H(dk[0], key + 32);
LOAD32H(dk[1], key + 36);
setup(dk, sk, skey->multi2.uk);
zeromem(sk, sizeof(sk));
zeromem(dk, sizeof(dk));
return CRYPT_OK;
}
/**
Encrypts a block of text with multi2
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
ulong32 p[2];
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
LOAD32H(p[0], pt);
LOAD32H(p[1], pt+4);
encrypt(p, skey->multi2.N, skey->multi2.uk);
STORE32H(p[0], ct);
STORE32H(p[1], ct+4);
return CRYPT_OK;
}
/**
Decrypts a block of text with multi2
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
ulong32 p[2];
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
LOAD32H(p[0], ct);
LOAD32H(p[1], ct+4);
decrypt(p, skey->multi2.N, skey->multi2.uk);
STORE32H(p[0], pt);
STORE32H(p[1], pt+4);
return CRYPT_OK;
}
/**
Performs a self-test of the multi2 block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int multi2_test(void)
{
static const struct {
unsigned char key[40];
unsigned char pt[8], ct[8];
int rounds;
} tests[] = {
{
{
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x01, 0x23, 0x45, 0x67,
0x89, 0xAB, 0xCD, 0xEF
},
{
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01,
},
{
0xf8, 0x94, 0x40, 0x84,
0x5e, 0x11, 0xcf, 0x89
},
128,
},
{
{
0x35, 0x91, 0x9d, 0x96,
0x07, 0x02, 0xe2, 0xce,
0x8d, 0x0b, 0x58, 0x3c,
0xc9, 0xc8, 0x9d, 0x59,
0xa2, 0xae, 0x96, 0x4e,
0x87, 0x82, 0x45, 0xed,
0x3f, 0x2e, 0x62, 0xd6,
0x36, 0x35, 0xd0, 0x67,
0xb1, 0x27, 0xb9, 0x06,
0xe7, 0x56, 0x22, 0x38,
},
{
0x1f, 0xb4, 0x60, 0x60,
0xd0, 0xb3, 0x4f, 0xa5
},
{
0xca, 0x84, 0xa9, 0x34,
0x75, 0xc8, 0x60, 0xe5
},
216,
}
};
unsigned char buf[8];
symmetric_key skey;
int err, x;
for (x = 1; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
if ((err = multi2_setup(tests[x].key, 40, tests[x].rounds, &skey)) != CRYPT_OK) {
return err;
}
if ((err = multi2_ecb_encrypt(tests[x].pt, buf, &skey)) != CRYPT_OK) {
return err;
}
if (compare_testvector(buf, 8, tests[x].ct, 8, "Multi2 Encrypt", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
if ((err = multi2_ecb_decrypt(buf, buf, &skey)) != CRYPT_OK) {
return err;
}
if (compare_testvector(buf, 8, tests[x].pt, 8, "Multi2 Decrypt", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
for (x = 128; x < 256; ++x) {
unsigned char ct[8];
if ((err = multi2_setup(tests[0].key, 40, x, &skey)) != CRYPT_OK) {
return err;
}
if ((err = multi2_ecb_encrypt(tests[0].pt, ct, &skey)) != CRYPT_OK) {
return err;
}
if ((err = multi2_ecb_decrypt(ct, buf, &skey)) != CRYPT_OK) {
return err;
}
if (compare_testvector(buf, 8, tests[0].pt, 8, "Multi2 Rounds", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
}
/** Terminate the context
@param skey The scheduled key
*/
void multi2_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int multi2_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize >= 40) {
*keysize = 40;
} else {
return CRYPT_INVALID_KEYSIZE;
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

328
thirdparty/libtomcrypt/ciphers/noekeon.c vendored Normal file
View File

@@ -0,0 +1,328 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file noekeon.c
Implementation of the Noekeon block cipher by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_NOEKEON
const struct ltc_cipher_descriptor noekeon_desc =
{
"noekeon",
16,
16, 16, 16, 16,
&noekeon_setup,
&noekeon_ecb_encrypt,
&noekeon_ecb_decrypt,
&noekeon_test,
&noekeon_done,
&noekeon_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static const ulong32 RC[] = {
0x00000080UL, 0x0000001bUL, 0x00000036UL, 0x0000006cUL,
0x000000d8UL, 0x000000abUL, 0x0000004dUL, 0x0000009aUL,
0x0000002fUL, 0x0000005eUL, 0x000000bcUL, 0x00000063UL,
0x000000c6UL, 0x00000097UL, 0x00000035UL, 0x0000006aUL,
0x000000d4UL
};
#define kTHETA(a, b, c, d) \
temp = a^c; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
b ^= temp; d ^= temp; \
temp = b^d; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
a ^= temp; c ^= temp;
#define THETA(k, a, b, c, d) \
temp = a^c; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
b ^= temp ^ k[1]; d ^= temp ^ k[3]; \
temp = b^d; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \
a ^= temp ^ k[0]; c ^= temp ^ k[2];
#define GAMMA(a, b, c, d) \
b ^= ~(d|c); \
a ^= c&b; \
temp = d; d = a; a = temp;\
c ^= a ^ b ^ d; \
b ^= ~(d|c); \
a ^= c&b;
#define PI1(a, b, c, d) \
b = ROLc(b, 1); c = ROLc(c, 5); d = ROLc(d, 2);
#define PI2(a, b, c, d) \
b = RORc(b, 1); c = RORc(c, 5); d = RORc(d, 2);
/**
Initialize the Noekeon block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
ulong32 temp;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (keylen != 16) {
return CRYPT_INVALID_KEYSIZE;
}
if (num_rounds != 16 && num_rounds != 0) {
return CRYPT_INVALID_ROUNDS;
}
LOAD32H(skey->noekeon.K[0],&key[0]);
LOAD32H(skey->noekeon.K[1],&key[4]);
LOAD32H(skey->noekeon.K[2],&key[8]);
LOAD32H(skey->noekeon.K[3],&key[12]);
LOAD32H(skey->noekeon.dK[0],&key[0]);
LOAD32H(skey->noekeon.dK[1],&key[4]);
LOAD32H(skey->noekeon.dK[2],&key[8]);
LOAD32H(skey->noekeon.dK[3],&key[12]);
kTHETA(skey->noekeon.dK[0], skey->noekeon.dK[1], skey->noekeon.dK[2], skey->noekeon.dK[3]);
return CRYPT_OK;
}
/**
Encrypts a block of text with Noekeon
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 a,b,c,d,temp;
int r;
LTC_ARGCHK(skey != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LOAD32H(a,&pt[0]); LOAD32H(b,&pt[4]);
LOAD32H(c,&pt[8]); LOAD32H(d,&pt[12]);
#define ROUND(i) \
a ^= RC[i]; \
THETA(skey->noekeon.K, a,b,c,d); \
PI1(a,b,c,d); \
GAMMA(a,b,c,d); \
PI2(a,b,c,d);
for (r = 0; r < 16; ++r) {
ROUND(r);
}
#undef ROUND
a ^= RC[16];
THETA(skey->noekeon.K, a, b, c, d);
STORE32H(a,&ct[0]); STORE32H(b,&ct[4]);
STORE32H(c,&ct[8]); STORE32H(d,&ct[12]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
int err = _noekeon_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(ulong32) * 5 + sizeof(int));
return err;
}
#endif
/**
Decrypts a block of text with Noekeon
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 a,b,c,d, temp;
int r;
LTC_ARGCHK(skey != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LOAD32H(a,&ct[0]); LOAD32H(b,&ct[4]);
LOAD32H(c,&ct[8]); LOAD32H(d,&ct[12]);
#define ROUND(i) \
THETA(skey->noekeon.dK, a,b,c,d); \
a ^= RC[i]; \
PI1(a,b,c,d); \
GAMMA(a,b,c,d); \
PI2(a,b,c,d);
for (r = 16; r > 0; --r) {
ROUND(r);
}
#undef ROUND
THETA(skey->noekeon.dK, a,b,c,d);
a ^= RC[0];
STORE32H(a,&pt[0]); STORE32H(b, &pt[4]);
STORE32H(c,&pt[8]); STORE32H(d, &pt[12]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
int err = _noekeon_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(ulong32) * 5 + sizeof(int));
return err;
}
#endif
/**
Performs a self-test of the Noekeon block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int noekeon_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen;
unsigned char key[16], pt[16], ct[16];
} tests[] = {
{
16,
{ 0xAA, 0x3C, 0x8C, 0x86, 0xD9, 0x8B, 0xF8, 0xBE, 0x21, 0xE0, 0x36, 0x09, 0x78, 0xFB, 0xE4, 0x90 },
{ 0xE4, 0x96, 0x6C, 0xD3, 0x13, 0xA0, 0x6C, 0xAF, 0xD0, 0x23, 0xC9, 0xFD, 0x45, 0x32, 0x23, 0x16 },
{ 0xA6, 0xEC, 0xB8, 0xA8, 0x61, 0xFD, 0x62, 0xD9, 0x13, 0x02, 0xFE, 0x9E, 0x47, 0x01, 0x3F, 0xC3 }
},
{
16,
{ 0xED, 0x43, 0xD1, 0x87, 0x21, 0x7E, 0xE0, 0x97, 0x3D, 0x76, 0xC3, 0x37, 0x2E, 0x7D, 0xAE, 0xD3 },
{ 0xE3, 0x38, 0x32, 0xCC, 0xF2, 0x2F, 0x2F, 0x0A, 0x4A, 0x8B, 0x8F, 0x18, 0x12, 0x20, 0x17, 0xD3 },
{ 0x94, 0xA5, 0xDF, 0xF5, 0xAE, 0x1C, 0xBB, 0x22, 0xAD, 0xEB, 0xA7, 0x0D, 0xB7, 0x82, 0x90, 0xA0 }
},
{
16,
{ 0x6F, 0xDC, 0x23, 0x38, 0xF2, 0x10, 0xFB, 0xD3, 0xC1, 0x8C, 0x02, 0xF6, 0xB4, 0x6A, 0xD5, 0xA8 },
{ 0xDB, 0x29, 0xED, 0xB5, 0x5F, 0xB3, 0x60, 0x3A, 0x92, 0xA8, 0xEB, 0x9C, 0x6D, 0x9D, 0x3E, 0x8F },
{ 0x78, 0xF3, 0x6F, 0xF8, 0x9E, 0xBB, 0x8C, 0x6A, 0xE8, 0x10, 0xF7, 0x00, 0x22, 0x15, 0x30, 0x3D }
},
{
16,
{ 0x2C, 0x0C, 0x02, 0xEF, 0x6B, 0xC4, 0xF2, 0x0B, 0x2E, 0xB9, 0xE0, 0xBF, 0xD9, 0x36, 0xC2, 0x4E },
{ 0x84, 0xE2, 0xFE, 0x64, 0xB1, 0xB9, 0xFE, 0x76, 0xA8, 0x3F, 0x45, 0xC7, 0x40, 0x7A, 0xAF, 0xEE },
{ 0x2A, 0x08, 0xD6, 0xA2, 0x1C, 0x63, 0x08, 0xB0, 0xF8, 0xBC, 0xB3, 0xA1, 0x66, 0xF7, 0xAE, 0xCF }
},
{
16,
{ 0x6F, 0x30, 0xF8, 0x9F, 0xDA, 0x6E, 0xA0, 0x91, 0x04, 0x0F, 0x6C, 0x8B, 0x7D, 0xF7, 0x2A, 0x4B },
{ 0x65, 0xB6, 0xA6, 0xD0, 0x42, 0x14, 0x08, 0x60, 0x34, 0x8D, 0x37, 0x2F, 0x01, 0xF0, 0x46, 0xBE },
{ 0x66, 0xAC, 0x0B, 0x62, 0x1D, 0x68, 0x11, 0xF5, 0x27, 0xB1, 0x13, 0x5D, 0xF3, 0x2A, 0xE9, 0x18 }
},
{
16,
{ 0xCA, 0xA4, 0x16, 0xB7, 0x1C, 0x92, 0x2E, 0xAD, 0xEB, 0xA7, 0xDB, 0x69, 0x92, 0xCB, 0x35, 0xEF },
{ 0x81, 0x6F, 0x8E, 0x4D, 0x96, 0xC6, 0xB3, 0x67, 0x83, 0xF5, 0x63, 0xC7, 0x20, 0x6D, 0x40, 0x23 },
{ 0x44, 0xF7, 0x63, 0x62, 0xF0, 0x43, 0xBB, 0x67, 0x4A, 0x75, 0x12, 0x42, 0x46, 0x29, 0x28, 0x19 }
},
{
16,
{ 0x6B, 0xCF, 0x22, 0x2F, 0xE0, 0x1B, 0xB0, 0xAA, 0xD8, 0x3C, 0x91, 0x99, 0x18, 0xB2, 0x28, 0xE8 },
{ 0x7C, 0x37, 0xC7, 0xD0, 0xAC, 0x92, 0x29, 0xF1, 0x60, 0x82, 0x93, 0x89, 0xAA, 0x61, 0xAA, 0xA9 },
{ 0xE5, 0x89, 0x1B, 0xB3, 0xFE, 0x8B, 0x0C, 0xA1, 0xA6, 0xC7, 0xBE, 0x12, 0x73, 0x0F, 0xC1, 0x19 }
},
{
16,
{ 0xE6, 0xD0, 0xF1, 0x03, 0x2E, 0xDE, 0x70, 0x8D, 0xD8, 0x9E, 0x36, 0x5C, 0x05, 0x52, 0xE7, 0x0D },
{ 0xE2, 0x42, 0xE7, 0x92, 0x0E, 0xF7, 0x82, 0xA2, 0xB8, 0x21, 0x8D, 0x26, 0xBA, 0x2D, 0xE6, 0x32 },
{ 0x1E, 0xDD, 0x75, 0x22, 0xB9, 0x36, 0x8A, 0x0F, 0x32, 0xFD, 0xD4, 0x48, 0x65, 0x12, 0x5A, 0x2F }
}
};
symmetric_key key;
unsigned char tmp[2][16];
int err, i, y;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
zeromem(&key, sizeof(key));
if ((err = noekeon_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
return err;
}
noekeon_ecb_encrypt(tests[i].pt, tmp[0], &key);
noekeon_ecb_decrypt(tmp[0], tmp[1], &key);
if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "Noekeon Encrypt", i) ||
compare_testvector(tmp[1], 16, tests[i].pt, 16, "Noekeon Decrypt", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 16; y++) tmp[0][y] = 0;
for (y = 0; y < 1000; y++) noekeon_ecb_encrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 1000; y++) noekeon_ecb_decrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
/** Terminate the context
@param skey The scheduled key
*/
void noekeon_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int noekeon_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 16) {
return CRYPT_INVALID_KEYSIZE;
} else {
*keysize = 16;
return CRYPT_OK;
}
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

417
thirdparty/libtomcrypt/ciphers/rc2.c vendored Normal file
View File

@@ -0,0 +1,417 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**********************************************************************\
* To commemorate the 1996 RSA Data Security Conference, the following *
* code is released into the public domain by its author. Prost! *
* *
* This cipher uses 16-bit words and little-endian byte ordering. *
* I wonder which processor it was optimized for? *
* *
* Thanks to CodeView, SoftIce, and D86 for helping bring this code to *
* the public. *
\**********************************************************************/
#include "tomcrypt.h"
/**
@file rc2.c
Implementation of RC2 with fixed effective key length of 64bits
*/
#ifdef LTC_RC2
const struct ltc_cipher_descriptor rc2_desc = {
"rc2",
12, 8, 128, 8, 16,
&rc2_setup,
&rc2_ecb_encrypt,
&rc2_ecb_decrypt,
&rc2_test,
&rc2_done,
&rc2_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
/* 256-entry permutation table, probably derived somehow from pi */
static const unsigned char permute[256] = {
217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157,
198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162,
23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50,
189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130,
84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220,
18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38,
111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3,
248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215,
8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42,
150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236,
194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57,
153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49,
45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201,
211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169,
13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46,
197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173
};
/**
Initialize the RC2 block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param bits The effective key length in bits
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
int rc2_setup_ex(const unsigned char *key, int keylen, int bits, int num_rounds, symmetric_key *skey)
{
unsigned *xkey = skey->rc2.xkey;
unsigned char tmp[128];
unsigned T8, TM;
int i;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (keylen == 0 || keylen > 128 || bits > 1024) {
return CRYPT_INVALID_KEYSIZE;
}
if (bits == 0) {
bits = 1024;
}
if (num_rounds != 0 && num_rounds != 16) {
return CRYPT_INVALID_ROUNDS;
}
for (i = 0; i < keylen; i++) {
tmp[i] = key[i] & 255;
}
/* Phase 1: Expand input key to 128 bytes */
if (keylen < 128) {
for (i = keylen; i < 128; i++) {
tmp[i] = permute[(tmp[i - 1] + tmp[i - keylen]) & 255];
}
}
/* Phase 2 - reduce effective key size to "bits" */
T8 = (unsigned)(bits+7)>>3;
TM = (255 >> (unsigned)(7 & -bits));
tmp[128 - T8] = permute[tmp[128 - T8] & TM];
for (i = 127 - T8; i >= 0; i--) {
tmp[i] = permute[tmp[i + 1] ^ tmp[i + T8]];
}
/* Phase 3 - copy to xkey in little-endian order */
for (i = 0; i < 64; i++) {
xkey[i] = (unsigned)tmp[2*i] + ((unsigned)tmp[2*i+1] << 8);
}
#ifdef LTC_CLEAN_STACK
zeromem(tmp, sizeof(tmp));
#endif
return CRYPT_OK;
}
/**
Initialize the RC2 block cipher
The effective key length is here always keylen * 8
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
return rc2_setup_ex(key, keylen, keylen * 8, num_rounds, skey);
}
/**********************************************************************\
* Encrypt an 8-byte block of plaintext using the given key. *
\**********************************************************************/
/**
Encrypts a block of text with RC2
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _rc2_ecb_encrypt( const unsigned char *pt,
unsigned char *ct,
symmetric_key *skey)
#else
int rc2_ecb_encrypt( const unsigned char *pt,
unsigned char *ct,
symmetric_key *skey)
#endif
{
unsigned *xkey;
unsigned x76, x54, x32, x10, i;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
xkey = skey->rc2.xkey;
x76 = ((unsigned)pt[7] << 8) + (unsigned)pt[6];
x54 = ((unsigned)pt[5] << 8) + (unsigned)pt[4];
x32 = ((unsigned)pt[3] << 8) + (unsigned)pt[2];
x10 = ((unsigned)pt[1] << 8) + (unsigned)pt[0];
for (i = 0; i < 16; i++) {
x10 = (x10 + (x32 & ~x76) + (x54 & x76) + xkey[4*i+0]) & 0xFFFF;
x10 = ((x10 << 1) | (x10 >> 15));
x32 = (x32 + (x54 & ~x10) + (x76 & x10) + xkey[4*i+1]) & 0xFFFF;
x32 = ((x32 << 2) | (x32 >> 14));
x54 = (x54 + (x76 & ~x32) + (x10 & x32) + xkey[4*i+2]) & 0xFFFF;
x54 = ((x54 << 3) | (x54 >> 13));
x76 = (x76 + (x10 & ~x54) + (x32 & x54) + xkey[4*i+3]) & 0xFFFF;
x76 = ((x76 << 5) | (x76 >> 11));
if (i == 4 || i == 10) {
x10 = (x10 + xkey[x76 & 63]) & 0xFFFF;
x32 = (x32 + xkey[x10 & 63]) & 0xFFFF;
x54 = (x54 + xkey[x32 & 63]) & 0xFFFF;
x76 = (x76 + xkey[x54 & 63]) & 0xFFFF;
}
}
ct[0] = (unsigned char)x10;
ct[1] = (unsigned char)(x10 >> 8);
ct[2] = (unsigned char)x32;
ct[3] = (unsigned char)(x32 >> 8);
ct[4] = (unsigned char)x54;
ct[5] = (unsigned char)(x54 >> 8);
ct[6] = (unsigned char)x76;
ct[7] = (unsigned char)(x76 >> 8);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int rc2_ecb_encrypt( const unsigned char *pt,
unsigned char *ct,
symmetric_key *skey)
{
int err = _rc2_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5);
return err;
}
#endif
/**********************************************************************\
* Decrypt an 8-byte block of ciphertext using the given key. *
\**********************************************************************/
/**
Decrypts a block of text with RC2
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _rc2_ecb_decrypt( const unsigned char *ct,
unsigned char *pt,
symmetric_key *skey)
#else
int rc2_ecb_decrypt( const unsigned char *ct,
unsigned char *pt,
symmetric_key *skey)
#endif
{
unsigned x76, x54, x32, x10;
unsigned *xkey;
int i;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
xkey = skey->rc2.xkey;
x76 = ((unsigned)ct[7] << 8) + (unsigned)ct[6];
x54 = ((unsigned)ct[5] << 8) + (unsigned)ct[4];
x32 = ((unsigned)ct[3] << 8) + (unsigned)ct[2];
x10 = ((unsigned)ct[1] << 8) + (unsigned)ct[0];
for (i = 15; i >= 0; i--) {
if (i == 4 || i == 10) {
x76 = (x76 - xkey[x54 & 63]) & 0xFFFF;
x54 = (x54 - xkey[x32 & 63]) & 0xFFFF;
x32 = (x32 - xkey[x10 & 63]) & 0xFFFF;
x10 = (x10 - xkey[x76 & 63]) & 0xFFFF;
}
x76 = ((x76 << 11) | (x76 >> 5));
x76 = (x76 - ((x10 & ~x54) + (x32 & x54) + xkey[4*i+3])) & 0xFFFF;
x54 = ((x54 << 13) | (x54 >> 3));
x54 = (x54 - ((x76 & ~x32) + (x10 & x32) + xkey[4*i+2])) & 0xFFFF;
x32 = ((x32 << 14) | (x32 >> 2));
x32 = (x32 - ((x54 & ~x10) + (x76 & x10) + xkey[4*i+1])) & 0xFFFF;
x10 = ((x10 << 15) | (x10 >> 1));
x10 = (x10 - ((x32 & ~x76) + (x54 & x76) + xkey[4*i+0])) & 0xFFFF;
}
pt[0] = (unsigned char)x10;
pt[1] = (unsigned char)(x10 >> 8);
pt[2] = (unsigned char)x32;
pt[3] = (unsigned char)(x32 >> 8);
pt[4] = (unsigned char)x54;
pt[5] = (unsigned char)(x54 >> 8);
pt[6] = (unsigned char)x76;
pt[7] = (unsigned char)(x76 >> 8);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int rc2_ecb_decrypt( const unsigned char *ct,
unsigned char *pt,
symmetric_key *skey)
{
int err = _rc2_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int));
return err;
}
#endif
/**
Performs a self-test of the RC2 block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int rc2_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen, bits;
unsigned char key[16], pt[8], ct[8];
} tests[] = {
{ 8, 63,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff }
},
{ 8, 64,
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
{ 0x27, 0x8b, 0x27, 0xe4, 0x2e, 0x2f, 0x0d, 0x49 }
},
{ 8, 64,
{ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
{ 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2 }
},
{ 1, 64,
{ 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x61, 0xa8, 0xa2, 0x44, 0xad, 0xac, 0xcc, 0xf0 }
},
{ 7, 64,
{ 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x6c, 0xcf, 0x43, 0x08, 0x97, 0x4c, 0x26, 0x7f }
},
{ 16, 64,
{ 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f,
0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x1a, 0x80, 0x7d, 0x27, 0x2b, 0xbe, 0x5d, 0xb1 }
},
{ 16, 128,
{ 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f,
0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6 }
}
};
int x, y, err;
symmetric_key skey;
unsigned char tmp[2][8];
for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
zeromem(tmp, sizeof(tmp));
if (tests[x].bits == (tests[x].keylen * 8)) {
if ((err = rc2_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) {
return err;
}
}
else {
if ((err = rc2_setup_ex(tests[x].key, tests[x].keylen, tests[x].bits, 0, &skey)) != CRYPT_OK) {
return err;
}
}
rc2_ecb_encrypt(tests[x].pt, tmp[0], &skey);
rc2_ecb_decrypt(tmp[0], tmp[1], &skey);
if (compare_testvector(tmp[0], 8, tests[x].ct, 8, "RC2 CT", x) ||
compare_testvector(tmp[1], 8, tests[x].pt, 8, "RC2 PT", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 8; y++) tmp[0][y] = 0;
for (y = 0; y < 1000; y++) rc2_ecb_encrypt(tmp[0], tmp[0], &skey);
for (y = 0; y < 1000; y++) rc2_ecb_decrypt(tmp[0], tmp[0], &skey);
for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
/** Terminate the context
@param skey The scheduled key
*/
void rc2_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int rc2_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 1) {
return CRYPT_INVALID_KEYSIZE;
} else if (*keysize > 128) {
*keysize = 128;
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

322
thirdparty/libtomcrypt/ciphers/rc5.c vendored Normal file
View File

@@ -0,0 +1,322 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file rc5.c
LTC_RC5 code by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_RC5
const struct ltc_cipher_descriptor rc5_desc =
{
"rc5",
2,
8, 128, 8, 12,
&rc5_setup,
&rc5_ecb_encrypt,
&rc5_ecb_decrypt,
&rc5_test,
&rc5_done,
&rc5_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static const ulong32 stab[50] = {
0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL,
0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL,
0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL,
0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL,
0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL,
0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL, 0xe96a3d2fUL, 0x87a1b6e8UL, 0x25d930a1UL, 0xc410aa5aUL,
0x62482413UL, 0x007f9dccUL
};
/**
Initialize the LTC_RC5 block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#else
int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#endif
{
ulong32 L[64], *S, A, B, i, j, v, s, t, l;
LTC_ARGCHK(skey != NULL);
LTC_ARGCHK(key != NULL);
/* test parameters */
if (num_rounds == 0) {
num_rounds = rc5_desc.default_rounds;
}
if (num_rounds < 12 || num_rounds > 24) {
return CRYPT_INVALID_ROUNDS;
}
/* key must be between 64 and 1024 bits */
if (keylen < 8 || keylen > 128) {
return CRYPT_INVALID_KEYSIZE;
}
skey->rc5.rounds = num_rounds;
S = skey->rc5.K;
/* copy the key into the L array */
for (A = i = j = 0; i < (ulong32)keylen; ) {
A = (A << 8) | ((ulong32)(key[i++] & 255));
if ((i & 3) == 0) {
L[j++] = BSWAP(A);
A = 0;
}
}
if ((keylen & 3) != 0) {
A <<= (ulong32)((8 * (4 - (keylen&3))));
L[j++] = BSWAP(A);
}
/* setup the S array */
t = (ulong32)(2 * (num_rounds + 1));
XMEMCPY(S, stab, t * sizeof(*S));
/* mix buffer */
s = 3 * MAX(t, j);
l = j;
for (A = B = i = j = v = 0; v < s; v++) {
A = S[i] = ROLc(S[i] + A + B, 3);
B = L[j] = ROL(L[j] + A + B, (A+B));
if (++i == t) { i = 0; }
if (++j == l) { j = 0; }
}
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int x;
x = _rc5_setup(key, keylen, num_rounds, skey);
burn_stack(sizeof(ulong32) * 122 + sizeof(int));
return x;
}
#endif
/**
Encrypts a block of text with LTC_RC5
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 A, B, *K;
int r;
LTC_ARGCHK(skey != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LOAD32L(A, &pt[0]);
LOAD32L(B, &pt[4]);
A += skey->rc5.K[0];
B += skey->rc5.K[1];
K = skey->rc5.K + 2;
if ((skey->rc5.rounds & 1) == 0) {
for (r = 0; r < skey->rc5.rounds; r += 2) {
A = ROL(A ^ B, B) + K[0];
B = ROL(B ^ A, A) + K[1];
A = ROL(A ^ B, B) + K[2];
B = ROL(B ^ A, A) + K[3];
K += 4;
}
} else {
for (r = 0; r < skey->rc5.rounds; r++) {
A = ROL(A ^ B, B) + K[0];
B = ROL(B ^ A, A) + K[1];
K += 2;
}
}
STORE32L(A, &ct[0]);
STORE32L(B, &ct[4]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
int err = _rc5_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(ulong32) * 2 + sizeof(int));
return err;
}
#endif
/**
Decrypts a block of text with LTC_RC5
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 A, B, *K;
int r;
LTC_ARGCHK(skey != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LOAD32L(A, &ct[0]);
LOAD32L(B, &ct[4]);
K = skey->rc5.K + (skey->rc5.rounds << 1);
if ((skey->rc5.rounds & 1) == 0) {
K -= 2;
for (r = skey->rc5.rounds - 1; r >= 0; r -= 2) {
B = ROR(B - K[3], A) ^ A;
A = ROR(A - K[2], B) ^ B;
B = ROR(B - K[1], A) ^ A;
A = ROR(A - K[0], B) ^ B;
K -= 4;
}
} else {
for (r = skey->rc5.rounds - 1; r >= 0; r--) {
B = ROR(B - K[1], A) ^ A;
A = ROR(A - K[0], B) ^ B;
K -= 2;
}
}
A -= skey->rc5.K[0];
B -= skey->rc5.K[1];
STORE32L(A, &pt[0]);
STORE32L(B, &pt[4]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
int err = _rc5_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(ulong32) * 2 + sizeof(int));
return err;
}
#endif
/**
Performs a self-test of the LTC_RC5 block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int rc5_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
unsigned char key[16], pt[8], ct[8];
} tests[] = {
{
{ 0x91, 0x5f, 0x46, 0x19, 0xbe, 0x41, 0xb2, 0x51,
0x63, 0x55, 0xa5, 0x01, 0x10, 0xa9, 0xce, 0x91 },
{ 0x21, 0xa5, 0xdb, 0xee, 0x15, 0x4b, 0x8f, 0x6d },
{ 0xf7, 0xc0, 0x13, 0xac, 0x5b, 0x2b, 0x89, 0x52 }
},
{
{ 0x78, 0x33, 0x48, 0xe7, 0x5a, 0xeb, 0x0f, 0x2f,
0xd7, 0xb1, 0x69, 0xbb, 0x8d, 0xc1, 0x67, 0x87 },
{ 0xF7, 0xC0, 0x13, 0xAC, 0x5B, 0x2B, 0x89, 0x52 },
{ 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 }
},
{
{ 0xDC, 0x49, 0xdb, 0x13, 0x75, 0xa5, 0x58, 0x4f,
0x64, 0x85, 0xb4, 0x13, 0xb5, 0xf1, 0x2b, 0xaf },
{ 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 },
{ 0x65, 0xc1, 0x78, 0xb2, 0x84, 0xd1, 0x97, 0xcc }
}
};
unsigned char tmp[2][8];
int x, y, err;
symmetric_key key;
for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
/* setup key */
if ((err = rc5_setup(tests[x].key, 16, 12, &key)) != CRYPT_OK) {
return err;
}
/* encrypt and decrypt */
rc5_ecb_encrypt(tests[x].pt, tmp[0], &key);
rc5_ecb_decrypt(tmp[0], tmp[1], &key);
/* compare */
if (compare_testvector(tmp[0], 8, tests[x].ct, 8, "RC5 Encrypt", x) != 0 ||
compare_testvector(tmp[1], 8, tests[x].pt, 8, "RC5 Decrypt", x) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 8; y++) tmp[0][y] = 0;
for (y = 0; y < 1000; y++) rc5_ecb_encrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 1000; y++) rc5_ecb_decrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
/** Terminate the context
@param skey The scheduled key
*/
void rc5_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int rc5_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 8) {
return CRYPT_INVALID_KEYSIZE;
} else if (*keysize > 128) {
*keysize = 128;
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

331
thirdparty/libtomcrypt/ciphers/rc6.c vendored Normal file
View File

@@ -0,0 +1,331 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file rc6.c
LTC_RC6 code by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_RC6
const struct ltc_cipher_descriptor rc6_desc =
{
"rc6",
3,
8, 128, 16, 20,
&rc6_setup,
&rc6_ecb_encrypt,
&rc6_ecb_decrypt,
&rc6_test,
&rc6_done,
&rc6_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static const ulong32 stab[44] = {
0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL,
0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL,
0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL,
0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL,
0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL,
0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL };
/**
Initialize the LTC_RC6 block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#else
int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#endif
{
ulong32 L[64], S[50], A, B, i, j, v, s, l;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
/* test parameters */
if (num_rounds != 0 && num_rounds != 20) {
return CRYPT_INVALID_ROUNDS;
}
/* key must be between 64 and 1024 bits */
if (keylen < 8 || keylen > 128) {
return CRYPT_INVALID_KEYSIZE;
}
/* copy the key into the L array */
for (A = i = j = 0; i < (ulong32)keylen; ) {
A = (A << 8) | ((ulong32)(key[i++] & 255));
if (!(i & 3)) {
L[j++] = BSWAP(A);
A = 0;
}
}
/* handle odd sized keys */
if (keylen & 3) {
A <<= (8 * (4 - (keylen&3)));
L[j++] = BSWAP(A);
}
/* setup the S array */
XMEMCPY(S, stab, 44 * sizeof(stab[0]));
/* mix buffer */
s = 3 * MAX(44, j);
l = j;
for (A = B = i = j = v = 0; v < s; v++) {
A = S[i] = ROLc(S[i] + A + B, 3);
B = L[j] = ROL(L[j] + A + B, (A+B));
if (++i == 44) { i = 0; }
if (++j == l) { j = 0; }
}
/* copy to key */
for (i = 0; i < 44; i++) {
skey->rc6.K[i] = S[i];
}
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int x;
x = _rc6_setup(key, keylen, num_rounds, skey);
burn_stack(sizeof(ulong32) * 122);
return x;
}
#endif
/**
Encrypts a block of text with LTC_RC6
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
*/
#ifdef LTC_CLEAN_STACK
static int _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 a,b,c,d,t,u, *K;
int r;
LTC_ARGCHK(skey != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LOAD32L(a,&pt[0]);LOAD32L(b,&pt[4]);LOAD32L(c,&pt[8]);LOAD32L(d,&pt[12]);
b += skey->rc6.K[0];
d += skey->rc6.K[1];
#define RND(a,b,c,d) \
t = (b * (b + b + 1)); t = ROLc(t, 5); \
u = (d * (d + d + 1)); u = ROLc(u, 5); \
a = ROL(a^t,u) + K[0]; \
c = ROL(c^u,t) + K[1]; K += 2;
K = skey->rc6.K + 2;
for (r = 0; r < 20; r += 4) {
RND(a,b,c,d);
RND(b,c,d,a);
RND(c,d,a,b);
RND(d,a,b,c);
}
#undef RND
a += skey->rc6.K[42];
c += skey->rc6.K[43];
STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
int err = _rc6_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(ulong32) * 6 + sizeof(int));
return err;
}
#endif
/**
Decrypts a block of text with LTC_RC6
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
*/
#ifdef LTC_CLEAN_STACK
static int _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 a,b,c,d,t,u, *K;
int r;
LTC_ARGCHK(skey != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LOAD32L(a,&ct[0]);LOAD32L(b,&ct[4]);LOAD32L(c,&ct[8]);LOAD32L(d,&ct[12]);
a -= skey->rc6.K[42];
c -= skey->rc6.K[43];
#define RND(a,b,c,d) \
t = (b * (b + b + 1)); t = ROLc(t, 5); \
u = (d * (d + d + 1)); u = ROLc(u, 5); \
c = ROR(c - K[1], t) ^ u; \
a = ROR(a - K[0], u) ^ t; K -= 2;
K = skey->rc6.K + 40;
for (r = 0; r < 20; r += 4) {
RND(d,a,b,c);
RND(c,d,a,b);
RND(b,c,d,a);
RND(a,b,c,d);
}
#undef RND
b -= skey->rc6.K[0];
d -= skey->rc6.K[1];
STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
int err = _rc6_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(ulong32) * 6 + sizeof(int));
return err;
}
#endif
/**
Performs a self-test of the LTC_RC6 block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int rc6_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
} tests[] = {
{
16,
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 },
{ 0x52, 0x4e, 0x19, 0x2f, 0x47, 0x15, 0xc6, 0x23,
0x1f, 0x51, 0xf6, 0x36, 0x7e, 0xa4, 0x3f, 0x18 }
},
{
24,
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 },
{ 0x68, 0x83, 0x29, 0xd0, 0x19, 0xe5, 0x05, 0x04,
0x1e, 0x52, 0xe9, 0x2a, 0xf9, 0x52, 0x91, 0xd4 }
},
{
32,
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0,
0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe },
{ 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 },
{ 0xc8, 0x24, 0x18, 0x16, 0xf0, 0xd7, 0xe4, 0x89,
0x20, 0xad, 0x16, 0xa1, 0x67, 0x4e, 0x5d, 0x48 }
}
};
unsigned char tmp[2][16];
int x, y, err;
symmetric_key key;
for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
/* setup key */
if ((err = rc6_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) {
return err;
}
/* encrypt and decrypt */
rc6_ecb_encrypt(tests[x].pt, tmp[0], &key);
rc6_ecb_decrypt(tmp[0], tmp[1], &key);
/* compare */
if (compare_testvector(tmp[0], 16, tests[x].ct, 16, "RC6 Encrypt", x) ||
compare_testvector(tmp[1], 16, tests[x].pt, 16, "RC6 Decrypt", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 16; y++) tmp[0][y] = 0;
for (y = 0; y < 1000; y++) rc6_ecb_encrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 1000; y++) rc6_ecb_decrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
/** Terminate the context
@param skey The scheduled key
*/
void rc6_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int rc6_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 8) {
return CRYPT_INVALID_KEYSIZE;
} else if (*keysize > 128) {
*keysize = 128;
}
return CRYPT_OK;
}
#endif /*LTC_RC6*/
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,495 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/*******************************************************************************
*
* FILE: safer.c
*
* LTC_DESCRIPTION: block-cipher algorithm LTC_SAFER (Secure And Fast Encryption
* Routine) in its four versions: LTC_SAFER K-64, LTC_SAFER K-128,
* LTC_SAFER SK-64 and LTC_SAFER SK-128.
*
* AUTHOR: Richard De Moliner (demoliner@isi.ee.ethz.ch)
* Signal and Information Processing Laboratory
* Swiss Federal Institute of Technology
* CH-8092 Zuerich, Switzerland
*
* DATE: September 9, 1995
*
* CHANGE HISTORY:
*
*******************************************************************************/
#include "tomcrypt.h"
#ifdef LTC_SAFER
#define __LTC_SAFER_TAB_C__
#include "safer_tab.c"
const struct ltc_cipher_descriptor safer_k64_desc = {
"safer-k64",
8, 8, 8, 8, LTC_SAFER_K64_DEFAULT_NOF_ROUNDS,
&safer_k64_setup,
&safer_ecb_encrypt,
&safer_ecb_decrypt,
&safer_k64_test,
&safer_done,
&safer_64_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
},
safer_sk64_desc = {
"safer-sk64",
9, 8, 8, 8, LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS,
&safer_sk64_setup,
&safer_ecb_encrypt,
&safer_ecb_decrypt,
&safer_sk64_test,
&safer_done,
&safer_64_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
},
safer_k128_desc = {
"safer-k128",
10, 16, 16, 8, LTC_SAFER_K128_DEFAULT_NOF_ROUNDS,
&safer_k128_setup,
&safer_ecb_encrypt,
&safer_ecb_decrypt,
&safer_sk128_test,
&safer_done,
&safer_128_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
},
safer_sk128_desc = {
"safer-sk128",
11, 16, 16, 8, LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS,
&safer_sk128_setup,
&safer_ecb_encrypt,
&safer_ecb_decrypt,
&safer_sk128_test,
&safer_done,
&safer_128_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
/******************* Constants ************************************************/
/* #define TAB_LEN 256 */
/******************* Assertions ***********************************************/
/******************* Macros ***************************************************/
#define ROL8(x, n) ((unsigned char)((unsigned int)(x) << (n)\
|(unsigned int)((x) & 0xFF) >> (8 - (n))))
#define EXP(x) safer_ebox[(x) & 0xFF]
#define LOG(x) safer_lbox[(x) & 0xFF]
#define PHT(x, y) { y += x; x += y; }
#define IPHT(x, y) { x -= y; y -= x; }
/******************* Types ****************************************************/
#ifdef LTC_CLEAN_STACK
static void _Safer_Expand_Userkey(const unsigned char *userkey_1,
const unsigned char *userkey_2,
unsigned int nof_rounds,
int strengthened,
safer_key_t key)
#else
static void Safer_Expand_Userkey(const unsigned char *userkey_1,
const unsigned char *userkey_2,
unsigned int nof_rounds,
int strengthened,
safer_key_t key)
#endif
{ unsigned int i, j, k;
unsigned char ka[LTC_SAFER_BLOCK_LEN + 1];
unsigned char kb[LTC_SAFER_BLOCK_LEN + 1];
if (LTC_SAFER_MAX_NOF_ROUNDS < nof_rounds)
nof_rounds = LTC_SAFER_MAX_NOF_ROUNDS;
*key++ = (unsigned char)nof_rounds;
ka[LTC_SAFER_BLOCK_LEN] = (unsigned char)0;
kb[LTC_SAFER_BLOCK_LEN] = (unsigned char)0;
k = 0;
for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) {
ka[j] = ROL8(userkey_1[j], 5);
ka[LTC_SAFER_BLOCK_LEN] ^= ka[j];
kb[j] = *key++ = userkey_2[j];
kb[LTC_SAFER_BLOCK_LEN] ^= kb[j];
}
for (i = 1; i <= nof_rounds; i++) {
for (j = 0; j < LTC_SAFER_BLOCK_LEN + 1; j++) {
ka[j] = ROL8(ka[j], 6);
kb[j] = ROL8(kb[j], 6);
}
if (strengthened) {
k = 2 * i - 1;
while (k >= (LTC_SAFER_BLOCK_LEN + 1)) { k -= LTC_SAFER_BLOCK_LEN + 1; }
}
for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) {
if (strengthened) {
*key++ = (ka[k]
+ safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF;
if (++k == (LTC_SAFER_BLOCK_LEN + 1)) { k = 0; }
} else {
*key++ = (ka[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF;
}
}
if (strengthened) {
k = 2 * i;
while (k >= (LTC_SAFER_BLOCK_LEN + 1)) { k -= LTC_SAFER_BLOCK_LEN + 1; }
}
for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) {
if (strengthened) {
*key++ = (kb[k]
+ safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF;
if (++k == (LTC_SAFER_BLOCK_LEN + 1)) { k = 0; }
} else {
*key++ = (kb[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF;
}
}
}
#ifdef LTC_CLEAN_STACK
zeromem(ka, sizeof(ka));
zeromem(kb, sizeof(kb));
#endif
}
#ifdef LTC_CLEAN_STACK
static void Safer_Expand_Userkey(const unsigned char *userkey_1,
const unsigned char *userkey_2,
unsigned int nof_rounds,
int strengthened,
safer_key_t key)
{
_Safer_Expand_Userkey(userkey_1, userkey_2, nof_rounds, strengthened, key);
burn_stack(sizeof(unsigned char) * (2 * (LTC_SAFER_BLOCK_LEN + 1)) + sizeof(unsigned int)*2);
}
#endif
int safer_k64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
{
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) {
return CRYPT_INVALID_ROUNDS;
}
if (keylen != 8) {
return CRYPT_INVALID_KEYSIZE;
}
Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_K64_DEFAULT_NOF_ROUNDS), 0, skey->safer.key);
return CRYPT_OK;
}
int safer_sk64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
{
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) {
return CRYPT_INVALID_ROUNDS;
}
if (keylen != 8) {
return CRYPT_INVALID_KEYSIZE;
}
Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS), 1, skey->safer.key);
return CRYPT_OK;
}
int safer_k128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
{
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) {
return CRYPT_INVALID_ROUNDS;
}
if (keylen != 16) {
return CRYPT_INVALID_KEYSIZE;
}
Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_K128_DEFAULT_NOF_ROUNDS), 0, skey->safer.key);
return CRYPT_OK;
}
int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
{
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) {
return CRYPT_INVALID_ROUNDS;
}
if (keylen != 16) {
return CRYPT_INVALID_KEYSIZE;
}
Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0?numrounds:LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS), 1, skey->safer.key);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int _safer_ecb_encrypt(const unsigned char *block_in,
unsigned char *block_out,
symmetric_key *skey)
#else
int safer_ecb_encrypt(const unsigned char *block_in,
unsigned char *block_out,
symmetric_key *skey)
#endif
{ unsigned char a, b, c, d, e, f, g, h, t;
unsigned int round;
unsigned char *key;
LTC_ARGCHK(block_in != NULL);
LTC_ARGCHK(block_out != NULL);
LTC_ARGCHK(skey != NULL);
key = skey->safer.key;
a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3];
e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7];
if (LTC_SAFER_MAX_NOF_ROUNDS < (round = *key)) round = LTC_SAFER_MAX_NOF_ROUNDS;
while(round-- > 0)
{
a ^= *++key; b += *++key; c += *++key; d ^= *++key;
e ^= *++key; f += *++key; g += *++key; h ^= *++key;
a = EXP(a) + *++key; b = LOG(b) ^ *++key;
c = LOG(c) ^ *++key; d = EXP(d) + *++key;
e = EXP(e) + *++key; f = LOG(f) ^ *++key;
g = LOG(g) ^ *++key; h = EXP(h) + *++key;
PHT(a, b); PHT(c, d); PHT(e, f); PHT(g, h);
PHT(a, c); PHT(e, g); PHT(b, d); PHT(f, h);
PHT(a, e); PHT(b, f); PHT(c, g); PHT(d, h);
t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t;
}
a ^= *++key; b += *++key; c += *++key; d ^= *++key;
e ^= *++key; f += *++key; g += *++key; h ^= *++key;
block_out[0] = a & 0xFF; block_out[1] = b & 0xFF;
block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int safer_ecb_encrypt(const unsigned char *block_in,
unsigned char *block_out,
symmetric_key *skey)
{
int err = _safer_ecb_encrypt(block_in, block_out, skey);
burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
return err;
}
#endif
#ifdef LTC_CLEAN_STACK
static int _safer_ecb_decrypt(const unsigned char *block_in,
unsigned char *block_out,
symmetric_key *skey)
#else
int safer_ecb_decrypt(const unsigned char *block_in,
unsigned char *block_out,
symmetric_key *skey)
#endif
{ unsigned char a, b, c, d, e, f, g, h, t;
unsigned int round;
unsigned char *key;
LTC_ARGCHK(block_in != NULL);
LTC_ARGCHK(block_out != NULL);
LTC_ARGCHK(skey != NULL);
key = skey->safer.key;
a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3];
e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7];
if (LTC_SAFER_MAX_NOF_ROUNDS < (round = *key)) round = LTC_SAFER_MAX_NOF_ROUNDS;
key += LTC_SAFER_BLOCK_LEN * (1 + 2 * round);
h ^= *key; g -= *--key; f -= *--key; e ^= *--key;
d ^= *--key; c -= *--key; b -= *--key; a ^= *--key;
while (round--)
{
t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t;
IPHT(a, e); IPHT(b, f); IPHT(c, g); IPHT(d, h);
IPHT(a, c); IPHT(e, g); IPHT(b, d); IPHT(f, h);
IPHT(a, b); IPHT(c, d); IPHT(e, f); IPHT(g, h);
h -= *--key; g ^= *--key; f ^= *--key; e -= *--key;
d -= *--key; c ^= *--key; b ^= *--key; a -= *--key;
h = LOG(h) ^ *--key; g = EXP(g) - *--key;
f = EXP(f) - *--key; e = LOG(e) ^ *--key;
d = LOG(d) ^ *--key; c = EXP(c) - *--key;
b = EXP(b) - *--key; a = LOG(a) ^ *--key;
}
block_out[0] = a & 0xFF; block_out[1] = b & 0xFF;
block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int safer_ecb_decrypt(const unsigned char *block_in,
unsigned char *block_out,
symmetric_key *skey)
{
int err = _safer_ecb_decrypt(block_in, block_out, skey);
burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
return err;
}
#endif
int safer_64_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 8) {
return CRYPT_INVALID_KEYSIZE;
} else {
*keysize = 8;
return CRYPT_OK;
}
}
int safer_128_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 16) {
return CRYPT_INVALID_KEYSIZE;
} else {
*keysize = 16;
return CRYPT_OK;
}
}
int safer_k64_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const unsigned char k64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
k64_key[] = { 8, 7, 6, 5, 4, 3, 2, 1 },
k64_ct[] = { 200, 242, 156, 221, 135, 120, 62, 217 };
symmetric_key skey;
unsigned char buf[2][8];
int err;
/* test K64 */
if ((err = safer_k64_setup(k64_key, 8, 6, &skey)) != CRYPT_OK) {
return err;
}
safer_ecb_encrypt(k64_pt, buf[0], &skey);
safer_ecb_decrypt(buf[0], buf[1], &skey);
if (compare_testvector(buf[0], 8, k64_ct, 8, "Safer K64 Encrypt", 0) != 0 ||
compare_testvector(buf[1], 8, k64_pt, 8, "Safer K64 Decrypt", 0) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
int safer_sk64_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const unsigned char sk64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
sk64_key[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
sk64_ct[] = { 95, 206, 155, 162, 5, 132, 56, 199 };
symmetric_key skey;
unsigned char buf[2][8];
int err, y;
/* test SK64 */
if ((err = safer_sk64_setup(sk64_key, 8, 6, &skey)) != CRYPT_OK) {
return err;
}
safer_ecb_encrypt(sk64_pt, buf[0], &skey);
safer_ecb_decrypt(buf[0], buf[1], &skey);
if (compare_testvector(buf[0], 8, sk64_ct, 8, "Safer SK64 Encrypt", 0) != 0 ||
compare_testvector(buf[1], 8, sk64_pt, 8, "Safer SK64 Decrypt", 0) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 8; y++) buf[0][y] = 0;
for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey);
for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey);
for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
return CRYPT_OK;
#endif
}
/** Terminate the context
@param skey The scheduled key
*/
void safer_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
int safer_sk128_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const unsigned char sk128_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
sk128_key[] = { 1, 2, 3, 4, 5, 6, 7, 8,
0, 0, 0, 0, 0, 0, 0, 0 },
sk128_ct[] = { 255, 120, 17, 228, 179, 167, 46, 113 };
symmetric_key skey;
unsigned char buf[2][8];
int err, y;
/* test SK128 */
if ((err = safer_sk128_setup(sk128_key, 16, 0, &skey)) != CRYPT_OK) {
return err;
}
safer_ecb_encrypt(sk128_pt, buf[0], &skey);
safer_ecb_decrypt(buf[0], buf[1], &skey);
if (compare_testvector(buf[0], 8, sk128_ct, 8, "Safer SK128 Encrypt", 0) != 0 ||
compare_testvector(buf[1], 8, sk128_pt, 8, "Safer SK128 Decrypt", 0) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 8; y++) buf[0][y] = 0;
for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey);
for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey);
for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,64 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file safer_tab.c
Tables for LTC_SAFER block ciphers
*/
#ifdef __LTC_SAFER_TAB_C__
/* This is the box defined by ebox[x] = 45^x mod 257.
* Its assumed that the value "256" corresponds to zero. */
static const unsigned char safer_ebox[256] = {
1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63,
8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247,
64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177,
255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131,
241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20,
129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160,
4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252,
32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217,
0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194,
249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10,
193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80,
2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126,
16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237,
128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97,
253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5,
225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40
};
/* This is the inverse of ebox or the base 45 logarithm */
static const unsigned char safer_lbox[256] = {
128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248,
192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130,
112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37,
201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15,
32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198,
175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84,
121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188,
189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217,
208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158,
210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42,
95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219,
164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29,
41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14,
122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104,
109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66,
184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48
};
#endif /* __LTC_SAFER_TAB_C__ */
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,568 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file saferp.c
LTC_SAFER+ Implementation by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_SAFERP
#define __LTC_SAFER_TAB_C__
#include "safer_tab.c"
const struct ltc_cipher_descriptor saferp_desc =
{
"safer+",
4,
16, 32, 16, 8,
&saferp_setup,
&saferp_ecb_encrypt,
&saferp_ecb_decrypt,
&saferp_test,
&saferp_done,
&saferp_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
/* ROUND(b,i)
*
* This is one forward key application. Note the basic form is
* key addition, substitution, key addition. The safer_ebox and safer_lbox
* are the exponentiation box and logarithm boxes respectively.
* The value of 'i' is the current round number which allows this
* function to be unrolled massively. Most of LTC_SAFER+'s speed
* comes from not having to compute indirect accesses into the
* array of 16 bytes b[0..15] which is the block of data
*/
#define ROUND(b, i) do { \
b[0] = (safer_ebox[(b[0] ^ skey->saferp.K[i][0]) & 255] + skey->saferp.K[i+1][0]) & 255; \
b[1] = safer_lbox[(b[1] + skey->saferp.K[i][1]) & 255] ^ skey->saferp.K[i+1][1]; \
b[2] = safer_lbox[(b[2] + skey->saferp.K[i][2]) & 255] ^ skey->saferp.K[i+1][2]; \
b[3] = (safer_ebox[(b[3] ^ skey->saferp.K[i][3]) & 255] + skey->saferp.K[i+1][3]) & 255; \
b[4] = (safer_ebox[(b[4] ^ skey->saferp.K[i][4]) & 255] + skey->saferp.K[i+1][4]) & 255; \
b[5] = safer_lbox[(b[5] + skey->saferp.K[i][5]) & 255] ^ skey->saferp.K[i+1][5]; \
b[6] = safer_lbox[(b[6] + skey->saferp.K[i][6]) & 255] ^ skey->saferp.K[i+1][6]; \
b[7] = (safer_ebox[(b[7] ^ skey->saferp.K[i][7]) & 255] + skey->saferp.K[i+1][7]) & 255; \
b[8] = (safer_ebox[(b[8] ^ skey->saferp.K[i][8]) & 255] + skey->saferp.K[i+1][8]) & 255; \
b[9] = safer_lbox[(b[9] + skey->saferp.K[i][9]) & 255] ^ skey->saferp.K[i+1][9]; \
b[10] = safer_lbox[(b[10] + skey->saferp.K[i][10]) & 255] ^ skey->saferp.K[i+1][10]; \
b[11] = (safer_ebox[(b[11] ^ skey->saferp.K[i][11]) & 255] + skey->saferp.K[i+1][11]) & 255; \
b[12] = (safer_ebox[(b[12] ^ skey->saferp.K[i][12]) & 255] + skey->saferp.K[i+1][12]) & 255; \
b[13] = safer_lbox[(b[13] + skey->saferp.K[i][13]) & 255] ^ skey->saferp.K[i+1][13]; \
b[14] = safer_lbox[(b[14] + skey->saferp.K[i][14]) & 255] ^ skey->saferp.K[i+1][14]; \
b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255; \
} while (0)
/* This is one inverse key application */
#define iROUND(b, i) do { \
b[0] = safer_lbox[(b[0] - skey->saferp.K[i+1][0]) & 255] ^ skey->saferp.K[i][0]; \
b[1] = (safer_ebox[(b[1] ^ skey->saferp.K[i+1][1]) & 255] - skey->saferp.K[i][1]) & 255; \
b[2] = (safer_ebox[(b[2] ^ skey->saferp.K[i+1][2]) & 255] - skey->saferp.K[i][2]) & 255; \
b[3] = safer_lbox[(b[3] - skey->saferp.K[i+1][3]) & 255] ^ skey->saferp.K[i][3]; \
b[4] = safer_lbox[(b[4] - skey->saferp.K[i+1][4]) & 255] ^ skey->saferp.K[i][4]; \
b[5] = (safer_ebox[(b[5] ^ skey->saferp.K[i+1][5]) & 255] - skey->saferp.K[i][5]) & 255; \
b[6] = (safer_ebox[(b[6] ^ skey->saferp.K[i+1][6]) & 255] - skey->saferp.K[i][6]) & 255; \
b[7] = safer_lbox[(b[7] - skey->saferp.K[i+1][7]) & 255] ^ skey->saferp.K[i][7]; \
b[8] = safer_lbox[(b[8] - skey->saferp.K[i+1][8]) & 255] ^ skey->saferp.K[i][8]; \
b[9] = (safer_ebox[(b[9] ^ skey->saferp.K[i+1][9]) & 255] - skey->saferp.K[i][9]) & 255; \
b[10] = (safer_ebox[(b[10] ^ skey->saferp.K[i+1][10]) & 255] - skey->saferp.K[i][10]) & 255; \
b[11] = safer_lbox[(b[11] - skey->saferp.K[i+1][11]) & 255] ^ skey->saferp.K[i][11]; \
b[12] = safer_lbox[(b[12] - skey->saferp.K[i+1][12]) & 255] ^ skey->saferp.K[i][12]; \
b[13] = (safer_ebox[(b[13] ^ skey->saferp.K[i+1][13]) & 255] - skey->saferp.K[i][13]) & 255; \
b[14] = (safer_ebox[(b[14] ^ skey->saferp.K[i+1][14]) & 255] - skey->saferp.K[i][14]) & 255; \
b[15] = safer_lbox[(b[15] - skey->saferp.K[i+1][15]) & 255] ^ skey->saferp.K[i][15]; \
} while (0)
/* This is a forward single layer PHT transform. */
#define PHT(b) do { \
b[0] = (b[0] + (b[1] = (b[0] + b[1]) & 255)) & 255; \
b[2] = (b[2] + (b[3] = (b[3] + b[2]) & 255)) & 255; \
b[4] = (b[4] + (b[5] = (b[5] + b[4]) & 255)) & 255; \
b[6] = (b[6] + (b[7] = (b[7] + b[6]) & 255)) & 255; \
b[8] = (b[8] + (b[9] = (b[9] + b[8]) & 255)) & 255; \
b[10] = (b[10] + (b[11] = (b[11] + b[10]) & 255)) & 255; \
b[12] = (b[12] + (b[13] = (b[13] + b[12]) & 255)) & 255; \
b[14] = (b[14] + (b[15] = (b[15] + b[14]) & 255)) & 255; \
} while (0)
/* This is an inverse single layer PHT transform */
#define iPHT(b) do { \
b[15] = (b[15] - (b[14] = (b[14] - b[15]) & 255)) & 255; \
b[13] = (b[13] - (b[12] = (b[12] - b[13]) & 255)) & 255; \
b[11] = (b[11] - (b[10] = (b[10] - b[11]) & 255)) & 255; \
b[9] = (b[9] - (b[8] = (b[8] - b[9]) & 255)) & 255; \
b[7] = (b[7] - (b[6] = (b[6] - b[7]) & 255)) & 255; \
b[5] = (b[5] - (b[4] = (b[4] - b[5]) & 255)) & 255; \
b[3] = (b[3] - (b[2] = (b[2] - b[3]) & 255)) & 255; \
b[1] = (b[1] - (b[0] = (b[0] - b[1]) & 255)) & 255; \
} while (0)
/* This is the "Armenian" Shuffle. It takes the input from b and stores it in b2 */
#define SHUF(b, b2) do { \
b2[0] = b[8]; b2[1] = b[11]; b2[2] = b[12]; b2[3] = b[15]; \
b2[4] = b[2]; b2[5] = b[1]; b2[6] = b[6]; b2[7] = b[5]; \
b2[8] = b[10]; b2[9] = b[9]; b2[10] = b[14]; b2[11] = b[13]; \
b2[12] = b[0]; b2[13] = b[7]; b2[14] = b[4]; b2[15] = b[3]; \
} while (0)
/* This is the inverse shuffle. It takes from b and gives to b2 */
#define iSHUF(b, b2) do { \
b2[0] = b[12]; b2[1] = b[5]; b2[2] = b[4]; b2[3] = b[15]; \
b2[4] = b[14]; b2[5] = b[7]; b2[6] = b[6]; b2[7] = b[13]; \
b2[8] = b[0]; b2[9] = b[9]; b2[10] = b[8]; b2[11] = b[1]; \
b2[12] = b[2]; b2[13] = b[11]; b2[14] = b[10]; b2[15] = b[3]; \
} while (0)
/* The complete forward Linear Transform layer.
* Note that alternating usage of b and b2.
* Each round of LT starts in 'b' and ends in 'b2'.
*/
#define LT(b, b2) do { \
PHT(b); SHUF(b, b2); \
PHT(b2); SHUF(b2, b); \
PHT(b); SHUF(b, b2); \
PHT(b2); \
} while (0)
/* This is the inverse linear transform layer. */
#define iLT(b, b2) do { \
iPHT(b); \
iSHUF(b, b2); iPHT(b2); \
iSHUF(b2, b); iPHT(b); \
iSHUF(b, b2); iPHT(b2); \
} while (0)
#ifdef LTC_SMALL_CODE
static void _round(unsigned char *b, int i, symmetric_key *skey)
{
ROUND(b, i);
}
static void _iround(unsigned char *b, int i, symmetric_key *skey)
{
iROUND(b, i);
}
static void _lt(unsigned char *b, unsigned char *b2)
{
LT(b, b2);
}
static void _ilt(unsigned char *b, unsigned char *b2)
{
iLT(b, b2);
}
#undef ROUND
#define ROUND(b, i) _round(b, i, skey)
#undef iROUND
#define iROUND(b, i) _iround(b, i, skey)
#undef LT
#define LT(b, b2) _lt(b, b2)
#undef iLT
#define iLT(b, b2) _ilt(b, b2)
#endif
/* These are the 33, 128-bit bias words for the key schedule */
static const unsigned char safer_bias[33][16] = {
{ 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172, 100},
{ 236, 171, 170, 198, 103, 149, 88, 13, 248, 154, 246, 110, 102, 220, 5, 61},
{ 138, 195, 216, 137, 106, 233, 54, 73, 67, 191, 235, 212, 150, 155, 104, 160},
{ 93, 87, 146, 31, 213, 113, 92, 187, 34, 193, 190, 123, 188, 153, 99, 148},
{ 42, 97, 184, 52, 50, 25, 253, 251, 23, 64, 230, 81, 29, 65, 68, 143},
{ 221, 4, 128, 222, 231, 49, 214, 127, 1, 162, 247, 57, 218, 111, 35, 202},
{ 58, 208, 28, 209, 48, 62, 18, 161, 205, 15, 224, 168, 175, 130, 89, 44},
{ 125, 173, 178, 239, 194, 135, 206, 117, 6, 19, 2, 144, 79, 46, 114, 51},
{ 192, 141, 207, 169, 129, 226, 196, 39, 47, 108, 122, 159, 82, 225, 21, 56},
{ 252, 32, 66, 199, 8, 228, 9, 85, 94, 140, 20, 118, 96, 255, 223, 215},
{ 250, 11, 33, 0, 26, 249, 166, 185, 232, 158, 98, 76, 217, 145, 80, 210},
{ 24, 180, 7, 132, 234, 91, 164, 200, 14, 203, 72, 105, 75, 78, 156, 53},
{ 69, 77, 84, 229, 37, 60, 12, 74, 139, 63, 204, 167, 219, 107, 174, 244},
{ 45, 243, 124, 109, 157, 181, 38, 116, 242, 147, 83, 176, 240, 17, 237, 131},
{ 182, 3, 22, 115, 59, 30, 142, 112, 189, 134, 27, 71, 126, 36, 86, 241},
{ 136, 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172},
{ 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51, 239},
{ 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, 129, 151, 113, 202},
{ 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 4, 180, 133, 74, 246},
{ 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 32, 155, 36, 78, 169, 152},
{ 171, 242, 96, 208, 108, 234, 250, 199, 217, 0, 212, 31, 110, 67, 188, 236},
{ 137, 254, 122, 93, 73, 201, 50, 194, 249, 154, 248, 109, 22, 219, 89, 150},
{ 233, 205, 230, 70, 66, 143, 10, 193, 204, 185, 101, 176, 210, 198, 172, 30},
{ 98, 41, 46, 14, 116, 80, 2, 90, 195, 37, 123, 138, 42, 91, 240, 6},
{ 71, 111, 112, 157, 126, 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104},
{ 117, 125, 228, 237, 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175},
{ 229, 25, 97, 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35},
{ 200, 5, 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7},
{ 40, 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207},
{ 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247},
{ 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, 255},
{ 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51}};
/**
Initialize the LTC_SAFER+ block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
unsigned x, y, z;
unsigned char t[33];
static const int rounds[3] = { 8, 12, 16 };
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
/* check arguments */
if (keylen != 16 && keylen != 24 && keylen != 32) {
return CRYPT_INVALID_KEYSIZE;
}
/* Is the number of rounds valid? Either use zero for default or
* 8,12,16 rounds for 16,24,32 byte keys
*/
if (num_rounds != 0 && num_rounds != rounds[(keylen/8)-2]) {
return CRYPT_INVALID_ROUNDS;
}
/* 128 bit key version */
if (keylen == 16) {
/* copy key into t */
for (x = y = 0; x < 16; x++) {
t[x] = key[x];
y ^= key[x];
}
t[16] = y;
/* make round keys */
for (x = 0; x < 16; x++) {
skey->saferp.K[0][x] = t[x];
}
/* make the 16 other keys as a transformation of the first key */
for (x = 1; x < 17; x++) {
/* rotate 3 bits each */
for (y = 0; y < 17; y++) {
t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
}
/* select and add */
z = x;
for (y = 0; y < 16; y++) {
skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255;
if (++z == 17) { z = 0; }
}
}
skey->saferp.rounds = 8;
} else if (keylen == 24) {
/* copy key into t */
for (x = y = 0; x < 24; x++) {
t[x] = key[x];
y ^= key[x];
}
t[24] = y;
/* make round keys */
for (x = 0; x < 16; x++) {
skey->saferp.K[0][x] = t[x];
}
for (x = 1; x < 25; x++) {
/* rotate 3 bits each */
for (y = 0; y < 25; y++) {
t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
}
/* select and add */
z = x;
for (y = 0; y < 16; y++) {
skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255;
if (++z == 25) { z = 0; }
}
}
skey->saferp.rounds = 12;
} else {
/* copy key into t */
for (x = y = 0; x < 32; x++) {
t[x] = key[x];
y ^= key[x];
}
t[32] = y;
/* make round keys */
for (x = 0; x < 16; x++) {
skey->saferp.K[0][x] = t[x];
}
for (x = 1; x < 33; x++) {
/* rotate 3 bits each */
for (y = 0; y < 33; y++) {
t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
}
/* select and add */
z = x;
for (y = 0; y < 16; y++) {
skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255;
if (++z == 33) { z = 0; }
}
}
skey->saferp.rounds = 16;
}
#ifdef LTC_CLEAN_STACK
zeromem(t, sizeof(t));
#endif
return CRYPT_OK;
}
/**
Encrypts a block of text with LTC_SAFER+
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
unsigned char b[16];
int x;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
/* do eight rounds */
for (x = 0; x < 16; x++) {
b[x] = pt[x];
}
ROUND(b, 0); LT(b, ct);
ROUND(ct, 2); LT(ct, b);
ROUND(b, 4); LT(b, ct);
ROUND(ct, 6); LT(ct, b);
ROUND(b, 8); LT(b, ct);
ROUND(ct, 10); LT(ct, b);
ROUND(b, 12); LT(b, ct);
ROUND(ct, 14); LT(ct, b);
/* 192-bit key? */
if (skey->saferp.rounds > 8) {
ROUND(b, 16); LT(b, ct);
ROUND(ct, 18); LT(ct, b);
ROUND(b, 20); LT(b, ct);
ROUND(ct, 22); LT(ct, b);
}
/* 256-bit key? */
if (skey->saferp.rounds > 12) {
ROUND(b, 24); LT(b, ct);
ROUND(ct, 26); LT(ct, b);
ROUND(b, 28); LT(b, ct);
ROUND(ct, 30); LT(ct, b);
}
ct[0] = b[0] ^ skey->saferp.K[skey->saferp.rounds*2][0];
ct[1] = (b[1] + skey->saferp.K[skey->saferp.rounds*2][1]) & 255;
ct[2] = (b[2] + skey->saferp.K[skey->saferp.rounds*2][2]) & 255;
ct[3] = b[3] ^ skey->saferp.K[skey->saferp.rounds*2][3];
ct[4] = b[4] ^ skey->saferp.K[skey->saferp.rounds*2][4];
ct[5] = (b[5] + skey->saferp.K[skey->saferp.rounds*2][5]) & 255;
ct[6] = (b[6] + skey->saferp.K[skey->saferp.rounds*2][6]) & 255;
ct[7] = b[7] ^ skey->saferp.K[skey->saferp.rounds*2][7];
ct[8] = b[8] ^ skey->saferp.K[skey->saferp.rounds*2][8];
ct[9] = (b[9] + skey->saferp.K[skey->saferp.rounds*2][9]) & 255;
ct[10] = (b[10] + skey->saferp.K[skey->saferp.rounds*2][10]) & 255;
ct[11] = b[11] ^ skey->saferp.K[skey->saferp.rounds*2][11];
ct[12] = b[12] ^ skey->saferp.K[skey->saferp.rounds*2][12];
ct[13] = (b[13] + skey->saferp.K[skey->saferp.rounds*2][13]) & 255;
ct[14] = (b[14] + skey->saferp.K[skey->saferp.rounds*2][14]) & 255;
ct[15] = b[15] ^ skey->saferp.K[skey->saferp.rounds*2][15];
#ifdef LTC_CLEAN_STACK
zeromem(b, sizeof(b));
#endif
return CRYPT_OK;
}
/**
Decrypts a block of text with LTC_SAFER+
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
unsigned char b[16];
int x;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
/* do eight rounds */
b[0] = ct[0] ^ skey->saferp.K[skey->saferp.rounds*2][0];
b[1] = (ct[1] - skey->saferp.K[skey->saferp.rounds*2][1]) & 255;
b[2] = (ct[2] - skey->saferp.K[skey->saferp.rounds*2][2]) & 255;
b[3] = ct[3] ^ skey->saferp.K[skey->saferp.rounds*2][3];
b[4] = ct[4] ^ skey->saferp.K[skey->saferp.rounds*2][4];
b[5] = (ct[5] - skey->saferp.K[skey->saferp.rounds*2][5]) & 255;
b[6] = (ct[6] - skey->saferp.K[skey->saferp.rounds*2][6]) & 255;
b[7] = ct[7] ^ skey->saferp.K[skey->saferp.rounds*2][7];
b[8] = ct[8] ^ skey->saferp.K[skey->saferp.rounds*2][8];
b[9] = (ct[9] - skey->saferp.K[skey->saferp.rounds*2][9]) & 255;
b[10] = (ct[10] - skey->saferp.K[skey->saferp.rounds*2][10]) & 255;
b[11] = ct[11] ^ skey->saferp.K[skey->saferp.rounds*2][11];
b[12] = ct[12] ^ skey->saferp.K[skey->saferp.rounds*2][12];
b[13] = (ct[13] - skey->saferp.K[skey->saferp.rounds*2][13]) & 255;
b[14] = (ct[14] - skey->saferp.K[skey->saferp.rounds*2][14]) & 255;
b[15] = ct[15] ^ skey->saferp.K[skey->saferp.rounds*2][15];
/* 256-bit key? */
if (skey->saferp.rounds > 12) {
iLT(b, pt); iROUND(pt, 30);
iLT(pt, b); iROUND(b, 28);
iLT(b, pt); iROUND(pt, 26);
iLT(pt, b); iROUND(b, 24);
}
/* 192-bit key? */
if (skey->saferp.rounds > 8) {
iLT(b, pt); iROUND(pt, 22);
iLT(pt, b); iROUND(b, 20);
iLT(b, pt); iROUND(pt, 18);
iLT(pt, b); iROUND(b, 16);
}
iLT(b, pt); iROUND(pt, 14);
iLT(pt, b); iROUND(b, 12);
iLT(b, pt); iROUND(pt,10);
iLT(pt, b); iROUND(b, 8);
iLT(b, pt); iROUND(pt,6);
iLT(pt, b); iROUND(b, 4);
iLT(b, pt); iROUND(pt,2);
iLT(pt, b); iROUND(b, 0);
for (x = 0; x < 16; x++) {
pt[x] = b[x];
}
#ifdef LTC_CLEAN_STACK
zeromem(b, sizeof(b));
#endif
return CRYPT_OK;
}
/**
Performs a self-test of the LTC_SAFER+ block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int saferp_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
} tests[] = {
{
16,
{ 41, 35, 190, 132, 225, 108, 214, 174,
82, 144, 73, 241, 241, 187, 233, 235 },
{ 179, 166, 219, 60, 135, 12, 62, 153,
36, 94, 13, 28, 6, 183, 71, 222 },
{ 224, 31, 182, 10, 12, 255, 84, 70,
127, 13, 89, 249, 9, 57, 165, 220 }
}, {
24,
{ 72, 211, 143, 117, 230, 217, 29, 42,
229, 192, 247, 43, 120, 129, 135, 68,
14, 95, 80, 0, 212, 97, 141, 190 },
{ 123, 5, 21, 7, 59, 51, 130, 31,
24, 112, 146, 218, 100, 84, 206, 177 },
{ 92, 136, 4, 63, 57, 95, 100, 0,
150, 130, 130, 16, 193, 111, 219, 133 }
}, {
32,
{ 243, 168, 141, 254, 190, 242, 235, 113,
255, 160, 208, 59, 117, 6, 140, 126,
135, 120, 115, 77, 208, 190, 130, 190,
219, 194, 70, 65, 43, 140, 250, 48 },
{ 127, 112, 240, 167, 84, 134, 50, 149,
170, 91, 104, 19, 11, 230, 252, 245 },
{ 88, 11, 25, 36, 172, 229, 202, 213,
170, 65, 105, 153, 220, 104, 153, 138 }
}
};
unsigned char tmp[2][16];
symmetric_key skey;
int err, i, y;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
if ((err = saferp_setup(tests[i].key, tests[i].keylen, 0, &skey)) != CRYPT_OK) {
return err;
}
saferp_ecb_encrypt(tests[i].pt, tmp[0], &skey);
saferp_ecb_decrypt(tmp[0], tmp[1], &skey);
/* compare */
if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "Safer+ Encrypt", i) ||
compare_testvector(tmp[1], 16, tests[i].pt, 16, "Safer+ Decrypt", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 16; y++) tmp[0][y] = 0;
for (y = 0; y < 1000; y++) saferp_ecb_encrypt(tmp[0], tmp[0], &skey);
for (y = 0; y < 1000; y++) saferp_ecb_decrypt(tmp[0], tmp[0], &skey);
for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
/** Terminate the context
@param skey The scheduled key
*/
void saferp_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int saferp_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 16)
return CRYPT_INVALID_KEYSIZE;
if (*keysize < 24) {
*keysize = 16;
} else if (*keysize < 32) {
*keysize = 24;
} else {
*keysize = 32;
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,343 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file skipjack.c
Skipjack Implementation by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_SKIPJACK
const struct ltc_cipher_descriptor skipjack_desc =
{
"skipjack",
17,
10, 10, 8, 32,
&skipjack_setup,
&skipjack_ecb_encrypt,
&skipjack_ecb_decrypt,
&skipjack_test,
&skipjack_done,
&skipjack_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
static const unsigned char sbox[256] = {
0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9,
0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28,
0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53,
0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2,
0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8,
0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90,
0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76,
0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d,
0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18,
0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4,
0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40,
0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5,
0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2,
0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8,
0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac,
0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46
};
/* simple x + 1 (mod 10) in one step. */
static const int keystep[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
/* simple x - 1 (mod 10) in one step */
static const int ikeystep[] = { 9, 0, 1, 2, 3, 4, 5, 6, 7, 8 };
/**
Initialize the Skipjack block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int x;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (keylen != 10) {
return CRYPT_INVALID_KEYSIZE;
}
if (num_rounds != 32 && num_rounds != 0) {
return CRYPT_INVALID_ROUNDS;
}
/* make sure the key is in range for platforms where CHAR_BIT != 8 */
for (x = 0; x < 10; x++) {
skey->skipjack.key[x] = key[x] & 255;
}
return CRYPT_OK;
}
#define RULE_A \
tmp = g_func(w1, &kp, skey->skipjack.key); \
w1 = tmp ^ w4 ^ x; \
w4 = w3; w3 = w2; \
w2 = tmp;
#define RULE_B \
tmp = g_func(w1, &kp, skey->skipjack.key); \
tmp1 = w4; w4 = w3; \
w3 = w1 ^ w2 ^ x; \
w1 = tmp1; w2 = tmp;
#define RULE_A1 \
tmp = w1 ^ w2 ^ x; \
w1 = ig_func(w2, &kp, skey->skipjack.key); \
w2 = w3; w3 = w4; w4 = tmp;
#define RULE_B1 \
tmp = ig_func(w2, &kp, skey->skipjack.key); \
w2 = tmp ^ w3 ^ x; \
w3 = w4; w4 = w1; w1 = tmp;
static unsigned g_func(unsigned w, int *kp, unsigned char *key)
{
unsigned char g1,g2;
g1 = (w >> 8) & 255; g2 = w & 255;
g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp];
g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp];
g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp];
g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp];
return ((unsigned)g1<<8)|(unsigned)g2;
}
static unsigned ig_func(unsigned w, int *kp, unsigned char *key)
{
unsigned char g1,g2;
g1 = (w >> 8) & 255; g2 = w & 255;
*kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]];
*kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]];
*kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]];
*kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]];
return ((unsigned)g1<<8)|(unsigned)g2;
}
/**
Encrypts a block of text with Skipjack
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
unsigned w1,w2,w3,w4,tmp,tmp1;
int x, kp;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
/* load block */
w1 = ((unsigned)pt[0]<<8)|pt[1];
w2 = ((unsigned)pt[2]<<8)|pt[3];
w3 = ((unsigned)pt[4]<<8)|pt[5];
w4 = ((unsigned)pt[6]<<8)|pt[7];
/* 8 rounds of RULE A */
for (x = 1, kp = 0; x < 9; x++) {
RULE_A;
}
/* 8 rounds of RULE B */
for (; x < 17; x++) {
RULE_B;
}
/* 8 rounds of RULE A */
for (; x < 25; x++) {
RULE_A;
}
/* 8 rounds of RULE B */
for (; x < 33; x++) {
RULE_B;
}
/* store block */
ct[0] = (w1>>8)&255; ct[1] = w1&255;
ct[2] = (w2>>8)&255; ct[3] = w2&255;
ct[4] = (w3>>8)&255; ct[5] = w3&255;
ct[6] = (w4>>8)&255; ct[7] = w4&255;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
int err = _skipjack_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(unsigned) * 8 + sizeof(int) * 2);
return err;
}
#endif
/**
Decrypts a block of text with Skipjack
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
unsigned w1,w2,w3,w4,tmp;
int x, kp;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
/* load block */
w1 = ((unsigned)ct[0]<<8)|ct[1];
w2 = ((unsigned)ct[2]<<8)|ct[3];
w3 = ((unsigned)ct[4]<<8)|ct[5];
w4 = ((unsigned)ct[6]<<8)|ct[7];
/* 8 rounds of RULE B^-1
Note the value "kp = 8" comes from "kp = (32 * 4) mod 10" where 32*4 is 128 which mod 10 is 8
*/
for (x = 32, kp = 8; x > 24; x--) {
RULE_B1;
}
/* 8 rounds of RULE A^-1 */
for (; x > 16; x--) {
RULE_A1;
}
/* 8 rounds of RULE B^-1 */
for (; x > 8; x--) {
RULE_B1;
}
/* 8 rounds of RULE A^-1 */
for (; x > 0; x--) {
RULE_A1;
}
/* store block */
pt[0] = (w1>>8)&255; pt[1] = w1&255;
pt[2] = (w2>>8)&255; pt[3] = w2&255;
pt[4] = (w3>>8)&255; pt[5] = w3&255;
pt[6] = (w4>>8)&255; pt[7] = w4&255;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
int err = _skipjack_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(unsigned) * 7 + sizeof(int) * 2);
return err;
}
#endif
/**
Performs a self-test of the Skipjack block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int skipjack_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
unsigned char key[10], pt[8], ct[8];
} tests[] = {
{
{ 0x00, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 },
{ 0x33, 0x22, 0x11, 0x00, 0xdd, 0xcc, 0xbb, 0xaa },
{ 0x25, 0x87, 0xca, 0xe2, 0x7a, 0x12, 0xd3, 0x00 }
}
};
unsigned char buf[2][8];
int x, y, err;
symmetric_key key;
for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
/* setup key */
if ((err = skipjack_setup(tests[x].key, 10, 0, &key)) != CRYPT_OK) {
return err;
}
/* encrypt and decrypt */
skipjack_ecb_encrypt(tests[x].pt, buf[0], &key);
skipjack_ecb_decrypt(buf[0], buf[1], &key);
/* compare */
if (compare_testvector(buf[0], 8, tests[x].ct, 8, "Skipjack Encrypt", x) != 0 ||
compare_testvector(buf[1], 8, tests[x].pt, 8, "Skipjack Decrypt", x) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 8; y++) buf[0][y] = 0;
for (y = 0; y < 1000; y++) skipjack_ecb_encrypt(buf[0], buf[0], &key);
for (y = 0; y < 1000; y++) skipjack_ecb_decrypt(buf[0], buf[0], &key);
for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
/** Terminate the context
@param skey The scheduled key
*/
void skipjack_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int skipjack_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 10) {
return CRYPT_INVALID_KEYSIZE;
} else if (*keysize > 10) {
*keysize = 10;
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,711 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file twofish.c
Implementation of Twofish by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_TWOFISH
/* first LTC_TWOFISH_ALL_TABLES must ensure LTC_TWOFISH_TABLES is defined */
#ifdef LTC_TWOFISH_ALL_TABLES
#ifndef LTC_TWOFISH_TABLES
#define LTC_TWOFISH_TABLES
#endif
#endif
const struct ltc_cipher_descriptor twofish_desc =
{
"twofish",
7,
16, 32, 16, 16,
&twofish_setup,
&twofish_ecb_encrypt,
&twofish_ecb_decrypt,
&twofish_test,
&twofish_done,
&twofish_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
/* the two polynomials */
#define MDS_POLY 0x169
#define RS_POLY 0x14D
/* The 4x8 RS Linear Transform */
static const unsigned char RS[4][8] = {
{ 0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E },
{ 0xA4, 0x56, 0x82, 0xF3, 0X1E, 0XC6, 0X68, 0XE5 },
{ 0X02, 0XA1, 0XFC, 0XC1, 0X47, 0XAE, 0X3D, 0X19 },
{ 0XA4, 0X55, 0X87, 0X5A, 0X58, 0XDB, 0X9E, 0X03 }
};
#ifdef LTC_TWOFISH_SMALL
/* sbox usage orderings */
static const unsigned char qord[4][5] = {
{ 1, 1, 0, 0, 1 },
{ 0, 1, 1, 0, 0 },
{ 0, 0, 0, 1, 1 },
{ 1, 0, 1, 1, 0 }
};
#endif /* LTC_TWOFISH_SMALL */
#ifdef LTC_TWOFISH_TABLES
#define __LTC_TWOFISH_TAB_C__
#include "twofish_tab.c"
#define sbox(i, x) ((ulong32)SBOX[i][(x)&255])
#else
/* The Q-box tables */
static const unsigned char qbox[2][4][16] = {
{
{ 0x8, 0x1, 0x7, 0xD, 0x6, 0xF, 0x3, 0x2, 0x0, 0xB, 0x5, 0x9, 0xE, 0xC, 0xA, 0x4 },
{ 0xE, 0XC, 0XB, 0X8, 0X1, 0X2, 0X3, 0X5, 0XF, 0X4, 0XA, 0X6, 0X7, 0X0, 0X9, 0XD },
{ 0XB, 0XA, 0X5, 0XE, 0X6, 0XD, 0X9, 0X0, 0XC, 0X8, 0XF, 0X3, 0X2, 0X4, 0X7, 0X1 },
{ 0XD, 0X7, 0XF, 0X4, 0X1, 0X2, 0X6, 0XE, 0X9, 0XB, 0X3, 0X0, 0X8, 0X5, 0XC, 0XA }
},
{
{ 0X2, 0X8, 0XB, 0XD, 0XF, 0X7, 0X6, 0XE, 0X3, 0X1, 0X9, 0X4, 0X0, 0XA, 0XC, 0X5 },
{ 0X1, 0XE, 0X2, 0XB, 0X4, 0XC, 0X3, 0X7, 0X6, 0XD, 0XA, 0X5, 0XF, 0X9, 0X0, 0X8 },
{ 0X4, 0XC, 0X7, 0X5, 0X1, 0X6, 0X9, 0XA, 0X0, 0XE, 0XD, 0X8, 0X2, 0XB, 0X3, 0XF },
{ 0xB, 0X9, 0X5, 0X1, 0XC, 0X3, 0XD, 0XE, 0X6, 0X4, 0X7, 0XF, 0X2, 0X0, 0X8, 0XA }
}
};
/* computes S_i[x] */
#ifdef LTC_CLEAN_STACK
static ulong32 _sbox(int i, ulong32 x)
#else
static ulong32 sbox(int i, ulong32 x)
#endif
{
unsigned char a0,b0,a1,b1,a2,b2,a3,b3,a4,b4,y;
/* a0,b0 = [x/16], x mod 16 */
a0 = (unsigned char)((x>>4)&15);
b0 = (unsigned char)((x)&15);
/* a1 = a0 ^ b0 */
a1 = a0 ^ b0;
/* b1 = a0 ^ ROR(b0, 1) ^ 8a0 */
b1 = (a0 ^ ((b0<<3)|(b0>>1)) ^ (a0<<3)) & 15;
/* a2,b2 = t0[a1], t1[b1] */
a2 = qbox[i][0][(int)a1];
b2 = qbox[i][1][(int)b1];
/* a3 = a2 ^ b2 */
a3 = a2 ^ b2;
/* b3 = a2 ^ ROR(b2, 1) ^ 8a2 */
b3 = (a2 ^ ((b2<<3)|(b2>>1)) ^ (a2<<3)) & 15;
/* a4,b4 = t2[a3], t3[b3] */
a4 = qbox[i][2][(int)a3];
b4 = qbox[i][3][(int)b3];
/* y = 16b4 + a4 */
y = (b4 << 4) + a4;
/* return result */
return (ulong32)y;
}
#ifdef LTC_CLEAN_STACK
static ulong32 sbox(int i, ulong32 x)
{
ulong32 y;
y = _sbox(i, x);
burn_stack(sizeof(unsigned char) * 11);
return y;
}
#endif /* LTC_CLEAN_STACK */
#endif /* LTC_TWOFISH_TABLES */
/* computes ab mod p */
static ulong32 gf_mult(ulong32 a, ulong32 b, ulong32 p)
{
ulong32 result, B[2], P[2];
P[1] = p;
B[1] = b;
result = P[0] = B[0] = 0;
/* unrolled branchless GF multiplier */
result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1);
result ^= B[a&1];
return result;
}
/* computes [y0 y1 y2 y3] = MDS . [x0] */
#ifndef LTC_TWOFISH_TABLES
static ulong32 mds_column_mult(unsigned char in, int col)
{
ulong32 x01, x5B, xEF;
x01 = in;
x5B = gf_mult(in, 0x5B, MDS_POLY);
xEF = gf_mult(in, 0xEF, MDS_POLY);
switch (col) {
case 0:
return (x01 << 0 ) |
(x5B << 8 ) |
(xEF << 16) |
(xEF << 24);
case 1:
return (xEF << 0 ) |
(xEF << 8 ) |
(x5B << 16) |
(x01 << 24);
case 2:
return (x5B << 0 ) |
(xEF << 8 ) |
(x01 << 16) |
(xEF << 24);
case 3:
return (x5B << 0 ) |
(x01 << 8 ) |
(xEF << 16) |
(x5B << 24);
}
/* avoid warnings, we'd never get here normally but just to calm compiler warnings... */
return 0;
}
#else /* !LTC_TWOFISH_TABLES */
#define mds_column_mult(x, i) mds_tab[i][x]
#endif /* LTC_TWOFISH_TABLES */
/* Computes [y0 y1 y2 y3] = MDS . [x0 x1 x2 x3] */
static void mds_mult(const unsigned char *in, unsigned char *out)
{
int x;
ulong32 tmp;
for (tmp = x = 0; x < 4; x++) {
tmp ^= mds_column_mult(in[x], x);
}
STORE32L(tmp, out);
}
#ifdef LTC_TWOFISH_ALL_TABLES
/* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */
static void rs_mult(const unsigned char *in, unsigned char *out)
{
ulong32 tmp;
tmp = rs_tab0[in[0]] ^ rs_tab1[in[1]] ^ rs_tab2[in[2]] ^ rs_tab3[in[3]] ^
rs_tab4[in[4]] ^ rs_tab5[in[5]] ^ rs_tab6[in[6]] ^ rs_tab7[in[7]];
STORE32L(tmp, out);
}
#else /* !LTC_TWOFISH_ALL_TABLES */
/* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */
static void rs_mult(const unsigned char *in, unsigned char *out)
{
int x, y;
for (x = 0; x < 4; x++) {
out[x] = 0;
for (y = 0; y < 8; y++) {
out[x] ^= gf_mult(in[y], RS[x][y], RS_POLY);
}
}
}
#endif
/* computes h(x) */
static void h_func(const unsigned char *in, unsigned char *out, unsigned char *M, int k, int offset)
{
int x;
unsigned char y[4];
for (x = 0; x < 4; x++) {
y[x] = in[x];
}
switch (k) {
case 4:
y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (6 + offset) + 0]);
y[1] = (unsigned char)(sbox(0, (ulong32)y[1]) ^ M[4 * (6 + offset) + 1]);
y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (6 + offset) + 2]);
y[3] = (unsigned char)(sbox(1, (ulong32)y[3]) ^ M[4 * (6 + offset) + 3]);
/* FALLTHROUGH */
case 3:
y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (4 + offset) + 0]);
y[1] = (unsigned char)(sbox(1, (ulong32)y[1]) ^ M[4 * (4 + offset) + 1]);
y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (4 + offset) + 2]);
y[3] = (unsigned char)(sbox(0, (ulong32)y[3]) ^ M[4 * (4 + offset) + 3]);
/* FALLTHROUGH */
case 2:
y[0] = (unsigned char)(sbox(1, sbox(0, sbox(0, (ulong32)y[0]) ^ M[4 * (2 + offset) + 0]) ^ M[4 * (0 + offset) + 0]));
y[1] = (unsigned char)(sbox(0, sbox(0, sbox(1, (ulong32)y[1]) ^ M[4 * (2 + offset) + 1]) ^ M[4 * (0 + offset) + 1]));
y[2] = (unsigned char)(sbox(1, sbox(1, sbox(0, (ulong32)y[2]) ^ M[4 * (2 + offset) + 2]) ^ M[4 * (0 + offset) + 2]));
y[3] = (unsigned char)(sbox(0, sbox(1, sbox(1, (ulong32)y[3]) ^ M[4 * (2 + offset) + 3]) ^ M[4 * (0 + offset) + 3]));
/* FALLTHROUGH */
}
mds_mult(y, out);
}
#ifndef LTC_TWOFISH_SMALL
/* for GCC we don't use pointer aliases */
#if defined(__GNUC__)
#define S1 skey->twofish.S[0]
#define S2 skey->twofish.S[1]
#define S3 skey->twofish.S[2]
#define S4 skey->twofish.S[3]
#endif
/* the G function */
#define g_func(x, dum) (S1[byte(x,0)] ^ S2[byte(x,1)] ^ S3[byte(x,2)] ^ S4[byte(x,3)])
#define g1_func(x, dum) (S2[byte(x,0)] ^ S3[byte(x,1)] ^ S4[byte(x,2)] ^ S1[byte(x,3)])
#else
#ifdef LTC_CLEAN_STACK
static ulong32 _g_func(ulong32 x, symmetric_key *key)
#else
static ulong32 g_func(ulong32 x, symmetric_key *key)
#endif
{
unsigned char g, i, y, z;
ulong32 res;
res = 0;
for (y = 0; y < 4; y++) {
z = key->twofish.start;
/* do unkeyed substitution */
g = sbox(qord[y][z++], (x >> (8*y)) & 255);
/* first subkey */
i = 0;
/* do key mixing+sbox until z==5 */
while (z != 5) {
g = g ^ key->twofish.S[4*i++ + y];
g = sbox(qord[y][z++], g);
}
/* multiply g by a column of the MDS */
res ^= mds_column_mult(g, y);
}
return res;
}
#define g1_func(x, key) g_func(ROLc(x, 8), key)
#ifdef LTC_CLEAN_STACK
static ulong32 g_func(ulong32 x, symmetric_key *key)
{
ulong32 y;
y = _g_func(x, key);
burn_stack(sizeof(unsigned char) * 4 + sizeof(ulong32));
return y;
}
#endif /* LTC_CLEAN_STACK */
#endif /* LTC_TWOFISH_SMALL */
/**
Initialize the Twofish block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#else
int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#endif
{
#ifndef LTC_TWOFISH_SMALL
unsigned char S[4*4], tmpx0, tmpx1;
#endif
int k, x, y;
unsigned char tmp[4], tmp2[4], M[8*4];
ulong32 A, B;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
/* invalid arguments? */
if (num_rounds != 16 && num_rounds != 0) {
return CRYPT_INVALID_ROUNDS;
}
if (keylen != 16 && keylen != 24 && keylen != 32) {
return CRYPT_INVALID_KEYSIZE;
}
/* k = keysize/64 [but since our keysize is in bytes...] */
k = keylen / 8;
/* copy the key into M */
for (x = 0; x < keylen; x++) {
M[x] = key[x] & 255;
}
/* create the S[..] words */
#ifndef LTC_TWOFISH_SMALL
for (x = 0; x < k; x++) {
rs_mult(M+(x*8), S+(x*4));
}
#else
for (x = 0; x < k; x++) {
rs_mult(M+(x*8), skey->twofish.S+(x*4));
}
#endif
/* make subkeys */
for (x = 0; x < 20; x++) {
/* A = h(p * 2x, Me) */
for (y = 0; y < 4; y++) {
tmp[y] = x+x;
}
h_func(tmp, tmp2, M, k, 0);
LOAD32L(A, tmp2);
/* B = ROL(h(p * (2x + 1), Mo), 8) */
for (y = 0; y < 4; y++) {
tmp[y] = (unsigned char)(x+x+1);
}
h_func(tmp, tmp2, M, k, 1);
LOAD32L(B, tmp2);
B = ROLc(B, 8);
/* K[2i] = A + B */
skey->twofish.K[x+x] = (A + B) & 0xFFFFFFFFUL;
/* K[2i+1] = (A + 2B) <<< 9 */
skey->twofish.K[x+x+1] = ROLc(B + B + A, 9);
}
#ifndef LTC_TWOFISH_SMALL
/* make the sboxes (large ram variant) */
if (k == 2) {
for (x = 0; x < 256; x++) {
tmpx0 = (unsigned char)sbox(0, x);
tmpx1 = (unsigned char)sbox(1, x);
skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0);
skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1);
skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2);
skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, tmpx1 ^ S[3]) ^ S[7])),3);
}
} else if (k == 3) {
for (x = 0; x < 256; x++) {
tmpx0 = (unsigned char)sbox(0, x);
tmpx1 = (unsigned char)sbox(1, x);
skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0);
skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1);
skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2);
skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, tmpx0 ^ S[3]) ^ S[7]) ^ S[11])),3);
}
} else {
for (x = 0; x < 256; x++) {
tmpx0 = (unsigned char)sbox(0, x);
tmpx1 = (unsigned char)sbox(1, x);
skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, sbox(1, tmpx1 ^ S[0]) ^ S[4]) ^ S[8]) ^ S[12])),0);
skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, sbox(1, tmpx0 ^ S[1]) ^ S[5]) ^ S[9]) ^ S[13])),1);
skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10]) ^ S[14])),2);
skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, sbox(0, tmpx1 ^ S[3]) ^ S[7]) ^ S[11]) ^ S[15])),3);
}
}
#else
/* where to start in the sbox layers */
/* small ram variant */
switch (k) {
case 4 : skey->twofish.start = 0; break;
case 3 : skey->twofish.start = 1; break;
default: skey->twofish.start = 2; break;
}
#endif
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int x;
x = _twofish_setup(key, keylen, num_rounds, skey);
burn_stack(sizeof(int) * 7 + sizeof(unsigned char) * 56 + sizeof(ulong32) * 2);
return x;
}
#endif
/**
Encrypts a block of text with Twofish
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
int r;
#if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
ulong32 *S1, *S2, *S3, *S4;
#endif
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
#if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
S1 = skey->twofish.S[0];
S2 = skey->twofish.S[1];
S3 = skey->twofish.S[2];
S4 = skey->twofish.S[3];
#endif
LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]);
LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]);
a ^= skey->twofish.K[0];
b ^= skey->twofish.K[1];
c ^= skey->twofish.K[2];
d ^= skey->twofish.K[3];
k = skey->twofish.K + 8;
for (r = 8; r != 0; --r) {
t2 = g1_func(b, skey);
t1 = g_func(a, skey) + t2;
c = RORc(c ^ (t1 + k[0]), 1);
d = ROLc(d, 1) ^ (t2 + t1 + k[1]);
t2 = g1_func(d, skey);
t1 = g_func(c, skey) + t2;
a = RORc(a ^ (t1 + k[2]), 1);
b = ROLc(b, 1) ^ (t2 + t1 + k[3]);
k += 4;
}
/* output with "undo last swap" */
ta = c ^ skey->twofish.K[4];
tb = d ^ skey->twofish.K[5];
tc = a ^ skey->twofish.K[6];
td = b ^ skey->twofish.K[7];
/* store output */
STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]);
STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
int err = _twofish_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(ulong32) * 10 + sizeof(int));
return err;
}
#endif
/**
Decrypts a block of text with Twofish
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k;
int r;
#if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
ulong32 *S1, *S2, *S3, *S4;
#endif
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
#if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__)
S1 = skey->twofish.S[0];
S2 = skey->twofish.S[1];
S3 = skey->twofish.S[2];
S4 = skey->twofish.S[3];
#endif
/* load input */
LOAD32L(ta,&ct[0]); LOAD32L(tb,&ct[4]);
LOAD32L(tc,&ct[8]); LOAD32L(td,&ct[12]);
/* undo undo final swap */
a = tc ^ skey->twofish.K[6];
b = td ^ skey->twofish.K[7];
c = ta ^ skey->twofish.K[4];
d = tb ^ skey->twofish.K[5];
k = skey->twofish.K + 36;
for (r = 8; r != 0; --r) {
t2 = g1_func(d, skey);
t1 = g_func(c, skey) + t2;
a = ROLc(a, 1) ^ (t1 + k[2]);
b = RORc(b ^ (t2 + t1 + k[3]), 1);
t2 = g1_func(b, skey);
t1 = g_func(a, skey) + t2;
c = ROLc(c, 1) ^ (t1 + k[0]);
d = RORc(d ^ (t2 + t1 + k[1]), 1);
k -= 4;
}
/* pre-white */
a ^= skey->twofish.K[0];
b ^= skey->twofish.K[1];
c ^= skey->twofish.K[2];
d ^= skey->twofish.K[3];
/* store */
STORE32L(a, &pt[0]); STORE32L(b, &pt[4]);
STORE32L(c, &pt[8]); STORE32L(d, &pt[12]);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
int err =_twofish_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(ulong32) * 10 + sizeof(int));
return err;
}
#endif
/**
Performs a self-test of the Twofish block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int twofish_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
} tests[] = {
{ 16,
{ 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A },
{ 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,
0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 },
{ 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,
0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 }
}, {
24,
{ 0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36,
0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88,
0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 },
{ 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5,
0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 },
{ 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45,
0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 }
}, {
32,
{ 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F },
{ 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F,
0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 },
{ 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97,
0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA }
}
};
symmetric_key key;
unsigned char tmp[2][16];
int err, i, y;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
return err;
}
twofish_ecb_encrypt(tests[i].pt, tmp[0], &key);
twofish_ecb_decrypt(tmp[0], tmp[1], &key);
if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "Twofish Encrypt", i) != 0 ||
compare_testvector(tmp[1], 16, tests[i].pt, 16, "Twofish Decrypt", i) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 16; y++) tmp[0][y] = 0;
for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 1000; y++) twofish_ecb_decrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
/** Terminate the context
@param skey The scheduled key
*/
void twofish_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int twofish_keysize(int *keysize)
{
LTC_ARGCHK(keysize);
if (*keysize < 16)
return CRYPT_INVALID_KEYSIZE;
if (*keysize < 24) {
*keysize = 16;
return CRYPT_OK;
} else if (*keysize < 32) {
*keysize = 24;
return CRYPT_OK;
} else {
*keysize = 32;
return CRYPT_OK;
}
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,496 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file twofish_tab.c
Twofish tables, Tom St Denis
*/
#ifdef LTC_TWOFISH_TABLES
#ifdef __LTC_TWOFISH_TAB_C__
/* pre generated 8x8 tables from the four 4x4s */
static const unsigned char SBOX[2][256] = {
{
0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92,
0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38, 0x0d, 0xc6, 0x35, 0x98,
0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13,
0x94, 0x48, 0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23,
0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82, 0x63, 0x01,
0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe,
0x16, 0x0c, 0xe3, 0x61, 0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c,
0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1,
0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95,
0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7, 0xfb, 0xc3, 0x8e, 0xb5,
0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9,
0x62, 0x71, 0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8,
0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7, 0xa1, 0x1d,
0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11,
0x31, 0xc2, 0x27, 0x90, 0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c,
0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef,
0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87,
0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64, 0x2a, 0xce, 0xcb, 0x2f,
0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e,
0xa7, 0x5a, 0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02,
0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d, 0x57, 0xc7,
0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12,
0x58, 0x07, 0x99, 0x34, 0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc,
0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4,
0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d,
0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0},
{
0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3,
0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b, 0xd6, 0x32, 0xd8, 0xfd,
0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa,
0x06, 0x3f, 0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d,
0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5, 0xa0, 0x84,
0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54,
0x92, 0x74, 0x36, 0x51, 0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60,
0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c,
0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3,
0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8, 0xa6, 0x83, 0x20, 0xff,
0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7,
0x2b, 0xe2, 0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9,
0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17, 0x66, 0x94,
0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c,
0xef, 0xd1, 0x53, 0x3e, 0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76,
0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9,
0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23,
0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48, 0x4f, 0xf2, 0x65, 0x8e,
0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f,
0x05, 0x64, 0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5,
0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69, 0x29, 0x2e,
0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34,
0x35, 0x6a, 0xcf, 0xdc, 0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4,
0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9,
0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25,
0x86, 0x56, 0x55, 0x09, 0xbe, 0x91}
};
/* the 4x4 MDS in a nicer format */
static const ulong32 mds_tab[4][256] = {
{
0x00000000UL, 0xefef5b01UL, 0xb7b7b602UL, 0x5858ed03UL, 0x07070504UL, 0xe8e85e05UL, 0xb0b0b306UL, 0x5f5fe807UL,
0x0e0e0a08UL, 0xe1e15109UL, 0xb9b9bc0aUL, 0x5656e70bUL, 0x09090f0cUL, 0xe6e6540dUL, 0xbebeb90eUL, 0x5151e20fUL,
0x1c1c1410UL, 0xf3f34f11UL, 0xababa212UL, 0x4444f913UL, 0x1b1b1114UL, 0xf4f44a15UL, 0xacaca716UL, 0x4343fc17UL,
0x12121e18UL, 0xfdfd4519UL, 0xa5a5a81aUL, 0x4a4af31bUL, 0x15151b1cUL, 0xfafa401dUL, 0xa2a2ad1eUL, 0x4d4df61fUL,
0x38382820UL, 0xd7d77321UL, 0x8f8f9e22UL, 0x6060c523UL, 0x3f3f2d24UL, 0xd0d07625UL, 0x88889b26UL, 0x6767c027UL,
0x36362228UL, 0xd9d97929UL, 0x8181942aUL, 0x6e6ecf2bUL, 0x3131272cUL, 0xdede7c2dUL, 0x8686912eUL, 0x6969ca2fUL,
0x24243c30UL, 0xcbcb6731UL, 0x93938a32UL, 0x7c7cd133UL, 0x23233934UL, 0xcccc6235UL, 0x94948f36UL, 0x7b7bd437UL,
0x2a2a3638UL, 0xc5c56d39UL, 0x9d9d803aUL, 0x7272db3bUL, 0x2d2d333cUL, 0xc2c2683dUL, 0x9a9a853eUL, 0x7575de3fUL,
0x70705040UL, 0x9f9f0b41UL, 0xc7c7e642UL, 0x2828bd43UL, 0x77775544UL, 0x98980e45UL, 0xc0c0e346UL, 0x2f2fb847UL,
0x7e7e5a48UL, 0x91910149UL, 0xc9c9ec4aUL, 0x2626b74bUL, 0x79795f4cUL, 0x9696044dUL, 0xcecee94eUL, 0x2121b24fUL,
0x6c6c4450UL, 0x83831f51UL, 0xdbdbf252UL, 0x3434a953UL, 0x6b6b4154UL, 0x84841a55UL, 0xdcdcf756UL, 0x3333ac57UL,
0x62624e58UL, 0x8d8d1559UL, 0xd5d5f85aUL, 0x3a3aa35bUL, 0x65654b5cUL, 0x8a8a105dUL, 0xd2d2fd5eUL, 0x3d3da65fUL,
0x48487860UL, 0xa7a72361UL, 0xffffce62UL, 0x10109563UL, 0x4f4f7d64UL, 0xa0a02665UL, 0xf8f8cb66UL, 0x17179067UL,
0x46467268UL, 0xa9a92969UL, 0xf1f1c46aUL, 0x1e1e9f6bUL, 0x4141776cUL, 0xaeae2c6dUL, 0xf6f6c16eUL, 0x19199a6fUL,
0x54546c70UL, 0xbbbb3771UL, 0xe3e3da72UL, 0x0c0c8173UL, 0x53536974UL, 0xbcbc3275UL, 0xe4e4df76UL, 0x0b0b8477UL,
0x5a5a6678UL, 0xb5b53d79UL, 0xededd07aUL, 0x02028b7bUL, 0x5d5d637cUL, 0xb2b2387dUL, 0xeaead57eUL, 0x05058e7fUL,
0xe0e0a080UL, 0x0f0ffb81UL, 0x57571682UL, 0xb8b84d83UL, 0xe7e7a584UL, 0x0808fe85UL, 0x50501386UL, 0xbfbf4887UL,
0xeeeeaa88UL, 0x0101f189UL, 0x59591c8aUL, 0xb6b6478bUL, 0xe9e9af8cUL, 0x0606f48dUL, 0x5e5e198eUL, 0xb1b1428fUL,
0xfcfcb490UL, 0x1313ef91UL, 0x4b4b0292UL, 0xa4a45993UL, 0xfbfbb194UL, 0x1414ea95UL, 0x4c4c0796UL, 0xa3a35c97UL,
0xf2f2be98UL, 0x1d1de599UL, 0x4545089aUL, 0xaaaa539bUL, 0xf5f5bb9cUL, 0x1a1ae09dUL, 0x42420d9eUL, 0xadad569fUL,
0xd8d888a0UL, 0x3737d3a1UL, 0x6f6f3ea2UL, 0x808065a3UL, 0xdfdf8da4UL, 0x3030d6a5UL, 0x68683ba6UL, 0x878760a7UL,
0xd6d682a8UL, 0x3939d9a9UL, 0x616134aaUL, 0x8e8e6fabUL, 0xd1d187acUL, 0x3e3edcadUL, 0x666631aeUL, 0x89896aafUL,
0xc4c49cb0UL, 0x2b2bc7b1UL, 0x73732ab2UL, 0x9c9c71b3UL, 0xc3c399b4UL, 0x2c2cc2b5UL, 0x74742fb6UL, 0x9b9b74b7UL,
0xcaca96b8UL, 0x2525cdb9UL, 0x7d7d20baUL, 0x92927bbbUL, 0xcdcd93bcUL, 0x2222c8bdUL, 0x7a7a25beUL, 0x95957ebfUL,
0x9090f0c0UL, 0x7f7fabc1UL, 0x272746c2UL, 0xc8c81dc3UL, 0x9797f5c4UL, 0x7878aec5UL, 0x202043c6UL, 0xcfcf18c7UL,
0x9e9efac8UL, 0x7171a1c9UL, 0x29294ccaUL, 0xc6c617cbUL, 0x9999ffccUL, 0x7676a4cdUL, 0x2e2e49ceUL, 0xc1c112cfUL,
0x8c8ce4d0UL, 0x6363bfd1UL, 0x3b3b52d2UL, 0xd4d409d3UL, 0x8b8be1d4UL, 0x6464bad5UL, 0x3c3c57d6UL, 0xd3d30cd7UL,
0x8282eed8UL, 0x6d6db5d9UL, 0x353558daUL, 0xdada03dbUL, 0x8585ebdcUL, 0x6a6ab0ddUL, 0x32325ddeUL, 0xdddd06dfUL,
0xa8a8d8e0UL, 0x474783e1UL, 0x1f1f6ee2UL, 0xf0f035e3UL, 0xafafdde4UL, 0x404086e5UL, 0x18186be6UL, 0xf7f730e7UL,
0xa6a6d2e8UL, 0x494989e9UL, 0x111164eaUL, 0xfefe3febUL, 0xa1a1d7ecUL, 0x4e4e8cedUL, 0x161661eeUL, 0xf9f93aefUL,
0xb4b4ccf0UL, 0x5b5b97f1UL, 0x03037af2UL, 0xecec21f3UL, 0xb3b3c9f4UL, 0x5c5c92f5UL, 0x04047ff6UL, 0xebeb24f7UL,
0xbabac6f8UL, 0x55559df9UL, 0x0d0d70faUL, 0xe2e22bfbUL, 0xbdbdc3fcUL, 0x525298fdUL, 0x0a0a75feUL, 0xe5e52effUL
},
{
0x00000000UL, 0x015befefUL, 0x02b6b7b7UL, 0x03ed5858UL, 0x04050707UL, 0x055ee8e8UL, 0x06b3b0b0UL, 0x07e85f5fUL,
0x080a0e0eUL, 0x0951e1e1UL, 0x0abcb9b9UL, 0x0be75656UL, 0x0c0f0909UL, 0x0d54e6e6UL, 0x0eb9bebeUL, 0x0fe25151UL,
0x10141c1cUL, 0x114ff3f3UL, 0x12a2ababUL, 0x13f94444UL, 0x14111b1bUL, 0x154af4f4UL, 0x16a7acacUL, 0x17fc4343UL,
0x181e1212UL, 0x1945fdfdUL, 0x1aa8a5a5UL, 0x1bf34a4aUL, 0x1c1b1515UL, 0x1d40fafaUL, 0x1eada2a2UL, 0x1ff64d4dUL,
0x20283838UL, 0x2173d7d7UL, 0x229e8f8fUL, 0x23c56060UL, 0x242d3f3fUL, 0x2576d0d0UL, 0x269b8888UL, 0x27c06767UL,
0x28223636UL, 0x2979d9d9UL, 0x2a948181UL, 0x2bcf6e6eUL, 0x2c273131UL, 0x2d7cdedeUL, 0x2e918686UL, 0x2fca6969UL,
0x303c2424UL, 0x3167cbcbUL, 0x328a9393UL, 0x33d17c7cUL, 0x34392323UL, 0x3562ccccUL, 0x368f9494UL, 0x37d47b7bUL,
0x38362a2aUL, 0x396dc5c5UL, 0x3a809d9dUL, 0x3bdb7272UL, 0x3c332d2dUL, 0x3d68c2c2UL, 0x3e859a9aUL, 0x3fde7575UL,
0x40507070UL, 0x410b9f9fUL, 0x42e6c7c7UL, 0x43bd2828UL, 0x44557777UL, 0x450e9898UL, 0x46e3c0c0UL, 0x47b82f2fUL,
0x485a7e7eUL, 0x49019191UL, 0x4aecc9c9UL, 0x4bb72626UL, 0x4c5f7979UL, 0x4d049696UL, 0x4ee9ceceUL, 0x4fb22121UL,
0x50446c6cUL, 0x511f8383UL, 0x52f2dbdbUL, 0x53a93434UL, 0x54416b6bUL, 0x551a8484UL, 0x56f7dcdcUL, 0x57ac3333UL,
0x584e6262UL, 0x59158d8dUL, 0x5af8d5d5UL, 0x5ba33a3aUL, 0x5c4b6565UL, 0x5d108a8aUL, 0x5efdd2d2UL, 0x5fa63d3dUL,
0x60784848UL, 0x6123a7a7UL, 0x62ceffffUL, 0x63951010UL, 0x647d4f4fUL, 0x6526a0a0UL, 0x66cbf8f8UL, 0x67901717UL,
0x68724646UL, 0x6929a9a9UL, 0x6ac4f1f1UL, 0x6b9f1e1eUL, 0x6c774141UL, 0x6d2caeaeUL, 0x6ec1f6f6UL, 0x6f9a1919UL,
0x706c5454UL, 0x7137bbbbUL, 0x72dae3e3UL, 0x73810c0cUL, 0x74695353UL, 0x7532bcbcUL, 0x76dfe4e4UL, 0x77840b0bUL,
0x78665a5aUL, 0x793db5b5UL, 0x7ad0ededUL, 0x7b8b0202UL, 0x7c635d5dUL, 0x7d38b2b2UL, 0x7ed5eaeaUL, 0x7f8e0505UL,
0x80a0e0e0UL, 0x81fb0f0fUL, 0x82165757UL, 0x834db8b8UL, 0x84a5e7e7UL, 0x85fe0808UL, 0x86135050UL, 0x8748bfbfUL,
0x88aaeeeeUL, 0x89f10101UL, 0x8a1c5959UL, 0x8b47b6b6UL, 0x8cafe9e9UL, 0x8df40606UL, 0x8e195e5eUL, 0x8f42b1b1UL,
0x90b4fcfcUL, 0x91ef1313UL, 0x92024b4bUL, 0x9359a4a4UL, 0x94b1fbfbUL, 0x95ea1414UL, 0x96074c4cUL, 0x975ca3a3UL,
0x98bef2f2UL, 0x99e51d1dUL, 0x9a084545UL, 0x9b53aaaaUL, 0x9cbbf5f5UL, 0x9de01a1aUL, 0x9e0d4242UL, 0x9f56adadUL,
0xa088d8d8UL, 0xa1d33737UL, 0xa23e6f6fUL, 0xa3658080UL, 0xa48ddfdfUL, 0xa5d63030UL, 0xa63b6868UL, 0xa7608787UL,
0xa882d6d6UL, 0xa9d93939UL, 0xaa346161UL, 0xab6f8e8eUL, 0xac87d1d1UL, 0xaddc3e3eUL, 0xae316666UL, 0xaf6a8989UL,
0xb09cc4c4UL, 0xb1c72b2bUL, 0xb22a7373UL, 0xb3719c9cUL, 0xb499c3c3UL, 0xb5c22c2cUL, 0xb62f7474UL, 0xb7749b9bUL,
0xb896cacaUL, 0xb9cd2525UL, 0xba207d7dUL, 0xbb7b9292UL, 0xbc93cdcdUL, 0xbdc82222UL, 0xbe257a7aUL, 0xbf7e9595UL,
0xc0f09090UL, 0xc1ab7f7fUL, 0xc2462727UL, 0xc31dc8c8UL, 0xc4f59797UL, 0xc5ae7878UL, 0xc6432020UL, 0xc718cfcfUL,
0xc8fa9e9eUL, 0xc9a17171UL, 0xca4c2929UL, 0xcb17c6c6UL, 0xccff9999UL, 0xcda47676UL, 0xce492e2eUL, 0xcf12c1c1UL,
0xd0e48c8cUL, 0xd1bf6363UL, 0xd2523b3bUL, 0xd309d4d4UL, 0xd4e18b8bUL, 0xd5ba6464UL, 0xd6573c3cUL, 0xd70cd3d3UL,
0xd8ee8282UL, 0xd9b56d6dUL, 0xda583535UL, 0xdb03dadaUL, 0xdceb8585UL, 0xddb06a6aUL, 0xde5d3232UL, 0xdf06ddddUL,
0xe0d8a8a8UL, 0xe1834747UL, 0xe26e1f1fUL, 0xe335f0f0UL, 0xe4ddafafUL, 0xe5864040UL, 0xe66b1818UL, 0xe730f7f7UL,
0xe8d2a6a6UL, 0xe9894949UL, 0xea641111UL, 0xeb3ffefeUL, 0xecd7a1a1UL, 0xed8c4e4eUL, 0xee611616UL, 0xef3af9f9UL,
0xf0ccb4b4UL, 0xf1975b5bUL, 0xf27a0303UL, 0xf321ececUL, 0xf4c9b3b3UL, 0xf5925c5cUL, 0xf67f0404UL, 0xf724ebebUL,
0xf8c6babaUL, 0xf99d5555UL, 0xfa700d0dUL, 0xfb2be2e2UL, 0xfcc3bdbdUL, 0xfd985252UL, 0xfe750a0aUL, 0xff2ee5e5UL
},
{
0x00000000UL, 0xef01ef5bUL, 0xb702b7b6UL, 0x580358edUL, 0x07040705UL, 0xe805e85eUL, 0xb006b0b3UL, 0x5f075fe8UL,
0x0e080e0aUL, 0xe109e151UL, 0xb90ab9bcUL, 0x560b56e7UL, 0x090c090fUL, 0xe60de654UL, 0xbe0ebeb9UL, 0x510f51e2UL,
0x1c101c14UL, 0xf311f34fUL, 0xab12aba2UL, 0x441344f9UL, 0x1b141b11UL, 0xf415f44aUL, 0xac16aca7UL, 0x431743fcUL,
0x1218121eUL, 0xfd19fd45UL, 0xa51aa5a8UL, 0x4a1b4af3UL, 0x151c151bUL, 0xfa1dfa40UL, 0xa21ea2adUL, 0x4d1f4df6UL,
0x38203828UL, 0xd721d773UL, 0x8f228f9eUL, 0x602360c5UL, 0x3f243f2dUL, 0xd025d076UL, 0x8826889bUL, 0x672767c0UL,
0x36283622UL, 0xd929d979UL, 0x812a8194UL, 0x6e2b6ecfUL, 0x312c3127UL, 0xde2dde7cUL, 0x862e8691UL, 0x692f69caUL,
0x2430243cUL, 0xcb31cb67UL, 0x9332938aUL, 0x7c337cd1UL, 0x23342339UL, 0xcc35cc62UL, 0x9436948fUL, 0x7b377bd4UL,
0x2a382a36UL, 0xc539c56dUL, 0x9d3a9d80UL, 0x723b72dbUL, 0x2d3c2d33UL, 0xc23dc268UL, 0x9a3e9a85UL, 0x753f75deUL,
0x70407050UL, 0x9f419f0bUL, 0xc742c7e6UL, 0x284328bdUL, 0x77447755UL, 0x9845980eUL, 0xc046c0e3UL, 0x2f472fb8UL,
0x7e487e5aUL, 0x91499101UL, 0xc94ac9ecUL, 0x264b26b7UL, 0x794c795fUL, 0x964d9604UL, 0xce4ecee9UL, 0x214f21b2UL,
0x6c506c44UL, 0x8351831fUL, 0xdb52dbf2UL, 0x345334a9UL, 0x6b546b41UL, 0x8455841aUL, 0xdc56dcf7UL, 0x335733acUL,
0x6258624eUL, 0x8d598d15UL, 0xd55ad5f8UL, 0x3a5b3aa3UL, 0x655c654bUL, 0x8a5d8a10UL, 0xd25ed2fdUL, 0x3d5f3da6UL,
0x48604878UL, 0xa761a723UL, 0xff62ffceUL, 0x10631095UL, 0x4f644f7dUL, 0xa065a026UL, 0xf866f8cbUL, 0x17671790UL,
0x46684672UL, 0xa969a929UL, 0xf16af1c4UL, 0x1e6b1e9fUL, 0x416c4177UL, 0xae6dae2cUL, 0xf66ef6c1UL, 0x196f199aUL,
0x5470546cUL, 0xbb71bb37UL, 0xe372e3daUL, 0x0c730c81UL, 0x53745369UL, 0xbc75bc32UL, 0xe476e4dfUL, 0x0b770b84UL,
0x5a785a66UL, 0xb579b53dUL, 0xed7aedd0UL, 0x027b028bUL, 0x5d7c5d63UL, 0xb27db238UL, 0xea7eead5UL, 0x057f058eUL,
0xe080e0a0UL, 0x0f810ffbUL, 0x57825716UL, 0xb883b84dUL, 0xe784e7a5UL, 0x088508feUL, 0x50865013UL, 0xbf87bf48UL,
0xee88eeaaUL, 0x018901f1UL, 0x598a591cUL, 0xb68bb647UL, 0xe98ce9afUL, 0x068d06f4UL, 0x5e8e5e19UL, 0xb18fb142UL,
0xfc90fcb4UL, 0x139113efUL, 0x4b924b02UL, 0xa493a459UL, 0xfb94fbb1UL, 0x149514eaUL, 0x4c964c07UL, 0xa397a35cUL,
0xf298f2beUL, 0x1d991de5UL, 0x459a4508UL, 0xaa9baa53UL, 0xf59cf5bbUL, 0x1a9d1ae0UL, 0x429e420dUL, 0xad9fad56UL,
0xd8a0d888UL, 0x37a137d3UL, 0x6fa26f3eUL, 0x80a38065UL, 0xdfa4df8dUL, 0x30a530d6UL, 0x68a6683bUL, 0x87a78760UL,
0xd6a8d682UL, 0x39a939d9UL, 0x61aa6134UL, 0x8eab8e6fUL, 0xd1acd187UL, 0x3ead3edcUL, 0x66ae6631UL, 0x89af896aUL,
0xc4b0c49cUL, 0x2bb12bc7UL, 0x73b2732aUL, 0x9cb39c71UL, 0xc3b4c399UL, 0x2cb52cc2UL, 0x74b6742fUL, 0x9bb79b74UL,
0xcab8ca96UL, 0x25b925cdUL, 0x7dba7d20UL, 0x92bb927bUL, 0xcdbccd93UL, 0x22bd22c8UL, 0x7abe7a25UL, 0x95bf957eUL,
0x90c090f0UL, 0x7fc17fabUL, 0x27c22746UL, 0xc8c3c81dUL, 0x97c497f5UL, 0x78c578aeUL, 0x20c62043UL, 0xcfc7cf18UL,
0x9ec89efaUL, 0x71c971a1UL, 0x29ca294cUL, 0xc6cbc617UL, 0x99cc99ffUL, 0x76cd76a4UL, 0x2ece2e49UL, 0xc1cfc112UL,
0x8cd08ce4UL, 0x63d163bfUL, 0x3bd23b52UL, 0xd4d3d409UL, 0x8bd48be1UL, 0x64d564baUL, 0x3cd63c57UL, 0xd3d7d30cUL,
0x82d882eeUL, 0x6dd96db5UL, 0x35da3558UL, 0xdadbda03UL, 0x85dc85ebUL, 0x6add6ab0UL, 0x32de325dUL, 0xdddfdd06UL,
0xa8e0a8d8UL, 0x47e14783UL, 0x1fe21f6eUL, 0xf0e3f035UL, 0xafe4afddUL, 0x40e54086UL, 0x18e6186bUL, 0xf7e7f730UL,
0xa6e8a6d2UL, 0x49e94989UL, 0x11ea1164UL, 0xfeebfe3fUL, 0xa1eca1d7UL, 0x4eed4e8cUL, 0x16ee1661UL, 0xf9eff93aUL,
0xb4f0b4ccUL, 0x5bf15b97UL, 0x03f2037aUL, 0xecf3ec21UL, 0xb3f4b3c9UL, 0x5cf55c92UL, 0x04f6047fUL, 0xebf7eb24UL,
0xbaf8bac6UL, 0x55f9559dUL, 0x0dfa0d70UL, 0xe2fbe22bUL, 0xbdfcbdc3UL, 0x52fd5298UL, 0x0afe0a75UL, 0xe5ffe52eUL
},
{
0x00000000UL, 0x5bef015bUL, 0xb6b702b6UL, 0xed5803edUL, 0x05070405UL, 0x5ee8055eUL, 0xb3b006b3UL, 0xe85f07e8UL,
0x0a0e080aUL, 0x51e10951UL, 0xbcb90abcUL, 0xe7560be7UL, 0x0f090c0fUL, 0x54e60d54UL, 0xb9be0eb9UL, 0xe2510fe2UL,
0x141c1014UL, 0x4ff3114fUL, 0xa2ab12a2UL, 0xf94413f9UL, 0x111b1411UL, 0x4af4154aUL, 0xa7ac16a7UL, 0xfc4317fcUL,
0x1e12181eUL, 0x45fd1945UL, 0xa8a51aa8UL, 0xf34a1bf3UL, 0x1b151c1bUL, 0x40fa1d40UL, 0xada21eadUL, 0xf64d1ff6UL,
0x28382028UL, 0x73d72173UL, 0x9e8f229eUL, 0xc56023c5UL, 0x2d3f242dUL, 0x76d02576UL, 0x9b88269bUL, 0xc06727c0UL,
0x22362822UL, 0x79d92979UL, 0x94812a94UL, 0xcf6e2bcfUL, 0x27312c27UL, 0x7cde2d7cUL, 0x91862e91UL, 0xca692fcaUL,
0x3c24303cUL, 0x67cb3167UL, 0x8a93328aUL, 0xd17c33d1UL, 0x39233439UL, 0x62cc3562UL, 0x8f94368fUL, 0xd47b37d4UL,
0x362a3836UL, 0x6dc5396dUL, 0x809d3a80UL, 0xdb723bdbUL, 0x332d3c33UL, 0x68c23d68UL, 0x859a3e85UL, 0xde753fdeUL,
0x50704050UL, 0x0b9f410bUL, 0xe6c742e6UL, 0xbd2843bdUL, 0x55774455UL, 0x0e98450eUL, 0xe3c046e3UL, 0xb82f47b8UL,
0x5a7e485aUL, 0x01914901UL, 0xecc94aecUL, 0xb7264bb7UL, 0x5f794c5fUL, 0x04964d04UL, 0xe9ce4ee9UL, 0xb2214fb2UL,
0x446c5044UL, 0x1f83511fUL, 0xf2db52f2UL, 0xa93453a9UL, 0x416b5441UL, 0x1a84551aUL, 0xf7dc56f7UL, 0xac3357acUL,
0x4e62584eUL, 0x158d5915UL, 0xf8d55af8UL, 0xa33a5ba3UL, 0x4b655c4bUL, 0x108a5d10UL, 0xfdd25efdUL, 0xa63d5fa6UL,
0x78486078UL, 0x23a76123UL, 0xceff62ceUL, 0x95106395UL, 0x7d4f647dUL, 0x26a06526UL, 0xcbf866cbUL, 0x90176790UL,
0x72466872UL, 0x29a96929UL, 0xc4f16ac4UL, 0x9f1e6b9fUL, 0x77416c77UL, 0x2cae6d2cUL, 0xc1f66ec1UL, 0x9a196f9aUL,
0x6c54706cUL, 0x37bb7137UL, 0xdae372daUL, 0x810c7381UL, 0x69537469UL, 0x32bc7532UL, 0xdfe476dfUL, 0x840b7784UL,
0x665a7866UL, 0x3db5793dUL, 0xd0ed7ad0UL, 0x8b027b8bUL, 0x635d7c63UL, 0x38b27d38UL, 0xd5ea7ed5UL, 0x8e057f8eUL,
0xa0e080a0UL, 0xfb0f81fbUL, 0x16578216UL, 0x4db8834dUL, 0xa5e784a5UL, 0xfe0885feUL, 0x13508613UL, 0x48bf8748UL,
0xaaee88aaUL, 0xf10189f1UL, 0x1c598a1cUL, 0x47b68b47UL, 0xafe98cafUL, 0xf4068df4UL, 0x195e8e19UL, 0x42b18f42UL,
0xb4fc90b4UL, 0xef1391efUL, 0x024b9202UL, 0x59a49359UL, 0xb1fb94b1UL, 0xea1495eaUL, 0x074c9607UL, 0x5ca3975cUL,
0xbef298beUL, 0xe51d99e5UL, 0x08459a08UL, 0x53aa9b53UL, 0xbbf59cbbUL, 0xe01a9de0UL, 0x0d429e0dUL, 0x56ad9f56UL,
0x88d8a088UL, 0xd337a1d3UL, 0x3e6fa23eUL, 0x6580a365UL, 0x8ddfa48dUL, 0xd630a5d6UL, 0x3b68a63bUL, 0x6087a760UL,
0x82d6a882UL, 0xd939a9d9UL, 0x3461aa34UL, 0x6f8eab6fUL, 0x87d1ac87UL, 0xdc3eaddcUL, 0x3166ae31UL, 0x6a89af6aUL,
0x9cc4b09cUL, 0xc72bb1c7UL, 0x2a73b22aUL, 0x719cb371UL, 0x99c3b499UL, 0xc22cb5c2UL, 0x2f74b62fUL, 0x749bb774UL,
0x96cab896UL, 0xcd25b9cdUL, 0x207dba20UL, 0x7b92bb7bUL, 0x93cdbc93UL, 0xc822bdc8UL, 0x257abe25UL, 0x7e95bf7eUL,
0xf090c0f0UL, 0xab7fc1abUL, 0x4627c246UL, 0x1dc8c31dUL, 0xf597c4f5UL, 0xae78c5aeUL, 0x4320c643UL, 0x18cfc718UL,
0xfa9ec8faUL, 0xa171c9a1UL, 0x4c29ca4cUL, 0x17c6cb17UL, 0xff99ccffUL, 0xa476cda4UL, 0x492ece49UL, 0x12c1cf12UL,
0xe48cd0e4UL, 0xbf63d1bfUL, 0x523bd252UL, 0x09d4d309UL, 0xe18bd4e1UL, 0xba64d5baUL, 0x573cd657UL, 0x0cd3d70cUL,
0xee82d8eeUL, 0xb56dd9b5UL, 0x5835da58UL, 0x03dadb03UL, 0xeb85dcebUL, 0xb06addb0UL, 0x5d32de5dUL, 0x06dddf06UL,
0xd8a8e0d8UL, 0x8347e183UL, 0x6e1fe26eUL, 0x35f0e335UL, 0xddafe4ddUL, 0x8640e586UL, 0x6b18e66bUL, 0x30f7e730UL,
0xd2a6e8d2UL, 0x8949e989UL, 0x6411ea64UL, 0x3ffeeb3fUL, 0xd7a1ecd7UL, 0x8c4eed8cUL, 0x6116ee61UL, 0x3af9ef3aUL,
0xccb4f0ccUL, 0x975bf197UL, 0x7a03f27aUL, 0x21ecf321UL, 0xc9b3f4c9UL, 0x925cf592UL, 0x7f04f67fUL, 0x24ebf724UL,
0xc6baf8c6UL, 0x9d55f99dUL, 0x700dfa70UL, 0x2be2fb2bUL, 0xc3bdfcc3UL, 0x9852fd98UL, 0x750afe75UL, 0x2ee5ff2eUL
}};
#ifdef LTC_TWOFISH_ALL_TABLES
/* the 4x8 RS transform */
static const ulong32 rs_tab0[256] = {
0x00000000LU, 0xa402a401LU, 0x05040502LU, 0xa106a103LU, 0x0a080a04LU, 0xae0aae05LU, 0x0f0c0f06LU, 0xab0eab07LU,
0x14101408LU, 0xb012b009LU, 0x1114110aLU, 0xb516b50bLU, 0x1e181e0cLU, 0xba1aba0dLU, 0x1b1c1b0eLU, 0xbf1ebf0fLU,
0x28202810LU, 0x8c228c11LU, 0x2d242d12LU, 0x89268913LU, 0x22282214LU, 0x862a8615LU, 0x272c2716LU, 0x832e8317LU,
0x3c303c18LU, 0x98329819LU, 0x3934391aLU, 0x9d369d1bLU, 0x3638361cLU, 0x923a921dLU, 0x333c331eLU, 0x973e971fLU,
0x50405020LU, 0xf442f421LU, 0x55445522LU, 0xf146f123LU, 0x5a485a24LU, 0xfe4afe25LU, 0x5f4c5f26LU, 0xfb4efb27LU,
0x44504428LU, 0xe052e029LU, 0x4154412aLU, 0xe556e52bLU, 0x4e584e2cLU, 0xea5aea2dLU, 0x4b5c4b2eLU, 0xef5eef2fLU,
0x78607830LU, 0xdc62dc31LU, 0x7d647d32LU, 0xd966d933LU, 0x72687234LU, 0xd66ad635LU, 0x776c7736LU, 0xd36ed337LU,
0x6c706c38LU, 0xc872c839LU, 0x6974693aLU, 0xcd76cd3bLU, 0x6678663cLU, 0xc27ac23dLU, 0x637c633eLU, 0xc77ec73fLU,
0xa080a040LU, 0x04820441LU, 0xa584a542LU, 0x01860143LU, 0xaa88aa44LU, 0x0e8a0e45LU, 0xaf8caf46LU, 0x0b8e0b47LU,
0xb490b448LU, 0x10921049LU, 0xb194b14aLU, 0x1596154bLU, 0xbe98be4cLU, 0x1a9a1a4dLU, 0xbb9cbb4eLU, 0x1f9e1f4fLU,
0x88a08850LU, 0x2ca22c51LU, 0x8da48d52LU, 0x29a62953LU, 0x82a88254LU, 0x26aa2655LU, 0x87ac8756LU, 0x23ae2357LU,
0x9cb09c58LU, 0x38b23859LU, 0x99b4995aLU, 0x3db63d5bLU, 0x96b8965cLU, 0x32ba325dLU, 0x93bc935eLU, 0x37be375fLU,
0xf0c0f060LU, 0x54c25461LU, 0xf5c4f562LU, 0x51c65163LU, 0xfac8fa64LU, 0x5eca5e65LU, 0xffccff66LU, 0x5bce5b67LU,
0xe4d0e468LU, 0x40d24069LU, 0xe1d4e16aLU, 0x45d6456bLU, 0xeed8ee6cLU, 0x4ada4a6dLU, 0xebdceb6eLU, 0x4fde4f6fLU,
0xd8e0d870LU, 0x7ce27c71LU, 0xdde4dd72LU, 0x79e67973LU, 0xd2e8d274LU, 0x76ea7675LU, 0xd7ecd776LU, 0x73ee7377LU,
0xccf0cc78LU, 0x68f26879LU, 0xc9f4c97aLU, 0x6df66d7bLU, 0xc6f8c67cLU, 0x62fa627dLU, 0xc3fcc37eLU, 0x67fe677fLU,
0x0d4d0d80LU, 0xa94fa981LU, 0x08490882LU, 0xac4bac83LU, 0x07450784LU, 0xa347a385LU, 0x02410286LU, 0xa643a687LU,
0x195d1988LU, 0xbd5fbd89LU, 0x1c591c8aLU, 0xb85bb88bLU, 0x1355138cLU, 0xb757b78dLU, 0x1651168eLU, 0xb253b28fLU,
0x256d2590LU, 0x816f8191LU, 0x20692092LU, 0x846b8493LU, 0x2f652f94LU, 0x8b678b95LU, 0x2a612a96LU, 0x8e638e97LU,
0x317d3198LU, 0x957f9599LU, 0x3479349aLU, 0x907b909bLU, 0x3b753b9cLU, 0x9f779f9dLU, 0x3e713e9eLU, 0x9a739a9fLU,
0x5d0d5da0LU, 0xf90ff9a1LU, 0x580958a2LU, 0xfc0bfca3LU, 0x570557a4LU, 0xf307f3a5LU, 0x520152a6LU, 0xf603f6a7LU,
0x491d49a8LU, 0xed1feda9LU, 0x4c194caaLU, 0xe81be8abLU, 0x431543acLU, 0xe717e7adLU, 0x461146aeLU, 0xe213e2afLU,
0x752d75b0LU, 0xd12fd1b1LU, 0x702970b2LU, 0xd42bd4b3LU, 0x7f257fb4LU, 0xdb27dbb5LU, 0x7a217ab6LU, 0xde23deb7LU,
0x613d61b8LU, 0xc53fc5b9LU, 0x643964baLU, 0xc03bc0bbLU, 0x6b356bbcLU, 0xcf37cfbdLU, 0x6e316ebeLU, 0xca33cabfLU,
0xadcdadc0LU, 0x09cf09c1LU, 0xa8c9a8c2LU, 0x0ccb0cc3LU, 0xa7c5a7c4LU, 0x03c703c5LU, 0xa2c1a2c6LU, 0x06c306c7LU,
0xb9ddb9c8LU, 0x1ddf1dc9LU, 0xbcd9bccaLU, 0x18db18cbLU, 0xb3d5b3ccLU, 0x17d717cdLU, 0xb6d1b6ceLU, 0x12d312cfLU,
0x85ed85d0LU, 0x21ef21d1LU, 0x80e980d2LU, 0x24eb24d3LU, 0x8fe58fd4LU, 0x2be72bd5LU, 0x8ae18ad6LU, 0x2ee32ed7LU,
0x91fd91d8LU, 0x35ff35d9LU, 0x94f994daLU, 0x30fb30dbLU, 0x9bf59bdcLU, 0x3ff73fddLU, 0x9ef19edeLU, 0x3af33adfLU,
0xfd8dfde0LU, 0x598f59e1LU, 0xf889f8e2LU, 0x5c8b5ce3LU, 0xf785f7e4LU, 0x538753e5LU, 0xf281f2e6LU, 0x568356e7LU,
0xe99de9e8LU, 0x4d9f4de9LU, 0xec99eceaLU, 0x489b48ebLU, 0xe395e3ecLU, 0x479747edLU, 0xe691e6eeLU, 0x429342efLU,
0xd5add5f0LU, 0x71af71f1LU, 0xd0a9d0f2LU, 0x74ab74f3LU, 0xdfa5dff4LU, 0x7ba77bf5LU, 0xdaa1daf6LU, 0x7ea37ef7LU,
0xc1bdc1f8LU, 0x65bf65f9LU, 0xc4b9c4faLU, 0x60bb60fbLU, 0xcbb5cbfcLU, 0x6fb76ffdLU, 0xceb1cefeLU, 0x6ab36affLU };
static const ulong32 rs_tab1[256] = {
0x00000000LU, 0x55a156a4LU, 0xaa0fac05LU, 0xffaefaa1LU, 0x191e150aLU, 0x4cbf43aeLU, 0xb311b90fLU, 0xe6b0efabLU,
0x323c2a14LU, 0x679d7cb0LU, 0x98338611LU, 0xcd92d0b5LU, 0x2b223f1eLU, 0x7e8369baLU, 0x812d931bLU, 0xd48cc5bfLU,
0x64785428LU, 0x31d9028cLU, 0xce77f82dLU, 0x9bd6ae89LU, 0x7d664122LU, 0x28c71786LU, 0xd769ed27LU, 0x82c8bb83LU,
0x56447e3cLU, 0x03e52898LU, 0xfc4bd239LU, 0xa9ea849dLU, 0x4f5a6b36LU, 0x1afb3d92LU, 0xe555c733LU, 0xb0f49197LU,
0xc8f0a850LU, 0x9d51fef4LU, 0x62ff0455LU, 0x375e52f1LU, 0xd1eebd5aLU, 0x844febfeLU, 0x7be1115fLU, 0x2e4047fbLU,
0xfacc8244LU, 0xaf6dd4e0LU, 0x50c32e41LU, 0x056278e5LU, 0xe3d2974eLU, 0xb673c1eaLU, 0x49dd3b4bLU, 0x1c7c6defLU,
0xac88fc78LU, 0xf929aadcLU, 0x0687507dLU, 0x532606d9LU, 0xb596e972LU, 0xe037bfd6LU, 0x1f994577LU, 0x4a3813d3LU,
0x9eb4d66cLU, 0xcb1580c8LU, 0x34bb7a69LU, 0x611a2ccdLU, 0x87aac366LU, 0xd20b95c2LU, 0x2da56f63LU, 0x780439c7LU,
0xddad1da0LU, 0x880c4b04LU, 0x77a2b1a5LU, 0x2203e701LU, 0xc4b308aaLU, 0x91125e0eLU, 0x6ebca4afLU, 0x3b1df20bLU,
0xef9137b4LU, 0xba306110LU, 0x459e9bb1LU, 0x103fcd15LU, 0xf68f22beLU, 0xa32e741aLU, 0x5c808ebbLU, 0x0921d81fLU,
0xb9d54988LU, 0xec741f2cLU, 0x13dae58dLU, 0x467bb329LU, 0xa0cb5c82LU, 0xf56a0a26LU, 0x0ac4f087LU, 0x5f65a623LU,
0x8be9639cLU, 0xde483538LU, 0x21e6cf99LU, 0x7447993dLU, 0x92f77696LU, 0xc7562032LU, 0x38f8da93LU, 0x6d598c37LU,
0x155db5f0LU, 0x40fce354LU, 0xbf5219f5LU, 0xeaf34f51LU, 0x0c43a0faLU, 0x59e2f65eLU, 0xa64c0cffLU, 0xf3ed5a5bLU,
0x27619fe4LU, 0x72c0c940LU, 0x8d6e33e1LU, 0xd8cf6545LU, 0x3e7f8aeeLU, 0x6bdedc4aLU, 0x947026ebLU, 0xc1d1704fLU,
0x7125e1d8LU, 0x2484b77cLU, 0xdb2a4dddLU, 0x8e8b1b79LU, 0x683bf4d2LU, 0x3d9aa276LU, 0xc23458d7LU, 0x97950e73LU,
0x4319cbccLU, 0x16b89d68LU, 0xe91667c9LU, 0xbcb7316dLU, 0x5a07dec6LU, 0x0fa68862LU, 0xf00872c3LU, 0xa5a92467LU,
0xf7173a0dLU, 0xa2b66ca9LU, 0x5d189608LU, 0x08b9c0acLU, 0xee092f07LU, 0xbba879a3LU, 0x44068302LU, 0x11a7d5a6LU,
0xc52b1019LU, 0x908a46bdLU, 0x6f24bc1cLU, 0x3a85eab8LU, 0xdc350513LU, 0x899453b7LU, 0x763aa916LU, 0x239bffb2LU,
0x936f6e25LU, 0xc6ce3881LU, 0x3960c220LU, 0x6cc19484LU, 0x8a717b2fLU, 0xdfd02d8bLU, 0x207ed72aLU, 0x75df818eLU,
0xa1534431LU, 0xf4f21295LU, 0x0b5ce834LU, 0x5efdbe90LU, 0xb84d513bLU, 0xedec079fLU, 0x1242fd3eLU, 0x47e3ab9aLU,
0x3fe7925dLU, 0x6a46c4f9LU, 0x95e83e58LU, 0xc04968fcLU, 0x26f98757LU, 0x7358d1f3LU, 0x8cf62b52LU, 0xd9577df6LU,
0x0ddbb849LU, 0x587aeeedLU, 0xa7d4144cLU, 0xf27542e8LU, 0x14c5ad43LU, 0x4164fbe7LU, 0xbeca0146LU, 0xeb6b57e2LU,
0x5b9fc675LU, 0x0e3e90d1LU, 0xf1906a70LU, 0xa4313cd4LU, 0x4281d37fLU, 0x172085dbLU, 0xe88e7f7aLU, 0xbd2f29deLU,
0x69a3ec61LU, 0x3c02bac5LU, 0xc3ac4064LU, 0x960d16c0LU, 0x70bdf96bLU, 0x251cafcfLU, 0xdab2556eLU, 0x8f1303caLU,
0x2aba27adLU, 0x7f1b7109LU, 0x80b58ba8LU, 0xd514dd0cLU, 0x33a432a7LU, 0x66056403LU, 0x99ab9ea2LU, 0xcc0ac806LU,
0x18860db9LU, 0x4d275b1dLU, 0xb289a1bcLU, 0xe728f718LU, 0x019818b3LU, 0x54394e17LU, 0xab97b4b6LU, 0xfe36e212LU,
0x4ec27385LU, 0x1b632521LU, 0xe4cddf80LU, 0xb16c8924LU, 0x57dc668fLU, 0x027d302bLU, 0xfdd3ca8aLU, 0xa8729c2eLU,
0x7cfe5991LU, 0x295f0f35LU, 0xd6f1f594LU, 0x8350a330LU, 0x65e04c9bLU, 0x30411a3fLU, 0xcfefe09eLU, 0x9a4eb63aLU,
0xe24a8ffdLU, 0xb7ebd959LU, 0x484523f8LU, 0x1de4755cLU, 0xfb549af7LU, 0xaef5cc53LU, 0x515b36f2LU, 0x04fa6056LU,
0xd076a5e9LU, 0x85d7f34dLU, 0x7a7909ecLU, 0x2fd85f48LU, 0xc968b0e3LU, 0x9cc9e647LU, 0x63671ce6LU, 0x36c64a42LU,
0x8632dbd5LU, 0xd3938d71LU, 0x2c3d77d0LU, 0x799c2174LU, 0x9f2ccedfLU, 0xca8d987bLU, 0x352362daLU, 0x6082347eLU,
0xb40ef1c1LU, 0xe1afa765LU, 0x1e015dc4LU, 0x4ba00b60LU, 0xad10e4cbLU, 0xf8b1b26fLU, 0x071f48ceLU, 0x52be1e6aLU };
static const ulong32 rs_tab2[256] = {
0x00000000LU, 0x87fc8255LU, 0x43b549aaLU, 0xc449cbffLU, 0x86279219LU, 0x01db104cLU, 0xc592dbb3LU, 0x426e59e6LU,
0x414e6932LU, 0xc6b2eb67LU, 0x02fb2098LU, 0x8507a2cdLU, 0xc769fb2bLU, 0x4095797eLU, 0x84dcb281LU, 0x032030d4LU,
0x829cd264LU, 0x05605031LU, 0xc1299bceLU, 0x46d5199bLU, 0x04bb407dLU, 0x8347c228LU, 0x470e09d7LU, 0xc0f28b82LU,
0xc3d2bb56LU, 0x442e3903LU, 0x8067f2fcLU, 0x079b70a9LU, 0x45f5294fLU, 0xc209ab1aLU, 0x064060e5LU, 0x81bce2b0LU,
0x4975e9c8LU, 0xce896b9dLU, 0x0ac0a062LU, 0x8d3c2237LU, 0xcf527bd1LU, 0x48aef984LU, 0x8ce7327bLU, 0x0b1bb02eLU,
0x083b80faLU, 0x8fc702afLU, 0x4b8ec950LU, 0xcc724b05LU, 0x8e1c12e3LU, 0x09e090b6LU, 0xcda95b49LU, 0x4a55d91cLU,
0xcbe93bacLU, 0x4c15b9f9LU, 0x885c7206LU, 0x0fa0f053LU, 0x4dcea9b5LU, 0xca322be0LU, 0x0e7be01fLU, 0x8987624aLU,
0x8aa7529eLU, 0x0d5bd0cbLU, 0xc9121b34LU, 0x4eee9961LU, 0x0c80c087LU, 0x8b7c42d2LU, 0x4f35892dLU, 0xc8c90b78LU,
0x92ea9fddLU, 0x15161d88LU, 0xd15fd677LU, 0x56a35422LU, 0x14cd0dc4LU, 0x93318f91LU, 0x5778446eLU, 0xd084c63bLU,
0xd3a4f6efLU, 0x545874baLU, 0x9011bf45LU, 0x17ed3d10LU, 0x558364f6LU, 0xd27fe6a3LU, 0x16362d5cLU, 0x91caaf09LU,
0x10764db9LU, 0x978acfecLU, 0x53c30413LU, 0xd43f8646LU, 0x9651dfa0LU, 0x11ad5df5LU, 0xd5e4960aLU, 0x5218145fLU,
0x5138248bLU, 0xd6c4a6deLU, 0x128d6d21LU, 0x9571ef74LU, 0xd71fb692LU, 0x50e334c7LU, 0x94aaff38LU, 0x13567d6dLU,
0xdb9f7615LU, 0x5c63f440LU, 0x982a3fbfLU, 0x1fd6bdeaLU, 0x5db8e40cLU, 0xda446659LU, 0x1e0dada6LU, 0x99f12ff3LU,
0x9ad11f27LU, 0x1d2d9d72LU, 0xd964568dLU, 0x5e98d4d8LU, 0x1cf68d3eLU, 0x9b0a0f6bLU, 0x5f43c494LU, 0xd8bf46c1LU,
0x5903a471LU, 0xdeff2624LU, 0x1ab6eddbLU, 0x9d4a6f8eLU, 0xdf243668LU, 0x58d8b43dLU, 0x9c917fc2LU, 0x1b6dfd97LU,
0x184dcd43LU, 0x9fb14f16LU, 0x5bf884e9LU, 0xdc0406bcLU, 0x9e6a5f5aLU, 0x1996dd0fLU, 0xdddf16f0LU, 0x5a2394a5LU,
0x699973f7LU, 0xee65f1a2LU, 0x2a2c3a5dLU, 0xadd0b808LU, 0xefbee1eeLU, 0x684263bbLU, 0xac0ba844LU, 0x2bf72a11LU,
0x28d71ac5LU, 0xaf2b9890LU, 0x6b62536fLU, 0xec9ed13aLU, 0xaef088dcLU, 0x290c0a89LU, 0xed45c176LU, 0x6ab94323LU,
0xeb05a193LU, 0x6cf923c6LU, 0xa8b0e839LU, 0x2f4c6a6cLU, 0x6d22338aLU, 0xeadeb1dfLU, 0x2e977a20LU, 0xa96bf875LU,
0xaa4bc8a1LU, 0x2db74af4LU, 0xe9fe810bLU, 0x6e02035eLU, 0x2c6c5ab8LU, 0xab90d8edLU, 0x6fd91312LU, 0xe8259147LU,
0x20ec9a3fLU, 0xa710186aLU, 0x6359d395LU, 0xe4a551c0LU, 0xa6cb0826LU, 0x21378a73LU, 0xe57e418cLU, 0x6282c3d9LU,
0x61a2f30dLU, 0xe65e7158LU, 0x2217baa7LU, 0xa5eb38f2LU, 0xe7856114LU, 0x6079e341LU, 0xa43028beLU, 0x23ccaaebLU,
0xa270485bLU, 0x258cca0eLU, 0xe1c501f1LU, 0x663983a4LU, 0x2457da42LU, 0xa3ab5817LU, 0x67e293e8LU, 0xe01e11bdLU,
0xe33e2169LU, 0x64c2a33cLU, 0xa08b68c3LU, 0x2777ea96LU, 0x6519b370LU, 0xe2e53125LU, 0x26acfadaLU, 0xa150788fLU,
0xfb73ec2aLU, 0x7c8f6e7fLU, 0xb8c6a580LU, 0x3f3a27d5LU, 0x7d547e33LU, 0xfaa8fc66LU, 0x3ee13799LU, 0xb91db5ccLU,
0xba3d8518LU, 0x3dc1074dLU, 0xf988ccb2LU, 0x7e744ee7LU, 0x3c1a1701LU, 0xbbe69554LU, 0x7faf5eabLU, 0xf853dcfeLU,
0x79ef3e4eLU, 0xfe13bc1bLU, 0x3a5a77e4LU, 0xbda6f5b1LU, 0xffc8ac57LU, 0x78342e02LU, 0xbc7de5fdLU, 0x3b8167a8LU,
0x38a1577cLU, 0xbf5dd529LU, 0x7b141ed6LU, 0xfce89c83LU, 0xbe86c565LU, 0x397a4730LU, 0xfd338ccfLU, 0x7acf0e9aLU,
0xb20605e2LU, 0x35fa87b7LU, 0xf1b34c48LU, 0x764fce1dLU, 0x342197fbLU, 0xb3dd15aeLU, 0x7794de51LU, 0xf0685c04LU,
0xf3486cd0LU, 0x74b4ee85LU, 0xb0fd257aLU, 0x3701a72fLU, 0x756ffec9LU, 0xf2937c9cLU, 0x36dab763LU, 0xb1263536LU,
0x309ad786LU, 0xb76655d3LU, 0x732f9e2cLU, 0xf4d31c79LU, 0xb6bd459fLU, 0x3141c7caLU, 0xf5080c35LU, 0x72f48e60LU,
0x71d4beb4LU, 0xf6283ce1LU, 0x3261f71eLU, 0xb59d754bLU, 0xf7f32cadLU, 0x700faef8LU, 0xb4466507LU, 0x33bae752LU };
static const ulong32 rs_tab3[256] = {
0x00000000LU, 0x5ac1f387LU, 0xb4cfab43LU, 0xee0e58c4LU, 0x25d31b86LU, 0x7f12e801LU, 0x911cb0c5LU, 0xcbdd4342LU,
0x4aeb3641LU, 0x102ac5c6LU, 0xfe249d02LU, 0xa4e56e85LU, 0x6f382dc7LU, 0x35f9de40LU, 0xdbf78684LU, 0x81367503LU,
0x949b6c82LU, 0xce5a9f05LU, 0x2054c7c1LU, 0x7a953446LU, 0xb1487704LU, 0xeb898483LU, 0x0587dc47LU, 0x5f462fc0LU,
0xde705ac3LU, 0x84b1a944LU, 0x6abff180LU, 0x307e0207LU, 0xfba34145LU, 0xa162b2c2LU, 0x4f6cea06LU, 0x15ad1981LU,
0x657bd849LU, 0x3fba2bceLU, 0xd1b4730aLU, 0x8b75808dLU, 0x40a8c3cfLU, 0x1a693048LU, 0xf467688cLU, 0xaea69b0bLU,
0x2f90ee08LU, 0x75511d8fLU, 0x9b5f454bLU, 0xc19eb6ccLU, 0x0a43f58eLU, 0x50820609LU, 0xbe8c5ecdLU, 0xe44dad4aLU,
0xf1e0b4cbLU, 0xab21474cLU, 0x452f1f88LU, 0x1feeec0fLU, 0xd433af4dLU, 0x8ef25ccaLU, 0x60fc040eLU, 0x3a3df789LU,
0xbb0b828aLU, 0xe1ca710dLU, 0x0fc429c9LU, 0x5505da4eLU, 0x9ed8990cLU, 0xc4196a8bLU, 0x2a17324fLU, 0x70d6c1c8LU,
0xcaf6fd92LU, 0x90370e15LU, 0x7e3956d1LU, 0x24f8a556LU, 0xef25e614LU, 0xb5e41593LU, 0x5bea4d57LU, 0x012bbed0LU,
0x801dcbd3LU, 0xdadc3854LU, 0x34d26090LU, 0x6e139317LU, 0xa5ced055LU, 0xff0f23d2LU, 0x11017b16LU, 0x4bc08891LU,
0x5e6d9110LU, 0x04ac6297LU, 0xeaa23a53LU, 0xb063c9d4LU, 0x7bbe8a96LU, 0x217f7911LU, 0xcf7121d5LU, 0x95b0d252LU,
0x1486a751LU, 0x4e4754d6LU, 0xa0490c12LU, 0xfa88ff95LU, 0x3155bcd7LU, 0x6b944f50LU, 0x859a1794LU, 0xdf5be413LU,
0xaf8d25dbLU, 0xf54cd65cLU, 0x1b428e98LU, 0x41837d1fLU, 0x8a5e3e5dLU, 0xd09fcddaLU, 0x3e91951eLU, 0x64506699LU,
0xe566139aLU, 0xbfa7e01dLU, 0x51a9b8d9LU, 0x0b684b5eLU, 0xc0b5081cLU, 0x9a74fb9bLU, 0x747aa35fLU, 0x2ebb50d8LU,
0x3b164959LU, 0x61d7badeLU, 0x8fd9e21aLU, 0xd518119dLU, 0x1ec552dfLU, 0x4404a158LU, 0xaa0af99cLU, 0xf0cb0a1bLU,
0x71fd7f18LU, 0x2b3c8c9fLU, 0xc532d45bLU, 0x9ff327dcLU, 0x542e649eLU, 0x0eef9719LU, 0xe0e1cfddLU, 0xba203c5aLU,
0xd9a1b769LU, 0x836044eeLU, 0x6d6e1c2aLU, 0x37afefadLU, 0xfc72acefLU, 0xa6b35f68LU, 0x48bd07acLU, 0x127cf42bLU,
0x934a8128LU, 0xc98b72afLU, 0x27852a6bLU, 0x7d44d9ecLU, 0xb6999aaeLU, 0xec586929LU, 0x025631edLU, 0x5897c26aLU,
0x4d3adbebLU, 0x17fb286cLU, 0xf9f570a8LU, 0xa334832fLU, 0x68e9c06dLU, 0x322833eaLU, 0xdc266b2eLU, 0x86e798a9LU,
0x07d1edaaLU, 0x5d101e2dLU, 0xb31e46e9LU, 0xe9dfb56eLU, 0x2202f62cLU, 0x78c305abLU, 0x96cd5d6fLU, 0xcc0caee8LU,
0xbcda6f20LU, 0xe61b9ca7LU, 0x0815c463LU, 0x52d437e4LU, 0x990974a6LU, 0xc3c88721LU, 0x2dc6dfe5LU, 0x77072c62LU,
0xf6315961LU, 0xacf0aae6LU, 0x42fef222LU, 0x183f01a5LU, 0xd3e242e7LU, 0x8923b160LU, 0x672de9a4LU, 0x3dec1a23LU,
0x284103a2LU, 0x7280f025LU, 0x9c8ea8e1LU, 0xc64f5b66LU, 0x0d921824LU, 0x5753eba3LU, 0xb95db367LU, 0xe39c40e0LU,
0x62aa35e3LU, 0x386bc664LU, 0xd6659ea0LU, 0x8ca46d27LU, 0x47792e65LU, 0x1db8dde2LU, 0xf3b68526LU, 0xa97776a1LU,
0x13574afbLU, 0x4996b97cLU, 0xa798e1b8LU, 0xfd59123fLU, 0x3684517dLU, 0x6c45a2faLU, 0x824bfa3eLU, 0xd88a09b9LU,
0x59bc7cbaLU, 0x037d8f3dLU, 0xed73d7f9LU, 0xb7b2247eLU, 0x7c6f673cLU, 0x26ae94bbLU, 0xc8a0cc7fLU, 0x92613ff8LU,
0x87cc2679LU, 0xdd0dd5feLU, 0x33038d3aLU, 0x69c27ebdLU, 0xa21f3dffLU, 0xf8dece78LU, 0x16d096bcLU, 0x4c11653bLU,
0xcd271038LU, 0x97e6e3bfLU, 0x79e8bb7bLU, 0x232948fcLU, 0xe8f40bbeLU, 0xb235f839LU, 0x5c3ba0fdLU, 0x06fa537aLU,
0x762c92b2LU, 0x2ced6135LU, 0xc2e339f1LU, 0x9822ca76LU, 0x53ff8934LU, 0x093e7ab3LU, 0xe7302277LU, 0xbdf1d1f0LU,
0x3cc7a4f3LU, 0x66065774LU, 0x88080fb0LU, 0xd2c9fc37LU, 0x1914bf75LU, 0x43d54cf2LU, 0xaddb1436LU, 0xf71ae7b1LU,
0xe2b7fe30LU, 0xb8760db7LU, 0x56785573LU, 0x0cb9a6f4LU, 0xc764e5b6LU, 0x9da51631LU, 0x73ab4ef5LU, 0x296abd72LU,
0xa85cc871LU, 0xf29d3bf6LU, 0x1c936332LU, 0x465290b5LU, 0x8d8fd3f7LU, 0xd74e2070LU, 0x394078b4LU, 0x63818b33LU };
static const ulong32 rs_tab4[256] = {
0x00000000LU, 0x58471e5aLU, 0xb08e3cb4LU, 0xe8c922eeLU, 0x2d517825LU, 0x7516667fLU, 0x9ddf4491LU, 0xc5985acbLU,
0x5aa2f04aLU, 0x02e5ee10LU, 0xea2cccfeLU, 0xb26bd2a4LU, 0x77f3886fLU, 0x2fb49635LU, 0xc77db4dbLU, 0x9f3aaa81LU,
0xb409ad94LU, 0xec4eb3ceLU, 0x04879120LU, 0x5cc08f7aLU, 0x9958d5b1LU, 0xc11fcbebLU, 0x29d6e905LU, 0x7191f75fLU,
0xeeab5ddeLU, 0xb6ec4384LU, 0x5e25616aLU, 0x06627f30LU, 0xc3fa25fbLU, 0x9bbd3ba1LU, 0x7374194fLU, 0x2b330715LU,
0x25121765LU, 0x7d55093fLU, 0x959c2bd1LU, 0xcddb358bLU, 0x08436f40LU, 0x5004711aLU, 0xb8cd53f4LU, 0xe08a4daeLU,
0x7fb0e72fLU, 0x27f7f975LU, 0xcf3edb9bLU, 0x9779c5c1LU, 0x52e19f0aLU, 0x0aa68150LU, 0xe26fa3beLU, 0xba28bde4LU,
0x911bbaf1LU, 0xc95ca4abLU, 0x21958645LU, 0x79d2981fLU, 0xbc4ac2d4LU, 0xe40ddc8eLU, 0x0cc4fe60LU, 0x5483e03aLU,
0xcbb94abbLU, 0x93fe54e1LU, 0x7b37760fLU, 0x23706855LU, 0xe6e8329eLU, 0xbeaf2cc4LU, 0x56660e2aLU, 0x0e211070LU,
0x4a242ecaLU, 0x12633090LU, 0xfaaa127eLU, 0xa2ed0c24LU, 0x677556efLU, 0x3f3248b5LU, 0xd7fb6a5bLU, 0x8fbc7401LU,
0x1086de80LU, 0x48c1c0daLU, 0xa008e234LU, 0xf84ffc6eLU, 0x3dd7a6a5LU, 0x6590b8ffLU, 0x8d599a11LU, 0xd51e844bLU,
0xfe2d835eLU, 0xa66a9d04LU, 0x4ea3bfeaLU, 0x16e4a1b0LU, 0xd37cfb7bLU, 0x8b3be521LU, 0x63f2c7cfLU, 0x3bb5d995LU,
0xa48f7314LU, 0xfcc86d4eLU, 0x14014fa0LU, 0x4c4651faLU, 0x89de0b31LU, 0xd199156bLU, 0x39503785LU, 0x611729dfLU,
0x6f3639afLU, 0x377127f5LU, 0xdfb8051bLU, 0x87ff1b41LU, 0x4267418aLU, 0x1a205fd0LU, 0xf2e97d3eLU, 0xaaae6364LU,
0x3594c9e5LU, 0x6dd3d7bfLU, 0x851af551LU, 0xdd5deb0bLU, 0x18c5b1c0LU, 0x4082af9aLU, 0xa84b8d74LU, 0xf00c932eLU,
0xdb3f943bLU, 0x83788a61LU, 0x6bb1a88fLU, 0x33f6b6d5LU, 0xf66eec1eLU, 0xae29f244LU, 0x46e0d0aaLU, 0x1ea7cef0LU,
0x819d6471LU, 0xd9da7a2bLU, 0x311358c5LU, 0x6954469fLU, 0xaccc1c54LU, 0xf48b020eLU, 0x1c4220e0LU, 0x44053ebaLU,
0x94485cd9LU, 0xcc0f4283LU, 0x24c6606dLU, 0x7c817e37LU, 0xb91924fcLU, 0xe15e3aa6LU, 0x09971848LU, 0x51d00612LU,
0xceeaac93LU, 0x96adb2c9LU, 0x7e649027LU, 0x26238e7dLU, 0xe3bbd4b6LU, 0xbbfccaecLU, 0x5335e802LU, 0x0b72f658LU,
0x2041f14dLU, 0x7806ef17LU, 0x90cfcdf9LU, 0xc888d3a3LU, 0x0d108968LU, 0x55579732LU, 0xbd9eb5dcLU, 0xe5d9ab86LU,
0x7ae30107LU, 0x22a41f5dLU, 0xca6d3db3LU, 0x922a23e9LU, 0x57b27922LU, 0x0ff56778LU, 0xe73c4596LU, 0xbf7b5bccLU,
0xb15a4bbcLU, 0xe91d55e6LU, 0x01d47708LU, 0x59936952LU, 0x9c0b3399LU, 0xc44c2dc3LU, 0x2c850f2dLU, 0x74c21177LU,
0xebf8bbf6LU, 0xb3bfa5acLU, 0x5b768742LU, 0x03319918LU, 0xc6a9c3d3LU, 0x9eeedd89LU, 0x7627ff67LU, 0x2e60e13dLU,
0x0553e628LU, 0x5d14f872LU, 0xb5ddda9cLU, 0xed9ac4c6LU, 0x28029e0dLU, 0x70458057LU, 0x988ca2b9LU, 0xc0cbbce3LU,
0x5ff11662LU, 0x07b60838LU, 0xef7f2ad6LU, 0xb738348cLU, 0x72a06e47LU, 0x2ae7701dLU, 0xc22e52f3LU, 0x9a694ca9LU,
0xde6c7213LU, 0x862b6c49LU, 0x6ee24ea7LU, 0x36a550fdLU, 0xf33d0a36LU, 0xab7a146cLU, 0x43b33682LU, 0x1bf428d8LU,
0x84ce8259LU, 0xdc899c03LU, 0x3440beedLU, 0x6c07a0b7LU, 0xa99ffa7cLU, 0xf1d8e426LU, 0x1911c6c8LU, 0x4156d892LU,
0x6a65df87LU, 0x3222c1ddLU, 0xdaebe333LU, 0x82acfd69LU, 0x4734a7a2LU, 0x1f73b9f8LU, 0xf7ba9b16LU, 0xaffd854cLU,
0x30c72fcdLU, 0x68803197LU, 0x80491379LU, 0xd80e0d23LU, 0x1d9657e8LU, 0x45d149b2LU, 0xad186b5cLU, 0xf55f7506LU,
0xfb7e6576LU, 0xa3397b2cLU, 0x4bf059c2LU, 0x13b74798LU, 0xd62f1d53LU, 0x8e680309LU, 0x66a121e7LU, 0x3ee63fbdLU,
0xa1dc953cLU, 0xf99b8b66LU, 0x1152a988LU, 0x4915b7d2LU, 0x8c8ded19LU, 0xd4caf343LU, 0x3c03d1adLU, 0x6444cff7LU,
0x4f77c8e2LU, 0x1730d6b8LU, 0xfff9f456LU, 0xa7beea0cLU, 0x6226b0c7LU, 0x3a61ae9dLU, 0xd2a88c73LU, 0x8aef9229LU,
0x15d538a8LU, 0x4d9226f2LU, 0xa55b041cLU, 0xfd1c1a46LU, 0x3884408dLU, 0x60c35ed7LU, 0x880a7c39LU, 0xd04d6263LU };
static const ulong32 rs_tab5[256] = {
0x00000000LU, 0xdbaec658LU, 0xfb11c1b0LU, 0x20bf07e8LU, 0xbb22cf2dLU, 0x608c0975LU, 0x40330e9dLU, 0x9b9dc8c5LU,
0x3b44d35aLU, 0xe0ea1502LU, 0xc05512eaLU, 0x1bfbd4b2LU, 0x80661c77LU, 0x5bc8da2fLU, 0x7b77ddc7LU, 0xa0d91b9fLU,
0x7688ebb4LU, 0xad262decLU, 0x8d992a04LU, 0x5637ec5cLU, 0xcdaa2499LU, 0x1604e2c1LU, 0x36bbe529LU, 0xed152371LU,
0x4dcc38eeLU, 0x9662feb6LU, 0xb6ddf95eLU, 0x6d733f06LU, 0xf6eef7c3LU, 0x2d40319bLU, 0x0dff3673LU, 0xd651f02bLU,
0xec5d9b25LU, 0x37f35d7dLU, 0x174c5a95LU, 0xcce29ccdLU, 0x577f5408LU, 0x8cd19250LU, 0xac6e95b8LU, 0x77c053e0LU,
0xd719487fLU, 0x0cb78e27LU, 0x2c0889cfLU, 0xf7a64f97LU, 0x6c3b8752LU, 0xb795410aLU, 0x972a46e2LU, 0x4c8480baLU,
0x9ad57091LU, 0x417bb6c9LU, 0x61c4b121LU, 0xba6a7779LU, 0x21f7bfbcLU, 0xfa5979e4LU, 0xdae67e0cLU, 0x0148b854LU,
0xa191a3cbLU, 0x7a3f6593LU, 0x5a80627bLU, 0x812ea423LU, 0x1ab36ce6LU, 0xc11daabeLU, 0xe1a2ad56LU, 0x3a0c6b0eLU,
0x95ba7b4aLU, 0x4e14bd12LU, 0x6eabbafaLU, 0xb5057ca2LU, 0x2e98b467LU, 0xf536723fLU, 0xd58975d7LU, 0x0e27b38fLU,
0xaefea810LU, 0x75506e48LU, 0x55ef69a0LU, 0x8e41aff8LU, 0x15dc673dLU, 0xce72a165LU, 0xeecda68dLU, 0x356360d5LU,
0xe33290feLU, 0x389c56a6LU, 0x1823514eLU, 0xc38d9716LU, 0x58105fd3LU, 0x83be998bLU, 0xa3019e63LU, 0x78af583bLU,
0xd87643a4LU, 0x03d885fcLU, 0x23678214LU, 0xf8c9444cLU, 0x63548c89LU, 0xb8fa4ad1LU, 0x98454d39LU, 0x43eb8b61LU,
0x79e7e06fLU, 0xa2492637LU, 0x82f621dfLU, 0x5958e787LU, 0xc2c52f42LU, 0x196be91aLU, 0x39d4eef2LU, 0xe27a28aaLU,
0x42a33335LU, 0x990df56dLU, 0xb9b2f285LU, 0x621c34ddLU, 0xf981fc18LU, 0x222f3a40LU, 0x02903da8LU, 0xd93efbf0LU,
0x0f6f0bdbLU, 0xd4c1cd83LU, 0xf47eca6bLU, 0x2fd00c33LU, 0xb44dc4f6LU, 0x6fe302aeLU, 0x4f5c0546LU, 0x94f2c31eLU,
0x342bd881LU, 0xef851ed9LU, 0xcf3a1931LU, 0x1494df69LU, 0x8f0917acLU, 0x54a7d1f4LU, 0x7418d61cLU, 0xafb61044LU,
0x6739f694LU, 0xbc9730ccLU, 0x9c283724LU, 0x4786f17cLU, 0xdc1b39b9LU, 0x07b5ffe1LU, 0x270af809LU, 0xfca43e51LU,
0x5c7d25ceLU, 0x87d3e396LU, 0xa76ce47eLU, 0x7cc22226LU, 0xe75feae3LU, 0x3cf12cbbLU, 0x1c4e2b53LU, 0xc7e0ed0bLU,
0x11b11d20LU, 0xca1fdb78LU, 0xeaa0dc90LU, 0x310e1ac8LU, 0xaa93d20dLU, 0x713d1455LU, 0x518213bdLU, 0x8a2cd5e5LU,
0x2af5ce7aLU, 0xf15b0822LU, 0xd1e40fcaLU, 0x0a4ac992LU, 0x91d70157LU, 0x4a79c70fLU, 0x6ac6c0e7LU, 0xb16806bfLU,
0x8b646db1LU, 0x50caabe9LU, 0x7075ac01LU, 0xabdb6a59LU, 0x3046a29cLU, 0xebe864c4LU, 0xcb57632cLU, 0x10f9a574LU,
0xb020beebLU, 0x6b8e78b3LU, 0x4b317f5bLU, 0x909fb903LU, 0x0b0271c6LU, 0xd0acb79eLU, 0xf013b076LU, 0x2bbd762eLU,
0xfdec8605LU, 0x2642405dLU, 0x06fd47b5LU, 0xdd5381edLU, 0x46ce4928LU, 0x9d608f70LU, 0xbddf8898LU, 0x66714ec0LU,
0xc6a8555fLU, 0x1d069307LU, 0x3db994efLU, 0xe61752b7LU, 0x7d8a9a72LU, 0xa6245c2aLU, 0x869b5bc2LU, 0x5d359d9aLU,
0xf2838ddeLU, 0x292d4b86LU, 0x09924c6eLU, 0xd23c8a36LU, 0x49a142f3LU, 0x920f84abLU, 0xb2b08343LU, 0x691e451bLU,
0xc9c75e84LU, 0x126998dcLU, 0x32d69f34LU, 0xe978596cLU, 0x72e591a9LU, 0xa94b57f1LU, 0x89f45019LU, 0x525a9641LU,
0x840b666aLU, 0x5fa5a032LU, 0x7f1aa7daLU, 0xa4b46182LU, 0x3f29a947LU, 0xe4876f1fLU, 0xc43868f7LU, 0x1f96aeafLU,
0xbf4fb530LU, 0x64e17368LU, 0x445e7480LU, 0x9ff0b2d8LU, 0x046d7a1dLU, 0xdfc3bc45LU, 0xff7cbbadLU, 0x24d27df5LU,
0x1ede16fbLU, 0xc570d0a3LU, 0xe5cfd74bLU, 0x3e611113LU, 0xa5fcd9d6LU, 0x7e521f8eLU, 0x5eed1866LU, 0x8543de3eLU,
0x259ac5a1LU, 0xfe3403f9LU, 0xde8b0411LU, 0x0525c249LU, 0x9eb80a8cLU, 0x4516ccd4LU, 0x65a9cb3cLU, 0xbe070d64LU,
0x6856fd4fLU, 0xb3f83b17LU, 0x93473cffLU, 0x48e9faa7LU, 0xd3743262LU, 0x08daf43aLU, 0x2865f3d2LU, 0xf3cb358aLU,
0x53122e15LU, 0x88bce84dLU, 0xa803efa5LU, 0x73ad29fdLU, 0xe830e138LU, 0x339e2760LU, 0x13212088LU, 0xc88fe6d0LU };
static const ulong32 rs_tab6[256] = {
0x00000000LU, 0x9e3d68dbLU, 0x717ad0fbLU, 0xef47b820LU, 0xe2f4edbbLU, 0x7cc98560LU, 0x938e3d40LU, 0x0db3559bLU,
0x89a5973bLU, 0x1798ffe0LU, 0xf8df47c0LU, 0x66e22f1bLU, 0x6b517a80LU, 0xf56c125bLU, 0x1a2baa7bLU, 0x8416c2a0LU,
0x5f076376LU, 0xc13a0badLU, 0x2e7db38dLU, 0xb040db56LU, 0xbdf38ecdLU, 0x23cee616LU, 0xcc895e36LU, 0x52b436edLU,
0xd6a2f44dLU, 0x489f9c96LU, 0xa7d824b6LU, 0x39e54c6dLU, 0x345619f6LU, 0xaa6b712dLU, 0x452cc90dLU, 0xdb11a1d6LU,
0xbe0ec6ecLU, 0x2033ae37LU, 0xcf741617LU, 0x51497eccLU, 0x5cfa2b57LU, 0xc2c7438cLU, 0x2d80fbacLU, 0xb3bd9377LU,
0x37ab51d7LU, 0xa996390cLU, 0x46d1812cLU, 0xd8ece9f7LU, 0xd55fbc6cLU, 0x4b62d4b7LU, 0xa4256c97LU, 0x3a18044cLU,
0xe109a59aLU, 0x7f34cd41LU, 0x90737561LU, 0x0e4e1dbaLU, 0x03fd4821LU, 0x9dc020faLU, 0x728798daLU, 0xecbaf001LU,
0x68ac32a1LU, 0xf6915a7aLU, 0x19d6e25aLU, 0x87eb8a81LU, 0x8a58df1aLU, 0x1465b7c1LU, 0xfb220fe1LU, 0x651f673aLU,
0x311cc195LU, 0xaf21a94eLU, 0x4066116eLU, 0xde5b79b5LU, 0xd3e82c2eLU, 0x4dd544f5LU, 0xa292fcd5LU, 0x3caf940eLU,
0xb8b956aeLU, 0x26843e75LU, 0xc9c38655LU, 0x57feee8eLU, 0x5a4dbb15LU, 0xc470d3ceLU, 0x2b376beeLU, 0xb50a0335LU,
0x6e1ba2e3LU, 0xf026ca38LU, 0x1f617218LU, 0x815c1ac3LU, 0x8cef4f58LU, 0x12d22783LU, 0xfd959fa3LU, 0x63a8f778LU,
0xe7be35d8LU, 0x79835d03LU, 0x96c4e523LU, 0x08f98df8LU, 0x054ad863LU, 0x9b77b0b8LU, 0x74300898LU, 0xea0d6043LU,
0x8f120779LU, 0x112f6fa2LU, 0xfe68d782LU, 0x6055bf59LU, 0x6de6eac2LU, 0xf3db8219LU, 0x1c9c3a39LU, 0x82a152e2LU,
0x06b79042LU, 0x988af899LU, 0x77cd40b9LU, 0xe9f02862LU, 0xe4437df9LU, 0x7a7e1522LU, 0x9539ad02LU, 0x0b04c5d9LU,
0xd015640fLU, 0x4e280cd4LU, 0xa16fb4f4LU, 0x3f52dc2fLU, 0x32e189b4LU, 0xacdce16fLU, 0x439b594fLU, 0xdda63194LU,
0x59b0f334LU, 0xc78d9befLU, 0x28ca23cfLU, 0xb6f74b14LU, 0xbb441e8fLU, 0x25797654LU, 0xca3ece74LU, 0x5403a6afLU,
0x6238cf67LU, 0xfc05a7bcLU, 0x13421f9cLU, 0x8d7f7747LU, 0x80cc22dcLU, 0x1ef14a07LU, 0xf1b6f227LU, 0x6f8b9afcLU,
0xeb9d585cLU, 0x75a03087LU, 0x9ae788a7LU, 0x04dae07cLU, 0x0969b5e7LU, 0x9754dd3cLU, 0x7813651cLU, 0xe62e0dc7LU,
0x3d3fac11LU, 0xa302c4caLU, 0x4c457ceaLU, 0xd2781431LU, 0xdfcb41aaLU, 0x41f62971LU, 0xaeb19151LU, 0x308cf98aLU,
0xb49a3b2aLU, 0x2aa753f1LU, 0xc5e0ebd1LU, 0x5bdd830aLU, 0x566ed691LU, 0xc853be4aLU, 0x2714066aLU, 0xb9296eb1LU,
0xdc36098bLU, 0x420b6150LU, 0xad4cd970LU, 0x3371b1abLU, 0x3ec2e430LU, 0xa0ff8cebLU, 0x4fb834cbLU, 0xd1855c10LU,
0x55939eb0LU, 0xcbaef66bLU, 0x24e94e4bLU, 0xbad42690LU, 0xb767730bLU, 0x295a1bd0LU, 0xc61da3f0LU, 0x5820cb2bLU,
0x83316afdLU, 0x1d0c0226LU, 0xf24bba06LU, 0x6c76d2ddLU, 0x61c58746LU, 0xfff8ef9dLU, 0x10bf57bdLU, 0x8e823f66LU,
0x0a94fdc6LU, 0x94a9951dLU, 0x7bee2d3dLU, 0xe5d345e6LU, 0xe860107dLU, 0x765d78a6LU, 0x991ac086LU, 0x0727a85dLU,
0x53240ef2LU, 0xcd196629LU, 0x225ede09LU, 0xbc63b6d2LU, 0xb1d0e349LU, 0x2fed8b92LU, 0xc0aa33b2LU, 0x5e975b69LU,
0xda8199c9LU, 0x44bcf112LU, 0xabfb4932LU, 0x35c621e9LU, 0x38757472LU, 0xa6481ca9LU, 0x490fa489LU, 0xd732cc52LU,
0x0c236d84LU, 0x921e055fLU, 0x7d59bd7fLU, 0xe364d5a4LU, 0xeed7803fLU, 0x70eae8e4LU, 0x9fad50c4LU, 0x0190381fLU,
0x8586fabfLU, 0x1bbb9264LU, 0xf4fc2a44LU, 0x6ac1429fLU, 0x67721704LU, 0xf94f7fdfLU, 0x1608c7ffLU, 0x8835af24LU,
0xed2ac81eLU, 0x7317a0c5LU, 0x9c5018e5LU, 0x026d703eLU, 0x0fde25a5LU, 0x91e34d7eLU, 0x7ea4f55eLU, 0xe0999d85LU,
0x648f5f25LU, 0xfab237feLU, 0x15f58fdeLU, 0x8bc8e705LU, 0x867bb29eLU, 0x1846da45LU, 0xf7016265LU, 0x693c0abeLU,
0xb22dab68LU, 0x2c10c3b3LU, 0xc3577b93LU, 0x5d6a1348LU, 0x50d946d3LU, 0xcee42e08LU, 0x21a39628LU, 0xbf9efef3LU,
0x3b883c53LU, 0xa5b55488LU, 0x4af2eca8LU, 0xd4cf8473LU, 0xd97cd1e8LU, 0x4741b933LU, 0xa8060113LU, 0x363b69c8LU };
static const ulong32 rs_tab7[256] = {
0x00000000LU, 0x0319e59eLU, 0x06328771LU, 0x052b62efLU, 0x0c6443e2LU, 0x0f7da67cLU, 0x0a56c493LU, 0x094f210dLU,
0x18c88689LU, 0x1bd16317LU, 0x1efa01f8LU, 0x1de3e466LU, 0x14acc56bLU, 0x17b520f5LU, 0x129e421aLU, 0x1187a784LU,
0x30dd415fLU, 0x33c4a4c1LU, 0x36efc62eLU, 0x35f623b0LU, 0x3cb902bdLU, 0x3fa0e723LU, 0x3a8b85ccLU, 0x39926052LU,
0x2815c7d6LU, 0x2b0c2248LU, 0x2e2740a7LU, 0x2d3ea539LU, 0x24718434LU, 0x276861aaLU, 0x22430345LU, 0x215ae6dbLU,
0x60f782beLU, 0x63ee6720LU, 0x66c505cfLU, 0x65dce051LU, 0x6c93c15cLU, 0x6f8a24c2LU, 0x6aa1462dLU, 0x69b8a3b3LU,
0x783f0437LU, 0x7b26e1a9LU, 0x7e0d8346LU, 0x7d1466d8LU, 0x745b47d5LU, 0x7742a24bLU, 0x7269c0a4LU, 0x7170253aLU,
0x502ac3e1LU, 0x5333267fLU, 0x56184490LU, 0x5501a10eLU, 0x5c4e8003LU, 0x5f57659dLU, 0x5a7c0772LU, 0x5965e2ecLU,
0x48e24568LU, 0x4bfba0f6LU, 0x4ed0c219LU, 0x4dc92787LU, 0x4486068aLU, 0x479fe314LU, 0x42b481fbLU, 0x41ad6465LU,
0xc0a34931LU, 0xc3baacafLU, 0xc691ce40LU, 0xc5882bdeLU, 0xccc70ad3LU, 0xcfdeef4dLU, 0xcaf58da2LU, 0xc9ec683cLU,
0xd86bcfb8LU, 0xdb722a26LU, 0xde5948c9LU, 0xdd40ad57LU, 0xd40f8c5aLU, 0xd71669c4LU, 0xd23d0b2bLU, 0xd124eeb5LU,
0xf07e086eLU, 0xf367edf0LU, 0xf64c8f1fLU, 0xf5556a81LU, 0xfc1a4b8cLU, 0xff03ae12LU, 0xfa28ccfdLU, 0xf9312963LU,
0xe8b68ee7LU, 0xebaf6b79LU, 0xee840996LU, 0xed9dec08LU, 0xe4d2cd05LU, 0xe7cb289bLU, 0xe2e04a74LU, 0xe1f9afeaLU,
0xa054cb8fLU, 0xa34d2e11LU, 0xa6664cfeLU, 0xa57fa960LU, 0xac30886dLU, 0xaf296df3LU, 0xaa020f1cLU, 0xa91bea82LU,
0xb89c4d06LU, 0xbb85a898LU, 0xbeaeca77LU, 0xbdb72fe9LU, 0xb4f80ee4LU, 0xb7e1eb7aLU, 0xb2ca8995LU, 0xb1d36c0bLU,
0x90898ad0LU, 0x93906f4eLU, 0x96bb0da1LU, 0x95a2e83fLU, 0x9cedc932LU, 0x9ff42cacLU, 0x9adf4e43LU, 0x99c6abddLU,
0x88410c59LU, 0x8b58e9c7LU, 0x8e738b28LU, 0x8d6a6eb6LU, 0x84254fbbLU, 0x873caa25LU, 0x8217c8caLU, 0x810e2d54LU,
0xcd0b9262LU, 0xce1277fcLU, 0xcb391513LU, 0xc820f08dLU, 0xc16fd180LU, 0xc276341eLU, 0xc75d56f1LU, 0xc444b36fLU,
0xd5c314ebLU, 0xd6daf175LU, 0xd3f1939aLU, 0xd0e87604LU, 0xd9a75709LU, 0xdabeb297LU, 0xdf95d078LU, 0xdc8c35e6LU,
0xfdd6d33dLU, 0xfecf36a3LU, 0xfbe4544cLU, 0xf8fdb1d2LU, 0xf1b290dfLU, 0xf2ab7541LU, 0xf78017aeLU, 0xf499f230LU,
0xe51e55b4LU, 0xe607b02aLU, 0xe32cd2c5LU, 0xe035375bLU, 0xe97a1656LU, 0xea63f3c8LU, 0xef489127LU, 0xec5174b9LU,
0xadfc10dcLU, 0xaee5f542LU, 0xabce97adLU, 0xa8d77233LU, 0xa198533eLU, 0xa281b6a0LU, 0xa7aad44fLU, 0xa4b331d1LU,
0xb5349655LU, 0xb62d73cbLU, 0xb3061124LU, 0xb01ff4baLU, 0xb950d5b7LU, 0xba493029LU, 0xbf6252c6LU, 0xbc7bb758LU,
0x9d215183LU, 0x9e38b41dLU, 0x9b13d6f2LU, 0x980a336cLU, 0x91451261LU, 0x925cf7ffLU, 0x97779510LU, 0x946e708eLU,
0x85e9d70aLU, 0x86f03294LU, 0x83db507bLU, 0x80c2b5e5LU, 0x898d94e8LU, 0x8a947176LU, 0x8fbf1399LU, 0x8ca6f607LU,
0x0da8db53LU, 0x0eb13ecdLU, 0x0b9a5c22LU, 0x0883b9bcLU, 0x01cc98b1LU, 0x02d57d2fLU, 0x07fe1fc0LU, 0x04e7fa5eLU,
0x15605ddaLU, 0x1679b844LU, 0x1352daabLU, 0x104b3f35LU, 0x19041e38LU, 0x1a1dfba6LU, 0x1f369949LU, 0x1c2f7cd7LU,
0x3d759a0cLU, 0x3e6c7f92LU, 0x3b471d7dLU, 0x385ef8e3LU, 0x3111d9eeLU, 0x32083c70LU, 0x37235e9fLU, 0x343abb01LU,
0x25bd1c85LU, 0x26a4f91bLU, 0x238f9bf4LU, 0x20967e6aLU, 0x29d95f67LU, 0x2ac0baf9LU, 0x2febd816LU, 0x2cf23d88LU,
0x6d5f59edLU, 0x6e46bc73LU, 0x6b6dde9cLU, 0x68743b02LU, 0x613b1a0fLU, 0x6222ff91LU, 0x67099d7eLU, 0x641078e0LU,
0x7597df64LU, 0x768e3afaLU, 0x73a55815LU, 0x70bcbd8bLU, 0x79f39c86LU, 0x7aea7918LU, 0x7fc11bf7LU, 0x7cd8fe69LU,
0x5d8218b2LU, 0x5e9bfd2cLU, 0x5bb09fc3LU, 0x58a97a5dLU, 0x51e65b50LU, 0x52ffbeceLU, 0x57d4dc21LU, 0x54cd39bfLU,
0x454a9e3bLU, 0x46537ba5LU, 0x4378194aLU, 0x4061fcd4LU, 0x492eddd9LU, 0x4a373847LU, 0x4f1c5aa8LU, 0x4c05bf36LU };
#endif /* LTC_TWOFISH_ALL_TABLES */
#endif /* __LTC_TWOFISH_TAB_C__ */
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

261
thirdparty/libtomcrypt/ciphers/xtea.c vendored Normal file
View File

@@ -0,0 +1,261 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file xtea.c
Implementation of LTC_XTEA, Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_XTEA
const struct ltc_cipher_descriptor xtea_desc =
{
"xtea",
1,
16, 16, 8, 32,
&xtea_setup,
&xtea_ecb_encrypt,
&xtea_ecb_decrypt,
&xtea_test,
&xtea_done,
&xtea_keysize,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
ulong32 x, sum, K[4];
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
/* check arguments */
if (keylen != 16) {
return CRYPT_INVALID_KEYSIZE;
}
if (num_rounds != 0 && num_rounds != 32) {
return CRYPT_INVALID_ROUNDS;
}
/* load key */
LOAD32H(K[0], key+0);
LOAD32H(K[1], key+4);
LOAD32H(K[2], key+8);
LOAD32H(K[3], key+12);
for (x = sum = 0; x < 32; x++) {
skey->xtea.A[x] = (sum + K[sum&3]) & 0xFFFFFFFFUL;
sum = (sum + 0x9E3779B9UL) & 0xFFFFFFFFUL;
skey->xtea.B[x] = (sum + K[(sum>>11)&3]) & 0xFFFFFFFFUL;
}
#ifdef LTC_CLEAN_STACK
zeromem(&K, sizeof(K));
#endif
return CRYPT_OK;
}
/**
Encrypts a block of text with LTC_XTEA
@param pt The input plaintext (8 bytes)
@param ct The output ciphertext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
ulong32 y, z;
int r;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
LOAD32H(y, &pt[0]);
LOAD32H(z, &pt[4]);
for (r = 0; r < 32; r += 4) {
y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r])) & 0xFFFFFFFFUL;
z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r])) & 0xFFFFFFFFUL;
y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+1])) & 0xFFFFFFFFUL;
z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+1])) & 0xFFFFFFFFUL;
y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+2])) & 0xFFFFFFFFUL;
z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+2])) & 0xFFFFFFFFUL;
y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+3])) & 0xFFFFFFFFUL;
z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+3])) & 0xFFFFFFFFUL;
}
STORE32H(y, &ct[0]);
STORE32H(z, &ct[4]);
return CRYPT_OK;
}
/**
Decrypts a block of text with LTC_XTEA
@param ct The input ciphertext (8 bytes)
@param pt The output plaintext (8 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
ulong32 y, z;
int r;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
LOAD32H(y, &ct[0]);
LOAD32H(z, &ct[4]);
for (r = 31; r >= 0; r -= 4) {
z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r])) & 0xFFFFFFFFUL;
y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r])) & 0xFFFFFFFFUL;
z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-1])) & 0xFFFFFFFFUL;
y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-1])) & 0xFFFFFFFFUL;
z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-2])) & 0xFFFFFFFFUL;
y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-2])) & 0xFFFFFFFFUL;
z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-3])) & 0xFFFFFFFFUL;
y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-3])) & 0xFFFFFFFFUL;
}
STORE32H(y, &pt[0]);
STORE32H(z, &pt[4]);
return CRYPT_OK;
}
/**
Performs a self-test of the LTC_XTEA block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int xtea_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
unsigned char key[16], pt[8], ct[8];
} tests[] = {
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xde, 0xe9, 0xd4, 0xd8, 0xf7, 0x13, 0x1e, 0xd9 }
}, {
{ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xa5, 0x97, 0xab, 0x41, 0x76, 0x01, 0x4d, 0x72 }
}, {
{ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04,
0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06 },
{ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02 },
{ 0xb1, 0xfd, 0x5d, 0xa9, 0xcc, 0x6d, 0xc9, 0xdc }
}, {
{ 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f,
0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
{ 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 },
{ 0x70, 0x4b, 0x31, 0x34, 0x47, 0x44, 0xdf, 0xab }
}, {
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
{ 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 }
}, {
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
{ 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 }
}, {
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f },
{ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
}, {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 },
{ 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 }
}, {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 },
{ 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d }
}, {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 },
{ 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }
}
};
unsigned char tmp[2][8];
symmetric_key skey;
int i, err, y;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
zeromem(&skey, sizeof(skey));
if ((err = xtea_setup(tests[i].key, 16, 0, &skey)) != CRYPT_OK) {
return err;
}
xtea_ecb_encrypt(tests[i].pt, tmp[0], &skey);
xtea_ecb_decrypt(tmp[0], tmp[1], &skey);
if (compare_testvector(tmp[0], 8, tests[i].ct, 8, "XTEA Encrypt", i) != 0 ||
compare_testvector(tmp[1], 8, tests[i].pt, 8, "XTEA Decrypt", i) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 8; y++) tmp[0][y] = 0;
for (y = 0; y < 1000; y++) xtea_ecb_encrypt(tmp[0], tmp[0], &skey);
for (y = 0; y < 1000; y++) xtea_ecb_decrypt(tmp[0], tmp[0], &skey);
for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
} /* for */
return CRYPT_OK;
#endif
}
/** Terminate the context
@param skey The scheduled key
*/
void xtea_done(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int xtea_keysize(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 16) {
return CRYPT_INVALID_KEYSIZE;
}
*keysize = 16;
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,63 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_CCM_MODE
/**
Add AAD to the CCM state
@param ccm The CCM state
@param adata The additional authentication data to add to the CCM state
@param adatalen The length of the AAD data.
@return CRYPT_OK on success
*/
int ccm_add_aad(ccm_state *ccm,
const unsigned char *adata, unsigned long adatalen)
{
unsigned long y;
int err;
LTC_ARGCHK(ccm != NULL);
LTC_ARGCHK(adata != NULL);
if (ccm->aadlen < ccm->current_aadlen + adatalen) {
return CRYPT_INVALID_ARG;
}
ccm->current_aadlen += adatalen;
/* now add the data */
for (y = 0; y < adatalen; y++) {
if (ccm->x == 16) {
/* full block so let's encrypt it */
if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) {
return err;
}
ccm->x = 0;
}
ccm->PAD[ccm->x++] ^= adata[y];
}
/* remainder? */
if (ccm->aadlen == ccm->current_aadlen) {
if (ccm->x != 0) {
if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) {
return err;
}
}
ccm->x = 0;
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,113 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_CCM_MODE
/**
Add nonce data to the CCM state
@param ccm The CCM state
@param nonce The nonce data to add
@param noncelen The length of the nonce
@return CRYPT_OK on success
*/
int ccm_add_nonce(ccm_state *ccm,
const unsigned char *nonce, unsigned long noncelen)
{
unsigned long x, y, len;
int err;
LTC_ARGCHK(ccm != NULL);
LTC_ARGCHK(nonce != NULL);
/* increase L to match the nonce len */
ccm->noncelen = (noncelen > 13) ? 13 : noncelen;
if ((15 - ccm->noncelen) > ccm->L) {
ccm->L = 15 - ccm->noncelen;
}
/* decrease noncelen to match L */
if ((ccm->noncelen + ccm->L) > 15) {
ccm->noncelen = 15 - ccm->L;
}
/* form B_0 == flags | Nonce N | l(m) */
x = 0;
ccm->PAD[x++] = (unsigned char)(((ccm->aadlen > 0) ? (1<<6) : 0) |
(((ccm->taglen - 2)>>1)<<3) |
(ccm->L-1));
/* nonce */
for (y = 0; y < (16 - (ccm->L + 1)); y++) {
ccm->PAD[x++] = nonce[y];
}
/* store len */
len = ccm->ptlen;
/* shift len so the upper bytes of len are the contents of the length */
for (y = ccm->L; y < 4; y++) {
len <<= 8;
}
/* store l(m) (only store 32-bits) */
for (y = 0; ccm->L > 4 && (ccm->L-y)>4; y++) {
ccm->PAD[x++] = 0;
}
for (; y < ccm->L; y++) {
ccm->PAD[x++] = (unsigned char)((len >> 24) & 255);
len <<= 8;
}
/* encrypt PAD */
if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) {
return err;
}
/* handle header */
ccm->x = 0;
if (ccm->aadlen > 0) {
/* store length */
if (ccm->aadlen < ((1UL<<16) - (1UL<<8))) {
ccm->PAD[ccm->x++] ^= (ccm->aadlen>>8) & 255;
ccm->PAD[ccm->x++] ^= ccm->aadlen & 255;
} else {
ccm->PAD[ccm->x++] ^= 0xFF;
ccm->PAD[ccm->x++] ^= 0xFE;
ccm->PAD[ccm->x++] ^= (ccm->aadlen>>24) & 255;
ccm->PAD[ccm->x++] ^= (ccm->aadlen>>16) & 255;
ccm->PAD[ccm->x++] ^= (ccm->aadlen>>8) & 255;
ccm->PAD[ccm->x++] ^= ccm->aadlen & 255;
}
}
/* setup the ctr counter */
x = 0;
/* flags */
ccm->ctr[x++] = (unsigned char)ccm->L-1;
/* nonce */
for (y = 0; y < (16 - (ccm->L+1)); ++y) {
ccm->ctr[x++] = nonce[y];
}
/* offset */
while (x < 16) {
ccm->ctr[x++] = 0;
}
ccm->CTRlen = 16;
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,65 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_CCM_MODE
/**
Terminate a CCM stream
@param ccm The CCM state
@param tag [out] The destination for the MAC tag
@param taglen [in/out] The length of the MAC tag
@return CRYPT_OK on success
*/
int ccm_done(ccm_state *ccm,
unsigned char *tag, unsigned long *taglen)
{
unsigned long x, y;
int err;
LTC_ARGCHK(ccm != NULL);
/* Check all data have been processed */
if (ccm->ptlen != ccm->current_ptlen) {
return CRYPT_ERROR;
}
LTC_ARGCHK(tag != NULL);
LTC_ARGCHK(taglen != NULL);
if (ccm->x != 0) {
if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) {
return err;
}
}
/* setup CTR for the TAG (zero the count) */
for (y = 15; y > 15 - ccm->L; y--) {
ccm->ctr[y] = 0x00;
}
if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->ctr, ccm->CTRPAD, &ccm->K)) != CRYPT_OK) {
return err;
}
cipher_descriptor[ccm->cipher].done(&ccm->K);
/* store the TAG */
for (x = 0; x < 16 && x < *taglen; x++) {
tag[x] = ccm->PAD[x] ^ ccm->CTRPAD[x];
}
*taglen = x;
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,81 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_CCM_MODE
/**
Initialize a CCM state
@param ccm The CCM state to initialize
@param cipher The index of the cipher to use
@param key The secret key
@param keylen The length of the secret key
@param ptlen The length of the plain/cipher text that will be processed
@param taglen The max length of the MAC tag
@param aadlen The length of the AAD
@return CRYPT_OK on success
*/
int ccm_init(ccm_state *ccm, int cipher,
const unsigned char *key, int keylen, int ptlen, int taglen, int aadlen)
{
int err;
LTC_ARGCHK(ccm != NULL);
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(taglen != 0);
XMEMSET(ccm, 0, sizeof(ccm_state));
/* check cipher input */
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
if (cipher_descriptor[cipher].block_length != 16) {
return CRYPT_INVALID_CIPHER;
}
/* make sure the taglen is even and <= 16 */
ccm->taglen = taglen;
ccm->taglen &= ~1;
if (ccm->taglen > 16) {
ccm->taglen = 16;
}
/* can't use < 4 */
if (ccm->taglen < 4) {
return CRYPT_INVALID_ARG;
}
/* schedule key */
if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ccm->K)) != CRYPT_OK) {
return err;
}
ccm->cipher = cipher;
/* let's get the L value */
ccm->ptlen = ptlen;
ccm->L = 0;
while (ptlen) {
++ccm->L;
ptlen >>= 8;
}
if (ccm->L <= 1) {
ccm->L = 2;
}
ccm->aadlen = aadlen;
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,407 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file ccm_memory.c
CCM support, process a block of memory, Tom St Denis
*/
#ifdef LTC_CCM_MODE
/**
CCM encrypt/decrypt and produce an authentication tag
*1 'pt', 'ct' and 'tag' can both be 'in' or 'out', depending on 'direction'
@param cipher The index of the cipher desired
@param key The secret key to use
@param keylen The length of the secret key (octets)
@param uskey A previously scheduled key [optional can be NULL]
@param nonce The session nonce [use once]
@param noncelen The length of the nonce
@param header The header for the session
@param headerlen The length of the header (octets)
@param pt [*1] The plaintext
@param ptlen The length of the plaintext (octets)
@param ct [*1] The ciphertext
@param tag [*1] The destination tag
@param taglen The max size and resulting size of the authentication tag
@param direction Encrypt or Decrypt direction (0 or 1)
@return CRYPT_OK if successful
*/
int ccm_memory(int cipher,
const unsigned char *key, unsigned long keylen,
symmetric_key *uskey,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen,
int direction)
{
unsigned char PAD[16], ctr[16], CTRPAD[16], ptTag[16], b, *pt_real;
unsigned char *pt_work = NULL;
symmetric_key *skey;
int err;
unsigned long len, L, x, y, z, CTRlen;
#ifdef LTC_FAST
LTC_FAST_TYPE fastMask = ~(LTC_FAST_TYPE)0; /* initialize fastMask at all zeroes */
#endif
unsigned char mask = 0xff; /* initialize mask at all zeroes */
if (uskey == NULL) {
LTC_ARGCHK(key != NULL);
}
LTC_ARGCHK(nonce != NULL);
if (headerlen > 0) {
LTC_ARGCHK(header != NULL);
}
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(tag != NULL);
LTC_ARGCHK(taglen != NULL);
pt_real = pt;
#ifdef LTC_FAST
if (16 % sizeof(LTC_FAST_TYPE)) {
return CRYPT_INVALID_ARG;
}
#endif
/* check cipher input */
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
if (cipher_descriptor[cipher].block_length != 16) {
return CRYPT_INVALID_CIPHER;
}
/* make sure the taglen is even and <= 16 */
*taglen &= ~1;
if (*taglen > 16) {
*taglen = 16;
}
/* can't use < 4 */
if (*taglen < 4) {
return CRYPT_INVALID_ARG;
}
/* is there an accelerator? */
if (cipher_descriptor[cipher].accel_ccm_memory != NULL) {
return cipher_descriptor[cipher].accel_ccm_memory(
key, keylen,
uskey,
nonce, noncelen,
header, headerlen,
pt, ptlen,
ct,
tag, taglen,
direction);
}
/* let's get the L value */
len = ptlen;
L = 0;
while (len) {
++L;
len >>= 8;
}
if (L <= 1) {
L = 2;
}
/* increase L to match the nonce len */
noncelen = (noncelen > 13) ? 13 : noncelen;
if ((15 - noncelen) > L) {
L = 15 - noncelen;
}
/* allocate mem for the symmetric key */
if (uskey == NULL) {
skey = XMALLOC(sizeof(*skey));
if (skey == NULL) {
return CRYPT_MEM;
}
/* initialize the cipher */
if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) {
XFREE(skey);
return err;
}
} else {
skey = uskey;
}
/* initialize buffer for pt */
if (direction == CCM_DECRYPT && ptlen > 0) {
pt_work = XMALLOC(ptlen);
if (pt_work == NULL) {
goto error;
}
pt = pt_work;
}
/* form B_0 == flags | Nonce N | l(m) */
x = 0;
PAD[x++] = (unsigned char)(((headerlen > 0) ? (1<<6) : 0) |
(((*taglen - 2)>>1)<<3) |
(L-1));
/* nonce */
for (y = 0; y < (16 - (L + 1)); y++) {
PAD[x++] = nonce[y];
}
/* store len */
len = ptlen;
/* shift len so the upper bytes of len are the contents of the length */
for (y = L; y < 4; y++) {
len <<= 8;
}
/* store l(m) (only store 32-bits) */
for (y = 0; L > 4 && (L-y)>4; y++) {
PAD[x++] = 0;
}
for (; y < L; y++) {
PAD[x++] = (unsigned char)((len >> 24) & 255);
len <<= 8;
}
/* encrypt PAD */
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
goto error;
}
/* handle header */
if (headerlen > 0) {
x = 0;
/* store length */
if (headerlen < ((1UL<<16) - (1UL<<8))) {
PAD[x++] ^= (headerlen>>8) & 255;
PAD[x++] ^= headerlen & 255;
} else {
PAD[x++] ^= 0xFF;
PAD[x++] ^= 0xFE;
PAD[x++] ^= (headerlen>>24) & 255;
PAD[x++] ^= (headerlen>>16) & 255;
PAD[x++] ^= (headerlen>>8) & 255;
PAD[x++] ^= headerlen & 255;
}
/* now add the data */
for (y = 0; y < headerlen; y++) {
if (x == 16) {
/* full block so let's encrypt it */
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
goto error;
}
x = 0;
}
PAD[x++] ^= header[y];
}
/* remainder */
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
goto error;
}
}
/* setup the ctr counter */
x = 0;
/* flags */
ctr[x++] = (unsigned char)L-1;
/* nonce */
for (y = 0; y < (16 - (L+1)); ++y) {
ctr[x++] = nonce[y];
}
/* offset */
while (x < 16) {
ctr[x++] = 0;
}
x = 0;
CTRlen = 16;
/* now handle the PT */
if (ptlen > 0) {
y = 0;
#ifdef LTC_FAST
if (ptlen & ~15) {
if (direction == CCM_ENCRYPT) {
for (; y < (ptlen & ~15); y += 16) {
/* increment the ctr? */
for (z = 15; z > 15-L; z--) {
ctr[z] = (ctr[z] + 1) & 255;
if (ctr[z]) break;
}
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
goto error;
}
/* xor the PT against the pad first */
for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST(&PAD[z])) ^= *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z]));
*(LTC_FAST_TYPE_PTR_CAST(&ct[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])) ^ *(LTC_FAST_TYPE_PTR_CAST(&CTRPAD[z]));
}
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
goto error;
}
}
} else { /* direction == CCM_DECRYPT */
for (; y < (ptlen & ~15); y += 16) {
/* increment the ctr? */
for (z = 15; z > 15-L; z--) {
ctr[z] = (ctr[z] + 1) & 255;
if (ctr[z]) break;
}
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
goto error;
}
/* xor the PT against the pad last */
for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&ct[y+z])) ^ *(LTC_FAST_TYPE_PTR_CAST(&CTRPAD[z]));
*(LTC_FAST_TYPE_PTR_CAST(&PAD[z])) ^= *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z]));
}
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
goto error;
}
}
}
}
#endif
for (; y < ptlen; y++) {
/* increment the ctr? */
if (CTRlen == 16) {
for (z = 15; z > 15-L; z--) {
ctr[z] = (ctr[z] + 1) & 255;
if (ctr[z]) break;
}
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
goto error;
}
CTRlen = 0;
}
/* if we encrypt we add the bytes to the MAC first */
if (direction == CCM_ENCRYPT) {
b = pt[y];
ct[y] = b ^ CTRPAD[CTRlen++];
} else {
b = ct[y] ^ CTRPAD[CTRlen++];
pt[y] = b;
}
if (x == 16) {
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
goto error;
}
x = 0;
}
PAD[x++] ^= b;
}
if (x != 0) {
if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) {
goto error;
}
}
}
/* setup CTR for the TAG (zero the count) */
for (y = 15; y > 15 - L; y--) {
ctr[y] = 0x00;
}
if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) {
goto error;
}
if (skey != uskey) {
cipher_descriptor[cipher].done(skey);
#ifdef LTC_CLEAN_STACK
zeromem(skey, sizeof(*skey));
#endif
}
if (direction == CCM_ENCRYPT) {
/* store the TAG */
for (x = 0; x < 16 && x < *taglen; x++) {
tag[x] = PAD[x] ^ CTRPAD[x];
}
*taglen = x;
} else { /* direction == CCM_DECRYPT */
/* decrypt the tag */
for (x = 0; x < 16 && x < *taglen; x++) {
ptTag[x] = tag[x] ^ CTRPAD[x];
}
*taglen = x;
/* check validity of the decrypted tag against the computed PAD (in constant time) */
/* HACK: the boolean value of XMEM_NEQ becomes either 0 (CRYPT_OK) or 1 (CRYPT_ERR).
* there should be a better way of setting the correct error code in constant
* time.
*/
err = XMEM_NEQ(ptTag, PAD, *taglen);
/* Zero the plaintext if the tag was invalid (in constant time) */
if (ptlen > 0) {
y = 0;
mask *= 1 - err; /* mask = ( err ? 0 : 0xff ) */
#ifdef LTC_FAST
fastMask *= 1 - err;
if (ptlen & ~15) {
for (; y < (ptlen & ~15); y += 16) {
for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST(&pt_real[y+z])) = *(LTC_FAST_TYPE_PTR_CAST(&pt[y+z])) & fastMask;
}
}
}
#endif
for (; y < ptlen; y++) {
pt_real[y] = pt[y] & mask;
}
}
}
#ifdef LTC_CLEAN_STACK
#ifdef LTC_FAST
fastMask = 0;
#endif
mask = 0;
zeromem(PAD, sizeof(PAD));
zeromem(CTRPAD, sizeof(CTRPAD));
if (pt_work != NULL) {
zeromem(pt_work, ptlen);
}
#endif
error:
if (pt_work) {
XFREE(pt_work);
}
if (skey != uskey) {
XFREE(skey);
}
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,88 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_CCM_MODE
/**
Process plaintext/ciphertext through CCM
@param ccm The CCM state
@param pt The plaintext
@param ptlen The plaintext length (ciphertext length is the same)
@param ct The ciphertext
@param direction Encrypt or Decrypt mode (CCM_ENCRYPT or CCM_DECRYPT)
@return CRYPT_OK on success
*/
int ccm_process(ccm_state *ccm,
unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
int direction)
{
unsigned char z, b;
unsigned long y;
int err;
LTC_ARGCHK(ccm != NULL);
/* Check aad has been correctly added */
if (ccm->aadlen != ccm->current_aadlen) {
return CRYPT_ERROR;
}
/* Check we do not process too much data */
if (ccm->ptlen < ccm->current_ptlen + ptlen) {
return CRYPT_ERROR;
}
ccm->current_ptlen += ptlen;
/* now handle the PT */
if (ptlen > 0) {
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
for (y = 0; y < ptlen; y++) {
/* increment the ctr? */
if (ccm->CTRlen == 16) {
for (z = 15; z > 15-ccm->L; z--) {
ccm->ctr[z] = (ccm->ctr[z] + 1) & 255;
if (ccm->ctr[z]) break;
}
if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->ctr, ccm->CTRPAD, &ccm->K)) != CRYPT_OK) {
return err;
}
ccm->CTRlen = 0;
}
/* if we encrypt we add the bytes to the MAC first */
if (direction == CCM_ENCRYPT) {
b = pt[y];
ct[y] = b ^ ccm->CTRPAD[ccm->CTRlen++];
} else {
b = ct[y] ^ ccm->CTRPAD[ccm->CTRlen++];
pt[y] = b;
}
if (ccm->x == 16) {
if ((err = cipher_descriptor[ccm->cipher].ecb_encrypt(ccm->PAD, ccm->PAD, &ccm->K)) != CRYPT_OK) {
return err;
}
ccm->x = 0;
}
ccm->PAD[ccm->x++] ^= b;
}
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,35 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_CCM_MODE
/**
Reset a CCM state to as if you just called ccm_init(). This saves the initialization time.
@param ccm The CCM state to reset
@return CRYPT_OK on success
*/
int ccm_reset(ccm_state *ccm)
{
LTC_ARGCHK(ccm != NULL);
zeromem(ccm->PAD, sizeof(ccm->PAD));
zeromem(ccm->ctr, sizeof(ccm->ctr));
zeromem(ccm->CTRPAD, sizeof(ccm->CTRPAD));
ccm->CTRlen = 0;
ccm->current_ptlen = 0;
ccm->current_aadlen = 0;
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,257 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file ccm_test.c
CCM support, process a block of memory, Tom St Denis
*/
#ifdef LTC_CCM_MODE
int ccm_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
unsigned char key[16];
unsigned char nonce[16];
int noncelen;
unsigned char header[64];
int headerlen;
unsigned char pt[64];
int ptlen;
unsigned char ct[64];
unsigned char tag[16];
unsigned long taglen;
} tests[] = {
/* 13 byte nonce, 8 byte auth, 23 byte pt */
{
{ 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF },
{ 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0,
0xA1, 0xA2, 0xA3, 0xA4, 0xA5 },
13,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
8,
{ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E },
23,
{ 0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2,
0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80,
0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84 },
{ 0x17, 0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0 },
8
},
/* 13 byte nonce, 12 byte header, 19 byte pt */
{
{ 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF },
{ 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x03, 0xA0,
0xA1, 0xA2, 0xA3, 0xA4, 0xA5 },
13,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B },
12,
{ 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13,
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
0x1C, 0x1D, 0x1E },
19,
{ 0xA2, 0x8C, 0x68, 0x65, 0x93, 0x9A, 0x9A, 0x79,
0xFA, 0xAA, 0x5C, 0x4C, 0x2A, 0x9D, 0x4A, 0x91,
0xCD, 0xAC, 0x8C },
{ 0x96, 0xC8, 0x61, 0xB9, 0xC9, 0xE6, 0x1E, 0xF1 },
8
},
/* supplied by Brian Gladman */
{
{ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f },
{ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 },
7,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 },
8,
{ 0x20, 0x21, 0x22, 0x23 },
4,
{ 0x71, 0x62, 0x01, 0x5b },
{ 0x4d, 0xac, 0x25, 0x5d },
4
},
{
{ 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85,
0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f },
{ 0x00, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xb5,
0x03, 0x97, 0x76, 0xe7, 0x0c },
13,
{ 0x08, 0x40, 0x0f, 0xd2, 0xe1, 0x28, 0xa5, 0x7c,
0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xab, 0xae,
0xa5, 0xb8, 0xfc, 0xba, 0x00, 0x00 },
22,
{ 0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae,
0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb,
0x7e, 0x78, 0xa0, 0x50 },
20,
{ 0xf3, 0xd0, 0xa2, 0xfe, 0x9a, 0x3d, 0xbf, 0x23,
0x42, 0xa6, 0x43, 0xe4, 0x32, 0x46, 0xe8, 0x0c,
0x3c, 0x04, 0xd0, 0x19 },
{ 0x78, 0x45, 0xce, 0x0b, 0x16, 0xf9, 0x76, 0x23 },
8
},
};
unsigned long taglen, x, y;
unsigned char buf[64], buf2[64], tag[16], tag2[16], tag3[16], zero[64];
int err, idx;
symmetric_key skey;
ccm_state ccm;
zeromem(zero, 64);
idx = find_cipher("aes");
if (idx == -1) {
idx = find_cipher("rijndael");
if (idx == -1) {
return CRYPT_NOP;
}
}
for (x = 0; x < (sizeof(tests)/sizeof(tests[0])); x++) {
for (y = 0; y < 2; y++) {
taglen = tests[x].taglen;
if (y == 0) {
if ((err = cipher_descriptor[idx].setup(tests[x].key, 16, 0, &skey)) != CRYPT_OK) {
return err;
}
if ((err = ccm_memory(idx,
tests[x].key, 16,
&skey,
tests[x].nonce, tests[x].noncelen,
tests[x].header, tests[x].headerlen,
(unsigned char*)tests[x].pt, tests[x].ptlen,
buf,
tag, &taglen, 0)) != CRYPT_OK) {
return err;
}
/* run a second time to make sure skey is not touched */
if ((err = ccm_memory(idx,
tests[x].key, 16,
&skey,
tests[x].nonce, tests[x].noncelen,
tests[x].header, tests[x].headerlen,
(unsigned char*)tests[x].pt, tests[x].ptlen,
buf,
tag, &taglen, 0)) != CRYPT_OK) {
return err;
}
} else {
if ((err = ccm_init(&ccm, idx, tests[x].key, 16, tests[x].ptlen, tests[x].taglen, tests[x].headerlen)) != CRYPT_OK) {
return err;
}
if ((err = ccm_add_nonce(&ccm, tests[x].nonce, tests[x].noncelen)) != CRYPT_OK) {
return err;
}
if ((err = ccm_add_aad(&ccm, tests[x].header, tests[x].headerlen)) != CRYPT_OK) {
return err;
}
if ((err = ccm_process(&ccm, (unsigned char*)tests[x].pt, tests[x].ptlen, buf, CCM_ENCRYPT)) != CRYPT_OK) {
return err;
}
if ((err = ccm_done(&ccm, tag, &taglen)) != CRYPT_OK) {
return err;
}
}
if (compare_testvector(buf, tests[x].ptlen, tests[x].ct, tests[x].ptlen, "CCM encrypt data", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
if (compare_testvector(tag, taglen, tests[x].tag, tests[x].taglen, "CCM encrypt tag", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
if (y == 0) {
XMEMCPY(tag3, tests[x].tag, tests[x].taglen);
taglen = tests[x].taglen;
if ((err = ccm_memory(idx,
tests[x].key, 16,
NULL,
tests[x].nonce, tests[x].noncelen,
tests[x].header, tests[x].headerlen,
buf2, tests[x].ptlen,
buf,
tag3, &taglen, 1 )) != CRYPT_OK) {
return err;
}
} else {
if ((err = ccm_init(&ccm, idx, tests[x].key, 16, tests[x].ptlen, tests[x].taglen, tests[x].headerlen)) != CRYPT_OK) {
return err;
}
if ((err = ccm_add_nonce(&ccm, tests[x].nonce, tests[x].noncelen)) != CRYPT_OK) {
return err;
}
if ((err = ccm_add_aad(&ccm, tests[x].header, tests[x].headerlen)) != CRYPT_OK) {
return err;
}
if ((err = ccm_process(&ccm, buf2, tests[x].ptlen, buf, CCM_DECRYPT)) != CRYPT_OK) {
return err;
}
if ((err = ccm_done(&ccm, tag2, &taglen)) != CRYPT_OK) {
return err;
}
}
if (compare_testvector(buf2, tests[x].ptlen, tests[x].pt, tests[x].ptlen, "CCM decrypt data", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
if (y == 0) {
/* check if decryption with the wrong tag does not reveal the plaintext */
XMEMCPY(tag3, tests[x].tag, tests[x].taglen);
tag3[0] ^= 0xff; /* set the tag to the wrong value */
taglen = tests[x].taglen;
if ((err = ccm_memory(idx,
tests[x].key, 16,
NULL,
tests[x].nonce, tests[x].noncelen,
tests[x].header, tests[x].headerlen,
buf2, tests[x].ptlen,
buf,
tag3, &taglen, 1 )) != CRYPT_ERROR) {
return CRYPT_FAIL_TESTVECTOR;
}
if (compare_testvector(buf2, tests[x].ptlen, zero, tests[x].ptlen, "CCM decrypt wrong tag", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
} else {
if (compare_testvector(tag2, taglen, tests[x].tag, tests[x].taglen, "CCM decrypt tag", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
if (y == 0) {
cipher_descriptor[idx].done(&skey);
}
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,38 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_CHACHA20POLY1305_MODE
/**
Add AAD to the ChaCha20Poly1305 state
@param st The ChaCha20Poly1305 state
@param in The additional authentication data to add to the ChaCha20Poly1305 state
@param inlen The length of the ChaCha20Poly1305 data.
@return CRYPT_OK on success
*/
int chacha20poly1305_add_aad(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen)
{
int err;
if (inlen == 0) return CRYPT_OK; /* nothing to do */
LTC_ARGCHK(st != NULL);
if (st->aadflg == 0) return CRYPT_ERROR;
if ((err = poly1305_process(&st->poly, in, inlen)) != CRYPT_OK) return err;
st->aadlen += (ulong64)inlen;
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,49 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_CHACHA20POLY1305_MODE
/**
Decrypt bytes of ciphertext with ChaCha20Poly1305
@param st The ChaCha20Poly1305 state
@param in The ciphertext
@param inlen The length of the input (octets)
@param out [out] The plaintext (length inlen)
@return CRYPT_OK if successful
*/
int chacha20poly1305_decrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
{
unsigned char padzero[16] = { 0 };
unsigned long padlen;
int err;
if (inlen == 0) return CRYPT_OK; /* nothing to do */
LTC_ARGCHK(st != NULL);
if (st->aadflg) {
padlen = 16 - (unsigned long)(st->aadlen % 16);
if (padlen < 16) {
if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err;
}
st->aadflg = 0; /* no more AAD */
}
if (st->aadflg) st->aadflg = 0; /* no more AAD */
if ((err = poly1305_process(&st->poly, in, inlen)) != CRYPT_OK) return err;
if ((err = chacha_crypt(&st->chacha, in, inlen, out)) != CRYPT_OK) return err;
st->ctlen += (ulong64)inlen;
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,46 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_CHACHA20POLY1305_MODE
/**
Terminate a ChaCha20Poly1305 stream
@param st The ChaCha20Poly1305 state
@param tag [out] The destination for the MAC tag
@param taglen [in/out] The length of the MAC tag
@return CRYPT_OK on success
*/
int chacha20poly1305_done(chacha20poly1305_state *st, unsigned char *tag, unsigned long *taglen)
{
unsigned char padzero[16] = { 0 };
unsigned long padlen;
unsigned char buf[16];
int err;
LTC_ARGCHK(st != NULL);
padlen = 16 - (unsigned long)(st->ctlen % 16);
if (padlen < 16) {
if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err;
}
STORE64L(st->aadlen, buf);
STORE64L(st->ctlen, buf + 8);
if ((err = poly1305_process(&st->poly, buf, 16)) != CRYPT_OK) return err;
if ((err = poly1305_done(&st->poly, tag, taglen)) != CRYPT_OK) return err;
if ((err = chacha_done(&st->chacha)) != CRYPT_OK) return err;
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,48 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_CHACHA20POLY1305_MODE
/**
Encrypt bytes of ciphertext with ChaCha20Poly1305
@param st The ChaCha20Poly1305 state
@param in The plaintext
@param inlen The length of the input (octets)
@param out [out] The ciphertext (length inlen)
@return CRYPT_OK if successful
*/
int chacha20poly1305_encrypt(chacha20poly1305_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out)
{
unsigned char padzero[16] = { 0 };
unsigned long padlen;
int err;
if (inlen == 0) return CRYPT_OK; /* nothing to do */
LTC_ARGCHK(st != NULL);
if ((err = chacha_crypt(&st->chacha, in, inlen, out)) != CRYPT_OK) return err;
if (st->aadflg) {
padlen = 16 - (unsigned long)(st->aadlen % 16);
if (padlen < 16) {
if ((err = poly1305_process(&st->poly, padzero, padlen)) != CRYPT_OK) return err;
}
st->aadflg = 0; /* no more AAD */
}
if ((err = poly1305_process(&st->poly, out, inlen)) != CRYPT_OK) return err;
st->ctlen += (ulong64)inlen;
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,30 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_CHACHA20POLY1305_MODE
/**
Initialize an ChaCha20Poly1305 context (only the key)
@param st [out] The destination of the ChaCha20Poly1305 state
@param key The secret key
@param keylen The length of the secret key (octets)
@return CRYPT_OK if successful
*/
int chacha20poly1305_init(chacha20poly1305_state *st, const unsigned char *key, unsigned long keylen)
{
return chacha_setup(&st->chacha, key, keylen, 20);
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,74 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_CHACHA20POLY1305_MODE
/**
Process an entire GCM packet in one call.
@param key The secret key
@param keylen The length of the secret key
@param iv The initialization vector
@param ivlen The length of the initialization vector
@param aad The additional authentication data (header)
@param aadlen The length of the aad
@param in The plaintext
@param inlen The length of the plaintext (ciphertext length is the same)
@param out The ciphertext
@param tag [out] The MAC tag
@param taglen [in/out] The MAC tag length
@param direction Encrypt or Decrypt mode (CHACHA20POLY1305_ENCRYPT or CHACHA20POLY1305_DECRYPT)
@return CRYPT_OK on success
*/
int chacha20poly1305_memory(const unsigned char *key, unsigned long keylen,
const unsigned char *iv, unsigned long ivlen,
const unsigned char *aad, unsigned long aadlen,
const unsigned char *in, unsigned long inlen,
unsigned char *out,
unsigned char *tag, unsigned long *taglen,
int direction)
{
chacha20poly1305_state st;
int err;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(iv != NULL);
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(tag != NULL);
if ((err = chacha20poly1305_init(&st, key, keylen)) != CRYPT_OK) { goto LBL_ERR; }
if ((err = chacha20poly1305_setiv(&st, iv, ivlen)) != CRYPT_OK) { goto LBL_ERR; }
if (aad && aadlen > 0) {
if ((err = chacha20poly1305_add_aad(&st, aad, aadlen)) != CRYPT_OK) { goto LBL_ERR; }
}
if (direction == CHACHA20POLY1305_ENCRYPT) {
if ((err = chacha20poly1305_encrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; }
}
else if (direction == CHACHA20POLY1305_DECRYPT) {
if ((err = chacha20poly1305_decrypt(&st, in, inlen, out)) != CRYPT_OK) { goto LBL_ERR; }
}
else {
err = CRYPT_INVALID_ARG;
goto LBL_ERR;
}
err = chacha20poly1305_done(&st, tag, taglen);
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(&st, sizeof(chacha20poly1305_state));
#endif
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,68 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_CHACHA20POLY1305_MODE
/**
Set IV + counter data to the ChaCha20Poly1305 state and reset the context
@param st The ChaCha20Poly1305 state
@param iv The IV data to add
@param ivlen The length of the IV (must be 12 or 8)
@return CRYPT_OK on success
*/
int chacha20poly1305_setiv(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen)
{
chacha_state tmp_st;
int i, err;
unsigned char polykey[32];
LTC_ARGCHK(st != NULL);
LTC_ARGCHK(iv != NULL);
LTC_ARGCHK(ivlen == 12 || ivlen == 8);
/* set IV for chacha20 */
if (ivlen == 12) {
/* IV 96bit */
if ((err = chacha_ivctr32(&st->chacha, iv, ivlen, 1)) != CRYPT_OK) return err;
}
else {
/* IV 64bit */
if ((err = chacha_ivctr64(&st->chacha, iv, ivlen, 1)) != CRYPT_OK) return err;
}
/* copy chacha20 key to temporary state */
for(i = 0; i < 12; i++) tmp_st.input[i] = st->chacha.input[i];
tmp_st.rounds = 20;
/* set IV */
if (ivlen == 12) {
/* IV 32bit */
if ((err = chacha_ivctr32(&tmp_st, iv, ivlen, 0)) != CRYPT_OK) return err;
}
else {
/* IV 64bit */
if ((err = chacha_ivctr64(&tmp_st, iv, ivlen, 0)) != CRYPT_OK) return err;
}
/* (re)generate new poly1305 key */
if ((err = chacha_keystream(&tmp_st, polykey, 32)) != CRYPT_OK) return err;
/* (re)initialise poly1305 */
if ((err = poly1305_init(&st->poly, polykey, 32)) != CRYPT_OK) return err;
st->ctlen = 0;
st->aadlen = 0;
st->aadflg = 1;
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,40 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_CHACHA20POLY1305_MODE
/**
Set IV + counter data (with RFC7905-magic) to the ChaCha20Poly1305 state and reset the context
@param st The ChaCha20Poly1305 state
@param iv The IV data to add
@param ivlen The length of the IV (must be 12 or 8)
@param sequence_number 64bit sequence number which is incorporated into IV as described in RFC7905
@return CRYPT_OK on success
*/
int chacha20poly1305_setiv_rfc7905(chacha20poly1305_state *st, const unsigned char *iv, unsigned long ivlen, ulong64 sequence_number)
{
int i;
unsigned char combined_iv[12] = { 0 };
LTC_ARGCHK(st != NULL);
LTC_ARGCHK(iv != NULL);
LTC_ARGCHK(ivlen == 12);
STORE64L(sequence_number, combined_iv + 4);
for (i = 0; i < 12; i++) combined_iv[i] = iv[i] ^ combined_iv[i];
return chacha20poly1305_setiv(st, combined_iv, 12);
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,134 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_CHACHA20POLY1305_MODE
int chacha20poly1305_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
chacha20poly1305_state st1, st2;
unsigned char k[] = { 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f };
unsigned char i12[] = { 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 };
unsigned char i8[] = { 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43 };
unsigned char aad[] = { 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 };
unsigned char enc[] = { 0xD3, 0x1A, 0x8D, 0x34, 0x64, 0x8E, 0x60, 0xDB, 0x7B, 0x86, 0xAF, 0xBC, 0x53, 0xEF, 0x7E, 0xC2,
0xA4, 0xAD, 0xED, 0x51, 0x29, 0x6E, 0x08, 0xFE, 0xA9, 0xE2, 0xB5, 0xA7, 0x36, 0xEE, 0x62, 0xD6,
0x3D, 0xBE, 0xA4, 0x5E, 0x8C, 0xA9, 0x67, 0x12, 0x82, 0xFA, 0xFB, 0x69, 0xDA, 0x92, 0x72, 0x8B,
0x1A, 0x71, 0xDE, 0x0A, 0x9E, 0x06, 0x0B, 0x29, 0x05, 0xD6, 0xA5, 0xB6, 0x7E, 0xCD, 0x3B, 0x36,
0x92, 0xDD, 0xBD, 0x7F, 0x2D, 0x77, 0x8B, 0x8C, 0x98, 0x03, 0xAE, 0xE3, 0x28, 0x09, 0x1B, 0x58,
0xFA, 0xB3, 0x24, 0xE4, 0xFA, 0xD6, 0x75, 0x94, 0x55, 0x85, 0x80, 0x8B, 0x48, 0x31, 0xD7, 0xBC,
0x3F, 0xF4, 0xDE, 0xF0, 0x8E, 0x4B, 0x7A, 0x9D, 0xE5, 0x76, 0xD2, 0x65, 0x86, 0xCE, 0xC6, 0x4B,
0x61, 0x16 };
unsigned char tag[] = { 0x1A, 0xE1, 0x0B, 0x59, 0x4F, 0x09, 0xE2, 0x6A, 0x7E, 0x90, 0x2E, 0xCB, 0xD0, 0x60, 0x06, 0x91 };
char m[] = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it.";
unsigned long mlen = strlen(m);
unsigned long len;
unsigned char rfc7905_pt[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
unsigned char rfc7905_enc[] = { 0xE4, 0x62, 0x85, 0xB4, 0x29, 0x95, 0x34, 0x96, 0xAB, 0xFB, 0x67, 0xCD, 0xAE, 0xAC, 0x94, 0x1E };
unsigned char rfc7905_tag[] = { 0x16, 0x2C, 0x92, 0x48, 0x2A, 0xDB, 0xD3, 0x5D, 0x48, 0xBE, 0xC6, 0xFF, 0x10, 0x9C, 0xBA, 0xE4 };
unsigned char ct[1000], pt[1000], emac[16], dmac[16];
int err;
/* encrypt IV 96bit */
if ((err = chacha20poly1305_init(&st1, k, sizeof(k))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_setiv(&st1, i12, sizeof(i12))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_add_aad(&st1, aad, sizeof(aad))) != CRYPT_OK) return err;
/* encrypt piece by piece */
if ((err = chacha20poly1305_encrypt(&st1, (unsigned char *)m, 25, ct)) != CRYPT_OK) return err;
if ((err = chacha20poly1305_encrypt(&st1, (unsigned char *)m + 25, 10, ct + 25)) != CRYPT_OK) return err;
if ((err = chacha20poly1305_encrypt(&st1, (unsigned char *)m + 35, 35, ct + 35)) != CRYPT_OK) return err;
if ((err = chacha20poly1305_encrypt(&st1, (unsigned char *)m + 70, 5, ct + 70)) != CRYPT_OK) return err;
if ((err = chacha20poly1305_encrypt(&st1, (unsigned char *)m + 75, 5, ct + 75)) != CRYPT_OK) return err;
if ((err = chacha20poly1305_encrypt(&st1, (unsigned char *)m + 80, mlen - 80, ct + 80)) != CRYPT_OK) return err;
len = sizeof(emac);
if ((err = chacha20poly1305_done(&st1, emac, &len)) != CRYPT_OK) return err;
if (compare_testvector(ct, mlen, enc, sizeof(enc), "ENC-CT", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
if (compare_testvector(emac, len, tag, sizeof(tag), "ENC-TAG", 2) != 0) return CRYPT_FAIL_TESTVECTOR;
/* decrypt IV 96bit */
if ((err = chacha20poly1305_init(&st2, k, sizeof(k))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_setiv(&st2, i12, sizeof(i12))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_add_aad(&st2, aad, sizeof(aad))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_decrypt(&st2, ct, 21, pt)) != CRYPT_OK) return err;
if ((err = chacha20poly1305_decrypt(&st2, ct + 21, mlen - 21, pt + 21)) != CRYPT_OK) return err;
len = sizeof(dmac);
if ((err = chacha20poly1305_done(&st2, dmac, &len)) != CRYPT_OK) return err;
if (compare_testvector(pt, mlen, m, mlen, "DEC-PT", 3) != 0) return CRYPT_FAIL_TESTVECTOR;
if (compare_testvector(dmac, len, tag, sizeof(tag), "DEC-TAG", 4) != 0) return CRYPT_FAIL_TESTVECTOR;
/* chacha20poly1305_memory - encrypt */
len = sizeof(emac);
if ((err = chacha20poly1305_memory(k, sizeof(k), i12, sizeof(i12), aad, sizeof(aad), (unsigned char *)m,
mlen, ct, emac, &len, CHACHA20POLY1305_ENCRYPT)) != CRYPT_OK) return err;
if (compare_testvector(ct, mlen, enc, sizeof(enc), "ENC-CT2", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
if (compare_testvector(emac, len, tag, sizeof(tag), "ENC-TAG2", 2) != 0) return CRYPT_FAIL_TESTVECTOR;
/* chacha20poly1305_memory - decrypt */
len = sizeof(dmac);
if ((err = chacha20poly1305_memory(k, sizeof(k), i12, sizeof(i12), aad, sizeof(aad),
ct, mlen, pt, dmac, &len, CHACHA20POLY1305_DECRYPT)) != CRYPT_OK) return err;
if (compare_testvector(pt, mlen, m, mlen, "DEC-PT2", 3) != 0) return CRYPT_FAIL_TESTVECTOR;
if (compare_testvector(dmac, len, tag, sizeof(tag), "DEC-TAG2", 4) != 0) return CRYPT_FAIL_TESTVECTOR;
/* encrypt - rfc7905 */
if ((err = chacha20poly1305_init(&st1, k, sizeof(k))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_setiv_rfc7905(&st1, i12, sizeof(i12), CONST64(0x1122334455667788))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_add_aad(&st1, aad, sizeof(aad))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_encrypt(&st1, rfc7905_pt, 16, ct)) != CRYPT_OK) return err;
len = sizeof(emac);
if ((err = chacha20poly1305_done(&st1, emac, &len)) != CRYPT_OK) return err;
if (compare_testvector(ct, 16, rfc7905_enc, 16, "ENC-CT3", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
if (compare_testvector(emac, len, rfc7905_tag, 16, "ENC-TAG3", 2) != 0) return CRYPT_FAIL_TESTVECTOR;
/* decrypt - rfc7905 */
if ((err = chacha20poly1305_init(&st1, k, sizeof(k))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_setiv_rfc7905(&st1, i12, sizeof(i12), CONST64(0x1122334455667788))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_add_aad(&st1, aad, sizeof(aad))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_decrypt(&st1, ct, 16, pt)) != CRYPT_OK) return err;
len = sizeof(dmac);
if ((err = chacha20poly1305_done(&st1, dmac, &len)) != CRYPT_OK) return err;
if (compare_testvector(pt, 16, rfc7905_pt, 16, "DEC-CT3", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
if (compare_testvector(dmac, len, rfc7905_tag, 16, "DEC-TAG3", 2) != 0) return CRYPT_FAIL_TESTVECTOR;
/* encrypt IV 64bit */
if ((err = chacha20poly1305_init(&st1, k, sizeof(k))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_setiv(&st1, i8, sizeof(i8))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_add_aad(&st1, aad, sizeof(aad))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_encrypt(&st1, (unsigned char *)m, mlen, ct)) != CRYPT_OK) return err;
len = sizeof(emac);
if ((err = chacha20poly1305_done(&st1, emac, &len)) != CRYPT_OK) return err;
/* decrypt IV 64bit */
if ((err = chacha20poly1305_init(&st2, k, sizeof(k))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_setiv(&st2, i8, sizeof(i8))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_add_aad(&st2, aad, sizeof(aad))) != CRYPT_OK) return err;
if ((err = chacha20poly1305_decrypt(&st2, ct, mlen, pt)) != CRYPT_OK) return err;
len = sizeof(dmac);
if ((err = chacha20poly1305_done(&st2, dmac, &len)) != CRYPT_OK) return err;
if (compare_testvector(pt, mlen, m, mlen, "DEC-PT4", 1) != 0) return CRYPT_FAIL_TESTVECTOR;
if (compare_testvector(dmac, len, emac, len, "DEC-TAG4", 2) != 0) return CRYPT_FAIL_TESTVECTOR;
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,36 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file eax_addheader.c
EAX implementation, add meta-data, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_EAX_MODE
/**
add header (metadata) to the stream
@param eax The current EAX state
@param header The header (meta-data) data you wish to add to the state
@param length The length of the header data
@return CRYPT_OK if successful
*/
int eax_addheader(eax_state *eax, const unsigned char *header,
unsigned long length)
{
LTC_ARGCHK(eax != NULL);
LTC_ARGCHK(header != NULL);
return omac_process(&eax->headeromac, header, length);
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,48 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file eax_decrypt.c
EAX implementation, decrypt block, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_EAX_MODE
/**
Decrypt data with the EAX protocol
@param eax The EAX state
@param ct The ciphertext
@param pt [out] The plaintext
@param length The length (octets) of the ciphertext
@return CRYPT_OK if successful
*/
int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt,
unsigned long length)
{
int err;
LTC_ARGCHK(eax != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
/* omac ciphertext */
if ((err = omac_process(&eax->ctomac, ct, length)) != CRYPT_OK) {
return err;
}
/* decrypt */
return ctr_decrypt(ct, pt, length, &eax->ctr);
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,109 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file eax_decrypt_verify_memory.c
EAX implementation, decrypt block of memory, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_EAX_MODE
/**
Decrypt a block of memory and verify the provided MAC tag with EAX
@param cipher The index of the cipher desired
@param key The secret key
@param keylen The length of the key (octets)
@param nonce The nonce data (use once) for the session
@param noncelen The length of the nonce data.
@param header The session header data
@param headerlen The length of the header (octets)
@param ct The ciphertext
@param ctlen The length of the ciphertext (octets)
@param pt [out] The plaintext
@param tag The authentication tag provided by the encoder
@param taglen [in/out] The length of the tag (octets)
@param stat [out] The result of the decryption (1==valid tag, 0==invalid)
@return CRYPT_OK if successful regardless of the resulting tag comparison
*/
int eax_decrypt_verify_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
const unsigned char *ct, unsigned long ctlen,
unsigned char *pt,
unsigned char *tag, unsigned long taglen,
int *stat)
{
int err;
eax_state *eax;
unsigned char *buf;
unsigned long buflen;
LTC_ARGCHK(stat != NULL);
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(tag != NULL);
/* default to zero */
*stat = 0;
/* limit taglen */
taglen = MIN(taglen, MAXBLOCKSIZE);
/* allocate ram */
buf = XMALLOC(taglen);
eax = XMALLOC(sizeof(*eax));
if (eax == NULL || buf == NULL) {
if (eax != NULL) {
XFREE(eax);
}
if (buf != NULL) {
XFREE(buf);
}
return CRYPT_MEM;
}
if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = eax_decrypt(eax, ct, pt, ctlen)) != CRYPT_OK) {
goto LBL_ERR;
}
buflen = taglen;
if ((err = eax_done(eax, buf, &buflen)) != CRYPT_OK) {
goto LBL_ERR;
}
/* compare tags */
if (buflen >= taglen && XMEM_NEQ(buf, tag, taglen) == 0) {
*stat = 1;
}
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(buf, taglen);
zeromem(eax, sizeof(*eax));
#endif
XFREE(eax);
XFREE(buf);
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,92 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file eax_done.c
EAX implementation, terminate session, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_EAX_MODE
/**
Terminate an EAX session and get the tag.
@param eax The EAX state
@param tag [out] The destination of the authentication tag
@param taglen [in/out] The max length and resulting length of the authentication tag
@return CRYPT_OK if successful
*/
int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen)
{
int err;
unsigned char *headermac, *ctmac;
unsigned long x, len;
LTC_ARGCHK(eax != NULL);
LTC_ARGCHK(tag != NULL);
LTC_ARGCHK(taglen != NULL);
/* allocate ram */
headermac = XMALLOC(MAXBLOCKSIZE);
ctmac = XMALLOC(MAXBLOCKSIZE);
if (headermac == NULL || ctmac == NULL) {
if (headermac != NULL) {
XFREE(headermac);
}
if (ctmac != NULL) {
XFREE(ctmac);
}
return CRYPT_MEM;
}
/* finish ctomac */
len = MAXBLOCKSIZE;
if ((err = omac_done(&eax->ctomac, ctmac, &len)) != CRYPT_OK) {
goto LBL_ERR;
}
/* finish headeromac */
/* note we specifically don't reset len so the two lens are minimal */
if ((err = omac_done(&eax->headeromac, headermac, &len)) != CRYPT_OK) {
goto LBL_ERR;
}
/* terminate the CTR chain */
if ((err = ctr_done(&eax->ctr)) != CRYPT_OK) {
goto LBL_ERR;
}
/* compute N xor H xor C */
for (x = 0; x < len && x < *taglen; x++) {
tag[x] = eax->N[x] ^ headermac[x] ^ ctmac[x];
}
*taglen = x;
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(ctmac, MAXBLOCKSIZE);
zeromem(headermac, MAXBLOCKSIZE);
zeromem(eax, sizeof(*eax));
#endif
XFREE(ctmac);
XFREE(headermac);
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,49 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file eax_encrypt.c
EAX implementation, encrypt block by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_EAX_MODE
/**
Encrypt with EAX a block of data.
@param eax The EAX state
@param pt The plaintext to encrypt
@param ct [out] The ciphertext as encrypted
@param length The length of the plaintext (octets)
@return CRYPT_OK if successful
*/
int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct,
unsigned long length)
{
int err;
LTC_ARGCHK(eax != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
/* encrypt */
if ((err = ctr_encrypt(pt, ct, length, &eax->ctr)) != CRYPT_OK) {
return err;
}
/* omac ciphertext */
return omac_process(&eax->ctomac, ct, length);
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,80 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file eax_encrypt_authenticate_memory.c
EAX implementation, encrypt a block of memory, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_EAX_MODE
/**
EAX encrypt and produce an authentication tag
@param cipher The index of the cipher desired
@param key The secret key to use
@param keylen The length of the secret key (octets)
@param nonce The session nonce [use once]
@param noncelen The length of the nonce
@param header The header for the session
@param headerlen The length of the header (octets)
@param pt The plaintext
@param ptlen The length of the plaintext (octets)
@param ct [out] The ciphertext
@param tag [out] The destination tag
@param taglen [in/out] The max size and resulting size of the authentication tag
@return CRYPT_OK if successful
*/
int eax_encrypt_authenticate_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen,
const unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen)
{
int err;
eax_state *eax;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(tag != NULL);
LTC_ARGCHK(taglen != NULL);
eax = XMALLOC(sizeof(*eax));
if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = eax_encrypt(eax, pt, ct, ptlen)) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = eax_done(eax, tag, taglen)) != CRYPT_OK) {
goto LBL_ERR;
}
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(eax, sizeof(*eax));
#endif
XFREE(eax);
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,142 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file eax_init.c
EAX implementation, initialized EAX state, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_EAX_MODE
/**
Initialized an EAX state
@param eax [out] The EAX state to initialize
@param cipher The index of the desired cipher
@param key The secret key
@param keylen The length of the secret key (octets)
@param nonce The use-once nonce for the session
@param noncelen The length of the nonce (octets)
@param header The header for the EAX state
@param headerlen The header length (octets)
@return CRYPT_OK if successful
*/
int eax_init(eax_state *eax, int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *header, unsigned long headerlen)
{
unsigned char *buf;
int err, blklen;
omac_state *omac;
unsigned long len;
LTC_ARGCHK(eax != NULL);
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(nonce != NULL);
if (headerlen > 0) {
LTC_ARGCHK(header != NULL);
}
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
blklen = cipher_descriptor[cipher].block_length;
/* allocate ram */
buf = XMALLOC(MAXBLOCKSIZE);
omac = XMALLOC(sizeof(*omac));
if (buf == NULL || omac == NULL) {
if (buf != NULL) {
XFREE(buf);
}
if (omac != NULL) {
XFREE(omac);
}
return CRYPT_MEM;
}
/* N = LTC_OMAC_0K(nonce) */
zeromem(buf, MAXBLOCKSIZE);
if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) {
goto LBL_ERR;
}
/* omac the [0]_n */
if ((err = omac_process(omac, buf, blklen)) != CRYPT_OK) {
goto LBL_ERR;
}
/* omac the nonce */
if ((err = omac_process(omac, nonce, noncelen)) != CRYPT_OK) {
goto LBL_ERR;
}
/* store result */
len = sizeof(eax->N);
if ((err = omac_done(omac, eax->N, &len)) != CRYPT_OK) {
goto LBL_ERR;
}
/* H = LTC_OMAC_1K(header) */
zeromem(buf, MAXBLOCKSIZE);
buf[blklen - 1] = 1;
if ((err = omac_init(&eax->headeromac, cipher, key, keylen)) != CRYPT_OK) {
goto LBL_ERR;
}
/* omac the [1]_n */
if ((err = omac_process(&eax->headeromac, buf, blklen)) != CRYPT_OK) {
goto LBL_ERR;
}
/* omac the header */
if (headerlen != 0) {
if ((err = omac_process(&eax->headeromac, header, headerlen)) != CRYPT_OK) {
goto LBL_ERR;
}
}
/* note we don't finish the headeromac, this allows us to add more header later */
/* setup the CTR mode */
if ((err = ctr_start(cipher, eax->N, key, keylen, 0, CTR_COUNTER_BIG_ENDIAN, &eax->ctr)) != CRYPT_OK) {
goto LBL_ERR;
}
/* setup the LTC_OMAC for the ciphertext */
if ((err = omac_init(&eax->ctomac, cipher, key, keylen)) != CRYPT_OK) {
goto LBL_ERR;
}
/* omac [2]_n */
zeromem(buf, MAXBLOCKSIZE);
buf[blklen-1] = 2;
if ((err = omac_process(&eax->ctomac, buf, blklen)) != CRYPT_OK) {
goto LBL_ERR;
}
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(buf, MAXBLOCKSIZE);
zeromem(omac, sizeof(*omac));
#endif
XFREE(omac);
XFREE(buf);
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,259 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file eax_test.c
EAX implementation, self-test, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_EAX_MODE
/**
Test the EAX implementation
@return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
*/
int eax_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen,
noncelen,
headerlen,
msglen;
unsigned char key[MAXBLOCKSIZE],
nonce[MAXBLOCKSIZE],
header[MAXBLOCKSIZE],
plaintext[MAXBLOCKSIZE],
ciphertext[MAXBLOCKSIZE],
tag[MAXBLOCKSIZE];
} tests[] = {
/* NULL message */
{
16, 0, 0, 0,
/* key */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* nonce */
{ 0 },
/* header */
{ 0 },
/* plaintext */
{ 0 },
/* ciphertext */
{ 0 },
/* tag */
{ 0x9a, 0xd0, 0x7e, 0x7d, 0xbf, 0xf3, 0x01, 0xf5,
0x05, 0xde, 0x59, 0x6b, 0x96, 0x15, 0xdf, 0xff }
},
/* test with nonce */
{
16, 16, 0, 0,
/* key */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* nonce */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* header */
{ 0 },
/* plaintext */
{ 0 },
/* ciphertext */
{ 0 },
/* tag */
{ 0x1c, 0xe1, 0x0d, 0x3e, 0xff, 0xd4, 0xca, 0xdb,
0xe2, 0xe4, 0x4b, 0x58, 0xd6, 0x0a, 0xb9, 0xec }
},
/* test with header [no nonce] */
{
16, 0, 16, 0,
/* key */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* nonce */
{ 0 },
/* header */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* plaintext */
{ 0 },
/* ciphertext */
{ 0 },
/* tag */
{ 0x3a, 0x69, 0x8f, 0x7a, 0x27, 0x0e, 0x51, 0xb0,
0xf6, 0x5b, 0x3d, 0x3e, 0x47, 0x19, 0x3c, 0xff }
},
/* test with header + nonce + plaintext */
{
16, 16, 16, 32,
/* key */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* nonce */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* header */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* plaintext */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
/* ciphertext */
{ 0x29, 0xd8, 0x78, 0xd1, 0xa3, 0xbe, 0x85, 0x7b,
0x6f, 0xb8, 0xc8, 0xea, 0x59, 0x50, 0xa7, 0x78,
0x33, 0x1f, 0xbf, 0x2c, 0xcf, 0x33, 0x98, 0x6f,
0x35, 0xe8, 0xcf, 0x12, 0x1d, 0xcb, 0x30, 0xbc },
/* tag */
{ 0x4f, 0xbe, 0x03, 0x38, 0xbe, 0x1c, 0x8c, 0x7e,
0x1d, 0x7a, 0xe7, 0xe4, 0x5b, 0x92, 0xc5, 0x87 }
},
/* test with header + nonce + plaintext [not even sizes!] */
{
16, 15, 14, 29,
/* key */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* nonce */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e },
/* header */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d },
/* plaintext */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c },
/* ciphertext */
{ 0xdd, 0x25, 0xc7, 0x54, 0xc5, 0xb1, 0x7c, 0x59,
0x28, 0xb6, 0x9b, 0x73, 0x15, 0x5f, 0x7b, 0xb8,
0x88, 0x8f, 0xaf, 0x37, 0x09, 0x1a, 0xd9, 0x2c,
0x8a, 0x24, 0xdb, 0x86, 0x8b },
/* tag */
{ 0x0d, 0x1a, 0x14, 0xe5, 0x22, 0x24, 0xff, 0xd2,
0x3a, 0x05, 0xfa, 0x02, 0xcd, 0xef, 0x52, 0xda }
},
/* Vectors from Brian Gladman */
{
16, 16, 8, 0,
/* key */
{ 0x23, 0x39, 0x52, 0xde, 0xe4, 0xd5, 0xed, 0x5f,
0x9b, 0x9c, 0x6d, 0x6f, 0xf8, 0x0f, 0xf4, 0x78 },
/* nonce */
{ 0x62, 0xec, 0x67, 0xf9, 0xc3, 0xa4, 0xa4, 0x07,
0xfc, 0xb2, 0xa8, 0xc4, 0x90, 0x31, 0xa8, 0xb3 },
/* header */
{ 0x6b, 0xfb, 0x91, 0x4f, 0xd0, 0x7e, 0xae, 0x6b },
/* PT */
{ 0x00 },
/* CT */
{ 0x00 },
/* tag */
{ 0xe0, 0x37, 0x83, 0x0e, 0x83, 0x89, 0xf2, 0x7b,
0x02, 0x5a, 0x2d, 0x65, 0x27, 0xe7, 0x9d, 0x01 }
},
{
16, 16, 8, 2,
/* key */
{ 0x91, 0x94, 0x5d, 0x3f, 0x4d, 0xcb, 0xee, 0x0b,
0xf4, 0x5e, 0xf5, 0x22, 0x55, 0xf0, 0x95, 0xa4 },
/* nonce */
{ 0xbe, 0xca, 0xf0, 0x43, 0xb0, 0xa2, 0x3d, 0x84,
0x31, 0x94, 0xba, 0x97, 0x2c, 0x66, 0xde, 0xbd },
/* header */
{ 0xfa, 0x3b, 0xfd, 0x48, 0x06, 0xeb, 0x53, 0xfa },
/* PT */
{ 0xf7, 0xfb },
/* CT */
{ 0x19, 0xdd },
/* tag */
{ 0x5c, 0x4c, 0x93, 0x31, 0x04, 0x9d, 0x0b, 0xda,
0xb0, 0x27, 0x74, 0x08, 0xf6, 0x79, 0x67, 0xe5 }
},
{
16, 16, 8, 5,
/* key */
{ 0x01, 0xf7, 0x4a, 0xd6, 0x40, 0x77, 0xf2, 0xe7,
0x04, 0xc0, 0xf6, 0x0a, 0xda, 0x3d, 0xd5, 0x23 },
/* nonce */
{ 0x70, 0xc3, 0xdb, 0x4f, 0x0d, 0x26, 0x36, 0x84,
0x00, 0xa1, 0x0e, 0xd0, 0x5d, 0x2b, 0xff, 0x5e },
/* header */
{ 0x23, 0x4a, 0x34, 0x63, 0xc1, 0x26, 0x4a, 0xc6 },
/* PT */
{ 0x1a, 0x47, 0xcb, 0x49, 0x33 },
/* CT */
{ 0xd8, 0x51, 0xd5, 0xba, 0xe0 },
/* Tag */
{ 0x3a, 0x59, 0xf2, 0x38, 0xa2, 0x3e, 0x39, 0x19,
0x9d, 0xc9, 0x26, 0x66, 0x26, 0xc4, 0x0f, 0x80 }
}
};
int err, x, idx, res;
unsigned long len;
unsigned char outct[MAXBLOCKSIZE], outtag[MAXBLOCKSIZE];
/* AES can be under rijndael or aes... try to find it */
if ((idx = find_cipher("aes")) == -1) {
if ((idx = find_cipher("rijndael")) == -1) {
return CRYPT_NOP;
}
}
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
len = sizeof(outtag);
if ((err = eax_encrypt_authenticate_memory(idx, tests[x].key, tests[x].keylen,
tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen,
tests[x].plaintext, tests[x].msglen, outct, outtag, &len)) != CRYPT_OK) {
return err;
}
if (compare_testvector(outtag, len, tests[x].tag, len, "EAX Tag", x) ||
compare_testvector(outct, tests[x].msglen, tests[x].ciphertext, tests[x].msglen, "EAX CT", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* test decrypt */
if ((err = eax_decrypt_verify_memory(idx, tests[x].key, tests[x].keylen,
tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen,
outct, tests[x].msglen, outct, outtag, len, &res)) != CRYPT_OK) {
return err;
}
if ((res != 1) || compare_testvector(outct, tests[x].msglen, tests[x].plaintext, tests[x].msglen, "EAX", x)) {
#ifdef LTC_TEST_DBG
printf("\n\nEAX: Failure-decrypt - res = %d\n", res);
#endif
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif /* LTC_TEST */
}
#endif /* LTC_EAX_MODE */
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,124 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file gcm_add_aad.c
GCM implementation, Add AAD data to the stream, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_GCM_MODE
/**
Add AAD to the GCM state
@param gcm The GCM state
@param adata The additional authentication data to add to the GCM state
@param adatalen The length of the AAD data.
@return CRYPT_OK on success
*/
int gcm_add_aad(gcm_state *gcm,
const unsigned char *adata, unsigned long adatalen)
{
unsigned long x;
int err;
#ifdef LTC_FAST
unsigned long y;
#endif
LTC_ARGCHK(gcm != NULL);
if (adatalen > 0) {
LTC_ARGCHK(adata != NULL);
}
if (gcm->buflen > 16 || gcm->buflen < 0) {
return CRYPT_INVALID_ARG;
}
if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
return err;
}
/* in IV mode? */
if (gcm->mode == LTC_GCM_MODE_IV) {
/* IV length must be > 0 */
if (gcm->buflen == 0 && gcm->totlen == 0) return CRYPT_ERROR;
/* let's process the IV */
if (gcm->ivmode || gcm->buflen != 12) {
for (x = 0; x < (unsigned long)gcm->buflen; x++) {
gcm->X[x] ^= gcm->buf[x];
}
if (gcm->buflen) {
gcm->totlen += gcm->buflen * CONST64(8);
gcm_mult_h(gcm, gcm->X);
}
/* mix in the length */
zeromem(gcm->buf, 8);
STORE64H(gcm->totlen, gcm->buf+8);
for (x = 0; x < 16; x++) {
gcm->X[x] ^= gcm->buf[x];
}
gcm_mult_h(gcm, gcm->X);
/* copy counter out */
XMEMCPY(gcm->Y, gcm->X, 16);
zeromem(gcm->X, 16);
} else {
XMEMCPY(gcm->Y, gcm->buf, 12);
gcm->Y[12] = 0;
gcm->Y[13] = 0;
gcm->Y[14] = 0;
gcm->Y[15] = 1;
}
XMEMCPY(gcm->Y_0, gcm->Y, 16);
zeromem(gcm->buf, 16);
gcm->buflen = 0;
gcm->totlen = 0;
gcm->mode = LTC_GCM_MODE_AAD;
}
if (gcm->mode != LTC_GCM_MODE_AAD || gcm->buflen >= 16) {
return CRYPT_INVALID_ARG;
}
x = 0;
#ifdef LTC_FAST
if (gcm->buflen == 0) {
for (x = 0; x < (adatalen & ~15); x += 16) {
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&adata[x + y]));
}
gcm_mult_h(gcm, gcm->X);
gcm->totlen += 128;
}
adata += x;
}
#endif
/* start adding AAD data to the state */
for (; x < adatalen; x++) {
gcm->X[gcm->buflen++] ^= *adata++;
if (gcm->buflen == 16) {
/* GF mult it */
gcm_mult_h(gcm, gcm->X);
gcm->buflen = 0;
gcm->totlen += 128;
}
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,92 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file gcm_add_iv.c
GCM implementation, add IV data to the state, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_GCM_MODE
/**
Add IV data to the GCM state
@param gcm The GCM state
@param IV The initial value data to add
@param IVlen The length of the IV
@return CRYPT_OK on success
*/
int gcm_add_iv(gcm_state *gcm,
const unsigned char *IV, unsigned long IVlen)
{
unsigned long x, y;
int err;
LTC_ARGCHK(gcm != NULL);
if (IVlen > 0) {
LTC_ARGCHK(IV != NULL);
}
/* must be in IV mode */
if (gcm->mode != LTC_GCM_MODE_IV) {
return CRYPT_INVALID_ARG;
}
if (gcm->buflen >= 16 || gcm->buflen < 0) {
return CRYPT_INVALID_ARG;
}
if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
return err;
}
/* trip the ivmode flag */
if (IVlen + gcm->buflen > 12) {
gcm->ivmode |= 1;
}
x = 0;
#ifdef LTC_FAST
if (gcm->buflen == 0) {
for (x = 0; x < (IVlen & ~15); x += 16) {
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&IV[x + y]));
}
gcm_mult_h(gcm, gcm->X);
gcm->totlen += 128;
}
IV += x;
}
#endif
/* start adding IV data to the state */
for (; x < IVlen; x++) {
gcm->buf[gcm->buflen++] = *IV++;
if (gcm->buflen == 16) {
/* GF mult it */
for (y = 0; y < 16; y++) {
gcm->X[y] ^= gcm->buf[y];
}
gcm_mult_h(gcm, gcm->X);
gcm->buflen = 0;
gcm->totlen += 128;
}
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,90 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file gcm_done.c
GCM implementation, Terminate the stream, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_GCM_MODE
/**
Terminate a GCM stream
@param gcm The GCM state
@param tag [out] The destination for the MAC tag
@param taglen [in/out] The length of the MAC tag
@return CRYPT_OK on success
*/
int gcm_done(gcm_state *gcm,
unsigned char *tag, unsigned long *taglen)
{
unsigned long x;
int err;
LTC_ARGCHK(gcm != NULL);
LTC_ARGCHK(tag != NULL);
LTC_ARGCHK(taglen != NULL);
if (gcm->buflen > 16 || gcm->buflen < 0) {
return CRYPT_INVALID_ARG;
}
if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
return err;
}
if (gcm->mode == LTC_GCM_MODE_IV) {
/* let's process the IV */
if ((err = gcm_add_aad(gcm, NULL, 0)) != CRYPT_OK) return err;
}
if (gcm->mode == LTC_GCM_MODE_AAD) {
/* let's process the AAD */
if ((err = gcm_process(gcm, NULL, 0, NULL, 0)) != CRYPT_OK) return err;
}
if (gcm->mode != LTC_GCM_MODE_TEXT) {
return CRYPT_INVALID_ARG;
}
/* handle remaining ciphertext */
if (gcm->buflen) {
gcm->pttotlen += gcm->buflen * CONST64(8);
gcm_mult_h(gcm, gcm->X);
}
/* length */
STORE64H(gcm->totlen, gcm->buf);
STORE64H(gcm->pttotlen, gcm->buf+8);
for (x = 0; x < 16; x++) {
gcm->X[x] ^= gcm->buf[x];
}
gcm_mult_h(gcm, gcm->X);
/* encrypt original counter */
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K)) != CRYPT_OK) {
return err;
}
for (x = 0; x < 16 && x < *taglen; x++) {
tag[x] = gcm->buf[x] ^ gcm->X[x];
}
*taglen = x;
cipher_descriptor[gcm->cipher].done(&gcm->K);
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,219 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file gcm_gf_mult.c
GCM implementation, do the GF mult, by Tom St Denis
*/
#include "tomcrypt.h"
#if defined(LTC_GCM_TABLES) || defined(LTC_LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST))
/* this is x*2^128 mod p(x) ... the results are 16 bytes each stored in a packed format. Since only the
* lower 16 bits are not zero'ed I removed the upper 14 bytes */
const unsigned char gcm_shift_table[256*2] = {
0x00, 0x00, 0x01, 0xc2, 0x03, 0x84, 0x02, 0x46, 0x07, 0x08, 0x06, 0xca, 0x04, 0x8c, 0x05, 0x4e,
0x0e, 0x10, 0x0f, 0xd2, 0x0d, 0x94, 0x0c, 0x56, 0x09, 0x18, 0x08, 0xda, 0x0a, 0x9c, 0x0b, 0x5e,
0x1c, 0x20, 0x1d, 0xe2, 0x1f, 0xa4, 0x1e, 0x66, 0x1b, 0x28, 0x1a, 0xea, 0x18, 0xac, 0x19, 0x6e,
0x12, 0x30, 0x13, 0xf2, 0x11, 0xb4, 0x10, 0x76, 0x15, 0x38, 0x14, 0xfa, 0x16, 0xbc, 0x17, 0x7e,
0x38, 0x40, 0x39, 0x82, 0x3b, 0xc4, 0x3a, 0x06, 0x3f, 0x48, 0x3e, 0x8a, 0x3c, 0xcc, 0x3d, 0x0e,
0x36, 0x50, 0x37, 0x92, 0x35, 0xd4, 0x34, 0x16, 0x31, 0x58, 0x30, 0x9a, 0x32, 0xdc, 0x33, 0x1e,
0x24, 0x60, 0x25, 0xa2, 0x27, 0xe4, 0x26, 0x26, 0x23, 0x68, 0x22, 0xaa, 0x20, 0xec, 0x21, 0x2e,
0x2a, 0x70, 0x2b, 0xb2, 0x29, 0xf4, 0x28, 0x36, 0x2d, 0x78, 0x2c, 0xba, 0x2e, 0xfc, 0x2f, 0x3e,
0x70, 0x80, 0x71, 0x42, 0x73, 0x04, 0x72, 0xc6, 0x77, 0x88, 0x76, 0x4a, 0x74, 0x0c, 0x75, 0xce,
0x7e, 0x90, 0x7f, 0x52, 0x7d, 0x14, 0x7c, 0xd6, 0x79, 0x98, 0x78, 0x5a, 0x7a, 0x1c, 0x7b, 0xde,
0x6c, 0xa0, 0x6d, 0x62, 0x6f, 0x24, 0x6e, 0xe6, 0x6b, 0xa8, 0x6a, 0x6a, 0x68, 0x2c, 0x69, 0xee,
0x62, 0xb0, 0x63, 0x72, 0x61, 0x34, 0x60, 0xf6, 0x65, 0xb8, 0x64, 0x7a, 0x66, 0x3c, 0x67, 0xfe,
0x48, 0xc0, 0x49, 0x02, 0x4b, 0x44, 0x4a, 0x86, 0x4f, 0xc8, 0x4e, 0x0a, 0x4c, 0x4c, 0x4d, 0x8e,
0x46, 0xd0, 0x47, 0x12, 0x45, 0x54, 0x44, 0x96, 0x41, 0xd8, 0x40, 0x1a, 0x42, 0x5c, 0x43, 0x9e,
0x54, 0xe0, 0x55, 0x22, 0x57, 0x64, 0x56, 0xa6, 0x53, 0xe8, 0x52, 0x2a, 0x50, 0x6c, 0x51, 0xae,
0x5a, 0xf0, 0x5b, 0x32, 0x59, 0x74, 0x58, 0xb6, 0x5d, 0xf8, 0x5c, 0x3a, 0x5e, 0x7c, 0x5f, 0xbe,
0xe1, 0x00, 0xe0, 0xc2, 0xe2, 0x84, 0xe3, 0x46, 0xe6, 0x08, 0xe7, 0xca, 0xe5, 0x8c, 0xe4, 0x4e,
0xef, 0x10, 0xee, 0xd2, 0xec, 0x94, 0xed, 0x56, 0xe8, 0x18, 0xe9, 0xda, 0xeb, 0x9c, 0xea, 0x5e,
0xfd, 0x20, 0xfc, 0xe2, 0xfe, 0xa4, 0xff, 0x66, 0xfa, 0x28, 0xfb, 0xea, 0xf9, 0xac, 0xf8, 0x6e,
0xf3, 0x30, 0xf2, 0xf2, 0xf0, 0xb4, 0xf1, 0x76, 0xf4, 0x38, 0xf5, 0xfa, 0xf7, 0xbc, 0xf6, 0x7e,
0xd9, 0x40, 0xd8, 0x82, 0xda, 0xc4, 0xdb, 0x06, 0xde, 0x48, 0xdf, 0x8a, 0xdd, 0xcc, 0xdc, 0x0e,
0xd7, 0x50, 0xd6, 0x92, 0xd4, 0xd4, 0xd5, 0x16, 0xd0, 0x58, 0xd1, 0x9a, 0xd3, 0xdc, 0xd2, 0x1e,
0xc5, 0x60, 0xc4, 0xa2, 0xc6, 0xe4, 0xc7, 0x26, 0xc2, 0x68, 0xc3, 0xaa, 0xc1, 0xec, 0xc0, 0x2e,
0xcb, 0x70, 0xca, 0xb2, 0xc8, 0xf4, 0xc9, 0x36, 0xcc, 0x78, 0xcd, 0xba, 0xcf, 0xfc, 0xce, 0x3e,
0x91, 0x80, 0x90, 0x42, 0x92, 0x04, 0x93, 0xc6, 0x96, 0x88, 0x97, 0x4a, 0x95, 0x0c, 0x94, 0xce,
0x9f, 0x90, 0x9e, 0x52, 0x9c, 0x14, 0x9d, 0xd6, 0x98, 0x98, 0x99, 0x5a, 0x9b, 0x1c, 0x9a, 0xde,
0x8d, 0xa0, 0x8c, 0x62, 0x8e, 0x24, 0x8f, 0xe6, 0x8a, 0xa8, 0x8b, 0x6a, 0x89, 0x2c, 0x88, 0xee,
0x83, 0xb0, 0x82, 0x72, 0x80, 0x34, 0x81, 0xf6, 0x84, 0xb8, 0x85, 0x7a, 0x87, 0x3c, 0x86, 0xfe,
0xa9, 0xc0, 0xa8, 0x02, 0xaa, 0x44, 0xab, 0x86, 0xae, 0xc8, 0xaf, 0x0a, 0xad, 0x4c, 0xac, 0x8e,
0xa7, 0xd0, 0xa6, 0x12, 0xa4, 0x54, 0xa5, 0x96, 0xa0, 0xd8, 0xa1, 0x1a, 0xa3, 0x5c, 0xa2, 0x9e,
0xb5, 0xe0, 0xb4, 0x22, 0xb6, 0x64, 0xb7, 0xa6, 0xb2, 0xe8, 0xb3, 0x2a, 0xb1, 0x6c, 0xb0, 0xae,
0xbb, 0xf0, 0xba, 0x32, 0xb8, 0x74, 0xb9, 0xb6, 0xbc, 0xf8, 0xbd, 0x3a, 0xbf, 0x7c, 0xbe, 0xbe };
#endif
#if defined(LTC_GCM_MODE) || defined(LRW_MODE)
#ifndef LTC_FAST
/* right shift */
static void _gcm_rightshift(unsigned char *a)
{
int x;
for (x = 15; x > 0; x--) {
a[x] = (a[x]>>1) | ((a[x-1]<<7)&0x80);
}
a[0] >>= 1;
}
/* c = b*a */
static const unsigned char mask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
static const unsigned char poly[] = { 0x00, 0xE1 };
/**
GCM GF multiplier (internal use only) bitserial
@param a First value
@param b Second value
@param c Destination for a * b
*/
void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c)
{
unsigned char Z[16], V[16];
unsigned char x, y, z;
zeromem(Z, 16);
XMEMCPY(V, a, 16);
for (x = 0; x < 128; x++) {
if (b[x>>3] & mask[x&7]) {
for (y = 0; y < 16; y++) {
Z[y] ^= V[y];
}
}
z = V[15] & 0x01;
_gcm_rightshift(V);
V[0] ^= poly[z];
}
XMEMCPY(c, Z, 16);
}
#else
/* map normal numbers to "ieee" way ... e.g. bit reversed */
#define M(x) ( ((x&8)>>3) | ((x&4)>>1) | ((x&2)<<1) | ((x&1)<<3) )
#define BPD (sizeof(LTC_FAST_TYPE) * 8)
#define WPV (1 + (16 / sizeof(LTC_FAST_TYPE)))
/**
GCM GF multiplier (internal use only) word oriented
@param a First value
@param b Second value
@param c Destination for a * b
*/
void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c)
{
int i, j, k, u;
LTC_FAST_TYPE B[16][WPV], tmp[32 / sizeof(LTC_FAST_TYPE)], pB[16 / sizeof(LTC_FAST_TYPE)], zz, z;
unsigned char pTmp[32];
/* create simple tables */
zeromem(B[0], sizeof(B[0]));
zeromem(B[M(1)], sizeof(B[M(1)]));
#ifdef ENDIAN_32BITWORD
for (i = 0; i < 4; i++) {
LOAD32H(B[M(1)][i], a + (i<<2));
LOAD32L(pB[i], b + (i<<2));
}
#else
for (i = 0; i < 2; i++) {
LOAD64H(B[M(1)][i], a + (i<<3));
LOAD64L(pB[i], b + (i<<3));
}
#endif
/* now create 2, 4 and 8 */
B[M(2)][0] = B[M(1)][0] >> 1;
B[M(4)][0] = B[M(1)][0] >> 2;
B[M(8)][0] = B[M(1)][0] >> 3;
for (i = 1; i < (int)WPV; i++) {
B[M(2)][i] = (B[M(1)][i-1] << (BPD-1)) | (B[M(1)][i] >> 1);
B[M(4)][i] = (B[M(1)][i-1] << (BPD-2)) | (B[M(1)][i] >> 2);
B[M(8)][i] = (B[M(1)][i-1] << (BPD-3)) | (B[M(1)][i] >> 3);
}
/* now all values with two bits which are 3, 5, 6, 9, 10, 12 */
for (i = 0; i < (int)WPV; i++) {
B[M(3)][i] = B[M(1)][i] ^ B[M(2)][i];
B[M(5)][i] = B[M(1)][i] ^ B[M(4)][i];
B[M(6)][i] = B[M(2)][i] ^ B[M(4)][i];
B[M(9)][i] = B[M(1)][i] ^ B[M(8)][i];
B[M(10)][i] = B[M(2)][i] ^ B[M(8)][i];
B[M(12)][i] = B[M(8)][i] ^ B[M(4)][i];
/* now all 3 bit values and the only 4 bit value: 7, 11, 13, 14, 15 */
B[M(7)][i] = B[M(3)][i] ^ B[M(4)][i];
B[M(11)][i] = B[M(3)][i] ^ B[M(8)][i];
B[M(13)][i] = B[M(1)][i] ^ B[M(12)][i];
B[M(14)][i] = B[M(6)][i] ^ B[M(8)][i];
B[M(15)][i] = B[M(7)][i] ^ B[M(8)][i];
}
zeromem(tmp, sizeof(tmp));
/* compute product four bits of each word at a time */
/* for each nibble */
for (i = (BPD/4)-1; i >= 0; i--) {
/* for each word */
for (j = 0; j < (int)(WPV-1); j++) {
/* grab the 4 bits recall the nibbles are backwards so it's a shift by (i^1)*4 */
u = (pB[j] >> ((i^1)<<2)) & 15;
/* add offset by the word count the table looked up value to the result */
for (k = 0; k < (int)WPV; k++) {
tmp[k+j] ^= B[u][k];
}
}
/* shift result up by 4 bits */
if (i != 0) {
for (z = j = 0; j < (int)(32 / sizeof(LTC_FAST_TYPE)); j++) {
zz = tmp[j] << (BPD-4);
tmp[j] = (tmp[j] >> 4) | z;
z = zz;
}
}
}
/* store product */
#ifdef ENDIAN_32BITWORD
for (i = 0; i < 8; i++) {
STORE32H(tmp[i], pTmp + (i<<2));
}
#else
for (i = 0; i < 4; i++) {
STORE64H(tmp[i], pTmp + (i<<3));
}
#endif
/* reduce by taking most significant byte and adding the appropriate two byte sequence 16 bytes down */
for (i = 31; i >= 16; i--) {
pTmp[i-16] ^= gcm_shift_table[((unsigned)pTmp[i]<<1)];
pTmp[i-15] ^= gcm_shift_table[((unsigned)pTmp[i]<<1)+1];
}
for (i = 0; i < 16; i++) {
c[i] = pTmp[i];
}
}
#endif
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,105 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file gcm_init.c
GCM implementation, initialize state, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_GCM_MODE
/**
Initialize a GCM state
@param gcm The GCM state to initialize
@param cipher The index of the cipher to use
@param key The secret key
@param keylen The length of the secret key
@return CRYPT_OK on success
*/
int gcm_init(gcm_state *gcm, int cipher,
const unsigned char *key, int keylen)
{
int err;
unsigned char B[16];
#ifdef LTC_GCM_TABLES
int x, y, z, t;
#endif
LTC_ARGCHK(gcm != NULL);
LTC_ARGCHK(key != NULL);
#ifdef LTC_FAST
if (16 % sizeof(LTC_FAST_TYPE)) {
return CRYPT_INVALID_ARG;
}
#endif
/* is cipher valid? */
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
if (cipher_descriptor[cipher].block_length != 16) {
return CRYPT_INVALID_CIPHER;
}
/* schedule key */
if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &gcm->K)) != CRYPT_OK) {
return err;
}
/* H = E(0) */
zeromem(B, 16);
if ((err = cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K)) != CRYPT_OK) {
return err;
}
/* setup state */
zeromem(gcm->buf, sizeof(gcm->buf));
zeromem(gcm->X, sizeof(gcm->X));
gcm->cipher = cipher;
gcm->mode = LTC_GCM_MODE_IV;
gcm->ivmode = 0;
gcm->buflen = 0;
gcm->totlen = 0;
gcm->pttotlen = 0;
#ifdef LTC_GCM_TABLES
/* setup tables */
/* generate the first table as it has no shifting (from which we make the other tables) */
zeromem(B, 16);
for (y = 0; y < 256; y++) {
B[0] = y;
gcm_gf_mult(gcm->H, B, &gcm->PC[0][y][0]);
}
/* now generate the rest of the tables based the previous table */
for (x = 1; x < 16; x++) {
for (y = 0; y < 256; y++) {
/* now shift it right by 8 bits */
t = gcm->PC[x-1][y][15];
for (z = 15; z > 0; z--) {
gcm->PC[x][y][z] = gcm->PC[x-1][y][z-1];
}
gcm->PC[x][y][0] = gcm_shift_table[t<<1];
gcm->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1];
}
}
#endif
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,106 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file gcm_memory.c
GCM implementation, process a packet, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_GCM_MODE
/**
Process an entire GCM packet in one call.
@param cipher Index of cipher to use
@param key The secret key
@param keylen The length of the secret key
@param IV The initialization vector
@param IVlen The length of the initialization vector
@param adata The additional authentication data (header)
@param adatalen The length of the adata
@param pt The plaintext
@param ptlen The length of the plaintext (ciphertext length is the same)
@param ct The ciphertext
@param tag [out] The MAC tag
@param taglen [in/out] The MAC tag length
@param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
@return CRYPT_OK on success
*/
int gcm_memory( int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *IV, unsigned long IVlen,
const unsigned char *adata, unsigned long adatalen,
unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen,
int direction)
{
void *orig;
gcm_state *gcm;
int err;
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
if (cipher_descriptor[cipher].accel_gcm_memory != NULL) {
return cipher_descriptor[cipher].accel_gcm_memory
(key, keylen,
IV, IVlen,
adata, adatalen,
pt, ptlen,
ct,
tag, taglen,
direction);
}
#ifndef LTC_GCM_TABLES_SSE2
orig = gcm = XMALLOC(sizeof(*gcm));
#else
orig = gcm = XMALLOC(sizeof(*gcm) + 16);
#endif
if (gcm == NULL) {
return CRYPT_MEM;
}
/* Force GCM to be on a multiple of 16 so we can use 128-bit aligned operations
* note that we only modify gcm and keep orig intact. This code is not portable
* but again it's only for SSE2 anyways, so who cares?
*/
#ifdef LTC_GCM_TABLES_SSE2
if ((unsigned long)gcm & 15) {
gcm = (gcm_state *)((unsigned long)gcm + (16 - ((unsigned long)gcm & 15)));
}
#endif
if ((err = gcm_init(gcm, cipher, key, keylen)) != CRYPT_OK) {
goto LTC_ERR;
}
if ((err = gcm_add_iv(gcm, IV, IVlen)) != CRYPT_OK) {
goto LTC_ERR;
}
if ((err = gcm_add_aad(gcm, adata, adatalen)) != CRYPT_OK) {
goto LTC_ERR;
}
if ((err = gcm_process(gcm, pt, ptlen, ct, direction)) != CRYPT_OK) {
goto LTC_ERR;
}
err = gcm_done(gcm, tag, taglen);
LTC_ERR:
XFREE(orig);
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,57 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file gcm_mult_h.c
GCM implementation, do the GF mult, by Tom St Denis
*/
#include "tomcrypt.h"
#if defined(LTC_GCM_MODE)
/**
GCM multiply by H
@param gcm The GCM state which holds the H value
@param I The value to multiply H by
*/
void gcm_mult_h(gcm_state *gcm, unsigned char *I)
{
unsigned char T[16];
#ifdef LTC_GCM_TABLES
int x;
#ifdef LTC_GCM_TABLES_SSE2
asm("movdqa (%0),%%xmm0"::"r"(&gcm->PC[0][I[0]][0]));
for (x = 1; x < 16; x++) {
asm("pxor (%0),%%xmm0"::"r"(&gcm->PC[x][I[x]][0]));
}
asm("movdqa %%xmm0,(%0)"::"r"(&T));
#else
int y;
XMEMCPY(T, &gcm->PC[0][I[0]][0], 16);
for (x = 1; x < 16; x++) {
#ifdef LTC_FAST
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST(T + y)) ^= *(LTC_FAST_TYPE_PTR_CAST(&gcm->PC[x][I[x]][y]));
}
#else
for (y = 0; y < 16; y++) {
T[y] ^= gcm->PC[x][I[x]][y];
}
#endif /* LTC_FAST */
}
#endif /* LTC_GCM_TABLES_SSE2 */
#else
gcm_gf_mult(gcm->H, I, T);
#endif
XMEMCPY(I, T, 16);
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,160 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file gcm_process.c
GCM implementation, process message data, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_GCM_MODE
/**
Process plaintext/ciphertext through GCM
@param gcm The GCM state
@param pt The plaintext
@param ptlen The plaintext length (ciphertext length is the same)
@param ct The ciphertext
@param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT)
@return CRYPT_OK on success
*/
int gcm_process(gcm_state *gcm,
unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
int direction)
{
unsigned long x;
int y, err;
unsigned char b;
LTC_ARGCHK(gcm != NULL);
if (ptlen > 0) {
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
}
if (gcm->buflen > 16 || gcm->buflen < 0) {
return CRYPT_INVALID_ARG;
}
if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) {
return err;
}
/* 0xFFFFFFFE0 = ((2^39)-256)/8 */
if (gcm->pttotlen / 8 + (ulong64)gcm->buflen + (ulong64)ptlen >= CONST64(0xFFFFFFFE0)) {
return CRYPT_INVALID_ARG;
}
if (gcm->mode == LTC_GCM_MODE_IV) {
/* let's process the IV */
if ((err = gcm_add_aad(gcm, NULL, 0)) != CRYPT_OK) return err;
}
/* in AAD mode? */
if (gcm->mode == LTC_GCM_MODE_AAD) {
/* let's process the AAD */
if (gcm->buflen) {
gcm->totlen += gcm->buflen * CONST64(8);
gcm_mult_h(gcm, gcm->X);
}
/* increment counter */
for (y = 15; y >= 12; y--) {
if (++gcm->Y[y] & 255) { break; }
}
/* encrypt the counter */
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
return err;
}
gcm->buflen = 0;
gcm->mode = LTC_GCM_MODE_TEXT;
}
if (gcm->mode != LTC_GCM_MODE_TEXT) {
return CRYPT_INVALID_ARG;
}
x = 0;
#ifdef LTC_FAST
if (gcm->buflen == 0) {
if (direction == GCM_ENCRYPT) {
for (x = 0; x < (ptlen & ~15); x += 16) {
/* ctr encrypt */
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST(&ct[x + y])) = *(LTC_FAST_TYPE_PTR_CAST(&pt[x+y])) ^ *(LTC_FAST_TYPE_PTR_CAST(&gcm->buf[y]));
*(LTC_FAST_TYPE_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&ct[x+y]));
}
/* GMAC it */
gcm->pttotlen += 128;
gcm_mult_h(gcm, gcm->X);
/* increment counter */
for (y = 15; y >= 12; y--) {
if (++gcm->Y[y] & 255) { break; }
}
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
return err;
}
}
} else {
for (x = 0; x < (ptlen & ~15); x += 16) {
/* ctr encrypt */
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&ct[x+y]));
*(LTC_FAST_TYPE_PTR_CAST(&pt[x + y])) = *(LTC_FAST_TYPE_PTR_CAST(&ct[x+y])) ^ *(LTC_FAST_TYPE_PTR_CAST(&gcm->buf[y]));
}
/* GMAC it */
gcm->pttotlen += 128;
gcm_mult_h(gcm, gcm->X);
/* increment counter */
for (y = 15; y >= 12; y--) {
if (++gcm->Y[y] & 255) { break; }
}
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
return err;
}
}
}
}
#endif
/* process text */
for (; x < ptlen; x++) {
if (gcm->buflen == 16) {
gcm->pttotlen += 128;
gcm_mult_h(gcm, gcm->X);
/* increment counter */
for (y = 15; y >= 12; y--) {
if (++gcm->Y[y] & 255) { break; }
}
if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) {
return err;
}
gcm->buflen = 0;
}
if (direction == GCM_ENCRYPT) {
b = ct[x] = pt[x] ^ gcm->buf[gcm->buflen];
} else {
b = ct[x];
pt[x] = ct[x] ^ gcm->buf[gcm->buflen];
}
gcm->X[gcm->buflen++] ^= b;
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,42 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file gcm_reset.c
GCM implementation, reset a used state so it can accept IV data, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_GCM_MODE
/**
Reset a GCM state to as if you just called gcm_init(). This saves the initialization time.
@param gcm The GCM state to reset
@return CRYPT_OK on success
*/
int gcm_reset(gcm_state *gcm)
{
LTC_ARGCHK(gcm != NULL);
zeromem(gcm->buf, sizeof(gcm->buf));
zeromem(gcm->X, sizeof(gcm->X));
gcm->mode = LTC_GCM_MODE_IV;
gcm->ivmode = 0;
gcm->buflen = 0;
gcm->totlen = 0;
gcm->pttotlen = 0;
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,392 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file gcm_test.c
GCM implementation, testing, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_GCM_MODE
/**
Test the GCM code
@return CRYPT_OK on success
*/
int gcm_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
unsigned char K[32];
int keylen;
unsigned char P[128];
unsigned long ptlen;
unsigned char A[128];
unsigned long alen;
unsigned char IV[128];
unsigned long IVlen;
unsigned char C[128];
unsigned char T[16];
} tests[] = {
/* test case #1 */
{
/* key */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
16,
/* plaintext */
{ 0 },
0,
/* AAD data */
{ 0 },
0,
/* IV */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 },
12,
/* ciphertext */
{ 0 },
/* tag */
{ 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61,
0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }
},
/* test case #2 */
{
/* key */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
16,
/* PT */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
16,
/* ADATA */
{ 0 },
0,
/* IV */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 },
12,
/* CT */
{ 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92,
0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 },
/* TAG */
{ 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd,
0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }
},
/* test case #3 */
{
/* key */
{ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, },
16,
/* PT */
{ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, },
64,
/* ADATA */
{ 0 },
0,
/* IV */
{ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
0xde, 0xca, 0xf8, 0x88, },
12,
/* CT */
{ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85, },
/* TAG */
{ 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6,
0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4, }
},
/* test case #4 */
{
/* key */
{ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, },
16,
/* PT */
{ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39, },
60,
/* ADATA */
{ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
0xab, 0xad, 0xda, 0xd2, },
20,
/* IV */
{ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
0xde, 0xca, 0xf8, 0x88, },
12,
/* CT */
{ 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
0x3d, 0x58, 0xe0, 0x91, },
/* TAG */
{ 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47, }
},
/* test case #5 */
{
/* key */
{ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, },
16,
/* PT */
{ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39, },
60,
/* ADATA */
{ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
0xab, 0xad, 0xda, 0xd2, },
20,
/* IV */
{ 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, },
8,
/* CT */
{ 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a,
0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55,
0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8,
0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23,
0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2,
0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42,
0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07,
0xc2, 0x3f, 0x45, 0x98, },
/* TAG */
{ 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85,
0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb, }
},
/* test case #6 */
{
/* key */
{ 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, },
16,
/* PT */
{ 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
0xba, 0x63, 0x7b, 0x39, },
60,
/* ADATA */
{ 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
0xab, 0xad, 0xda, 0xd2, },
20,
/* IV */
{ 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5,
0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa,
0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1,
0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28,
0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39,
0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54,
0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57,
0xa6, 0x37, 0xb3, 0x9b, },
60,
/* CT */
{ 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6,
0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94,
0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8,
0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7,
0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90,
0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f,
0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03,
0x4c, 0x34, 0xae, 0xe5, },
/* TAG */
{ 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa,
0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50, }
},
/* test case #46 from BG (catches the LTC bug of v1.15) */
{
/* key */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
16,
/* PT */
{ 0xa2, 0xaa, 0xb3, 0xad, 0x8b, 0x17, 0xac, 0xdd,
0xa2, 0x88, 0x42, 0x6c, 0xd7, 0xc4, 0x29, 0xb7,
0xca, 0x86, 0xb7, 0xac, 0xa0, 0x58, 0x09, 0xc7,
0x0c, 0xe8, 0x2d, 0xb2, 0x57, 0x11, 0xcb, 0x53,
0x02, 0xeb, 0x27, 0x43, 0xb0, 0x36, 0xf3, 0xd7,
0x50, 0xd6, 0xcf, 0x0d, 0xc0, 0xac, 0xb9, 0x29,
0x50, 0xd5, 0x46, 0xdb, 0x30, 0x8f, 0x93, 0xb4,
0xff, 0x24, 0x4a, 0xfa, 0x9d, 0xc7, 0x2b, 0xcd,
0x75, 0x8d, 0x2c },
67,
/* ADATA */
{ 0x68, 0x8e, 0x1a, 0xa9, 0x84, 0xde, 0x92, 0x6d,
0xc7, 0xb4, 0xc4, 0x7f, 0x44 },
13,
/* IV */
{ 0xb7, 0x21, 0x38, 0xb5, 0xa0, 0x5f, 0xf5, 0x07,
0x0e, 0x8c, 0xd9, 0x41, 0x83, 0xf7, 0x61, 0xd8 },
16,
/* CT */
{ 0xcb, 0xc8, 0xd2, 0xf1, 0x54, 0x81, 0xa4, 0xcc,
0x7d, 0xd1, 0xe1, 0x9a, 0xaa, 0x83, 0xde, 0x56,
0x78, 0x48, 0x3e, 0xc3, 0x59, 0xae, 0x7d, 0xec,
0x2a, 0xb8, 0xd5, 0x34, 0xe0, 0x90, 0x6f, 0x4b,
0x46, 0x63, 0xfa, 0xff, 0x58, 0xa8, 0xb2, 0xd7,
0x33, 0xb8, 0x45, 0xee, 0xf7, 0xc9, 0xb3, 0x31,
0xe9, 0xe1, 0x0e, 0xb2, 0x61, 0x2c, 0x99, 0x5f,
0xeb, 0x1a, 0xc1, 0x5a, 0x62, 0x86, 0xcc, 0xe8,
0xb2, 0x97, 0xa8 },
/* TAG */
{ 0x8d, 0x2d, 0x2a, 0x93, 0x72, 0x62, 0x6f, 0x6b,
0xee, 0x85, 0x80, 0x27, 0x6a, 0x63, 0x66, 0xbf }
}
/* rest of test cases are the same except AES key size changes... ignored... */
};
int idx, err;
unsigned long x, y;
unsigned char out[2][128], T[2][16];
gcm_state gcm;
/* find aes */
idx = find_cipher("aes");
if (idx == -1) {
idx = find_cipher("rijndael");
if (idx == -1) {
return CRYPT_NOP;
}
}
/* Special test case for empty AAD + empty PT */
y = sizeof(T[0]);
if ((err = gcm_init(&gcm, idx, tests[0].K, tests[0].keylen)) != CRYPT_OK) return err;
if ((err = gcm_add_iv(&gcm, tests[0].IV, tests[0].IVlen)) != CRYPT_OK) return err;
/* intentionally skip gcm_add_aad + gcm_process */
if ((err = gcm_done(&gcm, T[0], &y)) != CRYPT_OK) return err;
if (compare_testvector(T[0], y, tests[0].T, 16, "GCM Encrypt Tag-special", 0)) return CRYPT_FAIL_TESTVECTOR;
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
y = sizeof(T[0]);
if ((err = gcm_memory(idx, tests[x].K, tests[x].keylen,
tests[x].IV, tests[x].IVlen,
tests[x].A, tests[x].alen,
(unsigned char*)tests[x].P, tests[x].ptlen,
out[0], T[0], &y, GCM_ENCRYPT)) != CRYPT_OK) {
return err;
}
if (compare_testvector(out[0], tests[x].ptlen, tests[x].C, tests[x].ptlen, "GCM CT", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
if (compare_testvector(T[0], y, tests[x].T, 16, "GCM Encrypt Tag", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
y = sizeof(T[1]);
if ((err = gcm_memory(idx, tests[x].K, tests[x].keylen,
tests[x].IV, tests[x].IVlen,
tests[x].A, tests[x].alen,
out[1], tests[x].ptlen,
out[0], T[1], &y, GCM_DECRYPT)) != CRYPT_OK) {
return err;
}
if (compare_testvector(out[1], tests[x].ptlen, tests[x].P, tests[x].ptlen, "GCM PT", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
if (compare_testvector(T[1], y, tests[x].T, 16, "GCM Decrypt Tag", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,77 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb_decrypt.c
OCB implementation, decrypt data, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB_MODE
/**
Decrypt a block with OCB.
@param ocb The OCB state
@param ct The ciphertext (length of the block size of the block cipher)
@param pt [out] The plaintext (length of ct)
@return CRYPT_OK if successful
*/
int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt)
{
unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE];
int err, x;
LTC_ARGCHK(ocb != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
/* check if valid cipher */
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
return err;
}
LTC_ARGCHK(cipher_descriptor[ocb->cipher].ecb_decrypt != NULL);
/* check length */
if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
return CRYPT_INVALID_ARG;
}
/* Get Z[i] value */
ocb_shift_xor(ocb, Z);
/* xor ct in, encrypt, xor Z out */
for (x = 0; x < ocb->block_len; x++) {
tmp[x] = ct[x] ^ Z[x];
}
if ((err = cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key)) != CRYPT_OK) {
return err;
}
for (x = 0; x < ocb->block_len; x++) {
pt[x] ^= Z[x];
}
/* compute checksum */
for (x = 0; x < ocb->block_len; x++) {
ocb->checksum[x] ^= pt[x];
}
#ifdef LTC_CLEAN_STACK
zeromem(Z, sizeof(Z));
zeromem(tmp, sizeof(tmp));
#endif
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,84 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb_decrypt_verify_memory.c
OCB implementation, helper to decrypt block of memory, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB_MODE
/**
Decrypt and compare the tag with OCB.
@param cipher The index of the cipher desired
@param key The secret key
@param keylen The length of the secret key (octets)
@param nonce The session nonce (length of the block size of the block cipher)
@param ct The ciphertext
@param ctlen The length of the ciphertext (octets)
@param pt [out] The plaintext
@param tag The tag to compare against
@param taglen The length of the tag (octets)
@param stat [out] The result of the tag comparison (1==valid, 0==invalid)
@return CRYPT_OK if successful regardless of the tag comparison
*/
int ocb_decrypt_verify_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce,
const unsigned char *ct, unsigned long ctlen,
unsigned char *pt,
const unsigned char *tag, unsigned long taglen,
int *stat)
{
int err;
ocb_state *ocb;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(nonce != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(tag != NULL);
LTC_ARGCHK(stat != NULL);
/* allocate memory */
ocb = XMALLOC(sizeof(ocb_state));
if (ocb == NULL) {
return CRYPT_MEM;
}
if ((err = ocb_init(ocb, cipher, key, keylen, nonce)) != CRYPT_OK) {
goto LBL_ERR;
}
while (ctlen > (unsigned long)ocb->block_len) {
if ((err = ocb_decrypt(ocb, ct, pt)) != CRYPT_OK) {
goto LBL_ERR;
}
ctlen -= ocb->block_len;
pt += ocb->block_len;
ct += ocb->block_len;
}
err = ocb_done_decrypt(ocb, ct, ctlen, pt, tag, taglen, stat);
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(ocb, sizeof(ocb_state));
#endif
XFREE(ocb);
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,78 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb_done_decrypt.c
OCB implementation, terminate decryption, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB_MODE
/**
Terminate a decrypting OCB state
@param ocb The OCB state
@param ct The ciphertext (if any)
@param ctlen The length of the ciphertext (octets)
@param pt [out] The plaintext
@param tag The authentication tag (to compare against)
@param taglen The length of the authentication tag provided
@param stat [out] The result of the tag comparison
@return CRYPT_OK if the process was successful regardless if the tag is valid
*/
int ocb_done_decrypt(ocb_state *ocb,
const unsigned char *ct, unsigned long ctlen,
unsigned char *pt,
const unsigned char *tag, unsigned long taglen, int *stat)
{
int err;
unsigned char *tagbuf;
unsigned long tagbuflen;
LTC_ARGCHK(ocb != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(tag != NULL);
LTC_ARGCHK(stat != NULL);
/* default to failed */
*stat = 0;
/* allocate memory */
tagbuf = XMALLOC(MAXBLOCKSIZE);
if (tagbuf == NULL) {
return CRYPT_MEM;
}
tagbuflen = MAXBLOCKSIZE;
if ((err = s_ocb_done(ocb, ct, ctlen, pt, tagbuf, &tagbuflen, 1)) != CRYPT_OK) {
goto LBL_ERR;
}
if (taglen <= tagbuflen && XMEM_NEQ(tagbuf, tag, taglen) == 0) {
*stat = 1;
}
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(tagbuf, MAXBLOCKSIZE);
#endif
XFREE(tagbuf);
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,44 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb_done_encrypt.c
OCB implementation, terminate encryption, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB_MODE
/**
Terminate an encryption OCB state
@param ocb The OCB state
@param pt Remaining plaintext (if any)
@param ptlen The length of the plaintext (octets)
@param ct [out] The ciphertext (if any)
@param tag [out] The tag for the OCB stream
@param taglen [in/out] The max size and resulting size of the tag
@return CRYPT_OK if successful
*/
int ocb_done_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
unsigned char *ct, unsigned char *tag, unsigned long *taglen)
{
LTC_ARGCHK(ocb != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(tag != NULL);
LTC_ARGCHK(taglen != NULL);
return s_ocb_done(ocb, pt, ptlen, ct, tag, taglen, 0);
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,70 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb_encrypt.c
OCB implementation, encrypt data, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB_MODE
/**
Encrypt a block of data with OCB.
@param ocb The OCB state
@param pt The plaintext (length of the block size of the block cipher)
@param ct [out] The ciphertext (same size as the pt)
@return CRYPT_OK if successful
*/
int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct)
{
unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE];
int err, x;
LTC_ARGCHK(ocb != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
return err;
}
if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
return CRYPT_INVALID_ARG;
}
/* compute checksum */
for (x = 0; x < ocb->block_len; x++) {
ocb->checksum[x] ^= pt[x];
}
/* Get Z[i] value */
ocb_shift_xor(ocb, Z);
/* xor pt in, encrypt, xor Z out */
for (x = 0; x < ocb->block_len; x++) {
tmp[x] = pt[x] ^ Z[x];
}
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key)) != CRYPT_OK) {
return err;
}
for (x = 0; x < ocb->block_len; x++) {
ct[x] ^= Z[x];
}
#ifdef LTC_CLEAN_STACK
zeromem(Z, sizeof(Z));
zeromem(tmp, sizeof(tmp));
#endif
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,82 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb_encrypt_authenticate_memory.c
OCB implementation, encrypt block of memory, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB_MODE
/**
Encrypt and generate an authentication code for a buffer of memory
@param cipher The index of the cipher desired
@param key The secret key
@param keylen The length of the secret key (octets)
@param nonce The session nonce (length of the block ciphers block size)
@param pt The plaintext
@param ptlen The length of the plaintext (octets)
@param ct [out] The ciphertext
@param tag [out] The authentication tag
@param taglen [in/out] The max size and resulting size of the authentication tag
@return CRYPT_OK if successful
*/
int ocb_encrypt_authenticate_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce,
const unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen)
{
int err;
ocb_state *ocb;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(nonce != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(tag != NULL);
LTC_ARGCHK(taglen != NULL);
/* allocate ram */
ocb = XMALLOC(sizeof(ocb_state));
if (ocb == NULL) {
return CRYPT_MEM;
}
if ((err = ocb_init(ocb, cipher, key, keylen, nonce)) != CRYPT_OK) {
goto LBL_ERR;
}
while (ptlen > (unsigned long)ocb->block_len) {
if ((err = ocb_encrypt(ocb, pt, ct)) != CRYPT_OK) {
goto LBL_ERR;
}
ptlen -= ocb->block_len;
pt += ocb->block_len;
ct += ocb->block_len;
}
err = ocb_done_encrypt(ocb, pt, ptlen, ct, tag, taglen);
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(ocb, sizeof(ocb_state));
#endif
XFREE(ocb);
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,139 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb_init.c
OCB implementation, initialize state, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB_MODE
static const struct {
int len;
unsigned char poly_div[MAXBLOCKSIZE],
poly_mul[MAXBLOCKSIZE];
} polys[] = {
{
8,
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B }
}, {
16,
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }
}
};
/**
Initialize an OCB context.
@param ocb [out] The destination of the OCB state
@param cipher The index of the desired cipher
@param key The secret key
@param keylen The length of the secret key (octets)
@param nonce The session nonce (length of the block size of the cipher)
@return CRYPT_OK if successful
*/
int ocb_init(ocb_state *ocb, int cipher,
const unsigned char *key, unsigned long keylen, const unsigned char *nonce)
{
int poly, x, y, m, err;
LTC_ARGCHK(ocb != NULL);
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(nonce != NULL);
/* valid cipher? */
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
/* determine which polys to use */
ocb->block_len = cipher_descriptor[cipher].block_length;
x = (int)(sizeof(polys)/sizeof(polys[0]));
for (poly = 0; poly < x; poly++) {
if (polys[poly].len == ocb->block_len) {
break;
}
}
if (poly == x) {
return CRYPT_INVALID_ARG; /* block_len not found in polys */
}
if (polys[poly].len != ocb->block_len) {
return CRYPT_INVALID_ARG;
}
/* schedule the key */
if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) {
return err;
}
/* find L = E[0] */
zeromem(ocb->L, ocb->block_len);
if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key)) != CRYPT_OK) {
return err;
}
/* find R = E[N xor L] */
for (x = 0; x < ocb->block_len; x++) {
ocb->R[x] = ocb->L[x] ^ nonce[x];
}
if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key)) != CRYPT_OK) {
return err;
}
/* find Ls[i] = L << i for i == 0..31 */
XMEMCPY(ocb->Ls[0], ocb->L, ocb->block_len);
for (x = 1; x < 32; x++) {
m = ocb->Ls[x-1][0] >> 7;
for (y = 0; y < ocb->block_len-1; y++) {
ocb->Ls[x][y] = ((ocb->Ls[x-1][y] << 1) | (ocb->Ls[x-1][y+1] >> 7)) & 255;
}
ocb->Ls[x][ocb->block_len-1] = (ocb->Ls[x-1][ocb->block_len-1] << 1) & 255;
if (m == 1) {
for (y = 0; y < ocb->block_len; y++) {
ocb->Ls[x][y] ^= polys[poly].poly_mul[y];
}
}
}
/* find Lr = L / x */
m = ocb->L[ocb->block_len-1] & 1;
/* shift right */
for (x = ocb->block_len - 1; x > 0; x--) {
ocb->Lr[x] = ((ocb->L[x] >> 1) | (ocb->L[x-1] << 7)) & 255;
}
ocb->Lr[0] = ocb->L[0] >> 1;
if (m == 1) {
for (x = 0; x < ocb->block_len; x++) {
ocb->Lr[x] ^= polys[poly].poly_div[x];
}
}
/* set Li, checksum */
zeromem(ocb->Li, ocb->block_len);
zeromem(ocb->checksum, ocb->block_len);
/* set other params */
ocb->block_index = 1;
ocb->cipher = cipher;
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,40 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb_ntz.c
OCB implementation, internal function, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB_MODE
/**
Returns the number of leading zero bits [from lsb up]
@param x The 32-bit value to observe
@return The number of bits [from the lsb up] that are zero
*/
int ocb_ntz(unsigned long x)
{
int c;
x &= 0xFFFFFFFFUL;
c = 0;
while ((x & 1) == 0) {
++c;
x >>= 1;
}
return c;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,37 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb_shift_xor.c
OCB implementation, internal function, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB_MODE
/**
Compute the shift/xor for OCB (internal function)
@param ocb The OCB state
@param Z The destination of the shift
*/
void ocb_shift_xor(ocb_state *ocb, unsigned char *Z)
{
int x, y;
y = ocb_ntz(ocb->block_index++);
for (x = 0; x < ocb->block_len; x++) {
ocb->Li[x] ^= ocb->Ls[y][x];
Z[x] = ocb->Li[x] ^ ocb->R[x];
}
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,215 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb_test.c
OCB implementation, self-test by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB_MODE
/**
Test the OCB protocol
@return CRYPT_OK if successful
*/
int ocb_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int ptlen;
unsigned char key[16], nonce[16], pt[34], ct[34], tag[16];
} tests[] = {
/* OCB-AES-128-0B */
{
0,
/* key */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* nonce */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
/* pt */
{ 0 },
/* ct */
{ 0 },
/* tag */
{ 0x15, 0xd3, 0x7d, 0xd7, 0xc8, 0x90, 0xd5, 0xd6,
0xac, 0xab, 0x92, 0x7b, 0xc0, 0xdc, 0x60, 0xee },
},
/* OCB-AES-128-3B */
{
3,
/* key */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* nonce */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
/* pt */
{ 0x00, 0x01, 0x02 },
/* ct */
{ 0xfc, 0xd3, 0x7d },
/* tag */
{ 0x02, 0x25, 0x47, 0x39, 0xa5, 0xe3, 0x56, 0x5a,
0xe2, 0xdc, 0xd6, 0x2c, 0x65, 0x97, 0x46, 0xba },
},
/* OCB-AES-128-16B */
{
16,
/* key */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* nonce */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
/* pt */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* ct */
{ 0x37, 0xdf, 0x8c, 0xe1, 0x5b, 0x48, 0x9b, 0xf3,
0x1d, 0x0f, 0xc4, 0x4d, 0xa1, 0xfa, 0xf6, 0xd6 },
/* tag */
{ 0xdf, 0xb7, 0x63, 0xeb, 0xdb, 0x5f, 0x0e, 0x71,
0x9c, 0x7b, 0x41, 0x61, 0x80, 0x80, 0x04, 0xdf },
},
/* OCB-AES-128-20B */
{
20,
/* key */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* nonce */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
/* pt */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13 },
/* ct */
{ 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4,
0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb,
0x70, 0x03, 0xeb, 0x55},
/* tag */
{ 0x75, 0x30, 0x84, 0x14, 0x4e, 0xb6, 0x3b, 0x77,
0x0b, 0x06, 0x3c, 0x2e, 0x23, 0xcd, 0xa0, 0xbb },
},
/* OCB-AES-128-32B */
{
32,
/* key */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* nonce */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
/* pt */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
/* ct */
{ 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4,
0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb,
0x4a, 0xfc, 0xbb, 0x7f, 0xed, 0xc0, 0x8c, 0xa8,
0x65, 0x4c, 0x6d, 0x30, 0x4d, 0x16, 0x12, 0xfa },
/* tag */
{ 0xc1, 0x4c, 0xbf, 0x2c, 0x1a, 0x1f, 0x1c, 0x3c,
0x13, 0x7e, 0xad, 0xea, 0x1f, 0x2f, 0x2f, 0xcf },
},
/* OCB-AES-128-34B */
{
34,
/* key */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
/* nonce */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
/* pt */
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21 },
/* ct */
{ 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4,
0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb,
0xd4, 0x90, 0x3d, 0xd0, 0x02, 0x5b, 0xa4, 0xaa,
0x83, 0x7c, 0x74, 0xf1, 0x21, 0xb0, 0x26, 0x0f,
0xa9, 0x5d },
/* tag */
{ 0xcf, 0x83, 0x41, 0xbb, 0x10, 0x82, 0x0c, 0xcf,
0x14, 0xbd, 0xec, 0x56, 0xb8, 0xd7, 0xd6, 0xab },
},
};
int err, x, idx, res;
unsigned long len;
unsigned char outct[MAXBLOCKSIZE], outtag[MAXBLOCKSIZE];
/* AES can be under rijndael or aes... try to find it */
if ((idx = find_cipher("aes")) == -1) {
if ((idx = find_cipher("rijndael")) == -1) {
return CRYPT_NOP;
}
}
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
len = sizeof(outtag);
if ((err = ocb_encrypt_authenticate_memory(idx, tests[x].key, 16,
tests[x].nonce, tests[x].pt, tests[x].ptlen, outct, outtag, &len)) != CRYPT_OK) {
return err;
}
if (compare_testvector(outtag, len, tests[x].tag, sizeof(tests[x].tag), "OCB Tag", x) ||
compare_testvector(outct, tests[x].ptlen, tests[x].ct, tests[x].ptlen, "OCB CT", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
if ((err = ocb_decrypt_verify_memory(idx, tests[x].key, 16, tests[x].nonce, outct, tests[x].ptlen,
outct, tests[x].tag, len, &res)) != CRYPT_OK) {
return err;
}
if ((res != 1) || compare_testvector(outct, tests[x].ptlen, tests[x].pt, tests[x].ptlen, "OCB", x)) {
#ifdef LTC_TEST_DBG
printf("\n\nOCB: Failure-decrypt - res = %d\n", res);
#endif
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif /* LTC_TEST */
}
#endif /* LTC_OCB_MODE */
/* some comments
-- it's hard to seek
-- hard to stream [you can't emit ciphertext until full block]
-- The setup is somewhat complicated...
*/
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,146 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file s_ocb_done.c
OCB implementation, internal helper, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB_MODE
/* Since the last block is encrypted in CTR mode the same code can
* be used to finish a decrypt or encrypt stream. The only difference
* is we XOR the final ciphertext into the checksum so we have to xor it
* before we CTR [decrypt] or after [encrypt]
*
* the names pt/ptlen/ct really just mean in/inlen/out but this is the way I wrote it...
*/
/**
Shared code to finish an OCB stream
@param ocb The OCB state
@param pt The remaining plaintext [or input]
@param ptlen The length of the input (octets)
@param ct [out] The output buffer
@param tag [out] The destination for the authentication tag
@param taglen [in/out] The max size and resulting size of the authentication tag
@param mode The mode we are terminating, 0==encrypt, 1==decrypt
@return CRYPT_OK if successful
*/
int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode)
{
unsigned char *Z, *Y, *X;
int err, x;
LTC_ARGCHK(ocb != NULL);
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(tag != NULL);
LTC_ARGCHK(taglen != NULL);
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
return err;
}
if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length ||
(int)ptlen > ocb->block_len || (int)ptlen < 0) {
return CRYPT_INVALID_ARG;
}
/* allocate ram */
Z = XMALLOC(MAXBLOCKSIZE);
Y = XMALLOC(MAXBLOCKSIZE);
X = XMALLOC(MAXBLOCKSIZE);
if (X == NULL || Y == NULL || Z == NULL) {
if (X != NULL) {
XFREE(X);
}
if (Y != NULL) {
XFREE(Y);
}
if (Z != NULL) {
XFREE(Z);
}
return CRYPT_MEM;
}
/* compute X[m] = len(pt[m]) XOR Lr XOR Z[m] */
ocb_shift_xor(ocb, X);
XMEMCPY(Z, X, ocb->block_len);
X[ocb->block_len-1] ^= (ptlen*8)&255;
X[ocb->block_len-2] ^= ((ptlen*8)>>8)&255;
for (x = 0; x < ocb->block_len; x++) {
X[x] ^= ocb->Lr[x];
}
/* Y[m] = E(X[m])) */
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key)) != CRYPT_OK) {
goto error;
}
if (mode == 1) {
/* decrypt mode, so let's xor it first */
/* xor C[m] into checksum */
for (x = 0; x < (int)ptlen; x++) {
ocb->checksum[x] ^= ct[x];
}
}
/* C[m] = P[m] xor Y[m] */
for (x = 0; x < (int)ptlen; x++) {
ct[x] = pt[x] ^ Y[x];
}
if (mode == 0) {
/* encrypt mode */
/* xor C[m] into checksum */
for (x = 0; x < (int)ptlen; x++) {
ocb->checksum[x] ^= ct[x];
}
}
/* xor Y[m] and Z[m] into checksum */
for (x = 0; x < ocb->block_len; x++) {
ocb->checksum[x] ^= Y[x] ^ Z[x];
}
/* encrypt checksum, er... tag!! */
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key)) != CRYPT_OK) {
goto error;
}
cipher_descriptor[ocb->cipher].done(&ocb->key);
/* now store it */
for (x = 0; x < ocb->block_len && x < (int)*taglen; x++) {
tag[x] = X[x];
}
*taglen = x;
#ifdef LTC_CLEAN_STACK
zeromem(X, MAXBLOCKSIZE);
zeromem(Y, MAXBLOCKSIZE);
zeromem(Z, MAXBLOCKSIZE);
zeromem(ocb, sizeof(*ocb));
#endif
error:
XFREE(X);
XFREE(Y);
XFREE(Z);
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,106 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb3_add_aad.c
OCB implementation, add AAD data, by Karel Miko
*/
#include "tomcrypt.h"
#ifdef LTC_OCB3_MODE
/**
Add one block of AAD data (internal function)
@param ocb The OCB state
@param aad_block [in] AAD data (block_len size)
@return CRYPT_OK if successful
*/
static int _ocb3_int_aad_add_block(ocb3_state *ocb, const unsigned char *aad_block)
{
unsigned char tmp[MAXBLOCKSIZE];
int err;
/* Offset_i = Offset_{i-1} xor L_{ntz(i)} */
ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_[ocb3_int_ntz(ocb->ablock_index)], ocb->block_len);
/* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */
ocb3_int_xor_blocks(tmp, aad_block, ocb->aOffset_current, ocb->block_len);
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
return err;
}
ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len);
ocb->ablock_index++;
return CRYPT_OK;
}
/**
Add AAD - additional associated data
@param ocb The OCB state
@param aad The AAD data
@param aadlen The size of AAD data (octets)
@return CRYPT_OK if successful
*/
int ocb3_add_aad(ocb3_state *ocb, const unsigned char *aad, unsigned long aadlen)
{
int err, x, full_blocks, full_blocks_len, last_block_len;
unsigned char *data;
unsigned long datalen, l;
LTC_ARGCHK(ocb != NULL);
if (aadlen == 0) return CRYPT_OK;
LTC_ARGCHK(aad != NULL);
if (ocb->adata_buffer_bytes > 0) {
l = ocb->block_len - ocb->adata_buffer_bytes;
if (l > aadlen) l = aadlen;
XMEMCPY(ocb->adata_buffer+ocb->adata_buffer_bytes, aad, l);
ocb->adata_buffer_bytes += l;
if (ocb->adata_buffer_bytes == ocb->block_len) {
if ((err = _ocb3_int_aad_add_block(ocb, ocb->adata_buffer)) != CRYPT_OK) {
return err;
}
ocb->adata_buffer_bytes = 0;
}
data = (unsigned char *)aad + l;
datalen = aadlen - l;
}
else {
data = (unsigned char *)aad;
datalen = aadlen;
}
if (datalen == 0) return CRYPT_OK;
full_blocks = datalen/ocb->block_len;
full_blocks_len = full_blocks * ocb->block_len;
last_block_len = datalen - full_blocks_len;
for (x=0; x<full_blocks; x++) {
if ((err = _ocb3_int_aad_add_block(ocb, data+x*ocb->block_len)) != CRYPT_OK) {
return err;
}
}
if (last_block_len>0) {
XMEMCPY(ocb->adata_buffer, data+full_blocks_len, last_block_len);
ocb->adata_buffer_bytes = last_block_len;
}
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,86 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb3_decrypt.c
OCB implementation, decrypt data, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB3_MODE
/**
Decrypt blocks of ciphertext with OCB
@param ocb The OCB state
@param ct The ciphertext (length multiple of the block size of the block cipher)
@param ctlen The length of the input (octets)
@param pt [out] The plaintext (length of ct)
@return CRYPT_OK if successful
*/
int ocb3_decrypt(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt)
{
unsigned char tmp[MAXBLOCKSIZE];
int err, i, full_blocks;
unsigned char *pt_b, *ct_b;
LTC_ARGCHK(ocb != NULL);
if (ctlen == 0) return CRYPT_OK; /* no data, nothing to do */
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(pt != NULL);
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
return err;
}
if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
return CRYPT_INVALID_ARG;
}
if (ctlen % ocb->block_len) { /* ctlen has to bu multiple of block_len */
return CRYPT_INVALID_ARG;
}
full_blocks = ctlen/ocb->block_len;
for(i=0; i<full_blocks; i++) {
pt_b = (unsigned char *)pt+i*ocb->block_len;
ct_b = (unsigned char *)ct+i*ocb->block_len;
/* ocb->Offset_current[] = ocb->Offset_current[] ^ Offset_{ntz(block_index)} */
ocb3_int_xor_blocks(ocb->Offset_current, ocb->Offset_current, ocb->L_[ocb3_int_ntz(ocb->block_index)], ocb->block_len);
/* tmp[] = ct[] XOR ocb->Offset_current[] */
ocb3_int_xor_blocks(tmp, ct_b, ocb->Offset_current, ocb->block_len);
/* decrypt */
if ((err = cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
goto LBL_ERR;
}
/* pt[] = tmp[] XOR ocb->Offset_current[] */
ocb3_int_xor_blocks(pt_b, tmp, ocb->Offset_current, ocb->block_len);
/* ocb->checksum[] = ocb->checksum[] XOR pt[] */
ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt_b, ocb->block_len);
ocb->block_index++;
}
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(tmp, sizeof(tmp));
#endif
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,110 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb3_decrypt_last.c
OCB implementation, internal helper, by Karel Miko
*/
#include "tomcrypt.h"
#ifdef LTC_OCB3_MODE
/**
Finish an OCB (decryption) stream
@param ocb The OCB state
@param ct The remaining ciphertext
@param ctlen The length of the ciphertext (octets)
@param pt [out] The output buffer
@return CRYPT_OK if successful
*/
int ocb3_decrypt_last(ocb3_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt)
{
unsigned char iOffset_star[MAXBLOCKSIZE];
unsigned char iPad[MAXBLOCKSIZE];
int err, x, full_blocks, full_blocks_len, last_block_len;
LTC_ARGCHK(ocb != NULL);
if (ct == NULL) LTC_ARGCHK(ctlen == 0);
if (ctlen != 0) {
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(pt != NULL);
}
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
goto LBL_ERR;
}
full_blocks = ctlen/ocb->block_len;
full_blocks_len = full_blocks * ocb->block_len;
last_block_len = ctlen - full_blocks_len;
/* process full blocks first */
if (full_blocks>0) {
if ((err = ocb3_decrypt(ocb, ct, full_blocks_len, pt)) != CRYPT_OK) {
goto LBL_ERR;
}
}
if (last_block_len>0) {
/* Offset_* = Offset_m xor L_* */
ocb3_int_xor_blocks(iOffset_star, ocb->Offset_current, ocb->L_star, ocb->block_len);
/* Pad = ENCIPHER(K, Offset_*) */
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) {
goto LBL_ERR;
}
/* P_* = C_* xor Pad[1..bitlen(C_*)] */
ocb3_int_xor_blocks(pt+full_blocks_len, (unsigned char *)ct+full_blocks_len, iPad, last_block_len);
/* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt+full_blocks_len, last_block_len);
for(x=last_block_len; x<ocb->block_len; x++) {
if (x == last_block_len)
ocb->checksum[x] ^= 0x80;
else
ocb->checksum[x] ^= 0x00;
}
/* Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) */
/* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) */
for(x=0; x<ocb->block_len; x++) {
ocb->tag_part[x] = (ocb->checksum[x] ^ iOffset_star[x]) ^ ocb->L_dollar[x];
}
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
goto LBL_ERR;
}
}
else {
/* Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K,A) */
/* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) */
for(x=0; x<ocb->block_len; x++) {
ocb->tag_part[x] = (ocb->checksum[x] ^ ocb->Offset_current[x]) ^ ocb->L_dollar[x];
}
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
goto LBL_ERR;
}
}
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(iOffset_star, MAXBLOCKSIZE);
zeromem(iPad, MAXBLOCKSIZE);
#endif
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,110 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb3_decrypt_verify_memory.c
OCB implementation, helper to decrypt block of memory, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB3_MODE
/**
Decrypt and compare the tag with OCB
@param cipher The index of the cipher desired
@param key The secret key
@param keylen The length of the secret key (octets)
@param nonce The session nonce (length of the block size of the block cipher)
@param noncelen The length of the nonce (octets)
@param adata The AAD - additional associated data
@param adatalen The length of AAD (octets)
@param ct The ciphertext
@param ctlen The length of the ciphertext (octets)
@param pt [out] The plaintext
@param tag The tag to compare against
@param taglen The length of the tag (octets)
@param stat [out] The result of the tag comparison (1==valid, 0==invalid)
@return CRYPT_OK if successful regardless of the tag comparison
*/
int ocb3_decrypt_verify_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *adata, unsigned long adatalen,
const unsigned char *ct, unsigned long ctlen,
unsigned char *pt,
const unsigned char *tag, unsigned long taglen,
int *stat)
{
int err;
ocb3_state *ocb;
unsigned char *buf;
unsigned long buflen;
LTC_ARGCHK(stat != NULL);
/* default to zero */
*stat = 0;
/* limit taglen */
taglen = MIN(taglen, MAXBLOCKSIZE);
/* allocate memory */
buf = XMALLOC(taglen);
ocb = XMALLOC(sizeof(ocb3_state));
if (ocb == NULL || buf == NULL) {
if (ocb != NULL) {
XFREE(ocb);
}
if (buf != NULL) {
XFREE(buf);
}
return CRYPT_MEM;
}
if ((err = ocb3_init(ocb, cipher, key, keylen, nonce, noncelen, taglen)) != CRYPT_OK) {
goto LBL_ERR;
}
if (adata != NULL || adatalen != 0) {
if ((err = ocb3_add_aad(ocb, adata, adatalen)) != CRYPT_OK) {
goto LBL_ERR;
}
}
if ((err = ocb3_decrypt_last(ocb, ct, ctlen, pt)) != CRYPT_OK) {
goto LBL_ERR;
}
buflen = taglen;
if ((err = ocb3_done(ocb, buf, &buflen)) != CRYPT_OK) {
goto LBL_ERR;
}
/* compare tags */
if (buflen >= taglen && XMEM_NEQ(buf, tag, taglen) == 0) {
*stat = 1;
}
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(ocb, sizeof(ocb3_state));
#endif
XFREE(ocb);
XFREE(buf);
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,92 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb3_done.c
OCB implementation, INTERNAL ONLY helper, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB3_MODE
/**
Finish OCB processing and compute the tag
@param ocb The OCB state
@param tag [out] The destination for the authentication tag
@param taglen [in/out] The max size and resulting size of the authentication tag
@return CRYPT_OK if successful
*/
int ocb3_done(ocb3_state *ocb, unsigned char *tag, unsigned long *taglen)
{
unsigned char tmp[MAXBLOCKSIZE];
int err, x;
LTC_ARGCHK(ocb != NULL);
LTC_ARGCHK(tag != NULL);
LTC_ARGCHK(taglen != NULL);
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
goto LBL_ERR;
}
/* check taglen */
if ((int)*taglen < ocb->tag_len) {
*taglen = (unsigned long)ocb->tag_len;
return CRYPT_BUFFER_OVERFLOW;
}
/* finalize AAD processing */
if (ocb->adata_buffer_bytes>0) {
/* Offset_* = Offset_m xor L_* */
ocb3_int_xor_blocks(ocb->aOffset_current, ocb->aOffset_current, ocb->L_star, ocb->block_len);
/* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */
ocb3_int_xor_blocks(tmp, ocb->adata_buffer, ocb->aOffset_current, ocb->adata_buffer_bytes);
for(x=ocb->adata_buffer_bytes; x<ocb->block_len; x++) {
if (x == ocb->adata_buffer_bytes) {
tmp[x] = 0x80 ^ ocb->aOffset_current[x];
}
else {
tmp[x] = 0x00 ^ ocb->aOffset_current[x];
}
}
/* Sum = Sum_m xor ENCIPHER(K, CipherInput) */
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
goto LBL_ERR;
}
ocb3_int_xor_blocks(ocb->aSum_current, ocb->aSum_current, tmp, ocb->block_len);
}
/* finalize TAG computing */
/* at this point ocb->aSum_current = HASH(K, A) */
/* tag = tag ^ HASH(K, A) */
ocb3_int_xor_blocks(tmp, ocb->tag_part, ocb->aSum_current, ocb->block_len);
/* copy tag bytes */
for(x = 0; x < ocb->tag_len; x++) tag[x] = tmp[x];
*taglen = (unsigned long)ocb->tag_len;
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(tmp, MAXBLOCKSIZE);
zeromem(ocb, sizeof(*ocb));
#endif
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,86 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb3_encrypt.c
OCB implementation, encrypt data, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB3_MODE
/**
Encrypt blocks of data with OCB
@param ocb The OCB state
@param pt The plaintext (length multiple of the block size of the block cipher)
@param ptlen The length of the input (octets)
@param ct [out] The ciphertext (same size as the pt)
@return CRYPT_OK if successful
*/
int ocb3_encrypt(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct)
{
unsigned char tmp[MAXBLOCKSIZE];
int err, i, full_blocks;
unsigned char *pt_b, *ct_b;
LTC_ARGCHK(ocb != NULL);
if (ptlen == 0) return CRYPT_OK; /* no data, nothing to do */
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
return err;
}
if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
return CRYPT_INVALID_ARG;
}
if (ptlen % ocb->block_len) { /* ptlen has to bu multiple of block_len */
return CRYPT_INVALID_ARG;
}
full_blocks = ptlen/ocb->block_len;
for(i=0; i<full_blocks; i++) {
pt_b = (unsigned char *)pt+i*ocb->block_len;
ct_b = (unsigned char *)ct+i*ocb->block_len;
/* ocb->Offset_current[] = ocb->Offset_current[] ^ Offset_{ntz(block_index)} */
ocb3_int_xor_blocks(ocb->Offset_current, ocb->Offset_current, ocb->L_[ocb3_int_ntz(ocb->block_index)], ocb->block_len);
/* tmp[] = pt[] XOR ocb->Offset_current[] */
ocb3_int_xor_blocks(tmp, pt_b, ocb->Offset_current, ocb->block_len);
/* encrypt */
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, tmp, &ocb->key)) != CRYPT_OK) {
goto LBL_ERR;
}
/* ct[] = tmp[] XOR ocb->Offset_current[] */
ocb3_int_xor_blocks(ct_b, tmp, ocb->Offset_current, ocb->block_len);
/* ocb->checksum[] = ocb->checksum[] XOR pt[] */
ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt_b, ocb->block_len);
ocb->block_index++;
}
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(tmp, sizeof(tmp));
#endif
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,82 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb3_encrypt_authenticate_memory.c
OCB implementation, encrypt block of memory, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB3_MODE
/**
Encrypt and generate an authentication code for a buffer of memory
@param cipher The index of the cipher desired
@param key The secret key
@param keylen The length of the secret key (octets)
@param nonce The session nonce (length of the block ciphers block size)
@param noncelen The length of the nonce (octets)
@param adata The AAD - additional associated data
@param adatalen The length of AAD (octets)
@param pt The plaintext
@param ptlen The length of the plaintext (octets)
@param ct [out] The ciphertext
@param tag [out] The authentication tag
@param taglen [in/out] The max size and resulting size of the authentication tag
@return CRYPT_OK if successful
*/
int ocb3_encrypt_authenticate_memory(int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce, unsigned long noncelen,
const unsigned char *adata, unsigned long adatalen,
const unsigned char *pt, unsigned long ptlen,
unsigned char *ct,
unsigned char *tag, unsigned long *taglen)
{
int err;
ocb3_state *ocb;
LTC_ARGCHK(taglen != NULL);
/* allocate memory */
ocb = XMALLOC(sizeof(ocb3_state));
if (ocb == NULL) {
return CRYPT_MEM;
}
if ((err = ocb3_init(ocb, cipher, key, keylen, nonce, noncelen, *taglen)) != CRYPT_OK) {
goto LBL_ERR;
}
if (adata != NULL || adatalen != 0) {
if ((err = ocb3_add_aad(ocb, adata, adatalen)) != CRYPT_OK) {
goto LBL_ERR;
}
}
if ((err = ocb3_encrypt_last(ocb, pt, ptlen, ct)) != CRYPT_OK) {
goto LBL_ERR;
}
err = ocb3_done(ocb, tag, taglen);
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(ocb, sizeof(ocb3_state));
#endif
XFREE(ocb);
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,112 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb3_encrypt_last.c
OCB implementation, internal helper, by Karel Miko
*/
#include "tomcrypt.h"
#ifdef LTC_OCB3_MODE
/**
Finish an OCB (encryption) stream
@param ocb The OCB state
@param pt The remaining plaintext
@param ptlen The length of the plaintext (octets)
@param ct [out] The output buffer
@return CRYPT_OK if successful
*/
int ocb3_encrypt_last(ocb3_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct)
{
unsigned char iOffset_star[MAXBLOCKSIZE];
unsigned char iPad[MAXBLOCKSIZE];
int err, x, full_blocks, full_blocks_len, last_block_len;
LTC_ARGCHK(ocb != NULL);
if (pt == NULL) LTC_ARGCHK(ptlen == 0);
if (ptlen != 0) {
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
}
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
goto LBL_ERR;
}
full_blocks = ptlen/ocb->block_len;
full_blocks_len = full_blocks * ocb->block_len;
last_block_len = ptlen - full_blocks_len;
/* process full blocks first */
if (full_blocks>0) {
if ((err = ocb3_encrypt(ocb, pt, full_blocks_len, ct)) != CRYPT_OK) {
goto LBL_ERR;
}
}
/* at this point: m = ocb->block_index (last block index), Offset_m = ocb->Offset_current */
if (last_block_len>0) {
/* Offset_* = Offset_m xor L_* */
ocb3_int_xor_blocks(iOffset_star, ocb->Offset_current, ocb->L_star, ocb->block_len);
/* Pad = ENCIPHER(K, Offset_*) */
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(iOffset_star, iPad, &ocb->key)) != CRYPT_OK) {
goto LBL_ERR;
}
/* C_* = P_* xor Pad[1..bitlen(P_*)] */
ocb3_int_xor_blocks(ct+full_blocks_len, pt+full_blocks_len, iPad, last_block_len);
/* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */
ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt+full_blocks_len, last_block_len);
for(x=last_block_len; x<ocb->block_len; x++) {
if (x == last_block_len)
ocb->checksum[x] ^= 0x80;
else
ocb->checksum[x] ^= 0x00;
}
/* Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) */
/* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) */
for(x=0; x<ocb->block_len; x++) {
ocb->tag_part[x] = (ocb->checksum[x] ^ iOffset_star[x]) ^ ocb->L_dollar[x];
}
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
goto LBL_ERR;
}
}
else {
/* Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K,A) */
/* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) */
for(x=0; x<ocb->block_len; x++) {
ocb->tag_part[x] = (ocb->checksum[x] ^ ocb->Offset_current[x]) ^ ocb->L_dollar[x];
}
if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) {
goto LBL_ERR;
}
}
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(iOffset_star, MAXBLOCKSIZE);
zeromem(iPad, MAXBLOCKSIZE);
#endif
return err;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,196 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb3_init.c
OCB implementation, initialize state, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB3_MODE
static void _ocb3_int_calc_offset_zero(ocb3_state *ocb, const unsigned char *nonce, unsigned long noncelen, unsigned long taglen)
{
int x, y, bottom;
int idx, shift;
unsigned char iNonce[MAXBLOCKSIZE];
unsigned char iKtop[MAXBLOCKSIZE];
unsigned char iStretch[MAXBLOCKSIZE+8];
/* Nonce = zeros(127-bitlen(N)) || 1 || N */
zeromem(iNonce, sizeof(iNonce));
for (x = ocb->block_len-1, y=0; y<(int)noncelen; x--, y++) {
iNonce[x] = nonce[noncelen-y-1];
}
iNonce[x] = 0x01;
iNonce[0] |= ((taglen*8) % 128) << 1;
/* bottom = str2num(Nonce[123..128]) */
bottom = iNonce[ocb->block_len-1] & 0x3F;
/* Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6)) */
iNonce[ocb->block_len-1] = iNonce[ocb->block_len-1] & 0xC0;
if ((cipher_descriptor[ocb->cipher].ecb_encrypt(iNonce, iKtop, &ocb->key)) != CRYPT_OK) {
zeromem(ocb->Offset_current, ocb->block_len);
return;
}
/* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */
for (x = 0; x < ocb->block_len; x++) {
iStretch[x] = iKtop[x];
}
for (y = 0; y < 8; y++) {
iStretch[x+y] = iKtop[y] ^ iKtop[y+1];
}
/* Offset_0 = Stretch[1+bottom..128+bottom] */
idx = bottom / 8;
shift = (bottom % 8);
for (x = 0; x < ocb->block_len; x++) {
ocb->Offset_current[x] = iStretch[idx+x] << shift;
if (shift > 0) {
ocb->Offset_current[x] |= iStretch[idx+x+1] >> (8-shift);
}
}
}
static const struct {
int len;
unsigned char poly_mul[MAXBLOCKSIZE];
} polys[] = {
{
8,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B }
}, {
16,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }
}
};
/**
Initialize an OCB context
@param ocb [out] The destination of the OCB state
@param cipher The index of the desired cipher
@param key The secret key
@param keylen The length of the secret key (octets)
@param nonce The session nonce
@param noncelen The length of the session nonce (octets, up to 15)
@param taglen The length of the tag (octets, up to 16)
@return CRYPT_OK if successful
*/
int ocb3_init(ocb3_state *ocb, int cipher,
const unsigned char *key, unsigned long keylen,
const unsigned char *nonce, unsigned long noncelen,
unsigned long taglen)
{
int poly, x, y, m, err;
unsigned char *previous, *current;
LTC_ARGCHK(ocb != NULL);
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(nonce != NULL);
/* valid cipher? */
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
ocb->cipher = cipher;
/* Valid Nonce?
* As of RFC7253: "string of no more than 120 bits" */
if (noncelen > (120/8)) {
return CRYPT_INVALID_ARG;
}
/* The blockcipher must have a 128-bit blocksize */
if (cipher_descriptor[cipher].block_length != 16) {
return CRYPT_INVALID_ARG;
}
/* The TAGLEN may be any value up to 128 (bits) */
if (taglen > 16) {
return CRYPT_INVALID_ARG;
}
ocb->tag_len = taglen;
/* determine which polys to use */
ocb->block_len = cipher_descriptor[cipher].block_length;
x = (int)(sizeof(polys)/sizeof(polys[0]));
for (poly = 0; poly < x; poly++) {
if (polys[poly].len == ocb->block_len) {
break;
}
}
if (poly == x) {
return CRYPT_INVALID_ARG; /* block_len not found in polys */
}
if (polys[poly].len != ocb->block_len) {
return CRYPT_INVALID_ARG;
}
/* schedule the key */
if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) {
return err;
}
/* L_* = ENCIPHER(K, zeros(128)) */
zeromem(ocb->L_star, ocb->block_len);
if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L_star, ocb->L_star, &ocb->key)) != CRYPT_OK) {
return err;
}
/* compute L_$, L_0, L_1, ... */
for (x = -1; x < 32; x++) {
if (x == -1) { /* gonna compute: L_$ = double(L_*) */
current = ocb->L_dollar;
previous = ocb->L_star;
}
else if (x == 0) { /* gonna compute: L_0 = double(L_$) */
current = ocb->L_[0];
previous = ocb->L_dollar;
}
else { /* gonna compute: L_i = double(L_{i-1}) for every integer i > 0 */
current = ocb->L_[x];
previous = ocb->L_[x-1];
}
m = previous[0] >> 7;
for (y = 0; y < ocb->block_len-1; y++) {
current[y] = ((previous[y] << 1) | (previous[y+1] >> 7)) & 255;
}
current[ocb->block_len-1] = (previous[ocb->block_len-1] << 1) & 255;
if (m == 1) {
/* current[] = current[] XOR polys[poly].poly_mul[]*/
ocb3_int_xor_blocks(current, current, polys[poly].poly_mul, ocb->block_len);
}
}
/* initialize ocb->Offset_current = Offset_0 */
_ocb3_int_calc_offset_zero(ocb, nonce, noncelen, taglen);
/* initialize checksum to all zeros */
zeromem(ocb->checksum, ocb->block_len);
/* set block index */
ocb->block_index = 1;
/* initialize AAD related stuff */
ocb->ablock_index = 1;
ocb->adata_buffer_bytes = 0;
zeromem(ocb->aOffset_current, ocb->block_len);
zeromem(ocb->aSum_current, ocb->block_len);
return CRYPT_OK;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,39 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb3_int_ntz.c
OCB implementation, INTERNAL ONLY helper, by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB3_MODE
/**
Returns the number of leading zero bits [from lsb up] (internal function)
@param x The 32-bit value to observe
@return The number of bits [from the lsb up] that are zero
*/
int ocb3_int_ntz(unsigned long x)
{
int c;
x &= 0xFFFFFFFFUL;
c = 0;
while ((x & 1) == 0) {
++c;
x >>= 1;
}
return c;
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,40 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb3_int_xor_blocks.c
OCB implementation, INTERNAL ONLY helper, by Karel Miko
*/
#include "tomcrypt.h"
#ifdef LTC_OCB3_MODE
/**
Compute xor for two blocks of bytes 'out = block_a XOR block_b' (internal function)
@param out The block of bytes (output)
@param block_a The block of bytes (input)
@param block_b The block of bytes (input)
@param block_len The size of block_a, block_b, out
*/
void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const unsigned char *block_b, unsigned long block_len)
{
int x;
if (out == block_a) {
for (x = 0; x < (int)block_len; x++) out[x] ^= block_b[x];
}
else {
for (x = 0; x < (int)block_len; x++) out[x] = block_a[x] ^ block_b[x];
}
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,309 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@file ocb3_test.c
OCB implementation, self-test by Tom St Denis
*/
#include "tomcrypt.h"
#ifdef LTC_OCB3_MODE
/**
Test the OCB protocol
@return CRYPT_OK if successful
*/
int ocb3_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
/* test vectors from: http://tools.ietf.org/html/draft-krovetz-ocb-03 */
unsigned char key[16] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F };
unsigned char nonce[12] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B };
const struct {
int ptlen;
int aadlen;
unsigned char pt[64], aad[64], ct[64], tag[16];
} tests[] = {
{ /* index:0 */
0, /* PLAINTEXT length */
0, /* AAD length */
{ 0 }, /* PLAINTEXT */
{ 0 }, /* AAD */
{ 0 }, /* CIPHERTEXT */
{ 0x19,0x7b,0x9c,0x3c,0x44,0x1d,0x3c,0x83,0xea,0xfb,0x2b,0xef,0x63,0x3b,0x91,0x82 }, /* TAG */
},
{ /* index:1 */
8, /* PLAINTEXT length */
8, /* AAD length */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 }, /* PLAINTEXT */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 }, /* AAD */
{ 0x92,0xb6,0x57,0x13,0x0a,0x74,0xb8,0x5a }, /* CIPHERTEXT */
{ 0x16,0xdc,0x76,0xa4,0x6d,0x47,0xe1,0xea,0xd5,0x37,0x20,0x9e,0x8a,0x96,0xd1,0x4e }, /* TAG */
},
{ /* index:2 */
0, /* PLAINTEXT length */
8, /* AAD length */
{ 0 }, /* PLAINTEXT */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 }, /* AAD */
{ 0 }, /* CIPHERTEXT */
{ 0x98,0xb9,0x15,0x52,0xc8,0xc0,0x09,0x18,0x50,0x44,0xe3,0x0a,0x6e,0xb2,0xfe,0x21 }, /* TAG */
},
{ /* index:3 */
8, /* PLAINTEXT length */
0, /* AAD length */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 }, /* PLAINTEXT */
{ 0 }, /* AAD */
{ 0x92,0xb6,0x57,0x13,0x0a,0x74,0xb8,0x5a }, /* CIPHERTEXT */
{ 0x97,0x1e,0xff,0xca,0xe1,0x9a,0xd4,0x71,0x6f,0x88,0xe8,0x7b,0x87,0x1f,0xbe,0xed }, /* TAG */
},
{ /* index:4 */
16, /* PLAINTEXT length */
16, /* AAD length */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }, /* PLAINTEXT */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }, /* AAD */
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22 }, /* CIPHERTEXT */
{ 0x77,0x6c,0x99,0x24,0xd6,0x72,0x3a,0x1f,0xc4,0x52,0x45,0x32,0xac,0x3e,0x5b,0xeb }, /* TAG */
},
{ /* index:5 */
0, /* PLAINTEXT length */
16, /* AAD length */
{ 0 }, /* PLAINTEXT */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }, /* AAD */
{ 0 }, /* CIPHERTEXT */
{ 0x7d,0xdb,0x8e,0x6c,0xea,0x68,0x14,0x86,0x62,0x12,0x50,0x96,0x19,0xb1,0x9c,0xc6 }, /* TAG */
},
{ /* index:6 */
16, /* PLAINTEXT length */
0, /* AAD length */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f }, /* PLAINTEXT */
{ 0 }, /* AAD */
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22 }, /* CIPHERTEXT */
{ 0x13,0xcc,0x8b,0x74,0x78,0x07,0x12,0x1a,0x4c,0xbb,0x3e,0x4b,0xd6,0xb4,0x56,0xaf }, /* TAG */
},
{ /* index:7 */
24, /* PLAINTEXT length */
24, /* AAD length */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 }, /* PLAINTEXT */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 }, /* AAD */
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22,0xfc,0xfc,0xee,0x7a,0x2a,0x8d,0x4d,0x48 }, /* CIPHERTEXT */
{ 0x5f,0xa9,0x4f,0xc3,0xf3,0x88,0x20,0xf1,0xdc,0x3f,0x3d,0x1f,0xd4,0xe5,0x5e,0x1c }, /* TAG */
},
{ /* index:8 */
0, /* PLAINTEXT length */
24, /* AAD length */
{ 0 }, /* PLAINTEXT */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 }, /* AAD */
{ 0 }, /* CIPHERTEXT */
{ 0x28,0x20,0x26,0xda,0x30,0x68,0xbc,0x9f,0xa1,0x18,0x68,0x1d,0x55,0x9f,0x10,0xf6 }, /* TAG */
},
{ /* index:9 */
24, /* PLAINTEXT length */
0, /* AAD length */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 }, /* PLAINTEXT */
{ 0 }, /* AAD */
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22,0xfc,0xfc,0xee,0x7a,0x2a,0x8d,0x4d,0x48 }, /* CIPHERTEXT */
{ 0x6e,0xf2,0xf5,0x25,0x87,0xfd,0xa0,0xed,0x97,0xdc,0x7e,0xed,0xe2,0x41,0xdf,0x68 }, /* TAG */
},
{ /* index:10 */
32, /* PLAINTEXT length */
32, /* AAD length */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f }, /* PLAINTEXT */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f }, /* AAD */
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22,0xce,0xaa,0xb9,0xb0,0x5d,0xf7,0x71,0xa6,0x57,0x14,0x9d,0x53,0x77,0x34,0x63,0xcb }, /* CIPHERTEXT */
{ 0xb2,0xa0,0x40,0xdd,0x3b,0xd5,0x16,0x43,0x72,0xd7,0x6d,0x7b,0xb6,0x82,0x42,0x40 }, /* TAG */
},
{ /* index:11 */
0, /* PLAINTEXT length */
32, /* AAD length */
{ 0 }, /* PLAINTEXT */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f }, /* AAD */
{ 0 }, /* CIPHERTEXT */
{ 0xe1,0xe0,0x72,0x63,0x3b,0xad,0xe5,0x1a,0x60,0xe8,0x59,0x51,0xd9,0xc4,0x2a,0x1b }, /* TAG */
},
{ /* index:12 */
32, /* PLAINTEXT length */
0, /* AAD length */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f }, /* PLAINTEXT */
{ 0 }, /* AAD */
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22,0xce,0xaa,0xb9,0xb0,0x5d,0xf7,0x71,0xa6,0x57,0x14,0x9d,0x53,0x77,0x34,0x63,0xcb }, /* CIPHERTEXT */
{ 0x4a,0x3b,0xae,0x82,0x44,0x65,0xcf,0xda,0xf8,0xc4,0x1f,0xc5,0x0c,0x7d,0xf9,0xd9 }, /* TAG */
},
{ /* index:13 */
40, /* PLAINTEXT length */
40, /* AAD length */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 }, /* PLAINTEXT */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 }, /* AAD */
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22,0xce,0xaa,0xb9,0xb0,0x5d,0xf7,0x71,0xa6,0x57,0x14,0x9d,0x53,0x77,0x34,0x63,0xcb,0x68,0xc6,0x57,0x78,0xb0,0x58,0xa6,0x35 }, /* CIPHERTEXT */
{ 0x65,0x9c,0x62,0x32,0x11,0xde,0xea,0x0d,0xe3,0x0d,0x2c,0x38,0x18,0x79,0xf4,0xc8 }, /* TAG */
},
{ /* index:14 */
0, /* PLAINTEXT length */
40, /* AAD length */
{ 0 }, /* PLAINTEXT */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 }, /* AAD */
{ 0 }, /* CIPHERTEXT */
{ 0x7a,0xeb,0x7a,0x69,0xa1,0x68,0x7d,0xd0,0x82,0xca,0x27,0xb0,0xd9,0xa3,0x70,0x96 }, /* TAG */
},
{ /* index:15 */
40, /* PLAINTEXT length */
0, /* AAD length */
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 }, /* PLAINTEXT */
{ 0 }, /* AAD */
{ 0xbe,0xa5,0xe8,0x79,0x8d,0xbe,0x71,0x10,0x03,0x1c,0x14,0x4d,0xa0,0xb2,0x61,0x22,0xce,0xaa,0xb9,0xb0,0x5d,0xf7,0x71,0xa6,0x57,0x14,0x9d,0x53,0x77,0x34,0x63,0xcb,0x68,0xc6,0x57,0x78,0xb0,0x58,0xa6,0x35 }, /* CIPHERTEXT */
{ 0x06,0x0c,0x84,0x67,0xf4,0xab,0xab,0x5e,0x8b,0x3c,0x20,0x67,0xa2,0xe1,0x15,0xdc }, /* TAG */
},
};
/* As of RFC 7253 - 'Appendix A. Sample Results'
* The next tuple shows a result with a tag length of 96 bits and a
different key.
K: 0F0E0D0C0B0A09080706050403020100
N: BBAA9988776655443322110D
A: 000102030405060708090A0B0C0D0E0F1011121314151617
18191A1B1C1D1E1F2021222324252627
P: 000102030405060708090A0B0C0D0E0F1011121314151617
18191A1B1C1D1E1F2021222324252627
C: 1792A4E31E0755FB03E31B22116E6C2DDF9EFD6E33D536F1
A0124B0A55BAE884ED93481529C76B6AD0C515F4D1CDD4FD
AC4F02AA
The C has been split up in C and T (tag)
*/
const unsigned char K[] = { 0x0F,0x0E,0x0D,0x0C,0x0B,0x0A,0x09,0x08,
0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 };
const unsigned char N[] = { 0xBB,0xAA,0x99,0x88,0x77,0x66,0x55,0x44,
0x33,0x22,0x11,0x0D };
const unsigned char A[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 };
const unsigned char P[] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 };
const unsigned char C[] = { 0x17,0x92,0xA4,0xE3,0x1E,0x07,0x55,0xFB,
0x03,0xE3,0x1B,0x22,0x11,0x6E,0x6C,0x2D,
0xDF,0x9E,0xFD,0x6E,0x33,0xD5,0x36,0xF1,
0xA0,0x12,0x4B,0x0A,0x55,0xBA,0xE8,0x84,
0xED,0x93,0x48,0x15,0x29,0xC7,0x6B,0x6A };
const unsigned char T[] = { 0xD0,0xC5,0x15,0xF4,0xD1,0xCD,0xD4,0xFD,
0xAC,0x4F,0x02,0xAA };
int err, x, idx, res;
unsigned long len;
unsigned char outct[MAXBLOCKSIZE] = { 0 };
unsigned char outtag[MAXBLOCKSIZE] = { 0 };
ocb3_state ocb;
/* AES can be under rijndael or aes... try to find it */
if ((idx = find_cipher("aes")) == -1) {
if ((idx = find_cipher("rijndael")) == -1) {
return CRYPT_NOP;
}
}
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
len = 16; /* must be the same as the required taglen */
if ((err = ocb3_encrypt_authenticate_memory(idx,
key, sizeof(key),
nonce, sizeof(nonce),
tests[x].aadlen != 0 ? tests[x].aad : NULL, tests[x].aadlen,
tests[x].ptlen != 0 ? tests[x].pt : NULL, tests[x].ptlen,
tests[x].ptlen != 0 ? outct : NULL, outtag, &len)) != CRYPT_OK) {
return err;
}
if (compare_testvector(outtag, len, tests[x].tag, sizeof(tests[x].tag), "OCB3 Tag", x) ||
compare_testvector(outct, tests[x].ptlen, tests[x].ct, tests[x].ptlen, "OCB3 CT", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
if ((err = ocb3_decrypt_verify_memory(idx,
key, sizeof(key),
nonce, sizeof(nonce),
tests[x].aadlen != 0 ? tests[x].aad : NULL, tests[x].aadlen,
tests[x].ptlen != 0 ? outct : NULL, tests[x].ptlen,
tests[x].ptlen != 0 ? outct : NULL, tests[x].tag, len, &res)) != CRYPT_OK) {
return err;
}
if ((res != 1) || compare_testvector(outct, tests[x].ptlen, tests[x].pt, tests[x].ptlen, "OCB3", x)) {
#ifdef LTC_TEST_DBG
printf("\n\nOCB3: Failure-decrypt - res = %d\n", res);
#endif
return CRYPT_FAIL_TESTVECTOR;
}
}
/* RFC 7253 - test vector with a tag length of 96 bits - part 1 */
x = 99;
len = 12;
if ((err = ocb3_encrypt_authenticate_memory(idx,
K, sizeof(K),
N, sizeof(N),
A, sizeof(A),
P, sizeof(P),
outct, outtag, &len)) != CRYPT_OK) {
return err;
}
if (compare_testvector(outtag, len, T, sizeof(T), "OCB3 Tag", x) ||
compare_testvector(outct, sizeof(P), C, sizeof(C), "OCB3 CT", x)) {
return CRYPT_FAIL_TESTVECTOR;
}
if ((err = ocb3_decrypt_verify_memory(idx,
K, sizeof(K),
N, sizeof(N),
A, sizeof(A),
C, sizeof(C),
outct, T, sizeof(T), &res)) != CRYPT_OK) {
return err;
}
if ((res != 1) || compare_testvector(outct, sizeof(C), P, sizeof(P), "OCB3", x)) {
#ifdef LTC_TEST_DBG
printf("\n\nOCB3: Failure-decrypt - res = %d\n", res);
#endif
return CRYPT_FAIL_TESTVECTOR;
}
/* RFC 7253 - test vector with a tag length of 96 bits - part 2 */
x = 100;
if ((err = ocb3_init(&ocb, idx, K, sizeof(K), N, sizeof(N), 12)) != CRYPT_OK) return err;
if ((err = ocb3_add_aad(&ocb, A, sizeof(A))) != CRYPT_OK) return err;
if ((err = ocb3_encrypt(&ocb, P, 32, outct)) != CRYPT_OK) return err;
if ((err = ocb3_encrypt_last(&ocb, P+32, sizeof(P)-32, outct+32)) != CRYPT_OK) return err;
len = sizeof(outtag); /* intentionally more than 12 */
if ((err = ocb3_done(&ocb, outtag, &len)) != CRYPT_OK) return err;
if (compare_testvector(outct, sizeof(P), C, sizeof(C), "OCB3 CT", x)) return CRYPT_FAIL_TESTVECTOR;
if (compare_testvector(outtag, len, T, sizeof(T), "OCB3 Tag.enc", x)) return CRYPT_FAIL_TESTVECTOR;
if ((err = ocb3_init(&ocb, idx, K, sizeof(K), N, sizeof(N), 12)) != CRYPT_OK) return err;
if ((err = ocb3_add_aad(&ocb, A, sizeof(A))) != CRYPT_OK) return err;
if ((err = ocb3_decrypt(&ocb, C, 32, outct)) != CRYPT_OK) return err;
if ((err = ocb3_decrypt_last(&ocb, C+32, sizeof(C)-32, outct+32)) != CRYPT_OK) return err;
len = sizeof(outtag); /* intentionally more than 12 */
if ((err = ocb3_done(&ocb, outtag, &len)) != CRYPT_OK) return err;
if (compare_testvector(outct, sizeof(C), P, sizeof(P), "OCB3 PT", x)) return CRYPT_FAIL_TESTVECTOR;
if (compare_testvector(outtag, len, T, sizeof(T), "OCB3 Tag.dec", x)) return CRYPT_FAIL_TESTVECTOR;
return CRYPT_OK;
#endif /* LTC_TEST */
}
#endif /* LTC_OCB3_MODE */
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

588
thirdparty/libtomcrypt/hashes/blake2b.c vendored Normal file
View File

@@ -0,0 +1,588 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/
/* see also https://www.ietf.org/rfc/rfc7693.txt */
#include "tomcrypt.h"
#ifdef LTC_BLAKE2B
enum blake2b_constant {
BLAKE2B_BLOCKBYTES = 128,
BLAKE2B_OUTBYTES = 64,
BLAKE2B_KEYBYTES = 64,
BLAKE2B_SALTBYTES = 16,
BLAKE2B_PERSONALBYTES = 16,
BLAKE2B_PARAM_SIZE = 64
};
/* param offsets */
enum {
O_DIGEST_LENGTH = 0,
O_KEY_LENGTH = 1,
O_FANOUT = 2,
O_DEPTH = 3,
O_LEAF_LENGTH = 4,
O_NODE_OFFSET = 8,
O_XOF_LENGTH = 12,
O_NODE_DEPTH = 16,
O_INNER_LENGTH = 17,
O_RESERVED = 18,
O_SALT = 32,
O_PERSONAL = 48
};
/*
struct blake2b_param {
unsigned char digest_length;
unsigned char key_length;
unsigned char fanout;
unsigned char depth;
ulong32 leaf_length;
ulong32 node_offset;
ulong32 xof_length;
unsigned char node_depth;
unsigned char inner_length;
unsigned char reserved[14];
unsigned char salt[BLAKE2B_SALTBYTES];
unsigned char personal[BLAKE2B_PERSONALBYTES];
};
*/
const struct ltc_hash_descriptor blake2b_160_desc =
{
"blake2b-160",
25,
20,
128,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 5 },
11,
&blake2b_160_init,
&blake2b_process,
&blake2b_done,
&blake2b_160_test,
NULL
};
const struct ltc_hash_descriptor blake2b_256_desc =
{
"blake2b-256",
26,
32,
128,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 8 },
11,
&blake2b_256_init,
&blake2b_process,
&blake2b_done,
&blake2b_256_test,
NULL
};
const struct ltc_hash_descriptor blake2b_384_desc =
{
"blake2b-384",
27,
48,
128,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 12 },
11,
&blake2b_384_init,
&blake2b_process,
&blake2b_done,
&blake2b_384_test,
NULL
};
const struct ltc_hash_descriptor blake2b_512_desc =
{
"blake2b-512",
28,
64,
128,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 1, 16 },
11,
&blake2b_512_init,
&blake2b_process,
&blake2b_done,
&blake2b_512_test,
NULL
};
static const ulong64 blake2b_IV[8] =
{
CONST64(0x6a09e667f3bcc908), CONST64(0xbb67ae8584caa73b),
CONST64(0x3c6ef372fe94f82b), CONST64(0xa54ff53a5f1d36f1),
CONST64(0x510e527fade682d1), CONST64(0x9b05688c2b3e6c1f),
CONST64(0x1f83d9abfb41bd6b), CONST64(0x5be0cd19137e2179)
};
static const unsigned char blake2b_sigma[12][16] =
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
};
static void blake2b_set_lastnode(hash_state *md) { md->blake2b.f[1] = CONST64(0xffffffffffffffff); }
/* Some helper functions, not necessarily useful */
static int blake2b_is_lastblock(const hash_state *md) { return md->blake2b.f[0] != 0; }
static void blake2b_set_lastblock(hash_state *md)
{
if (md->blake2b.last_node)
blake2b_set_lastnode(md);
md->blake2b.f[0] = CONST64(0xffffffffffffffff);
}
static void blake2b_increment_counter(hash_state *md, ulong64 inc)
{
md->blake2b.t[0] += inc;
if (md->blake2b.t[0] < inc) md->blake2b.t[1]++;
}
static void blake2b_init0(hash_state *md)
{
unsigned long i;
XMEMSET(&md->blake2b, 0, sizeof(md->blake2b));
for (i = 0; i < 8; ++i)
md->blake2b.h[i] = blake2b_IV[i];
}
/* init xors IV with input parameter block */
static int blake2b_init_param(hash_state *md, const unsigned char *P)
{
unsigned long i;
blake2b_init0(md);
/* IV XOR ParamBlock */
for (i = 0; i < 8; ++i) {
ulong64 tmp;
LOAD64L(tmp, P + i * 8);
md->blake2b.h[i] ^= tmp;
}
md->blake2b.outlen = P[O_DIGEST_LENGTH];
return CRYPT_OK;
}
int blake2b_init(hash_state *md, unsigned long outlen, const unsigned char *key, unsigned long keylen)
{
unsigned char P[BLAKE2B_PARAM_SIZE];
int err;
LTC_ARGCHK(md != NULL);
if ((!outlen) || (outlen > BLAKE2B_OUTBYTES))
return CRYPT_INVALID_ARG;
if ((key && !keylen) || (keylen && !key) || (keylen > BLAKE2B_KEYBYTES))
return CRYPT_INVALID_ARG;
XMEMSET(P, 0, sizeof(P));
P[O_DIGEST_LENGTH] = (unsigned char)outlen;
P[O_KEY_LENGTH] = (unsigned char)keylen;
P[O_FANOUT] = 1;
P[O_DEPTH] = 1;
err = blake2b_init_param(md, P);
if (err != CRYPT_OK) return err;
if (key) {
unsigned char block[BLAKE2B_BLOCKBYTES];
XMEMSET(block, 0, BLAKE2B_BLOCKBYTES);
XMEMCPY(block, key, keylen);
blake2b_process(md, block, BLAKE2B_BLOCKBYTES);
#ifdef LTC_CLEAN_STACK
zeromem(block, sizeof(block));
#endif
}
return CRYPT_OK;
}
int blake2b_160_init(hash_state *md) { return blake2b_init(md, 20, NULL, 0); }
int blake2b_256_init(hash_state *md) { return blake2b_init(md, 32, NULL, 0); }
int blake2b_384_init(hash_state *md) { return blake2b_init(md, 48, NULL, 0); }
int blake2b_512_init(hash_state *md) { return blake2b_init(md, 64, NULL, 0); }
#define G(r, i, a, b, c, d) \
do { \
a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \
d = ROR64(d ^ a, 32); \
c = c + d; \
b = ROR64(b ^ c, 24); \
a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \
d = ROR64(d ^ a, 16); \
c = c + d; \
b = ROR64(b ^ c, 63); \
} while (0)
#define ROUND(r) \
do { \
G(r, 0, v[0], v[4], v[8], v[12]); \
G(r, 1, v[1], v[5], v[9], v[13]); \
G(r, 2, v[2], v[6], v[10], v[14]); \
G(r, 3, v[3], v[7], v[11], v[15]); \
G(r, 4, v[0], v[5], v[10], v[15]); \
G(r, 5, v[1], v[6], v[11], v[12]); \
G(r, 6, v[2], v[7], v[8], v[13]); \
G(r, 7, v[3], v[4], v[9], v[14]); \
} while (0)
#ifdef LTC_CLEAN_STACK
static int _blake2b_compress(hash_state *md, const unsigned char *buf)
#else
static int blake2b_compress(hash_state *md, const unsigned char *buf)
#endif
{
ulong64 m[16];
ulong64 v[16];
unsigned long i;
for (i = 0; i < 16; ++i) {
LOAD64L(m[i], buf + i * sizeof(m[i]));
}
for (i = 0; i < 8; ++i) {
v[i] = md->blake2b.h[i];
}
v[8] = blake2b_IV[0];
v[9] = blake2b_IV[1];
v[10] = blake2b_IV[2];
v[11] = blake2b_IV[3];
v[12] = blake2b_IV[4] ^ md->blake2b.t[0];
v[13] = blake2b_IV[5] ^ md->blake2b.t[1];
v[14] = blake2b_IV[6] ^ md->blake2b.f[0];
v[15] = blake2b_IV[7] ^ md->blake2b.f[1];
ROUND(0);
ROUND(1);
ROUND(2);
ROUND(3);
ROUND(4);
ROUND(5);
ROUND(6);
ROUND(7);
ROUND(8);
ROUND(9);
ROUND(10);
ROUND(11);
for (i = 0; i < 8; ++i) {
md->blake2b.h[i] = md->blake2b.h[i] ^ v[i] ^ v[i + 8];
}
return CRYPT_OK;
}
#undef G
#undef ROUND
#ifdef LTC_CLEAN_STACK
static int blake2b_compress(hash_state *md, const unsigned char *buf)
{
int err;
err = _blake2b_compress(md, buf);
burn_stack(sizeof(ulong64) * 32 + sizeof(unsigned long));
return err;
}
#endif
int blake2b_process(hash_state *md, const unsigned char *in, unsigned long inlen)
{
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(in != NULL);
if (md->blake2b.curlen > sizeof(md->blake2b.buf)) {
return CRYPT_INVALID_ARG;
}
if (inlen > 0) {
unsigned long left = md->blake2b.curlen;
unsigned long fill = BLAKE2B_BLOCKBYTES - left;
if (inlen > fill) {
md->blake2b.curlen = 0;
XMEMCPY(md->blake2b.buf + (left % sizeof(md->blake2b.buf)), in, fill); /* Fill buffer */
blake2b_increment_counter(md, BLAKE2B_BLOCKBYTES);
blake2b_compress(md, md->blake2b.buf); /* Compress */
in += fill;
inlen -= fill;
while (inlen > BLAKE2B_BLOCKBYTES) {
blake2b_increment_counter(md, BLAKE2B_BLOCKBYTES);
blake2b_compress(md, in);
in += BLAKE2B_BLOCKBYTES;
inlen -= BLAKE2B_BLOCKBYTES;
}
}
XMEMCPY(md->blake2b.buf + md->blake2b.curlen, in, inlen);
md->blake2b.curlen += inlen;
}
return CRYPT_OK;
}
int blake2b_done(hash_state *md, unsigned char *out)
{
unsigned char buffer[BLAKE2B_OUTBYTES] = { 0 };
unsigned long i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
/* if(md->blakebs.outlen != outlen) return CRYPT_INVALID_ARG; */
if (blake2b_is_lastblock(md))
return CRYPT_ERROR;
blake2b_increment_counter(md, md->blake2b.curlen);
blake2b_set_lastblock(md);
XMEMSET(md->blake2b.buf + md->blake2b.curlen, 0, BLAKE2B_BLOCKBYTES - md->blake2b.curlen); /* Padding */
blake2b_compress(md, md->blake2b.buf);
for (i = 0; i < 8; ++i) /* Output full hash to temp buffer */
STORE64L(md->blake2b.h[i], buffer + i * 8);
XMEMCPY(out, buffer, md->blake2b.outlen);
zeromem(md, sizeof(hash_state));
#ifdef LTC_CLEAN_STACK
zeromem(buffer, sizeof(buffer));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2b_512_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[64];
} tests[] = {
{ "",
{ 0x78, 0x6a, 0x02, 0xf7, 0x42, 0x01, 0x59, 0x03,
0xc6, 0xc6, 0xfd, 0x85, 0x25, 0x52, 0xd2, 0x72,
0x91, 0x2f, 0x47, 0x40, 0xe1, 0x58, 0x47, 0x61,
0x8a, 0x86, 0xe2, 0x17, 0xf7, 0x1f, 0x54, 0x19,
0xd2, 0x5e, 0x10, 0x31, 0xaf, 0xee, 0x58, 0x53,
0x13, 0x89, 0x64, 0x44, 0x93, 0x4e, 0xb0, 0x4b,
0x90, 0x3a, 0x68, 0x5b, 0x14, 0x48, 0xb7, 0x55,
0xd5, 0x6f, 0x70, 0x1a, 0xfe, 0x9b, 0xe2, 0xce } },
{ "abc",
{ 0xba, 0x80, 0xa5, 0x3f, 0x98, 0x1c, 0x4d, 0x0d,
0x6a, 0x27, 0x97, 0xb6, 0x9f, 0x12, 0xf6, 0xe9,
0x4c, 0x21, 0x2f, 0x14, 0x68, 0x5a, 0xc4, 0xb7,
0x4b, 0x12, 0xbb, 0x6f, 0xdb, 0xff, 0xa2, 0xd1,
0x7d, 0x87, 0xc5, 0x39, 0x2a, 0xab, 0x79, 0x2d,
0xc2, 0x52, 0xd5, 0xde, 0x45, 0x33, 0xcc, 0x95,
0x18, 0xd3, 0x8a, 0xa8, 0xdb, 0xf1, 0x92, 0x5a,
0xb9, 0x23, 0x86, 0xed, 0xd4, 0x00, 0x99, 0x23 } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[64];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2b_512_init(&md);
blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
blake2b_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_512", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2b_384_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[48];
} tests[] = {
{ "",
{ 0xb3, 0x28, 0x11, 0x42, 0x33, 0x77, 0xf5, 0x2d,
0x78, 0x62, 0x28, 0x6e, 0xe1, 0xa7, 0x2e, 0xe5,
0x40, 0x52, 0x43, 0x80, 0xfd, 0xa1, 0x72, 0x4a,
0x6f, 0x25, 0xd7, 0x97, 0x8c, 0x6f, 0xd3, 0x24,
0x4a, 0x6c, 0xaf, 0x04, 0x98, 0x81, 0x26, 0x73,
0xc5, 0xe0, 0x5e, 0xf5, 0x83, 0x82, 0x51, 0x00 } },
{ "abc",
{ 0x6f, 0x56, 0xa8, 0x2c, 0x8e, 0x7e, 0xf5, 0x26,
0xdf, 0xe1, 0x82, 0xeb, 0x52, 0x12, 0xf7, 0xdb,
0x9d, 0xf1, 0x31, 0x7e, 0x57, 0x81, 0x5d, 0xbd,
0xa4, 0x60, 0x83, 0xfc, 0x30, 0xf5, 0x4e, 0xe6,
0xc6, 0x6b, 0xa8, 0x3b, 0xe6, 0x4b, 0x30, 0x2d,
0x7c, 0xba, 0x6c, 0xe1, 0x5b, 0xb5, 0x56, 0xf4 } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[48];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2b_384_init(&md);
blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
blake2b_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_384", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2b_256_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[32];
} tests[] = {
{ "",
{ 0x0e, 0x57, 0x51, 0xc0, 0x26, 0xe5, 0x43, 0xb2,
0xe8, 0xab, 0x2e, 0xb0, 0x60, 0x99, 0xda, 0xa1,
0xd1, 0xe5, 0xdf, 0x47, 0x77, 0x8f, 0x77, 0x87,
0xfa, 0xab, 0x45, 0xcd, 0xf1, 0x2f, 0xe3, 0xa8 } },
{ "abc",
{ 0xbd, 0xdd, 0x81, 0x3c, 0x63, 0x42, 0x39, 0x72,
0x31, 0x71, 0xef, 0x3f, 0xee, 0x98, 0x57, 0x9b,
0x94, 0x96, 0x4e, 0x3b, 0xb1, 0xcb, 0x3e, 0x42,
0x72, 0x62, 0xc8, 0xc0, 0x68, 0xd5, 0x23, 0x19 } },
{ "12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890",
{ 0x0f, 0x6e, 0x01, 0x8d, 0x38, 0xd6, 0x3f, 0x08,
0x4d, 0x58, 0xe3, 0x0c, 0x90, 0xfb, 0xa2, 0x41,
0x5f, 0xca, 0x17, 0xfa, 0x66, 0x26, 0x49, 0xf3,
0x8a, 0x30, 0x41, 0x7c, 0x57, 0xcd, 0xa8, 0x14 } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[32];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2b_256_init(&md);
blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
blake2b_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_256", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2b_160_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[20];
} tests[] = {
{ "",
{ 0x33, 0x45, 0x52, 0x4a, 0xbf, 0x6b, 0xbe, 0x18,
0x09, 0x44, 0x92, 0x24, 0xb5, 0x97, 0x2c, 0x41,
0x79, 0x0b, 0x6c, 0xf2 } },
{ "abc",
{ 0x38, 0x42, 0x64, 0xf6, 0x76, 0xf3, 0x95, 0x36,
0x84, 0x05, 0x23, 0xf2, 0x84, 0x92, 0x1c, 0xdc,
0x68, 0xb6, 0x84, 0x6b } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[20];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2b_160_init(&md);
blake2b_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
blake2b_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2B_160", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

563
thirdparty/libtomcrypt/hashes/blake2s.c vendored Normal file
View File

@@ -0,0 +1,563 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/
/* see also https://www.ietf.org/rfc/rfc7693.txt */
#include "tomcrypt.h"
#ifdef LTC_BLAKE2S
enum blake2s_constant {
BLAKE2S_BLOCKBYTES = 64,
BLAKE2S_OUTBYTES = 32,
BLAKE2S_KEYBYTES = 32,
BLAKE2S_SALTBYTES = 8,
BLAKE2S_PERSONALBYTES = 8,
BLAKE2S_PARAM_SIZE = 32
};
/* param offsets */
enum {
O_DIGEST_LENGTH = 0,
O_KEY_LENGTH = 1,
O_FANOUT = 2,
O_DEPTH = 3,
O_LEAF_LENGTH = 4,
O_NODE_OFFSET = 8,
O_XOF_LENGTH = 12,
O_NODE_DEPTH = 14,
O_INNER_LENGTH = 15,
O_SALT = 16,
O_PERSONAL = 24
};
/*
struct blake2s_param {
unsigned char digest_length;
unsigned char key_length;
unsigned char fanout;
unsigned char depth;
ulong32 leaf_length;
ulong32 node_offset;
ushort16 xof_length;
unsigned char node_depth;
unsigned char inner_length;
unsigned char salt[BLAKE2S_SALTBYTES];
unsigned char personal[BLAKE2S_PERSONALBYTES];
};
*/
const struct ltc_hash_descriptor blake2s_128_desc =
{
"blake2s-128",
21,
16,
64,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 4 },
11,
&blake2s_128_init,
&blake2s_process,
&blake2s_done,
&blake2s_128_test,
NULL
};
const struct ltc_hash_descriptor blake2s_160_desc =
{
"blake2s-160",
22,
20,
64,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 5 },
11,
&blake2s_160_init,
&blake2s_process,
&blake2s_done,
&blake2s_160_test,
NULL
};
const struct ltc_hash_descriptor blake2s_224_desc =
{
"blake2s-224",
23,
28,
64,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 7 },
11,
&blake2s_224_init,
&blake2s_process,
&blake2s_done,
&blake2s_224_test,
NULL
};
const struct ltc_hash_descriptor blake2s_256_desc =
{
"blake2s-256",
24,
32,
64,
{ 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 8 },
11,
&blake2s_256_init,
&blake2s_process,
&blake2s_done,
&blake2s_256_test,
NULL
};
static const ulong32 blake2s_IV[8] = {
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
};
static const unsigned char blake2s_sigma[10][16] = {
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
};
static void blake2s_set_lastnode(hash_state *md) { md->blake2s.f[1] = 0xffffffffUL; }
/* Some helper functions, not necessarily useful */
static int blake2s_is_lastblock(const hash_state *md) { return md->blake2s.f[0] != 0; }
static void blake2s_set_lastblock(hash_state *md)
{
if (md->blake2s.last_node)
blake2s_set_lastnode(md);
md->blake2s.f[0] = 0xffffffffUL;
}
static void blake2s_increment_counter(hash_state *md, const ulong32 inc)
{
md->blake2s.t[0] += inc;
if (md->blake2s.t[0] < inc) md->blake2s.t[1]++;
}
static int blake2s_init0(hash_state *md)
{
int i;
XMEMSET(&md->blake2s, 0, sizeof(struct blake2s_state));
for (i = 0; i < 8; ++i)
md->blake2s.h[i] = blake2s_IV[i];
return CRYPT_OK;
}
/* init2 xors IV with input parameter block */
static int blake2s_init_param(hash_state *md, const unsigned char *P)
{
unsigned long i;
blake2s_init0(md);
/* IV XOR ParamBlock */
for (i = 0; i < 8; ++i) {
ulong32 tmp;
LOAD32L(tmp, P + i * 4);
md->blake2s.h[i] ^= tmp;
}
md->blake2s.outlen = P[O_DIGEST_LENGTH];
return CRYPT_OK;
}
int blake2s_init(hash_state *md, unsigned long outlen, const unsigned char *key, unsigned long keylen)
{
unsigned char P[BLAKE2S_PARAM_SIZE];
int err;
LTC_ARGCHK(md != NULL);
if ((!outlen) || (outlen > BLAKE2S_OUTBYTES))
return CRYPT_INVALID_ARG;
if ((key && !keylen) || (keylen && !key) || (keylen > BLAKE2S_KEYBYTES))
return CRYPT_INVALID_ARG;
XMEMSET(P, 0, sizeof(P));
P[O_DIGEST_LENGTH] = (unsigned char)outlen;
P[O_KEY_LENGTH] = (unsigned char)keylen;
P[O_FANOUT] = 1;
P[O_DEPTH] = 1;
err = blake2s_init_param(md, P);
if (err != CRYPT_OK) return err;
if (key) {
unsigned char block[BLAKE2S_BLOCKBYTES];
XMEMSET(block, 0, BLAKE2S_BLOCKBYTES);
XMEMCPY(block, key, keylen);
blake2s_process(md, block, BLAKE2S_BLOCKBYTES);
#ifdef LTC_CLEAN_STACK
zeromem(block, sizeof(block));
#endif
}
return CRYPT_OK;
}
int blake2s_128_init(hash_state *md) { return blake2s_init(md, 16, NULL, 0); }
int blake2s_160_init(hash_state *md) { return blake2s_init(md, 20, NULL, 0); }
int blake2s_224_init(hash_state *md) { return blake2s_init(md, 28, NULL, 0); }
int blake2s_256_init(hash_state *md) { return blake2s_init(md, 32, NULL, 0); }
#define G(r, i, a, b, c, d) \
do { \
a = a + b + m[blake2s_sigma[r][2 * i + 0]]; \
d = ROR(d ^ a, 16); \
c = c + d; \
b = ROR(b ^ c, 12); \
a = a + b + m[blake2s_sigma[r][2 * i + 1]]; \
d = ROR(d ^ a, 8); \
c = c + d; \
b = ROR(b ^ c, 7); \
} while (0)
#define ROUND(r) \
do { \
G(r, 0, v[0], v[4], v[8], v[12]); \
G(r, 1, v[1], v[5], v[9], v[13]); \
G(r, 2, v[2], v[6], v[10], v[14]); \
G(r, 3, v[3], v[7], v[11], v[15]); \
G(r, 4, v[0], v[5], v[10], v[15]); \
G(r, 5, v[1], v[6], v[11], v[12]); \
G(r, 6, v[2], v[7], v[8], v[13]); \
G(r, 7, v[3], v[4], v[9], v[14]); \
} while (0)
#ifdef LTC_CLEAN_STACK
static int _blake2s_compress(hash_state *md, const unsigned char *buf)
#else
static int blake2s_compress(hash_state *md, const unsigned char *buf)
#endif
{
unsigned long i;
ulong32 m[16];
ulong32 v[16];
for (i = 0; i < 16; ++i) {
LOAD32L(m[i], buf + i * sizeof(m[i]));
}
for (i = 0; i < 8; ++i)
v[i] = md->blake2s.h[i];
v[8] = blake2s_IV[0];
v[9] = blake2s_IV[1];
v[10] = blake2s_IV[2];
v[11] = blake2s_IV[3];
v[12] = md->blake2s.t[0] ^ blake2s_IV[4];
v[13] = md->blake2s.t[1] ^ blake2s_IV[5];
v[14] = md->blake2s.f[0] ^ blake2s_IV[6];
v[15] = md->blake2s.f[1] ^ blake2s_IV[7];
ROUND(0);
ROUND(1);
ROUND(2);
ROUND(3);
ROUND(4);
ROUND(5);
ROUND(6);
ROUND(7);
ROUND(8);
ROUND(9);
for (i = 0; i < 8; ++i)
md->blake2s.h[i] = md->blake2s.h[i] ^ v[i] ^ v[i + 8];
return CRYPT_OK;
}
#undef G
#undef ROUND
#ifdef LTC_CLEAN_STACK
static int blake2s_compress(hash_state *md, const unsigned char *buf)
{
int err;
err = _blake2s_compress(md, buf);
burn_stack(sizeof(ulong32) * (32) + sizeof(unsigned long));
return err;
}
#endif
int blake2s_process(hash_state *md, const unsigned char *in, unsigned long inlen)
{
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(in != NULL);
if (md->blake2s.curlen > sizeof(md->blake2s.buf)) {
return CRYPT_INVALID_ARG;
}
if (inlen > 0) {
unsigned long left = md->blake2s.curlen;
unsigned long fill = BLAKE2S_BLOCKBYTES - left;
if (inlen > fill) {
md->blake2s.curlen = 0;
XMEMCPY(md->blake2s.buf + (left % sizeof(md->blake2s.buf)), in, fill); /* Fill buffer */
blake2s_increment_counter(md, BLAKE2S_BLOCKBYTES);
blake2s_compress(md, md->blake2s.buf); /* Compress */
in += fill;
inlen -= fill;
while (inlen > BLAKE2S_BLOCKBYTES) {
blake2s_increment_counter(md, BLAKE2S_BLOCKBYTES);
blake2s_compress(md, in);
in += BLAKE2S_BLOCKBYTES;
inlen -= BLAKE2S_BLOCKBYTES;
}
}
XMEMCPY(md->blake2s.buf + md->blake2s.curlen, in, inlen);
md->blake2s.curlen += inlen;
}
return CRYPT_OK;
}
int blake2s_done(hash_state *md, unsigned char *out)
{
unsigned char buffer[BLAKE2S_OUTBYTES] = { 0 };
unsigned long i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
/* if(md->blake2s.outlen != outlen) return CRYPT_INVALID_ARG; */
if (blake2s_is_lastblock(md))
return CRYPT_ERROR;
blake2s_increment_counter(md, md->blake2s.curlen);
blake2s_set_lastblock(md);
XMEMSET(md->blake2s.buf + md->blake2s.curlen, 0, BLAKE2S_BLOCKBYTES - md->blake2s.curlen); /* Padding */
blake2s_compress(md, md->blake2s.buf);
for (i = 0; i < 8; ++i) /* Output full hash to temp buffer */
STORE32L(md->blake2s.h[i], buffer + i * 4);
XMEMCPY(out, buffer, md->blake2s.outlen);
zeromem(md, sizeof(hash_state));
#ifdef LTC_CLEAN_STACK
zeromem(buffer, sizeof(buffer));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2s_256_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[32];
} tests[] = {
{ "",
{ 0x69, 0x21, 0x7a, 0x30, 0x79, 0x90, 0x80, 0x94,
0xe1, 0x11, 0x21, 0xd0, 0x42, 0x35, 0x4a, 0x7c,
0x1f, 0x55, 0xb6, 0x48, 0x2c, 0xa1, 0xa5, 0x1e,
0x1b, 0x25, 0x0d, 0xfd, 0x1e, 0xd0, 0xee, 0xf9 } },
{ "abc",
{ 0x50, 0x8c, 0x5e, 0x8c, 0x32, 0x7c, 0x14, 0xe2,
0xe1, 0xa7, 0x2b, 0xa3, 0x4e, 0xeb, 0x45, 0x2f,
0x37, 0x45, 0x8b, 0x20, 0x9e, 0xd6, 0x3a, 0x29,
0x4d, 0x99, 0x9b, 0x4c, 0x86, 0x67, 0x59, 0x82 } },
{ "12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890"
"12345678901234567890123456789012345678901234567890",
{ 0xa3, 0x78, 0x8b, 0x5b, 0x59, 0xee, 0xe4, 0x41,
0x95, 0x23, 0x58, 0x00, 0xa4, 0xf9, 0xfa, 0x41,
0x86, 0x0c, 0x7b, 0x1c, 0x35, 0xa2, 0x42, 0x70,
0x50, 0x80, 0x79, 0x56, 0xe3, 0xbe, 0x31, 0x74 } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[32];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2s_256_init(&md);
blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
blake2s_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_256", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2s_224_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[28];
} tests[] = {
{ "",
{ 0x1f, 0xa1, 0x29, 0x1e, 0x65, 0x24, 0x8b, 0x37,
0xb3, 0x43, 0x34, 0x75, 0xb2, 0xa0, 0xdd, 0x63,
0xd5, 0x4a, 0x11, 0xec, 0xc4, 0xe3, 0xe0, 0x34,
0xe7, 0xbc, 0x1e, 0xf4 } },
{ "abc",
{ 0x0b, 0x03, 0x3f, 0xc2, 0x26, 0xdf, 0x7a, 0xbd,
0xe2, 0x9f, 0x67, 0xa0, 0x5d, 0x3d, 0xc6, 0x2c,
0xf2, 0x71, 0xef, 0x3d, 0xfe, 0xa4, 0xd3, 0x87,
0x40, 0x7f, 0xbd, 0x55 } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[28];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2s_224_init(&md);
blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
blake2s_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_224", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2s_160_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[20];
} tests[] = {
{ "",
{ 0x35, 0x4c, 0x9c, 0x33, 0xf7, 0x35, 0x96, 0x24,
0x18, 0xbd, 0xac, 0xb9, 0x47, 0x98, 0x73, 0x42,
0x9c, 0x34, 0x91, 0x6f} },
{ "abc",
{ 0x5a, 0xe3, 0xb9, 0x9b, 0xe2, 0x9b, 0x01, 0x83,
0x4c, 0x3b, 0x50, 0x85, 0x21, 0xed, 0xe6, 0x04,
0x38, 0xf8, 0xde, 0x17 } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[20];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2s_160_init(&md);
blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
blake2s_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_160", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int blake2s_128_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[16];
} tests[] = {
{ "",
{ 0x64, 0x55, 0x0d, 0x6f, 0xfe, 0x2c, 0x0a, 0x01,
0xa1, 0x4a, 0xba, 0x1e, 0xad, 0xe0, 0x20, 0x0c } },
{ "abc",
{ 0xaa, 0x49, 0x38, 0x11, 0x9b, 0x1d, 0xc7, 0xb8,
0x7c, 0xba, 0xd0, 0xff, 0xd2, 0x00, 0xd0, 0xae } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[16];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
blake2s_128_init(&md);
blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
blake2s_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_128", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

306
thirdparty/libtomcrypt/hashes/chc/chc.c vendored Normal file
View File

@@ -0,0 +1,306 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file chc.c
CHC support. (Tom St Denis)
*/
#ifdef LTC_CHC_HASH
#define UNDEFED_HASH -17
/* chc settings */
static int cipher_idx=UNDEFED_HASH, /* which cipher */
cipher_blocksize; /* blocksize of cipher */
const struct ltc_hash_descriptor chc_desc = {
"chc_hash", 12, 0, 0, { 0 }, 0,
&chc_init,
&chc_process,
&chc_done,
&chc_test,
NULL
};
/**
Initialize the CHC state with a given cipher
@param cipher The index of the cipher you wish to bind
@return CRYPT_OK if successful
*/
int chc_register(int cipher)
{
int err, kl, idx;
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
/* will it be valid? */
kl = cipher_descriptor[cipher].block_length;
/* must be >64 bit block */
if (kl <= 8) {
return CRYPT_INVALID_CIPHER;
}
/* can we use the ideal keysize? */
if ((err = cipher_descriptor[cipher].keysize(&kl)) != CRYPT_OK) {
return err;
}
/* we require that key size == block size be a valid choice */
if (kl != cipher_descriptor[cipher].block_length) {
return CRYPT_INVALID_CIPHER;
}
/* determine if chc_hash has been register_hash'ed already */
if ((err = hash_is_valid(idx = find_hash("chc_hash"))) != CRYPT_OK) {
return err;
}
/* store into descriptor */
hash_descriptor[idx].hashsize =
hash_descriptor[idx].blocksize = cipher_descriptor[cipher].block_length;
/* store the idx and block size */
cipher_idx = cipher;
cipher_blocksize = cipher_descriptor[cipher].block_length;
return CRYPT_OK;
}
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int chc_init(hash_state *md)
{
symmetric_key *key;
unsigned char buf[MAXBLOCKSIZE];
int err;
LTC_ARGCHK(md != NULL);
/* is the cipher valid? */
if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) {
return err;
}
if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) {
return CRYPT_INVALID_CIPHER;
}
if ((key = XMALLOC(sizeof(*key))) == NULL) {
return CRYPT_MEM;
}
/* zero key and what not */
zeromem(buf, cipher_blocksize);
if ((err = cipher_descriptor[cipher_idx].setup(buf, cipher_blocksize, 0, key)) != CRYPT_OK) {
XFREE(key);
return err;
}
/* encrypt zero block */
cipher_descriptor[cipher_idx].ecb_encrypt(buf, md->chc.state, key);
/* zero other members */
md->chc.length = 0;
md->chc.curlen = 0;
zeromem(md->chc.buf, sizeof(md->chc.buf));
XFREE(key);
return CRYPT_OK;
}
/*
key <= state
T0,T1 <= block
T0 <= encrypt T0
state <= state xor T0 xor T1
*/
static int chc_compress(hash_state *md, unsigned char *buf)
{
unsigned char T[2][MAXBLOCKSIZE];
symmetric_key *key;
int err, x;
if ((key = XMALLOC(sizeof(*key))) == NULL) {
return CRYPT_MEM;
}
if ((err = cipher_descriptor[cipher_idx].setup(md->chc.state, cipher_blocksize, 0, key)) != CRYPT_OK) {
XFREE(key);
return err;
}
XMEMCPY(T[1], buf, cipher_blocksize);
cipher_descriptor[cipher_idx].ecb_encrypt(buf, T[0], key);
for (x = 0; x < cipher_blocksize; x++) {
md->chc.state[x] ^= T[0][x] ^ T[1][x];
}
#ifdef LTC_CLEAN_STACK
zeromem(T, sizeof(T));
zeromem(key, sizeof(*key));
#endif
XFREE(key);
return CRYPT_OK;
}
/**
Function for processing blocks
@param md The hash state
@param buf The data to hash
@param len The length of the data (octets)
@return CRYPT_OK if successful
*/
static int _chc_process(hash_state * md, const unsigned char *buf, unsigned long len);
static HASH_PROCESS(_chc_process, chc_compress, chc, (unsigned long)cipher_blocksize)
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen)
{
int err;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(in != NULL);
/* is the cipher valid? */
if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) {
return err;
}
if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) {
return CRYPT_INVALID_CIPHER;
}
return _chc_process(md, in, inlen);
}
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (length of the block size of the block cipher)
@return CRYPT_OK if successful
*/
int chc_done(hash_state *md, unsigned char *out)
{
int err;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
/* is the cipher valid? */
if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) {
return err;
}
if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) {
return CRYPT_INVALID_CIPHER;
}
if (md->chc.curlen >= sizeof(md->chc.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->chc.length += md->chc.curlen * 8;
/* append the '1' bit */
md->chc.buf[md->chc.curlen++] = (unsigned char)0x80;
/* if the length is currently above l-8 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->chc.curlen > (unsigned long)(cipher_blocksize - 8)) {
while (md->chc.curlen < (unsigned long)cipher_blocksize) {
md->chc.buf[md->chc.curlen++] = (unsigned char)0;
}
chc_compress(md, md->chc.buf);
md->chc.curlen = 0;
}
/* pad upto l-8 bytes of zeroes */
while (md->chc.curlen < (unsigned long)(cipher_blocksize - 8)) {
md->chc.buf[md->chc.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->chc.length, md->chc.buf+(cipher_blocksize-8));
chc_compress(md, md->chc.buf);
/* copy output */
XMEMCPY(out, md->chc.state, cipher_blocksize);
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int chc_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
unsigned char *msg,
hash[MAXBLOCKSIZE];
int len;
} tests[] = {
{
(unsigned char *)"hello world",
{ 0xcf, 0x57, 0x9d, 0xc3, 0x0a, 0x0e, 0xea, 0x61,
0x0d, 0x54, 0x47, 0xc4, 0x3c, 0x06, 0xf5, 0x4e },
16
}
};
int i, oldhashidx, idx;
unsigned char tmp[MAXBLOCKSIZE];
hash_state md;
/* AES can be under rijndael or aes... try to find it */
if ((idx = find_cipher("aes")) == -1) {
if ((idx = find_cipher("rijndael")) == -1) {
return CRYPT_NOP;
}
}
oldhashidx = cipher_idx;
chc_register(idx);
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
chc_init(&md);
chc_process(&md, tests[i].msg, strlen((char *)tests[i].msg));
chc_done(&md, tmp);
if (compare_testvector(tmp, tests[i].len, tests[i].hash, tests[i].len, "CHC", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
if (oldhashidx != UNDEFED_HASH) {
chc_register(oldhashidx);
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,53 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifndef LTC_NO_FILE
/**
@file hash_file.c
Hash a file, Tom St Denis
*/
/**
@param hash The index of the hash desired
@param fname The name of the file you wish to hash
@param out [out] The destination of the digest
@param outlen [in/out] The max size and resulting size of the message digest
@result CRYPT_OK if successful
*/
int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen)
{
FILE *in;
int err;
LTC_ARGCHK(fname != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
return err;
}
in = fopen(fname, "rb");
if (in == NULL) {
return CRYPT_FILE_NOTFOUND;
}
err = hash_filehandle(hash, in, out, outlen);
if (fclose(in) != 0) {
return CRYPT_ERROR;
}
return err;
}
#endif /* #ifndef LTC_NO_FILE */
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,74 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifndef LTC_NO_FILE
/**
@file hash_filehandle.c
Hash open files, Tom St Denis
*/
/**
Hash data from an open file handle.
@param hash The index of the hash you want to use
@param in The FILE* handle of the file you want to hash
@param out [out] The destination of the digest
@param outlen [in/out] The max size and resulting size of the digest
@result CRYPT_OK if successful
*/
int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen)
{
hash_state md;
unsigned char *buf;
size_t x;
int err;
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
LTC_ARGCHK(in != NULL);
if ((buf = XMALLOC(LTC_FILE_READ_BUFSIZE)) == NULL) {
return CRYPT_MEM;
}
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
goto LBL_ERR;
}
if (*outlen < hash_descriptor[hash].hashsize) {
*outlen = hash_descriptor[hash].hashsize;
err = CRYPT_BUFFER_OVERFLOW;
goto LBL_ERR;
}
if ((err = hash_descriptor[hash].init(&md)) != CRYPT_OK) {
goto LBL_ERR;
}
do {
x = fread(buf, 1, LTC_FILE_READ_BUFSIZE, in);
if ((err = hash_descriptor[hash].process(&md, buf, (unsigned long)x)) != CRYPT_OK) {
goto LBL_CLEANBUF;
}
} while (x == LTC_FILE_READ_BUFSIZE);
if ((err = hash_descriptor[hash].done(&md, out)) == CRYPT_OK) {
*outlen = hash_descriptor[hash].hashsize;
}
LBL_CLEANBUF:
zeromem(buf, LTC_FILE_READ_BUFSIZE);
LBL_ERR:
XFREE(buf);
return err;
}
#endif /* #ifndef LTC_NO_FILE */
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,69 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#ifdef LTC_HASH_HELPERS
/**
@file hash_memory.c
Hash memory helper, Tom St Denis
*/
/**
Hash a block of memory and store the digest.
@param hash The index of the hash you wish to use
@param in The data you wish to hash
@param inlen The length of the data to hash (octets)
@param out [out] Where to store the digest
@param outlen [in/out] Max size and resulting size of the digest
@return CRYPT_OK if successful
*/
int hash_memory(int hash, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen)
{
hash_state *md;
int err;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
return err;
}
if (*outlen < hash_descriptor[hash].hashsize) {
*outlen = hash_descriptor[hash].hashsize;
return CRYPT_BUFFER_OVERFLOW;
}
md = XMALLOC(sizeof(hash_state));
if (md == NULL) {
return CRYPT_MEM;
}
if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = hash_descriptor[hash].process(md, in, inlen)) != CRYPT_OK) {
goto LBL_ERR;
}
err = hash_descriptor[hash].done(md, out);
*outlen = hash_descriptor[hash].hashsize;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
XFREE(md);
return err;
}
#endif /* #ifdef LTC_HASH_HELPERS */
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,88 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
#include <stdarg.h>
#ifdef LTC_HASH_HELPERS
/**
@file hash_memory_multi.c
Hash (multiple buffers) memory helper, Tom St Denis
*/
/**
Hash multiple (non-adjacent) blocks of memory at once.
@param hash The index of the hash you wish to use
@param out [out] Where to store the digest
@param outlen [in/out] Max size and resulting size of the digest
@param in The data you wish to hash
@param inlen The length of the data to hash (octets)
@param ... tuples of (data,len) pairs to hash, terminated with a (NULL,x) (x=don't care)
@return CRYPT_OK if successful
*/
int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen,
const unsigned char *in, unsigned long inlen, ...)
{
hash_state *md;
int err;
va_list args;
const unsigned char *curptr;
unsigned long curlen;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
return err;
}
if (*outlen < hash_descriptor[hash].hashsize) {
*outlen = hash_descriptor[hash].hashsize;
return CRYPT_BUFFER_OVERFLOW;
}
md = XMALLOC(sizeof(hash_state));
if (md == NULL) {
return CRYPT_MEM;
}
if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) {
goto LBL_ERR;
}
va_start(args, inlen);
curptr = in;
curlen = inlen;
for (;;) {
/* process buf */
if ((err = hash_descriptor[hash].process(md, curptr, curlen)) != CRYPT_OK) {
goto LBL_ERR;
}
/* step to next */
curptr = va_arg(args, const unsigned char*);
if (curptr == NULL) {
break;
}
curlen = va_arg(args, unsigned long);
}
err = hash_descriptor[hash].done(md, out);
*outlen = hash_descriptor[hash].hashsize;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
XFREE(md);
va_end(args);
return err;
}
#endif /* #ifdef LTC_HASH_HELPERS */
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

250
thirdparty/libtomcrypt/hashes/md2.c vendored Normal file
View File

@@ -0,0 +1,250 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@param md2.c
LTC_MD2 (RFC 1319) hash function implementation by Tom St Denis
*/
#ifdef LTC_MD2
const struct ltc_hash_descriptor md2_desc =
{
"md2",
7,
16,
16,
/* OID */
{ 1, 2, 840, 113549, 2, 2, },
6,
&md2_init,
&md2_process,
&md2_done,
&md2_test,
NULL
};
static const unsigned char PI_SUBST[256] = {
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
};
/* adds 16 bytes to the checksum */
static void md2_update_chksum(hash_state *md)
{
int j;
unsigned char L;
L = md->md2.chksum[15];
for (j = 0; j < 16; j++) {
/* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference source code [and test vectors] say
otherwise.
*/
L = (md->md2.chksum[j] ^= PI_SUBST[(int)(md->md2.buf[j] ^ L)] & 255);
}
}
static void md2_compress(hash_state *md)
{
int j, k;
unsigned char t;
/* copy block */
for (j = 0; j < 16; j++) {
md->md2.X[16+j] = md->md2.buf[j];
md->md2.X[32+j] = md->md2.X[j] ^ md->md2.X[16+j];
}
t = (unsigned char)0;
/* do 18 rounds */
for (j = 0; j < 18; j++) {
for (k = 0; k < 48; k++) {
t = (md->md2.X[k] ^= PI_SUBST[(int)(t & 255)]);
}
t = (t + (unsigned char)j) & 255;
}
}
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int md2_init(hash_state *md)
{
LTC_ARGCHK(md != NULL);
/* LTC_MD2 uses a zero'ed state... */
zeromem(md->md2.X, sizeof(md->md2.X));
zeromem(md->md2.chksum, sizeof(md->md2.chksum));
zeromem(md->md2.buf, sizeof(md->md2.buf));
md->md2.curlen = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
int md2_process(hash_state *md, const unsigned char *in, unsigned long inlen)
{
unsigned long n;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(in != NULL);
if (md-> md2 .curlen > sizeof(md-> md2 .buf)) {
return CRYPT_INVALID_ARG;
}
while (inlen > 0) {
n = MIN(inlen, (16 - md->md2.curlen));
XMEMCPY(md->md2.buf + md->md2.curlen, in, (size_t)n);
md->md2.curlen += n;
in += n;
inlen -= n;
/* is 16 bytes full? */
if (md->md2.curlen == 16) {
md2_compress(md);
md2_update_chksum(md);
md->md2.curlen = 0;
}
}
return CRYPT_OK;
}
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (16 bytes)
@return CRYPT_OK if successful
*/
int md2_done(hash_state * md, unsigned char *out)
{
unsigned long i, k;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->md2.curlen >= sizeof(md->md2.buf)) {
return CRYPT_INVALID_ARG;
}
/* pad the message */
k = 16 - md->md2.curlen;
for (i = md->md2.curlen; i < 16; i++) {
md->md2.buf[i] = (unsigned char)k;
}
/* hash and update */
md2_compress(md);
md2_update_chksum(md);
/* hash checksum */
XMEMCPY(md->md2.buf, md->md2.chksum, 16);
md2_compress(md);
/* output is lower 16 bytes of X */
XMEMCPY(out, md->md2.X, 16);
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int md2_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[16];
} tests[] = {
{ "",
{0x83,0x50,0xe5,0xa3,0xe2,0x4c,0x15,0x3d,
0xf2,0x27,0x5c,0x9f,0x80,0x69,0x27,0x73
}
},
{ "a",
{0x32,0xec,0x01,0xec,0x4a,0x6d,0xac,0x72,
0xc0,0xab,0x96,0xfb,0x34,0xc0,0xb5,0xd1
}
},
{ "message digest",
{0xab,0x4f,0x49,0x6b,0xfb,0x2a,0x53,0x0b,
0x21,0x9f,0xf3,0x30,0x31,0xfe,0x06,0xb0
}
},
{ "abcdefghijklmnopqrstuvwxyz",
{0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab,
0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b
}
},
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39,
0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd
}
},
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
{0xd5,0x97,0x6f,0x79,0xd8,0x3d,0x3a,0x0d,
0xc9,0x80,0x6c,0x3c,0x66,0xf3,0xef,0xd8
}
}
};
int i;
unsigned char tmp[16];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
md2_init(&md);
md2_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
md2_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "MD2", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

306
thirdparty/libtomcrypt/hashes/md4.c vendored Normal file
View File

@@ -0,0 +1,306 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@param md4.c
Submitted by Dobes Vandermeer (dobes@smartt.com)
*/
#ifdef LTC_MD4
const struct ltc_hash_descriptor md4_desc =
{
"md4",
6,
16,
64,
/* OID */
{ 1, 2, 840, 113549, 2, 4, },
6,
&md4_init,
&md4_process,
&md4_done,
&md4_test,
NULL
};
#define S11 3
#define S12 7
#define S13 11
#define S14 19
#define S21 3
#define S22 5
#define S23 9
#define S24 13
#define S31 3
#define S32 9
#define S33 11
#define S34 15
/* F, G and H are basic LTC_MD4 functions. */
#define F(x, y, z) (z ^ (x & (y ^ z)))
#define G(x, y, z) ((x & y) | (z & (x | y)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
/* ROTATE_LEFT rotates x left n bits. */
#define ROTATE_LEFT(x, n) ROLc(x, n)
/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
/* Rotation is separate from addition to prevent recomputation */
#define FF(a, b, c, d, x, s) { \
(a) += F ((b), (c), (d)) + (x); \
(a) = ROTATE_LEFT ((a), (s)); \
}
#define GG(a, b, c, d, x, s) { \
(a) += G ((b), (c), (d)) + (x) + 0x5a827999UL; \
(a) = ROTATE_LEFT ((a), (s)); \
}
#define HH(a, b, c, d, x, s) { \
(a) += H ((b), (c), (d)) + (x) + 0x6ed9eba1UL; \
(a) = ROTATE_LEFT ((a), (s)); \
}
#ifdef LTC_CLEAN_STACK
static int _md4_compress(hash_state *md, unsigned char *buf)
#else
static int md4_compress(hash_state *md, unsigned char *buf)
#endif
{
ulong32 x[16], a, b, c, d;
int i;
/* copy state */
a = md->md4.state[0];
b = md->md4.state[1];
c = md->md4.state[2];
d = md->md4.state[3];
/* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD32L(x[i], buf + (4*i));
}
/* Round 1 */
FF (a, b, c, d, x[ 0], S11); /* 1 */
FF (d, a, b, c, x[ 1], S12); /* 2 */
FF (c, d, a, b, x[ 2], S13); /* 3 */
FF (b, c, d, a, x[ 3], S14); /* 4 */
FF (a, b, c, d, x[ 4], S11); /* 5 */
FF (d, a, b, c, x[ 5], S12); /* 6 */
FF (c, d, a, b, x[ 6], S13); /* 7 */
FF (b, c, d, a, x[ 7], S14); /* 8 */
FF (a, b, c, d, x[ 8], S11); /* 9 */
FF (d, a, b, c, x[ 9], S12); /* 10 */
FF (c, d, a, b, x[10], S13); /* 11 */
FF (b, c, d, a, x[11], S14); /* 12 */
FF (a, b, c, d, x[12], S11); /* 13 */
FF (d, a, b, c, x[13], S12); /* 14 */
FF (c, d, a, b, x[14], S13); /* 15 */
FF (b, c, d, a, x[15], S14); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 0], S21); /* 17 */
GG (d, a, b, c, x[ 4], S22); /* 18 */
GG (c, d, a, b, x[ 8], S23); /* 19 */
GG (b, c, d, a, x[12], S24); /* 20 */
GG (a, b, c, d, x[ 1], S21); /* 21 */
GG (d, a, b, c, x[ 5], S22); /* 22 */
GG (c, d, a, b, x[ 9], S23); /* 23 */
GG (b, c, d, a, x[13], S24); /* 24 */
GG (a, b, c, d, x[ 2], S21); /* 25 */
GG (d, a, b, c, x[ 6], S22); /* 26 */
GG (c, d, a, b, x[10], S23); /* 27 */
GG (b, c, d, a, x[14], S24); /* 28 */
GG (a, b, c, d, x[ 3], S21); /* 29 */
GG (d, a, b, c, x[ 7], S22); /* 30 */
GG (c, d, a, b, x[11], S23); /* 31 */
GG (b, c, d, a, x[15], S24); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 0], S31); /* 33 */
HH (d, a, b, c, x[ 8], S32); /* 34 */
HH (c, d, a, b, x[ 4], S33); /* 35 */
HH (b, c, d, a, x[12], S34); /* 36 */
HH (a, b, c, d, x[ 2], S31); /* 37 */
HH (d, a, b, c, x[10], S32); /* 38 */
HH (c, d, a, b, x[ 6], S33); /* 39 */
HH (b, c, d, a, x[14], S34); /* 40 */
HH (a, b, c, d, x[ 1], S31); /* 41 */
HH (d, a, b, c, x[ 9], S32); /* 42 */
HH (c, d, a, b, x[ 5], S33); /* 43 */
HH (b, c, d, a, x[13], S34); /* 44 */
HH (a, b, c, d, x[ 3], S31); /* 45 */
HH (d, a, b, c, x[11], S32); /* 46 */
HH (c, d, a, b, x[ 7], S33); /* 47 */
HH (b, c, d, a, x[15], S34); /* 48 */
/* Update our state */
md->md4.state[0] = md->md4.state[0] + a;
md->md4.state[1] = md->md4.state[1] + b;
md->md4.state[2] = md->md4.state[2] + c;
md->md4.state[3] = md->md4.state[3] + d;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int md4_compress(hash_state *md, unsigned char *buf)
{
int err;
err = _md4_compress(md, buf);
burn_stack(sizeof(ulong32) * 20 + sizeof(int));
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int md4_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->md4.state[0] = 0x67452301UL;
md->md4.state[1] = 0xefcdab89UL;
md->md4.state[2] = 0x98badcfeUL;
md->md4.state[3] = 0x10325476UL;
md->md4.length = 0;
md->md4.curlen = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(md4_process, md4_compress, md4, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (16 bytes)
@return CRYPT_OK if successful
*/
int md4_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->md4.curlen >= sizeof(md->md4.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->md4.length += md->md4.curlen * 8;
/* append the '1' bit */
md->md4.buf[md->md4.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->md4.curlen > 56) {
while (md->md4.curlen < 64) {
md->md4.buf[md->md4.curlen++] = (unsigned char)0;
}
md4_compress(md, md->md4.buf);
md->md4.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->md4.curlen < 56) {
md->md4.buf[md->md4.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->md4.length, md->md4.buf+56);
md4_compress(md, md->md4.buf);
/* copy output */
for (i = 0; i < 4; i++) {
STORE32L(md->md4.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int md4_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct md4_test_case {
const char *input;
unsigned char hash[16];
} tests[] = {
{ "",
{0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0} },
{ "a",
{0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46,
0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24} },
{ "abc",
{0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52,
0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d} },
{ "message digest",
{0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8,
0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b} },
{ "abcdefghijklmnopqrstuvwxyz",
{0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd,
0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9} },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35,
0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4} },
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
{0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19,
0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36} },
};
int i;
unsigned char tmp[16];
hash_state md;
for(i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
md4_init(&md);
md4_process(&md, (unsigned char *)tests[i].input, (unsigned long)strlen(tests[i].input));
md4_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "MD4", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

366
thirdparty/libtomcrypt/hashes/md5.c vendored Normal file
View File

@@ -0,0 +1,366 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file md5.c
LTC_MD5 hash function by Tom St Denis
*/
#ifdef LTC_MD5
const struct ltc_hash_descriptor md5_desc =
{
"md5",
3,
16,
64,
/* OID */
{ 1, 2, 840, 113549, 2, 5, },
6,
&md5_init,
&md5_process,
&md5_done,
&md5_test,
NULL
};
#define F(x,y,z) (z ^ (x & (y ^ z)))
#define G(x,y,z) (y ^ (z & (y ^ x)))
#define H(x,y,z) (x^y^z)
#define I(x,y,z) (y^(x|(~z)))
#ifdef LTC_SMALL_CODE
#define FF(a,b,c,d,M,s,t) \
a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b;
#define GG(a,b,c,d,M,s,t) \
a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b;
#define HH(a,b,c,d,M,s,t) \
a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b;
#define II(a,b,c,d,M,s,t) \
a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
static const unsigned char Worder[64] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
};
static const unsigned char Rorder[64] = {
7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
};
static const ulong32 Korder[64] = {
0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
};
#else
#define FF(a,b,c,d,M,s,t) \
a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b;
#define GG(a,b,c,d,M,s,t) \
a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b;
#define HH(a,b,c,d,M,s,t) \
a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b;
#define II(a,b,c,d,M,s,t) \
a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b;
#endif
#ifdef LTC_CLEAN_STACK
static int _md5_compress(hash_state *md, unsigned char *buf)
#else
static int md5_compress(hash_state *md, unsigned char *buf)
#endif
{
ulong32 i, W[16], a, b, c, d;
#ifdef LTC_SMALL_CODE
ulong32 t;
#endif
/* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD32L(W[i], buf + (4*i));
}
/* copy state */
a = md->md5.state[0];
b = md->md5.state[1];
c = md->md5.state[2];
d = md->md5.state[3];
#ifdef LTC_SMALL_CODE
for (i = 0; i < 16; ++i) {
FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
for (; i < 32; ++i) {
GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
for (; i < 48; ++i) {
HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
for (; i < 64; ++i) {
II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
#else
FF(a,b,c,d,W[0],7,0xd76aa478UL)
FF(d,a,b,c,W[1],12,0xe8c7b756UL)
FF(c,d,a,b,W[2],17,0x242070dbUL)
FF(b,c,d,a,W[3],22,0xc1bdceeeUL)
FF(a,b,c,d,W[4],7,0xf57c0fafUL)
FF(d,a,b,c,W[5],12,0x4787c62aUL)
FF(c,d,a,b,W[6],17,0xa8304613UL)
FF(b,c,d,a,W[7],22,0xfd469501UL)
FF(a,b,c,d,W[8],7,0x698098d8UL)
FF(d,a,b,c,W[9],12,0x8b44f7afUL)
FF(c,d,a,b,W[10],17,0xffff5bb1UL)
FF(b,c,d,a,W[11],22,0x895cd7beUL)
FF(a,b,c,d,W[12],7,0x6b901122UL)
FF(d,a,b,c,W[13],12,0xfd987193UL)
FF(c,d,a,b,W[14],17,0xa679438eUL)
FF(b,c,d,a,W[15],22,0x49b40821UL)
GG(a,b,c,d,W[1],5,0xf61e2562UL)
GG(d,a,b,c,W[6],9,0xc040b340UL)
GG(c,d,a,b,W[11],14,0x265e5a51UL)
GG(b,c,d,a,W[0],20,0xe9b6c7aaUL)
GG(a,b,c,d,W[5],5,0xd62f105dUL)
GG(d,a,b,c,W[10],9,0x02441453UL)
GG(c,d,a,b,W[15],14,0xd8a1e681UL)
GG(b,c,d,a,W[4],20,0xe7d3fbc8UL)
GG(a,b,c,d,W[9],5,0x21e1cde6UL)
GG(d,a,b,c,W[14],9,0xc33707d6UL)
GG(c,d,a,b,W[3],14,0xf4d50d87UL)
GG(b,c,d,a,W[8],20,0x455a14edUL)
GG(a,b,c,d,W[13],5,0xa9e3e905UL)
GG(d,a,b,c,W[2],9,0xfcefa3f8UL)
GG(c,d,a,b,W[7],14,0x676f02d9UL)
GG(b,c,d,a,W[12],20,0x8d2a4c8aUL)
HH(a,b,c,d,W[5],4,0xfffa3942UL)
HH(d,a,b,c,W[8],11,0x8771f681UL)
HH(c,d,a,b,W[11],16,0x6d9d6122UL)
HH(b,c,d,a,W[14],23,0xfde5380cUL)
HH(a,b,c,d,W[1],4,0xa4beea44UL)
HH(d,a,b,c,W[4],11,0x4bdecfa9UL)
HH(c,d,a,b,W[7],16,0xf6bb4b60UL)
HH(b,c,d,a,W[10],23,0xbebfbc70UL)
HH(a,b,c,d,W[13],4,0x289b7ec6UL)
HH(d,a,b,c,W[0],11,0xeaa127faUL)
HH(c,d,a,b,W[3],16,0xd4ef3085UL)
HH(b,c,d,a,W[6],23,0x04881d05UL)
HH(a,b,c,d,W[9],4,0xd9d4d039UL)
HH(d,a,b,c,W[12],11,0xe6db99e5UL)
HH(c,d,a,b,W[15],16,0x1fa27cf8UL)
HH(b,c,d,a,W[2],23,0xc4ac5665UL)
II(a,b,c,d,W[0],6,0xf4292244UL)
II(d,a,b,c,W[7],10,0x432aff97UL)
II(c,d,a,b,W[14],15,0xab9423a7UL)
II(b,c,d,a,W[5],21,0xfc93a039UL)
II(a,b,c,d,W[12],6,0x655b59c3UL)
II(d,a,b,c,W[3],10,0x8f0ccc92UL)
II(c,d,a,b,W[10],15,0xffeff47dUL)
II(b,c,d,a,W[1],21,0x85845dd1UL)
II(a,b,c,d,W[8],6,0x6fa87e4fUL)
II(d,a,b,c,W[15],10,0xfe2ce6e0UL)
II(c,d,a,b,W[6],15,0xa3014314UL)
II(b,c,d,a,W[13],21,0x4e0811a1UL)
II(a,b,c,d,W[4],6,0xf7537e82UL)
II(d,a,b,c,W[11],10,0xbd3af235UL)
II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
II(b,c,d,a,W[9],21,0xeb86d391UL)
#endif
md->md5.state[0] = md->md5.state[0] + a;
md->md5.state[1] = md->md5.state[1] + b;
md->md5.state[2] = md->md5.state[2] + c;
md->md5.state[3] = md->md5.state[3] + d;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int md5_compress(hash_state *md, unsigned char *buf)
{
int err;
err = _md5_compress(md, buf);
burn_stack(sizeof(ulong32) * 21);
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int md5_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->md5.state[0] = 0x67452301UL;
md->md5.state[1] = 0xefcdab89UL;
md->md5.state[2] = 0x98badcfeUL;
md->md5.state[3] = 0x10325476UL;
md->md5.curlen = 0;
md->md5.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(md5_process, md5_compress, md5, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (16 bytes)
@return CRYPT_OK if successful
*/
int md5_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->md5.curlen >= sizeof(md->md5.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->md5.length += md->md5.curlen * 8;
/* append the '1' bit */
md->md5.buf[md->md5.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->md5.curlen > 56) {
while (md->md5.curlen < 64) {
md->md5.buf[md->md5.curlen++] = (unsigned char)0;
}
md5_compress(md, md->md5.buf);
md->md5.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->md5.curlen < 56) {
md->md5.buf[md->md5.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->md5.length, md->md5.buf+56);
md5_compress(md, md->md5.buf);
/* copy output */
for (i = 0; i < 4; i++) {
STORE32L(md->md5.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int md5_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[16];
} tests[] = {
{ "",
{ 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
{ "a",
{0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
{ "abc",
{ 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } },
{ "message digest",
{ 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } },
{ "abcdefghijklmnopqrstuvwxyz",
{ 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{ 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } },
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
{ 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } },
{ NULL, { 0 } }
};
int i;
unsigned char tmp[16];
hash_state md;
for (i = 0; tests[i].msg != NULL; i++) {
md5_init(&md);
md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
md5_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "MD5", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

406
thirdparty/libtomcrypt/hashes/rmd128.c vendored Normal file
View File

@@ -0,0 +1,406 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@param rmd128.c
RMD128 Hash function
*/
/* Implementation of LTC_RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC
*
* This source has been radically overhauled to be portable and work within
* the LibTomCrypt API by Tom St Denis
*/
#ifdef LTC_RIPEMD128
const struct ltc_hash_descriptor rmd128_desc =
{
"rmd128",
8,
16,
64,
/* OID */
{ 1, 0, 10118, 3, 0, 50 },
6,
&rmd128_init,
&rmd128_process,
&rmd128_done,
&rmd128_test,
NULL
};
/* the four basic functions F(), G() and H() */
#define F(x, y, z) ((x) ^ (y) ^ (z))
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define H(x, y, z) (((x) | ~(y)) ^ (z))
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
/* the eight basic operations FF() through III() */
#define FF(a, b, c, d, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s));
#define GG(a, b, c, d, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
(a) = ROLc((a), (s));
#define HH(a, b, c, d, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
(a) = ROLc((a), (s));
#define II(a, b, c, d, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
(a) = ROLc((a), (s));
#define FFF(a, b, c, d, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s));
#define GGG(a, b, c, d, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\
(a) = ROLc((a), (s));
#define HHH(a, b, c, d, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\
(a) = ROLc((a), (s));
#define III(a, b, c, d, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\
(a) = ROLc((a), (s));
#ifdef LTC_CLEAN_STACK
static int _rmd128_compress(hash_state *md, unsigned char *buf)
#else
static int rmd128_compress(hash_state *md, unsigned char *buf)
#endif
{
ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16];
int i;
/* load words X */
for (i = 0; i < 16; i++){
LOAD32L(X[i], buf + (4 * i));
}
/* load state */
aa = aaa = md->rmd128.state[0];
bb = bbb = md->rmd128.state[1];
cc = ccc = md->rmd128.state[2];
dd = ddd = md->rmd128.state[3];
/* round 1 */
FF(aa, bb, cc, dd, X[ 0], 11);
FF(dd, aa, bb, cc, X[ 1], 14);
FF(cc, dd, aa, bb, X[ 2], 15);
FF(bb, cc, dd, aa, X[ 3], 12);
FF(aa, bb, cc, dd, X[ 4], 5);
FF(dd, aa, bb, cc, X[ 5], 8);
FF(cc, dd, aa, bb, X[ 6], 7);
FF(bb, cc, dd, aa, X[ 7], 9);
FF(aa, bb, cc, dd, X[ 8], 11);
FF(dd, aa, bb, cc, X[ 9], 13);
FF(cc, dd, aa, bb, X[10], 14);
FF(bb, cc, dd, aa, X[11], 15);
FF(aa, bb, cc, dd, X[12], 6);
FF(dd, aa, bb, cc, X[13], 7);
FF(cc, dd, aa, bb, X[14], 9);
FF(bb, cc, dd, aa, X[15], 8);
/* round 2 */
GG(aa, bb, cc, dd, X[ 7], 7);
GG(dd, aa, bb, cc, X[ 4], 6);
GG(cc, dd, aa, bb, X[13], 8);
GG(bb, cc, dd, aa, X[ 1], 13);
GG(aa, bb, cc, dd, X[10], 11);
GG(dd, aa, bb, cc, X[ 6], 9);
GG(cc, dd, aa, bb, X[15], 7);
GG(bb, cc, dd, aa, X[ 3], 15);
GG(aa, bb, cc, dd, X[12], 7);
GG(dd, aa, bb, cc, X[ 0], 12);
GG(cc, dd, aa, bb, X[ 9], 15);
GG(bb, cc, dd, aa, X[ 5], 9);
GG(aa, bb, cc, dd, X[ 2], 11);
GG(dd, aa, bb, cc, X[14], 7);
GG(cc, dd, aa, bb, X[11], 13);
GG(bb, cc, dd, aa, X[ 8], 12);
/* round 3 */
HH(aa, bb, cc, dd, X[ 3], 11);
HH(dd, aa, bb, cc, X[10], 13);
HH(cc, dd, aa, bb, X[14], 6);
HH(bb, cc, dd, aa, X[ 4], 7);
HH(aa, bb, cc, dd, X[ 9], 14);
HH(dd, aa, bb, cc, X[15], 9);
HH(cc, dd, aa, bb, X[ 8], 13);
HH(bb, cc, dd, aa, X[ 1], 15);
HH(aa, bb, cc, dd, X[ 2], 14);
HH(dd, aa, bb, cc, X[ 7], 8);
HH(cc, dd, aa, bb, X[ 0], 13);
HH(bb, cc, dd, aa, X[ 6], 6);
HH(aa, bb, cc, dd, X[13], 5);
HH(dd, aa, bb, cc, X[11], 12);
HH(cc, dd, aa, bb, X[ 5], 7);
HH(bb, cc, dd, aa, X[12], 5);
/* round 4 */
II(aa, bb, cc, dd, X[ 1], 11);
II(dd, aa, bb, cc, X[ 9], 12);
II(cc, dd, aa, bb, X[11], 14);
II(bb, cc, dd, aa, X[10], 15);
II(aa, bb, cc, dd, X[ 0], 14);
II(dd, aa, bb, cc, X[ 8], 15);
II(cc, dd, aa, bb, X[12], 9);
II(bb, cc, dd, aa, X[ 4], 8);
II(aa, bb, cc, dd, X[13], 9);
II(dd, aa, bb, cc, X[ 3], 14);
II(cc, dd, aa, bb, X[ 7], 5);
II(bb, cc, dd, aa, X[15], 6);
II(aa, bb, cc, dd, X[14], 8);
II(dd, aa, bb, cc, X[ 5], 6);
II(cc, dd, aa, bb, X[ 6], 5);
II(bb, cc, dd, aa, X[ 2], 12);
/* parallel round 1 */
III(aaa, bbb, ccc, ddd, X[ 5], 8);
III(ddd, aaa, bbb, ccc, X[14], 9);
III(ccc, ddd, aaa, bbb, X[ 7], 9);
III(bbb, ccc, ddd, aaa, X[ 0], 11);
III(aaa, bbb, ccc, ddd, X[ 9], 13);
III(ddd, aaa, bbb, ccc, X[ 2], 15);
III(ccc, ddd, aaa, bbb, X[11], 15);
III(bbb, ccc, ddd, aaa, X[ 4], 5);
III(aaa, bbb, ccc, ddd, X[13], 7);
III(ddd, aaa, bbb, ccc, X[ 6], 7);
III(ccc, ddd, aaa, bbb, X[15], 8);
III(bbb, ccc, ddd, aaa, X[ 8], 11);
III(aaa, bbb, ccc, ddd, X[ 1], 14);
III(ddd, aaa, bbb, ccc, X[10], 14);
III(ccc, ddd, aaa, bbb, X[ 3], 12);
III(bbb, ccc, ddd, aaa, X[12], 6);
/* parallel round 2 */
HHH(aaa, bbb, ccc, ddd, X[ 6], 9);
HHH(ddd, aaa, bbb, ccc, X[11], 13);
HHH(ccc, ddd, aaa, bbb, X[ 3], 15);
HHH(bbb, ccc, ddd, aaa, X[ 7], 7);
HHH(aaa, bbb, ccc, ddd, X[ 0], 12);
HHH(ddd, aaa, bbb, ccc, X[13], 8);
HHH(ccc, ddd, aaa, bbb, X[ 5], 9);
HHH(bbb, ccc, ddd, aaa, X[10], 11);
HHH(aaa, bbb, ccc, ddd, X[14], 7);
HHH(ddd, aaa, bbb, ccc, X[15], 7);
HHH(ccc, ddd, aaa, bbb, X[ 8], 12);
HHH(bbb, ccc, ddd, aaa, X[12], 7);
HHH(aaa, bbb, ccc, ddd, X[ 4], 6);
HHH(ddd, aaa, bbb, ccc, X[ 9], 15);
HHH(ccc, ddd, aaa, bbb, X[ 1], 13);
HHH(bbb, ccc, ddd, aaa, X[ 2], 11);
/* parallel round 3 */
GGG(aaa, bbb, ccc, ddd, X[15], 9);
GGG(ddd, aaa, bbb, ccc, X[ 5], 7);
GGG(ccc, ddd, aaa, bbb, X[ 1], 15);
GGG(bbb, ccc, ddd, aaa, X[ 3], 11);
GGG(aaa, bbb, ccc, ddd, X[ 7], 8);
GGG(ddd, aaa, bbb, ccc, X[14], 6);
GGG(ccc, ddd, aaa, bbb, X[ 6], 6);
GGG(bbb, ccc, ddd, aaa, X[ 9], 14);
GGG(aaa, bbb, ccc, ddd, X[11], 12);
GGG(ddd, aaa, bbb, ccc, X[ 8], 13);
GGG(ccc, ddd, aaa, bbb, X[12], 5);
GGG(bbb, ccc, ddd, aaa, X[ 2], 14);
GGG(aaa, bbb, ccc, ddd, X[10], 13);
GGG(ddd, aaa, bbb, ccc, X[ 0], 13);
GGG(ccc, ddd, aaa, bbb, X[ 4], 7);
GGG(bbb, ccc, ddd, aaa, X[13], 5);
/* parallel round 4 */
FFF(aaa, bbb, ccc, ddd, X[ 8], 15);
FFF(ddd, aaa, bbb, ccc, X[ 6], 5);
FFF(ccc, ddd, aaa, bbb, X[ 4], 8);
FFF(bbb, ccc, ddd, aaa, X[ 1], 11);
FFF(aaa, bbb, ccc, ddd, X[ 3], 14);
FFF(ddd, aaa, bbb, ccc, X[11], 14);
FFF(ccc, ddd, aaa, bbb, X[15], 6);
FFF(bbb, ccc, ddd, aaa, X[ 0], 14);
FFF(aaa, bbb, ccc, ddd, X[ 5], 6);
FFF(ddd, aaa, bbb, ccc, X[12], 9);
FFF(ccc, ddd, aaa, bbb, X[ 2], 12);
FFF(bbb, ccc, ddd, aaa, X[13], 9);
FFF(aaa, bbb, ccc, ddd, X[ 9], 12);
FFF(ddd, aaa, bbb, ccc, X[ 7], 5);
FFF(ccc, ddd, aaa, bbb, X[10], 15);
FFF(bbb, ccc, ddd, aaa, X[14], 8);
/* combine results */
ddd += cc + md->rmd128.state[1]; /* final result for MDbuf[0] */
md->rmd128.state[1] = md->rmd128.state[2] + dd + aaa;
md->rmd128.state[2] = md->rmd128.state[3] + aa + bbb;
md->rmd128.state[3] = md->rmd128.state[0] + bb + ccc;
md->rmd128.state[0] = ddd;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int rmd128_compress(hash_state *md, unsigned char *buf)
{
int err;
err = _rmd128_compress(md, buf);
burn_stack(sizeof(ulong32) * 24 + sizeof(int));
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int rmd128_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->rmd128.state[0] = 0x67452301UL;
md->rmd128.state[1] = 0xefcdab89UL;
md->rmd128.state[2] = 0x98badcfeUL;
md->rmd128.state[3] = 0x10325476UL;
md->rmd128.curlen = 0;
md->rmd128.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(rmd128_process, rmd128_compress, rmd128, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (16 bytes)
@return CRYPT_OK if successful
*/
int rmd128_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->rmd128.curlen >= sizeof(md->rmd128.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->rmd128.length += md->rmd128.curlen * 8;
/* append the '1' bit */
md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->rmd128.curlen > 56) {
while (md->rmd128.curlen < 64) {
md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0;
}
rmd128_compress(md, md->rmd128.buf);
md->rmd128.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->rmd128.curlen < 56) {
md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->rmd128.length, md->rmd128.buf+56);
rmd128_compress(md, md->rmd128.buf);
/* copy output */
for (i = 0; i < 4; i++) {
STORE32L(md->rmd128.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int rmd128_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[16];
} tests[] = {
{ "",
{ 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e,
0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 }
},
{ "a",
{ 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7,
0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 }
},
{ "abc",
{ 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba,
0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 }
},
{ "message digest",
{ 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62,
0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 }
},
{ "abcdefghijklmnopqrstuvwxyz",
{ 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5,
0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e }
},
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{ 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f,
0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 }
}
};
int i;
unsigned char tmp[16];
hash_state md;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
rmd128_init(&md);
rmd128_process(&md, (unsigned char *)tests[i].msg, strlen(tests[i].msg));
rmd128_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "RIPEMD128", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

465
thirdparty/libtomcrypt/hashes/rmd160.c vendored Normal file
View File

@@ -0,0 +1,465 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file rmd160.c
RMD160 hash function
*/
/* Implementation of LTC_RIPEMD-160 based on the source by Antoon Bosselaers, ESAT-COSIC
*
* This source has been radically overhauled to be portable and work within
* the LibTomCrypt API by Tom St Denis
*/
#ifdef LTC_RIPEMD160
const struct ltc_hash_descriptor rmd160_desc =
{
"rmd160",
9,
20,
64,
/* OID */
{ 1, 3, 36, 3, 2, 1, },
6,
&rmd160_init,
&rmd160_process,
&rmd160_done,
&rmd160_test,
NULL
};
/* the five basic functions F(), G() and H() */
#define F(x, y, z) ((x) ^ (y) ^ (z))
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define H(x, y, z) (((x) | ~(y)) ^ (z))
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define J(x, y, z) ((x) ^ ((y) | ~(z)))
/* the ten basic operations FF() through III() */
#define FF(a, b, c, d, e, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define GG(a, b, c, d, e, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define HH(a, b, c, d, e, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define II(a, b, c, d, e, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define JJ(a, b, c, d, e, x, s) \
(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define FFF(a, b, c, d, e, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define GGG(a, b, c, d, e, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define HHH(a, b, c, d, e, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define III(a, b, c, d, e, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define JJJ(a, b, c, d, e, x, s) \
(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#ifdef LTC_CLEAN_STACK
static int _rmd160_compress(hash_state *md, unsigned char *buf)
#else
static int rmd160_compress(hash_state *md, unsigned char *buf)
#endif
{
ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16];
int i;
/* load words X */
for (i = 0; i < 16; i++){
LOAD32L(X[i], buf + (4 * i));
}
/* load state */
aa = aaa = md->rmd160.state[0];
bb = bbb = md->rmd160.state[1];
cc = ccc = md->rmd160.state[2];
dd = ddd = md->rmd160.state[3];
ee = eee = md->rmd160.state[4];
/* round 1 */
FF(aa, bb, cc, dd, ee, X[ 0], 11);
FF(ee, aa, bb, cc, dd, X[ 1], 14);
FF(dd, ee, aa, bb, cc, X[ 2], 15);
FF(cc, dd, ee, aa, bb, X[ 3], 12);
FF(bb, cc, dd, ee, aa, X[ 4], 5);
FF(aa, bb, cc, dd, ee, X[ 5], 8);
FF(ee, aa, bb, cc, dd, X[ 6], 7);
FF(dd, ee, aa, bb, cc, X[ 7], 9);
FF(cc, dd, ee, aa, bb, X[ 8], 11);
FF(bb, cc, dd, ee, aa, X[ 9], 13);
FF(aa, bb, cc, dd, ee, X[10], 14);
FF(ee, aa, bb, cc, dd, X[11], 15);
FF(dd, ee, aa, bb, cc, X[12], 6);
FF(cc, dd, ee, aa, bb, X[13], 7);
FF(bb, cc, dd, ee, aa, X[14], 9);
FF(aa, bb, cc, dd, ee, X[15], 8);
/* round 2 */
GG(ee, aa, bb, cc, dd, X[ 7], 7);
GG(dd, ee, aa, bb, cc, X[ 4], 6);
GG(cc, dd, ee, aa, bb, X[13], 8);
GG(bb, cc, dd, ee, aa, X[ 1], 13);
GG(aa, bb, cc, dd, ee, X[10], 11);
GG(ee, aa, bb, cc, dd, X[ 6], 9);
GG(dd, ee, aa, bb, cc, X[15], 7);
GG(cc, dd, ee, aa, bb, X[ 3], 15);
GG(bb, cc, dd, ee, aa, X[12], 7);
GG(aa, bb, cc, dd, ee, X[ 0], 12);
GG(ee, aa, bb, cc, dd, X[ 9], 15);
GG(dd, ee, aa, bb, cc, X[ 5], 9);
GG(cc, dd, ee, aa, bb, X[ 2], 11);
GG(bb, cc, dd, ee, aa, X[14], 7);
GG(aa, bb, cc, dd, ee, X[11], 13);
GG(ee, aa, bb, cc, dd, X[ 8], 12);
/* round 3 */
HH(dd, ee, aa, bb, cc, X[ 3], 11);
HH(cc, dd, ee, aa, bb, X[10], 13);
HH(bb, cc, dd, ee, aa, X[14], 6);
HH(aa, bb, cc, dd, ee, X[ 4], 7);
HH(ee, aa, bb, cc, dd, X[ 9], 14);
HH(dd, ee, aa, bb, cc, X[15], 9);
HH(cc, dd, ee, aa, bb, X[ 8], 13);
HH(bb, cc, dd, ee, aa, X[ 1], 15);
HH(aa, bb, cc, dd, ee, X[ 2], 14);
HH(ee, aa, bb, cc, dd, X[ 7], 8);
HH(dd, ee, aa, bb, cc, X[ 0], 13);
HH(cc, dd, ee, aa, bb, X[ 6], 6);
HH(bb, cc, dd, ee, aa, X[13], 5);
HH(aa, bb, cc, dd, ee, X[11], 12);
HH(ee, aa, bb, cc, dd, X[ 5], 7);
HH(dd, ee, aa, bb, cc, X[12], 5);
/* round 4 */
II(cc, dd, ee, aa, bb, X[ 1], 11);
II(bb, cc, dd, ee, aa, X[ 9], 12);
II(aa, bb, cc, dd, ee, X[11], 14);
II(ee, aa, bb, cc, dd, X[10], 15);
II(dd, ee, aa, bb, cc, X[ 0], 14);
II(cc, dd, ee, aa, bb, X[ 8], 15);
II(bb, cc, dd, ee, aa, X[12], 9);
II(aa, bb, cc, dd, ee, X[ 4], 8);
II(ee, aa, bb, cc, dd, X[13], 9);
II(dd, ee, aa, bb, cc, X[ 3], 14);
II(cc, dd, ee, aa, bb, X[ 7], 5);
II(bb, cc, dd, ee, aa, X[15], 6);
II(aa, bb, cc, dd, ee, X[14], 8);
II(ee, aa, bb, cc, dd, X[ 5], 6);
II(dd, ee, aa, bb, cc, X[ 6], 5);
II(cc, dd, ee, aa, bb, X[ 2], 12);
/* round 5 */
JJ(bb, cc, dd, ee, aa, X[ 4], 9);
JJ(aa, bb, cc, dd, ee, X[ 0], 15);
JJ(ee, aa, bb, cc, dd, X[ 5], 5);
JJ(dd, ee, aa, bb, cc, X[ 9], 11);
JJ(cc, dd, ee, aa, bb, X[ 7], 6);
JJ(bb, cc, dd, ee, aa, X[12], 8);
JJ(aa, bb, cc, dd, ee, X[ 2], 13);
JJ(ee, aa, bb, cc, dd, X[10], 12);
JJ(dd, ee, aa, bb, cc, X[14], 5);
JJ(cc, dd, ee, aa, bb, X[ 1], 12);
JJ(bb, cc, dd, ee, aa, X[ 3], 13);
JJ(aa, bb, cc, dd, ee, X[ 8], 14);
JJ(ee, aa, bb, cc, dd, X[11], 11);
JJ(dd, ee, aa, bb, cc, X[ 6], 8);
JJ(cc, dd, ee, aa, bb, X[15], 5);
JJ(bb, cc, dd, ee, aa, X[13], 6);
/* parallel round 1 */
JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
/* parallel round 2 */
III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
III(ddd, eee, aaa, bbb, ccc, X[11], 13);
III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
III(eee, aaa, bbb, ccc, ddd, X[13], 8);
III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
III(ccc, ddd, eee, aaa, bbb, X[10], 11);
III(bbb, ccc, ddd, eee, aaa, X[14], 7);
III(aaa, bbb, ccc, ddd, eee, X[15], 7);
III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
III(ddd, eee, aaa, bbb, ccc, X[12], 7);
III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
/* parallel round 3 */
HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
/* parallel round 4 */
GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
/* parallel round 5 */
FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
/* combine results */
ddd += cc + md->rmd160.state[1]; /* final result for md->rmd160.state[0] */
md->rmd160.state[1] = md->rmd160.state[2] + dd + eee;
md->rmd160.state[2] = md->rmd160.state[3] + ee + aaa;
md->rmd160.state[3] = md->rmd160.state[4] + aa + bbb;
md->rmd160.state[4] = md->rmd160.state[0] + bb + ccc;
md->rmd160.state[0] = ddd;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int rmd160_compress(hash_state *md, unsigned char *buf)
{
int err;
err = _rmd160_compress(md, buf);
burn_stack(sizeof(ulong32) * 26 + sizeof(int));
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int rmd160_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->rmd160.state[0] = 0x67452301UL;
md->rmd160.state[1] = 0xefcdab89UL;
md->rmd160.state[2] = 0x98badcfeUL;
md->rmd160.state[3] = 0x10325476UL;
md->rmd160.state[4] = 0xc3d2e1f0UL;
md->rmd160.curlen = 0;
md->rmd160.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(rmd160_process, rmd160_compress, rmd160, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (20 bytes)
@return CRYPT_OK if successful
*/
int rmd160_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->rmd160.curlen >= sizeof(md->rmd160.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->rmd160.length += md->rmd160.curlen * 8;
/* append the '1' bit */
md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->rmd160.curlen > 56) {
while (md->rmd160.curlen < 64) {
md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0;
}
rmd160_compress(md, md->rmd160.buf);
md->rmd160.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->rmd160.curlen < 56) {
md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->rmd160.length, md->rmd160.buf+56);
rmd160_compress(md, md->rmd160.buf);
/* copy output */
for (i = 0; i < 5; i++) {
STORE32L(md->rmd160.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int rmd160_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[20];
} tests[] = {
{ "",
{ 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28,
0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }
},
{ "a",
{ 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae,
0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }
},
{ "abc",
{ 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04,
0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }
},
{ "message digest",
{ 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8,
0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }
},
{ "abcdefghijklmnopqrstuvwxyz",
{ 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb,
0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }
},
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{ 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05,
0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }
}
};
int i;
unsigned char tmp[20];
hash_state md;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
rmd160_init(&md);
rmd160_process(&md, (unsigned char *)tests[i].msg, strlen(tests[i].msg));
rmd160_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "RIPEMD160", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

430
thirdparty/libtomcrypt/hashes/rmd256.c vendored Normal file
View File

@@ -0,0 +1,430 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@param rmd256.c
RLTC_MD256 Hash function
*/
#ifdef LTC_RIPEMD256
const struct ltc_hash_descriptor rmd256_desc =
{
"rmd256",
13,
32,
64,
/* OID */
{ 1, 3, 36, 3, 2, 3 },
6,
&rmd256_init,
&rmd256_process,
&rmd256_done,
&rmd256_test,
NULL
};
/* the four basic functions F(), G() and H() */
#define F(x, y, z) ((x) ^ (y) ^ (z))
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define H(x, y, z) (((x) | ~(y)) ^ (z))
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
/* the eight basic operations FF() through III() */
#define FF(a, b, c, d, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s));
#define GG(a, b, c, d, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
(a) = ROLc((a), (s));
#define HH(a, b, c, d, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
(a) = ROLc((a), (s));
#define II(a, b, c, d, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
(a) = ROLc((a), (s));
#define FFF(a, b, c, d, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s));
#define GGG(a, b, c, d, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\
(a) = ROLc((a), (s));
#define HHH(a, b, c, d, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\
(a) = ROLc((a), (s));
#define III(a, b, c, d, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\
(a) = ROLc((a), (s));
#ifdef LTC_CLEAN_STACK
static int _rmd256_compress(hash_state *md, unsigned char *buf)
#else
static int rmd256_compress(hash_state *md, unsigned char *buf)
#endif
{
ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,tmp,X[16];
int i;
/* load words X */
for (i = 0; i < 16; i++){
LOAD32L(X[i], buf + (4 * i));
}
/* load state */
aa = md->rmd256.state[0];
bb = md->rmd256.state[1];
cc = md->rmd256.state[2];
dd = md->rmd256.state[3];
aaa = md->rmd256.state[4];
bbb = md->rmd256.state[5];
ccc = md->rmd256.state[6];
ddd = md->rmd256.state[7];
/* round 1 */
FF(aa, bb, cc, dd, X[ 0], 11);
FF(dd, aa, bb, cc, X[ 1], 14);
FF(cc, dd, aa, bb, X[ 2], 15);
FF(bb, cc, dd, aa, X[ 3], 12);
FF(aa, bb, cc, dd, X[ 4], 5);
FF(dd, aa, bb, cc, X[ 5], 8);
FF(cc, dd, aa, bb, X[ 6], 7);
FF(bb, cc, dd, aa, X[ 7], 9);
FF(aa, bb, cc, dd, X[ 8], 11);
FF(dd, aa, bb, cc, X[ 9], 13);
FF(cc, dd, aa, bb, X[10], 14);
FF(bb, cc, dd, aa, X[11], 15);
FF(aa, bb, cc, dd, X[12], 6);
FF(dd, aa, bb, cc, X[13], 7);
FF(cc, dd, aa, bb, X[14], 9);
FF(bb, cc, dd, aa, X[15], 8);
/* parallel round 1 */
III(aaa, bbb, ccc, ddd, X[ 5], 8);
III(ddd, aaa, bbb, ccc, X[14], 9);
III(ccc, ddd, aaa, bbb, X[ 7], 9);
III(bbb, ccc, ddd, aaa, X[ 0], 11);
III(aaa, bbb, ccc, ddd, X[ 9], 13);
III(ddd, aaa, bbb, ccc, X[ 2], 15);
III(ccc, ddd, aaa, bbb, X[11], 15);
III(bbb, ccc, ddd, aaa, X[ 4], 5);
III(aaa, bbb, ccc, ddd, X[13], 7);
III(ddd, aaa, bbb, ccc, X[ 6], 7);
III(ccc, ddd, aaa, bbb, X[15], 8);
III(bbb, ccc, ddd, aaa, X[ 8], 11);
III(aaa, bbb, ccc, ddd, X[ 1], 14);
III(ddd, aaa, bbb, ccc, X[10], 14);
III(ccc, ddd, aaa, bbb, X[ 3], 12);
III(bbb, ccc, ddd, aaa, X[12], 6);
tmp = aa; aa = aaa; aaa = tmp;
/* round 2 */
GG(aa, bb, cc, dd, X[ 7], 7);
GG(dd, aa, bb, cc, X[ 4], 6);
GG(cc, dd, aa, bb, X[13], 8);
GG(bb, cc, dd, aa, X[ 1], 13);
GG(aa, bb, cc, dd, X[10], 11);
GG(dd, aa, bb, cc, X[ 6], 9);
GG(cc, dd, aa, bb, X[15], 7);
GG(bb, cc, dd, aa, X[ 3], 15);
GG(aa, bb, cc, dd, X[12], 7);
GG(dd, aa, bb, cc, X[ 0], 12);
GG(cc, dd, aa, bb, X[ 9], 15);
GG(bb, cc, dd, aa, X[ 5], 9);
GG(aa, bb, cc, dd, X[ 2], 11);
GG(dd, aa, bb, cc, X[14], 7);
GG(cc, dd, aa, bb, X[11], 13);
GG(bb, cc, dd, aa, X[ 8], 12);
/* parallel round 2 */
HHH(aaa, bbb, ccc, ddd, X[ 6], 9);
HHH(ddd, aaa, bbb, ccc, X[11], 13);
HHH(ccc, ddd, aaa, bbb, X[ 3], 15);
HHH(bbb, ccc, ddd, aaa, X[ 7], 7);
HHH(aaa, bbb, ccc, ddd, X[ 0], 12);
HHH(ddd, aaa, bbb, ccc, X[13], 8);
HHH(ccc, ddd, aaa, bbb, X[ 5], 9);
HHH(bbb, ccc, ddd, aaa, X[10], 11);
HHH(aaa, bbb, ccc, ddd, X[14], 7);
HHH(ddd, aaa, bbb, ccc, X[15], 7);
HHH(ccc, ddd, aaa, bbb, X[ 8], 12);
HHH(bbb, ccc, ddd, aaa, X[12], 7);
HHH(aaa, bbb, ccc, ddd, X[ 4], 6);
HHH(ddd, aaa, bbb, ccc, X[ 9], 15);
HHH(ccc, ddd, aaa, bbb, X[ 1], 13);
HHH(bbb, ccc, ddd, aaa, X[ 2], 11);
tmp = bb; bb = bbb; bbb = tmp;
/* round 3 */
HH(aa, bb, cc, dd, X[ 3], 11);
HH(dd, aa, bb, cc, X[10], 13);
HH(cc, dd, aa, bb, X[14], 6);
HH(bb, cc, dd, aa, X[ 4], 7);
HH(aa, bb, cc, dd, X[ 9], 14);
HH(dd, aa, bb, cc, X[15], 9);
HH(cc, dd, aa, bb, X[ 8], 13);
HH(bb, cc, dd, aa, X[ 1], 15);
HH(aa, bb, cc, dd, X[ 2], 14);
HH(dd, aa, bb, cc, X[ 7], 8);
HH(cc, dd, aa, bb, X[ 0], 13);
HH(bb, cc, dd, aa, X[ 6], 6);
HH(aa, bb, cc, dd, X[13], 5);
HH(dd, aa, bb, cc, X[11], 12);
HH(cc, dd, aa, bb, X[ 5], 7);
HH(bb, cc, dd, aa, X[12], 5);
/* parallel round 3 */
GGG(aaa, bbb, ccc, ddd, X[15], 9);
GGG(ddd, aaa, bbb, ccc, X[ 5], 7);
GGG(ccc, ddd, aaa, bbb, X[ 1], 15);
GGG(bbb, ccc, ddd, aaa, X[ 3], 11);
GGG(aaa, bbb, ccc, ddd, X[ 7], 8);
GGG(ddd, aaa, bbb, ccc, X[14], 6);
GGG(ccc, ddd, aaa, bbb, X[ 6], 6);
GGG(bbb, ccc, ddd, aaa, X[ 9], 14);
GGG(aaa, bbb, ccc, ddd, X[11], 12);
GGG(ddd, aaa, bbb, ccc, X[ 8], 13);
GGG(ccc, ddd, aaa, bbb, X[12], 5);
GGG(bbb, ccc, ddd, aaa, X[ 2], 14);
GGG(aaa, bbb, ccc, ddd, X[10], 13);
GGG(ddd, aaa, bbb, ccc, X[ 0], 13);
GGG(ccc, ddd, aaa, bbb, X[ 4], 7);
GGG(bbb, ccc, ddd, aaa, X[13], 5);
tmp = cc; cc = ccc; ccc = tmp;
/* round 4 */
II(aa, bb, cc, dd, X[ 1], 11);
II(dd, aa, bb, cc, X[ 9], 12);
II(cc, dd, aa, bb, X[11], 14);
II(bb, cc, dd, aa, X[10], 15);
II(aa, bb, cc, dd, X[ 0], 14);
II(dd, aa, bb, cc, X[ 8], 15);
II(cc, dd, aa, bb, X[12], 9);
II(bb, cc, dd, aa, X[ 4], 8);
II(aa, bb, cc, dd, X[13], 9);
II(dd, aa, bb, cc, X[ 3], 14);
II(cc, dd, aa, bb, X[ 7], 5);
II(bb, cc, dd, aa, X[15], 6);
II(aa, bb, cc, dd, X[14], 8);
II(dd, aa, bb, cc, X[ 5], 6);
II(cc, dd, aa, bb, X[ 6], 5);
II(bb, cc, dd, aa, X[ 2], 12);
/* parallel round 4 */
FFF(aaa, bbb, ccc, ddd, X[ 8], 15);
FFF(ddd, aaa, bbb, ccc, X[ 6], 5);
FFF(ccc, ddd, aaa, bbb, X[ 4], 8);
FFF(bbb, ccc, ddd, aaa, X[ 1], 11);
FFF(aaa, bbb, ccc, ddd, X[ 3], 14);
FFF(ddd, aaa, bbb, ccc, X[11], 14);
FFF(ccc, ddd, aaa, bbb, X[15], 6);
FFF(bbb, ccc, ddd, aaa, X[ 0], 14);
FFF(aaa, bbb, ccc, ddd, X[ 5], 6);
FFF(ddd, aaa, bbb, ccc, X[12], 9);
FFF(ccc, ddd, aaa, bbb, X[ 2], 12);
FFF(bbb, ccc, ddd, aaa, X[13], 9);
FFF(aaa, bbb, ccc, ddd, X[ 9], 12);
FFF(ddd, aaa, bbb, ccc, X[ 7], 5);
FFF(ccc, ddd, aaa, bbb, X[10], 15);
FFF(bbb, ccc, ddd, aaa, X[14], 8);
tmp = dd; dd = ddd; ddd = tmp;
/* combine results */
md->rmd256.state[0] += aa;
md->rmd256.state[1] += bb;
md->rmd256.state[2] += cc;
md->rmd256.state[3] += dd;
md->rmd256.state[4] += aaa;
md->rmd256.state[5] += bbb;
md->rmd256.state[6] += ccc;
md->rmd256.state[7] += ddd;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int rmd256_compress(hash_state *md, unsigned char *buf)
{
int err;
err = _rmd256_compress(md, buf);
burn_stack(sizeof(ulong32) * 25 + sizeof(int));
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int rmd256_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->rmd256.state[0] = 0x67452301UL;
md->rmd256.state[1] = 0xefcdab89UL;
md->rmd256.state[2] = 0x98badcfeUL;
md->rmd256.state[3] = 0x10325476UL;
md->rmd256.state[4] = 0x76543210UL;
md->rmd256.state[5] = 0xfedcba98UL;
md->rmd256.state[6] = 0x89abcdefUL;
md->rmd256.state[7] = 0x01234567UL;
md->rmd256.curlen = 0;
md->rmd256.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(rmd256_process, rmd256_compress, rmd256, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (16 bytes)
@return CRYPT_OK if successful
*/
int rmd256_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->rmd256.curlen >= sizeof(md->rmd256.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->rmd256.length += md->rmd256.curlen * 8;
/* append the '1' bit */
md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->rmd256.curlen > 56) {
while (md->rmd256.curlen < 64) {
md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0;
}
rmd256_compress(md, md->rmd256.buf);
md->rmd256.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->rmd256.curlen < 56) {
md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->rmd256.length, md->rmd256.buf+56);
rmd256_compress(md, md->rmd256.buf);
/* copy output */
for (i = 0; i < 8; i++) {
STORE32L(md->rmd256.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int rmd256_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[32];
} tests[] = {
{ "",
{ 0x02, 0xba, 0x4c, 0x4e, 0x5f, 0x8e, 0xcd, 0x18,
0x77, 0xfc, 0x52, 0xd6, 0x4d, 0x30, 0xe3, 0x7a,
0x2d, 0x97, 0x74, 0xfb, 0x1e, 0x5d, 0x02, 0x63,
0x80, 0xae, 0x01, 0x68, 0xe3, 0xc5, 0x52, 0x2d }
},
{ "a",
{ 0xf9, 0x33, 0x3e, 0x45, 0xd8, 0x57, 0xf5, 0xd9,
0x0a, 0x91, 0xba, 0xb7, 0x0a, 0x1e, 0xba, 0x0c,
0xfb, 0x1b, 0xe4, 0xb0, 0x78, 0x3c, 0x9a, 0xcf,
0xcd, 0x88, 0x3a, 0x91, 0x34, 0x69, 0x29, 0x25 }
},
{ "abc",
{ 0xaf, 0xbd, 0x6e, 0x22, 0x8b, 0x9d, 0x8c, 0xbb,
0xce, 0xf5, 0xca, 0x2d, 0x03, 0xe6, 0xdb, 0xa1,
0x0a, 0xc0, 0xbc, 0x7d, 0xcb, 0xe4, 0x68, 0x0e,
0x1e, 0x42, 0xd2, 0xe9, 0x75, 0x45, 0x9b, 0x65 }
},
{ "message digest",
{ 0x87, 0xe9, 0x71, 0x75, 0x9a, 0x1c, 0xe4, 0x7a,
0x51, 0x4d, 0x5c, 0x91, 0x4c, 0x39, 0x2c, 0x90,
0x18, 0xc7, 0xc4, 0x6b, 0xc1, 0x44, 0x65, 0x55,
0x4a, 0xfc, 0xdf, 0x54, 0xa5, 0x07, 0x0c, 0x0e }
},
{ "abcdefghijklmnopqrstuvwxyz",
{ 0x64, 0x9d, 0x30, 0x34, 0x75, 0x1e, 0xa2, 0x16,
0x77, 0x6b, 0xf9, 0xa1, 0x8a, 0xcc, 0x81, 0xbc,
0x78, 0x96, 0x11, 0x8a, 0x51, 0x97, 0x96, 0x87,
0x82, 0xdd, 0x1f, 0xd9, 0x7d, 0x8d, 0x51, 0x33 }
},
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
{ 0x57, 0x40, 0xa4, 0x08, 0xac, 0x16, 0xb7, 0x20,
0xb8, 0x44, 0x24, 0xae, 0x93, 0x1c, 0xbb, 0x1f,
0xe3, 0x63, 0xd1, 0xd0, 0xbf, 0x40, 0x17, 0xf1,
0xa8, 0x9f, 0x7e, 0xa6, 0xde, 0x77, 0xa0, 0xb8 }
}
};
int i;
unsigned char tmp[32];
hash_state md;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
rmd256_init(&md);
rmd256_process(&md, (unsigned char *)tests[i].msg, strlen(tests[i].msg));
rmd256_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "RIPEMD256", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

495
thirdparty/libtomcrypt/hashes/rmd320.c vendored Normal file
View File

@@ -0,0 +1,495 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file rmd320.c
RMD320 hash function
*/
#ifdef LTC_RIPEMD320
const struct ltc_hash_descriptor rmd320_desc =
{
"rmd320",
14,
40,
64,
/* OID ... does not exist
* http://oid-info.com/get/1.3.36.3.2 */
{ 0 },
0,
&rmd320_init,
&rmd320_process,
&rmd320_done,
&rmd320_test,
NULL
};
/* the five basic functions F(), G() and H() */
#define F(x, y, z) ((x) ^ (y) ^ (z))
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define H(x, y, z) (((x) | ~(y)) ^ (z))
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define J(x, y, z) ((x) ^ ((y) | ~(z)))
/* the ten basic operations FF() through III() */
#define FF(a, b, c, d, e, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define GG(a, b, c, d, e, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define HH(a, b, c, d, e, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define II(a, b, c, d, e, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define JJ(a, b, c, d, e, x, s) \
(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define FFF(a, b, c, d, e, x, s) \
(a) += F((b), (c), (d)) + (x);\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define GGG(a, b, c, d, e, x, s) \
(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define HHH(a, b, c, d, e, x, s) \
(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define III(a, b, c, d, e, x, s) \
(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#define JJJ(a, b, c, d, e, x, s) \
(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
(a) = ROLc((a), (s)) + (e);\
(c) = ROLc((c), 10);
#ifdef LTC_CLEAN_STACK
static int _rmd320_compress(hash_state *md, unsigned char *buf)
#else
static int rmd320_compress(hash_state *md, unsigned char *buf)
#endif
{
ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,tmp,X[16];
int i;
/* load words X */
for (i = 0; i < 16; i++){
LOAD32L(X[i], buf + (4 * i));
}
/* load state */
aa = md->rmd320.state[0];
bb = md->rmd320.state[1];
cc = md->rmd320.state[2];
dd = md->rmd320.state[3];
ee = md->rmd320.state[4];
aaa = md->rmd320.state[5];
bbb = md->rmd320.state[6];
ccc = md->rmd320.state[7];
ddd = md->rmd320.state[8];
eee = md->rmd320.state[9];
/* round 1 */
FF(aa, bb, cc, dd, ee, X[ 0], 11);
FF(ee, aa, bb, cc, dd, X[ 1], 14);
FF(dd, ee, aa, bb, cc, X[ 2], 15);
FF(cc, dd, ee, aa, bb, X[ 3], 12);
FF(bb, cc, dd, ee, aa, X[ 4], 5);
FF(aa, bb, cc, dd, ee, X[ 5], 8);
FF(ee, aa, bb, cc, dd, X[ 6], 7);
FF(dd, ee, aa, bb, cc, X[ 7], 9);
FF(cc, dd, ee, aa, bb, X[ 8], 11);
FF(bb, cc, dd, ee, aa, X[ 9], 13);
FF(aa, bb, cc, dd, ee, X[10], 14);
FF(ee, aa, bb, cc, dd, X[11], 15);
FF(dd, ee, aa, bb, cc, X[12], 6);
FF(cc, dd, ee, aa, bb, X[13], 7);
FF(bb, cc, dd, ee, aa, X[14], 9);
FF(aa, bb, cc, dd, ee, X[15], 8);
/* parallel round 1 */
JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
tmp = aa; aa = aaa; aaa = tmp;
/* round 2 */
GG(ee, aa, bb, cc, dd, X[ 7], 7);
GG(dd, ee, aa, bb, cc, X[ 4], 6);
GG(cc, dd, ee, aa, bb, X[13], 8);
GG(bb, cc, dd, ee, aa, X[ 1], 13);
GG(aa, bb, cc, dd, ee, X[10], 11);
GG(ee, aa, bb, cc, dd, X[ 6], 9);
GG(dd, ee, aa, bb, cc, X[15], 7);
GG(cc, dd, ee, aa, bb, X[ 3], 15);
GG(bb, cc, dd, ee, aa, X[12], 7);
GG(aa, bb, cc, dd, ee, X[ 0], 12);
GG(ee, aa, bb, cc, dd, X[ 9], 15);
GG(dd, ee, aa, bb, cc, X[ 5], 9);
GG(cc, dd, ee, aa, bb, X[ 2], 11);
GG(bb, cc, dd, ee, aa, X[14], 7);
GG(aa, bb, cc, dd, ee, X[11], 13);
GG(ee, aa, bb, cc, dd, X[ 8], 12);
/* parallel round 2 */
III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
III(ddd, eee, aaa, bbb, ccc, X[11], 13);
III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
III(eee, aaa, bbb, ccc, ddd, X[13], 8);
III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
III(ccc, ddd, eee, aaa, bbb, X[10], 11);
III(bbb, ccc, ddd, eee, aaa, X[14], 7);
III(aaa, bbb, ccc, ddd, eee, X[15], 7);
III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
III(ddd, eee, aaa, bbb, ccc, X[12], 7);
III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
tmp = bb; bb = bbb; bbb = tmp;
/* round 3 */
HH(dd, ee, aa, bb, cc, X[ 3], 11);
HH(cc, dd, ee, aa, bb, X[10], 13);
HH(bb, cc, dd, ee, aa, X[14], 6);
HH(aa, bb, cc, dd, ee, X[ 4], 7);
HH(ee, aa, bb, cc, dd, X[ 9], 14);
HH(dd, ee, aa, bb, cc, X[15], 9);
HH(cc, dd, ee, aa, bb, X[ 8], 13);
HH(bb, cc, dd, ee, aa, X[ 1], 15);
HH(aa, bb, cc, dd, ee, X[ 2], 14);
HH(ee, aa, bb, cc, dd, X[ 7], 8);
HH(dd, ee, aa, bb, cc, X[ 0], 13);
HH(cc, dd, ee, aa, bb, X[ 6], 6);
HH(bb, cc, dd, ee, aa, X[13], 5);
HH(aa, bb, cc, dd, ee, X[11], 12);
HH(ee, aa, bb, cc, dd, X[ 5], 7);
HH(dd, ee, aa, bb, cc, X[12], 5);
/* parallel round 3 */
HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
tmp = cc; cc = ccc; ccc = tmp;
/* round 4 */
II(cc, dd, ee, aa, bb, X[ 1], 11);
II(bb, cc, dd, ee, aa, X[ 9], 12);
II(aa, bb, cc, dd, ee, X[11], 14);
II(ee, aa, bb, cc, dd, X[10], 15);
II(dd, ee, aa, bb, cc, X[ 0], 14);
II(cc, dd, ee, aa, bb, X[ 8], 15);
II(bb, cc, dd, ee, aa, X[12], 9);
II(aa, bb, cc, dd, ee, X[ 4], 8);
II(ee, aa, bb, cc, dd, X[13], 9);
II(dd, ee, aa, bb, cc, X[ 3], 14);
II(cc, dd, ee, aa, bb, X[ 7], 5);
II(bb, cc, dd, ee, aa, X[15], 6);
II(aa, bb, cc, dd, ee, X[14], 8);
II(ee, aa, bb, cc, dd, X[ 5], 6);
II(dd, ee, aa, bb, cc, X[ 6], 5);
II(cc, dd, ee, aa, bb, X[ 2], 12);
/* parallel round 4 */
GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
tmp = dd; dd = ddd; ddd = tmp;
/* round 5 */
JJ(bb, cc, dd, ee, aa, X[ 4], 9);
JJ(aa, bb, cc, dd, ee, X[ 0], 15);
JJ(ee, aa, bb, cc, dd, X[ 5], 5);
JJ(dd, ee, aa, bb, cc, X[ 9], 11);
JJ(cc, dd, ee, aa, bb, X[ 7], 6);
JJ(bb, cc, dd, ee, aa, X[12], 8);
JJ(aa, bb, cc, dd, ee, X[ 2], 13);
JJ(ee, aa, bb, cc, dd, X[10], 12);
JJ(dd, ee, aa, bb, cc, X[14], 5);
JJ(cc, dd, ee, aa, bb, X[ 1], 12);
JJ(bb, cc, dd, ee, aa, X[ 3], 13);
JJ(aa, bb, cc, dd, ee, X[ 8], 14);
JJ(ee, aa, bb, cc, dd, X[11], 11);
JJ(dd, ee, aa, bb, cc, X[ 6], 8);
JJ(cc, dd, ee, aa, bb, X[15], 5);
JJ(bb, cc, dd, ee, aa, X[13], 6);
/* parallel round 5 */
FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
tmp = ee; ee = eee; eee = tmp;
/* combine results */
md->rmd320.state[0] += aa;
md->rmd320.state[1] += bb;
md->rmd320.state[2] += cc;
md->rmd320.state[3] += dd;
md->rmd320.state[4] += ee;
md->rmd320.state[5] += aaa;
md->rmd320.state[6] += bbb;
md->rmd320.state[7] += ccc;
md->rmd320.state[8] += ddd;
md->rmd320.state[9] += eee;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int rmd320_compress(hash_state *md, unsigned char *buf)
{
int err;
err = _rmd320_compress(md, buf);
burn_stack(sizeof(ulong32) * 27 + sizeof(int));
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int rmd320_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->rmd320.state[0] = 0x67452301UL;
md->rmd320.state[1] = 0xefcdab89UL;
md->rmd320.state[2] = 0x98badcfeUL;
md->rmd320.state[3] = 0x10325476UL;
md->rmd320.state[4] = 0xc3d2e1f0UL;
md->rmd320.state[5] = 0x76543210UL;
md->rmd320.state[6] = 0xfedcba98UL;
md->rmd320.state[7] = 0x89abcdefUL;
md->rmd320.state[8] = 0x01234567UL;
md->rmd320.state[9] = 0x3c2d1e0fUL;
md->rmd320.curlen = 0;
md->rmd320.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(rmd320_process, rmd320_compress, rmd320, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (20 bytes)
@return CRYPT_OK if successful
*/
int rmd320_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->rmd320.curlen >= sizeof(md->rmd320.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->rmd320.length += md->rmd320.curlen * 8;
/* append the '1' bit */
md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->rmd320.curlen > 56) {
while (md->rmd320.curlen < 64) {
md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
}
rmd320_compress(md, md->rmd320.buf);
md->rmd320.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->rmd320.curlen < 56) {
md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0;
}
/* store length */
STORE64L(md->rmd320.length, md->rmd320.buf+56);
rmd320_compress(md, md->rmd320.buf);
/* copy output */
for (i = 0; i < 10; i++) {
STORE32L(md->rmd320.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int rmd320_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[40];
} tests[] = {
{ "",
{ 0x22, 0xd6, 0x5d, 0x56, 0x61, 0x53, 0x6c, 0xdc, 0x75, 0xc1,
0xfd, 0xf5, 0xc6, 0xde, 0x7b, 0x41, 0xb9, 0xf2, 0x73, 0x25,
0xeb, 0xc6, 0x1e, 0x85, 0x57, 0x17, 0x7d, 0x70, 0x5a, 0x0e,
0xc8, 0x80, 0x15, 0x1c, 0x3a, 0x32, 0xa0, 0x08, 0x99, 0xb8 }
},
{ "a",
{ 0xce, 0x78, 0x85, 0x06, 0x38, 0xf9, 0x26, 0x58, 0xa5, 0xa5,
0x85, 0x09, 0x75, 0x79, 0x92, 0x6d, 0xda, 0x66, 0x7a, 0x57,
0x16, 0x56, 0x2c, 0xfc, 0xf6, 0xfb, 0xe7, 0x7f, 0x63, 0x54,
0x2f, 0x99, 0xb0, 0x47, 0x05, 0xd6, 0x97, 0x0d, 0xff, 0x5d }
},
{ "abc",
{ 0xde, 0x4c, 0x01, 0xb3, 0x05, 0x4f, 0x89, 0x30, 0xa7, 0x9d,
0x09, 0xae, 0x73, 0x8e, 0x92, 0x30, 0x1e, 0x5a, 0x17, 0x08,
0x5b, 0xef, 0xfd, 0xc1, 0xb8, 0xd1, 0x16, 0x71, 0x3e, 0x74,
0xf8, 0x2f, 0xa9, 0x42, 0xd6, 0x4c, 0xdb, 0xc4, 0x68, 0x2d }
},
{ "message digest",
{ 0x3a, 0x8e, 0x28, 0x50, 0x2e, 0xd4, 0x5d, 0x42, 0x2f, 0x68,
0x84, 0x4f, 0x9d, 0xd3, 0x16, 0xe7, 0xb9, 0x85, 0x33, 0xfa,
0x3f, 0x2a, 0x91, 0xd2, 0x9f, 0x84, 0xd4, 0x25, 0xc8, 0x8d,
0x6b, 0x4e, 0xff, 0x72, 0x7d, 0xf6, 0x6a, 0x7c, 0x01, 0x97 }
},
{ "abcdefghijklmnopqrstuvwxyz",
{ 0xca, 0xbd, 0xb1, 0x81, 0x0b, 0x92, 0x47, 0x0a, 0x20, 0x93,
0xaa, 0x6b, 0xce, 0x05, 0x95, 0x2c, 0x28, 0x34, 0x8c, 0xf4,
0x3f, 0xf6, 0x08, 0x41, 0x97, 0x51, 0x66, 0xbb, 0x40, 0xed,
0x23, 0x40, 0x04, 0xb8, 0x82, 0x44, 0x63, 0xe6, 0xb0, 0x09 }
},
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{ 0xd0, 0x34, 0xa7, 0x95, 0x0c, 0xf7, 0x22, 0x02, 0x1b, 0xa4,
0xb8, 0x4d, 0xf7, 0x69, 0xa5, 0xde, 0x20, 0x60, 0xe2, 0x59,
0xdf, 0x4c, 0x9b, 0xb4, 0xa4, 0x26, 0x8c, 0x0e, 0x93, 0x5b,
0xbc, 0x74, 0x70, 0xa9, 0x69, 0xc9, 0xd0, 0x72, 0xa1, 0xac }
}
};
int i;
unsigned char tmp[40];
hash_state md;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
rmd320_init(&md);
rmd320_process(&md, (unsigned char *)tests[i].msg, strlen(tests[i].msg));
rmd320_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "RIPEMD320", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

286
thirdparty/libtomcrypt/hashes/sha1.c vendored Normal file
View File

@@ -0,0 +1,286 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file sha1.c
LTC_SHA1 code by Tom St Denis
*/
#ifdef LTC_SHA1
const struct ltc_hash_descriptor sha1_desc =
{
"sha1",
2,
20,
64,
/* OID */
{ 1, 3, 14, 3, 2, 26, },
6,
&sha1_init,
&sha1_process,
&sha1_done,
&sha1_test,
NULL
};
#define F0(x,y,z) (z ^ (x & (y ^ z)))
#define F1(x,y,z) (x ^ y ^ z)
#define F2(x,y,z) ((x & y) | (z & (x | y)))
#define F3(x,y,z) (x ^ y ^ z)
#ifdef LTC_CLEAN_STACK
static int _sha1_compress(hash_state *md, unsigned char *buf)
#else
static int sha1_compress(hash_state *md, unsigned char *buf)
#endif
{
ulong32 a,b,c,d,e,W[80],i;
#ifdef LTC_SMALL_CODE
ulong32 t;
#endif
/* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD32H(W[i], buf + (4*i));
}
/* copy state */
a = md->sha1.state[0];
b = md->sha1.state[1];
c = md->sha1.state[2];
d = md->sha1.state[3];
e = md->sha1.state[4];
/* expand it */
for (i = 16; i < 80; i++) {
W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
}
/* compress */
/* round one */
#define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
#define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
#define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
#define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
#ifdef LTC_SMALL_CODE
for (i = 0; i < 20; ) {
FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 40; ) {
FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 60; ) {
FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 80; ) {
FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
#else
for (i = 0; i < 20; ) {
FF0(a,b,c,d,e,i++);
FF0(e,a,b,c,d,i++);
FF0(d,e,a,b,c,i++);
FF0(c,d,e,a,b,i++);
FF0(b,c,d,e,a,i++);
}
/* round two */
for (; i < 40; ) {
FF1(a,b,c,d,e,i++);
FF1(e,a,b,c,d,i++);
FF1(d,e,a,b,c,i++);
FF1(c,d,e,a,b,i++);
FF1(b,c,d,e,a,i++);
}
/* round three */
for (; i < 60; ) {
FF2(a,b,c,d,e,i++);
FF2(e,a,b,c,d,i++);
FF2(d,e,a,b,c,i++);
FF2(c,d,e,a,b,i++);
FF2(b,c,d,e,a,i++);
}
/* round four */
for (; i < 80; ) {
FF3(a,b,c,d,e,i++);
FF3(e,a,b,c,d,i++);
FF3(d,e,a,b,c,i++);
FF3(c,d,e,a,b,i++);
FF3(b,c,d,e,a,i++);
}
#endif
#undef FF0
#undef FF1
#undef FF2
#undef FF3
/* store */
md->sha1.state[0] = md->sha1.state[0] + a;
md->sha1.state[1] = md->sha1.state[1] + b;
md->sha1.state[2] = md->sha1.state[2] + c;
md->sha1.state[3] = md->sha1.state[3] + d;
md->sha1.state[4] = md->sha1.state[4] + e;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int sha1_compress(hash_state *md, unsigned char *buf)
{
int err;
err = _sha1_compress(md, buf);
burn_stack(sizeof(ulong32) * 87);
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha1_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha1.state[0] = 0x67452301UL;
md->sha1.state[1] = 0xefcdab89UL;
md->sha1.state[2] = 0x98badcfeUL;
md->sha1.state[3] = 0x10325476UL;
md->sha1.state[4] = 0xc3d2e1f0UL;
md->sha1.curlen = 0;
md->sha1.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(sha1_process, sha1_compress, sha1, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (20 bytes)
@return CRYPT_OK if successful
*/
int sha1_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->sha1.curlen >= sizeof(md->sha1.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->sha1.length += md->sha1.curlen * 8;
/* append the '1' bit */
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->sha1.curlen > 56) {
while (md->sha1.curlen < 64) {
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
}
sha1_compress(md, md->sha1.buf);
md->sha1.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->sha1.curlen < 56) {
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
}
/* store length */
STORE64H(md->sha1.length, md->sha1.buf+56);
sha1_compress(md, md->sha1.buf);
/* copy output */
for (i = 0; i < 5; i++) {
STORE32H(md->sha1.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha1_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[20];
} tests[] = {
{ "abc",
{ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
0x9c, 0xd0, 0xd8, 0x9d }
},
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
0xE5, 0x46, 0x70, 0xF1 }
}
};
int i;
unsigned char tmp[20];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha1_init(&md);
sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
sha1_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA1", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,129 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@param sha224.c
LTC_SHA-224 new NIST standard based off of LTC_SHA-256 truncated to 224 bits (Tom St Denis)
*/
#include "tomcrypt.h"
#if defined(LTC_SHA224) && defined(LTC_SHA256)
const struct ltc_hash_descriptor sha224_desc =
{
"sha224",
10,
28,
64,
/* OID */
{ 2, 16, 840, 1, 101, 3, 4, 2, 4, },
9,
&sha224_init,
&sha256_process,
&sha224_done,
&sha224_test,
NULL
};
/* init the sha256 er... sha224 state ;-) */
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha224_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha256.curlen = 0;
md->sha256.length = 0;
md->sha256.state[0] = 0xc1059ed8UL;
md->sha256.state[1] = 0x367cd507UL;
md->sha256.state[2] = 0x3070dd17UL;
md->sha256.state[3] = 0xf70e5939UL;
md->sha256.state[4] = 0xffc00b31UL;
md->sha256.state[5] = 0x68581511UL;
md->sha256.state[6] = 0x64f98fa7UL;
md->sha256.state[7] = 0xbefa4fa4UL;
return CRYPT_OK;
}
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (28 bytes)
@return CRYPT_OK if successful
*/
int sha224_done(hash_state * md, unsigned char *out)
{
unsigned char buf[32];
int err;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
err = sha256_done(md, buf);
XMEMCPY(out, buf, 28);
#ifdef LTC_CLEAN_STACK
zeromem(buf, sizeof(buf));
#endif
return err;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha224_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[28];
} tests[] = {
{ "abc",
{ 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8,
0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2,
0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd,
0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 }
},
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{ 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76,
0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89,
0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4,
0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 }
},
};
int i;
unsigned char tmp[28];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha224_init(&md);
sha224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
sha224_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA224", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif /* defined(LTC_SHA224) && defined(LTC_SHA256) */
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,334 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@file sha256.c
LTC_SHA256 by Tom St Denis
*/
#ifdef LTC_SHA256
const struct ltc_hash_descriptor sha256_desc =
{
"sha256",
0,
32,
64,
/* OID */
{ 2, 16, 840, 1, 101, 3, 4, 2, 1, },
9,
&sha256_init,
&sha256_process,
&sha256_done,
&sha256_test,
NULL
};
#ifdef LTC_SMALL_CODE
/* the K array */
static const ulong32 K[64] = {
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
};
#endif
/* Various logical functions */
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
#define Maj(x,y,z) (((x | y) & z) | (x & y))
#define S(x, n) RORc((x),(n))
#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
/* compress 512-bits */
#ifdef LTC_CLEAN_STACK
static int _sha256_compress(hash_state * md, unsigned char *buf)
#else
static int sha256_compress(hash_state * md, unsigned char *buf)
#endif
{
ulong32 S[8], W[64], t0, t1;
#ifdef LTC_SMALL_CODE
ulong32 t;
#endif
int i;
/* copy state into S */
for (i = 0; i < 8; i++) {
S[i] = md->sha256.state[i];
}
/* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD32H(W[i], buf + (4*i));
}
/* fill W[16..63] */
for (i = 16; i < 64; i++) {
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
}
/* Compress */
#ifdef LTC_SMALL_CODE
#define RND(a,b,c,d,e,f,g,h,i) \
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
for (i = 0; i < 64; ++i) {
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
}
#else
#define RND(a,b,c,d,e,f,g,h,i,ki) \
t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
#undef RND
#endif
/* feedback */
for (i = 0; i < 8; i++) {
md->sha256.state[i] = md->sha256.state[i] + S[i];
}
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int sha256_compress(hash_state * md, unsigned char *buf)
{
int err;
err = _sha256_compress(md, buf);
burn_stack(sizeof(ulong32) * 74);
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha256_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha256.curlen = 0;
md->sha256.length = 0;
md->sha256.state[0] = 0x6A09E667UL;
md->sha256.state[1] = 0xBB67AE85UL;
md->sha256.state[2] = 0x3C6EF372UL;
md->sha256.state[3] = 0xA54FF53AUL;
md->sha256.state[4] = 0x510E527FUL;
md->sha256.state[5] = 0x9B05688CUL;
md->sha256.state[6] = 0x1F83D9ABUL;
md->sha256.state[7] = 0x5BE0CD19UL;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(sha256_process, sha256_compress, sha256, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (32 bytes)
@return CRYPT_OK if successful
*/
int sha256_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->sha256.curlen >= sizeof(md->sha256.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->sha256.length += md->sha256.curlen * 8;
/* append the '1' bit */
md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80;
/* if the length is currently above 56 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->sha256.curlen > 56) {
while (md->sha256.curlen < 64) {
md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
}
sha256_compress(md, md->sha256.buf);
md->sha256.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->sha256.curlen < 56) {
md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
}
/* store length */
STORE64H(md->sha256.length, md->sha256.buf+56);
sha256_compress(md, md->sha256.buf);
/* copy output */
for (i = 0; i < 8; i++) {
STORE32H(md->sha256.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha256_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[32];
} tests[] = {
{ "abc",
{ 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }
},
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{ 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }
},
};
int i;
unsigned char tmp[32];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha256_init(&md);
sha256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
sha256_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA256", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,134 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
/**
@param sha384.c
LTC_SHA384 hash included in sha512.c, Tom St Denis
*/
#include "tomcrypt.h"
#if defined(LTC_SHA384) && defined(LTC_SHA512)
const struct ltc_hash_descriptor sha384_desc =
{
"sha384",
4,
48,
128,
/* OID */
{ 2, 16, 840, 1, 101, 3, 4, 2, 2, },
9,
&sha384_init,
&sha512_process,
&sha384_done,
&sha384_test,
NULL
};
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha384_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha512.curlen = 0;
md->sha512.length = 0;
md->sha512.state[0] = CONST64(0xcbbb9d5dc1059ed8);
md->sha512.state[1] = CONST64(0x629a292a367cd507);
md->sha512.state[2] = CONST64(0x9159015a3070dd17);
md->sha512.state[3] = CONST64(0x152fecd8f70e5939);
md->sha512.state[4] = CONST64(0x67332667ffc00b31);
md->sha512.state[5] = CONST64(0x8eb44a8768581511);
md->sha512.state[6] = CONST64(0xdb0c2e0d64f98fa7);
md->sha512.state[7] = CONST64(0x47b5481dbefa4fa4);
return CRYPT_OK;
}
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (48 bytes)
@return CRYPT_OK if successful
*/
int sha384_done(hash_state * md, unsigned char *out)
{
unsigned char buf[64];
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
return CRYPT_INVALID_ARG;
}
sha512_done(md, buf);
XMEMCPY(out, buf, 48);
#ifdef LTC_CLEAN_STACK
zeromem(buf, sizeof(buf));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha384_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[48];
} tests[] = {
{ "abc",
{ 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 }
},
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
{ 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 }
},
};
int i;
unsigned char tmp[48];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha384_init(&md);
sha384_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
sha384_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA384", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif /* defined(LTC_SHA384) && defined(LTC_SHA512) */
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

View File

@@ -0,0 +1,313 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*/
#include "tomcrypt.h"
/**
@param sha512.c
LTC_SHA512 by Tom St Denis
*/
#ifdef LTC_SHA512
const struct ltc_hash_descriptor sha512_desc =
{
"sha512",
5,
64,
128,
/* OID */
{ 2, 16, 840, 1, 101, 3, 4, 2, 3, },
9,
&sha512_init,
&sha512_process,
&sha512_done,
&sha512_test,
NULL
};
/* the K array */
static const ulong64 K[80] = {
CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd),
CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019),
CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe),
CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1),
CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3),
CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483),
CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210),
CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725),
CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926),
CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8),
CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910),
CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53),
CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb),
CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60),
CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9),
CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207),
CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6),
CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493),
CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a),
CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
};
/* Various logical functions */
#define Ch(x,y,z) (z ^ (x & (y ^ z)))
#define Maj(x,y,z) (((x | y) & z) | (x & y))
#define S(x, n) ROR64c(x, n)
#define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
/* compress 1024-bits */
#ifdef LTC_CLEAN_STACK
static int _sha512_compress(hash_state * md, unsigned char *buf)
#else
static int sha512_compress(hash_state * md, unsigned char *buf)
#endif
{
ulong64 S[8], W[80], t0, t1;
int i;
/* copy state into S */
for (i = 0; i < 8; i++) {
S[i] = md->sha512.state[i];
}
/* copy the state into 1024-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD64H(W[i], buf + (8*i));
}
/* fill W[16..79] */
for (i = 16; i < 80; i++) {
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
}
/* Compress */
#ifdef LTC_SMALL_CODE
for (i = 0; i < 80; i++) {
t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
S[7] = S[6];
S[6] = S[5];
S[5] = S[4];
S[4] = S[3] + t0;
S[3] = S[2];
S[2] = S[1];
S[1] = S[0];
S[0] = t0 + t1;
}
#else
#define RND(a,b,c,d,e,f,g,h,i) \
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c); \
d += t0; \
h = t0 + t1;
for (i = 0; i < 80; i += 8) {
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
}
#endif
/* feedback */
for (i = 0; i < 8; i++) {
md->sha512.state[i] = md->sha512.state[i] + S[i];
}
return CRYPT_OK;
}
/* compress 1024-bits */
#ifdef LTC_CLEAN_STACK
static int sha512_compress(hash_state * md, unsigned char *buf)
{
int err;
err = _sha512_compress(md, buf);
burn_stack(sizeof(ulong64) * 90 + sizeof(int));
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha512_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha512.curlen = 0;
md->sha512.length = 0;
md->sha512.state[0] = CONST64(0x6a09e667f3bcc908);
md->sha512.state[1] = CONST64(0xbb67ae8584caa73b);
md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b);
md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1);
md->sha512.state[4] = CONST64(0x510e527fade682d1);
md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f);
md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b);
md->sha512.state[7] = CONST64(0x5be0cd19137e2179);
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(sha512_process, sha512_compress, sha512, 128)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (64 bytes)
@return CRYPT_OK if successful
*/
int sha512_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->sha512.length += md->sha512.curlen * CONST64(8);
/* append the '1' bit */
md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80;
/* if the length is currently above 112 bytes we append zeros
* then compress. Then we can fall back to padding zeros and length
* encoding like normal.
*/
if (md->sha512.curlen > 112) {
while (md->sha512.curlen < 128) {
md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
}
sha512_compress(md, md->sha512.buf);
md->sha512.curlen = 0;
}
/* pad upto 120 bytes of zeroes
* note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
* > 2^64 bits of data... :-)
*/
while (md->sha512.curlen < 120) {
md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
}
/* store length */
STORE64H(md->sha512.length, md->sha512.buf+120);
sha512_compress(md, md->sha512.buf);
/* copy output */
for (i = 0; i < 8; i++) {
STORE64H(md->sha512.state[i], out+(8*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha512_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
const char *msg;
unsigned char hash[64];
} tests[] = {
{ "abc",
{ 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
},
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
{ 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
},
};
int i;
unsigned char tmp[64];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha512_init(&md);
sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
sha512_done(&md, tmp);
if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "SHA512", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* ref: HEAD -> master, tag: v1.18.2 */
/* git commit: 7e7eb695d581782f04b24dc444cbfde86af59853 */
/* commit time: 2018-07-01 22:49:01 +0200 */

Some files were not shown because too many files have changed in this diff Show More