svn: ecrypt/trunk/submissions/fubuki/fubuki.c
File:
[svn] /
ecrypt /
trunk /
submissions /
fubuki / fubuki.c
(
download)
(
as text)
Revision:
11,
Sun Jun 26 20:50:49 2005 UTC (7 years, 11 months ago) by
cdecanni
File size: 19620 byte(s)
* disabled `main()' function with an #ifndef ECRYPT_API.
* included `mt-fubuki.c' in order to have a single object.
* moved static variables `mt' and `mti' to `ECRYPT_ctx'.
* moved static variables
u32 multi_table[32];
u32 inv_table[32];
u32 add_table[32];
int jump;
to `ECRYPT_ctx' (which was not as easy as it sounds ...).
/* FUBUKI encryption system, by Hagita-Matsumoto-Nishimura-Saito */
/* Coded by Makoto Matsumoto, 2001/12/25 */
/* Re-Coded by Makoto Matsumoto, 2005/03/29 */
/* Multiplication-based by Makoto Matsumoto, 2005/04/10 */
/* Variable Tuple by Takuji Nishimura, 2005/04/12 */
/* Tough against differential crypt attack, 2005/04/13 */
/* 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"
void genrand_tuple_int32(ECRYPT_ctx* ctx, u32 rand_tuple[], s32 len);
void init_by_array(ECRYPT_ctx* ctx, u32 init_key[], int key_length);
#ifdef ECRYPT_API
#include "mt-fubuki.c"
#endif
/* This is a stream cipher. One word means a 32 bit word. */
/* Tuple words will be gather to make one Block. */
/* Typically Tuple is 4. Log_Tuple is log2(Tuple) */
#define Log_Tuple 2
#define Tuple (U32C(1) << Log_Tuple)
#define Low_Mask (Tuple-1)
#define Iteration 4 /* <=32: number of primitive encrypt function iterations */
#define Multi_Size 32 /* number of constant multipliers */
#define Log_Add_Size 5 /* Log of Add_Size */
#define Add_Size 32 /* number of constant adders */
/* for debug */
void print_block(u32 block[]) {
s32 i;
for (i=0; i<Tuple; i++) printf("%8x ", block[i]);
printf("\n");
}
/**********************************************/
/******** Precomputation of Tables **********/
/**********************************************/
/* Compute Multiplication Constants: 3 mod 8, 7 mod 16 */
void prepare_multi(ECRYPT_ctx* ctx) {
s32 i;
for (i=0; i<Multi_Size; i+=4) {
genrand_tuple_int32(ctx, &ctx->multi_table[i], 4);
}
for (i=0; i< Multi_Size; i+=2) {
ctx->multi_table[i] = (ctx->multi_table[i] & U32C(0xfffffff8)) | U32C(0x3);
ctx->multi_table[i] |= (U32C(0x80000000) >> (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] |= (U32C(0x80000000) >> (i+1 % 8));
ctx->multi_table[i+1] &= ~(U32C(0x40000000) >> (i+1 % 8));
}
}
/* compute multiplicative inverse mod 2^32 */
unsigned int inv_mod_32(u32 m)
{
u32 inv;
s32 i;
if ((m & U32C(0x1)) == 0) { printf("error\n"); return -1;}
inv = 1;
for (i=30; i>=0; i--) {
if (((inv * m - 1) << i) != 0) inv |= (0x1 << (32-i-1));
}
return inv;
}
/* prepare the table of inverses */
void prepare_multi_inv(ECRYPT_ctx* ctx) {
s32 i;
for (i=0; i< Multi_Size; i++) {
ctx->inv_table[i] = inv_mod_32(ctx->multi_table[i]);
}
}
/* Compute addition constants */
void prepare_add_table(ECRYPT_ctx* ctx) {
s32 i;
genrand_tuple_int32(ctx, ctx->add_table, Add_Size);
for (i=0; i< Add_Size; i++) {
u32 s;
s = (i * 1103515245 + 12345) & (Add_Size - 1);
s ^= (s >> (Log_Add_Size / 2));
ctx->add_table[i] <<= Log_Add_Size;
ctx->add_table[i] |= s;
}
}
/**********************************************/
/*******Primitive Ecnryption Families**********/
/**********************************************/
/**********************************************/
/*******PEF (almost word wise operation)*******/
/**********************************************/
/* word wise encrypt by Exor Mult table-Plus Rotate */
/* rotate number is between 16 - 23 */
void crypt_empr(ECRYPT_ctx* ctx, u32 block[Tuple])
{
s32 i, s;
u32 param[Tuple];
genrand_tuple_int32(ctx, param, Tuple);
for (i=0; i<Tuple; i++) {
s = ((param[i] >> (32 - 4)) | 0x10 ) & 0x17;
block[i] ^= param[i];
block[i] *= ctx->multi_table[param[(i+1) % Tuple]>> (32 - 5)];
block[(i+ctx->jump) & Low_Mask] += ctx->add_table[block[i] >> (32 - Log_Add_Size)];
block[i] = ((~block[i]) << (32 - s)) | (block[i] >> s);
}
}
void crypt_empr_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple])
{
s32 i, s;
for (i=Tuple-1; i>=0; i--) {
s = ((param[i] >> (32 - 4)) | 0x10 ) & 0x17;
block[i] = ((~block[i]) >> (32 - s)) | (block[i] << s);
block[(i+ctx->jump) & Low_Mask] -= ctx->add_table[block[i] >> (32 - Log_Add_Size)];
block[i] *= ctx->inv_table[param[(i+1) % Tuple]>> (32 - 5)];
block[i] ^= param[i];
}
}
/* word wise encrypt by Exor Mult table-Exor Rotate */
/* rotate number is between 16 - 23 */
void crypt_emer(ECRYPT_ctx* ctx, u32 block[Tuple])
{
s32 i, s;
u32 param[Tuple];
genrand_tuple_int32(ctx, param, Tuple);
for (i=0; i<Tuple; i++) {
s = ((param[i] >> (32 - 4)) | 0x10 ) & 0x17;
block[i] ^= param[i];
block[i] *= ctx->multi_table[param[(i+2) % Tuple]>> (32 - 5)];
block[(i+ctx->jump) & Low_Mask] ^= ctx->add_table[block[i] >> (32 - Log_Add_Size)];
block[i] = ((~block[i]) << (32 - s)) | (block[i] >> s);
}
}
void crypt_emer_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple])
{
s32 i, s;
for (i=Tuple-1; i>=0; i--) {
s = ((param[i] >> (32 - 4)) | 0x10 ) & 0x17;
block[i] = ((~block[i]) >> (32 - s)) | (block[i] << s);
block[(i+ctx->jump) & Low_Mask] ^= ctx->add_table[block[i] >> (32 - Log_Add_Size)];
block[i] *= ctx->inv_table[param[(i+2) % Tuple]>> (32 - 5)];
block[i] ^= param[i];
}
}
/* word wise encrypt by Exor Mult table-Plus Shift */
/* Shift number is betwee 16 - 23 */
void crypt_emps(ECRYPT_ctx* ctx, u32 block[Tuple])
{
s32 i, s;
u32 param[Tuple];
genrand_tuple_int32(ctx, param, Tuple);
for (i=0; i<Tuple; i++) {
s = ((param[i] >> (32 - 4)) | 0x10 ) & 0x17;
block[i] ^= param[i];
block[i] *= ctx->multi_table[param[(i+2) % Tuple]>> (32 - 5)];
block[(i+ctx->jump) & Low_Mask] += ctx->add_table[block[i] >> (32 - Log_Add_Size)];
block[i] ^= ((~block[i]) >> s);
}
}
void crypt_emps_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple])
{
s32 i, s;
for (i=Tuple-1; i>=0; i--) {
s = ((param[i] >> (32 - 4)) | 0x10 ) & 0x17;
block[i] ^= ((~block[i]) >> s);
block[(i+ctx->jump) & Low_Mask] -= ctx->add_table[block[i] >> (32 - Log_Add_Size)];
block[i] *= ctx->inv_table[param[(i+2) % Tuple]>> (32 - 5)];
block[i] ^= param[i];
}
}
/* word wise encrypt by Exor Mult table-Exor Shift */
/* Shift number is betwee 16 - 23 */
void crypt_emes(ECRYPT_ctx* ctx, u32 block[Tuple])
{
s32 i, s;
u32 param[Tuple];
genrand_tuple_int32(ctx, param, Tuple);
for (i=0; i<Tuple; i++) {
s = ((param[i] >> (32 - 4)) | 0x10 ) & 0x17;
block[i] ^= param[i];
block[i] *= ctx->multi_table[param[(i+3) % Tuple]>> (32 - 5)];
block[(i+ctx->jump) & Low_Mask] ^= ctx->add_table[block[i] >> (32 - Log_Add_Size)];
block[i] ^= ((~block[i]) >> s);
}
}
void crypt_emes_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple])
{
s32 i, s;
for (i=Tuple-1; i>=0; i--) {
s = ((param[i] >> (32 - 4)) | 0x10 ) & 0x17;
block[i] ^= ((~block[i]) >> s);
block[(i+ctx->jump) & Low_Mask] ^= ctx->add_table[block[i] >> (32 - Log_Add_Size)];
block[i] *= ctx->inv_table[param[(i+3) % Tuple]>> (32 - 5)];
block[i] ^= param[i];
}
}
/* Inter-word operations */
/* multiply to one and add to the other */
void crypt_ma(ECRYPT_ctx* ctx, u32 block[Tuple])
{
s32 i, j, s;
u32 param[Tuple];
genrand_tuple_int32(ctx, param, Tuple);
for (i=0; i<Tuple; i++) {
j = (i - ctx->jump) & Low_Mask;
s = ((param[j] >> (32 - 4)) | 0x10 ) & 0x17;
block[i] += (block[j]*param[i]);
block[i] ^= ((~block[i]) >> s);
}
}
void crypt_ma_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple])
{
s32 i, j, s;
for (i=Tuple-1; i>=0; i--) {
j = (i - ctx->jump) & Low_Mask;
s = ((param[j] >> (32 - 4)) | 0x10 ) & 0x17;
block[i] ^= ((~block[i]) >> s);
block[i] -= (block[j]*param[i]);
}
}
/* multiply two words, exor to another words, and minus */
void crypt_mem(ECRYPT_ctx* ctx, u32 block[Tuple])
{
s32 i, j, k;
u32 param[Tuple];
genrand_tuple_int32(ctx, param, Tuple);
for (i=0; i<Tuple; i++) {
j = (i - ctx->jump) & Low_Mask;
k = param[j] >> (32 - Log_Tuple);
if (k==i) k=(k-1) & Low_Mask;
block[i] ^= (block[j]*block[k]);
block[i] -= param[i];
block[i] ^= (block[i] >> 16);
}
}
void crypt_mem_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple])
{
s32 i, j, k;
for (i=Tuple-1; i>=0; i--) {
j = (i - ctx->jump) & Low_Mask;
k = param[j] >> (32 - Log_Tuple);
if (k==i) k=(k-1) & Low_Mask;
block[i] ^= (block[i] >> 16);
block[i] += param[i];
block[i] ^= (block[j]*block[k]);
}
}
/* (one word OR param) times another word) is EXORed to another */
void crypt_ome(ECRYPT_ctx* ctx, u32 block[Tuple])
{
s32 i, j, k;
u32 param[Tuple];
genrand_tuple_int32(ctx, param, Tuple);
for (i=0; i<Tuple; i++) {
j = (i - ctx->jump) & Low_Mask;
k = param[j] >> (32 - Log_Tuple);
if (k==i) k=(k-1) & Low_Mask;
block[i] ^= (block[k]|param[i])*block[j];
block[i] ^= (block[i] >> 16);
}
}
void crypt_ome_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple])
{
s32 i, j, k;
for (i=Tuple-1; i>=0; i--) {
j = (i - ctx->jump) & Low_Mask;
k = param[j] >> (32 - Log_Tuple);
if (k==i) k=(k-1) & Low_Mask;
block[i] ^= (block[i] >> 16);
block[i] ^= (block[k]|param[i])*block[j];
}
}
/* (one word EXOR param) times another word) is EXORed to another */
void crypt_eme(ECRYPT_ctx* ctx, u32 block[Tuple])
{
s32 i, j, k;
u32 param[Tuple];
genrand_tuple_int32(ctx, param, Tuple);
for (i=0; i<Tuple; i++) {
j = (i - ctx->jump) & Low_Mask;
k = param[j] >> (32 - Log_Tuple);
if (k==i) k=(k-1) & Low_Mask;
block[i] ^= (block[k]^param[i])*block[j];
block[i] ^= (block[i] >> 17);
}
}
void crypt_eme_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple])
{
s32 i, j, k;
for (i=Tuple-1; i>=0; i--) {
j = (i - ctx->jump) & Low_Mask;
k = param[j] >> (32 - Log_Tuple);
if (k==i) k=(k-1) & Low_Mask;
block[i] ^= (block[i] >> 17);
block[i] ^= (block[k]^param[i])*block[j];
}
}
/* vertical partial rotation with bit inversion*/
void crypt_vert_rotate(ECRYPT_ctx* ctx, u32 block[Tuple])
{
u32 key, rkey, s;
s32 i, j, jump_odd;
u32 param[Tuple];
jump_odd = (ctx->jump - 1) | 0x1;
genrand_tuple_int32(ctx, param, Tuple);
key = ((param[0]+param[Tuple-1])<< 2) + 1;
rkey = ~key;
s = block[0];
j = 0;
for (i=0; i<Tuple ; i++) {
int u;
u = (j-jump_odd) & Low_Mask;
block[j] = (block[j] & rkey) | (~block[u] & key);
j = u;
}
block[j] = (block[j] & rkey) | (~s & key);
for (i=0; i<Tuple; i++) {
block[i] += param[i];
}
}
void crypt_vert_rotate_inv(ECRYPT_ctx* ctx, u32 block[Tuple], u32 param[Tuple])
{
u32 key, rkey, s;
s32 i, j, jump_odd;
jump_odd = (ctx->jump - 1)| 0x1;
for (i=0; i<Tuple; i++) {
block[i] -= param[i];
}
key = ((param[0]+param[Tuple-1])<< 2) + 1;
rkey = ~key;
s = block[0];
j = 0;
for (i=0; i<Tuple; i++) {
int u;
u = (j+jump_odd) & Low_Mask;
block[j] = (block[j] & rkey) | (~block[u] & key);
j = u;
}
block[j] = (block[j] & rkey) | (~s & key);
}
void set_buf(u32 buf[], const u8* text, u32 cpos, u32 msglen)
{
u32 x;
s32 i, j, s, t, diff;
diff = msglen - cpos;
if ( diff >= 4*Tuple ) {
for (i=0; i<Tuple; i++) {
x = (u32)text[cpos++];
x |= ((u32)text[cpos++]) << 8;
x |= ((u32)text[cpos++]) << 16;
x |= ((u32)text[cpos++]) << 24;
buf[i] = x;
}
}
else {
for (i=0; i<Tuple; i++) buf[i] = 0;
s = diff / 4;
t = diff % 4;
for (i=0; i<s; i++) {
x = (u32)text[cpos++];
x |= ((u32)text[cpos++]) << 8;
x |= ((u32)text[cpos++]) << 16;
x |= ((u32)text[cpos++]) << 24;
buf[i] = x;
}
x = 0;
for (j=0; j<t; j++) {
x |= (u32)text[cpos++] << (8*j);
}
buf[i] = x;
}
}
void set_array(u32 buf[], u8* text, u32 cpos)
{
s32 i;
for (i=0; i<Tuple; i++) {
text[cpos++] = (u8)(buf[i] & U32C(0xFF));
text[cpos++] = (u8)((buf[i]>>8) & U32C(0xFF));
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. */
{
s32 i, j, repeat;
u32 msgbuf[Tuple];
u32 cinpos, coutpos;
repeat = msglen/(4*Tuple);
if (msglen % (4*Tuple))
repeat++;
cinpos = coutpos = 0;;
for (i=0; i<repeat; i++) {
u32 func_choice[Tuple];
set_buf(msgbuf, plaintext, cinpos, msglen);
cinpos += 4*Tuple;
genrand_tuple_int32(ctx, func_choice, 4);
func_choice[2] *= (func_choice[0] | 0x1UL);
func_choice[3] *= (func_choice[1] | 0x1UL);
func_choice[0] ^= (func_choice[3] >> 5);
func_choice[1] ^= (func_choice[2] >> 5);
ctx->jump = 1;
for (j=0; j< 2*Iteration;) {
s32 c, t;
t = j >> 4;
c = (func_choice[t] >> ((j++ & 0xfUL) * 2)) & 0x3UL;
switch (c) {
case 0: crypt_empr(ctx, msgbuf); break;
case 1: crypt_emer(ctx, msgbuf); break;
case 2: crypt_emps(ctx, msgbuf); break;
case 3: crypt_emes(ctx, msgbuf); break;
}
if ((ctx->jump <<= 1) >= Tuple) ctx->jump = 1;
t = j >> 4;
c = (func_choice[t] >> ((j++ & 0xfUL) * 2)) & 0x3UL;
switch (c) {
case 0: crypt_ma(ctx, msgbuf); break;
case 1: crypt_mem(ctx, msgbuf); break;
case 2: crypt_ome(ctx, msgbuf); break;
case 3: crypt_eme(ctx, msgbuf); break;
}
if ((ctx->jump <<= 1) >= Tuple) ctx->jump = 1;
crypt_vert_rotate(ctx, msgbuf);
if ((ctx->jump <<= 1) >= Tuple) ctx->jump = 1;
}
set_array(msgbuf, ciphertext, coutpos);
coutpos += 4*Tuple;
}
}
void hmndecode(ECRYPT_ctx* ctx, const u8* ciphertext, u8* plaintext, u32 msglen) /* Message length in bytes. */
{
s32 i, j, k, repeat;
u32 temp_rand[3*Iteration][Tuple];
u32 msgbuf[Tuple];
s32 cinpos, coutpos;
repeat = msglen/(4*Tuple);
cinpos = coutpos = 0;
for (i=0; i<repeat; i++) {
u32 func_choice[Tuple];
set_buf(msgbuf, ciphertext, cinpos, msglen);
cinpos += 4*Tuple;
genrand_tuple_int32(ctx, func_choice, 4);
func_choice[2] *= (func_choice[0] | 0x1UL);
func_choice[3] *= (func_choice[1] | 0x1UL);
func_choice[0] ^= (func_choice[3] >> 5);
func_choice[1] ^= (func_choice[2] >> 5);
for (k=0; k< 3*Iteration; k++)
genrand_tuple_int32(ctx, temp_rand[k], Tuple);
ctx->jump = 1 << ((3*Iteration-1) % Log_Tuple);
for (j=2*Iteration -1; j>=0;) {
s32 c, t;
t = j >> 4;
c = (func_choice[t] >> ((j-- & 0xfUL) * 2)) & 0x3UL;
crypt_vert_rotate_inv(ctx, msgbuf,temp_rand[--k]);
if ((ctx->jump >>= 1) == 0) ctx->jump = Tuple >> 1;
switch (c) {
case 0: crypt_ma_inv(ctx, msgbuf,temp_rand[--k]); break;
case 1: crypt_mem_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;
}
if ((ctx->jump >>= 1) == 0) ctx->jump = Tuple >> 1;
t = j >> 4;
c = (func_choice[t] >> ((j-- & 0xfUL) * 2)) & 0x3UL;
switch (c) {
case 0: crypt_empr_inv(ctx, msgbuf,temp_rand[--k]); break;
case 1: crypt_emer_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;
}
if ((ctx->jump >>= 1) == 0) ctx->jump = Tuple >> 1;
}
set_array(msgbuf, plaintext, coutpos);
coutpos += 4*Tuple;
}
}
void ECRYPT_init()
{
/* do nothing */
}
void ECRYPT_keysetup(
ECRYPT_ctx* ctx,
const u8* key,
u32 keysize, /* Key size in bits. */
u32 ivsize) /* IV size in bits. */
{
s32 i;
ctx->keysize = keysize;
ctx->ivsize = ivsize;
for (i=0; i<keysize/8; i++)
ctx->key[i] = key[i];
}
void ECRYPT_ivsetup(
ECRYPT_ctx* ctx,
const u8* iv)
{
s32 i,j,k,t,s;
u32 x, init_array[(ECRYPT_MAXKEYSIZE+ECRYPT_MAXIVSIZE)/32];
for (i=0; i<ctx->ivsize/8; i++)
ctx->iv[i] = iv[i];
j = 0;
t = ctx->keysize/32;
for (i=0; i<t; i++) {
x = (u32)ctx->key[j++];
x |= ((u32)ctx->key[j++]) << 8;
x |= ((u32)ctx->key[j++]) << 16;
x |= ((u32)ctx->key[j++]) << 24;
init_array[i] = x;
}
if ( ctx->keysize % 32 != 0 ) {
x = 0;
k = (ctx->keysize % 32)/8;
for (i=0; i<k; i++) {
x |= ((u32)ctx->key[j++]) << (8*k);
}
init_array[t++] = x;
}
j = 0;
s = ctx->ivsize/32;
for (i=0; i<s; i++) {
x = (u32)ctx->iv[j++];
x |= ((u32)ctx->iv[j++]) << 8;
x |= ((u32)ctx->iv[j++]) << 16;
x |= ((u32)ctx->iv[j++]) << 24;
init_array[t+i] = x;
}
if ( ctx->ivsize % 32 != 0 ) {
x = 0;
k = (ctx->ivsize % 32)/8;
for (i=0; i<k; i++) {
x |= ((u32)ctx->iv[j++]) << (8*k);
}
init_array[t+(s++)] = x;
}
init_by_array(ctx, init_array, t+s);
prepare_multi(ctx);
prepare_multi_inv(ctx);
prepare_add_table(ctx);
}
void ECRYPT_keystream_bytes(
ECRYPT_ctx* ctx,
u8* keystream,
u32 length) /* length % (4*Tuple) == 0 */ /* Length of keystream in bytes. */
{
s32 i, j, repeat;
u32 msgbuf[Tuple];
u32 coutpos;
repeat = length/(4*Tuple);
if (length % (4*Tuple))
repeat++;
coutpos = 0;;
for (i=0; i<repeat; i++) {
u32 func_choice[Tuple];
for (j=0; j<Tuple; j++) msgbuf[j] = 0;
genrand_tuple_int32(ctx, func_choice, 4);
func_choice[2] *= (func_choice[0] | 0x1UL);
func_choice[3] *= (func_choice[1] | 0x1UL);
func_choice[0] ^= (func_choice[3] >> 5);
func_choice[1] ^= (func_choice[2] >> 5);
for (j=0; j< 2*Iteration;) {
s32 c, t;
t = j >> 4;
c = (func_choice[t] >> ((j++ & 0xfUL) * 2)) & 0x3UL;
switch (c) {
case 0: crypt_empr(ctx, msgbuf); break;
case 1: crypt_emer(ctx, msgbuf); break;
case 2: crypt_emps(ctx, msgbuf); break;
case 3: crypt_emes(ctx, msgbuf); break;
}
t = j >> 4;
c = (func_choice[t] >> ((j++ & 0xfUL) * 2)) & 0x3UL;
switch (c) {
case 0: crypt_ma(ctx, msgbuf); break;
case 1: crypt_mem(ctx, msgbuf); break;
case 2: crypt_ome(ctx, msgbuf); break;
case 3: crypt_eme(ctx, msgbuf); break;
}
crypt_vert_rotate(ctx, msgbuf);
}
set_array(msgbuf, keystream, coutpos);
coutpos += 4*Tuple;
}
}
void ECRYPT_encrypt_bytes(
ECRYPT_ctx* ctx,
const u8* plaintext,
u8* ciphertext,
u32 msglen) /* Message length in bytes. */
{
hmnencode(ctx, plaintext, ciphertext, msglen);
}
void ECRYPT_decrypt_bytes(
ECRYPT_ctx* ctx,
const u8* ciphertext,
u8* plaintext,
u32 msglen) /* Message length in bytes. */
{
if ( (msglen % (4*Tuple)) != 0 ) {
printf("ECRYPT_decrypt_bytes: msglen should be multiple of %d.\n", 4*Tuple);
return;
}
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