Sections
Below are the sections of Cryptode framework, these sections contain different type of cryptological functions.
AES Encryption
This encryption technique is one of the safest encryption technique. Implemented code uses AES-128 variant which operates on 128-bit blocks to perform encryption and decryption.
Example Usage
Blake2b Encryption
The blake2b function takes three arguments:
m: The message to be hashed as a byte slice (&[u8]).
k: The key used for hashing as a byte slice (&[u8]).
nn: The desired size of the output hash in bytes as a u8.
The function returns a Vec
In the main function, we define a message and a key as byte slices. We also specify the desired output size in bytes using the output_size variable.
We then call the blake2b function with the message, key, and output_size as arguments, and store the resulting hash in the hash variable.
Finally, we print the hash to the console.
Example Usage
fn main() {
let message = b"Hello, World!";
let key = b"SecretKey";
let output_size = 32; // Output size in bytes
let hash = blake2b(message, key, output_size);
println!("Hash: {:?}", hash);
}
Chacha Encryption
The chacha20 function takes two arguments:
input: A reference to an array of 16 u32 values representing the input block.
output: A mutable reference to an array of 16 u32 values where the resulting output block will be stored.
The function applies the ChaCha20 encryption algorithm to the input block and stores the result in the output block.
In the main function, we define an input array containing 16 u32 values. You can provide your own input values here.
We also create an output array initialized with zeros to store the resulting output.
We then call the chacha20 function with the input and output arrays as arguments. The function modifies the output array to contain the encrypted result.
Finally, we print the output array to the console.
Example Usage
fn main() {
let input: [u32; 16] = [
0x61707865, 0x3320646e, 0x79622d32, 0x6b206574,
// Additional input values...
];
let mut output: [u32; 16] = [0; 16];
chacha20(&input, &mut output);
println!("Output: {:?}", output);
}
Diffie Hellman Encryption
generate_private_key: This function generates a random private key for a party. It takes the size of the prime number (p) as input and returns a random private key (x) within the range [2, p-2].
generate_public_key: This function calculates the public key (y) for a party given their private key (x) and the prime number (p). The public key is computed as y = g^x mod p, where g is a generator.
generate_shared_secret: This function calculates the shared secret (z) between two parties given their public and private keys. The shared secret is computed as z = y^x mod p.
Example Usage
let prime_5 = PRIMES.get(&5).unwrap();
let private_key = generate_private_key(prime_5);
let generator = BigUint::from(2u8);
let private_key = generate_private_key(prime_5);
let public_key = generate_public_key(&generator, &private_key, prime_5);
// Assuming Alice's public key is `alice_public_key` and Bob's private key is `bob_private_key`
let shared_secret = generate_shared_secret(&alice_public_key, &bob_private_key, prime_5);
Encryption File
The encrypt_bytes_to_string function encrypts the provided content using the given key and returns an encrypted string.
The encrypt_file_to_file_buffered function reads from an input file, encrypts the data using the key, and writes the encrypted content to an output file.
The decrypt_from_string function decrypts the provided ciphertext using the given key and returns the decrypted string.
The decrypt_file_to_file_buffered function reads from an encrypted input file, decrypts the content using the key, and writes the decrypted data to an output file.
The write_fernet_key_to_file function writes the provided key to a file named ".secret.key". If the file already exists, it asks the user whether to use the existing key or exit the program
The read_fernet_key_from_file function reads the key from the ".secret.key" file. If the file doesn't exist, it exits the program.
Example Usage
fn main() {
// Encrypt bytes to string
let key = "your_key";
let content = b"Hello, world!";
let encrypted_string = encrypt_bytes_to_string(key, content);
println!("Encrypted string: {}", encrypted_string);
// Encrypt file to file (buffered)
let input_file = File::open("input.txt").expect("Failed to open input file");
let output_file = File::create("output.txt").expect("Failed to create output file");
let reader = BufReader::new(input_file);
let writer = BufWriter::new(output_file);
encrypt_file_to_file_buffered(key, reader, writer).expect("Failed to encrypt file");
// Decrypt from string
let ciphertext = "encrypted_string";
let decrypted_string = decrypt_from_string(key, ciphertext).expect("Failed to decrypt string");
println!("Decrypted string: {}", decrypted_string);
// Decrypt file to file (buffered)
let input_file = File::open("encrypted_file.txt").expect("Failed to open encrypted file");
let output_file = File::create("decrypted_file.txt").expect("Failed to create decrypted file");
let reader = BufReader::new(input_file);
let writer = BufWriter::new(output_file);
decrypt_file_to_file_buffered(key, reader, writer).expect("Failed to decrypt file");
// Write fernet key to file
let key = "your_key".to_owned();
write_fernet_key_to_file(key);
// Read fernet key from file
let key = read_fernet_key_from_file();
println!("Fernet key: {}", key);
}
Kerninghan Encryption
The kerninghan function takes an unsigned integer n as input and returns the count of set bits.
It initializes a variable count to keep track of the number of set bits.
Example Usage
fn main() {
let number = 123456789;
let count = kerninghan(number);
println!("Number of set bits in {}: {}", number, count);
}
Morse Code Encryption
The encode function takes a message as input and returns the Morse code representation of the message as a string.
The decode function takes an encoded Morse code string as input and attempts to decode it back to the original message.
Example Usage
fn main() {
let message = "HELLO WORLD";
let encoded = encode(message);
let decoded = decode(&encoded).unwrap();
println!("Original Message: {}", message);
println!("Encoded Message: {}", encoded);
println!("Decoded Message: {}", decoded);
}
Polybius Encryption
The encode_ascii function takes a string of ASCII characters as input and returns an encoded version of the string as a string of numbers.
The decode_ascii function takes an encoded string as input and attempts to decode it back to the original ASCII message.
Example Usage
fn main() {
let message = "Hello, World!";
let encoded = encode_ascii(message);
let decoded = decode_ascii(&encoded);
println!("Original Message: {}", message);
println!("Encoded Message: {}", encoded);
println!("Decoded Message: {}", decoded);
}
Railfence Encryption
The rail_fence_encrypt function takes a plain text string and a key (number of rails) as input and returns the encrypted version of the plain text as a string.
The rail_fence_decrypt function takes an encrypted cipher text string and the key (number of rails) as input and returns the decrypted version of the cipher text as a string.
Example Usage
fn main() {
let plain_text = "Hello, World!";
let key = 3;
let encrypted = rail_fence_encrypt(plain_text, key);
let decrypted = rail_fence_decrypt(&encrypted, key);
println!("Plain Text: {}", plain_text);
println!("Encrypted Text: {}", encrypted);
println!("Decrypted Text: {}", decrypted);
}
Rot13 Encryption
The rot13 function takes a text string as input and returns the encrypted version of the text as a string.
The character c is matched against specific ranges using the match expression:
If c is in the range 'A'..='M', which represents the first half of the uppercase alphabet, it is shifted by adding 13 to its ASCII value. The resulting value is then casted back to a character.
If c is in the range 'N'..='Z', which represents the second half of the uppercase alphabet, it is shifted by subtracting 13 from its ASCII value. The resulting value is then casted back to a character.
If c doesn't fall into any of the specified ranges, it remains unchanged.
Example Usage
fn main() {
let text = "Hello, World!";
let encrypted = rot13(text);
println!("Original Text: {}", text);
println!("Encrypted Text: {}", encrypted);
}
Salsa Encryption
The salsa20 function takes an input array of 16 u32 values (input) and an output array of 16 u32 values (output) as parameters. It performs the Salsa20 encryption algorithm on the input and stores the result in the output array.
Example Usage
fn main() {
let input: [u32; 16] = [
0x00000001, 0x00000023, 0x00000456, 0x00000789,
0x0000009A, 0x000000BC, 0x00000DEF, 0x000000FE,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
];
let mut output: [u32; 16] = [0; 16];
salsa20(&input, &mut output);
println!("Input: {:?}", input);
println!("Output: {:?}", output);
}
SHA3 Encryption
The sha3! macro is used to generate specific hash functions based on the Keccak algorithm. It takes two arguments: the name of the hash function and the desired output size in bits.
Example Usage
fn main() {
let message = b"Hello, world!";
let hash = sha3_256(message);
println!("Message: {}", String::from_utf8_lossy(message));
println!("SHA3-256 Hash: {:x}", hash);
}
SHA256 Encryption
SHA256 is a struct that represents the SHA-256 hashing state. It contains the internal buffer, the length of the input data, the current hash values, working variables, a flag indicating if the hashing is finalized, and a round array.
Example Usage
let mut hasher = SHA256::new_default();
hasher.update(&data);
let hash = hasher.get_hash();
TEA Encryption
Tiny Encryption Algorithm (TEA), a symmetric block cipher. It includes functions for encrypting and decrypting data using TEA.
The tea_encrypt function takes the plain text and key as input and returns the encrypted data as a Vec
Example Usage
fn main() {
let plaintext = b"Hello, World!"; // Plain text to encrypt
let key = b"This is a key!"; // Encryption key
let ciphertext = tea_encrypt(plaintext, key); // Encrypt the plaintext using TEA
println!("Ciphertext: {:?}", ciphertext);
let decrypted_text = tea_decrypt(&ciphertext, key); // Decrypt the ciphertext using TEA
println!("Decrypted text: {:?}", decrypted_text);
}
Theoretical Rot13 Encryption
This is another approach of rot13 encryption, a bit more simpler with decryption.
Example Usage
fn main() {
let plaintext = "Hello, World!"; // Plain text to encrypt
let ciphertext = theoretical_rot13(plaintext); // Encrypt the plaintext using ROT13
println!("Ciphertext: {}", ciphertext);
let decrypted_text = theoretical_rot13(&ciphertext); // Decrypt the ciphertext using ROT13
println!("Decrypted text: {}", decrypted_text);
}
Transposition Encryption
The transposition function takes three parameters: decrypt_mode (a boolean indicating whether to encrypt or decrypt), msg (the message to encrypt or decrypt), and key (the key used for the transposition).
Example Usage
fn main() {
let message = "Hello, World!"; // Message to encrypt or decrypt
let key = "KEY"; // Key used for transposition
let encrypted_message = transposition(false, message, key); // Encrypt the message using the transposition cipher
println!("Encrypted Message: {}", encrypted_message);
let decrypted_message = transposition(true, &encrypted_message, key); // Decrypt the message using the transposition cipher
println!("Decrypted Message: {}", decrypted_message);
}
Utility File
Just some Utility functions
Example Usage
fn main() {
let file_name = "example.txt"; // Name of the file
if warn_if_file_exists(file_name) {
// File does not exist or user confirmed overwrite
println!("Writing content to {}...", file_name);
// Write your file writing logic here
} else {
println!("File not overwritten.");
}
let answer = ask_bool("Do you want to continue?", true);
match answer {
Some(true) => println!("Continuing..."),
Some(false) => println!("Exiting..."),
None => println!("Invalid input, assuming default."),
}
}
XOR Encryption
The xor_bytes function takes a slice of bytes (text) and a single-byte key (key). It uses the iter method to iterate over each byte in text, applies the XOR operation (^) with the key, and collects the results into a new Vec
The xor function is a convenience function that takes a string (text) and a single-byte key (key). It converts the string to bytes using as_bytes and calls xor_bytes to perform the XOR operation.
In the example code, the original text is XORed with the key using xor_bytes, and the result is converted back to a string using String::from_utf8_lossy. The XORed text is then printed.
Example Usage
fn main() {
let text = "Hello, world!"; // Text to be XORed
let key = 0xAB; // XOR key
let xored_bytes = xor_bytes(text.as_bytes(), key);
let xored_text = String::from_utf8_lossy(&xored_bytes);
println!("Original text: {}", text);
println!("XOR key: 0x{:02X}", key);
println!("XORed text: {}", xored_text);
let decrypted_bytes = xor_bytes(&xored_bytes, key);
let decrypted_text = String::from_utf8_lossy(&decrypted_bytes);
println!("Decrypted text: {}", decrypted_text);
}
Alphabet Encryption
find_position(&self, c: char) -> Option
get_letter(&self, index: usize, is_uppercase: bool) -> char: Given an index and a flag indicating whether the letter should be uppercase, this method returns the corresponding letter from the alphabet.
modulo(&self, i: isize) -> usize: This method performs modulo arithmetic on a given value i using the length of the alphabet. It ensures that the result is a valid index within the alphabet.
is_valid(&self, text: &str) -> bool: This method checks if all characters in the provided text are valid characters in the alphabet.
scrub(&self, text: &str) -> String: This method removes any characters from the text that are not valid characters in the alphabet and returns a new string containing only the valid characters
multiplicative_inverse(&self, a: isize) -> Option
length(&self) -> usize: This method returns the length of the alphabet.
Example Usage
fn main() {
let standard_alphabet = Standard;
let alphanumeric_alphabet = Alphanumeric;
let playfair_alphabet = Playfair;
let position = standard_alphabet.find_position('a');
println!("Position of 'a' in the standard alphabet: {:?}", position);
let letter = alphanumeric_alphabet.get_letter(10, true);
println!("Letter at index 10 in the alphanumeric alphabet (uppercase): {}", letter);
let modulo_result = playfair_alphabet.modulo(30);
println!("Modulo result of 30 in the playfair alphabet: {}", modulo_result);
let is_valid_text = standard_alphabet.is_valid("Hello, world!");
println!("Is 'Hello, world!' a valid text in the standard alphabet? {}", is_valid_text);
let scrubbed_text = alphanumeric_alphabet.scrub("abc123xyz!@#");
println!("Scrubbed text in the alphanumeric alphabet: {}", scrubbed_text);
let multiplicative_inverse = playfair_alphabet.multiplicative_inverse(7);
println!("Multiplicative inverse of 7 in the playfair alphabet: {:?}", multiplicative_inverse);
let alphabet_length = standard_alphabet.length();
println!("Length of the standard alphabet: {}", alphabet_length);
}
Keygen File
keyed_alphabet: This function generates a modified alphabet based on a given key and alphabet type. It takes three arguments: key (the key string), alpha_type (the type of alphabet to use), and to_uppercase (a boolean indicating whether the generated alphabet should be in uppercase). The function returns a string representing the modified alphabet.
columnar_key: This function generates a columnar key from a given keystream. It takes one argument: keystream (the string representing the keystream). The function returns a vector of tuples, where each tuple contains a character and an empty vector.
polybius_square: This function generates a Polybius square based on a given key, column IDs, and row IDs. It takes three arguments: key (the key string), column_ids (an array of 6 characters representing column identifiers), and row_ids (an array of 6 characters representing row identifiers). The function returns a HashMap that maps string coordinates to characters.
playfair_table: This function generates a Playfair cipher table based on a given keystream. It takes one argument: keystream (the string representing the keystream). The function returns a tuple containing two arrays of strings: ([String; 5], [String; 5]). Each array represents a row or column in the Playfair table.
cyclic_keystream: This function generates a cyclic keystream based on a given key and message. It takes two arguments: key (the string representing the key) and message (the string representing the message). The function returns a string representing the cyclic keystream.
concatonated_keystream: This function generates a concatenated keystream based on a given key and message. It takes two arguments: key (the string representing the key) and message (the string representing the message
Example Usage
let key = "lemon";
let modified_alphabet = keyed_alphabet(key, &STANDARD, false);
println!("{}", modified_alphabet);
let keystream = "zebras";
let columnar_key = columnar_key(keystream);
for (ch, vec) in columnar_key {
println!("Character: {}", ch);
println!("Vector: {:?}", vec);
}
let key = "abcdefghijklmnopqrstuvwxyz0123456789";
let column_ids = ['a', 'b', 'c', 'd', 'e', 'f'];
let row_ids = ['a', 'b', 'c', 'd', 'e', 'f'];
let polybius_table = polybius_square(key, &column_ids, &row_ids);
println!("{:?}", polybius_table);
let keystream = "playfairexample";
let (rows, cols) = playfair_table(keystream);
println!("{:?}", rows);
println!("{:?}", cols);
let key = "lemon";
let message = "We are under seige!";
let keystream = cyclic_keystream(key, message);
println!("{}", keystream);
Substitution Encryption
shift_substitution:
This function performs a shift substitution cipher on the input text.
It takes two arguments: text (the input text to be encrypted) and calc_index (a closure that calculates the new index based on the current index).
The function iterates over each character in the input text.
It finds the position of the character in the STANDARD alphabet using alphabet::STANDARD.find_position(c).
If the character is found in the alphabet, it calculates the new index using the closure calc_index and retrieves the corresponding letter using alphabet::STANDARD.get_letter(si, c.is_uppercase()).
If the character is not found in the alphabet, it appends the character as is.
The function returns the substituted text.
key_substitution:
This function performs a key substitution cipher on the input text using a keystream.
It takes three arguments: text (the input text to be encrypted), keystream (the keystream used for substitution), and calc_index (a closure that calculates the new index based on the current indexes of the text and keystream characters).
The function iterates over each character in the input text.
It finds the position of the text character in the STANDARD alphabet using alphabet::STANDARD.find_position(tc).
If the text character is found in the alphabet, it checks if there is a character available in the keystream_iter.
If there is a keystream character, it finds the position of the keystream character in the STANDARD alphabet using alphabet::STANDARD.find_position(*kc).
It then calculates the new index using the closure calc_index and retrieves the corresponding letter using alphabet::STANDARD.get_letter(si, tc.is_uppercase()).
If the keystream character is not found in the alphabet, it throws a panic indicating a non-alphabetic symbol in the keystream.
If there is no keystream character available, it throws a panic indicating that the keystream is not large enough for full substitution of the message.
The function returns the substituted text.
Example Usage
let text = "Hello, World!";
let new_text = shift_substitution(text, |pos| (pos + 3) % 26);
println!("{}", new_text);
let text = "Hello, World!";
let keystream = "lemon";
let new_text = key_substitution(text, keystream, |ti, ki| (ti + ki) % 26);
println!("{}", new_text);
ADFGVX Encryption
The ADFGVX struct has two fields: polybius_cipher of type Polybius and columnar_cipher of type ColumnarTransposition. These fields represent the two steps involved in the ADFGVX cipher.
The Polybius cipher is used for the first step of encryption and decryption in the ADFGVX cipher. It maps each character of the input message to a pair of ADFGVX characters based on a Polybius square. The Polybius struct is instantiated with the key, ADFGVX row characters, and ADFGVX column characters.
The ColumnarTransposition cipher is used for the second step of encryption and decryption in the ADFGVX cipher. It performs a columnar transposition on the output of the Polybius cipher. The ColumnarTransposition struct is instantiated with the columnar key and an optional columnar padding character.
Example Usage
// Create an instance of ADFGVX cipher with a key
let key = ("POLYBIUSKEY".to_string(), "COLUMNARKEY".to_string(), Some('X'));
let adfgvx_cipher = ADFGVX::new(key);
// Encrypt a message
let plaintext = "HELLO";
let ciphertext = adfgvx_cipher.encrypt(plaintext).unwrap();
println!("Ciphertext: {}", ciphertext);
// Decrypt the ciphertext
let decrypted_text = adfgvx_cipher.decrypt(&ciphertext).unwrap();
println!("Decrypted text: {}", decrypted_text);
Affine Encryption
The Affine struct represents the Affine cipher, which is a substitution cipher that combines the encryption steps of the Caesar cipher and the Multiplicative cipher.
Example Usage
// Create an instance of Affine cipher with a key
let key = (5, 8);
let affine_cipher = Affine::new(key);
// Encrypt a message
let plaintext = "HELLO";
let ciphertext = affine_cipher.encrypt(plaintext).unwrap();
println!("Ciphertext: {}", ciphertext);
// Decrypt the ciphertext
let decrypted_text = affine_cipher.decrypt(&ciphertext).unwrap();
println!("Decrypted text: {}", decrypted_text);
Autokey Encryption
The encrypt method takes a message as input, performs encryption using the Autokey cipher, and returns the ciphertext as a Result
The decrypt method takes a ciphertext as input, performs decryption using the Autokey cipher, and returns the plaintext as a Result
Example Usage
// Create an instance of Autokey cipher with a key
let key = "KEY";
let autokey_cipher = Autokey::new(key.to_string());
// Encrypt a message
let plaintext = "HELLO";
let ciphertext = autokey_cipher.encrypt(plaintext).unwrap();
println!("Ciphertext: {}", ciphertext);
// Decrypt the ciphertext
let decrypted_text = autokey_cipher.decrypt(&ciphertext).unwrap();
println!("Decrypted text: {}", decrypted_text);
Baconian Encryption
The get_code function takes a boolean flag use_distinct_alphabet and a key as input and returns the Baconian code for the given key. It first converts the key to uppercase and checks if the use_distinct_alphabet flag is set. If the flag is set and the key is "J" or "U", it substitutes them with "I" and "V" respectively. Then, it retrieves the Baconian code from the CODE_MAP using the modified key and returns it.
The get_key function takes a Baconian code as input and returns the corresponding letter key. It iterates over the CODE_MAP and checks for a match between the code and the values in the map. When a match is found, it adds the corresponding key to the key string and returns it.
The Baconian struct represents the Baconian cipher and implements the Cipher trait. It has two fields: use_distinct_alphabet (a boolean flag indicating whether to use a distinct alphabet) and decoy_text (a string representing the decoy text used for encryption).
The encrypt method takes a message as input, performs encryption using the Baconian cipher, and returns the ciphertext as a Result
The decrypt method takes a message as input, performs decryption using the Baconian cipher, and returns the plaintext as a Result
Example Usage
fn main() {
let baconian = Baconian::new((true, None)); // Use distinct alphabet and no decoy text
let message = "HELLO";
let ciphertext = baconian.encrypt(message).unwrap();
println!("Ciphertext: {}", ciphertext);
let decrypted_message = baconian.decrypt(&ciphertext).unwrap();
println!("Decrypted message: {}", decrypted_message);
}
Columnar Transposition Encryption
The encrypt method takes a message as input, performs encryption using the Columnar Transposition cipher, and returns the ciphertext as a Result
The decrypt method takes a ciphertext as input, performs decryption using the Columnar Transposition cipher, and returns the plaintext as a Result
Example Usage
fn main() {
let key = ("SECRETKEY".to_string(), Some('_')); // Create a key with the keystream "SECRETKEY" and null character '_'
let columnar = ColumnarTransposition::new(key);
let message = "HELLO";
let ciphertext = columnar.encrypt(message).unwrap();
println!("Ciphertext: {}", ciphertext);
let decrypted_message = columnar.decrypt(&ciphertext).unwrap();
println!("Decrypted message: {}", decrypted_message);
}
Caesar Encryption
The encrypt method takes a message as input, performs encryption using the Caesar cipher, and returns the ciphertext as a Result
The decrypt method takes a ciphertext as input, performs decryption using the Caesar cipher, and returns the plaintext as a Result
Example Usage
fn main() {
let caesar = Caesar::new(3); // Create a Caesar cipher with a shift of 3
let message = "HELLO";
let ciphertext = caesar.encrypt(message).unwrap();
println!("Ciphertext: {}", ciphertext);
let decrypted_message = caesar.decrypt(&ciphertext).unwrap();
println!("Decrypted message: {}", decrypted_message);
}
Franctionated Morse Encryption
The encrypt method takes a message as input, performs encryption using the Fractionated Morse cipher, and returns the ciphertext as a Result
The decrypt method takes a cipher_text as input, performs decryption using the Fractionated Morse cipher, and returns the plaintext as a Result
Example Usage
fn main() {
let key = "KEY"; // Create a key
let fractionated_morse = FractionatedMorse::new(key.to_string());
let message = "HELLO";
let ciphertext = fractionated_morse.encrypt(message).unwrap();
println!("Ciphertext: {}", ciphertext);
let decrypted_message = fractionated_morse.decrypt(&ciphertext).unwrap();
println!("Decrypted message: {}", decrypted_message);
}
Hill Encryption
The encrypt method takes a message as input, performs encryption using the Hill cipher, and returns the ciphertext as a Result
The decrypt method takes a ciphertext as input, performs decryption using the Hill cipher, and returns the plaintext as a Result
Example Usage
fn main() {
let key = Matrix::new(2, 2, vec![1, 2, 3, 4]); // Create a key matrix
let hill = Hill::new(key);
let message = "HELLO";
let ciphertext = hill.encrypt(message).unwrap();
println!("Ciphertext: {}", ciphertext);
let decrypted_message = hill.decrypt(&ciphertext).unwrap();
println!("Decrypted message: {}", decrypted_message);
}
Playfair Encryption
The encrypt method takes a message as input, performs encryption using the Playfair cipher, and returns the ciphertext as a Result
The decrypt method takes a ciphertext as input, performs decryption using the Playfair cipher, and returns the plaintext as a Result
Example Usage
fn main() {
let key = ("KEY".to_string(), Some('Z')); // Create a key tuple
let playfair = Playfair::new(key);
let message = "HELLO";
let ciphertext = playfair.encrypt(message).unwrap();
println!("Ciphertext: {}", ciphertext);
let decrypted_message = playfair.decrypt(&ciphertext).unwrap();
println!("Decrypted message: {}", decrypted_message);
}
Polybius Second Approach Encryption
The encrypt method takes a message as input, performs encryption using the Polybius cipher, and returns the ciphertext as a Result
The decrypt method takes a ciphertext as input, performs decryption using the Polybius cipher, and returns the plaintext as a Result
Example Usage
fn main() {
let key = ("KEY".to_string(), ['A', 'B', 'C', 'D', 'E', 'F'], ['1', '2', '3', '4', '5', '6']); // Create a key tuple
let polybius = Polybius::new(key);
let message = "HELLO";
let ciphertext = polybius.encrypt(message).unwrap();
println!("Ciphertext: {}", ciphertext);
let decrypted_message = polybius.decrypt(&ciphertext).unwrap();
println!("Decrypted message: {}", decrypted_message);
}
Porta Encryption
The encrypt method takes a message as input, performs encryption using the Porta cipher, and returns the ciphertext as a Result
The decrypt method takes a ciphertext as input, performs decryption using the Porta cipher, and returns the plaintext as a Result
Example Usage
fn main() {
let key = "KEY".to_string(); // Create a key
let porta = Porta::new(key);
let message = "HELLO";
let ciphertext = porta.encrypt(message).unwrap();
println!("Ciphertext: {}", ciphertext);
let decrypted_message = porta.decrypt(&ciphertext).unwrap();
println!("Decrypted message: {}", decrypted_message);
}
Railfence Second Approach Encryption
The encrypt method takes a message as input, performs encryption using the Railfence cipher, and returns the ciphertext as a Result
The decrypt method takes a ciphertext as input, performs decryption using the Railfence cipher, and returns the plaintext as a Result
Example Usage
fn main() {
let rails = 3; // Number of rails
let railfence = Railfence::new(rails);
let message = "HELLO";
let ciphertext = railfence.encrypt(message).unwrap();
println!("Ciphertext: {}", ciphertext);
let decrypted_message = railfence.decrypt(&ciphertext).unwrap();
println!("Decrypted message: {}", decrypted_message);
}
ROT13 Second Approach Encryption
The encrypt function takes a message as input, performs encryption using a shift substitution cipher with a fixed shift value of 13, and returns the ciphertext as a String. It uses the substitute::shift_substitution function, which applies a shift substitution to each character of the message. The shift value is calculated by adding 13 to the index of the character in the standard alphabet (alphabet::STANDARD). The alphabet::STANDARD.modulo function ensures that the resulting index wraps around within the valid range of the alphabet.
The decrypt function is identical to the encrypt function. It takes a message as input, performs decryption using the same shift substitution cipher with a shift value of 13, and returns the plaintext as a String.
Example Usage
fn main() {
let message = "HELLO";
let ciphertext = encrypt(message);
println!("Ciphertext: {}", ciphertext);
let decrypted_message = decrypt(&ciphertext);
println!("Decrypted message: {}", decrypted_message);
}
Scytale Encryption
The encrypt function takes a message as input, performs encryption using the Scytale cipher, and returns the ciphertext as a Result
The decrypt function takes a ciphertext as input, performs decryption using the Scytale cipher, and returns the plaintext as a Result
Example Usage
fn main() {
let scytale = Scytale::new(4); // Create a Scytale cipher with height 4
let plaintext = "HELLO WORLD";
let ciphertext = scytale.encrypt(plaintext).unwrap();
println!("Ciphertext: {}", ciphertext);
let decrypted_text = scytale.decrypt(&ciphertext).unwrap();
println!("Decrypted text: {}", decrypted_text);
}
Vigenere Encryption
The encrypt function takes a message as input, performs encryption using the Vigenere cipher, and returns the ciphertext as a Result
The decrypt function takes a ciphertext as input, performs decryption using the Vigenere cipher, and returns the plaintext as a Result
Example Usage
fn main() {
let vigenere = Vigenere::new("KEY".to_string()); // Create a Vigenere cipher with the key "KEY"
let plaintext = "HELLO WORLD";
let ciphertext = vigenere.encrypt(plaintext).unwrap();
println!("Ciphertext: {}", ciphertext);
let decrypted_text = vigenere.decrypt(&ciphertext).unwrap();
println!("Decrypted text: {}", decrypted_text);
}
Argon2 Macros Encryption
The macro argon2_module is used to generate the functions and constants based on the provided parameters. Here's a breakdown of the macro parameters:
$pwhash_name: The name of the function used to derive a key from a password and salt.
$pwhash_str_name: The name of the function used to hash a password and produce a string representation.
$pwhash_str_verify_name: The name of the function used to verify a password against a hashed string.
$saltbytes: The number of bytes for the salt.
$hashedpasswordbytes: The number of bytes for the hashed password.
$strprefix: The prefix used in the string representation of the hashed password.
$opslimit_interative, $opslimit_moderate, $opslimit_sensitive: The values for interactive, moderate, and sensitive operations limits, respectively.
$memlimit_interative, $memlimit_moderate, $memlimit_sensitive: The values for interactive, moderate, and sensitive memory limits, respectively.
$variant: The variant value for Argon2.
The generated code includes the following:
Constants: SALTBYTES, HASHEDPASSWORDBYTES, STRPREFIX, OPSLIMIT_INTERACTIVE, MEMLIMIT_INTERACTIVE, OPSLIMIT_MODERATE, MEMLIMIT_MODERATE, OPSLIMIT_SENSITIVE, MEMLIMIT_SENSITIVE, and VARIANT. These constants represent the various parameters and limits for the Argon2 algorithm.
Structs: OpsLimit and MemLimit. These are newtype structs that wrap the underlying usize values for operations limit and memory limit, respectively.
Types: Salt and HashedPassword. These are newtype wrappers for the byte arrays used to store the salt and hashed password, respectively.
Functions:
gen_salt: Generates a random salt value of SALTBYTES length and returns it as a Salt object.
derive_key: Derives a key from a password and salt using the Argon2 algorithm. It takes a mutable key buffer, the passwd (password) byte slice, the Salt, OpsLimit, and MemLimit as input. It returns a Result containing a reference to the derived key on success, or an empty () on failure.
pwhash: Hashes a password using the Argon2 algorithm and returns the hashed password as a HashedPassword object. It takes the passwd (password) byte slice, OpsLimit, and MemLimit as input. It returns a Result containing the hashed password on success, or an empty () on failure.
pwhash_verify: Verifies a password against a hashed password string. It takes a reference to the HashedPassword and the passwd (password) byte slice as input. It returns a bool indicating whether the password is verified (true) or not (false).
Example Usage
argon2_module!(
argon2_derive_key,
argon2_hash_encoded,
argon2_hash_verify,
16,
32,
b"$argon2",
3,
4,
5,
65536,
131072,
262144,
19
);
fn main() {
let password = "mysecretpassword".as_bytes();
// Generate a random salt
let salt = gen_salt();
// Derive a key from the password and salt
let mut key = [0u8; HASHEDPASSWORDBYTES];
let result = derive_key(&mut key, password, &salt, OPSLIMIT_INTERACTIVE, MEMLIMIT_INTERACTIVE);
match result {
Ok(derived_key) => {
println!("Derived key: {:?}", derived_key);
// Hash the password
let hashed_password = pwhash(password, OPSLIMIT_INTERACTIVE, MEMLIMIT_INTERACTIVE);
match hashed_password {
Ok(hashed) => {
println!("Hashed password: {:?}", hashed);
// Verify a password against a hashed password
let verified = pwhash_verify(&hashed, password);
if verified {
println!("Password verification succeeded.");
} else {
println!("Password verification failed.");
}
},
Err(_) => {
println!("Error hashing the password.");
}
}
},
Err(_) => {
println!("Error deriving the key.");
}
}
}
Bcrypt Encryption
The hash_password function takes a byte slice (&[u8]) as input and returns a Result containing either the hashed password as a String or an error of type bcrypt::Error. It generates a random salt, hashes the password using bcrypt with the specified cost, encodes the salt and hashed password using Base64, and returns the formatted string.
The verify_password function takes a byte slice (&[u8]) representing a password and a string (&str) containing the hashed password. It returns a Result containing either a boolean indicating whether the password is valid or an error of type bcrypt::Error. It parses the hashed password string, extracts the cost, salt, and decoded password, and compares the result of hashing the input password with the decoded password.
Example Usage
fn main() {
let password = "my_password".as_bytes();
// Hash the password
let hashed_password = match hash_password(password) {
Ok(hashed) => hashed,
Err(err) => {
println!("Error hashing password: {}", err);
return;
}
};
println!("Hashed password: {}", hashed_password);
// Verify the password
let is_password_valid = match verify_password(password, &hashed_password) {
Ok(valid) => valid,
Err(err) => {
println!("Error verifying password: {}", err);
return;
}
};
if is_password_valid {
println!("Password is valid!");
} else {
println!("Password is invalid!");
}
}
DS Encryption
The function calculates the number of blocks required based on the desired key length. It then iterates over each block, computes the HMAC of the password and block using the hmac function, and XORs the resulting HMAC with the salt. This result is then used as the input for subsequent iterations.
Example Usage
fn main() {
let password = "my_password".as_bytes();
let salt = "mysalt".as_bytes();
let iterations = 10000;
let dk_len = 32;
let derived_key = pbkdf2(password, salt, iterations, dk_len);
println!("Derived key: {:?}", derived_key);
}
Hash Macros Encryption
The macro takes several parameters that define the hash algorithm:
$hash_name: The name of the hash algorithm function.
$hash_state: The name of the hash state struct.
$hash_init: The name of the function to initialize the hash state.
$hash_update: The name of the function to update the hash state with data.
$hash_final: The name of the function to finalize the hash and produce the digest.
$hashbytes: The number of bytes in the hash digest.
$blockbytes: The number of bytes in a block of data processed by the hash algorithm.
The macro generates the following items:
Digest: A newtype struct that represents the hash digest. It has a constant size equal to $hashbytes.
hash: A function that takes a byte slice m as input and returns a Digest representing the hash of m.
State: A struct representing the hash state. It has methods for initialization, updating with data, and finalizing the hash.
impl blocks for the State struct, including implementations of new, update, and finalize.
impl block for Default trait, providing a default implementation for creating a new State.
Optional test modules for testing the hash algorithm and serialization (if the serde feature is enabled).
Optional benchmark module for benchmarking the hash algorithm (if the benchmarks feature is enabled).
Example Usage
fn main() {
let message = b"Hello, world!";
// Hash the message
let digest = hash(message);
println!("Hash digest: {:?}", digest);
// Create a hash state and update it with data
let mut state = State::new();
state.update(message);
let final_digest = state.finalize();
println!("Final hash digest: {:?}", final_digest);
}
Hmac Encryption
The Hmac is just another approach of hash macros encryption.
Example Usage
fn main() {
let key = b"my_key";
let message = b"Hello, world!";
let hash_func = |data: &[u8]| -> Vec {
let mut hasher = Sha256::new();
hasher.update(data);
hasher.finalize().to_vec()
};
let hmac_result = hmac(&hash_func, key, message);
println!("HMAC result: {:?}", hmac_result);
}
Keyexchange Encryption
Keyexchange is another implementation of Diffie Hellman Encryption.
Example Usage
fn main() {
// Create two DiffieHellman instances
let mut alice = DiffieHellman::new();
let mut bob = DiffieHellman::new();
// Alice generates her public key
let alice_public_key = alice.generate_public_key();
// Bob generates his public key
let bob_public_key = bob.generate_public_key();
// Alice computes the shared secret using Bob's public key
let alice_shared_secret = alice.compute_shared_secret(bob_public_key);
// Bob computes the shared secret using Alice's public key
let bob_shared_secret = bob.compute_shared_secret(alice_public_key);
// The shared secrets should be equal
assert_eq!(alice_shared_secret, bob_shared_secret);
// Print the shared secret
println!("Shared Secret: {}", alice_shared_secret);
}
MAC Encryption
Here is another implementation of Hmac encryption which is an another implementation of Hash Macros Encryption.
Example Usage
fn main() {
let key = b"secret_key";
let message = b"Hello, world!";
let hmac_result = hmac(key, message);
println!("HMAC: {:?}", hmac_result);
}
MD5 Encryption
The md5 function processes the input in 64-byte chunks, performs the MD5 rounds according to the MD5 algorithm, and updates the state with the computed values. Finally, it converts the state into a 16-byte array as the final hash result.
Example Usage
fn main() {
let input = b"Hello, world!";
let hash = md5(input);
println!("MD5 Hash: {:02X?}", hash);
}
Scrypt Encryption
To hash a password, you can call the hash_password function and provide the password as a byte slice. The function will return a Result where the Ok variant contains the hashed password as a String. If an error occurs during the hashing process, such as invalid parameters, a CryptoError will be returned.
Example Usage
fn main() {
let password = b"my_password";
let hashed_password = hash_password(password).unwrap();
println!("Hashed Password: {}", hashed_password);
}
fn main() {
let password = b"my_password";
let hashed_password = "$scrypt$0$14$8$1$asdfghjkl1234567890";
let is_valid = verify_password(password, hashed_password);
println!("Password is valid: {}", is_valid);
}
Scryptsalsa208sha256 Encryption
The gen_salt function generates a random salt using the randombytes_into function from the randombytes crate.
The derive_key function is used to derive a key from a password and salt using the scryptsalsa208sha256 algorithm. It takes the key buffer, password, salt, operational limit, and memory limit as parameters. The function modifies the key buffer in place and returns a result indicating success or failure.
The derive_key_interactive and derive_key_sensitive functions are convenience wrappers around derive_key with predefined operational and memory limits for interactive and sensitive scenarios, respectively.
The pwhash function generates a hashed password from a password using the scryptsalsa208sha256 algorithm. It takes the password, operational limit, and memory limit as parameters and returns a result containing the hashed password.
The pwhash_interactive and pwhash_sensitive functions are convenience wrappers around pwhash with predefined operational and memory limits for interactive and sensitive scenarios, respectively.
The pwhash_verify function is used to verify a password against a hashed password. It takes the hashed password and the password to be verified as parameters and returns a boolean indicating whether the verification succeeded or not.
Example Usage
fn main() {
let password = b"my_password";
// Generate a random salt
let salt = gen_salt();
// Derive a key from the password and salt
let mut derived_key = [0u8; 32];
derive_key_interactive(&mut derived_key, password, &salt).unwrap();
// Perform cryptographic operations using the derived key
// ...
// Verify a password
let hashed_password = pwhash(password, OPSLIMIT_INTERACTIVE, MEMLIMIT_INTERACTIVE).unwrap();
let is_valid = pwhash_verify(&hashed_password, password);
println!("Password is valid: {}", is_valid);
}
SHA1 Encryption
The sha1 function is the main entry point for calculating the SHA-1 hash. It takes an input byte slice and returns a 20-byte array representing the hash value. It follows the SHA-1 algorithm steps to process the input and update the internal state accordingly.
sha512: This function takes an input byte slice and returns a 64-byte array representing the SHA-512 hash of the input. It initializes the state with the initial hash values, pads the input message, and processes the message in blocks using the SHA-512 compression function.
The gen_key function generates a random key of length KEYBYTES using the randombytes_into function from the randombytes crate.
The pad_message function is used to add padding to the input message according to the SHA-1 specifications. It appends the bit 1 to the message, followed by zero or more 0 bytes to reach a certain length, and finally appends the original message length in bits. The resulting padded message is returned as a Vec
The create_word_array function converts a block of bytes into an array of 32-bit words, as required by the SHA-1 algorithm. It first converts each 4-byte chunk of the block into a u32 value using the from_be_bytes function. Then, it applies a transformation to generate the remaining words based on the previous words in the array.
Example Usage
SHA512 Encryption
pad_message: This function takes an input byte slice and returns a padded byte vector according to the SHA-512 padding scheme. It adds the bit 0x80 to mark the end of the message, appends padding bytes to reach a multiple of the block size, and appends the bit length of the original message.
create_word_array: This function takes a block (128 bytes) of input and returns an array of 80 64-bit words. It converts each 8-byte chunk of the block into a 64-bit word using big-endian byte order. It then expands the 16 initial words into the remaining 64 words using a specific formula.
Example Usage
SipHash24 Encryption
The shorthash function takes a message m and a key k as input and returns the hash of the message using the SipHash-2-4 algorithm. It uses the ffi::crypto_shorthash_siphash24 function from the ffi crate to perform the actual hash computation.
Example Usage