OpenCores
URL https://opencores.org/ocsvn/gost28147-89/gost28147-89/trunk

Subversion Repositories gost28147-89

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /gost28147-89
    from Rev 4 to Rev 5
    Reverse comparison

Rev 4 → Rev 5

/trunk/testbench/gost89_ecb_tb.v
0,0 → 1,107
`timescale 1ns / 1ps
 
module gost89_ecb_tb;
reg clk;
always
#1 clk = ~clk;
 
reg [511:0] sbox = 512'h 4a92d80e6b1c7f53eb4c6dfa23810759581da342efc7609b7da1089fe46cb2536c715fd84a9e03b24ba0721d36859cfedb413f590ae7682c1fd057a4923e6b8c;
reg [255:0] key = 256'h 0475f6e05038fbfad2c7c390edb3ca3d1547124291ae1e8a2f79cd9ed2bcefbd;
wire mode_e = 0, mode_d = 1;
reg reset;
reg load_data;
reg [63:0] in_e1, in_e2, in_d1, in_d2;
wire [63:0] out_e1, out_e2, out_d1, out_d2;
wire busy_e1, busy_e2, busy_d1, busy_d2;
 
gost89_ecb
ecb1(clk, reset, mode_e, load_data, sbox, key, in_e1, out_e1, busy_e1),
ecb2(clk, reset, mode_d, load_data, sbox, key, in_d1, out_d1, busy_d1);
gost89_ecb_encrypt
ecb_encrypt(clk, reset, load_data, sbox, key, in_e2, out_e2, busy_e2);
gost89_ecb_decrypt
ecb_decrypt(clk, reset, load_data, sbox, key, in_d2, out_d2, busy_d2);
 
/*
ECB mode:
d5a8a608f4f115b4 389eb44a391474c4 379e59c3c96bb2ab 3f38ae3b8f541361
d658a36b11cf46eb 7aea1ed18e604249 c35472c91cd78640 3b5834a000fba066
*/
 
initial begin
$dumpfile("gost89_ecb_tb.vcd");
$dumpvars(0, gost89_ecb_tb);
 
clk = 0;
reset = 0;
load_data = 0;
 
// Normal usage
#1;
in_e1 = 64'h d5a8a608f4f115b4; in_d1 = 64'h d658a36b11cf46eb;
in_e2 = 64'h d5a8a608f4f115b4; in_d2 = 64'h d658a36b11cf46eb;
load_data = 1;
#2;
load_data = 0;
#66;
if (out_e1 != out_e2 || out_e2 != 64'h d658a36b11cf46eb || out_d1 != out_d2 || out_d2 != 64'h d5a8a608f4f115b4)
begin $display("E"); $finish; end
$display("OK");
 
// After reset
#2;
reset = 1;
#2;
reset = 0;
#2;
in_e1 = 64'h 389eb44a391474c4; in_d1 = 64'h 7aea1ed18e604249;
in_e2 = 64'h 389eb44a391474c4; in_d2 = 64'h 7aea1ed18e604249;
load_data = 1;
#2;
load_data = 0;
#66;
if (out_e1 != out_e2 || out_e2 != 64'h 7aea1ed18e604249 || out_d1 != out_d2 || out_d2 != 64'h 389eb44a391474c4)
begin $display("E"); $finish; end
$display("OK");
 
// Reset in processing
#2;
in_e1 = 64'h 0123456789abcdef; in_d1 = 64'h 0123456789abcdef;
in_e2 = 64'h 0123456789abcdef; in_d2 = 64'h 0123456789abcdef;
load_data = 1;
#2;
load_data = 0;
#12;
reset = 1;
#2;
reset = 0;
#2;
in_e1 = 64'h 379e59c3c96bb2ab; in_d1 = 64'h c35472c91cd78640;
in_e2 = 64'h 379e59c3c96bb2ab; in_d2 = 64'h c35472c91cd78640;
load_data = 1;
#2;
load_data = 0;
#66;
if (out_e1 != out_e2 || out_e2 != 64'h c35472c91cd78640 || out_d1 != out_d2 || out_d2 != 64'h 379e59c3c96bb2ab)
begin $display("E"); $finish; end
$display("OK");
 
// Start with reset
#2;
in_e1 = 64'h 3f38ae3b8f541361; in_d1 = 64'h 3b5834a000fba066;
in_e2 = 64'h 3f38ae3b8f541361; in_d2 = 64'h 3b5834a000fba066;
load_data = 1;
reset = 1;
#2;
load_data = 0;
reset = 0;
#66;
if (out_e1 != out_e2 || out_e2 != 64'h 3b5834a000fba066 || out_d1 != out_d2 || out_d2 != 64'h 3f38ae3b8f541361)
begin $display("E"); $finish; end
$display("OK");
 
#10;
$display("All passed");
$finish;
end
endmodule
/trunk/testbench/gost89_cfb_tb.v
0,0 → 1,118
`timescale 1ns / 1ps
 
module gost89_cfb_tb;
reg clk;
always
#1 clk = ~clk;
 
reg [511:0] sbox = 512'h 4a92d80e6b1c7f53eb4c6dfa23810759581da342efc7609b7da1089fe46cb2536c715fd84a9e03b24ba0721d36859cfedb413f590ae7682c1fd057a4923e6b8c;
reg [255:0] key = 256'h 0475f6e05038fbfad2c7c390edb3ca3d1547124291ae1e8a2f79cd9ed2bcefbd;
wire mode_e = 0, mode_d = 1;
reg reset;
reg load_data;
reg [63:0] in_e1, in_e2, in_d1, in_d2;
wire [63:0] out_e1, out_e2, out_d1, out_d2;
wire busy_e1, busy_e2, busy_d1, busy_d2;
 
gost89_cfb
cfb1(clk, reset, mode_e, load_data, sbox, key, in_e1, out_e1, busy_e1),
cfb2(clk, reset, mode_d, load_data, sbox, key, in_d1, out_d1, busy_d1);
gost89_cfb_encrypt
cfb_encrypt1(clk, reset, load_data, sbox, key, in_e2, out_e2, busy_e2);
gost89_cfb_decrypt
cfb_decrypt1(clk, reset, load_data, sbox, key, in_d2, out_d2, busy_d2);
 
/*
CFB mode (gamma: 6aa0379517bb57af):
8d437364581af0da 12911df3eddcc0fb b73369c4b5cf3e7d
54826055ab718bc7 585ddacf1a45e472 a3ec5a4eb4359095
 
CFB mode (gamma: fa5679a45f118aed):
419677a6eff07f2f 4f40b75be8e64341 cd02e6ef903d27da
27d3e781cc4fcf43 9c7480fb9ea9df69 458ff5081b0fd688
*/
 
initial begin
$dumpfile("gost89_cfb_tb.vcd");
$dumpvars(0, gost89_cfb_tb);
 
clk = 0;
reset = 0;
load_data = 0;
 
// Normal usage
#1;
in_e1 = 64'h 6aa0379517bb57af; in_d1 = 64'h 6aa0379517bb57af;
in_e2 = 64'h 6aa0379517bb57af; in_d2 = 64'h 6aa0379517bb57af;
reset = 1;
#2;
reset = 0;
in_e1 = 64'h 8d437364581af0da; in_d1 = 64'h 54826055ab718bc7;
in_e2 = 64'h 8d437364581af0da; in_d2 = 64'h 54826055ab718bc7;
load_data = 1;
#2;
load_data = 0;
#68;
if (out_e1 != out_e2 || out_e2 != 64'h 54826055ab718bc7 || out_d1 != out_d2 || out_d2 != 64'h 8d437364581af0da)
begin $display("E"); $finish; end
$display("OK");
in_e1 = 64'h 12911df3eddcc0fb; in_d1 = 64'h 585ddacf1a45e472;
in_e2 = 64'h 12911df3eddcc0fb; in_d2 = 64'h 585ddacf1a45e472;
load_data = 1;
#2;
load_data = 0;
#68;
if (out_e1 != out_e2 || out_e2 != 64'h 585ddacf1a45e472 || out_d1 != out_d2 || out_d2 != 64'h 12911df3eddcc0fb)
begin $display("E"); $finish; end
$display("OK");
 
// Change gamma
#2;
in_e1 = 64'h fa5679a45f118aed; in_d1 = 64'h fa5679a45f118aed;
in_e2 = 64'h fa5679a45f118aed; in_d2 = 64'h fa5679a45f118aed;
reset = 1;
#2;
reset = 0;
in_e1 = 64'h 419677a6eff07f2f; in_d1 = 64'h 27d3e781cc4fcf43;
in_e2 = 64'h 419677a6eff07f2f; in_d2 = 64'h 27d3e781cc4fcf43;
load_data = 1;
#2;
load_data = 0;
#68;
if (out_e1 != out_e2 || out_e2 != 64'h 27d3e781cc4fcf43 || out_d1 != out_d2 || out_d2 != 64'h 419677a6eff07f2f)
begin $display("E"); $finish; end
$display("OK");
 
