curv/elliptic/curves/wrappers/
scalar.rs

1use std::{fmt, iter};
2
3use crate::elliptic::curves::traits::{Curve, ECScalar};
4use crate::elliptic::curves::wrappers::encoded_scalar::EncodedScalar;
5use crate::elliptic::curves::{DeserializationError, ZeroScalarError};
6use crate::BigInt;
7
8/// Scalar value in a prime field
9///
10/// ## Guarantees
11///
12/// * Modulus group order
13///
14///   Denoting [group order](Self::group_order) as `n`, any instance `s` of `Scalar<E>` is guaranteed
15///   to be non-negative integer modulo `n`: `0 <= s < n`
16///
17/// ## Arithmetics
18///
19/// Supported operations:
20/// * Unary: you can [invert](Self::invert) and negate a scalar
21/// * Binary: you can add, subtract, and multiply two scalars
22///
23/// ### Example
24///
25///  ```rust
26/// # use curv::elliptic::curves::{Scalar, Secp256k1};
27/// fn expression(
28///     a: &Scalar<Secp256k1>,
29///     b: &Scalar<Secp256k1>,
30///     c: &Scalar<Secp256k1>
31/// ) -> Scalar<Secp256k1> {
32///     a + b * c
33/// }
34/// ```
35#[repr(transparent)]
36pub struct Scalar<E: Curve> {
37    raw_scalar: E::Scalar,
38}
39
40impl<E: Curve> Scalar<E> {
41    /// Ensures that `self` is not zero, returns `Err(_)` otherwise
42    pub fn ensure_nonzero(&self) -> Result<(), ZeroScalarError> {
43        if self.is_zero() {
44            Err(ZeroScalarError::new())
45        } else {
46            Ok(())
47        }
48    }
49
50    /// Samples a random nonzero scalar
51    pub fn random() -> Self {
52        loop {
53            let s = E::Scalar::random();
54            if !s.is_zero() {
55                break Scalar::from_raw(s);
56            }
57        }
58    }
59
60    /// Constructs zero scalar
61    pub fn zero() -> Self {
62        Self::from_raw(E::Scalar::zero())
63    }
64
65    /// Checks if a scalar is zero
66    pub fn is_zero(&self) -> bool {
67        self.as_raw().is_zero()
68    }
69
70    /// Converts a scalar to [BigInt]
71    pub fn to_bigint(&self) -> BigInt {
72        self.as_raw().to_bigint()
73    }
74
75    /// Constructs a scalar `n % curve_order` from given `n`
76    pub fn from_bigint(n: &BigInt) -> Self {
77        Self::from_raw(E::Scalar::from_bigint(n))
78    }
79
80    /// Serializes a scalar to bytes
81    pub fn to_bytes(&self) -> EncodedScalar<E> {
82        EncodedScalar::from(self)
83    }
84
85    /// Constructs a scalar from bytes
86    pub fn from_bytes(bytes: &[u8]) -> Result<Self, DeserializationError> {
87        ECScalar::deserialize(bytes).map(Self::from_raw)
88    }
89
90    /// Returns an order of generator point
91    pub fn group_order() -> &'static BigInt {
92        E::Scalar::group_order()
93    }
94
95    /// Returns inversion `self^-1 mod group_order`, or None if `self` is zero
96    pub fn invert(&self) -> Option<Self> {
97        self.as_raw().invert().map(Self::from_raw)
98    }
99
100    /// Constructs a `Scalar<E>` from low-level [ECScalar] implementor
101    ///
102    /// Typically, you don't need to use this constructor. See [random](Self::random),
103    /// [from_bigint](Self::from_bigint) constructors, and `From<T>`, `TryFrom<T>` traits implemented
104    /// for `Scalar<E>`.
105    ///
106    /// [ECScalar]: crate::elliptic::curves::ECScalar
107    pub fn from_raw(raw_scalar: E::Scalar) -> Self {
108        Self { raw_scalar }
109    }
110
111    /// Returns a reference to low-level scalar implementation
112    ///
113    /// Typically, you don't need to work with `ECScalar` trait directly. `Scalar<E>` wraps `ECScalar`
114    /// and provides convenient utilities around it: it implements arithmetic operators, (de)serialization
115    /// traits, etc. If you believe that some functionality is missing, please
116    /// [open an issue](https://github.com/ZenGo-X/curv).
117    pub fn as_raw(&self) -> &E::Scalar {
118        &self.raw_scalar
119    }
120
121    /// Converts a scalar into inner low-level scalar implementation
122    ///
123    /// Typically, you don't need to work with `ECScalar` trait directly. `Scalar<E>` wraps `ECScalar`
124    /// and provides convenient utilities around it: it implements arithmetic operators, (de)serialization
125    /// traits, etc. If you believe that some functionality is missing, please
126    /// [open an issue](https://github.com/ZenGo-X/curv).
127    pub fn into_raw(self) -> E::Scalar {
128        self.raw_scalar
129    }
130}
131
132impl<E: Curve> Clone for Scalar<E> {
133    fn clone(&self) -> Self {
134        Self::from_raw(self.as_raw().clone())
135    }
136}
137
138impl<E: Curve> fmt::Debug for Scalar<E> {
139    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
140        self.as_raw().fmt(f)
141    }
142}
143
144impl<E: Curve> PartialEq for Scalar<E> {
145    fn eq(&self, other: &Self) -> bool {
146        self.as_raw().eq(other.as_raw())
147    }
148}
149
150impl<E: Curve> Eq for Scalar<E> {}
151
152impl<E: Curve> From<u16> for Scalar<E> {
153    fn from(n: u16) -> Self {
154        Self::from(&BigInt::from(n))
155    }
156}
157
158impl<E: Curve> From<u32> for Scalar<E> {
159    fn from(n: u32) -> Self {
160        Self::from(&BigInt::from(n))
161    }
162}
163
164impl<E: Curve> From<u64> for Scalar<E> {
165    fn from(n: u64) -> Self {
166        Self::from(&BigInt::from(n))
167    }
168}
169
170impl<E: Curve> From<i32> for Scalar<E> {
171    fn from(n: i32) -> Self {
172        Self::from(&BigInt::from(n))
173    }
174}
175
176impl<E: Curve> From<&BigInt> for Scalar<E> {
177    fn from(n: &BigInt) -> Self {
178        Scalar::from_raw(E::Scalar::from_bigint(n))
179    }
180}
181
182impl<E: Curve> From<BigInt> for Scalar<E> {
183    fn from(n: BigInt) -> Self {
184        Self::from(&n)
185    }
186}
187
188impl<E: Curve> iter::Sum for Scalar<E> {
189    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
190        iter.fold(Scalar::zero(), |acc, s| acc + s)
191    }
192}
193
194impl<'s, E: Curve> iter::Sum<&'s Scalar<E>> for Scalar<E> {
195    fn sum<I: Iterator<Item = &'s Scalar<E>>>(iter: I) -> Self {
196        iter.fold(Scalar::zero(), |acc, s| acc + s)
197    }
198}
199
200impl<E: Curve> iter::Product for Scalar<E> {
201    fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
202        iter.fold(Scalar::from(1), |acc, s| acc * s)
203    }
204}
205
206impl<'s, E: Curve> iter::Product<&'s Scalar<E>> for Scalar<E> {
207    fn product<I: Iterator<Item = &'s Scalar<E>>>(iter: I) -> Self {
208        iter.fold(Scalar::from(1), |acc, s| acc * s)
209    }
210}