miden-crypto/src/dsa/rpo_falcon512/mod.rs
src/dsa/rpo_falcon512/mod.rsRaw
1use crate::{
2 hash::rpo::Rpo256,
3 utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
4 Felt, Word, ZERO,
5};
6
7mod hash_to_point;
8mod keys;
9mod math;
10mod signature;
11
12#[cfg(test)]
13mod tests;
14
15pub use self::keys::{PubKeyPoly, PublicKey, SecretKey};
16pub use self::math::Polynomial;
17pub use self::signature::{Signature, SignatureHeader, SignaturePoly};
18
19// CONSTANTS
20// ================================================================================================
21
22// The Falcon modulus p.
23const MODULUS: i16 = 12289;
24
25// Number of bits needed to encode an element in the Falcon field.
26const FALCON_ENCODING_BITS: u32 = 14;
27
28// The Falcon parameters for Falcon-512. This is the degree of the polynomial `phi := x^N + 1`
29// defining the ring Z_p[x]/(phi).
30const N: usize = 512;
31const LOG_N: u8 = 9;
32
33/// Length of nonce used for key-pair generation.
34const SIG_NONCE_LEN: usize = 40;
35
36/// Number of filed elements used to encode a nonce.
37const NONCE_ELEMENTS: usize = 8;
38
39/// Public key length as a u8 vector.
40pub const PK_LEN: usize = 897;
41
42/// Secret key length as a u8 vector.
43pub const SK_LEN: usize = 1281;
44
45/// Signature length as a u8 vector.
46const SIG_POLY_BYTE_LEN: usize = 625;
47
48/// Bound on the squared-norm of the signature.
49const SIG_L2_BOUND: u64 = 34034726;
50
51/// Standard deviation of the Gaussian over the lattice.
52const SIGMA: f64 = 165.7366171829776;
53
54/// Length of the seed for the ChaCha20-based PRNG.
55#[cfg(test)]
56pub(crate) const CHACHA_SEED_LEN: usize = 56;
57
58// TYPE ALIASES
59// ================================================================================================
60
61type ShortLatticeBasis = [Polynomial<i16>; 4];
62
63// NONCE
64// ================================================================================================
65
66/// Nonce of the Falcon signature.
67#[derive(Debug, Clone, PartialEq, Eq)]
68pub struct Nonce([u8; SIG_NONCE_LEN]);
69
70impl Nonce {
71 /// Returns a new [Nonce] instantiated from the provided bytes.
72 pub fn new(bytes: [u8; SIG_NONCE_LEN]) -> Self {
73 Self(bytes)
74 }
75
76 /// Returns the underlying bytes of this nonce.
77 pub fn as_bytes(&self) -> &[u8; SIG_NONCE_LEN] {
78 &self.0
79 }
80
81 /// Converts byte representation of the nonce into field element representation.
82 ///
83 /// Nonce bytes are converted to field elements by taking consecutive 5 byte chunks
84 /// of the nonce and interpreting them as field elements.
85 pub fn to_elements(&self) -> [Felt; NONCE_ELEMENTS] {
86 let mut buffer = [0_u8; 8];
87 let mut result = [ZERO; 8];
88 for (i, bytes) in self.0.chunks(5).enumerate() {
89 buffer[..5].copy_from_slice(bytes);
90 // we can safely (without overflow) create a new Felt from u64 value here since this
91 // value contains at most 5 bytes
92 result[i] = Felt::new(u64::from_le_bytes(buffer));
93 }
94
95 result
96 }
97}
98
99impl Serializable for &Nonce {
100 fn write_into<W: ByteWriter>(&self, target: &mut W) {
101 target.write_bytes(&self.0)
102 }
103}
104
105impl Deserializable for Nonce {
106 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
107 let bytes = source.read()?;
108 Ok(Self(bytes))
109 }
110}