subtle
subtle copied to clipboard
derive macros to extend constant-time comparisons to user-defined aggregate structs
TODO
- [ ] #98
- [ ] #99
Problem
As described in #98, the Signal client crypto implementation wants to use subtle
to filter and sort PrivateKey
structs with constant-time operations, but goes through a hacky two-step process to achieve this by first serializing the PrivateKey
struct to a byte slice (which often incurs a heap allocation for legacy reasons with the Signal code), then calling the .ct_eq()
implementation predefined for byte slices. #98 proposes a method with a lookup table to process Ordering
-like results without branching.
Solution
I'm not deeply familiar with the problem space of constant-time operations, but I saw that someone else had already worked out how to accumulate sequences of constant-time logical operations in that .ct_eq()
implementation for byte slices, so in #99 I exposed the IteratedOperation
trait and related structs for specific iterated logical comparisons.
Result
I created a proc macro crate at https://github.com/cosmicexplorer/subtle-derive. Example doctest from that crate:
use subtle::ConstantTimeOrd;
use subtle_derive::{ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, ConstEq, ConstPartialOrd, ConstOrd};
#[derive(Debug, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess, ConstEq, ConstPartialOrd, ConstOrd)]
pub struct S(pub u8);
impl ConstantTimeOrd for S {}
assert!(S(0) == S(0));
assert!(S(0) < S(1));
assert!(S(0) <= S(1));
If the current maintainers think it fits, I could instead convert my subtle-derive
crate into a PR against this repo instead (and we could hide the proc macro dependency behind a "derive"
feature flag the way serde
does: https://serde.rs/derive.html).