|
79 | 79 | //! |
80 | 80 | //! This makes it possible to use `ctutils` in a codebase where other dependencies are using |
81 | 81 | //! `subtle`. |
| 82 | +//! |
| 83 | +//! # [`subtle`] migration guide |
| 84 | +//! |
| 85 | +//! This library presents an API which is largely the same shape as `subtle` and amenable to mostly |
| 86 | +//! mechanical find-and-replace updates. Using the above `subtle` interop, you can also migrate |
| 87 | +//! incrementally by converting `ctutils::Choice` <=> `subtle::Choice` and `ctutils::CtOption` |
| 88 | +//! <=> `subtle::CtOption`. |
| 89 | +//! |
| 90 | +//! The following substitutions can be used to perform the migration: |
| 91 | +//! |
| 92 | +//! 1. `subtle` => `ctutils` |
| 93 | +//! 2. `ConstantTimeEq` => `CtEq`, `ConstantTimeGreater` => `CtGt`, `ConstantTimeLess` => `CtLt`. |
| 94 | +//! - These all use the same `ct_eq`/`ct_gt`/`ct_lt` method names as `subtle` with the same type |
| 95 | +//! signatures, so only the trait names need to be changed. |
| 96 | +//! 3. `ConditionallySelectable` => `CtSelect`, `conditional_select` => `ct_select`. |
| 97 | +//! - Note that `ct_select` has a slightly different type signature in that it accepts `&self` |
| 98 | +//! as the LHS argument. This needs to be changed in the `impl` blocks, but call sites are |
| 99 | +//! compatible if you update the method name alone because it's valid "fully qualified syntax". |
| 100 | +//! Changing them from `T::conditional_select(&a, &b, choice)` => `a.ct_select(&b, choice)` |
| 101 | +//! may still be nice for brevity. |
| 102 | +//! - `conditional_assign` => `CtAssign::ct_assign`: this one will require some manual work as |
| 103 | +//! this method has been split out of `ConditionallySelectable` into its own `CtAssign` trait, |
| 104 | +//! which makes it possible to impl on DSTs like slices which can't be returned from a select |
| 105 | +//! operation because they're `!Sized`. |
| 106 | +//! 4. `ConditionallyNegatable` => `CtNeg`, `conditional_negate` => `ct_neg` |
| 107 | +//! |
| 108 | +//! ## `CtOption` notes |
| 109 | +//! |
| 110 | +//! A notable semantic change from `subtle` is combinators like `CtOption::map` no longer have a |
| 111 | +//! `Default` bound and will call the provided function with the contained value unconditionally. |
| 112 | +//! |
| 113 | +//! This means whatever value was provided at the time the `CtOption` was constructed now needs to |
| 114 | +//! uphold whatever invariants the provided function is expecting. |
| 115 | +//! |
| 116 | +//! Code which previously constructed a `CtOption` with an invalid inner value that worked with |
| 117 | +//! `subtle` because the `Default` value upheld these invariants might break when the provided |
| 118 | +//! function is now called with the invalid inner value. |
| 119 | +//! |
| 120 | +//! See also: [dalek-cryptography/subtle#63](https://github.com/dalek-cryptography/subtle/issues/63) |
82 | 121 |
|
83 | 122 | #[cfg(feature = "alloc")] |
84 | 123 | extern crate alloc; |
|
0 commit comments