Repository navigation
3.0.1 is the first supported v3 release. The 3.0.0 published before it went
out by accident and was yanked; 3.0.1 is not API-compatible with that artifact
(see the 3.0.0 entry), and code locked to it must migrate. The supported
upgrade path is from 2.x: follow
Migrating from 2.x
and the breaking entries below.
Added
- The canonical generic field family
FiniteField<const P: u64, const N: u32, R: FiniteFieldRepr<P, N> = Residue>with theResiduepresentation at
degree one over everyu64prime. Each row exposes the full scalar and
constelement surface (from_raw, checkedfrom_residue,to_residue,
arithmetic,pow,canonical),
total arithmetic under the crate-wide conventions (inv(0) == 0,
x / 0 == 0,0^0 == 1, with the explicit inverse-zero branch at
P = 2), a little-endian wire lane sized to the characteristic —
characteristic two uses an eight-byte lane, and an odd characteristic
uses one, two, four, or eight bytes as its residues fit within2^8,
2^16,2^32, andu64— withFieldBuffer::decode/encodeas the
byte API of these rows, the checked packed
operation surface with prepared coefficients, and vector routing on
capable x86-64 hosts — AVX2 single-row kernels, AVX-512 undersimd512—
withScalarrouting elsewhere. Broadcast add/sub take the modular path
for every characteristic, so packed lanes stay canonical atP = 2.
Values live in
field::finite_field, re-exported at the root. - Sealed
PrimeFieldmarker for degree-one fields, the validatedconst
integer reductionsfield::prime::reduceandreduce_wide,RangeError
for out-of-range conversions, and thePrimeIdentitycharacteristic
factsBITS,TWO_ADICITY, andRESIDUE_MOD_8. just compile-failcompiles the negative consumer snippets under
tests/compile_fail/on the crate MSRV, each required to fail with its
declared crate panic fragment, or simply to be rejected for trait-bound
and privacy cases, andjust msrv-acceptruns
those snippets plus thetests/consumers.rscompile-and-run matrix on
the MSRV toolchain.- Wiki source guides cover the generic type model, field presentations,
embeddings, custom towers and scalar fields, packed workflows, preparation,
prime and bit-packed arithmetic, deployment, and migration from 2.x.
wiki/Home.mdand the sidebar organize the reader paths. - Sealed presentations
MersenneFold(labelmersenne-fold) and
GoldilocksFold(labelgoldilocks-fold), re-exported at the root. Both
rows implementPrimeFieldand gainconstfrom_residue(u64) -> Result<Self, RangeError>andto_residue(self) -> Option<u64>. The
defaultResiduerow at either modulus remains a distinct type with its
own lane width; values move between the two by residue conversion. - The binary degree-one rows
FiniteField<2, 1, R>implementPrimeField
and gainconstfrom_residue(u64) -> Result<Self, RangeError>and
to_residue(self) -> Option<u64>; they stay distinct from
FiniteField<2, 1, Residue>, which stores au64residue. just external-checktype-checks every package underexternal/
against the working copy.- The generic extension presentation
FiniteField<P, N, Extension<S, D>>
with data-onlyExtensionSpecproviders, the sealed storage family
(Components,Packed,PackedPadded), the opaque const-constructible
Relation, generic arithmetic under the crate-wide total conventions,
component bytes and the checked packed surface withScalarrouting,
ExtensionFieldcomponent conversions, andBinaryFieldon
characteristic-two rows over binary bases. The surface lives in
field::extension, re-exported at the root.EmbeddingErrorgains the
NoCanonicalMapvariant for dividing degrees with no canonical map. ComplexMersenne31, theExtensionSpec<2>ofQuadMersenne31:
Mersenne31extended byt^2 + 1withComponentsstorage,
re-exported at the root.- An extension row whose base presentation, relation, and storage equal a
shipped instance's runs that instance's specialized scalar arithmetic and
reaches its kernel arms; every other extension row runs the generic body
and reportsScalar. FieldElem::from_residue/to_residueandfrom_index/to_indexon
every row: the prime-subfield value and the presentation index share one
generic body over the crate-private row hooks, and the inherentconst
residue constructors check through the same bound.- The characteristic-independent relation surface in
field::embedding,
re-exported at the root:Embedding<S, T>over every pair of rows of
equal characteristic whose degrees divide, withfrom_images,
to_images,generator_count,generator,then, and
Isomorphism<S, T>withapply, a totalunapply,
inverse, and composition; and theNoCanonicalMapandInvalidImages
variants ofEmbeddingError. Maps come from structural inclusions, the
frozen binary ladder, or validated caller images; every pre-cutover
binary result is unchanged. - Wiki reference for operation suffixes, destination behavior, prepared state,
row addressing, and allocation. - One-time field migration verification is recorded in
Issue #41, rather than a
permanent expanded regression corpus. - Behavioral regressions cover irreducible and reducible extension relations,
relation-field arithmetic, ordered-basis subfield embeddings, rejected
restrictions and degree mismatches, and quadratic prime identity predicates. - Raw kernel dispatch is unreachable outside the crate: every
FieldKernels
kernel entry takes the crate-privateRawDispatchproof argument, so code
holding anF: FieldKernelsbound — including underinternals— cannot
call the raw entries. The negative consumer snippet
tests/compile_fail/raw_dispatch_without_proof.rspins the rejection. - Three examples join the educational set, each running against the library
withstdandallocdisabled:custom_extensionsdefines a custom
ExtensionSpecfield,basis_mapsmoves values throughEmbedding
between basis presentations, andpacked_no_allocruns packed row
operations without an allocator.just examples-portableruns them in
that configuration. just release-acceptruns the crate-specific release acceptance, separate
from the shared pull-request gatejust validate. Its pieces also stand
alone:just test-gather-validation-32runs the gather validation as a
release i686 build with overflow checks disabled — the configuration the
gather fix below required — and CI runs it as its own job;
just benchmark-checkvalidates portable benchmark fixtures and compares
their inventory with compiler-derived public API declarations;
just benchmark-check-nativevalidates the GF16 presentation comparisons
and existing native geometries on capable hosts.just isa-accept EXPECTED
requires the requested process backend and positive execution evidence
before running the full tier matrix. Native release acceptance uses
dedicated Willow Cove (v4x) and Golden Cove (v3_gfni_crypto) hosts.- The
surfacesbenchmark artifact measures the public API end to end:
scalar arithmetic, packed single-row and multi-row operations, prepared
coefficient forms, andEmbedding/Isomorphismmaps, over representative
fields including the AES byte field, the Rijndael sixteen tower, and the
MersenneFold/GoldilocksFoldprime rows.--inventoryprints every
registered measurement without timing,--checkruns each fixture's
correctness check once, and--smokeshortens repetition without
dropping cases. Each timed record names its public callable paths, exact
registered field label, scope, logical byte numerator, lane and
source/destination counts, and the resolved backend; a byte-XOR control
identifies itself withcontrolandphasefields, and zero-work APIs
report latency instead of throughput. - The native GF16 comparison gains
--presentations, a separate output mode
beside the legacy format so existing parsing is unchanged. It covers
representative shipped Rijndael and Fan-Paar fields, custom RS-rooted
fields, normal and Cantor bases, and competitor-matched fields, with
duplicatefgfcontrol arms, interleaved arms and fixed/cycling
coefficients, and every map and fixture validated outside timing;
--presentations --checkvalidates every new geometry without timing,
and--presentations --smokeshortens the sampling budget without
dropping a registered case. Both output modes open with a
BENCHMARK_MODEbanner (full,smoke, orcheck), and each
GF16_SURFACErecord carries its sample count and calibrated batch size
assamplesandbatch_reps. Presentation conversions run public scalar
caller loops. - The capture family
surfacesrecords the artifact and the GF16
--presentationsmode for current v3 in five rounds per host, published
in the v3 record (benchmarks/v3/public-api.md,benchmarks/v3/maps.md,
and the GF16 presentation panels). No released-v2 counterpart is
fabricated for the new public APIs.
Changed
- Breaking: generic residue rows size their byte lane to the
characteristic instead of always storing eight bytes: characteristic
two keeps an eight-byte lane, and an odd characteristic uses one, two,
four, or eight bytes as its residues fit within2^8,2^16,2^32,
andu64— for exampleFiniteField<7, 1>moves one byte per element
andFiniteField<1_000_000_007, 1>moves four.FieldBuffer::decode
andencodeare the byte API of these rows. Migration: the inherent
fixed-arrayfrom_bytes/to_bytesare absent for these rows (every
characteristic,P = 2included), and noconstbyte form exists for
them — size buffers fromFieldBuffer::BYTES, decode and encode
throughFieldBuffer, and inconstcode build fromfrom_rawwith
u64::from_le_bytesand read back throughto_raw. Extensions over a
residue base shrink with the base lane; the named prime rows, binary
rows, towers, andQuadMersenne31keep their lane widths and fixed-array
methods. - Breaking:
Mersenne31andGoldilocksare type aliases of the
canonical family rowsFiniteField<0x7FFF_FFFF, 1, MersenneFold>and
FiniteField<0xFFFF_FFFF_0000_0001, 1, GoldilocksFold>instead of unit
marker structs. Moduli, raw widths, bytes, generators, arithmetic, and
kernel routing are unchanged. The aliases are no longer value
expressions: replaceMersenne31orGoldilocksused as a value with
Mersenne31::default()(or drop the value where only the type was
needed). MarkerDebugnow prints the family spelling, e.g.
FiniteField<2147483647, 1, mersenne-fold>. Kernel receivers move to the
rows with the aliases, soFieldKernelscalls through the alias names
compile unchanged. - Breaking: the
Binary<N, R>marker is removed without an alias;
binary fields are the canonical family rowsFiniteField<2, N, R>.
ReplaceBinary<8, Polynomial<AES>>withFiniteField<2, 8, Polynomial<AES>>andBinary::<…>withFiniteField::<2, …>, and
importFiniteFieldinstead ofBinary. Raw widths, bytes, descriptors,
coordinates, embeddings, bit-packed buffers, and kernel routing are
unchanged. - Breaking:
BinaryRepr<const N: u32>andBinaryDegree<const N: u32>
takeu32degree parameters instead ofu8; generic code declaring
const N: u8against them changes the parameter type. - Breaking:
BinaryReprnow extendsFiniteFieldRepr<2, N>, which
ownsNAMEandVALID. Replace<R as BinaryRepr<N>>::NAMEand
::VALIDwith<R as FiniteFieldRepr<2, N>>::NAMEand::VALID;
DESCRIPTIONandLOG_EXPstay onBinaryRepr. - Breaking: binary marker
Debugprints the family spelling with the
presentation label, e.g.FiniteField<2, 8, GF(2^8)/0x11B>, instead of
the label alone. ElementDebugand every wire format are unchanged. - Breaking: binary rows validate their defining data at every entry
point:ZERO_RAW,ONE_RAW, and every rawFieldmethod now fail const
evaluation for an invalid polynomial or basis, asfrom_rawalready did.
Valid presentations are unaffected. - Breaking:
Field,HasGenerator, andFieldBufferare sealed.
Implementing any of them outside the crate no longer compiles. Migrate a
custom prime field to the family's degree-one rowFiniteField<P, 1>
(the defaultResiduepresentation) at any checkedu64prime: it
suppliesField,PrimeField,FieldBuffer, the checked packed
operation surface, and theconstelement API. Migrate a custom
extension to anExtensionSpecover a crate row. - Breaking: the shipped towers are extension rows:
FiniteField<2, N, Tower<S>>is spelledFiniteField<2, N, Extension<S, 2>>forSin
Rijndael16,Rijndael32,Rijndael64, andFanPaar2through
FanPaar64, each now anExtensionSpec<2>withPacked<W>storage
(PackedPadded<u8>forFanPaar2andFanPaar4). Raw words, bytes,
coordinate words, generators, embeddings, and kernel routing are
unchanged, and each instance keeps itsconstelement surface and
mul_alpha. ReplaceTower<S>withExtension<S, 2>and import
Extension. - Breaking: the wide shipped instances' component conversions take
and return arrays:Elem::<F>::from_components(a, b)becomes
from_components([a, b])andto_components()returns[a, b]instead
of(a, b), matchingExtensionField<2>. - Breaking: towers leave
BinaryRepr:BinaryRepr<N>covers the flat
presentations only, and no flat presentation exists at degrees 16, 32,
and 64. Replace generic boundsR: BinaryRepr<N>that reached towers with
field-level bounds (F: BinaryDegree<N>orF: BinaryField) and
<Tower<S> as BinaryRepr<N>>::DESCRIPTIONwithF::DESCRIPTION. - Breaking:
QuadMersenne31is a type alias of
FiniteField<0x7FFF_FFFF, 2, Extension<ComplexMersenne31, 2>>instead of
a unit marker struct, and its raw word is[u32; 2]instead of
(u32, u32), with the same limbs in the same order. Replace
Elem::<QuadMersenne31>::from_raw(re, im)withfrom_raw([re, im]),
to_raw().0and.1withto_raw()[0]and[1],from_components(re, im)withfrom_components([re, im]), and tuple destructuring of
to_components()with array destructuring. ElementDisplayprints
[re, im]in the base field's form instead of(re+imi); bytes,
arithmetic, the generator,I,conjugate,norm, and kernel routing
are unchanged. ReplaceQuadMersenne31used as a value with
QuadMersenne31::default(). BinaryDescription::invtakes canonical coordinate words. On a
polynomial-root description, a word with bits at or abovedegree()
inverts its lowdegree()bits instead of returning an unspecified
value; on other roots such a word still gives an unspecified result.
Results on canonical words are unchanged.- Breaking:
FieldElemowns the residue and index conversions
from_residue/to_residueandfrom_index/to_index, shared by every
row.BinaryField::to_coordinates/from_coordinatesare removed: use
to_index/from_index, identical words below degree 64 widened to
u128.CoordinateErroris replaced byfgf::RangeError(also
fgf::field::RangeError). Residues and indices are distinct: the index
of one is the presentation's coordinate encoding of one. - Binary embedding evaluation no longer uses precomputed linear columns:
maps evaluate by Horner substitution and restrict through trace-dual
bases, with unchanged results on every pair. - Breaking: the
field::binaryembedding paths are removed without
an alias:fgf::field::binary::embedding,Embedding, and
EmbeddingErrorunder it. Import from the crate root or
field::embeddinginstead; the struct bounds widen fromBinaryField
toField, andEmbeddingkeepsClone,Copy, andDebug. - The dependency lock records published sources for locked MSRV checks;
umbrella-local patch resolution is excluded from the publication lock. - Public documentation leads with
FiniteField, its representations, and
Elem<F>; named prime families appear as specializations. Wiki guides
follow field selection, scalar arithmetic, packing, row operations,
preparation, and deployment, with task-oriented navigation and a custom
prime-base extension example. - Benchmark publication preserves the complete public-operation, field-map,
GF16-presentation, size-sweep, and competitor inventory in task-oriented
pages. Shared geometry is prose; varying counts occupy named columns.
Exact callable paths, setup, resolved backends, and controls are expandable.
SVG overviews complement exact figures. Public v2 and comparison pages are
removed; their samples remain in raw campaign evidence. - Wiki guides use 3.0.1 as the base v3 release and lead from field construction
and arithmetic through presentations, embeddings, and custom fields.
Migration guidance goes directly from 2.x to 3.0.1. - Wiki navigation groups the reading path in the home page and sidebar instead
of per-pageNext:footers. - AVX-512 generic residue kernels under
simd512: nibble-tableu8,
Shoup and Barrettu32, Montgomeryu64, and delayed-reduction prepared
matrices. Capable residue rows reportV4x; short rows retain narrower
or portable routes, and zero/unit coefficient byte behavior is unchanged. - Four-byte generic residue rows vectorize elementwise multiplication on
AVX2-capable x86 hosts. - One-byte generic residue rows at moduli up to 127 vectorize prepared
fixed-coefficient scaling through nibble-table lookups, four-byte rows
through Shoup multiplication, and eight-byte rows at odd moduli through
doubleword Montgomery multiplication; those rows report the vector
backend, and vector-routed operations produce byte-identical output to
the portable path on every input, applying the documented zero/unit
shortcuts before vector dispatch. - Four-byte generic residue rows delay reduction across shared sources in
prepared overwrite/accumulate four-output matrices with enough shared
sources and modulus headroom, as recorded in
the residue benchmark record, with delayed
accumulation falling back to the repeated single-row path when an output
row's coefficients are all zero. - Operation implementations move from
ops.rsinto theops/coefficient,
single-row, scatter, gather, matrix, and packing modules, retaining public
ops::*paths. Byte dispatch moves intokernel/bytes.rs. - Generic residue single-row AVX2 kernels move from
residue/avx2/single.rs
intoresidue/avx2/single/{u8,u32,u64}.rs. - Breaking: Unstable residue kernel entries use
u8,u32, andu64
lane names instead ofbyte,word, anddoubleword;WordParams
becomesU32Params. Migrate directinternalscallers to the explicit
lane-width spellings. - Breaking: Unstable residue routing queries report an actual
Backendthroughsingle_row_backendanddelayed_matrix_backend.
Replace boolean selector calls with comparisons toBackend::Scalar;
useavx2_floor_op_lenfor the AVX2-specific row floor.
Removed
- Breaking:
Tower,TowerSpec, andTowerGeneratorSpecare removed
without an alias. A custom tower becomes anExtensionSpec<2>:impl TowerSpec for SwithLINEAR_COEFFICIENT = Aand
CONSTANT_COEFFICIENT = Bbecomesimpl ExtensionSpec<2> for Swith
the sameBaseandNAME,type Storage = Packed<W>at the field's
width (PackedPadded<u8>below one byte), andconst RELATION: Relation = Relation::from_binary_words::<Base>(&[B, A])— constant coefficient
first, the reverse of the old field order. The row is
FiniteField<2, N, Extension<S, 2>>. - Breaking: custom extension rows carry no generator:
TowerGeneratorSpechas no replacement, andHasGeneratorbelongs to the
shipped instances only. Request a shipped instance for a presentation that
needs a checked generator. - Breaking: custom extension rows have no
constelement surface:
from_raw,from_bytes,to_bytes, the arithmetic methods, and the
component conversions that custom towers exposed asconst fnare gone.
Use theFieldElemmethods and operators,FieldBuffer::decodeand
encode, andExtensionField::from_componentsandto_componentsat
run time;Elem::ZERO,Elem::ONE, andto_rawstayconst. - The wiki migration guide written for the withdrawn v3 release candidate.
Fixed
ops::add_gather_offsetsprevalidated its source spans with unchecked
addition: on 32-bit targets,offset + dst.len()wraps when overflow
checks are disabled, so a release build could admit a source row that
reaches pastregionand panic mid-fold with the destination already
partially mutated. The offset-plus-span check now uses checked arithmetic
on every target, and the direct AVX2 gather prevalidates every offset —
an invalid later offset included — before the first destination write.
Invalid geometry still panics before any mutation; the defect was a
partial write before the panic, never a memory-safety violation.- Default-feature 32-bit x86 builds use the portable backend. X64 capability
tokens and their architecture kernels compile only forx86_64; enabling
simdorinternalson i686 no longer imports unavailable x64 entries.