qfall-math 0.1.1

Mathematical foundations for rapid prototyping of lattice-based cryptography
Documentation
// Copyright © 2023 Marcel Luca Schmidt, Niklas Siemer
//
// This file is part of qFALL-math.
//
// qFALL-math is free software: you can redistribute it and/or modify it under
// the terms of the Mozilla Public License Version 2.0 as published by the
// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.

//! Define default values for [`Q`].

use super::Q;
use flint_sys::{fmpq::fmpq, fmpz::fmpz};

impl Default for Q {
    /// Returns an instantiation of [`Q`] with value `0/1`.
    ///
    /// # Examples
    /// ```
    /// use std::default::Default;
    /// use qfall_math::rational::Q;
    ///  
    /// let a: Q = Q::default();
    /// ```
    fn default() -> Self {
        // needs to stay a manual instantiation as try_from uses default inside
        Q {
            value: fmpq {
                num: fmpz(0),
                den: fmpz(1),
            },
        }
    }
}

impl Q {
    /// Returns an instantiation of [`Q`] with value `1`.
    ///
    /// # Examples
    /// ```
    /// use qfall_math::rational::Q;
    ///  
    /// let a: Q = Q::ONE;
    /// ```
    pub const ONE: Q = Q {
        value: fmpq {
            num: fmpz(1),
            den: fmpz(1),
        },
    };

    /// Returns an instantiation of [`Q`] with value `0`.
    ///
    /// # Examples
    /// ```
    /// use qfall_math::rational::Q;
    ///  
    /// let a: Q = Q::ZERO;
    /// ```
    pub const ZERO: Q = Q {
        value: fmpq {
            num: fmpz(0),
            den: fmpz(1),
        },
    };

    /// Returns an instantiation of [`Q`] with value `-1`.
    ///
    /// # Examples
    /// ```
    /// use qfall_math::rational::Q;
    ///  
    /// let a: Q = Q::MINUS_ONE;
    /// ```
    pub const MINUS_ONE: Q = Q {
        value: fmpq {
            num: fmpz(-1),
            den: fmpz(1),
        },
    };

    /// Returns an instantiation of [`Q`] with value `e ≈ 2.718281...`
    /// with a precision of ~ 10^-36.
    ///
    /// # Examples
    /// ```
    /// use qfall_math::rational::Q;
    ///  
    /// let a: Q = Q::E;
    /// ```
    pub const E: Q = Q {
        // generated with continued fraction (40 factors)
        value: fmpq {
            num: fmpz(2922842896378005707),
            den: fmpz(1075253811351460636),
        },
    };

    /// Returns an instantiation of [`Q`] with value `pi ≈ 3.141592...`
    /// with a precision of ~ 10^-37.
    ///
    /// # Examples
    /// ```
    /// use qfall_math::rational::Q;
    ///  
    /// let a: Q = Q::PI;
    /// ```
    pub const PI: Q = Q {
        // generated with continued fraction (33 factors)
        value: fmpq {
            num: fmpz(2646693125139304345),
            den: fmpz(842468587426513207),
        },
    };

    /// Returns an instantiation of [`Q`] with value `2^62 - 1`.
    ///
    /// # Examples
    /// ```
    /// use qfall_math::rational::Q;
    ///  
    /// let a: Q = Q::MAX62;
    /// ```
    pub const MAX62: Q = Q {
        value: fmpq {
            num: fmpz(i64::pow(2, 62) - 1),
            den: fmpz(1),
        },
    };

    /// Returns an instantiation of [`Q`] with value `1 / (2^62 - 1)`.
    ///
    /// # Examples
    /// ```
    /// use qfall_math::rational::Q;
    ///  
    /// let a: Q = Q::INV_MAX62;
    /// ```
    pub const INV_MAX62: Q = Q {
        value: fmpq {
            num: fmpz(1),
            den: fmpz(i64::pow(2, 62) - 1),
        },
    };

    /// Returns an instantiation of [`Q`] with value `2^32 - 1`.
    ///
    /// # Examples
    /// ```
    /// use qfall_math::rational::Q;
    ///  
    /// let a: Q = Q::MAX32;
    /// ```
    pub const MAX32: Q = Q {
        value: fmpq {
            num: fmpz(i64::pow(2, 32) - 1),
            den: fmpz(1),
        },
    };

    /// Returns an instantiation of [`Q`] with value `1 / (2^32 - 1)`.
    ///
    /// # Examples
    /// ```
    /// use qfall_math::rational::Q;
    ///  
    /// let a: Q = Q::INV_MAX32;
    /// ```
    pub const INV_MAX32: Q = Q {
        value: fmpq {
            num: fmpz(1),
            den: fmpz(i64::pow(2, 32) - 1),
        },
    };