// Reset in processing
#2;
in_e1 = 64'h 6aa0379517bb57af; in_d1 = 64'h 6aa0379517bb57af;
in_e2 = 64'h 6aa0379517bb57af; in_d2 = 64'h 6aa0379517bb57af;
reset = 1;
#2;
reset = 0;
in_e1 = 64'h 8d437364581af0da; in_d1 = 64'h 54826055ab718bc7;
in_e2 = 64'h 8d437364581af0da; in_d2 = 64'h 54826055ab718bc7;
load_data = 1;
#2;
load_data = 0;
#10;
in_e1 = 64'h fa5679a45f118aed; in_d1 = 64'h fa5679a45f118aed;
in_e2 = 64'h fa5679a45f118aed; in_d2 = 64'h fa5679a45f118aed;
reset = 1;
#2;
reset = 0;
in_e1 = 64'h 419677a6eff07f2f; in_d1 = 64'h 27d3e781cc4fcf43;
in_e2 = 64'h 419677a6eff07f2f; in_d2 = 64'h 27d3e781cc4fcf43;
load_data = 1;
#2;
load_data = 0;
#68;
if (out_e1 != out_e2 || out_e2 != 64'h 27d3e781cc4fcf43 || out_d1 != out_d2 || out_d2 != 64'h 419677a6eff07f2f)
begin $display("E"); $finish; end
$display("OK");
 
#10;
$display("All passed");
$finish;
end
endmodule
/trunk/testbench/gost89_mac_tb.v
0,0 → 1,130
`timescale 1ns / 1ps
 
module gost89_mac_tb;
reg clk;
always
#1 clk = ~clk;
 
reg [511:0] sbox = 512'h 4a92d80e6b1c7f53eb4c6dfa23810759581da342efc7609b7da1089fe46cb2536c715fd84a9e03b24ba0721d36859cfedb413f590ae7682c1fd057a4923e6b8c;
reg [255:0] key = 256'h 0475f6e05038fbfad2c7c390edb3ca3d1547124291ae1e8a2f79cd9ed2bcefbd;
reg reset, load_data;
reg [63:0] in;
wire [31:0] out;
wire busy;
wire [31:0] result = out[31:0];
 
gost89_mac mac1(clk, reset, load_data, sbox, key, in, out, busy);
 
initial begin
$dumpfile("gost89_mac_tb.vcd");
$dumpvars(0, gost89_mac_tb);
 
clk = 0;
reset = 0;
load_data = 0;
 
/* Normal usage
4b657e2ef0d2dfa2 af36b591bbd96c85 3569faad243d6fa4
b4a50c2c00000000
*/
#1
reset = 1;
#2
reset = 0;
#2
in = 64'h 4b657e2ef0d2dfa2;
load_data = 1;
#2;
load_data = 0;
 
#34;
in = 64'h af36b591bbd96c85;
load_data = 1;
#2;
load_data = 0;
 
#34;
in = 64'h 3569faad243d6fa4;
load_data = 1;
#2;
load_data = 0;
 
#34;
if (result !== 32'h b4a50c2c)
begin $display("E"); $finish; end
$display("OK");
 
/* Reset in processing
845fbd32d185bbf2 387172424b8518a3 ba95eadaa69ed200
7acc77a200000000
*/
reset = 1;
#2
reset = 0;
#2
in = 64'h 4b657e2ef0d2dfa2;
load_data = 1;
#2;
load_data = 0;
#10
reset = 1;
#2
reset = 0;
 
#4
in = 64'h 845fbd32d185bbf2;
load_data = 1;
#2;
load_data = 0;
 
#34;
in = 64'h 387172424b8518a3;
load_data = 1;
#2;
load_data = 0;
 
#34;
in = 64'h ba95eadaa69ed200;
load_data = 1;
#2;
load_data = 0;
 
#34;
if (result !== 32'h 7acc77a2)
begin $display("E"); $finish; end
$display("OK");
 
/* Start with reset
ba3d8a2c8fe0307a c1fe2bf562c45b53 c066169b334014e0
c9541f2800000000
*/
#2
in = 64'h ba3d8a2c8fe0307a;
load_data = 1;
reset = 1;
#2;
load_data = 0;
reset = 0;
 
#34;
in = 64'h c1fe2bf562c45b53;
load_data = 1;
#2;
load_data = 0;
 
#34;
in = 64'h c066169b334014e0;
load_data = 1;
#2;
load_data = 0;
 
#34;
if (result !== 32'h c9541f28)
begin $display("E"); $finish; end
$display("OK");
 
#10;
$display("All passed");
$finish;
end
endmodule
/trunk/testbench/gost89_pipelined_ecb_tb.v
0,0 → 1,62
`timescale 1ns / 1ps
 
module gost89_pipelined_ecb_tb;
reg clk;
always
#1 clk = ~clk;
 
reg [511:0] sbox = 512'h 4a92d80e6b1c7f53eb4c6dfa23810759581da342efc7609b7da1089fe46cb2536c715fd84a9e03b24ba0721d36859cfedb413f590ae7682c1fd057a4923e6b8c;
reg [255:0] key = 256'h 0475f6e05038fbfad2c7c390edb3ca3d1547124291ae1e8a2f79cd9ed2bcefbd;
reg [63:0] in_e, in_d;
wire [63:0] out_e, out_d;
 
gost89_pipelined_ecb_encrypt
pipelined_ecb_encrypt(clk, sbox, key, in_e, out_e);
gost89_pipelined_ecb_decrypt
pipelined_ecb_decrypt(clk, sbox, key, in_d, out_d);
 
/*
ECB mode:
d5a8a608f4f115b4 389eb44a391474c4 379e59c3c96bb2ab 3f38ae3b8f541361
d658a36b11cf46eb 7aea1ed18e604249 c35472c91cd78640 3b5834a000fba066
*/
 
initial begin
$dumpfile("gost89_pipelined_ecb_tb.vcd");
$dumpvars(0, gost89_pipelined_ecb_tb);
 
clk = 0;
 
// One vector
#1;
in_e = 64'h d5a8a608f4f115b4; in_d = 64'h d658a36b11cf46eb;
#64;
if (out_e !== 64'h d658a36b11cf46eb || out_d !== 64'h d5a8a608f4f115b4)
begin $display("E"); $finish; end
$display("OK");
 
// Three vectors
#4
in_e = 64'h 389eb44a391474c4; in_d = 64'h 7aea1ed18e604249;
#2;
in_e = 64'h 379e59c3c96bb2ab; in_d = 64'h c35472c91cd78640;
#8;
in_e = 64'h 3f38ae3b8f541361; in_d = 64'h 3b5834a000fba066;
#54;
if (out_e !== 64'h 7aea1ed18e604249 || out_d !== 64'h 389eb44a391474c4)
begin $display("E"); $finish; end
$display("OK");
#2;
if (out_e !== 64'h c35472c91cd78640 || out_d !== 64'h 379e59c3c96bb2ab)
begin $display("E"); $finish; end
$display("OK");
#8;
if (out_e !== 64'h 3b5834a000fba066 || out_d !== 64'h 3f38ae3b8f541361)
begin $display("E"); $finish; end
$display("OK");
 
#10;
$display("All passed");
$finish;
end
endmodule
/trunk/testbench/makefile
0,0 → 1,11
%_tb: %_tb.v
iverilog -o $@.vo $< ../rtl/*.v
vvp $@.vo
 
all: gost89_pipelined_ecb_tb gost89_ecb_tb gost89_cfb_tb gost89_mac_tb
 
clean:
rm -f *.vo *.vcd
 
.DEFAULT_GOAL := all
 
/trunk/utils/gost89.h
0,0 → 1,48
#ifndef __GOST89_H
#define __GOST89_H
 
#include <stdint.h>
#include <stddef.h>
 
 
/* GOST substitution blocks */
typedef struct {
uint8_t k1[16];
uint8_t k2[16];
uint8_t k3[16];
uint8_t k4[16];
uint8_t k5[16];
uint8_t k6[16];
uint8_t k7[16];
uint8_t k8[16];
} gost_subst_block;
 
/* Cipher context */
typedef struct {
uint32_t k[8];
uint32_t k87[256], k65[256], k43[256], k21[256];
} gost_ctx;
 
/* Set S-blocks into context */
void gost_init(gost_ctx *c, const gost_subst_block* b);
/* Clean up context */
void gost_destroy(gost_ctx* c);
/* Set key into context */
void gost_set_key(gost_ctx *c, const uint8_t *k);
/* Get key from context */
void gost_get_key(gost_ctx *c, uint8_t *k);
 
/* Encrypt several full blocks in ECB mode */
void gost_ecb_encrypt(gost_ctx *ctx, const uint8_t *in, uint8_t *out, size_t blocks);
/* Decrypt several full blocks in ECB mode */
void gost_ecb_decrypt(gost_ctx *ctx, const uint8_t *in, uint8_t *out, size_t blocks);
 
