Mejorando Grasshopper en Rust

Comienzo

A veces, una solución simple y hermosa es mejor que una correcta y consistente. Quizás este sería el caso si todo en la vida sucediera como en los libros de texto. En la práctica, sin embargo, se necesita un largo camino para hacer las cosas.





Partiendo de la letra, en este artículo quiero contarle al lector interesado sobre el cifrado GOST, a saber, el algoritmo Grasshopper, y sobre el hecho de que vale la pena prestar atención a herramientas nuevas y prometedoras: el lenguaje Rust.





¡Basta de digresiones, te sugiero que empieces!





¿Qué habrá en este artículo?

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. .





, , , . , , .





, , , . . , .





  • .





  • (, , .).





  • .





  • .





  • , .





Poner todos sus pensamientos en un artículo, en mi opinión, sería incorrecto. Por lo que puede cansarse rápidamente y perder interés en el material. Además, me complacería escuchar su opinión y considerar temas comunes con usted.





Eso es todo por ahora. Espero que este artículo ayude a alguien a comprender el algoritmo Grasshopper y el lenguaje Rust. Gracias por la atención.





Un agradecimiento especial a Chris F por las fotos del saltamontes.








All Articles