|
41 | 41 | //! inner `u8` by passing it through a volatile read. For more information, see
|
42 | 42 | //! the _About_ section below.
|
43 | 43 | //!
|
| 44 | +//! Rust versions from 1.66 or higher support a new best-effort optimization |
| 45 | +//! barrier ([`core::hint::black_box`]). To use the new optimization barrier, |
| 46 | +//! enable the `core_hint_black_box` feature. |
| 47 | +//! |
| 48 | +//! Rust versions from 1.51 or higher have const generics support. You may enable |
| 49 | +//! `const-generics` feautre to have `subtle` traits implemented for arrays `[T; N]`. |
| 50 | +//! |
44 | 51 | //! Versions prior to `2.2` recommended use of the `nightly` feature to enable an
|
45 | 52 | //! optimization barrier; this is not required in versions `2.2` and above.
|
46 | 53 | //!
|
|
63 | 70 | //!
|
64 | 71 | //! This library aims to be the Rust equivalent of Go’s `crypto/subtle` module.
|
65 | 72 | //!
|
66 |
| -//! The optimization barrier in `impl From<u8> for Choice` was based on Tim |
67 |
| -//! Maclean's [work on `rust-timing-shield`][rust-timing-shield], which attempts to |
68 |
| -//! provide a more comprehensive approach for preventing software side-channels in |
69 |
| -//! Rust code. |
| 73 | +//! Old versions of the optimization barrier in `impl From<u8> for Choice` were |
| 74 | +//! based on Tim Maclean's [work on `rust-timing-shield`][rust-timing-shield], |
| 75 | +//! which attempts to provide a more comprehensive approach for preventing |
| 76 | +//! software side-channels in Rust code. |
| 77 | +//! |
| 78 | +//! From version `2.2`, it was based on Diane Hosfelt and Amber Sprenkels' work on |
| 79 | +//! "Secret Types in Rust". Version `2.3` adds the `core_hint_black_box` feature, |
| 80 | +//! which uses the original method through the [`core::hint::black_box`] function |
| 81 | +//! from the Rust standard library. |
70 | 82 | //!
|
71 | 83 | //! `subtle` is authored by isis agora lovecruft and Henry de Valence.
|
72 | 84 | //!
|
|
81 | 93 | //! **USE AT YOUR OWN RISK**
|
82 | 94 | //!
|
83 | 95 | //! [docs]: https://docs.rs/subtle
|
| 96 | +//! [`core::hint::black_box`]: https://doc.rust-lang.org/core/hint/fn.black_box.html |
84 | 97 | //! [rust-timing-shield]: https://www.chosenplaintext.ca/open-source/rust-timing-shield/security
|
85 | 98 |
|
86 | 99 | #[cfg(feature = "std")]
|
@@ -565,6 +578,25 @@ impl ConditionallySelectable for Choice {
|
565 | 578 | }
|
566 | 579 | }
|
567 | 580 |
|
| 581 | +#[cfg(feature = "const-generics")] |
| 582 | +impl<T, const N: usize> ConditionallySelectable for [T; N] |
| 583 | +where |
| 584 | + T: ConditionallySelectable, |
| 585 | +{ |
| 586 | + #[inline] |
| 587 | + fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { |
| 588 | + let mut output = *a; |
| 589 | + output.conditional_assign(b, choice); |
| 590 | + output |
| 591 | + } |
| 592 | + |
| 593 | + fn conditional_assign(&mut self, other: &Self, choice: Choice) { |
| 594 | + for (a_i, b_i) in self.iter_mut().zip(other) { |
| 595 | + a_i.conditional_assign(b_i, choice) |
| 596 | + } |
| 597 | + } |
| 598 | +} |
| 599 | + |
568 | 600 | /// A type which can be conditionally negated in constant time.
|
569 | 601 | ///
|
570 | 602 | /// # Note
|
@@ -862,7 +894,7 @@ macro_rules! generate_unsigned_integer_greater {
|
862 | 894 | Choice::from((bit & 1) as u8)
|
863 | 895 | }
|
864 | 896 | }
|
865 |
| - } |
| 897 | + }; |
866 | 898 | }
|
867 | 899 |
|
868 | 900 | generate_unsigned_integer_greater!(u8, 8);
|
|
0 commit comments