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 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/testbench/gost89_ecb_tb.v
0,0 → 1,98
`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; |
reg reset_e, reset_d; |
reg load_data_e, load_data_d; |
reg [63:0] in_e, in_d; |
wire [63:0] out_e, out_d; |
wire busy_e, busy_d; |
|
gost89_ecb_encrypt |
ecb_encrypt(clk, reset_e, load_data_e, sbox, key, in_e, out_e, busy_e); |
gost89_ecb_decrypt |
ecb_decrypt(clk, reset_d, load_data_d, sbox, key, in_d, out_d, busy_d); |
|
/* |
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_e = 0; reset_d = 0; |
load_data_e = 0; load_data_d = 0; |
|
// Normal usage |
#1; |
in_e = 64'h d5a8a608f4f115b4; in_d = 64'h d658a36b11cf46eb; |
load_data_e = 1; load_data_d = 1; |
#2; |
load_data_e = 0; load_data_d = 0; |
#66; |
if (out_e !== 64'h d658a36b11cf46eb || out_d !== 64'h d5a8a608f4f115b4) |
begin $display("E"); $finish; end |
$display("OK"); |
|
// After reset |
#2; |
reset_e = 1; reset_d = 1; |
#2; |
reset_e = 0; reset_d = 0; |
#2; |
in_e = 64'h 389eb44a391474c4; in_d = 64'h 7aea1ed18e604249; |
load_data_e = 1; load_data_d = 1; |
#2; |
load_data_e = 0; load_data_d = 0; |
#66; |
if (out_e !== 64'h 7aea1ed18e604249 || out_d !== 64'h 389eb44a391474c4) |
begin $display("E"); $finish; end |
$display("OK"); |
|
// Reset in processing |
#2; |
in_e = 64'h 0123456789abcdef; in_d = 64'h 0123456789abcdef; |
load_data_e = 1; load_data_d = 1; |
#2; |
load_data_e = 0; load_data_d = 0; |
#12; |
reset_e = 1; reset_d = 1; |
#2; |
reset_e = 0; reset_d = 0; |
#2; |
in_e = 64'h 379e59c3c96bb2ab; in_d = 64'h c35472c91cd78640; |
load_data_e = 1; load_data_d = 1; |
#2; |
load_data_e = 0; load_data_d = 0; |
#66; |
if (out_e !== 64'h c35472c91cd78640 || out_d !== 64'h 379e59c3c96bb2ab) |
begin $display("E"); $finish; end |
$display("OK"); |
|
// Start with reset |
#2; |
in_e = 64'h 3f38ae3b8f541361; in_d = 64'h 3b5834a000fba066; |
load_data_e = 1; load_data_d = 1; |
reset_e = 1; reset_d = 1; |
#2; |
load_data_e = 0; load_data_d = 0; |
reset_e = 0; reset_d = 0; |
#66; |
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/gost89_cfb_tb.v
0,0 → 1,107
`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; |
reg reset_e, reset_d; |
reg load_data_e, load_data_d; |
reg [63:0] in_e, in_d; |
wire [63:0] out_e, out_d; |
wire busy_e, busy_d; |
|
gost89_cfb_encrypt |
cfb_encrypt1(clk, reset_e, load_data_e, sbox, key, in_e, out_e, busy_e); |
gost89_cfb_decrypt |
cfb_decrypt1(clk, reset_d, load_data_d, sbox, key, in_d, out_d, busy_d); |
|
/* |
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_e = 0; |
reset_d = 0; |
load_data_e = 0; |
load_data_d = 0; |
|
// Normal usage |
#1; |
in_e = 64'h 6aa0379517bb57af; in_d = 64'h 6aa0379517bb57af; |
reset_e = 1; reset_d = 1; |
#2; |
reset_e = 0; reset_d = 0; |
in_e = 64'h 8d437364581af0da; in_d = 64'h 54826055ab718bc7; |
load_data_e = 1; load_data_d = 1; |
#2; |
load_data_e = 0; load_data_d = 0; |
#68; |
if (out_e !== 64'h 54826055ab718bc7 && out_d !== 64'h 8d437364581af0da) |
begin $display("E"); $finish; end |
$display("OK"); |
in_e = 64'h 12911df3eddcc0fb; in_d = 64'h 585ddacf1a45e472; |
load_data_e = 1; load_data_d = 1; |
#2; |
load_data_e = 0; load_data_d = 0; |
#68; |
if (out_e !== 64'h 585ddacf1a45e472 && out_d !== 64'h 12911df3eddcc0fb) |
begin $display("E"); $finish; end |
$display("OK"); |
|
// Change gamma |
#2; |
in_e = 64'h fa5679a45f118aed; in_d = 64'h fa5679a45f118aed; |
reset_e = 1; reset_d = 1; |
#2; |
reset_e = 0; reset_d = 0; |
in_e = 64'h 419677a6eff07f2f; in_d = 64'h 27d3e781cc4fcf43; |
load_data_e = 1; load_data_d = 1; |
#2; |
load_data_e = 0; load_data_d = 0; |
#68; |
if (out_e !== 64'h 27d3e781cc4fcf43 && out_d !== 64'h 419677a6eff07f2f) |
begin $display("E"); $finish; end |
$display("OK"); |
|
// Reset in processing |
#2; |
in_e = 64'h 6aa0379517bb57af; in_d = 64'h 6aa0379517bb57af; |
reset_e = 1; reset_d = 1; |
#2; |
reset_e = 0; reset_d = 0; |
in_e = 64'h 8d437364581af0da; in_d = 64'h 54826055ab718bc7; |
load_data_e = 1; load_data_d = 1; |
#2; |
load_data_e = 0; load_data_d = 0; |
#10; |
in_e = 64'h fa5679a45f118aed; in_d = 64'h fa5679a45f118aed; |
reset_e = 1; reset_d = 1; |
#2; |
reset_e = 0; reset_d = 0; |
in_e = 64'h 419677a6eff07f2f; in_d = 64'h 27d3e781cc4fcf43; |
load_data_e = 1; load_data_d = 1; |
#2; |
load_data_e = 0; load_data_d = 0; |
#68; |
if (out_e !== 64'h 27d3e781cc4fcf43 && out_d !== 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,91
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; |
|
initial begin |
busy = 0; |
counter = 17; |
need_xor = 0; |
end |
|
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; |
out <= 32'h xxxxxxxx; |
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; |
out <= 32'h xxxxxxxx; |
end |
|
if (reset && load_data) begin |
n1 <= in[63:32]; |
n2 <= in[31:0]; |
counter <= 0; |
need_xor <= 1; |
busy <= 1; |
out <= 32'h xxxxxxxx; |
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]; |
default: round_key <= 32'h xxxxxxxx; |
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,177
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; |
|
initial begin |
busy = 0; |
round_num = 32; |
end |
|
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]; |
out <= 64'h xxxxxxxxxxxxxxxx; |
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]; |
default: round_key <= 32'h xxxxxxxx; |
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]; |
out <= 64'h xxxxxxxxxxxxxxxx; |
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]; |
default: round_key <= 32'h xxxxxxxx; |
endcase |
endmodule |
/trunk/rtl/gost89_cfb.v
0,0 → 1,81
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_e; |
wire load_e, busy_e; |
|
assign load_e = !reset && load_data; |
|
gost89_ecb_encrypt |
ecb_encrypt(clk, load_e, load_e, sbox, key, gamma, out_e, busy_e); |
|
always @(posedge clk) begin |
if (reset && !load_data) begin |
gamma <= in; |
out <= 64'h xxxxxxxxxxxxxxxx; |
busy <= 0; |
end |
|
if (!reset & load_data) begin |
in_value <= in; |
out <= 64'h xxxxxxxxxxxxxxxx; |
busy <= 1; |
end |
|
if (!reset && !load_data && !busy_e && busy) begin |
gamma <= out_e ^ in_value; |
out <= out_e ^ 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_e; |
wire load_e, busy_e; |
|
assign load_e = !reset && load_data; |
|
gost89_ecb_encrypt |
ecb_encrypt(clk, load_e, load_e, sbox, key, gamma, out_e, busy_e); |
|
always @(posedge clk) begin |
if (reset && !load_data) begin |
gamma <= in; |
out <= 64'h xxxxxxxxxxxxxxxx; |
busy <= 0; |
end |
|
if (!reset & load_data) begin |
in_value <= in; |
out <= 64'h xxxxxxxxxxxxxxxx; |
busy <= 1; |
end |
|
if (!reset && !load_data && !busy_e && busy) begin |
gamma <= in_value; |
out <= out_e ^ 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,219
\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.1} |
\newcommand{\releaseDate}{March 10, 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 |
\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{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{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 2)
@@ -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)
+