Evaluate a low-to-high quotient-coefficient list at a quotient point.
The list [c₀, c₁, ...] denotes c₀ + β * (c₁ + β * (...)). This
proof-facing evaluator is separate from executable packed polynomial
evaluation; it is used by quotient-field root-count arguments.
Equations
- Hex.GF2nPoly.evalCoeffList [] x✝ = 0
- Hex.GF2nPoly.evalCoeffList (c :: cs) x✝ = c + x✝ * Hex.GF2nPoly.evalCoeffList cs x✝
Instances For
Evaluating the empty coefficient list yields 0.
Horner recursion equation: evaluating c :: cs at β peels off the head
coefficient c and folds the tail through one more multiplication by β.
Internal root-count helper: synthetic quotient coefficients for the divided
difference of cs at the base point α.
If P is represented by cs, this list represents the quotient
(P(T) + P(α)) / (T + α) in characteristic two. Its length is one less
than the input list, which is the measure used by root-count induction.
Equations
- Hex.GF2nPoly.Internal.dividedDifferenceCoeffs [] x✝ = []
- Hex.GF2nPoly.Internal.dividedDifferenceCoeffs [head] x✝ = []
- Hex.GF2nPoly.Internal.dividedDifferenceCoeffs (head :: c :: cs) x✝ = Hex.GF2nPoly.evalCoeffList (c :: cs) x✝ :: Hex.GF2nPoly.Internal.dividedDifferenceCoeffs (c :: cs) x✝
Instances For
The divided-difference coefficient list of the zero polynomial is empty.
A constant coefficient list has no divided-difference coefficients.
Divided differences peel the tail polynomial evaluated at the base point.
The synthetic divided-difference coefficient list has one fewer entry.
Internal root-count helper: evaluate the divided difference of a
quotient-coefficient polynomial between the base point α and target point
β.
Equations
Instances For
The divided difference of an empty coefficient list is zero.
The divided difference of a nonconstant list satisfies the synthetic recurrence used by the root-count induction.
The quotient-coefficient divided difference satisfies
P(β) + P(α) = (β + α) * DD(P, α, β).
This is the characteristic-two orientation of the usual
P(β) - P(α) = (β - α) * Q(β) identity, and is the API consumed by
the root-count induction.
Iterated Frobenius preserves multiplication in the packed quotient.
Iterated Frobenius preserves addition in the packed quotient.
Zero is fixed by every iterated Frobenius.
Fixed packed quotient elements are closed under addition for a shared Frobenius iterate.
Fixed packed quotient elements are closed under multiplication for a shared Frobenius iterate.
One is fixed by every iterated Frobenius.
Reducing the constant-one monomial gives the quotient one.
If the quotient class of X is fixed by a Frobenius iterate, then every
monomial quotient class is fixed by the same iterate.
If the quotient class of X is fixed by a Frobenius iterate, then any
Boolean coefficient list starting at an arbitrary monomial degree is fixed.
If the quotient class of X is fixed by a Frobenius iterate, then every
Boolean coefficient expression generated from X is fixed.
If the quotient class of X is fixed by a Frobenius iterate, then every
packed quotient-field element is fixed by the same iterate.
The inverse cancels on the left for nonzero quotient elements.
The product of two nonzero packed quotient elements is nonzero.
The highest coefficient in a low-to-high quotient coefficient list is nonzero.
This predicate gives the syntactic degree bound consumed by the root-count
theorem: a list satisfying it represents a polynomial of degree strictly below
the list length, with actual degree exactly length - 1.
Equations
Instances For
Internal root-count helper: roots of a quotient-coefficient polynomial inside the canonical quotient enumeration.
Equations
- Hex.GF2nPoly.Internal.rootsOfCoeffList cs = List.filter (fun (β : Hex.GF2nPoly f hirr) => decide (Hex.GF2nPoly.evalCoeffList cs β = 0)) Hex.GF2nPoly.elements
Instances For
Membership in the computed root list is exactly vanishing of the coefficient-list polynomial at that quotient element.
The quotient-coefficient root list has no duplicate roots.
A nonzero quotient-coefficient polynomial has at most its degree many roots in the duplicate-free packed quotient enumeration.
The coefficient list is low-to-high, and coeffListTopNonzero cs says the
highest listed coefficient is nonzero, so the degree bound is cs.length - 1.
Direct root-count bound for the canonical elements filter form used by
callers.
Multiplication by a nonzero packed quotient element permutes the nonzero
enumeration. The list of nonzero elements multiplied on the left by a is a
permutation of the original nonzero list.
Internal proof-facing linear natural powers in the packed quotient field.
This variant has simple recursion equations; executable exponentiation remains
the Pow instance above.
Equations
Instances For
Base case of proof-facing linear exponentiation: the zeroth power is 1.
Recursion equation for proof-facing linear exponentiation: each successor
power multiplies the previous power by one more factor of a.
The odd-exponent companion of Hex.GF2nPoly.Internal.linearPow_double.
The executable square-and-multiply accumulator computes acc * base ^ k.
This is the invariant that ties the fast Pow instance to the linear reference:
the loop halves the exponent and squares the base, so the accumulator carries
exactly the factors already consumed.
The executable square-and-multiply power agrees with the linear reference.
Iterated Frobenius squaring agrees with linear powering by 2^k.
Coefficients for the characteristic-two polynomial T^(2^k) + T.
For 0 < k, the list is low-to-high with nonzero coefficients exactly at
degrees 1 and 2^k. The k = 0 list intentionally evaluates to zero,
matching T + T; root-count callers use the positive-k theorem below.
Equations
Instances For
At most 2^k packed quotient elements are fixed by the k-fold Frobenius
when 0 < k.
This is the root-count specialization for T^(2^k) + T, stated directly
against the canonical duplicate-free elements enumeration so downstream
Rabin arguments can combine it with elements_card.
If every packed quotient element is fixed by a positive Frobenius iterate, then the iterate is at least the modulus degree.
This is the downstream cardinality form of the fixed-root bound: otherwise
all 2^f.natDegree quotient elements would be roots of T^(2^k) + T, whose
packed root-count bound is only 2^k.
For a positive iterate below the packed quotient degree, not every quotient element can be fixed by Frobenius.
This contrapositive is the form Rabin soundness uses after reducing an exponent modulo the irreducible factor degree.
A positive iterate below the quotient degree has some non-fixed element.
For a positive iterate below the quotient degree, the quotient class of X
cannot be fixed by Frobenius.
If X were fixed, the existing quotient-generation theorem would make every
element fixed, contradicting the fixed-point cardinality bound.
Internal proof-facing product of a list of packed quotient elements (right fold), used with the canonical nonzero quotient enumeration.
Equations
- Hex.GF2nPoly.Internal.listProd xs = List.foldr (fun (x1 x2 : Hex.GF2nPoly f hirr) => x1 * x2) 1 xs
Instances For
The right-folded product of the empty quotient-element list is one.
Mapping a list by left-multiplication factors out as a linear power of the multiplier times the original list product.
Finite-field exponent theorem for the packed quotient: every nonzero
quotient element raised to the number of nonzero representatives is 1.
Every packed quotient element is fixed by the degree-cardinality Frobenius iterate.
Adding any multiple of the modulus degree to a Frobenius iterate does not change the result.
If a quotient element is fixed by the n-fold Frobenius, it is also fixed
by the remainder of n modulo the modulus degree.