generic_ec/
secret_scalar.rs1use core::fmt;
2use core::iter::{Product, Sum};
3
4use rand_core::{CryptoRng, RngCore};
5use subtle::{Choice, ConstantTimeEq};
6
7use crate::EncodedSecretScalar;
8use crate::{errors::InvalidScalar, secret, Curve, Scalar};
9
10pub struct SecretScalar<E: Curve>(secret::Secret<Scalar<E>>);
30
31impl<E: Curve> Scalar<E> {
32 #[inline(always)] pub fn into_secret(mut self) -> SecretScalar<E> {
36 SecretScalar::new(&mut self)
37 }
38}
39
40impl<E: Curve> SecretScalar<E> {
41 pub fn new(scalar: &mut Scalar<E>) -> Self {
47 Self(secret::new(scalar))
48 }
49
50 pub fn zero() -> Self {
52 Self::new(&mut Scalar::zero())
53 }
54
55 pub fn one() -> Self {
57 Self::new(&mut Scalar::one())
58 }
59
60 pub fn invert(&self) -> Option<Self> {
62 let scalar: Option<Scalar<E>> = self.as_ref().ct_invert().into();
63 Some(Self::new(&mut scalar?))
64 }
65
66 pub fn random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
68 let mut scalar = Scalar::random(rng);
69 Self::new(&mut scalar)
70 }
71
72 #[doc = include_str!("../docs/hash_to_scalar.md")]
73 #[cfg(feature = "hash-to-scalar")]
95 pub fn from_hash<D: digest::Digest>(data: &impl udigest::Digestable) -> Self {
96 let mut rng = rand_hash::HashRng::<D, _>::from_seed(data);
97 Self::random(&mut rng)
98 }
99
100 pub fn as_nonsecret(&self) -> &Scalar<E> {
108 secret::inner_ref(&self.0)
109 }
110
111 pub fn to_be_bytes(&self) -> EncodedSecretScalar<E> {
113 let bytes = self.as_ref().to_be_bytes();
114 EncodedSecretScalar::new(bytes)
115 }
116
117 pub fn to_le_bytes(&self) -> EncodedSecretScalar<E> {
119 let bytes = self.as_ref().to_le_bytes();
120 EncodedSecretScalar::new(bytes)
121 }
122
123 pub fn from_be_bytes(bytes: &[u8]) -> Result<Self, InvalidScalar> {
125 let mut scalar = Scalar::from_be_bytes(bytes)?;
126 Ok(Self::new(&mut scalar))
127 }
128
129 pub fn from_le_bytes(bytes: &[u8]) -> Result<Self, InvalidScalar> {
131 let mut scalar = Scalar::from_le_bytes(bytes)?;
132 Ok(Self::new(&mut scalar))
133 }
134}
135
136impl<E: Curve> AsRef<Scalar<E>> for SecretScalar<E> {
137 fn as_ref(&self) -> &Scalar<E> {
138 self.as_nonsecret()
139 }
140}
141
142impl<E: Curve> Clone for SecretScalar<E> {
143 fn clone(&self) -> Self {
144 Self(self.0.clone())
145 }
146}
147
148impl<E: Curve> ConstantTimeEq for SecretScalar<E> {
149 fn ct_eq(&self, other: &Self) -> Choice {
150 self.as_ref().ct_eq(other.as_ref())
151 }
152}
153
154impl<E: Curve> Sum<SecretScalar<E>> for Scalar<E> {
155 fn sum<I: Iterator<Item = SecretScalar<E>>>(iter: I) -> Self {
156 iter.fold(Scalar::<E>::zero(), |acc, i| acc + &i)
157 }
158}
159
160impl<'s, E: Curve> Sum<&'s SecretScalar<E>> for Scalar<E> {
161 fn sum<I: Iterator<Item = &'s SecretScalar<E>>>(iter: I) -> Self {
162 iter.fold(Scalar::<E>::zero(), |acc, i| acc + i)
163 }
164}
165
166impl<E: Curve> Product<SecretScalar<E>> for Scalar<E> {
167 fn product<I: Iterator<Item = SecretScalar<E>>>(iter: I) -> Self {
168 iter.fold(Scalar::<E>::one(), |acc, i| acc * &i)
169 }
170}
171
172impl<'s, E: Curve> Product<&'s SecretScalar<E>> for Scalar<E> {
173 fn product<I: Iterator<Item = &'s SecretScalar<E>>>(iter: I) -> Self {
174 iter.fold(Scalar::<E>::one(), |acc, i| acc * i)
175 }
176}
177
178impl<E: Curve> fmt::Debug for SecretScalar<E> {
179 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
180 f.write_str("SecretScalar")
181 }
182}
183
184impl<E: Curve> crate::traits::Samplable for SecretScalar<E> {
185 fn random<R: RngCore>(rng: &mut R) -> Self {
186 let mut scalar = Scalar::random(rng);
187 Self::new(&mut scalar)
188 }
189
190 fn random_vartime<R: rand_core::RngCore>(rng: &mut R) -> Self {
191 let mut scalar = Scalar::random_vartime(rng);
192 Self::new(&mut scalar)
193 }
194}