ark_feanor/
field_wrapper.rs

1//! Core field wrapper that implements feanor-math's RingBase trait for arkworks fields.
2
3use ark_ff::Field;
4use feanor_math::ring::*;
5use feanor_math::integer::IntegerRing;
6use std::marker::PhantomData;
7use std::fmt::{self, Debug, Display};
8
9/// Wrapper struct that allows arkworks `Field` types to be used as feanor-math rings.
10/// 
11/// This is a zero-sized type that acts as a bridge between the two type systems.
12/// All arkworks field operations are mapped to their feanor-math equivalents.
13#[derive(Clone, Copy)]
14pub struct ArkFieldWrapper<F: Field> {
15    _phantom: PhantomData<F>,
16}
17
18impl<F: Field> ArkFieldWrapper<F> {
19    /// Create a new instance of the field wrapper.
20    /// 
21    /// # Example
22    /// ```ignore
23    /// use ark_bn254::Fr;
24    /// use ark_feanor::ArkFieldWrapper;
25    /// 
26    /// let field = ArkFieldWrapper::<Fr>::new();
27    /// ```
28    pub const fn new() -> Self {
29        Self {
30            _phantom: PhantomData,
31        }
32    }
33}
34
35impl<F: Field> Default for ArkFieldWrapper<F> {
36    fn default() -> Self {
37        Self::new()
38    }
39}
40
41impl<F: Field> Debug for ArkFieldWrapper<F> {
42    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43        write!(f, "ArkFieldWrapper<{}>", std::any::type_name::<F>())
44    }
45}
46
47impl<F: Field> Display for ArkFieldWrapper<F> {
48    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49        write!(f, "Field({})", std::any::type_name::<F>())
50    }
51}
52
53// All instances of the same field type are considered equal
54impl<F: Field> PartialEq for ArkFieldWrapper<F> {
55    fn eq(&self, _other: &Self) -> bool {
56        true // All instances of the same field type are the same ring
57    }
58}
59
60impl<F: Field> Eq for ArkFieldWrapper<F> {}
61
62impl<F: Field> RingBase for ArkFieldWrapper<F> {
63    type Element = F;
64
65    fn clone_el(&self, el: &Self::Element) -> Self::Element {
66        *el
67    }
68
69    fn add_assign(&self, lhs: &mut Self::Element, rhs: Self::Element) {
70        *lhs += rhs;
71    }
72
73    fn add_ref(&self, lhs: &Self::Element, rhs: &Self::Element) -> Self::Element {
74        *lhs + *rhs
75    }
76
77    fn negate_inplace(&self, el: &mut Self::Element) {
78        *el = -*el;
79    }
80
81    fn mul_assign(&self, lhs: &mut Self::Element, rhs: Self::Element) {
82        *lhs *= rhs;
83    }
84
85    fn mul_ref(&self, lhs: &Self::Element, rhs: &Self::Element) -> Self::Element {
86        *lhs * *rhs
87    }
88
89    fn from_int(&self, value: i32) -> Self::Element {
90        if value >= 0 {
91            F::from(value as u64)
92        } else {
93            -F::from((-value) as u64)
94        }
95    }
96
97    fn eq_el(&self, lhs: &Self::Element, rhs: &Self::Element) -> bool {
98        lhs == rhs
99    }
100
101    fn is_zero(&self, el: &Self::Element) -> bool {
102        el.is_zero()
103    }
104
105    fn is_one(&self, el: &Self::Element) -> bool {
106        el.is_one()
107    }
108
109    fn is_neg_one(&self, el: &Self::Element) -> bool {
110        *el == -F::one()
111    }
112
113    fn zero(&self) -> Self::Element {
114        F::zero()
115    }
116
117    fn one(&self) -> Self::Element {
118        F::one()
119    }
120
121    fn neg_one(&self) -> Self::Element {
122        -F::one()
123    }
124
125    fn is_commutative(&self) -> bool {
126        true // All fields are commutative
127    }
128
129    fn is_noetherian(&self) -> bool {
130        true // All fields are noetherian
131    }
132
133    fn is_approximate(&self) -> bool {
134        false // Finite fields are exact
135    }
136
137    fn dbg<'a>(&self, el: &Self::Element, out: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
138        write!(out, "{:?}", el)
139    }
140
141    fn dbg_within<'a>(&self, el: &Self::Element, out: &mut std::fmt::Formatter<'a>, _env: EnvBindingStrength) -> std::fmt::Result {
142        write!(out, "{:?}", el)
143    }
144
145    fn characteristic<I>(&self, _int_ring: I) -> Option<<I::Type as RingBase>::Element>
146    where
147        I: RingStore + Copy,
148        I::Type: IntegerRing,
149    {
150        // For fields with known characteristic, we would return it here
151        // For now, return None to indicate unknown/zero characteristic
152        None
153    }
154}
155
156#[cfg(test)]
157mod tests {
158    use super::*;
159    use ark_bn254::Fr;
160
161    #[test]
162    fn test_basic_operations() {
163        let field = ArkFieldWrapper::<Fr>::new();
164        
165        // Test zero and one
166        assert!(field.is_zero(&field.zero()));
167        assert!(field.is_one(&field.one()));
168        
169        // Test basic arithmetic
170        let a = field.from_int(5);
171        let b = field.from_int(3);
172        let c = field.add_ref(&a, &b);
173        let expected = field.from_int(8);
174        assert!(field.eq_el(&c, &expected));
175        
176        // Test multiplication
177        let d = field.mul_ref(&a, &b);
178        let expected = field.from_int(15);
179        assert!(field.eq_el(&d, &expected));
180        
181        // Test negation
182        let neg_a = field.negate(field.clone_el(&a));
183        let zero = field.add_ref(&a, &neg_a);
184        assert!(field.is_zero(&zero));
185    }
186}