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}