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::Samplable,
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 pub fn random<R: RngCore>(rng: &mut R) -> Self {
54 match iter::repeat_with(|| E::Scalar::random(rng))
55 .take(100)
56 .flat_map(|s| NonZero::from_scalar(Scalar::from_raw(s)))
57 .next()
58 {
59 Some(s) => s,
60 None => panic!("defected source of randomness"),
61 }
62 }
63
64 #[doc = include_str!("../../docs/hash_to_scalar.md")]
65 #[cfg(feature = "hash-to-scalar")]
87 pub fn from_hash<D: digest::Digest>(data: &impl udigest::Digestable) -> Self {
88 let mut rng = rand_hash::HashRng::<D, _>::from_seed(data);
89 Self::random(&mut rng)
90 }
91
92 pub fn one() -> Self {
94 Self::new_unchecked(Scalar::one())
96 }
97
98 pub fn from_scalar(scalar: Scalar<E>) -> Option<Self> {
102 Self::ct_from_scalar(scalar).into()
103 }
104
105 pub fn ct_from_scalar(scalar: Scalar<E>) -> CtOption<Self> {
109 let zero = Scalar::zero();
110 let is_non_zero = !scalar.ct_eq(&zero);
111
112 CtOption::new(Self::new_unchecked(scalar), is_non_zero)
116 }
117
118 pub fn invert(&self) -> NonZero<Scalar<E>> {
123 #[allow(clippy::expect_used)]
124 let inv = (**self)
125 .invert()
126 .expect("nonzero scalar always has an invert");
127 Self::new_unchecked(inv)
129 }
130
131 pub fn into_secret(self) -> NonZero<SecretScalar<E>> {
133 let mut scalar = self.into_inner();
134 let secret_scalar = SecretScalar::new(&mut scalar);
135 NonZero::new_unchecked(secret_scalar)
137 }
138}
139
140impl<E: Curve> NonZero<SecretScalar<E>> {
141 pub fn random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
151 <Self as crate::traits::Samplable>::random(rng)
152 }
153
154 pub fn one() -> Self {
156 Self::new_unchecked(SecretScalar::one())
158 }
159
160 pub fn from_secret_scalar(scalar: SecretScalar<E>) -> Option<Self> {
164 Self::ct_from_secret_scalar(scalar).into()
165 }
166
167 pub fn ct_from_secret_scalar(secret_scalar: SecretScalar<E>) -> CtOption<Self> {
171 let zero = Scalar::zero();
172 let is_non_zero = !secret_scalar.as_ref().ct_eq(&zero);
173
174 CtOption::new(Self::new_unchecked(secret_scalar), is_non_zero)
178 }
179
180 pub fn invert(&self) -> NonZero<SecretScalar<E>> {
185 #[allow(clippy::expect_used)]
186 let inv = (**self)
187 .invert()
188 .expect("nonzero scalar always has an invert");
189 Self::new_unchecked(inv)
191 }
192}
193
194impl<E: Curve> From<NonZero<Point<E>>> for Point<E> {
195 fn from(point: NonZero<Point<E>>) -> Self {
196 point.into_inner()
197 }
198}
199
200impl<E: Curve> From<NonZero<Scalar<E>>> for Scalar<E> {
201 fn from(scalar: NonZero<Scalar<E>>) -> Self {
202 scalar.into_inner()
203 }
204}
205
206impl<E: Curve> From<NonZero<SecretScalar<E>>> for SecretScalar<E> {
207 fn from(secret_scalar: NonZero<SecretScalar<E>>) -> Self {
208 secret_scalar.into_inner()
209 }
210}
211
212impl<E: Curve> TryFrom<Point<E>> for NonZero<Point<E>> {
213 type Error = ZeroPoint;
214
215 fn try_from(point: Point<E>) -> Result<Self, Self::Error> {
216 Self::from_point(point).ok_or(ZeroPoint)
217 }
218}
219
220impl<E: Curve> TryFrom<Scalar<E>> for NonZero<Scalar<E>> {
221 type Error = ZeroScalar;
222
223 fn try_from(scalar: Scalar<E>) -> Result<Self, Self::Error> {
224 Self::from_scalar(scalar).ok_or(ZeroScalar)
225 }
226}
227
228impl<E: Curve> TryFrom<SecretScalar<E>> for NonZero<SecretScalar<E>> {
229 type Error = ZeroScalar;
230
231 fn try_from(secret_scalar: SecretScalar<E>) -> Result<Self, Self::Error> {
232 Self::from_secret_scalar(secret_scalar).ok_or(ZeroScalar)
233 }
234}
235
236impl<E: Curve> Sum<NonZero<Scalar<E>>> for Scalar<E> {
237 fn sum<I: Iterator<Item = NonZero<Scalar<E>>>>(iter: I) -> Self {
238 iter.fold(Scalar::zero(), |acc, x| acc + x)
239 }
240}
241
242impl<'s, E: Curve> Sum<&'s NonZero<Scalar<E>>> for Scalar<E> {
243 fn sum<I: Iterator<Item = &'s NonZero<Scalar<E>>>>(iter: I) -> Self {
244 iter.fold(Scalar::zero(), |acc, x| acc + x)
245 }
246}
247
248impl<'s, E: Curve> Sum<&'s NonZero<SecretScalar<E>>> for SecretScalar<E> {
249 fn sum<I: Iterator<Item = &'s NonZero<SecretScalar<E>>>>(iter: I) -> Self {
250 let mut out = Scalar::zero();
251 iter.for_each(|x| out += x);
252 SecretScalar::new(&mut out)
253 }
254}
255
256impl<E: Curve> Sum<NonZero<SecretScalar<E>>> for SecretScalar<E> {
257 fn sum<I: Iterator<Item = NonZero<SecretScalar<E>>>>(iter: I) -> Self {
258 let mut out = Scalar::zero();
259 iter.for_each(|x| out += x);
260 SecretScalar::new(&mut out)
261 }
262}
263
264impl<E: Curve> Product<NonZero<Scalar<E>>> for NonZero<Scalar<E>> {
265 fn product<I: Iterator<Item = NonZero<Scalar<E>>>>(iter: I) -> Self {
266 iter.fold(Self::one(), |acc, x| acc * x)
267 }
268}
269
270impl<'s, E: Curve> Product<&'s NonZero<Scalar<E>>> for NonZero<Scalar<E>> {
271 fn product<I: Iterator<Item = &'s NonZero<Scalar<E>>>>(iter: I) -> Self {
272 iter.fold(Self::one(), |acc, x| acc * x)
273 }
274}
275
276impl<'s, E: Curve> Product<&'s NonZero<SecretScalar<E>>> for NonZero<SecretScalar<E>> {
277 fn product<I: Iterator<Item = &'s NonZero<SecretScalar<E>>>>(iter: I) -> Self {
278 let mut out = NonZero::<Scalar<E>>::one();
279 iter.for_each(|x| out *= x);
280 out.into_secret()
281 }
282}
283
284impl<E: Curve> Product<NonZero<SecretScalar<E>>> for NonZero<SecretScalar<E>> {
285 fn product<I: Iterator<Item = NonZero<SecretScalar<E>>>>(iter: I) -> Self {
286 let mut out = NonZero::<Scalar<E>>::one();
287 iter.for_each(|x| out *= x);
288 out.into_secret()
289 }
290}
291
292impl<E: Curve> Sum<NonZero<Point<E>>> for Point<E> {
293 fn sum<I: Iterator<Item = NonZero<Point<E>>>>(iter: I) -> Self {
294 iter.fold(Point::zero(), |acc, x| acc + x)
295 }
296}
297impl<'s, E: Curve> Sum<&'s NonZero<Point<E>>> for Point<E> {
298 fn sum<I: Iterator<Item = &'s NonZero<Point<E>>>>(iter: I) -> Self {
299 iter.fold(Point::zero(), |acc, x| acc + x)
300 }
301}
302
303impl<E: Curve> crate::traits::Samplable for NonZero<Scalar<E>> {
304 fn random<R: RngCore>(rng: &mut R) -> Self {
305 Self::random(rng)
306 }
307}
308
309impl<E: Curve> crate::traits::Samplable for NonZero<SecretScalar<E>> {
310 fn random<R: RngCore>(rng: &mut R) -> Self {
311 NonZero::<Scalar<E>>::random(rng).into_secret()
312 }
313}
314
315impl<T> crate::traits::IsZero for NonZero<T> {
316 #[inline(always)]
318 fn is_zero(&self) -> bool {
319 false
320 }
321}
322
323impl<E: Curve> crate::traits::One for NonZero<Scalar<E>> {
324 fn one() -> Self {
325 Self::one()
326 }
327
328 fn is_one(x: &Self) -> subtle::Choice {
329 x.ct_eq(&Self::one())
330 }
331}
332
333impl<E: Curve> AsRef<Scalar<E>> for NonZero<SecretScalar<E>> {
334 fn as_ref(&self) -> &Scalar<E> {
335 let secret_scalar: &SecretScalar<E> = self.as_ref();
336 secret_scalar.as_ref()
337 }
338}
339
340impl<T> cmp::PartialEq<T> for NonZero<T>
341where
342 T: cmp::PartialEq,
343{
344 fn eq(&self, other: &T) -> bool {
345 self.as_ref() == other
346 }
347}
348
349impl<T> cmp::PartialOrd<T> for NonZero<T>
350where
351 T: cmp::PartialOrd,
352{
353 fn partial_cmp(&self, other: &T) -> Option<cmp::Ordering> {
354 self.as_ref().partial_cmp(other)
355 }
356}
357
358macro_rules! impl_reverse_partial_eq_cmp {
366 ($($t:ty),+) => {$(
367 impl<E: Curve> cmp::PartialEq<NonZero<$t>> for $t {
368 fn eq(&self, other: &NonZero<$t>) -> bool {
369 let other: &$t = other.as_ref();
370 self == other
371 }
372 }
373 impl<E: Curve> cmp::PartialOrd<NonZero<$t>> for $t {
374 fn partial_cmp(&self, other: &NonZero<$t>) -> Option<cmp::Ordering> {
375 let other: &$t = other.as_ref();
376 self.partial_cmp(other)
377 }
378 }
379 )*};
380}
381
382impl_reverse_partial_eq_cmp!(Point<E>, Scalar<E>);
384
385impl<T: ConstantTimeEq> ConstantTimeEq for NonZero<T> {
386 fn ct_eq(&self, other: &Self) -> subtle::Choice {
387 self.as_ref().ct_eq(other.as_ref())
388 }
389}
390
391#[cfg(all(test, feature = "serde"))]
392mod non_zero_is_serializable {
393 use crate::{Curve, NonZero, Point, Scalar, SecretScalar};
394
395 fn impls_serde<T>()
396 where
397 T: serde::Serialize + serde::de::DeserializeOwned,
398 {
399 }
400
401 #[allow(dead_code)]
402 fn ensure_non_zero_is_serde<E: Curve>() {
403 impls_serde::<NonZero<Point<E>>>();
404 impls_serde::<NonZero<Scalar<E>>>();
405 impls_serde::<NonZero<SecretScalar<E>>>();
406 }
407}