generic_ec/secret_scalar/
mod.rs

1use core::fmt;
2use core::iter::{Product, Sum};
3
4use rand_core::{CryptoRng, RngCore};
5use subtle::{Choice, ConstantTimeEq};
6
7use crate::{errors::InvalidScalar, Curve, Scalar};
8
9use self::definition::SecretScalar;
10
11pub mod definition;
12
13impl<E: Curve> SecretScalar<E> {
14    /// Returns scalar $S = 0$
15    pub fn zero() -> Self {
16        Self::new(&mut Scalar::zero())
17    }
18
19    /// Returns scalar $S = 1$
20    pub fn one() -> Self {
21        Self::new(&mut Scalar::one())
22    }
23
24    /// Returns scalar inverse
25    pub fn invert(&self) -> Option<Self> {
26        let scalar: Option<Scalar<E>> = self.as_ref().ct_invert().into();
27        Some(Self::new(&mut scalar?))
28    }
29
30    /// Generates random secret scalar
31    pub fn random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
32        let mut scalar = Scalar::random(rng);
33        Self::new(&mut scalar)
34    }
35
36    #[doc = include_str!("../../docs/hash_to_scalar.md")]
37    ///
38    /// ## Example
39    /// ```rust
40    /// use generic_ec::{SecretScalar, curves::Secp256k1};
41    /// use sha2::Sha256;
42    ///
43    /// #[derive(udigest::Digestable)]
44    /// struct Data<'a> {
45    ///     nonce: &'a [u8],
46    ///     param_a: &'a str,
47    ///     param_b: u128,
48    ///     // ...
49    /// }
50    ///
51    /// let scalar = SecretScalar::<Secp256k1>::from_hash::<Sha256>(&Data {
52    ///     nonce: b"some data",
53    ///     param_a: "some other data",
54    ///     param_b: 12345,
55    ///     // ...
56    /// });
57    /// ```
58    #[cfg(feature = "hash-to-scalar")]
59    pub fn from_hash<D: digest::Digest>(data: &impl udigest::Digestable) -> Self {
60        let mut rng = rand_hash::HashRng::<D, _>::from_seed(data);
61        Self::random(&mut rng)
62    }
63
64    /// Decodes scalar from its bytes representation in big-endian order
65    pub fn from_be_bytes(bytes: &[u8]) -> Result<Self, InvalidScalar> {
66        let mut scalar = Scalar::from_be_bytes(bytes)?;
67        Ok(Self::new(&mut scalar))
68    }
69
70    /// Decodes scalar from its bytes representation in little-endian order
71    pub fn from_le_bytes(bytes: &[u8]) -> Result<Self, InvalidScalar> {
72        let mut scalar = Scalar::from_le_bytes(bytes)?;
73        Ok(Self::new(&mut scalar))
74    }
75}
76
77impl<E: Curve> ConstantTimeEq for SecretScalar<E> {
78    fn ct_eq(&self, other: &Self) -> Choice {
79        self.as_ref().ct_eq(other.as_ref())
80    }
81}
82
83impl<E: Curve> Sum<SecretScalar<E>> for Scalar<E> {
84    fn sum<I: Iterator<Item = SecretScalar<E>>>(iter: I) -> Self {
85        iter.fold(Scalar::<E>::zero(), |acc, i| acc + &i)
86    }
87}
88
89impl<'s, E: Curve> Sum<&'s SecretScalar<E>> for Scalar<E> {
90    fn sum<I: Iterator<Item = &'s SecretScalar<E>>>(iter: I) -> Self {
91        iter.fold(Scalar::<E>::zero(), |acc, i| acc + i)
92    }
93}
94
95impl<E: Curve> Product<SecretScalar<E>> for Scalar<E> {
96    fn product<I: Iterator<Item = SecretScalar<E>>>(iter: I) -> Self {
97        iter.fold(Scalar::<E>::one(), |acc, i| acc * &i)
98    }
99}
100
101impl<'s, E: Curve> Product<&'s SecretScalar<E>> for Scalar<E> {
102    fn product<I: Iterator<Item = &'s SecretScalar<E>>>(iter: I) -> Self {
103        iter.fold(Scalar::<E>::one(), |acc, i| acc * i)
104    }
105}
106
107impl<E: Curve> fmt::Debug for SecretScalar<E> {
108    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109        f.write_str("SecretScalar")
110    }
111}
112
113impl<E: Curve> crate::traits::Samplable for SecretScalar<E> {
114    fn random<R: RngCore>(rng: &mut R) -> Self {
115        let mut scalar = Scalar::random(rng);
116        Self::new(&mut scalar)
117    }
118}