Assembly Language Programming

November 12, 2013

GOST Encryption 28147-89 ECB

The GOST cipher was developed by the Soviet government in the 1970’s and is still used by the Russian government to this day.

An English translation of the GOST 28147-89 standard can be found here:

http://tools.ietf.org/html/rfc5830

The Russian version can be found here:

http://standartgost.ru/%D0%93%D0%9E%D0%A1%D0%A2%2028147-89

It contains some useful diagrams that are not shown in the English version.

Related Post

GOST Encryption 28147-89 – Counter and Cipher Feedback Modes

GOST 28147-89 Specification (ECB – Simple Replacement)

- A 256 bit key is used to encrypt data in blocks of 64 bits at a time.

- There are 32 rounds.

- The 32 bit little endian registers X0 X1 X2 X3 X4 X5 X6 X7 store the key.

- The 32 bit little endian registers N1 N2 store the 64 bit input block.

- The s-box is defined as K = K8 K7 K6 K5 K4 K3 K2 K1.

- CM1, CM2 and R are 32 bit little endian registers.

- Pseudo code for the encryption is then:

  for(round=0;round<32;round++)
  {
   CM1 = N1 + X(round);

   R = K(CM1);
	
   R = ROTL(R,11);

   CM2 = R xor N2;

   if(round==31) break;

   N2 = N1;

   N1 = CM2;
  }

  N2 = CM2; 

- For round = 0-7, 8-15, 16-23 the order of X(round) is X0 X1 X2 X3 X4 X5 X6 X7.

- For round = 24-31 the order of X(round) is X7 X6 X5 X4 X3 X2 X1 X0.

The S-Box

The S-box K consists of the 8 substitution points K8 K7 K6 K5 K4 K3 K2 K1.

Each Ki is a lookup table of size 16 containing a permutation of the 4-bit values 0-15. The 4-bit input to each Ki is used as the index to an entry in the table. The 4-bit value at that location is substituted for the 4-bit input and becomes the output.

A 32 bit little endian input value (CM1 in the above pseudo code) is put through the S-box K as follows. The upper 4 bits go through K8, the next 4 bits go through K7, and so on, until the lowest 4 bits go through K1.

Two S-boxes are built into the program below:

(1) The first 8 rows of the DES S-boxes:

 K8 = 14 4 13 1 2 15 11 8 3 10 6 12 5 9 0 7

 K7 = 15 1 8 14 6 11 3 4 9 7 2 13 12 0 5 10

 K6 = 10 0 9 14 6 3 15 5 1 13 12 7 11 4 2 8

 K5 = 7 13 14 3 0 6 9 10 1 2 8 5 11 12 4 15

 K4 = 2 12 4 1 7 10 11 6 8 5 3 15 13 0 14 9

 K3 = 12 1 10 15 9 2 6 8 0 13 3 4 14 7 5 11

 K2 = 4 11 2 14 15 0 8 13 3 12 9 7 5 10 6 1

 K1 = 13 2 8 4 6 15 11 1 10 9 3 14 5 0 12 7

(2) The S-box given in GOST 34.11-94: http://tools.ietf.org/html/rfc5831

           8 7 6 5 4 3 2 1

       0   1 D 4 6 7 5 E 4
       1   F B B C D 8 B A
       2   D 4 A 7 A 1 4 9
       3   0 1 0 1 1 D C 2
       4   5 3 7 5 0 A 6 D
       5   7 F 2 F 8 3 D 8
       6   A 5 1 D 9 4 F 0
       7   4 9 D 8 F 2 A E
       8   9 0 3 4 E E 2 6
       9   2 A 6 A 4 F 3 B
      10   3 E 8 9 6 C 8 1
      11   E 7 5 E C 7 1 C
      12   6 6 9 0 B 6 0 7
      13   B 8 C 3 2 0 7 F
      14   8 2 F B 5 9 5 5
      15   C C E 2 3 B 9 3

Column 8 gives K8, column 7 gives K7, and so on.

Bit String To Little Endian

GOST 28147-89 specifies how the bit strings containing the 256 bit Key and 64 bit input block are converted to little endian values. First the bit strings are divided up into 32 bit words. Then the order of bits within each 32 bit word is reversed.

