From a6b9ab84b457a9f54cfa4d83b7265453cd4bf079 Mon Sep 17 00:00:00 2001 From: jnsiemer Date: Tue, 18 Nov 2025 22:04:12 +0000 Subject: [PATCH 01/10] First draft of new Readme containing todos --- README.md | 156 +++++++++++++++++++----------------------------------- 1 file changed, 55 insertions(+), 101 deletions(-) diff --git a/README.md b/README.md index ac6618bcb..175e42b51 100644 --- a/README.md +++ b/README.md @@ -1,128 +1,82 @@ # qFALL-math - [![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. +[![Pipeline](https://github.com/qfall/math/actions/workflows/push.yml/badge.svg)](https://github.com/qfall/math/actions/workflows/push.yml) +[![License: MPL 2.0](https://img.shields.io/badge/License-MPL_2.0-blue.svg)](https://opensource.org/licenses/MPL-2.0) -## 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. +The `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. ## Quick-Start - -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 - +To use this crate, make sure that `m4`, a C-compiler such as `gcc`, and `make` are installed by running ```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/). +- We recommend [our tutorial](https://qfall.github.io/book) to start working with qFALL. +- Read the [documentation of this crate](TODO). -### 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`](TODO_Link_to_documentation): Represents $\mathbb Z$. +- [`MatZ`](TODO_Link_to_documentation): Represents matrices over $\mathbb Z$. +- [`PolyOverZ`](TODO_Link_to_documentation): Represents polynomials with coefficients over $\mathbb Z$. +- [`MatPolyOverZ`](TODO_Link_to_documentation): Represents matrices of polynomials with coefficients over $\mathbb Z$. ### Integers mod q - -- [`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). - -```rust -use qfall_math::integer_mod_q::Zq; -use qfall_math::integer_mod_q::Modulus; - -let modulus = Modulus::from(24); -let a = Zq::from((42, &modulus)); -let b = Zq::from((17, &modulus)); - -let res_add: Zq = &a + &b; -let res_sub: Zq = a - 10; -let res_mul: Zq = 3 * b; -``` +- [`Zq`](TODO_Link_to_documentation): Represents $\mathbb Z_q$. +- [`MatZq`](TODO_Link_to_documentation): Represents matrices over $\mathbb Z_q$. +- [`PolyOverZq`](TODO_Link_to_documentation): Represents polynomials with coefficients over $\mathbb Z_q$. +- [`PolynomialRingZq`](TODO_Link_to_documentation): Represents quotient rings $\mathbb Z_q[X]/f(X)$. +- [`MatPolynomialRingZq`](TODO_Link_to_documentation): Represents matrices over quotient rings $\mathbb Z_q[X]/f(X)$. +- [`NTTPolynomialRingZq`](TODO_Link_to_documentation): Represents quotient rings $\mathbb Z_q[X]/f(X)$ in NTT form. +- [`MatNTTPolynomialRingZq`](TODO_Link_to_documentation): Represents matrices over quotient rings $\mathbb Z_q[X]/f(X)$ in NTT form. ### Rationals +- [`Q`](TODO_Link_to_documentation): Represents $\mathbb Q$. +- [`MatQ`](TODO_Link_to_documentation): Represents matrices over $\mathbb Q$. +- [`PolyOverQ`](TODO_Link_to_documentation): Represents polynomials with coefficients over $\mathbb Q$. -- [`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$. - -```rust -use qfall_math::rational::Q; - -let a = Q::from((17, 19)); -let b = Q::from(0.5); +## Bugs +Please report bugs through the [GitHub issue tracker](https://github.com/qfall/math/issues). -let res_add: Q = &a + &b; -let res_sub: Q = a - 10.5; -let res_mul: Q = 3 * b; -``` - -## External Libraries - -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](TODO_Contribute_file) 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} -} +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** which can be found [here](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. From b988cf1b283ddad8a25ea8b885fc035849dbe56a Mon Sep 17 00:00:00 2001 From: jnsiemer Date: Wed, 19 Nov 2025 09:15:04 +0000 Subject: [PATCH 02/10] Add example to readme --- README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 175e42b51..2c700774f 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,24 @@ Arithmetic operations, comparisons, and conversions are supported across several - [`MatQ`](TODO_Link_to_documentation): Represents matrices over $\mathbb Q$. - [`PolyOverQ`](TODO_Link_to_documentation): Represents polynomials with coefficients over $\mathbb Q$. +## Quick Example +```rust +use qfall_math::{integer_mod_q::MatZq, integer::MatZ}; + +# parameters: nr_rows, nr_columns, modulus +let mat_a = MatZq::sample_uniform(2, 3, 257); +# parameters: nr_rows, nr_columns, lower_bound, upper_bound +let vec_s = MatZ::sample_uniform(1, 2, 0, 2); +# parameters: nr_rows, nr_columns, center, Gaussian parameter +let vec_e = MatZ::sample_discrete_gauss(1, 3, 0, 4.0); + +# SIS-instance: t = A * e^T mod 257 +let vec_t = mat_a * vec_e.transpose(); + +# LWE-instance: b = s * A + e mod 257 +let vec_b = vec_s * mat_a + vec_e; +``` + ## Bugs Please report bugs through the [GitHub issue tracker](https://github.com/qfall/math/issues). @@ -78,5 +96,5 @@ Furthermore, we utilized [serde](https://crates.io/crates/serde) and [serde_json ## License -This library is distributed under the **Mozilla Public License Version 2.0** which can be found [here](https://github.com/qfall/math/blob/dev/LICENSE). +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. From 3b681c638081f8574e6de4071be9adc1ba78bb0b Mon Sep 17 00:00:00 2001 From: jnsiemer Date: Sat, 22 Nov 2025 00:28:16 +0000 Subject: [PATCH 03/10] Preparation for publication --- Cargo.toml | 17 +++++++++--- README.md | 12 ++++++--- benches/classic_crypto.rs | 54 +++++++++++++++++++-------------------- 3 files changed, 48 insertions(+), 35 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 70cb48052..4f9fbd2e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,16 @@ [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" +license-file = "LICENSE" +keywords = ["math", "prototype", "lattice", "cryptography"] +categories = ["cryptography", "development-tools::build-utils", "development-tools::profiling", "development-tools::testing", "mathematics"] autobenches = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -11,12 +20,12 @@ criterion = { version = "0.7", 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 2c700774f..6ffbcd6f8 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ # qFALL-math -[![made-with-rust](https://img.shields.io/badge/Made%20with-Rust-1f425f.svg)](https://www.rust-lang.org/) -[![Pipeline](https://github.com/qfall/math/actions/workflows/push.yml/badge.svg)](https://github.com/qfall/math/actions/workflows/push.yml) -[![License: MPL 2.0](https://img.shields.io/badge/License-MPL_2.0-blue.svg)](https://opensource.org/licenses/MPL-2.0) +[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://opensource.org/licenses/MPL-2.0) `qFALL` is a prototyping library for lattice-based constructions. The `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. @@ -15,9 +18,10 @@ Then, add you can add this crate to your project by executing the following comm ```bash cargo add qfall-math ``` +This crate requires `rustc --version >= 1.85`. As it depends on FLINT, this crate requires a Linux or Mac operating system to compile. - Find further information on [our website](https://qfall.github.io/). - We recommend [our tutorial](https://qfall.github.io/book) to start working with qFALL. -- Read the [documentation of this crate](TODO). +- Read the [documentation of this crate](https://docs.rs/qfall-math). ## What does qFALL-math offer? We would like to point out a few supported features which are specifically important for lattice-based cryptography. diff --git a/benches/classic_crypto.rs b/benches/classic_crypto.rs index 7a47a5aed..b5bfc4271 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, ); From 184603d66afc358f81c118738ed5b7d6cd0d37de Mon Sep 17 00:00:00 2001 From: jnsiemer Date: Sat, 22 Nov 2025 08:21:39 +0000 Subject: [PATCH 04/10] Consequences of Rust edition bump --- Cargo.toml | 7 +- benches/matrix_arith.rs | 2 +- src/integer.rs | 2 +- src/integer/mat_poly_over_z/cmp.rs | 8 +- .../mat_poly_over_z/coefficient_embedding.rs | 2 +- src/integer/mat_poly_over_z/reduce.rs | 2 +- src/integer/mat_poly_over_z/serialize.rs | 2 +- src/integer/mat_poly_over_z/set.rs | 7 +- src/integer/mat_z/arithmetic/div.rs | 4 +- src/integer/mat_z/sample/discrete_gauss.rs | 4 +- src/integer/mat_z/serialize.rs | 2 +- src/integer/mat_z/set.rs | 7 +- src/integer/mat_z/vector/norm.rs | 2 +- src/integer/poly_over_z/fmpz_poly_helpers.rs | 4 +- src/integer/poly_over_z/reduce.rs | 2 +- src/integer/poly_over_z/serialize.rs | 2 +- src/integer/z/arithmetic/logarithm.rs | 2 +- src/integer/z/fmpz_helpers.rs | 18 ++-- src/integer/z/serialize.rs | 2 +- src/integer_mod_q.rs | 2 +- .../arithmetic/mul.rs | 6 +- .../mat_ntt_polynomial_ring_zq/cmp.rs | 48 ++++++---- .../arithmetic/mul_scalar.rs | 8 +- .../mat_polynomial_ring_zq/cmp.rs | 48 ++++++---- .../coefficient_embedding.rs | 2 +- .../mat_polynomial_ring_zq/from.rs | 2 +- .../mat_polynomial_ring_zq/get.rs | 11 ++- .../mat_polynomial_ring_zq/reduce.rs | 2 +- .../mat_polynomial_ring_zq/set.rs | 7 +- src/integer_mod_q/mat_zq/cmp.rs | 8 +- src/integer_mod_q/mat_zq/from.rs | 2 +- src/integer_mod_q/mat_zq/get.rs | 2 +- .../mat_zq/sample/discrete_gauss.rs | 4 +- src/integer_mod_q/mat_zq/serialize.rs | 2 +- src/integer_mod_q/mat_zq/set.rs | 7 +- src/integer_mod_q/mat_zq/solve.rs | 4 +- .../mat_zq/vector/dot_product.rs | 2 +- src/integer_mod_q/modulus/fmpz_helpers.rs | 4 +- src/integer_mod_q/modulus/serialize.rs | 2 +- .../modulus_polynomial_ring_zq/from.rs | 14 +-- .../modulus_polynomial_ring_zq/get.rs | 2 +- .../modulus_polynomial_ring_zq/ntt_basis.rs | 2 +- .../modulus_polynomial_ring_zq/serialize.rs | 2 +- .../ntt_basis_polynomial_ring_zq/inv_ntt.rs | 2 +- .../ntt_basis_polynomial_ring_zq/ntt.rs | 2 +- src/integer_mod_q/ntt_polynomial_ring_zq.rs | 2 +- .../ntt_polynomial_ring_zq/cmp.rs | 24 +++-- src/integer_mod_q/poly_over_zq/cmp.rs | 16 ++-- src/integer_mod_q/poly_over_zq/from.rs | 8 +- src/integer_mod_q/poly_over_zq/get.rs | 2 +- src/integer_mod_q/poly_over_zq/norm.rs | 2 +- src/integer_mod_q/poly_over_zq/serialize.rs | 2 +- src/integer_mod_q/poly_over_zq/set.rs | 2 +- .../poly_over_zq/unsafe_functions.rs | 2 +- src/integer_mod_q/polynomial_ring_zq/cmp.rs | 24 +++-- src/integer_mod_q/polynomial_ring_zq/from.rs | 6 +- src/integer_mod_q/z_q/fmpz_mod_helpers.rs | 6 +- src/integer_mod_q/z_q/get.rs | 4 +- src/integer_mod_q/z_q/sample/binomial.rs | 2 +- src/macros/for_others.rs | 4 +- src/macros/unsafe_passthrough.rs | 6 +- src/rational/mat_q/serialize.rs | 2 +- src/rational/mat_q/set.rs | 7 +- src/rational/poly_over_q/serialize.rs | 2 +- src/rational/q/arithmetic/logarithm.rs | 2 +- src/rational/q/from.rs | 2 +- src/rational/q/serialize.rs | 2 +- src/traits.rs | 16 ++-- src/utils/dimensions.rs | 2 +- src/utils/index.rs | 10 +- src/utils/sample/binomial.rs | 2 +- src/utils/sample/discrete_gauss.rs | 91 +++++++++++-------- src/utils/sample/uniform.rs | 2 +- 73 files changed, 301 insertions(+), 229 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4f9fbd2e6..9c636597e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,14 +7,11 @@ 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" -license-file = "LICENSE" +license = "MPL-2.0" keywords = ["math", "prototype", "lattice", "cryptography"] -categories = ["cryptography", "development-tools::build-utils", "development-tools::profiling", "development-tools::testing", "mathematics"] +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"] } flint-sys = "0.7.3" diff --git a/benches/matrix_arith.rs b/benches/matrix_arith.rs index e22dde789..385e496a9 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/integer.rs b/src/integer.rs index 7fb5c2344..ae132614f 100644 --- a/src/integer.rs +++ b/src/integer.rs @@ -21,5 +21,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 c5f86977d..1771fa550 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 b3ef89ea7..0f2c0bfd6 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 609204f85..64b1d7564 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 a25e564d3..8d746146b 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 ba5c2b443..2de30a943 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 565e5facf..1c58e9776 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 f02e49283..cd60980bc 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 fd806a1c5..7ba0e0267 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 7de527acf..ac055dd7a 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 c5510c61f..d6cb76ba4 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 eef5f52f3..6847fd8dd 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 81f1de4db..57714fe32 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 6cbdaf6d6..bdc91d794 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 45eac7a43..4eb9c51e7 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 fe25dd795..1732d7373 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 157a21b99..d7417c96c 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 ccd321790..6a619960c 100644 --- a/src/integer_mod_q.rs +++ b/src/integer_mod_q.rs @@ -39,5 +39,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 109659de8..95df66ecc 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 a3c48eb57..b5000dd4e 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 18725a7e7..3d07a9620 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 156e8f788..731ced7c6 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 6f481cf81..00a0ddfc8 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 5e7949732..931f207a0 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 6ca754845..3fa21585c 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 6125e8262..76fd70447 100644 --- a/src/integer_mod_q/mat_polynomial_ring_zq/reduce.rs +++ b/src/integer_mod_q/mat_polynomial_ring_zq/reduce.rs @@ -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 193dedfe8..f9540747e 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/cmp.rs b/src/integer_mod_q/mat_zq/cmp.rs index cc117c148..6812605d0 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 07757f4a3..68e53a786 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 97e20454b..9b1f6b387 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 cd68d3925..ff899ccca 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 923823ef9..902c67811 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 94b98c5fd..f2334e7d7 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 fc549c502..6490184a1 100644 --- a/src/integer_mod_q/mat_zq/solve.rs +++ b/src/integer_mod_q/mat_zq/solve.rs @@ -638,7 +638,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 +669,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 afc4a2ee7..04d7df4cb 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 f8490f250..6b770df29 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 795a5e263..0b9e89517 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 4f9929600..e11710635 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 56722efa3..d2035f073 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 586f6aa3b..e2be5beb9 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 aeae6c1f9..c2321f9f9 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 c9fec0cb6..d3974a7e6 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 7f19a2f96..11fc91c77 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 4a014a7df..73b48b9e8 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 7bcb3eb18..bd8e4e62a 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/cmp.rs b/src/integer_mod_q/poly_over_zq/cmp.rs index f727cc61a..e309a7c6f 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 c07734a8c..9f9470b08 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 36501f9e0..12f0c2b86 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 8c5fdbdad..b207fa3a0 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 cc3f504de..cfc74c15f 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 337507a32..6161187f0 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 f0b994f80..feb2c726f 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/cmp.rs b/src/integer_mod_q/polynomial_ring_zq/cmp.rs index dc42945c2..77e1ab87b 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 efdd61427..6c5a3d05e 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/z_q/fmpz_mod_helpers.rs b/src/integer_mod_q/z_q/fmpz_mod_helpers.rs index 314081246..c4de93aeb 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 d2c29a5ec..f4cea6884 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/sample/binomial.rs b/src/integer_mod_q/z_q/sample/binomial.rs index 2c5c1c9a4..4243f4190 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/macros/for_others.rs b/src/macros/for_others.rs index 576259d62..daea85ba9 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 5b8d3424f..1f4b0cd94 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/mat_q/serialize.rs b/src/rational/mat_q/serialize.rs index bad53832a..6bb4f632f 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 1df47a244..d8f5a77a7 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/serialize.rs b/src/rational/poly_over_q/serialize.rs index 447d635e7..09e11b015 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/arithmetic/logarithm.rs b/src/rational/q/arithmetic/logarithm.rs index 3ed20dc5e..700134592 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 843a488c9..d7da4aadd 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 453bf86a5..ab2e5d739 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 87a1c395c..4c6e87402 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -316,7 +316,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 +351,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 +771,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/dimensions.rs b/src/utils/dimensions.rs index ec1eaf330..4b6055f4e 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 b6d2fdb94..ac853f922 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 0d34a4d11..f4f5b9c00 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 ecb088d40..3f968758e 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 82be11a2b..6a134b3fd 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)`. /// From a15f0e47783151a03ac664319d33523f3077d373 Mon Sep 17 00:00:00 2001 From: jnsiemer Date: Sat, 22 Nov 2025 09:01:00 +0000 Subject: [PATCH 05/10] Insert links in readme --- README.md | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 6ffbcd6f8..0087220e2 100644 --- a/README.md +++ b/README.md @@ -3,14 +3,17 @@ [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://opensource.org/licenses/MPL-2.0) +[build](https://github.com/qfall/math/actions/workflows/push.yml) +[license](https://github.com/qfall/math/blob/dev/LICENSE) `qFALL` is a prototyping library for lattice-based constructions. -The `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 `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 -To use this crate, make sure that `m4`, a C-compiler such as `gcc`, and `make` are installed by running +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. + +Furthermore, it's required that `m4`, a C-compiler such as `gcc`, and `make` are installed. ```bash sudo apt-get install m4 gcc make ``` @@ -18,10 +21,9 @@ Then, add you can add this crate to your project by executing the following comm ```bash cargo add qfall-math ``` -This crate requires `rustc --version >= 1.85`. As it depends on FLINT, this crate requires a Linux or Mac operating system to compile. -- Find further information on [our website](https://qfall.github.io/). -- We recommend [our tutorial](https://qfall.github.io/book) to start working with qFALL. +- 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. ## What does qFALL-math offer? We would like to point out a few supported features which are specifically important for lattice-based cryptography. @@ -34,24 +36,24 @@ Furthermore, this crate simplifies the implementation of your prototype by suppo Arithmetic operations, comparisons, and conversions are supported across several types. You can find all supported data-types below. ### Integers -- [`Z`](TODO_Link_to_documentation): Represents $\mathbb Z$. -- [`MatZ`](TODO_Link_to_documentation): Represents matrices over $\mathbb Z$. -- [`PolyOverZ`](TODO_Link_to_documentation): Represents polynomials with coefficients over $\mathbb Z$. -- [`MatPolyOverZ`](TODO_Link_to_documentation): Represents matrices of polynomials with coefficients over $\mathbb Z$. +- [`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`](TODO_Link_to_documentation): Represents $\mathbb Z_q$. -- [`MatZq`](TODO_Link_to_documentation): Represents matrices over $\mathbb Z_q$. -- [`PolyOverZq`](TODO_Link_to_documentation): Represents polynomials with coefficients over $\mathbb Z_q$. -- [`PolynomialRingZq`](TODO_Link_to_documentation): Represents quotient rings $\mathbb Z_q[X]/f(X)$. -- [`MatPolynomialRingZq`](TODO_Link_to_documentation): Represents matrices over quotient rings $\mathbb Z_q[X]/f(X)$. -- [`NTTPolynomialRingZq`](TODO_Link_to_documentation): Represents quotient rings $\mathbb Z_q[X]/f(X)$ in NTT form. -- [`MatNTTPolynomialRingZq`](TODO_Link_to_documentation): Represents matrices over quotient rings $\mathbb Z_q[X]/f(X)$ in NTT form. +- [`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. ### Rationals -- [`Q`](TODO_Link_to_documentation): Represents $\mathbb Q$. -- [`MatQ`](TODO_Link_to_documentation): Represents matrices over $\mathbb Q$. -- [`PolyOverQ`](TODO_Link_to_documentation): Represents polynomials with coefficients over $\mathbb Q$. +- [`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 @@ -89,7 +91,7 @@ See [Contributing](TODO_Contribute_file) for details on how to contribute. Please use the following bibtex entry to cite [qFALL](https://qfall.github.io). ```text -Update to eprint +TODO: Update to eprint ``` ## Dependencies @@ -100,5 +102,5 @@ Furthermore, we utilized [serde](https://crates.io/crates/serde) and [serde_json ## License -This library is distributed under the [Mozilla Public License Version 2.0]((https://github.com/qfall/math/blob/dev/LICENSE)). +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. From 5bf8bd82cc9eace69a3cf9965f52205d9a8a65d3 Mon Sep 17 00:00:00 2001 From: jnsiemer Date: Sat, 22 Nov 2025 20:03:27 +0000 Subject: [PATCH 06/10] Revise example --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 0087220e2..a7373f1aa 100644 --- a/README.md +++ b/README.md @@ -59,18 +59,18 @@ Arithmetic operations, comparisons, and conversions are supported across several ```rust use qfall_math::{integer_mod_q::MatZq, integer::MatZ}; -# parameters: nr_rows, nr_columns, modulus -let mat_a = MatZq::sample_uniform(2, 3, 257); -# parameters: nr_rows, nr_columns, lower_bound, upper_bound -let vec_s = MatZ::sample_uniform(1, 2, 0, 2); -# parameters: nr_rows, nr_columns, center, Gaussian parameter -let vec_e = MatZ::sample_discrete_gauss(1, 3, 0, 4.0); - -# SIS-instance: t = A * e^T mod 257 -let vec_t = mat_a * vec_e.transpose(); - -# LWE-instance: b = s * A + e mod 257 -let vec_b = vec_s * mat_a + vec_e; +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(); ``` ## Bugs From d304ff0fe30b7f2668abb29ef52a10238a37b0bf Mon Sep 17 00:00:00 2001 From: jnsiemer Date: Sat, 22 Nov 2025 23:42:12 +0000 Subject: [PATCH 07/10] Brief pass over documentation --- src/error.rs | 34 ++++++------ src/integer.rs | 2 + src/integer_mod_q.rs | 6 +- .../mat_polynomial_ring_zq/reduce.rs | 10 ++-- src/integer_mod_q/mat_zq.rs | 8 +-- src/integer_mod_q/mat_zq/solve.rs | 11 +++- src/integer_mod_q/poly_over_zq.rs | 8 +-- src/integer_mod_q/polynomial_ring_zq.rs | 12 ++-- .../polynomial_ring_zq/reduce.rs | 10 ++-- src/integer_mod_q/z_q.rs | 8 +-- src/integer_mod_q/z_q/reduce.rs | 10 ++-- src/lib.rs | 55 ++++++++++--------- src/rational.rs | 2 + src/rational/mat_q.rs | 8 +-- src/rational/poly_over_q.rs | 10 ++-- src/rational/q.rs | 8 +-- src/traits.rs | 2 + src/utils.rs | 2 +- 18 files changed, 111 insertions(+), 95 deletions(-) diff --git a/src/error.rs b/src/error.rs index cc1271ed2..b319ccc42 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 ae132614f..bd0825adc 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. diff --git a/src/integer_mod_q.rs b/src/integer_mod_q.rs index 6a619960c..a1baf3ffb 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; 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 76fd70447..8b1c15d9d 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; diff --git a/src/integer_mod_q/mat_zq.rs b/src/integer_mod_q/mat_zq.rs index a3c94317f..d11a82108 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/solve.rs b/src/integer_mod_q/mat_zq/solve.rs index 6490184a1..52ea0b2de 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; diff --git a/src/integer_mod_q/poly_over_zq.rs b/src/integer_mod_q/poly_over_zq.rs index 3f580ff15..37c52d9fa 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/polynomial_ring_zq.rs b/src/integer_mod_q/polynomial_ring_zq.rs index 3d205b755..6286181ff 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/reduce.rs b/src/integer_mod_q/polynomial_ring_zq/reduce.rs index c5f9ad862..224bf7365 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 9c0fd68c2..8708a84c8 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/reduce.rs b/src/integer_mod_q/z_q/reduce.rs index 307304398..c107fa710 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/lib.rs b/src/lib.rs index dbb3bfac2..ba4d188b8 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). +//! +//! 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. +//! //! -//! Each of these types also has a matrix and a polynomial version. -//! Further a polynomial ring is supported with -//! [PolynomialRingZq](integer_mod_q::PolynomialRingZq). -//! -//! 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/rational.rs b/src/rational.rs index 5ab3b6720..d92eceea9 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 51cb49153..e97fc104d 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/poly_over_q.rs b/src/rational/poly_over_q.rs index afac2c9b3..03977fa28 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/q.rs b/src/rational/q.rs index e8d5f786b..495b0acac 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/traits.rs b/src/traits.rs index 4c6e87402..7939db738 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. diff --git a/src/utils.rs b/src/utils.rs index 163c94410..738250a1f 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. From f3b83ff403d9e074bd0874f0524e60d969a96f7d Mon Sep 17 00:00:00 2001 From: jnsiemer Date: Sat, 22 Nov 2025 23:50:05 +0000 Subject: [PATCH 08/10] Format --- src/error.rs | 2 +- src/integer.rs | 2 +- src/integer_mod_q.rs | 2 +- src/integer_mod_q/mat_zq/solve.rs | 2 +- src/lib.rs | 12 ++++++------ src/rational.rs | 2 +- src/traits.rs | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/error.rs b/src/error.rs index b319ccc42..b4d547e9d 100644 --- a/src/error.rs +++ b/src/error.rs @@ -7,7 +7,7 @@ // 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 diff --git a/src/integer.rs b/src/integer.rs index bd0825adc..f3843f443 100644 --- a/src/integer.rs +++ b/src/integer.rs @@ -7,7 +7,7 @@ // 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. diff --git a/src/integer_mod_q.rs b/src/integer_mod_q.rs index a1baf3ffb..e7bda860f 100644 --- a/src/integer_mod_q.rs +++ b/src/integer_mod_q.rs @@ -7,7 +7,7 @@ // 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. diff --git a/src/integer_mod_q/mat_zq/solve.rs b/src/integer_mod_q/mat_zq/solve.rs index 52ea0b2de..06dad67ec 100644 --- a/src/integer_mod_q/mat_zq/solve.rs +++ b/src/integer_mod_q/mat_zq/solve.rs @@ -48,7 +48,7 @@ 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" diff --git a/src/lib.rs b/src/lib.rs index ba4d188b8..167f837b1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,27 +13,27 @@ //! - 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). -//! +//! //! 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. -//! +//! //! //! ## 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(); //! ``` diff --git a/src/rational.rs b/src/rational.rs index d92eceea9..a227fa401 100644 --- a/src/rational.rs +++ b/src/rational.rs @@ -7,7 +7,7 @@ // 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/traits.rs b/src/traits.rs index 7939db738..260e39fcd 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -7,7 +7,7 @@ // 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. From 04c07779718270722f84fc7cca69221179ff45bf Mon Sep 17 00:00:00 2001 From: jnsiemer Date: Fri, 28 Nov 2025 17:02:25 +0000 Subject: [PATCH 09/10] Update link to contributing file --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a7373f1aa..b6d719483 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ Contributors are: - Marcel Luca Schmidt - Jan Niklas Siemer -See [Contributing](TODO_Contribute_file) for details on how to contribute. +See [Contributing](https://github.com/qfall/math/blob/dev/CONTRIBUTING.md) for details on how to contribute. ## Citing From 08da0b31a733e7399ade48480d02a5e03589ae99 Mon Sep 17 00:00:00 2001 From: jnsiemer Date: Tue, 9 Dec 2025 15:48:13 +0000 Subject: [PATCH 10/10] Bump criterion version --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 9c636597e..1e78c1b71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ categories = ["cryptography", "mathematics", "development-tools::build-utils", " autobenches = false [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"