arnaucube
arnaucube/miden-cryptoPublic Self-hosted repository
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}