pub struct MD4_Generic<const N: usize = 4, const H0: u32 = 1732584193, const H1: u32 = 4023233417, const H2: u32 = 2562383102, const H3: u32 = 271733878, const ROUND: usize = 48, const K0: u32 = 0, const K1: u32 = 1518500249, const K2: u32 = 1859775393, const R00: u32 = 3, const R01: u32 = 7, const R02: u32 = 11, const R03: u32 = 19, const R10: u32 = 3, const R11: u32 = 5, const R12: u32 = 9, const R13: u32 = 13, const R20: u32 = 3, const R21: u32 = 9, const R22: u32 = 11, const R23: u32 = 15> { /* private fields */ }Expand description
A MD4 message-digest algorithm that lossily compresses data of arbitrary
length into a 128-bit hash value, and its flexible variants that allows
you to develop your own MD4-based hash algorithms
§Introduction
MD4 was designed by Ronald Rivest who is one of the inventors of RSA
asymmetric cryptographic algorithm. MD4 was invented in 1990. It was
specified in 1992 as RFC 1320.
This module provides not only the official MD4 but also its expanded
versions which is implemented with the name MD4_Generic.
MD4 uses the
Merkle–Damgård construction.
§Vulnerability
The security of MD4 has been severely compromised. Today, MD4 is not recommended for serious cryptographic purposes anymore. So, NIST also does not include MD4 in their list of recommended hashes for password storage. DO NOT USE MD4 FOR SERIOUS CRYPTOGRAPHIC PURPOSES AT ALL! If you need to use a hash algorithm for serious cryptographic purposes, you are highly recommended to use SHA-2 or SHA-3 hash algorithm, for example, instead of MD4.
§Use of MD4 and their variants
Though MD4 and its variants are lack of cryptographic security, MD4 and its variants can be still used for non-cryptograpic purposes such as:
- Generating small number of IDs
- Integrity test in some collision-free situations
- Storing passwords with limited security
- Key generation
- Study of hash algorithms
- Cryptanalysis Research to find the weakness of MD4 and Merkle-Damgard construction which MD2, MD4, MD5, SHA0, SHA1, and all SHA2 family use
§Generic Parameters
You can create your own expanded version of MD4 by changing the generic parameters N, H0 ~ H3, ROUND, K0 ~ K2, R00 ~ R03, R10 ~ R13, and R20 ~ R23.
- N : the size of output. N cannot be 0 or greater than 4. If N is 4, the output is 128 bits, while if N is 1, the output is 32 bits.
- H0 ~ H3 : the initial hash values, four u32 values. The default values of H0, H1, H2, and H3 are 0x67452301, 0xefcdab89, 0x98badcfe, and 0x10325476, respectively (in little endian representation).
- ROUND : the number of rounds. The default value of it is
48(= 16 * 3). - K0 ~ K2 : the added values in hashing process, three u32 values. The default values of K0, K1, and K2 are 0x00000000, 0x5A827999, and 0x6ED9EBA1, respectively (in little endian representation). 0x5A827999 is a 32-bit constant of the square root of 2 in little endian prepresentation. 0x6ED9EBA1 is a 32-bit constant of the square root of 3 in little endian prepresentation.
- R00 ~ R03, R10 ~ R13, and R20 ~ R23 : the amounts of rotate left in the hashing process. The default values of R00, R01, R02, and R03 are 3, 7, 11, and 19, respectively. The default values of R10, R11, R12, and R13 are 3, 5, 9, and 13, respectively. The default values of R20, R11, R12, and R23 are 3, 9, 11, and 15, respecively.
About the parameters and their default values, read more
§Security of your own expanded version
Your own algrorithm based on MD4 may be stronger or weaker than official MD4. Unless you seriously checked the cryptographic security of your own algorithms, it is hard to assume that your own alogrithms are stronger than the official MD4.
§Reference
Read more about MD4 in detail.
§Quick Start
In order to use the module MD4, you don’t have to import (or use) cryptocol::hash::md4::* directly because the module cryptocol::hash::md4 is re-exported. All you have to do is only import MD4, MD4_Expanded, MD4_Generic_HR_fixed and/or MD4_Generic in the module cryptocol::hash. Example 1 shows how to import structs MD4, MD4_Expanded, MD4_Generic_HR_fixed and/or MD4_Generic. Plus, what you have to know is these. All the types (or structs) are the specific versions of MD4_Generic. Actually, MD4 is a specific version of MD4_Expanded. MD4_Expanded and MD4_Generic_HR_fixed are specific versions of MD4_Generic.
§Example 1
use cryptocol::hash::MD4;
use cryptocol::hash::MD4_Expanded;
use cryptocol::hash::MD4_Generic_HR_fixed;
use cryptocol::hash::MD4_Generic;Then, you create MD4 object by the method MD4::new(). Now, you are ready to
use all provided methods to hash any data. If you want to hash a string,
for example, you can use the method digest_str(). Then, the MD4 object that
you created will contain its hash value. You can use the macro println!(),
for instance, to print on a commandline screen by println!("{}", hash)
where hash is the MD4 object. Example 2 shows how to use MD4 struct quickly.
§Example 2 for MD4
use std::string::*;
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let mut txt = "";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
assert_eq!(hash.get_hash_value_in_string(), "31D6CFE0D16AE931B73C59D7E0C089C0");
let txt_stirng = String::from("A");
hash.digest_string(&txt_stirng);
println!("Msg =\t\"{}\"\nHash =\t{}\n", txt_stirng, hash);
assert_eq!(hash.to_string(), "D5EF20EEB3F75679F86CF57F93ED0FFE");
let txt_array = ['W' as u8, 'o' as u8, 'w' as u8];
hash.digest_array(&txt_array);
println!("Msg =\t\"{:?}\"\nHash =\t{}\n", txt_array, hash);
assert_eq!(hash.get_hash_value_in_string(), "6407C0E728DA762A04924ADFE630974C");
txt = "This data is 26-byte long.";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
assert_eq!(hash.to_string(), "4F4A24D124B996BEA395344419F9A06B");
txt = "The unit of data length is not byte but bit.";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
assert_eq!(hash.get_hash_value_in_string(), "9DE35D8FCF68E74867FFB63F28625ABE");
txt = "I am testing MD4 for the data whose length is sixty-two bytes.";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
assert_eq!(hash.to_string(), "3A9F1487472B3A4315E0C90DC5CB3A2E");
txt = "I am testing MD4 for the message which is sixty-four bytes long.";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
assert_eq!(hash.get_hash_value_in_string(), "6CDB5B2BFF823A4A7B23675180EB7BEF");
txt = "I am testing MD4 for the case data whose length is more than sixty-four bytes is given.";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
assert_eq!(hash.to_string(), "56771653687981390B0EB2A7D0A40DBB");Example 3 shows how to use quickly MD4_Expanded which is the expanded version of MD4.
§Example 3 for MD4_Expanded
use std::string::*;
use cryptocol::hash::MD4_Expanded;
type MyMD4 = MD4_Expanded<4, 0x1111_1111, 0x4444_4444, 0x8888_8888, 0xffff_ffff, 96>;
let mut hash = MyMD4::new();
let mut txt = "";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
assert_eq!(hash.get_hash_value_in_string(), "13892AE087B903E5EC030A51E1BC720A");
let txt_stirng = String::from("A");
hash.digest_string(&txt_stirng);
println!("Msg =\t\"{}\"\nHash =\t{}\n", txt_stirng, hash);
assert_eq!(hash.to_string(), "0C0BE1B8893E47C005D95C69234141E9");
let txt_array = ['W' as u8, 'o' as u8, 'w' as u8];
hash.digest_array(&txt_array);
println!("Msg =\t\"{:?}\"\nHash =\t{}\n", txt_array, hash);
assert_eq!(hash.get_hash_value_in_string(), "17545CEB681C5B848234A557C5957AA7");
txt = "This data is 26-byte long.";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
assert_eq!(hash.to_string(), "70F3EA1DCDE46C65868DC0937E374433");
txt = "The unit of data length is not byte but bit.";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
assert_eq!(hash.get_hash_value_in_string(), "640B4635ED76F6574FC30AB233B74712");
txt = "I am testing MD4_Expanded for the data of the length 62 bytes.";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
assert_eq!(hash.to_string(), "B0D18D969B99F4BF48365449AF82EAFB");
txt = "I am testing MD4_Expanded for the message which is 64 byte-long.";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
assert_eq!(hash.get_hash_value_in_string(), "2D4ADABC3504B4A1B98FCCBFC48145AE");
txt = "I am testing MD4_Expanded for the case data whose length is more than 64 bytes is given.";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
assert_eq!(hash.to_string(), "26E5336E4D863BBAD6347918CE6DBAF5");§Big-endian issue
It is just experimental for Big Endian CPUs. So, you are not encouraged to use it for Big Endian CPUs for serious purpose. Only use this crate for Big-endian CPUs with your own full responsibility.
§A Simple but Useful Application using cryptocol
The following is the source code of the commandline MD4 hash value extractor using the struct MD4 of this module. You can get the hash value from a text or a file. The following source code assumes its executable file name will be “md4_app”. You can find all the examples including the following source code in the folder “examples” of this crate.
use std::{ io, env, fs };
use std::io::BufRead;
use std::convert::From;
use cryptocol::hash::MD4;
type HASH = MD4;
fn main()
{
let args: Vec<String> = env::args().collect();
if args.len() < 3
{
help();
return;
}
let arg = &args[1][..];
match arg
{
"--text" | "-t" => { get_hash_value_from_text(&args[2][..]); },
"--file" | "-f" => { get_hash_value_from_file(&args[2][..]); },
"--check" | "-c" => { check_files(&args[2][..]) },
_ => { help(); },
}
}
fn get_hash_value_from_text(txt: &str)
{
let mut hash = HASH::new();
hash.digest_str(txt);
println!("Hash value:\t{}", hash.get_hash_value_in_string());
}
fn get_hash_value_from_file(file: &str)
{
if let Ok(contents) = fs::read(file)
{
let mut hash = HASH::new();
hash.digest_vec(&contents);
println!("Hash value:\t{}", hash.get_hash_value_in_string());
}
else
{
println!("File Error!");
}
}
fn check_files(file_list: &str)
{
let mut reader;
match fs::File::open(file_list)
{
Ok(file) => {
reader = io::BufReader::new(file);
let mut line = String::new();
while let Ok(n) = reader.read_line(&mut line)
{
if n == 0
{ break; }
let txt = line.trim();
if txt.chars().nth(0).unwrap() == '#'
{
line.clear();
continue;
}
let elem: Vec<&str> = txt.split_whitespace().collect();
let item = elem[0];
let h = String::from(elem[1]).to_uppercase();
if let Ok(contents) = fs::read(item)
{
let mut hash = HASH::new();
hash.digest_vec(&contents);
if hash.to_string() == h
{ println!("{} ---> OK", item); }
else
{ println!("{} ---> Corrupted", item); }
}
line.clear();
}
},
_ => {
println!("File open error");
return;
}
}
}
fn help()
{
println!("This is an MD4 hash value extractor from a text or a file, using cryptocol.");
println!("Usage: md4_app <option> <source>");
println!("options description");
println!("--text, -t : <source> is a text to get a hash code.");
println!(" The text should be enclosed by ' or \".");
println!("--file, -f : <source> is the name of the file to get a hash code.");
println!("--check, -c : <source> is the name of the file that contains pairs");
println!(" of file and its hash code.");
println!("--help, -h : print this help message on screen\n");
println!("Examples:");
println!("\tmd4_app -t 'How are you doing?'");
println!("\tmd4_app -f linuxmint-21.3-cinnamon-64bit.iso");
println!("\tmd4_app -c CHECKSUM");
}Implementations§
Source§impl<const N: usize, const H0: u32, const H1: u32, const H2: u32, const H3: u32, const ROUND: usize, const K0: u32, const K1: u32, const K2: u32, const R00: u32, const R01: u32, const R02: u32, const R03: u32, const R10: u32, const R11: u32, const R12: u32, const R13: u32, const R20: u32, const R21: u32, const R22: u32, const R23: u32> MD4_Generic<N, H0, H1, H2, H3, ROUND, K0, K1, K2, R00, R01, R02, R03, R10, R11, R12, R13, R20, R21, R22, R23>
impl<const N: usize, const H0: u32, const H1: u32, const H2: u32, const H3: u32, const ROUND: usize, const K0: u32, const K1: u32, const K2: u32, const R00: u32, const R01: u32, const R02: u32, const R03: u32, const R10: u32, const R11: u32, const R12: u32, const R13: u32, const R20: u32, const R21: u32, const R22: u32, const R23: u32> MD4_Generic<N, H0, H1, H2, H3, ROUND, K0, K1, K2, R00, R01, R02, R03, R10, R11, R12, R13, R20, R21, R22, R23>
Sourcepub fn new() -> Self
pub fn new() -> Self
Constructs a new MD4 object or a new MD4-based hash object.
§Output
A new object of MD4 or a new MD4-based hash object.
§Initialization
All the attributes of the constructed object, which is initial hash
value, will be initialized with 0123456789ABCDEFFEDCBA9876543210 for
MD4. However, if you use your own MD4-expanded version, it will be
initialized with your special values H0 ~ H3.
§Example 1 for MD4
use cryptocol::hash::MD4;
let hash = MD4::new();
println!("Hash =\t{}", hash);
assert_eq!(hash.to_string(), "0123456789ABCDEFFEDCBA9876543210");§For more examples,
click here
Sourcepub fn digest(&mut self, message: *const u8, length_in_bytes: u64)
pub fn digest(&mut self, message: *const u8, length_in_bytes: u64)
Computes hash value.
§Features
This function has the generalized interface (pointer, *const u8)
so as to enable other functions to wrap this function with any
convenient interface for uses. So, this function is usually not called
directly in Rust. This function is provided to be called from other
programming languages such as C/C++.
§Arguments
messageis pointer to const u8.length_in_bytesis the size of message in the unit of bytes, and its data type isu64.
§Counterpart Methods
- If you want to compute of the hash value of a string slice, you are highly recommended to use the method digest_str() rather than this method.
- If you want to compute of the hash value of the content of String object, you are highly recommended to use the method digest_string() rather than this method.
- If you want to compute of the hash value of the content of Array object, you are highly recommended to use the method digest_array() rather than this method.
- If you want to compute of the hash value of the content of Vec object, you are highly recommended to use the method digest_vec() rather than this method.
§Example 1 for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let txt = "This is an example of the method digest().";
hash.digest(txt.as_ptr(), txt.len() as u64);
println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
assert_eq!(hash.to_string(), "A18836F660C3C66B8CBEE4BD24FEFFA9");§For more examples,
click here
Sourcepub fn digest_str(&mut self, message: &str)
pub fn digest_str(&mut self, message: &str)
Computes hash value.
§Features
This function is a wrapping function of digest().
This function computes hash value of the content of string slice.
§Argument
- message is
&str.
§Counterpart Methods
- If you want to compute of the hash value of the content of String object, you are highly recommended to use the method digest_string() rather than this method.
- If you want to compute of the hash value of the content of Array object, you are highly recommended to use the method digest_array() rather than this method.
- If you want to compute of the hash value of the content of Vec object, you are highly recommended to use the method digest_vec() rather than this method.
- If you want to use this method from other programming languages such as C/C++, you are highly recommended to use the method digest() rather than this method.
§Example 1 for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let txt = "This is an example of the method digest_str().";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
assert_eq!(hash.to_string(), "E396CE68E2BE1001BCBFD62B49E226C0");§For more examples,
click here
Sourcepub fn digest_string(&mut self, message: &String)
pub fn digest_string(&mut self, message: &String)
Computes hash value.
§Features
This function is a wrapping function of digest().
This function computes hash value of the content of String object.
§Argument
- message is
&String.
§Counterpart Methods
- If you want to compute of the hash value of a string slice, you are highly recommended to use the method digest_str() rather than this method.
- If you want to compute of the hash value of the content of Array object, you are highly recommended to use the method digest_array() rather than this method.
- If you want to compute of the hash value of the content of Vec object, you are highly recommended to use the method digest_vec() rather than this method.
- If you want to use this method from other programming languages such as C/C++, you are highly recommended to use the method digest() rather than this method.
§Example 1 for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let txt = "This is an example of the method digest_string().".to_string();
hash.digest_string(&txt);
println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
assert_eq!(hash.to_string(), "DF23C7808B2B158C5E2D8C9FE1FF2ECC");§For more examples,
click here
Sourcepub fn digest_array<T, const M: usize>(&mut self, message: &[T; M])
pub fn digest_array<T, const M: usize>(&mut self, message: &[T; M])
Computes hash value.
§Features
This function is a wrapping function of digest().
This function computes hash value of the content of Array object.
§Argument
- message is
&[T; M].
§Counterpart Methods
- If you want to compute of the hash value of a string slice, you are highly recommended to use the method digest_str() rather than this method.
- If you want to compute of the hash value of the content of String object, you are highly recommended to use the method digest_string() rather than this method.
- If you want to compute of the hash value of the content of Vec object, you are highly recommended to use the method digest_vec() rather than this method.
- If you want to use this method from other programming languages such as C/C++, you are highly recommended to use the method digest() rather than this method.
§Example 1 for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let data = [ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
hash.digest_array(&data);
println!("Msg =\t{:?}\nHash =\t{}", data, hash);
assert_eq!(hash.to_string(), "31489CF63B7FC170E9046F0176A60B39");§For more examples,
click here
Sourcepub fn digest_vec<T>(&mut self, message: &Vec<T>)
pub fn digest_vec<T>(&mut self, message: &Vec<T>)
Computes hash value.
§Features
This function is a wrapping function of digest().
This function computes hash value of the content of Vec object.
§Argument
- message is
&Vec<T>.
§Counterpart Methods
- If you want to compute of the hash value of a string slice, you are highly recommended to use the method digest_str() rather than this method.
- If you want to compute of the hash value of the content of String object, you are highly recommended to use the method digest_string() rather than this method.
- If you want to compute of the hash value of the content of Array object, you are highly recommended to use the method digest_array() rather than this method.
- If you want to use this method from other programming languages such as C/C++, you are highly recommended to use the method digest() rather than this method.
§Example 1 for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let data = vec![ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
hash.digest_vec(&data);
println!("Msg =\t{:?}\nHash =\t{}", data, hash);
assert_eq!(hash.to_string(), "31489CF63B7FC170E9046F0176A60B39");§For more examples,
click here
Sourcepub fn ruminate(&mut self, n: usize, message: *const u8, length_in_bytes: u64)
pub fn ruminate(&mut self, n: usize, message: *const u8, length_in_bytes: u64)
Computes a hash value of message, and then computes a new hash value
of the hash value of the message, and then computes a hash value of the
previous hash value, and then … n times repeatedly.
§Arguments
nis the number of repetition of digestionmessageis pointer to const u8.length_in_bytesis the size of message in the unit of bytes, and data type isu64.
§Origin
Double hashing is invented by Ferguson and Schneier in their book Practical Cryptography to countermeasure against length extension attacks. Plus, Bitcoin uses double hashing. This is generalized version of it.
§Features
This function has the generalized interface (pointer, *const u8)
so as to enable other functions to wrap this function with any
convenient interface for uses. So, this function is usually not called
directly in Rust. This function is provided to be called from other
programming languages such as C/C++.
§Security Issue
The author doubts that the double hashing is securer than normal hashing. The double hashing will be as secure as the normal hashing at most because birthday paradox applies twice for the double hashing though the size of the domain is the same size of the codomain for second hashing of the double hashing, while the birthday paradox applies only once for the normal hashing.
Example 1 for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let txt = "This is an example of the method ruminate().";
hash.ruminate(2, txt.as_ptr(), txt.len() as u64);
println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
assert_eq!(hash.to_string(), "23EAC3CEE64E4266EEDFE2D6AB255B9F");§For more examples,
click here
Sourcepub fn ruminate_str(&mut self, n: usize, message: &str)
pub fn ruminate_str(&mut self, n: usize, message: &str)
Computes a hash value of message, and then computes a new hash value
of the hash value of the message, and then computes a hash value of the
previous hash value, and then … n times repeatedly.
§Arguments
nis the number of repetition of digestionmessageis&str.
§Origin
Double hashing is invented by Ferguson and Schneier in their book Practical Cryptography to countermeasure against length extension attacks. Plus, Bitcoin uses double hashing. This is generalized version of it.
§Features
This function is a wrapping function of ruminate().
This function computes hash value of the content of string slice.
§Security Issue
The author doubts that the double hashing is securer than normal hashing. The double hashing will be as secure as the normal hashing at most because birthday paradox applies twice for the double hashing though the size of the domain is the same size of the codomain for second hashing of the double hashing, while the birthday paradox applies only once for the normal hashing.
Example 1 for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let txt = "This is an example of the method ruminate_str().";
hash.ruminate_str(3, txt);
println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
assert_eq!(hash.to_string(), "B19769E514631D59FD257C4AD667BD9D");§For more examples,
click here
Sourcepub fn ruminate_string(&mut self, n: usize, message: &String)
pub fn ruminate_string(&mut self, n: usize, message: &String)
Computes a hash value of message, and then computes a new hash value
of the hash value of the message, and then computes a hash value of the
previous hash value, and then … n times repeatedly.
§Arguments
nis the number of repetition of digestionmessageis&String.
§Origin
Double hashing is invented by Ferguson and Schneier in their book Practical Cryptography to countermeasure against length extension attacks. Plus, Bitcoin uses double hashing. This is generalized version of it.
§Features
This function is a wrapping function of ruminate().
This function computes hash value of the content of String object.
§Security Issue
The author doubts that the double hashing is securer than normal hashing. The double hashing will be as secure as the normal hashing at most because birthday paradox applies twice for the double hashing though the size of the domain is the same size of the codomain for second hashing of the double hashing, while the birthday paradox applies only once for the normal hashing.
Example 1 for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let txt = "This is an example of the method ruminate_string().".to_string();
hash.ruminate_string(2, &txt);
println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
assert_eq!(hash.to_string(), "71D3AB5636348DB24A7AE302E7E6C05A");§For more examples,
click here
Sourcepub fn ruminate_array<T, const M: usize>(&mut self, n: usize, message: &[T; M])
pub fn ruminate_array<T, const M: usize>(&mut self, n: usize, message: &[T; M])
Computes a hash value of message, and then computes a new hash value
of the hash value of the message, and then computes a hash value of the
previous hash value, and then … n times repeatedly.
§Arguments
nis the number of repetition of digestionmessageis&[T; M].
§Origin
Double hashing is invented by Ferguson and Schneier in their book Practical Cryptography to countermeasure against length extension attacks. Plus, Bitcoin uses double hashing. This is generalized version of it.
§Features
This function is a wrapping function of ruminate().
This function computes hash value of the content of Array object.
§Security Issue
The author doubts that the double hashing is securer than normal hashing. The double hashing will be as secure as the normal hashing at most because birthday paradox applies twice for the double hashing though the size of the domain is the same size of the codomain for second hashing of the double hashing, while the birthday paradox applies only once for the normal hashing.
Example 1 for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let data = [ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
hash.ruminate_array(5,&data);
println!("Msg =\t{:?}\nHash =\t{}", data, hash);
assert_eq!(hash.to_string(), "810F75A7BD28179BA2D4604A3092FBC8");§For more examples,
click here
Sourcepub fn ruminate_vec<T>(&mut self, n: usize, message: &Vec<T>)
pub fn ruminate_vec<T>(&mut self, n: usize, message: &Vec<T>)
Computes a hash value of message, and then computes a new hash value
of the hash value of the message, and then computes a hash value of the
previous hash value, and then … n times repeatedly.
§Arguments
nis the number of repetition of digestionmessageis&Vec<T>.
§Origin
Double hashing is invented by Ferguson and Schneier in their book Practical Cryptography to countermeasure against length extension attacks. Plus, Bitcoin uses double hashing. This is generalized version of it.
§Features
This function is a wrapping function of ruminate().
This function computes hash value of the content of Vec object.
§Security Issue
The author doubts that the double hashing is securer than normal hashing. The double hashing will be as secure as the normal hashing at most because birthday paradox applies twice for the double hashing though the size of the domain is the same size of the codomain for second hashing of the double hashing, while the birthday paradox applies only once for the normal hashing.
Example 1 for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let data = vec![ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
hash.ruminate_vec(2, &data);
println!("Msg =\t{:?}\nHash =\t{}", data, hash);
assert_eq!(hash.to_string(), "B3E296760B88B44613DB03D72CE59917");§For more examples,
click here
Sourcepub fn get_hash_value(&self, hash_value: *mut u8, length: usize)
pub fn get_hash_value(&self, hash_value: *mut u8, length: usize)
Gives a hash value to the place where hash_value points to.
§Features
This function has the generalized interface (pointer, *mut u8)
so as to enable other functions to wrap this function with any
convenient interface for uses. So, this function is usually not called
directly in Rust. This function is provided to be called from other
programming languages such as C/C++.
§Arguments
hash_valueis the pointer to the place to hold the result hash value.lengthis the size of the place thathash_valuepoints to.
§Counterpart Methods
- If you want to get the hash value in the form of String object, you are highly recommended to use the method get_hash_value_string() rather than this method.
- If you want to get the hash value in the form of array object, you are highly recommended to use the method get_hash_value_in_array() rather than this method.
- If you want to get the hash value in the form of Vec object, you are highly recommended to use the method get_hash_value_in_vec() rather than this method.
§Example 1 for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let txt = "This is an example of the method get_hash_value().";
let hash_value = [0_u8; 16];
hash.digest_str(txt);
hash.get_hash_value(hash_value.as_ptr() as *mut u8, hash_value.len());
println!("Msg =\t\"{}\"\nHash =\t{:02X?}", txt, hash_value);
assert_eq!(format!("{:02X?}", hash_value), "[A7, AD, DF, 36, A2, 43, 97, D1, 6D, 3C, 99, 78, A6, D5, 6E, 74]");§For more examples,
click here
Sourcepub fn get_hash_value_in_string(&self) -> String
pub fn get_hash_value_in_string(&self) -> String
Returns a hash value in the form of String object.
§Output
It returns String object.
§Counterpart Methods
- If you want to get the hash value in the form of array object, you are highly recommended to use the method get_hash_value_in_array() rather than this method.
- If you want to get the hash value in the form of Vec object, you are highly recommended to use the method get_hash_value_in_vec() rather than this method.
- If you want to use this method from other programming languages such as C/C++, you are highly recommended to use the method get_hash_value() rather than this method.
§Example 1 for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let txt = "This is an example of the method get_hash_value_in_string().";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash.get_hash_value_in_string());
assert_eq!(hash.get_hash_value_in_string(), "FA48527AD8257A371E70AA9473D425D6");§For more examples,
click here
Sourcepub fn get_hash_value_in_array(&self) -> [u32; N]
pub fn get_hash_value_in_array(&self) -> [u32; N]
Returns a hash value in the form of array object.
§Output
It returns [u32; N].
§Counterpart Methods
- If you want to get the hash value in any form of Array object, you are highly recommended to use the method put_hash_value_in_array() rather than this method.
- If you want to get the hash value in the form of String object, you are highly recommended to use the method get_hash_value_in_string() rather than this method.
- If you want to get the hash value in the form of Vec object, you are highly recommended to use the method get_hash_value_in_vec() rather than this method.
- If you want to use this method from other programming languages such as C/C++, you are highly recommended to use the method get_hash_value() rather than this method.
§Example 1 for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let txt = "This is an example of the method get_hash_value_in_array().";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{:08X?}", txt, hash.get_hash_value_in_array());
assert_eq!(format!("{:08X?}", hash.get_hash_value_in_array()), "[832C724B, 4A73A717, 5EA679B8, E991D13B]");§For more examples,
click here
Sourcepub fn get_hash_value_in_vec(&self) -> Vec<u32>
pub fn get_hash_value_in_vec(&self) -> Vec<u32>
Returns a hash value in the form of Vec object.
§Output
It returns Vec<u32>.
§Counterpart Methods
- If you want to get the hash value in the form of String object, you are highly recommended to use the method get_hash_value_string() rather than this method.
- If you want to get the hash value in the form of array object, you are highly recommended to use the method get_hash_value_in_array() rather than this method.
- If you want to use this method from other programming languages such as C/C++, you are highly recommended to use the method get_hash_value() rather than this method.
§Example 1 for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let txt = "This is an example of the method get_hash_value_in_vec().";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{:08X?}", txt, hash.get_hash_value_in_vec());
assert_eq!(format!("{:08X?}", hash.get_hash_value_in_vec()), "[EE74475E, ECA09C8F, 038A89A3, 9B2A6C4F]");§For more examples,
click here
Sourcepub fn put_hash_value_in_array<T, const M: usize>(&self, out: &mut [T; M])
pub fn put_hash_value_in_array<T, const M: usize>(&self, out: &mut [T; M])
Puts a hash value in the form of array object.
§Argument
out is the array [T; M] which is the place to put the hash value.
§Features
If M * mem::size_of::<T>() > mem::size_of::<u32>() * N,
it pass the output as the amount of mem::size_of::<u32>() * N.
§Example 1 for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let txt = "This is an example of the method put_hash_value_in_array().";
let mut hash_code = [0_u32; 4];
hash.digest_str(txt);
hash.put_hash_value_in_array(&mut hash_code);
println!("Msg =\t\"{}\"\nHash =\t{:08X?}", txt, hash_code);
assert_eq!(format!("{:08X?}", hash_code), "[147DD795, C34F9C9D, 80B94C86, FB922262]");§For more examples,
click here
Sourcepub fn tangle(&mut self, tangling: u64)
pub fn tangle(&mut self, tangling: u64)
Tangles the hash value
§Argument
u32 constant to tangle the hash value
§Features
It is for using this struct as random number generator.
Example for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let txt = "TANGLING";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{:08X?}", txt, hash.get_hash_value_in_array());
assert_eq!(format!("{:08X?}", hash.get_hash_value_in_array()), "[BC65D6E1, F0F37B4E, 2F404331, A8F25E2A]");
hash.tangle(1);
println!("Hash =\t{:08X?}", hash.get_hash_value_in_array());
assert_eq!(format!("{:08X?}", hash.get_hash_value_in_array()), "[CE1E07A3, F3373D70, 95A8F098, 9BC7894E]");
hash.tangle(1);
println!("Hash =\t{:08X?}", hash.get_hash_value_in_array());
assert_eq!(format!("{:08X?}", hash.get_hash_value_in_array()), "[5B9A2D14, 64888002, 15282E23, E5B2F4BD]");§For more examples,
click here
Trait Implementations§
Source§impl<const N: usize, const H0: u32, const H1: u32, const H2: u32, const H3: u32, const ROUND: usize, const K0: u32, const K1: u32, const K2: u32, const R00: u32, const R01: u32, const R02: u32, const R03: u32, const R10: u32, const R11: u32, const R12: u32, const R13: u32, const R20: u32, const R21: u32, const R22: u32, const R23: u32> Clone for MD4_Generic<N, H0, H1, H2, H3, ROUND, K0, K1, K2, R00, R01, R02, R03, R10, R11, R12, R13, R20, R21, R22, R23>
impl<const N: usize, const H0: u32, const H1: u32, const H2: u32, const H3: u32, const ROUND: usize, const K0: u32, const K1: u32, const K2: u32, const R00: u32, const R01: u32, const R02: u32, const R03: u32, const R10: u32, const R11: u32, const R12: u32, const R13: u32, const R20: u32, const R21: u32, const R22: u32, const R23: u32> Clone for MD4_Generic<N, H0, H1, H2, H3, ROUND, K0, K1, K2, R00, R01, R02, R03, R10, R11, R12, R13, R20, R21, R22, R23>
Source§fn clone(
&self,
) -> MD4_Generic<N, H0, H1, H2, H3, ROUND, K0, K1, K2, R00, R01, R02, R03, R10, R11, R12, R13, R20, R21, R22, R23>
fn clone( &self, ) -> MD4_Generic<N, H0, H1, H2, H3, ROUND, K0, K1, K2, R00, R01, R02, R03, R10, R11, R12, R13, R20, R21, R22, R23>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<const N: usize, const H0: u32, const H1: u32, const H2: u32, const H3: u32, const ROUND: usize, const K0: u32, const K1: u32, const K2: u32, const R00: u32, const R01: u32, const R02: u32, const R03: u32, const R10: u32, const R11: u32, const R12: u32, const R13: u32, const R20: u32, const R21: u32, const R22: u32, const R23: u32> Debug for MD4_Generic<N, H0, H1, H2, H3, ROUND, K0, K1, K2, R00, R01, R02, R03, R10, R11, R12, R13, R20, R21, R22, R23>
impl<const N: usize, const H0: u32, const H1: u32, const H2: u32, const H3: u32, const ROUND: usize, const K0: u32, const K1: u32, const K2: u32, const R00: u32, const R01: u32, const R02: u32, const R03: u32, const R10: u32, const R11: u32, const R12: u32, const R13: u32, const R20: u32, const R21: u32, const R22: u32, const R23: u32> Debug for MD4_Generic<N, H0, H1, H2, H3, ROUND, K0, K1, K2, R00, R01, R02, R03, R10, R11, R12, R13, R20, R21, R22, R23>
Source§impl<const N: usize, const H0: u32, const H1: u32, const H2: u32, const H3: u32, const ROUND: usize, const K0: u32, const K1: u32, const K2: u32, const R00: u32, const R01: u32, const R02: u32, const R03: u32, const R10: u32, const R11: u32, const R12: u32, const R13: u32, const R20: u32, const R21: u32, const R22: u32, const R23: u32> Display for MD4_Generic<N, H0, H1, H2, H3, ROUND, K0, K1, K2, R00, R01, R02, R03, R10, R11, R12, R13, R20, R21, R22, R23>
impl<const N: usize, const H0: u32, const H1: u32, const H2: u32, const H3: u32, const ROUND: usize, const K0: u32, const K1: u32, const K2: u32, const R00: u32, const R01: u32, const R02: u32, const R03: u32, const R10: u32, const R11: u32, const R12: u32, const R13: u32, const R20: u32, const R21: u32, const R22: u32, const R23: u32> Display for MD4_Generic<N, H0, H1, H2, H3, ROUND, K0, K1, K2, R00, R01, R02, R03, R10, R11, R12, R13, R20, R21, R22, R23>
Source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Formats the value using the given formatter.
You will hardly use this method directly.
Automagically the function to_string() will be implemented. So, you
can use the function to_string(), and you can also print the MD4
object in the macro println!() directly for example.
f is a buffer, this method must write the formatted string into it.
Read more
§Example 1 for the method to_string() for MD4
use cryptocol::hash::MD4;
let mut hash = MD4::new();
let txt = "Display::fmt() automagically implement to_string().";
hash.digest_str(txt);
println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash.to_string());
assert_eq!(hash.to_string(), "E2244B71E17D5BD7E1CCEB58C8F8C82E");§For more examples,
click here