/* Encrypt several full blocks in CFB mode */
void gost_cfb_encrypt(gost_ctx *ctx, const uint8_t *iv, const uint8_t *in, uint8_t *out, size_t blocks);
/* Decrypt several full blocks in CFB mode */
void gost_cfb_decrypt(gost_ctx *ctx, const uint8_t *iv, const uint8_t *in, uint8_t *out, size_t blocks);
 
/* Compute MAC of given length in bits from data */
void gost_mac(gost_ctx *ctx, const uint8_t *data, size_t data_len, uint8_t *mac, size_t mac_len);
 
#endif
/trunk/utils/generator.c
0,0 → 1,101
#include <stdio.h>
#include <string.h>
#include <stdint.h>
 
#include <openssl/rand.h>
 
#include "gost89.h"
 
gost_subst_block gost_sbox = {
{0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3},
{0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9},
{0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB},
{0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3},
{0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2},
{0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE},
{0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC},
{0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC}
};
 
uint8_t gost_key[] = {
0x04, 0x75, 0xF6, 0xE0, 0x50, 0x38, 0xFB, 0xFA,
0xD2, 0xC7, 0xC3, 0x90, 0xED, 0xB3, 0xCA, 0x3D,
0x15, 0x47, 0x12, 0x42, 0x91, 0xAE, 0x1E, 0x8A,
0x2F, 0x79, 0xCD, 0x9E, 0xD2, 0xBC, 0xEF, 0xBD
};
 
void print8bytes(const uint8_t* data) {
for (int i = 0; i < 8; ++i)
printf("%02x", data[i]);
}
 
void printNblocks(const uint8_t* data, size_t blocks) {
while (blocks--) {
print8bytes(&data[0]);
printf(" ");
data += 8;
}
}
 
int main(int argc, char **argv) {
int i;
 
printf("SBox: 512'h ");
for(i = 0; i < 16; i+=2) printf("%02x", (gost_sbox.k1[i]<<4) | gost_sbox.k1[i+1]);
for(i = 0; i < 16; i+=2) printf("%02x", (gost_sbox.k2[i]<<4) | gost_sbox.k2[i+1]);
for(i = 0; i < 16; i+=2) printf("%02x", (gost_sbox.k3[i]<<4) | gost_sbox.k3[i+1]);
for(i = 0; i < 16; i+=2) printf("%02x", (gost_sbox.k4[i]<<4) | gost_sbox.k4[i+1]);
for(i = 0; i < 16; i+=2) printf("%02x", (gost_sbox.k5[i]<<4) | gost_sbox.k5[i+1]);
for(i = 0; i < 16; i+=2) printf("%02x", (gost_sbox.k6[i]<<4) | gost_sbox.k6[i+1]);
for(i = 0; i < 16; i+=2) printf("%02x", (gost_sbox.k7[i]<<4) | gost_sbox.k7[i+1]);
for(i = 0; i < 16; i+=2) printf("%02x", (gost_sbox.k8[i]<<4) | gost_sbox.k8[i+1]);
printf("\n\n");
 
printf("Key: 256'h ");
for (i = 0; i < 32; ++i)
printf("%02x", gost_key[i]);
printf("\n\n");
 
gost_ctx ctx;
gost_init(&ctx, &gost_sbox);
gost_set_key(&ctx, &gost_key[0]);
 
uint8_t gamma[8];
RAND_bytes(gamma, sizeof(gamma));
 
uint8_t in[24];
RAND_bytes(in, sizeof(in));
uint8_t out1[sizeof(in)];
uint8_t out2[sizeof(in)];
 
/* ECB mode */
printf("ECB mode:\n");
printNblocks(&in[0], sizeof(in)/8); printf("\n");
gost_ecb_encrypt(&ctx, &in[0], &out1[0], sizeof(in)/8);
printNblocks(&out1[0], sizeof(in)/8); printf("\n");
gost_ecb_decrypt(&ctx, &out1[0], &out2[0], sizeof(in)/8);
printNblocks(&out2[0], sizeof(in)/8); printf("\n");
if (memcmp((const void*) &in[0], (const void*) &out2[0], sizeof(in)))
printf("error!\n");
printf("\n");
 
/* CFB mode */
printf("CFB mode (gamma: "); print8bytes(&gamma[0]); printf("):\n");
printNblocks(&in[0], sizeof(in)/8); printf("\n");
gost_cfb_encrypt(&ctx, &gamma[0], &in[0], &out1[0], sizeof(in)/8);
printNblocks(&out1[0], sizeof(in)/8); printf("\n");
gost_cfb_decrypt(&ctx, &gamma[0], &out1[0], &out2[0], sizeof(in)/8);
printNblocks(&out2[0], sizeof(in)/8); printf("\n");
if (memcmp((const void*) &in[0], (const void*) &out2[0], sizeof(in)))
printf("error!\n");
printf("\n");
 
/* MAC mode */
printf("MAC mode (length: 32bit): \n");
printNblocks(&in[0], sizeof(in)/8); printf("\n");
memset((void*) &out1[0], 0, 8);
gost_mac(&ctx, &in[0], sizeof(in), &out1[0], 32);
print8bytes(&out1[0]); printf("\n\n");
 
return 0;
}
/trunk/utils/benchmark.c
0,0 → 1,76
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <math.h>
 
#include <sys/time.h>
 
#include <openssl/rand.h>
 
#include "gost89.h"
 
#define TEST_SIZE 80*1024*1024
 
 
gost_subst_block gost_sbox = {
{0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3},
{0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9},
{0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB},
{0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3},
{0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2},
{0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE},
{0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC},
{0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC}
};
 
uint8_t gost_key[] = {
0x04, 0x75, 0xF6, 0xE0, 0x50, 0x38, 0xFB, 0xFA,
0xD2, 0xC7, 0xC3, 0x90, 0xED, 0xB3, 0xCA, 0x3D,
0x15, 0x47, 0x12, 0x42, 0x91, 0xAE, 0x1E, 0x8A,
0x2F, 0x79, 0xCD, 0x9E, 0xD2, 0xBC, 0xEF, 0xBD
};
 
double delta(struct timeval* t1, struct timeval* t2) {
return (t2->tv_sec - t1->tv_sec) + (double) (t2->tv_usec - t1->tv_usec)/1000000;
}
 
int main(int argc, char **argv) {
uint8_t gamma[8];
uint8_t *in, *out;
struct timeval t1, t2;
 
gost_ctx ctx;
gost_init(&ctx, &gost_sbox);
gost_set_key(&ctx, &gost_key[0]);
 
RAND_bytes(gamma, sizeof(gamma));
 
in = (uint8_t*) malloc(TEST_SIZE);
assert(in != NULL);
out = (uint8_t*) malloc(TEST_SIZE);
assert(in != NULL);
printf("TEST_SIZE: %d bytes\n", TEST_SIZE);
 
gettimeofday(&t1, NULL);
RAND_bytes(in, TEST_SIZE);
gettimeofday(&t2, NULL);
printf("RAND_bytes: %.6lf seconds, %.6lf bytes/s\n", delta(&t1, &t2), TEST_SIZE/delta(&t1, &t2));
 
gettimeofday(&t1, NULL);
gost_ecb_encrypt(&ctx, &in[0], &out[0], TEST_SIZE/8);
gettimeofday(&t2, NULL);
printf("ECB mode: %.6lf seconds, %.6lf bytes/s\n", delta(&t1, &t2), TEST_SIZE/delta(&t1, &t2));
 
gettimeofday(&t1, NULL);
gost_cfb_encrypt(&ctx, &gamma[0], &in[0], &out[0], TEST_SIZE/8);
gettimeofday(&t2, NULL);
printf("CFB mode: %.6lf seconds, %.6lf bytes/s\n", delta(&t1, &t2), TEST_SIZE/delta(&t1, &t2));
 
gettimeofday(&t1, NULL);
gost_mac(&ctx, &in[0], TEST_SIZE, &out[0], 20);
gettimeofday(&t2, NULL);
printf("MAC mode: %.6lf seconds, %.6lf bytes/s\n", delta(&t1, &t2), TEST_SIZE/delta(&t1, &t2));
 
return 0;
}
/trunk/utils/makefile
0,0 → 1,22
CC = gcc
CFLAGS =
DEFS = -std=c11 -Wall -O2
LIBS = -lssl -lcrypto
DEPS = gost89.h
 
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(DEFS) $(CFLAGS)
 
benchmark: benchmark.o gost89.o
$(CC) -o $@ $^ $(DEFS) $(CFLAGS) $(LIBS)
 
generator: generator.o gost89.o
$(CC) -o $@ $^ $(DEFS) $(CFLAGS) $(LIBS)
 
all: benchmark generator
 
