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)
        }
    }
}