secp256k1/
scalar.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Provides [`Scalar`] and related types.
4//!
5//! In elliptic curve cryptography scalars are non-point values that can be used to multiply
6//! points. The most common type of scalars are private keys. However not all scalars are private
7//! keys. They can even be public *values*. To make handling them safer and easier this module
8//! provides the `Scalar` type and related.
9//!
10
11use core::{fmt, ops};
12
13use crate::constants;
14
15/// Positive 256-bit integer guaranteed to be less than the secp256k1 curve order.
16///
17/// The difference between `PrivateKey` and `Scalar` is that `Scalar` doesn't guarantee being
18/// securely usable as a private key.
19///
20/// **Warning: the operations on this type are NOT constant time!**
21/// Using this with secret values is not advised.
22// Internal represenation is big endian to match what `libsecp256k1` uses.
23// Also easier to implement comparison.
24// Debug impl omitted for now, the bytes may be secret
25#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
26pub struct Scalar([u8; 32]);
27impl_pretty_debug!(Scalar);
28impl_non_secure_erase!(Scalar, 0, [0u8; 32]);
29
30const MAX_RAW: [u8; 32] = [
31    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
32    0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x40,
33];
34
35impl Scalar {
36    /// Scalar representing `0`
37    pub const ZERO: Scalar = Scalar(constants::ZERO);
38    /// Scalar representing `1`
39    pub const ONE: Scalar = Scalar(constants::ONE);
40    /// Maximum valid value: `curve_order - 1`
41    pub const MAX: Scalar = Scalar(MAX_RAW);
42
43    /// Generates a random scalar
44    #[cfg(feature = "rand-std")]
45    pub fn random() -> Self { Self::random_custom(rand::thread_rng()) }
46
47    /// Generates a random scalar using supplied RNG
48    #[cfg(feature = "rand")]
49    pub fn random_custom<R: rand::Rng>(mut rng: R) -> Self {
50        let mut bytes = [0u8; 32];
51        loop {
52            rng.fill_bytes(&mut bytes);
53            // unlikely to go past MAX
54            if let Ok(scalar) = Scalar::from_be_bytes(bytes) {
55                break scalar;
56            }
57        }
58    }
59
60    /// Tries to deserialize from big endian bytes
61    ///
62    /// **Security warning:** this function is not constant time!
63    /// Passing secret data is not recommended.
64    ///
65    /// # Errors
66    ///
67    /// Returns error when the value is above the curve order.
68    pub fn from_be_bytes(value: [u8; 32]) -> Result<Self, OutOfRangeError> {
69        // Lexicographic ordering of arrays of the same length is same as ordering of BE numbers
70        if value <= MAX_RAW {
71            Ok(Scalar(value))
72        } else {
73            Err(OutOfRangeError {})
74        }
75    }
76
77    /// Tries to deserialize from little endian bytes
78    ///
79    /// **Security warning:** this function is not constant time!
80    /// Passing secret data is not recommended.
81    ///
82    /// # Errors
83    ///
84    /// Returns error when the value is above the curve order.
85    pub fn from_le_bytes(mut value: [u8; 32]) -> Result<Self, OutOfRangeError> {
86        value.reverse();
87        Self::from_be_bytes(value)
88    }
89
90    /// Serializes to big endian bytes
91    pub fn to_be_bytes(self) -> [u8; 32] { self.0 }
92
93    /// Serializes to little endian bytes
94    pub fn to_le_bytes(self) -> [u8; 32] {
95        let mut res = self.0;
96        res.reverse();
97        res
98    }
99
100    // returns a reference to internal bytes
101    // non-public to not leak the internal representation
102    pub(crate) fn as_be_bytes(&self) -> &[u8; 32] { &self.0 }
103
104    pub(crate) fn as_c_ptr(&self) -> *const u8 {
105        use secp256k1_sys::CPtr;
106
107        self.as_be_bytes().as_c_ptr()
108    }
109}
110
111impl<I> ops::Index<I> for Scalar
112where
113    [u8]: ops::Index<I>,
114{
115    type Output = <[u8] as ops::Index<I>>::Output;
116
117    #[inline]
118    fn index(&self, index: I) -> &Self::Output { &self.0[index] }
119}
120
121impl From<crate::SecretKey> for Scalar {
122    fn from(value: crate::SecretKey) -> Self { Scalar(value.secret_bytes()) }
123}
124
125/// Error returned when the value of scalar is invalid - larger than the curve order.
126// Intentionally doesn't implement `Copy` to improve forward compatibility.
127// Same reason for `non_exhaustive`.
128#[allow(missing_copy_implementations)]
129#[derive(Debug, Clone, Eq, PartialEq, Hash)]
130#[non_exhaustive]
131pub struct OutOfRangeError {}
132
133impl fmt::Display for OutOfRangeError {
134    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
135        fmt::Display::fmt("the value is not a member of secp256k1 field", f)
136    }
137}
138
139#[cfg(feature = "std")]
140impl std::error::Error for OutOfRangeError {}