clean:
rm -f *.o benchmark generator
 
.DEFAULT_GOAL := all
 
/trunk/utils/gost89.c
0,0 → 1,222
#include <assert.h>
#include <string.h>
 
#include "gost89.h"
 
 
// Substitution blocks from RFC 4357, item 11.2
gost_subst_block GOST28147_89_RFC = {
{0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0x3},
{0xE,0xB,0x4,0xC,0x6,0xD,0xF,0xA,0x2,0x3,0x8,0x1,0x0,0x7,0x5,0x9},
{0x5,0x8,0x1,0xD,0xA,0x3,0x4,0x2,0xE,0xF,0xC,0x7,0x6,0x0,0x9,0xB},
{0x7,0xD,0xA,0x1,0x0,0x8,0x9,0xF,0xE,0x4,0x6,0xC,0xB,0x2,0x5,0x3},
{0x6,0xC,0x7,0x1,0x5,0xF,0xD,0x8,0x4,0xA,0x9,0xE,0x0,0x3,0xB,0x2},
{0x4,0xB,0xA,0x0,0x7,0x2,0x1,0xD,0x3,0x6,0x8,0x5,0x9,0xC,0xF,0xE},
{0xD,0xB,0x4,0x1,0x3,0xF,0x5,0x9,0x0,0xA,0xE,0x7,0x6,0x8,0x2,0xC},
{0x1,0xF,0xD,0x0,0x5,0x7,0xA,0x4,0x9,0x2,0x3,0xE,0x6,0xB,0x8,0xC}
};
 
 
void gost_init(gost_ctx *c, const gost_subst_block* b) {
int i;
 
if (!b)
b = &GOST28147_89_RFC;
 
for (i = 0; i < 256; ++i) {
c->k21[i] = (b->k2[i>>4]<<4 | b->k1 [i&15]);
c->k43[i] = (b->k4[i>>4]<<4 | b->k3 [i&15])<<8;
c->k65[i] = (b->k6[i>>4]<<4 | b->k5 [i&15])<<16;
c->k87[i] = (b->k8[i>>4]<<4 | b->k7 [i&15])<<24;
}
}
 
void gost_destroy(gost_ctx *c) {
int i;
 
for (i = 0; i < 8; ++i)
c->k[i] = 0;
for (i = 0; i < 256; ++i)
c->k87[i] = c->k65[i] = c->k43[i] = c->k21[i] = 0;
}
 
void gost_set_key(gost_ctx *c, const uint8_t *k) {
int i, j;
for (i=0, j=0; i < 8; i+=1, j+=4)
c->k[i] = (k[j]<<24) | (k[j+1]<<16) | (k[j+2]<<8) | k[j+3];
}
 
void gost_get_key(gost_ctx *c, uint8_t *k) {
int i, j;
 
for (i=0, j=0; i < 8; i+=1, j+=4) {
k[j] = (uint8_t) ((c->k[i] ) &0xFF);
k[j+1] = (uint8_t) ((c->k[i]>>8 ) &0xFF);
k[j+2] = (uint8_t) ((c->k[i]>>16) &0xFF);
k[j+3] = (uint8_t) ((c->k[i]>>24) &0xFF);
}
}
 
inline uint32_t f(gost_ctx *c, uint32_t x) {
x = c->k87[x>>24 & 255] | c->k65[x>>16 & 255] |
c->k43[x>> 8 & 255] | c->k21[x & 255];
return x<<11 | x>>(32-11);
}
 
inline void gost_encrypt_block(gost_ctx *c, const uint8_t *in, uint8_t *out) {
register uint32_t n1, n2;
n1 = (in[0]<<24) | (in[1]<<16) | (in[2]<<8) | in[3];
n2 = (in[4]<<24) | (in[5]<<16) | (in[6]<<8) | in[7];
 
n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
 
out[0] = (uint8_t) (n2>>24); out[1] = (uint8_t) ((n2>>16)&0xff);
out[2] = (uint8_t) ((n2>>8)&0xff); out[3] = (uint8_t) (n2&0xff);
out[4] = (uint8_t) (n1>>24); out[5] = (uint8_t) ((n1>>16)&0xff);
out[6] = (uint8_t) ((n1>>8)&0xff); out[7] = (uint8_t) (n1&0xff);
}
 
inline void gost_decrypt_block(gost_ctx *c, const uint8_t *in, uint8_t *out) {
register uint32_t n1, n2;
n1 = (in[0]<<24) | (in[1]<<16) | (in[2]<<8) | in[3];
n2 = (in[4]<<24) | (in[5]<<16) | (in[6]<<8) | in[7];
 
n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
 
n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
n2 ^= f(c,n1+c->k[7]); n1 ^= f(c,n2+c->k[6]);
n2 ^= f(c,n1+c->k[5]); n1 ^= f(c,n2+c->k[4]);
n2 ^= f(c,n1+c->k[3]); n1 ^= f(c,n2+c->k[2]);
n2 ^= f(c,n1+c->k[1]); n1 ^= f(c,n2+c->k[0]);
 
out[0] = (uint8_t) (n2>>24); out[1] = (uint8_t) ((n2>>16)&0xff);
out[2] = (uint8_t) ((n2>>8)&0xff); out[3] = (uint8_t) (n2&0xff);
out[4] = (uint8_t) (n1>>24); out[5] = (uint8_t) ((n1>>16)&0xff);
out[6] = (uint8_t) ((n1>>8)&0xff); out[7] = (uint8_t) (n1&0xff);
}
 
void gost_ecb_encrypt(gost_ctx *ctx, const uint8_t *in, uint8_t *out, size_t blocks) {
while (blocks--) {
gost_encrypt_block(ctx, in, out);
in += 8;
out += 8;
}
}
 
void gost_ecb_decrypt(gost_ctx *ctx, const uint8_t *in, uint8_t *out, size_t blocks) {
while (blocks--) {
gost_decrypt_block(ctx, in, out);
in += 8;
out += 8;
}
}
 
void gost_cfb_encrypt(gost_ctx *ctx, const uint8_t *iv, const uint8_t *in, uint8_t *out, size_t blocks) {
uint8_t cur_iv[8], gamma[8];
memcpy((void*) &cur_iv[0], (const void*) &iv[0], 8);
while (blocks--) {
gost_encrypt_block(ctx, cur_iv, gamma);
for (int i = 0; i < 8; ++i) {
out[i] = in[i] ^ gamma[i];
cur_iv[i] = out[i];
}
in += 8;
out += 8;
}
}
 
void gost_cfb_decrypt(gost_ctx *ctx, const uint8_t *iv, const uint8_t *in, uint8_t *out, size_t blocks) {
uint8_t cur_iv[8], gamma[8];
memcpy((void*) &cur_iv[0], (const void*) &iv[0], 8);
while (blocks--) {
gost_encrypt_block(ctx, cur_iv, gamma);
for (int i = 0; i < 8; ++i) {
out[i] = in[i] ^ gamma[i];
cur_iv[i] = in[i];
}
in += 8;
out += 8;
}
}
 
inline void gost_mac_block(gost_ctx *c, const uint8_t *in, uint8_t *out) {
register uint32_t n1, n2;
n1 = (in[0]<<24) | (in[1]<<16) | (in[2]<<8) | in[3];
n2 = (in[4]<<24) | (in[5]<<16) | (in[6]<<8) | in[7];
 
n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
n2 ^= f(c,n1+c->k[0]); n1 ^= f(c,n2+c->k[1]);
n2 ^= f(c,n1+c->k[2]); n1 ^= f(c,n2+c->k[3]);
n2 ^= f(c,n1+c->k[4]); n1 ^= f(c,n2+c->k[5]);
n2 ^= f(c,n1+c->k[6]); n1 ^= f(c,n2+c->k[7]);
 
out[0] = (uint8_t) (n2>>24); out[1] = (uint8_t) ((n2>>16)&0xff);
out[2] = (uint8_t) ((n2>>8)&0xff); out[3] = (uint8_t) (n2&0xff);
out[4] = (uint8_t) (n1>>24); out[5] = (uint8_t) ((n1>>16)&0xff);
out[6] = (uint8_t) ((n1>>8)&0xff); out[7] = (uint8_t) (n1&0xff);
}
 
