cryptocol/hash/
sha2_512_t.rs

1// Copyright 2023, 2024, 2025 PARK Youngho.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6// This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! The module that contains SHA1 hash algorithm
10
11// #![warn(missing_docs)]
12// #![warn(rustdoc::missing_doc_code_examples)]
13
14use std::fmt::{ self, Debug, Display, Formatter };
15use std::ptr::copy_nonoverlapping;
16
17use crate::number::{ SmallUInt, LongUnion };
18
19
20/// You have freedom of changing t, A5A5A5A5A5A5A5A5, H0 ~ H7, and ROUND
21/// for SHA-2-512/t.
22/// 
23/// # Generic Parameters
24/// You can create your own expanded version of SHA-2-512/t by changing the
25/// generic parameters t, A5A5A5A5A5A5A5A5, H0 ~ H7, and ROUND.
26/// - t : the truncating bit at which the output is constructed by truncating
27/// the concatenation of h0 through h7. t should be multiple of 8 and equal to
28/// or less than 512. If t is not a multiple of eight, t will be overestimated
29/// to make a multiple of eight. The default value of t is 512.
30/// - A5A5A5A5A5A5A5A5 : the hexadecimal constant with which its initial values
31/// h0 through h7 have each been XORed.
32/// The default value of A5A5A5A5A5A5A5A5 is 0xa5a5a5a5a5a5a5a5. 
33/// - H0 ~ H7 : the initial hash values, eight u32 values.
34/// The default values of H0 ~ H7 are defined to be first 64 bits of the
35/// fractional parts of the square roots of the first 8 primes 2..19. So,
36/// H0 ~ H7 are 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b,
37/// 0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
38/// 0x1f83d9abfb41bd6b, and 0x5be0cd19137e2179, respectively (in big endian
39/// representation).
40/// - ROUND : the number of rounds. The default value of it is `80` (= 20 * 4).
41#[allow(non_camel_case_types)]
42#[allow(non_upper_case_globals)]
43pub type SHA2_512_t_Expanded<const t: usize = 512,
44                const A5A5A5A5A5A5A5A5: u64 = 0xa5a5a5a5a5a5a5a5,
45                const H0: u64 = 0x6a09e667f3bcc908, const H1: u64 = 0xbb67ae8584caa73b,
46                const H2: u64 = 0x3c6ef372fe94f82b, const H3: u64 = 0xa54ff53a5f1d36f1,
47                const H4: u64 = 0x510e527fade682d1, const H5: u64 = 0x9b05688c2b3e6c1f,
48                const H6: u64 = 0x1f83d9abfb41bd6b, const H7: u64 = 0x5be0cd19137e2179,
49                const ROUND: usize = 80>
50    = SHA2_512_t_Generic<t, A5A5A5A5A5A5A5A5, H0, H1, H2, H3, H4, H5, H6, H7, ROUND>;
51
52/// You have freedom of changing A5A5A5A5A5A5A5A5 and ROUND for HA-2-512/256.
53/// 
54/// # Generic Parameters
55/// You can create your own expanded version of SHA-2-512/256 by changing the
56/// generic parameters A5A5A5A5A5A5A5A5 and ROUND.
57/// - A5A5A5A5A5A5A5A5 : the hexadecimal constant with which its initial values
58/// h0 through h7 have each been XORed.
59/// The default value of A5A5A5A5A5A5A5A5 is 0xa5a5a5a5a5a5a5a5.
60/// - ROUND : the number of rounds. The default value of it is `80` (= 20 * 4).
61#[allow(non_camel_case_types)]
62pub type SHA2_512_t_256_Expanded<const A5A5A5A5A5A5A5A5: u64 = 0xa5a5a5a5a5a5a5a5,
63                                const ROUND: usize = 80>
64            = SHA2_512_t_Expanded<256, A5A5A5A5A5A5A5A5,
65                                0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
66                                0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
67                                0x510e527fade682d1, 0x9b05688c2b3e6c1f,
68                                0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, ROUND>;
69
70/// You have freedom of changing A5A5A5A5A5A5A5A5 and ROUND for SHA-2-512/224.
71/// 
72/// # Generic Parameters
73/// You can create your own expanded version of SHA-2-512/224 by changing the
74/// generic parameters A5A5A5A5A5A5A5A5 and ROUND.
75/// - A5A5A5A5A5A5A5A5 : the hexadecimal constant with which its initial values
76/// h0 through h7 have each been XORed.
77/// The default value of A5A5A5A5A5A5A5A5 is 0xa5a5a5a5a5a5a5a5.
78/// - ROUND : the number of rounds. The default value of it is `80` (= 20 * 4).
79#[allow(non_camel_case_types)]
80pub type SHA2_512_t_224_Expanded<const A5A5A5A5A5A5A5A5: u64 = 0xa5a5a5a5a5a5a5a5,
81                                const ROUND: usize = 80>
82            = SHA2_512_t_Expanded<224, A5A5A5A5A5A5A5A5,
83                                0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
84                                0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
85                                0x510e527fade682d1, 0x9b05688c2b3e6c1f,
86                                0x1f83d9abfb41bd6b, 0x5be0cd19137e2179, ROUND>;
87
88/// You have freedom of changing t, ROUND, and K00 ~ K79 for SHA-2-512/t.
89/// 
90/// # Generic Parameters
91/// You can create your own expanded version of SHA-2-512/t by changing the
92/// generic parameters t, ROUND, and K00 ~ K79.
93/// - t : the truncating bit at which the output is constructed by truncating
94/// the concatenation of h0 through h7. t should be multiple of 8 and equal to
95/// or less than 512. If t is not a multiple of eight, t will be overestimated
96/// to make a multiple of eight. The default value of t is 512.
97/// - ROUND : the number of rounds. The default value of it is `80` (= 20 * 4).
98/// - K0 ~ K79 : the added values in hashing process, which are eighty u64
99/// values and called round constants.
100/// The default values of K0 ~ K79 are defined to be first 64 bits of the
101/// fractional parts of the cube roots of the first 80 primes 2..409,
102/// respectivey (in big endian representation). So, K0 ~ K79 are 
103/// 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
104/// 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
105/// 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
106/// 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
107/// 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
108/// 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
109/// 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
110/// 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
111/// 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
112/// 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
113/// 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
114/// 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
115/// 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
116/// 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
117/// 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
118/// 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
119/// 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
120/// 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
121/// 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
122/// 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817,
123/// respectively (in big endian representation).
124#[allow(non_camel_case_types)]
125#[allow(non_upper_case_globals)]
126pub type SHA2_512_t_Generic_HRS_fixed<const t: usize = 512, const ROUND: usize = 80,
127                const K00: u64 = 0x428a2f98d728ae22, const K01: u64 = 0x7137449123ef65cd, 
128                const K02: u64 = 0xb5c0fbcfec4d3b2f, const K03: u64 = 0xe9b5dba58189dbbc,
129                const K04: u64 = 0x3956c25bf348b538, const K05: u64 = 0x59f111f1b605d019, 
130                const K06: u64 = 0x923f82a4af194f9b, const K07: u64 = 0xab1c5ed5da6d8118,
131                const K08: u64 = 0xd807aa98a3030242, const K09: u64 = 0x12835b0145706fbe, 
132                const K10: u64 = 0x243185be4ee4b28c, const K11: u64 = 0x550c7dc3d5ffb4e2,
133                const K12: u64 = 0x72be5d74f27b896f, const K13: u64 = 0x80deb1fe3b1696b1, 
134                const K14: u64 = 0x9bdc06a725c71235, const K15: u64 = 0xc19bf174cf692694,
135                const K16: u64 = 0xe49b69c19ef14ad2, const K17: u64 = 0xefbe4786384f25e3, 
136                const K18: u64 = 0x0fc19dc68b8cd5b5, const K19: u64 = 0x240ca1cc77ac9c65,
137                const K20: u64 = 0x2de92c6f592b0275, const K21: u64 = 0x4a7484aa6ea6e483, 
138                const K22: u64 = 0x5cb0a9dcbd41fbd4, const K23: u64 = 0x76f988da831153b5,
139                const K24: u64 = 0x983e5152ee66dfab, const K25: u64 = 0xa831c66d2db43210, 
140                const K26: u64 = 0xb00327c898fb213f, const K27: u64 = 0xbf597fc7beef0ee4,
141                const K28: u64 = 0xc6e00bf33da88fc2, const K29: u64 = 0xd5a79147930aa725, 
142                const K30: u64 = 0x06ca6351e003826f, const K31: u64 = 0x142929670a0e6e70,
143                const K32: u64 = 0x27b70a8546d22ffc, const K33: u64 = 0x2e1b21385c26c926, 
144                const K34: u64 = 0x4d2c6dfc5ac42aed, const K35: u64 = 0x53380d139d95b3df,
145                const K36: u64 = 0x650a73548baf63de, const K37: u64 = 0x766a0abb3c77b2a8, 
146                const K38: u64 = 0x81c2c92e47edaee6, const K39: u64 = 0x92722c851482353b,
147                const K40: u64 = 0xa2bfe8a14cf10364, const K41: u64 = 0xa81a664bbc423001, 
148                const K42: u64 = 0xc24b8b70d0f89791, const K43: u64 = 0xc76c51a30654be30,
149                const K44: u64 = 0xd192e819d6ef5218, const K45: u64 = 0xd69906245565a910, 
150                const K46: u64 = 0xf40e35855771202a, const K47: u64 = 0x106aa07032bbd1b8,
151                const K48: u64 = 0x19a4c116b8d2d0c8, const K49: u64 = 0x1e376c085141ab53, 
152                const K50: u64 = 0x2748774cdf8eeb99, const K51: u64 = 0x34b0bcb5e19b48a8,
153                const K52: u64 = 0x391c0cb3c5c95a63, const K53: u64 = 0x4ed8aa4ae3418acb, 
154                const K54: u64 = 0x5b9cca4f7763e373, const K55: u64 = 0x682e6ff3d6b2b8a3,
155                const K56: u64 = 0x748f82ee5defb2fc, const K57: u64 = 0x78a5636f43172f60, 
156                const K58: u64 = 0x84c87814a1f0ab72, const K59: u64 = 0x8cc702081a6439ec,
157                const K60: u64 = 0x90befffa23631e28, const K61: u64 = 0xa4506cebde82bde9, 
158                const K62: u64 = 0xbef9a3f7b2c67915, const K63: u64 = 0xc67178f2e372532b,
159                const K64: u64 = 0xca273eceea26619c, const K65: u64 = 0xd186b8c721c0c207, 
160                const K66: u64 = 0xeada7dd6cde0eb1e, const K67: u64 = 0xf57d4f7fee6ed178,
161                const K68: u64 = 0x06f067aa72176fba, const K69: u64 = 0x0a637dc5a2c898a6, 
162                const K70: u64 = 0x113f9804bef90dae, const K71: u64 = 0x1b710b35131c471b,
163                const K72: u64 = 0x28db77f523047d84, const K73: u64 = 0x32caab7b40c72493, 
164                const K74: u64 = 0x3c9ebe0a15c9bebc, const K75: u64 = 0x431d67c49c100d4c,
165                const K76: u64 = 0x4cc5d4becb3e42b6, const K77: u64 = 0x597f299cfc657e2a, 
166                const K78: u64 = 0x5fcb6fab3ad6faec, const K79: u64 = 0x6c44198c4a475817>
167    = SHA2_512_t_Generic<t, 0xa5a5a5a5a5a5a5a5,
168                            0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
169                            0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
170                            0x510e527fade682d1, 0x9b05688c2b3e6c1f,
171                            0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
172                            ROUND,  
173                            K00, K01, K02, K03, K04, K05, K06, K07,
174                            K08, K09, K10, K11, K12, K13, K14, K15,
175                            K16, K17, K18, K19, K20, K21, K22, K23,
176                            K24, K25, K26, K27, K28, K29, K30, K31,
177                            K32, K33, K34, K35, K36, K37, K38, K39,
178                            K40, K41, K42, K43, K44, K45, K46, K47,
179                            K48, K49, K50, K51, K52, K53, K54, K55,
180                            K56, K57, K58, K59, K60, K61, K62, K63,
181                            K64, K65, K66, K67, K68, K69, K70, K71,
182                            K72, K73, K74, K75, K76, K77, K78, K79,
183                            1, 8, 14, 18, 19, 28, 34, 39, 41, 61, 6, 7>;
184
185/// You have freedom of changing t for SHA-2-512/t.
186/// 
187/// # Generic Parameters
188/// You can create your own expanded version of SHA-2-512/t by changing the
189/// generic parameter t.
190/// - t : the truncating bit at which the output is constructed by truncating
191/// the concatenation of h0 through h7. t should be multiple of 8 and equal to
192/// or less than 512. If t is not a multiple of eight, t will be overestimated
193/// to make a multiple of eight. The default value of t is 512.
194#[allow(non_camel_case_types)]
195#[allow(non_upper_case_globals)]
196pub type SHA2_512_t<const t: usize = 512> = SHA2_512_t_Generic<t>;
197// equivalent to `pub type SHA2_512_t<const t: usize = 512> = SHA2_512_t_Expanded<t>;`
198
199/// The official SHA-512/256 hash algorithm
200#[allow(non_camel_case_types)]
201pub type SHA2_512_t_256 = SHA2_512_t_Generic<256>;
202// equivalent to `pub type SHA2_512_t_256 = SHA2_512_t_256_Expanded;`
203
204/// The official SHA-512/224 hash algorithm
205#[allow(non_camel_case_types)]
206pub type SHA2_512_t_224 = SHA2_512_t_Generic<224>;
207// equivalent to `pub type SHA2_512_t_224 = SHA2_512_t_224_Expanded;`
208
209/// The simulation of the official SHA-512 hash algorithm
210#[allow(non_camel_case_types)]
211pub type SHA2_512_0 = SHA2_512_t_Generic;
212// equivalent to `pub type SHA2_512_0 = SHA2_512_t;`
213
214
215/// SHA-2-512/t message-digest algorithm that lossily compresses data of
216/// arbitrary length into a any-bit hash values less than 512 bits, and
217/// its flexible variants that allows you to develop your own
218/// `SHA-2-512/t`-based hash algorithms
219/// 
220/// # Introduction
221/// Keccak was designed by the United States National Security Agency,
222/// and are a U.S. Federal Information Processing Standard. SHA-2-512/t
223/// produces a message digest based on principles similar to those used by
224/// Ronald L. Rivest of MIT in the design of the MD2, MD4, MD5, SHA0, SHA-1,
225/// SHA-2-256, SHA-2-224, SHA-2-512. and SHA-2-512-384 message digest
226/// algorithms, but generates a flexible hash value (t bits vs. 256, 224, 160
227/// bits and 128 bits). SHA-2-512/t uses the
228/// [Merkle–Damgård construction](https://en.wikipedia.org/wiki/Merkle%E2%80%93Damg%C3%A5rd_construction).
229/// 
230/// # Vulnerability
231/// There have been several attacks against Keccak
232/// but they are all incomplete attacks.
233/// Read [more](https://en.wikipedia.org/wiki/SHA-2#Cryptanalysis_and_validation)
234/// 
235/// # Use of SHA-2-512/t and their variations
236/// You can use SHA-2-512/t for cryptographic purposes such as:
237/// - Generating IDs
238/// - Integrity test
239/// - Storing passwords
240/// - Digital Signature
241/// - Key generation
242/// - Implementing proof of work for block chain.
243/// - Study of hash algorithms
244/// - Cryptanalysis Research to find the weakness of SHA-512/t and Merkle-Damgard
245/// construction which MD2, MD4, MD5, SHA0, SHA1, and all SHA2 family use
246/// 
247/// # Generic Parameters
248/// You can create your own expanded version of SHA-2-512/t by changing the
249/// generic parameters t, A5A5A5A5A5A5A5A5, H0 ~ H7, ROUND, K00 ~ K79, RR1,
250/// RR8, RR14, RR18, RR19, RR28, RR34, RR39, RR41, RR61, SR6, and SR7.
251/// - t : the truncating bit at which the output is constructed by truncating
252/// the concatenation of h0 through h7. t should be multiple of 8 and equal to
253/// or less than 512. If t is not a multiple of eight, t will be overestimated
254/// to make a multiple of eight. The default value of t is 512.
255/// - A5A5A5A5A5A5A5A5 : the hexadecimal constant with which its initial values
256/// h0 through h7 have each been XORed.
257/// The default value of A5A5A5A5A5A5A5A5 is 0xa5a5a5a5a5a5a5a5. 
258/// - H0 ~ H7 : the initial hash values, eight u32 values.
259/// The default values of H0 ~ H7 are defined to be first 64 bits of the
260/// fractional parts of the square roots of the first 8 primes 2..19. So,
261/// H0 ~ H7 are 0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b,
262/// 0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
263/// 0x1f83d9abfb41bd6b, and 0x5be0cd19137e2179, respectively (in big endian
264/// representation).
265/// - ROUND : the number of rounds. The default value of it is `80` (= 20 * 4).
266/// - K0 ~ K79 : the added values in hashing process, which are eighty u64
267/// values and called round constants.
268/// The default values of K0 ~ K79 are defined to be first 64 bits of the
269/// fractional parts of the cube roots of the first 80 primes 2..409,
270/// respectivey (in big endian representation). So, K0 ~ K79 are 
271/// 0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
272/// 0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
273/// 0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
274/// 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
275/// 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
276/// 0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
277/// 0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
278/// 0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
279/// 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
280/// 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
281/// 0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
282/// 0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
283/// 0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
284/// 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
285/// 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
286/// 0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
287/// 0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
288/// 0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
289/// 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
290/// 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817,
291/// respectively (in big endian representation).
292/// - RR1, RR8, RR14, RR18, RR19, RR28, RR34, RR39, RR41, and RR61 : the amounts
293/// of rotate right in the hashing process.
294/// The default values of RR1, RR8, RR14, RR18, RR19, RR28, RR34, RR39, RR41,
295/// and RR61 are 1, 8, 14, 18, 19, 28, 34, 39, 41, and 61, respecively.
296/// - SR6 and SR7 : the amounts of shift right in the hashing process.
297/// The default values of SR6 and SR7 are 6 and 7 respectively.
298/// 
299/// About the parameters and their default values,
300/// read [more](https://en.wikipedia.org/wiki/SHA-2#Pseudocode)
301/// 
302/// # Security of your own expanded version
303/// Your own algrorithm based on SHA-2-512/t may be stronger or weaker than
304/// official SHA-2-512/t. Unless you seriously checked the cryptographic
305/// security of your own algorithms, it is hard to assume that your own
306/// alogrithms are stronger than the official SHA-2-512/t.
307/// 
308/// Read [this](https://doi.org/10.6028/NIST.FIPS.180-4)
309/// and [that](https://en.wikipedia.org/wiki/SHA-2)
310/// 
311/// # Quick Start
312/// In order to use the module sha2_512_t, you don't have to import (or use)
313/// cryptocol::hash::sha2_512_t::* directly because the module
314/// cryptocol::hash::sha2_512_t is re-exported. All you have to do is only
315/// import SHA2_512_t, SHA2_512_t_256, SHA2_512_t_224, SHA2_512_0,
316/// SHA2_512_t_Expanded, SHA2_512_t_256_Expanded, SHA2_512_t_224_Expanded,
317/// SHA2_512_t_Generic_HRS_fixed, and/or SHA2_512_t_Generic in the module
318/// cryptocol::hash. Example 1 shows how to import structs SHA2_512_t,
319/// SHA2_512_t_256, SHA2_512_t_224, SHA2_512_0, SHA2_512_t_Expanded,
320/// SHA2_512_t_256_Expanded, SHA2_512_t_224_Expanded,
321/// SHA2_512_t_Generic_HRS_fixed, and/or SHA2_512_t_Generic. Plus, what you
322/// have to know is these. All the types (or structs) are the specific versions
323/// of SHA2_512_t_Generic. Actually, SHA2_512_0 is a specific version of
324/// SHA2_512_t. SHA2_512_t_256 is a specific version of SHA2_512_t_256_Expanded.
325/// SHA2_512_t_224 is a specific version of SHA2_512_t_224_Expanded. 
326/// SHA2_512_t, SHA2_512_t_256_Expanded, and SHA2_512_t_224_Expanded
327/// are specific versions of SHA2_512_t_Expanded. SHA2_512_t_Expanded and
328/// SHA2_512_t_Generic_HRS_fixed are specific versions of SHA2_512_t_Generic.
329/// 
330/// ## Example 1
331/// ```
332/// use cryptocol::hash::SHA2_512_0;
333/// use cryptocol::hash::SHA2_512_t;
334/// use cryptocol::hash::SHA2_512_t_256;
335/// use cryptocol::hash::SHA2_512_t_224;
336/// use cryptocol::hash::SHA2_512_t_Expanded;
337/// use cryptocol::hash::SHA2_512_t_256_Expanded;
338/// use cryptocol::hash::SHA2_512_t_224_Expanded;
339/// use cryptocol::hash::SHA2_512_t_Generic_HRS_fixed;
340/// use cryptocol::hash::SHA2_512_t_Generic;
341/// ```
342/// Then, you can create SHA1 object by the method SHA1::new() for example.
343/// Now, you are ready to use all prepared methods to hash any data. If you
344/// want to hash a string, for example, you can use the method digest_str().
345/// Then, the SHA1 object that you created will contain its hash value. You can
346/// use the macro println!() for instance to print on a commandline screen by
347/// `println!("{}", hash)` where hash is the SHA1 object.
348/// Example 2 shows how to use SHA1 struct quickly.
349/// 
350/// ## Example 2 for SHA-512/256
351/// ```
352/// use std::string::*;
353/// use cryptocol::hash::SHA2_512_t_256;
354/// let mut hash = SHA2_512_t_256::new();
355/// 
356/// let mut txt = "";
357/// hash.digest_str(txt);
358/// println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash.get_hash_value_in_string());
359/// assert_eq!(hash.get_hash_value_in_string(), "C672B8D1EF56ED28AB87C3622C5114069BDD3AD7B8F9737498D0C01ECEF0967A");
360/// 
361/// let txt_stirng = String::from("A");
362/// hash.digest_string(&txt_stirng);
363/// println!("Msg =\t\"{}\"\nHash =\t{}\n", txt_stirng, hash);
364/// assert_eq!(hash.to_string(), "65A992AD19967492B5780D76A4733AF553F796F688B79102D01EC7FDE5590CAB");
365/// 
366/// let txt_array = ['W' as u8, 'o' as u8, 'w' as u8];
367/// hash.digest_array(&txt_array);
368/// println!("Msg =\t\"{:?}\"\nHash =\t{}\n", txt_array, hash);
369/// assert_eq!(hash.get_hash_value_in_string(), "E4AF36E824AFDB9E42291983AFA292B894DED2CCAFCCF53346B223FCA846694D");
370/// 
371/// txt = "The length of this message is forty-eight bytes.";
372/// hash.digest_str(txt);
373/// println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
374/// assert_eq!(hash.to_string(), "4E730BDADF49EC9F3E920F72EAD3AC8D09B459900BE4F6E27848652632277205");
375/// 
376/// txt = "The unit of the message length is not byte but bit.";
377/// hash.digest_str(txt);
378/// println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
379/// assert_eq!(hash.get_hash_value_in_string(), "AE0EAB6824897F575FCC051DBC2D1AA7F7BF0DB2C80172F639CE20B3B498C9D5");
380/// 
381/// txt = "This algorithm SHA-2/512/256 is being tested with this message, the length of which is one hundred twelve bytes.";
382/// hash.digest_str(txt);
383/// println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
384/// assert_eq!(hash.to_string(), "7876C6F1285C4B6EC6A2F4A76BBF81815B470536F3A38B7028AA88A3C5C31651");
385/// 
386/// txt = "This algorithm SHA-2/512/256 is being tested for this message the length of which is one hundred sixty-nine long so as to check whether or not this algorithm works well.";
387/// hash.digest_str(txt);
388/// println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
389/// assert_eq!(hash.get_hash_value_in_string(), "6FCE377EA6116BEAC9C11606C59A5D034C8C6EF5A1920B783A9097E07BE36D31");
390/// 
391/// txt = "This algorithm SHA-2/512/256 is being tested with this message the length of which is two hundred ninety-seven long so that whether or not this algorithm works well is checked. The message is 'Do you see a man skilled in his work? He will serve before kings; he will not serve before obscure men.'";
392/// hash.digest_str(txt);
393/// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
394/// assert_eq!(hash.to_string(), "63FD06E11EF67F0F5EF598C3B2F2E221D5557AD1EEA46156D1B657F1EDF08D5D");
395/// ```
396/// 
397/// ## Example 3 for SHA-512/224
398/// ```
399/// use std::string::*;
400/// use cryptocol::hash::SHA2_512_t_224;
401/// let mut hash = SHA2_512_t_224::new();
402/// 
403/// let mut txt = "";
404/// hash.digest_str(txt);
405/// println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash.get_hash_value_in_string());
406/// assert_eq!(hash.get_hash_value_in_string(), "6ED0DD02806FA89E25DE060C19D3AC86CABB87D6A0DDD05C333B84F4");
407/// 
408/// let txt_stirng = String::from("A");
409/// hash.digest_string(&txt_stirng);
410/// println!("Msg =\t\"{}\"\nHash =\t{}\n", txt_stirng, hash);
411/// assert_eq!(hash.to_string(), "1DEF1E6A5344538A07A3C93A3A765FA1D2859A576947791A9047C3E6");
412/// 
413/// let txt_array = ['W' as u8, 'o' as u8, 'w' as u8];
414/// hash.digest_array(&txt_array);
415/// println!("Msg =\t\"{:?}\"\nHash =\t{}\n", txt_array, hash);
416/// assert_eq!(hash.get_hash_value_in_string(), "021B7E0CFE3FBD598CF0366464AEB4C93A900BBA1DF8CADB5F611345");
417/// 
418/// txt = "The length of this message is forty-eight bytes.";
419/// hash.digest_str(txt);
420/// println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
421/// assert_eq!(hash.to_string(), "1E6EEBF17E8B2B1D2A41B14D9813561E44814E35F01119ED7BA3E19F");
422/// 
423/// txt = "The unit of the message length is not byte but bit.";
424/// hash.digest_str(txt);
425/// println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
426/// assert_eq!(hash.get_hash_value_in_string(), "5251D628FE99DA19238D277DF9AC03382249FF3830AD764EF0A68CDA");
427/// 
428/// txt = "This algorithm SHA-2/512/224 is being tested with this message, the length of which is one hundred twelve bytes.";
429/// hash.digest_str(txt);
430/// println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
431/// assert_eq!(hash.to_string(), "225B3D39D9B91705E7C08DBBF66E5F34E88554685C78AF2535FD3CE2");
432/// 
433/// txt = "This algorithm SHA-2/512/224 is being tested for this message the length of which is one hundred sixty-nine long so as to check whether or not this algorithm works well.";
434/// hash.digest_str(txt);
435/// println!("Msg =\t\"{}\"\nHash =\t{}\n", txt, hash);
436/// assert_eq!(hash.get_hash_value_in_string(), "3DD5D6503AFE8247B37AFD72DFD56718E6CA70D0B425739928885D0F");
437/// 
438/// txt = "This algorithm SHA-2/512/224 is being tested with this message the length of which is two hundred ninety-seven long so that whether or not this algorithm works well is checked. The message is 'Do you see a man skilled in his work? He will serve before kings; he will not serve before obscure men.'";
439/// hash.digest_str(txt);
440/// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
441/// assert_eq!(hash.to_string(), "D709EC6C2CAA1DAC61B0121675C3B131C23209F9E9ABC60392D99F52");
442/// ```
443/// # Big-endian issue
444/// It is just experimental for Big Endian CPUs. So, you are not encouraged
445/// to use it for Big Endian CPUs for serious purpose. Only use this crate
446/// for Big-endian CPUs with your own full responsibility.
447/// 
448/// # A Simple but Useful Application using cryptocol
449/// The following is the source code of the commandline SHA2_512_224 hash value
450/// extractor using the struct SHA2_512_224 of this module. You can get the
451/// hash value from a text or a file. The following source code assumes its
452/// executable file name will be "sha2_512_224_app". You can find all the
453/// examples including the following source code in the folder "examples"
454/// of this crate.
455/// ```
456/// use std::{ io, env, fs };
457/// use std::io::BufRead;
458/// use std::convert::From;
459/// use cryptocol::hash::SHA2_512_t_224;
460/// 
461/// type HASH = SHA2_512_t_224;
462/// 
463/// fn main()
464/// {
465///     let args: Vec<String> = env::args().collect();
466///     if args.len() < 3
467///     {
468///         help();
469///         return;
470///     }
471/// 
472///     let arg = &args[1][..];
473///     match arg
474///     {
475///         "--text" | "-t" =>  { get_hash_value_from_text(&args[2][..]); },
476///         "--file" | "-f" =>  { get_hash_value_from_file(&args[2][..]); },
477///         "--check" | "-c" => { check_files(&args[2][..]) },
478///         _ =>  { help(); },
479///     }
480/// }
481/// 
482/// fn get_hash_value_from_text(txt: &str)
483/// {
484///     let mut hash = HASH::new();
485///     hash.digest_str(txt);
486///     println!("Hash value:\t{}", hash.get_hash_value_in_string());
487/// }
488/// 
489/// fn get_hash_value_from_file(file: &str)
490/// {
491///     if let Ok(contents) = fs::read(file)
492///     {
493///         let mut hash = HASH::new();
494///         hash.digest_vec(&contents);
495///         println!("Hash value:\t{}", hash.get_hash_value_in_string());
496///     }
497///     else
498///     {
499///         println!("File Error!");
500///     }
501/// }
502/// 
503/// fn check_files(file_list: &str)
504/// {
505///     let mut reader;
506///     match fs::File::open(file_list)
507///     {
508///         Ok(file) => {
509///                 reader = io::BufReader::new(file);
510///                 let mut line = String::new();
511///                 while let Ok(n) = reader.read_line(&mut line)
512///                 {
513///                     if n == 0
514///                         { break; }
515///                     let txt = line.trim();
516///                     if txt.chars().nth(0).unwrap() == '#'
517///                     { 
518///                         line.clear();
519///                         continue;
520///                     }
521///                     let elem: Vec<&str> = txt.split_whitespace().collect();
522///                     let item = elem[0];
523///                     let h = String::from(elem[1]).to_uppercase();
524///                     if let Ok(contents) = fs::read(item)
525///                     {
526///                         let mut hash = HASH::new();
527///                         hash.digest_vec(&contents);
528///                         if hash.to_string() == h
529///                             { println!("{} ---> OK", item); }
530///                         else
531///                             { println!("{} ---> Corrupted", item); }
532///                     }
533///                     line.clear();
534///                 }
535///             },
536///         _ => {
537///                 println!("File open error");
538///                 return;
539///             }
540///     }
541/// }
542/// 
543/// fn help()
544/// {
545///     println!("This is an SHA2_512_t_224 hash value extractor from a text or a file, using cryptocol.");
546///     println!("Usage: sha2_512_224_app <option> <source>");
547///     println!("options       description");
548///     println!("--text, -t    : <source> is a text to get a hash code.");
549///     println!("                The text should be enclosed by ' or \".");
550///     println!("--file, -f    : <source> is the name of the file to get a hash code.");
551///     println!("--check, -c   : <source> is the name of the file that contains pairs");
552///     println!("                of file and its hash code.");
553///     println!("--help, -h    : print this help message on screen\n");
554///     println!("Examples:");
555///     println!("\tsha2_512_224_app -t 'How are you doing?'");
556///     println!("\tsha2_512_224_app -f linuxmint-21.3-cinnamon-64bit.iso");
557///     println!("\tsha2_512_224_app -c CHECKSUM");
558/// }
559/// ```
560#[derive(Debug, Clone)]
561#[allow(non_camel_case_types)]
562#[allow(non_upper_case_globals)]
563pub struct SHA2_512_t_Generic<const t: usize = 512, 
564                const A5A5A5A5A5A5A5A5: u64 = 0xa5a5a5a5a5a5a5a5, 
565                const H0: u64 = 0x6a09e667f3bcc908, const H1: u64 = 0xbb67ae8584caa73b, 
566                const H2: u64 = 0x3c6ef372fe94f82b, const H3: u64 = 0xa54ff53a5f1d36f1,
567                const H4: u64 = 0x510e527fade682d1, const H5: u64 = 0x9b05688c2b3e6c1f, 
568                const H6: u64 = 0x1f83d9abfb41bd6b, const H7: u64 = 0x5be0cd19137e2179,
569                const ROUND: usize = 80,
570                const K00: u64 = 0x428a2f98d728ae22, const K01: u64 = 0x7137449123ef65cd, 
571                const K02: u64 = 0xb5c0fbcfec4d3b2f, const K03: u64 = 0xe9b5dba58189dbbc,
572                const K04: u64 = 0x3956c25bf348b538, const K05: u64 = 0x59f111f1b605d019, 
573                const K06: u64 = 0x923f82a4af194f9b, const K07: u64 = 0xab1c5ed5da6d8118,
574                const K08: u64 = 0xd807aa98a3030242, const K09: u64 = 0x12835b0145706fbe, 
575                const K10: u64 = 0x243185be4ee4b28c, const K11: u64 = 0x550c7dc3d5ffb4e2,
576                const K12: u64 = 0x72be5d74f27b896f, const K13: u64 = 0x80deb1fe3b1696b1, 
577                const K14: u64 = 0x9bdc06a725c71235, const K15: u64 = 0xc19bf174cf692694,
578                const K16: u64 = 0xe49b69c19ef14ad2, const K17: u64 = 0xefbe4786384f25e3, 
579                const K18: u64 = 0x0fc19dc68b8cd5b5, const K19: u64 = 0x240ca1cc77ac9c65,
580                const K20: u64 = 0x2de92c6f592b0275, const K21: u64 = 0x4a7484aa6ea6e483, 
581                const K22: u64 = 0x5cb0a9dcbd41fbd4, const K23: u64 = 0x76f988da831153b5,
582                const K24: u64 = 0x983e5152ee66dfab, const K25: u64 = 0xa831c66d2db43210, 
583                const K26: u64 = 0xb00327c898fb213f, const K27: u64 = 0xbf597fc7beef0ee4,
584                const K28: u64 = 0xc6e00bf33da88fc2, const K29: u64 = 0xd5a79147930aa725, 
585                const K30: u64 = 0x06ca6351e003826f, const K31: u64 = 0x142929670a0e6e70,
586                const K32: u64 = 0x27b70a8546d22ffc, const K33: u64 = 0x2e1b21385c26c926, 
587                const K34: u64 = 0x4d2c6dfc5ac42aed, const K35: u64 = 0x53380d139d95b3df,
588                const K36: u64 = 0x650a73548baf63de, const K37: u64 = 0x766a0abb3c77b2a8, 
589                const K38: u64 = 0x81c2c92e47edaee6, const K39: u64 = 0x92722c851482353b,
590                const K40: u64 = 0xa2bfe8a14cf10364, const K41: u64 = 0xa81a664bbc423001, 
591                const K42: u64 = 0xc24b8b70d0f89791, const K43: u64 = 0xc76c51a30654be30,
592                const K44: u64 = 0xd192e819d6ef5218, const K45: u64 = 0xd69906245565a910, 
593                const K46: u64 = 0xf40e35855771202a, const K47: u64 = 0x106aa07032bbd1b8,
594                const K48: u64 = 0x19a4c116b8d2d0c8, const K49: u64 = 0x1e376c085141ab53, 
595                const K50: u64 = 0x2748774cdf8eeb99, const K51: u64 = 0x34b0bcb5e19b48a8,
596                const K52: u64 = 0x391c0cb3c5c95a63, const K53: u64 = 0x4ed8aa4ae3418acb, 
597                const K54: u64 = 0x5b9cca4f7763e373, const K55: u64 = 0x682e6ff3d6b2b8a3,
598                const K56: u64 = 0x748f82ee5defb2fc, const K57: u64 = 0x78a5636f43172f60, 
599                const K58: u64 = 0x84c87814a1f0ab72, const K59: u64 = 0x8cc702081a6439ec,
600                const K60: u64 = 0x90befffa23631e28, const K61: u64 = 0xa4506cebde82bde9, 
601                const K62: u64 = 0xbef9a3f7b2c67915, const K63: u64 = 0xc67178f2e372532b,
602                const K64: u64 = 0xca273eceea26619c, const K65: u64 = 0xd186b8c721c0c207, 
603                const K66: u64 = 0xeada7dd6cde0eb1e, const K67: u64 = 0xf57d4f7fee6ed178,
604                const K68: u64 = 0x06f067aa72176fba, const K69: u64 = 0x0a637dc5a2c898a6, 
605                const K70: u64 = 0x113f9804bef90dae, const K71: u64 = 0x1b710b35131c471b,
606                const K72: u64 = 0x28db77f523047d84, const K73: u64 = 0x32caab7b40c72493, 
607                const K74: u64 = 0x3c9ebe0a15c9bebc, const K75: u64 = 0x431d67c49c100d4c,
608                const K76: u64 = 0x4cc5d4becb3e42b6, const K77: u64 = 0x597f299cfc657e2a, 
609                const K78: u64 = 0x5fcb6fab3ad6faec, const K79: u64 = 0x6c44198c4a475817,
610                const RR1: u32 = 1, const RR8: u32 = 8,  const RR14: u32 = 14,
611                const RR18: u32 = 18, const RR19: u32 = 19, const RR28: u32 = 28, 
612                const RR34: u32 = 34, const RR39: u32 = 39, const RR41: u32 = 41,
613                const RR61: u32 = 61, const SR6: i32 = 6, const SR7: i32 = 7>
614{
615    hash_code: [LongUnion; 8],
616    o: [u64; 8],
617}
618
619#[allow(non_upper_case_globals)]
620impl<const t: usize, const A5A5A5A5A5A5A5A5: u64,
621    const H0: u64, const H1: u64, const H2: u64, const H3: u64,
622    const H4: u64, const H5: u64, const H6: u64, const H7: u64,
623    const ROUND: usize,
624    const K00: u64, const K01: u64, const K02: u64, const K03: u64,
625    const K04: u64, const K05: u64, const K06: u64, const K07: u64,
626    const K08: u64, const K09: u64, const K10: u64, const K11: u64,
627    const K12: u64, const K13: u64, const K14: u64, const K15: u64,
628    const K16: u64, const K17: u64, const K18: u64, const K19: u64,
629    const K20: u64, const K21: u64, const K22: u64, const K23: u64,
630    const K24: u64, const K25: u64, const K26: u64, const K27: u64,
631    const K28: u64, const K29: u64, const K30: u64, const K31: u64,
632    const K32: u64, const K33: u64, const K34: u64, const K35: u64,
633    const K36: u64, const K37: u64, const K38: u64, const K39: u64,
634    const K40: u64, const K41: u64, const K42: u64, const K43: u64,
635    const K44: u64, const K45: u64, const K46: u64, const K47: u64,
636    const K48: u64, const K49: u64, const K50: u64, const K51: u64,
637    const K52: u64, const K53: u64, const K54: u64, const K55: u64,
638    const K56: u64, const K57: u64, const K58: u64, const K59: u64,
639    const K60: u64, const K61: u64, const K62: u64, const K63: u64,
640    const K64: u64, const K65: u64, const K66: u64, const K67: u64,
641    const K68: u64, const K69: u64, const K70: u64, const K71: u64,
642    const K72: u64, const K73: u64, const K74: u64, const K75: u64,
643    const K76: u64, const K77: u64, const K78: u64, const K79: u64,
644    const RR1: u32, const RR8: u32, const RR14: u32, const RR18: u32, 
645    const RR19: u32, const RR28: u32, const RR34: u32, const RR39: u32, 
646    const RR41: u32, const RR61: u32, const SR6: i32, const SR7: i32>
647SHA2_512_t_Generic<t, A5A5A5A5A5A5A5A5,
648                    H0, H1, H2, H3, H4, H5, H6, H7, ROUND,
649                    K00, K01, K02, K03, K04, K05, K06, K07,
650                    K08, K09, K10, K11, K12, K13, K14, K15,
651                    K16, K17, K18, K19, K20, K21, K22, K23,
652                    K24, K25, K26, K27, K28, K29, K30, K31,
653                    K32, K33, K34, K35, K36, K37, K38, K39,
654                    K40, K41, K42, K43, K44, K45, K46, K47,
655                    K48, K49, K50, K51, K52, K53, K54, K55,
656                    K56, K57, K58, K59, K60, K61, K62, K63,
657                    K64, K65, K66, K67, K68, K69, K70, K71,
658                    K72, K73, K74, K75, K76, K77, K78, K79,
659                    RR1, RR8, RR14, RR18, RR19, RR28, RR34,
660                    RR39, RR41, RR61, SR6, SR7>
661{
662    const K: [u64; 80] = [  K00, K01, K02, K03, K04, K05, K06, K07,
663                            K08, K09, K10, K11, K12, K13, K14, K15,
664                            K16, K17, K18, K19, K20, K21, K22, K23,
665                            K24, K25, K26, K27, K28, K29, K30, K31,
666                            K32, K33, K34, K35, K36, K37, K38, K39,
667                            K40, K41, K42, K43, K44, K45, K46, K47,
668                            K48, K49, K50, K51, K52, K53, K54, K55,
669                            K56, K57, K58, K59, K60, K61, K62, K63,
670                            K64, K65, K66, K67, K68, K69, K70, K71,
671                            K72, K73, K74, K75, K76, K77, K78, K79 ];
672    const H: [u64; 8] = [ H0, H1, H2, H3, H4, H5, H6, H7 ];
673
674    // pub fn new() -> Self
675    /// Constructs a new object of `SHA2_256` or `SHA2_224`,
676    /// or a new SHA2_256-based object.
677    /// 
678    /// # Output
679    /// A new object of `SHA2_512_t_256` or `SHA2_512_t_224`,
680    /// or a new SHA2_512_t-based object.
681    /// 
682    /// # Example 1 for SHA2_512_t_256
683    /// ```
684    /// use cryptocol::hash::SHA2_512_t_256;
685    /// let hash = SHA2_512_t_256::new();
686    /// println!("Hash =\t{}", hash);
687    /// assert_eq!(hash.to_string(), "22312194FC2BF72C9F555FA3C84C64C22393B86B6F53B151963877195940EABD");
688    /// ```
689    /// 
690    /// # Example 2 for SHA2_512_t_256_Expanded
691    /// ```
692    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
693    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
694    /// let my_hash = MySHA2::new();
695    /// println!("Hash =\t{}", my_hash);
696    /// assert_eq!(my_hash.to_string(), "B80E7C569545AF48629EF11E2E14B8204F74747C4F949C6D60FEB4CC233775A7");
697    /// ```
698    /// 
699    /// # Example 3 for SHA2_512_t_224
700    /// ```
701    /// use cryptocol::hash::SHA2_512_t_224;
702    /// let hash = SHA2_512_t_224::new();
703    /// println!("Hash =\t{}", hash);
704    /// assert_eq!(hash.to_string(), "8C3D37C819544DA273E1996689DCD4D61DFAB7AE32FF9C82679DD514");
705    /// ```
706    /// 
707    /// # Example 4 for SHA2_512_t_224_Expanded
708    /// ```
709    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
710    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
711    /// let my_hash = MySHA2::new();
712    /// println!("Hash =\t{}", my_hash);
713    /// assert_eq!(my_hash.to_string(), "6053A0C18224AF65E6633DEA9B125B74309B64519F70586FF009DFF5");
714    /// ```
715    #[inline]
716    pub fn new() -> Self
717    {
718        Self::new_with_seed_text(format!("SHA-512/{}", t).as_str())
719    }
720
721    // pub fn new_with_seed_text(seed_text: &str) -> Self
722    /// Constructs a new object of `SHA2_256` or `SHA2_224`,
723    /// or a new SHA2_256-based object with seed text
724    /// 
725    /// # Output
726    /// A new object of `SHA2_512_t_256` or `SHA2_512_t_224`,
727    /// or a new SHA2_512_t-based object.
728    /// 
729    /// # Argument
730    /// The `seed_text` to make initial hash values.
731    /// 
732    /// # Example 1 for SHA2_512_t_256
733    /// ```
734    /// use cryptocol::hash::SHA2_512_t_256;
735    /// let hash = SHA2_512_t_256::new_with_seed_text("샤-");
736    /// // '샤' is from Hangeul which is Korean letter, sounds like 'sha'
737    /// println!("Hash =\t{}", hash);
738    /// assert_eq!(hash.to_string(), "6E231779CE7B233F74077E896D4ABCCA8B31054CB94168164E08BD8F31764DCB");
739    /// ```
740    /// 
741    /// # Example 2 for SHA2_512_t_256_Expanded
742    /// ```
743    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
744    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
745    /// let my_hash = MySHA2::new_with_seed_text("샤-");
746    /// // '샤' is from Hangeul which is Korean letter, sounds like 'sha'
747    /// println!("Hash =\t{}", my_hash);
748    /// assert_eq!(my_hash.to_string(), "A15939C18C313184EA37451948F708F5C7B1FBE11E40F8795EF6BF52DB4EC9E9");
749    /// ```
750    /// 
751    /// # Example 3 for SHA2_512_t_224
752    /// ```
753    /// use cryptocol::hash::SHA2_512_t_224;
754    /// let hash = SHA2_512_t_224::new_with_seed_text("샤-");
755    /// // '샤' is from Hangeul which is Korean letter, sounds like 'sha'
756    /// println!("Hash =\t{}", hash);
757    /// assert_eq!(hash.to_string(), "6E231779CE7B233F74077E896D4ABCCA8B31054CB94168164E08BD8F");
758    /// ```
759    /// 
760    /// # Example 4 for SHA2_512_t_224_Expanded
761    /// ```
762    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
763    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
764    /// let my_hash = MySHA2::new_with_seed_text("샤-");
765    /// // '샤' is from Hangeul which is Korean letter, sounds like 'sha'
766    /// println!("Hash =\t{}", my_hash);
767    /// assert_eq!(my_hash.to_string(), "A15939C18C313184EA37451948F708F5C7B1FBE11E40F8795EF6BF52");
768    /// ```
769    pub fn new_with_seed_text(seed_text: &str) -> Self
770    {
771        if t > 512
772            { panic!("t cannot be greater than 512."); }
773        if (t & 0b111) != 0
774            { panic!("t should be multiple of 8."); }
775
776        let seed_text = format!("{}", seed_text);
777        let o = [ Self::H[0] ^ A5A5A5A5A5A5A5A5,
778                            Self::H[1] ^ A5A5A5A5A5A5A5A5, 
779                            Self::H[2] ^ A5A5A5A5A5A5A5A5,
780                            Self::H[3] ^ A5A5A5A5A5A5A5A5,
781                            Self::H[4] ^ A5A5A5A5A5A5A5A5,
782                            Self::H[5] ^ A5A5A5A5A5A5A5A5, 
783                            Self::H[6] ^ A5A5A5A5A5A5A5A5,
784                            Self::H[7] ^ A5A5A5A5A5A5A5A5 ];
785
786        let mut h = SHA2_512_0::new_with_h(&o);
787        h.digest(seed_text.as_ptr(), seed_text.len() as u64);
788        let mut o = [0_u64; 8];
789        h.put_hash_value_in_array(&mut o);
790        for i in 0..8
791            { o[i] = o[i].to_be(); }
792        Self::new_with_h(&o)
793    }
794
795    // pub fn new_with_h(H: &[u64; 8]) -> Self
796    /// Constructs a new object of `SHA2_256` or `SHA2_224`,
797    /// or a new SHA2_256-based object with initial hash value
798    /// 
799    /// # Output
800    /// A new object of `SHA2_512_t_256` or `SHA2_512_t_224`,
801    /// or a new SHA2_512_t-based object.
802    /// 
803    /// # Argument
804    /// The initial hash value `H` to set initial value.
805    fn new_with_h(h: &[u64; 8]) -> Self
806    {
807        Self
808        {
809            hash_code: [LongUnion::new_with(h[0]),
810                        LongUnion::new_with(h[1]),
811                        LongUnion::new_with(h[2]),
812                        LongUnion::new_with(h[3]),
813                        LongUnion::new_with(h[4]),
814                        LongUnion::new_with(h[5]),
815                        LongUnion::new_with(h[6]),
816                        LongUnion::new_with(h[7])],
817            o: [ h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7] ],
818        }
819    }
820
821    // // pub fn digest_c(&mut self, message: *const u8, length_in_bytes_low: u64, length_in_bytes_high: u64)
822    // /// Computes hash value.
823    // /// 
824    // /// # Features
825    // /// This function has the generalized interface (pointer, `*const u8`).
826    // /// So, this function is usually not called directly in Rust. This function
827    // /// is provided to be called from other programming languages such as C/C++.
828    // /// 
829    // /// # Arguments
830    // /// - `message` is pointer to const u8.
831    // /// - `length_in_bytes_low` is the lower 64 bits of the size of message
832    // /// in the unit of bytes.
833    // /// - `length_in_bytes_high` is the higher 64 bits of the size of message
834    // /// in the unit of bytes.
835    // /// 
836    // /// # Counterpart Methods
837    // /// - If you want to compute of the hash value of a string slice,
838    // /// you are highly recommended to use the method
839    // /// [digest_str()](struct@SHA2_512_t_Generic#method.digest_str)
840    // /// rather than this method.
841    // /// - If you want to compute of the hash value of the content of String
842    // /// object, you are highly recommended to use the method
843    // /// [digest_string()](struct@SHA2_512_t_Generic#method.digest_string)
844    // /// rather than this method.
845    // /// - If you want to compute of the hash value of the content of Array
846    // /// object, you are highly recommended to use the method
847    // /// [digest_array()](struct@SHA2_512_t_Generic#method.digest_array)
848    // /// rather than this method.
849    // /// - If you want to compute of the hash value of the content of Vec
850    // /// object, you are highly recommended to use the method
851    // /// [digest_vec()](struct@SHA2_512_t_Generic#method.digest_array)
852    // /// rather than this method.
853    // /// 
854    // /// # Example 1 for SHA2_512_t_256
855    // /// ```
856    // /// use cryptocol::hash::SHA2_512_t_256;
857    // /// let mut hash = SHA2_512_t_256::new();
858    // /// let txt = "This is an example of the method digest_c().";
859    // /// hash.digest_c(txt.as_ptr(), txt.len() as u64, 0);
860    // /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
861    // /// assert_eq!(hash.to_string(), "AE67F5B190BB09DC615859EC2D11736DA6CBE00340EE39396FE76257238E3AF1");
862    // /// ```
863    // /// 
864    // /// # Example 2 for SHA2_512_t_256_Expanded
865    // /// ```
866    // /// use cryptocol::hash::SHA2_512_t_256_Expanded;
867    // /// type MySHA2 = SHA2_512_t_256_Expanded<0x123456789abcdef0, 160>;
868    // /// let mut my_hash = MySHA2::new();
869    // /// let txt = "This is an example of the method digest_c().";
870    // /// my_hash.digest_c(txt.as_ptr(), txt.len() as u64, 0);
871    // /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
872    // /// assert_eq!(my_hash.to_string(), "D9BE41EF1B7AFDCF7E3E8256661ACD436E3D0811FD433D5A6BF48823F2A004B4");
873    // /// ```
874    // /// 
875    // /// # Example 3 for SHA2_512_t_224
876    // /// ```
877    // /// use cryptocol::hash::SHA2_512_t_224;
878    // /// let mut hash = SHA2_512_t_224::new();
879    // /// let txt = "This is an example of the method digest_c().";
880    // /// hash.digest_c(txt.as_ptr(), txt.len() as u64, 0);
881    // /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
882    // /// assert_eq!(hash.to_string(), "E7B8A450F1F3E90B361BED00083D6E14A90C2A074C71038D0743E384");
883    // /// ```
884    // /// 
885    // /// # Example 4 for SHA2_512_t_224_Expanded
886    // /// ```
887    // /// use cryptocol::hash::SHA2_512_t_224_Expanded;
888    // /// type MySHA2 = SHA2_512_t_224_Expanded<0x123456789abcdef0, 160>;
889    // /// let mut my_hash = MySHA2::new();
890    // /// let txt = "This is an example of the method digest_c().";
891    // /// my_hash.digest_c(txt.as_ptr(), txt.len() as u64, 0);
892    // /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
893    // /// assert_eq!(my_hash.to_string(), "9B38B1C0434F66DB99A76273D167237ABC3BF8BC96F91DF051A3E31B");
894    // /// ```
895    // /// 
896    // /// # Big-endian issue
897    // /// It is just experimental for Big Endian CPUs. So, you are not encouraged
898    // /// to use it for Big Endian CPUs for serious purpose. Only use this crate
899    // /// for Big-endian CPUs with your own full responsibility.
900    // pub fn digest_c(&mut self, message: *const u8, length_in_bytes_low: u64, length_in_bytes_high: u64)
901    // {
902    //     let mut vu = LongerUnion::new();
903    //     vu.set_ulong_(0, length_in_bytes_low);
904    //     vu.set_ulong_(1, length_in_bytes_high);
905    //     self.digest(message, vu.get());
906    // }
907
908    // pub fn digest(&mut self, message: *const u8, length_in_bytes: u64)
909    /// Computes hash value.
910    /// 
911    /// # Features
912    /// This function has the generalized interface (pointer, `*const u8`)
913    /// so as to enable other functions to wrap this function with any
914    /// convenient interface for uses. So, this function can be called in Rust.
915    /// 
916    /// # Arguments
917    /// - `message` is pointer to const u8.
918    /// - `length_in_bytes` is the size of message in the unit of bytes, and
919    /// data type is `u64`.
920    /// 
921    /// # Counterpart Methods
922    /// - If you want to compute of the hash value of a string slice,
923    /// you are highly recommended to use the method
924    /// [digest_str()](struct@SHA2_512_t_Generic#method.digest_str)
925    /// rather than this method.
926    /// - If you want to compute of the hash value of the content of String
927    /// object, you are highly recommended to use the method
928    /// [digest_string()](struct@SHA2_512_t_Generic#method.digest_string)
929    /// rather than this method.
930    /// - If you want to compute of the hash value of the content of Array
931    /// object, you are highly recommended to use the method
932    /// [digest_array()](struct@SHA2_512_t_Generic#method.digest_array)
933    /// rather than this method.
934    /// - If you want to compute of the hash value of the content of Vec
935    /// object, you are highly recommended to use the method
936    /// [digest_vec()](struct@SHA2_512_t_Generic#method.digest_array)
937    /// rather than this method.
938    /// 
939    /// # Example 1 for SHA2_512_t_256
940    /// ```
941    /// use cryptocol::hash::SHA2_512_t_256;
942    /// let mut hash = SHA2_512_t_256::new();
943    /// let txt = "This is an example of the method digest().";
944    /// hash.digest(txt.as_ptr(), txt.len() as u64);
945    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
946    /// assert_eq!(hash.to_string(), "BF3A06F51CE91951607AABD2E33AD24D8B75618F2366B90D98991AD28E47FAA5");
947    /// ```
948    /// 
949    /// # Example 2 for SHA2_512_t_256_Expanded
950    /// ```
951    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
952    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
953    /// let mut my_hash = MySHA2::new();
954    /// my_hash.digest(txt.as_ptr(), txt.len() as u64);
955    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
956    /// assert_eq!(my_hash.to_string(), "645C53583A01ABF44F279BEC2CC07AB072B57AA319962B524C73435DBE564CEF");
957    /// ```
958    /// 
959    /// # Example 3 for SHA2_512_t_224
960    /// ```
961    /// use cryptocol::hash::SHA2_512_t_224;
962    /// let mut hash = SHA2_512_t_224::new();
963    /// let txt = "This is an example of the method digest().";
964    /// hash.digest(txt.as_ptr(), txt.len() as u64);
965    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
966    /// assert_eq!(hash.to_string(), "2269C5A3791E72D00337D9EDDE9BA9568539F4E131B7DB7555545633");
967    /// ```
968    /// 
969    /// # Example 4 for SHA2_512_t_224_Expanded
970    /// ```
971    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
972    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
973    /// let mut my_hash = MySHA2::new();
974    /// let txt = "This is an example of the method digest().";
975    /// my_hash.digest(txt.as_ptr(), txt.len() as u64);
976    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
977    /// assert_eq!(my_hash.to_string(), "1DCBF56DC6F3387734139CC5CA14FAC05DF67CD4B14AE86E474F421C");
978    /// ```
979    /// 
980    /// # Big-endian issue
981    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
982    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
983    /// for Big-endian CPUs with your own full responsibility.
984    pub fn digest(&mut self, message: *const u8, length_in_bytes: u64)
985    {
986        type MessageType = u64;
987        const SHIFT_NUM: usize = 7;
988        const CHUNK_NUM: usize = 16;
989        let mut block: [MessageType; CHUNK_NUM] = [0; CHUNK_NUM];
990        self.initialize();
991        let length_done = (length_in_bytes >> SHIFT_NUM) as usize;
992        for i in 0..length_done
993        {
994            unsafe { copy_nonoverlapping(message.add(i << SHIFT_NUM) as *const u8, block.as_mut_ptr() as *mut u8, CHUNK_NUM * 8); }
995            self.update(&block);
996        }
997        self.finalize(unsafe { message.add(length_done << SHIFT_NUM) }, length_in_bytes);
998    }
999
1000    // pub fn digest_str(&mut self, message: &str)
1001    /// Computes hash value.
1002    /// 
1003    /// # Features
1004    /// This function is a wrapping function of `digest()`.
1005    /// This function computes hash value of the content of string slice.
1006    /// 
1007    /// # Argument
1008    /// - message is `&str`.
1009    /// 
1010    /// # Counterpart Methods
1011    /// - If you want to compute of the hash value of the content of String
1012    /// object, you are highly recommended to use the method
1013    /// [digest_string()](struct@SHA2_512_t_Generic#method.digest_string)
1014    /// rather than this method.
1015    /// - If you want to compute of the hash value of the content of Array
1016    /// object, you are highly recommended to use the method
1017    /// [digest_array()](struct@SHA2_512_t_Generic#method.digest_array)
1018    /// rather than this method.
1019    /// - If you want to compute of the hash value of the content of Vec
1020    /// object, you are highly recommended to use the method
1021    /// [digest_vec()](struct@SHA2_512_t_Generic#method.digest_array)
1022    /// rather than this method.
1023    /// - If you want to use this method from other programming languages such
1024    /// as C/C++, you are highly recommended to use the method
1025    /// [digest()](struct@SHA2_512_t_Generic#method.digest)
1026    /// rather than this method.
1027    /// 
1028    /// # Example 1 for SHA2_512_t_256
1029    /// ```
1030    /// use cryptocol::hash::SHA2_512_t_256;
1031    /// let mut hash = SHA2_512_t_256::new();
1032    /// let txt = "This is an example of the method digest_str().";
1033    /// hash.digest_str(txt);
1034    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
1035    /// assert_eq!(hash.to_string(), "D0ED13389E431C8D74FE6E8DB5B6194682874B52E800524136E35D7E9CFA496B");
1036    /// ```
1037    /// 
1038    /// # Example 2 for SHA2_512_t_256_Expanded
1039    /// ```
1040    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
1041    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
1042    /// let mut my_hash = MySHA2::new();
1043    /// let txt = "This is an example of the method digest_str().";
1044    /// my_hash.digest_str(txt);
1045    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
1046    /// assert_eq!(my_hash.to_string(), "2ABEF10487ECC51EA8953654E972C7C57817D674B12B89E175E569169F43ED9B");
1047    /// ```
1048    /// 
1049    /// # Example 3 for SHA2_512_t_224
1050    /// ```
1051    /// use cryptocol::hash::SHA2_512_t_224;
1052    /// let mut hash = SHA2_512_t_224::new();
1053    /// let txt = "This is an example of the method digest_str().";
1054    /// hash.digest_str(txt);
1055    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
1056    /// assert_eq!(hash.to_string(), "17E80E466E706474DB2C9E39691150805AC536319125AFB1E436BE8F");
1057    /// ```
1058    /// 
1059    /// # Example 4 for SHA2_512_t_224_Expanded
1060    /// ```
1061    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
1062    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
1063    /// let mut my_hash = MySHA2::new();
1064    /// let txt = "This is an example of the method digest_str().";
1065    /// my_hash.digest_str(txt);
1066    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
1067    /// assert_eq!(my_hash.to_string(), "44C91FB5B6352E89DF5B5230A004B8594FC7B7AF6F61D3E332C4AC01");
1068    /// ```
1069    /// 
1070    /// # Big-endian issue
1071    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
1072    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
1073    /// for Big-endian CPUs with your own full responsibility.
1074    #[inline]
1075    pub fn digest_str(&mut self, message: &str)
1076    {
1077        self.digest(message.as_ptr(), message.len() as u64);
1078    }
1079
1080    // pub fn digest_string(&mut self, message: &String)
1081    /// Computes hash value.
1082    /// 
1083    /// # Features
1084    /// This function is a wrapping function of `digest()`.
1085    /// This function computes hash value of the content of String object.
1086    /// 
1087    /// # Argument
1088    /// - message is `&String`.
1089    /// 
1090    /// # Counterpart Methods
1091    /// - If you want to compute of the hash value of a string slice,
1092    /// you are highly recommended to use the method
1093    /// [digest_str()](struct@SHA2_512_t_Generic#method.digest_str)
1094    /// rather than this method.
1095    /// - If you want to compute of the hash value of the content of Array
1096    /// object, you are highly recommended to use the method
1097    /// [digest_array()](struct@SHA2_512_t_Generic#method.digest_array)
1098    /// rather than this method.
1099    /// - If you want to compute of the hash value of the content of Vec
1100    /// object, you are highly recommended to use the method
1101    /// [digest_vec()](struct@SHA2_512_t_Generic#method.digest_array)
1102    /// rather than this method.
1103    /// - If you want to use this method from other programming languages such
1104    /// as C/C++, you are highly recommended to use the method
1105    /// [digest()](struct@SHA2_512_t_Generic#method.digest)
1106    /// rather than this method.
1107    /// 
1108    /// # Example 1 for SHA2_512_t_256
1109    /// ```
1110    /// use cryptocol::hash::SHA2_512_t_256;
1111    /// let mut hash = SHA2_512_t_256::new();
1112    /// let txt = "This is an example of the method digest_string().".to_string();
1113    /// hash.digest_string(&txt);
1114    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
1115    /// assert_eq!(hash.to_string(), "2824B79B5D8A1D02454612B72B9CD9544D0DF8E126E7A01E55AC479B0903297C");
1116    /// ```
1117    /// 
1118    /// # Example 2 for SHA2_512_t_256_Expanded
1119    /// ```
1120    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
1121    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
1122    /// let mut my_hash = MySHA2::new();
1123    /// let txt = "This is an example of the method digest_string().".to_string();
1124    /// my_hash.digest_string(&txt);
1125    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
1126    /// assert_eq!(my_hash.to_string(), "B9D855F972D884C200B5EFECB105B115065AC58540099777A84766623BF87C15");
1127    /// ```
1128    /// 
1129    /// # Example 3 for SHA2_512_t_224
1130    /// ```
1131    /// use cryptocol::hash::SHA2_512_t_224;
1132    /// let mut hash = SHA2_512_t_224::new();
1133    /// let txt = "This is an example of the method digest_string().".to_string();
1134    /// hash.digest_string(&txt);
1135    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
1136    /// assert_eq!(hash.to_string(), "E1423096CED4DC8D9522C75C8BBB12B59A4510093CFA4FD480D270FD");
1137    /// ```
1138    /// 
1139    /// # Example 4 for SHA2_512_t_224_Expanded
1140    /// ```
1141    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
1142    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
1143    /// let mut my_hash = MySHA2::new();
1144    /// let txt = "This is an example of the method digest_string().".to_string();
1145    /// my_hash.digest_string(&txt);
1146    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
1147    /// assert_eq!(my_hash.to_string(), "092A7203B3BD5C72852B0507989257577808C453C2C7F915BAD1CF5C");
1148    /// ```
1149    /// 
1150    /// # Big-endian issue
1151    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
1152    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
1153    /// for Big-endian CPUs with your own full responsibility.
1154    #[inline]
1155    pub fn digest_string(&mut self, message: &String)
1156    {
1157        self.digest(message.as_ptr(), message.len() as u64);
1158    }
1159
1160    // pub fn digest_array<T, const M: usize>(&mut self, message: &[T; M])
1161    /// Computes hash value.
1162    /// 
1163    /// # Features
1164    /// This function is a wrapping function of `digest()`.
1165    /// This function computes hash value of the content of Array object.
1166    /// 
1167    /// # Argument
1168    /// - message is `&[T; M]`.
1169    /// 
1170    /// # Counterpart Methods
1171    /// - If you want to compute of the hash value of a string slice,
1172    /// you are highly recommended to use the method
1173    /// [digest_str()](struct@SHA2_512_t_Generic#method.digest_str)
1174    /// rather than this method.
1175    /// - If you want to compute of the hash value of the content of String
1176    /// object, you are highly recommended to use the method
1177    /// [digest_string()](struct@SHA2_512_t_Generic#method.digest_string)
1178    /// rather than this method.
1179    /// - If you want to compute of the hash value of the content of Vec
1180    /// object, you are highly recommended to use the method
1181    /// [digest_vec()](struct@SHA2_512_t_Generic#method.digest_array)
1182    /// rather than this method.
1183    /// - If you want to use this method from other programming languages such
1184    /// as C/C++, you are highly recommended to use the method
1185    /// [digest()](struct@SHA2_512_t_Generic#method.digest)
1186    /// rather than this method.
1187    /// 
1188    /// # Example 1 for SHA2_512_t_256
1189    /// ```
1190    /// use cryptocol::hash::SHA2_512_t_256;
1191    /// let mut hash = SHA2_512_t_256::new();
1192    /// let data = [ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1193    /// hash.digest_array(&data);
1194    /// println!("Msg =\t{:?}\nHash =\t{}", data, hash);
1195    /// assert_eq!(hash.to_string(), "E9A9876BBF1432C27CE58D6B8EA66B5A0B719FA80832D491768033F4DAF65A64");
1196    /// ```
1197    /// 
1198    /// # Example 2 for SHA2_512_t_256_Expanded
1199    /// ```
1200    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
1201    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
1202    /// let mut my_hash = MySHA2::new();
1203    /// let data = [ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1204    /// my_hash.digest_array(&data);
1205    /// println!("Msg =\t{:?}\nHash =\t{}", data, my_hash);
1206    /// assert_eq!(my_hash.to_string(), "4AA24C35A21F9D0552E0C3A69A5A59EFE1936FD361ABA1C6E8F6DA22FC39D236");
1207    /// ```
1208    /// 
1209    /// # Example 3 for SHA2_512_t_224
1210    /// ```
1211    /// use cryptocol::hash::SHA2_512_t_224;
1212    /// let mut hash = SHA2_512_t_224::new();
1213    /// let data = [ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1214    /// hash.digest_array(&data);
1215    /// println!("Msg =\t{:?}\nHash =\t{}", data, hash);
1216    /// assert_eq!(hash.to_string(), "3F600A922240910231ACA350DEDD49BD875936BE5AAB8A034D09334B");
1217    /// ```
1218    /// 
1219    /// # Example 4 for SHA2_512_t_224_Expanded
1220    /// ```
1221    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
1222    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
1223    /// let mut my_hash = MySHA2::new();
1224    /// let data = [ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1225    /// my_hash.digest_array(&data);
1226    /// println!("Msg =\t{:?}\nHash =\t{}", data, my_hash);
1227    /// assert_eq!(my_hash.to_string(), "504B348485EC8CF96E630DFC90D75DC1543A3A2B3B895A0261CAF0CE");
1228    /// ```
1229    /// 
1230    /// # Big-endian issue
1231    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
1232    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
1233    /// for Big-endian CPUs with your own full responsibility.
1234    #[inline]
1235    pub fn digest_array<T, const M: usize>(&mut self, message: &[T; M])
1236    where T: SmallUInt + Copy + Clone + Display + Debug + ToString
1237    {
1238        self.digest(message.as_ptr() as *const u8, (M as u32 * T::size_in_bytes()) as u64);
1239    }
1240
1241    // pub fn digest_vec<T>(&mut self, message: &Vec<T>)
1242    /// Computes hash value.
1243    /// 
1244    /// # Features
1245    /// This function is a wrapping function of `digest()`.
1246    /// This function computes hash value of the content of Vec object.
1247    /// 
1248    /// # Argument
1249    /// - message is `&Vec<T>`.
1250    /// 
1251    /// # Counterpart Methods
1252    /// - If you want to compute of the hash value of a string slice,
1253    /// you are highly recommended to use the method
1254    /// [digest_str()](struct@SHA2_512_t_Generic#method.digest_str)
1255    /// rather than this method.
1256    /// - If you want to compute of the hash value of the content of String
1257    /// object, you are highly recommended to use the method
1258    /// [digest_string()](struct@SHA2_512_t_Generic#method.digest_string)
1259    /// rather than this method.
1260    /// - If you want to compute of the hash value of the content of Array
1261    /// object, you are highly recommended to use the method
1262    /// [digest_array()](struct@SHA2_512_t_Generic#method.digest_array)
1263    /// rather than this method.
1264    /// - If you want to use this method from other programming languages such
1265    /// as C/C++, you are highly recommended to use the method
1266    /// [digest()](struct@SHA2_512_t_Generic#method.digest)
1267    /// rather than this method.
1268    /// 
1269    /// # Example 1 for SHA2_512_t_256
1270    /// ```
1271    /// use cryptocol::hash::SHA2_512_t_256;
1272    /// let mut hash = SHA2_512_t_256::new();
1273    /// let data = vec![ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1274    /// hash.digest_vec(&data);
1275    /// println!("Msg =\t{:?}\nHash =\t{}", data, hash);
1276    /// assert_eq!(hash.to_string(), "E9A9876BBF1432C27CE58D6B8EA66B5A0B719FA80832D491768033F4DAF65A64");
1277    /// ```
1278    /// 
1279    /// # Example 2 for SHA2_512_t_256_Expanded
1280    /// ```
1281    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
1282    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
1283    /// let mut my_hash = MySHA2::new();
1284    /// let data = vec![ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1285    /// my_hash.digest_vec(&data);
1286    /// println!("Msg =\t{:?}\nHash =\t{}", data, my_hash);
1287    /// assert_eq!(my_hash.to_string(), "4AA24C35A21F9D0552E0C3A69A5A59EFE1936FD361ABA1C6E8F6DA22FC39D236");
1288    /// ```
1289    /// 
1290    /// # Example 3 for SHA2_512_t_224
1291    /// ```
1292    /// use cryptocol::hash::SHA2_512_t_224;
1293    /// let mut hash = SHA2_512_t_224::new();
1294    /// let data = vec![ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1295    /// hash.digest_vec(&data);
1296    /// println!("Msg =\t{:?}\nHash =\t{}", data, hash);
1297    /// assert_eq!(hash.to_string(), "3F600A922240910231ACA350DEDD49BD875936BE5AAB8A034D09334B");
1298    /// ```
1299    /// 
1300    /// # Example 4 for SHA2_512_t_224_Expanded
1301    /// ```
1302    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
1303    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
1304    /// let mut my_hash = MySHA2::new();
1305    /// let data = vec![ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1306    /// my_hash.digest_vec(&data);
1307    /// println!("Msg =\t{:?}\nHash =\t{}", data, my_hash);
1308    /// assert_eq!(my_hash.to_string(), "504B348485EC8CF96E630DFC90D75DC1543A3A2B3B895A0261CAF0CE");
1309    /// ```
1310    /// 
1311    /// # Big-endian issue
1312    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
1313    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
1314    /// for Big-endian CPUs with your own full responsibility.
1315    #[inline]
1316    pub fn digest_vec<T>(&mut self, message: &Vec<T>)
1317    where T: SmallUInt + Copy + Clone + Display + Debug + ToString
1318    {
1319        self.digest(message.as_ptr() as *const u8, (message.len() as u32 * T::size_in_bytes()) as u64);
1320    }
1321
1322    // pub fn ruminate(&mut self, n: usize, message: *const u8, length_in_bytes: u64)
1323    /// Computes a hash value of `message`, and then computes a new hash value
1324    /// of the hash value of the message, and then computes a hash value of the
1325    /// previous hash value, and then ... `n` times repeatedly.
1326    /// 
1327    /// # Arguments
1328    /// - `n` is the number of repetition of digestion
1329    /// - `message` is pointer to const u8.
1330    /// - `length_in_bytes` is the size of message in the unit of bytes, and
1331    /// data type is `u64`.
1332    /// 
1333    /// # Origin
1334    /// Double hashing is invented by Ferguson and Schneier in their book
1335    /// Practical Cryptography to countermeasure against length extension
1336    /// attacks. Plus, Bitcoin uses double hashing.
1337    /// This is generalized version of it.
1338    /// 
1339    /// # Features
1340    /// This function has the generalized interface (pointer, `*const u8`)
1341    /// so as to enable other functions to wrap this function with any
1342    /// convenient interface for uses. So, this function is usually not called
1343    /// directly in Rust. This function is provided to be called from other
1344    /// programming languages such as C/C++.
1345    /// 
1346    /// # Security Issue
1347    /// The author doubts that the double hashing is securer than normal
1348    /// hashing. The double hashing will be as secure as the normal hashing
1349    /// at most because birthday paradox applies twice for the double hashing
1350    /// though the size of the domain is the same size of the codomain for
1351    /// second hashing of the double hashing, while the birthday paradox
1352    /// applies only once for the normal hashing.
1353    /// 
1354    /// # Example 1 for SHA2_512_t_256
1355    /// ```
1356    /// use cryptocol::hash::SHA2_512_t_256;
1357    /// let mut hash = SHA2_512_t_256::new();
1358    /// let txt = "This is an example of the method ruminate().";
1359    /// hash.ruminate(2, txt.as_ptr(), txt.len() as u64);
1360    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
1361    /// assert_eq!(hash.to_string(), "EBA9C4DE950CE07EDB662147C3246779660F03607D27493A0D62ECC6282C4501");
1362    /// ```
1363    /// 
1364    /// # Example 2 for SHA2_512_t_256_Expanded
1365    /// ```
1366    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
1367    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
1368    /// let mut my_hash = MySHA2::new();
1369    /// let txt = "This is an example of the method ruminate().";
1370    /// my_hash.ruminate(2, txt.as_ptr(), txt.len() as u64);
1371    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
1372    /// assert_eq!(my_hash.to_string(), "B60D75418A979C6B4E444B755D535257969C5FFC465FA84988026219FC7BD8B7");
1373    /// ```
1374    /// 
1375    /// # Example 3 for SHA2_512_t_224
1376    /// ```
1377    /// use cryptocol::hash::SHA2_512_t_224;
1378    /// let mut hash = SHA2_512_t_224::new();
1379    /// let txt = "This is an example of the method ruminate().";
1380    /// hash.ruminate(2, txt.as_ptr(), txt.len() as u64);
1381    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
1382    /// assert_eq!(hash.to_string(), "A3280359EA2135FE3E2667724FCA6996A47B362544FA60FD59D95DBF");
1383    /// ```
1384    /// 
1385    /// # Example 4 for SHA2_512_t_224_Expanded
1386    /// ```
1387    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
1388    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
1389    /// let mut my_hash = MySHA2::new();
1390    /// let txt = "This is an example of the method ruminate().";
1391    /// my_hash.ruminate(2, txt.as_ptr(), txt.len() as u64);
1392    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
1393    /// assert_eq!(my_hash.to_string(), "E587737E4BC3E1D859AA7FDDD90D3E769158173B7A22FA4BC76E47BA");
1394    /// ```
1395    /// 
1396    /// # Big-endian issue
1397    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
1398    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
1399    /// for Big-endian CPUs with your own full responsibility.
1400    pub fn ruminate(&mut self, n: usize, message: *const u8, length_in_bytes: u64)
1401    {
1402        self.digest(message, length_in_bytes);
1403        for _ in 1..n
1404            { self.digest_array(&self.get_hash_value_in_array()); }
1405    }
1406
1407    // // pub fn ruminate_c(&mut self, n: usize, message: *const u8, length_in_bytes_low: u64, length_in_bytes_high: u64)
1408    // /// Computes a hash value of `message`, and then computes a new hash value
1409    // /// of the hash value of the message, and then computes a hash value of the
1410    // /// previous hash value, and then ... `n` times repeatedly.
1411    // /// 
1412    // /// # Features
1413    // /// This function has the generalized interface (pointer, `*const u8`).
1414    // /// So, this function is usually not called directly in Rust. This function
1415    // /// is provided to be called from other programming languages such as C/C++.
1416    // /// 
1417    // /// # Arguments
1418    // /// - `n` is the number of repetition of digestion
1419    // /// - `message` is pointer to const u8.
1420    // /// - `length_in_bytes_low` is the lower 64 bits of the size of message
1421    // /// in the unit of bytes.
1422    // /// - `length_in_bytes_high` is the higher 64 bits of the size of message
1423    // /// in the unit of bytes.
1424    // /// 
1425    // /// # Origin
1426    // /// Double hashing is invented by Ferguson and Schneier in their book
1427    // /// Practical Cryptography to countermeasure against length extension
1428    // /// attacks. Plus, Bitcoin uses double hashing.
1429    // /// This is generalized version of it.
1430    // /// 
1431    // /// # Security Issue
1432    // /// The author doubts that the double hashing is securer than normal
1433    // /// hashing. The double hashing will be as secure as the normal hashing
1434    // /// at most because birthday paradox applies twice for the double hashing
1435    // /// though the size of the domain is the same size of the codomain for
1436    // /// second hashing of the double hashing, while the birthday paradox
1437    // /// applies only once for the normal hashing.
1438    // /// 
1439    // /// # Example 1 for SHA2_512_t_256
1440    // /// ```
1441    // /// use cryptocol::hash::SHA2_512_t_256;
1442    // /// let mut hash = SHA2_512_t_256::new();
1443    // /// let txt = "This is an example of the method ruminate_c().";
1444    // /// hash.ruminate_c(2, txt.as_ptr(), txt.len() as u64, 0);
1445    // /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
1446    // /// assert_eq!(hash.to_string(), "71D8FB0BC160A3EAA18ED54D48EC54A2FBA4364D4592917CEB8846CAB1492DB6");
1447    // /// ```
1448    // /// 
1449    // /// # Example 2 for SHA2_512_t_256_Expanded
1450    // /// ```
1451    // /// use cryptocol::hash::SHA2_512_t_256_Expanded;
1452    // /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
1453    // /// let mut my_hash = MySHA2::new();
1454    // /// let txt = "This is an example of the method ruminate_c().";
1455    // /// my_hash.ruminate_c(2, txt.as_ptr(), txt.len() as u64, 0);
1456    // /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
1457    // /// assert_eq!(my_hash.to_string(), "A5098CDF4CAFEC47765E2D87557587D50CFA802385C39B3596A816B863C45F82");
1458    // /// ```
1459    // /// # Example 3 for SHA2_512_t_224
1460    // /// ```
1461    // /// use cryptocol::hash::SHA2_512_t_224;
1462    // /// let mut hash = SHA2_512_t_224::new();
1463    // /// let txt = "This is an example of the method ruminate_c().";
1464    // /// hash.ruminate_c(2, txt.as_ptr(), txt.len() as u64, 0);
1465    // /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
1466    // /// assert_eq!(hash.to_string(), "4DA0CB3085D73CA7459E326D51349B5A7C065A270347558DA7FB3784");
1467    // /// ```
1468    // /// 
1469    // /// # Example 4 for SHA2_512_t_224_Expanded
1470    // /// ```
1471    // /// use cryptocol::hash::SHA2_512_t_224_Expanded;
1472    // /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
1473    // /// let mut my_hash = MySHA2::new();
1474    // /// let txt = "This is an example of the method ruminate_c().";
1475    // /// my_hash.ruminate_c(2, txt.as_ptr(), txt.len() as u64, 0);
1476    // /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
1477    // /// assert_eq!(my_hash.to_string(), "4AAE39BF545F153044E1A9D10CDAA98F56D048619C406770709FB015");
1478    // /// ```
1479    // /// 
1480    // /// # Big-endian issue
1481    // /// It is just experimental for Big Endian CPUs. So, you are not encouraged
1482    // /// to use it for Big Endian CPUs for serious purpose. Only use this crate
1483    // /// for Big-endian CPUs with your own full responsibility.
1484    // pub fn ruminate_c(&mut self, n: usize, message: *const u8, length_in_bytes_low: u64, length_in_bytes_high: u64)
1485    // {
1486    //     self.digest_c(message, length_in_bytes_low, length_in_bytes_high);
1487    //     for _ in 1..n
1488    //         { self.digest_array(&self.get_hash_value_in_array()); }
1489    // }
1490
1491    // pub fn ruminate_str(&mut self, n: usize, message: &str)
1492    /// Computes a hash value of `message`, and then computes a new hash value
1493    /// of the hash value of the message, and then computes a hash value of the
1494    /// previous hash value, and then ... `n` times repeatedly.
1495    /// 
1496    /// # Arguments
1497    /// - `n` is the number of repetition of digestion
1498    /// - `message` is `&str`.
1499    /// 
1500    /// # Origin
1501    /// Double hashing is invented by Ferguson and Schneier in their book
1502    /// Practical Cryptography to countermeasure against length extension
1503    /// attacks. Plus, Bitcoin uses double hashing.
1504    /// This is generalized version of it.
1505    /// 
1506    /// # Features
1507    /// This function is a wrapping function of `ruminate()`.
1508    /// This function computes hash value of the content of string slice.
1509    /// 
1510    /// # Security Issue
1511    /// The author doubts that the double hashing is securer than normal
1512    /// hashing. The double hashing will be as secure as the normal hashing
1513    /// at most because birthday paradox applies twice for the double hashing
1514    /// though the size of the domain is the same size of the codomain for
1515    /// second hashing of the double hashing, while the birthday paradox
1516    /// applies only once for the normal hashing.
1517    /// 
1518    /// # Example 1 for SHA2_512_t_256
1519    /// ```
1520    /// use cryptocol::hash::SHA2_512_t_256;
1521    /// let mut hash = SHA2_512_t_256::new();
1522    /// let txt = "This is an example of the method ruminate_str().";
1523    /// hash.ruminate_str(3, txt);
1524    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
1525    /// assert_eq!(hash.to_string(), "D2ACE4176F3EBD2F5786EFD459D72AD44D24425D05494A8FFEFCA75BAB007FA6");
1526    /// ```
1527    /// 
1528    /// # Example 2 for SHA2_512_t_256_Expanded
1529    /// ```
1530    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
1531    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
1532    /// let mut my_hash = MySHA2::new();
1533    /// let txt = "This is an example of the method ruminate_str().";
1534    /// my_hash.ruminate_str(3, txt);
1535    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
1536    /// assert_eq!(my_hash.to_string(), "C5FE6148F6177C5208C8992D2ED20C3016681289ACF5B161D0AD95FB5C4CE5EA");
1537    /// ```
1538    /// 
1539    /// # Example 3 for SHA2_512_t_224
1540    /// ```
1541    /// use cryptocol::hash::SHA2_512_t_224;
1542    /// let mut hash = SHA2_512_t_224::new();
1543    /// let txt = "This is an example of the method ruminate_str().";
1544    /// hash.ruminate_str(3, txt);
1545    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
1546    /// assert_eq!(hash.to_string(), "7FB2230906052932F044352E65F590C416C09C3A7290EF3BC39635EF");
1547    /// ```
1548    /// 
1549    /// # Example 4 for SHA2_512_t_224_Expanded
1550    /// ```
1551    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
1552    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
1553    /// let mut my_hash = MySHA2::new();
1554    /// let txt = "This is an example of the method ruminate_str().";
1555    /// my_hash.ruminate_str(3, txt);
1556    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
1557    /// assert_eq!(my_hash.to_string(), "9FD72DC6516F3E01FAE29244B70D501F6AE73B25CB462F816F01C6F0");
1558    /// ```
1559    /// 
1560    /// # Big-endian issue
1561    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
1562    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
1563    /// for Big-endian CPUs with your own full responsibility.
1564    #[inline]
1565    pub fn ruminate_str(&mut self, n: usize, message: &str)
1566    {
1567        self.ruminate(n, message.as_ptr(), message.len() as u64);
1568    }
1569
1570    // pub fn ruminate_string(&mut self, n: usize, message: &String)
1571    /// Computes a hash value of `message`, and then computes a new hash value
1572    /// of the hash value of the message, and then computes a hash value of the
1573    /// previous hash value, and then ... `n` times repeatedly.
1574    /// 
1575    /// # Arguments
1576    /// - `n` is the number of repetition of digestion
1577    /// - `message` is `&String`.
1578    /// 
1579    /// # Origin
1580    /// Double hashing is invented by Ferguson and Schneier in their book
1581    /// Practical Cryptography to countermeasure against length extension
1582    /// attacks. Plus, Bitcoin uses double hashing.
1583    /// This is generalized version of it.
1584    /// 
1585    /// # Features
1586    /// This function is a wrapping function of `ruminate()`.
1587    /// This function computes hash value of the content of String object.
1588    /// 
1589    /// # Security Issue
1590    /// The author doubts that the double hashing is securer than normal
1591    /// hashing. The double hashing will be as secure as the normal hashing
1592    /// at most because birthday paradox applies twice for the double hashing
1593    /// though the size of the domain is the same size of the codomain for
1594    /// second hashing of the double hashing, while the birthday paradox
1595    /// applies only once for the normal hashing.
1596    /// 
1597    /// # Example 1 for SHA2_512_t_256
1598    /// ```
1599    /// use cryptocol::hash::SHA2_512_t_256;
1600    /// let mut hash = SHA2_512_t_256::new();
1601    /// let txt = "This is an example of the method ruminate_string().".to_string();
1602    /// hash.ruminate_string(2, &txt);
1603    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
1604    /// assert_eq!(hash.to_string(), "7E93544875E40C8F25DDD93AEC9A447C124B22C3DDCDB7479FAD6C144FFC74B2");
1605    /// ```
1606    /// 
1607    /// # Example 2 for SHA2_512_t_256_Expanded
1608    /// ```
1609    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
1610    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
1611    /// let mut my_hash = MySHA2::new();
1612    /// let txt = "This is an example of the method ruminate_string().".to_string();
1613    /// my_hash.ruminate_string(2, &txt);
1614    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
1615    /// assert_eq!(my_hash.to_string(), "8391EA69564967DF827872115E35A98DFEFF72894F6497C369D83C25C8C50E2E");
1616    /// ```
1617    /// 
1618    /// # Example 3 for SHA2_512_t_224
1619    /// ```
1620    /// use cryptocol::hash::SHA2_512_t_224;
1621    /// let mut hash = SHA2_512_t_224::new();
1622    /// let txt = "This is an example of the method ruminate_string().".to_string();
1623    /// hash.ruminate_string(2, &txt);
1624    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
1625    /// assert_eq!(hash.to_string(), "C6887398FA4DA83CD5039DC2764BB363B65F1C557006D627F95B5392");
1626    /// ```
1627    /// 
1628    /// # Example 4 for SHA2_512_t_224_Expanded
1629    /// ```
1630    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
1631    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
1632    /// let mut my_hash = MySHA2::new();
1633    /// let txt = "This is an example of the method ruminate_string().".to_string();
1634    /// my_hash.ruminate_string(2, &txt);
1635    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
1636    /// assert_eq!(my_hash.to_string(), "9B1BFD42888B1655735F6E0F1122E25D33F8DBF6E65D54D4EA0884A3");
1637    /// ```
1638    /// 
1639    /// # Big-endian issue
1640    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
1641    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
1642    /// for Big-endian CPUs with your own full responsibility.
1643    #[inline]
1644    pub fn ruminate_string(&mut self, n: usize, message: &String)
1645    {
1646        self.ruminate(n, message.as_ptr(), message.len() as u64);
1647    }
1648
1649    // pub fn ruminate_array<T, const M: usize>(&mut self, n: usize, message: &[T; M])
1650    /// Computes a hash value of `message`, and then computes a new hash value
1651    /// of the hash value of the message, and then computes a hash value of the
1652    /// previous hash value, and then ... `n` times repeatedly.
1653    /// 
1654    /// # Arguments
1655    /// - `n` is the number of repetition of digestion
1656    /// - `message` is `&[T; M]`.
1657    /// 
1658    /// # Origin
1659    /// Double hashing is invented by Ferguson and Schneier in their book
1660    /// Practical Cryptography to countermeasure against length extension
1661    /// attacks. Plus, Bitcoin uses double hashing.
1662    /// This is generalized version of it.
1663    /// 
1664    /// # Features
1665    /// This function is a wrapping function of `ruminate()`.
1666    /// This function computes hash value of the content of Array object.
1667    /// 
1668    /// # Security Issue
1669    /// The author doubts that the double hashing is securer than normal
1670    /// hashing. The double hashing will be as secure as the normal hashing
1671    /// at most because birthday paradox applies twice for the double hashing
1672    /// though the size of the domain is the same size of the codomain for
1673    /// second hashing of the double hashing, while the birthday paradox
1674    /// applies only once for the normal hashing.
1675    /// 
1676    /// # Example 1 for SHA2_512_t_256
1677    /// ```
1678    /// use cryptocol::hash::SHA2_512_t_256;
1679    /// let mut hash = SHA2_512_t_256::new();
1680    /// let data = [ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1681    /// hash.ruminate_array(5,&data);
1682    /// println!("Msg =\t{:?}\nHash =\t{}", data, hash);
1683    /// assert_eq!(hash.to_string(), "5C8D4F9C47C99BD322E44AA2B6F265D7A788B8898F072E9E998122EB3DE256F9");
1684    /// ```
1685    /// 
1686    /// # Example 2 for SHA2_512_t_256_Expanded
1687    /// ```
1688    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
1689    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
1690    /// let mut my_hash = MySHA2::new();
1691    /// let data = [ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1692    /// my_hash.ruminate_array(5,&data);
1693    /// println!("Msg =\t{:?}\nHash =\t{}", data, my_hash);
1694    /// assert_eq!(my_hash.to_string(), "1A86BD0B53A9CD64FB43CF6BD82107782210A3F5FEC34CAF23B33D51A3B66011");
1695    /// ```
1696    /// 
1697    /// # Example 3 for SHA2_512_t_224
1698    /// ```
1699    /// use cryptocol::hash::SHA2_512_t_224;
1700    /// let mut hash = SHA2_512_t_224::new();
1701    /// let data = [ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1702    /// hash.ruminate_array(5,&data);
1703    /// println!("Msg =\t{:?}\nHash =\t{}", data, hash);
1704    /// assert_eq!(hash.to_string(), "987227F7EC37FCF30A83BE661BF7018616CE5B9C9553AA7892C738D3");
1705    /// ```
1706    /// 
1707    /// # Example 4 for SHA2_512_t_224_Expanded
1708    /// ```
1709    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
1710    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
1711    /// let mut my_hash = MySHA2::new();
1712    /// let data = [ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1713    /// my_hash.ruminate_array(5,&data);
1714    /// println!("Msg =\t{:?}\nHash =\t{}", data, my_hash);
1715    /// assert_eq!(my_hash.to_string(), "BDF3FB6FCEAEB9A75FAA42CE759019A60FEB23E40DBC676F9BE36DE4");
1716    /// ```
1717    /// 
1718    /// # Big-endian issue
1719    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
1720    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
1721    /// for Big-endian CPUs with your own full responsibility.
1722    #[inline]
1723    pub fn ruminate_array<T, const M: usize>(&mut self, n: usize, message: &[T; M])
1724    where T: SmallUInt + Copy + Clone
1725    {
1726        self.ruminate(n, message.as_ptr() as *const u8, (M as u32 * T::size_in_bytes()) as u64);
1727    }
1728
1729    // pub fn ruminate_vec<T>(&mut self, n: usize, message: &Vec<T>)
1730    /// Computes a hash value of `message`, and then computes a new hash value
1731    /// of the hash value of the message, and then computes a hash value of the
1732    /// previous hash value, and then ... `n` times repeatedly.
1733    /// 
1734    /// # Arguments
1735    /// - `n` is the number of repetition of digestion
1736    /// - `message` is `&Vec<T>`.
1737    /// 
1738    /// # Origin
1739    /// Double hashing is invented by Ferguson and Schneier in their book
1740    /// Practical Cryptography to countermeasure against length extension
1741    /// attacks. Plus, Bitcoin uses double hashing.
1742    /// This is generalized version of it.
1743    /// 
1744    /// # Features
1745    /// This function is a wrapping function of `ruminate()`.
1746    /// This function computes hash value of the content of Vec object.
1747    /// 
1748    /// # Security Issue
1749    /// The author doubts that the double hashing is securer than normal
1750    /// hashing. The double hashing will be as secure as the normal hashing
1751    /// at most because birthday paradox applies twice for the double hashing
1752    /// though the size of the domain is the same size of the codomain for
1753    /// second hashing of the double hashing, while the birthday paradox
1754    /// applies only once for the normal hashing.
1755    /// 
1756    /// # Example 1 for SHA2_512_t_256
1757    /// ```
1758    /// use cryptocol::hash::SHA2_512_t_256;
1759    /// let mut hash = SHA2_512_t_256::new();
1760    /// let data = vec![ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1761    /// hash.ruminate_vec(2, &data);
1762    /// println!("Msg =\t{:?}\nHash =\t{}", data, hash);
1763    /// assert_eq!(hash.to_string(), "6A999B22F62122B781705BBEB635E0DFD6F922FB2B0921F912ACA585B618D7F0");
1764    /// ```
1765    /// 
1766    /// # Example 2 for SHA2_512_t_256_Expanded
1767    /// ```
1768    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
1769    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
1770    /// let mut my_hash = MySHA2::new();
1771    /// let data = vec![ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1772    /// my_hash.ruminate_vec(2, &data);
1773    /// println!("Msg =\t{:?}\nHash =\t{}", data, my_hash);
1774    /// assert_eq!(my_hash.to_string(), "2396C1C598B43E445261971C74170745DDB2FD0527684545FFB9818D1D0057AD");
1775    /// ```
1776    /// 
1777    /// # Example 3 for SHA2_512_t_224
1778    /// ```
1779    /// use cryptocol::hash::SHA2_512_t_224;
1780    /// let mut hash = SHA2_512_t_224::new();
1781    /// let data = vec![ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1782    /// hash.ruminate_vec(2, &data);
1783    /// println!("Msg =\t{:?}\nHash =\t{}", data, hash);
1784    /// assert_eq!(hash.to_string(), "ACA9B9D5B327FFE4140F131642F92DCBDFD678FA5F7A42536D27BAF8");
1785    /// ```
1786    /// 
1787    /// # Example 4 for SHA2_512_t_224_Expanded
1788    /// ```
1789    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
1790    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
1791    /// let mut my_hash = MySHA2::new();
1792    /// let data = vec![ 0x67452301_u32.to_le(), 0xefcdab89_u32.to_le(), 0x98badcfe_u32.to_le(), 0x10325476_u32.to_le() ];
1793    /// my_hash.ruminate_vec(2, &data);
1794    /// println!("Msg =\t{:?}\nHash =\t{}", data, my_hash);
1795    /// assert_eq!(my_hash.to_string(), "1AAC9EE0F6B45991CC58691DF19079E99422925DC600789343BEAA24");
1796    /// ```
1797    /// 
1798    /// # Big-endian issue
1799    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
1800    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
1801    /// for Big-endian CPUs with your own full responsibility.
1802    #[inline]
1803    pub fn ruminate_vec<T>(&mut self, n: usize, message: &Vec<T>)
1804    where T: SmallUInt + Copy + Clone
1805    {
1806        self.ruminate(n, message.as_ptr() as *const u8, (message.len() as u32 * T::size_in_bytes()) as u64);
1807    }
1808
1809    // pub fn get_hash_value(&self, hash_value: *mut u8, length: usize)
1810    /// Gives a hash value to the place where `hash_value` points to.
1811    /// 
1812    /// # Features
1813    /// This function has the generalized interface (pointer, `*mut u8`)
1814    /// so as to enable other functions to wrap this function with any
1815    /// convenient interface for uses. So, this function is usually not called
1816    /// directly in Rust. This function is provided to be called from other
1817    /// programming languages such as C/C++.
1818    /// 
1819    /// # Arguments
1820    /// - `hash_value` is the pointer to the place to hold the result hash value.
1821    /// - `length` is the size of the place that `hash_value` points to. 
1822    /// 
1823    /// # Counterpart Methods
1824    /// - If you want to get the hash value in the form of String object,
1825    /// you are highly recommended to use the method
1826    /// [get_hash_value_string()](struct@SHA2_512_t_Generic#method.get_hash_value_string)
1827    /// rather than this method.
1828    /// - If you want to get the hash value in the form of array object,
1829    /// you are highly recommended to use the method
1830    /// [get_hash_value_in_array()](struct@SHA2_512_t_Generic#method.get_hash_value_in_array)
1831    /// rather than this method.
1832    /// - If you want to get the hash value in the form of Vec object,
1833    /// you are highly recommended to use the method
1834    /// [get_hash_value_in_vec()](struct@SHA2_512_t_Generic#method.get_hash_value_in_vec)
1835    /// rather than this method.
1836    /// 
1837    /// # Example 1 for SHA2_512_t_256
1838    /// ```
1839    /// use cryptocol::hash::SHA2_512_t_256;
1840    /// let mut hash = SHA2_512_t_256::new();
1841    /// let txt = "This is an example of the method get_hash_value().";
1842    /// let hash_value = [0_u8; 32];
1843    /// hash.digest_str(txt);
1844    /// hash.get_hash_value(hash_value.as_ptr() as *mut u8, hash_value.len());
1845    /// println!("Msg =\t\"{}\"\nHash =\t{:02X?}", txt, hash_value);
1846    /// assert_eq!(format!("{:02X?}", hash_value), "[50, EA, 83, BF, 41, 5D, 1C, C0, 15, 6C, BF, 90, 5B, AC, BD, 72, A3, BD, 62, 1B, 94, 3A, 64, 64, 13, 05, CF, 17, 43, 52, CF, AD]");
1847    /// ```
1848    /// 
1849    /// # Example 2 for SHA2_512_t_256_Expanded
1850    /// ```
1851    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
1852    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
1853    /// let mut my_hash = MySHA2::new();
1854    /// let txt = "This is an example of the method get_hash_value().";
1855    /// let hash_value = [0_u8; 32];
1856    /// my_hash.digest_str(txt);
1857    /// my_hash.get_hash_value(hash_value.as_ptr() as *mut u8, hash_value.len());
1858    /// println!("Msg =\t\"{}\"\nHash =\t{:02X?}", txt, hash_value);
1859    /// assert_eq!(format!("{:02X?}", hash_value), "[D1, 15, 58, 28, FA, A6, 27, F9, 7E, DE, D0, 98, 74, C0, A1, DB, FA, 5E, C0, E9, A9, 98, 35, DD, B8, 00, DC, B4, 28, 79, A9, D3]");
1860    /// ```
1861    /// 
1862    /// # Example 3 for SHA2_512_t_224
1863    /// ```
1864    /// use cryptocol::hash::SHA2_512_t_224;
1865    /// let mut hash = SHA2_512_t_224::new();
1866    /// let txt = "This is an example of the method get_hash_value().";
1867    /// let hash_value = [0_u8; 28];
1868    /// hash.digest_str(txt);
1869    /// hash.get_hash_value(hash_value.as_ptr() as *mut u8, hash_value.len());
1870    /// println!("Msg =\t\"{}\"\nHash =\t{:02X?}", txt, hash_value);
1871    /// assert_eq!(format!("{:02X?}", hash_value), "[8B, 40, A3, E7, 02, A8, 18, 25, 12, 2C, C8, 55, 07, 4F, 5B, 0F, 73, BD, 30, 42, 5F, 3A, A9, 55, 92, 28, 27, 9E]");
1872    /// ```
1873    /// 
1874    /// # Example 4 for SHA2_512_t_224_Expanded
1875    /// ```
1876    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
1877    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
1878    /// let mut my_hash = MySHA2::new();
1879    /// let txt = "This is an example of the method get_hash_value().";
1880    /// let hash_value = [0_u8; 28];
1881    /// my_hash.digest_str(txt);
1882    /// my_hash.get_hash_value(hash_value.as_ptr() as *mut u8, hash_value.len());
1883    /// println!("Msg =\t\"{}\"\nHash =\t{:02X?}", txt, hash_value);
1884    /// assert_eq!(format!("{:02X?}", hash_value), "[A7, A9, A3, 52, EB, E6, 06, 3E, 80, F1, 7E, 62, 27, 6B, AB, F6, 5C, 21, 8E, 56, B7, 2A, 04, 4C, 7D, 11, C5, 40]");
1885    /// ```
1886    /// 
1887    /// # Big-endian issue
1888    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
1889    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
1890    /// for Big-endian CPUs with your own full responsibility.
1891    pub fn get_hash_value(&self, hash_value: *mut u8, length: usize)
1892    {
1893        let n = t & 0b11_1111;
1894        let nn = (t >> 6) + if n == 0 {0} else {1};
1895        let n_length = if length < (t >> 3) {length} else {t >> 3};
1896        let mut hash_code = [0_u64; 8];
1897        for i in 0..nn
1898            { hash_code[i] = self.hash_code[i].get(); }
1899        if n != 0
1900        {
1901            let mask = (!0_u64) << (64-n);
1902            hash_code[nn-1] &= mask;
1903        }
1904        for i in 0..nn
1905            { hash_code[i] = hash_code[i].to_be(); }
1906        unsafe { copy_nonoverlapping(hash_code.as_ptr() as *const u8, hash_value, n_length); }
1907    }
1908
1909    // pub fn get_hash_value_in_string(&self) -> String
1910    /// Returns a hash value in the form of String object.
1911    /// 
1912    /// # Counterpart Methods
1913    /// - If you want to get the hash value in the form of array object,
1914    /// you are highly recommended to use the method
1915    /// [get_hash_value_in_array()](struct@SHA2_512_t_Generic#method.get_hash_value_in_array)
1916    /// rather than this method.
1917    /// - If you want to get the hash value in the form of Vec object,
1918    /// you are highly recommended to use the method
1919    /// [get_hash_value_in_vec()](struct@SHA2_512_t_Generic#method.get_hash_value_in_vec)
1920    /// rather than this method.
1921    /// - If you want to use this method from other programming languages such
1922    /// as C/C++, you are highly recommended to use the method
1923    /// [get_hash_value()](struct@SHA2_512_t_Generic#method.get_hash_value)
1924    /// rather than this method.
1925    /// 
1926    /// # Example 1 for SHA2_512_t_256
1927    /// ```
1928    /// use cryptocol::hash::SHA2_512_t_256;
1929    /// let mut hash = SHA2_512_t_256::new();
1930    /// let txt = "This is an example of the method get_hash_value_in_string().";
1931    /// hash.digest_str(txt);
1932    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash.get_hash_value_in_string());
1933    /// assert_eq!(hash.get_hash_value_in_string(), "F3E8E24304CD04DBE509FE47FFA84DA4CF15E70EEFD447F34A069047735014DC");
1934    /// ```
1935    /// 
1936    /// # Example 2 for SHA2_512_t_256_Expanded
1937    /// ```
1938    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
1939    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
1940    /// let mut my_hash = MySHA2::new();
1941    /// let txt = "This is an example of the method get_hash_value_in_string().";
1942    /// my_hash.digest_str(txt);
1943    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash.get_hash_value_in_string());
1944    /// assert_eq!(my_hash.get_hash_value_in_string(), "9FF616CE58C7CD8988DD1AF54F9AB5E8674ADF5037A7B059AF7B608023D44FBC");
1945    /// ```
1946    /// 
1947    /// # Example 3 for SHA2_512_t_224
1948    /// ```
1949    /// use cryptocol::hash::SHA2_512_t_224;
1950    /// let mut hash = SHA2_512_t_224::new();
1951    /// let txt = "This is an example of the method get_hash_value_in_string().";
1952    /// hash.digest_str(txt);
1953    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash.get_hash_value_in_string());
1954    /// assert_eq!(hash.get_hash_value_in_string(), "412823A4ED7BBA8C052F3C9B218A9847CDD341818E773F5593011135");
1955    /// ```
1956    /// 
1957    /// # Example 4 for SHA2_512_t_224_Expanded
1958    /// ```
1959    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
1960    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
1961    /// let mut my_hash = MySHA2::new();
1962    /// let txt = "This is an example of the method get_hash_value_in_string().";
1963    /// my_hash.digest_str(txt);
1964    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash.get_hash_value_in_string());
1965    /// assert_eq!(my_hash.get_hash_value_in_string(), "1E5E301B37EC1336D5EB0D9A4AE18833F418C93F8ADBD87BE6817922");
1966    /// ```
1967    /// 
1968    /// # Big-endian issue
1969    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
1970    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
1971    /// for Big-endian CPUs with your own full responsibility.
1972    pub fn get_hash_value_in_string(&self) -> String
1973    {
1974        let n = t & 0b11_1111;  // equivalent to = t % 64
1975        let nn = (t >> 6) + if n != 0 {1} else {0};
1976        let mut txt = String::new();
1977        for i in 0..if n == 0 {nn} else {nn-1}
1978        {
1979            let hs = self.hash_code[i];
1980            for j in 0..8
1981            {
1982                let byte = hs.get_ubyte_(7-j);
1983                txt.push(Self::to_char(byte >> 4));
1984                txt.push(Self::to_char(byte & 0b1111));
1985            }
1986        }
1987        if n != 0
1988        {
1989            let hs = self.hash_code[nn-1];
1990            let m = n >> 3; // equivalent to = n / 8
1991            for j in 0..m
1992            {
1993                let byte = hs.get_ubyte_(7-j);
1994                txt.push(Self::to_char(byte >> 4));
1995                txt.push(Self::to_char(byte & 0b1111));
1996            }
1997        }
1998        txt
1999    }
2000
2001    // pub fn get_hash_value_in_array(&self) -> [u64; 8]
2002    /// Returns a hash value in the form of array object.
2003    /// 
2004    /// # Counterpart Methods
2005    /// - If you want to get the hash value in the form of String object,
2006    /// you are highly recommended to use the method
2007    /// [get_hash_value_string()](struct@SHA2_512_t_Generic#method.get_hash_value_string)
2008    /// rather than this method.
2009    /// - If you want to get the hash value in the form of Vec object,
2010    /// you are highly recommended to use the method
2011    /// [get_hash_value_in_vec()](struct@SHA2_512_t_Generic#method.get_hash_value_in_vec)
2012    /// rather than this method.
2013    /// - If you want to use this method from other programming languages such
2014    /// as C/C++, you are highly recommended to use the method
2015    /// [get_hash_value()](struct@SHA2_512_t_Generic#method.get_hash_value)
2016    /// rather than this method.
2017    /// 
2018    /// # Example 1 for SHA2_512_t_256
2019    /// ```
2020    /// use cryptocol::hash::SHA2_512_t_256;
2021    /// let mut hash = SHA2_512_t_256::new();
2022    /// let txt = "This is an example of the method get_hash_value_in_array().";
2023    /// hash.digest_str(txt);
2024    /// let h = hash.get_hash_value_in_array();
2025    /// println!("Msg =\t\"{}\"\nHash =\t{:016X?}", txt, h);
2026    /// assert_eq!(format!("{:016X?}", h), "[7770814665222F53, FAF871C4D20657F0, 4E3F488853C5C485, CDCFE5F1EB447C2F, 14F3BFD7D115FE93, 308218F3657D3CE6, 5D68300E49B0BE02, 9F8286AC65BAC220]");
2027    /// ```
2028    /// 
2029    /// # Example 2 for SHA2_512_t_256_Expanded
2030    /// ```
2031    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
2032    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
2033    /// let mut my_hash = MySHA2::new();
2034    /// let txt = "This is an example of the method get_hash_value_in_array().";
2035    /// my_hash.digest_str(txt);
2036    /// let h = my_hash.get_hash_value_in_array();
2037    /// println!("Msg =\t\"{}\"\nHash =\t{:016X?}", txt, h);
2038    /// assert_eq!(format!("{:016X?}", h), "[74688674B8E8B4BA, 439E1BEC604C9A30, C3E0398F8D52D970, 44B615CD387A9826, AE64BC4B33F5B6B3, 8D7A9CE85CB18255, E30515AA6BC2C25F, 2BA7DE436CE08812]");
2039    /// ```
2040    /// 
2041    /// # Example 3 for SHA2_512_t_224
2042    /// ```
2043    /// use cryptocol::hash::SHA2_512_t_224;
2044    /// let mut hash = SHA2_512_t_224::new();
2045    /// let txt = "This is an example of the method get_hash_value_in_array().";
2046    /// hash.digest_str(txt);
2047    /// let h = hash.get_hash_value_in_array();
2048    /// println!("Msg =\t\"{}\"\nHash =\t{:016X?}", txt, h);
2049    /// assert_eq!(format!("{:016X?}", h), "[5D4F9158C3082FB5, DA01BFDDDDC44C7B, 8E72845FCC6EF467, EBCF28927DFDDD35, E9ACDB58F2E01FAE, E62CF6411757DAD2, 9CC9EF5BD989F543, 055C3169B2B23276]");
2050    /// ```
2051    /// 
2052    /// # Example 4 for SHA2_512_t_224_Expanded
2053    /// ```
2054    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
2055    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
2056    /// let mut my_hash = MySHA2::new();
2057    /// let txt = "This is an example of the method get_hash_value_in_array().";
2058    /// my_hash.digest_str(txt);
2059    /// let h = my_hash.get_hash_value_in_array();
2060    /// println!("Msg =\t\"{}\"\nHash =\t{:016X?}", txt, h);
2061    /// assert_eq!(format!("{:016X?}", h), "[66E3FC505AE3D81E, 09B33F26C109A6D8, 0965E49C9CEC98D8, BEDFF6D3ACA89A9C, 95C0831C1F650A37, BEAAC6B754481D81, D4EEECD4ADE7BF93, FFA8A6B1808E60DD]");
2062    /// ```
2063    /// 
2064    /// # Big-endian issue
2065    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
2066    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
2067    /// for Big-endian CPUs with your own full responsibility.
2068    pub fn get_hash_value_in_array(&self) -> [u64; 8]
2069    {
2070        let mut res = [0_u64; 8];
2071        for i in 0..8
2072            { res[i] = self.hash_code[i].get().to_be(); }
2073        res
2074    }
2075
2076    // pub fn get_hash_value_in_array_tm<T, const M: usize>(&self) -> [T; M]
2077    /// Returns a hash value in the form of array object.
2078    /// 
2079    /// # Generic Parameters
2080    /// - `T`: primitive datatype of each element.
2081    /// - `M`: the number of elements
2082    /// 
2083    /// # Counterpart Methods
2084    /// - If you want to get the hash value in the form of String object,
2085    /// you are highly recommended to use the method
2086    /// [get_hash_value_string()](struct@SHA2_512_t_Generic#method.get_hash_value_string)
2087    /// rather than this method.
2088    /// - If you want to get the hash value in the form of Vec object,
2089    /// you are highly recommended to use the method
2090    /// [get_hash_value_in_vec()](struct@SHA2_512_t_Generic#method.get_hash_value_in_vec)
2091    /// rather than this method.
2092    /// - If you want to use this method from other programming languages such
2093    /// as C/C++, you are highly recommended to use the method
2094    /// [get_hash_value()](struct@SHA2_512_t_Generic#method.get_hash_value)
2095    /// rather than this method.
2096    /// 
2097    /// # Example 1 for SHA2_512_t_256
2098    /// ```
2099    /// use cryptocol::hash::SHA2_512_t_256;
2100    /// let mut hash = SHA2_512_t_256::new();
2101    /// let txt = "This is an example of the method get_hash_value_in_array_tm().";
2102    /// hash.digest_str(txt);
2103    /// let h: [u64; 4] = hash.get_hash_value_in_array_tm();
2104    /// println!("Msg =\t\"{}\"\nHash =\t{:016X?}", txt, h);
2105    /// assert_eq!(format!("{:016X?}", h), "[B2CB9E8954581373, CB03D5E9B4A232D3, B6A92CB91A33C2B6, A78A5A9914FFAAFD]");
2106    /// ```
2107    /// 
2108    /// # Example 2 for SHA2_512_t_256_Expanded
2109    /// ```
2110    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
2111    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
2112    /// let mut my_hash = MySHA2::new();
2113    /// let txt = "This is an example of the method get_hash_value_in_array_tm().";
2114    /// my_hash.digest_str(txt);
2115    /// let h: [u64; 4] = hash.get_hash_value_in_array_tm();
2116    /// println!("Msg =\t\"{}\"\nHash =\t{:016X?}", txt, h);
2117    /// assert_eq!(format!("{:016X?}", h), "[B2CB9E8954581373, CB03D5E9B4A232D3, B6A92CB91A33C2B6, A78A5A9914FFAAFD]");
2118    /// ```
2119    /// 
2120    /// # Example 3 for SHA2_512_t_224
2121    /// ```
2122    /// use cryptocol::hash::SHA2_512_t_256;
2123    /// let mut hash = SHA2_512_t_256::new();
2124    /// let txt = "This is an example of the method get_hash_value_in_array_tm().";
2125    /// hash.digest_str(txt);
2126    /// let h: [u32; 7] = hash.get_hash_value_in_array_tm();
2127    /// println!("Msg =\t\"{}\"\nHash =\t{:08X?}", txt, h);
2128    /// assert_eq!(format!("{:08X?}", h), "[54581373, B2CB9E89, B4A232D3, CB03D5E9, 1A33C2B6, B6A92CB9, 14FFAAFD]");
2129    /// ```
2130    /// 
2131    /// # Example 4 for SHA2_512_t_224_Expanded
2132    /// ```
2133    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
2134    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
2135    /// let mut my_hash = MySHA2::new();
2136    /// let txt = "This is an example of the method get_hash_value_in_array_tm().";
2137    /// my_hash.digest_str(txt);
2138    /// let h: [u32; 7] = my_hash.get_hash_value_in_array_tm();
2139    /// println!("Msg =\t\"{}\"\nHash =\t{:08X?}", txt, h);
2140    /// assert_eq!(format!("{:08X?}", h), "[63D2D0E1, A3378487, 116930CC, 1DD5D525, 47DAE024, 0B502841, AC13B293]");
2141    /// ```
2142    /// 
2143    /// # Big-endian issue
2144    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
2145    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
2146    /// for Big-endian CPUs with your own full responsibility.
2147    pub fn get_hash_value_in_array_tm<T, const M: usize>(&self) -> [T; M]
2148    where T: SmallUInt + Copy + Clone + Display + Debug + ToString
2149    {
2150        let mut o = [T::zero(); M];
2151        self.put_hash_value_in_array(&mut o);
2152        o
2153    }
2154
2155    // pub fn get_hash_value_in_vec(&self) -> Vec
2156    /// Returns a hash value in the form of Vec object.
2157    /// 
2158    /// # Counterpart Methods
2159    /// - If you want to get the hash value in the form of String object,
2160    /// you are highly recommended to use the method
2161    /// [get_hash_value_string()](struct@SHA2_512_t_Generic#method.get_hash_value_string)
2162    /// rather than this method.
2163    /// - If you want to get the hash value in the form of array object,
2164    /// you are highly recommended to use the method
2165    /// [get_hash_value_in_array()](struct@SHA2_512_t_Generic#method.get_hash_value_in_array)
2166    /// rather than this method.
2167    /// - If you want to use this method from other programming languages such
2168    /// as C/C++, you are highly recommended to use the method
2169    /// [get_hash_value()](struct@SHA2_512_t_Generic#method.get_hash_value)
2170    /// rather than this method.
2171    /// 
2172    /// # Example 1 for SHA2_512_t_256
2173    /// ```
2174    /// use cryptocol::hash::SHA2_512_t_256;
2175    /// let mut hash = SHA2_512_t_256::new();
2176    /// let txt = "This is an example of the method get_hash_value_in_vec().";
2177    /// hash.digest_str(txt);
2178    /// println!("Msg =\t\"{}\"\nHash =\t{:016X?}", txt, hash.get_hash_value_in_vec());
2179    /// assert_eq!(format!("{:016X?}", hash.get_hash_value_in_vec()), "[80A8B6995518FCAE, 88552E1A484EDBE2, 0D97F5D05378D628, 5B7CE15DDBCA6AFA]");
2180    /// ```
2181    /// 
2182    /// # Example 2 for SHA2_512_t_256_Expanded
2183    /// ```
2184    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
2185    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
2186    /// let mut my_hash = MySHA2::new();
2187    /// let txt = "This is an example of the method get_hash_value_in_vec().";
2188    /// my_hash.digest_str(txt);
2189    /// println!("Msg =\t\"{}\"\nHash =\t{:016X?}", txt, my_hash.get_hash_value_in_vec());
2190    /// assert_eq!(format!("{:016X?}", my_hash.get_hash_value_in_vec()), "[CAE7273F660C1371, F0A69EBDB143A63D, 37701C05D8CAA659, 76C307D312210B47]");
2191    /// ```
2192    /// 
2193    /// # Example 3 for SHA2_512_t_224
2194    /// ```
2195    /// use cryptocol::hash::SHA2_512_t_224;
2196    /// let mut hash = SHA2_512_t_224::new();
2197    /// let txt = "This is an example of the method get_hash_value_in_vec().";
2198    /// hash.digest_str(txt);
2199    /// println!("Msg =\t\"{}\"\nHash =\t{:016X?}", txt, hash.get_hash_value_in_vec());
2200    /// assert_eq!(format!("{:016X?}", hash.get_hash_value_in_vec()), "[CDDD34F4216F38F0, CF7779A43F982E1A, 964CE2DBE181F3D3, 95AFDE2500000000]");
2201    /// ```
2202    /// 
2203    /// # Example 4 for SHA2_512_t_224_Expanded
2204    /// ```
2205    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
2206    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
2207    /// let mut my_hash = MySHA2::new();
2208    /// let txt = "This is an example of the method get_hash_value_in_vec().";
2209    /// my_hash.digest_str(txt);
2210    /// println!("Msg =\t\"{}\"\nHash =\t{:016X?}", txt, my_hash.get_hash_value_in_vec());
2211    /// assert_eq!(format!("{:016X?}", my_hash.get_hash_value_in_vec()), "[BEBD35E3ECE3EE83, 1A9F9889D1926D37, 08CF548C8A943F0A, 1BFECCAF00000000]");
2212    /// ```
2213    /// 
2214    /// # Big-endian issue
2215    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
2216    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
2217    /// for Big-endian CPUs with your own full responsibility.
2218    pub fn get_hash_value_in_vec(&self) -> Vec<u64>
2219    {
2220        let n = t & 0b11_1111;  // equivalent to = t % 64
2221        let nn = (t >> 6) + if n == 0 {0} else {1};
2222        let mut res = Vec::new();
2223        for i in 0..nn
2224            { res.push(self.hash_code[i].get().to_be()); }
2225        if n != 0
2226            { res[nn-1] &= (!0_u64) << (64-n); }
2227        res
2228    }
2229
2230    // pub fn put_hash_value_in_array<T, const M: usize>(&self, out: &mut [T; M])
2231    /// Puts a hash value in the form of array object.
2232    /// 
2233    /// # Argument
2234    /// `out` is the array [T; M] which is the place to put the hash value.
2235    /// 
2236    /// # Features
2237    /// If `M * mem::size_of::<T>()` > `64`,
2238    /// it pass the output as the amount of `64`.
2239    /// 
2240    /// # Example 1 for SHA2_512_t_256
2241    /// ```
2242    /// use cryptocol::hash::SHA2_512_t_256;
2243    /// let mut hash = SHA2_512_t_256::new();
2244    /// let txt = "This is an example of the method put_hash_value_in_array().";
2245    /// let mut hash_code = [0_u64; 4];
2246    /// hash.digest_str(txt);
2247    /// hash.put_hash_value_in_array(&mut hash_code);
2248    /// println!("Msg =\t\"{}\"\nHash =\t{:016X?}", txt, hash_code);
2249    /// assert_eq!(format!("{:016X?}", hash_code), "[9BEF237372571C24, 77A1E2AFFDC98530, A0B9D10323B70681, 436DAE1631785347]");
2250    /// ```
2251    /// 
2252    /// # Example 2 for SHA2_512_t_256_Expanded
2253    /// ```
2254    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
2255    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
2256    /// let mut my_hash = MySHA2::new();
2257    /// let txt = "This is an example of the method put_hash_value_in_array().";
2258    /// let mut hash_code = [0_u64; 4];
2259    /// my_hash.digest_str(txt);
2260    /// my_hash.put_hash_value_in_array(&mut hash_code);
2261    /// println!("Msg =\t\"{}\"\nHash =\t{:016X?}", txt, hash_code);
2262    /// assert_eq!(format!("{:016X?}", hash_code), "[DFE2E754EF11C0D9, 01EAC6F6FF8C0BDB, FF5A2F28DA6C75FA, E0A9B70B2498F0AC]");
2263    /// ```
2264    /// 
2265    /// # Example 3 for SHA2_512_t_224
2266    /// ```
2267    /// use cryptocol::hash::SHA2_512_t_224;
2268    /// let mut hash = SHA2_512_t_224::new();
2269    /// let txt = "This is an example of the method put_hash_value_in_array().";
2270    /// let mut hash_code = [0_u32; 7];
2271    /// hash.digest_str(txt);
2272    /// hash.put_hash_value_in_array(&mut hash_code);
2273    /// println!("Msg =\t\"{}\"\nHash =\t{:08X?}", txt, hash_code);
2274    /// assert_eq!(format!("{:08X?}", hash_code), "[4475114A, BD7D631C, 0A487709, 8B533EBA, 29C83AAF, BD7EB4EF, 77256C3D]");
2275    /// ```
2276    /// 
2277    /// # Example 4 for SHA2_512_t_224_Expanded
2278    /// ```
2279    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
2280    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
2281    /// let mut my_hash = MySHA2::new();
2282    /// let txt = "This is an example of the method put_hash_value_in_array().";
2283    /// let mut hash_code = [0_u32; 7];
2284    /// my_hash.digest_str(txt);
2285    /// my_hash.put_hash_value_in_array(&mut hash_code);
2286    /// println!("Msg =\t\"{}\"\nHash =\t{:08X?}", txt, hash_code);
2287    /// assert_eq!(format!("{:08X?}", hash_code), "[3AAAFB02, A794F5B0, 917078C8, 20548087, 3A7C909F, 4F998CBE, 3A926E6B]");
2288    /// ```
2289    /// 
2290    /// # Big-endian issue
2291    /// It is just experimental for Big Endian CPUs. So, you are not encouraged
2292    /// to use it for Big Endian CPUs for serious purpose. Only use this crate
2293    /// for Big-endian CPUs with your own full responsibility.
2294    pub fn put_hash_value_in_array<T, const M: usize>(&self, out: &mut [T; M])
2295    where T: SmallUInt + Copy + Clone + Display + Debug + ToString
2296    {
2297        let res = self.get_hash_value_in_array();
2298        let out_size = T::size_in_bytes() * M as u32;
2299        let length = if out_size < 64 {out_size} else {64};
2300        unsafe { copy_nonoverlapping(res.as_ptr() as *const u8, out as *mut T as *mut u8, length as usize); }
2301    }
2302
2303    // pub fn tangle(&mut self, tangling: u64)
2304    /// Tangles the hash value
2305    /// 
2306    /// # Argument
2307    /// u64 constants to tangle the hash value
2308    /// 
2309    /// # Features
2310    /// It is for using this struct as random number generator.
2311    /// 
2312    /// # Example 1 for SHA2_512_t_256
2313    /// ```
2314    /// use cryptocol::hash::SHA2_512_t_256;
2315    /// let mut hash = SHA2_512_t_256::new();
2316    /// let txt = "TANGLING";
2317    /// hash.digest_str(txt);
2318    /// println!("Msg =\t\"{}\"\nHash =\t{:016X?}", txt, hash.get_hash_value_in_array_tm::<u64, 4>());
2319    /// assert_eq!(format!("{:016X?}", hash.get_hash_value_in_array_tm::<u64, 4>()), "[FC36648637962C38, BDFBBAE5DEA75E0E, D72827D56EB79EF9, 4969BAA99DB0E42B]");
2320    /// hash.tangle(1);
2321    /// println!("Hash =\t{:016X?}", hash.get_hash_value_in_array_tm::<u64, 4>());
2322    /// assert_eq!(format!("{:016X?}", hash.get_hash_value_in_array_tm::<u64, 4>()), "[96CA6859E014C355, 6BBED0E8DA26FFAD, A4F89477C93C9E8C, 806148BDB037AE26]");
2323    /// hash.tangle(1);
2324    /// println!("Hash =\t{:016X?}", hash.get_hash_value_in_array_tm::<u64, 4>());
2325    /// assert_eq!(format!("{:016X?}", hash.get_hash_value_in_array_tm::<u64, 4>()), "[11F5369ABC9E3B5D, D3D869131E697AB2, 1899C8D791BB09FC, 0C6CE82AE3B9D583]");
2326    /// ```
2327    /// 
2328    /// # Example 2 for SHA2_512_t_256_Expanded
2329    /// ```
2330    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
2331    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
2332    /// let mut my_hash = MySHA2::new();
2333    /// let txt = "TANGLING";
2334    /// my_hash.digest_str(txt);
2335    /// println!("Msg =\t\"{}\"\nHash =\t{:016X?}", txt, my_hash.get_hash_value_in_array_tm::<u64, 4>());
2336    /// assert_eq!(format!("{:016X?}", my_hash.get_hash_value_in_array_tm::<u64, 4>()), "[C60A42A16859F8B8, 7EAB94538B024642, 654DD7795DDDD39B, 12E1A03748AEFFF3]");
2337    /// my_hash.tangle(1);
2338    /// println!("Hash =\t{:016X?}", my_hash.get_hash_value_in_array_tm::<u64, 4>());
2339    /// assert_eq!(format!("{:016X?}", my_hash.get_hash_value_in_array_tm::<u64, 4>()), "[05A82162DE47FEE5, 4B7C2320AF525665, 0D9A9FC79B16B8E6, B51D2D5242BADECD]");
2340    /// my_hash.tangle(1);
2341    /// println!("Hash =\t{:016X?}", my_hash.get_hash_value_in_array_tm::<u64, 4>());
2342    /// assert_eq!(format!("{:016X?}", my_hash.get_hash_value_in_array_tm::<u64, 4>()), "[BC74B5902DD2AB00, 680C9FE85FED5E60, 4FAAF51214292837, B9292AFDBF94B64E]");
2343    /// ```
2344    /// 
2345    /// # Example 3 for SHA2_512_t_224
2346    /// ```
2347    /// use cryptocol::hash::SHA2_512_t_224;
2348    /// let mut hash = SHA2_512_t_224::new();
2349    /// let txt = "TANGLING";
2350    /// hash.digest_str(txt);
2351    /// println!("Msg =\t\"{}\"\nHash =\t{:08X?}", txt, hash.get_hash_value_in_array_tm::<u32, 7>());
2352    /// assert_eq!(format!("{:08X?}", hash.get_hash_value_in_array_tm::<u32, 7>()), "[72E2E82F, C78389DA, 112F494F, B415B8C4, EF993BFA, EDB5091B, 8C03F067]");
2353    /// hash.tangle(1);
2354    /// println!("Hash =\t{:08X?}", hash.get_hash_value_in_array_tm::<u32, 7>());
2355    /// assert_eq!(format!("{:08X?}", hash.get_hash_value_in_array_tm::<u32, 7>()), "[A7CED549, 2C050740, 9BC2F6E5, EAC6D908, 26148AE9, 966D5E72, ED5DF840]");
2356    /// hash.tangle(1);
2357    /// println!("Hash =\t{:08X?}", hash.get_hash_value_in_array_tm::<u32, 7>());
2358    /// assert_eq!(format!("{:08X?}", hash.get_hash_value_in_array_tm::<u32, 7>()), "[14C24EAE, B39CD243, 8C484722, CB1A03AA, F1F9F55E, 955A27D8, 70A3ED4F]");
2359    /// ```
2360    /// 
2361    /// # Example 4 for SHA2_512_t_224_Expanded
2362    /// ```
2363    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
2364    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
2365    /// let mut my_hash = MySHA2::new();
2366    /// let txt = "TANGLING";
2367    /// my_hash.digest_str(txt);
2368    /// println!("Msg =\t\"{}\"\nHash =\t{:08X?}", txt, my_hash.get_hash_value_in_array_tm::<u32, 7>());
2369    /// assert_eq!(format!("{:08X?}", my_hash.get_hash_value_in_array_tm::<u32, 7>()), "[6EF90662, CD08A7EA, 93D0EDFC, 390175A6, 53368038, ADC8BCC8, 11351AB8]");
2370    /// my_hash.tangle(1);
2371    /// println!("Hash =\t{:08X?}", my_hash.get_hash_value_in_array_tm::<u32, 7>());
2372    /// assert_eq!(format!("{:08X?}", my_hash.get_hash_value_in_array_tm::<u32, 7>()), "[F7566CAF, B1039FF1, 722C9B99, 5AA84D67, E6C1182A, 3B4D2DBF, 7F1FA1C8]");
2373    /// my_hash.tangle(1);
2374    /// println!("Hash =\t{:08X?}", my_hash.get_hash_value_in_array_tm::<u32, 7>());
2375    /// assert_eq!(format!("{:08X?}", my_hash.get_hash_value_in_array_tm::<u32, 7>()), "[5B74C46E, F433ACC6, 6A402398, 39126678, 581E67AD, 14A4C823, 4B387049]");
2376    /// ```
2377    #[inline]
2378    pub fn tangle(&mut self, tangling: u64)
2379    {
2380        let mut m = [0_u64; 9];
2381        for i in 0..8
2382            { m[i] = self.hash_code[i].get(); }
2383        m[8] = tangling;
2384        self.finalize(m.as_ptr() as *const u8, 72);
2385    }
2386
2387    // fn initialize(&mut self)
2388    /// Initializes all five self.hash_code[] with predetermined values H[].
2389    fn initialize(&mut self)
2390    {
2391        for i in 0..8_usize
2392            { self.hash_code[i] = LongUnion::new_with(self.o[i]); }
2393    }
2394
2395    // fn update(&mut self, message: &[u32])
2396    /// This method is the core part of MD5 hash algorithm.
2397    /// It has sixty-four rounds. It updates self.hash_code[] for those
2398    /// sixty-four rounds.
2399    fn update(&mut self, message: &[u64])
2400    {
2401        let mut w = [0_u64; 16];
2402        let mut a = self.hash_code[0].get();
2403        let mut b = self.hash_code[1].get();
2404        let mut c = self.hash_code[2].get();
2405        let mut d = self.hash_code[3].get();
2406        let mut e = self.hash_code[4].get();
2407        let mut f = self.hash_code[5].get();
2408        let mut g = self.hash_code[6].get();
2409        let mut h = self.hash_code[7].get();
2410
2411        for i in 0..16_usize
2412        {
2413            w[i] = message[i].to_be();
2414            let s1 = e.rotate_right(RR14) ^ e.rotate_right(RR18) ^ e.rotate_right(RR41);
2415            let t1 = Self::ch(e, f, g).wrapping_add(h)
2416                                .wrapping_add(Self::get_k(i))
2417                                .wrapping_add(w[i])
2418                                .wrapping_add(s1);
2419            let s0 = a.rotate_right(RR28) ^ a.rotate_right(RR34) ^ a.rotate_right(RR39);
2420            let t2 = Self::maj(a, b, c).wrapping_add(s0);
2421            h = g;
2422            g = f;
2423            f = e;
2424            e = d.wrapping_add(t1);
2425            d = c;
2426            c = b;
2427            b = a;
2428            a = t1.wrapping_add(t2);
2429        }
2430        for i in 16..ROUND // ROUND = 64_usize for officiial SHA-2/256
2431        {
2432            let j = i & 0b1111;
2433            w[j] = Self::get_w(&w, i);
2434            let s1 = e.rotate_right(RR14) ^ e.rotate_right(RR18) ^ e.rotate_right(RR41);
2435            let t1 = Self::ch(e, f, g).wrapping_add(h)
2436                                .wrapping_add(Self::get_k(i))
2437                                .wrapping_add(w[j])
2438                                .wrapping_add(s1);
2439            let s0 = a.rotate_right(RR28) ^ a.rotate_right(RR34) ^ a.rotate_right(RR39);
2440            let t2 = Self::maj(a, b, c).wrapping_add(s0);
2441            h = g;
2442            g = f;
2443            f = e;
2444            e = d.wrapping_add(t1);
2445            d = c;
2446            c = b;
2447            b = a;
2448            a = t1.wrapping_add(t2);
2449        }
2450
2451        self.hash_code[0].set(self.hash_code[0].get().wrapping_add(a));
2452        self.hash_code[1].set(self.hash_code[1].get().wrapping_add(b));
2453        self.hash_code[2].set(self.hash_code[2].get().wrapping_add(c));
2454        self.hash_code[3].set(self.hash_code[3].get().wrapping_add(d));
2455        self.hash_code[4].set(self.hash_code[4].get().wrapping_add(e));
2456        self.hash_code[5].set(self.hash_code[5].get().wrapping_add(f));
2457        self.hash_code[6].set(self.hash_code[6].get().wrapping_add(g));
2458        self.hash_code[7].set(self.hash_code[7].get().wrapping_add(h));
2459    }
2460
2461    // fn finalize(&mut self, message: *const u8, length_in_bytes: u64)
2462    /// finalizes the hash process. In this process, it pads with padding bits,
2463    /// which are bit one, bits zeros, and eight bytes that show the message
2464    /// size in the unit of bits with big endianness so as to make the data
2465    /// (message + padding bits) be multiples of 512 bits (64 bytes).
2466    fn finalize(&mut self, message: *const u8, length_in_bytes: u64)
2467    {
2468        type ChunkType = u128;
2469        type PieceType = u64;
2470        const MESSAGE_NUM: usize = 128;
2471        const LAST_BYTES: u64 = 0b111_1111;
2472        union MU
2473        {
2474            chunk: [ChunkType; 8],
2475            piece: [PieceType; 16],
2476            txt: [u8; MESSAGE_NUM],
2477        }
2478
2479        let mut mu = MU { txt: [0; MESSAGE_NUM] };
2480        let last_bytes = (length_in_bytes & LAST_BYTES) as usize;    // equivalent to (length_in_bytes % 128) as usize
2481        unsafe { copy_nonoverlapping(message, mu.txt.as_mut_ptr(), last_bytes); }
2482        unsafe { mu.txt[last_bytes] = 0b1000_0000; }
2483        // 데이터 기록후, 데이터의 길이를 비트 단위로 기록하기 위한 64 비트(8 바이트)와
2484        // 0b1000_0000를 기록하기 위한 한 바이트의 여유공간이 남아있지 않으면,
2485        if last_bytes > 110  // (128 - 16 - 1)
2486        {
2487            self.update(unsafe {&mu.piece});
2488            for i in 0..7
2489                { unsafe { mu.chunk[i] = 0; } }
2490        }
2491        unsafe { mu.chunk[7] = ((length_in_bytes as u128) << 3).to_be(); }    // 데이터 길이의 단위는 바이트가 아니라 비트이다.
2492        self.update(unsafe {&mu.piece});
2493    }
2494
2495	#[inline] fn get_k(idx: usize) -> u64    { Self::K[idx % 80] }
2496    #[inline] fn get_s0(w: &[u64; 16], idx: usize) -> u64  { let ww = w[(idx-15) & 0b1111]; ww.rotate_right(RR1) ^ ww.rotate_right(RR8) ^ (ww >> SR7) }
2497    #[inline] fn get_s1(w: &[u64; 16], idx: usize) -> u64  { let ww = w[(idx-2) & 0b1111]; ww.rotate_right(RR19) ^ ww.rotate_right(RR61) ^ (ww >> SR6) }
2498    #[inline] fn get_w(w: &[u64; 16], idx: usize) -> u64   { w[(idx-16) & 0b1111].wrapping_add(Self::get_s0(&w, idx)).wrapping_add(w[(idx-7) & 0b1111]).wrapping_add(Self::get_s1(&w, idx)) }
2499	#[inline] fn ch(x: u64, y: u64, z: u64) -> u64  { z ^ (x & (y ^ z)) }   // equivalent to { (x & y) | (!x & z) }
2500	#[inline] fn maj(x: u64, y: u64, z: u64) -> u64  { (x & y) | (z & (x | y)) } // equivalent to { (x & y) | (y & z) | (z & x) }
2501    #[inline] fn to_char(nibble: u8) -> char    { if nibble < 10  { ('0' as u8 + nibble) as u8 as char } else { ('A' as u8 - 10 + nibble) as char } }
2502}
2503
2504
2505#[allow(non_upper_case_globals)]
2506impl<const t: usize, const A5A5A5A5A5A5A5A5: u64,
2507    const H0: u64, const H1: u64, const H2: u64, const H3: u64,
2508    const H4: u64, const H5: u64, const H6: u64, const H7: u64,
2509    const ROUND: usize,
2510    const K00: u64, const K01: u64, const K02: u64, const K03: u64,
2511    const K04: u64, const K05: u64, const K06: u64, const K07: u64,
2512    const K08: u64, const K09: u64, const K10: u64, const K11: u64,
2513    const K12: u64, const K13: u64, const K14: u64, const K15: u64,
2514    const K16: u64, const K17: u64, const K18: u64, const K19: u64,
2515    const K20: u64, const K21: u64, const K22: u64, const K23: u64,
2516    const K24: u64, const K25: u64, const K26: u64, const K27: u64,
2517    const K28: u64, const K29: u64, const K30: u64, const K31: u64,
2518    const K32: u64, const K33: u64, const K34: u64, const K35: u64,
2519    const K36: u64, const K37: u64, const K38: u64, const K39: u64,
2520    const K40: u64, const K41: u64, const K42: u64, const K43: u64,
2521    const K44: u64, const K45: u64, const K46: u64, const K47: u64,
2522    const K48: u64, const K49: u64, const K50: u64, const K51: u64,
2523    const K52: u64, const K53: u64, const K54: u64, const K55: u64,
2524    const K56: u64, const K57: u64, const K58: u64, const K59: u64,
2525    const K60: u64, const K61: u64, const K62: u64, const K63: u64,
2526    const K64: u64, const K65: u64, const K66: u64, const K67: u64,
2527    const K68: u64, const K69: u64, const K70: u64, const K71: u64,
2528    const K72: u64, const K73: u64, const K74: u64, const K75: u64,
2529    const K76: u64, const K77: u64, const K78: u64, const K79: u64,
2530    const RR1: u32, const RR8: u32, const RR14: u32, const RR18: u32, 
2531    const RR19: u32, const RR28: u32, const RR34: u32, const RR39: u32, 
2532    const RR41: u32, const RR61: u32, const SR6: i32, const SR7: i32>
2533Display for SHA2_512_t_Generic<t, A5A5A5A5A5A5A5A5,
2534                                H0, H1, H2, H3, H4, H5, H6, H7, ROUND,
2535                                K00, K01, K02, K03, K04, K05, K06, K07,
2536                                K08, K09, K10, K11, K12, K13, K14, K15,
2537                                K16, K17, K18, K19, K20, K21, K22, K23,
2538                                K24, K25, K26, K27, K28, K29, K30, K31,
2539                                K32, K33, K34, K35, K36, K37, K38, K39,
2540                                K40, K41, K42, K43, K44, K45, K46, K47,
2541                                K48, K49, K50, K51, K52, K53, K54, K55,
2542                                K56, K57, K58, K59, K60, K61, K62, K63,
2543                                K64, K65, K66, K67, K68, K69, K70, K71,
2544                                K72, K73, K74, K75, K76, K77, K78, K79,
2545                                RR1, RR8, RR14, RR18, RR19, RR28, RR34,
2546                                RR39, RR41, RR61, SR6, SR7>
2547{
2548    /// Formats the value using the given formatter.
2549    /// You will hardly use this method directly.
2550    /// Automagically the function `to_string()` will be implemented. So, you
2551    /// can use the function `to_string()`, and you can also print the SHA-1
2552    /// object in the macro `println!()` directly for example.
2553    /// `f` is a buffer, this method must write the formatted string into it.
2554    /// [Read more](https://doc.rust-lang.org/core/fmt/trait.Display.html#tymethod.fmt)
2555    /// 
2556    /// # Example 1 for SHA2_512_t_256 for the method to_string()
2557    /// ```
2558    /// use cryptocol::hash::SHA2_512_t_256;
2559    /// let mut hash = SHA2_512_t_256::new();
2560    /// let txt = "Display::fmt() automagically implement to_string().";
2561    /// hash.digest_str(txt);
2562    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash.to_string());
2563    /// assert_eq!(hash.to_string(), "5ED309022841125DE856B25C56A741166872A1D681DF5C69F84AD8B2F30E6DD8");
2564    /// ```
2565    /// 
2566    /// # Example 2 for SHA2_512_t_256_Expanded for the method to_string()
2567    /// ```
2568    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
2569    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
2570    /// let mut my_hash = MySHA2::new();
2571    /// let txt = "Display::fmt() automagically implement to_string().";
2572    /// my_hash.digest_str(txt);
2573    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash.to_string());
2574    /// assert_eq!(my_hash.to_string(), "377687DECF57B2340B282130B55C74C349376F8727BECA86C904673CD8CD50A7");
2575    /// ```
2576    /// 
2577    /// # Example 3 for SHA2_512_t_224 for the method to_string()
2578    /// ```
2579    /// use cryptocol::hash::SHA2_512_t_224;
2580    /// let mut hash = SHA2_512_t_224::new();
2581    /// let txt = "Display::fmt() automagically implement to_string().";
2582    /// hash.digest_str(txt);
2583    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash.to_string());
2584    /// assert_eq!(hash.to_string(), "0FFD651E288004466FF247808E1FF5B482AFF547E94C66FF507BF021");
2585    /// ```
2586    /// 
2587    /// # Example 4 for SHA2_512_t_224_Expanded for the method to_string()
2588    /// ```
2589    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
2590    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
2591    /// let mut my_hash = MySHA2::new();
2592    /// let txt = "Display::fmt() automagically implement to_string().";
2593    /// my_hash.digest_str(txt);
2594    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash.to_string());
2595    /// assert_eq!(my_hash.to_string(), "B130035D26D3BED1F991CB78DFC93F39F8CEF176BC4D7CF8B266027B");
2596    /// ```
2597    /// 
2598    /// # Example 5 for SHA2_512_t_256 for the use in the macro println!()
2599    /// ```
2600    /// use cryptocol::hash::SHA2_512_t_256;
2601    /// let mut hash = SHA2_512_t_256::new();
2602    /// let txt = "Display::fmt() enables the object to be printed in the macro println!() directly for example.";
2603    /// hash.digest_str(txt);
2604    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
2605    /// assert_eq!(hash.to_string(), "660F8CA5DDC61C43BCEBAB6B8FFD4081F9015CE9A7800BFE29B5100709C3E232");
2606    /// ```
2607    /// 
2608    /// # Example 6 for SHA2_512_t_256_Expanded for the use in the macro println!()
2609    /// ```
2610    /// use cryptocol::hash::SHA2_512_t_256_Expanded;
2611    /// type MySHA2 = SHA2_512_t_256_Expanded<160>;
2612    /// let mut my_hash = MySHA2::new();
2613    /// let txt = "Display::fmt() enables the object to be printed in the macro println!() directly for example.";
2614    /// my_hash.digest_str(txt);
2615    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
2616    /// assert_eq!(my_hash.to_string(), "C44370416B0925577339DECCC8529A68D29D4E79083658F260D4219DA6C2B0D1");
2617    /// ```
2618    /// 
2619    /// # Example 7 for SHA2_512_t_224 for the use in the macro println!()
2620    /// ```
2621    /// use cryptocol::hash::SHA2_512_t_224;
2622    /// let mut hash = SHA2_512_t_224::new();
2623    /// let txt = "Display::fmt() enables the object to be printed in the macro println!() directly for example.";
2624    /// hash.digest_str(txt);
2625    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, hash);
2626    /// assert_eq!(hash.to_string(), "7988DFC3FB4BB8DB449B189C5D906901921C1AC0D60D94376B498795");
2627    /// ```
2628    /// 
2629    /// # Example 8 for SHA2_512_t_224_Expanded for the use in the macro println!()
2630    /// ```
2631    /// use cryptocol::hash::SHA2_512_t_224_Expanded;
2632    /// type MySHA2 = SHA2_512_t_224_Expanded<160>;
2633    /// let mut my_hash = MySHA2::new();
2634    /// let txt = "Display::fmt() enables the object to be printed in the macro println!() directly for example.";
2635    /// my_hash.digest_str(txt);
2636    /// println!("Msg =\t\"{}\"\nHash =\t{}", txt, my_hash);
2637    /// assert_eq!(my_hash.to_string(), "831E095076EAE29CBC5BD2960D074BAC9E07C9189B9A5FCAE29FD5DB");
2638    /// ```
2639    fn fmt(&self, f: &mut Formatter) -> fmt::Result
2640    {
2641        // `write!` is like `format!`, but it will write the formatted string
2642        // into a buffer (the first argument)
2643        write!(f, "{}", self.get_hash_value_in_string())
2644    }
2645}