From bd6f2f628106a7db5925051144d01e711364f4c2 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sun, 24 Mar 2024 20:07:19 +0000 Subject: [PATCH 1/8] bump MSRV to 1.56.1. I want to use const generics and I need 1.56 to do it. The rest of the rust-bitcoin ecosystem has moved to 1.56.1. --- .github/workflows/rust.yml | 4 ++-- README.md | 2 +- clippy.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 40da8238f..5b1fcd5cf 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -54,7 +54,7 @@ jobs: run: ./contrib/test.sh MSRV: - name: Test - 1.48.0 toolchain + name: Test - 1.56.1 toolchain runs-on: ubuntu-latest strategy: fail-fast: false @@ -62,7 +62,7 @@ jobs: - name: Checkout Crate uses: actions/checkout@v3 - name: Checkout Toolchain - uses: dtolnay/rust-toolchain@1.48.0 + uses: dtolnay/rust-toolchain@1.56.1 - name: Running test script env: DO_FEATURE_MATRIX: true diff --git a/README.md b/README.md index 7067c9ab4..dfd465b88 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Bitcoin-specific address encoding is handled by the `bitcoin-bech32` crate. ## MSRV -This library should always compile with any combination of features on **Rust 1.48.0**. +This library should always compile with any combination of features on **Rust 1.56.1**. ## Githooks diff --git a/clippy.toml b/clippy.toml index 11d46a73f..56ce04e44 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1 +1 @@ -msrv = "1.48.0" +msrv = "1.56.1" From 8b085351e9bbe82f217b704031571c6552df4ab0 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sat, 23 Mar 2024 14:30:20 +0000 Subject: [PATCH 2/8] primitives: introduce Field trait This new trait covers a larger matrix of ops, and implements them all with a single macro. Will allow us to introduce new fields (in particular, extension fields of GF32) in a future commit with more consistent/less boilerplate heavy implementations of basic arithmetic. We run the API checker in this commit so you can see that the API changes are strictly additive and only add missing op implementations. --- api/all-features.txt | 41 +++++ api/alloc-only.txt | 41 +++++ api/no-features.txt | 41 +++++ src/primitives/field.rs | 367 ++++++++++++++++++++++++++++++++++++++++ src/primitives/gf32.rs | 112 ++++-------- src/primitives/mod.rs | 3 + 6 files changed, 528 insertions(+), 77 deletions(-) create mode 100644 src/primitives/field.rs diff --git a/api/all-features.txt b/api/all-features.txt index ffc33b132..93c718cce 100644 --- a/api/all-features.txt +++ b/api/all-features.txt @@ -20,6 +20,7 @@ #[repr(transparent)] pub struct bech32::primitives::gf32::Fe32(_) impl !core::panic::unwind_safe::RefUnwindSafe for bech32::EncodeIoError impl !core::panic::unwind_safe::UnwindSafe for bech32::EncodeIoError +impl bech32::primitives::Field for bech32::primitives::gf32::Fe32 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32m impl bech32::primitives::checksum::Checksum for bech32::primitives::NoChecksum @@ -334,21 +335,26 @@ impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for &bech32::primiti impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Add for &bech32::primitives::gf32::Fe32 impl core::ops::arith::AddAssign for bech32::primitives::gf32::Fe32 +impl core::ops::arith::AddAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div for &bech32::primitives::gf32::Fe32 impl core::ops::arith::DivAssign for bech32::primitives::gf32::Fe32 +impl core::ops::arith::DivAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul for &bech32::primitives::gf32::Fe32 impl core::ops::arith::MulAssign for bech32::primitives::gf32::Fe32 +impl core::ops::arith::MulAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::Neg for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub for &bech32::primitives::gf32::Fe32 impl core::ops::arith::SubAssign for bech32::primitives::gf32::Fe32 +impl core::ops::arith::SubAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::bit::BitXor for bech32::primitives::checksum::PackedNull impl core::panic::unwind_safe::RefUnwindSafe for bech32::DecodeError impl core::panic::unwind_safe::RefUnwindSafe for bech32::EncodeError @@ -638,6 +644,14 @@ pub const bech32::primitives::Bech32m::CHECKSUM_LENGTH: usize pub const bech32::primitives::Bech32m::CODE_LENGTH: usize pub const bech32::primitives::Bech32m::GENERATOR_SH: [u32; 5] pub const bech32::primitives::Bech32m::TARGET_RESIDUE: u32 +pub const bech32::primitives::ExtensionField::DEGREE: usize +pub const bech32::primitives::ExtensionField::EXT_ELEM: Self +pub const bech32::primitives::ExtensionField::POLYNOMIAL: Self +pub const bech32::primitives::Field::GENERATOR: Self +pub const bech32::primitives::Field::MULTIPLICATIVE_ORDER: usize +pub const bech32::primitives::Field::MULTIPLICATIVE_ORDER_FACTORS: &'static [usize] +pub const bech32::primitives::Field::ONE: Self +pub const bech32::primitives::Field::ZERO: Self pub const bech32::primitives::NoChecksum::CHECKSUM_LENGTH: usize pub const bech32::primitives::NoChecksum::CODE_LENGTH: usize pub const bech32::primitives::NoChecksum::GENERATOR_SH: [bech32::primitives::checksum::PackedNull; 5] @@ -655,12 +669,16 @@ pub const bech32::primitives::gf32::Fe32::D: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::E: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::F: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::G: bech32::primitives::gf32::Fe32 +pub const bech32::primitives::gf32::Fe32::GENERATOR: Self pub const bech32::primitives::gf32::Fe32::H: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::J: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::K: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::L: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::M: bech32::primitives::gf32::Fe32 +pub const bech32::primitives::gf32::Fe32::MULTIPLICATIVE_ORDER: usize +pub const bech32::primitives::gf32::Fe32::MULTIPLICATIVE_ORDER_FACTORS: &'static [usize] pub const bech32::primitives::gf32::Fe32::N: bech32::primitives::gf32::Fe32 +pub const bech32::primitives::gf32::Fe32::ONE: Self pub const bech32::primitives::gf32::Fe32::P: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::Q: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::R: bech32::primitives::gf32::Fe32 @@ -672,6 +690,7 @@ pub const bech32::primitives::gf32::Fe32::W: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::X: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::Y: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::Z: bech32::primitives::gf32::Fe32 +pub const bech32::primitives::gf32::Fe32::ZERO: Self pub const bech32::primitives::gf32::Fe32::_0: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::_2: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::_3: bech32::primitives::gf32::Fe32 @@ -747,6 +766,14 @@ pub fn bech32::primitives::Bech32m::cmp(&self, other: &bech32::primitives::Bech3 pub fn bech32::primitives::Bech32m::eq(&self, other: &bech32::primitives::Bech32m) -> bool pub fn bech32::primitives::Bech32m::hash<__H: core::hash::Hasher>(&self, state: &mut __H) pub fn bech32::primitives::Bech32m::partial_cmp(&self, other: &bech32::primitives::Bech32m) -> core::option::Option +pub fn bech32::primitives::Field::_add(&self, other: &Self) -> Self +pub fn bech32::primitives::Field::_div(&self, other: &Self) -> Self +pub fn bech32::primitives::Field::_mul(&self, other: &Self) -> Self +pub fn bech32::primitives::Field::_neg(self) -> Self +pub fn bech32::primitives::Field::_sub(&self, other: &Self) -> Self +pub fn bech32::primitives::Field::multiplicative_inverse(self) -> Self +pub fn bech32::primitives::Field::multiplicative_order(&self) -> usize +pub fn bech32::primitives::Field::powi(&self, n: i64) -> Self pub fn bech32::primitives::NoChecksum::clone(&self) -> bech32::primitives::NoChecksum pub fn bech32::primitives::NoChecksum::cmp(&self, other: &bech32::primitives::NoChecksum) -> core::cmp::Ordering pub fn bech32::primitives::NoChecksum::eq(&self, other: &bech32::primitives::NoChecksum) -> bool @@ -868,13 +895,20 @@ pub fn bech32::primitives::encode::Fe32Iter<'hrp, I, Ck>::size_hint(&self) -> (u pub fn bech32::primitives::encode::WitnessVersionIter::new(witness_version: core::option::Option, iter: I) -> Self pub fn bech32::primitives::encode::WitnessVersionIter::next(&mut self) -> core::option::Option pub fn bech32::primitives::encode::WitnessVersionIter::size_hint(&self) -> (usize, core::option::Option) +pub fn bech32::primitives::gf32::Fe32::_add(&self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::_div(&self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::_mul(&self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::_neg(self) -> Self +pub fn bech32::primitives::gf32::Fe32::_sub(&self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::add(self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::add(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::add_assign(&mut self, other: &bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::add_assign(&mut self, other: bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::as_ref(&self) -> &u8 pub fn bech32::primitives::gf32::Fe32::clone(&self) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::div(self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::div(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::div_assign(&mut self, other: &bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::div_assign(&mut self, other: bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::eq(&self, other: &bech32::primitives::gf32::Fe32) -> bool pub fn bech32::primitives::gf32::Fe32::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result @@ -884,9 +918,13 @@ pub fn bech32::primitives::gf32::Fe32::hash<__H: core::hash::Hasher>(&self, stat pub fn bech32::primitives::gf32::Fe32::iter_alpha() -> impl core::iter::traits::iterator::Iterator pub fn bech32::primitives::gf32::Fe32::mul(self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::mul(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::mul_assign(&mut self, other: &bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::mul_assign(&mut self, other: bech32::primitives::gf32::Fe32) +pub fn bech32::primitives::gf32::Fe32::multiplicative_inverse(self) -> Self +pub fn bech32::primitives::gf32::Fe32::neg(self) -> Self pub fn bech32::primitives::gf32::Fe32::sub(self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::sub(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::sub_assign(&mut self, other: &bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::sub_assign(&mut self, other: bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::to_char(self) -> char pub fn bech32::primitives::gf32::Fe32::to_u8(self) -> u8 @@ -1049,6 +1087,8 @@ pub struct bech32::primitives::iter::FesToBytes pub trait bech32::Checksum pub trait bech32::Fe32IterExt: core::marker::Sized + core::iter::traits::iterator::Iterator +pub trait bech32::primitives::ExtensionField: bech32::primitives::Field + core::convert::From +pub trait bech32::primitives::Field: core::marker::Sized + core::cmp::PartialEq + core::cmp::Eq + core::clone::Clone + core::hash::Hash + core::fmt::Debug + core::fmt::Display + core::ops::arith::Add + core::ops::arith::Sub + core::ops::arith::AddAssign + core::ops::arith::SubAssign + core::ops::arith::Mul + core::ops::arith::MulAssign + core::ops::arith::Div + core::ops::arith::DivAssign + for<'a> core::ops::arith::Add<&'a Self, Output = Self> + for<'a> core::ops::arith::AddAssign<&'a Self> + for<'a> core::ops::arith::Sub<&'a Self, Output = Self> + for<'a> core::ops::arith::SubAssign<&'a Self> + for<'a> core::ops::arith::Mul<&'a Self, Output = Self> + for<'a> core::ops::arith::MulAssign<&'a Self> + for<'a> core::ops::arith::Div<&'a Self, Output = Self> + for<'a> core::ops::arith::DivAssign<&'a Self> + core::ops::arith::Neg pub trait bech32::primitives::checksum::Checksum pub trait bech32::primitives::checksum::PackedFe32: core::marker::Copy + core::cmp::PartialEq + core::cmp::Eq + core::ops::bit::BitXor pub trait bech32::primitives::iter::ByteIterExt: core::marker::Sized + core::iter::traits::iterator::Iterator @@ -1057,6 +1097,7 @@ pub type &bech32::primitives::gf32::Fe32::Output = bech32::primitives::gf32::Fe3 pub type bech32::Checksum::MidstateRepr: bech32::primitives::checksum::PackedFe32 pub type bech32::primitives::Bech32::MidstateRepr = u32 pub type bech32::primitives::Bech32m::MidstateRepr = u32 +pub type bech32::primitives::ExtensionField::BaseField: bech32::primitives::Field pub type bech32::primitives::NoChecksum::MidstateRepr = bech32::primitives::checksum::PackedNull pub type bech32::primitives::checksum::Checksum::MidstateRepr: bech32::primitives::checksum::PackedFe32 pub type bech32::primitives::checksum::HrpFe32Iter<'hrp>::Item = bech32::primitives::gf32::Fe32 diff --git a/api/alloc-only.txt b/api/alloc-only.txt index 859d09161..72ea31394 100644 --- a/api/alloc-only.txt +++ b/api/alloc-only.txt @@ -17,6 +17,7 @@ #[non_exhaustive] pub struct bech32::segwit::DecodeError(pub bech32::primitives::decode::SegwitHrpstringError) #[repr(transparent)] pub struct bech32::Fe32(_) #[repr(transparent)] pub struct bech32::primitives::gf32::Fe32(_) +impl bech32::primitives::Field for bech32::primitives::gf32::Fe32 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32m impl bech32::primitives::checksum::Checksum for bech32::primitives::NoChecksum @@ -305,21 +306,26 @@ impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for &bech32::primiti impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Add for &bech32::primitives::gf32::Fe32 impl core::ops::arith::AddAssign for bech32::primitives::gf32::Fe32 +impl core::ops::arith::AddAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div for &bech32::primitives::gf32::Fe32 impl core::ops::arith::DivAssign for bech32::primitives::gf32::Fe32 +impl core::ops::arith::DivAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul for &bech32::primitives::gf32::Fe32 impl core::ops::arith::MulAssign for bech32::primitives::gf32::Fe32 +impl core::ops::arith::MulAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::Neg for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub for &bech32::primitives::gf32::Fe32 impl core::ops::arith::SubAssign for bech32::primitives::gf32::Fe32 +impl core::ops::arith::SubAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::bit::BitXor for bech32::primitives::checksum::PackedNull impl core::panic::unwind_safe::RefUnwindSafe for bech32::DecodeError impl core::panic::unwind_safe::RefUnwindSafe for bech32::EncodeError @@ -607,6 +613,14 @@ pub const bech32::primitives::Bech32m::CHECKSUM_LENGTH: usize pub const bech32::primitives::Bech32m::CODE_LENGTH: usize pub const bech32::primitives::Bech32m::GENERATOR_SH: [u32; 5] pub const bech32::primitives::Bech32m::TARGET_RESIDUE: u32 +pub const bech32::primitives::ExtensionField::DEGREE: usize +pub const bech32::primitives::ExtensionField::EXT_ELEM: Self +pub const bech32::primitives::ExtensionField::POLYNOMIAL: Self +pub const bech32::primitives::Field::GENERATOR: Self +pub const bech32::primitives::Field::MULTIPLICATIVE_ORDER: usize +pub const bech32::primitives::Field::MULTIPLICATIVE_ORDER_FACTORS: &'static [usize] +pub const bech32::primitives::Field::ONE: Self +pub const bech32::primitives::Field::ZERO: Self pub const bech32::primitives::NoChecksum::CHECKSUM_LENGTH: usize pub const bech32::primitives::NoChecksum::CODE_LENGTH: usize pub const bech32::primitives::NoChecksum::GENERATOR_SH: [bech32::primitives::checksum::PackedNull; 5] @@ -624,12 +638,16 @@ pub const bech32::primitives::gf32::Fe32::D: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::E: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::F: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::G: bech32::primitives::gf32::Fe32 +pub const bech32::primitives::gf32::Fe32::GENERATOR: Self pub const bech32::primitives::gf32::Fe32::H: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::J: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::K: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::L: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::M: bech32::primitives::gf32::Fe32 +pub const bech32::primitives::gf32::Fe32::MULTIPLICATIVE_ORDER: usize +pub const bech32::primitives::gf32::Fe32::MULTIPLICATIVE_ORDER_FACTORS: &'static [usize] pub const bech32::primitives::gf32::Fe32::N: bech32::primitives::gf32::Fe32 +pub const bech32::primitives::gf32::Fe32::ONE: Self pub const bech32::primitives::gf32::Fe32::P: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::Q: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::R: bech32::primitives::gf32::Fe32 @@ -641,6 +659,7 @@ pub const bech32::primitives::gf32::Fe32::W: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::X: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::Y: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::Z: bech32::primitives::gf32::Fe32 +pub const bech32::primitives::gf32::Fe32::ZERO: Self pub const bech32::primitives::gf32::Fe32::_0: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::_2: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::_3: bech32::primitives::gf32::Fe32 @@ -707,6 +726,14 @@ pub fn bech32::primitives::Bech32m::cmp(&self, other: &bech32::primitives::Bech3 pub fn bech32::primitives::Bech32m::eq(&self, other: &bech32::primitives::Bech32m) -> bool pub fn bech32::primitives::Bech32m::hash<__H: core::hash::Hasher>(&self, state: &mut __H) pub fn bech32::primitives::Bech32m::partial_cmp(&self, other: &bech32::primitives::Bech32m) -> core::option::Option +pub fn bech32::primitives::Field::_add(&self, other: &Self) -> Self +pub fn bech32::primitives::Field::_div(&self, other: &Self) -> Self +pub fn bech32::primitives::Field::_mul(&self, other: &Self) -> Self +pub fn bech32::primitives::Field::_neg(self) -> Self +pub fn bech32::primitives::Field::_sub(&self, other: &Self) -> Self +pub fn bech32::primitives::Field::multiplicative_inverse(self) -> Self +pub fn bech32::primitives::Field::multiplicative_order(&self) -> usize +pub fn bech32::primitives::Field::powi(&self, n: i64) -> Self pub fn bech32::primitives::NoChecksum::clone(&self) -> bech32::primitives::NoChecksum pub fn bech32::primitives::NoChecksum::cmp(&self, other: &bech32::primitives::NoChecksum) -> core::cmp::Ordering pub fn bech32::primitives::NoChecksum::eq(&self, other: &bech32::primitives::NoChecksum) -> bool @@ -820,13 +847,20 @@ pub fn bech32::primitives::encode::Fe32Iter<'hrp, I, Ck>::size_hint(&self) -> (u pub fn bech32::primitives::encode::WitnessVersionIter::new(witness_version: core::option::Option, iter: I) -> Self pub fn bech32::primitives::encode::WitnessVersionIter::next(&mut self) -> core::option::Option pub fn bech32::primitives::encode::WitnessVersionIter::size_hint(&self) -> (usize, core::option::Option) +pub fn bech32::primitives::gf32::Fe32::_add(&self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::_div(&self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::_mul(&self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::_neg(self) -> Self +pub fn bech32::primitives::gf32::Fe32::_sub(&self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::add(self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::add(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::add_assign(&mut self, other: &bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::add_assign(&mut self, other: bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::as_ref(&self) -> &u8 pub fn bech32::primitives::gf32::Fe32::clone(&self) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::div(self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::div(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::div_assign(&mut self, other: &bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::div_assign(&mut self, other: bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::eq(&self, other: &bech32::primitives::gf32::Fe32) -> bool pub fn bech32::primitives::gf32::Fe32::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result @@ -836,9 +870,13 @@ pub fn bech32::primitives::gf32::Fe32::hash<__H: core::hash::Hasher>(&self, stat pub fn bech32::primitives::gf32::Fe32::iter_alpha() -> impl core::iter::traits::iterator::Iterator pub fn bech32::primitives::gf32::Fe32::mul(self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::mul(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::mul_assign(&mut self, other: &bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::mul_assign(&mut self, other: bech32::primitives::gf32::Fe32) +pub fn bech32::primitives::gf32::Fe32::multiplicative_inverse(self) -> Self +pub fn bech32::primitives::gf32::Fe32::neg(self) -> Self pub fn bech32::primitives::gf32::Fe32::sub(self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::sub(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::sub_assign(&mut self, other: &bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::sub_assign(&mut self, other: bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::to_char(self) -> char pub fn bech32::primitives::gf32::Fe32::to_u8(self) -> u8 @@ -991,6 +1029,8 @@ pub struct bech32::primitives::iter::FesToBytes pub trait bech32::Checksum pub trait bech32::Fe32IterExt: core::marker::Sized + core::iter::traits::iterator::Iterator +pub trait bech32::primitives::ExtensionField: bech32::primitives::Field + core::convert::From +pub trait bech32::primitives::Field: core::marker::Sized + core::cmp::PartialEq + core::cmp::Eq + core::clone::Clone + core::hash::Hash + core::fmt::Debug + core::fmt::Display + core::ops::arith::Add + core::ops::arith::Sub + core::ops::arith::AddAssign + core::ops::arith::SubAssign + core::ops::arith::Mul + core::ops::arith::MulAssign + core::ops::arith::Div + core::ops::arith::DivAssign + for<'a> core::ops::arith::Add<&'a Self, Output = Self> + for<'a> core::ops::arith::AddAssign<&'a Self> + for<'a> core::ops::arith::Sub<&'a Self, Output = Self> + for<'a> core::ops::arith::SubAssign<&'a Self> + for<'a> core::ops::arith::Mul<&'a Self, Output = Self> + for<'a> core::ops::arith::MulAssign<&'a Self> + for<'a> core::ops::arith::Div<&'a Self, Output = Self> + for<'a> core::ops::arith::DivAssign<&'a Self> + core::ops::arith::Neg pub trait bech32::primitives::checksum::Checksum pub trait bech32::primitives::checksum::PackedFe32: core::marker::Copy + core::cmp::PartialEq + core::cmp::Eq + core::ops::bit::BitXor pub trait bech32::primitives::iter::ByteIterExt: core::marker::Sized + core::iter::traits::iterator::Iterator @@ -999,6 +1039,7 @@ pub type &bech32::primitives::gf32::Fe32::Output = bech32::primitives::gf32::Fe3 pub type bech32::Checksum::MidstateRepr: bech32::primitives::checksum::PackedFe32 pub type bech32::primitives::Bech32::MidstateRepr = u32 pub type bech32::primitives::Bech32m::MidstateRepr = u32 +pub type bech32::primitives::ExtensionField::BaseField: bech32::primitives::Field pub type bech32::primitives::NoChecksum::MidstateRepr = bech32::primitives::checksum::PackedNull pub type bech32::primitives::checksum::Checksum::MidstateRepr: bech32::primitives::checksum::PackedFe32 pub type bech32::primitives::checksum::HrpFe32Iter<'hrp>::Item = bech32::primitives::gf32::Fe32 diff --git a/api/no-features.txt b/api/no-features.txt index 357820dbf..fb4d8bd1c 100644 --- a/api/no-features.txt +++ b/api/no-features.txt @@ -14,6 +14,7 @@ #[non_exhaustive] pub struct bech32::primitives::segwit::InvalidWitnessVersionError(pub bech32::primitives::gf32::Fe32) #[repr(transparent)] pub struct bech32::Fe32(_) #[repr(transparent)] pub struct bech32::primitives::gf32::Fe32(_) +impl bech32::primitives::Field for bech32::primitives::gf32::Fe32 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32m impl bech32::primitives::checksum::Checksum for bech32::primitives::NoChecksum @@ -266,21 +267,26 @@ impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for &bech32::primiti impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Add for &bech32::primitives::gf32::Fe32 impl core::ops::arith::AddAssign for bech32::primitives::gf32::Fe32 +impl core::ops::arith::AddAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div for &bech32::primitives::gf32::Fe32 impl core::ops::arith::DivAssign for bech32::primitives::gf32::Fe32 +impl core::ops::arith::DivAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul for &bech32::primitives::gf32::Fe32 impl core::ops::arith::MulAssign for bech32::primitives::gf32::Fe32 +impl core::ops::arith::MulAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::Neg for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub for &bech32::primitives::gf32::Fe32 impl core::ops::arith::SubAssign for bech32::primitives::gf32::Fe32 +impl core::ops::arith::SubAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::bit::BitXor for bech32::primitives::checksum::PackedNull impl core::panic::unwind_safe::RefUnwindSafe for bech32::EncodeError impl core::panic::unwind_safe::RefUnwindSafe for bech32::primitives::Bech32 @@ -556,6 +562,14 @@ pub const bech32::primitives::Bech32m::CHECKSUM_LENGTH: usize pub const bech32::primitives::Bech32m::CODE_LENGTH: usize pub const bech32::primitives::Bech32m::GENERATOR_SH: [u32; 5] pub const bech32::primitives::Bech32m::TARGET_RESIDUE: u32 +pub const bech32::primitives::ExtensionField::DEGREE: usize +pub const bech32::primitives::ExtensionField::EXT_ELEM: Self +pub const bech32::primitives::ExtensionField::POLYNOMIAL: Self +pub const bech32::primitives::Field::GENERATOR: Self +pub const bech32::primitives::Field::MULTIPLICATIVE_ORDER: usize +pub const bech32::primitives::Field::MULTIPLICATIVE_ORDER_FACTORS: &'static [usize] +pub const bech32::primitives::Field::ONE: Self +pub const bech32::primitives::Field::ZERO: Self pub const bech32::primitives::NoChecksum::CHECKSUM_LENGTH: usize pub const bech32::primitives::NoChecksum::CODE_LENGTH: usize pub const bech32::primitives::NoChecksum::GENERATOR_SH: [bech32::primitives::checksum::PackedNull; 5] @@ -573,12 +587,16 @@ pub const bech32::primitives::gf32::Fe32::D: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::E: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::F: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::G: bech32::primitives::gf32::Fe32 +pub const bech32::primitives::gf32::Fe32::GENERATOR: Self pub const bech32::primitives::gf32::Fe32::H: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::J: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::K: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::L: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::M: bech32::primitives::gf32::Fe32 +pub const bech32::primitives::gf32::Fe32::MULTIPLICATIVE_ORDER: usize +pub const bech32::primitives::gf32::Fe32::MULTIPLICATIVE_ORDER_FACTORS: &'static [usize] pub const bech32::primitives::gf32::Fe32::N: bech32::primitives::gf32::Fe32 +pub const bech32::primitives::gf32::Fe32::ONE: Self pub const bech32::primitives::gf32::Fe32::P: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::Q: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::R: bech32::primitives::gf32::Fe32 @@ -590,6 +608,7 @@ pub const bech32::primitives::gf32::Fe32::W: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::X: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::Y: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::Z: bech32::primitives::gf32::Fe32 +pub const bech32::primitives::gf32::Fe32::ZERO: Self pub const bech32::primitives::gf32::Fe32::_0: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::_2: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::_3: bech32::primitives::gf32::Fe32 @@ -648,6 +667,14 @@ pub fn bech32::primitives::Bech32m::cmp(&self, other: &bech32::primitives::Bech3 pub fn bech32::primitives::Bech32m::eq(&self, other: &bech32::primitives::Bech32m) -> bool pub fn bech32::primitives::Bech32m::hash<__H: core::hash::Hasher>(&self, state: &mut __H) pub fn bech32::primitives::Bech32m::partial_cmp(&self, other: &bech32::primitives::Bech32m) -> core::option::Option +pub fn bech32::primitives::Field::_add(&self, other: &Self) -> Self +pub fn bech32::primitives::Field::_div(&self, other: &Self) -> Self +pub fn bech32::primitives::Field::_mul(&self, other: &Self) -> Self +pub fn bech32::primitives::Field::_neg(self) -> Self +pub fn bech32::primitives::Field::_sub(&self, other: &Self) -> Self +pub fn bech32::primitives::Field::multiplicative_inverse(self) -> Self +pub fn bech32::primitives::Field::multiplicative_order(&self) -> usize +pub fn bech32::primitives::Field::powi(&self, n: i64) -> Self pub fn bech32::primitives::NoChecksum::clone(&self) -> bech32::primitives::NoChecksum pub fn bech32::primitives::NoChecksum::cmp(&self, other: &bech32::primitives::NoChecksum) -> core::cmp::Ordering pub fn bech32::primitives::NoChecksum::eq(&self, other: &bech32::primitives::NoChecksum) -> bool @@ -761,13 +788,20 @@ pub fn bech32::primitives::encode::Fe32Iter<'hrp, I, Ck>::size_hint(&self) -> (u pub fn bech32::primitives::encode::WitnessVersionIter::new(witness_version: core::option::Option, iter: I) -> Self pub fn bech32::primitives::encode::WitnessVersionIter::next(&mut self) -> core::option::Option pub fn bech32::primitives::encode::WitnessVersionIter::size_hint(&self) -> (usize, core::option::Option) +pub fn bech32::primitives::gf32::Fe32::_add(&self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::_div(&self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::_mul(&self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::_neg(self) -> Self +pub fn bech32::primitives::gf32::Fe32::_sub(&self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::add(self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::add(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::add_assign(&mut self, other: &bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::add_assign(&mut self, other: bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::as_ref(&self) -> &u8 pub fn bech32::primitives::gf32::Fe32::clone(&self) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::div(self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::div(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::div_assign(&mut self, other: &bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::div_assign(&mut self, other: bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::eq(&self, other: &bech32::primitives::gf32::Fe32) -> bool pub fn bech32::primitives::gf32::Fe32::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result @@ -777,9 +811,13 @@ pub fn bech32::primitives::gf32::Fe32::hash<__H: core::hash::Hasher>(&self, stat pub fn bech32::primitives::gf32::Fe32::iter_alpha() -> impl core::iter::traits::iterator::Iterator pub fn bech32::primitives::gf32::Fe32::mul(self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::mul(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::mul_assign(&mut self, other: &bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::mul_assign(&mut self, other: bech32::primitives::gf32::Fe32) +pub fn bech32::primitives::gf32::Fe32::multiplicative_inverse(self) -> Self +pub fn bech32::primitives::gf32::Fe32::neg(self) -> Self pub fn bech32::primitives::gf32::Fe32::sub(self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn bech32::primitives::gf32::Fe32::sub(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn bech32::primitives::gf32::Fe32::sub_assign(&mut self, other: &bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::sub_assign(&mut self, other: bech32::primitives::gf32::Fe32) pub fn bech32::primitives::gf32::Fe32::to_char(self) -> char pub fn bech32::primitives::gf32::Fe32::to_u8(self) -> u8 @@ -916,6 +954,8 @@ pub struct bech32::primitives::iter::FesToBytes pub trait bech32::Checksum pub trait bech32::Fe32IterExt: core::marker::Sized + core::iter::traits::iterator::Iterator +pub trait bech32::primitives::ExtensionField: bech32::primitives::Field + core::convert::From +pub trait bech32::primitives::Field: core::marker::Sized + core::cmp::PartialEq + core::cmp::Eq + core::clone::Clone + core::hash::Hash + core::fmt::Debug + core::fmt::Display + core::ops::arith::Add + core::ops::arith::Sub + core::ops::arith::AddAssign + core::ops::arith::SubAssign + core::ops::arith::Mul + core::ops::arith::MulAssign + core::ops::arith::Div + core::ops::arith::DivAssign + for<'a> core::ops::arith::Add<&'a Self, Output = Self> + for<'a> core::ops::arith::AddAssign<&'a Self> + for<'a> core::ops::arith::Sub<&'a Self, Output = Self> + for<'a> core::ops::arith::SubAssign<&'a Self> + for<'a> core::ops::arith::Mul<&'a Self, Output = Self> + for<'a> core::ops::arith::MulAssign<&'a Self> + for<'a> core::ops::arith::Div<&'a Self, Output = Self> + for<'a> core::ops::arith::DivAssign<&'a Self> + core::ops::arith::Neg pub trait bech32::primitives::checksum::Checksum pub trait bech32::primitives::checksum::PackedFe32: core::marker::Copy + core::cmp::PartialEq + core::cmp::Eq + core::ops::bit::BitXor pub trait bech32::primitives::iter::ByteIterExt: core::marker::Sized + core::iter::traits::iterator::Iterator @@ -924,6 +964,7 @@ pub type &bech32::primitives::gf32::Fe32::Output = bech32::primitives::gf32::Fe3 pub type bech32::Checksum::MidstateRepr: bech32::primitives::checksum::PackedFe32 pub type bech32::primitives::Bech32::MidstateRepr = u32 pub type bech32::primitives::Bech32m::MidstateRepr = u32 +pub type bech32::primitives::ExtensionField::BaseField: bech32::primitives::Field pub type bech32::primitives::NoChecksum::MidstateRepr = bech32::primitives::checksum::PackedNull pub type bech32::primitives::checksum::Checksum::MidstateRepr: bech32::primitives::checksum::PackedFe32 pub type bech32::primitives::checksum::HrpFe32Iter<'hrp>::Item = bech32::primitives::gf32::Fe32 diff --git a/src/primitives/field.rs b/src/primitives/field.rs new file mode 100644 index 000000000..d7da8c794 --- /dev/null +++ b/src/primitives/field.rs @@ -0,0 +1,367 @@ +// SPDX-License-Identifier: MIT + +//! Generic Field Traits + +use core::{fmt, hash, ops}; + +/// A generic field. +pub trait Field: + Sized + + PartialEq + + Eq + + Clone + + hash::Hash + + fmt::Debug + + fmt::Display + + ops::Add + + ops::Sub + + ops::AddAssign + + ops::SubAssign + + ops::Mul + + ops::MulAssign + + ops::Div + + ops::DivAssign + + for<'a> ops::Add<&'a Self, Output = Self> + + for<'a> ops::AddAssign<&'a Self> + + for<'a> ops::Sub<&'a Self, Output = Self> + + for<'a> ops::SubAssign<&'a Self> + + for<'a> ops::Mul<&'a Self, Output = Self> + + for<'a> ops::MulAssign<&'a Self> + + for<'a> ops::Div<&'a Self, Output = Self> + + for<'a> ops::DivAssign<&'a Self> + + ops::Neg +{ + /// The zero constant of the field. + const ZERO: Self; + + /// The one constant of the field. + const ONE: Self; + + /// A primitive element, i.e. a generator of the multiplicative group of the field. + const GENERATOR: Self; + + /// The order of the multiplicative group of the field. + const MULTIPLICATIVE_ORDER: usize; + + /// All factors of the multiplicative order, in increasing order. + /// + /// Include both 1 and the number itself. So for example if you have `n` distinct + /// prime factors which each appearing once, this array would have size `2^n`. + const MULTIPLICATIVE_ORDER_FACTORS: &'static [usize]; + + /// Adds a value to `self`. This is a helper function for implementing the + /// [`ops::Add`] and [`ops::AddAssign`] traits, which should probably be called + /// instead of calling this. + fn _add(&self, other: &Self) -> Self; + + /// Subtracts a value from `self`. This is a helper function for implementing the + /// [`ops::Sub`] and [`ops::SubAssign`] traits, which should probably be called + /// instead of calling this. + fn _sub(&self, other: &Self) -> Self; + + /// Multiplies a value by `self`. This is a helper function for implementing the + /// [`ops::Mul`] and [`ops::MulAssign`] traits, which should probably be called + /// instead of calling this. + fn _mul(&self, other: &Self) -> Self; + + /// Divides a value from `self`. This is a helper function for implementing the + /// [`ops::Div`] and [`ops::DivAssign`] traits, which should probably be called + /// instead of calling this. + fn _div(&self, other: &Self) -> Self; + + /// Computes the additive inverse of an element. + fn _neg(self) -> Self; + + /// Computes the multiplicative inverse of an element. + fn multiplicative_inverse(self) -> Self; + + /// Takes the element to the power of some integer. + fn powi(&self, mut n: i64) -> Self { + let base = if n >= 0 { + self.clone() + } else { + n *= -1; + self.clone().multiplicative_inverse() + }; + n %= Self::MULTIPLICATIVE_ORDER as i64; + + let mut mask = Self::MULTIPLICATIVE_ORDER.next_power_of_two() as i64; + let mut ret = Self::ONE; + while mask > 0 { + ret *= ret.clone(); + if n & mask != 0 { + ret *= base.clone(); + } + mask >>= 1; + } + ret + } + + /// The multiplicative order of an element. + fn multiplicative_order(&self) -> usize { + for &ord in Self::MULTIPLICATIVE_ORDER_FACTORS { + if self.powi(ord as i64) == Self::ONE { + return ord; + } + } + panic!( + "bug: `ExtensionField::MULTIPLICATIVE_ORDER_FACTORS` did not include full group order" + ); + } +} + +/// Trait describing a simple extension field (field obtained from another by +/// adjoining one element). +pub trait ExtensionField: Field + From { + /// The type of the base field. + type BaseField: Field; + + /// The degree of the extension. + /// + /// Must be strictly greater than 1. + const DEGREE: usize; + + /// An extension field is defined as `GF32[x]/p(x)`, for some irreducible + /// monic polynomial p whose degree then becomes the degree of the extension. + /// + /// If p(x) = x^d + ... p_1x + p_0 we can represent p by an element of + /// the extension field, specifically the image of p(x) - x^d. Equivalently, + /// if zeta is the image of x in the quotient map, then this value is + /// equal to zeta^d. + /// + /// This value is used to define multiplication in the extension field. + const POLYNOMIAL: Self; + + /// The element which is adjoined to the base field to get this field. + /// + /// In other words, the image of x in the isomorphism from + /// [`Self::BaseField`]`[x]`/[`Self::POLYNOMIAL`] to [`Self`]. + const EXT_ELEM: Self; +} + +macro_rules! impl_ops_for_fe { + (impl for $op:ident) => { + // add + impl core::ops::Add<$op> for $op { + type Output = Self; + #[inline] + fn add(self, other: $op) -> $op { + use $crate::primitives::Field as _; + self._add(&other) + } + } + + impl core::ops::Add<&$op> for $op { + type Output = Self; + #[inline] + fn add(self, other: &$op) -> $op { + use $crate::primitives::Field as _; + self._add(other) + } + } + + impl core::ops::Add<$op> for &$op { + type Output = $op; + #[inline] + fn add(self, other: $op) -> $op { + use $crate::primitives::Field as _; + self._add(&other) + } + } + + impl core::ops::Add<&$op> for &$op { + type Output = $op; + #[inline] + fn add(self, other: &$op) -> $op { + use $crate::primitives::Field as _; + self._add(other) + } + } + + impl core::ops::AddAssign for $op { + #[inline] + fn add_assign(&mut self, other: $op) { + use $crate::primitives::Field as _; + *self = self._add(&other) + } + } + + impl core::ops::AddAssign<&$op> for $op { + #[inline] + fn add_assign(&mut self, other: &$op) { + use $crate::primitives::Field as _; + *self = self._add(other) + } + } + + // sub + impl core::ops::Sub<$op> for $op { + type Output = Self; + #[inline] + fn sub(self, other: $op) -> $op { + use $crate::primitives::Field as _; + self._sub(&other) + } + } + + impl core::ops::Sub<&$op> for $op { + type Output = Self; + #[inline] + fn sub(self, other: &$op) -> $op { + use $crate::primitives::Field as _; + self._sub(other) + } + } + + impl core::ops::Sub<$op> for &$op { + type Output = $op; + #[inline] + fn sub(self, other: $op) -> $op { + use $crate::primitives::Field as _; + self._sub(&other) + } + } + + impl core::ops::Sub<&$op> for &$op { + type Output = $op; + #[inline] + fn sub(self, other: &$op) -> $op { + use $crate::primitives::Field as _; + self._sub(other) + } + } + + impl core::ops::SubAssign for $op { + #[inline] + fn sub_assign(&mut self, other: $op) { + use $crate::primitives::Field as _; + *self = self._sub(&other) + } + } + + impl core::ops::SubAssign<&$op> for $op { + #[inline] + fn sub_assign(&mut self, other: &$op) { + use $crate::primitives::Field as _; + *self = self._sub(other) + } + } + + // mul + impl core::ops::Mul<$op> for $op { + type Output = Self; + #[inline] + fn mul(self, other: $op) -> $op { + use $crate::primitives::Field as _; + self._mul(&other) + } + } + + impl core::ops::Mul<&$op> for $op { + type Output = Self; + #[inline] + fn mul(self, other: &$op) -> $op { + use $crate::primitives::Field as _; + self._mul(other) + } + } + + impl core::ops::Mul<$op> for &$op { + type Output = $op; + #[inline] + fn mul(self, other: $op) -> $op { + use $crate::primitives::Field as _; + self._mul(&other) + } + } + + impl core::ops::Mul<&$op> for &$op { + type Output = $op; + #[inline] + fn mul(self, other: &$op) -> $op { + use $crate::primitives::Field as _; + self._mul(other) + } + } + + impl core::ops::MulAssign for $op { + #[inline] + fn mul_assign(&mut self, other: $op) { + use $crate::primitives::Field as _; + *self = self._mul(&other) + } + } + + impl core::ops::MulAssign<&$op> for $op { + #[inline] + fn mul_assign(&mut self, other: &$op) { + use $crate::primitives::Field as _; + *self = self._mul(other) + } + } + + // div + impl core::ops::Div<$op> for $op { + type Output = Self; + #[inline] + fn div(self, other: $op) -> $op { + use $crate::primitives::Field as _; + self._div(&other) + } + } + + impl core::ops::Div<&$op> for $op { + type Output = Self; + #[inline] + fn div(self, other: &$op) -> $op { + use $crate::primitives::Field as _; + self._div(other) + } + } + + impl core::ops::Div<$op> for &$op { + type Output = $op; + #[inline] + fn div(self, other: $op) -> $op { + use $crate::primitives::Field as _; + self._div(&other) + } + } + + impl core::ops::Div<&$op> for &$op { + type Output = $op; + #[inline] + fn div(self, other: &$op) -> $op { + use $crate::primitives::Field as _; + self._div(other) + } + } + + impl core::ops::DivAssign for $op { + #[inline] + fn div_assign(&mut self, other: $op) { + use $crate::primitives::Field as _; + *self = self._div(&other) + } + } + + impl core::ops::DivAssign<&$op> for $op { + #[inline] + fn div_assign(&mut self, other: &$op) { + use $crate::primitives::Field as _; + *self = self._div(other) + } + } + + // neg + impl core::ops::Neg for $op { + type Output = Self; + #[inline] + fn neg(self) -> Self { + use $crate::primitives::Field as _; + self._neg() + } + } + }; +} +pub(super) use impl_ops_for_fe; diff --git a/src/primitives/gf32.rs b/src/primitives/gf32.rs index 5b8fb20ae..0c56841a0 100644 --- a/src/primitives/gf32.rs +++ b/src/primitives/gf32.rs @@ -13,7 +13,7 @@ //! [BIP-173]: use core::convert::{Infallible, TryFrom}; -use core::{fmt, num, ops}; +use core::{fmt, num}; #[cfg(all(test, mutate))] use mutagen::mutate; @@ -215,35 +215,6 @@ impl Fe32 { /// of the polynomial representation. #[inline] pub fn to_u8(self) -> u8 { self.0 } - - fn _add(self, other: Fe32) -> Fe32 { Fe32(self.0 ^ other.0) } - - // Subtraction is the same as addition in a char-2 field. - fn _sub(self, other: Fe32) -> Fe32 { self + other } - - #[cfg_attr(all(test, mutate), mutate)] - fn _mul(self, other: Fe32) -> Fe32 { - if self.0 == 0 || other.0 == 0 { - Fe32(0) - } else { - let log1 = LOG[self.0 as usize]; - let log2 = LOG[other.0 as usize]; - Fe32(LOG_INV[((log1 + log2) % 31) as usize]) - } - } - - #[cfg_attr(all(test, mutate), mutate)] - fn _div(self, other: Fe32) -> Fe32 { - if self.0 == 0 { - Fe32(0) - } else if other.0 == 0 { - panic!("Attempt to divide {} by 0 in GF32", self); - } else { - let log1 = LOG[self.0 as usize]; - let log2 = LOG[other.0 as usize]; - Fe32(LOG_INV[((31 + log1 - log2) % 31) as usize]) - } - } } impl fmt::Display for Fe32 { @@ -285,58 +256,45 @@ impl AsRef for Fe32 { fn as_ref(&self) -> &u8 { &self.0 } } -/// Implements $op for the 2x2 matrix of type by ref to type -macro_rules! impl_op_matrix { - ($op:ident, $op_fn:ident, $call_fn:ident) => { - impl ops::$op for Fe32 { - type Output = Fe32; - #[inline] - fn $op_fn(self, other: Fe32) -> Fe32 { self.$call_fn(other) } - } - - impl ops::$op for &Fe32 { - type Output = Fe32; - #[inline] - fn $op_fn(self, other: Fe32) -> Fe32 { self.$call_fn(other) } - } - - impl ops::$op<&Fe32> for Fe32 { - type Output = Fe32; - #[inline] - fn $op_fn(self, other: &Fe32) -> Fe32 { self.$call_fn(*other) } +impl super::Field for Fe32 { + const ZERO: Self = Fe32::Q; + const ONE: Self = Fe32::P; + const GENERATOR: Self = Fe32::Z; + const MULTIPLICATIVE_ORDER: usize = 31; + const MULTIPLICATIVE_ORDER_FACTORS: &'static [usize] = &[1, 31]; + + fn _add(&self, other: &Fe32) -> Fe32 { Fe32(self.0 ^ other.0) } + // Subtraction is the same as addition in a characteristic-2 field + fn _sub(&self, other: &Fe32) -> Fe32 { self._add(other) } + fn _mul(&self, other: &Fe32) -> Fe32 { + if self.0 == 0 || other.0 == 0 { + Fe32(0) + } else { + let log1 = LOG[self.0 as usize]; + let log2 = LOG[other.0 as usize]; + let mult_order = Self::MULTIPLICATIVE_ORDER as isize; + Fe32(LOG_INV[((log1 + log2) % mult_order) as usize]) } - - impl ops::$op<&Fe32> for &Fe32 { - type Output = Fe32; - #[inline] - fn $op_fn(self, other: &Fe32) -> Fe32 { self.$call_fn(*other) } + } + fn _div(&self, other: &Fe32) -> Fe32 { + if self.0 == 0 { + Fe32(0) + } else if other.0 == 0 { + panic!("Attempt to divide {} by 0 in GF32", self); + } else { + let log1 = LOG[self.0 as usize]; + let log2 = LOG[other.0 as usize]; + let mult_order = Self::MULTIPLICATIVE_ORDER as isize; + Fe32(LOG_INV[((mult_order + log1 - log2) % mult_order) as usize]) } - }; -} -impl_op_matrix!(Add, add, _add); -impl_op_matrix!(Sub, sub, _sub); -impl_op_matrix!(Mul, mul, _mul); -impl_op_matrix!(Div, div, _div); - -impl ops::AddAssign for Fe32 { - #[inline] - fn add_assign(&mut self, other: Fe32) { *self = *self + other; } -} + } -impl ops::SubAssign for Fe32 { - #[inline] - fn sub_assign(&mut self, other: Fe32) { *self = *self - other; } -} + fn _neg(self) -> Self { self } -impl ops::MulAssign for Fe32 { - #[inline] - fn mul_assign(&mut self, other: Fe32) { *self = *self * other; } + fn multiplicative_inverse(self) -> Self { Self::ONE._div(&self) } } -impl ops::DivAssign for Fe32 { - #[inline] - fn div_assign(&mut self, other: Fe32) { *self = *self / other; } -} +super::impl_ops_for_fe!(impl for Fe32); /// A galois field error when converting from a character. #[derive(Copy, Clone, PartialEq, Eq, Debug)] @@ -506,7 +464,7 @@ mod tests { fn mul_zero() { for c in &CHARS_LOWER[..] { let fe = Fe32::from_char(*c).unwrap(); - assert_eq!(fe._mul(Fe32::Q), Fe32::Q) // Fe32::Q == Fe32(0) + assert_eq!(fe * Fe32::Q, Fe32::Q) // Fe32::Q == Fe32(0) } } diff --git a/src/primitives/mod.rs b/src/primitives/mod.rs index 50463dc3a..c90f9e94f 100644 --- a/src/primitives/mod.rs +++ b/src/primitives/mod.rs @@ -5,12 +5,15 @@ pub mod checksum; pub mod decode; pub mod encode; +mod field; pub mod gf32; pub mod hrp; pub mod iter; pub mod segwit; use checksum::{Checksum, PackedNull}; +use field::impl_ops_for_fe; +pub use field::{ExtensionField, Field}; /// The "null checksum" used on bech32 strings for which we want to do no checksum checking. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] From cf545e48081b46e52f9598e2b76449741c07b444 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Fri, 5 Jul 2024 20:23:43 +0000 Subject: [PATCH 3/8] primitives: add extension field module, define GF1024 Again, strictly adding API surface, not removing anything. --- api/all-features.txt | 87 ++++++++++++ api/alloc-only.txt | 87 ++++++++++++ api/no-features.txt | 87 ++++++++++++ src/lib.rs | 1 + src/primitives/gf32_ext.rs | 272 +++++++++++++++++++++++++++++++++++++ src/primitives/mod.rs | 1 + 6 files changed, 535 insertions(+) create mode 100644 src/primitives/gf32_ext.rs diff --git a/api/all-features.txt b/api/all-features.txt index 93c718cce..233b3c2c1 100644 --- a/api/all-features.txt +++ b/api/all-features.txt @@ -20,7 +20,9 @@ #[repr(transparent)] pub struct bech32::primitives::gf32::Fe32(_) impl !core::panic::unwind_safe::RefUnwindSafe for bech32::EncodeIoError impl !core::panic::unwind_safe::UnwindSafe for bech32::EncodeIoError +impl bech32::primitives::ExtensionField for bech32::primitives::gf32_ext::Fe1024 impl bech32::primitives::Field for bech32::primitives::gf32::Fe32 +impl bech32::primitives::Field for bech32::primitives::gf32_ext::Fe1024 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32m impl bech32::primitives::checksum::Checksum for bech32::primitives::NoChecksum @@ -333,28 +335,44 @@ impl core::marker::Unpin for bech32::segwit::EncodeError impl core::ops::arith::Add for bech32::primitives::gf32::Fe32 impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Add for &bech32::primitives::gf32::Fe32 +impl core::ops::arith::Add> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::AddAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::AddAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::AddAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Div for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Div for &bech32::primitives::gf32::Fe32 +impl core::ops::arith::Div> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::DivAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::DivAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::DivAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Mul for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Mul for &bech32::primitives::gf32::Fe32 +impl core::ops::arith::Mul> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::MulAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::MulAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::MulAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Neg for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Sub for &bech32::primitives::gf32::Fe32 +impl core::ops::arith::Sub> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::SubAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::SubAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::SubAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::bit::BitXor for bech32::primitives::checksum::PackedNull impl core::panic::unwind_safe::RefUnwindSafe for bech32::DecodeError impl core::panic::unwind_safe::RefUnwindSafe for bech32::EncodeError @@ -585,6 +603,26 @@ impl core::panic::unwind_safe::RefUnwindSafe for bech32::primitives::iter::Fe impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::encode::WitnessVersionIter where I: core::panic::unwind_safe::UnwindSafe impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::iter::BytesToFes where I: core::panic::unwind_safe::UnwindSafe impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::iter::FesToBytes where I: core::panic::unwind_safe::UnwindSafe +impl bech32::primitives::gf32_ext::Fe32Ext where Self: bech32::primitives::ExtensionField +impl core::clone::Clone for bech32::primitives::gf32_ext::Fe32Ext +impl core::cmp::Eq for bech32::primitives::gf32_ext::Fe32Ext +impl core::cmp::PartialEq for bech32::primitives::gf32_ext::Fe32Ext +impl core::convert::From for bech32::primitives::gf32_ext::Fe32Ext +impl core::fmt::Debug for bech32::primitives::gf32_ext::Fe32Ext +impl core::fmt::Display for bech32::primitives::gf32_ext::Fe32Ext +impl core::hash::Hash for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::Copy for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::Freeze for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::Send for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::StructuralPartialEq for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::Sync for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::Unpin for bech32::primitives::gf32_ext::Fe32Ext +impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32_ext::Fe32Ext +impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32_ext::Fe32Ext +impl core::ops::arith::Mul for &bech32::primitives::gf32_ext::Fe32Ext +impl core::ops::arith::Mul for bech32::primitives::gf32_ext::Fe32Ext +impl core::panic::unwind_safe::RefUnwindSafe for bech32::primitives::gf32_ext::Fe32Ext +impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::gf32_ext::Fe32Ext pub bech32::DecodeError::Checksum(bech32::primitives::decode::ChecksumError) pub bech32::DecodeError::Parse(bech32::primitives::decode::UncheckedHrpstringError) pub bech32::EncodeError::Fmt(core::fmt::Error) @@ -700,6 +738,14 @@ pub const bech32::primitives::gf32::Fe32::_6: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::_7: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::_8: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::_9: bech32::primitives::gf32::Fe32 +pub const bech32::primitives::gf32_ext::Fe1024::DEGREE: usize +pub const bech32::primitives::gf32_ext::Fe1024::EXT_ELEM: Self +pub const bech32::primitives::gf32_ext::Fe1024::GENERATOR: Self +pub const bech32::primitives::gf32_ext::Fe1024::MULTIPLICATIVE_ORDER: usize +pub const bech32::primitives::gf32_ext::Fe1024::MULTIPLICATIVE_ORDER_FACTORS: &'static [usize] +pub const bech32::primitives::gf32_ext::Fe1024::ONE: Self +pub const bech32::primitives::gf32_ext::Fe1024::POLYNOMIAL: Self +pub const bech32::primitives::gf32_ext::Fe1024::ZERO: Self pub const bech32::primitives::hrp::BC: bech32::primitives::hrp::Hrp pub const bech32::primitives::hrp::BCRT: bech32::primitives::hrp::Hrp pub const bech32::primitives::hrp::TB: bech32::primitives::hrp::Hrp @@ -708,6 +754,7 @@ pub const bech32::primitives::segwit::VERSION_0: bech32::primitives::gf32::Fe32 pub const bech32::primitives::segwit::VERSION_1: bech32::primitives::gf32::Fe32 pub const bech32::segwit::VERSION_0: bech32::primitives::gf32::Fe32 pub const bech32::segwit::VERSION_1: bech32::primitives::gf32::Fe32 +pub const fn bech32::primitives::gf32_ext::Fe32Ext::new(inner: [bech32::primitives::gf32::Fe32; DEG]) -> Self pub const fn bech32::primitives::hrp::Hrp::parse_unchecked(hrp: &str) -> Self pub const u128::ONE: Self pub const u32::ONE: Self @@ -726,6 +773,16 @@ pub fn &bech32::primitives::gf32::Fe32::mul(self, other: &bech32::primitives::gf pub fn &bech32::primitives::gf32::Fe32::mul(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn &bech32::primitives::gf32::Fe32::sub(self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn &bech32::primitives::gf32::Fe32::sub(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn &bech32::primitives::gf32_ext::Fe1024::add(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::add(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::div(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::div(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::mul(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::mul(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::sub(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::sub(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: &bech32::primitives::gf32::Fe32) -> Self::Output +pub fn &bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: bech32::primitives::gf32::Fe32) -> Self::Output pub fn bech32::ByteIterExt::bytes_to_fes(self) -> bech32::primitives::iter::BytesToFes pub fn bech32::Checksum::sanity_check() pub fn bech32::DecodeError::clone(&self) -> bech32::DecodeError @@ -948,6 +1005,27 @@ pub fn bech32::primitives::gf32::TryFromError::fmt(&self, f: &mut core::fmt::For pub fn bech32::primitives::gf32::TryFromError::from(e: core::num::error::TryFromIntError) -> Self pub fn bech32::primitives::gf32::TryFromError::from(i: core::convert::Infallible) -> Self pub fn bech32::primitives::gf32::TryFromError::source(&self) -> core::option::Option<&(dyn core::error::Error + 'static)> +pub fn bech32::primitives::gf32_ext::Fe1024::_add(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::_div(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::_mul(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::_neg(self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::_sub(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::add(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn bech32::primitives::gf32_ext::Fe1024::add_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe1024) +pub fn bech32::primitives::gf32_ext::Fe1024::div(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn bech32::primitives::gf32_ext::Fe1024::div_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe1024) +pub fn bech32::primitives::gf32_ext::Fe1024::mul(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn bech32::primitives::gf32_ext::Fe1024::mul_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe1024) +pub fn bech32::primitives::gf32_ext::Fe1024::multiplicative_inverse(self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::sub(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn bech32::primitives::gf32_ext::Fe1024::sub_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe1024) +pub fn bech32::primitives::gf32_ext::Fe32Ext::clone(&self) -> bech32::primitives::gf32_ext::Fe32Ext +pub fn bech32::primitives::gf32_ext::Fe32Ext::eq(&self, other: &bech32::primitives::gf32_ext::Fe32Ext) -> bool +pub fn bech32::primitives::gf32_ext::Fe32Ext::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +pub fn bech32::primitives::gf32_ext::Fe32Ext::from(fe: bech32::primitives::gf32::Fe32) -> Self +pub fn bech32::primitives::gf32_ext::Fe32Ext::hash<__H: core::hash::Hasher>(&self, state: &mut __H) +pub fn bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: &bech32::primitives::gf32::Fe32) -> Self::Output +pub fn bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: bech32::primitives::gf32::Fe32) -> Self::Output pub fn bech32::primitives::hrp::ByteIter<'b>::len(&self) -> usize pub fn bech32::primitives::hrp::ByteIter<'b>::next(&mut self) -> core::option::Option pub fn bech32::primitives::hrp::ByteIter<'b>::next_back(&mut self) -> core::option::Option @@ -1057,6 +1135,7 @@ pub mod bech32::primitives::checksum pub mod bech32::primitives::decode pub mod bech32::primitives::encode pub mod bech32::primitives::gf32 +pub mod bech32::primitives::gf32_ext pub mod bech32::primitives::hrp pub mod bech32::primitives::iter pub mod bech32::primitives::segwit @@ -1076,6 +1155,7 @@ pub struct bech32::primitives::encode::CharIter<'hrp, I, Ck> where I: core::iter pub struct bech32::primitives::encode::Encoder<'hrp, I, Ck> where I: core::iter::traits::iterator::Iterator, Ck: bech32::primitives::checksum::Checksum pub struct bech32::primitives::encode::Fe32Iter<'hrp, I, Ck> where I: core::iter::traits::iterator::Iterator, Ck: bech32::primitives::checksum::Checksum pub struct bech32::primitives::encode::WitnessVersionIter where I: core::iter::traits::iterator::Iterator +pub struct bech32::primitives::gf32_ext::Fe32Ext pub struct bech32::primitives::hrp::ByteIter<'b> pub struct bech32::primitives::hrp::CharIter<'b> pub struct bech32::primitives::hrp::Hrp @@ -1094,7 +1174,10 @@ pub trait bech32::primitives::checksum::PackedFe32: core::marker::Copy + core::c pub trait bech32::primitives::iter::ByteIterExt: core::marker::Sized + core::iter::traits::iterator::Iterator pub trait bech32::primitives::iter::Fe32IterExt: core::marker::Sized + core::iter::traits::iterator::Iterator pub type &bech32::primitives::gf32::Fe32::Output = bech32::primitives::gf32::Fe32 +pub type &bech32::primitives::gf32_ext::Fe1024::Output = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type &bech32::primitives::gf32_ext::Fe32Ext::Output = bech32::primitives::gf32_ext::Fe32Ext pub type bech32::Checksum::MidstateRepr: bech32::primitives::checksum::PackedFe32 +pub type bech32::Fe1024 = bech32::primitives::gf32_ext::Fe32Ext<2> pub type bech32::primitives::Bech32::MidstateRepr = u32 pub type bech32::primitives::Bech32m::MidstateRepr = u32 pub type bech32::primitives::ExtensionField::BaseField: bech32::primitives::Field @@ -1110,6 +1193,10 @@ pub type bech32::primitives::encode::Fe32Iter<'hrp, I, Ck>::Item = bech32::primi pub type bech32::primitives::encode::WitnessVersionIter::Item = bech32::primitives::gf32::Fe32 pub type bech32::primitives::gf32::Fe32::Error = bech32::primitives::gf32::TryFromError pub type bech32::primitives::gf32::Fe32::Output = bech32::primitives::gf32::Fe32 +pub type bech32::primitives::gf32_ext::Fe1024 = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type bech32::primitives::gf32_ext::Fe1024::BaseField = bech32::primitives::gf32::Fe32 +pub type bech32::primitives::gf32_ext::Fe1024::Output = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type bech32::primitives::gf32_ext::Fe32Ext::Output = bech32::primitives::gf32_ext::Fe32Ext pub type bech32::primitives::hrp::ByteIter<'b>::Item = u8 pub type bech32::primitives::hrp::CharIter<'b>::Item = char pub type bech32::primitives::hrp::LowercaseByteIter<'b>::Item = u8 diff --git a/api/alloc-only.txt b/api/alloc-only.txt index 72ea31394..c36b173d9 100644 --- a/api/alloc-only.txt +++ b/api/alloc-only.txt @@ -17,7 +17,9 @@ #[non_exhaustive] pub struct bech32::segwit::DecodeError(pub bech32::primitives::decode::SegwitHrpstringError) #[repr(transparent)] pub struct bech32::Fe32(_) #[repr(transparent)] pub struct bech32::primitives::gf32::Fe32(_) +impl bech32::primitives::ExtensionField for bech32::primitives::gf32_ext::Fe1024 impl bech32::primitives::Field for bech32::primitives::gf32::Fe32 +impl bech32::primitives::Field for bech32::primitives::gf32_ext::Fe1024 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32m impl bech32::primitives::checksum::Checksum for bech32::primitives::NoChecksum @@ -304,28 +306,44 @@ impl core::marker::Unpin for bech32::segwit::EncodeError impl core::ops::arith::Add for bech32::primitives::gf32::Fe32 impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Add for &bech32::primitives::gf32::Fe32 +impl core::ops::arith::Add> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::AddAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::AddAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::AddAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Div for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Div for &bech32::primitives::gf32::Fe32 +impl core::ops::arith::Div> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::DivAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::DivAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::DivAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Mul for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Mul for &bech32::primitives::gf32::Fe32 +impl core::ops::arith::Mul> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::MulAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::MulAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::MulAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Neg for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Sub for &bech32::primitives::gf32::Fe32 +impl core::ops::arith::Sub> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::SubAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::SubAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::SubAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::bit::BitXor for bech32::primitives::checksum::PackedNull impl core::panic::unwind_safe::RefUnwindSafe for bech32::DecodeError impl core::panic::unwind_safe::RefUnwindSafe for bech32::EncodeError @@ -556,6 +574,26 @@ impl core::panic::unwind_safe::RefUnwindSafe for bech32::primitives::iter::Fe impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::encode::WitnessVersionIter where I: core::panic::unwind_safe::UnwindSafe impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::iter::BytesToFes where I: core::panic::unwind_safe::UnwindSafe impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::iter::FesToBytes where I: core::panic::unwind_safe::UnwindSafe +impl bech32::primitives::gf32_ext::Fe32Ext where Self: bech32::primitives::ExtensionField +impl core::clone::Clone for bech32::primitives::gf32_ext::Fe32Ext +impl core::cmp::Eq for bech32::primitives::gf32_ext::Fe32Ext +impl core::cmp::PartialEq for bech32::primitives::gf32_ext::Fe32Ext +impl core::convert::From for bech32::primitives::gf32_ext::Fe32Ext +impl core::fmt::Debug for bech32::primitives::gf32_ext::Fe32Ext +impl core::fmt::Display for bech32::primitives::gf32_ext::Fe32Ext +impl core::hash::Hash for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::Copy for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::Freeze for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::Send for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::StructuralPartialEq for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::Sync for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::Unpin for bech32::primitives::gf32_ext::Fe32Ext +impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32_ext::Fe32Ext +impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32_ext::Fe32Ext +impl core::ops::arith::Mul for &bech32::primitives::gf32_ext::Fe32Ext +impl core::ops::arith::Mul for bech32::primitives::gf32_ext::Fe32Ext +impl core::panic::unwind_safe::RefUnwindSafe for bech32::primitives::gf32_ext::Fe32Ext +impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::gf32_ext::Fe32Ext pub bech32::DecodeError::Checksum(bech32::primitives::decode::ChecksumError) pub bech32::DecodeError::Parse(bech32::primitives::decode::UncheckedHrpstringError) pub bech32::EncodeError::Fmt(core::fmt::Error) @@ -669,6 +707,14 @@ pub const bech32::primitives::gf32::Fe32::_6: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::_7: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::_8: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::_9: bech32::primitives::gf32::Fe32 +pub const bech32::primitives::gf32_ext::Fe1024::DEGREE: usize +pub const bech32::primitives::gf32_ext::Fe1024::EXT_ELEM: Self +pub const bech32::primitives::gf32_ext::Fe1024::GENERATOR: Self +pub const bech32::primitives::gf32_ext::Fe1024::MULTIPLICATIVE_ORDER: usize +pub const bech32::primitives::gf32_ext::Fe1024::MULTIPLICATIVE_ORDER_FACTORS: &'static [usize] +pub const bech32::primitives::gf32_ext::Fe1024::ONE: Self +pub const bech32::primitives::gf32_ext::Fe1024::POLYNOMIAL: Self +pub const bech32::primitives::gf32_ext::Fe1024::ZERO: Self pub const bech32::primitives::hrp::BC: bech32::primitives::hrp::Hrp pub const bech32::primitives::hrp::BCRT: bech32::primitives::hrp::Hrp pub const bech32::primitives::hrp::TB: bech32::primitives::hrp::Hrp @@ -677,6 +723,7 @@ pub const bech32::primitives::segwit::VERSION_0: bech32::primitives::gf32::Fe32 pub const bech32::primitives::segwit::VERSION_1: bech32::primitives::gf32::Fe32 pub const bech32::segwit::VERSION_0: bech32::primitives::gf32::Fe32 pub const bech32::segwit::VERSION_1: bech32::primitives::gf32::Fe32 +pub const fn bech32::primitives::gf32_ext::Fe32Ext::new(inner: [bech32::primitives::gf32::Fe32; DEG]) -> Self pub const fn bech32::primitives::hrp::Hrp::parse_unchecked(hrp: &str) -> Self pub const u128::ONE: Self pub const u32::ONE: Self @@ -695,6 +742,16 @@ pub fn &bech32::primitives::gf32::Fe32::mul(self, other: &bech32::primitives::gf pub fn &bech32::primitives::gf32::Fe32::mul(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn &bech32::primitives::gf32::Fe32::sub(self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn &bech32::primitives::gf32::Fe32::sub(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn &bech32::primitives::gf32_ext::Fe1024::add(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::add(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::div(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::div(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::mul(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::mul(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::sub(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::sub(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: &bech32::primitives::gf32::Fe32) -> Self::Output +pub fn &bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: bech32::primitives::gf32::Fe32) -> Self::Output pub fn bech32::ByteIterExt::bytes_to_fes(self) -> bech32::primitives::iter::BytesToFes pub fn bech32::Checksum::sanity_check() pub fn bech32::DecodeError::clone(&self) -> bech32::DecodeError @@ -898,6 +955,27 @@ pub fn bech32::primitives::gf32::TryFromError::eq(&self, other: &bech32::primiti pub fn bech32::primitives::gf32::TryFromError::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bech32::primitives::gf32::TryFromError::from(e: core::num::error::TryFromIntError) -> Self pub fn bech32::primitives::gf32::TryFromError::from(i: core::convert::Infallible) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::_add(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::_div(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::_mul(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::_neg(self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::_sub(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::add(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn bech32::primitives::gf32_ext::Fe1024::add_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe1024) +pub fn bech32::primitives::gf32_ext::Fe1024::div(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn bech32::primitives::gf32_ext::Fe1024::div_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe1024) +pub fn bech32::primitives::gf32_ext::Fe1024::mul(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn bech32::primitives::gf32_ext::Fe1024::mul_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe1024) +pub fn bech32::primitives::gf32_ext::Fe1024::multiplicative_inverse(self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::sub(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn bech32::primitives::gf32_ext::Fe1024::sub_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe1024) +pub fn bech32::primitives::gf32_ext::Fe32Ext::clone(&self) -> bech32::primitives::gf32_ext::Fe32Ext +pub fn bech32::primitives::gf32_ext::Fe32Ext::eq(&self, other: &bech32::primitives::gf32_ext::Fe32Ext) -> bool +pub fn bech32::primitives::gf32_ext::Fe32Ext::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +pub fn bech32::primitives::gf32_ext::Fe32Ext::from(fe: bech32::primitives::gf32::Fe32) -> Self +pub fn bech32::primitives::gf32_ext::Fe32Ext::hash<__H: core::hash::Hasher>(&self, state: &mut __H) +pub fn bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: &bech32::primitives::gf32::Fe32) -> Self::Output +pub fn bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: bech32::primitives::gf32::Fe32) -> Self::Output pub fn bech32::primitives::hrp::ByteIter<'b>::len(&self) -> usize pub fn bech32::primitives::hrp::ByteIter<'b>::next(&mut self) -> core::option::Option pub fn bech32::primitives::hrp::ByteIter<'b>::next_back(&mut self) -> core::option::Option @@ -999,6 +1077,7 @@ pub mod bech32::primitives::checksum pub mod bech32::primitives::decode pub mod bech32::primitives::encode pub mod bech32::primitives::gf32 +pub mod bech32::primitives::gf32_ext pub mod bech32::primitives::hrp pub mod bech32::primitives::iter pub mod bech32::primitives::segwit @@ -1018,6 +1097,7 @@ pub struct bech32::primitives::encode::CharIter<'hrp, I, Ck> where I: core::iter pub struct bech32::primitives::encode::Encoder<'hrp, I, Ck> where I: core::iter::traits::iterator::Iterator, Ck: bech32::primitives::checksum::Checksum pub struct bech32::primitives::encode::Fe32Iter<'hrp, I, Ck> where I: core::iter::traits::iterator::Iterator, Ck: bech32::primitives::checksum::Checksum pub struct bech32::primitives::encode::WitnessVersionIter where I: core::iter::traits::iterator::Iterator +pub struct bech32::primitives::gf32_ext::Fe32Ext pub struct bech32::primitives::hrp::ByteIter<'b> pub struct bech32::primitives::hrp::CharIter<'b> pub struct bech32::primitives::hrp::Hrp @@ -1036,7 +1116,10 @@ pub trait bech32::primitives::checksum::PackedFe32: core::marker::Copy + core::c pub trait bech32::primitives::iter::ByteIterExt: core::marker::Sized + core::iter::traits::iterator::Iterator pub trait bech32::primitives::iter::Fe32IterExt: core::marker::Sized + core::iter::traits::iterator::Iterator pub type &bech32::primitives::gf32::Fe32::Output = bech32::primitives::gf32::Fe32 +pub type &bech32::primitives::gf32_ext::Fe1024::Output = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type &bech32::primitives::gf32_ext::Fe32Ext::Output = bech32::primitives::gf32_ext::Fe32Ext pub type bech32::Checksum::MidstateRepr: bech32::primitives::checksum::PackedFe32 +pub type bech32::Fe1024 = bech32::primitives::gf32_ext::Fe32Ext<2> pub type bech32::primitives::Bech32::MidstateRepr = u32 pub type bech32::primitives::Bech32m::MidstateRepr = u32 pub type bech32::primitives::ExtensionField::BaseField: bech32::primitives::Field @@ -1052,6 +1135,10 @@ pub type bech32::primitives::encode::Fe32Iter<'hrp, I, Ck>::Item = bech32::primi pub type bech32::primitives::encode::WitnessVersionIter::Item = bech32::primitives::gf32::Fe32 pub type bech32::primitives::gf32::Fe32::Error = bech32::primitives::gf32::TryFromError pub type bech32::primitives::gf32::Fe32::Output = bech32::primitives::gf32::Fe32 +pub type bech32::primitives::gf32_ext::Fe1024 = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type bech32::primitives::gf32_ext::Fe1024::BaseField = bech32::primitives::gf32::Fe32 +pub type bech32::primitives::gf32_ext::Fe1024::Output = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type bech32::primitives::gf32_ext::Fe32Ext::Output = bech32::primitives::gf32_ext::Fe32Ext pub type bech32::primitives::hrp::ByteIter<'b>::Item = u8 pub type bech32::primitives::hrp::CharIter<'b>::Item = char pub type bech32::primitives::hrp::LowercaseByteIter<'b>::Item = u8 diff --git a/api/no-features.txt b/api/no-features.txt index fb4d8bd1c..661ae751d 100644 --- a/api/no-features.txt +++ b/api/no-features.txt @@ -14,7 +14,9 @@ #[non_exhaustive] pub struct bech32::primitives::segwit::InvalidWitnessVersionError(pub bech32::primitives::gf32::Fe32) #[repr(transparent)] pub struct bech32::Fe32(_) #[repr(transparent)] pub struct bech32::primitives::gf32::Fe32(_) +impl bech32::primitives::ExtensionField for bech32::primitives::gf32_ext::Fe1024 impl bech32::primitives::Field for bech32::primitives::gf32::Fe32 +impl bech32::primitives::Field for bech32::primitives::gf32_ext::Fe1024 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32m impl bech32::primitives::checksum::Checksum for bech32::primitives::NoChecksum @@ -265,28 +267,44 @@ impl core::marker::Unpin for bech32::primitives::segwit::WitnessLengthError impl core::ops::arith::Add for bech32::primitives::gf32::Fe32 impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Add for &bech32::primitives::gf32::Fe32 +impl core::ops::arith::Add> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::AddAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::AddAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::AddAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Div for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Div for &bech32::primitives::gf32::Fe32 +impl core::ops::arith::Div> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::DivAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::DivAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::DivAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Mul for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Mul for &bech32::primitives::gf32::Fe32 +impl core::ops::arith::Mul> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::MulAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::MulAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::MulAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Neg for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Sub for &bech32::primitives::gf32::Fe32 +impl core::ops::arith::Sub> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::SubAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::SubAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 +impl core::ops::arith::SubAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 impl core::ops::bit::BitXor for bech32::primitives::checksum::PackedNull impl core::panic::unwind_safe::RefUnwindSafe for bech32::EncodeError impl core::panic::unwind_safe::RefUnwindSafe for bech32::primitives::Bech32 @@ -511,6 +529,26 @@ impl core::panic::unwind_safe::RefUnwindSafe for bech32::primitives::iter::Fe impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::encode::WitnessVersionIter where I: core::panic::unwind_safe::UnwindSafe impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::iter::BytesToFes where I: core::panic::unwind_safe::UnwindSafe impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::iter::FesToBytes where I: core::panic::unwind_safe::UnwindSafe +impl bech32::primitives::gf32_ext::Fe32Ext where Self: bech32::primitives::ExtensionField +impl core::clone::Clone for bech32::primitives::gf32_ext::Fe32Ext +impl core::cmp::Eq for bech32::primitives::gf32_ext::Fe32Ext +impl core::cmp::PartialEq for bech32::primitives::gf32_ext::Fe32Ext +impl core::convert::From for bech32::primitives::gf32_ext::Fe32Ext +impl core::fmt::Debug for bech32::primitives::gf32_ext::Fe32Ext +impl core::fmt::Display for bech32::primitives::gf32_ext::Fe32Ext +impl core::hash::Hash for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::Copy for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::Freeze for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::Send for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::StructuralPartialEq for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::Sync for bech32::primitives::gf32_ext::Fe32Ext +impl core::marker::Unpin for bech32::primitives::gf32_ext::Fe32Ext +impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32_ext::Fe32Ext +impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32_ext::Fe32Ext +impl core::ops::arith::Mul for &bech32::primitives::gf32_ext::Fe32Ext +impl core::ops::arith::Mul for bech32::primitives::gf32_ext::Fe32Ext +impl core::panic::unwind_safe::RefUnwindSafe for bech32::primitives::gf32_ext::Fe32Ext +impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::gf32_ext::Fe32Ext pub bech32::EncodeError::Fmt(core::fmt::Error) pub bech32::EncodeError::TooLong(bech32::primitives::decode::CodeLengthError) pub bech32::primitives::decode::CharError::InvalidChar(char) @@ -618,6 +656,14 @@ pub const bech32::primitives::gf32::Fe32::_6: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::_7: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::_8: bech32::primitives::gf32::Fe32 pub const bech32::primitives::gf32::Fe32::_9: bech32::primitives::gf32::Fe32 +pub const bech32::primitives::gf32_ext::Fe1024::DEGREE: usize +pub const bech32::primitives::gf32_ext::Fe1024::EXT_ELEM: Self +pub const bech32::primitives::gf32_ext::Fe1024::GENERATOR: Self +pub const bech32::primitives::gf32_ext::Fe1024::MULTIPLICATIVE_ORDER: usize +pub const bech32::primitives::gf32_ext::Fe1024::MULTIPLICATIVE_ORDER_FACTORS: &'static [usize] +pub const bech32::primitives::gf32_ext::Fe1024::ONE: Self +pub const bech32::primitives::gf32_ext::Fe1024::POLYNOMIAL: Self +pub const bech32::primitives::gf32_ext::Fe1024::ZERO: Self pub const bech32::primitives::hrp::BC: bech32::primitives::hrp::Hrp pub const bech32::primitives::hrp::BCRT: bech32::primitives::hrp::Hrp pub const bech32::primitives::hrp::TB: bech32::primitives::hrp::Hrp @@ -626,6 +672,7 @@ pub const bech32::primitives::segwit::VERSION_0: bech32::primitives::gf32::Fe32 pub const bech32::primitives::segwit::VERSION_1: bech32::primitives::gf32::Fe32 pub const bech32::segwit::VERSION_0: bech32::primitives::gf32::Fe32 pub const bech32::segwit::VERSION_1: bech32::primitives::gf32::Fe32 +pub const fn bech32::primitives::gf32_ext::Fe32Ext::new(inner: [bech32::primitives::gf32::Fe32; DEG]) -> Self pub const fn bech32::primitives::hrp::Hrp::parse_unchecked(hrp: &str) -> Self pub const u128::ONE: Self pub const u32::ONE: Self @@ -644,6 +691,16 @@ pub fn &bech32::primitives::gf32::Fe32::mul(self, other: &bech32::primitives::gf pub fn &bech32::primitives::gf32::Fe32::mul(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn &bech32::primitives::gf32::Fe32::sub(self, other: &bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 pub fn &bech32::primitives::gf32::Fe32::sub(self, other: bech32::primitives::gf32::Fe32) -> bech32::primitives::gf32::Fe32 +pub fn &bech32::primitives::gf32_ext::Fe1024::add(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::add(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::div(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::div(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::mul(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::mul(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::sub(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe1024::sub(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: &bech32::primitives::gf32::Fe32) -> Self::Output +pub fn &bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: bech32::primitives::gf32::Fe32) -> Self::Output pub fn bech32::ByteIterExt::bytes_to_fes(self) -> bech32::primitives::iter::BytesToFes pub fn bech32::Checksum::sanity_check() pub fn bech32::EncodeError::clone(&self) -> bech32::EncodeError @@ -839,6 +896,27 @@ pub fn bech32::primitives::gf32::TryFromError::eq(&self, other: &bech32::primiti pub fn bech32::primitives::gf32::TryFromError::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bech32::primitives::gf32::TryFromError::from(e: core::num::error::TryFromIntError) -> Self pub fn bech32::primitives::gf32::TryFromError::from(i: core::convert::Infallible) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::_add(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::_div(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::_mul(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::_neg(self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::_sub(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::add(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn bech32::primitives::gf32_ext::Fe1024::add_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe1024) +pub fn bech32::primitives::gf32_ext::Fe1024::div(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn bech32::primitives::gf32_ext::Fe1024::div_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe1024) +pub fn bech32::primitives::gf32_ext::Fe1024::mul(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn bech32::primitives::gf32_ext::Fe1024::mul_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe1024) +pub fn bech32::primitives::gf32_ext::Fe1024::multiplicative_inverse(self) -> Self +pub fn bech32::primitives::gf32_ext::Fe1024::sub(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn bech32::primitives::gf32_ext::Fe1024::sub_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe1024) +pub fn bech32::primitives::gf32_ext::Fe32Ext::clone(&self) -> bech32::primitives::gf32_ext::Fe32Ext +pub fn bech32::primitives::gf32_ext::Fe32Ext::eq(&self, other: &bech32::primitives::gf32_ext::Fe32Ext) -> bool +pub fn bech32::primitives::gf32_ext::Fe32Ext::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +pub fn bech32::primitives::gf32_ext::Fe32Ext::from(fe: bech32::primitives::gf32::Fe32) -> Self +pub fn bech32::primitives::gf32_ext::Fe32Ext::hash<__H: core::hash::Hasher>(&self, state: &mut __H) +pub fn bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: &bech32::primitives::gf32::Fe32) -> Self::Output +pub fn bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: bech32::primitives::gf32::Fe32) -> Self::Output pub fn bech32::primitives::hrp::ByteIter<'b>::len(&self) -> usize pub fn bech32::primitives::hrp::ByteIter<'b>::next(&mut self) -> core::option::Option pub fn bech32::primitives::hrp::ByteIter<'b>::next_back(&mut self) -> core::option::Option @@ -924,6 +1002,7 @@ pub mod bech32::primitives::checksum pub mod bech32::primitives::decode pub mod bech32::primitives::encode pub mod bech32::primitives::gf32 +pub mod bech32::primitives::gf32_ext pub mod bech32::primitives::hrp pub mod bech32::primitives::iter pub mod bech32::primitives::segwit @@ -943,6 +1022,7 @@ pub struct bech32::primitives::encode::CharIter<'hrp, I, Ck> where I: core::iter pub struct bech32::primitives::encode::Encoder<'hrp, I, Ck> where I: core::iter::traits::iterator::Iterator, Ck: bech32::primitives::checksum::Checksum pub struct bech32::primitives::encode::Fe32Iter<'hrp, I, Ck> where I: core::iter::traits::iterator::Iterator, Ck: bech32::primitives::checksum::Checksum pub struct bech32::primitives::encode::WitnessVersionIter where I: core::iter::traits::iterator::Iterator +pub struct bech32::primitives::gf32_ext::Fe32Ext pub struct bech32::primitives::hrp::ByteIter<'b> pub struct bech32::primitives::hrp::CharIter<'b> pub struct bech32::primitives::hrp::Hrp @@ -961,7 +1041,10 @@ pub trait bech32::primitives::checksum::PackedFe32: core::marker::Copy + core::c pub trait bech32::primitives::iter::ByteIterExt: core::marker::Sized + core::iter::traits::iterator::Iterator pub trait bech32::primitives::iter::Fe32IterExt: core::marker::Sized + core::iter::traits::iterator::Iterator pub type &bech32::primitives::gf32::Fe32::Output = bech32::primitives::gf32::Fe32 +pub type &bech32::primitives::gf32_ext::Fe1024::Output = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type &bech32::primitives::gf32_ext::Fe32Ext::Output = bech32::primitives::gf32_ext::Fe32Ext pub type bech32::Checksum::MidstateRepr: bech32::primitives::checksum::PackedFe32 +pub type bech32::Fe1024 = bech32::primitives::gf32_ext::Fe32Ext<2> pub type bech32::primitives::Bech32::MidstateRepr = u32 pub type bech32::primitives::Bech32m::MidstateRepr = u32 pub type bech32::primitives::ExtensionField::BaseField: bech32::primitives::Field @@ -977,6 +1060,10 @@ pub type bech32::primitives::encode::Fe32Iter<'hrp, I, Ck>::Item = bech32::primi pub type bech32::primitives::encode::WitnessVersionIter::Item = bech32::primitives::gf32::Fe32 pub type bech32::primitives::gf32::Fe32::Error = bech32::primitives::gf32::TryFromError pub type bech32::primitives::gf32::Fe32::Output = bech32::primitives::gf32::Fe32 +pub type bech32::primitives::gf32_ext::Fe1024 = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type bech32::primitives::gf32_ext::Fe1024::BaseField = bech32::primitives::gf32::Fe32 +pub type bech32::primitives::gf32_ext::Fe1024::Output = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type bech32::primitives::gf32_ext::Fe32Ext::Output = bech32::primitives::gf32_ext::Fe32Ext pub type bech32::primitives::hrp::ByteIter<'b>::Item = u8 pub type bech32::primitives::hrp::CharIter<'b>::Item = char pub type bech32::primitives::hrp::LowercaseByteIter<'b>::Item = u8 diff --git a/src/lib.rs b/src/lib.rs index 3a90922b0..ab86aeb21 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -161,6 +161,7 @@ use crate::primitives::decode::{ChecksumError, UncheckedHrpstring, UncheckedHrps pub use { crate::primitives::checksum::Checksum, crate::primitives::gf32::Fe32, + crate::primitives::gf32_ext::Fe1024, crate::primitives::hrp::Hrp, crate::primitives::iter::{ByteIterExt, Fe32IterExt}, crate::primitives::{Bech32, Bech32m, NoChecksum}, diff --git a/src/primitives/gf32_ext.rs b/src/primitives/gf32_ext.rs new file mode 100644 index 000000000..5fddebed8 --- /dev/null +++ b/src/primitives/gf32_ext.rs @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: MIT + +//! Extension Fields over GF32 +//! +//! Correcting errors in BCH codes requires working over an extension field +//! of GF32 (or whatever the base field is, which in this library is always +//! GF32 represented using the bech32 alphabet). +//! +//! We support specifically the fields GF1024 and GF32768 (the extension +//! fields of degree 2 and 3, respectively), though we have tried to write +//! the code in such a way that more can be added if codes require them. +//! + +use core::{fmt, ops}; + +use super::field::{ExtensionField, Field}; +use crate::Fe32; + +/// An element of the extension field. +#[derive(Copy, Clone, PartialEq, Eq, Hash)] +pub struct Fe32Ext { + /// The polynomial representation of the element in "little-endian" order; + /// that is, the element is the sum `inner[i] * EXT_ELEM^i`. + inner: [Fe32; DEG], +} + +impl From for Fe32Ext { + fn from(fe: Fe32) -> Self { + let mut ret = Self { inner: [Fe32::Q; DEG] }; + ret.inner[0] = fe; + ret + } +} + +impl fmt::Debug for Fe32Ext { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(self, f) } +} + +impl fmt::Display for Fe32Ext { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for elem in &self.inner { + elem.fmt(f)?; + } + Ok(()) + } +} + +impl ops::Mul<&Fe32> for Fe32Ext { + type Output = Fe32Ext; + fn mul(mut self, other: &Fe32) -> Self::Output { + for elem in &mut self.inner { + *elem *= other; + } + self + } +} + +impl ops::Mul for Fe32Ext { + type Output = Fe32Ext; + fn mul(self, other: Fe32) -> Self::Output { self.mul(&other) } +} + +impl ops::Mul for &Fe32Ext { + type Output = Fe32Ext; + fn mul(self, other: Fe32) -> Self::Output { (*self).mul(other) } +} + +impl ops::Mul<&Fe32> for &Fe32Ext { + type Output = Fe32Ext; + fn mul(self, other: &Fe32) -> Self::Output { (*self).mul(other) } +} + +impl Fe32Ext +where + Self: ExtensionField, +{ + /// Constructs a new extension-field element given a polynomial representation + /// of the element in terms of the base field. + pub const fn new(inner: [Fe32; DEG]) -> Self { Self { inner } } + + /// Multiplies a given element by the extension-defining element. + fn mul_by_ext_elem(&mut self) { + let xn_coeff = self.inner[DEG - 1]; + for i in (0..DEG - 1).rev() { + self.inner[i + 1] = self.inner[i]; + } + self.inner[0] = Fe32::Q; + for i in 0..DEG { + self.inner[i] += xn_coeff * Self::POLYNOMIAL.inner[i] + } + } + + // We just use naive n^2 muliplication because this is easy to write in + // generic code, and because our GF32 implementation makes multiplication + // (almost) as cheap as addition. + // + // Specifically for DEG = 2, 3 which we care about, Karatsuba multiplication + // may be more efficient -- but since it trades off adds for mults, it's not + // obviously so. Maybe worth benchmarking in the future. + fn mul_by_elem(&self, other: &Self) -> Self { + let mut acc = Self::ZERO; + for xi in other.inner.iter().rev() { + acc.mul_by_ext_elem(); + acc += self * xi; + } + acc + } +} + +/// The field of order 1024. +pub type Fe1024 = Fe32Ext<2>; + +impl Field for Fe1024 { + /// The zero element of the field. + const ZERO: Self = Self::new([Fe32::Q, Fe32::Q]); + + /// The one element of the field. + const ONE: Self = Self::new([Fe32::P, Fe32::Q]); + + // Chosen somewhat arbitrarily. + /// A generator of the field. + const GENERATOR: Self = Self::new([Fe32::P, Fe32::H]); + + /// The order of the multiplicative group of the field. + /// + /// This constant also serves as a compile-time check that we can count + /// the entire field using a `usize` as a counter. + const MULTIPLICATIVE_ORDER: usize = 1023; + + const MULTIPLICATIVE_ORDER_FACTORS: &'static [usize] = &[1, 3, 11, 31, 33, 93, 341, 1023]; + + #[inline] + fn _add(&self, other: &Self) -> Self { + Self::new([self.inner[0] + other.inner[0], self.inner[1] + other.inner[1]]) + } + + #[inline] + fn _sub(&self, other: &Self) -> Self { self._add(other) } + + #[inline] + fn _mul(&self, other: &Self) -> Self { self.mul_by_elem(other) } + + #[inline] + fn _div(&self, other: &Self) -> Self { other.multiplicative_inverse() * self } + + #[inline] + fn _neg(self) -> Self { self } + + fn multiplicative_inverse(self) -> Self { + // Aliases to make the below equations easier to read + let a0 = self.inner[0]; + let a1 = self.inner[1]; + let p0 = Self::POLYNOMIAL.inner[0]; + let p1 = Self::POLYNOMIAL.inner[1]; + + // Inverse of the 2x2 multiplication matrix defined by a0, a1. + let det = (a0 * a0) + (p1 * a0 * a1) + (p0 * a1 * a1); + Self::new([(a0 + p1 * a1) / det, (Fe32::Q - a1) / det]) + } +} +super::impl_ops_for_fe!(impl for Fe1024); + +impl ExtensionField for Fe1024 { + type BaseField = Fe32; + + const DEGREE: usize = 2; + + // Ultimately it doesn't really matter what choice of polynomial we make + // here. We choose the value from BIP 93, which we note differs from the + // value used in bech32 error correcting code, such as + // https://github.com/sipa/bech32/commit/e97932d4c86e343ace49ae6170ae0c4871820152 + // + // (Specifically, the third element of that exp table, 311, expanded into binary, + // 01001 10111, and mapped back to Fe32, gives us FH rather than PP. But really, + // it doesn't matter, except that it is part of the `Fe1024` API and we cannot + // change it once we have published it, since changing it amounts to moving to + // a different, though isomorphic, field.) + const POLYNOMIAL: Self = Self::new([Fe32::P, Fe32::P]); + + /// The element zeta such that the extension field is defined as `GF32[zeta]`. + /// + /// Alternately, the image of x in the mapping `GF32[x]/p(x) -> ` + const EXT_ELEM: Self = Self::new([Fe32::Q, Fe32::P]); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn gf1024_div() { + for a0 in 0..32 { + for a1 in 0..32 { + let gf1 = Fe1024::new([Fe32(a0), Fe32(a1)]); + if gf1 == Fe1024::ZERO { + continue; + } + assert_eq!(gf1 / gf1, Fe1024::ONE); + } + } + + const ITERS: u8 = 10; // max 32. + for a0 in 0..ITERS { + for a1 in 0..ITERS { + for b0 in 0..ITERS { + for b1 in 0..ITERS { + let gf1 = Fe1024::new([Fe32(a0), Fe32(a1)]); + let gf2 = Fe1024::new([Fe32(b0), Fe32(b1)]); + if gf1 == Fe1024::ZERO { + continue; + } + let rat = gf2 / gf1; + assert_eq!(rat * gf1, gf2); + assert_eq!(gf1 * rat, gf2); + } + } + } + } + } + + #[test] + fn gf1024_mult() { + // Check that all base field elements to the power of 32 are themselves + for i in 0..32 { + let mut sq = Fe32(i); + for _ in 0..5 { + sq = sq * sq; + } + assert_eq!(sq, Fe32(i)); + } + // Check that all ext field elements to the power of 1024 are themselves + for j in 0..32 { + for i in 0..32 { + let mut sq = Fe1024::new([Fe32(i), Fe32(j)]); + for _ in 0..10 { + sq = sq * sq; + } + assert_eq!(sq, Fe1024::new([Fe32(i), Fe32(j)])); + } + } + + assert_eq!(Fe1024::EXT_ELEM * Fe1024::EXT_ELEM, Fe1024::POLYNOMIAL,); + } + + #[test] + fn gf1024_mult_inverse() { + assert_eq!(Fe1024::ONE.multiplicative_inverse(), Fe1024::ONE); + + for i in 0..32 { + for j in 0..32 { + if i != 0 || j != 0 { + let fe1024 = Fe1024::new([Fe32(i), Fe32(j)]); + assert_eq!(fe1024.multiplicative_inverse().multiplicative_inverse(), fe1024,); + } + } + } + } + + #[test] + fn gf1024_powi() { + // A "random" element + let elem = Fe1024::new([Fe32::K, Fe32::L]); + assert_eq!(elem.powi(2), elem * elem); + assert_eq!(elem.powi(3), elem * elem * elem); + assert_eq!(elem.powi(0), Fe1024::ONE); + assert_eq!(elem.powi(-1), elem.multiplicative_inverse()); + + assert_eq!(elem.multiplicative_order(), 1023); + assert_eq!(elem.powi(3).multiplicative_order(), 341); + assert_eq!(elem.powi(341).multiplicative_order(), 3); + } +} diff --git a/src/primitives/mod.rs b/src/primitives/mod.rs index c90f9e94f..72d8c0e2b 100644 --- a/src/primitives/mod.rs +++ b/src/primitives/mod.rs @@ -7,6 +7,7 @@ pub mod decode; pub mod encode; mod field; pub mod gf32; +pub mod gf32_ext; pub mod hrp; pub mod iter; pub mod segwit; From a24825dded3e2b6ef37642116ce1964f03f269b8 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sat, 23 Mar 2024 13:32:26 +0000 Subject: [PATCH 4/8] primitives: introduce `Polynomial` type, generator polynomial analysis This introduces a type `Polynomial` which wraps a vector of field elements which it treats as the coefficients of a polynomial. It exposes only an ad-hoc set of functionality needed for error correction and is not intended to be a general-purpose polynomial type, so it is not exposed in the public API. Because it is backed by a `Vec` the type and its module are only available when the alloc feature is available. --- src/primitives/mod.rs | 4 + src/primitives/polynomial.rs | 280 +++++++++++++++++++++++++++++++++++ 2 files changed, 284 insertions(+) create mode 100644 src/primitives/polynomial.rs diff --git a/src/primitives/mod.rs b/src/primitives/mod.rs index 72d8c0e2b..28ca963a8 100644 --- a/src/primitives/mod.rs +++ b/src/primitives/mod.rs @@ -10,11 +10,15 @@ pub mod gf32; pub mod gf32_ext; pub mod hrp; pub mod iter; +#[cfg(feature = "alloc")] +mod polynomial; pub mod segwit; use checksum::{Checksum, PackedNull}; use field::impl_ops_for_fe; pub use field::{ExtensionField, Field}; +#[cfg(feature = "alloc")] +use polynomial::Polynomial; /// The "null checksum" used on bech32 strings for which we want to do no checksum checking. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] diff --git a/src/primitives/polynomial.rs b/src/primitives/polynomial.rs new file mode 100644 index 000000000..a09750522 --- /dev/null +++ b/src/primitives/polynomial.rs @@ -0,0 +1,280 @@ +// SPDX-License-Identifier: MIT + +//! Polynomials over Finite Fields + +#[cfg(all(feature = "alloc", not(feature = "std"), not(test)))] +use alloc::vec::Vec; +use core::{iter, ops}; + +use super::Field; + +/// A polynomial over some field. +#[derive(PartialEq, Eq, Clone, Debug, Hash)] +pub struct Polynomial { + inner: Vec, +} + +impl Polynomial { + /// Constructor for a polynomial from a vector of coefficients. + /// + /// These coefficients are in "little endian" order. That is, the ith + /// coefficient is the one multiplied by x^i. + pub fn new(f: Vec) -> Self { Self { inner: f } } +} + +impl Polynomial { + /// The degree of the polynomial. + /// + /// For constants it will return zero, including for the constant zero. + pub fn degree(&self) -> usize { + debug_assert_ne!(self.inner.len(), 0, "polynomials never have no terms"); + let degree_without_leading_zeros = self.inner.len() - 1; + let leading_zeros = self.inner.iter().rev().take_while(|el| **el == F::ZERO).count(); + degree_without_leading_zeros - leading_zeros + } + + /// The leading term of the polynomial. + /// + /// For the constant 0 polynomial, will return 0. + pub fn leading_term(&self) -> F { + for term in self.inner.iter().rev() { + if *term != F::ZERO { + return term.clone(); + } + } + F::ZERO + } +} + +impl Polynomial { + /// Finds all roots of the polynomial in the given field, in + /// no particular order. + /// + /// Does not consider multiplicity; it assumes there are no + /// repeated roots. (FIXME we really ought to do so, and + /// definitely should before exposing this function in the + /// public API.) + /// + /// If the polynomial does not split, then the returned vector + /// will have length strictly less than [`Self::degree`]. If + /// the polynomial _does_ split then the length will be equal. + /// + /// For constants, will return vec![0] for the constant 0 and the + /// empty vector for any other constant. Probably the caller wants + /// to check if they have a constant and special-case this. + pub fn find_distinct_roots(&self) -> Vec { + // Implements Chien search + + let mut ret = Vec::with_capacity(self.degree()); + // Check if zero is a root + if self.inner.is_empty() || self.leading_term() == F::ZERO { + ret.push(F::ZERO); + } + // Special-case constants, which have 0 as a root iff they are the constant 0. + if self.degree() == 1 { + return ret; + // from here on out we know self.inner[0] won't panic + } + + // Vector of [1, gen, gen^2, ...] up to the degree d. + debug_assert_eq!(F::GENERATOR.multiplicative_order(), F::MULTIPLICATIVE_ORDER); + let gen_power = iter::successors(Some(F::ONE), |gen| Some(F::GENERATOR * gen)) + .take(self.degree() + 1) + .collect::>(); + + // We special-cased 0 above. So now we can check every nonzero element + // to see if it is a root. We brute-force this using Chein's algorithm, + // which exploits the fact that we can go from f(alpha^i) to f(alpha^{i+1}) + // pretty efficiently. So iterate through all the powers of the generator + // in this way. + let mut cand = F::ONE; + let mut eval = self.clone(); + for _ in 0..F::MULTIPLICATIVE_ORDER { + let sum = eval.inner.iter().cloned().fold(F::ZERO, F::add); + if sum == F::ZERO { + ret.push(cand.clone()); + } + + for (i, gen_power) in gen_power.iter().enumerate() { + eval.inner[i] *= gen_power; + } + cand *= F::GENERATOR; + } + + ret + } + + /// Given a BCH generator polynomial, find an element alpha that maximizes the + /// consecutive range i..j such that `alpha^i `through `alpha^j` are all roots + /// of the polynomial. + /// + /// (Despite the name, the returned element might not actually be a primitive + /// element. For a "primitive BCH code" it will be, but in general not. But + /// there is no standard name for the element this function returns, and + /// "primitive element" is suggestive.) + /// + /// # Panics + /// + /// Panics if there are fewer roots than the degree of the polynomial, or if + /// the longest geometric series in the roots appears to be of the form + /// alpha*beta^i where alpha is not 1. Either situation indicates that your + /// BCH generator polynomial is weird in some way, and you should file a bug + /// or (more likely) fix your polynomial. + /// + /// # Returns + /// + /// Returns a primitive element, its order (which is the length of the code), + /// and the longest range of exponents of the element which are roots of the + /// polynomial. For the avoidance of doubt it returns a [`ops::RangeInclusive`] + /// (syntax `a..=b`) rather than the more-common [`ops::Range`] (syntax `a..b`). + /// Both endpoints are included in the set of values. + /// + /// Internally this function analyzes the roots in an arbitrary (randomized) + /// order, and therefore may return different values on consecutive runs. If + /// there is a particular "elegant" value you are looking for, it may be + /// worthwhile to run the function multiple times. + pub fn bch_generator_primitive_element(&self) -> (F, usize, ops::RangeInclusive) { + let roots = self.find_distinct_roots(); + debug_assert!(roots.len() <= self.degree(),); + assert_eq!( + self.degree(), + roots.len(), + "Found {} roots ({:?}) for a polynomial of degree {}; polynomial appears not to split.", + roots.len(), + roots, + self.degree(), + ); + + // Brute-force (worst case n^3 in the length of the polynomial) the longest + // geometric series within the set of roots. The common ratio between these + // roots will be our primitive element. + // + // We also learn the length of the series and the first root in the series. + let mut max_length = 0; + let mut max_start = F::ZERO; + let mut max_ratio = F::ZERO; + for r1 in &roots { + for r2 in &roots { + if r1 == r2 { + continue; + } + let ratio = r2.clone() / r1; + + let mut len = 1; + let mut elem = r1.clone(); + while roots.contains(&(elem.clone() * &ratio)) { + len += 1; + elem *= ∶ + } + if len > max_length { + max_length = len; + max_start = r2.clone(); + max_ratio = ratio; + } + } + } + + // We have the primitive element (max_ratio) and the first element in the + // series with that ratio (max_start). To get the actual exponents of the + // series, we need i such that max_start = max_ratio^i. + // + // It may occur that no such i exists, if the entire series is in a coset + // of the group generated by max_ratio. In *theory* this means that we + // should go back and find the second-longest geometric series and try + // that, because for a real-life BCH code this situation indicates that + // something is wrong and we should just panic. + let code_len = max_ratio.multiplicative_order(); + + let mut min_index = None; + let mut base = F::ONE; + for i in 0..code_len { + base *= &max_ratio; + if base == max_start { + min_index = Some(i); + } + } + + let min_index = match min_index { + Some(idx) => idx, + None => panic!("Found geometric series within roots starting from {} (ratio {} length {}), but this series does not consist of powers of any generator.", max_start, max_ratio, max_length), + }; + + // We write `a..=b - 1` instead of `a..b` because RangeInclusive is actually + // a different type than Range, so the two syntaxes are not equivalent here. + (max_ratio, code_len, min_index..=min_index + max_length - 1) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{Fe1024, Fe32}; + + #[test] + fn roots() { + let bip93_poly = Polynomial::::new( + [ + Fe32::S, + Fe32::S, + Fe32::C, + Fe32::M, + Fe32::L, + Fe32::E, + Fe32::E, + Fe32::E, + Fe32::Q, + Fe32::G, + Fe32::_3, + Fe32::M, + Fe32::E, + Fe32::P, + ] + .iter() + .copied() + .map(Fe1024::from) + .collect(), + ); + + assert_eq!(bip93_poly.degree(), 13); + + let (elem, order, root_indices) = bip93_poly.bch_generator_primitive_element(); + // Basically, only the order and the length of the `root_indices` range are + // guaranteed to be consistent across runs. There will be two possible ranges, + // a "low" one (in this case 9..16) and a "high one" (77..84) whose generator + // is the multiplicative inverse of the small one. These correspond to the + // fact that for any order-93 element, e^x = (e^-1)^(93 - x). + // + // Then in addition to the element/inverse symmetry, for this polynomial there + // is also an entire second generator which can produce the same set of roots. + // So we get that one and _its_ inverse. + // + // Also, BTW, the range 77..84 appears in the Appendix to BIP93 so you can + // verify its correctness there. + assert_eq!(order, 93); + // These next three assertions just illustrate the above comment... + assert_eq!( + Fe1024::new([Fe32::Q, Fe32::_9]).multiplicative_inverse(), + Fe1024::new([Fe32::G, Fe32::G]), + ); + assert_eq!( + Fe1024::new([Fe32::Q, Fe32::_9]).powi(9), + Fe1024::new([Fe32::G, Fe32::G]).powi(84), + ); + assert_eq!( + Fe1024::new([Fe32::Q, Fe32::_9]).powi(16), + Fe1024::new([Fe32::G, Fe32::G]).powi(77), + ); + // ...and these ones are actual unit tests. + if elem == Fe1024::new([Fe32::_9, Fe32::_9]) { + assert_eq!(root_indices, 9..=16); + } else if elem == Fe1024::new([Fe32::Q, Fe32::G]) { + assert_eq!(root_indices, 77..=84); + } else if elem == Fe1024::new([Fe32::Q, Fe32::_9]) { + assert_eq!(root_indices, 9..=16); + } else if elem == Fe1024::new([Fe32::G, Fe32::G]) { + assert_eq!(root_indices, 77..=84); + } else { + panic!("Unexpected generator {}", elem); + } + } +} From 4c06f723249c1bb15a14768ab938dffa99174439 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sun, 24 Mar 2024 14:36:22 +0000 Subject: [PATCH 5/8] PackedFe32: introduce ability to re-pack elements Adds a couple elements to the API. Note that this *is* a breaking change because we are adding a method to the `PackedFe32` trait, which is not sealed, so any downstream implementors will be broken. --- api/all-features.txt | 5 ++++ api/alloc-only.txt | 5 ++++ api/no-features.txt | 5 ++++ src/primitives/checksum.rs | 52 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+) diff --git a/api/all-features.txt b/api/all-features.txt index 233b3c2c1..648605452 100644 --- a/api/all-features.txt +++ b/api/all-features.txt @@ -850,12 +850,14 @@ pub fn bech32::primitives::checksum::HrpFe32Iter<'hrp>::new(hrp: &'hrp bech32::p pub fn bech32::primitives::checksum::HrpFe32Iter<'hrp>::next(&mut self) -> core::option::Option pub fn bech32::primitives::checksum::HrpFe32Iter<'hrp>::size_hint(&self) -> (usize, core::option::Option) pub fn bech32::primitives::checksum::PackedFe32::mul_by_x_then_add(&mut self, degree: usize, add: u8) -> u8 +pub fn bech32::primitives::checksum::PackedFe32::pack>(iter: I) -> Self pub fn bech32::primitives::checksum::PackedFe32::unpack(&self, n: usize) -> u8 pub fn bech32::primitives::checksum::PackedNull::bitxor(self, bech32::primitives::checksum::PackedNull) -> bech32::primitives::checksum::PackedNull pub fn bech32::primitives::checksum::PackedNull::clone(&self) -> bech32::primitives::checksum::PackedNull pub fn bech32::primitives::checksum::PackedNull::eq(&self, other: &bech32::primitives::checksum::PackedNull) -> bool pub fn bech32::primitives::checksum::PackedNull::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bech32::primitives::checksum::PackedNull::mul_by_x_then_add(&mut self, usize, u8) -> u8 +pub fn bech32::primitives::checksum::PackedNull::pack>(iter: I) -> Self pub fn bech32::primitives::checksum::PackedNull::unpack(&self, usize) -> u8 pub fn bech32::primitives::decode::AsciiToFe32Iter<'s>::len(&self) -> usize pub fn bech32::primitives::decode::AsciiToFe32Iter<'s>::next(&mut self) -> core::option::Option @@ -1122,10 +1124,13 @@ pub fn bech32::segwit::encode_v0(hrp: bech32::primitives::hrp::Hrp, witness_prog pub fn bech32::segwit::encode_v1(hrp: bech32::primitives::hrp::Hrp, witness_program: &[u8]) -> core::result::Result pub fn bech32::segwit::encoded_length(hrp: bech32::primitives::hrp::Hrp, _witness_version: bech32::primitives::gf32::Fe32, witness_program: &[u8]) -> core::result::Result pub fn u128::mul_by_x_then_add(&mut self, degree: usize, add: u8) -> u8 +pub fn u128::pack>(iter: I) -> Self pub fn u128::unpack(&self, n: usize) -> u8 pub fn u32::mul_by_x_then_add(&mut self, degree: usize, add: u8) -> u8 +pub fn u32::pack>(iter: I) -> Self pub fn u32::unpack(&self, n: usize) -> u8 pub fn u64::mul_by_x_then_add(&mut self, degree: usize, add: u8) -> u8 +pub fn u64::pack>(iter: I) -> Self pub fn u64::unpack(&self, n: usize) -> u8 pub fn u8::from(v: bech32::primitives::gf32::Fe32) -> u8 pub mod bech32 diff --git a/api/alloc-only.txt b/api/alloc-only.txt index c36b173d9..b09a4ab9a 100644 --- a/api/alloc-only.txt +++ b/api/alloc-only.txt @@ -810,12 +810,14 @@ pub fn bech32::primitives::checksum::HrpFe32Iter<'hrp>::new(hrp: &'hrp bech32::p pub fn bech32::primitives::checksum::HrpFe32Iter<'hrp>::next(&mut self) -> core::option::Option pub fn bech32::primitives::checksum::HrpFe32Iter<'hrp>::size_hint(&self) -> (usize, core::option::Option) pub fn bech32::primitives::checksum::PackedFe32::mul_by_x_then_add(&mut self, degree: usize, add: u8) -> u8 +pub fn bech32::primitives::checksum::PackedFe32::pack>(iter: I) -> Self pub fn bech32::primitives::checksum::PackedFe32::unpack(&self, n: usize) -> u8 pub fn bech32::primitives::checksum::PackedNull::bitxor(self, bech32::primitives::checksum::PackedNull) -> bech32::primitives::checksum::PackedNull pub fn bech32::primitives::checksum::PackedNull::clone(&self) -> bech32::primitives::checksum::PackedNull pub fn bech32::primitives::checksum::PackedNull::eq(&self, other: &bech32::primitives::checksum::PackedNull) -> bool pub fn bech32::primitives::checksum::PackedNull::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bech32::primitives::checksum::PackedNull::mul_by_x_then_add(&mut self, usize, u8) -> u8 +pub fn bech32::primitives::checksum::PackedNull::pack>(iter: I) -> Self pub fn bech32::primitives::checksum::PackedNull::unpack(&self, usize) -> u8 pub fn bech32::primitives::decode::AsciiToFe32Iter<'s>::len(&self) -> usize pub fn bech32::primitives::decode::AsciiToFe32Iter<'s>::next(&mut self) -> core::option::Option @@ -1064,10 +1066,13 @@ pub fn bech32::segwit::encode_v0(hrp: bech32::primitives::hrp::Hrp, witness_prog pub fn bech32::segwit::encode_v1(hrp: bech32::primitives::hrp::Hrp, witness_program: &[u8]) -> core::result::Result pub fn bech32::segwit::encoded_length(hrp: bech32::primitives::hrp::Hrp, _witness_version: bech32::primitives::gf32::Fe32, witness_program: &[u8]) -> core::result::Result pub fn u128::mul_by_x_then_add(&mut self, degree: usize, add: u8) -> u8 +pub fn u128::pack>(iter: I) -> Self pub fn u128::unpack(&self, n: usize) -> u8 pub fn u32::mul_by_x_then_add(&mut self, degree: usize, add: u8) -> u8 +pub fn u32::pack>(iter: I) -> Self pub fn u32::unpack(&self, n: usize) -> u8 pub fn u64::mul_by_x_then_add(&mut self, degree: usize, add: u8) -> u8 +pub fn u64::pack>(iter: I) -> Self pub fn u64::unpack(&self, n: usize) -> u8 pub fn u8::from(v: bech32::primitives::gf32::Fe32) -> u8 pub mod bech32 diff --git a/api/no-features.txt b/api/no-features.txt index 661ae751d..74b0f119d 100644 --- a/api/no-features.txt +++ b/api/no-features.txt @@ -751,12 +751,14 @@ pub fn bech32::primitives::checksum::HrpFe32Iter<'hrp>::new(hrp: &'hrp bech32::p pub fn bech32::primitives::checksum::HrpFe32Iter<'hrp>::next(&mut self) -> core::option::Option pub fn bech32::primitives::checksum::HrpFe32Iter<'hrp>::size_hint(&self) -> (usize, core::option::Option) pub fn bech32::primitives::checksum::PackedFe32::mul_by_x_then_add(&mut self, degree: usize, add: u8) -> u8 +pub fn bech32::primitives::checksum::PackedFe32::pack>(iter: I) -> Self pub fn bech32::primitives::checksum::PackedFe32::unpack(&self, n: usize) -> u8 pub fn bech32::primitives::checksum::PackedNull::bitxor(self, bech32::primitives::checksum::PackedNull) -> bech32::primitives::checksum::PackedNull pub fn bech32::primitives::checksum::PackedNull::clone(&self) -> bech32::primitives::checksum::PackedNull pub fn bech32::primitives::checksum::PackedNull::eq(&self, other: &bech32::primitives::checksum::PackedNull) -> bool pub fn bech32::primitives::checksum::PackedNull::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result pub fn bech32::primitives::checksum::PackedNull::mul_by_x_then_add(&mut self, usize, u8) -> u8 +pub fn bech32::primitives::checksum::PackedNull::pack>(iter: I) -> Self pub fn bech32::primitives::checksum::PackedNull::unpack(&self, usize) -> u8 pub fn bech32::primitives::decode::AsciiToFe32Iter<'s>::len(&self) -> usize pub fn bech32::primitives::decode::AsciiToFe32Iter<'s>::next(&mut self) -> core::option::Option @@ -989,10 +991,13 @@ pub fn bech32::segwit::encode_to_fmt_unchecked(fmt: &mut W, pub fn bech32::segwit::encode_upper_to_fmt_unchecked(fmt: &mut W, hrp: bech32::primitives::hrp::Hrp, witness_version: bech32::primitives::gf32::Fe32, witness_program: &[u8]) -> core::fmt::Result pub fn bech32::segwit::encoded_length(hrp: bech32::primitives::hrp::Hrp, _witness_version: bech32::primitives::gf32::Fe32, witness_program: &[u8]) -> core::result::Result pub fn u128::mul_by_x_then_add(&mut self, degree: usize, add: u8) -> u8 +pub fn u128::pack>(iter: I) -> Self pub fn u128::unpack(&self, n: usize) -> u8 pub fn u32::mul_by_x_then_add(&mut self, degree: usize, add: u8) -> u8 +pub fn u32::pack>(iter: I) -> Self pub fn u32::unpack(&self, n: usize) -> u8 pub fn u64::mul_by_x_then_add(&mut self, degree: usize, add: u8) -> u8 +pub fn u64::pack>(iter: I) -> Self pub fn u64::unpack(&self, n: usize) -> u8 pub fn u8::from(v: bech32::primitives::gf32::Fe32) -> u8 pub mod bech32 diff --git a/src/primitives/checksum.rs b/src/primitives/checksum.rs index 894d368e6..e3724d816 100644 --- a/src/primitives/checksum.rs +++ b/src/primitives/checksum.rs @@ -154,6 +154,18 @@ pub trait PackedFe32: Copy + PartialEq + Eq + ops::BitXor { /// The number of fe32s that can fit into the type; computed as floor(bitwidth / 5). const WIDTH: usize = mem::size_of::() * 8 / 5; + /// Takes an iterator of `u8`s (or [`Fe32`]s converted to `u8`s) and packs + /// them into a [`Self`]. + /// + /// For sequences representing polynomials, the iterator should yield the + /// coefficients in little-endian order, i.e. the 0th coefficien first. + /// + /// # Panics + /// + /// May panic if the iterator yields more items than can fit into the bit-packed + /// type. + fn pack>(iter: I) -> Self; + /// Extracts the coefficient of the x^n from the packed polynomial. fn unpack(&self, n: usize) -> u8; @@ -183,6 +195,14 @@ impl PackedFe32 for PackedNull { fn unpack(&self, _: usize) -> u8 { 0 } #[inline] fn mul_by_x_then_add(&mut self, _: usize, _: u8) -> u8 { 0 } + + #[inline] + fn pack>(mut iter: I) -> Self { + if iter.next().is_some() { + panic!("Cannot pack anything into a PackedNull"); + } + Self + } } macro_rules! impl_packed_fe32 { @@ -207,6 +227,18 @@ macro_rules! impl_packed_fe32 { *self |= Self::from(add); ret } + + #[inline] + fn pack>(iter: I) -> Self { + let mut ret: Self = 0; + for (n, elem) in iter.enumerate() { + debug_assert!(elem < 32); + debug_assert!(n < Self::WIDTH); + ret <<= 5; + ret |= Self::from(elem); + } + ret + } } }; } @@ -276,3 +308,23 @@ impl<'hrp> Iterator for HrpFe32Iter<'hrp> { (min, max) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn pack_unpack() { + let packed = u128::pack([0, 0, 0, 1].iter().copied()); + assert_eq!(packed, 1); + assert_eq!(packed.unpack(0), 1); + assert_eq!(packed.unpack(3), 0); + + let packed = u128::pack([1, 2, 3, 4].iter().copied()); + assert_eq!(packed, 0b00001_00010_00011_00100); + assert_eq!(packed.unpack(0), 4); + assert_eq!(packed.unpack(1), 3); + assert_eq!(packed.unpack(2), 2); + assert_eq!(packed.unpack(3), 1); + } +} From 65aefd2ca87e73a37c33ceb6632e66e24b3ff666 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Fri, 5 Jul 2024 20:23:57 +0000 Subject: [PATCH 6/8] gf_ext: add cubic extension field of GF32, GF32768 --- api/all-features.txt | 53 ++++++++++++++++ api/alloc-only.txt | 53 ++++++++++++++++ api/no-features.txt | 53 ++++++++++++++++ src/lib.rs | 2 +- src/primitives/gf32_ext.rs | 122 +++++++++++++++++++++++++++++++++++++ 5 files changed, 282 insertions(+), 1 deletion(-) diff --git a/api/all-features.txt b/api/all-features.txt index 648605452..34562bf4e 100644 --- a/api/all-features.txt +++ b/api/all-features.txt @@ -21,8 +21,10 @@ impl !core::panic::unwind_safe::RefUnwindSafe for bech32::EncodeIoError impl !core::panic::unwind_safe::UnwindSafe for bech32::EncodeIoError impl bech32::primitives::ExtensionField for bech32::primitives::gf32_ext::Fe1024 +impl bech32::primitives::ExtensionField for bech32::primitives::gf32_ext::Fe32768 impl bech32::primitives::Field for bech32::primitives::gf32::Fe32 impl bech32::primitives::Field for bech32::primitives::gf32_ext::Fe1024 +impl bech32::primitives::Field for bech32::primitives::gf32_ext::Fe32768 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32m impl bech32::primitives::checksum::Checksum for bech32::primitives::NoChecksum @@ -337,42 +339,58 @@ impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for &bech32::primiti impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<3>> for &bech32::primitives::gf32_ext::Fe32768 +impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Add for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Add> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Add> for &bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::AddAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::AddAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::AddAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::AddAssign<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Div for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<3>> for &bech32::primitives::gf32_ext::Fe32768 +impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Div for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Div> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Div> for &bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::DivAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::DivAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::DivAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::DivAssign<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Mul for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<3>> for &bech32::primitives::gf32_ext::Fe32768 +impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Mul for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Mul> for &bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::MulAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::MulAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::MulAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::MulAssign<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Neg for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<3>> for &bech32::primitives::gf32_ext::Fe32768 +impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Sub for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Sub> for &bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::SubAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::SubAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::SubAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::SubAssign<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::bit::BitXor for bech32::primitives::checksum::PackedNull impl core::panic::unwind_safe::RefUnwindSafe for bech32::DecodeError impl core::panic::unwind_safe::RefUnwindSafe for bech32::EncodeError @@ -746,6 +764,14 @@ pub const bech32::primitives::gf32_ext::Fe1024::MULTIPLICATIVE_ORDER_FACTORS: &' pub const bech32::primitives::gf32_ext::Fe1024::ONE: Self pub const bech32::primitives::gf32_ext::Fe1024::POLYNOMIAL: Self pub const bech32::primitives::gf32_ext::Fe1024::ZERO: Self +pub const bech32::primitives::gf32_ext::Fe32768::DEGREE: usize +pub const bech32::primitives::gf32_ext::Fe32768::EXT_ELEM: Self +pub const bech32::primitives::gf32_ext::Fe32768::GENERATOR: Self +pub const bech32::primitives::gf32_ext::Fe32768::MULTIPLICATIVE_ORDER: usize +pub const bech32::primitives::gf32_ext::Fe32768::MULTIPLICATIVE_ORDER_FACTORS: &'static [usize] +pub const bech32::primitives::gf32_ext::Fe32768::ONE: Self +pub const bech32::primitives::gf32_ext::Fe32768::POLYNOMIAL: Self +pub const bech32::primitives::gf32_ext::Fe32768::ZERO: Self pub const bech32::primitives::hrp::BC: bech32::primitives::hrp::Hrp pub const bech32::primitives::hrp::BCRT: bech32::primitives::hrp::Hrp pub const bech32::primitives::hrp::TB: bech32::primitives::hrp::Hrp @@ -781,6 +807,14 @@ pub fn &bech32::primitives::gf32_ext::Fe1024::mul(self, other: &bech32::primitiv pub fn &bech32::primitives::gf32_ext::Fe1024::mul(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 pub fn &bech32::primitives::gf32_ext::Fe1024::sub(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 pub fn &bech32::primitives::gf32_ext::Fe1024::sub(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe32768::add(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::add(self, other: bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::div(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::div(self, other: bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::mul(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::mul(self, other: bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::sub(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::sub(self, other: bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 pub fn &bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: &bech32::primitives::gf32::Fe32) -> Self::Output pub fn &bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: bech32::primitives::gf32::Fe32) -> Self::Output pub fn bech32::ByteIterExt::bytes_to_fes(self) -> bech32::primitives::iter::BytesToFes @@ -1021,6 +1055,20 @@ pub fn bech32::primitives::gf32_ext::Fe1024::mul_assign(&mut self, other: &bech3 pub fn bech32::primitives::gf32_ext::Fe1024::multiplicative_inverse(self) -> Self pub fn bech32::primitives::gf32_ext::Fe1024::sub(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 pub fn bech32::primitives::gf32_ext::Fe1024::sub_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe1024) +pub fn bech32::primitives::gf32_ext::Fe32768::_add(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::_div(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::_mul(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::_neg(self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::_sub(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::add(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn bech32::primitives::gf32_ext::Fe32768::add_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe32768) +pub fn bech32::primitives::gf32_ext::Fe32768::div(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn bech32::primitives::gf32_ext::Fe32768::div_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe32768) +pub fn bech32::primitives::gf32_ext::Fe32768::mul(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn bech32::primitives::gf32_ext::Fe32768::mul_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe32768) +pub fn bech32::primitives::gf32_ext::Fe32768::multiplicative_inverse(self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::sub(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn bech32::primitives::gf32_ext::Fe32768::sub_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe32768) pub fn bech32::primitives::gf32_ext::Fe32Ext::clone(&self) -> bech32::primitives::gf32_ext::Fe32Ext pub fn bech32::primitives::gf32_ext::Fe32Ext::eq(&self, other: &bech32::primitives::gf32_ext::Fe32Ext) -> bool pub fn bech32::primitives::gf32_ext::Fe32Ext::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result @@ -1180,9 +1228,11 @@ pub trait bech32::primitives::iter::ByteIterExt: core::marker::Sized + core::ite pub trait bech32::primitives::iter::Fe32IterExt: core::marker::Sized + core::iter::traits::iterator::Iterator pub type &bech32::primitives::gf32::Fe32::Output = bech32::primitives::gf32::Fe32 pub type &bech32::primitives::gf32_ext::Fe1024::Output = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type &bech32::primitives::gf32_ext::Fe32768::Output = bech32::primitives::gf32_ext::Fe32Ext<3> pub type &bech32::primitives::gf32_ext::Fe32Ext::Output = bech32::primitives::gf32_ext::Fe32Ext pub type bech32::Checksum::MidstateRepr: bech32::primitives::checksum::PackedFe32 pub type bech32::Fe1024 = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type bech32::Fe32768 = bech32::primitives::gf32_ext::Fe32Ext<3> pub type bech32::primitives::Bech32::MidstateRepr = u32 pub type bech32::primitives::Bech32m::MidstateRepr = u32 pub type bech32::primitives::ExtensionField::BaseField: bech32::primitives::Field @@ -1201,6 +1251,9 @@ pub type bech32::primitives::gf32::Fe32::Output = bech32::primitives::gf32::Fe32 pub type bech32::primitives::gf32_ext::Fe1024 = bech32::primitives::gf32_ext::Fe32Ext<2> pub type bech32::primitives::gf32_ext::Fe1024::BaseField = bech32::primitives::gf32::Fe32 pub type bech32::primitives::gf32_ext::Fe1024::Output = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type bech32::primitives::gf32_ext::Fe32768 = bech32::primitives::gf32_ext::Fe32Ext<3> +pub type bech32::primitives::gf32_ext::Fe32768::BaseField = bech32::primitives::gf32::Fe32 +pub type bech32::primitives::gf32_ext::Fe32768::Output = bech32::primitives::gf32_ext::Fe32Ext<3> pub type bech32::primitives::gf32_ext::Fe32Ext::Output = bech32::primitives::gf32_ext::Fe32Ext pub type bech32::primitives::hrp::ByteIter<'b>::Item = u8 pub type bech32::primitives::hrp::CharIter<'b>::Item = char diff --git a/api/alloc-only.txt b/api/alloc-only.txt index b09a4ab9a..a13fc1f5f 100644 --- a/api/alloc-only.txt +++ b/api/alloc-only.txt @@ -18,8 +18,10 @@ #[repr(transparent)] pub struct bech32::Fe32(_) #[repr(transparent)] pub struct bech32::primitives::gf32::Fe32(_) impl bech32::primitives::ExtensionField for bech32::primitives::gf32_ext::Fe1024 +impl bech32::primitives::ExtensionField for bech32::primitives::gf32_ext::Fe32768 impl bech32::primitives::Field for bech32::primitives::gf32::Fe32 impl bech32::primitives::Field for bech32::primitives::gf32_ext::Fe1024 +impl bech32::primitives::Field for bech32::primitives::gf32_ext::Fe32768 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32m impl bech32::primitives::checksum::Checksum for bech32::primitives::NoChecksum @@ -308,42 +310,58 @@ impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for &bech32::primiti impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<3>> for &bech32::primitives::gf32_ext::Fe32768 +impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Add for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Add> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Add> for &bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::AddAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::AddAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::AddAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::AddAssign<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Div for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<3>> for &bech32::primitives::gf32_ext::Fe32768 +impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Div for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Div> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Div> for &bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::DivAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::DivAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::DivAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::DivAssign<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Mul for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<3>> for &bech32::primitives::gf32_ext::Fe32768 +impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Mul for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Mul> for &bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::MulAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::MulAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::MulAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::MulAssign<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Neg for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<3>> for &bech32::primitives::gf32_ext::Fe32768 +impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Sub for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Sub> for &bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::SubAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::SubAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::SubAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::SubAssign<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::bit::BitXor for bech32::primitives::checksum::PackedNull impl core::panic::unwind_safe::RefUnwindSafe for bech32::DecodeError impl core::panic::unwind_safe::RefUnwindSafe for bech32::EncodeError @@ -715,6 +733,14 @@ pub const bech32::primitives::gf32_ext::Fe1024::MULTIPLICATIVE_ORDER_FACTORS: &' pub const bech32::primitives::gf32_ext::Fe1024::ONE: Self pub const bech32::primitives::gf32_ext::Fe1024::POLYNOMIAL: Self pub const bech32::primitives::gf32_ext::Fe1024::ZERO: Self +pub const bech32::primitives::gf32_ext::Fe32768::DEGREE: usize +pub const bech32::primitives::gf32_ext::Fe32768::EXT_ELEM: Self +pub const bech32::primitives::gf32_ext::Fe32768::GENERATOR: Self +pub const bech32::primitives::gf32_ext::Fe32768::MULTIPLICATIVE_ORDER: usize +pub const bech32::primitives::gf32_ext::Fe32768::MULTIPLICATIVE_ORDER_FACTORS: &'static [usize] +pub const bech32::primitives::gf32_ext::Fe32768::ONE: Self +pub const bech32::primitives::gf32_ext::Fe32768::POLYNOMIAL: Self +pub const bech32::primitives::gf32_ext::Fe32768::ZERO: Self pub const bech32::primitives::hrp::BC: bech32::primitives::hrp::Hrp pub const bech32::primitives::hrp::BCRT: bech32::primitives::hrp::Hrp pub const bech32::primitives::hrp::TB: bech32::primitives::hrp::Hrp @@ -750,6 +776,14 @@ pub fn &bech32::primitives::gf32_ext::Fe1024::mul(self, other: &bech32::primitiv pub fn &bech32::primitives::gf32_ext::Fe1024::mul(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 pub fn &bech32::primitives::gf32_ext::Fe1024::sub(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 pub fn &bech32::primitives::gf32_ext::Fe1024::sub(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe32768::add(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::add(self, other: bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::div(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::div(self, other: bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::mul(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::mul(self, other: bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::sub(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::sub(self, other: bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 pub fn &bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: &bech32::primitives::gf32::Fe32) -> Self::Output pub fn &bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: bech32::primitives::gf32::Fe32) -> Self::Output pub fn bech32::ByteIterExt::bytes_to_fes(self) -> bech32::primitives::iter::BytesToFes @@ -971,6 +1005,20 @@ pub fn bech32::primitives::gf32_ext::Fe1024::mul_assign(&mut self, other: &bech3 pub fn bech32::primitives::gf32_ext::Fe1024::multiplicative_inverse(self) -> Self pub fn bech32::primitives::gf32_ext::Fe1024::sub(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 pub fn bech32::primitives::gf32_ext::Fe1024::sub_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe1024) +pub fn bech32::primitives::gf32_ext::Fe32768::_add(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::_div(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::_mul(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::_neg(self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::_sub(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::add(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn bech32::primitives::gf32_ext::Fe32768::add_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe32768) +pub fn bech32::primitives::gf32_ext::Fe32768::div(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn bech32::primitives::gf32_ext::Fe32768::div_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe32768) +pub fn bech32::primitives::gf32_ext::Fe32768::mul(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn bech32::primitives::gf32_ext::Fe32768::mul_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe32768) +pub fn bech32::primitives::gf32_ext::Fe32768::multiplicative_inverse(self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::sub(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn bech32::primitives::gf32_ext::Fe32768::sub_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe32768) pub fn bech32::primitives::gf32_ext::Fe32Ext::clone(&self) -> bech32::primitives::gf32_ext::Fe32Ext pub fn bech32::primitives::gf32_ext::Fe32Ext::eq(&self, other: &bech32::primitives::gf32_ext::Fe32Ext) -> bool pub fn bech32::primitives::gf32_ext::Fe32Ext::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result @@ -1122,9 +1170,11 @@ pub trait bech32::primitives::iter::ByteIterExt: core::marker::Sized + core::ite pub trait bech32::primitives::iter::Fe32IterExt: core::marker::Sized + core::iter::traits::iterator::Iterator pub type &bech32::primitives::gf32::Fe32::Output = bech32::primitives::gf32::Fe32 pub type &bech32::primitives::gf32_ext::Fe1024::Output = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type &bech32::primitives::gf32_ext::Fe32768::Output = bech32::primitives::gf32_ext::Fe32Ext<3> pub type &bech32::primitives::gf32_ext::Fe32Ext::Output = bech32::primitives::gf32_ext::Fe32Ext pub type bech32::Checksum::MidstateRepr: bech32::primitives::checksum::PackedFe32 pub type bech32::Fe1024 = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type bech32::Fe32768 = bech32::primitives::gf32_ext::Fe32Ext<3> pub type bech32::primitives::Bech32::MidstateRepr = u32 pub type bech32::primitives::Bech32m::MidstateRepr = u32 pub type bech32::primitives::ExtensionField::BaseField: bech32::primitives::Field @@ -1143,6 +1193,9 @@ pub type bech32::primitives::gf32::Fe32::Output = bech32::primitives::gf32::Fe32 pub type bech32::primitives::gf32_ext::Fe1024 = bech32::primitives::gf32_ext::Fe32Ext<2> pub type bech32::primitives::gf32_ext::Fe1024::BaseField = bech32::primitives::gf32::Fe32 pub type bech32::primitives::gf32_ext::Fe1024::Output = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type bech32::primitives::gf32_ext::Fe32768 = bech32::primitives::gf32_ext::Fe32Ext<3> +pub type bech32::primitives::gf32_ext::Fe32768::BaseField = bech32::primitives::gf32::Fe32 +pub type bech32::primitives::gf32_ext::Fe32768::Output = bech32::primitives::gf32_ext::Fe32Ext<3> pub type bech32::primitives::gf32_ext::Fe32Ext::Output = bech32::primitives::gf32_ext::Fe32Ext pub type bech32::primitives::hrp::ByteIter<'b>::Item = u8 pub type bech32::primitives::hrp::CharIter<'b>::Item = char diff --git a/api/no-features.txt b/api/no-features.txt index 74b0f119d..4357094c9 100644 --- a/api/no-features.txt +++ b/api/no-features.txt @@ -15,8 +15,10 @@ #[repr(transparent)] pub struct bech32::Fe32(_) #[repr(transparent)] pub struct bech32::primitives::gf32::Fe32(_) impl bech32::primitives::ExtensionField for bech32::primitives::gf32_ext::Fe1024 +impl bech32::primitives::ExtensionField for bech32::primitives::gf32_ext::Fe32768 impl bech32::primitives::Field for bech32::primitives::gf32::Fe32 impl bech32::primitives::Field for bech32::primitives::gf32_ext::Fe1024 +impl bech32::primitives::Field for bech32::primitives::gf32_ext::Fe32768 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32 impl bech32::primitives::checksum::Checksum for bech32::primitives::Bech32m impl bech32::primitives::checksum::Checksum for bech32::primitives::NoChecksum @@ -269,42 +271,58 @@ impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for &bech32::primiti impl core::ops::arith::Add<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<3>> for &bech32::primitives::gf32_ext::Fe32768 +impl core::ops::arith::Add<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Add for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Add> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Add> for &bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::AddAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::AddAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::AddAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::AddAssign<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Div for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<3>> for &bech32::primitives::gf32_ext::Fe32768 +impl core::ops::arith::Div<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Div for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Div> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Div> for &bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::DivAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::DivAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::DivAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::DivAssign<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Mul for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<3>> for &bech32::primitives::gf32_ext::Fe32768 +impl core::ops::arith::Mul<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Mul for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Mul> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Mul> for &bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::MulAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::MulAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::MulAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::MulAssign<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Neg for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<2>> for &bech32::primitives::gf32_ext::Fe1024 impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<3>> for &bech32::primitives::gf32_ext::Fe32768 +impl core::ops::arith::Sub<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::Sub for &bech32::primitives::gf32::Fe32 impl core::ops::arith::Sub> for &bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::Sub> for &bech32::primitives::gf32_ext::Fe32768 impl core::ops::arith::SubAssign for bech32::primitives::gf32::Fe32 impl core::ops::arith::SubAssign<&bech32::primitives::gf32::Fe32> for bech32::primitives::gf32::Fe32 impl core::ops::arith::SubAssign<&bech32::primitives::gf32_ext::Fe32Ext<2>> for bech32::primitives::gf32_ext::Fe1024 +impl core::ops::arith::SubAssign<&bech32::primitives::gf32_ext::Fe32Ext<3>> for bech32::primitives::gf32_ext::Fe32768 impl core::ops::bit::BitXor for bech32::primitives::checksum::PackedNull impl core::panic::unwind_safe::RefUnwindSafe for bech32::EncodeError impl core::panic::unwind_safe::RefUnwindSafe for bech32::primitives::Bech32 @@ -664,6 +682,14 @@ pub const bech32::primitives::gf32_ext::Fe1024::MULTIPLICATIVE_ORDER_FACTORS: &' pub const bech32::primitives::gf32_ext::Fe1024::ONE: Self pub const bech32::primitives::gf32_ext::Fe1024::POLYNOMIAL: Self pub const bech32::primitives::gf32_ext::Fe1024::ZERO: Self +pub const bech32::primitives::gf32_ext::Fe32768::DEGREE: usize +pub const bech32::primitives::gf32_ext::Fe32768::EXT_ELEM: Self +pub const bech32::primitives::gf32_ext::Fe32768::GENERATOR: Self +pub const bech32::primitives::gf32_ext::Fe32768::MULTIPLICATIVE_ORDER: usize +pub const bech32::primitives::gf32_ext::Fe32768::MULTIPLICATIVE_ORDER_FACTORS: &'static [usize] +pub const bech32::primitives::gf32_ext::Fe32768::ONE: Self +pub const bech32::primitives::gf32_ext::Fe32768::POLYNOMIAL: Self +pub const bech32::primitives::gf32_ext::Fe32768::ZERO: Self pub const bech32::primitives::hrp::BC: bech32::primitives::hrp::Hrp pub const bech32::primitives::hrp::BCRT: bech32::primitives::hrp::Hrp pub const bech32::primitives::hrp::TB: bech32::primitives::hrp::Hrp @@ -699,6 +725,14 @@ pub fn &bech32::primitives::gf32_ext::Fe1024::mul(self, other: &bech32::primitiv pub fn &bech32::primitives::gf32_ext::Fe1024::mul(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 pub fn &bech32::primitives::gf32_ext::Fe1024::sub(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 pub fn &bech32::primitives::gf32_ext::Fe1024::sub(self, other: bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 +pub fn &bech32::primitives::gf32_ext::Fe32768::add(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::add(self, other: bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::div(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::div(self, other: bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::mul(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::mul(self, other: bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::sub(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn &bech32::primitives::gf32_ext::Fe32768::sub(self, other: bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 pub fn &bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: &bech32::primitives::gf32::Fe32) -> Self::Output pub fn &bech32::primitives::gf32_ext::Fe32Ext::mul(self, other: bech32::primitives::gf32::Fe32) -> Self::Output pub fn bech32::ByteIterExt::bytes_to_fes(self) -> bech32::primitives::iter::BytesToFes @@ -912,6 +946,20 @@ pub fn bech32::primitives::gf32_ext::Fe1024::mul_assign(&mut self, other: &bech3 pub fn bech32::primitives::gf32_ext::Fe1024::multiplicative_inverse(self) -> Self pub fn bech32::primitives::gf32_ext::Fe1024::sub(self, other: &bech32::primitives::gf32_ext::Fe1024) -> bech32::primitives::gf32_ext::Fe1024 pub fn bech32::primitives::gf32_ext::Fe1024::sub_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe1024) +pub fn bech32::primitives::gf32_ext::Fe32768::_add(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::_div(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::_mul(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::_neg(self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::_sub(&self, other: &Self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::add(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn bech32::primitives::gf32_ext::Fe32768::add_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe32768) +pub fn bech32::primitives::gf32_ext::Fe32768::div(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn bech32::primitives::gf32_ext::Fe32768::div_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe32768) +pub fn bech32::primitives::gf32_ext::Fe32768::mul(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn bech32::primitives::gf32_ext::Fe32768::mul_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe32768) +pub fn bech32::primitives::gf32_ext::Fe32768::multiplicative_inverse(self) -> Self +pub fn bech32::primitives::gf32_ext::Fe32768::sub(self, other: &bech32::primitives::gf32_ext::Fe32768) -> bech32::primitives::gf32_ext::Fe32768 +pub fn bech32::primitives::gf32_ext::Fe32768::sub_assign(&mut self, other: &bech32::primitives::gf32_ext::Fe32768) pub fn bech32::primitives::gf32_ext::Fe32Ext::clone(&self) -> bech32::primitives::gf32_ext::Fe32Ext pub fn bech32::primitives::gf32_ext::Fe32Ext::eq(&self, other: &bech32::primitives::gf32_ext::Fe32Ext) -> bool pub fn bech32::primitives::gf32_ext::Fe32Ext::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result @@ -1047,9 +1095,11 @@ pub trait bech32::primitives::iter::ByteIterExt: core::marker::Sized + core::ite pub trait bech32::primitives::iter::Fe32IterExt: core::marker::Sized + core::iter::traits::iterator::Iterator pub type &bech32::primitives::gf32::Fe32::Output = bech32::primitives::gf32::Fe32 pub type &bech32::primitives::gf32_ext::Fe1024::Output = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type &bech32::primitives::gf32_ext::Fe32768::Output = bech32::primitives::gf32_ext::Fe32Ext<3> pub type &bech32::primitives::gf32_ext::Fe32Ext::Output = bech32::primitives::gf32_ext::Fe32Ext pub type bech32::Checksum::MidstateRepr: bech32::primitives::checksum::PackedFe32 pub type bech32::Fe1024 = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type bech32::Fe32768 = bech32::primitives::gf32_ext::Fe32Ext<3> pub type bech32::primitives::Bech32::MidstateRepr = u32 pub type bech32::primitives::Bech32m::MidstateRepr = u32 pub type bech32::primitives::ExtensionField::BaseField: bech32::primitives::Field @@ -1068,6 +1118,9 @@ pub type bech32::primitives::gf32::Fe32::Output = bech32::primitives::gf32::Fe32 pub type bech32::primitives::gf32_ext::Fe1024 = bech32::primitives::gf32_ext::Fe32Ext<2> pub type bech32::primitives::gf32_ext::Fe1024::BaseField = bech32::primitives::gf32::Fe32 pub type bech32::primitives::gf32_ext::Fe1024::Output = bech32::primitives::gf32_ext::Fe32Ext<2> +pub type bech32::primitives::gf32_ext::Fe32768 = bech32::primitives::gf32_ext::Fe32Ext<3> +pub type bech32::primitives::gf32_ext::Fe32768::BaseField = bech32::primitives::gf32::Fe32 +pub type bech32::primitives::gf32_ext::Fe32768::Output = bech32::primitives::gf32_ext::Fe32Ext<3> pub type bech32::primitives::gf32_ext::Fe32Ext::Output = bech32::primitives::gf32_ext::Fe32Ext pub type bech32::primitives::hrp::ByteIter<'b>::Item = u8 pub type bech32::primitives::hrp::CharIter<'b>::Item = char diff --git a/src/lib.rs b/src/lib.rs index ab86aeb21..4ca1381b1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -161,7 +161,7 @@ use crate::primitives::decode::{ChecksumError, UncheckedHrpstring, UncheckedHrps pub use { crate::primitives::checksum::Checksum, crate::primitives::gf32::Fe32, - crate::primitives::gf32_ext::Fe1024, + crate::primitives::gf32_ext::{Fe1024, Fe32768}, crate::primitives::hrp::Hrp, crate::primitives::iter::{ByteIterExt, Fe32IterExt}, crate::primitives::{Bech32, Bech32m, NoChecksum}, diff --git a/src/primitives/gf32_ext.rs b/src/primitives/gf32_ext.rs index 5fddebed8..faff434b1 100644 --- a/src/primitives/gf32_ext.rs +++ b/src/primitives/gf32_ext.rs @@ -183,6 +183,95 @@ impl ExtensionField for Fe1024 { const EXT_ELEM: Self = Self::new([Fe32::Q, Fe32::P]); } +/// The field of order 32768. +pub type Fe32768 = Fe32Ext<3>; + +impl Field for Fe32768 { + /// The zero element of the field. + const ZERO: Self = Self::new([Fe32::Q, Fe32::Q, Fe32::Q]); + + /// The one element of the field. + const ONE: Self = Self::new([Fe32::P, Fe32::Q, Fe32::Q]); + + // Chosen somewhat arbitrarily, by just guessing values until one came + // out with the correct order. + /// A generator of the field. + const GENERATOR: Self = Self::new([Fe32::A, Fe32::C, Fe32::Q]); + + /// The order of the multiplicative group of the field. + /// + /// This constant also serves as a compile-time check that we can count + /// the entire field using a `usize` as a counter. + const MULTIPLICATIVE_ORDER: usize = 32767; + + const MULTIPLICATIVE_ORDER_FACTORS: &'static [usize] = &[1, 7, 31, 151, 217, 1057, 4681, 32767]; + + #[inline] + fn _add(&self, other: &Self) -> Self { + Self::new([ + self.inner[0] + other.inner[0], + self.inner[1] + other.inner[1], + self.inner[2] + other.inner[2], + ]) + } + + #[inline] + fn _sub(&self, other: &Self) -> Self { self._add(other) } + + #[inline] + fn _mul(&self, other: &Self) -> Self { self.mul_by_elem(other) } + + #[inline] + fn _div(&self, other: &Self) -> Self { other.multiplicative_inverse() * self } + + #[inline] + fn _neg(self) -> Self { self } + + fn multiplicative_inverse(self) -> Self { + // Unlike in the GF1024 case we don't bother being generic over + // arbitrary values of POLYNOMIAL, since doing so means a ton + // of extra work for everybody (me, the reviewer, and the CPU + // that has to do a bunch of mulitplications by values that + // turn out to always be 0). + debug_assert_eq!(Self::POLYNOMIAL, Self::new([Fe32::P, Fe32::P, Fe32::Q])); + // Aliases to make the below equations easier to read + let a0 = self.inner[0]; + let a1 = self.inner[1]; + let a2 = self.inner[2]; + + let a0_2 = a0 * a0; + let a1_2 = a1 * a1; + let a2_2 = a2 * a2; + + let a0a1 = a0 * a1; + let a0a2 = a0 * a2; + let a1a2 = a1 * a2; + + // Inverse of the 3x3 multiplication matrix defined by a0, a1, a2. + let det = (a0_2 * a0) + a1_2 * (a0 + a1) + a2_2 * (a0 + a1 + a2) + (a0 * a1a2); + Self::new([ + (a0_2 + a1_2 + a2_2 + a1a2) / det, + (a2_2 + a0a1) / det, + (a1_2 + a2_2 + a0a2) / det, + ]) + } +} +super::impl_ops_for_fe!(impl for Fe32768); + +impl ExtensionField for Fe32768 { + type BaseField = Fe32; + + const DEGREE: usize = 3; + + // Arbitrary irreducible polynomial x^3 = x + 1 + const POLYNOMIAL: Self = Self::new([Fe32::P, Fe32::P, Fe32::Q]); + + /// The element zeta such that the extension field is defined as `GF32[zeta]`. + /// + /// Alternately, the image of x in the mapping `GF32[x]/p(x) -> ` + const EXT_ELEM: Self = Self::new([Fe32::Q, Fe32::P, Fe32::Q]); +} + #[cfg(test)] mod tests { use super::*; @@ -269,4 +358,37 @@ mod tests { assert_eq!(elem.powi(3).multiplicative_order(), 341); assert_eq!(elem.powi(341).multiplicative_order(), 3); } + + #[test] + fn gf32768_mult_inverse() { + assert_eq!(Fe32768::ONE.multiplicative_inverse(), Fe32768::ONE); + + for i in 0..32 { + for j in 0..32 { + for k in 0..32 { + if i != 0 || j != 0 || k != 0 { + let fe32768 = Fe32768::new([Fe32(i), Fe32(j), Fe32(k)]); + assert_eq!( + fe32768.multiplicative_inverse().multiplicative_inverse(), + fe32768, + ); + } + } + } + } + } + + #[test] + fn gf32768_powi() { + // A "random" element + let elem = Fe32768::new([Fe32::A, Fe32::C, Fe32::Q]); + assert_eq!(elem.powi(2), elem * elem); + assert_eq!(elem.powi(3), elem * elem * elem); + assert_eq!(elem.powi(0), Fe32768::ONE); + assert_eq!(elem.powi(-1), elem.multiplicative_inverse()); + + assert_eq!(elem.multiplicative_order(), 32767); + assert_eq!(elem.powi(7).multiplicative_order(), 4681); + assert_eq!(elem.powi(341).multiplicative_order(), 1057); + } } From b44431fae7b6a634b0a81ddcfe08da1434cb3e8c Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Sun, 24 Mar 2024 15:15:04 +0000 Subject: [PATCH 7/8] checksum: introduce `PrintImpl` object to print `impl Checksum` blocks For the most part, BCH codes used in the ecosystem are defined as generator polynomials over GF32 and a target residue polynomial, and the remaining code parameters are not specified, or are only specified indirectly. It is difficult for non-experts to compute or even validate parameters such as the length of the code or the shifted+packed generator polynomials. It will be even more difficult in the sequel when we extend the Checksum trait to also cover error-correction parameters (some of which will depend on our particular choice of representation for GF1024 elements, which is not canonical and differs between different documents). So we introduce an object `PrintImpl` and a unit test and doctest demonstrating its use, which will generate all of the needed parameters and output a block of Rust code. --- api/all-features.txt | 12 ++ api/alloc-only.txt | 12 ++ src/lib.rs | 2 + src/primitives/checksum.rs | 233 ++++++++++++++++++++++++++++++++++++- 4 files changed, 257 insertions(+), 2 deletions(-) diff --git a/api/all-features.txt b/api/all-features.txt index 34562bf4e..5b282444e 100644 --- a/api/all-features.txt +++ b/api/all-features.txt @@ -438,6 +438,14 @@ impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::segwit::Invali impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::segwit::WitnessLengthError impl core::panic::unwind_safe::UnwindSafe for bech32::segwit::DecodeError impl core::panic::unwind_safe::UnwindSafe for bech32::segwit::EncodeError +impl<'a, ExtField> bech32::primitives::checksum::PrintImpl<'a, ExtField> +impl<'a, ExtField> core::fmt::Display for bech32::primitives::checksum::PrintImpl<'a, ExtField> where ExtField: bech32::primitives::ExtensionField + core::convert::From +impl<'a, ExtField> core::marker::Freeze for bech32::primitives::checksum::PrintImpl<'a, ExtField> +impl<'a, ExtField> core::marker::Send for bech32::primitives::checksum::PrintImpl<'a, ExtField> where ExtField: core::marker::Send +impl<'a, ExtField> core::marker::Sync for bech32::primitives::checksum::PrintImpl<'a, ExtField> where ExtField: core::marker::Sync +impl<'a, ExtField> core::marker::Unpin for bech32::primitives::checksum::PrintImpl<'a, ExtField> where ExtField: core::marker::Unpin +impl<'a, ExtField> core::panic::unwind_safe::RefUnwindSafe for bech32::primitives::checksum::PrintImpl<'a, ExtField> where ExtField: core::panic::unwind_safe::RefUnwindSafe +impl<'a, ExtField> core::panic::unwind_safe::UnwindSafe for bech32::primitives::checksum::PrintImpl<'a, ExtField> where ExtField: core::panic::unwind_safe::UnwindSafe impl<'a, I, Ck> core::iter::traits::iterator::Iterator for bech32::primitives::encode::ByteIter<'a, I, Ck> where I: core::iter::traits::iterator::Iterator, Ck: bech32::primitives::checksum::Checksum impl<'a, I, Ck> core::iter::traits::iterator::Iterator for bech32::primitives::encode::CharIter<'a, I, Ck> where I: core::iter::traits::iterator::Iterator, Ck: bech32::primitives::checksum::Checksum impl<'b> core::iter::traits::double_ended::DoubleEndedIterator for bech32::primitives::hrp::ByteIter<'b> @@ -893,6 +901,8 @@ pub fn bech32::primitives::checksum::PackedNull::fmt(&self, f: &mut core::fmt::F pub fn bech32::primitives::checksum::PackedNull::mul_by_x_then_add(&mut self, usize, u8) -> u8 pub fn bech32::primitives::checksum::PackedNull::pack>(iter: I) -> Self pub fn bech32::primitives::checksum::PackedNull::unpack(&self, usize) -> u8 +pub fn bech32::primitives::checksum::PrintImpl<'a, ExtField>::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +pub fn bech32::primitives::checksum::PrintImpl<'a, ExtField>::new(name: &'a str, generator: &'a [bech32::primitives::gf32::Fe32], target: &'a [bech32::primitives::gf32::Fe32]) -> Self pub fn bech32::primitives::decode::AsciiToFe32Iter<'s>::len(&self) -> usize pub fn bech32::primitives::decode::AsciiToFe32Iter<'s>::next(&mut self) -> core::option::Option pub fn bech32::primitives::decode::AsciiToFe32Iter<'s>::size_hint(&self) -> (usize, core::option::Option) @@ -1194,10 +1204,12 @@ pub mod bech32::primitives::iter pub mod bech32::primitives::segwit pub mod bech32::segwit pub struct bech32::Hrp +pub struct bech32::PrintImpl<'a, ExtField> pub struct bech32::hrp::Hrp pub struct bech32::primitives::checksum::Engine pub struct bech32::primitives::checksum::HrpFe32Iter<'hrp> pub struct bech32::primitives::checksum::PackedNull +pub struct bech32::primitives::checksum::PrintImpl<'a, ExtField> pub struct bech32::primitives::decode::AsciiToFe32Iter<'s> pub struct bech32::primitives::decode::ByteIter<'s> pub struct bech32::primitives::decode::CheckedHrpstring<'s> diff --git a/api/alloc-only.txt b/api/alloc-only.txt index a13fc1f5f..ddf1cb3b3 100644 --- a/api/alloc-only.txt +++ b/api/alloc-only.txt @@ -409,6 +409,14 @@ impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::segwit::Invali impl core::panic::unwind_safe::UnwindSafe for bech32::primitives::segwit::WitnessLengthError impl core::panic::unwind_safe::UnwindSafe for bech32::segwit::DecodeError impl core::panic::unwind_safe::UnwindSafe for bech32::segwit::EncodeError +impl<'a, ExtField> bech32::primitives::checksum::PrintImpl<'a, ExtField> +impl<'a, ExtField> core::fmt::Display for bech32::primitives::checksum::PrintImpl<'a, ExtField> where ExtField: bech32::primitives::ExtensionField + core::convert::From +impl<'a, ExtField> core::marker::Freeze for bech32::primitives::checksum::PrintImpl<'a, ExtField> +impl<'a, ExtField> core::marker::Send for bech32::primitives::checksum::PrintImpl<'a, ExtField> where ExtField: core::marker::Send +impl<'a, ExtField> core::marker::Sync for bech32::primitives::checksum::PrintImpl<'a, ExtField> where ExtField: core::marker::Sync +impl<'a, ExtField> core::marker::Unpin for bech32::primitives::checksum::PrintImpl<'a, ExtField> where ExtField: core::marker::Unpin +impl<'a, ExtField> core::panic::unwind_safe::RefUnwindSafe for bech32::primitives::checksum::PrintImpl<'a, ExtField> where ExtField: core::panic::unwind_safe::RefUnwindSafe +impl<'a, ExtField> core::panic::unwind_safe::UnwindSafe for bech32::primitives::checksum::PrintImpl<'a, ExtField> where ExtField: core::panic::unwind_safe::UnwindSafe impl<'a, I, Ck> core::iter::traits::iterator::Iterator for bech32::primitives::encode::ByteIter<'a, I, Ck> where I: core::iter::traits::iterator::Iterator, Ck: bech32::primitives::checksum::Checksum impl<'a, I, Ck> core::iter::traits::iterator::Iterator for bech32::primitives::encode::CharIter<'a, I, Ck> where I: core::iter::traits::iterator::Iterator, Ck: bech32::primitives::checksum::Checksum impl<'b> core::iter::traits::double_ended::DoubleEndedIterator for bech32::primitives::hrp::ByteIter<'b> @@ -853,6 +861,8 @@ pub fn bech32::primitives::checksum::PackedNull::fmt(&self, f: &mut core::fmt::F pub fn bech32::primitives::checksum::PackedNull::mul_by_x_then_add(&mut self, usize, u8) -> u8 pub fn bech32::primitives::checksum::PackedNull::pack>(iter: I) -> Self pub fn bech32::primitives::checksum::PackedNull::unpack(&self, usize) -> u8 +pub fn bech32::primitives::checksum::PrintImpl<'a, ExtField>::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +pub fn bech32::primitives::checksum::PrintImpl<'a, ExtField>::new(name: &'a str, generator: &'a [bech32::primitives::gf32::Fe32], target: &'a [bech32::primitives::gf32::Fe32]) -> Self pub fn bech32::primitives::decode::AsciiToFe32Iter<'s>::len(&self) -> usize pub fn bech32::primitives::decode::AsciiToFe32Iter<'s>::next(&mut self) -> core::option::Option pub fn bech32::primitives::decode::AsciiToFe32Iter<'s>::size_hint(&self) -> (usize, core::option::Option) @@ -1136,10 +1146,12 @@ pub mod bech32::primitives::iter pub mod bech32::primitives::segwit pub mod bech32::segwit pub struct bech32::Hrp +pub struct bech32::PrintImpl<'a, ExtField> pub struct bech32::hrp::Hrp pub struct bech32::primitives::checksum::Engine pub struct bech32::primitives::checksum::HrpFe32Iter<'hrp> pub struct bech32::primitives::checksum::PackedNull +pub struct bech32::primitives::checksum::PrintImpl<'a, ExtField> pub struct bech32::primitives::decode::AsciiToFe32Iter<'s> pub struct bech32::primitives::decode::ByteIter<'s> pub struct bech32::primitives::decode::CheckedHrpstring<'s> diff --git a/src/lib.rs b/src/lib.rs index 4ca1381b1..41e474af4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -166,6 +166,8 @@ pub use { crate::primitives::iter::{ByteIterExt, Fe32IterExt}, crate::primitives::{Bech32, Bech32m, NoChecksum}, }; +#[cfg(feature = "alloc")] +pub use crate::primitives::checksum::PrintImpl; // Write to fmt buffer, small during testing to exercise full code path. #[cfg(not(test))] diff --git a/src/primitives/checksum.rs b/src/primitives/checksum.rs index e3724d816..d9ee80d4f 100644 --- a/src/primitives/checksum.rs +++ b/src/primitives/checksum.rs @@ -4,10 +4,20 @@ //! //! [BCH]: +#[cfg(all(feature = "alloc", not(feature = "std"), not(test)))] +use alloc::vec::Vec; +#[cfg(feature = "alloc")] +use core::fmt; +#[cfg(feature = "alloc")] +use core::marker::PhantomData; use core::{mem, ops}; -use crate::primitives::gf32::Fe32; +#[cfg(feature = "alloc")] +use super::Polynomial; use crate::primitives::hrp::Hrp; +#[cfg(feature = "alloc")] +use crate::Fe1024; +use crate::Fe32; /// Trait defining a particular checksum. /// @@ -49,7 +59,7 @@ pub trait Checksum { /// /// These cannot be usefully pre-computed because of Rust's limited constfn support /// as of 1.67, so they must be specified manually for each checksum. To check the - /// values for consistency, run `Self::sanity_check()`. + /// values for consistency, run [`Self::sanity_check`]. const GENERATOR_SH: [Self::MidstateRepr; 5]; /// The residue, modulo the generator polynomial, that a valid codeword will have. @@ -83,6 +93,184 @@ pub trait Checksum { } } +/// Given a polynomial representation for your generator polynomial and your +/// target residue, outputs a `impl Checksum` block. +/// +/// You must specify an extension field. You should try [`crate::Fe1024`], and if +/// you get an error about a polynomial not splitting, try [`crate::Fe32768`]. +/// +/// Used like +/// +/// ``` +/// # #[cfg(feature = "alloc")] { +/// use core::convert::TryFrom; +/// +/// use bech32::{Fe32, Fe1024, PrintImpl}; +/// use bech32::primitives::checksum::PackedFe32; +/// +/// // In codes specified in BIPs, the code generator polynomial and residue +/// // are often only given indirectly, in the reference code which encodes +/// // it in a packed form (shifted multiple times). +/// // +/// // For example in the BIP173 Python reference code you will see an array +/// // called `generator` whose first entry is 0x3b6a57b2. This first entry +/// // is the generator polynomial in packed form. +/// // +/// // To get the expanded polynomial form you can use `u128::unpack` like so: +/// let unpacked_poly = (0..6) +/// .rev() // Note .rev() to convert from BE integer literal to LE polynomial! +/// .map(|i| 0x3b6a57b2u128.unpack(i)) +/// .map(|u| Fe32::try_from(u).unwrap()) +/// .collect::>(); +/// let unpacked_residue = (0..6) +/// .rev() +/// .map(|i| 0x1u128.unpack(i)) +/// .map(|u| Fe32::try_from(u).unwrap()) +/// .collect::>(); +/// println!( +/// "{}", +/// PrintImpl::::new( +/// "Bech32", +/// &unpacked_poly, +/// &unpacked_residue, +/// ), +/// ); +/// # } +/// ``` +/// +/// The awkward API is to allow this type to be used in the widest set of +/// circumstances, including in nostd settings. (However, the underlying +/// polynomial math requires the `alloc` feature.) +/// +/// Both polynomial representations should be in little-endian order, so that +/// the coefficient of x^i appears in the ith slot. The generator polynomial +/// should be a monic polynomial but you should not include the monic term, +/// so that both `generator` and `target` are arrays of the same length. +/// +/// **This function should never need to be called by users, but will be helpful +/// for developers.** +/// +/// In general, when defining a checksum, it is best to call this method (and +/// to add a unit test that calls [`Checksum::sanity_check`] rather than trying +/// to compute the values yourself. The reason is that the specific values +/// used depend on the representation of extension fields, which may differ +/// between implementations (and between specifications) of your BCH code. +#[cfg(feature = "alloc")] +pub struct PrintImpl<'a, ExtField = Fe1024> { + name: &'a str, + generator: &'a [Fe32], + target: &'a [Fe32], + bit_len: usize, + hex_width: usize, + midstate_repr: &'static str, + phantom: PhantomData, +} + +#[cfg(feature = "alloc")] +impl<'a, ExtField> PrintImpl<'a, ExtField> { + /// Constructor for an object to print an impl-block for the [`Checksum`] trait. + /// + /// # Panics + /// + /// Panics if any of the input values fail various sanity checks. + pub fn new(name: &'a str, generator: &'a [Fe32], target: &'a [Fe32]) -> Self { + // Sanity checks. + assert_ne!(name.len(), 0, "type name cannot be the empty string",); + assert_ne!( + generator.len(), + 0, + "generator polynomial cannot be the empty string (constant 1)" + ); + assert_ne!(target.len(), 0, "target residue cannot be the empty string"); + if generator.len() != target.len() { + let hint = if generator.len() == target.len() + 1 { + " (you should not include the monic term of the generator polynomial" + } else if generator.len() > target.len() { + " (you may need to zero-pad your target residue)" + } else { + "" + }; + panic!( + "Generator length {} does not match target residue length {}{}", + generator.len(), + target.len(), + hint + ); + } + + let bit_len = 5 * target.len(); + let (hex_width, midstate_repr) = if bit_len <= 32 { + (8, "u32") + } else if bit_len <= 64 { + (16, "u64") + } else if bit_len <= 128 { + (32, "u128") + } else { + panic!("Generator length {} cannot exceed 25, as we cannot represent it by packing bits into a Rust numeric type", generator.len()); + }; + // End sanity checks. + PrintImpl { + name, + generator, + target, + bit_len, + hex_width, + midstate_repr, + phantom: PhantomData, + } + } +} + +#[cfg(feature = "alloc")] +impl<'a, ExtField> fmt::Display for PrintImpl<'a, ExtField> +where + ExtField: super::ExtensionField + From, +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Generator polynomial as a polynomial over GF1024 + let gen_poly = { + let mut v = Vec::with_capacity(self.generator.len() + 1); + v.push(ExtField::ONE); + v.extend(self.generator.iter().cloned().map(ExtField::from)); + Polynomial::new(v) + }; + let (_gen, length, _exponents) = gen_poly.bch_generator_primitive_element(); + + write!(f, "// Code block generated by Checksum::print_impl polynomial ")?; + for fe in self.generator { + write!(f, "{}", fe)?; + } + write!(f, " target ")?; + for fe in self.target { + write!(f, "{}", fe)?; + } + f.write_str("\n")?; + writeln!(f, "impl Checksum for {} {{", self.name)?; + writeln!( + f, + " type MidstateRepr = {}; // checksum packs into {} bits", + self.midstate_repr, self.bit_len + )?; + writeln!(f, " const CODE_LENGTH: usize = {};", length)?; + writeln!(f, " const CHECKSUM_LENGTH: usize = {};", gen_poly.degree())?; + writeln!(f, " const GENERATOR_SH: [{}; 5] = [", self.midstate_repr)?; + let mut gen5 = self.generator.to_vec(); + for _ in 0..5 { + let gen_packed = u128::pack(gen5.iter().copied().map(From::from)); + writeln!(f, " 0x{:0width$x},", gen_packed, width = self.hex_width)?; + gen5.iter_mut().for_each(|x| *x *= Fe32::Z); + } + writeln!(f, " ];")?; + writeln!( + f, + " const TARGET_RESIDUE: {} = {:?};", + self.midstate_repr, + u128::pack(self.target.iter().copied().map(From::from)) + )?; + f.write_str("}") + } +} + /// A checksum engine, which can be used to compute or verify a checksum. /// /// Use this to verify a checksum, feed it the data to be checksummed using @@ -311,6 +499,9 @@ impl<'hrp> Iterator for HrpFe32Iter<'hrp> { #[cfg(test)] mod tests { + #[cfg(feature = "alloc")] + use core::convert::TryFrom; + use super::*; #[test] @@ -327,4 +518,42 @@ mod tests { assert_eq!(packed.unpack(2), 2); assert_eq!(packed.unpack(3), 1); } + + #[test] + #[cfg(feature = "alloc")] + fn bech32() { + // In codes that Pieter specifies typically the generator polynomial is + // only given indirectly, in the reference code which encodes it in a + // packed form (shifted multiple times). + // + // For example in the BIP173 Python reference code you will see an array + // called `generator` whose first entry is 0x3b6a57b2. This first entry + // is the generator polynomial in packed form. + // + // To get the expanded polynomial form you can use `u128::unpack` like so: + let unpacked_poly = (0..6) + .rev() // Note .rev() to convert from BE integer literal to LE polynomial! + .map(|i| 0x3b6a57b2u128.unpack(i)) + .map(|u| Fe32::try_from(u).unwrap()) + .collect::>(); + assert_eq!(unpacked_poly, [Fe32::A, Fe32::K, Fe32::_5, Fe32::_4, Fe32::A, Fe32::J],); + // To get a version of the above with bech32 chars instead of Fe32s, which + // can be a bit hard to print, just stick a `.map(Fe32::to_char)` into the + // above iterator chain. + + // Ok, exposition over. The actual unit test follows. + + // Run with -- --nocapture to see the output of this. This unit test + // does not check the exact output because it is not deterministic, + // and cannot check the code semantics because Rust does not have + // any sort of `eval`, but you can manually check the output works. + let _s = PrintImpl::::new( + "Bech32", + &[Fe32::A, Fe32::K, Fe32::_5, Fe32::_4, Fe32::A, Fe32::J], + &[Fe32::Q, Fe32::Q, Fe32::Q, Fe32::Q, Fe32::Q, Fe32::P], + ) + .to_string(); + #[cfg(feature = "std")] + println!("{}", _s); + } } From caefc449b77fd6dd7dea7755c1023ec44de26750 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Tue, 26 Mar 2024 14:37:47 +0000 Subject: [PATCH 8/8] checksum: add unit test to print parameters of the descriptor checksum --- src/primitives/checksum.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/primitives/checksum.rs b/src/primitives/checksum.rs index d9ee80d4f..544851166 100644 --- a/src/primitives/checksum.rs +++ b/src/primitives/checksum.rs @@ -556,4 +556,35 @@ mod tests { #[cfg(feature = "std")] println!("{}", _s); } + + #[test] + #[cfg(feature = "alloc")] + fn descriptor() { + // This magic constant came from Bitcoin Core, src/script/descriptor.cpp. + // + // Note that this generator polynomial has degree 8, not 6, reflected + // in the initial range being (0..8). + let unpacked_poly = (0..8) + .rev() // Note .rev() to convert from BE integer literal to LE polynomial! + .map(|i| 0xf5dee51989u64.unpack(i)) + .map(|u| Fe32::try_from(u).unwrap()) + .collect::>(); + assert_eq!( + unpacked_poly, + [Fe32::_7, Fe32::H, Fe32::_0, Fe32::W, Fe32::_2, Fe32::X, Fe32::V, Fe32::F], + ); + + // Run with -- --nocapture to see the output of this. This unit test + // does not check the exact output because it is not deterministic, + // and cannot check the code semantics because Rust does not have + // any sort of `eval`, but you can manually check the output works. + let _s = PrintImpl::::new( + "DescriptorChecksum", + &[Fe32::_7, Fe32::H, Fe32::_0, Fe32::W, Fe32::_2, Fe32::X, Fe32::V, Fe32::F], + &[Fe32::Q, Fe32::Q, Fe32::Q, Fe32::Q, Fe32::Q, Fe32::Q, Fe32::Q, Fe32::P], + ) + .to_string(); + #[cfg(feature = "std")] + println!("{}", _s); + } }