qfall_math/integer_mod_q/poly_over_zq/unsafe_functions.rs
1// Copyright © 2025 Niklas Siemer
2//
3// This file is part of qFALL-math.
4//
5// qFALL-math is free software: you can redistribute it and/or modify it under
6// the terms of the Mozilla Public License Version 2.0 as published by the
7// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.
8
9//! This module contains public functions that enable access to underlying
10//! [FLINT](https://flintlib.org/) structs. Therefore, they require to be unsafe.
11
12use super::PolyOverZq;
13use crate::macros::unsafe_passthrough::{
14 unsafe_getter, unsafe_getter_indirect, unsafe_setter_indirect,
15};
16use flint_sys::{
17 fmpz_mod::fmpz_mod_ctx,
18 fmpz_mod_poly::{fmpz_mod_poly_clear, fmpz_mod_poly_struct},
19};
20
21unsafe_getter!(PolyOverZq, poly, fmpz_mod_poly_struct);
22unsafe_getter_indirect!(PolyOverZq, modulus, get_fmpz_mod_ctx, fmpz_mod_ctx);
23
24impl PolyOverZq {
25 /// Sets the field `poly` of type [`PolyOverZq`] to `flint_struct`.
26 ///
27 /// Parameters:
28 /// - `flint_struct`: value to set the attribute to
29 ///
30 /// This function is a passthrough to enable users of this library to use [`flint_sys`]
31 /// and with that [FLINT](https://flintlib.org/) functions that might not be covered in our library yet.
32 /// If this is the case, please consider contributing to this open-source project
33 /// by opening a Pull Request at [qfall_math](https://github.com/qfall/math)
34 /// to provide this feature in the future.
35 ///
36 /// # Safety
37 /// Ensure that the old struct does not share any memory with any other structs
38 /// that might be used in the future. The memory of the old struct is freed
39 /// using this function.
40 ///
41 /// Any [`flint_sys`] struct and function is part of a FFI to the C-library `FLINT`.
42 /// As `FLINT` is a C-library, it does not provide all memory safety features
43 /// that Rust and our Wrapper provide.
44 /// Thus, using functions of [`flint_sys`] can introduce memory leaks.
45 pub unsafe fn set_fmpz_mod_poly_struct(&mut self, flint_struct: fmpz_mod_poly_struct) {
46 unsafe { fmpz_mod_poly_clear(&mut self.poly, self.modulus.get_fmpz_mod_ctx_struct()) };
47
48 self.poly = flint_struct;
49 }
50}
51unsafe_setter_indirect!(PolyOverZq, modulus, set_fmpz_mod_ctx, fmpz_mod_ctx);
52
53#[cfg(test)]
54mod test_get_fmpz_mod_poly_struct {
55 use super::PolyOverZq;
56 use flint_sys::fmpz_mod_poly::fmpz_mod_poly_set_ui;
57
58 /// Checks availability of the getter for [`PolyOverZq::poly`]
59 /// and its ability to be modified.
60 #[test]
61 #[allow(unused_mut)]
62 fn availability_and_modification() {
63 let mut poly = PolyOverZq::from((3, 7));
64
65 let mut fmpz_poly = unsafe { poly.get_fmpz_mod_poly_struct() };
66
67 unsafe { fmpz_mod_poly_set_ui(fmpz_poly, 5, poly.get_fmpz_mod_ctx()) };
68
69 assert_eq!(PolyOverZq::from((5, 7)), poly);
70 }
71}
72
73#[cfg(test)]
74mod test_set_fmpz_mod_poly_struct {
75 use super::PolyOverZq;
76 use crate::integer_mod_q::Modulus;
77 use flint_sys::fmpz_mod_poly::fmpz_mod_poly_init;
78 use std::mem::MaybeUninit;
79
80 /// Checks availability of the setter for [`PolyOverZq::poly`]
81 /// and its ability to modify [`PolyOverZq`].
82 #[test]
83 #[allow(unused_mut)]
84 fn availability_and_modification() {
85 let mut poly = PolyOverZq::from((3, 7));
86
87 let modulus = Modulus::from(7);
88 let mut flint_struct = MaybeUninit::uninit();
89 let flint_struct = unsafe {
90 fmpz_mod_poly_init(flint_struct.as_mut_ptr(), modulus.get_fmpz_mod_ctx_struct());
91 flint_struct.assume_init()
92 };
93
94 unsafe { poly.set_fmpz_mod_poly_struct(flint_struct) };
95
96 assert_eq!(PolyOverZq::from((0, 7)), poly);
97 }
98}