diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/rust/digest | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | third_party/rust/digest/.cargo-checksum.json | 1 | ||||
-rw-r--r-- | third_party/rust/digest/Cargo.toml | 36 | ||||
-rw-r--r-- | third_party/rust/digest/LICENSE-APACHE | 201 | ||||
-rw-r--r-- | third_party/rust/digest/LICENSE-MIT | 25 | ||||
-rw-r--r-- | third_party/rust/digest/src/dev.rs | 218 | ||||
-rw-r--r-- | third_party/rust/digest/src/digest.rs | 86 | ||||
-rw-r--r-- | third_party/rust/digest/src/dyn_digest.rs | 56 | ||||
-rw-r--r-- | third_party/rust/digest/src/errors.rs | 20 | ||||
-rw-r--r-- | third_party/rust/digest/src/lib.rs | 141 |
9 files changed, 784 insertions, 0 deletions
diff --git a/third_party/rust/digest/.cargo-checksum.json b/third_party/rust/digest/.cargo-checksum.json new file mode 100644 index 0000000000..9429389396 --- /dev/null +++ b/third_party/rust/digest/.cargo-checksum.json @@ -0,0 +1 @@ +{"files":{"Cargo.toml":"fe0caba7c3959c31f8b7a53d6d077a074e399c7604a2b03dfddcce9c0e56a81e","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"9e0dfd2dd4173a530e238cb6adb37aa78c34c6bc7444e0e10c1ab5d8881f63ba","src/dev.rs":"5890305be2cd3d221d1c2ce295b911cc57017dc341966ba434def4a072f8bf1c","src/digest.rs":"73f564cb8084e61baf850948443bacdea81727dfbff5abeb520c0e5bb690da7a","src/dyn_digest.rs":"2b3151c46d09dae2b7b0d0788d7bcc3517fe638c6a3f6fe43e357494de538049","src/errors.rs":"2584007e98d691160313cc27e6237db9bd886e9774137b59a1289a20054e9375","src/lib.rs":"8b336814939efcb1c1157ccadd52d9e4d6c99a84a799af2fe70cc50d05c45a32"},"package":"05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c"}
\ No newline at end of file diff --git a/third_party/rust/digest/Cargo.toml b/third_party/rust/digest/Cargo.toml new file mode 100644 index 0000000000..5b336043fc --- /dev/null +++ b/third_party/rust/digest/Cargo.toml @@ -0,0 +1,36 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + +[package] +name = "digest" +version = "0.8.0" +authors = ["RustCrypto Developers"] +description = "Traits for cryptographic hash functions" +documentation = "https://docs.rs/digest" +keywords = ["digest", "crypto", "hash"] +categories = ["cryptography", "no-std"] +license = "MIT OR Apache-2.0" +repository = "https://github.com/RustCrypto/traits" +[package.metadata.docs.rs] +features = ["std"] +[dependencies.blobby] +version = "0.1" +optional = true + +[dependencies.generic-array] +version = "0.12" + +[features] +dev = ["blobby"] +std = [] +[badges.travis-ci] +repository = "RustCrypto/traits" diff --git a/third_party/rust/digest/LICENSE-APACHE b/third_party/rust/digest/LICENSE-APACHE new file mode 100644 index 0000000000..78173fa2e7 --- /dev/null +++ b/third_party/rust/digest/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/third_party/rust/digest/LICENSE-MIT b/third_party/rust/digest/LICENSE-MIT new file mode 100644 index 0000000000..8dcb85b302 --- /dev/null +++ b/third_party/rust/digest/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2017 Artyom Pavlov + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/third_party/rust/digest/src/dev.rs b/third_party/rust/digest/src/dev.rs new file mode 100644 index 0000000000..e9950ee799 --- /dev/null +++ b/third_party/rust/digest/src/dev.rs @@ -0,0 +1,218 @@ +use super::{Input, VariableOutput, ExtendableOutput, Reset, XofReader}; +use core::fmt::Debug; + +#[macro_export] +macro_rules! new_test { + ($name:ident, $test_name:expr, $hasher:ty, $test_func:ident) => { + #[test] + fn $name() { + use digest::blobby::Blob2Iterator; + let data = include_bytes!(concat!("data/", $test_name, ".blb")); + + for (i, row) in Blob2Iterator::new(data).unwrap().enumerate() { + let input = row[0]; + let output = row[1]; + if let Some(desc) = $test_func::<$hasher>(input, output) { + panic!("\n\ + Failed test №{}: {}\n\ + input:\t{:?}\n\ + output:\t{:?}\n", + i, desc, input, output, + ); + } + } + } + } +} + +// module to separate Digest from other traits +mod foo { + use super::super::Digest; + use core::fmt::Debug; + + pub fn digest_test<D>(input: &[u8], output: &[u8]) -> Option<&'static str> + where D: Digest + Debug + Clone + { + let mut hasher = D::new(); + // Test that it works when accepting the message all at once + hasher.input(input); + let mut hasher2 = hasher.clone(); + if hasher.result().as_slice() != output { + return Some("whole message"); + } + + // Test if reset works correctly + hasher2.reset(); + hasher2.input(input); + if hasher2.result().as_slice() != output { + return Some("whole message after reset"); + } + + // Test that it works when accepting the message in pieces + let mut hasher = D::new(); + let len = input.len(); + let mut left = len; + while left > 0 { + let take = (left + 1) / 2; + hasher.input(&input[len - left..take + len - left]); + left = left - take; + } + if hasher.result().as_slice() != output { + return Some("message in pieces"); + } + + // Test processing byte-by-byte + let mut hasher = D::new(); + for chunk in input.chunks(1) { + hasher.input(chunk) + } + if hasher.result().as_slice() != output { + return Some("message byte-by-byte"); + } + None + } + + + pub fn one_million_a<D>(expected: &[u8]) + where D: Digest + Debug + Clone + { + let mut sh = D::new(); + for _ in 0..50_000 { + sh.input(&[b'a'; 10]); + } + sh.input(&[b'a'; 500_000][..]); + let out = sh.result(); + assert_eq!(out[..], expected[..]); + } +} + +pub use self::foo::{digest_test, one_million_a}; + +pub fn xof_test<D>(input: &[u8], output: &[u8]) + -> Option<&'static str> + where D: Input + ExtendableOutput + Default + Debug + Reset + Clone +{ + let mut hasher = D::default(); + let mut buf = [0u8; 1024]; + // Test that it works when accepting the message all at once + hasher.input(input); + + let mut hasher2 = hasher.clone(); + { + let out = &mut buf[..output.len()]; + hasher.xof_result().read(out); + + if out != output { return Some("whole message"); } + } + + // Test if hasher resets correctly + hasher2.reset(); + hasher2.input(input); + + { + let out = &mut buf[..output.len()]; + hasher2.xof_result().read(out); + + if out != output { return Some("whole message after reset"); } + } + + // Test if hasher accepts message in pieces correctly + let mut hasher = D::default(); + let len = input.len(); + let mut left = len; + while left > 0 { + let take = (left + 1) / 2; + hasher.input(&input[len - left..take + len - left]); + left = left - take; + } + + { + let out = &mut buf[..output.len()]; + hasher.xof_result().read(out); + if out != output { return Some("message in pieces"); } + } + + // Test reading from reader byte by byte + let mut hasher = D::default(); + hasher.input(input); + + let mut reader = hasher.xof_result(); + let out = &mut buf[..output.len()]; + for chunk in out.chunks_mut(1) { + reader.read(chunk); + } + + if out != output { return Some("message in pieces"); } + None +} + +pub fn variable_test<D>(input: &[u8], output: &[u8]) + -> Option<&'static str> + where D: Input + VariableOutput + Reset + Debug + Clone +{ + let mut hasher = D::new(output.len()).unwrap(); + let mut buf = [0u8; 128]; + let buf = &mut buf[..output.len()]; + // Test that it works when accepting the message all at once + hasher.input(input); + let mut hasher2 = hasher.clone(); + hasher.variable_result(|res| buf.copy_from_slice(res)); + if buf != output { return Some("whole message"); } + + // Test if reset works correctly + hasher2.reset(); + hasher2.input(input); + hasher2.variable_result(|res| buf.copy_from_slice(res)); + if buf != output { return Some("whole message after reset"); } + + // Test that it works when accepting the message in pieces + let mut hasher = D::new(output.len()).unwrap(); + let len = input.len(); + let mut left = len; + while left > 0 { + let take = (left + 1) / 2; + hasher.input(&input[len - left..take + len - left]); + left = left - take; + } + hasher.variable_result(|res| buf.copy_from_slice(res)); + if buf != output { return Some("message in pieces"); } + + // Test processing byte-by-byte + let mut hasher = D::new(output.len()).unwrap(); + for chunk in input.chunks(1) { + hasher.input(chunk) + } + hasher.variable_result(|res| buf.copy_from_slice(res)); + if buf != output { return Some("message byte-by-byte"); } + None +} + + +#[macro_export] +macro_rules! bench { + ($name:ident, $engine:path, $bs:expr) => { + #[bench] + fn $name(b: &mut Bencher) { + let mut d = <$engine>::default(); + let data = [0; $bs]; + + b.iter(|| { + d.input(&data[..]); + }); + + b.bytes = $bs; + } + }; + + ($engine:path) => { + extern crate test; + + use test::Bencher; + use digest::Digest; + + bench!(bench1_10, $engine, 10); + bench!(bench2_100, $engine, 100); + bench!(bench3_1000, $engine, 1000); + bench!(bench4_10000, $engine, 10000); + } +} diff --git a/third_party/rust/digest/src/digest.rs b/third_party/rust/digest/src/digest.rs new file mode 100644 index 0000000000..50128e13ec --- /dev/null +++ b/third_party/rust/digest/src/digest.rs @@ -0,0 +1,86 @@ +use super::{Input, FixedOutput, Reset}; +use generic_array::{GenericArray, ArrayLength}; +use generic_array::typenum::Unsigned; + +/// The `Digest` trait specifies an interface common for digest functions. +/// +/// It's a convenience wrapper around `Input`, `FixedOutput`, `Reset`, `Clone`, +/// and `Default` traits. It also provides additional convenience methods. +pub trait Digest { + type OutputSize: ArrayLength<u8>; + /// Create new hasher instance + fn new() -> Self; + + /// Digest input data. + /// + /// This method can be called repeatedly for use with streaming messages. + fn input<B: AsRef<[u8]>>(&mut self, data: B); + + /// Digest input data in a chained manner. + fn chain<B: AsRef<[u8]>>(self, data: B) -> Self where Self: Sized; + + /// Retrieve result and consume hasher instance. + fn result(self) -> GenericArray<u8, Self::OutputSize>; + + /// Retrieve result and reset hasher instance. + /// + /// This method sometimes can be more efficient compared to hasher + /// re-creation. + fn result_reset(&mut self) -> GenericArray<u8, Self::OutputSize>; + + /// Reset hasher instance to its initial state. + fn reset(&mut self); + + /// Get output size of the hasher + fn output_size() -> usize; + + /// Convenience function to compute hash of the `data`. It will handle + /// hasher creation, data feeding and finalization. + /// + /// Example: + /// + /// ```rust,ignore + /// println!("{:x}", sha2::Sha256::digest(b"Hello world")); + /// ``` + fn digest(data: &[u8]) -> GenericArray<u8, Self::OutputSize>; +} + +impl<D: Input + FixedOutput + Reset + Clone + Default> Digest for D { + type OutputSize = <Self as FixedOutput>::OutputSize; + + fn new() -> Self { + Self::default() + } + + fn input<B: AsRef<[u8]>>(&mut self, data: B) { + Input::input(self, data); + } + + fn chain<B: AsRef<[u8]>>(self, data: B) -> Self where Self: Sized { + Input::chain(self, data) + } + + fn result(self) -> GenericArray<u8, Self::OutputSize> { + self.fixed_result() + } + + fn result_reset(&mut self) -> GenericArray<u8, Self::OutputSize> { + let res = self.clone().fixed_result(); + self.reset(); + res + } + + fn reset(&mut self) { + <Self as Reset>::reset(self) + } + + fn output_size() -> usize { + Self::OutputSize::to_usize() + } + + fn digest(data: &[u8]) -> GenericArray<u8, Self::OutputSize> { + let mut hasher = Self::default(); + Input::input(&mut hasher, data); + hasher.fixed_result() + } +} diff --git a/third_party/rust/digest/src/dyn_digest.rs b/third_party/rust/digest/src/dyn_digest.rs new file mode 100644 index 0000000000..789cdc86ef --- /dev/null +++ b/third_party/rust/digest/src/dyn_digest.rs @@ -0,0 +1,56 @@ +#![cfg(feature = "std")] +use std::boxed::Box; + +use super::{Input, FixedOutput, Reset}; +use generic_array::typenum::Unsigned; + +/// The `DynDigest` trait is a modification of `Digest` trait suitable +/// for trait objects. +pub trait DynDigest { + /// Digest input data. + /// + /// This method can be called repeatedly for use with streaming messages. + fn input(&mut self, data: &[u8]); + + /// Retrieve result and reset hasher instance + fn result_reset(&mut self) -> Box<[u8]>; + + /// Retrieve result and consume boxed hasher instance + fn result(self: Box<Self>) -> Box<[u8]>; + + /// Reset hasher instance to its initial state. + fn reset(&mut self); + + /// Get output size of the hasher + fn output_size(&self) -> usize; +} + +impl<D: Input + FixedOutput + Reset + Clone> DynDigest for D { + /// Digest input data. + /// + /// This method can be called repeatedly for use with streaming messages. + fn input(&mut self, data: &[u8]) { + Input::input(self, data); + } + + /// Retrieve result and reset hasher instance + fn result_reset(&mut self) -> Box<[u8]> { + let res = self.clone().fixed_result().to_vec().into_boxed_slice(); + Reset::reset(self); + res + } + + /// Retrieve result and consume boxed hasher instance + fn result(self: Box<Self>) -> Box<[u8]> { + self.fixed_result().to_vec().into_boxed_slice() + } + + fn reset(&mut self) { + Reset::reset(self); + } + + /// Get output size of the hasher + fn output_size(&self) -> usize { + <Self as FixedOutput>::OutputSize::to_usize() + } +} diff --git a/third_party/rust/digest/src/errors.rs b/third_party/rust/digest/src/errors.rs new file mode 100644 index 0000000000..aa026a21a1 --- /dev/null +++ b/third_party/rust/digest/src/errors.rs @@ -0,0 +1,20 @@ +use core::fmt; +#[cfg(feature = "std")] +use std::error; + +/// The error type for variable hasher initialization +#[derive(Clone, Copy, Debug, Default)] +pub struct InvalidOutputSize; + +impl fmt::Display for InvalidOutputSize { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("invalid output size") + } +} + +#[cfg(feature = "std")] +impl error::Error for InvalidOutputSize { + fn description(&self) -> &str { + "invalid output size" + } +} diff --git a/third_party/rust/digest/src/lib.rs b/third_party/rust/digest/src/lib.rs new file mode 100644 index 0000000000..1a364f808c --- /dev/null +++ b/third_party/rust/digest/src/lib.rs @@ -0,0 +1,141 @@ +//! This crate provides traits which describe funcionality of cryptographic hash +//! functions. +//! +//! Traits in this repository can be separatedin two levels: +//! - Low level traits: `Input`, `BlockInput`, `Reset`, `FixedOutput`, +//! `VariableOutput`, `ExtendableOutput`. These traits atomically describe +//! available functionality of hash function implementations. +//! - Convinience trait: `Digest`, `DynDigest`. They are wrappers around +//! low level traits for most common hash-function use-cases. +//! +//! Additionally hash functions implement traits from `std`: `Default`, `Clone`, +//! `Write`. (the latter depends on enabled-by-default `std` crate feature) +//! +//! The `Digest` trait is the most commonly used trait. +#![no_std] +#![doc(html_logo_url = + "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] +pub extern crate generic_array; +#[cfg(feature = "std")] +#[macro_use] extern crate std; +#[cfg(feature = "dev")] +pub extern crate blobby; +use generic_array::{GenericArray, ArrayLength}; +#[cfg(feature = "std")] +use std::vec::Vec; + +mod digest; +mod dyn_digest; +mod errors; +#[cfg(feature = "dev")] +pub mod dev; + +pub use errors::InvalidOutputSize; +pub use digest::Digest; +#[cfg(feature = "std")] +pub use dyn_digest::DynDigest; + +/// Trait for processing input data +pub trait Input { + /// Digest input data. + /// + /// This method can be called repeatedly, e.g. for processing streaming + /// messages. + fn input<B: AsRef<[u8]>>(&mut self, data: B); + + /// Digest input data in a chained manner. + fn chain<B: AsRef<[u8]>>(mut self, data: B) -> Self where Self: Sized { + self.input(data); + self + } +} + +/// Trait to indicate that digest function processes data in blocks of size +/// `BlockSize`. +/// +/// The main usage of this trait is for implementing HMAC generically. +pub trait BlockInput { + type BlockSize: ArrayLength<u8>; +} + +/// Trait for returning digest result with the fixed size +pub trait FixedOutput { + type OutputSize: ArrayLength<u8>; + + /// Retrieve result and consume hasher instance. + fn fixed_result(self) -> GenericArray<u8, Self::OutputSize>; +} + +/// Trait for returning digest result with the varaible size +pub trait VariableOutput: core::marker::Sized { + /// Create new hasher instance with the given output size. + /// + /// It will return `Err(InvalidOutputSize)` in case if hasher can not return + /// specified output size. It will always return an error if output size + /// equals to zero. + fn new(output_size: usize) -> Result<Self, InvalidOutputSize>; + + /// Get output size of the hasher instance provided to the `new` method + fn output_size(&self) -> usize; + + /// Retrieve result via closure and consume hasher. + /// + /// Closure is guaranteed to be called, length of the buffer passed to it + /// will be equal to `output_size`. + fn variable_result<F: FnOnce(&[u8])>(self, f: F); + + /// Retrieve result into vector and consume hasher. + #[cfg(feature = "std")] + fn vec_result(self) -> Vec<u8> { + let mut buf = Vec::with_capacity(self.output_size()); + self.variable_result(|res| buf.extend_from_slice(res)); + buf + } +} + +/// Trait for decribing readers which are used to extract extendable output +/// from XOF (extendable-output function) result. +pub trait XofReader { + /// Read output into the `buffer`. Can be called unlimited number of times. + fn read(&mut self, buffer: &mut [u8]); +} + +/// Trait which describes extendable-output functions (XOF). +pub trait ExtendableOutput: core::marker::Sized { + type Reader: XofReader; + + /// Retrieve XOF reader and consume hasher instance. + fn xof_result(self) -> Self::Reader; + + /// Retrieve result into vector of specified length. + #[cfg(feature = "std")] + fn vec_result(self, n: usize) -> Vec<u8> { + let mut buf = vec![0u8; n]; + self.xof_result().read(&mut buf); + buf + } +} + +/// Trait for resetting hash instances +pub trait Reset { + /// Reset hasher instance to its initial state and return current state. + fn reset(&mut self); +} + +#[macro_export] +/// Implements `std::io::Write` trait for implementator of `Input` +macro_rules! impl_write { + ($hasher:ident) => { + #[cfg(feature = "std")] + impl ::std::io::Write for $hasher { + fn write(&mut self, buf: &[u8]) -> ::std::io::Result<usize> { + Input::input(self, buf); + Ok(buf.len()) + } + + fn flush(&mut self) -> ::std::io::Result<()> { + Ok(()) + } + } + } +} |