void gost_mac(gost_ctx *ctx, const uint8_t *data, size_t data_len, uint8_t *mac, const size_t mac_len) {
assert(data_len >= 16);
assert(mac_len <= 32);
 
uint8_t out[8] = {0};
 
while (data_len > 0) {
uint8_t in[8] = {0};
memcpy((void*) &in[0], (const void*) &data[0], data_len < 8 ? data_len : 8);
 
for (int i = 0; i < 8; ++i)
in[i] = in[i] ^ out[i];
gost_mac_block(ctx, in, &out[0]);
 
data_len -= 8;
data += 8;
}
 
uint8_t nbytes = (mac_len>>3) + ((mac_len&7) > 0 ? 1 : 0);
memset((void*) mac, 0, nbytes);
 
 
uint32_t fmac = (out[0]<<24) | (out[1]<<16) | (out[2]<<8) | out[3];
fmac <<= 32 - mac_len;
out[0] = (uint8_t) (fmac>>24); out[1] = (uint8_t) ((fmac>>16)&0xff);
out[2] = (uint8_t) ((fmac>>8)&0xff); out[3] = (uint8_t) (fmac&0xff);
 
for (int i = 0; i < nbytes; ++i)
mac[i] = out[i];
}
/trunk/rtl/gost89_mac.v
0,0 → 1,81
module gost89_mac(
input clk,
input reset,
input load_data,
input [511:0] sbox,
input [255:0] key,
input [63:0] in,
output reg [31:0] out,
output reg busy
);
reg [4:0] counter;
reg [31:0] round_key;
reg need_xor;
reg [31:0] n1, n2;
wire [31:0] out1, out2;
 
gost89_round
rnd(clk, sbox, round_key, n1, n2, out1, out2);
 
always @(posedge clk) begin
if (reset && !load_data) begin
counter <= 17;
need_xor <= 0;
busy <= 0;
end
 
if (!reset && load_data) begin
if (need_xor) begin
n1 <= in[63:32] ^ n2;
n2 <= in[31:0] ^ n1;
end else begin
n1 <= in[63:32];
n2 <= in[31:0];
need_xor <= 1;
end
counter <= 0;
busy <= 1;
end
 
if (reset && load_data) begin
n1 <= in[63:32];
n2 <= in[31:0];
counter <= 0;
need_xor <= 1;
busy <= 1;
end
 
if (!reset && !load_data) begin
if (counter < 17)
counter <= counter + 1;
if (counter > 0 && counter < 17) begin
n1 <= out1;
n2 <= out2;
end
if (counter == 16) begin
busy <= 0;
out <= out2;
end
end
end
 
always @(posedge clk)
case (counter)
0: round_key <= key[255:224];
1: round_key <= key[223:192];
2: round_key <= key[191:160];
3: round_key <= key[159:128];
4: round_key <= key[127:96];
5: round_key <= key[95:64];
6: round_key <= key[63:32];
7: round_key <= key[31:0];
8: round_key <= key[255:224];
9: round_key <= key[223:192];
10: round_key <= key[191:160];
11: round_key <= key[159:128];
12: round_key <= key[127:96];
13: round_key <= key[95:64];
14: round_key <= key[63:32];
15: round_key <= key[31:0];
endcase
endmodule
/trunk/rtl/gost89_pipelined_ecb.v
0,0 → 1,165
module gost89_pipelined_ecb_encrypt(
input clk,
input [511:0] sbox,
input [255:0] key,
input [63:0] in,
output [63:0] out
);
reg [31:0] n1[31:0], n2[31:0];
wire [31:0] out1[31:0], out2[31:0];
 
always @(posedge clk) begin
n1[0] <= in[63:32]; n2[0] <= in[31:0];
n1[1] <= out1[0]; n2[1] <= out2[0];
n1[2] <= out1[1]; n2[2] <= out2[1];
n1[3] <= out1[2]; n2[3] <= out2[2];
n1[4] <= out1[3]; n2[4] <= out2[3];
n1[5] <= out1[4]; n2[5] <= out2[4];
n1[6] <= out1[5]; n2[6] <= out2[5];
n1[7] <= out1[6]; n2[7] <= out2[6];
n1[8] <= out1[7]; n2[8] <= out2[7];
n1[9] <= out1[8]; n2[9] <= out2[8];
n1[10] <= out1[9]; n2[10] <= out2[9];
n1[11] <= out1[10]; n2[11] <= out2[10];
n1[12] <= out1[11]; n2[12] <= out2[11];
n1[13] <= out1[12]; n2[13] <= out2[12];
n1[14] <= out1[13]; n2[14] <= out2[13];
n1[15] <= out1[14]; n2[15] <= out2[14];
n1[16] <= out1[15]; n2[16] <= out2[15];
n1[17] <= out1[16]; n2[17] <= out2[16];
n1[18] <= out1[17]; n2[18] <= out2[17];
n1[19] <= out1[18]; n2[19] <= out2[18];
n1[20] <= out1[19]; n2[20] <= out2[19];
n1[21] <= out1[20]; n2[21] <= out2[20];
n1[22] <= out1[21]; n2[22] <= out2[21];
n1[23] <= out1[22]; n2[23] <= out2[22];
n1[24] <= out1[23]; n2[24] <= out2[23];
n1[25] <= out1[24]; n2[25] <= out2[24];
n1[26] <= out1[25]; n2[26] <= out2[25];
n1[27] <= out1[26]; n2[27] <= out2[26];
n1[28] <= out1[27]; n2[28] <= out2[27];
n1[29] <= out1[28]; n2[29] <= out2[28];
n1[30] <= out1[29]; n2[30] <= out2[29];
n1[31] <= out1[30]; n2[31] <= out2[30];
end
 
gost89_round
r1 (clk, sbox, key[255:224], n1[0], n2[0], out1[0], out2[0]),
r2 (clk, sbox, key[223:192], n1[1], n2[1], out1[1], out2[1]),
r3 (clk, sbox, key[191:160], n1[2], n2[2], out1[2], out2[2]),
r4 (clk, sbox, key[159:128], n1[3], n2[3], out1[3], out2[3]),
r5 (clk, sbox, key[127:96], n1[4], n2[4], out1[4], out2[4]),
r6 (clk, sbox, key[95:64], n1[5], n2[5], out1[5], out2[5]),
r7 (clk, sbox, key[63:32], n1[6], n2[6], out1[6], out2[6]),
r8 (clk, sbox, key[31:0], n1[7], n2[7], out1[7], out2[7]),
r9 (clk, sbox, key[255:224], n1[8], n2[8], out1[8], out2[8]),
r10(clk, sbox, key[223:192], n1[9], n2[9], out1[9], out2[9]),
r11(clk, sbox, key[191:160], n1[10], n2[10], out1[10], out2[10]),
r12(clk, sbox, key[159:128], n1[11], n2[11], out1[11], out2[11]),
r13(clk, sbox, key[127:96], n1[12], n2[12], out1[12], out2[12]),
r14(clk, sbox, key[95:64], n1[13], n2[13], out1[13], out2[13]),
r15(clk, sbox, key[63:32], n1[14], n2[14], out1[14], out2[14]),
r16(clk, sbox, key[31:0], n1[15], n2[15], out1[15], out2[15]),
r17(clk, sbox, key[255:224], n1[16], n2[16], out1[16], out2[16]),
r18(clk, sbox, key[223:192], n1[17], n2[17], out1[17], out2[17]),
r19(clk, sbox, key[191:160], n1[18], n2[18], out1[18], out2[18]),
r20(clk, sbox, key[159:128], n1[19], n2[19], out1[19], out2[19]),
r21(clk, sbox, key[127:96], n1[20], n2[20], out1[20], out2[20]),
r22(clk, sbox, key[95:64], n1[21], n2[21], out1[21], out2[21]),
r23(clk, sbox, key[63:32], n1[22], n2[22], out1[22], out2[22]),
r24(clk, sbox, key[31:0], n1[23], n2[23], out1[23], out2[23]),
r25(clk, sbox, key[31:0], n1[24], n2[24], out1[24], out2[24]),
r26(clk, sbox, key[63:32], n1[25], n2[25], out1[25], out2[25]),
r27(clk, sbox, key[95:64], n1[26], n2[26], out1[26], out2[26]),
r28(clk, sbox, key[127:96], n1[27], n2[27], out1[27], out2[27]),
r29(clk, sbox, key[159:128], n1[28], n2[28], out1[28], out2[28]),
r30(clk, sbox, key[191:160], n1[29], n2[29], out1[29], out2[29]),
r31(clk, sbox, key[223:192], n1[30], n2[30], out1[30], out2[30]),
r32(clk, sbox, key[255:224], n1[31], n2[31], out1[31], out2[31]);
 
assign out[31:0] = out1[31];
assign out[63:32] = out2[31];
endmodule
 
module gost89_pipelined_ecb_decrypt(
input clk,
input [511:0] sbox,
input [255:0] key,
input [63:0] in,
output [63:0] out
);
reg [31:0] n1[31:0], n2[31:0];
wire [31:0] out1[31:0], out2[31:0];
 
