| /* Variable Tuple by Takuji Nishimura, 2005/04/12 */ |
/* Variable Tuple by Takuji Nishimura, 2005/04/12 */ |
| /* Tough against differential crypt attack, 2005/04/13 */ |
/* Tough against differential crypt attack, 2005/04/13 */ |
| /* The algorithm is fixed, 2005/04/15 */ |
/* The algorithm is fixed, 2005/04/15 */ |
| #include <stdio.h> |
|
| |
|
| #include "ecrypt-config.h" |
|
| #include "ecrypt-machine.h" |
|
| #include "ecrypt-portable.h" |
|
| |
|
| #include "ecrypt-sync.h" |
/* |
| |
LICENSE CONDITION |
| |
|
| void genrand_tuple_int32(ECRYPT_ctx* ctx, u32 rand_tuple[], s32 len); |
1. A patent on this algorithm is pending as of 2005 May. The |
| void init_by_array(ECRYPT_ctx* ctx, u32 init_key[], int key_length); |
intellectual property belongs to Hiroshima University and Ochanomizu |
| |
University. |
| |
|
| |
2. This software is free for non-commercial use. |
| |
2-1 "Non-commercial use" explicitly includes research and educational |
| |
purposes, as well as use in software which is made available for free. |
| |
2-2 "Non-commercial use" also includes any other kind of use, except |
| |
those stated in item 3. |
| |
|
| |
3. Contacting the inventors is required for commercial use, as |
| |
defined in item 3-1. |
| |
3-1. In the case of selling software or hardware which utilizes this |
| |
software or this algorithm. |
| |
|
| |
4. Royalties may be required in cases of commercial use as defined in |
| |
item 3. However with the exception of a few cases as stated in |
| |
Background, below, it is our intention to allow general royalty-free |
| |
use. |
| |
|
| |
5. We disclaim any responsibility for any direct or indirect damages |
| |
caused by this software or algorithm. |
| |
|
| |
Background: |
| |
A. The inventors of this algorithm are Makoto Matsumoto (Hiroshima |
| |
University), Mariko Hagita (Ochanomizu University), Takuji Nishimura |
| |
(Yamagata University), and Mutsuo Saito (Hiroshima University). |
| |
(Affiliations as of 2005 Dec.) |
| |
|
| |
B. By the regulations of Hiroshima University and Ochanomizu |
| |
University, all inventions by the worker(s) are examined with respect |
| |
to patent, and their intellectual property is owned by the university |
| |
(ies), if deemed necessary. |
| |
|
| |
C. The inventors' wish is to allow the algorithm/software to be as |
| |
freely and widely used as possible. |
| |
|
| |
D. The desire of the intellectual property centers (IPCs) of |
| |
Hiroshima University and Ochanomizu University is to obtain the |
| |
minimum amount of income necessary to cover the expense for the |
| |
patent application, maintaining the patent, and continuing this |
| |
research. |
| |
|
| |
E. Thus, we plan to make this algorithm/software free even for |
| |
commercial uses, if the IPCs can obtain this amount of income from |
| |
large companies (such as Microsoft or Apple) or governmental |
| |
organizations, in the form of royalties or contributions. |
| |
|
| |
F. The names of companies and organizations who pay royalties or make |
| |
contributions will be included in this program when it is revised, |
| |
under the consent of the inventors, and will be advertised as |
| |
sponsors on the home page of this algorithm. |
| |
|
| |
G. This algorithm is an applicant for the eSTREAM stream cipher |
| |
project http://www.ecrypt.eu.org/stream/. If eSTREAM selects this |
| |
algorithm as one of the recommendable stream ciphers in its final |
| |
report planned for 2008 January, then we will make this algorithm/ |
| |
software free even for commercial use, regardless of the condition in |
| |
E. However, preferably we hope to recieve some royalties or |
| |
contributions to satisfy the desire in item D. |
| |
|
| |
These statements are claimed by us, namely, the Inventors listed in |
| |
item A, the IPC of Hiroshima University, and the IPC of Ochanomizu |
| |
University. |
| |
|
| |
Corresponding address: |
| |
Makoto Matsumoto, Department of Mathematics, Hiroshima University. |
| |
1-3-1 Kagamiyama, Higashi-Hiroshima 739-8526 Japan. |
| |
http://www.math.sci.hiroshima-u.ac.jp/~m-mat/eindex.html |
| |
email: m-mat "at-mark" math.sci.hiroshima-u.ac.jp |
| |
*/ |
| |
|
| #ifdef ECRYPT_API |
#include <stdio.h> |
| #include "mt-fubuki.c" |
#include "ecrypt-sync.h" |
| #endif |
#include "ecrypt-machine.h" |
| |
|
| /* This is a stream cipher. One word means a 32 bit word. */ |
/* This is a stream cipher. One word means a 32 bit word. */ |
| /* Tuple words will be gather to make one Block. */ |
/* Tuple words will be gather to make one Block. */ |
| /* Typically Tuple is 4. Log_Tuple is log2(Tuple) */ |
/* Typically Tuple is 4. Log_Tuple is log2(Tuple) */ |
| #define Log_Tuple 2 |
#define Log_Tuple 2 |
| |
|
| #define Tuple (U32C(1) << Log_Tuple) |
#define Tuple (U32C(1) << Log_Tuple) |
| |
|
| #define Low_Mask (Tuple-1) |
#define Low_Mask (Tuple-1) |
| |
|
| #define Iteration 4 /* <=32: number of primitive encrypt function iterations */ |
#define Iteration 4 /* <=32: number of primitive encrypt function iterations */ |
| |
|
| #define Multi_Size 32 /* number of constant multipliers */ |
#define Multi_Size 32 /* number of constant multipliers */ |
| |
|
| #define Log_Add_Size 5 /* Log of Add_Size */ |
#define Log_Add_Size 5 /* Log of Add_Size */ |
| #define Add_Size 32 /* number of constant adders */ |
#define Add_Size 32 /* number of constant adders */ |
| |
|
| /* for debug */ |
static void init_genrand(ECRYPT_ctx* ctx, u32 s); |
| void print_block(u32 block[]) { |
static void init_by_array(ECRYPT_ctx* ctx, u32 init_key[], int key_length); |
| |
static void genrand_whole_array(ECRYPT_ctx* ctx); |
| |
static void genrand_tuple_int32(ECRYPT_ctx* ctx, u32 rand_tuple[], s32 len); |
| |
|
| |
static void prepare_multi(ECRYPT_ctx *ctx); |
| |
static u32 inv_mod_32(u32 m); |
| |
static void prepare_multi_inv(ECRYPT_ctx *ctx); |
| |
static void prepare_add_table(ECRYPT_ctx *ctx); |
| |
static void crypt_empr(ECRYPT_ctx *ctx, u32 block[Tuple]); |
| |
static void crypt_empr_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]); |
| |
static void crypt_emer(ECRYPT_ctx *ctx, u32 block[Tuple]); |
| |
static void crypt_emer_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]); |
| |
static void crypt_emps(ECRYPT_ctx *ctx, u32 block[Tuple]); |
| |
static void crypt_emps_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]); |
| |
static void crypt_emes(ECRYPT_ctx *ctx, u32 block[Tuple]); |
| |
static void crypt_emes_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]); |
| |
static void crypt_ma(ECRYPT_ctx *ctx, u32 block[Tuple]); |
| |
static void crypt_ma_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]); |
| |
static void crypt_mem(ECRYPT_ctx *ctx, u32 block[Tuple]); |
| |
static void crypt_mem_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]); |
| |
static void crypt_ome(ECRYPT_ctx *ctx, u32 block[Tuple]); |
| |
static void crypt_ome_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]); |
| |
static void crypt_eme(ECRYPT_ctx *ctx, u32 block[Tuple]); |
| |
static void crypt_eme_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple]); |
| |
static void crypt_vert_rotate(ECRYPT_ctx *ctx, u32 block[Tuple]); |
| |
static void crypt_vert_rotate_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]); |
| |
static void set_buf(u32 buf[], const u8* text, u32 cpos, u32 msglen); |
| |
static void set_array(u32 buf[], u8* text, u32 cpos); |
| |
|
| |
|
| |
/* Period Parameters of MT */ |
| |
#define N 624 |
| |
#define M 397 |
| |
#define MATRIX_A U32C(0x9908B0DF) /* constant vector a */ |
| |
#define UPPER_MASK U32C(0x80000000) /* most significant w-r bits */ |
| |
#define LOWER_MASK U32C(0x7FFFFFFF) /* least significant r bits */ |
| |
|
| |
/* initializes ctx->mt[N] with a seed */ |
| |
static void init_genrand(ECRYPT_ctx* ctx, u32 s) |
| |
{ |
| |
ctx->mt[0]= s & U32C(0xFFFFFFFF); |
| |
for (ctx->i=1; ctx->i<N; ctx->i++) { |
| |
ctx->mt[ctx->i] = |
| |
(U32C(1812433253) * (ctx->mt[ctx->i-1] ^ (ctx->mt[ctx->i-1] >> 30)) + ctx->i); |
| |
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ |
| |
/* In the previous versions, MSBs of the seed affect */ |
| |
/* only MSBs of the array mt[]. */ |
| |
/* 2002/01/09 modified by Makoto Matsumoto */ |
| |
} |
| |
} |
| |
|
| |
/* initialize by an array with array-length */ |
| |
/* init_key is the array for initializing keys */ |
| |
/* key_length is its length */ |
| |
/* slight change for C++, 2004/2/26 */ |
| |
static void init_by_array(ECRYPT_ctx* ctx, u32 init_key[], int key_length) |
| |
{ |
| |
int i, j, k; |
| |
init_genrand(ctx, U32C(19650218)); |
| |
i=1; j=0; |
| |
k = (N>key_length ? N : key_length); |
| |
for (; k; k--) { |
| |
ctx->mt[i] = (ctx->mt[i] ^ ((ctx->mt[i-1] ^ (ctx->mt[i-1] >> 30)) * 1664525UL)) |
| |
+ init_key[j] + j; /* non linear */ |
| |
i++; j++; |
| |
if (i>=N) { ctx->mt[0] = ctx->mt[N-1]; i=1; } |
| |
if (j>=key_length) j=0; |
| |
} |
| |
for (k=N-1; k; k--) { |
| |
ctx->mt[i] = (ctx->mt[i] ^ ((ctx->mt[i-1] ^ (ctx->mt[i-1] >> 30)) * 1566083941UL)) |
| |
- i; /* non linear */ |
| |
i++; |
| |
if (i>=N) { ctx->mt[0] = ctx->mt[N-1]; i=1; } |
| |
} |
| |
|
| |
ctx->mt[0] = U32C(0x80000000); /* MSB is 1; assuring non-zero initial array */ |
| |
} |
| |
|
| |
/* generates whole array of random numbers in [0,0xffffffff]-interval */ |
| |
static void genrand_whole_array(ECRYPT_ctx* ctx) |
| |
{ |
| |
u32 y; |
| |
static u32 mag01[2]={U32C(0x0), MATRIX_A}; |
| |
/* mag01[x] = x * MATRIX_A for x=0,1 */ |
| |
|
| |
int kk; |
| |
|
| |
for (kk=0;kk<N-M;kk++) { |
| |
y = (ctx->mt[kk]&UPPER_MASK)|(ctx->mt[kk+1]&LOWER_MASK); |
| |
ctx->mt[kk] = ctx->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL]; |
| |
} |
| |
for (;kk<N-1;kk++) { |
| |
y = (ctx->mt[kk]&UPPER_MASK)|(ctx->mt[kk+1]&LOWER_MASK); |
| |
ctx->mt[kk] = ctx->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL]; |
| |
} |
| |
y = (ctx->mt[N-1]&UPPER_MASK)|(ctx->mt[0]&LOWER_MASK); |
| |
ctx->mt[N-1] = ctx->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; |
| |
|
| |
ctx->i = 0; |
| |
return ; |
| |
} |
| |
|
| |
/* generates len (<624) random numbers on [0,0xffffffff]-interval */ |
| |
/* rand_tuple[0]-[len-1] will be supplied with random numbers */ |
| |
static void genrand_tuple_int32(ECRYPT_ctx* ctx, u32 rand_tuple[], s32 len) |
| |
{ |
| s32 i; |
s32 i; |
| for (i=0; i<Tuple; i++) printf("%8x ", block[i]); |
|
| printf("\n"); |
if (ctx->i + len < N) { |
| |
for (i=0; i<len; i++) |
| |
rand_tuple[i] = ctx->mt[ctx->i++]; |
| |
} |
| |
else { |
| |
for (i=0; i<len; i++) { |
| |
if (ctx->i >= N) |
| |
genrand_whole_array(ctx); |
| |
rand_tuple[i] = ctx->mt[ctx->i++]; |
| |
} |
| |
} |
| } |
} |
| |
|
| |
|
| |
|
| /**********************************************/ |
/**********************************************/ |
| /******** Precomputation of Tables **********/ |
/******** Precomputation of Tables **********/ |
| /**********************************************/ |
/**********************************************/ |
| |
|
| /* Compute Multiplication Constants: 3 mod 8, 7 mod 16 */ |
/* Compute Multiplication Constants: 3 mod 8, 7 mod 16 */ |
| void prepare_multi(ECRYPT_ctx* ctx) { |
static void prepare_multi(ECRYPT_ctx *ctx) |
| |
{ |
| s32 i; |
s32 i; |
| |
|
| for (i=0; i<Multi_Size; i+=4) { |
for (i=0; i<Multi_Size; i+=4) { |
| genrand_tuple_int32(ctx, &ctx->multi_table[i], 4); |
genrand_tuple_int32(ctx, &ctx->multi_table[i], 4); |
| } |
} |
| ctx->multi_table[i] &= ~(U32C(0x40000000) >> (i % 8)); |
ctx->multi_table[i] &= ~(U32C(0x40000000) >> (i % 8)); |
| |
|
| ctx->multi_table[i+1] = (ctx->multi_table[i+1] & U32C(0xfffffff0)) | U32C(0x7); |
ctx->multi_table[i+1] = (ctx->multi_table[i+1] & U32C(0xfffffff0)) | U32C(0x7); |
| ctx->multi_table[i+1] |= (U32C(0x80000000) >> (i+1 % 8)); |
ctx->multi_table[i+1] |= (U32C(0x80000000) >> ((i+1) % 8)); |
| ctx->multi_table[i+1] &= ~(U32C(0x40000000) >> (i+1 % 8)); |
ctx->multi_table[i+1] &= ~(U32C(0x40000000) >> ((i+1) % 8)); |
| } |
} |
| } |
} |
| |
|
| /* compute multiplicative inverse mod 2^32 */ |
/* compute multiplicative inverse mod 2^32 */ |
| unsigned int inv_mod_32(u32 m) |
static u32 inv_mod_32(u32 m) |
| { |
{ |
| u32 inv; |
u32 inv; |
| s32 i; |
s32 i; |
| |
|
| |
|
| /* prepare the table of inverses */ |
/* prepare the table of inverses */ |
| void prepare_multi_inv(ECRYPT_ctx* ctx) { |
static void prepare_multi_inv(ECRYPT_ctx *ctx) |
| |
{ |
| s32 i; |
s32 i; |
| for (i=0; i< Multi_Size; i++) { |
for (i=0; i< Multi_Size; i++) { |
| ctx->inv_table[i] = inv_mod_32(ctx->multi_table[i]); |
ctx->inv_table[i] = inv_mod_32(ctx->multi_table[i]); |
| } |
} |
| |
|
| /* Compute addition constants */ |
/* Compute addition constants */ |
| void prepare_add_table(ECRYPT_ctx* ctx) { |
static void prepare_add_table(ECRYPT_ctx *ctx) |
| |
{ |
| s32 i; |
s32 i; |
| |
|
| genrand_tuple_int32(ctx, ctx->add_table, Add_Size); |
genrand_tuple_int32(ctx, ctx->add_table, Add_Size); |
| |
|
| /* word wise encrypt by Exor Mult table-Plus Rotate */ |
/* word wise encrypt by Exor Mult table-Plus Rotate */ |
| /* rotate number is between 16 - 23 */ |
/* rotate number is between 16 - 23 */ |
| void crypt_empr(ECRYPT_ctx* ctx, u32 block[Tuple]) |
static void crypt_empr(ECRYPT_ctx *ctx, u32 block[Tuple]) |
| { |
{ |
| s32 i, s; |
s32 i, s; |
| u32 param[Tuple]; |
u32 param[Tuple]; |
| } |
} |
| } |
} |
| |
|
| void crypt_empr_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple]) |
static void crypt_empr_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]) |
| { |
{ |
| s32 i, s; |
s32 i, s; |
| for (i=Tuple-1; i>=0; i--) { |
for (i=Tuple-1; i>=0; i--) { |
| |
|
| /* word wise encrypt by Exor Mult table-Exor Rotate */ |
/* word wise encrypt by Exor Mult table-Exor Rotate */ |
| /* rotate number is between 16 - 23 */ |
/* rotate number is between 16 - 23 */ |
| void crypt_emer(ECRYPT_ctx* ctx, u32 block[Tuple]) |
static void crypt_emer(ECRYPT_ctx *ctx, u32 block[Tuple]) |
| { |
{ |
| s32 i, s; |
s32 i, s; |
| u32 param[Tuple]; |
u32 param[Tuple]; |
| } |
} |
| } |
} |
| |
|
| void crypt_emer_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple]) |
static void crypt_emer_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]) |
| { |
{ |
| s32 i, s; |
s32 i, s; |
| for (i=Tuple-1; i>=0; i--) { |
for (i=Tuple-1; i>=0; i--) { |
| |
|
| /* word wise encrypt by Exor Mult table-Plus Shift */ |
/* word wise encrypt by Exor Mult table-Plus Shift */ |
| /* Shift number is betwee 16 - 23 */ |
/* Shift number is betwee 16 - 23 */ |
| void crypt_emps(ECRYPT_ctx* ctx, u32 block[Tuple]) |
static void crypt_emps(ECRYPT_ctx *ctx, u32 block[Tuple]) |
| { |
{ |
| s32 i, s; |
s32 i, s; |
| u32 param[Tuple]; |
u32 param[Tuple]; |
| } |
} |
| } |
} |
| |
|
| void crypt_emps_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple]) |
static void crypt_emps_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]) |
| { |
{ |
| s32 i, s; |
s32 i, s; |
| for (i=Tuple-1; i>=0; i--) { |
for (i=Tuple-1; i>=0; i--) { |
| |
|
| /* word wise encrypt by Exor Mult table-Exor Shift */ |
/* word wise encrypt by Exor Mult table-Exor Shift */ |
| /* Shift number is betwee 16 - 23 */ |
/* Shift number is betwee 16 - 23 */ |
| void crypt_emes(ECRYPT_ctx* ctx, u32 block[Tuple]) |
static void crypt_emes(ECRYPT_ctx *ctx, u32 block[Tuple]) |
| { |
{ |
| s32 i, s; |
s32 i, s; |
| u32 param[Tuple]; |
u32 param[Tuple]; |
| } |
} |
| } |
} |
| |
|
| void crypt_emes_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple]) |
static void crypt_emes_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]) |
| { |
{ |
| s32 i, s; |
s32 i, s; |
| for (i=Tuple-1; i>=0; i--) { |
for (i=Tuple-1; i>=0; i--) { |
| |
|
| /* Inter-word operations */ |
/* Inter-word operations */ |
| /* multiply to one and add to the other */ |
/* multiply to one and add to the other */ |
| void crypt_ma(ECRYPT_ctx* ctx, u32 block[Tuple]) |
static void crypt_ma(ECRYPT_ctx *ctx, u32 block[Tuple]) |
| { |
{ |
| s32 i, j, s; |
s32 i, j, s; |
| u32 param[Tuple]; |
u32 param[Tuple]; |
| genrand_tuple_int32(ctx, param, Tuple); |
|
| |
|
| |
genrand_tuple_int32(ctx, param, Tuple); |
| for (i=0; i<Tuple; i++) { |
for (i=0; i<Tuple; i++) { |
| j = (i - ctx->jump) & Low_Mask; |
j = (i - ctx->jump) & Low_Mask; |
| s = ((param[j] >> (32 - 4)) | 0x10 ) & 0x17; |
s = ((param[j] >> (32 - 4)) | 0x10 ) & 0x17; |
| } |
} |
| } |
} |
| |
|
| void crypt_ma_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple]) |
static void crypt_ma_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]) |
| { |
{ |
| s32 i, j, s; |
s32 i, j, s; |
| |
|
| } |
} |
| |
|
| /* multiply two words, exor to another words, and minus */ |
/* multiply two words, exor to another words, and minus */ |
| void crypt_mem(ECRYPT_ctx* ctx, u32 block[Tuple]) |
static void crypt_mem(ECRYPT_ctx *ctx, u32 block[Tuple]) |
| { |
{ |
| s32 i, j, k; |
s32 i, j, k; |
| u32 param[Tuple]; |
u32 param[Tuple]; |
| genrand_tuple_int32(ctx, param, Tuple); |
|
| |
|
| |
genrand_tuple_int32(ctx, param, Tuple); |
| for (i=0; i<Tuple; i++) { |
for (i=0; i<Tuple; i++) { |
| j = (i - ctx->jump) & Low_Mask; |
j = (i - ctx->jump) & Low_Mask; |
| k = param[j] >> (32 - Log_Tuple); |
k = param[j] >> (32 - Log_Tuple); |
| } |
} |
| } |
} |
| |
|
| void crypt_mem_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple]) |
static void crypt_mem_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]) |
| { |
{ |
| s32 i, j, k; |
s32 i, j, k; |
| |
|
| } |
} |
| |
|
| /* (one word OR param) times another word) is EXORed to another */ |
/* (one word OR param) times another word) is EXORed to another */ |
| void crypt_ome(ECRYPT_ctx* ctx, u32 block[Tuple]) |
static void crypt_ome(ECRYPT_ctx *ctx, u32 block[Tuple]) |
| { |
{ |
| s32 i, j, k; |
s32 i, j, k; |
| u32 param[Tuple]; |
u32 param[Tuple]; |
| genrand_tuple_int32(ctx, param, Tuple); |
|
| |
|
| |
genrand_tuple_int32(ctx, param, Tuple); |
| for (i=0; i<Tuple; i++) { |
for (i=0; i<Tuple; i++) { |
| j = (i - ctx->jump) & Low_Mask; |
j = (i - ctx->jump) & Low_Mask; |
| k = param[j] >> (32 - Log_Tuple); |
k = param[j] >> (32 - Log_Tuple); |
| } |
} |
| } |
} |
| |
|
| void crypt_ome_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple]) |
static void crypt_ome_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]) |
| { |
{ |
| s32 i, j, k; |
s32 i, j, k; |
| |
|
| } |
} |
| |
|
| /* (one word EXOR param) times another word) is EXORed to another */ |
/* (one word EXOR param) times another word) is EXORed to another */ |
| |
static void crypt_eme(ECRYPT_ctx *ctx, u32 block[Tuple]) |
| void crypt_eme(ECRYPT_ctx* ctx, u32 block[Tuple]) |
|
| { |
{ |
| s32 i, j, k; |
s32 i, j, k; |
| u32 param[Tuple]; |
u32 param[Tuple]; |
| genrand_tuple_int32(ctx, param, Tuple); |
|
| |
|
| |
genrand_tuple_int32(ctx, param, Tuple); |
| for (i=0; i<Tuple; i++) { |
for (i=0; i<Tuple; i++) { |
| j = (i - ctx->jump) & Low_Mask; |
j = (i - ctx->jump) & Low_Mask; |
| k = param[j] >> (32 - Log_Tuple); |
k = param[j] >> (32 - Log_Tuple); |
| } |
} |
| } |
} |
| |
|
| void crypt_eme_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple]) |
static void crypt_eme_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple]) |
| { |
{ |
| s32 i, j, k; |
s32 i, j, k; |
| |
|
| } |
} |
| |
|
| /* vertical partial rotation with bit inversion*/ |
/* vertical partial rotation with bit inversion*/ |
| void crypt_vert_rotate(ECRYPT_ctx* ctx, u32 block[Tuple]) |
static void crypt_vert_rotate(ECRYPT_ctx *ctx, u32 block[Tuple]) |
| { |
{ |
| u32 key, rkey, s; |
u32 key, rkey, s; |
| s32 i, j, jump_odd; |
s32 i, j, jump_odd; |
| } |
} |
| } |
} |
| |
|
| void crypt_vert_rotate_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple]) |
static void crypt_vert_rotate_inv(ECRYPT_ctx *ctx, u32 block[Tuple], u32 param[Tuple]) |
| { |
{ |
| u32 key, rkey, s; |
u32 key, rkey, s; |
| s32 i, j, jump_odd; |
s32 i, j, jump_odd; |
| block[j] = (block[j] & rkey) | (~s & key); |
block[j] = (block[j] & rkey) | (~s & key); |
| } |
} |
| |
|
| void set_buf(u32 buf[], const u8* text, u32 cpos, u32 msglen) |
static void set_buf(u32 buf[], const u8* text, u32 cpos, u32 msglen) |
| { |
{ |
| u32 x; |
u32 x; |
| s32 i, j, s, t, diff; |
s32 i, j, s, t, diff; |
| |
|
| diff = msglen - cpos; |
diff = msglen - cpos; |
| if ( diff >= 4*Tuple ) { |
if ( diff >= (4*Tuple) ) { |
| for (i=0; i<Tuple; i++) { |
for (i=0; i<Tuple; i++) { |
| x = (u32)text[cpos++]; |
buf[i] = U8TO32_LITTLE(text + cpos); |
| x |= ((u32)text[cpos++]) << 8; |
cpos += 4; |
| x |= ((u32)text[cpos++]) << 16; |
|
| x |= ((u32)text[cpos++]) << 24; |
|
| buf[i] = x; |
|
| } |
} |
| } |
} |
| else { |
else { |
| for (i=0; i<Tuple; i++) buf[i] = 0; |
for (i=0; i<Tuple; i++) buf[i] = 0; |
| s = diff / 4; |
s = diff >> 2; |
| t = diff % 4; |
t = diff & 3; |
| for (i=0; i<s; i++) { |
for (i=0; i<s; i++) { |
| x = (u32)text[cpos++]; |
buf[i] = U8TO32_LITTLE(text + cpos); |
| x |= ((u32)text[cpos++]) << 8; |
cpos += 4; |
| x |= ((u32)text[cpos++]) << 16; |
|
| x |= ((u32)text[cpos++]) << 24; |
|
| buf[i] = x; |
|
| } |
} |
| x = 0; |
x = 0; |
| for (j=0; j<t; j++) { |
for (j=0; j<t; j++) { |
| x |= (u32)text[cpos++] << (8*j); |
x |= (u32)text[cpos++] << (j<<3); |
| } |
} |
| buf[i] = x; |
buf[i] = x; |
| } |
} |
| } |
} |
| |
|
| void set_array(u32 buf[], u8* text, u32 cpos) |
static void set_array(u32 buf[], u8* text, u32 cpos) |
| { |
{ |
| s32 i; |
s32 i; |
| |
|
| for (i=0; i<Tuple; i++) { |
for (i=0; i<Tuple; i++) { |
| text[cpos++] = (u8)(buf[i] & U32C(0xFF)); |
U32TO8_LITTLE(text + cpos, buf[i]); |
| text[cpos++] = (u8)((buf[i]>>8) & U32C(0xFF)); |
cpos += 4; |
| text[cpos++] = (u8)((buf[i]>>16) & U32C(0xFF)); |
|
| text[cpos++] = (u8)((buf[i]>>24) & U32C(0xFF)); |
|
| } |
} |
| } |
} |
| |
|
| |
|
| void hmnencode(ECRYPT_ctx* ctx, const u8* plaintext, u8* ciphertext, u32 msglen) /* Message length in bytes. */ |
void hmnencode(ECRYPT_ctx *ctx, |
| |
const u8* plaintext, u8* ciphertext, u32 msglen) /* Message length in bytes. */ |
| { |
{ |
| s32 i, j, repeat; |
s32 i, j, repeat; |
| u32 msgbuf[Tuple]; |
u32 msgbuf[Tuple]; |
| |
|
| genrand_tuple_int32(ctx, func_choice, 4); |
genrand_tuple_int32(ctx, func_choice, 4); |
| |
|
| func_choice[2] *= (func_choice[0] | 0x1UL); |
func_choice[2] *= (func_choice[0] | 1); |
| func_choice[3] *= (func_choice[1] | 0x1UL); |
func_choice[3] *= (func_choice[1] | 1); |
| func_choice[0] ^= (func_choice[3] >> 5); |
func_choice[0] ^= (func_choice[3] >> 5); |
| func_choice[1] ^= (func_choice[2] >> 5); |
func_choice[1] ^= (func_choice[2] >> 5); |
| |
|
| s32 c, t; |
s32 c, t; |
| |
|
| t = j >> 4; |
t = j >> 4; |
| c = (func_choice[t] >> ((j++ & 0xfUL) * 2)) & 0x3UL; |
c = (func_choice[t] >> ((j++ & 0xf) * 2)) & 3; |
| switch (c) { |
switch (c) { |
| case 0: crypt_empr(ctx, msgbuf); break; |
case 0: crypt_empr(ctx, msgbuf); break; |
| case 1: crypt_emer(ctx, msgbuf); break; |
case 1: crypt_emer(ctx, msgbuf); break; |
| if ((ctx->jump <<= 1) >= Tuple) ctx->jump = 1; |
if ((ctx->jump <<= 1) >= Tuple) ctx->jump = 1; |
| |
|
| t = j >> 4; |
t = j >> 4; |
| c = (func_choice[t] >> ((j++ & 0xfUL) * 2)) & 0x3UL; |
c = (func_choice[t] >> ((j++ & 0xf) * 2)) & 3; |
| |
|
| switch (c) { |
switch (c) { |
| case 0: crypt_ma(ctx, msgbuf); break; |
case 0: crypt_ma(ctx, msgbuf); break; |
| } |
} |
| } |
} |
| |
|
| void hmndecode(ECRYPT_ctx* ctx, const u8* ciphertext, u8* plaintext, u32 msglen) /* Message length in bytes. */ |
void hmndecode(ECRYPT_ctx *ctx, |
| |
const u8* ciphertext, u8* plaintext, u32 msglen) /* Message length in bytes. */ |
| { |
{ |
| s32 i, j, k, repeat; |
s32 i, j, k, repeat; |
| u32 temp_rand[3*Iteration][Tuple]; |
u32 temp_rand[3*Iteration][Tuple]; |
| |
|
| genrand_tuple_int32(ctx, func_choice, 4); |
genrand_tuple_int32(ctx, func_choice, 4); |
| |
|
| func_choice[2] *= (func_choice[0] | 0x1UL); |
func_choice[2] *= (func_choice[0] | 1); |
| func_choice[3] *= (func_choice[1] | 0x1UL); |
func_choice[3] *= (func_choice[1] | 1); |
| func_choice[0] ^= (func_choice[3] >> 5); |
func_choice[0] ^= (func_choice[3] >> 5); |
| func_choice[1] ^= (func_choice[2] >> 5); |
func_choice[1] ^= (func_choice[2] >> 5); |
| |
|
| s32 c, t; |
s32 c, t; |
| |
|
| t = j >> 4; |
t = j >> 4; |
| c = (func_choice[t] >> ((j-- & 0xfUL) * 2)) & 0x3UL; |
c = (func_choice[t] >> ((j-- & 0xf) * 2)) & 3; |
| |
|
| crypt_vert_rotate_inv(ctx, msgbuf,temp_rand[--k]); |
crypt_vert_rotate_inv(ctx, msgbuf,temp_rand[--k]); |
| if ((ctx->jump >>= 1) == 0) ctx->jump = Tuple >> 1; |
if ((ctx->jump >>= 1) == 0) ctx->jump = Tuple/2; |
| |
|
| switch (c) { |
switch (c) { |
| case 0: crypt_ma_inv(ctx, msgbuf,temp_rand[--k]); break; |
case 0: crypt_ma_inv(ctx, msgbuf,temp_rand[--k]); break; |
| case 2: crypt_ome_inv(ctx, msgbuf,temp_rand[--k]); break; |
case 2: crypt_ome_inv(ctx, msgbuf,temp_rand[--k]); break; |
| case 3: crypt_eme_inv(ctx, msgbuf,temp_rand[--k]); break; |
case 3: crypt_eme_inv(ctx, msgbuf,temp_rand[--k]); break; |
| } |
} |
| if ((ctx->jump >>= 1) == 0) ctx->jump = Tuple >> 1; |
if ((ctx->jump >>= 1) == 0) ctx->jump = Tuple/2; |
| |
|
| t = j >> 4; |
t = j >> 4; |
| c = (func_choice[t] >> ((j-- & 0xfUL) * 2)) & 0x3UL; |
c = (func_choice[t] >> ((j-- & 0xf) * 2)) & 3; |
| |
|
| switch (c) { |
switch (c) { |
| case 0: crypt_empr_inv(ctx, msgbuf,temp_rand[--k]); break; |
case 0: crypt_empr_inv(ctx, msgbuf,temp_rand[--k]); break; |
| case 2: crypt_emps_inv(ctx, msgbuf,temp_rand[--k]); break; |
case 2: crypt_emps_inv(ctx, msgbuf,temp_rand[--k]); break; |
| case 3: crypt_emes_inv(ctx, msgbuf,temp_rand[--k]); break; |
case 3: crypt_emes_inv(ctx, msgbuf,temp_rand[--k]); break; |
| } |
} |
| if ((ctx->jump >>= 1) == 0) ctx->jump = Tuple >> 1; |
if ((ctx->jump >>= 1) == 0) ctx->jump = Tuple/2; |
| } |
} |
| |
|
| set_array(msgbuf, plaintext, coutpos); |
set_array(msgbuf, plaintext, coutpos); |
| |
|
| void ECRYPT_init() |
void ECRYPT_init() |
| { |
{ |
| /* do nothing */ |
|
| } |
} |
| |
|
| void ECRYPT_keysetup( |
void ECRYPT_keysetup( |
| ctx->keysize = keysize; |
ctx->keysize = keysize; |
| ctx->ivsize = ivsize; |
ctx->ivsize = ivsize; |
| |
|
| for (i=0; i<keysize/8; i++) |
for (i = 0; i < ctx->keysize/8; i++) |
| ctx->key[i] = key[i]; |
ctx->key[i] = key[i]; |
| } |
} |
| |
|
| s32 i,j,k,t,s; |
s32 i,j,k,t,s; |
| u32 x, init_array[(ECRYPT_MAXKEYSIZE+ECRYPT_MAXIVSIZE)/32]; |
u32 x, init_array[(ECRYPT_MAXKEYSIZE+ECRYPT_MAXIVSIZE)/32]; |
| |
|
| for (i=0; i<ctx->ivsize/8; i++) |
|
| ctx->iv[i] = iv[i]; |
|
| |
|
| j = 0; |
j = 0; |
| t = ctx->keysize/32; |
t = ctx->keysize/32; |
| for (i=0; i<t; i++) { |
for (i=0; i<t; i++) { |
| x = (u32)ctx->key[j++]; |
init_array[i] = U8TO32_LITTLE(ctx->key + j); |
| x |= ((u32)ctx->key[j++]) << 8; |
j += 4; |
| x |= ((u32)ctx->key[j++]) << 16; |
|
| x |= ((u32)ctx->key[j++]) << 24; |
|
| init_array[i] = x; |
|
| } |
} |
| if ( ctx->keysize % 32 != 0 ) { |
if ( ctx->keysize % 32 != 0 ) { |
| x = 0; |
x = 0; |
| j = 0; |
j = 0; |
| s = ctx->ivsize/32; |
s = ctx->ivsize/32; |
| for (i=0; i<s; i++) { |
for (i=0; i<s; i++) { |
| x = (u32)ctx->iv[j++]; |
init_array[t+i] = U8TO32_LITTLE(iv + j); |
| x |= ((u32)ctx->iv[j++]) << 8; |
j += 4; |
| x |= ((u32)ctx->iv[j++]) << 16; |
|
| x |= ((u32)ctx->iv[j++]) << 24; |
|
| init_array[t+i] = x; |
|
| } |
} |
| if ( ctx->ivsize % 32 != 0 ) { |
if ( ctx->ivsize % 32 != 0 ) { |
| x = 0; |
x = 0; |
| k = (ctx->ivsize % 32)/8; |
k = (ctx->ivsize % 32)/8; |
| for (i=0; i<k; i++) { |
for (i=0; i<k; i++) { |
| x |= ((u32)ctx->iv[j++]) << (8*k); |
x |= ((u32)iv[j++]) << (8*k); |
| } |
} |
| init_array[t+(s++)] = x; |
init_array[t+(s++)] = x; |
| } |
} |
| |
|
| genrand_tuple_int32(ctx, func_choice, 4); |
genrand_tuple_int32(ctx, func_choice, 4); |
| |
|
| func_choice[2] *= (func_choice[0] | 0x1UL); |
func_choice[2] *= (func_choice[0] | 1); |
| func_choice[3] *= (func_choice[1] | 0x1UL); |
func_choice[3] *= (func_choice[1] | 1); |
| func_choice[0] ^= (func_choice[3] >> 5); |
func_choice[0] ^= (func_choice[3] >> 5); |
| func_choice[1] ^= (func_choice[2] >> 5); |
func_choice[1] ^= (func_choice[2] >> 5); |
| |
|
| s32 c, t; |
s32 c, t; |
| |
|
| t = j >> 4; |
t = j >> 4; |
| c = (func_choice[t] >> ((j++ & 0xfUL) * 2)) & 0x3UL; |
c = (func_choice[t] >> ((j++ & 0xf) * 2)) & 3; |
| switch (c) { |
switch (c) { |
| case 0: crypt_empr(ctx, msgbuf); break; |
case 0: crypt_empr(ctx, msgbuf); break; |
| case 1: crypt_emer(ctx, msgbuf); break; |
case 1: crypt_emer(ctx, msgbuf); break; |
| } |
} |
| |
|
| t = j >> 4; |
t = j >> 4; |
| c = (func_choice[t] >> ((j++ & 0xfUL) * 2)) & 0x3UL; |
c = (func_choice[t] >> ((j++ & 0xf) * 2)) & 3; |
| |
|
| switch (c) { |
switch (c) { |
| case 0: crypt_ma(ctx, msgbuf); break; |
case 0: crypt_ma(ctx, msgbuf); break; |
| hmndecode(ctx, ciphertext, plaintext, msglen); |
hmndecode(ctx, ciphertext, plaintext, msglen); |
| } |
} |
| |
|
| #ifndef ECRYPT_API |
|
| |
|
| int main(void) |
|
| { |
|
| int i; |
|
| ECRYPT_ctx x; |
|
| u8 plaintext[128], plaintext2[128], ciphertext[128]; |
|
| |
|
| for (i=0; i<128; i++){ |
|
| plaintext[i]=0; |
|
| } |
|
| |
|
| ECRYPT_keysetup(&x, "1234567812345678", 128, 128); |
|
| ECRYPT_ivsetup(&x, "8765432187654321"); |
|
| ECRYPT_encrypt_bytes(&x, plaintext, ciphertext, 128); |
|
| for (i=0; i<16; i++) |
|
| printf("%2x ", ciphertext[i]); |
|
| printf("\n"); |
|
| |
|
| ECRYPT_ivsetup(&x, "8765432187654321"); |
|
| ECRYPT_decrypt_bytes(&x, ciphertext, plaintext2, 128); |
|
| for (i=0; i<16; i++) |
|
| printf("%2x ", plaintext2[i]); |
|
| printf("\n"); |
|
| |
|
| return 0; |
|
| } |
|
| |
|
| #endif |
|