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