always @(posedge clk) begin
n1[0] <= in[63:32]; n2[0] <= in[31:0];
n1[1] <= out1[0]; n2[1] <= out2[0];
n1[2] <= out1[1]; n2[2] <= out2[1];
n1[3] <= out1[2]; n2[3] <= out2[2];
n1[4] <= out1[3]; n2[4] <= out2[3];
n1[5] <= out1[4]; n2[5] <= out2[4];
n1[6] <= out1[5]; n2[6] <= out2[5];
n1[7] <= out1[6]; n2[7] <= out2[6];
n1[8] <= out1[7]; n2[8] <= out2[7];
n1[9] <= out1[8]; n2[9] <= out2[8];
n1[10] <= out1[9]; n2[10] <= out2[9];
n1[11] <= out1[10]; n2[11] <= out2[10];
n1[12] <= out1[11]; n2[12] <= out2[11];
n1[13] <= out1[12]; n2[13] <= out2[12];
n1[14] <= out1[13]; n2[14] <= out2[13];
n1[15] <= out1[14]; n2[15] <= out2[14];
n1[16] <= out1[15]; n2[16] <= out2[15];
n1[17] <= out1[16]; n2[17] <= out2[16];
n1[18] <= out1[17]; n2[18] <= out2[17];
n1[19] <= out1[18]; n2[19] <= out2[18];
n1[20] <= out1[19]; n2[20] <= out2[19];
n1[21] <= out1[20]; n2[21] <= out2[20];
n1[22] <= out1[21]; n2[22] <= out2[21];
n1[23] <= out1[22]; n2[23] <= out2[22];
n1[24] <= out1[23]; n2[24] <= out2[23];
n1[25] <= out1[24]; n2[25] <= out2[24];
n1[26] <= out1[25]; n2[26] <= out2[25];
n1[27] <= out1[26]; n2[27] <= out2[26];
n1[28] <= out1[27]; n2[28] <= out2[27];
n1[29] <= out1[28]; n2[29] <= out2[28];
n1[30] <= out1[29]; n2[30] <= out2[29];
n1[31] <= out1[30]; n2[31] <= out2[30];
end
 
gost89_round
r1 (clk, sbox, key[255:224], n1[0], n2[0], out1[0], out2[0]),
r2 (clk, sbox, key[223:192], n1[1], n2[1], out1[1], out2[1]),
r3 (clk, sbox, key[191:160], n1[2], n2[2], out1[2], out2[2]),
r4 (clk, sbox, key[159:128], n1[3], n2[3], out1[3], out2[3]),
r5 (clk, sbox, key[127:96], n1[4], n2[4], out1[4], out2[4]),
r6 (clk, sbox, key[95:64], n1[5], n2[5], out1[5], out2[5]),
r7 (clk, sbox, key[63:32], n1[6], n2[6], out1[6], out2[6]),
r8 (clk, sbox, key[31:0], n1[7], n2[7], out1[7], out2[7]),
r9 (clk, sbox, key[31:0], n1[8], n2[8], out1[8], out2[8]),
r10(clk, sbox, key[63:32], n1[9], n2[9], out1[9], out2[9]),
r11(clk, sbox, key[95:64], n1[10], n2[10], out1[10], out2[10]),
r12(clk, sbox, key[127:96], n1[11], n2[11], out1[11], out2[11]),
r13(clk, sbox, key[159:128], n1[12], n2[12], out1[12], out2[12]),
r14(clk, sbox, key[191:160], n1[13], n2[13], out1[13], out2[13]),
r15(clk, sbox, key[223:192], n1[14], n2[14], out1[14], out2[14]),
r16(clk, sbox, key[255:224], n1[15], n2[15], out1[15], out2[15]),
r17(clk, sbox, key[31:0], n1[16], n2[16], out1[16], out2[16]),
r18(clk, sbox, key[63:32], n1[17], n2[17], out1[17], out2[17]),
r19(clk, sbox, key[95:64], n1[18], n2[18], out1[18], out2[18]),
r20(clk, sbox, key[127:96], n1[19], n2[19], out1[19], out2[19]),
r21(clk, sbox, key[159:128], n1[20], n2[20], out1[20], out2[20]),
r22(clk, sbox, key[191:160], n1[21], n2[21], out1[21], out2[21]),
r23(clk, sbox, key[223:192], n1[22], n2[22], out1[22], out2[22]),
r24(clk, sbox, key[255:224], n1[23], n2[23], out1[23], out2[23]),
r25(clk, sbox, key[31:0], n1[24], n2[24], out1[24], out2[24]),
r26(clk, sbox, key[63:32], n1[25], n2[25], out1[25], out2[25]),
r27(clk, sbox, key[95:64], n1[26], n2[26], out1[26], out2[26]),
r28(clk, sbox, key[127:96], n1[27], n2[27], out1[27], out2[27]),
r29(clk, sbox, key[159:128], n1[28], n2[28], out1[28], out2[28]),
r30(clk, sbox, key[191:160], n1[29], n2[29], out1[29], out2[29]),
r31(clk, sbox, key[223:192], n1[30], n2[30], out1[30], out2[30]),
r32(clk, sbox, key[255:224], n1[31], n2[31], out1[31], out2[31]);
 
assign out[31:0] = out1[31];
assign out[63:32] = out2[31];
endmodule
/trunk/rtl/gost89_round.v
0,0 → 1,28
module gost89_round(
input clk,
input [511:0] sbox,
input [31:0] key,
input [31:0] n1,
input [31:0] n2,
output [31:0] out1,
output [31:0] out2
);
wire [31:0] tmp1, tmp2;
 
assign tmp1 = n1 + key;
 
gost89_sbox
sbox1(sbox[511:448], tmp1[3:0], tmp2[3:0]),
sbox2(sbox[447:384], tmp1[7:4], tmp2[7:4]),
sbox3(sbox[383:320], tmp1[11:8], tmp2[11:8]),
sbox4(sbox[319:256], tmp1[15:12], tmp2[15:12]),
sbox5(sbox[255:192], tmp1[19:16], tmp2[19:16]),
sbox6(sbox[191:128], tmp1[23:20], tmp2[23:20]),
sbox7(sbox[127:64], tmp1[27:24], tmp2[27:24]),
sbox8(sbox[63 :0], tmp1[31:28], tmp2[31:28]);
 
assign out1[10:0] = tmp2[31:21] ^ n2[10:0];
assign out1[31:11] = tmp2[20:0] ^ n2[31:11];
 
assign out2 = n1;
endmodule
/trunk/rtl/gost89_ecb.v
0,0 → 1,288
module gost89_ecb(
input clk,
input reset,
input mode,
input load_data,
input [511:0] sbox,
input [255:0] key,
input [63:0] in,
output reg [63:0] out,
output reg busy
);
reg [5:0] round_num;
reg [31:0] n1, n2, round_key;
wire [31:0] out1, out2;
 
gost89_round
rnd(clk, sbox, round_key, n1, n2, out1, out2);
 
always @(posedge clk) begin
if (load_data) begin
n1 <= in[63:32];
n2 <= in[31:0];
busy <= 1;
round_num <= 0;
end
 
if (reset && !load_data) begin
busy <= 0;
round_num <= 32;
end
 
if (!reset && !load_data) begin
if (round_num < 32)
round_num <= round_num + 1;
if (round_num > 0 && round_num < 32) begin
n1 <= out1;
n2 <= out2;
end
if (round_num == 32) begin
out[63:32] <= out2;
out[31:0] <= out1;
busy <= 0;
end
end
end
 
always @(posedge clk) begin
if (mode)
case (round_num)
0: round_key <= key[255:224];
1: round_key <= key[223:192];
2: round_key <= key[191:160];
3: round_key <= key[159:128];
4: round_key <= key[127:96];
5: round_key <= key[95:64];
6: round_key <= key[63:32];
7: round_key <= key[31:0];
8: round_key <= key[31:0];
9: round_key <= key[63:32];
10: round_key <= key[95:64];
11: round_key <= key[127:96];
12: round_key <= key[159:128];
13: round_key <= key[191:160];
14: round_key <= key[223:192];
15: round_key <= key[255:224];
16: round_key <= key[31:0];
17: round_key <= key[63:32];
18: round_key <= key[95:64];
19: round_key <= key[127:96];
20: round_key <= key[159:128];
21: round_key <= key[191:160];
22: round_key <= key[223:192];
23: round_key <= key[255:224];
24: round_key <= key[31:0];
25: round_key <= key[63:32];
26: round_key <= key[95:64];
27: round_key <= key[127:96];
28: round_key <= key[159:128];
29: round_key <= key[191:160];
30: round_key <= key[223:192];
31: round_key <= key[255:224];
endcase
else
case (round_num)
0: round_key <= key[255:224];
1: round_key <= key[223:192];
2: round_key <= key[191:160];
3: round_key <= key[159:128];
4: round_key <= key[127:96];
5: round_key <= key[95:64];
6: round_key <= key[63:32];
7: round_key <= key[31:0];
8: round_key <= key[255:224];
9: round_key <= key[223:192];
10: round_key <= key[191:160];
11: round_key <= key[159:128];
12: round_key <= key[127:96];
13: round_key <= key[95:64];
14: round_key <= key[63:32];
15: round_key <= key[31:0];
16: round_key <= key[255:224];
17: round_key <= key[223:192];
18: round_key <= key[191:160];
19: round_key <= key[159:128];
20: round_key <= key[127:96];
21: round_key <= key[95:64];
22: round_key <= key[63:32];
23: round_key <= key[31:0];
24: round_key <= key[31:0];
25: round_key <= key[63:32];
26: round_key <= key[95:64];
27: round_key <= key[127:96];
28: round_key <= key[159:128];
29: round_key <= key[191:160];
30: round_key <= key[223:192];
31: round_key <= key[255:224];
endcase
end
endmodule
 
