Skip to content

Commit c507049

Browse files
Denis Varlakovsurvived
authored andcommitted
Implement ConditionallySelectable trait for arrays
1 parent bd282be commit c507049

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

fuzz/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,7 @@ path = "fuzzers/conditional_assign_i8.rs"
3333
[[bin]]
3434
name = "conditional_assign_i128"
3535
path = "fuzzers/conditional_assign_i128.rs"
36+
37+
[[bin]]
38+
name = "conditional_assign_array"
39+
path = "fuzzers/conditional_assign_array.rs"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#![no_main]
2+
3+
#[macro_use]
4+
extern crate libfuzzer_sys;
5+
extern crate subtle;
6+
extern crate core;
7+
8+
use core::convert::TryFrom;
9+
10+
use subtle::ConditionallySelectable;
11+
12+
fuzz_target!(|data: &[u8]| {
13+
let chunk_size: usize = 16;
14+
15+
if data.len() % chunk_size != 0 {
16+
return;
17+
}
18+
19+
for bytes in data.chunks(chunk_size) {
20+
let mut x = [0u8; 16];
21+
let y = <[u8; 16]>::try_from(bytes).unwrap();
22+
23+
x.conditional_assign(&y, 0.into());
24+
assert_eq!(x, [0u8; 16]);
25+
26+
x.conditional_assign(&y, 1.into());
27+
assert_eq!(x, y);
28+
}
29+
});

src/lib.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
//!
5656
//! ## Minimum Supported Rust Version
5757
//!
58-
//! Rust **1.41** or higher.
58+
//! Rust **1.51** or higher.
5959
//!
6060
//! Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump.
6161
//!
@@ -539,6 +539,23 @@ impl ConditionallySelectable for Choice {
539539
}
540540
}
541541

542+
impl<T, const N: usize> ConditionallySelectable for [T; N]
543+
where T: ConditionallySelectable
544+
{
545+
#[inline]
546+
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
547+
let mut output = *a;
548+
output.conditional_assign(b, choice);
549+
output
550+
}
551+
552+
fn conditional_assign(&mut self, other: &Self, choice: Choice) {
553+
for (a_i, b_i) in self.iter_mut().zip(other) {
554+
a_i.conditional_assign(b_i, choice)
555+
}
556+
}
557+
}
558+
542559
/// A type which can be conditionally negated in constant time.
543560
///
544561
/// # Note

0 commit comments

Comments
 (0)