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}