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}