module gost89_ecb_encrypt(
input clk,
input reset,
input load_data,
input [511:0] sbox,
input [255:0] key,
input [63:0] in,
output reg [63:0] out,
output reg busy
);
reg [5:0] round_num;
reg [31:0] n1, n2, round_key;
wire [31:0] out1, out2;
 
gost89_round
rnd(clk, sbox, round_key, n1, n2, out1, out2);
 
always @(posedge clk) begin
if (load_data) begin
n1 <= in[63:32];
n2 <= in[31:0];
busy <= 1;
round_num <= 0;
end
 
if (reset && !load_data) begin
busy <= 0;
round_num <= 32;
end
 
if (!reset && !load_data) begin
if (round_num < 32)
round_num <= round_num + 1;
if (round_num > 0 && round_num < 32) begin
n1 <= out1;
n2 <= out2;
end
if (round_num == 32) begin
out[63:32] <= out2;
out[31:0] <= out1;
busy <= 0;
end
end
end
 
always @(posedge clk)
case (round_num)
0: round_key <= key[255:224];
1: round_key <= key[223:192];
2: round_key <= key[191:160];
3: round_key <= key[159:128];
4: round_key <= key[127:96];
5: round_key <= key[95:64];
6: round_key <= key[63:32];
7: round_key <= key[31:0];
8: round_key <= key[255:224];
9: round_key <= key[223:192];
10: round_key <= key[191:160];
11: round_key <= key[159:128];
12: round_key <= key[127:96];
13: round_key <= key[95:64];
14: round_key <= key[63:32];
15: round_key <= key[31:0];
16: round_key <= key[255:224];
17: round_key <= key[223:192];
18: round_key <= key[191:160];
19: round_key <= key[159:128];
20: round_key <= key[127:96];
21: round_key <= key[95:64];
22: round_key <= key[63:32];
23: round_key <= key[31:0];
24: round_key <= key[31:0];
25: round_key <= key[63:32];
26: round_key <= key[95:64];
27: round_key <= key[127:96];
28: round_key <= key[159:128];
29: round_key <= key[191:160];
30: round_key <= key[223:192];
31: round_key <= key[255:224];
endcase
endmodule
 
module gost89_ecb_decrypt(
input clk,
input reset,
input load_data,
input [511:0] sbox,
input [255:0] key,
input [63:0] in,
output reg [63:0] out,
output reg busy
);
reg [5:0] round_num;
reg [31:0] n1, n2, round_key;
wire [31:0] out1, out2;
 
gost89_round
rnd(clk, sbox, round_key, n1, n2, out1, out2);
 
initial begin
busy = 0;
round_num = 32;
end
 
always @(posedge clk) begin
if (load_data) begin
n1 <= in[63:32];
n2 <= in[31:0];
busy <= 1;
round_num <= 0;
end
 
if (reset && !load_data) begin
busy <= 0;
round_num <= 32;
end
 
if (!reset && !load_data) begin
if (round_num < 32)
round_num <= round_num + 1;
if (round_num > 0 && round_num < 32) begin
n1 <= out1;
n2 <= out2;
end
if (round_num == 32) begin
out[63:32] = out2;
out[31:0] = out1;
busy <= 0;
end
end
end
 
always @(posedge clk)
case (round_num)
0: round_key <= key[255:224];
1: round_key <= key[223:192];
2: round_key <= key[191:160];
3: round_key <= key[159:128];
4: round_key <= key[127:96];
5: round_key <= key[95:64];
6: round_key <= key[63:32];
7: round_key <= key[31:0];
8: round_key <= key[31:0];
9: round_key <= key[63:32];
10: round_key <= key[95:64];
11: round_key <= key[127:96];
12: round_key <= key[159:128];
13: round_key <= key[191:160];
14: round_key <= key[223:192];
15: round_key <= key[255:224];
16: round_key <= key[31:0];
17: round_key <= key[63:32];
18: round_key <= key[95:64];
19: round_key <= key[127:96];
20: round_key <= key[159:128];
21: round_key <= key[191:160];
22: round_key <= key[223:192];
23: round_key <= key[255:224];
24: round_key <= key[31:0];
25: round_key <= key[63:32];
26: round_key <= key[95:64];
27: round_key <= key[127:96];
28: round_key <= key[159:128];
29: round_key <= key[191:160];
30: round_key <= key[223:192];
31: round_key <= key[255:224];
endcase
endmodule
/trunk/rtl/gost89_cfb.v
0,0 → 1,121
module gost89_cfb(
input clk,
input reset,
input mode,
input load_data,
input [511:0] sbox,
input [255:0] key,
input [63:0] in,
output reg [63:0] out,
output reg busy
);
reg [63:0] gamma;
reg [63:0] in_value;
wire [63:0] out_ecb;
wire reset_ecb, load_ecb, busy_ecb;
 
assign load_ecb = !reset && load_data;
assign reset_ecb = load_ecb;
 
gost89_ecb_encrypt
ecb_encrypt(clk, reset_ecb, load_ecb, sbox, key, gamma, out_ecb, busy_ecb);
 
always @(posedge clk) begin
if (reset && !load_data) begin
gamma <= in;
busy <= 0;
end
 
if (!reset & load_data) begin
in_value <= in;
busy <= 1;
end
 
if (!reset && !load_data && !busy_ecb && busy) begin
if (mode) gamma <= in_value;
else gamma <= out_ecb ^ in_value;
out <= out_ecb ^ in_value;
busy <= 0;
end
end
endmodule
 
module gost89_cfb_encrypt(
input clk,
input reset,
input load_data,
input [511:0] sbox,
input [255:0] key,
input [63:0] in,
output reg [63:0] out,
output reg busy
);
reg [63:0] gamma;
reg [63:0] in_value;
wire [63:0] out_ecb;
wire load_ecb, busy_ecb;
 
assign load_ecb = !reset && load_data;
assign reset_ecb = load_ecb;
 
gost89_ecb_encrypt
ecb_encrypt(clk, reset_ecb, load_ecb, sbox, key, gamma, out_ecb, busy_ecb);
 
always @(posedge clk) begin
if (reset && !load_data) begin
gamma <= in;
busy <= 0;
end
 
if (!reset & load_data) begin
in_value <= in;
busy <= 1;
end
 
if (!reset && !load_data && !busy_ecb && busy) begin
gamma <= out_ecb ^ in_value;
out <= out_ecb ^ in_value;
busy <= 0;
end
end
endmodule
 
module gost89_cfb_decrypt(
input clk,
input reset,
input load_data,
input [511:0] sbox,
input [255:0] key,
input [63:0] in,
output reg [63:0] out,
output reg busy
);
reg [63:0] gamma;
reg [63:0] in_value;
wire [63:0] out_ecb;
wire load_ecb, busy_ecb;
 
assign load_ecb = !reset && load_data;
assign reset_ecb = load_ecb;
 
gost89_ecb_encrypt
ecb_encrypt(clk, reset_ecb, load_ecb, sbox, key, gamma, out_ecb, busy_ecb);
 
always @(posedge clk) begin
if (reset && !load_data) begin
gamma <= in;
busy <= 0;
end
 
if (!reset & load_data) begin
in_value <= in;
busy <= 1;
end
 
if (!reset && !load_data && !busy_ecb && busy) begin
gamma <= in_value;
out <= out_ecb ^ in_value;
busy <= 0;
end
end
endmodule
/trunk/rtl/gost89_sbox.v
0,0 → 1,25
module gost89_sbox(
input [63:0] sbox,
input [3:0] in,
output reg [3:0] out
);
always @(in or sbox)
case (in)
4'h0: out <= sbox[63:60];
4'h1: out <= sbox[59:56];
4'h2: out <= sbox[55:52];
4'h3: out <= sbox[51:48];
4'h4: out <= sbox[47:44];
4'h5: out <= sbox[43:40];
4'h6: out <= sbox[39:36];
4'h7: out <= sbox[35:32];
4'h8: out <= sbox[31:28];
4'h9: out <= sbox[27:24];
4'ha: out <= sbox[23:20];
4'hb: out <= sbox[19:16];
4'hc: out <= sbox[15:12];
4'hd: out <= sbox[11:8];
4'he: out <= sbox[7:4];
4'hf: out <= sbox[3:0];
endcase
endmodule
/trunk/LICENSE
0,0 → 1,25
Copyright (c) 2014, Kirill Fomichev
All rights reserved.
 
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
 
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
/trunk/doc/gost28147-89.tex
0,0 → 1,223
\documentclass[a4paper,12pt]{article}
\usepackage[utf8]{inputenc}
 
