1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
/// A marker trait implemented by [`Secret`] and [`Public`]. /// /// [`Scalar`s] and [`Point`s] both have a `Secrecy` type parameter which must /// be either [`Secret`] or [`Public`]. At a high level these indicate: /// /// - [`Secret`]: This value must be kept secret from parties I interact with. /// - [`Public`]: This value is known or it would not harm my security if this /// value is known to all parties I interact with. /// /// Note this consideration is only important if you do operations on the value /// during an interaction with a party. So if you would like to keep scalar `x` /// secret from party C but you only do operations on `x` while interacting with /// `B` (who perhaps, already knows it), then, in theory, `x` can be marked /// `Public`. However it is up to you to make sure these conditions hold so the /// prudent thing to do is make sure that anything that might be secret in some /// circumstance is marked [`Secret`]. /// /// [`Scalar`s] are by default [`Secret`] and [`Point`s] are by default /// [`Public`]. In order to change the default you must [`mark`] it. /// /// ``` /// use secp256kfun::{marker::*, Point, Scalar}; /// let public_scalar = Scalar::random(&mut rand::thread_rng()).mark::<Public>(); /// let secret_point = Point::random(&mut rand::thread_rng()).mark::<Secret>(); /// ``` /// /// The choice between a variable time or constant time algorithm is done /// through [_specialization_]. /// /// ``` /// use secp256kfun::{g, marker::*, Point, Scalar, G}; /// let x = Scalar::random(&mut rand::thread_rng()); /// let H = Point::random(&mut rand::thread_rng()); /// let X = g!(x * H); // This is constant time because x is secret /// let x = x.mark::<Public>(); /// let X = g!(x * H); // This will run faster (in variable time) /// ``` /// /// [`Secret`]: crate::marker::Secret /// [`Point`]: crate::marker::Public /// [`Scalar`s]: crate::Scalar /// [`Point`s]: crate::Point /// [`mark`]: crate::marker::Mark::mark /// [_specialization_]: https://github.com/rust-lang/rust/issues/31844 pub trait Secrecy: Default + Clone + PartialEq + Copy {} /// Indicates that the value is secret and therefore makes core operations /// executed on it to use _constant time_ versions of the operations. #[derive(Debug, Clone, Default, PartialEq, Copy)] #[cfg_attr( feature = "serialization", derive(serde::Serialize, serde::Deserialize) )] pub struct Secret; /// Indicates that variable time operations may be used on the value. #[derive(Debug, Clone, Default, PartialEq, Copy)] #[cfg_attr( feature = "serialization", derive(serde::Serialize, serde::Deserialize) )] pub struct Public; impl Secrecy for Secret {} impl Secrecy for Public {} mod change_marks { use super::*; use crate::{marker::ChangeMark, Point, Scalar, Slice}; impl<Z, S, SNew: Secrecy> ChangeMark<Scalar<S, Z>> for SNew { type Out = Scalar<SNew, Z>; fn change_mark(scalar: Scalar<S, Z>) -> Self::Out { Scalar::from_inner(scalar.0) } } impl<Z, S, Y, SNew: Secrecy> ChangeMark<Point<Y, S, Z>> for SNew { type Out = Point<Y, SNew, Z>; fn change_mark(point: Point<Y, S, Z>) -> Self::Out { Point::from_inner(point.0, point.1) } } impl<'a, S: Secrecy> ChangeMark<&'a [u8]> for S { type Out = Slice<'a, S>; fn change_mark(bytes: &'a [u8]) -> Self::Out { Slice::<S>::from_inner(bytes) } } impl<'a, S: Secrecy, SNew: Secrecy> ChangeMark<Slice<'a, S>> for SNew { type Out = Slice<'a, SNew>; fn change_mark(bytes: Slice<'a, S>) -> Self::Out { Slice::<SNew>::from_inner(bytes.inner) } } }