summaryrefslogtreecommitdiff
path: root/vendor/subtle
diff options
context:
space:
mode:
authormo khan <mo@mokhan.ca>2025-07-15 16:37:08 -0600
committermo khan <mo@mokhan.ca>2025-07-17 16:30:22 -0600
commit45df4d0d9b577fecee798d672695fe24ff57fb1b (patch)
tree1b99bf645035b58e0d6db08c7a83521f41f7a75b /vendor/subtle
parentf94f79608393d4ab127db63cc41668445ef6b243 (diff)
feat: migrate from Cedar to SpiceDB authorization system
This is a major architectural change that replaces the Cedar policy-based authorization system with SpiceDB's relation-based authorization. Key changes: - Migrate from Rust to Go implementation - Replace Cedar policies with SpiceDB schema and relationships - Switch from envoy `ext_authz` with Cedar to SpiceDB permission checks - Update build system and dependencies for Go ecosystem - Maintain Envoy integration for external authorization This change enables more flexible permission modeling through SpiceDB's Google Zanzibar inspired relation-based system, supporting complex hierarchical permissions that were difficult to express in Cedar. Breaking change: Existing Cedar policies and Rust-based configuration will no longer work and need to be migrated to SpiceDB schema.
Diffstat (limited to 'vendor/subtle')
-rw-r--r--vendor/subtle/.cargo-checksum.json1
-rw-r--r--vendor/subtle/CHANGELOG.md74
-rw-r--r--vendor/subtle/CONTRIBUTING.md33
-rw-r--r--vendor/subtle/Cargo.toml70
-rw-r--r--vendor/subtle/LICENSE29
-rw-r--r--vendor/subtle/README.md74
-rw-r--r--vendor/subtle/src/lib.rs1008
-rw-r--r--vendor/subtle/tests/mod.rs432
8 files changed, 0 insertions, 1721 deletions
diff --git a/vendor/subtle/.cargo-checksum.json b/vendor/subtle/.cargo-checksum.json
deleted file mode 100644
index 9a87d536..00000000
--- a/vendor/subtle/.cargo-checksum.json
+++ /dev/null
@@ -1 +0,0 @@
-{"files":{"CHANGELOG.md":"02f92a31269311c965b1dfa705f22f341dc9cce73af08a8c9840c91b8ceb79df","CONTRIBUTING.md":"2fbb44138ececdef7c0950fae6ed1dcad481fb2f368df0e3734c9902be791f3e","Cargo.toml":"a3b9aefa358b0cd742de62e880ea080414ead838847a95892acaa58575dfc4cf","LICENSE":"d1fc1bc0d155df60b2e7705b6b2ae02a05c96f948e1cec6e2fb86360b09f346b","README.md":"3c538225aea51d063002e1b9732904053061914993f7ec880a18bd597d9df49b","src/lib.rs":"ced6ebd3622af527cbbbb09feb57a2894751ff07e7ca8f97f22bad89401e5c8d","tests/mod.rs":"11223367ef0f5555bd7c5d52dbbc3cee481207208af82319e5c33eadf7a18c08"},"package":"13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"} \ No newline at end of file
diff --git a/vendor/subtle/CHANGELOG.md b/vendor/subtle/CHANGELOG.md
deleted file mode 100644
index e6a38636..00000000
--- a/vendor/subtle/CHANGELOG.md
+++ /dev/null
@@ -1,74 +0,0 @@
-# Changelog
-
-Entries are listed in reverse chronological order.
-
-## 2.5.0
-
-* Add constant-timedness note to the documentation for `CtOption::unwrap_or_else`.
-* Add `CtOption::expect`.
-* Add `ConstantTimeEq::ct_ne` with default implementation.
-* Add new `core_hint_black_box` feature from Diane Hosfelt and Amber
- Sprenkels which utilises the original `black_box` functionality from
- when subtle was first written, which has now found it's way into the
- Rust standard library.
-* Add new `const-generics` feature from @survived which adds support
- for subtle traits for generic arrays `[T; N]`.
-* Add new feature for supporting `core::cmp::Ordering` for types which
- implement subtle traits, patch from @tarcieri.
-* Update `rand` dependency to 0.8.
-
-## 2.4.1
-
-* Fix a bug in how the README was included in the documentation builds
- which caused nightly builds to break.
-
-## 2.4.0
-
-* Add new `ConstantTimeGreater` and `ConstantTimeLess` traits, as well
- as implementations for unsigned integers, by @isislovecruft.
-
-## 2.3.0
-
-* Add `impl ConstantTimeEq for Choice` by @tarcieri.
-* Add `impl From<CtOption<T>> for Option<T>` by @CPerezz. This is useful for
- handling library code that produces `CtOption`s in contexts where timing
- doesn't matter.
-* Introduce an MSRV policy.
-
-## 2.2.3
-
-* Remove the `nightly`-only asm-based `black_box` barrier in favor of the
- volatile-based one, fixing compilation on current nightlies.
-
-## 2.2.2
-
-* Update README.md to clarify that 2.2 and above do not require the `nightly`
- feature.
-
-## 2.2.1
-
-* Adds an `or_else` combinator for `CtOption`, by @ebfull.
-* Optimized `black_box` for `nightly`, by @jethrogb.
-* Optimized `black_box` for `stable`, by @dsprenkels.
-* Fixed CI for `no_std`, by @dsprenkels.
-* Fixed fuzz target compilation, by @3for.
-
-## 2.2.0
-
-* Error during `cargo publish`, yanked.
-
-## 2.1.1
-
-* Adds the "crypto" tag to crate metadata.
-* New shorter, more efficient ct_eq() for integers, contributed by Thomas Pornin.
-
-## 2.1.0
-
-* Adds a new `CtOption<T>` which acts as a constant-time `Option<T>`
- (thanks to @ebfull for the implementation).
-* `Choice` now itself implements `ConditionallySelectable`.
-
-## 2.0.0
-
-* Stable version with traits reworked from 1.0.0 to interact better
- with the orphan rules.
diff --git a/vendor/subtle/CONTRIBUTING.md b/vendor/subtle/CONTRIBUTING.md
deleted file mode 100644
index 2d246051..00000000
--- a/vendor/subtle/CONTRIBUTING.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Contributing to subtle
-
-If you have questions or comments, please feel free to email the
-authors.
-
-For feature requests, suggestions, and bug reports, please open an
-issue on [our Github](https://github.com/dalek-cryptography/subtle). (Or,
-send us an email if you're opposed to using Github for whatever reason.)
-
-Patches are welcomed as pull requests on
-[our Github](https://github.com/dalek-cryptography/subtle), as well as by
-email (preferably sent to all of the authors listed in `Cargo.toml`).
-
-We're happy to take generalised utility code, provided the code is:
-
-1. constant time for all potential valid invocations, and
-2. applicable to implementations of several different protocols/primitives.
-
-All issues on subtle are mentored, if you want help with a bug just ask
-@isislovecruft or @hdevalence.
-
-Some issues are easier than others. The `easy` label can be used to find the
-easy issues. If you want to work on an issue, please leave a comment so that we
-can assign it to you!
-
-# Code of Conduct
-
-We follow the [Rust Code of Conduct](http://www.rust-lang.org/conduct.html),
-with the following additional clauses:
-
-* We respect the rights to privacy and anonymity for contributors and people in
- the community. If someone wishes to contribute under a pseudonym different to
- their primary identity, that wish is to be respected by all contributors.
diff --git a/vendor/subtle/Cargo.toml b/vendor/subtle/Cargo.toml
deleted file mode 100644
index bf78f6f6..00000000
--- a/vendor/subtle/Cargo.toml
+++ /dev/null
@@ -1,70 +0,0 @@
-# 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 = "2018"
-name = "subtle"
-version = "2.6.1"
-authors = [
- "Isis Lovecruft <isis@patternsinthevoid.net>",
- "Henry de Valence <hdevalence@hdevalence.ca>",
-]
-build = false
-exclude = [
- "**/.gitignore",
- ".travis.yml",
-]
-autobins = false
-autoexamples = false
-autotests = false
-autobenches = false
-description = "Pure-Rust traits and utilities for constant-time cryptographic implementations."
-homepage = "https://dalek.rs/"
-documentation = "https://docs.rs/subtle"
-readme = "README.md"
-keywords = [
- "cryptography",
- "crypto",
- "constant-time",
- "utilities",
-]
-categories = [
- "cryptography",
- "no-std",
-]
-license = "BSD-3-Clause"
-repository = "https://github.com/dalek-cryptography/subtle"
-
-[lib]
-name = "subtle"
-path = "src/lib.rs"
-
-[[test]]
-name = "mod"
-path = "tests/mod.rs"
-
-[dev-dependencies.rand]
-version = "0.8"
-
-[features]
-const-generics = []
-core_hint_black_box = []
-default = [
- "std",
- "i128",
-]
-i128 = []
-nightly = []
-std = []
-
-[badges.travis-ci]
-branch = "main"
-repository = "dalek-cryptography/subtle"
diff --git a/vendor/subtle/LICENSE b/vendor/subtle/LICENSE
deleted file mode 100644
index 9e2751f8..00000000
--- a/vendor/subtle/LICENSE
+++ /dev/null
@@ -1,29 +0,0 @@
-Copyright (c) 2016-2017 Isis Agora Lovecruft, Henry de Valence. All rights reserved.
-Copyright (c) 2016-2024 Isis Agora Lovecruft. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-1. Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-
-3. Neither the name of the copyright holder nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/subtle/README.md b/vendor/subtle/README.md
deleted file mode 100644
index a9eb2610..00000000
--- a/vendor/subtle/README.md
+++ /dev/null
@@ -1,74 +0,0 @@
-# subtle [![](https://img.shields.io/crates/v/subtle.svg)](https://crates.io/crates/subtle) [![](https://img.shields.io/badge/dynamic/json.svg?label=docs&uri=https%3A%2F%2Fcrates.io%2Fapi%2Fv1%2Fcrates%2Fsubtle%2Fversions&query=%24.versions%5B0%5D.num&colorB=4F74A6)](https://doc.dalek.rs/subtle) [![](https://travis-ci.org/dalek-cryptography/subtle.svg?branch=master)](https://travis-ci.org/dalek-cryptography/subtle)
-
-**Pure-Rust traits and utilities for constant-time cryptographic implementations.**
-
-It consists of a `Choice` type, and a collection of traits using `Choice`
-instead of `bool` which are intended to execute in constant-time. The `Choice`
-type is a wrapper around a `u8` that holds a `0` or `1`.
-
-```toml
-subtle = "2.6"
-```
-
-This crate represents a “best-effort” attempt, since side-channels
-are ultimately a property of a deployed cryptographic system
-including the hardware it runs on, not just of software.
-
-The traits are implemented using bitwise operations, and should execute in
-constant time provided that a) the bitwise operations are constant-time and
-b) the bitwise operations are not recognized as a conditional assignment and
-optimized back into a branch.
-
-For a compiler to recognize that bitwise operations represent a conditional
-assignment, it needs to know that the value used to generate the bitmasks is
-really a boolean `i1` rather than an `i8` byte value. In an attempt to
-prevent this refinement, the crate tries to hide the value of a `Choice`'s
-inner `u8` by passing it through a volatile read. For more information, see
-the _About_ section below.
-
-Rust versions from 1.51 or higher have const generics support. You may enable
-`const-generics` feautre to have `subtle` traits implemented for arrays `[T; N]`.
-
-Versions prior to `2.2` recommended use of the `nightly` feature to enable an
-optimization barrier; this is not required in versions `2.2` and above.
-
-Note: the `subtle` crate contains `debug_assert`s to check invariants during
-debug builds. These invariant checks involve secret-dependent branches, and
-are not present when compiled in release mode. This crate is intended to be
-used in release mode.
-
-## Documentation
-
-Documentation is available [here][docs].
-
-## Minimum Supported Rust Version
-
-Rust **1.41** or higher.
-
-Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump.
-
-## About
-
-This library aims to be the Rust equivalent of Go’s `crypto/subtle` module.
-
-Old versions of the optimization barrier in `impl From<u8> for Choice` were
-based on Tim Maclean's [work on `rust-timing-shield`][rust-timing-shield],
-which attempts to provide a more comprehensive approach for preventing
-software side-channels in Rust code.
-From version `2.2`, it was based on Diane Hosfelt and Amber Sprenkels' work on
-"Secret Types in Rust".
-
-`subtle` is authored by isis agora lovecruft and Henry de Valence.
-
-## Warning
-
-This code is a low-level library, intended for specific use-cases implementing
-cryptographic protocols. It represents a best-effort attempt to protect
-against some software side-channels. Because side-channel resistance is not a
-property of software alone, but of software together with hardware, any such
-effort is fundamentally limited.
-
-**USE AT YOUR OWN RISK**
-
-[docs]: https://docs.rs/subtle
-[rust-timing-shield]: https://www.chosenplaintext.ca/open-source/rust-timing-shield/security
diff --git a/vendor/subtle/src/lib.rs b/vendor/subtle/src/lib.rs
deleted file mode 100644
index 9fc143b2..00000000
--- a/vendor/subtle/src/lib.rs
+++ /dev/null
@@ -1,1008 +0,0 @@
-// -*- mode: rust; -*-
-//
-// This file is part of subtle, part of the dalek cryptography project.
-// Copyright (c) 2016-2018 isis lovecruft, Henry de Valence
-// See LICENSE for licensing information.
-//
-// Authors:
-// - isis agora lovecruft <isis@patternsinthevoid.net>
-// - Henry de Valence <hdevalence@hdevalence.ca>
-
-#![no_std]
-#![deny(missing_docs)]
-#![doc(html_logo_url = "https://doc.dalek.rs/assets/dalek-logo-clear.png")]
-#![doc(html_root_url = "https://docs.rs/subtle/2.6.0")]
-
-//! # subtle [![](https://img.shields.io/crates/v/subtle.svg)](https://crates.io/crates/subtle) [![](https://img.shields.io/badge/dynamic/json.svg?label=docs&uri=https%3A%2F%2Fcrates.io%2Fapi%2Fv1%2Fcrates%2Fsubtle%2Fversions&query=%24.versions%5B0%5D.num&colorB=4F74A6)](https://doc.dalek.rs/subtle) [![](https://travis-ci.org/dalek-cryptography/subtle.svg?branch=master)](https://travis-ci.org/dalek-cryptography/subtle)
-//!
-//! **Pure-Rust traits and utilities for constant-time cryptographic implementations.**
-//!
-//! It consists of a `Choice` type, and a collection of traits using `Choice`
-//! instead of `bool` which are intended to execute in constant-time. The `Choice`
-//! type is a wrapper around a `u8` that holds a `0` or `1`.
-//!
-//! ```toml
-//! subtle = "2.6"
-//! ```
-//!
-//! This crate represents a “best-effort” attempt, since side-channels
-//! are ultimately a property of a deployed cryptographic system
-//! including the hardware it runs on, not just of software.
-//!
-//! The traits are implemented using bitwise operations, and should execute in
-//! constant time provided that a) the bitwise operations are constant-time and
-//! b) the bitwise operations are not recognized as a conditional assignment and
-//! optimized back into a branch.
-//!
-//! For a compiler to recognize that bitwise operations represent a conditional
-//! assignment, it needs to know that the value used to generate the bitmasks is
-//! really a boolean `i1` rather than an `i8` byte value. In an attempt to
-//! prevent this refinement, the crate tries to hide the value of a `Choice`'s
-//! inner `u8` by passing it through a volatile read. For more information, see
-//! the _About_ section below.
-//!
-//! Rust versions from 1.51 or higher have const generics support. You may enable
-//! `const-generics` feautre to have `subtle` traits implemented for arrays `[T; N]`.
-//!
-//! Versions prior to `2.2` recommended use of the `nightly` feature to enable an
-//! optimization barrier; this is not required in versions `2.2` and above.
-//!
-//! Note: the `subtle` crate contains `debug_assert`s to check invariants during
-//! debug builds. These invariant checks involve secret-dependent branches, and
-//! are not present when compiled in release mode. This crate is intended to be
-//! used in release mode.
-//!
-//! ## Documentation
-//!
-//! Documentation is available [here][docs].
-//!
-//! ## Minimum Supported Rust Version
-//!
-//! Rust **1.41** or higher.
-//!
-//! Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump.
-//!
-//! ## About
-//!
-//! This library aims to be the Rust equivalent of Go’s `crypto/subtle` module.
-//!
-//! Old versions of the optimization barrier in `impl From<u8> for Choice` were
-//! based on Tim Maclean's [work on `rust-timing-shield`][rust-timing-shield],
-//! which attempts to provide a more comprehensive approach for preventing
-//! software side-channels in Rust code.
-//! From version `2.2`, it was based on Diane Hosfelt and Amber Sprenkels' work on
-//! "Secret Types in Rust".
-//!
-//! `subtle` is authored by isis agora lovecruft and Henry de Valence.
-//!
-//! ## Warning
-//!
-//! This code is a low-level library, intended for specific use-cases implementing
-//! cryptographic protocols. It represents a best-effort attempt to protect
-//! against some software side-channels. Because side-channel resistance is not a
-//! property of software alone, but of software together with hardware, any such
-//! effort is fundamentally limited.
-//!
-//! **USE AT YOUR OWN RISK**
-//!
-//! [docs]: https://docs.rs/subtle
-//! [rust-timing-shield]: https://www.chosenplaintext.ca/open-source/rust-timing-shield/security
-
-#[cfg(feature = "std")]
-#[macro_use]
-extern crate std;
-
-use core::cmp;
-use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Neg, Not};
-use core::option::Option;
-
-#[cfg(feature = "core_hint_black_box")]
-use core::hint::black_box;
-
-/// The `Choice` struct represents a choice for use in conditional assignment.
-///
-/// It is a wrapper around a `u8`, which should have the value either `1` (true)
-/// or `0` (false).
-///
-/// The conversion from `u8` to `Choice` passes the value through an optimization
-/// barrier, as a best-effort attempt to prevent the compiler from inferring that
-/// the `Choice` value is a boolean. This strategy is based on Tim Maclean's
-/// [work on `rust-timing-shield`][rust-timing-shield], which attempts to provide
-/// a more comprehensive approach for preventing software side-channels in Rust
-/// code.
-///
-/// The `Choice` struct implements operators for AND, OR, XOR, and NOT, to allow
-/// combining `Choice` values. These operations do not short-circuit.
-///
-/// [rust-timing-shield]:
-/// https://www.chosenplaintext.ca/open-source/rust-timing-shield/security
-#[derive(Copy, Clone, Debug)]
-pub struct Choice(u8);
-
-impl Choice {
- /// Unwrap the `Choice` wrapper to reveal the underlying `u8`.
- ///
- /// # Note
- ///
- /// This function only exists as an **escape hatch** for the rare case
- /// where it's not possible to use one of the `subtle`-provided
- /// trait impls.
- ///
- /// **To convert a `Choice` to a `bool`, use the `From` implementation instead.**
- #[inline]
- pub fn unwrap_u8(&self) -> u8 {
- self.0
- }
-}
-
-impl From<Choice> for bool {
- /// Convert the `Choice` wrapper into a `bool`, depending on whether
- /// the underlying `u8` was a `0` or a `1`.
- ///
- /// # Note
- ///
- /// This function exists to avoid having higher-level cryptographic protocol
- /// implementations duplicating this pattern.
- ///
- /// The intended use case for this conversion is at the _end_ of a
- /// higher-level primitive implementation: for example, in checking a keyed
- /// MAC, where the verification should happen in constant-time (and thus use
- /// a `Choice`) but it is safe to return a `bool` at the end of the
- /// verification.
- #[inline]
- fn from(source: Choice) -> bool {
- debug_assert!((source.0 == 0u8) | (source.0 == 1u8));
- source.0 != 0
- }
-}
-
-impl BitAnd for Choice {
- type Output = Choice;
- #[inline]
- fn bitand(self, rhs: Choice) -> Choice {
- (self.0 & rhs.0).into()
- }
-}
-
-impl BitAndAssign for Choice {
- #[inline]
- fn bitand_assign(&mut self, rhs: Choice) {
- *self = *self & rhs;
- }
-}
-
-impl BitOr for Choice {
- type Output = Choice;
- #[inline]
- fn bitor(self, rhs: Choice) -> Choice {
- (self.0 | rhs.0).into()
- }
-}
-
-impl BitOrAssign for Choice {
- #[inline]
- fn bitor_assign(&mut self, rhs: Choice) {
- *self = *self | rhs;
- }
-}
-
-impl BitXor for Choice {
- type Output = Choice;
- #[inline]
- fn bitxor(self, rhs: Choice) -> Choice {
- (self.0 ^ rhs.0).into()
- }
-}
-
-impl BitXorAssign for Choice {
- #[inline]
- fn bitxor_assign(&mut self, rhs: Choice) {
- *self = *self ^ rhs;
- }
-}
-
-impl Not for Choice {
- type Output = Choice;
- #[inline]
- fn not(self) -> Choice {
- (1u8 & (!self.0)).into()
- }
-}
-
-/// This function is a best-effort attempt to prevent the compiler from knowing
-/// anything about the value of the returned `u8`, other than its type.
-///
-/// Because we want to support stable Rust, we don't have access to inline
-/// assembly or test::black_box, so we use the fact that volatile values will
-/// never be elided to register values.
-///
-/// Note: Rust's notion of "volatile" is subject to change over time. While this
-/// code may break in a non-destructive way in the future, “constant-time” code
-/// is a continually moving target, and this is better than doing nothing.
-#[cfg(not(feature = "core_hint_black_box"))]
-#[inline(never)]
-fn black_box<T: Copy>(input: T) -> T {
- unsafe {
- // Optimization barrier
- //
- // SAFETY:
- // - &input is not NULL because we own input;
- // - input is Copy and always live;
- // - input is always properly aligned.
- core::ptr::read_volatile(&input)
- }
-}
-
-impl From<u8> for Choice {
- #[inline]
- fn from(input: u8) -> Choice {
- debug_assert!((input == 0u8) | (input == 1u8));
-
- // Our goal is to prevent the compiler from inferring that the value held inside the
- // resulting `Choice` struct is really a `bool` instead of a `u8`.
- Choice(black_box(input))
- }
-}
-
-/// An `Eq`-like trait that produces a `Choice` instead of a `bool`.
-///
-/// # Example
-///
-/// ```
-/// use subtle::ConstantTimeEq;
-/// let x: u8 = 5;
-/// let y: u8 = 13;
-///
-/// assert_eq!(x.ct_eq(&y).unwrap_u8(), 0);
-/// assert_eq!(x.ct_eq(&x).unwrap_u8(), 1);
-/// ```
-//
-// #[inline] is specified on these function prototypes to signify that they
-#[allow(unused_attributes)] // should be in the actual implementation
-pub trait ConstantTimeEq {
- /// Determine if two items are equal.
- ///
- /// The `ct_eq` function should execute in constant time.
- ///
- /// # Returns
- ///
- /// * `Choice(1u8)` if `self == other`;
- /// * `Choice(0u8)` if `self != other`.
- #[inline]
- #[allow(unused_attributes)]
- fn ct_eq(&self, other: &Self) -> Choice;
-
- /// Determine if two items are NOT equal.
- ///
- /// The `ct_ne` function should execute in constant time.
- ///
- /// # Returns
- ///
- /// * `Choice(0u8)` if `self == other`;
- /// * `Choice(1u8)` if `self != other`.
- #[inline]
- fn ct_ne(&self, other: &Self) -> Choice {
- !self.ct_eq(other)
- }
-}
-
-impl<T: ConstantTimeEq> ConstantTimeEq for [T] {
- /// Check whether two slices of `ConstantTimeEq` types are equal.
- ///
- /// # Note
- ///
- /// This function short-circuits if the lengths of the input slices
- /// are different. Otherwise, it should execute in time independent
- /// of the slice contents.
- ///
- /// Since arrays coerce to slices, this function works with fixed-size arrays:
- ///
- /// ```
- /// # use subtle::ConstantTimeEq;
- /// #
- /// let a: [u8; 8] = [0,1,2,3,4,5,6,7];
- /// let b: [u8; 8] = [0,1,2,3,0,1,2,3];
- ///
- /// let a_eq_a = a.ct_eq(&a);
- /// let a_eq_b = a.ct_eq(&b);
- ///
- /// assert_eq!(a_eq_a.unwrap_u8(), 1);
- /// assert_eq!(a_eq_b.unwrap_u8(), 0);
- /// ```
- #[inline]
- fn ct_eq(&self, _rhs: &[T]) -> Choice {
- let len = self.len();
-
- // Short-circuit on the *lengths* of the slices, not their
- // contents.
- if len != _rhs.len() {
- return Choice::from(0);
- }
-
- // This loop shouldn't be shortcircuitable, since the compiler
- // shouldn't be able to reason about the value of the `u8`
- // unwrapped from the `ct_eq` result.
- let mut x = 1u8;
- for (ai, bi) in self.iter().zip(_rhs.iter()) {
- x &= ai.ct_eq(bi).unwrap_u8();
- }
-
- x.into()
- }
-}
-
-impl ConstantTimeEq for Choice {
- #[inline]
- fn ct_eq(&self, rhs: &Choice) -> Choice {
- !(*self ^ *rhs)
- }
-}
-
-/// Given the bit-width `$bit_width` and the corresponding primitive
-/// unsigned and signed types `$t_u` and `$t_i` respectively, generate
-/// an `ConstantTimeEq` implementation.
-macro_rules! generate_integer_equal {
- ($t_u:ty, $t_i:ty, $bit_width:expr) => {
- impl ConstantTimeEq for $t_u {
- #[inline]
- fn ct_eq(&self, other: &$t_u) -> Choice {
- // x == 0 if and only if self == other
- let x: $t_u = self ^ other;
-
- // If x == 0, then x and -x are both equal to zero;
- // otherwise, one or both will have its high bit set.
- let y: $t_u = (x | x.wrapping_neg()) >> ($bit_width - 1);
-
- // Result is the opposite of the high bit (now shifted to low).
- ((y ^ (1 as $t_u)) as u8).into()
- }
- }
- impl ConstantTimeEq for $t_i {
- #[inline]
- fn ct_eq(&self, other: &$t_i) -> Choice {
- // Bitcast to unsigned and call that implementation.
- (*self as $t_u).ct_eq(&(*other as $t_u))
- }
- }
- };
-}
-
-generate_integer_equal!(u8, i8, 8);
-generate_integer_equal!(u16, i16, 16);
-generate_integer_equal!(u32, i32, 32);
-generate_integer_equal!(u64, i64, 64);
-#[cfg(feature = "i128")]
-generate_integer_equal!(u128, i128, 128);
-generate_integer_equal!(usize, isize, ::core::mem::size_of::<usize>() * 8);
-
-/// `Ordering` is `#[repr(i8)]` making it possible to leverage `i8::ct_eq`.
-impl ConstantTimeEq for cmp::Ordering {
- #[inline]
- fn ct_eq(&self, other: &Self) -> Choice {
- (*self as i8).ct_eq(&(*other as i8))
- }
-}
-
-/// A type which can be conditionally selected in constant time.
-///
-/// This trait also provides generic implementations of conditional
-/// assignment and conditional swaps.
-//
-// #[inline] is specified on these function prototypes to signify that they
-#[allow(unused_attributes)] // should be in the actual implementation
-pub trait ConditionallySelectable: Copy {
- /// Select `a` or `b` according to `choice`.
- ///
- /// # Returns
- ///
- /// * `a` if `choice == Choice(0)`;
- /// * `b` if `choice == Choice(1)`.
- ///
- /// This function should execute in constant time.
- ///
- /// # Example
- ///
- /// ```
- /// use subtle::ConditionallySelectable;
- /// #
- /// # fn main() {
- /// let x: u8 = 13;
- /// let y: u8 = 42;
- ///
- /// let z = u8::conditional_select(&x, &y, 0.into());
- /// assert_eq!(z, x);
- /// let z = u8::conditional_select(&x, &y, 1.into());
- /// assert_eq!(z, y);
- /// # }
- /// ```
- #[inline]
- #[allow(unused_attributes)]
- fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self;
-
- /// Conditionally assign `other` to `self`, according to `choice`.
- ///
- /// This function should execute in constant time.
- ///
- /// # Example
- ///
- /// ```
- /// use subtle::ConditionallySelectable;
- /// #
- /// # fn main() {
- /// let mut x: u8 = 13;
- /// let mut y: u8 = 42;
- ///
- /// x.conditional_assign(&y, 0.into());
- /// assert_eq!(x, 13);
- /// x.conditional_assign(&y, 1.into());
- /// assert_eq!(x, 42);
- /// # }
- /// ```
- #[inline]
- fn conditional_assign(&mut self, other: &Self, choice: Choice) {
- *self = Self::conditional_select(self, other, choice);
- }
-
- /// Conditionally swap `self` and `other` if `choice == 1`; otherwise,
- /// reassign both unto themselves.
- ///
- /// This function should execute in constant time.
- ///
- /// # Example
- ///
- /// ```
- /// use subtle::ConditionallySelectable;
- /// #
- /// # fn main() {
- /// let mut x: u8 = 13;
- /// let mut y: u8 = 42;
- ///
- /// u8::conditional_swap(&mut x, &mut y, 0.into());
- /// assert_eq!(x, 13);
- /// assert_eq!(y, 42);
- /// u8::conditional_swap(&mut x, &mut y, 1.into());
- /// assert_eq!(x, 42);
- /// assert_eq!(y, 13);
- /// # }
- /// ```
- #[inline]
- fn conditional_swap(a: &mut Self, b: &mut Self, choice: Choice) {
- let t: Self = *a;
- a.conditional_assign(&b, choice);
- b.conditional_assign(&t, choice);
- }
-}
-
-macro_rules! to_signed_int {
- (u8) => {
- i8
- };
- (u16) => {
- i16
- };
- (u32) => {
- i32
- };
- (u64) => {
- i64
- };
- (u128) => {
- i128
- };
- (i8) => {
- i8
- };
- (i16) => {
- i16
- };
- (i32) => {
- i32
- };
- (i64) => {
- i64
- };
- (i128) => {
- i128
- };
-}
-
-macro_rules! generate_integer_conditional_select {
- ($($t:tt)*) => ($(
- impl ConditionallySelectable for $t {
- #[inline]
- fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
- // if choice = 0, mask = (-0) = 0000...0000
- // if choice = 1, mask = (-1) = 1111...1111
- let mask = -(choice.unwrap_u8() as to_signed_int!($t)) as $t;
- a ^ (mask & (a ^ b))
- }
-
- #[inline]
- fn conditional_assign(&mut self, other: &Self, choice: Choice) {
- // if choice = 0, mask = (-0) = 0000...0000
- // if choice = 1, mask = (-1) = 1111...1111
- let mask = -(choice.unwrap_u8() as to_signed_int!($t)) as $t;
- *self ^= mask & (*self ^ *other);
- }
-
- #[inline]
- fn conditional_swap(a: &mut Self, b: &mut Self, choice: Choice) {
- // if choice = 0, mask = (-0) = 0000...0000
- // if choice = 1, mask = (-1) = 1111...1111
- let mask = -(choice.unwrap_u8() as to_signed_int!($t)) as $t;
- let t = mask & (*a ^ *b);
- *a ^= t;
- *b ^= t;
- }
- }
- )*)
-}
-
-generate_integer_conditional_select!( u8 i8);
-generate_integer_conditional_select!( u16 i16);
-generate_integer_conditional_select!( u32 i32);
-generate_integer_conditional_select!( u64 i64);
-#[cfg(feature = "i128")]
-generate_integer_conditional_select!(u128 i128);
-
-/// `Ordering` is `#[repr(i8)]` where:
-///
-/// - `Less` => -1
-/// - `Equal` => 0
-/// - `Greater` => 1
-///
-/// Given this, it's possible to operate on orderings as if they're integers,
-/// which allows leveraging conditional masking for predication.
-impl ConditionallySelectable for cmp::Ordering {
- fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
- let a = *a as i8;
- let b = *b as i8;
- let ret = i8::conditional_select(&a, &b, choice);
-
- // SAFETY: `Ordering` is `#[repr(i8)]` and `ret` has been assigned to
- // a value which was originally a valid `Ordering` then cast to `i8`
- unsafe { *((&ret as *const _) as *const cmp::Ordering) }
- }
-}
-
-impl ConditionallySelectable for Choice {
- #[inline]
- fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
- Choice(u8::conditional_select(&a.0, &b.0, choice))
- }
-}
-
-#[cfg(feature = "const-generics")]
-impl<T, const N: usize> ConditionallySelectable for [T; N]
-where
- T: ConditionallySelectable,
-{
- #[inline]
- fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
- let mut output = *a;
- output.conditional_assign(b, choice);
- output
- }
-
- fn conditional_assign(&mut self, other: &Self, choice: Choice) {
- for (a_i, b_i) in self.iter_mut().zip(other) {
- a_i.conditional_assign(b_i, choice)
- }
- }
-}
-
-/// A type which can be conditionally negated in constant time.
-///
-/// # Note
-///
-/// A generic implementation of `ConditionallyNegatable` is provided
-/// for types `T` which are `ConditionallySelectable` and have `Neg`
-/// implemented on `&T`.
-//
-// #[inline] is specified on these function prototypes to signify that they
-#[allow(unused_attributes)] // should be in the actual implementation
-pub trait ConditionallyNegatable {
- /// Negate `self` if `choice == Choice(1)`; otherwise, leave it
- /// unchanged.
- ///
- /// This function should execute in constant time.
- #[inline]
- #[allow(unused_attributes)]
- fn conditional_negate(&mut self, choice: Choice);
-}
-
-impl<T> ConditionallyNegatable for T
-where
- T: ConditionallySelectable,
- for<'a> &'a T: Neg<Output = T>,
-{
- #[inline]
- fn conditional_negate(&mut self, choice: Choice) {
- // Need to cast to eliminate mutability
- let self_neg: T = -(self as &T);
- self.conditional_assign(&self_neg, choice);
- }
-}
-
-/// The `CtOption<T>` type represents an optional value similar to the
-/// [`Option<T>`](core::option::Option) type but is intended for
-/// use in constant time APIs.
-///
-/// Any given `CtOption<T>` is either `Some` or `None`, but unlike
-/// `Option<T>` these variants are not exposed. The
-/// [`is_some()`](CtOption::is_some) method is used to determine if
-/// the value is `Some`, and [`unwrap_or()`](CtOption::unwrap_or) and
-/// [`unwrap_or_else()`](CtOption::unwrap_or_else) methods are
-/// provided to access the underlying value. The value can also be
-/// obtained with [`unwrap()`](CtOption::unwrap) but this will panic
-/// if it is `None`.
-///
-/// Functions that are intended to be constant time may not produce
-/// valid results for all inputs, such as square root and inversion
-/// operations in finite field arithmetic. Returning an `Option<T>`
-/// from these functions makes it difficult for the caller to reason
-/// about the result in constant time, and returning an incorrect
-/// value burdens the caller and increases the chance of bugs.
-#[derive(Clone, Copy, Debug)]
-pub struct CtOption<T> {
- value: T,
- is_some: Choice,
-}
-
-impl<T> From<CtOption<T>> for Option<T> {
- /// Convert the `CtOption<T>` wrapper into an `Option<T>`, depending on whether
- /// the underlying `is_some` `Choice` was a `0` or a `1` once unwrapped.
- ///
- /// # Note
- ///
- /// This function exists to avoid ending up with ugly, verbose and/or bad handled
- /// conversions from the `CtOption<T>` wraps to an `Option<T>` or `Result<T, E>`.
- /// This implementation doesn't intend to be constant-time nor try to protect the
- /// leakage of the `T` since the `Option<T>` will do it anyways.
- fn from(source: CtOption<T>) -> Option<T> {
- if source.is_some().unwrap_u8() == 1u8 {
- Option::Some(source.value)
- } else {
- None
- }
- }
-}
-
-impl<T> CtOption<T> {
- /// This method is used to construct a new `CtOption<T>` and takes
- /// a value of type `T`, and a `Choice` that determines whether
- /// the optional value should be `Some` or not. If `is_some` is
- /// false, the value will still be stored but its value is never
- /// exposed.
- #[inline]
- pub fn new(value: T, is_some: Choice) -> CtOption<T> {
- CtOption {
- value: value,
- is_some: is_some,
- }
- }
-
- /// Returns the contained value, consuming the `self` value.
- ///
- /// # Panics
- ///
- /// Panics if the value is none with a custom panic message provided by
- /// `msg`.
- pub fn expect(self, msg: &str) -> T {
- assert_eq!(self.is_some.unwrap_u8(), 1, "{}", msg);
-
- self.value
- }
-
- /// This returns the underlying value but panics if it
- /// is not `Some`.
- #[inline]
- pub fn unwrap(self) -> T {
- assert_eq!(self.is_some.unwrap_u8(), 1);
-
- self.value
- }
-
- /// This returns the underlying value if it is `Some`
- /// or the provided value otherwise.
- #[inline]
- pub fn unwrap_or(self, def: T) -> T
- where
- T: ConditionallySelectable,
- {
- T::conditional_select(&def, &self.value, self.is_some)
- }
-
- /// This returns the underlying value if it is `Some`
- /// or the value produced by the provided closure otherwise.
- ///
- /// This operates in constant time, because the provided closure
- /// is always called.
- #[inline]
- pub fn unwrap_or_else<F>(self, f: F) -> T
- where
- T: ConditionallySelectable,
- F: FnOnce() -> T,
- {
- T::conditional_select(&f(), &self.value, self.is_some)
- }
-
- /// Returns a true `Choice` if this value is `Some`.
- #[inline]
- pub fn is_some(&self) -> Choice {
- self.is_some
- }
-
- /// Returns a true `Choice` if this value is `None`.
- #[inline]
- pub fn is_none(&self) -> Choice {
- !self.is_some
- }
-
- /// Returns a `None` value if the option is `None`, otherwise
- /// returns a `CtOption` enclosing the value of the provided closure.
- /// The closure is given the enclosed value or, if the option is
- /// `None`, it is provided a dummy value computed using
- /// `Default::default()`.
- ///
- /// This operates in constant time, because the provided closure
- /// is always called.
- #[inline]
- pub fn map<U, F>(self, f: F) -> CtOption<U>
- where
- T: Default + ConditionallySelectable,
- F: FnOnce(T) -> U,
- {
- CtOption::new(
- f(T::conditional_select(
- &T::default(),
- &self.value,
- self.is_some,
- )),
- self.is_some,
- )
- }
-
- /// Returns a `None` value if the option is `None`, otherwise
- /// returns the result of the provided closure. The closure is
- /// given the enclosed value or, if the option is `None`, it
- /// is provided a dummy value computed using `Default::default()`.
- ///
- /// This operates in constant time, because the provided closure
- /// is always called.
- #[inline]
- pub fn and_then<U, F>(self, f: F) -> CtOption<U>
- where
- T: Default + ConditionallySelectable,
- F: FnOnce(T) -> CtOption<U>,
- {
- let mut tmp = f(T::conditional_select(
- &T::default(),
- &self.value,
- self.is_some,
- ));
- tmp.is_some &= self.is_some;
-
- tmp
- }
-
- /// Returns `self` if it contains a value, and otherwise returns the result of
- /// calling `f`. The provided function `f` is always called.
- #[inline]
- pub fn or_else<F>(self, f: F) -> CtOption<T>
- where
- T: ConditionallySelectable,
- F: FnOnce() -> CtOption<T>,
- {
- let is_none = self.is_none();
- let f = f();
-
- Self::conditional_select(&self, &f, is_none)
- }
-
- /// Convert the `CtOption<T>` wrapper into an `Option<T>`, depending on whether
- /// the underlying `is_some` `Choice` was a `0` or a `1` once unwrapped.
- ///
- /// # Note
- ///
- /// This function exists to avoid ending up with ugly, verbose and/or bad handled
- /// conversions from the `CtOption<T>` wraps to an `Option<T>` or `Result<T, E>`.
- /// This implementation doesn't intend to be constant-time nor try to protect the
- /// leakage of the `T` since the `Option<T>` will do it anyways.
- ///
- /// It's equivalent to the corresponding `From` impl, however this version is
- /// friendlier for type inference.
- pub fn into_option(self) -> Option<T> {
- self.into()
- }
-}
-
-impl<T: ConditionallySelectable> ConditionallySelectable for CtOption<T> {
- fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
- CtOption::new(
- T::conditional_select(&a.value, &b.value, choice),
- Choice::conditional_select(&a.is_some, &b.is_some, choice),
- )
- }
-}
-
-impl<T: ConstantTimeEq> ConstantTimeEq for CtOption<T> {
- /// Two `CtOption<T>`s are equal if they are both `Some` and
- /// their values are equal, or both `None`.
- #[inline]
- fn ct_eq(&self, rhs: &CtOption<T>) -> Choice {
- let a = self.is_some();
- let b = rhs.is_some();
-
- (a & b & self.value.ct_eq(&rhs.value)) | (!a & !b)
- }
-}
-
-/// A type which can be compared in some manner and be determined to be greater
-/// than another of the same type.
-pub trait ConstantTimeGreater {
- /// Determine whether `self > other`.
- ///
- /// The bitwise-NOT of the return value of this function should be usable to
- /// determine if `self <= other`.
- ///
- /// This function should execute in constant time.
- ///
- /// # Returns
- ///
- /// A `Choice` with a set bit if `self > other`, and with no set bits
- /// otherwise.
- ///
- /// # Example
- ///
- /// ```
- /// use subtle::ConstantTimeGreater;
- ///
- /// let x: u8 = 13;
- /// let y: u8 = 42;
- ///
- /// let x_gt_y = x.ct_gt(&y);
- ///
- /// assert_eq!(x_gt_y.unwrap_u8(), 0);
- ///
- /// let y_gt_x = y.ct_gt(&x);
- ///
- /// assert_eq!(y_gt_x.unwrap_u8(), 1);
- ///
- /// let x_gt_x = x.ct_gt(&x);
- ///
- /// assert_eq!(x_gt_x.unwrap_u8(), 0);
- /// ```
- fn ct_gt(&self, other: &Self) -> Choice;
-}
-
-macro_rules! generate_unsigned_integer_greater {
- ($t_u: ty, $bit_width: expr) => {
- impl ConstantTimeGreater for $t_u {
- /// Returns Choice::from(1) iff x > y, and Choice::from(0) iff x <= y.
- ///
- /// # Note
- ///
- /// This algoritm would also work for signed integers if we first
- /// flip the top bit, e.g. `let x: u8 = x ^ 0x80`, etc.
- #[inline]
- fn ct_gt(&self, other: &$t_u) -> Choice {
- let gtb = self & !other; // All the bits in self that are greater than their corresponding bits in other.
- let mut ltb = !self & other; // All the bits in self that are less than their corresponding bits in other.
- let mut pow = 1;
-
- // Less-than operator is okay here because it's dependent on the bit-width.
- while pow < $bit_width {
- ltb |= ltb >> pow; // Bit-smear the highest set bit to the right.
- pow += pow;
- }
- let mut bit = gtb & !ltb; // Select the highest set bit.
- let mut pow = 1;
-
- while pow < $bit_width {
- bit |= bit >> pow; // Shift it to the right until we end up with either 0 or 1.
- pow += pow;
- }
- // XXX We should possibly do the above flattening to 0 or 1 in the
- // Choice constructor rather than making it a debug error?
- Choice::from((bit & 1) as u8)
- }
- }
- };
-}
-
-generate_unsigned_integer_greater!(u8, 8);
-generate_unsigned_integer_greater!(u16, 16);
-generate_unsigned_integer_greater!(u32, 32);
-generate_unsigned_integer_greater!(u64, 64);
-#[cfg(feature = "i128")]
-generate_unsigned_integer_greater!(u128, 128);
-
-impl ConstantTimeGreater for cmp::Ordering {
- #[inline]
- fn ct_gt(&self, other: &Self) -> Choice {
- // No impl of `ConstantTimeGreater` for `i8`, so use `u8`
- let a = (*self as i8) + 1;
- let b = (*other as i8) + 1;
- (a as u8).ct_gt(&(b as u8))
- }
-}
-
-/// A type which can be compared in some manner and be determined to be less
-/// than another of the same type.
-pub trait ConstantTimeLess: ConstantTimeEq + ConstantTimeGreater {
- /// Determine whether `self < other`.
- ///
- /// The bitwise-NOT of the return value of this function should be usable to
- /// determine if `self >= other`.
- ///
- /// A default implementation is provided and implemented for the unsigned
- /// integer types.
- ///
- /// This function should execute in constant time.
- ///
- /// # Returns
- ///
- /// A `Choice` with a set bit if `self < other`, and with no set bits
- /// otherwise.
- ///
- /// # Example
- ///
- /// ```
- /// use subtle::ConstantTimeLess;
- ///
- /// let x: u8 = 13;
- /// let y: u8 = 42;
- ///
- /// let x_lt_y = x.ct_lt(&y);
- ///
- /// assert_eq!(x_lt_y.unwrap_u8(), 1);
- ///
- /// let y_lt_x = y.ct_lt(&x);
- ///
- /// assert_eq!(y_lt_x.unwrap_u8(), 0);
- ///
- /// let x_lt_x = x.ct_lt(&x);
- ///
- /// assert_eq!(x_lt_x.unwrap_u8(), 0);
- /// ```
- #[inline]
- fn ct_lt(&self, other: &Self) -> Choice {
- !self.ct_gt(other) & !self.ct_eq(other)
- }
-}
-
-impl ConstantTimeLess for u8 {}
-impl ConstantTimeLess for u16 {}
-impl ConstantTimeLess for u32 {}
-impl ConstantTimeLess for u64 {}
-#[cfg(feature = "i128")]
-impl ConstantTimeLess for u128 {}
-
-impl ConstantTimeLess for cmp::Ordering {
- #[inline]
- fn ct_lt(&self, other: &Self) -> Choice {
- // No impl of `ConstantTimeLess` for `i8`, so use `u8`
- let a = (*self as i8) + 1;
- let b = (*other as i8) + 1;
- (a as u8).ct_lt(&(b as u8))
- }
-}
-
-/// Wrapper type which implements an optimization barrier for all accesses.
-#[derive(Clone, Copy, Debug)]
-pub struct BlackBox<T: Copy>(T);
-
-impl<T: Copy> BlackBox<T> {
- /// Constructs a new instance of `BlackBox` which will wrap the specified value.
- ///
- /// All access to the inner value will be mediated by a `black_box` optimization barrier.
- pub fn new(value: T) -> Self {
- Self(value)
- }
-
- /// Read the inner value, applying an optimization barrier on access.
- pub fn get(self) -> T {
- black_box(self.0)
- }
-}
diff --git a/vendor/subtle/tests/mod.rs b/vendor/subtle/tests/mod.rs
deleted file mode 100644
index 888b9d0d..00000000
--- a/vendor/subtle/tests/mod.rs
+++ /dev/null
@@ -1,432 +0,0 @@
-use std::cmp;
-
-use rand::rngs::OsRng;
-use rand::RngCore;
-
-use subtle::*;
-
-#[test]
-#[should_panic]
-fn slices_equal_different_lengths() {
- let a: [u8; 3] = [0, 0, 0];
- let b: [u8; 4] = [0, 0, 0, 0];
-
- assert_eq!((&a).ct_eq(&b).unwrap_u8(), 1);
-}
-
-#[test]
-fn slices_equal() {
- let a: [u8; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
- let b: [u8; 8] = [1, 2, 3, 4, 4, 3, 2, 1];
-
- let a_eq_a = (&a).ct_eq(&a);
- let a_eq_b = (&a).ct_eq(&b);
-
- assert_eq!(a_eq_a.unwrap_u8(), 1);
- assert_eq!(a_eq_b.unwrap_u8(), 0);
-
- let c: [u8; 16] = [0u8; 16];
-
- let a_eq_c = (&a).ct_eq(&c);
- assert_eq!(a_eq_c.unwrap_u8(), 0);
-}
-
-#[test]
-fn conditional_assign_i32() {
- let mut a: i32 = 5;
- let b: i32 = 13;
-
- a.conditional_assign(&b, 0.into());
- assert_eq!(a, 5);
- a.conditional_assign(&b, 1.into());
- assert_eq!(a, 13);
-}
-
-#[test]
-fn conditional_assign_i64() {
- let mut c: i64 = 2343249123;
- let d: i64 = 8723884895;
-
- c.conditional_assign(&d, 0.into());
- assert_eq!(c, 2343249123);
- c.conditional_assign(&d, 1.into());
- assert_eq!(c, 8723884895);
-}
-
-macro_rules! generate_integer_conditional_select_tests {
- ($($t:ty)*) => ($(
- let x: $t = 0; // all 0 bits
- let y: $t = !0; // all 1 bits
-
- assert_eq!(<$t>::conditional_select(&x, &y, 0.into()), x);
- assert_eq!(<$t>::conditional_select(&x, &y, 1.into()), y);
-
- let mut z = x;
- let mut w = y;
-
- <$t>::conditional_swap(&mut z, &mut w, 0.into());
- assert_eq!(z, x);
- assert_eq!(w, y);
- <$t>::conditional_swap(&mut z, &mut w, 1.into());
- assert_eq!(z, y);
- assert_eq!(w, x);
-
- z.conditional_assign(&x, 1.into());
- w.conditional_assign(&y, 0.into());
- assert_eq!(z, x);
- assert_eq!(w, x);
- )*)
-}
-
-#[test]
-fn integer_conditional_select() {
- generate_integer_conditional_select_tests!(u8 u16 u32 u64);
- generate_integer_conditional_select_tests!(i8 i16 i32 i64);
- #[cfg(feature = "i128")]
- generate_integer_conditional_select_tests!(i128 u128);
-}
-
-#[test]
-fn custom_conditional_select_i16() {
- let x: i16 = 257;
- let y: i16 = 514;
-
- assert_eq!(i16::conditional_select(&x, &y, 0.into()), 257);
- assert_eq!(i16::conditional_select(&x, &y, 1.into()), 514);
-}
-
-#[test]
-fn ordering_conditional_select() {
- assert_eq!(
- cmp::Ordering::conditional_select(&cmp::Ordering::Less, &cmp::Ordering::Greater, 0.into()),
- cmp::Ordering::Less
- );
-
- assert_eq!(
- cmp::Ordering::conditional_select(&cmp::Ordering::Less, &cmp::Ordering::Greater, 1.into()),
- cmp::Ordering::Greater
- );
-}
-
-macro_rules! generate_integer_equal_tests {
- ($($t:ty),*) => ($(
- let y: $t = 0; // all 0 bits
- let z: $t = !0; // all 1 bits
-
- let x = z;
-
- assert_eq!(x.ct_eq(&y).unwrap_u8(), 0);
- assert_eq!(x.ct_eq(&z).unwrap_u8(), 1);
- assert_eq!(x.ct_ne(&y).unwrap_u8(), 1);
- assert_eq!(x.ct_ne(&z).unwrap_u8(), 0);
- )*)
-}
-
-#[test]
-fn integer_equal() {
- generate_integer_equal_tests!(u8, u16, u32, u64);
- generate_integer_equal_tests!(i8, i16, i32, i64);
- #[cfg(feature = "i128")]
- generate_integer_equal_tests!(i128, u128);
- generate_integer_equal_tests!(isize, usize);
-}
-
-#[test]
-fn choice_into_bool() {
- let choice_true: bool = Choice::from(1).into();
-
- assert!(choice_true);
-
- let choice_false: bool = Choice::from(0).into();
-
- assert!(!choice_false);
-}
-
-#[test]
-fn conditional_select_choice() {
- let t = Choice::from(1);
- let f = Choice::from(0);
-
- assert_eq!(bool::from(Choice::conditional_select(&t, &f, f)), true);
- assert_eq!(bool::from(Choice::conditional_select(&t, &f, t)), false);
- assert_eq!(bool::from(Choice::conditional_select(&f, &t, f)), false);
- assert_eq!(bool::from(Choice::conditional_select(&f, &t, t)), true);
-}
-
-#[test]
-fn choice_equal() {
- assert!(Choice::from(0).ct_eq(&Choice::from(0)).unwrap_u8() == 1);
- assert!(Choice::from(0).ct_eq(&Choice::from(1)).unwrap_u8() == 0);
- assert!(Choice::from(1).ct_eq(&Choice::from(0)).unwrap_u8() == 0);
- assert!(Choice::from(1).ct_eq(&Choice::from(1)).unwrap_u8() == 1);
-}
-
-#[test]
-fn ordering_equal() {
- let a = cmp::Ordering::Equal;
- let b = cmp::Ordering::Greater;
- let c = a;
-
- assert_eq!(a.ct_eq(&b).unwrap_u8(), 0);
- assert_eq!(a.ct_eq(&c).unwrap_u8(), 1);
-}
-
-#[test]
-fn test_ctoption() {
- let a = CtOption::new(10, Choice::from(1));
- let b = CtOption::new(9, Choice::from(1));
- let c = CtOption::new(10, Choice::from(0));
- let d = CtOption::new(9, Choice::from(0));
-
- // Test is_some / is_none
- assert!(bool::from(a.is_some()));
- assert!(bool::from(!a.is_none()));
- assert!(bool::from(b.is_some()));
- assert!(bool::from(!b.is_none()));
- assert!(bool::from(!c.is_some()));
- assert!(bool::from(c.is_none()));
- assert!(bool::from(!d.is_some()));
- assert!(bool::from(d.is_none()));
-
- // Test unwrap for Some
- assert_eq!(a.unwrap(), 10);
- assert_eq!(b.unwrap(), 9);
-
- // Test equality
- assert!(bool::from(a.ct_eq(&a)));
- assert!(bool::from(!a.ct_eq(&b)));
- assert!(bool::from(!a.ct_eq(&c)));
- assert!(bool::from(!a.ct_eq(&d)));
-
- // Test equality of None with different
- // dummy value
- assert!(bool::from(c.ct_eq(&d)));
-
- // Test unwrap_or
- assert_eq!(CtOption::new(1, Choice::from(1)).unwrap_or(2), 1);
- assert_eq!(CtOption::new(1, Choice::from(0)).unwrap_or(2), 2);
-
- // Test unwrap_or_else
- assert_eq!(CtOption::new(1, Choice::from(1)).unwrap_or_else(|| 2), 1);
- assert_eq!(CtOption::new(1, Choice::from(0)).unwrap_or_else(|| 2), 2);
-
- // Test map
- assert_eq!(
- CtOption::new(1, Choice::from(1))
- .map(|v| {
- assert_eq!(v, 1);
- 2
- })
- .unwrap(),
- 2
- );
- assert_eq!(
- CtOption::new(1, Choice::from(0))
- .map(|_| 2)
- .is_none()
- .unwrap_u8(),
- 1
- );
-
- // Test and_then
- assert_eq!(
- CtOption::new(1, Choice::from(1))
- .and_then(|v| {
- assert_eq!(v, 1);
- CtOption::new(2, Choice::from(0))
- })
- .is_none()
- .unwrap_u8(),
- 1
- );
- assert_eq!(
- CtOption::new(1, Choice::from(1))
- .and_then(|v| {
- assert_eq!(v, 1);
- CtOption::new(2, Choice::from(1))
- })
- .unwrap(),
- 2
- );
-
- assert_eq!(
- CtOption::new(1, Choice::from(0))
- .and_then(|_| CtOption::new(2, Choice::from(0)))
- .is_none()
- .unwrap_u8(),
- 1
- );
- assert_eq!(
- CtOption::new(1, Choice::from(0))
- .and_then(|_| CtOption::new(2, Choice::from(1)))
- .is_none()
- .unwrap_u8(),
- 1
- );
-
- // Test or_else
- assert_eq!(
- CtOption::new(1, Choice::from(0))
- .or_else(|| CtOption::new(2, Choice::from(1)))
- .unwrap(),
- 2
- );
- assert_eq!(
- CtOption::new(1, Choice::from(1))
- .or_else(|| CtOption::new(2, Choice::from(0)))
- .unwrap(),
- 1
- );
- assert_eq!(
- CtOption::new(1, Choice::from(1))
- .or_else(|| CtOption::new(2, Choice::from(1)))
- .unwrap(),
- 1
- );
- assert!(bool::from(
- CtOption::new(1, Choice::from(0))
- .or_else(|| CtOption::new(2, Choice::from(0)))
- .is_none()
- ));
-
- // Test (in)equality
- assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(1, Choice::from(1))).unwrap_u8() == 0);
- assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(1, Choice::from(0))).unwrap_u8() == 0);
- assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(2, Choice::from(1))).unwrap_u8() == 0);
- assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(2, Choice::from(0))).unwrap_u8() == 0);
- assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(1, Choice::from(0))).unwrap_u8() == 1);
- assert!(CtOption::new(1, Choice::from(0)).ct_eq(&CtOption::new(2, Choice::from(0))).unwrap_u8() == 1);
- assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(2, Choice::from(1))).unwrap_u8() == 0);
- assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(2, Choice::from(1))).unwrap_u8() == 0);
- assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(1, Choice::from(1))).unwrap_u8() == 1);
- assert!(CtOption::new(1, Choice::from(1)).ct_eq(&CtOption::new(1, Choice::from(1))).unwrap_u8() == 1);
-}
-
-#[test]
-#[should_panic]
-fn unwrap_none_ctoption() {
- // This test might fail (in release mode?) if the
- // compiler decides to optimize it away.
- CtOption::new(10, Choice::from(0)).unwrap();
-}
-
-macro_rules! generate_greater_than_test {
- ($ty: ty) => {
- for _ in 0..100 {
- let x = OsRng.next_u64() as $ty;
- let y = OsRng.next_u64() as $ty;
- let z = x.ct_gt(&y);
-
- println!("x={}, y={}, z={:?}", x, y, z);
-
- if x < y {
- assert!(z.unwrap_u8() == 0);
- } else if x == y {
- assert!(z.unwrap_u8() == 0);
- } else if x > y {
- assert!(z.unwrap_u8() == 1);
- }
- }
- }
-}
-
-#[test]
-fn greater_than_u8() {
- generate_greater_than_test!(u8);
-}
-
-#[test]
-fn greater_than_u16() {
- generate_greater_than_test!(u16);
-}
-
-#[test]
-fn greater_than_u32() {
- generate_greater_than_test!(u32);
-}
-
-#[test]
-fn greater_than_u64() {
- generate_greater_than_test!(u64);
-}
-
-#[cfg(feature = "i128")]
-#[test]
-fn greater_than_u128() {
- generate_greater_than_test!(u128);
-}
-
-#[test]
-fn greater_than_ordering() {
- assert_eq!(cmp::Ordering::Less.ct_gt(&cmp::Ordering::Greater).unwrap_u8(), 0);
- assert_eq!(cmp::Ordering::Greater.ct_gt(&cmp::Ordering::Less).unwrap_u8(), 1);
-}
-
-#[test]
-/// Test that the two's compliment min and max, i.e. 0000...0001 < 1111...1110,
-/// gives the correct result. (This fails using the bit-twiddling algorithm that
-/// go/crypto/subtle uses.)
-fn less_than_twos_compliment_minmax() {
- let z = 1u32.ct_lt(&(2u32.pow(31)-1));
-
- assert!(z.unwrap_u8() == 1);
-}
-
-macro_rules! generate_less_than_test {
- ($ty: ty) => {
- for _ in 0..100 {
- let x = OsRng.next_u64() as $ty;
- let y = OsRng.next_u64() as $ty;
- let z = x.ct_gt(&y);
-
- println!("x={}, y={}, z={:?}", x, y, z);
-
- if x < y {
- assert!(z.unwrap_u8() == 0);
- } else if x == y {
- assert!(z.unwrap_u8() == 0);
- } else if x > y {
- assert!(z.unwrap_u8() == 1);
- }
- }
- }
-}
-
-#[test]
-fn less_than_u8() {
- generate_less_than_test!(u8);
-}
-
-#[test]
-fn less_than_u16() {
- generate_less_than_test!(u16);
-}
-
-#[test]
-fn less_than_u32() {
- generate_less_than_test!(u32);
-}
-
-#[test]
-fn less_than_u64() {
- generate_less_than_test!(u64);
-}
-
-#[cfg(feature = "i128")]
-#[test]
-fn less_than_u128() {
- generate_less_than_test!(u128);
-}
-
-#[test]
-fn less_than_ordering() {
- assert_eq!(cmp::Ordering::Greater.ct_lt(&cmp::Ordering::Less).unwrap_u8(), 0);
- assert_eq!(cmp::Ordering::Less.ct_lt(&cmp::Ordering::Greater).unwrap_u8(), 1);
-}
-
-#[test]
-fn black_box_round_trip() {
- let n = 42u64;
- let black_box = BlackBox::new(n);
- assert_eq!(n, black_box.get());
-}