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, SecretPoint, 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 #[inline(always)] pub fn into_secret(self) -> NonZero<SecretPoint<E>> {
46 let mut point = self.into_inner();
47 let secret_point = SecretPoint::new(&mut point);
48 NonZero::new_unchecked(secret_point)
50 }
51}
52
53impl<E: Curve> NonZero<SecretPoint<E>> {
54 pub fn generator() -> Self {
56 Self::new_unchecked(SecretPoint::generator())
58 }
59
60 pub fn from_secret_point(point: SecretPoint<E>) -> Option<Self> {
64 Self::ct_from_secret_point(point).into()
65 }
66
67 pub fn ct_from_secret_point(secret_point: SecretPoint<E>) -> CtOption<Self> {
71 let zero = Point::zero();
72 let is_non_zero = !secret_point.as_ref().ct_eq(&zero);
73
74 CtOption::new(Self::new_unchecked(secret_point), is_non_zero)
78 }
79}
80
81impl<E: Curve> NonZero<Scalar<E>> {
82 #[doc = include_str!("../../docs/nonzero_scalar_random.md")]
83 pub fn random<R: RngCore>(rng: &mut R) -> Self {
84 match iter::repeat_with(|| {
85 let mut bytes = <<E::Scalar as FromUniformBytes>::Bytes as ByteArray>::zeroes();
86 rng.fill_bytes(bytes.as_mut());
87 <E::Scalar as FromUniformBytes>::from_uniform_bytes(&bytes)
88 })
89 .take(100)
90 .flat_map(|s| NonZero::from_scalar(Scalar::from_raw(s)))
91 .next()
92 {
93 Some(s) => s,
94 None => panic!("defected source of randomness"),
95 }
96 }
97
98 #[doc = include_str!("../../docs/nonzero_scalar_random_vartime.md")]
99 pub fn random_vartime<R: RngCore>(rng: &mut R) -> Self {
100 match iter::repeat_with(|| {
101 <E::Scalar as generic_ec_core::SamplableVartime>::random_vartime(rng)
102 })
103 .take(100)
104 .flat_map(|s| NonZero::from_scalar(Scalar::from_raw(s)))
105 .next()
106 {
107 Some(s) => s,
108 None => panic!("defected source of randomness"),
109 }
110 }
111
112 #[doc = include_str!("../../docs/hash_to_scalar.md")]
113 #[cfg(feature = "hash-to-scalar")]
135 pub fn from_hash<D: digest::Digest>(data: &impl udigest::Digestable) -> Self {
136 let mut rng = rand_hash::HashRng::<D, _>::from_seed(data);
137 Self::random(&mut rng)
138 }
139
140 pub fn one() -> Self {
142 Self::new_unchecked(Scalar::one())
144 }
145
146 pub fn from_scalar(scalar: Scalar<E>) -> Option<Self> {
150 Self::ct_from_scalar(scalar).into()
151 }
152
153 pub fn ct_from_scalar(scalar: Scalar<E>) -> CtOption<Self> {
157 let zero = Scalar::zero();
158 let is_non_zero = !scalar.ct_eq(&zero);
159
160 CtOption::new(Self::new_unchecked(scalar), is_non_zero)
164 }
165
166 pub fn invert(&self) -> NonZero<Scalar<E>> {
171 #[allow(clippy::expect_used)]
172 let inv = (**self)
173 .invert()
174 .expect("nonzero scalar always has an invert");
175 Self::new_unchecked(inv)
177 }
178
179 #[inline(always)] pub fn into_secret(self) -> NonZero<SecretScalar<E>> {
182 let mut scalar = self.into_inner();
183 let secret_scalar = SecretScalar::new(&mut scalar);
184 NonZero::new_unchecked(secret_scalar)
186 }
187}
188
189impl<E: Curve> NonZero<SecretScalar<E>> {
190 #[doc = include_str!("../../docs/nonzero_scalar_random.md")]
191 pub fn random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
192 <Self as crate::traits::Samplable>::random(rng)
193 }
194
195 #[doc = include_str!("../../docs/nonzero_scalar_random_vartime.md")]
196 pub fn random_vartime<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
197 <Self as crate::traits::Samplable>::random_vartime(rng)
198 }
199
200 pub fn one() -> Self {
202 Self::new_unchecked(SecretScalar::one())
204 }
205
206 pub fn from_secret_scalar(scalar: SecretScalar<E>) -> Option<Self> {
210 Self::ct_from_secret_scalar(scalar).into()
211 }
212
213 pub fn ct_from_secret_scalar(secret_scalar: SecretScalar<E>) -> CtOption<Self> {
217 let zero = Scalar::zero();
218 let is_non_zero = !secret_scalar.as_ref().ct_eq(&zero);
219
220 CtOption::new(Self::new_unchecked(secret_scalar), is_non_zero)
224 }
225
226 pub fn invert(&self) -> NonZero<SecretScalar<E>> {
231 #[allow(clippy::expect_used)]
232 let inv = (**self)
233 .invert()
234 .expect("nonzero scalar always has an invert");
235 Self::new_unchecked(inv)
237 }
238}
239
240impl<E: Curve> From<NonZero<Point<E>>> for Point<E> {
241 fn from(point: NonZero<Point<E>>) -> Self {
242 point.into_inner()
243 }
244}
245
246impl<E: Curve> From<NonZero<SecretPoint<E>>> for SecretPoint<E> {
247 fn from(secret_point: NonZero<SecretPoint<E>>) -> Self {
248 secret_point.into_inner()
249 }
250}
251
252impl<E: Curve> From<NonZero<Scalar<E>>> for Scalar<E> {
253 fn from(scalar: NonZero<Scalar<E>>) -> Self {
254 scalar.into_inner()
255 }
256}
257
258impl<E: Curve> From<NonZero<SecretScalar<E>>> for SecretScalar<E> {
259 fn from(secret_scalar: NonZero<SecretScalar<E>>) -> Self {
260 secret_scalar.into_inner()
261 }
262}
263
264impl<E: Curve> TryFrom<Point<E>> for NonZero<Point<E>> {
265 type Error = ZeroPoint;
266
267 fn try_from(point: Point<E>) -> Result<Self, Self::Error> {
268 Self::from_point(point).ok_or(ZeroPoint)
269 }
270}
271
272impl<E: Curve> TryFrom<SecretPoint<E>> for NonZero<SecretPoint<E>> {
273 type Error = ZeroPoint;
274
275 fn try_from(secret_point: SecretPoint<E>) -> Result<Self, Self::Error> {
276 Self::from_secret_point(secret_point).ok_or(ZeroPoint)
277 }
278}
279
280impl<E: Curve> TryFrom<Scalar<E>> for NonZero<Scalar<E>> {
281 type Error = ZeroScalar;
282
283 fn try_from(scalar: Scalar<E>) -> Result<Self, Self::Error> {
284 Self::from_scalar(scalar).ok_or(ZeroScalar)
285 }
286}
287
288impl<E: Curve> TryFrom<SecretScalar<E>> for NonZero<SecretScalar<E>> {
289 type Error = ZeroScalar;
290
291 fn try_from(secret_scalar: SecretScalar<E>) -> Result<Self, Self::Error> {
292 Self::from_secret_scalar(secret_scalar).ok_or(ZeroScalar)
293 }
294}
295
296impl<E: Curve> Sum<NonZero<Scalar<E>>> for Scalar<E> {
297 fn sum<I: Iterator<Item = NonZero<Scalar<E>>>>(iter: I) -> Self {
298 iter.fold(Scalar::zero(), |acc, x| acc + x)
299 }
300}
301
302impl<'s, E: Curve> Sum<&'s NonZero<Scalar<E>>> for Scalar<E> {
303 fn sum<I: Iterator<Item = &'s NonZero<Scalar<E>>>>(iter: I) -> Self {
304 iter.fold(Scalar::zero(), |acc, x| acc + x)
305 }
306}
307
308impl<'s, E: Curve> Sum<&'s NonZero<SecretScalar<E>>> for SecretScalar<E> {
309 fn sum<I: Iterator<Item = &'s NonZero<SecretScalar<E>>>>(iter: I) -> Self {
310 let mut out = Scalar::zero();
311 iter.for_each(|x| out += x);
312 SecretScalar::new(&mut out)
313 }
314}
315
316impl<E: Curve> Sum<NonZero<SecretScalar<E>>> for SecretScalar<E> {
317 fn sum<I: Iterator<Item = NonZero<SecretScalar<E>>>>(iter: I) -> Self {
318 let mut out = Scalar::zero();
319 iter.for_each(|x| out += x);
320 SecretScalar::new(&mut out)
321 }
322}
323
324impl<E: Curve> Product<NonZero<Scalar<E>>> for NonZero<Scalar<E>> {
325 fn product<I: Iterator<Item = NonZero<Scalar<E>>>>(iter: I) -> Self {
326 iter.fold(Self::one(), |acc, x| acc * x)
327 }
328}
329
330impl<'s, E: Curve> Product<&'s NonZero<Scalar<E>>> for NonZero<Scalar<E>> {
331 fn product<I: Iterator<Item = &'s NonZero<Scalar<E>>>>(iter: I) -> Self {
332 iter.fold(Self::one(), |acc, x| acc * x)
333 }
334}
335
336impl<'s, E: Curve> Product<&'s NonZero<SecretScalar<E>>> for NonZero<SecretScalar<E>> {
337 fn product<I: Iterator<Item = &'s NonZero<SecretScalar<E>>>>(iter: I) -> Self {
338 let mut out = NonZero::<Scalar<E>>::one();
339 iter.for_each(|x| out *= x);
340 out.into_secret()
341 }
342}
343
344impl<E: Curve> Product<NonZero<SecretScalar<E>>> for NonZero<SecretScalar<E>> {
345 fn product<I: Iterator<Item = NonZero<SecretScalar<E>>>>(iter: I) -> Self {
346 let mut out = NonZero::<Scalar<E>>::one();
347 iter.for_each(|x| out *= x);
348 out.into_secret()
349 }
350}
351
352impl<E: Curve> Sum<NonZero<Point<E>>> for Point<E> {
353 fn sum<I: Iterator<Item = NonZero<Point<E>>>>(iter: I) -> Self {
354 iter.fold(Point::zero(), |acc, x| acc + x)
355 }
356}
357impl<'s, E: Curve> Sum<&'s NonZero<Point<E>>> for Point<E> {
358 fn sum<I: Iterator<Item = &'s NonZero<Point<E>>>>(iter: I) -> Self {
359 iter.fold(Point::zero(), |acc, x| acc + x)
360 }
361}
362
363impl<E: Curve> Sum<NonZero<SecretPoint<E>>> for SecretPoint<E> {
364 fn sum<I: Iterator<Item = NonZero<SecretPoint<E>>>>(iter: I) -> Self {
365 let mut out = Point::zero();
366 iter.for_each(|x| out += x);
367 SecretPoint::new(&mut out)
368 }
369}
370impl<'s, E: Curve> Sum<&'s NonZero<SecretPoint<E>>> for SecretPoint<E> {
371 fn sum<I: Iterator<Item = &'s NonZero<SecretPoint<E>>>>(iter: I) -> Self {
372 let mut out = Point::zero();
373 iter.for_each(|x| out += x);
374 SecretPoint::new(&mut out)
375 }
376}
377
378impl<E: Curve> crate::traits::Samplable for NonZero<Scalar<E>> {
379 fn random<R: RngCore>(rng: &mut R) -> Self {
380 Self::random(rng)
381 }
382
383 fn random_vartime<R: rand_core::RngCore>(rng: &mut R) -> Self {
384 Self::random_vartime(rng)
385 }
386}
387
388impl<E: Curve> crate::traits::Samplable for NonZero<SecretScalar<E>> {
389 fn random<R: RngCore>(rng: &mut R) -> Self {
390 NonZero::<Scalar<E>>::random(rng).into_secret()
391 }
392
393 fn random_vartime<R: rand_core::RngCore>(rng: &mut R) -> Self {
394 NonZero::<Scalar<E>>::random_vartime(rng).into_secret()
395 }
396}
397
398impl<T> crate::traits::IsZero for NonZero<T> {
399 #[inline(always)]
401 fn is_zero(&self) -> bool {
402 false
403 }
404}
405
406impl<E: Curve> crate::traits::One for NonZero<Scalar<E>> {
407 fn one() -> Self {
408 Self::one()
409 }
410
411 fn is_one(x: &Self) -> subtle::Choice {
412 x.ct_eq(&Self::one())
413 }
414}
415
416impl<E: Curve> AsRef<Point<E>> for NonZero<SecretPoint<E>> {
417 fn as_ref(&self) -> &Point<E> {
418 let secret_point: &SecretPoint<E> = self.as_ref();
419 secret_point.as_ref()
420 }
421}
422
423impl<E: Curve> AsRef<Scalar<E>> for NonZero<SecretScalar<E>> {
424 fn as_ref(&self) -> &Scalar<E> {
425 let secret_scalar: &SecretScalar<E> = self.as_ref();
426 secret_scalar.as_ref()
427 }
428}
429
430impl<T> cmp::PartialEq<T> for NonZero<T>
431where
432 T: cmp::PartialEq,
433{
434 fn eq(&self, other: &T) -> bool {
435 self.as_ref() == other
436 }
437}
438
439impl<T> cmp::PartialOrd<T> for NonZero<T>
440where
441 T: cmp::PartialOrd,
442{
443 fn partial_cmp(&self, other: &T) -> Option<cmp::Ordering> {
444 self.as_ref().partial_cmp(other)
445 }
446}
447
448macro_rules! impl_reverse_partial_eq_cmp {
456 ($($t:ty),+) => {$(
457 impl<E: Curve> cmp::PartialEq<NonZero<$t>> for $t {
458 fn eq(&self, other: &NonZero<$t>) -> bool {
459 let other: &$t = other.as_ref();
460 self == other
461 }
462 }
463 impl<E: Curve> cmp::PartialOrd<NonZero<$t>> for $t {
464 fn partial_cmp(&self, other: &NonZero<$t>) -> Option<cmp::Ordering> {
465 let other: &$t = other.as_ref();
466 self.partial_cmp(other)
467 }
468 }
469 )*};
470}
471
472impl_reverse_partial_eq_cmp!(Point<E>, Scalar<E>);
475
476impl<T: ConstantTimeEq> ConstantTimeEq for NonZero<T> {
477 fn ct_eq(&self, other: &Self) -> subtle::Choice {
478 self.as_ref().ct_eq(other.as_ref())
479 }
480}
481
482#[cfg(all(test, feature = "serde"))]
483mod non_zero_is_serializable {
484 use crate::{Curve, NonZero, Point, Scalar, SecretPoint, SecretScalar};
485
486 fn impls_serde<T>()
487 where
488 T: serde::Serialize + serde::de::DeserializeOwned,
489 {
490 }
491
492 #[allow(dead_code)]
493 fn ensure_non_zero_is_serde<E: Curve>() {
494 impls_serde::<NonZero<Point<E>>>();
495 impls_serde::<NonZero<SecretPoint<E>>>();
496 impls_serde::<NonZero<Scalar<E>>>();
497 impls_serde::<NonZero<SecretScalar<E>>>();
498 }
499}