As far as the key is concerned, the first 32 bits become X0, the next 32 bits become X1, and so on.

For the 64 bit input block, the first 32 bits become N1 and the last 32 bits become N2.

The Program

The program is written in Javascript. The input and output values are 32 bit little endian values.

– The key is entered as the little endian words X0 X1 X2 X3 X4 X5 X6 X7.

– The input is entered as the little endian words N1 and N2.

The program also enables the user to convert bit strings to little endian values, either by reversing the order of bits within each 32 bit word, or by reversing the order of bytes within each 32 bit word.

Test Vectors

(1) The first test vector comes from:

http://cryptomanager.com/tv.html

Key:

75 71 31 34 B6 0F EC 45 
A6 07 BB 83 AA 37 46 AF 
4F F9 9D A6 D1 B5 3B 5B 
1B 40 2A 1B AA 03 0D 1B

Input:

11 22 33 44 55 66 77 88 

Output:

03 25 1E 14 F9 D2 8A CB

S-Box:

GOST 34.11-94

The bytes in these test vectors are in byte array order. Converting to little endian numbers as required by my program gives:

Key:

34 31 71 75 45 ec 0f b6 
83 bb 07 a6 af 46 37 aa
a6 9d f9 4f 5b 3b b5 d1 
1b 2a 40 1b 1b 0d 03 aa

Input:

44 33 22 11 88 77 66 55

Output:

14 1e 25 03 cb 8a d2 f9

(2) The second test vector comes from (in the source code download):

http://edipermadi.wordpress.com/2008/02/11/gost-cipher-implementation-on-pic16f84/

In little endian byte order:

Key:

00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00

Input:

00 00 00 00 00 00 00 00

Output:

e7 2b 17 d7 02 f1 22 c0

S-Box:

DES

The HTML/Javascript Code

To grab this code, select with the mouse, and copy and paste into a text file.

<html>

<head>

<title>GOST Encryption</title>

<style type="text/css">

textarea,input,p
{
 font-family: Lucida Console;

 font-size: 11pt;
}

</style>

</head>

