Problems with the whirlpool encryption algorithm in the rust-crypto crate

Hello fellow rustaceans! Recently, I started a project that would simply ask a user to input a string, then have the whirlpool hashing algorithm from the rust-crypto crate
(https://crates.io/crates/rust-crypto). For some reason, after my program asks the user how many layers they want their code encrypted, the program quits. Could someone please help me? Here is the error message:

thread 'main' panicked at 'assertion failed: !self.finalized', /Users/xxxxxxxxx/.cargo/registry/src/github.com-1ecc6299db9ec823/rust-crypto-0.2.36/src/whirlpool.rs:63:9
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace.

Here is a sample run:
Testing the whirlpool encryptor...
Enter in a string to be encrypted:
hola
Enter in a name to identify the encrypted string:
hola
It worked, your string is stored in the variable encoded_text as : f4240b439507145980edbffc45ca76d6427487e0557fd1b479e37c6f6334a7ee71cd3f687032deae2a45e 2a29404faee6adca0b1cf5353168d57802515598ef7

Type in a string to be encrypted:
hola
Type in the number of layers of whirlpool encryption you want on your string:
2
thread 'main' panicked at 'assertion failed: !self.finalized', /Users/miguelknochel/.cargo/registry/src/github.com-1ecc6299db9ec823/rust-crypto-0.2.36/src/whirlpool.rs:63:9
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace.

Here is my code:

use { std::io, std::collections::HashMap, };
extern crate crypto;
extern crate rand;

use self::crypto::whirlpool::Whirlpool;
use self::crypto::digest::Digest;

fn main() {
    println!("Testing the whirlpool encryptor...");
    let encoded_text = twolayerwhirlpool();

    println!("It worked, your string is stored in the variable encoded_text as : {} \n\n\n", encoded_text);

    println!("Type in a string to be encrypted: ");
    let mut plaintext: String = String::new();
    io::stdin().read_line(&mut plaintext) .expect("Failed to read line");

    println!("Type in the number of layers of whirlpool encryption you want on your string: ");
    let mut layers = String::new();
    io::stdin().read_line(&mut layers).expect("Failed to read line");
    let layers: u32 = layers.trim().parse().expect("please type a number"); //converts layers to a u32

    //program quits here

    let encrypted_text = encrypttext(plaintext.trim().to_string(), layers);
    println!("your text was encoded with {:?} layers of encryption: {:?}", layers, encrypted_text);


}

#[allow(unused_variables)]
fn encrypttext(plaintext: String, layers: u32) -> String {
    let mut hasher = Whirlpool::new();
    let text = plaintext;
    for _x in 0..layers {
        hasher.input_str(&text[..]);
        let text = hasher.result_str();
    }
    return text;
}

fn twolayerwhirlpool() -> String {
    println!("Enter in a string to be encrypted: ");

    let mut string = String::new();
    io::stdin().read_line(&mut string)
        .expect("Failed to read line");

    let mut hasher1 = Whirlpool::new();
    hasher1.input_str(&string[..]);
    
    println!("Enter in a name to identify the encrypted string: ");
    let mut title = String::new();
    io::stdin().read_line(&mut title)
        .expect("failed to read line");

    let mut encrypted_values = HashMap::new();
    let mut hasher2 = Whirlpool::new();
    hasher2.input_str(&hasher1.result_str()[..]);
    encrypted_values.insert(title.trim(), hasher2.result_str());

    let returnthis = encrypted_values.get(&title.trim()).unwrap();
    return returnthis.clone();
}

It looks like you've forgotten to call reset() in between calling result_str() and providing more data. Adding in a call to reset() after calling result_str() should fix the problem.

However, there seems to be another issue in your code, which is that, as far as I can tell, encrypttext() just outputs its input, without changing it. I think you meant to make text mut and then assign a new value to it in the loop, rather than declaring a new local let binding.

Thank you so much, it worked like a charm. Thanks for helping me out, I'm quite new to rust.

1 Like

Note that rust-crypto is an unmaintained crate, so I recommend you to use the whirlpool crate instead. It is part of the RustCrypto project, which started as a modularization of rust-crypto.

Ok, Thanks! Ill go check out the RustCrypto project.