kyber_rs/
group.rs

1pub mod edwards25519;
2pub mod integer_field;
3mod internal;
4
5use digest::{Digest, FixedOutputReset, Reset, Update};
6use serde::de::DeserializeOwned;
7use serde::Serialize;
8use thiserror::Error;
9
10use crate::cipher::stream::Stream;
11use crate::dh::{Dh, HmacCompatible};
12use crate::encoding::Marshaling;
13use core::fmt::{Debug, Display};
14use core::ops::{Add, Mul};
15use std::io::Write;
16
17/// [`Scalar`] represents a scalar value by which
18/// a [`Point`] ([`Group`] element) may be encrypted to produce another [`Point`].
19/// This is an exponent in DSA-style groups,
20/// in which security is based on the Discrete Logarithm assumption,
21/// and a scalar multiplier in elliptic curve groups.
22pub trait Scalar:
23    Marshaling
24    + Clone
25    + Eq
26    + PartialEq
27    + Ord
28    + PartialOrd
29    + Debug
30    + Add<Self, Output = Self>
31    + Mul<Self, Output = Self>
32    + Default
33    + Serialize
34    + DeserializeOwned
35    + Display
36{
37    /// [`set()`] sets the receiver equal to another scalar `a`.
38    fn set(self, a: &Self) -> Self;
39
40    /// [`set_int64()`] sets the receiver to a small integer value.
41    fn set_int64(self, v: i64) -> Self;
42
43    /// [`zero()`] sets to the additive identity (`0`).
44    fn zero(self) -> Self;
45
46    /// [`sub()`] sets to the modular difference `a - b`.
47    fn sub(self, a: &Self, b: &Self) -> Self;
48
49    /// [`neg()`] sets to the modular negation of scalar `a`.
50    fn neg(self, a: &Self) -> Self;
51
52    /// [`one()`] sets to the multiplicative identity (`1`).
53    fn one(self) -> Self;
54
55    /// [`div()`] sets to the modular division of scalar a by scalar b.
56    fn div(self, a: &Self, b: &Self) -> Self;
57
58    /// [`inv()`] sets to the modular inverse of scalar a.
59    fn inv(self, a: &Self) -> Self;
60
61    /// [`pick()`] sets to a fresh random or pseudo-random scalar.
62    fn pick(self, rand: &mut impl Stream) -> Self;
63
64    /// [`set_bytes()`] sets the scalar from a byte-slice,
65    /// reducing if necessary to the appropriate modulus.
66    /// The endianess of the byte-slice is determined by the
67    /// implementation.
68    fn set_bytes(self, bytes: &[u8]) -> Self;
69}
70
71pub trait ScalarCanCheckCanonical {
72    fn is_canonical(&self, b: &[u8]) -> bool;
73}
74
75pub trait PointCanCheckCanonicalAndSmallOrder {
76    fn has_small_order(&self) -> bool;
77    fn is_canonical(&self, b: &[u8]) -> bool;
78}
79
80/// [`Point`] represents an element of a public-key cryptographic [`Group`].
81/// For example,
82/// this is a number modulo the prime P in a DSA-style Schnorr group,
83/// or an (x, y) point on an elliptic curve.
84/// A [`Point`] can contain a Diffie-Hellman public key, an ElGamal ciphertext, etc.
85pub trait Point:
86    Marshaling
87    + Clone
88    + Eq
89    + PartialEq
90    + Ord
91    + PartialOrd
92    + Debug
93    + Default
94    + Serialize
95    + DeserializeOwned
96    + Debug
97    + PartialEq
98    + Display
99{
100    type SCALAR: Scalar;
101
102    /// [`null()`] sets the receiver to the neutral identity element.
103    fn null(self) -> Self;
104
105    /// [`base()`] sets the receiver to this [`Group`]'s standard `base point`.
106    fn base(self) -> Self;
107
108    /// [`pick()`] sets the receiver to a fresh random or pseudo-random [`Point`].
109    fn pick<S: Stream>(self, rand: &mut S) -> Self;
110
111    /// [`set()`] sets the receiver equal to another [`Point`] `p`.
112    fn set(&mut self, p: &Self) -> Self;
113
114    /// [`embed_len()`] returns the maximum number of bytes that can be embedded in a single
115    /// group element via [`pick()`].
116    fn embed_len(&self) -> usize;
117
118    /// [`embed()`] encodes a limited amount of specified data in the
119    /// [`Point`], using `r` as a source of cryptographically secure
120    /// random data. Implementations only embed the first `embed_len`
121    /// bytes of the given data.
122    fn embed<S: Stream>(self, data: Option<&[u8]>, rand: &mut S) -> Self;
123
124    /// [`data()`] extracts data embedded in a [`Point`] chosen via [`embed()`].
125    /// Returns an [`Error`](PointError) if doesn't represent valid embedded data.
126    fn data(&self) -> Result<Vec<u8>, PointError>;
127
128    /// [`add()`] adds [`points`](Point) so that their [`scalars`](Scalar) add homomorphically.
129    fn add(self, a: &Self, b: &Self) -> Self;
130
131    /// [`sub()`] subtracts [`points`](Point) so that their [`scalars`](Scalar) subtract homomorphically.
132    fn sub(self, a: &Self, b: &Self) -> Self;
133
134    /// Set to the negation of point a.
135    fn neg(&mut self, a: &Self) -> Self;
136
137    /// [`mul()`] multiplies point `p` by the scalar `s`.
138    /// if `p == None`, multiply with the standard base point [`base()`].
139    fn mul(self, s: &Self::SCALAR, p: Option<&Self>) -> Self;
140}
141
142//TODO: fully implement var time management
143/// [`AllowsVarTime`] allows callers to determine if a given [`Scalar`]
144/// or [`Point`] supports opting-in to variable time operations. If
145/// an object implements [`AllowsVarTime`], then the caller can use
146/// [`allow_var_time(true)`] in order to allow variable time operations on
147/// that object until [`allow_var_time(false)`] is called. Variable time
148/// operations may be faster, but also risk leaking information via a
149/// timing side channel. Thus they are only safe to use on public
150/// [`scalars`](Scalar) and [`points`](Point), never on secret ones.
151pub trait AllowsVarTime {
152    // fn allow_var_time(bool);
153}
154
155/// [`Group`] interface represents a mathematical group
156/// usable for Diffie-Hellman key exchange, ElGamal encryption,
157/// and the related body of public-key cryptographic algorithms
158/// and zero-knowledge proof methods.
159/// The [`Group`] interface is designed in particular to be a generic front-end
160/// to both traditional DSA-style modular arithmetic groups
161/// and ECDSA-style elliptic curves:
162/// the caller of this interface's methods
163/// need not know or care which specific mathematical construction
164/// underlies the interface.
165///
166/// The Group interface is essentially just a "constructor" interface
167/// enabling the caller to generate the two particular types of objects
168/// relevant to DSA-style public-key cryptography;
169/// we call these objects Points and Scalars.
170/// The caller must explicitly initialize or set a new [`Point`] or [`Scalar`] object
171/// to some value before using it as an input to some other operation
172/// involving [`Point`] and/or [`Scalar`] objects.
173/// For example, to compare a point `P` against the neutral (identity) element,
174/// you might use `P.eq(suite.point().null())`,
175/// but not just `P.eq(suite.point())`.
176///
177/// It is expected that any implementation of this interface
178/// should satisfy suitable hardness assumptions for the applicable group:
179/// e.g., that it is cryptographically hard for an adversary to
180/// take an encrypted [`Point`] and the known generator it was based on,
181/// and derive the [`Scalar`] with which the [`Point`] was encrypted.
182/// Any implementation is also expected to satisfy
183/// the standard homomorphism properties that Diffie-Hellman
184/// and the associated body of public-key cryptography are based on.
185pub trait Group: Dh + Clone + Default + Debug + Display {
186    type POINT: Point;
187
188    /// [`scalar_len()`] returns the max length of scalars in bytes
189    fn scalar_len(&self) -> usize;
190
191    /// [`scalar()`] create new scalar
192    fn scalar(&self) -> <Self::POINT as Point>::SCALAR;
193
194    // [`point_len()`] returns the max length of point in bytes
195    fn point_len(&self) -> usize;
196
197    /// [`point()`] create new point
198    fn point(&self) -> Self::POINT;
199
200    /// [`is_prime_order()`] returns `Some(true)` if the group has a prime order,
201    /// if `None` is returned is assumes that the group has a prime order
202    fn is_prime_order(&self) -> Option<bool>;
203}
204
205/// A [`HashFactory`] is an interface that can be mixed in to local suite definitions.
206pub trait HashFactory {
207    type T: Hasher + HmacCompatible + Default + Update + Reset + FixedOutputReset + Clone + 'static;
208    fn hash(&self) -> Self::T {
209        Default::default()
210    }
211}
212
213pub trait Hasher: Digest + Write {}
214
215impl<T> Hasher for T
216where
217    T: Digest,
218    T: Write,
219{
220}
221
222#[derive(Error, Debug)]
223pub enum PointError {
224    #[error("invalid embedded data length")]
225    EmbedDataLength,
226}