Skip to content

Commit 690fc7d

Browse files
committed
polynomial: use FieldVec in Polynomial
We can now use `PrintImpl` even without an allocator. This is of limited use of course, but it paves the ground for use to do error correction without an allocator, which is interesting.
1 parent f2ec582 commit 690fc7d

File tree

4 files changed

+225
-141
lines changed

4 files changed

+225
-141
lines changed

src/primitives/checksum.rs

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,14 @@
44
//!
55
//! [BCH]: <https://en.wikipedia.org/wiki/BCH_code>
66
7-
#[cfg(all(feature = "alloc", not(feature = "std"), not(test)))]
7+
#[cfg(all(feature = "alloc", not(feature = "std")))]
88
use alloc::vec::Vec;
9-
#[cfg(feature = "alloc")]
10-
use core::fmt;
11-
#[cfg(feature = "alloc")]
129
use core::marker::PhantomData;
13-
use core::{mem, ops};
10+
use core::{fmt, mem, ops};
1411

15-
#[cfg(feature = "alloc")]
1612
use super::Polynomial;
1713
use crate::primitives::hrp::Hrp;
18-
#[cfg(feature = "alloc")]
19-
use crate::Fe1024;
20-
use crate::Fe32;
14+
use crate::{Fe1024, Fe32};
2115

2216
/// Trait defining a particular checksum.
2317
///
@@ -169,18 +163,16 @@ pub trait Checksum {
169163
/// to compute the values yourself. The reason is that the specific values
170164
/// used depend on the representation of extension fields, which may differ
171165
/// between implementations (and between specifications) of your BCH code.
172-
#[cfg(feature = "alloc")]
173166
pub struct PrintImpl<'a, ExtField = Fe1024> {
174167
name: &'a str,
175-
generator: &'a [Fe32],
168+
generator: Polynomial<Fe32>,
176169
target: &'a [Fe32],
177170
bit_len: usize,
178171
hex_width: usize,
179172
midstate_repr: &'static str,
180173
phantom: PhantomData<ExtField>,
181174
}
182175

183-
#[cfg(feature = "alloc")]
184176
impl<'a, ExtField> PrintImpl<'a, ExtField> {
185177
/// Constructor for an object to print an impl-block for the [`Checksum`] trait.
186178
///
@@ -225,7 +217,7 @@ impl<'a, ExtField> PrintImpl<'a, ExtField> {
225217
// End sanity checks.
226218
PrintImpl {
227219
name,
228-
generator,
220+
generator: Polynomial::with_monic_leading_term(generator),
229221
target,
230222
bit_len,
231223
hex_width,
@@ -235,23 +227,16 @@ impl<'a, ExtField> PrintImpl<'a, ExtField> {
235227
}
236228
}
237229

238-
#[cfg(feature = "alloc")]
239230
impl<'a, ExtField> fmt::Display for PrintImpl<'a, ExtField>
240231
where
241232
ExtField: super::Bech32Field + super::ExtensionField<BaseField = Fe32>,
242233
{
243234
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
244235
// Generator polynomial as a polynomial over GF1024
245-
let gen_poly = {
246-
let mut v = Vec::with_capacity(self.generator.len() + 1);
247-
v.push(ExtField::ONE);
248-
v.extend(self.generator.iter().cloned().map(ExtField::from));
249-
Polynomial::new(v)
250-
};
251-
let (gen, length, exponents) = gen_poly.bch_generator_primitive_element();
236+
let (gen, length, exponents) = self.generator.bch_generator_primitive_element::<ExtField>();
252237

253238
write!(f, "// Code block generated by Checksum::print_impl polynomial ")?;
254-
for fe in self.generator {
239+
for fe in self.generator.as_inner() {
255240
write!(f, "{}", fe)?;
256241
}
257242
write!(f, " target ")?;
@@ -278,9 +263,9 @@ where
278263
)?;
279264
f.write_str("\n")?;
280265
writeln!(f, " const CODE_LENGTH: usize = {};", length)?;
281-
writeln!(f, " const CHECKSUM_LENGTH: usize = {};", gen_poly.degree())?;
266+
writeln!(f, " const CHECKSUM_LENGTH: usize = {};", self.generator.degree())?;
282267
writeln!(f, " const GENERATOR_SH: [{}; 5] = [", self.midstate_repr)?;
283-
let mut gen5 = self.generator.to_vec();
268+
let mut gen5 = self.generator.clone().into_inner();
284269
for _ in 0..5 {
285270
let gen_packed = u128::pack(gen5.iter().copied().map(From::from));
286271
writeln!(f, " 0x{:0width$x},", gen_packed, width = self.hex_width)?;

src/primitives/fieldvec.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,34 @@ impl<F: Field> FieldVec<F> {
186186
}
187187
}
188188

189+
impl<F: Default> FieldVec<F> {
190+
/// Pushes an item onto the end of the vector.
191+
///
192+
/// # Panics
193+
///
194+
/// Panics if [`Self::has_data`] is false, or if it would be false after the push.
195+
pub fn push(&mut self, item: F) {
196+
self.len += 1;
197+
self.assert_has_data();
198+
199+
#[cfg(not(feature = "alloc"))]
200+
{
201+
self.inner_a[self.len - 1] = item;
202+
}
203+
204+
#[cfg(feature = "alloc")]
205+
if self.len < NO_ALLOC_MAX_LENGTH + 1 {
206+
self.inner_a[self.len - 1] = item;
207+
} else {
208+
if self.len == NO_ALLOC_MAX_LENGTH + 1 {
209+
let inner_a = core::mem::take(&mut self.inner_a);
210+
self.inner_v = inner_a.into();
211+
}
212+
self.inner_v.push(item);
213+
}
214+
}
215+
}
216+
189217
impl<F: Clone + Default> iter::FromIterator<F> for FieldVec<F> {
190218
/// Constructor from an iterator of elements.
191219
///

src/primitives/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@ pub mod gf32;
1212
pub mod gf32_ext;
1313
pub mod hrp;
1414
pub mod iter;
15-
#[cfg(feature = "alloc")]
1615
mod polynomial;
1716
pub mod segwit;
1817

1918
use checksum::{Checksum, PackedNull};
2019
use field::impl_ops_for_fe;
2120
pub use field::{Bech32Field, ExtensionField, Field};
22-
#[cfg(feature = "alloc")]
21+
use fieldvec::FieldVec;
2322
use polynomial::Polynomial;
2423

2524
use crate::{Fe1024, Fe32};

0 commit comments

Comments
 (0)