Start
Sometimes, a simple and beautiful solution is better than a correct and consistent one. Perhaps this would be the case if everything in life happened as in textbooks. In practice, however, it takes a long way to get things done.
Departing from the lyrics, in this article I want to tell the interested reader about encryption according to GOST, namely, the "Grasshopper" algorithm, and about the fact that it is worth paying attention to new and promising tools - the Rust language.
Enough digressions, I suggest you start!
What will be in this article
Rust. . . , , .
Rust Rust?
Rust C++, Go Rust, Rust β¦, , . Rust , , . , Rust , .
, Rust , , , C++. . , , . , .
, Β«Hello WorldΒ». kuznechik:
Cargo.toml:
[dependencies]
kuznechik = "0.2.0"
"Hello World!":
main.rs:
fn hello_world() {
//
let gamma = vec![0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xce, 0xf0, 0xa1, 0xb2, 0xc3, 0xd4, 0xe5, 0xf0, 0x01, 0x12,
0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, 0x90, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19];
let kuz = Kuznechik::new(" Rust").unwrap();
let mut alg = AlgOfb::new(&kuz);
alg.gamma = gamma.clone();
let data = String::from("Hello World!").into_bytes();
//
let enc_data = alg.encrypt(data.clone());
println!("Encrypted data:\n{:?}", &enc_data);
//
alg.gamma = gamma;
let dec_data = alg.decrypt(enc_data);
println!(
"Decrypted data:\n{}",
String::from_utf8(dec_data.clone()).unwrap()
);
assert_eq!(dec_data, data);
}
, Kuznechik . Kuznechik::new() Sha3-256 . , Kuznechik::new_with_master_key(). 256 ( [u8; 32]).
alg.encrypt() alg.decrypt() Vec<u8>. . , .
, β , Kuznechik, , Alg- ( - AlgOfb). . Kuznechik ( ) .
( AlgEcb, AlgCtr, AlgOfb, AlgCbc, AlgCfb, AlgMac). (OFB). , alg.gamma. , .
, Rust. GitHub.
:
pub fn encrypt_block(data: &mut Block128, keys: &[Block128; 10]) {
for i in 0..9 {
tfm_lsx(data, &keys[i]);
}
tfm_x(data, &keys[9]);
}
LSX- X-. 128 16 . Block128 , u8.
LSX-. X, S, L .
fn tfm_lsx(data: &mut Block128, key: &Block128) {
tfm_x(data, key);
tfm_s(data);
tfm_l(data);
}
X- 2 ( - XOR) :
fn tfm_x(data: &mut Block128, key: &Block128) {
for i in 0..16 {
data[i] ^= key[i];
}
}
S- Ο ().
fn tfm_s(data: &mut Block128) {
for i in 0..16 {
data[i] = K_PI[data[i] as usize];
}
}
L- 16 R- .
fn tfm_l(data: &mut Block128) {
for _ in 0..16 {
tfm_r(data);
}
}
R-:
fn tfm_r(data: &mut Block128) {
let temp = trf_linear(data);
data.rotate_right(1);
data[0] = temp;
}
. F β , 16 , .
:
L - , , , . 7 256 , ( 1 , .. ).
O(1) O(1) , 7 * 256 = 1792 , .
:
fn trf_linear(data: &Block128) -> u8 {
// indexes: 0, 1, 2, 3, 4, 5, 6
// values: 16, 32, 133, 148, 192, 194, 251
let mut res = 0u8;
res ^= MULT_TABLE[3][data[0] as usize];
res ^= MULT_TABLE[1][data[1] as usize];
res ^= MULT_TABLE[2][data[2] as usize];
res ^= MULT_TABLE[0][data[3] as usize];
res ^= MULT_TABLE[5][data[4] as usize];
res ^= MULT_TABLE[4][data[5] as usize];
res ^= data[6];
res ^= MULT_TABLE[6][data[7] as usize];
res ^= data[8];
res ^= MULT_TABLE[4][data[9] as usize];
res ^= MULT_TABLE[5][data[10] as usize];
res ^= MULT_TABLE[0][data[11] as usize];
res ^= MULT_TABLE[2][data[12] as usize];
res ^= MULT_TABLE[1][data[13] as usize];
res ^= MULT_TABLE[3][data[14] as usize];
res ^= data[15];
res
}
, XOR. .
, , , . , , .
, , , . . , .
.
(, , .).
.
.
, .
β¦
To place all your thoughts in one article, in my opinion, would be wrong. So you can quickly get tired and lose interest in the material. In addition, I would be pleased to hear your opinion and consider common topics with you.
That's all for now. Hope this article helps someone understand the Grasshopper algorithm and the Rust language. Thanks for attention.
Special thanks to Chris F for the photos of the grasshopper.