/**********************************************************************/
/*** ***/
/*** The core Frogbit algorithm ***/
/*** ***/
/**********************************************************************/
typedef int index;
typedef int bit;
/*--------------------------------------------------------------------*/
/*---------------- the state of the Frogbit algorithm ----------------*/
index T[10]; /* the current permutation table, T(i-1-r'(i-1)) */
index d_; /* the current key stream number, d'(i-1) */
bit s; /* the previous bit, s{i-1} */
/* local variables for the run length process */
index r_; /* the current bounded run count, r'(i-1) */
index acc_d; /* accumulated binary representation K2{i-1}, k2{i}*/
/*--------------------------------------------------------------------*/
/*------------------ keystream "drift" accumulators ------------------*/
/* These accumulators are for information purposes. Their final
values may come into play for a hash code. The active state of
the pseudo-random generators is dealt with later. */
struct cntr
{
unsigned long c; /* A count of consumed keystream bits ... */
int i; /* ... for this key stream source. */
} drift_cnt[10];
/*--------------------------------------------------------------------*/
/*------------------ the index permutation process -------------------*/
void index_permutation(int j)
{
int temp;
int temp_d_= T[j];
switch((d_<<1)+s)
{
case 0:
temp=T[0];T[0]=T[5];T[5]=T[2];T[2]=T[7];T[7]=temp;
temp=T[1];T[1]=T[8];T[8]=T[6];T[6]=T[4];T[4]=T[3];T[3]=T[9];
T[9]=temp;
break;
case 1:
temp=T[0];T[0]=T[2];T[2]=T[7];T[7]=temp;
temp=T[1];T[1]=T[3];T[3]=T[6];T[6]=T[9];T[9]=T[4];T[4]=T[8];
T[8]=T[5];T[5]=temp;
break;
case 2:
temp=T[0];T[0]=T[6];T[6]=T[8];T[8]=T[9];T[9]=T[5];T[5]=T[7];
T[7]=T[1];T[1]=temp;
temp=T[2];T[2]=T[4];T[4]=T[3];T[3]=temp;
break;
case 3:
temp=T[0];T[0]=T[6];T[6]=temp;
temp=T[1];T[1]=T[5];T[5]=T[3];T[3]=T[4];T[4]=T[2];T[2]=T[8];
T[8]=T[7];T[7]=T[9];T[9]=temp;
break;
case 4:
temp=T[0];T[0]=T[3];T[3]=T[6];T[6]=T[5];T[5]=T[1];T[1]=T[2];
T[2]=temp;
temp=T[4];T[4]=T[8];T[8]=T[7];T[7]=T[9];T[9]=temp;
break;
case 5:
temp=T[0];T[0]=T[6];T[6]=T[7];T[7]=T[3];T[3]=T[1];T[1]=T[2];
T[2]=T[9];T[9]=temp;
temp=T[4];T[4]=T[5];T[5]=T[8];T[8]=temp;
break;
case 6:
temp=T[0];T[0]=T[4];T[4]=T[3];T[3]=T[7];T[7]=T[6];T[6]=T[1];
T[1]=T[8];T[8]=T[5];T[5]=temp;
temp=T[2];T[2]=T[9];T[9]=temp;
break;
case 7:
temp=T[0];T[0]=T[5];T[5]=T[4];T[4]=temp;
temp=T[1];T[1]=T[9];T[9]=T[8];T[8]=T[6];T[6]=T[2];T[2]=T[3];
T[3]=T[7];T[7]=temp;
break;
case 8:
temp=T[0];T[0]=T[8];T[8]=T[9];T[9]=T[5];T[5]=T[3];T[3]=T[2];
T[2]=T[1];T[1]=temp;
temp=T[4];T[4]=T[6];T[6]=T[7];T[7]=temp;
break;
case 9:
temp=T[0];T[0]=T[9];T[9]=T[7];T[7]=T[8];T[8]=T[1];T[1]=T[4];
T[4]=T[2];T[2]=T[6];T[6]=temp;
temp=T[3];T[3]=T[5];T[5]=temp;
break;
case 10:
temp=T[0];T[0]=T[7];T[7]=T[2];T[2]=T[4];T[4]=T[1];T[1]=T[6];
T[6]=T[5];T[5]=T[9];T[9]=temp;
temp=T[3];T[3]=T[8];T[8]=temp;
break;
case 11:
temp=T[0];T[0]=T[1];T[1]=T[4];T[4]=T[7];T[7]=T[5];T[5]=T[2];
T[2]=T[8];T[8]=T[3];T[3]=temp;
temp=T[6];T[6]=T[9];T[9]=temp;
break;
case 12:
temp=T[0];T[0]=T[7];T[7]=T[6];T[6]=T[3];T[3]=temp;
temp=T[1];T[1]=T[4];T[4]=T[9];T[9]=T[2];T[2]=T[5];T[5]=T[8];
T[8]=temp;
break;
case 13:
temp=T[0];T[0]=T[3];T[3]=T[5];T[5]=T[2];T[2]=temp;
temp=T[1];T[1]=T[9];T[9]=T[7];T[7]=T[4];T[4]=T[6];T[6]=T[8];
T[8]=temp;
break;
case 14:
temp=T[0];T[0]=T[8];T[8]=T[4];T[4]=T[2];T[2]=T[1];T[1]=T[9];
T[9]=T[3];T[3]=temp;
temp=T[5];T[5]=T[7];T[7]=T[6];T[6]=temp;
break;
case 15:
temp=T[0];T[0]=T[9];T[9]=T[6];T[6]=T[3];T[3]=T[1];T[1]=T[5];
T[5]=temp;
temp=T[2];T[2]=T[4];T[4]=T[7];T[7]=T[8];T[8]=temp;
break;
case 16:
temp=T[0];T[0]=T[7];T[7]=T[2];T[2]=T[6];T[6]=T[1];T[1]=T[3];
T[3]=T[9];T[9]=T[8];T[8]=temp;
temp=T[4];T[4]=T[5];T[5]=temp;
break;
case 17:
temp=T[0];T[0]=T[4];T[4]=T[1];T[1]=T[7];T[7]=T[8];T[8]=temp;
temp=T[2];T[2]=T[9];T[9]=T[3];T[3]=T[5];T[5]=T[6];T[6]=temp;
break;
case 18:
temp=T[0];T[0]=T[2];T[2]=T[3];T[3]=T[8];T[8]=temp;
temp=T[1];T[1]=T[7];T[7]=T[5];T[5]=T[6];T[6]=T[4];T[4]=T[9];
T[9]=temp;
break;
case 19:
temp=T[0];T[0]=T[1];T[1]=T[6];T[6]=T[7];T[7]=T[3];T[3]=T[4];
T[4]=temp;
temp=T[2];T[2]=T[5];T[5]=T[9];T[9]=T[8];T[8]=temp;
break;
}
d_ = temp_d_;
}
/*--------------------------------------------------------------------*/
/*-------------------- the core Frogbit algorithm --------------------*/
bit get_PR_bit(index PR_gen_selector); /* Forward reference: key stream
sources */
bit encipher_bit(bit m_i_)
{
int base;
bit k1_i_ = get_PR_bit(d_);
bit k2_i_ = get_PR_bit(d_);
bit s_i_ = m_i_^k1_i_;
drift_cnt[d_].c++;
if (s!=s_i_)
if (r_==0) base=0;
else base=(acc_d+1)<<1;
else if (r_!=0) base=(acc_d+3)<<1;
else
{
acc_d=k2_i_;
r_=1;
return s_i_^k2_i_;
}
index_permutation(base+k2_i_);
r_= 0;
s=s_i_;
return s_i_^k2_i_;
}
bit decipher_bit(bit e_i_)
{
int base;
bit k1_i_ = get_PR_bit(d_);
bit k2_i_ = get_PR_bit(d_);
bit s_i_ = e_i_^k2_i_;
drift_cnt[d_].c++;
if (s!=s_i_)
if (r_==0) base=0;
else base=(acc_d+1)<<1;
else if (r_!=0) base=(acc_d+3)<<1;
else
{
acc_d=k2_i_;
r_=1;
return s_i_^k1_i_;
}
index_permutation(base+k2_i_);
r_= 0;
s=s_i_;
return s_i_^k1_i_;
}
/**********************************************************************/
/*** ***/
/*** The core Frogbit algorithm ***/
/*** ***/
/**********************************************************************/
typedef int index;
typedef int bit;
/*--------------------------------------------------------------------*/
/*---------------- the state of the Frogbit algorithm ----------------*/
index T[10]; /* the current permutation table, T(i-1-r'(i-1)) */
index d_; /* the current key stream number, d'(i-1) */
/* local variables for the run length process */
int k2_r_s_; /* accumulated binary representation K2{i-1}, k2{i}*/
/* the current bounded run count, r'(i-1) */
/* the previous bit, s{i-1} */
/*--------------------------------------------------------------------*/
/*------------------ keystream "drift" accumulators ------------------*/
/* These accumulators are for information purposes. Their final
values may come into play for a hash code. The active state of
the pseudo-random generators is dealt with later. */
struct cntr
{
unsigned long c; /* A count of consumed keystream bits ... */
int i; /* ... for this key stream source. */
} drift_cnt[10];
/*--------------------------------------------------------------------*/
/*-------------------- the core Frogbit algorithm --------------------*/
bit get_PR_bit(index PR_gen_selector); /* Forward reference: key stream
sources */
static const int rle_logic_table[128]=
{ 4, 5, 0, 1, 48, 49, 16, 17, 4, 5, 0, 1, 64, 65, 32, 33
,130,131,134,135,146,147,178,179,130,131,134,135,162,163,194,195
,140,139,136,143,184,155,152,187,140,139,136,143,200,171,168,203
, 10, 13, 14, 9, 26, 57, 58, 25, 10, 13, 14, 9, 42, 73, 74, 41
,130,133,134,129,146,177,178,145,130,133,134,129,162,193,194,161
, 4, 3, 0, 7, 48, 19, 16, 51, 4, 3, 0, 7, 64, 35, 32, 67
, 10, 11, 14, 15, 26, 27, 58, 59, 10, 11, 14, 15, 42, 43, 74, 75
,140,141,136,137,184,185,152,153,140,141,136,137,200,201,168,169
};
/*
We use a table-lookup the control part of Frogbit encryption and
decryption.
+----------------------------------------------------------+
| Inputs |
+---------------------+------------------------------------+
| | Internal memory |
+-----+-----+---------+-------+-------+------+-------------+
|k1{i}|k2{i}|m{i}/e{i}|k2{i-1}|r'(i-1)|s{i-1}|Direction bit|
+-----+-----+---------+-------+-------+------+-------------+
+-------------------------------------------------------------------+
| Outputs |
+----------------------------------+--------------------------------+
| | Internal memory |
+----------------------------------+-------------+----+-------------+
| Externally used | | Constant |
+----------+-------+-------+-------+-------+-----+----+-------------+
| | | | |d{0}(i)| | | |
|output bit|d{3}(i)|d{2}(i)|d{1}(i)| k2{i} |r'(i)|s{i}|Direction bit|
+----------+-------+-------+-------+-------+-----+----+-------------+
*/
bit process_bit(bit m_i_)
{
int t1;
{
bit k1_i_ = get_PR_bit(d_);
bit k2_i_ = get_PR_bit(d_);
drift_cnt[d_].c++;
t1=rle_logic_table[(k2_r_s_&15)|(k2_i_<<5)|(m_i_<<4)|(k1_i_<<6)];
}
{
int temp;
if (0==(t1&4))
{
temp=(d_<<1)+(0!=(k2_r_s_&2));
k2_r_s_=t1;
d_=T[(k2_r_s_>>3)&15];
switch(temp)
{
case 0:
temp=T[0];T[0]=T[5];T[5]=T[2];T[2]=T[7];T[7]=temp;
temp=T[1];T[1]=T[8];T[8]=T[6];T[6]=T[4];T[4]=T[3];T[3]=T[9];
T[9]=temp;
break;
case 1:
temp=T[0];T[0]=T[2];T[2]=T[7];T[7]=temp;
temp=T[1];T[1]=T[3];T[3]=T[6];T[6]=T[9];T[9]=T[4];T[4]=T[8];
T[8]=T[5];T[5]=temp;
break;
case 2:
temp=T[0];T[0]=T[6];T[6]=T[8];T[8]=T[9];T[9]=T[5];T[5]=T[7];
T[7]=T[1];T[1]=temp;
temp=T[2];T[2]=T[4];T[4]=T[3];T[3]=temp;
break;
case 3:
temp=T[0];T[0]=T[6];T[6]=temp;
temp=T[1];T[1]=T[5];T[5]=T[3];T[3]=T[4];T[4]=T[2];T[2]=T[8];
T[8]=T[7];T[7]=T[9];T[9]=temp;
break;
case 4:
temp=T[0];T[0]=T[3];T[3]=T[6];T[6]=T[5];T[5]=T[1];T[1]=T[2];
T[2]=temp;
temp=T[4];T[4]=T[8];T[8]=T[7];T[7]=T[9];T[9]=temp;
break;
case 5:
temp=T[0];T[0]=T[6];T[6]=T[7];T[7]=T[3];T[3]=T[1];T[1]=T[2];
T[2]=T[9];T[9]=temp;
temp=T[4];T[4]=T[5];T[5]=T[8];T[8]=temp;
break;
case 6:
temp=T[0];T[0]=T[4];T[4]=T[3];T[3]=T[7];T[7]=T[6];T[6]=T[1];
T[1]=T[8];T[8]=T[5];T[5]=temp;
temp=T[2];T[2]=T[9];T[9]=temp;
break;
case 7:
temp=T[0];T[0]=T[5];T[5]=T[4];T[4]=temp;
temp=T[1];T[1]=T[9];T[9]=T[8];T[8]=T[6];T[6]=T[2];T[2]=T[3];
T[3]=T[7];T[7]=temp;
break;
case 8:
temp=T[0];T[0]=T[8];T[8]=T[9];T[9]=T[5];T[5]=T[3];T[3]=T[2];
T[2]=T[1];T[1]=temp;
temp=T[4];T[4]=T[6];T[6]=T[7];T[7]=temp;
break;
case 9:
temp=T[0];T[0]=T[9];T[9]=T[7];T[7]=T[8];T[8]=T[1];T[1]=T[4];
T[4]=T[2];T[2]=T[6];T[6]=temp;
temp=T[3];T[3]=T[5];T[5]=temp;
break;
case 10:
temp=T[0];T[0]=T[7];T[7]=T[2];T[2]=T[4];T[4]=T[1];T[1]=T[6];
T[6]=T[5];T[5]=T[9];T[9]=temp;
temp=T[3];T[3]=T[8];T[8]=temp;
break;
case 11:
temp=T[0];T[0]=T[1];T[1]=T[4];T[4]=T[7];T[7]=T[5];T[5]=T[2];
T[2]=T[8];T[8]=T[3];T[3]=temp;
temp=T[6];T[6]=T[9];T[9]=temp;
break;
case 12:
temp=T[0];T[0]=T[7];T[7]=T[6];T[6]=T[3];T[3]=temp;
temp=T[1];T[1]=T[4];T[4]=T[9];T[9]=T[2];T[2]=T[5];T[5]=T[8];
T[8]=temp;
break;
case 13:
temp=T[0];T[0]=T[3];T[3]=T[5];T[5]=T[2];T[2]=temp;
temp=T[1];T[1]=T[9];T[9]=T[7];T[7]=T[4];T[4]=T[6];T[6]=T[8];
T[8]=temp;
break;
case 14:
temp=T[0];T[0]=T[8];T[8]=T[4];T[4]=T[2];T[2]=T[1];T[1]=T[9];
T[9]=T[3];T[3]=temp;
temp=T[5];T[5]=T[7];T[7]=T[6];T[6]=temp;
break;
case 15:
temp=T[0];T[0]=T[9];T[9]=T[6];T[6]=T[3];T[3]=T[1];T[1]=T[5];
T[5]=temp;
temp=T[2];T[2]=T[4];T[4]=T[7];T[7]=T[8];T[8]=temp;
break;
case 16:
temp=T[0];T[0]=T[7];T[7]=T[2];T[2]=T[6];T[6]=T[1];T[1]=T[3];
T[3]=T[9];T[9]=T[8];T[8]=temp;
temp=T[4];T[4]=T[5];T[5]=temp;
break;
case 17:
temp=T[0];T[0]=T[4];T[4]=T[1];T[1]=T[7];T[7]=T[8];T[8]=temp;
temp=T[2];T[2]=T[9];T[9]=T[3];T[3]=T[5];T[5]=T[6];T[6]=temp;
break;
case 18:
temp=T[0];T[0]=T[2];T[2]=T[3];T[3]=T[8];T[8]=temp;
temp=T[1];T[1]=T[7];T[7]=T[5];T[5]=T[6];T[6]=T[4];T[4]=T[9];
T[9]=temp;
break;
case 19:
temp=T[0];T[0]=T[1];T[1]=T[6];T[6]=T[7];T[7]=T[3];T[3]=T[4];
T[4]=temp;
temp=T[2];T[2]=T[5];T[5]=T[9];T[9]=T[8];T[8]=temp;
break;
}
return 0!=(k2_r_s_&128);
}
k2_r_s_=t1;
return 0!=(k2_r_s_&128);
}
}
void set_direction(bit decrypt_flag)
{
k2_r_s_=(k2_r_s_&~1)|(decrypt_flag!=0);
}
/**********************************************************************/
/*** ***/
/*** Initialization for the Frogbit lookup table ***/
/*** ***/
/**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv)
{
int inputs;
printf(" static const int rle_logic_table[128]=\n {");
for (inputs=0;inputs<128;inputs++)
{
int k1_i, k2_i, v_i, k2_i__1, r_i__1, s_i__1, dir;
int outputs;
/*
+----------------------------------------------------------+
| Inputs |
+---------------------+------------------------------------+
| | Internal memory |
+-----+-----+---------+-------+-------+------+-------------+
|k1{i}|k2{i}|m{i}/e{i}|k2{i-1}|r'(i-1)|s{i-1}|Direction bit|
+-----+-----+---------+-------+-------+------+-------------+
*/
k1_i =(inputs&64)!=0;
k2_i =(inputs&32)!=0;
v_i =(inputs&16)!=0;
k2_i__1=(inputs&8)!=0;
r_i__1 =(inputs&4)!=0;
s_i__1 =(inputs&2)!=0;
dir =(inputs&1)!=0;
/*
+-------------------------------------------------------------------+
| Outputs |
+----------------------------------+--------------------------------+
| | Internal memory |
+----------------------------------+-------------+----+-------------+
| Externally used | | Constant |
+----------+-------+-------+-------+-------+-----+----+-------------+
| | | | |d{0}(i)| | | |
|Output bit|d{3}(i)|d{2}(i)|d{1}(i)| k2{i} |r'(i)|s{i}|Direction bit|
+----------+-------+-------+-------+-------+-----+----+-------------+
*/
outputs=dir;
{
/* do the Frogbit processing with these inputs */
int s_i;
if (dir)
s_i=v_i^k2_i;
else
s_i=v_i^k1_i;
outputs|=((k2_i^v_i^k1_i)<<7)|(s_i<<1);
if (s_i__1!=s_i)
if (r_i__1==0) outputs|= k2_i <<3;
else outputs|= (2+(k2_i__1<<1)+k2_i)<<3;
else
if (r_i__1!=0) outputs|= (6+(k2_i__1<<1)+k2_i)<<3;
else outputs|=( k2_i <<3)|(1<<2);
}
printf("%3d%s",outputs
,((inputs+1)%16)?",":((inputs==127)?"\n };":"\n ,"));
}
return EXIT_SUCCESS;
}
/* Sample output from this program:
static const int rle_logic_table[128]=
{ 4, 5, 0, 1, 48, 49, 16, 17, 4, 5, 0, 1, 64, 65, 32, 33
,130,131,134,135,146,147,178,179,130,131,134,135,162,163,194,195
,140,139,136,143,184,155,152,187,140,139,136,143,200,171,168,203
, 10, 13, 14, 9, 26, 57, 58, 25, 10, 13, 14, 9, 42, 73, 74, 41
,130,133,134,129,146,177,178,145,130,133,134,129,162,193,194,161
, 4, 3, 0, 7, 48, 19, 16, 51, 4, 3, 0, 7, 64, 35, 32, 67
, 10, 11, 14, 15, 26, 27, 58, 59, 10, 11, 14, 15, 42, 43, 74, 75
,140,141,136,137,184,185,152,153,140,141,136,137,200,201,168,169
};
*/
CONNOTECH Experts-conseils Inc.
9130 Place de Montgolfier
Montréal, Québec, Canada, H2M 2A1
Tél.: +1-514-385-5691
Fax: +1-514-385-5900