diff --git a/Cargo.toml b/Cargo.toml index 70cb4805..1e78c1b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,22 +1,28 @@ [package] name = "qfall-math" version = "0.1.0" -edition = "2021" +edition = "2024" +rust-version = "1.85" # due to rand and rand_distr dependency +description = "Prototyping Library for Lattice-Based Cryptography" +readme = "README.md" +homepage = "https://qfall.github.io" +repository = "https://github.com/qfall/math" +license = "MPL-2.0" +keywords = ["math", "prototype", "lattice", "cryptography"] +categories = ["cryptography", "mathematics", "development-tools::build-utils", "development-tools::testing", "development-tools::profiling"] autobenches = false -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] -criterion = { version = "0.7", features = ["html_reports"] } +criterion = { version = "0.8", features = ["html_reports"] } flint-sys = "0.7.3" libc = "0.2" paste = "1.0" -rand = "0.9.0" -rand_distr = "0.5.0" +rand = "0.9" +rand_distr = "0.5" regex = "1" serde = {version="1.0", features=["derive"]} serde_json = "1.0" -string-builder = "0.2.0" +string-builder = "0.2" thiserror = "2.0" lazy_static = "1.4" probability = "0.20.3" diff --git a/README.md b/README.md index ac6618bc..b6d71948 100644 --- a/README.md +++ b/README.md @@ -1,128 +1,106 @@ # qFALL-math +[github](https://github.com/qfall/math) +[crates.io](https://crates.io/crates/qfall-math) +[docs.rs](https://docs.rs/qfall-math) +[tutorial](https://qfall.github.io/book) +[build](https://github.com/qfall/math/actions/workflows/push.yml) +[license](https://github.com/qfall/math/blob/dev/LICENSE) -[![made-with-rust](https://img.shields.io/badge/Made%20with-Rust-1f425f.svg)](https://www.rust-lang.org/) -[![CI](https://github.com/qfall/math/actions/workflows/push.yml/badge.svg?branch=dev)](https://github.com/qfall/math/actions/workflows/pull_request.yml) -[![License: MPL 2.0](https://img.shields.io/badge/License-MPL_2.0-brightgreen.svg)](https://opensource.org/licenses/MPL-2.0) - -This repository is currently being developed by the project group [qFALL - quantum resistant fast lattice library](https://cs.uni-paderborn.de/cuk/lehre/veranstaltungen/ws-2022-23/project-group-qfall) in the winter term 2022 and summer term 2023 by the Codes and Cryptography research group in Paderborn. - -The main objective of this project is to develop a memory-safe and efficient usage of -[FLINT](https://flintlib.org/) in [Rust](https://www.rust-lang.org/). Its main purpose -is to use this library as a building block to build other projects on top of it. - -## Disclaimer - -Currently, we are in the development phase and interfaces might change. -Feel free to check out the current progress, but be aware, that the content will -change in the upcoming weeks and months. An official release will most likely be published in the second half of 2024. +`qFALL` is a prototyping library for lattice-based constructions. +This `math`-crate is a memory-safe wrapper of [FLINT](https://flintlib.org/) in Rust, which provides several additional features often used in lattice-based cryptography. This crate is the foundation of the [qFALL project](https://qfall.github.io) containing further crates for prototyping of lattice-based cryptography. ## Quick-Start +First, ensure that you use a Unix-like distribution (Linux or MacOS). Setup [WSL](https://learn.microsoft.com/en-us/windows/wsl/install) if you're using Windows. This is required due to this crate's dependency on FLINT. +Then, make sure your `rustc --version` is `1.85` or newer. -Please refer to [our website](https://qfall.github.io/) as a central information point. - -To install and add our library to your project, please refer to [our tutorial](https://qfall.github.io/book/index.html). -It provides a step-by-step guide to install the required libraries and gives further insights into the usage of our crates. - -## What does qFALL-math offer? - -Extensive documentation can be generated using - +Furthermore, it's required that `m4`, a C-compiler such as `gcc`, and `make` are installed. ```bash -cargo doc # suffix with --open to directly open the documentation +sudo apt-get install m4 gcc make ``` - -once the project is cloned. Following, there is a small overview containing the general types of our library [qFALL-math](https://github.com/qfall/math). - +Then, add you can add this crate to your project by executing the following command. ```bash -math -├── ... -├── src -│ ├── integer # src folder containing implementations of integers -│ ├── integer_mod_q # src folder containing implementations of integers -│ │ # for which a certain modulus is applied -│ └── rational # src folder containing implementations of rationals -└── ... +cargo add qfall-math ``` +- Find further information on [our website](https://qfall.github.io/). Also check out [`qfall-tools`](https://github.com/qfall/tools) and [`qfall-schemes`](https://github.com/qfall/schemes). +- Read the [documentation of this crate](https://docs.rs/qfall-math). +- We recommend [our tutorial](https://qfall.github.io/book) to start working with qFALL. -### Integers - -- [`Z`](https://github.com/qfall/math/blob/dev/src/integer/z.rs): Represents $\mathbb Z$. -- [`MatZ`](https://github.com/qfall/math/blob/dev/src/integer/mat_z.rs): Represents matrices of $\mathbb Z$. -- [`PolyOverZ`](https://github.com/qfall/math/blob/dev/src/integer/poly_over_z.rs): Represents polynomials with coefficients over $\mathbb Z$. -- [`MatPolyOverZ`](https://github.com/qfall/math/blob/dev/src/integer/mat_poly_over_z.rs): Represents matrices of polynomials with coefficients over $\mathbb Z$. - -```rust -use qfall_math::integer::Z; +## What does qFALL-math offer? +We would like to point out a few supported features which are specifically important for lattice-based cryptography. +- Uniform, discrete Gaussian, and binomial sampling +- Support of several norms +- Solving systems of linear equations +- Support of the Number-Theoretic Transform (NTT) -let a = Z::from(24); -let b = Z::from(42); +Furthermore, this crate simplifies the implementation of your prototype by supporting a wide range of functions such as tensor multiplication, serialisation, matrix concatenations and many more. +Arithmetic operations, comparisons, and conversions are supported across several types. You can find all supported data-types below. -let res_add: Z = &a + &b; -let res_sub: Z = a - 10; -let res_mul: Z = 3 * b; -``` +### Integers +- [`Z`](https://docs.rs/qfall-math/latest/qfall_math/integer/struct.Z.html): Represents $\mathbb Z$. +- [`MatZ`](https://docs.rs/qfall-math/latest/qfall_math/integer/struct.MatZ.html): Represents matrices over $\mathbb Z$. +- [`PolyOverZ`](https://docs.rs/qfall-math/latest/qfall_math/integer/struct.PolyOverZ.html): Represents polynomials with coefficients over $\mathbb Z$. +- [`MatPolyOverZ`](https://docs.rs/qfall-math/latest/qfall_math/integer/struct.MatPolyOverZ.html): Represents matrices of polynomials with coefficients over $\mathbb Z$. ### Integers mod q +- [`Zq`](https://docs.rs/qfall-math/latest/qfall_math/integer_mod_q/struct.Zq.html): Represents $\mathbb Z_q$. +- [`MatZq`](https://docs.rs/qfall-math/latest/qfall_math/integer_mod_q/struct.MatZq.html): Represents matrices over $\mathbb Z_q$. +- [`PolyOverZq`](https://docs.rs/qfall-math/latest/qfall_math/integer_mod_q/struct.PolyOverZq.html): Represents polynomials with coefficients over $\mathbb Z_q$. +- [`PolynomialRingZq`](https://docs.rs/qfall-math/latest/qfall_math/integer_mod_q/struct.PolynomialRingZq.html): Represents quotient rings $\mathbb Z_q[X]/f(X)$. +- [`MatPolynomialRingZq`](https://docs.rs/qfall-math/latest/qfall_math/integer_mod_q/struct.MatPolynomialRingZq.html): Represents matrices over quotient rings $\mathbb Z_q[X]/f(X)$. +- [`NTTPolynomialRingZq`](https://docs.rs/qfall-math/latest/qfall_math/integer_mod_q/struct.NTTPolynomialRingZq.html): Represents quotient rings $\mathbb Z_q[X]/f(X)$ in NTT form. +- [`MatNTTPolynomialRingZq`](https://docs.rs/qfall-math/latest/qfall_math/integer_mod_q/struct.MatNTTPolynomialRingZq.html): Represents matrices over quotient rings $\mathbb Z_q[X]/f(X)$ in NTT form. -- [`Zq`](https://github.com/qfall/math/blob/dev/src/integer_mod_q/zq.rs): Represents $\mathbb Z_q$. -- [`MatZq`](https://github.com/qfall/math/blob/dev/src/integer_mod_q/mat_zq.rs): Represents matrices of $\mathbb Z_q$. -- [`PolyOverZq`](https://github.com/qfall/math/blob/dev/src/integer_mod_q/poly_over_zq.rs): Represents polynomials with coefficients over $\mathbb Z_q$. -- [`PolynomialRingZq`](https://github.com/qfall/math/blob/dev/src/integer_mod_q/polynomial_ring_zq.rs): Represents quotient rings of $\mathbb Z_q[X]/f(X)$ where $q$ is an integer modulus and $f(X)$ is a [`PolyOverZq`](https://github.com/qfall/math/blob/dev/src/integer_mod_q/poly_over_zq.rs). -- [`MatPolynomialRingZq`](https://github.com/qfall/math/blob/dev/src/integer_mod_q/mat_polynomial_ring_zq.rs): Represents matrices of quotient rings of $\mathbb Z_q[X]/f(X)$ where $q$ is an integer modulus and $f(X)$ is a [`PolyOverZq`](https://github.com/qfall/math/blob/dev/src/integer_mod_q/poly_over_zq.rs). +### Rationals +- [`Q`](https://docs.rs/qfall-math/latest/qfall_math/rational/struct.Q.html): Represents $\mathbb Q$. +- [`MatQ`](https://docs.rs/qfall-math/latest/qfall_math/rational/struct.MatQ.html): Represents matrices over $\mathbb Q$. +- [`PolyOverQ`](https://docs.rs/qfall-math/latest/qfall_math/rational/struct.PolyOverQ.html): Represents polynomials with coefficients over $\mathbb Q$. +## Quick Example ```rust -use qfall_math::integer_mod_q::Zq; -use qfall_math::integer_mod_q::Modulus; +use qfall_math::{integer_mod_q::MatZq, integer::MatZ}; -let modulus = Modulus::from(24); -let a = Zq::from((42, &modulus)); -let b = Zq::from((17, &modulus)); +let (n, m, q) = (256, 1024, 3329); +let (center, sigma) = (0.0, 8.0); -let res_add: Zq = &a + &b; -let res_sub: Zq = a - 10; -let res_mul: Zq = 3 * b; -``` - -### Rationals +let mat_a = MatZq::sample_uniform(n, m, q); +let vec_s = MatZ::sample_uniform(n, 1, 0, 2).unwrap(); +let vec_e = MatZ::sample_discrete_gauss(m, 1, center, sigma).unwrap(); -- [`Q`](https://github.com/qfall/math/blob/dev/src/rational/q.rs): Represents $\mathbb Q$. -- [`MatQ`](https://github.com/qfall/math/blob/dev/src/rational/mat.rs): Represents matrices of $\mathbb Q$. -- [`PolyOverQ`](https://github.com/qfall/math/blob/dev/src/rational/poly_over_q.rs): Represents polynomials with coefficients over $\mathbb Q$. +// SIS-Instance: t = A * e mod q +let vec_t = &mat_a * &vec_e; -```rust -use qfall_math::rational::Q; - -let a = Q::from((17, 19)); -let b = Q::from(0.5); - -let res_add: Q = &a + &b; -let res_sub: Q = a - 10.5; -let res_mul: Q = 3 * b; +// LWE-Instance: b^T = s^T * A + e^T mod q +let vec_b = vec_s.transpose() * mat_a + vec_e.transpose(); ``` -## External Libraries +## Bugs +Please report bugs through the [GitHub issue tracker](https://github.com/qfall/math/issues). -This project uses the C-based, optimized math library [FLINT](https://flintlib.org/). To use a C-library in Rust, there has to be an FFI (Foreign Function Interface) which allows to call the methods from [FLINT](https://flintlib.org/) in Rust. This project uses the crate [flint-sys](https://github.com/alex-ozdemir/flint-rs/tree/master/flint-sys) as a binding for [FLINT](https://flintlib.org/). -Furthermore, we utilized [serde](https://crates.io/crates/serde) and [serde_json](https://crates.io/crates/serde_json) to (de-)serialize objects to and from JSON. Last, but not least, our sampling algorithms heavily rely on the [rand-crate](https://crates.io/crates/rand). An extensive list can be found in our `Cargo.toml` file. - -## License +## Contributions +Contributors are: +- Marvin Beckmann +- Phil Milewski +- Sven Moog +- Marcel Luca Schmidt +- Jan Niklas Siemer -This library is distributed under the **Mozilla Public License Version 2.0** which can be found here [License](https://github.com/qfall/math/blob/dev/LICENSE). -Permissions of this weak copyleft license are conditioned on making available the source code of licensed files and modifications of those files under the same license (or in certain cases, one of the GNU licenses). Copyright and license notices must be preserved. Contributors provide an express grant of patent rights. However, a larger work using the licensed work may be distributed under different terms and without source code for files added to the larger work. +See [Contributing](https://github.com/qfall/math/blob/dev/CONTRIBUTING.md) for details on how to contribute. ## Citing -Please use the following bibtex entry to cite [qFALL-math](https://github.com/qfall/math): +Please use the following bibtex entry to cite [qFALL](https://qfall.github.io). ```text -@software{Porzenheim_qFALL-math, - author = {Porzenheim, Laurens and Beckmann, Marvin and Kramer, Paul and Milewski, Phil and Moog, Sven and Schmidt, Marcel and Siemer, Niklas}, - license = {MPL-2.0}, - title = {{qFALL-math}}, - url = {https://github.com/qfall/math} -} +TODO: Update to eprint ``` -## Get in Touch +## Dependencies +This project uses the C-based, optimized math-library [FLINT](https://flintlib.org/). We tested our use of FLINT extensively to ensure that you can not introduce memory-leaks by using our library. +If you need a function supported by FLINT that is not supported by this crate, we have created an `unsafe` passthrough to access and operate on FLINT's structs directly. + +Furthermore, we utilized [serde](https://crates.io/crates/serde) and [serde_json](https://crates.io/crates/serde_json) to (de-)serialize objects to and from JSON. Last, but not least, our sampling algorithms use the [rand](https://crates.io/crates/rand)-crate to generate uniformly random bits. An extensive list can be found in our `Cargo.toml` file. + +## License -To contact us, please refer to our mailing list `pg-qfall(at)lists.upb.de`. +This library is distributed under the [Mozilla Public License Version 2.0](https://github.com/qfall/math/blob/dev/LICENSE). +Permissions of this weak copyleft license are conditioned on making the source code of licensed files and modifications of those files available under the same license (or in certain cases, under one of the GNU licenses). Copyright and license notices must be preserved. Contributors provide an express grant of patent rights. However, a larger work using the licensed work may be distributed under different terms and without source code for files added to the larger work. diff --git a/benches/classic_crypto.rs b/benches/classic_crypto.rs index 7a47a5ae..b5bfc427 100644 --- a/benches/classic_crypto.rs +++ b/benches/classic_crypto.rs @@ -15,7 +15,7 @@ use qfall_math::{ traits::*, }; -/// This was previously generated by [`gen_prime_order_group_plus_generator`] +/// This was previously generated by [`generate_prime_order_group_plus_generator`] /// with a 1024 bit security level and is a generator of a prime order group given /// by its modulus. const GEN_PRIME_ORDER_GROUP: &str = "6699169310659235470225047447246035339577556238993322352393397681703675533291305168752108540160627484197919777651312939723365761438699736642357805668125639 mod 18400681887370733277111033107635204264308519065621966282426615876457082834857578485285974739251754512147175264691046473507777607318533584903054155533044823"; @@ -33,7 +33,7 @@ fn sample_prime_naive(lower_bound: &Z, upper_bound: &Z) -> Z { } /// Generates a prime [`Modulus`] (i.e. a prime order group) and a `generator` for that group. -pub fn gen_prime_order_group_plus_generator(security_lvl: u32) -> (Modulus, Zq) { +pub fn generate_prime_order_group_plus_generator(security_lvl: u32) -> (Modulus, Zq) { let two = Z::from(2); let lower_bound = two.pow(security_lvl / 2).unwrap(); let upper_bound = two.pow(security_lvl / 2 + 1).unwrap(); @@ -80,7 +80,7 @@ mod rsa_textbook { }; use std::str::FromStr; - /// These constants were previously generated by [`rsa_textbook::gen(1024)`] + /// These constants were previously generated by [`rsa_textbook::generate(1024)`] const RSA_N: &str = "432529019456174073628056731021899753880199292843627050477235451320968504136109996834942250928981978445989472551473247465106240932979604095669286519963140687101286153803154189345553920544182137022020540002491541180583190915417665399496578760830730904289091934652022809043462927391234535724121396575445021309223"; const RSA_PK: &str = "272636431233265956354044639799116206612921445708076864293675274944980833816969100954445036939076331379279263791466802764599215907676388073791876743514004914016502795361305034353643235925659883900363706630095745283005183368525178846360740971098036527594113502421475552957731655910068081721705039500289221854513"; @@ -99,7 +99,7 @@ mod rsa_textbook { /// efficient with this key, has sufficient size, and guarantees to have an inverse). /// 5. Calculate `sk = pk^(-1) mod phi(N)`. /// 6. Output `(N, pk, sk)`. - pub fn gen(security_lvl: u32) -> (Modulus, Z, Z) { + pub fn generate(security_lvl: u32) -> (Modulus, Z, Z) { let lower_bound = Z::from(2).pow(security_lvl / 2).unwrap(); let upper_bound = Z::from(2).pow(security_lvl / 2 + 1).unwrap(); @@ -124,8 +124,8 @@ mod rsa_textbook { (modulus, pk, sk) } - /// Returns a pre-computed RSA key pair that was computed with `gen(1024)`. - pub fn static_gen() -> (Modulus, Z, Z) { + /// Returns a pre-computed RSA key pair that was computed with `generate(1024)`. + pub fn static_generate() -> (Modulus, Z, Z) { let modulus = Modulus::from_str(RSA_N).unwrap(); let pk = Z::from(65537); let sk = Z::from_str(RSA_PK).unwrap(); @@ -151,11 +151,11 @@ mod rsa_textbook { } /// Run textbook RSA encryption with 1024 bit security. - /// 1. get (N, pk, sk) from a previously generated key pair with `gen(1024)` + /// 1. get (N, pk, sk) from a previously generated key pair with `generate(1024)` /// 2. run cycle of `dec(sk, enc(pk, msg)) == msg`, /// where `msg` is sampled uniformly at random in `[0, u64::MAX)` pub fn rsa_run_enc_dec() { - let (modulus, pk, sk) = static_gen(); + let (modulus, pk, sk) = static_generate(); let msg = Z::sample_uniform(0, u64::MAX).unwrap(); let cipher = enc(&modulus, &pk, &msg); @@ -169,9 +169,9 @@ pub fn bench_rsa_enc_dec(c: &mut Criterion) { c.bench_function("RSA enc+dec", |b| b.iter(rsa_textbook::rsa_run_enc_dec)); } -/// benchmark [`rsa gen`] for 1024 bit security -pub fn bench_rsa_gen(c: &mut Criterion) { - c.bench_function("RSA gen", |b| b.iter(|| rsa_textbook::gen(1024))); +/// benchmark [`rsa generate`] for 1024 bit security +pub fn bench_rsa_generate(c: &mut Criterion) { + c.bench_function("RSA generate", |b| b.iter(|| rsa_textbook::generate(1024))); } mod dh_ke { @@ -184,8 +184,8 @@ mod dh_ke { use std::str::FromStr; /// Returns a pre-computed set of public parameters that was - /// pre-computed with `gen_prime_order_group_plus_generator(1024)`. - pub fn static_gen_pp() -> (Modulus, Zq) { + /// pre-computed with `generate_prime_order_group_plus_generator(1024)`. + pub fn static_generate_pp() -> (Modulus, Zq) { let generator = Zq::from_str(GEN_PRIME_ORDER_GROUP).unwrap(); let modulus = generator.get_mod(); (modulus, generator) @@ -193,9 +193,9 @@ mod dh_ke { /// Computes all values needed for the initialization of the DH key exchange /// - /// `dh_ke::gen_key_pair(modulus, generator) -> (pk, sk)`, + /// `dh_ke::generate_key_pair(modulus, generator) -> (pk, sk)`, /// where `pk = g^sk mod modulus` and `sk` uniformly random - pub fn gen_key_pair(modulus: &Modulus, generator: &Zq) -> (Zq, Z) { + pub fn generate_key_pair(modulus: &Modulus, generator: &Zq) -> (Zq, Z) { let sk = Z::sample_uniform(0, modulus).unwrap(); let pk = generator.pow(&sk).unwrap(); (pk, sk) @@ -210,13 +210,13 @@ mod dh_ke { /// Run a Diffie-Hellman key exchange with precomputed public parameters with 1024 bit security. /// 1. get (p, g) from previously generated public parameters - /// 2. run one cycle of `gen_key_pair` and `combine_to_shared_sk` on each end (2 times), + /// 2. run one cycle of `generate_key_pair` and `combine_to_shared_sk` on each end (2 times), /// i.e. one key exchange at both ends and compare the computed shared secrets pub fn dh_run() { - let (modulus, generator) = static_gen_pp(); + let (modulus, generator) = static_generate_pp(); - let (pk_0, sk_0) = gen_key_pair(&modulus, &generator); - let (pk_1, sk_1) = gen_key_pair(&modulus, &generator); + let (pk_0, sk_0) = generate_key_pair(&modulus, &generator); + let (pk_1, sk_1) = generate_key_pair(&modulus, &generator); let shared_secret_0 = combine_to_shared_sk(&sk_0, &pk_1); let shared_secret_1 = combine_to_shared_sk(&sk_1, &pk_0); @@ -240,8 +240,8 @@ mod el_gamal_enc { use std::str::FromStr; /// Returns a pre-computed set of public parameters that was - /// computed with `gen_prime_order_group_plus_generator(1024)`. - pub fn static_gen_pp() -> (Modulus, Zq) { + /// computed with `generate_prime_order_group_plus_generator(1024)`. + pub fn static_generate_pp() -> (Modulus, Zq) { let generator = Zq::from_str(GEN_PRIME_ORDER_GROUP).unwrap(); let modulus = generator.get_mod(); (modulus, generator) @@ -249,9 +249,9 @@ mod el_gamal_enc { /// Generates a (pk, sk) key pair for ElGamal's encryption scheme /// - /// `gen_key_pair(p, g) -> (pk, sk)`, + /// `generate_key_pair(p, g) -> (pk, sk)`, /// where `pk = g^sk mod p` and `sk` uniformly random - pub fn gen_key_pair(modulus: &Modulus, generator: &Zq) -> (Zq, Z) { + pub fn generate_key_pair(modulus: &Modulus, generator: &Zq) -> (Zq, Z) { let sk = Z::sample_uniform(0, modulus).unwrap(); let pk = generator.pow(&sk).unwrap(); (pk, sk) @@ -274,11 +274,11 @@ mod el_gamal_enc { /// Run ElGamal gen+enc+dec with precomputed public parameters with 1024 bit security. /// 1. get (p, g) from previously generated public parameters - /// 2. run one cycle of `gen_key_pair`, `enc`, `dec`, and compare the `msg` to the result + /// 2. run one cycle of `generate_key_pair`, `enc`, `dec`, and compare the `msg` to the result pub fn el_gamal_run() { - let (modulus, generator) = static_gen_pp(); + let (modulus, generator) = static_generate_pp(); - let (pk, sk) = gen_key_pair(&modulus, &generator); + let (pk, sk) = generate_key_pair(&modulus, &generator); let msg = Zq::from((&Z::sample_uniform(0, &modulus).unwrap(), &modulus)); @@ -299,7 +299,7 @@ pub fn bench_el_gamal(c: &mut Criterion) { criterion_group!( benches, bench_rsa_enc_dec, - bench_rsa_gen, + bench_rsa_generate, bench_dh, bench_el_gamal, ); diff --git a/benches/matrix_arith.rs b/benches/matrix_arith.rs index e22dde78..385e496a 100644 --- a/benches/matrix_arith.rs +++ b/benches/matrix_arith.rs @@ -8,7 +8,7 @@ //! Create benchmark for matrix arithmetic in this file. -use criterion::{criterion_group, Criterion}; +use criterion::{Criterion, criterion_group}; use qfall_math::rational::MatQ; /// Benchmark [`MatQ::mul_f64_unchecked`]. diff --git a/src/error.rs b/src/error.rs index cc1271ed..b4d547e9 100644 --- a/src/error.rs +++ b/src/error.rs @@ -6,28 +6,30 @@ // the terms of the Mozilla Public License Version 2.0 as published by the // Mozilla Foundation. See . +//! Contains our central error enum for easy error propagation. +//! //! This module contains this crate's error enum. This enum can hold all sorts //! of errors occurring in this crate s.t. error propagation is simple for //! developers of this crate and all sorts of thrown errors and error types can //! be easily found and accessed by developers using this crate. Furthermore, //! the actual errors are wrapped s.t. all information about the error can be //! unwrapped again. -//! -//! **For developers:** -//! - How to add an error to an `enum`? First of all, find a name -//! that is not too specific for your current case s.t. it could be used in other -//! contexts afterwards as well. Then, find the spot according to your chosen error -//! name in a alphanumerically sorted way in the list of supported errors in the doc -//! comment and inside the `enum` itself. -//! Afterwards, add the error to the list of implemented error -//! types in the doc comment of the `enum` with a short description when it is thrown. -//! Probably use this description for the doc comment above the implementation of -//! error in the `enum`. Then, add `#[error()]` to define the error message -//! output once your error is thrown. Below, write down `(),` to -//! define the error with its name and possibly some inputs. The input can be of the -//! form [`String`], but also another error, whose conversion must be declared via -//! `#[from] OtherError`. It is best to use the existing structure as a guide. For any -//! further information, check out the here used [`thiserror`]-crate. + +// **For developers:** +// - How to add an error to an `enum`? First of all, find a name +// that is not too specific for your current case s.t. it could be used in other +// contexts afterwards as well. Then, find the spot according to your chosen error +// name in a alphanumerically sorted way in the list of supported errors in the doc +// comment and inside the `enum` itself. +// Afterwards, add the error to the list of implemented error +// types in the doc comment of the `enum` with a short description when it is thrown. +// Probably use this description for the doc comment above the implementation of +// error in the `enum`. Then, add `#[error()]` to define the error message +// output once your error is thrown. Below, write down `(),` to +// define the error with its name and possibly some inputs. The input can be of the +// form [`String`], but also another error, whose conversion must be declared via +// `#[from] OtherError`. It is best to use the existing structure as a guide. For any +// further information, check out the here used [`thiserror`]-crate. use std::ffi::NulError; use thiserror::Error; diff --git a/src/integer.rs b/src/integer.rs index 7fb5c234..f3843f44 100644 --- a/src/integer.rs +++ b/src/integer.rs @@ -6,6 +6,8 @@ // the terms of the Mozilla Public License Version 2.0 as published by the // Mozilla Foundation. See . +//! Integer-based types with arbitrary length based on [`Z`]. +//! //! This module contains the type [`Z`] for integers with arbitrary length and //! constructions over it. //! Each struct provides examples regarding usage. @@ -21,5 +23,5 @@ mod z; pub use mat_poly_over_z::MatPolyOverZ; pub use mat_z::MatZ; pub use poly_over_z::PolyOverZ; -pub(crate) use z::fmpz_helpers; pub use z::Z; +pub(crate) use z::fmpz_helpers; diff --git a/src/integer/mat_poly_over_z/cmp.rs b/src/integer/mat_poly_over_z/cmp.rs index c5f86977..1771fa55 100644 --- a/src/integer/mat_poly_over_z/cmp.rs +++ b/src/integer/mat_poly_over_z/cmp.rs @@ -255,9 +255,11 @@ mod test_compare_base { assert!(one_1.compare_base(&0_u64)); assert!(one_1.call_compare_base_error(&MatZ::new(1, 1)).is_none()); - assert!(one_1 - .call_compare_base_error(&MatPolyOverZ::new(1, 1)) - .is_none()); + assert!( + one_1 + .call_compare_base_error(&MatPolyOverZ::new(1, 1)) + .is_none() + ); assert!(one_1.call_compare_base_error(&Z::ONE).is_none()); assert!(one_1.call_compare_base_error(&0_i8).is_none()); assert!(one_1.call_compare_base_error(&0_i16).is_none()); diff --git a/src/integer/mat_poly_over_z/coefficient_embedding.rs b/src/integer/mat_poly_over_z/coefficient_embedding.rs index b3ef89ea..0f2c0bfd 100644 --- a/src/integer/mat_poly_over_z/coefficient_embedding.rs +++ b/src/integer/mat_poly_over_z/coefficient_embedding.rs @@ -113,7 +113,7 @@ impl FromCoefficientEmbedding<(&MatZ, i64)> for MatPolyOverZ { let num_columns = embedding.0.get_num_columns(); assert_eq!( - num_rows % (degree+1), + num_rows % (degree + 1), 0, "The provided degree of polynomials ({degree}) +1 must divide the number of rows of the embedding ({num_rows})." ); diff --git a/src/integer/mat_poly_over_z/reduce.rs b/src/integer/mat_poly_over_z/reduce.rs index 609204f8..64b1d756 100644 --- a/src/integer/mat_poly_over_z/reduce.rs +++ b/src/integer/mat_poly_over_z/reduce.rs @@ -12,7 +12,7 @@ use super::MatPolyOverZ; use crate::{ - integer::{poly_over_z::fmpz_poly_helpers::reduce_fmpz_poly_by_poly_over_z, PolyOverZ}, + integer::{PolyOverZ, poly_over_z::fmpz_poly_helpers::reduce_fmpz_poly_by_poly_over_z}, traits::MatrixDimensions, }; use flint_sys::fmpz_poly_mat::fmpz_poly_mat_entry; diff --git a/src/integer/mat_poly_over_z/serialize.rs b/src/integer/mat_poly_over_z/serialize.rs index a25e564d..8d746146 100644 --- a/src/integer/mat_poly_over_z/serialize.rs +++ b/src/integer/mat_poly_over_z/serialize.rs @@ -15,9 +15,9 @@ use super::MatPolyOverZ; use crate::macros::serialize::{deserialize, serialize}; use core::fmt; use serde::{ + Deserialize, Serialize, de::{Error, MapAccess, Unexpected, Visitor}, ser::SerializeStruct, - Deserialize, Serialize, }; use std::str::FromStr; diff --git a/src/integer/mat_poly_over_z/set.rs b/src/integer/mat_poly_over_z/set.rs index ba5c2b44..2de30a94 100644 --- a/src/integer/mat_poly_over_z/set.rs +++ b/src/integer/mat_poly_over_z/set.rs @@ -1000,9 +1000,10 @@ mod test_set_submatrix { fn submatrix_too_large() { let mut mat = MatPolyOverZ::sample_uniform(10, 10, 5, -100, 100).unwrap(); - assert!(mat - .set_submatrix(0, 0, &MatPolyOverZ::identity(11, 11), 0, 0, 10, 10) - .is_err()); + assert!( + mat.set_submatrix(0, 0, &MatPolyOverZ::identity(11, 11), 0, 0, 10, 10) + .is_err() + ); assert!(mat.set_submatrix(1, 2, &mat.clone(), 0, 0, 9, 9).is_err()); } diff --git a/src/integer/mat_z/arithmetic/div.rs b/src/integer/mat_z/arithmetic/div.rs index 565e5fac..1c58e977 100644 --- a/src/integer/mat_z/arithmetic/div.rs +++ b/src/integer/mat_z/arithmetic/div.rs @@ -50,7 +50,7 @@ impl MatZ { let divisor: Z = divisor.into(); assert!(!divisor.is_zero(), "Tried to divide {self} by zero."); - fmpz_mat_scalar_divexact_fmpz(&mut self.matrix, &self.matrix, &divisor.value); + unsafe { fmpz_mat_scalar_divexact_fmpz(&mut self.matrix, &self.matrix, &divisor.value) }; self } @@ -86,7 +86,7 @@ impl MatZ { assert!(!divisor.is_zero(), "Tried to divide {self} by zero."); let mut out = MatZ::new(self.get_num_rows(), self.get_num_columns()); - fmpz_mat_scalar_divexact_fmpz(&mut out.matrix, &self.matrix, &divisor.value); + unsafe { fmpz_mat_scalar_divexact_fmpz(&mut out.matrix, &self.matrix, &divisor.value) }; out } diff --git a/src/integer/mat_z/sample/discrete_gauss.rs b/src/integer/mat_z/sample/discrete_gauss.rs index f02e4928..cd60980b 100644 --- a/src/integer/mat_z/sample/discrete_gauss.rs +++ b/src/integer/mat_z/sample/discrete_gauss.rs @@ -14,8 +14,8 @@ use crate::{ rational::{MatQ, Q}, traits::{MatrixDimensions, MatrixSetEntry}, utils::sample::discrete_gauss::{ - sample_d, sample_d_precomputed_gso, DiscreteGaussianIntegerSampler, LookupTableSetting, - TAILCUT, + DiscreteGaussianIntegerSampler, LookupTableSetting, TAILCUT, sample_d, + sample_d_precomputed_gso, }, }; use std::fmt::Display; diff --git a/src/integer/mat_z/serialize.rs b/src/integer/mat_z/serialize.rs index fd806a1c..7ba0e026 100644 --- a/src/integer/mat_z/serialize.rs +++ b/src/integer/mat_z/serialize.rs @@ -15,9 +15,9 @@ use super::MatZ; use crate::macros::serialize::{deserialize, serialize}; use core::fmt; use serde::{ + Deserialize, Serialize, de::{Error, MapAccess, Unexpected, Visitor}, ser::SerializeStruct, - Deserialize, Serialize, }; use std::str::FromStr; diff --git a/src/integer/mat_z/set.rs b/src/integer/mat_z/set.rs index 7de527ac..ac055dd7 100644 --- a/src/integer/mat_z/set.rs +++ b/src/integer/mat_z/set.rs @@ -965,9 +965,10 @@ mod test_set_submatrix { fn submatrix_too_large() { let mut mat = MatZ::sample_uniform(10, 10, -100, 100).unwrap(); - assert!(mat - .set_submatrix(0, 0, &MatZ::identity(11, 11), 0, 0, 10, 10) - .is_err()); + assert!( + mat.set_submatrix(0, 0, &MatZ::identity(11, 11), 0, 0, 10, 10) + .is_err() + ); assert!(mat.set_submatrix(1, 2, &mat.clone(), 0, 0, 9, 9).is_err()); } diff --git a/src/integer/mat_z/vector/norm.rs b/src/integer/mat_z/vector/norm.rs index c5510c61..d6cb76ba 100644 --- a/src/integer/mat_z/vector/norm.rs +++ b/src/integer/mat_z/vector/norm.rs @@ -12,7 +12,7 @@ use super::super::MatZ; use crate::{ error::MathError, - integer::{fmpz_helpers::find_max_abs, Z}, + integer::{Z, fmpz_helpers::find_max_abs}, rational::Q, traits::MatrixDimensions, }; diff --git a/src/integer/poly_over_z/fmpz_poly_helpers.rs b/src/integer/poly_over_z/fmpz_poly_helpers.rs index eef5f52f..6847fd8d 100644 --- a/src/integer/poly_over_z/fmpz_poly_helpers.rs +++ b/src/integer/poly_over_z/fmpz_poly_helpers.rs @@ -42,7 +42,7 @@ pub(crate) unsafe fn reduce_fmpz_poly_by_poly_over_z( poly: *mut fmpz_poly_struct, modulus: &PolyOverZ, ) { - let self_nr_coeff = (*poly).length + 1; + let self_nr_coeff = unsafe { *poly }.length + 1; let modulus_nr_coeff = modulus.get_degree(); assert_eq!( @@ -65,7 +65,7 @@ pub(crate) unsafe fn reduce_fmpz_poly_by_poly_over_z( #[cfg(test)] mod test_reduce_fmpz_poly_by_poly_over_z { use crate::integer::{ - poly_over_z::fmpz_poly_helpers::reduce_fmpz_poly_by_poly_over_z, PolyOverZ, + PolyOverZ, poly_over_z::fmpz_poly_helpers::reduce_fmpz_poly_by_poly_over_z, }; use std::str::FromStr; diff --git a/src/integer/poly_over_z/reduce.rs b/src/integer/poly_over_z/reduce.rs index 81f1de4d..57714fe3 100644 --- a/src/integer/poly_over_z/reduce.rs +++ b/src/integer/poly_over_z/reduce.rs @@ -10,7 +10,7 @@ //! by reducing a [`PolyOverZ`] by a [`PolyOverZ`] that //! has a leading coefficient of `1`. -use super::{fmpz_poly_helpers::reduce_fmpz_poly_by_poly_over_z, PolyOverZ}; +use super::{PolyOverZ, fmpz_poly_helpers::reduce_fmpz_poly_by_poly_over_z}; impl PolyOverZ { /// Reduces a polynomial by a polynomial `modulus`. diff --git a/src/integer/poly_over_z/serialize.rs b/src/integer/poly_over_z/serialize.rs index 6cbdaf6d..bdc91d79 100644 --- a/src/integer/poly_over_z/serialize.rs +++ b/src/integer/poly_over_z/serialize.rs @@ -15,9 +15,9 @@ use super::PolyOverZ; use crate::macros::serialize::{deserialize, serialize}; use core::fmt; use serde::{ + Deserialize, Serialize, de::{Error, MapAccess, Unexpected, Visitor}, ser::SerializeStruct, - Deserialize, Serialize, }; use std::str::FromStr; diff --git a/src/integer/z/arithmetic/logarithm.rs b/src/integer/z/arithmetic/logarithm.rs index 45eac7a4..4eb9c51e 100644 --- a/src/integer/z/arithmetic/logarithm.rs +++ b/src/integer/z/arithmetic/logarithm.rs @@ -289,7 +289,7 @@ mod test_log_floor { #[cfg(test)] mod test_natural_ln { use crate::{integer::Z, rational::Q}; - use std::f64::consts::{LN_10, LN_2}; + use std::f64::consts::{LN_2, LN_10}; /// Ensure that an error is returned if `self` is too small #[test] diff --git a/src/integer/z/fmpz_helpers.rs b/src/integer/z/fmpz_helpers.rs index fe25dd79..1732d737 100644 --- a/src/integer/z/fmpz_helpers.rs +++ b/src/integer/z/fmpz_helpers.rs @@ -81,7 +81,7 @@ pub(crate) fn distance(value_1: &fmpz, value_2: &fmpz) -> Z { unsafe impl AsInteger for u64 { /// Documentation at [`AsInteger::into_fmpz`] unsafe fn into_fmpz(self) -> fmpz { - (&self).into_fmpz() + unsafe { (&self).into_fmpz() } } } @@ -89,7 +89,7 @@ unsafe impl AsInteger for &u64 { /// Documentation at [`AsInteger::into_fmpz`] unsafe fn into_fmpz(self) -> fmpz { let mut ret_value = fmpz(0); - fmpz_init_set_ui(&mut ret_value, *self); + unsafe { fmpz_init_set_ui(&mut ret_value, *self) }; ret_value } } @@ -103,7 +103,7 @@ macro_rules! implement_as_integer_over_i64 { /// Documentation at [`AsInteger::into_fmpz`] unsafe impl AsInteger for $type { unsafe fn into_fmpz(self) -> fmpz { - (&self).into_fmpz() + unsafe { (&self).into_fmpz() } } } @@ -111,7 +111,7 @@ macro_rules! implement_as_integer_over_i64 { unsafe impl AsInteger for &$type { unsafe fn into_fmpz(self) -> fmpz { let mut ret_value = fmpz(0); - fmpz_init_set_si(&mut ret_value, *self as i64); + unsafe { fmpz_init_set_si(&mut ret_value, *self as i64) }; ret_value } } @@ -125,7 +125,7 @@ unsafe impl AsInteger for Z { /// Documentation at [`AsInteger::into_fmpz`] unsafe fn into_fmpz(mut self) -> fmpz { let mut out = fmpz(0); - fmpz_swap(&mut out, &mut self.value); + unsafe { fmpz_swap(&mut out, &mut self.value) }; out } @@ -139,7 +139,7 @@ unsafe impl AsInteger for &Z { /// Documentation at [`AsInteger::into_fmpz`] unsafe fn into_fmpz(self) -> fmpz { let mut value = fmpz(0); - fmpz_init_set(&mut value, &self.value); + unsafe { fmpz_init_set(&mut value, &self.value) }; value } @@ -152,7 +152,7 @@ unsafe impl AsInteger for &Z { unsafe impl AsInteger for fmpz { /// Documentation at [`AsInteger::into_fmpz`] unsafe fn into_fmpz(self) -> fmpz { - (&self).into_fmpz() + unsafe { (&self).into_fmpz() } } /// Documentation at [`AsInteger::get_fmpz_ref`] @@ -165,7 +165,7 @@ unsafe impl AsInteger for &fmpz { /// Documentation at [`AsInteger::into_fmpz`] unsafe fn into_fmpz(self) -> fmpz { let mut value = fmpz(0); - fmpz_init_set(&mut value, self); + unsafe { fmpz_init_set(&mut value, self) }; value } @@ -336,8 +336,8 @@ mod test_find_max_abs { #[cfg(test)] mod test_distance { - use super::distance; use super::Z; + use super::distance; use flint_sys::fmpz::fmpz; /// Checks if distance is correctly output for small [`Z`] values diff --git a/src/integer/z/serialize.rs b/src/integer/z/serialize.rs index 157a21b9..d7417c96 100644 --- a/src/integer/z/serialize.rs +++ b/src/integer/z/serialize.rs @@ -15,9 +15,9 @@ use super::Z; use crate::macros::serialize::{deserialize, serialize}; use core::fmt; use serde::{ + Deserialize, Serialize, de::{Error, MapAccess, Unexpected, Visitor}, ser::SerializeStruct, - Deserialize, Serialize, }; use std::str::FromStr; diff --git a/src/integer_mod_q.rs b/src/integer_mod_q.rs index ccd32179..e7bda860 100644 --- a/src/integer_mod_q.rs +++ b/src/integer_mod_q.rs @@ -6,6 +6,8 @@ // the terms of the Mozilla Public License Version 2.0 as published by the // Mozilla Foundation. See . +//! Types for residue classes over integers with arbitrary length based on [`Zq`]. +//! //! This module contains the type [`Zq`] for integers with arbitrary length //! modulus `q` and constructions over it. //! Each struct provides examples regarding usage. @@ -14,10 +16,6 @@ //! e.g. the standard rust integers. //! The [`Modulus`] is constructed as an explicit struct and can be shared across several //! [`Zq`], [`MatZq`] and [`PolyOverZq`] instances with efficient memory usage. -//! -//! - \[1\] John D. Dixon. -//! "Exact Solution of Linear Equations Using P-Adic Expansions" -//! mod mat_ntt_polynomial_ring_zq; mod mat_polynomial_ring_zq; @@ -39,5 +37,5 @@ pub use ntt_basis_polynomial_ring_zq::{ConvolutionType, NTTBasisPolynomialRingZq pub use ntt_polynomial_ring_zq::NTTPolynomialRingZq; pub use poly_over_zq::PolyOverZq; pub use polynomial_ring_zq::PolynomialRingZq; -pub(crate) use z_q::fmpz_mod_helpers; pub use z_q::Zq; +pub(crate) use z_q::fmpz_mod_helpers; diff --git a/src/integer_mod_q/mat_ntt_polynomial_ring_zq/arithmetic/mul.rs b/src/integer_mod_q/mat_ntt_polynomial_ring_zq/arithmetic/mul.rs index 109659de..95df66ec 100644 --- a/src/integer_mod_q/mat_ntt_polynomial_ring_zq/arithmetic/mul.rs +++ b/src/integer_mod_q/mat_ntt_polynomial_ring_zq/arithmetic/mul.rs @@ -47,8 +47,10 @@ impl Mul for &MatNTTPolynomialRingZq { /// - if the number of rows of `self` and the number of columns of `other` does not match up. /// - if their moduli do not match. fn mul(self, other: Self) -> Self::Output { - assert_eq!(self.nr_columns, other.nr_rows, - "The number of rows of `self` and the number of columns of `other` has to be equal for matrix multiplication."); + assert_eq!( + self.nr_columns, other.nr_rows, + "The number of rows of `self` and the number of columns of `other` has to be equal for matrix multiplication." + ); if !self.compare_base(other) { panic!("{}", self.call_compare_base_error(other).unwrap()); } diff --git a/src/integer_mod_q/mat_ntt_polynomial_ring_zq/cmp.rs b/src/integer_mod_q/mat_ntt_polynomial_ring_zq/cmp.rs index a3c48eb5..b5000dd4 100644 --- a/src/integer_mod_q/mat_ntt_polynomial_ring_zq/cmp.rs +++ b/src/integer_mod_q/mat_ntt_polynomial_ring_zq/cmp.rs @@ -60,13 +60,17 @@ mod test_compare_base { assert!(one_1.compare_base(&0_u64)); assert!(one_1.call_compare_base_error(&MatZ::new(1, 1)).is_none()); - assert!(one_1 - .call_compare_base_error(&MatPolyOverZ::new(1, 1)) - .is_none()); + assert!( + one_1 + .call_compare_base_error(&MatPolyOverZ::new(1, 1)) + .is_none() + ); assert!(one_1.call_compare_base_error(&Z::ONE).is_none()); - assert!(one_1 - .call_compare_base_error(&PolyOverZ::from_str("1 3").unwrap()) - .is_none()); + assert!( + one_1 + .call_compare_base_error(&PolyOverZ::from_str("1 3").unwrap()) + .is_none() + ); assert!(one_1.call_compare_base_error(&0_i8).is_none()); assert!(one_1.call_compare_base_error(&0_i16).is_none()); assert!(one_1.call_compare_base_error(&0_i32).is_none()); @@ -98,18 +102,26 @@ mod test_compare_base { assert!(one_1.compare_base(&PolynomialRingZq::from(&modulus))); assert!(!one_1.compare_base(&PolynomialRingZq::from(&modulus_other))); - assert!(one_1 - .call_compare_base_error(&MatPolynomialRingZq::identity(10, 7, &modulus_other)) - .is_some()); + assert!( + one_1 + .call_compare_base_error(&MatPolynomialRingZq::identity(10, 7, &modulus_other)) + .is_some() + ); assert!(one_1.call_compare_base_error(&Zq::from((3, 18))).is_some()); - assert!(one_1 - .call_compare_base_error(&PolyOverZq::from_str("1 3 mod 18").unwrap()) - .is_some()); - assert!(one_1 - .call_compare_base_error(&MatZq::new(1, 1, 18)) - .is_some()); - assert!(one_1 - .call_compare_base_error(&PolynomialRingZq::from(&modulus_other)) - .is_some()); + assert!( + one_1 + .call_compare_base_error(&PolyOverZq::from_str("1 3 mod 18").unwrap()) + .is_some() + ); + assert!( + one_1 + .call_compare_base_error(&MatZq::new(1, 1, 18)) + .is_some() + ); + assert!( + one_1 + .call_compare_base_error(&PolynomialRingZq::from(&modulus_other)) + .is_some() + ); } } diff --git a/src/integer_mod_q/mat_polynomial_ring_zq/arithmetic/mul_scalar.rs b/src/integer_mod_q/mat_polynomial_ring_zq/arithmetic/mul_scalar.rs index 18725a7e..3d07a962 100644 --- a/src/integer_mod_q/mat_polynomial_ring_zq/arithmetic/mul_scalar.rs +++ b/src/integer_mod_q/mat_polynomial_ring_zq/arithmetic/mul_scalar.rs @@ -1131,9 +1131,11 @@ mod test_mul_poly_ring_zq { let poly = PolyOverZ::from_str("2 1 1").unwrap(); let poly_ring = PolynomialRingZq::from((&poly, &modulus2)); - assert!(&poly_ring_mat1 - .mul_scalar_poly_ring_zq_safe(&poly_ring) - .is_err()) + assert!( + &poly_ring_mat1 + .mul_scalar_poly_ring_zq_safe(&poly_ring) + .is_err() + ) } } diff --git a/src/integer_mod_q/mat_polynomial_ring_zq/cmp.rs b/src/integer_mod_q/mat_polynomial_ring_zq/cmp.rs index 156e8f78..731ced7c 100644 --- a/src/integer_mod_q/mat_polynomial_ring_zq/cmp.rs +++ b/src/integer_mod_q/mat_polynomial_ring_zq/cmp.rs @@ -58,13 +58,17 @@ mod test_compare_base { assert!(one_1.compare_base(&0_u64)); assert!(one_1.call_compare_base_error(&MatZ::new(1, 1)).is_none()); - assert!(one_1 - .call_compare_base_error(&MatPolyOverZ::new(1, 1)) - .is_none()); + assert!( + one_1 + .call_compare_base_error(&MatPolyOverZ::new(1, 1)) + .is_none() + ); assert!(one_1.call_compare_base_error(&Z::ONE).is_none()); - assert!(one_1 - .call_compare_base_error(&PolyOverZ::from_str("1 3").unwrap()) - .is_none()); + assert!( + one_1 + .call_compare_base_error(&PolyOverZ::from_str("1 3").unwrap()) + .is_none() + ); assert!(one_1.call_compare_base_error(&0_i8).is_none()); assert!(one_1.call_compare_base_error(&0_i16).is_none()); assert!(one_1.call_compare_base_error(&0_i32).is_none()); @@ -94,18 +98,26 @@ mod test_compare_base { assert!(one_1.compare_base(&PolynomialRingZq::from(&modulus))); assert!(!one_1.compare_base(&PolynomialRingZq::from(&modulus_other))); - assert!(one_1 - .call_compare_base_error(&MatPolynomialRingZq::identity(10, 7, &modulus_other)) - .is_some()); + assert!( + one_1 + .call_compare_base_error(&MatPolynomialRingZq::identity(10, 7, &modulus_other)) + .is_some() + ); assert!(one_1.call_compare_base_error(&Zq::from((3, 18))).is_some()); - assert!(one_1 - .call_compare_base_error(&PolyOverZq::from_str("1 3 mod 18").unwrap()) - .is_some()); - assert!(one_1 - .call_compare_base_error(&MatZq::new(1, 1, 18)) - .is_some()); - assert!(one_1 - .call_compare_base_error(&PolynomialRingZq::from(&modulus_other)) - .is_some()); + assert!( + one_1 + .call_compare_base_error(&PolyOverZq::from_str("1 3 mod 18").unwrap()) + .is_some() + ); + assert!( + one_1 + .call_compare_base_error(&MatZq::new(1, 1, 18)) + .is_some() + ); + assert!( + one_1 + .call_compare_base_error(&PolynomialRingZq::from(&modulus_other)) + .is_some() + ); } } diff --git a/src/integer_mod_q/mat_polynomial_ring_zq/coefficient_embedding.rs b/src/integer_mod_q/mat_polynomial_ring_zq/coefficient_embedding.rs index 6f481cf8..00a0ddfc 100644 --- a/src/integer_mod_q/mat_polynomial_ring_zq/coefficient_embedding.rs +++ b/src/integer_mod_q/mat_polynomial_ring_zq/coefficient_embedding.rs @@ -120,7 +120,7 @@ impl FromCoefficientEmbedding<(&MatZq, &ModulusPolynomialRingZq, i64)> for MatPo let num_columns = embedding.0.get_num_columns(); assert_eq!( - num_rows % (degree+1), + num_rows % (degree + 1), 0, "The provided degree of polynomials ({degree}) +1 must divide the number of rows of the embedding ({num_rows})." ); diff --git a/src/integer_mod_q/mat_polynomial_ring_zq/from.rs b/src/integer_mod_q/mat_polynomial_ring_zq/from.rs index 5e794973..931f207a 100644 --- a/src/integer_mod_q/mat_polynomial_ring_zq/from.rs +++ b/src/integer_mod_q/mat_polynomial_ring_zq/from.rs @@ -115,7 +115,7 @@ impl FromStr for MatPolynomialRingZq { None => { return Err(StringConversionError::InvalidMatrix(format!( "The delimiter '/' could not be found: {string}" - )))? + )))?; } }; diff --git a/src/integer_mod_q/mat_polynomial_ring_zq/get.rs b/src/integer_mod_q/mat_polynomial_ring_zq/get.rs index 6ca75484..3fa21585 100644 --- a/src/integer_mod_q/mat_polynomial_ring_zq/get.rs +++ b/src/integer_mod_q/mat_polynomial_ring_zq/get.rs @@ -138,7 +138,7 @@ impl MatrixGetEntry for MatPolynomialRingZq { /// assert_eq!(entry_2, PolyOverZ::from(42)); /// ``` unsafe fn get_entry_unchecked(&self, row: i64, column: i64) -> PolyOverZ { - self.matrix.get_entry_unchecked(row, column) + unsafe { self.matrix.get_entry_unchecked(row, column) } } } @@ -178,7 +178,7 @@ impl MatrixGetEntry for MatPolynomialRingZq { /// ``` unsafe fn get_entry_unchecked(&self, row: i64, column: i64) -> PolynomialRingZq { PolynomialRingZq { - poly: self.matrix.get_entry_unchecked(row, column), + poly: unsafe { self.matrix.get_entry_unchecked(row, column) }, modulus: self.get_mod(), } } @@ -230,9 +230,10 @@ impl MatrixGetSubmatrix for MatPolynomialRingZq { col_2: i64, ) -> Self { MatPolynomialRingZq { - matrix: self - .matrix - .get_submatrix_unchecked(row_1, row_2, col_1, col_2), + matrix: unsafe { + self.matrix + .get_submatrix_unchecked(row_1, row_2, col_1, col_2) + }, modulus: self.get_mod(), } } diff --git a/src/integer_mod_q/mat_polynomial_ring_zq/reduce.rs b/src/integer_mod_q/mat_polynomial_ring_zq/reduce.rs index 6125e826..8b1c15d9 100644 --- a/src/integer_mod_q/mat_polynomial_ring_zq/reduce.rs +++ b/src/integer_mod_q/mat_polynomial_ring_zq/reduce.rs @@ -8,11 +8,11 @@ //! Implementations to reduce a [`MatPolynomialRingZq`] with the //! [`ModulusPolynomialRingZq`](crate::integer_mod_q::ModulusPolynomialRingZq). -//! -//! **For Developers** note: The [`ModulusPolynomialRingZq`](crate::integer_mod_q::ModulusPolynomialRingZq) -//! is not applied automatically, and has to be called in the functions individually. -//! Additionally the comparisons assume that the entries are reduced, -//! hence no reduction is performed in the check. + +// **For Developers** note: The [`ModulusPolynomialRingZq`](crate::integer_mod_q::ModulusPolynomialRingZq) +// is not applied automatically, and has to be called in the functions individually. +// Additionally the comparisons assume that the entries are reduced, +// hence no reduction is performed in the check. use super::MatPolynomialRingZq; use crate::traits::MatrixDimensions; @@ -53,7 +53,7 @@ impl MatPolynomialRingZq { mod test_reduced { use crate::{ integer::MatPolyOverZ, - integer_mod_q::{mat_polynomial_ring_zq::MatPolynomialRingZq, ModulusPolynomialRingZq}, + integer_mod_q::{ModulusPolynomialRingZq, mat_polynomial_ring_zq::MatPolynomialRingZq}, }; use std::str::FromStr; diff --git a/src/integer_mod_q/mat_polynomial_ring_zq/set.rs b/src/integer_mod_q/mat_polynomial_ring_zq/set.rs index 193dedfe..f9540747 100644 --- a/src/integer_mod_q/mat_polynomial_ring_zq/set.rs +++ b/src/integer_mod_q/mat_polynomial_ring_zq/set.rs @@ -964,8 +964,8 @@ mod test_set_submatrix { ModulusPolynomialRingZq::from_str(&format!("4 1 0 0 1 mod {}", u64::MAX)).unwrap(); let mut mat = MatPolynomialRingZq::identity(10, 10, &modulus); - assert!(mat - .set_submatrix( + assert!( + mat.set_submatrix( 0, 0, &MatPolynomialRingZq::identity(11, 11, &modulus), @@ -974,7 +974,8 @@ mod test_set_submatrix { 10, 10 ) - .is_err()); + .is_err() + ); assert!(mat.set_submatrix(1, 2, &mat.clone(), 0, 0, 9, 9).is_err()); } diff --git a/src/integer_mod_q/mat_zq.rs b/src/integer_mod_q/mat_zq.rs index a3c94317..d11a8210 100644 --- a/src/integer_mod_q/mat_zq.rs +++ b/src/integer_mod_q/mat_zq.rs @@ -8,10 +8,10 @@ //! [`MatZq`] is a type of matrix with integer entries of arbitrary length modulo `q`. //! This implementation uses the [FLINT](https://flintlib.org/) library. -//! -//! For **DEVELOPERS**: Many functions assume that the [`MatZq`] instances are reduced. -//! To avoid unnecessary checks and reductions, always return canonical/reduced -//! values. The end-user should be unable to obtain a non-reduced value. + +// For **DEVELOPERS**: Many functions assume that the [`MatZq`] instances are reduced. +// To avoid unnecessary checks and reductions, always return canonical/reduced +// values. The end-user should be unable to obtain a non-reduced value. use crate::{integer_mod_q::Modulus, utils::parse::partial_string}; use flint_sys::fmpz_mod_mat::fmpz_mod_mat_struct; diff --git a/src/integer_mod_q/mat_zq/cmp.rs b/src/integer_mod_q/mat_zq/cmp.rs index cc117c14..6812605d 100644 --- a/src/integer_mod_q/mat_zq/cmp.rs +++ b/src/integer_mod_q/mat_zq/cmp.rs @@ -197,8 +197,10 @@ mod test_compare_base { assert!(!one_1.compare_base(&MatZq::new(1, 1, 18))); assert!(one_1.call_compare_base_error(&Zq::from((3, 18))).is_some()); - assert!(one_1 - .call_compare_base_error(&MatZq::new(1, 1, 18)) - .is_some()); + assert!( + one_1 + .call_compare_base_error(&MatZq::new(1, 1, 18)) + .is_some() + ); } } diff --git a/src/integer_mod_q/mat_zq/from.rs b/src/integer_mod_q/mat_zq/from.rs index 07757f4a..68e53a78 100644 --- a/src/integer_mod_q/mat_zq/from.rs +++ b/src/integer_mod_q/mat_zq/from.rs @@ -84,7 +84,7 @@ impl FromStr for MatZq { None => { return Err(StringConversionError::InvalidMatrix(format!( "The word 'mod' could not be found: {string}" - )))? + )))?; } }; diff --git a/src/integer_mod_q/mat_zq/get.rs b/src/integer_mod_q/mat_zq/get.rs index 97e20454..9b1f6b38 100644 --- a/src/integer_mod_q/mat_zq/get.rs +++ b/src/integer_mod_q/mat_zq/get.rs @@ -11,7 +11,7 @@ use super::MatZq; use crate::{ integer::{MatZ, Z}, - integer_mod_q::{fmpz_mod_helpers::length, Modulus, Zq}, + integer_mod_q::{Modulus, Zq, fmpz_mod_helpers::length}, traits::{MatrixDimensions, MatrixGetEntry, MatrixGetSubmatrix, MatrixSetEntry}, }; use flint_sys::{ diff --git a/src/integer_mod_q/mat_zq/sample/discrete_gauss.rs b/src/integer_mod_q/mat_zq/sample/discrete_gauss.rs index cd68d392..ff899ccc 100644 --- a/src/integer_mod_q/mat_zq/sample/discrete_gauss.rs +++ b/src/integer_mod_q/mat_zq/sample/discrete_gauss.rs @@ -14,8 +14,8 @@ use crate::{ rational::{MatQ, Q}, traits::{MatrixDimensions, MatrixSetEntry}, utils::sample::discrete_gauss::{ - sample_d, sample_d_precomputed_gso, DiscreteGaussianIntegerSampler, LookupTableSetting, - TAILCUT, + DiscreteGaussianIntegerSampler, LookupTableSetting, TAILCUT, sample_d, + sample_d_precomputed_gso, }, }; use std::fmt::Display; diff --git a/src/integer_mod_q/mat_zq/serialize.rs b/src/integer_mod_q/mat_zq/serialize.rs index 923823ef..902c6781 100644 --- a/src/integer_mod_q/mat_zq/serialize.rs +++ b/src/integer_mod_q/mat_zq/serialize.rs @@ -15,9 +15,9 @@ use super::MatZq; use crate::macros::serialize::{deserialize, serialize}; use core::fmt; use serde::{ + Deserialize, Serialize, de::{Error, MapAccess, Unexpected, Visitor}, ser::SerializeStruct, - Deserialize, Serialize, }; use std::str::FromStr; diff --git a/src/integer_mod_q/mat_zq/set.rs b/src/integer_mod_q/mat_zq/set.rs index 94b98c5f..f2334e7d 100644 --- a/src/integer_mod_q/mat_zq/set.rs +++ b/src/integer_mod_q/mat_zq/set.rs @@ -1194,9 +1194,10 @@ mod test_set_submatrix { let modulus = Modulus::from(u64::MAX); let mut mat = MatZq::identity(10, 10, &modulus); - assert!(mat - .set_submatrix(0, 0, &MatZq::identity(11, 11, &modulus), 0, 0, 10, 10) - .is_err()); + assert!( + mat.set_submatrix(0, 0, &MatZq::identity(11, 11, &modulus), 0, 0, 10, 10) + .is_err() + ); assert!(mat.set_submatrix(1, 2, &mat.clone(), 0, 0, 9, 9).is_err()); } diff --git a/src/integer_mod_q/mat_zq/solve.rs b/src/integer_mod_q/mat_zq/solve.rs index fc549c50..06dad67e 100644 --- a/src/integer_mod_q/mat_zq/solve.rs +++ b/src/integer_mod_q/mat_zq/solve.rs @@ -19,7 +19,7 @@ impl MatZq { /// The function uses Gaussian elimination together with Factor refinement /// to split the modulus and the Chinese remainder theorem and Hensel lifting /// to combine solutions under the split modulus. - /// For Hensel lifting we use the method from [\[1\]](). + /// For Hensel lifting we use the method from [\[1\]]. /// /// Note that this function does not compute a solution whenever there is one. /// If the matrix has not full rank under a modulus that divides the given one, @@ -48,6 +48,11 @@ impl MatZq { /// - if the the number of rows of the matrix and the syndrome are different. /// - if the syndrome is not a column vector. /// - if the moduli mismatch. + /// + /// # Reference + /// - \[1\] John D. Dixon. + /// "Exact Solution of Linear Equations Using P-Adic Expansions" + /// pub fn solve_gaussian_elimination(&self, y: &MatZq) -> Option { assert!(y.is_column_vector(), "The syndrome is not a column vector."); assert_eq!( @@ -217,7 +222,7 @@ impl MatZq { } /// Computes a solution for a system of linear equations under a modulus - /// of the form `z^a` with the help of [\[1\]](). + /// of the form `z^a` with the help of [\[1\]]. /// It solves `Ax = y` for `x` with `A` being a [`MatZq`] value. /// If no solution is found, `None` is returned. /// @@ -339,7 +344,7 @@ impl MatZq { }; } - // Use the method from [\[1\]]() + // Use the method from [\[1\]] // to compute a solution for the original system. let mut b_i = y.clone(); let mut x_i = &matrix_base_inv * &b_i; @@ -638,7 +643,7 @@ mod test_solve_gauss { mod test_find_invertible_entry_column { use crate::{ integer::Z, - integer_mod_q::{mat_zq::solve::find_invertible_entry_column, MatZq}, + integer_mod_q::{MatZq, mat_zq::solve::find_invertible_entry_column}, }; use std::str::FromStr; @@ -669,7 +674,7 @@ mod test_find_invertible_entry_column { #[cfg(test)] mod test_find_uninvertible_entry_column { - use crate::integer_mod_q::{mat_zq::solve::find_not_invertible_entry_column, MatZq}; + use crate::integer_mod_q::{MatZq, mat_zq::solve::find_not_invertible_entry_column}; use std::str::FromStr; /// Ensure that the first element is returned, that is not invertible diff --git a/src/integer_mod_q/mat_zq/vector/dot_product.rs b/src/integer_mod_q/mat_zq/vector/dot_product.rs index afc4a2ee..04d7df4c 100644 --- a/src/integer_mod_q/mat_zq/vector/dot_product.rs +++ b/src/integer_mod_q/mat_zq/vector/dot_product.rs @@ -90,7 +90,7 @@ impl MatZq { #[cfg(test)] mod test_dot_product { - use super::{MatZq, Zq, Z}; + use super::{MatZq, Z, Zq}; use std::str::FromStr; /// Check whether the dot product is calculated correctly for the combination: diff --git a/src/integer_mod_q/modulus/fmpz_helpers.rs b/src/integer_mod_q/modulus/fmpz_helpers.rs index f8490f25..6b770df2 100644 --- a/src/integer_mod_q/modulus/fmpz_helpers.rs +++ b/src/integer_mod_q/modulus/fmpz_helpers.rs @@ -15,7 +15,7 @@ use flint_sys::fmpz::{fmpz, fmpz_init_set}; unsafe impl AsInteger for Modulus { /// Documentation at [`AsInteger::into_fmpz`] unsafe fn into_fmpz(self) -> fmpz { - (&self).into_fmpz() + unsafe { (&self).into_fmpz() } } /// Documentation at [`AsInteger::get_fmpz_ref`] @@ -28,7 +28,7 @@ unsafe impl AsInteger for &Modulus { /// Documentation at [`AsInteger::into_fmpz`] unsafe fn into_fmpz(self) -> fmpz { let mut out = fmpz(0); - fmpz_init_set(&mut out, &self.modulus.n[0]); + unsafe { fmpz_init_set(&mut out, &self.modulus.n[0]) }; out } diff --git a/src/integer_mod_q/modulus/serialize.rs b/src/integer_mod_q/modulus/serialize.rs index 795a5e26..0b9e8951 100644 --- a/src/integer_mod_q/modulus/serialize.rs +++ b/src/integer_mod_q/modulus/serialize.rs @@ -15,9 +15,9 @@ use super::Modulus; use crate::macros::serialize::{deserialize, serialize}; use core::fmt; use serde::{ + Deserialize, Serialize, de::{Error, MapAccess, Unexpected, Visitor}, ser::SerializeStruct, - Deserialize, Serialize, }; use std::str::FromStr; diff --git a/src/integer_mod_q/modulus_polynomial_ring_zq/from.rs b/src/integer_mod_q/modulus_polynomial_ring_zq/from.rs index 4f992960..e1171063 100644 --- a/src/integer_mod_q/modulus_polynomial_ring_zq/from.rs +++ b/src/integer_mod_q/modulus_polynomial_ring_zq/from.rs @@ -368,12 +368,14 @@ mod test_from_str { /// Ensure that large coefficients work #[test] fn working_large_entries() { - assert!(ModulusPolynomialRingZq::from_str(&format!( - "4 0 1 3 {} mod {}", - u64::MAX, - 2_i32.pow(16) + 1 - )) - .is_ok()); + assert!( + ModulusPolynomialRingZq::from_str(&format!( + "4 0 1 3 {} mod {}", + u64::MAX, + 2_i32.pow(16) + 1 + )) + .is_ok() + ); } /// Ensure that primes and non-primes work as modulus diff --git a/src/integer_mod_q/modulus_polynomial_ring_zq/get.rs b/src/integer_mod_q/modulus_polynomial_ring_zq/get.rs index 56722efa..d2035f07 100644 --- a/src/integer_mod_q/modulus_polynomial_ring_zq/get.rs +++ b/src/integer_mod_q/modulus_polynomial_ring_zq/get.rs @@ -52,7 +52,7 @@ impl GetCoefficient for ModulusPolynomialRingZq { /// To use this function safely, make sure that the selected index /// is greater or equal than `0`. unsafe fn get_coeff_unchecked(&self, index: i64) -> Zq { - let out_z: Z = self.get_coeff_unchecked(index); + let out_z: Z = unsafe { self.get_coeff_unchecked(index) }; let mut ctx = MaybeUninit::uninit(); unsafe { diff --git a/src/integer_mod_q/modulus_polynomial_ring_zq/ntt_basis.rs b/src/integer_mod_q/modulus_polynomial_ring_zq/ntt_basis.rs index 586f6aa3..e2be5beb 100644 --- a/src/integer_mod_q/modulus_polynomial_ring_zq/ntt_basis.rs +++ b/src/integer_mod_q/modulus_polynomial_ring_zq/ntt_basis.rs @@ -18,8 +18,8 @@ use super::ModulusPolynomialRingZq; use crate::{ integer::Z, integer_mod_q::{ - ntt_basis_polynomial_ring_zq::{ConvolutionType, NTTBasisPolynomialRingZq}, Modulus, + ntt_basis_polynomial_ring_zq::{ConvolutionType, NTTBasisPolynomialRingZq}, }, traits::GetCoefficient, }; diff --git a/src/integer_mod_q/modulus_polynomial_ring_zq/serialize.rs b/src/integer_mod_q/modulus_polynomial_ring_zq/serialize.rs index aeae6c1f..c2321f9f 100644 --- a/src/integer_mod_q/modulus_polynomial_ring_zq/serialize.rs +++ b/src/integer_mod_q/modulus_polynomial_ring_zq/serialize.rs @@ -15,9 +15,9 @@ use super::ModulusPolynomialRingZq; use crate::macros::serialize::{deserialize, serialize}; use core::fmt; use serde::{ + Deserialize, Serialize, de::{Error, MapAccess, Unexpected, Visitor}, ser::SerializeStruct, - Deserialize, Serialize, }; use std::str::FromStr; diff --git a/src/integer_mod_q/ntt_basis_polynomial_ring_zq/inv_ntt.rs b/src/integer_mod_q/ntt_basis_polynomial_ring_zq/inv_ntt.rs index c9fec0cb..d3974a7e 100644 --- a/src/integer_mod_q/ntt_basis_polynomial_ring_zq/inv_ntt.rs +++ b/src/integer_mod_q/ntt_basis_polynomial_ring_zq/inv_ntt.rs @@ -12,7 +12,7 @@ //! //! The explicit functions contain the documentation. -use super::{from::ConvolutionType, NTTBasisPolynomialRingZq}; +use super::{NTTBasisPolynomialRingZq, from::ConvolutionType}; use crate::{ integer::Z, integer_mod_q::{Modulus, PolyOverZq}, diff --git a/src/integer_mod_q/ntt_basis_polynomial_ring_zq/ntt.rs b/src/integer_mod_q/ntt_basis_polynomial_ring_zq/ntt.rs index 7f19a2f9..11fc91c7 100644 --- a/src/integer_mod_q/ntt_basis_polynomial_ring_zq/ntt.rs +++ b/src/integer_mod_q/ntt_basis_polynomial_ring_zq/ntt.rs @@ -12,7 +12,7 @@ //! //! The explicit functions contain the documentation. -use super::{from::ConvolutionType, NTTBasisPolynomialRingZq}; +use super::{NTTBasisPolynomialRingZq, from::ConvolutionType}; use crate::{ integer::Z, integer_mod_q::{Modulus, PolyOverZq}, diff --git a/src/integer_mod_q/ntt_polynomial_ring_zq.rs b/src/integer_mod_q/ntt_polynomial_ring_zq.rs index 4a014a7d..73b48b9e 100644 --- a/src/integer_mod_q/ntt_polynomial_ring_zq.rs +++ b/src/integer_mod_q/ntt_polynomial_ring_zq.rs @@ -10,7 +10,7 @@ use crate::{ integer::Z, - integer_mod_q::{mat_ntt_polynomial_ring_zq::print_vec_z, ModulusPolynomialRingZq}, + integer_mod_q::{ModulusPolynomialRingZq, mat_ntt_polynomial_ring_zq::print_vec_z}, }; use derive_more::Display; use serde::{Deserialize, Serialize}; diff --git a/src/integer_mod_q/ntt_polynomial_ring_zq/cmp.rs b/src/integer_mod_q/ntt_polynomial_ring_zq/cmp.rs index 7bcb3eb1..bd8e4e62 100644 --- a/src/integer_mod_q/ntt_polynomial_ring_zq/cmp.rs +++ b/src/integer_mod_q/ntt_polynomial_ring_zq/cmp.rs @@ -55,9 +55,11 @@ mod test_compare_base { assert!(one_1.compare_base(&0_u64)); assert!(one_1.call_compare_base_error(&Z::ONE).is_none()); - assert!(one_1 - .call_compare_base_error(&PolyOverZ::from_str("1 3").unwrap()) - .is_none()); + assert!( + one_1 + .call_compare_base_error(&PolyOverZ::from_str("1 3").unwrap()) + .is_none() + ); assert!(one_1.call_compare_base_error(&0_i8).is_none()); assert!(one_1.call_compare_base_error(&0_i16).is_none()); assert!(one_1.call_compare_base_error(&0_i32).is_none()); @@ -87,11 +89,15 @@ mod test_compare_base { assert!(!one_1.compare_base(&PolynomialRingZq::from(&modulus_other))); assert!(one_1.call_compare_base_error(&Zq::from((3, 18))).is_some()); - assert!(one_1 - .call_compare_base_error(&PolyOverZq::from_str("1 3 mod 18").unwrap()) - .is_some()); - assert!(one_1 - .call_compare_base_error(&PolynomialRingZq::from(&modulus_other)) - .is_some()); + assert!( + one_1 + .call_compare_base_error(&PolyOverZq::from_str("1 3 mod 18").unwrap()) + .is_some() + ); + assert!( + one_1 + .call_compare_base_error(&PolynomialRingZq::from(&modulus_other)) + .is_some() + ); } } diff --git a/src/integer_mod_q/poly_over_zq.rs b/src/integer_mod_q/poly_over_zq.rs index 3f580ff1..37c52d9f 100644 --- a/src/integer_mod_q/poly_over_zq.rs +++ b/src/integer_mod_q/poly_over_zq.rs @@ -9,10 +9,10 @@ //! [`PolyOverZq`] is a type of polynomial with arbitrarily many coefficients of type //! [`Zq`](crate::integer_mod_q::Zq). //! This implementation uses the [FLINT](https://flintlib.org/) library. -//! -//! For **DEVELOPERS**: Many functions assume that the [`PolyOverZq`] instances are reduced. -//! To avoid unnecessary checks and reductions, always return canonical/reduced -//! values. The end-user should be unable to obtain a non-reduced value. + +// For **DEVELOPERS**: Many functions assume that the [`PolyOverZq`] instances are reduced. +// To avoid unnecessary checks and reductions, always return canonical/reduced +// values. The end-user should be unable to obtain a non-reduced value. use super::modulus::Modulus; use flint_sys::fmpz_mod_poly::fmpz_mod_poly_struct; diff --git a/src/integer_mod_q/poly_over_zq/cmp.rs b/src/integer_mod_q/poly_over_zq/cmp.rs index f727cc61..e309a7c6 100644 --- a/src/integer_mod_q/poly_over_zq/cmp.rs +++ b/src/integer_mod_q/poly_over_zq/cmp.rs @@ -283,9 +283,11 @@ mod test_compare_base { assert!(one_1.compare_base(&0_u64)); assert!(one_1.call_compare_base_error(&Z::ONE).is_none()); - assert!(one_1 - .call_compare_base_error(&PolyOverZ::from_str("1 3").unwrap()) - .is_none()); + assert!( + one_1 + .call_compare_base_error(&PolyOverZ::from_str("1 3").unwrap()) + .is_none() + ); assert!(one_1.call_compare_base_error(&0_i8).is_none()); assert!(one_1.call_compare_base_error(&0_i16).is_none()); assert!(one_1.call_compare_base_error(&0_i32).is_none()); @@ -309,8 +311,10 @@ mod test_compare_base { assert!(!one_1.compare_base(&PolyOverZq::from_str("1 3 mod 18").unwrap())); assert!(one_1.call_compare_base_error(&Zq::from((3, 18))).is_some()); - assert!(one_1 - .call_compare_base_error(&PolyOverZq::from_str("1 3 mod 18").unwrap()) - .is_some()); + assert!( + one_1 + .call_compare_base_error(&PolyOverZq::from_str("1 3 mod 18").unwrap()) + .is_some() + ); } } diff --git a/src/integer_mod_q/poly_over_zq/from.rs b/src/integer_mod_q/poly_over_zq/from.rs index c07734a8..9f9470b0 100644 --- a/src/integer_mod_q/poly_over_zq/from.rs +++ b/src/integer_mod_q/poly_over_zq/from.rs @@ -13,7 +13,7 @@ use crate::{ error::{MathError, StringConversionError}, integer::{PolyOverZ, Z}, - integer_mod_q::{modulus::Modulus, ModulusPolynomialRingZq, PolyOverZq, Zq}, + integer_mod_q::{ModulusPolynomialRingZq, PolyOverZq, Zq, modulus::Modulus}, macros::for_others::implement_for_owned, }; use flint_sys::fmpz_mod_poly::{ @@ -298,7 +298,7 @@ impl FromStr for PolyOverZq { None => { return Err(StringConversionError::InvalidStringToPolyModulusInput( s.to_owned(), - ))? + ))?; } }; @@ -586,7 +586,9 @@ mod test_from_str { /// Ensure that the input works with strings that have to be trimmed #[test] fn trim_input() { - let poly = PolyOverZq::from_str(" 4 1 2 3 -4 mod 17 "); + let poly = PolyOverZq::from_str( + " 4 1 2 3 -4 mod 17 ", + ); assert!(poly.is_ok()); assert_eq!( PolyOverZq::from_str("4 1 2 3 -4 mod 17").unwrap(), diff --git a/src/integer_mod_q/poly_over_zq/get.rs b/src/integer_mod_q/poly_over_zq/get.rs index 36501f9e..12f0c2b8 100644 --- a/src/integer_mod_q/poly_over_zq/get.rs +++ b/src/integer_mod_q/poly_over_zq/get.rs @@ -51,7 +51,7 @@ impl GetCoefficient for PolyOverZq { /// To use this function safely, make sure that the selected index /// is greater or equal than `0`. unsafe fn get_coeff_unchecked(&self, index: i64) -> Zq { - let out_z: Z = self.get_coeff_unchecked(index); + let out_z: Z = unsafe { self.get_coeff_unchecked(index) }; Zq::from((out_z, &self.modulus)) } } diff --git a/src/integer_mod_q/poly_over_zq/norm.rs b/src/integer_mod_q/poly_over_zq/norm.rs index 8c5fdbda..b207fa3a 100644 --- a/src/integer_mod_q/poly_over_zq/norm.rs +++ b/src/integer_mod_q/poly_over_zq/norm.rs @@ -11,7 +11,7 @@ use crate::{ integer::Z, - integer_mod_q::{fmpz_mod_helpers::length, PolyOverZq}, + integer_mod_q::{PolyOverZq, fmpz_mod_helpers::length}, traits::{GetCoefficient, Pow}, }; use std::cmp::max; diff --git a/src/integer_mod_q/poly_over_zq/serialize.rs b/src/integer_mod_q/poly_over_zq/serialize.rs index cc3f504d..cfc74c15 100644 --- a/src/integer_mod_q/poly_over_zq/serialize.rs +++ b/src/integer_mod_q/poly_over_zq/serialize.rs @@ -15,9 +15,9 @@ use super::PolyOverZq; use crate::macros::serialize::{deserialize, serialize}; use core::fmt; use serde::{ + Deserialize, Serialize, de::{Error, MapAccess, Unexpected, Visitor}, ser::SerializeStruct, - Deserialize, Serialize, }; use std::str::FromStr; diff --git a/src/integer_mod_q/poly_over_zq/set.rs b/src/integer_mod_q/poly_over_zq/set.rs index 337507a3..6161187f 100644 --- a/src/integer_mod_q/poly_over_zq/set.rs +++ b/src/integer_mod_q/poly_over_zq/set.rs @@ -86,7 +86,7 @@ impl SetCoefficient<&Zq> for PolyOverZq { /// is greater or equal than `0` and that the provided value has /// the same base so that they have a matching base. unsafe fn set_coeff_unchecked(&mut self, index: i64, value: &Zq) { - self.set_coeff_unchecked(index, &value.value) + unsafe { self.set_coeff_unchecked(index, &value.value) } } } diff --git a/src/integer_mod_q/poly_over_zq/unsafe_functions.rs b/src/integer_mod_q/poly_over_zq/unsafe_functions.rs index f0b994f8..feb2c726 100644 --- a/src/integer_mod_q/poly_over_zq/unsafe_functions.rs +++ b/src/integer_mod_q/poly_over_zq/unsafe_functions.rs @@ -43,7 +43,7 @@ impl PolyOverZq { /// that Rust and our Wrapper provide. /// Thus, using functions of [`flint_sys`] can introduce memory leaks. pub unsafe fn set_fmpz_mod_poly_struct(&mut self, flint_struct: fmpz_mod_poly_struct) { - fmpz_mod_poly_clear(&mut self.poly, self.modulus.get_fmpz_mod_ctx_struct()); + unsafe { fmpz_mod_poly_clear(&mut self.poly, self.modulus.get_fmpz_mod_ctx_struct()) }; self.poly = flint_struct; } diff --git a/src/integer_mod_q/polynomial_ring_zq.rs b/src/integer_mod_q/polynomial_ring_zq.rs index 3d205b75..6286181f 100644 --- a/src/integer_mod_q/polynomial_ring_zq.rs +++ b/src/integer_mod_q/polynomial_ring_zq.rs @@ -9,12 +9,12 @@ //! [`PolynomialRingZq`] is a type of ring over PolyOverZq/f(X). //! Where f(X) is a [`PolyOverZq`](crate::integer_mod_q::PolyOverZq). //! This implementation uses the [FLINT](https://flintlib.org/) library. -//! -//! For **DEVELOPERS**: Many functions assume that the [`PolynomialRingZq`] instances are reduced. -//! To avoid unnecessary checks and reductions, always return canonical/reduced -//! values. The end-user should be unable to obtain a non-reduced value. -//! Therefore, the DEVELOPER has to call the [`PolynomialRingZq::reduce`], whenever -//! a computation may exceed the modulus, because it is not reduced automatically + +// For **DEVELOPERS**: Many functions assume that the [`PolynomialRingZq`] instances are reduced. +// To avoid unnecessary checks and reductions, always return canonical/reduced +// values. The end-user should be unable to obtain a non-reduced value. +// Therefore, the DEVELOPER has to call the [`PolynomialRingZq::reduce`], whenever +// a computation may exceed the modulus, because it is not reduced automatically use super::ModulusPolynomialRingZq; use crate::integer::PolyOverZ; diff --git a/src/integer_mod_q/polynomial_ring_zq/cmp.rs b/src/integer_mod_q/polynomial_ring_zq/cmp.rs index dc42945c..77e1ab87 100644 --- a/src/integer_mod_q/polynomial_ring_zq/cmp.rs +++ b/src/integer_mod_q/polynomial_ring_zq/cmp.rs @@ -53,9 +53,11 @@ mod test_compare_base { assert!(one_1.compare_base(&0_u64)); assert!(one_1.call_compare_base_error(&Z::ONE).is_none()); - assert!(one_1 - .call_compare_base_error(&PolyOverZ::from_str("1 3").unwrap()) - .is_none()); + assert!( + one_1 + .call_compare_base_error(&PolyOverZ::from_str("1 3").unwrap()) + .is_none() + ); assert!(one_1.call_compare_base_error(&0_i8).is_none()); assert!(one_1.call_compare_base_error(&0_i16).is_none()); assert!(one_1.call_compare_base_error(&0_i32).is_none()); @@ -83,11 +85,15 @@ mod test_compare_base { assert!(!one_1.compare_base(&PolynomialRingZq::from(&modulus_other))); assert!(one_1.call_compare_base_error(&Zq::from((3, 18))).is_some()); - assert!(one_1 - .call_compare_base_error(&PolyOverZq::from_str("1 3 mod 18").unwrap()) - .is_some()); - assert!(one_1 - .call_compare_base_error(&PolynomialRingZq::from(&modulus_other)) - .is_some()); + assert!( + one_1 + .call_compare_base_error(&PolyOverZq::from_str("1 3 mod 18").unwrap()) + .is_some() + ); + assert!( + one_1 + .call_compare_base_error(&PolynomialRingZq::from(&modulus_other)) + .is_some() + ); } } diff --git a/src/integer_mod_q/polynomial_ring_zq/from.rs b/src/integer_mod_q/polynomial_ring_zq/from.rs index efdd6142..6c5a3d05 100644 --- a/src/integer_mod_q/polynomial_ring_zq/from.rs +++ b/src/integer_mod_q/polynomial_ring_zq/from.rs @@ -261,7 +261,7 @@ impl FromStr for PolynomialRingZq { None => { return Err(StringConversionError::InvalidStringToPolyRingZqInput( s.to_owned(), - ))? + ))?; } }; @@ -554,7 +554,9 @@ mod test_from_str { /// Ensure that the input works with strings that have to be trimmed #[test] fn trim_input() { - let poly = PolynomialRingZq::from_str(" 4 -1 0 1 1 / 4 1 2 3 -4 mod 17 "); + let poly = PolynomialRingZq::from_str( + " 4 -1 0 1 1 / 4 1 2 3 -4 mod 17 ", + ); assert!(poly.is_ok()); assert_eq!( PolynomialRingZq::from_str("4 -1 0 1 1 / 4 1 2 3 -4 mod 17").unwrap(), diff --git a/src/integer_mod_q/polynomial_ring_zq/reduce.rs b/src/integer_mod_q/polynomial_ring_zq/reduce.rs index c5f9ad86..224bf736 100644 --- a/src/integer_mod_q/polynomial_ring_zq/reduce.rs +++ b/src/integer_mod_q/polynomial_ring_zq/reduce.rs @@ -8,11 +8,11 @@ //! Implementations to reduce a [`PolynomialRingZq`] with the //! [`ModulusPolynomialRingZq`](crate::integer_mod_q::ModulusPolynomialRingZq). -//! -//! **For Developers** note: The [`ModulusPolynomialRingZq`](crate::integer_mod_q::ModulusPolynomialRingZq) -//! is not applied automatically, and has to be called in the functions individually. -//! Additionally the comparisons assume that the entries are reduced, -//! hence no reduction is performed in the check. + +// **For Developers** note: The [`ModulusPolynomialRingZq`](crate::integer_mod_q::ModulusPolynomialRingZq) +// is not applied automatically, and has to be called in the functions individually. +// Additionally the comparisons assume that the entries are reduced, +// hence no reduction is performed in the check. use super::PolynomialRingZq; use flint_sys::fq::fq_reduce; diff --git a/src/integer_mod_q/z_q.rs b/src/integer_mod_q/z_q.rs index 9c0fd68c..8708a84c 100644 --- a/src/integer_mod_q/z_q.rs +++ b/src/integer_mod_q/z_q.rs @@ -13,10 +13,10 @@ //! FLINT uses a `fmpz_mod_ctx_struct` to store functions and data used for //! optimizing modulo operations. //! This struct is wrapped in [`Modulus`] for easy use. -//! -//! For **DEVELOPERS**: Many functions assume that the [`Zq`] instances are reduced. -//! To avoid unnecessary checks and reductions, always return canonical/reduced -//! values. The end-user should be unable to obtain a non-reduced value. + +// For **DEVELOPERS**: Many functions assume that the [`Zq`] instances are reduced. +// To avoid unnecessary checks and reductions, always return canonical/reduced +// values. The end-user should be unable to obtain a non-reduced value. use super::Modulus; use crate::integer::Z; diff --git a/src/integer_mod_q/z_q/fmpz_mod_helpers.rs b/src/integer_mod_q/z_q/fmpz_mod_helpers.rs index 31408124..c4de93ae 100644 --- a/src/integer_mod_q/z_q/fmpz_mod_helpers.rs +++ b/src/integer_mod_q/z_q/fmpz_mod_helpers.rs @@ -10,7 +10,7 @@ use super::Zq; use crate::{ - integer::{fmpz_helpers::distance, Z}, + integer::{Z, fmpz_helpers::distance}, traits::AsInteger, }; use flint_sys::fmpz::fmpz; @@ -50,7 +50,7 @@ pub(crate) fn length(value: &fmpz, modulus: &fmpz) -> Z { unsafe impl AsInteger for Zq { /// Documentation at [`AsInteger::into_fmpz`] unsafe fn into_fmpz(self) -> fmpz { - AsInteger::into_fmpz(self.value) + unsafe { AsInteger::into_fmpz(self.value) } } /// Documentation at [`AsInteger::get_fmpz_ref`] @@ -62,7 +62,7 @@ unsafe impl AsInteger for Zq { unsafe impl AsInteger for &Zq { /// Documentation at [`AsInteger::into_fmpz`] unsafe fn into_fmpz(self) -> fmpz { - AsInteger::into_fmpz(&self.value) + unsafe { AsInteger::into_fmpz(&self.value) } } /// Documentation at [`AsInteger::get_fmpz_ref`] diff --git a/src/integer_mod_q/z_q/get.rs b/src/integer_mod_q/z_q/get.rs index d2c29a5e..f4cea688 100644 --- a/src/integer_mod_q/z_q/get.rs +++ b/src/integer_mod_q/z_q/get.rs @@ -80,7 +80,7 @@ impl Zq { #[cfg(test)] mod test_get_representative_least_nonnegative_residue { - use super::{Zq, Z}; + use super::{Z, Zq}; /// Check whether `get_representative_least_nonnegative_residue` outputs the correct value for small values #[test] @@ -111,7 +111,7 @@ mod test_get_representative_least_nonnegative_residue { #[cfg(test)] mod test_get_representative_least_absolute_residue { - use super::{Zq, Z}; + use super::{Z, Zq}; /// Check whether `get_representative_least_absolute_residue` outputs the correct value for small values #[test] diff --git a/src/integer_mod_q/z_q/reduce.rs b/src/integer_mod_q/z_q/reduce.rs index 30730439..c107fa71 100644 --- a/src/integer_mod_q/z_q/reduce.rs +++ b/src/integer_mod_q/z_q/reduce.rs @@ -7,11 +7,11 @@ // Mozilla Foundation. See . //! Implementations to reduce a [`Z`](crate::integer::Z) with the [`Modulus`](crate::integer_mod_q::Modulus). -//! -//! **For Developers** note: The [`Modulus`](crate::integer_mod_q::Modulus) -//! is not applied automatically, and has to be called in the functions individually. -//! Additionally the comparisons assume that the entries are reduced, -//! hence no reduction is performed in the check. + +// **For Developers** note: The [`Modulus`](crate::integer_mod_q::Modulus) +// is not applied automatically, and has to be called in the functions individually. +// Additionally the comparisons assume that the entries are reduced, +// hence no reduction is performed in the check. use super::Zq; use flint_sys::fmpz_mod::fmpz_mod_set_fmpz; diff --git a/src/integer_mod_q/z_q/sample/binomial.rs b/src/integer_mod_q/z_q/sample/binomial.rs index 2c5c1c9a..4243f419 100644 --- a/src/integer_mod_q/z_q/sample/binomial.rs +++ b/src/integer_mod_q/z_q/sample/binomial.rs @@ -63,7 +63,7 @@ impl Zq { #[cfg(test)] mod test_sample_binomial { - use super::{Zq, Q, Z}; + use super::{Q, Z, Zq}; // As all major tests regarding an appropriate binomial distribution, // whether the correct interval is kept, and if the errors are thrown correctly, diff --git a/src/lib.rs b/src/lib.rs index dbb3bfac..167f837b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,32 +6,37 @@ // the terms of the Mozilla Public License Version 2.0 as published by the // Mozilla Foundation. See . -//! # What is qFALL-math? -//! qFall-math is a high level interface to the library [FLINT](https://flintlib.org/). -//! It uses the FFI [flint-sys](https://docs.rs/flint-sys/latest/flint_sys/index.html) -//! to access the functionality of FLINT. -//! qFALL-math provides a memory-safe and easy to use interface that is ideal for -//! prototyping. It supports the basic types with arbitrary precision and length: -//! - Integers which are represented as [Z](integer::Z), -//! - Residue Classes over Integers which are represented as [Zq](integer_mod_q::Zq), -//! - Rationals which are represented as [Q](rational::Q). +//! `qFALL` is a prototyping library for lattice-based cryptography. +//! `qFALL-math` yields the mathematical foundation by providing an easy to use, high-level API based on [FLINT](https://flintlib.org/) +//! as well as several additional features often used in lattice-based cryptography. +//! At a high level, it provides the following classes of datatypes: +//! - Integer-based types such as [`Z`](integer::Z), [`MatZ`](integer::MatZ), [`PolyOverZ`](integer::PolyOverZ), [`MatPolyOverZ`](integer::MatPolyOverZ), +//! - Residue Classes over Integers such as [`Zq`](integer_mod_q::Zq), [`MatZq`](integer_mod_q::MatZq), [`PolyOverZq`](integer_mod_q::PolyOverZq), [`PolynomialRingZq`](integer_mod_q::PolynomialRingZq), [`MatPolynomialRingZq`](integer_mod_q::MatPolynomialRingZq), [`NTTPolynomialRingZq`](integer_mod_q::NTTPolynomialRingZq), [`MatNTTPolynomialRingZq`](integer_mod_q::MatNTTPolynomialRingZq), +//! - Rationals such as [Q](rational::Q), [`MatQ`](rational::MatQ), [`PolyOverQ`](rational::PolyOverQ). //! -//! Each of these types also has a matrix and a polynomial version. -//! Further a polynomial ring is supported with -//! [PolynomialRingZq](integer_mod_q::PolynomialRingZq). +//! The `qFALL` project contains two more crates called [`qFALL-tools`](https://crates.io/crates/qfall-tools) +//! and [`qFALL-schemes`](https://github.com/qfall/schemes) to support prototyping. +//! - Find further information on [our website](https://qfall.github.io/). +//! - We recommend [our tutorial](https://qfall.github.io/book) to start working with qFALL. //! -//! 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 . //! -//! ## Tutorial + Website -//! You can find a dedicated [tutorial](https://qfall.github.io/book/index.html) to qFALL-math on our [website](https://qfall.github.io/). -//! The tutorial explains the basic steps starting from installation and -//! continues with basic usage. -//! qFALL-math is co-developed together with qFALL-crypto. -//! qFALL-crypto uses qFALL-math to implement cryptographic primitives and can act -//! as inspiration for prototyping and an intuition on how qFALL-math can be used -//! for prototyping. +//! ## Quick Example +//! ``` +//! use qfall_math::{integer_mod_q::MatZq, integer::MatZ}; +//! +//! let (n, m, q) = (256, 1024, 3329); +//! let (center, sigma) = (0.0, 8.0); +//! +//! let mat_a = MatZq::sample_uniform(n, m, q); +//! let vec_s = MatZ::sample_uniform(n, 1, 0, 2).unwrap(); +//! let vec_e = MatZ::sample_discrete_gauss(m, 1, center, sigma).unwrap(); +//! +//! // SIS-Instance: t = A * e mod q +//! let vec_t = &mat_a * &vec_e; +//! +//! // LWE-Instance: b^T = s^T * A + e^T mod q +//! let vec_b = vec_s.transpose() * mat_a + vec_e.transpose(); +//! ``` pub mod error; pub mod integer; diff --git a/src/macros/for_others.rs b/src/macros/for_others.rs index 576259d6..daea85ba 100644 --- a/src/macros/for_others.rs +++ b/src/macros/for_others.rs @@ -236,7 +236,7 @@ macro_rules! implement_for_owned { index: i64, value: $source_type, ) { - self.set_coeff_unchecked(index, &value) + unsafe { self.set_coeff_unchecked(index, &value) } } } } @@ -263,7 +263,7 @@ macro_rules! implement_for_owned { column: i64, value: $source_type, ) { - self.set_entry_unchecked(row, column, &value); + unsafe { self.set_entry_unchecked(row, column, &value) }; } } } diff --git a/src/macros/unsafe_passthrough.rs b/src/macros/unsafe_passthrough.rs index 5b8d3424..1f4b0cd9 100644 --- a/src/macros/unsafe_passthrough.rs +++ b/src/macros/unsafe_passthrough.rs @@ -123,7 +123,7 @@ macro_rules! unsafe_getter_indirect { /// that Rust and our Wrapper provide. /// Thus, using functions of [`flint_sys`] can introduce memory leaks. pub unsafe fn [](&mut self) -> &mut $attribute_type { - self.$attribute_name.$function_name() + unsafe { self.$attribute_name.$function_name() } } } } @@ -168,7 +168,7 @@ macro_rules! unsafe_setter { /// that Rust and our Wrapper provide. /// Thus, using functions of [`flint_sys`] can introduce memory leaks. pub unsafe fn [](&mut self, flint_struct: $attribute_type) { - $clear_function(&mut self.$attribute_name); + unsafe { $clear_function(&mut self.$attribute_name) }; self.$attribute_name = flint_struct; } @@ -214,7 +214,7 @@ macro_rules! unsafe_setter_indirect { /// that Rust and our Wrapper provide. /// Thus, using functions of [`flint_sys`] can introduce memory leaks. pub unsafe fn [](&mut self, flint_struct: $attribute_type) { - self.$attribute_name.$function_name(flint_struct) + unsafe { self.$attribute_name.$function_name(flint_struct) } } } } diff --git a/src/rational.rs b/src/rational.rs index 5ab3b672..a227fa40 100644 --- a/src/rational.rs +++ b/src/rational.rs @@ -6,6 +6,8 @@ // the terms of the Mozilla Public License Version 2.0 as published by the // Mozilla Foundation. See . +//! Rational-based types based on [`Q`]. +//! //! This module contains the type [`Q`] for rationals with arbitrary length and //! constructions over it. //! Each struct provides examples regarding usage. diff --git a/src/rational/mat_q.rs b/src/rational/mat_q.rs index 51cb4915..e97fc104 100644 --- a/src/rational/mat_q.rs +++ b/src/rational/mat_q.rs @@ -8,10 +8,10 @@ //! [`MatQ`] is a type of matrix with rational entries of arbitrary length. //! This implementation uses the [FLINT](https://flintlib.org/) library. -//! -//! For **DEVELOPERS**: Many functions assume that the [`MatQ`] instances are reduced. -//! To avoid unnecessary checks and reductions, always return canonical/reduced -//! values. The end-user should be unable to obtain a non-reduced value. + +// For **DEVELOPERS**: Many functions assume that the [`MatQ`] instances are reduced. +// To avoid unnecessary checks and reductions, always return canonical/reduced +// values. The end-user should be unable to obtain a non-reduced value. use crate::utils::parse::partial_string; use flint_sys::fmpq_mat::fmpq_mat_struct; diff --git a/src/rational/mat_q/serialize.rs b/src/rational/mat_q/serialize.rs index bad53832..6bb4f632 100644 --- a/src/rational/mat_q/serialize.rs +++ b/src/rational/mat_q/serialize.rs @@ -15,9 +15,9 @@ use super::MatQ; use crate::macros::serialize::{deserialize, serialize}; use core::fmt; use serde::{ + Deserialize, Serialize, de::{Error, MapAccess, Unexpected, Visitor}, ser::SerializeStruct, - Deserialize, Serialize, }; use std::str::FromStr; diff --git a/src/rational/mat_q/set.rs b/src/rational/mat_q/set.rs index 1df47a24..d8f5a77a 100644 --- a/src/rational/mat_q/set.rs +++ b/src/rational/mat_q/set.rs @@ -995,9 +995,10 @@ mod test_set_submatrix { fn submatrix_too_large() { let mut mat = MatQ::new(10, 10); - assert!(mat - .set_submatrix(0, 0, &MatQ::identity(11, 11), 0, 0, 10, 10) - .is_err()); + assert!( + mat.set_submatrix(0, 0, &MatQ::identity(11, 11), 0, 0, 10, 10) + .is_err() + ); assert!(mat.set_submatrix(1, 2, &mat.clone(), 0, 0, 9, 9).is_err()); } diff --git a/src/rational/poly_over_q.rs b/src/rational/poly_over_q.rs index afac2c9b..03977fa2 100644 --- a/src/rational/poly_over_q.rs +++ b/src/rational/poly_over_q.rs @@ -9,11 +9,11 @@ //! [`PolyOverQ`] is a type of polynomial with arbitrarily many coefficients of type //! [`Q`](crate::rational::Q). //! This implementation uses the [FLINT](https://flintlib.org/) library. -//! -//! For **DEVELOPERS**: Many functions assume that the [`PolyOverQ`] instances -//! are reduced. To avoid unnecessary checks and reductions, always return -//! canonical/reduced values. The end-user should be unable to obtain a -//! non-reduced value. + +// For **DEVELOPERS**: Many functions assume that the [`PolyOverQ`] instances +// are reduced. To avoid unnecessary checks and reductions, always return +// canonical/reduced values. The end-user should be unable to obtain a +// non-reduced value. use flint_sys::fmpq_poly::fmpq_poly_struct; use std::fmt; diff --git a/src/rational/poly_over_q/serialize.rs b/src/rational/poly_over_q/serialize.rs index 447d635e..09e11b01 100644 --- a/src/rational/poly_over_q/serialize.rs +++ b/src/rational/poly_over_q/serialize.rs @@ -17,9 +17,9 @@ use crate::{ }; use core::fmt; use serde::{ + Deserialize, Serialize, de::{Error, MapAccess, Unexpected, Visitor}, ser::SerializeStruct, - Deserialize, Serialize, }; use std::str::FromStr; diff --git a/src/rational/q.rs b/src/rational/q.rs index e8d5f786..495b0aca 100644 --- a/src/rational/q.rs +++ b/src/rational/q.rs @@ -8,10 +8,10 @@ //! [`Q`] is a type for rationals of arbitrary length. //! This implementation uses the [FLINT](https://flintlib.org/) library. -//! -//! For **DEVELOPERS**: Many functions assume that the [`Q`] instances are reduced. -//! To avoid unnecessary checks and reductions, always return canonical/reduced -//! values. The end-user should be unable to obtain a non-reduced value. + +// For **DEVELOPERS**: Many functions assume that the [`Q`] instances are reduced. +// To avoid unnecessary checks and reductions, always return canonical/reduced +// values. The end-user should be unable to obtain a non-reduced value. use flint_sys::fmpq::fmpq; use std::fmt; diff --git a/src/rational/q/arithmetic/logarithm.rs b/src/rational/q/arithmetic/logarithm.rs index 3ed20dc5..70013459 100644 --- a/src/rational/q/arithmetic/logarithm.rs +++ b/src/rational/q/arithmetic/logarithm.rs @@ -91,7 +91,7 @@ impl Q { #[cfg(test)] mod test_natural_ln { use crate::rational::Q; - use std::f64::consts::{LN_10, LN_2}; + use std::f64::consts::{LN_2, LN_10}; /// Ensure that an error is returned if `self` is too small #[test] diff --git a/src/rational/q/from.rs b/src/rational/q/from.rs index 843a488c..d7da4aad 100644 --- a/src/rational/q/from.rs +++ b/src/rational/q/from.rs @@ -723,7 +723,7 @@ mod test_from_z { mod test_from_float { use super::Q; use std::{ - f64::consts::{E, LN_10, LN_2}, + f64::consts::{E, LN_2, LN_10}, str::FromStr, }; diff --git a/src/rational/q/serialize.rs b/src/rational/q/serialize.rs index 453bf86a..ab2e5d73 100644 --- a/src/rational/q/serialize.rs +++ b/src/rational/q/serialize.rs @@ -15,9 +15,9 @@ use super::Q; use crate::macros::serialize::{deserialize, serialize}; use core::fmt; use serde::{ + Deserialize, Serialize, de::{Error, MapAccess, Unexpected, Visitor}, ser::SerializeStruct, - Deserialize, Serialize, }; use std::str::FromStr; diff --git a/src/traits.rs b/src/traits.rs index 87a1c395..260e39fc 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -6,6 +6,8 @@ // the terms of the Mozilla Public License Version 2.0 as published by the // Mozilla Foundation. See . +//! Definitions of traits implemented and used in this crate. +//! //! This module contains basic traits for this library. These include //! specific traits for matrices and polynomials. @@ -316,7 +318,7 @@ where /// of the matrix. If it is not, memory leaks, unexpected panics, etc. might /// occur. unsafe fn get_row_unchecked(&self, row: i64) -> Self { - self.get_submatrix_unchecked(row, row + 1, 0, self.get_num_columns()) + unsafe { self.get_submatrix_unchecked(row, row + 1, 0, self.get_num_columns()) } } /// Outputs the column vector of the specified column. @@ -351,7 +353,7 @@ where /// of the matrix. If it is not, memory leaks, unexpected panics, etc. might /// occur. unsafe fn get_column_unchecked(&self, column: i64) -> Self { - self.get_submatrix_unchecked(0, self.get_num_rows(), column, column + 1) + unsafe { self.get_submatrix_unchecked(0, self.get_num_rows(), column, column + 1) } } /// Returns a deep copy of the submatrix defined by the given parameters. @@ -771,14 +773,14 @@ where evaluate_indices_for_matrix(other, row_other_end, col_other_end)?; assert!( - row_other_end >= row_other_start, - "The number of rows must be positive, i.e. row_other_end ({row_other_end}) must be greater or equal row_other_start ({row_other_start})" - ); + row_other_end >= row_other_start, + "The number of rows must be positive, i.e. row_other_end ({row_other_end}) must be greater or equal row_other_start ({row_other_start})" + ); assert!( - col_other_end >= col_other_start, - "The number of columns must be positive, i.e. col_other_end ({col_other_end}) must be greater or equal col_other_start ({col_other_start})" - ); + col_other_end >= col_other_start, + "The number of columns must be positive, i.e. col_other_end ({col_other_end}) must be greater or equal col_other_start ({col_other_start})" + ); // increase both values to have an inclusive capturing of the matrix entries let nr_rows = row_other_end - row_other_start; diff --git a/src/utils.rs b/src/utils.rs index 163c9441..738250a1 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -6,7 +6,7 @@ // the terms of the Mozilla Public License Version 2.0 as published by the // Mozilla Foundation. See . -//! This module contains common functions that are used by several crates. +//! Common functions useful across several datatypes and crates. //! //! This can include functions to pre-process inputs //! and similar tasks. diff --git a/src/utils/dimensions.rs b/src/utils/dimensions.rs index ec1eaf33..4b6055f4 100644 --- a/src/utils/dimensions.rs +++ b/src/utils/dimensions.rs @@ -31,7 +31,7 @@ pub(crate) fn find_matrix_dimensions(matrix: &Vec>) -> Result<(i64, i6 _ => { return Err(StringConversionError::InvalidMatrix( "Number of rows is too large (must fit into [`i64`]).".to_owned(), - ))? + ))?; } }; diff --git a/src/utils/index.rs b/src/utils/index.rs index b6d2fdb9..ac853f92 100644 --- a/src/utils/index.rs +++ b/src/utils/index.rs @@ -43,7 +43,7 @@ pub fn evaluate_index(index: impl TryInto + Display) -> Result + Display) -> Result( return Err(MathError::OutOfBounds( "fit into a i64".to_owned(), "unknown for performance reasons".to_owned(), - )) + )); } }; @@ -180,7 +180,7 @@ pub fn evaluate_indices_for_matrix( return Err(MathError::OutOfBounds( "fit into a i64".to_owned(), "unknown for performance reasons".to_owned(), - )) + )); } }; diff --git a/src/utils/sample/binomial.rs b/src/utils/sample/binomial.rs index 0d34a4d1..f4f5b9c0 100644 --- a/src/utils/sample/binomial.rs +++ b/src/utils/sample/binomial.rs @@ -65,7 +65,7 @@ pub(crate) fn sample_binomial(n: &Z, p: &Q) -> Result { #[cfg(test)] mod test_sample_binomial { - use super::{sample_binomial, Q, Z}; + use super::{Q, Z, sample_binomial}; /// Ensures that the doc tests works correctly. #[test] diff --git a/src/utils/sample/discrete_gauss.rs b/src/utils/sample/discrete_gauss.rs index ecb088d4..3f968758 100644 --- a/src/utils/sample/discrete_gauss.rs +++ b/src/utils/sample/discrete_gauss.rs @@ -157,11 +157,16 @@ impl DiscreteGaussianIntegerSampler { let mut table = HashMap::new(); if lookup_table_setting == LookupTableSetting::FillOnTheFly && interval_size > u16::MAX { - println!("WARNING: A completely filled lookup table will exceed 2^16 entries. You should reconsider your sampling method for discrete Gaussians.") + println!( + "WARNING: A completely filled lookup table will exceed 2^16 entries. You should reconsider your sampling method for discrete Gaussians." + ) } if lookup_table_setting == LookupTableSetting::Precompute { - assert!(interval_size <= u16::MAX, "The interval size {interval_size} for discrete Gaussian sampling exceeds 2^16 entries. You should reconsider your sampling method."); + assert!( + interval_size <= u16::MAX, + "The interval size {interval_size} for discrete Gaussian sampling exceeds 2^16 entries. You should reconsider your sampling method." + ); let mut i = lower_bound.clone(); while i <= upper_bound { @@ -369,11 +374,11 @@ pub(crate) fn sample_d_precomputed_gso( as they do not have the same number of columns." ); if center.get_num_rows() != basis.get_num_rows() { - return Err( MathError::MismatchingMatrixDimension(format!( + return Err(MathError::MismatchingMatrixDimension(format!( "sample_d requires center and basis to have the same number of columns, but they were {} and {}.", center.get_num_rows(), - basis.get_num_rows()) - )); + basis.get_num_rows() + ))); } if !center.is_column_vector() { Err(StringConversionError::InvalidMatrix(format!( @@ -479,20 +484,24 @@ mod test_discrete_gaussian_integer_sampler { fn invalid_gaussian_parameter() { let center = Q::ZERO; - assert!(DiscreteGaussianIntegerSampler::init( - ¢er, - &Q::MINUS_ONE, - 6.0, - LookupTableSetting::FillOnTheFly - ) - .is_err()); - assert!(DiscreteGaussianIntegerSampler::init( - ¢er, - &Q::from(i64::MIN), - 6.0, - LookupTableSetting::FillOnTheFly - ) - .is_err()); + assert!( + DiscreteGaussianIntegerSampler::init( + ¢er, + &Q::MINUS_ONE, + 6.0, + LookupTableSetting::FillOnTheFly + ) + .is_err() + ); + assert!( + DiscreteGaussianIntegerSampler::init( + ¢er, + &Q::from(i64::MIN), + 6.0, + LookupTableSetting::FillOnTheFly + ) + .is_err() + ); } /// Checks whether `sample_z` returns an error if `n < 0`. @@ -501,26 +510,30 @@ mod test_discrete_gaussian_integer_sampler { let center = Q::MINUS_ONE; let gaussian_parameter = Q::ONE; - assert!(DiscreteGaussianIntegerSampler::init( - ¢er, - &gaussian_parameter, - -0.1, - LookupTableSetting::FillOnTheFly - ) - .is_err()); - assert!(DiscreteGaussianIntegerSampler::init( - ¢er, - &gaussian_parameter, - i64::MIN, - LookupTableSetting::FillOnTheFly - ) - .is_err()); + assert!( + DiscreteGaussianIntegerSampler::init( + ¢er, + &gaussian_parameter, + -0.1, + LookupTableSetting::FillOnTheFly + ) + .is_err() + ); + assert!( + DiscreteGaussianIntegerSampler::init( + ¢er, + &gaussian_parameter, + i64::MIN, + LookupTableSetting::FillOnTheFly + ) + .is_err() + ); } } #[cfg(test)] mod test_gaussian_function { - use super::{gaussian_function, Q, Z}; + use super::{Q, Z, gaussian_function}; use crate::traits::Distance; /// Ensures that the doc test would run properly. @@ -690,10 +703,12 @@ mod test_sample_d { ); // check whether last vector is zero, i.e. was linearly dependent and part of lattice assert!(hnf_basis_concat_sample.get_column(2).unwrap().is_zero()); - assert!(hnf_basis_concat_sample_prec - .get_column(2) - .unwrap() - .is_zero()); + assert!( + hnf_basis_concat_sample_prec + .get_column(2) + .unwrap() + .is_zero() + ); } /// Checks whether `sample_d` returns an error if the gaussian parameter `s < 0`. diff --git a/src/utils/sample/uniform.rs b/src/utils/sample/uniform.rs index 82be11a2..6a134b3f 100644 --- a/src/utils/sample/uniform.rs +++ b/src/utils/sample/uniform.rs @@ -11,7 +11,7 @@ use crate::{error::MathError, integer::Z}; use flint_sys::fmpz::{fmpz_addmul_ui, fmpz_set_ui}; -use rand::{rngs::ThreadRng, RngCore}; +use rand::{RngCore, rngs::ThreadRng}; /// Enables uniformly random sampling a [`Z`] in `[0, interval_size)`. ///