summaryrefslogtreecommitdiffstats
path: root/vendor/base16ct
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/base16ct')
-rw-r--r--vendor/base16ct/.cargo-checksum.json1
-rw-r--r--vendor/base16ct/CHANGELOG.md14
-rw-r--r--vendor/base16ct/Cargo.toml32
-rw-r--r--vendor/base16ct/LICENSE-APACHE201
-rw-r--r--vendor/base16ct/LICENSE-MIT26
-rw-r--r--vendor/base16ct/README.md60
-rw-r--r--vendor/base16ct/benches/mod.rs69
-rw-r--r--vendor/base16ct/src/display.rs35
-rw-r--r--vendor/base16ct/src/error.rs32
-rw-r--r--vendor/base16ct/src/lib.rs118
-rw-r--r--vendor/base16ct/src/lower.rs80
-rw-r--r--vendor/base16ct/src/mixed.rs38
-rw-r--r--vendor/base16ct/src/upper.rs80
-rw-r--r--vendor/base16ct/tests/lib.rs163
14 files changed, 949 insertions, 0 deletions
diff --git a/vendor/base16ct/.cargo-checksum.json b/vendor/base16ct/.cargo-checksum.json
new file mode 100644
index 000000000..644cc2105
--- /dev/null
+++ b/vendor/base16ct/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"b74f249225e74ce70e911b3569a40e812d1941d13d5ef0ed6def2665943eca09","Cargo.toml":"d4406c7f39662e1feee04d54b308159eff624fe2f9b0127e0b14daaf7f03f861","LICENSE-APACHE":"a9040321c3712d8fd0b09cf52b17445de04a23a10165049ae187cd39e5c86be5","LICENSE-MIT":"0aa8963e105e8b6e02f634484145d4e5b0f42d0a6dd05c16f8148f033383adef","README.md":"3ec555623fab4feb5f805dbb0935a3408e8068b86f517c0b28edc171fd88f2a8","benches/mod.rs":"976e6c0443e69a0578a2cf2252c4ed486ff0dc39823d0c369625e31c89941657","src/display.rs":"7042d46254a4fe4c1d66fe41be90916010247fd6dbdf3e87532541aa1a199696","src/error.rs":"8c5ac9c8d2d3b6fe18d8cf56d7e48149fb4d44c32ccb71f566f243c70e9bb187","src/lib.rs":"75378dac02301ce69e419e58b98ff32f1f009f3cf4ef49b5c0791cdfa7d23abc","src/lower.rs":"d9a0a85be650d4d2b5154cd5886b95051314e6c5a53a9f8450dea2eeb1a0e553","src/mixed.rs":"f5fe584f2fb275ae28ce6c253b9faf8912038bbb83c331ad7f715c49ab8369a5","src/upper.rs":"5bae380ba3e515d4da7f498517d9f0ed9cf57416203a2d71474730f4bb4e6efe","tests/lib.rs":"1b5ae439670c8c1ca3843922bd484dc642b660d91f401a29fa279d9e01fdab92"},"package":"349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce"} \ No newline at end of file
diff --git a/vendor/base16ct/CHANGELOG.md b/vendor/base16ct/CHANGELOG.md
new file mode 100644
index 000000000..808c55253
--- /dev/null
+++ b/vendor/base16ct/CHANGELOG.md
@@ -0,0 +1,14 @@
+# Changelog
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## 0.1.1 (2022-01-15)
+### Added
+- `HexDisplay` type ([#329])
+
+[#329]: https://github.com/RustCrypto/formats/pull/329
+
+## 0.1.0 (2022-01-12)
+- Initial release
diff --git a/vendor/base16ct/Cargo.toml b/vendor/base16ct/Cargo.toml
new file mode 100644
index 000000000..dfeb08fdf
--- /dev/null
+++ b/vendor/base16ct/Cargo.toml
@@ -0,0 +1,32 @@
+# 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 are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2021"
+rust-version = "1.56"
+name = "base16ct"
+version = "0.1.1"
+authors = ["RustCrypto Developers"]
+description = "Pure Rust implementation of Base16 a.k.a hexadecimal (RFC 4648) which avoids\nany usages of data-dependent branches/LUTs and thereby provides portable\n\"best effort\" constant-time operation and embedded-friendly no_std support\n"
+documentation = "https://docs.rs/base16ct"
+readme = "README.md"
+keywords = ["crypto", "hex", "pem", "phc"]
+categories = ["cryptography", "encoding", "no-std", "parser-implementations"]
+license = "Apache-2.0 OR MIT"
+repository = "https://github.com/RustCrypto/formats/tree/master/base16ct"
+resolver = "2"
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = ["--cfg", "docsrs"]
+
+[features]
+alloc = []
+std = ["alloc"]
diff --git a/vendor/base16ct/LICENSE-APACHE b/vendor/base16ct/LICENSE-APACHE
new file mode 100644
index 000000000..78173fa2e
--- /dev/null
+++ b/vendor/base16ct/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/vendor/base16ct/LICENSE-MIT b/vendor/base16ct/LICENSE-MIT
new file mode 100644
index 000000000..f151c9982
--- /dev/null
+++ b/vendor/base16ct/LICENSE-MIT
@@ -0,0 +1,26 @@
+Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
+Copyright (c) 2022 The RustCrypto Project Developers
+
+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/vendor/base16ct/README.md b/vendor/base16ct/README.md
new file mode 100644
index 000000000..fad88dbf8
--- /dev/null
+++ b/vendor/base16ct/README.md
@@ -0,0 +1,60 @@
+# [RustCrypto]: Constant-Time Base16 (hexadecimal)
+
+[![crate][crate-image]][crate-link]
+[![Docs][docs-image]][docs-link]
+[![Build Status][build-image]][build-link]
+![Apache2/MIT licensed][license-image]
+![Rust Version][rustc-image]
+[![Project Chat][chat-image]][chat-link]
+
+Pure Rust implementation of Base16 ([RFC 4648]).
+
+Implements lower and upper case Base16 variants without data-dependent branches
+or lookup tables, thereby providing portable "best effort" constant-time
+operation.
+
+Supports `no_std` environments and avoids heap allocations in the core API
+(but also provides optional `alloc` support for convenience).
+
+[Documentation][docs-link]
+
+## Minimum Supported Rust Version
+
+This crate requires **Rust 1.56** at a minimum.
+
+We may change the MSRV in the future, but it will be accompanied by a minor
+version bump.
+
+## License
+
+Licensed under either of:
+
+ * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
+ * [MIT license](http://opensource.org/licenses/MIT)
+
+at your option.
+
+### Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
+
+[//]: # (badges)
+
+[crate-image]: https://img.shields.io/crates/v/base16ct.svg
+[crate-link]: https://crates.io/crates/base16ct
+[docs-image]: https://docs.rs/base16ct/badge.svg
+[docs-link]: https://docs.rs/base16ct/
+[build-image]: https://github.com/RustCrypto/formats/actions/workflows/base16ct.yml/badge.svg
+[build-link]: https://github.com/RustCrypto/formats/actions/workflows/base16ct.yml
+[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
+[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg
+[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
+[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/300570-formats
+
+[//]: # (links)
+
+[RustCrypto]: https://github.com/rustcrypto
+[RFC 4648]: https://tools.ietf.org/html/rfc4648
+[Util::Lookup]: https://arxiv.org/pdf/2108.04600.pdf
diff --git a/vendor/base16ct/benches/mod.rs b/vendor/base16ct/benches/mod.rs
new file mode 100644
index 000000000..75af0c9db
--- /dev/null
+++ b/vendor/base16ct/benches/mod.rs
@@ -0,0 +1,69 @@
+#![feature(test)]
+extern crate test;
+
+use test::{black_box, Bencher};
+
+#[bench]
+fn decode_lower(b: &mut Bencher) {
+ let input = vec![b'1'; 1 << 14];
+ let mut buf = vec![0u8; 1 << 13];
+
+ b.iter(|| {
+ let input = black_box(&input[..]);
+ let res = base16ct::lower::decode(input, &mut buf).unwrap();
+ black_box(res);
+ });
+ b.bytes = input.len() as u64;
+}
+
+#[bench]
+fn decode_upper(b: &mut Bencher) {
+ let input = vec![b'1'; 1 << 14];
+ let mut buf = vec![0u8; 1 << 13];
+
+ b.iter(|| {
+ let input = black_box(&input[..]);
+ let res = base16ct::upper::decode(input, &mut buf).unwrap();
+ black_box(res);
+ });
+ b.bytes = input.len() as u64;
+}
+
+#[bench]
+fn decode_mixed(b: &mut Bencher) {
+ let input = vec![b'1'; 1 << 14];
+ let mut buf = vec![0u8; 1 << 13];
+
+ b.iter(|| {
+ let input = black_box(&input[..]);
+ let res = base16ct::mixed::decode(input, &mut buf).unwrap();
+ black_box(res);
+ });
+ b.bytes = input.len() as u64;
+}
+
+#[bench]
+fn encode_lower(b: &mut Bencher) {
+ let input = vec![0x42; 1 << 14];
+ let mut buf = vec![0u8; 1 << 15];
+
+ b.iter(|| {
+ let input = black_box(&input[..]);
+ let res = base16ct::lower::encode(input, &mut buf).unwrap();
+ black_box(res);
+ });
+ b.bytes = input.len() as u64;
+}
+
+#[bench]
+fn encode_upper(b: &mut Bencher) {
+ let input = vec![0x42; 1 << 14];
+ let mut buf = vec![0u8; 1 << 15];
+
+ b.iter(|| {
+ let input = black_box(&input[..]);
+ let res = base16ct::upper::encode(input, &mut buf).unwrap();
+ black_box(res);
+ });
+ b.bytes = input.len() as u64;
+}
diff --git a/vendor/base16ct/src/display.rs b/vendor/base16ct/src/display.rs
new file mode 100644
index 000000000..1397a91dd
--- /dev/null
+++ b/vendor/base16ct/src/display.rs
@@ -0,0 +1,35 @@
+use core::fmt;
+
+/// `core::fmt` presenter for binary data encoded as hexadecimal (Base16).
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub struct HexDisplay<'a>(pub &'a [u8]);
+
+impl fmt::Display for HexDisplay<'_> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{:X}", self)
+ }
+}
+
+impl fmt::UpperHex for HexDisplay<'_> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let mut hex = [0u8; 2];
+
+ for &byte in self.0 {
+ f.write_str(crate::upper::encode_str(&[byte], &mut hex)?)?;
+ }
+
+ Ok(())
+ }
+}
+
+impl fmt::LowerHex for HexDisplay<'_> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let mut hex = [0u8; 2];
+
+ for &byte in self.0 {
+ f.write_str(crate::lower::encode_str(&[byte], &mut hex)?)?;
+ }
+
+ Ok(())
+ }
+}
diff --git a/vendor/base16ct/src/error.rs b/vendor/base16ct/src/error.rs
new file mode 100644
index 000000000..a5f99c2ea
--- /dev/null
+++ b/vendor/base16ct/src/error.rs
@@ -0,0 +1,32 @@
+use core::fmt;
+
+/// Result type with the `base16ct` crate's [`Error`] type.
+pub type Result<T> = core::result::Result<T, Error>;
+
+/// Error type
+#[derive(Clone, Eq, PartialEq, Debug)]
+pub enum Error {
+ /// Invalid encoding of provided Base16 string.
+ InvalidEncoding,
+
+ /// Insufficient output buffer length.
+ InvalidLength,
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self {
+ Error::InvalidEncoding => f.write_str("invalid Base16 encoding"),
+ Error::InvalidLength => f.write_str("invalid Base16 length"),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for Error {}
+
+impl From<Error> for core::fmt::Error {
+ fn from(_: Error) -> core::fmt::Error {
+ core::fmt::Error::default()
+ }
+}
diff --git a/vendor/base16ct/src/lib.rs b/vendor/base16ct/src/lib.rs
new file mode 100644
index 000000000..413d512d8
--- /dev/null
+++ b/vendor/base16ct/src/lib.rs
@@ -0,0 +1,118 @@
+//! Pure Rust implementation of Base16 ([RFC 4648], a.k.a. hex).
+//!
+//! Implements lower and upper case Base16 variants without data-dependent branches
+//! or lookup tables, thereby providing portable "best effort" constant-time
+//! operation. Not constant-time with respect to message length (only data).
+//!
+//! Supports `no_std` environments and avoids heap allocations in the core API
+//! (but also provides optional `alloc` support for convenience).
+//!
+//! Based on code from: <https://github.com/Sc00bz/ConstTimeEncoding/blob/master/hex.cpp>
+//!
+//! # Examples
+//! ```
+//! let lower_hex_str = "abcd1234";
+//! let upper_hex_str = "ABCD1234";
+//! let mixed_hex_str = "abCD1234";
+//! let raw = b"\xab\xcd\x12\x34";
+//!
+//! let mut buf = [0u8; 16];
+//! // length of return slice can be different from the input buffer!
+//! let res = base16ct::lower::decode(lower_hex_str, &mut buf).unwrap();
+//! assert_eq!(res, raw);
+//! let res = base16ct::lower::encode(raw, &mut buf).unwrap();
+//! assert_eq!(res, lower_hex_str.as_bytes());
+//! // you also can use `encode_str` and `encode_string` to get
+//! // `&str` and `String` respectively
+//! let res: &str = base16ct::lower::encode_str(raw, &mut buf).unwrap();
+//! assert_eq!(res, lower_hex_str);
+//!
+//! let res = base16ct::upper::decode(upper_hex_str, &mut buf).unwrap();
+//! assert_eq!(res, raw);
+//! let res = base16ct::upper::encode(raw, &mut buf).unwrap();
+//! assert_eq!(res, upper_hex_str.as_bytes());
+//!
+//! // In cases when you don't know if input contains upper or lower
+//! // hex-encoded value, then use functions from the `mixed` module
+//! let res = base16ct::mixed::decode(lower_hex_str, &mut buf).unwrap();
+//! assert_eq!(res, raw);
+//! let res = base16ct::mixed::decode(upper_hex_str, &mut buf).unwrap();
+//! assert_eq!(res, raw);
+//! let res = base16ct::mixed::decode(mixed_hex_str, &mut buf).unwrap();
+//! assert_eq!(res, raw);
+//! ```
+//!
+//! [RFC 4648]: https://tools.ietf.org/html/rfc4648
+
+#![no_std]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![warn(missing_docs, rust_2018_idioms)]
+#![doc(
+ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
+ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
+ html_root_url = "https://docs.rs/base16ct/0.1.1"
+)]
+
+#[cfg(feature = "alloc")]
+#[macro_use]
+extern crate alloc;
+#[cfg(feature = "std")]
+extern crate std;
+
+/// Function for decoding and encoding lower Base16 (hex)
+pub mod lower;
+/// Function for decoding mixed Base16 (hex)
+pub mod mixed;
+/// Function for decoding and encoding upper Base16 (hex)
+pub mod upper;
+
+/// Display formatter for hex.
+mod display;
+/// Error types.
+mod error;
+
+pub use crate::{
+ display::HexDisplay,
+ error::{Error, Result},
+};
+
+#[cfg(feature = "alloc")]
+use alloc::{string::String, vec::Vec};
+
+/// Compute decoded length of the given hex-encoded input.
+#[inline(always)]
+pub fn decoded_len(bytes: &[u8]) -> Result<usize> {
+ if bytes.len() & 1 == 0 {
+ Ok(bytes.len() / 2)
+ } else {
+ Err(Error::InvalidLength)
+ }
+}
+
+/// Get the length of Base16 (hex) produced by encoding the given bytes.
+#[inline(always)]
+pub fn encoded_len(bytes: &[u8]) -> usize {
+ bytes.len() * 2
+}
+
+fn decode_inner<'a>(
+ src: &[u8],
+ dst: &'a mut [u8],
+ decode_nibble: impl Fn(u8) -> u16,
+) -> Result<&'a [u8]> {
+ let dst = dst
+ .get_mut(..decoded_len(src)?)
+ .ok_or(Error::InvalidLength)?;
+
+ let mut err: u16 = 0;
+ for (src, dst) in src.chunks_exact(2).zip(dst.iter_mut()) {
+ let byte = (decode_nibble(src[0]) << 4) | decode_nibble(src[1]);
+ err |= byte >> 8;
+ *dst = byte as u8;
+ }
+
+ match err {
+ 0 => Ok(dst),
+ _ => Err(Error::InvalidEncoding),
+ }
+}
diff --git a/vendor/base16ct/src/lower.rs b/vendor/base16ct/src/lower.rs
new file mode 100644
index 000000000..b6d9f9453
--- /dev/null
+++ b/vendor/base16ct/src/lower.rs
@@ -0,0 +1,80 @@
+use crate::{decode_inner, encoded_len, Error};
+#[cfg(feature = "alloc")]
+use crate::{decoded_len, String, Vec};
+
+/// Decode a lower Base16 (hex) string into the provided destination buffer.
+pub fn decode(src: impl AsRef<[u8]>, dst: &mut [u8]) -> Result<&[u8], Error> {
+ decode_inner(src.as_ref(), dst, decode_nibble)
+}
+
+/// Decode a lower Base16 (hex) string into a byte vector.
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+pub fn decode_vec(input: impl AsRef<[u8]>) -> Result<Vec<u8>, Error> {
+ let mut output = vec![0u8; decoded_len(input.as_ref())?];
+ decode(input, &mut output)?;
+ Ok(output)
+}
+
+/// Encode the input byte slice as lower Base16.
+///
+/// Writes the result into the provided destination slice, returning an
+/// ASCII-encoded lower Base16 (hex) string value.
+pub fn encode<'a>(src: &[u8], dst: &'a mut [u8]) -> Result<&'a [u8], Error> {
+ let dst = dst
+ .get_mut(..encoded_len(src))
+ .ok_or(Error::InvalidLength)?;
+ for (src, dst) in src.iter().zip(dst.chunks_exact_mut(2)) {
+ dst[0] = encode_nibble(src >> 4);
+ dst[1] = encode_nibble(src & 0x0f);
+ }
+ Ok(dst)
+}
+
+/// Encode input byte slice into a [`&str`] containing lower Base16 (hex).
+pub fn encode_str<'a>(src: &[u8], dst: &'a mut [u8]) -> Result<&'a str, Error> {
+ encode(src, dst).map(|r| unsafe { core::str::from_utf8_unchecked(r) })
+}
+
+/// Encode input byte slice into a [`String`] containing lower Base16 (hex).
+///
+/// # Panics
+/// If `input` length is greater than `usize::MAX/2`.
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+pub fn encode_string(input: &[u8]) -> String {
+ let elen = encoded_len(input);
+ let mut dst = vec![0u8; elen];
+ let res = encode(input, &mut dst).expect("dst length is correct");
+
+ debug_assert_eq!(elen, res.len());
+ unsafe { String::from_utf8_unchecked(dst) }
+}
+
+/// Decode a single nibble of lower hex
+#[inline(always)]
+fn decode_nibble(src: u8) -> u16 {
+ // 0-9 0x30-0x39
+ // A-F 0x41-0x46 or a-f 0x61-0x66
+ let byte = src as i16;
+ let mut ret: i16 = -1;
+
+ // 0-9 0x30-0x39
+ // if (byte > 0x2f && byte < 0x3a) ret += byte - 0x30 + 1; // -47
+ ret += (((0x2fi16 - byte) & (byte - 0x3a)) >> 8) & (byte - 47);
+ // a-f 0x61-0x66
+ // if (byte > 0x60 && byte < 0x67) ret += byte - 0x61 + 10 + 1; // -86
+ ret += (((0x60i16 - byte) & (byte - 0x67)) >> 8) & (byte - 86);
+
+ ret as u16
+}
+
+/// Encode a single nibble of hex
+#[inline(always)]
+fn encode_nibble(src: u8) -> u8 {
+ let mut ret = src as i16 + 0x30;
+ // 0-9 0x30-0x39
+ // a-f 0x61-0x66
+ ret += ((0x39i16 - ret) >> 8) & (0x61i16 - 0x3a);
+ ret as u8
+}
diff --git a/vendor/base16ct/src/mixed.rs b/vendor/base16ct/src/mixed.rs
new file mode 100644
index 000000000..50f778d80
--- /dev/null
+++ b/vendor/base16ct/src/mixed.rs
@@ -0,0 +1,38 @@
+use crate::{decode_inner, Error};
+#[cfg(feature = "alloc")]
+use crate::{decoded_len, Vec};
+
+/// Decode a mixed Base16 (hex) string into the provided destination buffer.
+pub fn decode(src: impl AsRef<[u8]>, dst: &mut [u8]) -> Result<&[u8], Error> {
+ decode_inner(src.as_ref(), dst, decode_nibble)
+}
+
+/// Decode a mixed Base16 (hex) string into a byte vector.
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+pub fn decode_vec(input: impl AsRef<[u8]>) -> Result<Vec<u8>, Error> {
+ let mut output = vec![0u8; decoded_len(input.as_ref())?];
+ decode(input, &mut output)?;
+ Ok(output)
+}
+
+/// Decode a single nibble of lower hex
+#[inline(always)]
+fn decode_nibble(src: u8) -> u16 {
+ // 0-9 0x30-0x39
+ // A-F 0x41-0x46 or a-f 0x61-0x66
+ let byte = src as i16;
+ let mut ret: i16 = -1;
+
+ // 0-9 0x30-0x39
+ // if (byte > 0x2f && byte < 0x3a) ret += byte - 0x30 + 1; // -47
+ ret += (((0x2fi16 - byte) & (byte - 0x3a)) >> 8) & (byte - 47);
+ // A-F 0x41-0x46
+ // if (byte > 0x40 && byte < 0x47) ret += byte - 0x41 + 10 + 1; // -54
+ ret += (((0x40i16 - byte) & (byte - 0x47)) >> 8) & (byte - 54);
+ // a-f 0x61-0x66
+ // if (byte > 0x60 && byte < 0x67) ret += byte - 0x61 + 10 + 1; // -86
+ ret += (((0x60i16 - byte) & (byte - 0x67)) >> 8) & (byte - 86);
+
+ ret as u16
+}
diff --git a/vendor/base16ct/src/upper.rs b/vendor/base16ct/src/upper.rs
new file mode 100644
index 000000000..679006e21
--- /dev/null
+++ b/vendor/base16ct/src/upper.rs
@@ -0,0 +1,80 @@
+use crate::{decode_inner, encoded_len, Error};
+#[cfg(feature = "alloc")]
+use crate::{decoded_len, String, Vec};
+
+/// Decode an upper Base16 (hex) string into the provided destination buffer.
+pub fn decode(src: impl AsRef<[u8]>, dst: &mut [u8]) -> Result<&[u8], Error> {
+ decode_inner(src.as_ref(), dst, decode_nibble)
+}
+
+/// Decode an upper Base16 (hex) string into a byte vector.
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+pub fn decode_vec(input: impl AsRef<[u8]>) -> Result<Vec<u8>, Error> {
+ let mut output = vec![0u8; decoded_len(input.as_ref())?];
+ decode(input, &mut output)?;
+ Ok(output)
+}
+
+/// Encode the input byte slice as upper Base16.
+///
+/// Writes the result into the provided destination slice, returning an
+/// ASCII-encoded upper Base16 (hex) string value.
+pub fn encode<'a>(src: &[u8], dst: &'a mut [u8]) -> Result<&'a [u8], Error> {
+ let dst = dst
+ .get_mut(..encoded_len(src))
+ .ok_or(Error::InvalidLength)?;
+ for (src, dst) in src.iter().zip(dst.chunks_exact_mut(2)) {
+ dst[0] = encode_nibble(src >> 4);
+ dst[1] = encode_nibble(src & 0x0f);
+ }
+ Ok(dst)
+}
+
+/// Encode input byte slice into a [`&str`] containing upper Base16 (hex).
+pub fn encode_str<'a>(src: &[u8], dst: &'a mut [u8]) -> Result<&'a str, Error> {
+ encode(src, dst).map(|r| unsafe { core::str::from_utf8_unchecked(r) })
+}
+
+/// Encode input byte slice into a [`String`] containing upper Base16 (hex).
+///
+/// # Panics
+/// If `input` length is greater than `usize::MAX/2`.
+#[cfg(feature = "alloc")]
+#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
+pub fn encode_string(input: &[u8]) -> String {
+ let elen = encoded_len(input);
+ let mut dst = vec![0u8; elen];
+ let res = encode(input, &mut dst).expect("dst length is correct");
+
+ debug_assert_eq!(elen, res.len());
+ unsafe { crate::String::from_utf8_unchecked(dst) }
+}
+
+/// Decode a single nibble of upper hex
+#[inline(always)]
+fn decode_nibble(src: u8) -> u16 {
+ // 0-9 0x30-0x39
+ // A-F 0x41-0x46 or a-f 0x61-0x66
+ let byte = src as i16;
+ let mut ret: i16 = -1;
+
+ // 0-9 0x30-0x39
+ // if (byte > 0x2f && byte < 0x3a) ret += byte - 0x30 + 1; // -47
+ ret += (((0x2fi16 - byte) & (byte - 0x3a)) >> 8) & (byte - 47);
+ // A-F 0x41-0x46
+ // if (byte > 0x40 && byte < 0x47) ret += byte - 0x41 + 10 + 1; // -54
+ ret += (((0x40i16 - byte) & (byte - 0x47)) >> 8) & (byte - 54);
+
+ ret as u16
+}
+
+/// Encode a single nibble of hex
+#[inline(always)]
+fn encode_nibble(src: u8) -> u8 {
+ let mut ret = src as i16 + 0x30;
+ // 0-9 0x30-0x39
+ // A-F 0x41-0x46
+ ret += ((0x39i16 - ret) >> 8) & (0x41i16 - 0x3a);
+ ret as u8
+}
diff --git a/vendor/base16ct/tests/lib.rs b/vendor/base16ct/tests/lib.rs
new file mode 100644
index 000000000..eef1b5b84
--- /dev/null
+++ b/vendor/base16ct/tests/lib.rs
@@ -0,0 +1,163 @@
+//! Integration tests.
+
+/// Hexadecimal test vectors
+struct HexVector {
+ /// Raw bytes
+ raw: &'static [u8],
+ /// Lower hex encoded
+ lower_hex: &'static [u8],
+ /// Upper hex encoded
+ upper_hex: &'static [u8],
+}
+
+const HEX_TEST_VECTORS: &[HexVector] = &[
+ HexVector {
+ raw: b"",
+ lower_hex: b"",
+ upper_hex: b"",
+ },
+ HexVector {
+ raw: b"\0",
+ lower_hex: b"00",
+ upper_hex: b"00",
+ },
+ HexVector {
+ raw: b"***",
+ lower_hex: b"2a2a2a",
+ upper_hex: b"2A2A2A",
+ },
+ HexVector {
+ raw: b"\x01\x02\x03\x04",
+ lower_hex: b"01020304",
+ upper_hex: b"01020304",
+ },
+ HexVector {
+ raw: b"\xAD\xAD\xAD\xAD\xAD",
+ lower_hex: b"adadadadad",
+ upper_hex: b"ADADADADAD",
+ },
+ HexVector {
+ raw: b"\xFF\xFF\xFF\xFF\xFF",
+ lower_hex: b"ffffffffff",
+ upper_hex: b"FFFFFFFFFF",
+ },
+];
+
+#[test]
+fn lower_encode() {
+ for vector in HEX_TEST_VECTORS {
+ // 10 is the size of the largest encoded test vector
+ let mut buf = [0u8; 10];
+ let out = base16ct::lower::encode(vector.raw, &mut buf).unwrap();
+ assert_eq!(vector.lower_hex, out);
+ }
+}
+
+#[test]
+fn lower_decode() {
+ for vector in HEX_TEST_VECTORS {
+ // 5 is the size of the largest decoded test vector
+ let mut buf = [0u8; 5];
+ let out = base16ct::lower::decode(vector.lower_hex, &mut buf).unwrap();
+ assert_eq!(vector.raw, out);
+ }
+}
+
+#[test]
+fn lower_reject_odd_size_input() {
+ let mut out = [0u8; 3];
+ assert_eq!(
+ Err(base16ct::Error::InvalidLength),
+ base16ct::lower::decode(b"12345", &mut out),
+ )
+}
+
+#[test]
+fn upper_encode() {
+ for vector in HEX_TEST_VECTORS {
+ // 10 is the size of the largest encoded test vector
+ let mut buf = [0u8; 10];
+ let out = base16ct::upper::encode(vector.raw, &mut buf).unwrap();
+ assert_eq!(vector.upper_hex, out);
+ }
+}
+
+#[test]
+fn upper_decode() {
+ for vector in HEX_TEST_VECTORS {
+ // 5 is the size of the largest decoded test vector
+ let mut buf = [0u8; 5];
+ let out = base16ct::upper::decode(vector.upper_hex, &mut buf).unwrap();
+ assert_eq!(vector.raw, out);
+ }
+}
+
+#[test]
+fn upper_reject_odd_size_input() {
+ let mut out = [0u8; 3];
+ assert_eq!(
+ Err(base16ct::Error::InvalidLength),
+ base16ct::upper::decode(b"12345", &mut out),
+ )
+}
+
+#[test]
+fn mixed_decode() {
+ for vector in HEX_TEST_VECTORS {
+ // 5 is the size of the largest decoded test vector
+ let mut buf = [0u8; 5];
+ let out = base16ct::mixed::decode(vector.upper_hex, &mut buf).unwrap();
+ assert_eq!(vector.raw, out);
+ let out = base16ct::mixed::decode(vector.lower_hex, &mut buf).unwrap();
+ assert_eq!(vector.raw, out);
+ }
+}
+
+#[test]
+fn mixed_reject_odd_size_input() {
+ let mut out = [0u8; 3];
+ assert_eq!(
+ Err(base16ct::Error::InvalidLength),
+ base16ct::mixed::decode(b"12345", &mut out),
+ )
+}
+
+#[test]
+#[cfg(feature = "alloc")]
+fn encode_and_decode_various_lengths() {
+ let data = [b'X'; 64];
+
+ for i in 0..data.len() {
+ let encoded = base16ct::lower::encode_string(&data[..i]);
+ let decoded = base16ct::lower::decode_vec(encoded).unwrap();
+ assert_eq!(decoded.as_slice(), &data[..i]);
+
+ let encoded = base16ct::upper::encode_string(&data[..i]);
+ let decoded = base16ct::upper::decode_vec(encoded).unwrap();
+ assert_eq!(decoded.as_slice(), &data[..i]);
+
+ let encoded = base16ct::lower::encode_string(&data[..i]);
+ let decoded = base16ct::mixed::decode_vec(encoded).unwrap();
+ assert_eq!(decoded.as_slice(), &data[..i]);
+
+ let encoded = base16ct::upper::encode_string(&data[..i]);
+ let decoded = base16ct::mixed::decode_vec(encoded).unwrap();
+ assert_eq!(decoded.as_slice(), &data[..i]);
+ }
+}
+
+#[test]
+fn hex_display_upper() {
+ for vector in HEX_TEST_VECTORS {
+ let hex = format!("{:X}", base16ct::HexDisplay(vector.raw));
+ assert_eq!(hex.as_bytes(), vector.upper_hex);
+ }
+}
+
+#[test]
+fn hex_display_lower() {
+ for vector in HEX_TEST_VECTORS {
+ let hex = format!("{:x}", base16ct::HexDisplay(vector.raw));
+ assert_eq!(hex.as_bytes(), vector.lower_hex);
+ }
+}