fp/vector/
inner.rs

1// This generates better llvm optimization
2#![allow(clippy::int_plus_one)]
3
4use serde::{Deserialize, Deserializer, Serialize};
5
6use crate::{field::Field, limb::Limb};
7
8/// A vector over a finite field.
9///
10/// Interally, it packs entries of the vectors into limbs. However, this is an abstraction that must
11/// not leave the `fp` library.
12#[derive(Debug, Hash, Eq, PartialEq, Clone, Serialize)]
13pub struct FqVector<F: Field> {
14    fq: F,
15    len: usize,
16    limbs: Vec<Limb>,
17}
18
19// `Deserialize` is implemented manually rather than derived so that we can validate the
20// invariant `limbs.len() == fq.number(len)`. Without this check, malformed input that supplies
21// too few limbs would build an `FqVector` whose internal accessors (`entry`, `to_bytes`, etc.)
22// later panic on bounds-checked slice indexing. With it, malformed input surfaces as a normal
23// serde error from the `Deserialize` impl, which is the contract callers expect.
24impl<'de, F: Field + Deserialize<'de>> Deserialize<'de> for FqVector<F> {
25    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
26    where
27        D: Deserializer<'de>,
28    {
29        use serde::de::Error;
30
31        #[derive(Deserialize)]
32        #[serde(bound(deserialize = "F: Deserialize<'de>"))]
33        struct Raw<F> {
34            fq: F,
35            len: usize,
36            limbs: Vec<Limb>,
37        }
38
39        let raw = Raw::<F>::deserialize(deserializer)?;
40        let expected = raw.fq.number(raw.len);
41        if raw.limbs.len() != expected {
42            return Err(D::Error::custom(format!(
43                "FqVector limbs length {} does not match expected {} for len={}",
44                raw.limbs.len(),
45                expected,
46                raw.len,
47            )));
48        }
49        Ok(Self {
50            fq: raw.fq,
51            len: raw.len,
52            limbs: raw.limbs,
53        })
54    }
55}
56
57/// A slice of an `FqVector`.
58///
59/// This immutably borrows the vector and implements `Copy`.
60#[derive(Debug, Copy, Clone)]
61pub struct FqSlice<'a, F: Field> {
62    fq: F,
63    limbs: &'a [Limb],
64    start: usize,
65    end: usize,
66}
67
68/// A mutable slice of an `FqVector`.
69///
70/// This mutably borrows the vector. Since it is a mutable borrow, it cannot implement `Copy`.
71/// However, it has a [`FqSliceMut::copy`] function that imitates the reborrowing, that mutably
72/// borrows `FqSliceMut` and returns a `FqSliceMut` with a shorter lifetime.
73#[derive(Debug)]
74pub struct FqSliceMut<'a, F: Field> {
75    fq: F,
76    limbs: &'a mut [Limb],
77    start: usize,
78    end: usize,
79}
80
81// See impl_* for implementations
82
83// Accessors
84
85impl<F: Field> FqVector<F> {
86    pub fn from_raw_parts(fq: F, len: usize, limbs: Vec<Limb>) -> Self {
87        debug_assert_eq!(limbs.len(), fq.number(len));
88        Self { fq, len, limbs }
89    }
90
91    pub fn fq(&self) -> F {
92        self.fq
93    }
94
95    pub const fn len(&self) -> usize {
96        self.len
97    }
98
99    pub(super) fn limbs(&self) -> &[Limb] {
100        &self.limbs
101    }
102
103    pub(super) fn limbs_mut(&mut self) -> &mut [Limb] {
104        &mut self.limbs
105    }
106
107    pub(super) fn vec_mut(&mut self) -> &mut Vec<Limb> {
108        &mut self.limbs
109    }
110
111    pub(super) fn len_mut(&mut self) -> &mut usize {
112        &mut self.len
113    }
114}
115
116impl<'a, F: Field> FqSlice<'a, F> {
117    pub(super) fn new(fq: F, limbs: &'a [Limb], start: usize, end: usize) -> Self {
118        Self {
119            fq,
120            limbs,
121            start,
122            end,
123        }
124    }
125
126    pub fn fq(&self) -> F {
127        self.fq
128    }
129
130    pub(super) fn into_limbs(self) -> &'a [Limb] {
131        self.limbs
132    }
133
134    pub(super) const fn start(&self) -> usize {
135        self.start
136    }
137
138    pub(super) const fn end(&self) -> usize {
139        self.end
140    }
141
142    pub(super) fn limbs(&self) -> &[Limb] {
143        self.limbs
144    }
145}
146
147impl<'a, F: Field> FqSliceMut<'a, F> {
148    pub(super) fn new(fq: F, limbs: &'a mut [Limb], start: usize, end: usize) -> Self {
149        Self {
150            fq,
151            limbs,
152            start,
153            end,
154        }
155    }
156
157    pub fn fq(&self) -> F {
158        self.fq
159    }
160
161    pub(super) fn start(&self) -> usize {
162        self.start
163    }
164
165    pub(super) fn end(&self) -> usize {
166        self.end
167    }
168
169    pub(super) fn end_mut(&mut self) -> &mut usize {
170        &mut self.end
171    }
172
173    pub(super) fn limbs(&self) -> &[Limb] {
174        self.limbs
175    }
176
177    pub(super) fn limbs_mut(&mut self) -> &mut [Limb] {
178        self.limbs
179    }
180}