<script type="text/javascript">

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 // K_Arr is the s-box array: K8 K7 K6 K5 K4 K3 K2 K1

 var K_Arr = [];

 // the 256 bit key: X0 X1 X2 X3 X4 X5 X6 X7

 var X0;
 var X1;
 var X2;
 var X3;
 var X4;
 var X5;
 var X6;
 var X7;

 // the 64 bit input block: N1 N2

 var N1;
 var N2;

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Encrypt()
{
 // ===================================

 // for each round:

 // ===================================

 // CM1 = N1 + X(round)

 // R = K(CM1)

 // R = ROTL(R,11)

 // CM2 = R xor N2

 // ===================================

 // for all except the last round:

 // ===================================

 // N2 = N1

 // N1 = CM2

 // ===================================

 // for the last round:

 // ===================================

 // N2 = CM2

 // ===================================

 Read_Key();

 Read_Input();

 var CM1,CM2,R;

 var i;

 for(i=0;i<3;i++)
 {
  CM1 = N1 + X0;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  N2 = N1;
  N1 = CM2;

  CM1 = N1 + X1;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  N2 = N1;
  N1 = CM2;

  CM1 = N1 + X2;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  N2 = N1;
  N1 = CM2;

  CM1 = N1 + X3;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  N2 = N1;
  N1 = CM2;

  CM1 = N1 + X4;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  N2 = N1;
  N1 = CM2;

  CM1 = N1 + X5;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  N2 = N1;
  N1 = CM2;

  CM1 = N1 + X6;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  N2 = N1;
  N1 = CM2;

  CM1 = N1 + X7;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  N2 = N1;
  N1 = CM2;
 }

 CM1 = N1 + X7;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = N1;
 N1 = CM2;

 CM1 = N1 + X6;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = N1;
 N1 = CM2;

 CM1 = N1 + X5;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = N1;
 N1 = CM2;

 CM1 = N1 + X4;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = N1;
 N1 = CM2;

 CM1 = N1 + X3;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = N1;
 N1 = CM2;

 CM1 = N1 + X2;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = N1;
 N1 = CM2;

 CM1 = N1 + X1;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = N1;
 N1 = CM2;

 CM1 = N1 + X0;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = CM2;

 var str = "";

 str = Print_Word(N1) + " " + Print_Word(N2) + "\r\n";
 
 document.getElementById("txtOutput").value = str;
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Decrypt()
{
 // ===================================

 // for each round:

 // ===================================

 // CM1 = N1 + X(round)

 // R = K(CM1)

 // R = ROTL(R,11)

 // CM2 = R xor N2

 // ===================================

 // for all except the last round:

 // ===================================

 // N2 = N1

 // N1 = CM2

 // ===================================

 // for the last round:

 // ===================================

 // N2 = CM2

 // ===================================

 Read_Key();

 Read_Input();

 var CM1,CM2,R;

 CM1 = N1 + X0;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = N1;
 N1 = CM2;

 CM1 = N1 + X1;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = N1;
 N1 = CM2;

 CM1 = N1 + X2;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = N1;
 N1 = CM2;

 CM1 = N1 + X3;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = N1;
 N1 = CM2;

 CM1 = N1 + X4;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = N1;
 N1 = CM2;

 CM1 = N1 + X5;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = N1;
 N1 = CM2;

 CM1 = N1 + X6;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = N1;
 N1 = CM2;

 CM1 = N1 + X7;
 R = K_Sub(CM1);
 R = ROTL_11(R);
 CM2 = R ^ N2;

 N2 = N1;
 N1 = CM2;

 var i;

 for(i=0;i<3;i++)
 {
  CM1 = N1 + X7;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  N2 = N1;
  N1 = CM2;

  CM1 = N1 + X6;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  N2 = N1;
  N1 = CM2;

  CM1 = N1 + X5;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  N2 = N1;
  N1 = CM2;

  CM1 = N1 + X4;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  N2 = N1;
  N1 = CM2;

  CM1 = N1 + X3;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  N2 = N1;
  N1 = CM2;

  CM1 = N1 + X2;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  N2 = N1;
  N1 = CM2;

  CM1 = N1 + X1;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  N2 = N1;
  N1 = CM2;

  CM1 = N1 + X0;
  R = K_Sub(CM1);
  R = ROTL_11(R);
  CM2 = R ^ N2;

  if(i==2) break;

  N2 = N1;
  N1 = CM2;
 }

 N2 = CM2;

 var str = "";

 str = Print_Word(N1) + " " + Print_Word(N2) + "\r\n";
 
 document.getElementById("txtOutput").value = str;
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function K_Sub(w32)
{
 // do the s-box substitutions

 // the lower 4 bits in w32 go through K1

 // the upper 4 bits in w32 go through K8

 var tmp;

 var result = 0;

 for(var i=0;i<8;i++)
 {
  result = result >>> 4;

  // get the next 4 bits

  tmp = w32 & 0xf;

  // apply the substitution

  tmp = K_Arr[(i*16)+tmp] & 0xf;

  // update the result

  tmp = tmp << 28;

  result = result | tmp;

  w32 = w32 >>> 4;
 }

 return result & 0xffffffff;
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function ROTL_11(w32)
{
 // left rotate w32 by 11 bits

 var tmp = (w32 << 11) | (w32 >>> 21);

 return tmp & 0xffffffff;
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Read_Key()
{
 var str = document.getElementById("txtKey").value;

 // remove any non-hex characters

 str = StrToHexStr(str);

 // fix length to 64 hex digits

 // pad with zeroes

 while(str.length < 64) str += "0";

 if(str.length > 64) str = str.slice(0,64);

 // convert the key to an array of 32 bit words

 var X_Arr = [];

 X_Arr = HexStrToArray(str); 

 // initialise X0 .. X7

 X0 = X_Arr[0];
 X1 = X_Arr[1];
 X2 = X_Arr[2];
 X3 = X_Arr[3];
 X4 = X_Arr[4];
 X5 = X_Arr[5];
 X6 = X_Arr[6];
 X7 = X_Arr[7];

 // print X0 ... X7

 str = Print_Word(X0) + " " + Print_Word(X1) + " ";

 str += Print_Word(X2) + " " + Print_Word(X3) + "\r\n";

 str += Print_Word(X4) + " " + Print_Word(X5) + " ";

 str += Print_Word(X6) + " " + Print_Word(X7) + "\r\n";
 
 document.getElementById("txtKey").value = str;
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Read_Input()
{
 var str = document.getElementById("txtInput").value;

 // remove any non-hex characters

 str = StrToHexStr(str);

 // fix length to 16 hex digits

 // pad with zeroes

 while(str.length < 16) str += "0";

 if(str.length > 16) str = str.slice(0,16);

 // convert the str to an array of 32 bit words

 var N = [];

 N = HexStrToArray(str); 

 // initialise N1 and N2

 N1 = N[0];

 N2 = N[1];

 // print N1 and N2

 str = Print_Word(N1) + " " + Print_Word(N2) + "\r\n";
 
 document.getElementById("txtInput").value = str;
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function StrToHexStr(str)
{
 // remove all characters that are not hex digits:

 var ptn_not_hex = /[^0-9a-fA-F]{1,}/g; 

 str = str.replace(ptn_not_hex,"");

 return str;
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function HexStrToArray(str)
{
 // convert the string to an array of 32 bit words:

 var hex_arr = [];

 for(var i=0;i<str.length/8;i++)
 {
  var tstr = str.substr(8*i,8);

  var tmp = parseInt(tstr,16);

  hex_arr[i] = tmp & 0xffffffff;
 }

 return hex_arr;
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Default_S_Boxes()
{
 // load the default s-boxes

 GOST_34_11_94_S_Boxes();
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function GOST_34_11_94_S_Boxes()
{
 // load the GOST 34.11-94 S-boxes

 K_Arr = [];

 var K8 = [0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC];
 var K7 = [0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC];
 var K6 = [0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE];
 var K5 = [0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2];
 var K4 = [0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3];
 var K3 = [0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB];
 var K2 = [0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9];
 var K1 = [0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3];

 K_Arr = K1.concat(K2,K3,K4,K5,K6,K7,K8);

 document.getElementById("curr_s_box").innerHTML = "Current S-Box = GOST 34.11-94.";
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function DES_S_Boxes()
{
 // load the DES S-boxes

 K_Arr = [];

 var K8 = [14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7];
 var K7 = [15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10];
 var K6 = [10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8];
 var K5 = [7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15];
 var K4 = [2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9];
 var K3 = [12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11];
 var K2 = [4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1];
 var K1 = [13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7];

 K_Arr = K1.concat(K2,K3,K4,K5,K6,K7,K8);

 document.getElementById("curr_s_box").innerHTML = "Current S-Box = DES.";
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Print_Word(w)
{
 // print a 32 bit word

 var str = "";

 str = (w>>>0).toString(16);
 
 while(str.length < 8) str = "0" + str;

 return str;
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Clear()
{
 var str = "Enter X0 X1 X2 X3 X4 X5 X6 X7 as little endian 32 bit words:";

 document.getElementById("txtKey").value = str;

 str = "Enter N1 N2 as little endian 32 bit words:";

 document.getElementById("txtInput").value = str;

 document.getElementById("txtOutput").value = "";

 document.getElementById("txtBitString").value = "";

 document.getElementById("txtLittleEndian").value = "";

 Default_S_Boxes();
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Bits_Reverse()
{
 // divide a string into 32 bit words and then reverse the 
 // order of bits within each 32 bit word

 var str = document.getElementById("txtBitString").value;

 // remove any non-hex characters

 str = StrToHexStr(str);

 // fix length to a multiple of 8 hex digits

 // pad with zeroes

 while(str.length % 8 != 0) str += "0";

 // convert the str to an array of 32 bit words

 var N = [];

 N = HexStrToArray(str); 

 var i;

 // print the input bit string as 32 bit words

 str = "";

 for(i=0;i<N.length;i++)
 {
  str += Print_Word(N[i]) + " ";
 }
 
 document.getElementById("txtBitString").value = str;

 // reverse the bit order within each 32 bit word and print

 str = "";

 for(i=0;i<N.length;i++)
 {
  N[i]= Reverse_Bits(N[i]);

  str += Print_Word(N[i]) + " ";
 }

 document.getElementById("txtLittleEndian").value = str;
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Bytes_Reverse()
{
 // divide a string into 32 bit words and then reverse the 
 // order of bytes within each 32 bit word

 var str = document.getElementById("txtBitString").value;

 // remove any non-hex characters

 str = StrToHexStr(str);

 // fix length to a multiple of 8 hex digits

 // pad with zeroes

 while(str.length % 8 != 0) str += "0";

 // convert the str to an array of 32 bit words

 var N = [];

 N = HexStrToArray(str); 

 var i;

 // print the input bit string as 32 bit words

 str = "";

 for(i=0;i<N.length;i++)
 {
  str += Print_Word(N[i]) + " ";
 }
 
 document.getElementById("txtBitString").value = str;

 // reverse the byte order within each 32 bit word and print

 str = "";

 for(i=0;i<N.length;i++)
 {
  N[i]= Reverse_Bytes(N[i]);

  str += Print_Word(N[i]) + " ";
 }

 document.getElementById("txtLittleEndian").value = str;
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Reverse_Bytes(w32)
{
 // reverse the order of bytes in a 32 bit word

 // get the bytes

 var b1 = w32 & 0xff;
 var b2 = w32 & 0xff00;
 var b3 = w32 & 0xff0000;
 var b4 = w32 & 0xff000000;
 
 b2 = b2 >>> 8;
 b3 = b3 >>> 16;
 b4 = b4 >>> 24;

 // swap the bytes

 var result = b1;

 result = (result << 8) | b2;
 result = (result << 8) | b3;
 result = (result << 8) | b4;

 return result & 0xffffffff;
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Reverse_Bits(w32)
{
 // reverse the order of bits in a 32 bit word

 // get the bytes

 var b1 = w32 & 0xff;
 var b2 = w32 & 0xff00;
 var b3 = w32 & 0xff0000;
 var b4 = w32 & 0xff000000;
 
 b2 = b2 >>> 8;
 b3 = b3 >>> 16;
 b4 = b4 >>> 24;

 // swap the bits in each byte

 b1 = Swap_Bits(b1);
 b2 = Swap_Bits(b2);
 b3 = Swap_Bits(b3);
 b4 = Swap_Bits(b4);

 // swap the bytes

 var result = b1;

 result = (result << 8) | b2;
 result = (result << 8) | b3;
 result = (result << 8) | b4;

 return result & 0xffffffff;
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

function Swap_Bits(byte)
{
 // reverse the order of bits in a byte

 // get the nibbles first

 var n1 = byte & 0xf;

 var n2 = byte & 0xf0;

 // lookup table to swap the bits in a nibble

 var swp = [0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15];

 // swap the bits in n1

 n1 = swp[n1];

 // swap the bits in n2

 n2 = n2 >>> 4;

 n2 = swp[n2 & 0xf]; 

 // recombine the nibbles

 return ((n1 << 4) | n2) & 0xff;
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

</script>

<body onload="Clear()">

<h2>GOST 28147-89 Encryption - ECB Mode</h2>

<p>
Enter the 256 bit key X0 .. X7 and 64 bit input block N1 N2 as hexadecimal numbers.
</p>

<p id="curr_s_box">
Current S-Box = None.
</p>

<input type="button" value="Encrypt" onClick="Encrypt()">

<input type="button" value="Decrypt" onClick="Decrypt()">

<input type="button" value="DES S-Boxes" onClick="DES_S_Boxes()">

<input type="button" value="34.11-94 S-Boxes" onClick="GOST_34_11_94_S_Boxes()">

<input type="button" value="Clear" onClick="Clear()">

<br><br>

<textarea id="txtKey" rows="4" cols="60" spellcheck="false"></textarea>

<br>

<textarea id="txtInput" rows="2" cols="60" spellcheck="false"></textarea>

<br>

<textarea id="txtOutput" rows="2" cols="60" spellcheck="false"></textarea>

<h2>Bit String To Little Endian</h2>

<p>
Enter a bit string as a hexadecimal number. The bit string is broken up into 32 bit words and converted to little endian.
</p>

<input type="button" value="Reverse Bytes" onClick="Bytes_Reverse()">

<input type="button" value="Reverse Bits" onClick="Bits_Reverse()">

<br><br>

<textarea id="txtBitString" rows="4" cols="60" spellcheck="false"></textarea>

<br>

<textarea id="txtLittleEndian" rows="4" cols="60" spellcheck="false"></textarea>

</body>

</html>
Advertisements

Create a free website or blog at WordPress.com.

%d bloggers like this: