miden_crypto/dsa/rpo_falcon512/
mod.rs

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