\usepackage{titlesec}
\usepackage{tabularx}
\usepackage{lastpage}
\usepackage{tocloft}
\usepackage[us]{datetime}
 
\usepackage{hyperref}
\hypersetup{colorlinks=true,linkcolor=black,urlcolor=blue}
 
\usepackage[top=2.5cm, bottom=2.5cm, left=2.5cm, right=2cm]{geometry}
 
\usepackage{fancyhdr}
\pagestyle{fancy}
\lhead{GOST 28147-89 Core, rev. \currentRevision}
\rhead{\releaseDate}
\cfoot{\thepage\ of \pageref{LastPage}}
 
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0.4pt}
 
\renewcommand\cftsecdotsep{\cftdotsep}
 
\newcommand{\currentRevision}{0.2}
\newcommand{\releaseDate}{March 31, 2014}
 
\begin{document}
 
% Title
\begin{titlepage}
\begin{flushright}
 
\vspace*{4cm}
\Huge
\textbf{GOST 28147-89}\\IP Core
 
\vspace{4cm}
\large
Author: Kirill Fomichev\\
\textsl{fanatid@ya.ru}
 
\vspace{4cm}
\textbf{Revision \currentRevision\\\releaseDate}
 
\end{flushright}
\end{titlepage}
 
 
% Revision history
\begin{flushright}
\Large
\textbf{Revision History}
\normalsize
\end{flushright}
 
\begin{flushleft}
{\renewcommand{\arraystretch}{1.5}
\begin{tabularx}{\textwidth}{|l|l|l|X|}
\hline
\textbf{Rev.} & \textbf{Date} & \textbf{Author} & \textbf{Description}\\
\hline
0.1 & March 10, 2014 & Kirill Fomichev & Initial Release\\
\hline
0.2 & March 31, 2014 & Kirill Fomichev & Add bidirectional ECB and CFB modules\\
\hline
\end{tabularx}}
\end{flushleft}
 
% Contents
\newpage
\tableofcontents
 
% Introduction
\newpage
\section{Introduction}
 
\subsection{About GOST 28147-89}
\paragraph{}
The \textsl{GOST block cipher}, defined in standard \textsl{GOST 28147-89},
is a Soviet and Russian government standard symmetric key block cipher.
Developed in the 1970s, the standard has been marked "Top Secret" and
the downgraded to "Secret" in 1990. Shortly after the dissolution of the USSR,
it was declassified and it was released to the public in 1994.
 
\paragraph{}
GOST have a 64-bit block size and a key length of 256 bits.
It's S-Boxes can be secret, and they contain about 354($log_2(16!^8)$) bits of
secret information, so the effective key size can be increased to 610 bits;
however, a chosen-key attack can recover the contents of the S-Boxes
in approximately $2^{32}$ encryptions.
 
\subsection{This roject}
\paragraph{}
This project has implements \textsl{GOST block cipher} in three modes:
electronic codebook (ECB), cipher feedback (CFB) and message authentication code (MAC).
\paragraph{}
All files licensed under \textsl{BSD license}.
 
 
% Interface
\newpage
\section{Interface}
 
\paragraph{}
ECB mode\\
{\renewcommand{\arraystretch}{1.2}
\begin{tabularx}{\textwidth}{l|l l X}
\hline
Signal name & Width & In/Out & Description\\
\hline
\textsl{clk} & 1 & In & Clock\\
\textsl{reset} & 1 & In & Terminate current encryption/decryption process \\
\textsl{mode} & 1 & In & Decryption when mode equal 1, otherwise encryption\\
\textsl{load\_data} & 1 & In & Start of encryption/decryption \\
\textsl{sbox} & 512 & In & S-Box \\
\textsl{key} & 256 & In & Key \\
\textsl{in} & 64 & In & Plain text/Cipher text \\
\textsl{out} & 64 & Out & Cipher text/Plain text. Results available after 34 clock cycles. \\
\textsl{busy} & 1 & Out & Status flag, triggered to zero after finished encryption/decryption \\
\hline
\end{tabularx}}
 
\paragraph{}
ECB mode with pipeline\\
{\renewcommand{\arraystretch}{1.2}
\begin{tabularx}{\textwidth}{l|l l X}
\hline
Signal name & Width & In/Out & Description\\
\hline
\textsl{clk} & 1 & In & Clock\\
\textsl{sbox} & 512 & In & S-Box \\
\textsl{key} & 256 & In & Key \\
\textsl{in} & 64 & In & Plain text/Cipher text \\
\textsl{out} & 64 & Out & Cipher text/Plain text. Results available after 32 clock cycles. \\
\hline
\end{tabularx}}
 
\paragraph{}
CFB mode\\
{\renewcommand{\arraystretch}{1.2}
\begin{tabularx}{\textwidth}{l|l l X}
\hline
Signal name & Width & In/Out & Description\\
\hline
\textsl{clk} & 1 & In & Clock\\
\textsl{reset} & 1 & In & Terminate current encryption/decryption process and load gamma from \textsl{in} \\
\textsl{mode} & 1 & In & Decryption when mode equal 1, otherwise encryption\\
\textsl{load\_data} & 1 & In & Start of encryption/decryption \\
\textsl{sbox} & 512 & In & S-Box \\
\textsl{key} & 256 & In & Key \\
\textsl{in} & 64 & In & Gamma/Plain text/Cipher text \\
\textsl{out} & 64 & Out & Cipher text/Plain text. Results available after 35 clock cycles. \\
\textsl{busy} & 1 & Out & Status flag, triggered to zero after finished encryption/decryption \\
\hline
\end{tabularx}}
 
\paragraph{}
MAC mode\\
{\renewcommand{\arraystretch}{1.2}
\begin{tabularx}{\textwidth}{l|l l X}
\hline
Signal name & Width & In/Out & Description\\
\hline
\textsl{clk} & 1 & In & Clock\\
\textsl{reset} & 1 & In & Drop current mac \\
\textsl{load\_data} & 1 & In & Start calculate mac \\
\textsl{sbox} & 512 & In & S-Box \\
\textsl{key} & 256 & In & Key \\
\textsl{in} & 64 & In & Plain text \\
\textsl{out} & 32 & Out & MAC, available after 18 clock cycles. \\
\textsl{busy} & 1 & Out & Status flag, triggered to zero after finished processing\\
\hline
\end{tabularx}}
 
 
% Testbench
\newpage
\section{Testbench}
 
\paragraph{}
Makefile run simulation using
\href{http://iverilog.icarus.com/}{Icarus Verilog}
in testbench folder. You can see simulation results in
\href{http://gtkwave.sourceforge.net/}{GTKWave}.
 
\begin{flushleft}
{\renewcommand{\arraystretch}{1.5}
\begin{tabularx}{\textwidth}{l|X}
\hline
\textsl{File name} & \textsl{The module being tested}\\
\hline
gost89\_ecb\_tb.v & ECB encryption and decryption\\
\hline
gost89\_pipelined\_ecb\_tb.v & Pipelined ECB encryption and decryption\\
\hline
gost89\_cfb\_tb.v & CFB encryption and decryption\\
\hline
gost89\_mac\_tb.v & MAC mode\\
\hline
\end{tabularx}}
\end{flushleft}
 
 
% References
\newpage
\section{References}
 
\begin{enumerate}
\item GOST block cipher,\\
\url{http://en.wikipedia.org/wiki/GOST_(block_cipher)}
 
\item RFC 4357: Additional Cryptographic Algorithms for Use with GOST\\
\url{http://tools.ietf.org/html/rfc4357}
 
\item RFC 5830: GOST 28147-89 encryption, decryption and MAC algorithms\\
\url{http://tools.ietf.org/html/rfc5830}
 
\item Schneier, Bruce (1996). Applied cryptography: protocols, algorithms, and source code in C
\end{enumerate}
 
\end{document}
/trunk/doc/gost28147-89.pdf Cannot display: file marked as a binary type. svn:mime-type = application/pdf
trunk/doc/gost28147-89.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/pdf \ No newline at end of property Index: trunk/README.md =================================================================== --- trunk/README.md (nonexistent) +++ trunk/README.md (revision 5) @@ -0,0 +1,13 @@ +##About GOST 28147-89 +The GOST block cipher, defined in standard GOST 28147-89, is a Soviet and Russian +government standard symmetric key block cipher. Developed in the 1970s, the standard +has been marked ”Top Secret” and the downgraded to ”Secret” in 1990. Shortly after the +dissolution of the USSR, it was declassified and it was released to the public in 1994. + +##This project +This project has implements GOST block cipher in three modes: + +* electronic codebook (ECB) +* cipher feedback (CFB) +* message authentication code (MAC) +

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.