generic_ec/non_zero/
mod.rs1use core::{
2 cmp,
3 iter::{self, Product, Sum},
4};
5
6use rand_core::{CryptoRng, RngCore};
7use subtle::{ConstantTimeEq, CtOption};
8
9use crate::{
10 as_raw::FromRaw,
11 core::{ByteArray, FromUniformBytes},
12 errors::{ZeroPoint, ZeroScalar},
13 Curve, Point, Scalar, SecretScalar,
14};
15
16use self::definition::NonZero;
17
18pub mod coords;
19pub mod definition;
20
21impl<E: Curve> NonZero<Point<E>> {
22 pub fn from_point(point: Point<E>) -> Option<Self> {
26 Self::ct_from_point(point).into()
27 }
28
29 pub fn ct_from_point(point: Point<E>) -> CtOption<Self> {
33 let zero = Point::zero();
34 let is_non_zero = !point.ct_eq(&zero);
35
36 CtOption::new(Self::new_unchecked(point), is_non_zero)
40 }
41}
42
43impl<E: Curve> NonZero<Scalar<E>> {
44 #[doc = include_str!("../../docs/nonzero_scalar_random.md")]
45 pub fn random<R: RngCore>(rng: &mut R) -> Self {
46 match iter::repeat_with(|| {
47 let mut bytes = <<E::Scalar as FromUniformBytes>::Bytes as ByteArray>::zeroes();
48 rng.fill_bytes(bytes.as_mut());
49 <E::Scalar as FromUniformBytes>::from_uniform_bytes(&bytes)
50 })
51 .take(100)
52 .flat_map(|s| NonZero::from_scalar(Scalar::from_raw(s)))
53 .next()
54 {
55 Some(s) => s,
56 None => panic!("defected source of randomness"),
57 }
58 }
59
60 #[doc = include_str!("../../docs/nonzero_scalar_random_vartime.md")]
61 pub fn random_vartime<R: RngCore>(rng: &mut R) -> Self {
62 match iter::repeat_with(|| {
63 <E::Scalar as generic_ec_core::SamplableVartime>::random_vartime(rng)
64 })
65 .take(100)
66 .flat_map(|s| NonZero::from_scalar(Scalar::from_raw(s)))
67 .next()
68 {
69 Some(s) => s,
70 None => panic!("defected source of randomness"),
71 }
72 }
73
74 #[doc = include_str!("../../docs/hash_to_scalar.md")]
75 #[cfg(feature = "hash-to-scalar")]
97 pub fn from_hash<D: digest::Digest>(data: &impl udigest::Digestable) -> Self {
98 let mut rng = rand_hash::HashRng::<D, _>::from_seed(data);
99 Self::random(&mut rng)
100 }
101
102 pub fn one() -> Self {
104 Self::new_unchecked(Scalar::one())
106 }
107
108 pub fn from_scalar(scalar: Scalar<E>) -> Option<Self> {
112 Self::ct_from_scalar(scalar).into()
113 }
114
115 pub fn ct_from_scalar(scalar: Scalar<E>) -> CtOption<Self> {
119 let zero = Scalar::zero();
120 let is_non_zero = !scalar.ct_eq(&zero);
121
122 CtOption::new(Self::new_unchecked(scalar), is_non_zero)
126 }
127
128 pub fn invert(&self) -> NonZero<Scalar<E>> {
133 #[allow(clippy::expect_used)]
134 let inv = (**self)
135 .invert()
136 .expect("nonzero scalar always has an invert");
137 Self::new_unchecked(inv)
139 }
140
141 pub fn into_secret(self) -> NonZero<SecretScalar<E>> {
143 let mut scalar = self.into_inner();
144 let secret_scalar = SecretScalar::new(&mut scalar);
145 NonZero::new_unchecked(secret_scalar)
147 }
148}
149
150impl<E: Curve> NonZero<SecretScalar<E>> {
151 #[doc = include_str!("../../docs/nonzero_scalar_random.md")]
152 pub fn random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
153 <Self as crate::traits::Samplable>::random(rng)
154 }
155
156 #[doc = include_str!("../../docs/nonzero_scalar_random_vartime.md")]
157 pub fn random_vartime<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
158 <Self as crate::traits::Samplable>::random_vartime(rng)
159 }
160
161 pub fn one() -> Self {
163 Self::new_unchecked(SecretScalar::one())
165 }
166
167 pub fn from_secret_scalar(scalar: SecretScalar<E>) -> Option<Self> {
171 Self::ct_from_secret_scalar(scalar).into()
172 }
173
174 pub fn ct_from_secret_scalar(secret_scalar: SecretScalar<E>) -> CtOption<Self> {
178 let zero = Scalar::zero();
179 let is_non_zero = !secret_scalar.as_ref().ct_eq(&zero);
180
181 CtOption::new(Self::new_unchecked(secret_scalar), is_non_zero)
185 }
186
187 pub fn invert(&self) -> NonZero<SecretScalar<E>> {
192 #[allow(clippy::expect_used)]
193 let inv = (**self)
194 .invert()
195 .expect("nonzero scalar always has an invert");
196 Self::new_unchecked(inv)
198 }
199}
200
201impl<E: Curve> From<NonZero<Point<E>>> for Point<E> {
202 fn from(point: NonZero<Point<E>>) -> Self {
203 point.into_inner()
204 }
205}
206
207impl<E: Curve> From<NonZero<Scalar<E>>> for Scalar<E> {
208 fn from(scalar: NonZero<Scalar<E>>) -> Self {
209 scalar.into_inner()
210 }
211}
212
213impl<E: Curve> From<NonZero<SecretScalar<E>>> for SecretScalar<E> {
214 fn from(secret_scalar: NonZero<SecretScalar<E>>) -> Self {
215 secret_scalar.into_inner()
216 }
217}
218
219impl<E: Curve> TryFrom<Point<E>> for NonZero<Point<E>> {
220 type Error = ZeroPoint;
221
222 fn try_from(point: Point<E>) -> Result<Self, Self::Error> {
223 Self::from_point(point).ok_or(ZeroPoint)
224 }
225}
226
227impl<E: Curve> TryFrom<Scalar<E>> for NonZero<Scalar<E>> {
228 type Error = ZeroScalar;
229
230 fn try_from(scalar: Scalar<E>) -> Result<Self, Self::Error> {
231 Self::from_scalar(scalar).ok_or(ZeroScalar)
232 }
233}
234
235impl<E: Curve> TryFrom<SecretScalar<E>> for NonZero<SecretScalar<E>> {
236 type Error = ZeroScalar;
237
238 fn try_from(secret_scalar: SecretScalar<E>) -> Result<Self, Self::Error> {
239 Self::from_secret_scalar(secret_scalar).ok_or(ZeroScalar)
240 }
241}
242
243impl<E: Curve> Sum<NonZero<Scalar<E>>> for Scalar<E> {
244 fn sum<I: Iterator<Item = NonZero<Scalar<E>>>>(iter: I) -> Self {
245 iter.fold(Scalar::zero(), |acc, x| acc + x)
246 }
247}
248
249impl<'s, E: Curve> Sum<&'s NonZero<Scalar<E>>> for Scalar<E> {
250 fn sum<I: Iterator<Item = &'s NonZero<Scalar<E>>>>(iter: I) -> Self {
251 iter.fold(Scalar::zero(), |acc, x| acc + x)
252 }
253}
254
255impl<'s, E: Curve> Sum<&'s NonZero<SecretScalar<E>>> for SecretScalar<E> {
256 fn sum<I: Iterator<Item = &'s NonZero<SecretScalar<E>>>>(iter: I) -> Self {
257 let mut out = Scalar::zero();
258 iter.for_each(|x| out += x);
259 SecretScalar::new(&mut out)
260 }
261}
262
263impl<E: Curve> Sum<NonZero<SecretScalar<E>>> for SecretScalar<E> {
264 fn sum<I: Iterator<Item = NonZero<SecretScalar<E>>>>(iter: I) -> Self {
265 let mut out = Scalar::zero();
266 iter.for_each(|x| out += x);
267 SecretScalar::new(&mut out)
268 }
269}
270
271impl<E: Curve> Product<NonZero<Scalar<E>>> for NonZero<Scalar<E>> {
272 fn product<I: Iterator<Item = NonZero<Scalar<E>>>>(iter: I) -> Self {
273 iter.fold(Self::one(), |acc, x| acc * x)
274 }
275}
276
277impl<'s, E: Curve> Product<&'s NonZero<Scalar<E>>> for NonZero<Scalar<E>> {
278 fn product<I: Iterator<Item = &'s NonZero<Scalar<E>>>>(iter: I) -> Self {
279 iter.fold(Self::one(), |acc, x| acc * x)
280 }
281}
282
283impl<'s, E: Curve> Product<&'s NonZero<SecretScalar<E>>> for NonZero<SecretScalar<E>> {
284 fn product<I: Iterator<Item = &'s NonZero<SecretScalar<E>>>>(iter: I) -> Self {
285 let mut out = NonZero::<Scalar<E>>::one();
286 iter.for_each(|x| out *= x);
287 out.into_secret()
288 }
289}
290
291impl<E: Curve> Product<NonZero<SecretScalar<E>>> for NonZero<SecretScalar<E>> {
292 fn product<I: Iterator<Item = NonZero<SecretScalar<E>>>>(iter: I) -> Self {
293 let mut out = NonZero::<Scalar<E>>::one();
294 iter.for_each(|x| out *= x);
295 out.into_secret()
296 }
297}
298
299impl<E: Curve> Sum<NonZero<Point<E>>> for Point<E> {
300 fn sum<I: Iterator<Item = NonZero<Point<E>>>>(iter: I) -> Self {
301 iter.fold(Point::zero(), |acc, x| acc + x)
302 }
303}
304impl<'s, E: Curve> Sum<&'s NonZero<Point<E>>> for Point<E> {
305 fn sum<I: Iterator<Item = &'s NonZero<Point<E>>>>(iter: I) -> Self {
306 iter.fold(Point::zero(), |acc, x| acc + x)
307 }
308}
309
310impl<E: Curve> crate::traits::Samplable for NonZero<Scalar<E>> {
311 fn random<R: RngCore>(rng: &mut R) -> Self {
312 Self::random(rng)
313 }
314
315 fn random_vartime<R: rand_core::RngCore>(rng: &mut R) -> Self {
316 Self::random_vartime(rng)
317 }
318}
319
320impl<E: Curve> crate::traits::Samplable for NonZero<SecretScalar<E>> {
321 fn random<R: RngCore>(rng: &mut R) -> Self {
322 NonZero::<Scalar<E>>::random(rng).into_secret()
323 }
324
325 fn random_vartime<R: rand_core::RngCore>(rng: &mut R) -> Self {
326 NonZero::<Scalar<E>>::random_vartime(rng).into_secret()
327 }
328}
329
330impl<T> crate::traits::IsZero for NonZero<T> {
331 #[inline(always)]
333 fn is_zero(&self) -> bool {
334 false
335 }
336}
337
338impl<E: Curve> crate::traits::One for NonZero<Scalar<E>> {
339 fn one() -> Self {
340 Self::one()
341 }
342
343 fn is_one(x: &Self) -> subtle::Choice {
344 x.ct_eq(&Self::one())
345 }
346}
347
348impl<E: Curve> AsRef<Scalar<E>> for NonZero<SecretScalar<E>> {
349 fn as_ref(&self) -> &Scalar<E> {
350 let secret_scalar: &SecretScalar<E> = self.as_ref();
351 secret_scalar.as_ref()
352 }
353}
354
355impl<T> cmp::PartialEq<T> for NonZero<T>
356where
357 T: cmp::PartialEq,
358{
359 fn eq(&self, other: &T) -> bool {
360 self.as_ref() == other
361 }
362}
363
364impl<T> cmp::PartialOrd<T> for NonZero<T>
365where
366 T: cmp::PartialOrd,
367{
368 fn partial_cmp(&self, other: &T) -> Option<cmp::Ordering> {
369 self.as_ref().partial_cmp(other)
370 }
371}
372
373macro_rules! impl_reverse_partial_eq_cmp {
381 ($($t:ty),+) => {$(
382 impl<E: Curve> cmp::PartialEq<NonZero<$t>> for $t {
383 fn eq(&self, other: &NonZero<$t>) -> bool {
384 let other: &$t = other.as_ref();
385 self == other
386 }
387 }
388 impl<E: Curve> cmp::PartialOrd<NonZero<$t>> for $t {
389 fn partial_cmp(&self, other: &NonZero<$t>) -> Option<cmp::Ordering> {
390 let other: &$t = other.as_ref();
391 self.partial_cmp(other)
392 }
393 }
394 )*};
395}
396
397impl_reverse_partial_eq_cmp!(Point<E>, Scalar<E>);
399
400impl<T: ConstantTimeEq> ConstantTimeEq for NonZero<T> {
401 fn ct_eq(&self, other: &Self) -> subtle::Choice {
402 self.as_ref().ct_eq(other.as_ref())
403 }
404}
405
406#[cfg(all(test, feature = "serde"))]
407mod non_zero_is_serializable {
408 use crate::{Curve, NonZero, Point, Scalar, SecretScalar};
409
410 fn impls_serde<T>()
411 where
412 T: serde::Serialize + serde::de::DeserializeOwned,
413 {
414 }
415
416 #[allow(dead_code)]
417 fn ensure_non_zero_is_serde<E: Curve>() {
418 impls_serde::<NonZero<Point<E>>>();
419 impls_serde::<NonZero<Scalar<E>>>();
420 impls_serde::<NonZero<SecretScalar<E>>>();
421 }
422}