    /// Returns an instantiation of [`Q`] with value `2^16 - 1`.
    ///
    /// # Examples
    /// ```
    /// use qfall_math::rational::Q;
    ///  
    /// let a: Q = Q::MAX16;
    /// ```
    pub const MAX16: Q = Q {
        value: fmpq {
            num: fmpz(i64::pow(2, 16) - 1),
            den: fmpz(1),
        },
    };

    /// Returns an instantiation of [`Q`] with value `1 / (2^16 - 1)`.
    ///
    /// # Examples
    /// ```
    /// use qfall_math::rational::Q;
    ///  
    /// let a: Q = Q::INV_MAX16;
    /// ```
    pub const INV_MAX16: Q = Q {
        value: fmpq {
            num: fmpz(1),
            den: fmpz(i64::pow(2, 16) - 1),
        },
    };

    /// Returns an instantiation of [`Q`] with value `2^8 - 1`.
    ///
    /// # Examples
    /// ```
    /// use qfall_math::rational::Q;
    ///  
    /// let a: Q = Q::MAX8;
    /// ```
    pub const MAX8: Q = Q {
        value: fmpq {
            num: fmpz(i64::pow(2, 8) - 1),
            den: fmpz(1),
        },
    };

    /// Returns an instantiation of [`Q`] with value `1 / (2^8 - 1)`.
    ///
    /// # Examples
    /// ```
    /// use qfall_math::rational::Q;
    ///  
    /// let a: Q = Q::INV_MAX8;
    /// ```
    pub const INV_MAX8: Q = Q {
        value: fmpq {
            num: fmpz(1),
            den: fmpz(i64::pow(2, 8) - 1),
        },
    };
}

#[cfg(test)]
mod tests_init {
    use super::Q;

    /// Ensure that [`Default`] initializes [`Q`] with `0`.
    #[test]
    fn init_default() {
        assert_eq!(Q::ZERO, Q::default());
    }

    /// Ensure that `ZERO` initializes [`Q`] with `0`.
    #[test]
    fn init_zero() {
        assert_eq!(Q::from(0), Q::ZERO);
    }

    /// Ensure that `ONE` initializes [`Q`] with `1`.
    #[test]
    fn init_one() {
        assert_eq!(Q::from(1), Q::ONE);
    }

    /// Ensure that `MINUS_ONE` initializes [`Q`] with `-1`.
    #[test]
    fn init_minus_one() {
        assert_eq!(Q::from(-1), Q::MINUS_ONE);
    }

    /// Ensure that `MAX62` initializes [`Q`] with `2^62 - 1`.
    #[test]
    fn init_max62() {
        assert_eq!(Q::from(i64::pow(2, 62) - 1), Q::MAX62);
    }

    /// Ensure that `INV_MAX62` initializes [`Q`] with `1 / (2^62 - 1)`.
    #[test]
    fn init_inv_max62() {
        assert_eq!(Q::from((1, i64::pow(2, 62) - 1)), Q::INV_MAX62);
    }

    /// Ensure that `MAX32` initializes [`Q`] with `2^32 - 1`.
    #[test]
    fn init_max32() {
        assert_eq!(Q::from(i64::pow(2, 32) - 1), Q::MAX32);
    }

    /// Ensure that `INV_MAX32` initializes [`Q`] with `1 / (2^32 - 1)`.
    #[test]
    fn init_inv_max32() {
        assert_eq!(Q::from((1, i64::pow(2, 32) - 1)), Q::INV_MAX32);
    }

    /// Ensure that `MAX16` initializes [`Q`] with `2^16 - 1`.
    #[test]
    fn init_max16() {
        assert_eq!(Q::from(i64::pow(2, 16) - 1), Q::MAX16);
    }

    /// Ensure that `INV_MAX16` initializes [`Q`] with `1 / (2^16 - 1)`.
    #[test]
    fn init_inv_max16() {
        assert_eq!(Q::from((1, i64::pow(2, 16) - 1)), Q::INV_MAX16);
    }

    /// Ensure that `MAX8` initializes [`Q`] with `2^8 - 1`.
    #[test]
    fn init_max8() {
        assert_eq!(Q::from(i64::pow(2, 8) - 1), Q::MAX8);
    }

    /// Ensure that `INV_MAX8` initializes [`Q`] with `1 / (2^8 - 1)`.
    #[test]
    fn init_inv_max8() {
        assert_eq!(Q::from((1, i64::pow(2, 8) - 1)), Q::INV_MAX8);
    }
}