Equations
- ZMod.toFin q x = x.cast
Instances For
Canonical epimorphism / quotient map: ZMod q[X] ->*+ R q n
Equations
- R.fromPoly = Ideal.Quotient.mk (Ideal.span {f q n})
Instances For
A concrete version that shows that mapping into the ideal back from the
representative produces the representative' NOTE: Lean times out if I use the
abbreviation R.fromPoly
for unclear reasons!
The representative of a : R q n
is the (unique) polynomial p : ZMod q[X]
of degree < 2^n
such that R.fromPoly p = a
.
Equations
- R.representative q n x = R.representative' q n x %ₘ f q n
Instances For
R.representative
is in fact a representative of the equivalence class.
Characterization theorem for any potential representative (in terms of ideals).
For an a : (ZMod q)[X]
, the representative of its equivalence class
is just a + i
for some i ∈ (Ideal.span {f q n})
.
Characterization theorem for any potential representative (in terms of elements).
For an a : (ZMod q)[X]
, the representative of its equivalence class
is a concrete element of the form a + k * (f q n)
for some k ∈ (ZMod q)[X]
.
A theorem similar to R.fromPoly_rep'_eq_element
but uses fromPoly.toFun
to be more deterministic, as the toFun
sometimes sneaks in due to coercions.
The representative of 0 wil live in the ideal of {f q n}. To show that such
an element is a multiple of {f q n}, use Ideal.mem_span_singleton'
The representatiatve of 0 is a multiple of f q n
.
pushing and pulling negation through mod
%ₘ is a subtraction homomorphism (obviously)
Representative of (0 : R) is (0 : Z/qZ[X])
Characterization theorem for the representative.
Taking the representative of the equivalence class of a polynomial a : (ZMod q)[X]
is
the same as taking the remainder of a
modulo f q n
.
Representative is an additive homomorphism
Representative is an multiplicative homomorphism upto modulo
Another characterization of the representative: if the degree of x is less than that of (f q n), then we recover the same polynomial.
Equations
- a.repLength = match (R.representative q n a).degree with | none => 0 | some d => d + 1
Instances For
This function gets the i
th coefficient of the polynomial representative
(with degree < 2^n
) of an element a : R q n
. Note that this is not
invariant under the choice of representative.
Equations
- a.coeff i = (R.representative q n a).coeff i
Instances For
R.monomial i c
is the equivalence class of the monomial c * X^i
in R q n
.
Equations
- R.monomial c i = R.fromPoly ((Polynomial.monomial i) c)
Instances For
Given an equivalence class of polynomials a : R q n
with representative
p = p_0 + p_1 X + ... + p_{2^n - 1} X^{2^n - 1}
, R.slice a startIdx endIdx
yields
the equivalence class of the polynomial
`p_{startIdx}*X^{startIdx} + p_{startIdx + 1} X^{startIdx + 1} + ... + p_{endIdx
- 1} X^{endIdx - 1}` Note that this is not invariant under the choice of representative.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- a.leadingTerm = match (R.representative q n a).degree with | none => 0 | some deg => R.monomial (a.coeff deg) deg
Instances For
Equations
- R.fromTensor coeffs = List.foldl (fun (res : R q n) (x : ℕ × ℤ) => match x with | (i, c) => res + R.monomial (↑c) i) 0 coeffs.enum
Instances For
A definition of fromTensor that operates on Z/qZ[X], to provide a relationship between R and Z/qZ[X] as the polynomial in R is built.
Equations
- R.fromTensor' coeffs = List.foldl (fun (res : Polynomial (ZMod q)) (x : ℕ × ℤ) => match x with | (i, c) => res + (Polynomial.monomial i) ↑c) 0 coeffs.enum
Instances For
fromTensor = R.fromPoly ∘ fromTensor'. This permits reasoning about fromTensor directly on the polynomial ring.
an equivalent implementation of fromTensor
that uses Finsupp
to enable reasoning about values using mathlib's notions of
support, coefficients, etc.
Equations
- R.fromTensorFinsupp q coeffs = { toFinsupp := (List.map Int.cast coeffs).toFinsupp }
Instances For
degree of fromTensorFinsupp is at most the length of the coefficient list.
the ith coefficient of fromTensorFinsupp is a coercion of the 'coeffs' into the right list.
concatenating into a fromTensorFinsupp
is the same as adding a ⟨Finsupp.single⟩.
concatenating into a fromTensorFinsupp
is the same as adding a monomial.
show that fromTensor
is the same as fromPoly ∘ fromTensorFinsupp
.
The coefficient of fromTensor
is the same as the values available in the tensor input.
Converts an element of R
into a tensor (modeled as a List Int
)
with the representatives of the coefficients of the representative.
The length of the list is the degree of the representative + 1.
Equations
- a.toTensor = List.map (fun (i : ℕ) => ZMod.toInt q (a.coeff i)) (List.range a.repLength)
Instances For
The length of the tensor R.toTensor a
equals a.repLength
Equations
- trimTensor tensor = (List.dropWhile (fun (x : ℤ) => decide (x = 0)) tensor.reverse).reverse
Instances For
We define the base type of the representation, which encodes both natural numbers
and elements in the ring R q n
(which in FHE are sometimes called 'polynomials'
in allusion to R.representative
).
In this context, `Tensor is a 1-D tensor, which we model here as a list of integers.
- index: {q n : ℕ} → Ty q n
- integer: {q n : ℕ} → Ty q n
- tensor: {q n : ℕ} → Ty q n
- polynomialLike: {q n : ℕ} → Ty q n
Instances For
Equations
- instDecidableEqTy = decEqTy✝
The operation type of the Poly
dialect. Operations are parametrized by the
two parameters p
and n
that characterize the ring R q n
.
We parametrize the entire type by these since it makes no sense to mix
operations in different rings.
- add: {q n : ℕ} → Op q n
- sub: {q n : ℕ} → Op q n
- mul: {q n : ℕ} → Op q n
- mul_constant: {q n : ℕ} → Op q n
- leading_term: {q n : ℕ} → Op q n
- monomial: {q n : ℕ} → Op q n
- monomial_mul: {q n : ℕ} → Op q n
- from_tensor: {q n : ℕ} → Op q n
- to_tensor: {q n : ℕ} → Op q n
- const: {q n : ℕ} → R q n → Op q n
- const_int: {q n : ℕ} → ℤ → Op q n
- const_idx: {q n : ℕ} → ℕ → Op q n
Instances For
Equations
- Op.add.sig = [Ty.polynomialLike, Ty.polynomialLike]
- Op.sub.sig = [Ty.polynomialLike, Ty.polynomialLike]
- Op.mul.sig = [Ty.polynomialLike, Ty.polynomialLike]
- Op.mul_constant.sig = [Ty.polynomialLike, Ty.integer]
- Op.leading_term.sig = [Ty.polynomialLike]
- Op.monomial.sig = [Ty.integer, Ty.index]
- Op.monomial_mul.sig = [Ty.polynomialLike, Ty.index]
- Op.from_tensor.sig = [Ty.tensor]
- Op.to_tensor.sig = [Ty.polynomialLike]
- (Op.const c).sig = []
- (Op.const_int c).sig = []
- (Op.const_idx i).sig = []
Instances For
Equations
- Op.add.outTy = Ty.polynomialLike
- Op.sub.outTy = Ty.polynomialLike
- Op.mul.outTy = Ty.polynomialLike
- Op.mul_constant.outTy = Ty.polynomialLike
- Op.leading_term.outTy = Ty.polynomialLike
- Op.monomial.outTy = Ty.polynomialLike
- Op.monomial_mul.outTy = Ty.polynomialLike
- Op.from_tensor.outTy = Ty.polynomialLike
- (Op.const c).outTy = Ty.polynomialLike
- Op.to_tensor.outTy = Ty.tensor
- (Op.const_int c).outTy = Ty.integer
- (Op.const_idx i).outTy = Ty.index
Instances For
Equations
- o.signature = { sig := o.sig, regSig := [], outTy := o.outTy, effectKind := EffectKind.pure }
Instances For
Equations
- instDialectSignatureFHE = { signature := Op.signature }
Equations
- One or more equations did not get rendered due to their size.