miden_crypto/dsa/rpo_falcon512/
mod.rs

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