mirror of
https://github.com/saymrwulf/pasta-pallas-verified.git
synced 2026-09-04 20:03:39 +00:00
pasta field: foundation + helper + sub/neg proofs against REAL extraction
- extract.sh: scoped Charon/Aeneas extraction of fields::fp (pow_vartime patched upstream to index loops — semantics-preserving, crate tests pass; sqrt/cmp/sum/random/... opaque, documented) - gen/: real transpiled model; subtle/CtOption hand-modeled (Choice := U8, CtOption := value × is_some), all other externals are axioms outside certificate cones - Proofs/PPallas: Lucas/Pratt primality certificate (reused — it was the one genuine piece of the previous attempt) - Proofs/Denote: Montgomery denotation ⟪a⟫ = feVal a · R⁻¹, Canon invariant - Proofs/HelperSpecs: adc/sbb/mac exact ℕ specs (step-registered) - Proofs/SubNegSpec: sub_spec (general two-case identity covering the t<2P reduction shape) and neg_spec, proven, no axioms Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
14e6b74814
commit
75ae21df06
12 changed files with 3174 additions and 0 deletions
1
verification/PallasFp.llbc
Normal file
1
verification/PallasFp.llbc
Normal file
File diff suppressed because one or more lines are too long
143
verification/Proofs/Denote.lean
Normal file
143
verification/Proofs/Denote.lean
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/- ──────────────────────────────────────────────────────────────────────────────
|
||||
Proofs/Denote.lean — the SEMANTIC FOUNDATION: from machine limbs to 𝔽_p
|
||||
(Pallas base field), MONTGOMERY FORM.
|
||||
|
||||
WHAT THIS FILE PROVIDES
|
||||
* `P`, `Fp := ZMod P` — the Pallas modulus (primality from Proofs/PPallas.lean)
|
||||
* `Fe := fields.fp.Fp` — the transpiled element type: 4 little-endian u64
|
||||
limbs (`Array Std.U64 4`)
|
||||
* `limbsVal`/`feVal` — the EXACT natural-number value Σ lᵢ·2^(64i)
|
||||
* `R`, `Rinv` — the Montgomery factor 2²⁵⁶ and its inverse in 𝔽_p
|
||||
* `denote` (⟪·⟫) — THE DENOTATION: ⟪a⟫ = feVal a · R⁻¹ ∈ 𝔽_p.
|
||||
pasta_curves stores a·R mod p; dividing by R in the denotation makes
|
||||
every proof statement live in plain 𝔽_p (⟪mul a b⟫ = ⟪a⟫·⟪b⟫ with NO
|
||||
R-factor bookkeeping at the spec level).
|
||||
* `Canon` — the representation invariant: feVal a < P. Unlike dalek's
|
||||
radix-51 code (loose 2⁵²/2⁵⁴ bounds), pasta_curves keeps every element
|
||||
STRICTLY REDUCED: each op ends with a conditional subtraction of p.
|
||||
* `Fe.exists_limbs` — the destructuring device every proof starts with.
|
||||
|
||||
RUST ANALOG: src/fields/fp.rs — `pub struct Fp(pub(crate) [u64; 4])`,
|
||||
invariant documented at the type: "little-endian bit order; values are
|
||||
always in Montgomery form aR mod p, with the reduced representative".
|
||||
|
||||
Imports: gen/PallasFp (the transpiled code), Proofs/PPallas (primality).
|
||||
Imported by: every other proof file.
|
||||
────────────────────────────────────────────────────────────────────────────── -/
|
||||
import PallasFp.Funs
|
||||
import Proofs.PPallas
|
||||
open Aeneas Aeneas.Std Result
|
||||
open pasta_curves
|
||||
|
||||
namespace PastaProofs
|
||||
|
||||
/-- The Pallas base-field modulus
|
||||
p = 2²⁵⁴ + 45560315531419706090280762371685220353. -/
|
||||
def P : ℕ := 28948022309329048855892746252171976963363056481941560715954676764349967630337
|
||||
|
||||
theorem P_prime : Nat.Prime P := pallas_prime
|
||||
|
||||
instance : Fact (Nat.Prime P) := ⟨P_prime⟩
|
||||
|
||||
/-- 𝔽_p as mathlib's `ZMod P` — a `Field` because `P` is prime. -/
|
||||
abbrev Fp := ZMod P
|
||||
|
||||
/-- The transpiled element type: 4 little-endian u64 limbs. -/
|
||||
abbrev Fe := fields.fp.Fp
|
||||
|
||||
/-- Exact ℕ value of 4 little-endian u64 limbs. -/
|
||||
def limbsVal (a0 a1 a2 a3 : U64) : ℕ :=
|
||||
a0.val + 2^64 * a1.val + 2^128 * a2.val + 2^192 * a3.val
|
||||
|
||||
/-- Exact ℕ value of an `Fe`. -/
|
||||
def feVal (a : Fe) : ℕ :=
|
||||
match (↑a : List U64) with
|
||||
| [a0, a1, a2, a3] => limbsVal a0 a1 a2 a3
|
||||
| _ => 0
|
||||
|
||||
/-- Every `Fe` IS four named u64 limbs. -/
|
||||
theorem Fe.exists_limbs (a : Fe) :
|
||||
∃ a0 a1 a2 a3 : U64, (↑a : List U64) = [a0, a1, a2, a3] := by
|
||||
obtain ⟨l, hl⟩ := a
|
||||
match l, hl with
|
||||
| [a0, a1, a2, a3], _ => exact ⟨a0, a1, a2, a3, rfl⟩
|
||||
|
||||
/-- Once limbs are named, `feVal` unfolds to the polynomial. -/
|
||||
@[simp]
|
||||
theorem feVal_eq (a : Fe) (a0 a1 a2 a3 : U64)
|
||||
(h : (↑a : List U64) = [a0, a1, a2, a3]) :
|
||||
feVal a = limbsVal a0 a1 a2 a3 := by
|
||||
unfold feVal; rw [h]
|
||||
|
||||
/-- feVal of a literal `Array.make` — the form the generated code produces
|
||||
(the length side condition `h` is quantified so simp matches any proof). -/
|
||||
@[simp]
|
||||
theorem feVal_make (a0 a1 a2 a3 : U64) (h) :
|
||||
feVal (Array.make 4#usize [a0, a1, a2, a3] h) = limbsVal a0 a1 a2 a3 := rfl
|
||||
|
||||
/-- Any `Fe` value is < 2²⁵⁶ (four u64 limbs). -/
|
||||
theorem feVal_lt (a : Fe) : feVal a < 2^256 := by
|
||||
obtain ⟨a0, a1, a2, a3, hl⟩ := Fe.exists_limbs a
|
||||
rw [feVal_eq a a0 a1 a2 a3 hl]
|
||||
unfold limbsVal
|
||||
scalar_tac
|
||||
|
||||
/-- The representation invariant: strictly reduced (value below the modulus).
|
||||
Every constructor/operation of the crate maintains this. -/
|
||||
def Canon (a : Fe) : Prop := feVal a < P
|
||||
|
||||
/-- The Montgomery factor. -/
|
||||
def R : ℕ := 2^256
|
||||
|
||||
/-- P is odd (in particular ≠ 2), so 2 — hence R = 2²⁵⁶ — is a unit mod P. -/
|
||||
theorem two_ne_zero_fp : (2 : Fp) ≠ 0 := by
|
||||
intro h
|
||||
have h2 : ((2 : ℕ) : Fp).val = 2 :=
|
||||
ZMod.val_cast_of_lt (by norm_num [P])
|
||||
rw [show ((2:ℕ):Fp) = (2:Fp) by push_cast; ring, h, ZMod.val_zero] at h2
|
||||
norm_num at h2
|
||||
|
||||
theorem R_ne_zero : (R : Fp) ≠ 0 := by
|
||||
have hR : (R : Fp) = (2 : Fp)^256 := by unfold R; push_cast; ring
|
||||
rw [hR]
|
||||
exact pow_ne_zero 256 two_ne_zero_fp
|
||||
|
||||
/-- R⁻¹ in 𝔽_p (field inverse; noncomputable, spec-level only). -/
|
||||
noncomputable def Rinv : Fp := (R : Fp)⁻¹
|
||||
|
||||
theorem R_mul_Rinv : (R : Fp) * Rinv = 1 :=
|
||||
mul_inv_cancel₀ R_ne_zero
|
||||
|
||||
theorem Rinv_mul_R : Rinv * (R : Fp) = 1 := by
|
||||
rw [mul_comm]; exact R_mul_Rinv
|
||||
|
||||
theorem Rinv_ne_zero : Rinv ≠ 0 := by
|
||||
intro h
|
||||
have := R_mul_Rinv
|
||||
rw [h, mul_zero] at this
|
||||
exact one_ne_zero this.symm
|
||||
|
||||
/-- THE DENOTATION: machine limbs ↦ 𝔽_p, absorbing the Montgomery factor. -/
|
||||
noncomputable def denote (a : Fe) : Fp := (feVal a : Fp) * Rinv
|
||||
|
||||
notation "⟪" a "⟫" => denote a
|
||||
|
||||
/-- Two canonical representatives with equal denotation are limb-identical
|
||||
in value: ⟪·⟫ is injective on `Canon`. -/
|
||||
theorem denote_inj (a b : Fe) (ha : Canon a) (hb : Canon b)
|
||||
(h : ⟪a⟫ = ⟪b⟫) : feVal a = feVal b := by
|
||||
unfold denote at h
|
||||
have h' : (feVal a : Fp) = (feVal b : Fp) :=
|
||||
mul_right_cancel₀ Rinv_ne_zero h
|
||||
have := (ZMod.natCast_eq_natCast_iff' (feVal a) (feVal b) P).mp h'
|
||||
unfold Canon at ha hb
|
||||
rwa [Nat.mod_eq_of_lt ha, Nat.mod_eq_of_lt hb] at this
|
||||
|
||||
/-- Congruence mod P transfers to equal denotations. -/
|
||||
theorem denote_eq_of_feVal_congr (a b : Fe)
|
||||
(h : feVal a % P = feVal b % P) : ⟪a⟫ = ⟪b⟫ := by
|
||||
unfold denote
|
||||
congr 1
|
||||
exact (ZMod.natCast_eq_natCast_iff' _ _ _).mpr h
|
||||
|
||||
end PastaProofs
|
||||
104
verification/Proofs/HelperSpecs.lean
Normal file
104
verification/Proofs/HelperSpecs.lean
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/- ──────────────────────────────────────────────────────────────────────────────
|
||||
Proofs/HelperSpecs.lean — exact specs for the u64 carry primitives
|
||||
adc / sbb / mac (src/arithmetic/fields.rs), TRANSPILED TRANSPARENTLY.
|
||||
|
||||
These three ~5-line const fns are the atoms of every Pallas field op:
|
||||
* adc a b c = (lo, hi) with lo + 2⁶⁴·hi = a + b + c (exact ℕ)
|
||||
* mac a b c d = (lo, hi) with lo + 2⁶⁴·hi = a + b·c + d (exact ℕ)
|
||||
* sbb a b bor = (d, bor') with d + b + ⌊bor/2⁶³⌋ = a + 2⁶⁴·β'
|
||||
where bor' ∈ {0, 2⁶⁴−1} and β' = (bor' ≠ 0) (exact ℕ)
|
||||
(sbb consumes only the TOP BIT of the incoming borrow word and produces
|
||||
an all-ones/all-zeros borrow word — exactly the Rust convention:
|
||||
`let (_, borrow) = sbb(..)` then `mask & borrow` and `borrow >> 63`.)
|
||||
|
||||
The u128 intermediates cannot overflow: a + b + c ≤ 3·(2⁶⁴−1) < 2¹²⁸ and
|
||||
a + b·c + d ≤ (2⁶⁴−1) + (2⁶⁴−1)² + (2⁶⁴−1) < 2¹²⁸ — proved, not assumed.
|
||||
|
||||
Every lemma is `@[step]`-registered so the op proofs consume adc/sbb/mac
|
||||
calls in one `let*` step each.
|
||||
────────────────────────────────────────────────────────────────────────────── -/
|
||||
import Proofs.Denote
|
||||
open Aeneas Aeneas.Std Result
|
||||
open pasta_curves
|
||||
|
||||
set_option maxHeartbeats 4000000
|
||||
|
||||
namespace PastaProofs
|
||||
|
||||
open Aeneas.Std.WP
|
||||
|
||||
/-- Generic step rule for `lift` of a pure computation: the result IS the
|
||||
expression (the @[simp] val-lemmas of the Aeneas library then evaluate it). -/
|
||||
@[step]
|
||||
theorem lift_spec {α : Type u} (x : α) : lift x ⦃ y => y = x ⦄ := by
|
||||
simp [lift]
|
||||
|
||||
/-- `x ||| y = 0` forces both to be zero (bitwise). -/
|
||||
theorem nat_or_eq_zero {x y : ℕ} (h : x ||| y = 0) : x = 0 ∧ y = 0 := by
|
||||
constructor <;> {
|
||||
apply Nat.eq_of_testBit_eq
|
||||
intro i
|
||||
have := congrArg (fun n => n.testBit i) h
|
||||
simp [Nat.testBit_or] at this
|
||||
simp [this]
|
||||
}
|
||||
|
||||
/-- Discharge tactic shared by the steps (same as the ed25519 repos). -/
|
||||
macro "dis" : tactic =>
|
||||
`(tactic| (subst_vars; try simp [Array.set_val_eq, *]; try scalar_tac))
|
||||
|
||||
/-- `adc a b carry = (lo, hi)` with `lo + 2⁶⁴·hi = a + b + carry` (exact). -/
|
||||
@[step]
|
||||
theorem adc_spec (a b c : U64) :
|
||||
arithmetic.fields.adc a b c
|
||||
⦃ p => p.1.val + 2^64 * p.2.val = a.val + b.val + c.val ∧
|
||||
p.2.val ≤ 2 ⦄ := by
|
||||
unfold arithmetic.fields.adc
|
||||
have ha : a.val < 2^64 := by scalar_tac
|
||||
have hb : b.val < 2^64 := by scalar_tac
|
||||
have hc : c.val < 2^64 := by scalar_tac
|
||||
step* by dis
|
||||
-- lo = (a+b+c) mod 2⁶⁴, hi = (a+b+c) / 2⁶⁴: exact split of a 128-bit sum
|
||||
simp_all [UScalar.cast_val_eq, Nat.shiftRight_eq_div_pow]
|
||||
omega
|
||||
|
||||
/-- `mac a b c carry = (lo, hi)` with `lo + 2⁶⁴·hi = a + b·c + carry` (exact). -/
|
||||
@[step]
|
||||
theorem mac_spec (a b c d : U64) :
|
||||
arithmetic.fields.mac a b c d
|
||||
⦃ p => p.1.val + 2^64 * p.2.val = a.val + b.val * c.val + d.val ⦄ := by
|
||||
unfold arithmetic.fields.mac
|
||||
have ha : a.val < 2^64 := by scalar_tac
|
||||
have hb : b.val < 2^64 := by scalar_tac
|
||||
have hc : c.val < 2^64 := by scalar_tac
|
||||
have hd : d.val < 2^64 := by scalar_tac
|
||||
have hbc : b.val * c.val ≤ (2^64-1) * (2^64-1) :=
|
||||
Nat.mul_le_mul (by omega) (by omega)
|
||||
step* by dis
|
||||
simp_all [UScalar.cast_val_eq, Nat.shiftRight_eq_div_pow]
|
||||
omega
|
||||
|
||||
/-- `sbb a b borrow = (d, borrow')`:
|
||||
* only the top bit β = ⌊borrow/2⁶³⌋ of the incoming borrow is consumed;
|
||||
* `d + b + β = a + 2⁶⁴·β'` exactly, where β' ∈ {0,1} flags the borrow-out;
|
||||
* the outgoing borrow WORD is 0 or all-ones (β' spread over 64 bits) —
|
||||
the shape `mask & borrow` arithmetic downstream depends on. -/
|
||||
@[step]
|
||||
theorem sbb_spec (a b bor : U64) :
|
||||
arithmetic.fields.sbb a b bor
|
||||
⦃ p => (p.2.val = 0 ∧ p.1.val + b.val + bor.val / 2^63 = a.val) ∨
|
||||
(p.2.val = 2^64 - 1 ∧
|
||||
p.1.val + b.val + bor.val / 2^63 = a.val + 2^64) ⦄ := by
|
||||
unfold arithmetic.fields.sbb
|
||||
have ha : a.val < 2^64 := by scalar_tac
|
||||
have hb : b.val < 2^64 := by scalar_tac
|
||||
have hbor : bor.val < 2^64 := by scalar_tac
|
||||
have hβ : bor.val / 2^63 ≤ 1 := by omega
|
||||
step* by dis
|
||||
-- the wrapping u128 subtraction: ret = (a − b − β) mod 2¹²⁸;
|
||||
-- d = ret mod 2⁶⁴, borrow' = (ret >>> 64) mod 2⁶⁴
|
||||
simp_all [UScalar.cast_val_eq, Nat.shiftRight_eq_div_pow,
|
||||
UScalar.size, U128.size, U64.size, U128.numBits_def, U64.numBits_def]
|
||||
omega
|
||||
|
||||
end PastaProofs
|
||||
415
verification/Proofs/PPallas.lean
Normal file
415
verification/Proofs/PPallas.lean
Normal file
|
|
@ -0,0 +1,415 @@
|
|||
/-
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
Proofs/PPallas.lean — primality of the Pallas (Pasta) base-field modulus
|
||||
p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001
|
||||
═══════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
WHAT THIS FILE PROVES
|
||||
`pallas_prime : Nat.Prime P` where P is the 255-bit modulus of the Pallas
|
||||
curve base field F_p. Axiom-free Lucas/Pratt certificate.
|
||||
|
||||
CERTIFICATE TREE (p−1 factorization, leaves first)
|
||||
p − 1 = 2³² · 3 · 463 · f1 · f2
|
||||
where f1 = 539204044132271846773 (69 bits)
|
||||
f2 = 8999194758858563409123804352480028797519453 (143 bits)
|
||||
|
||||
f1 − 1 = 2² · 3⁵ · 89 · 14923 · 417677162933
|
||||
f2 − 1 = 2² · 3⁴ · 11 · 2531 · 115603 · 1197907 · 22160661629 · 325086459374267
|
||||
|
||||
Sub-leaves (all norm_num-certifiable):
|
||||
417677162933 − 1 = 2² · 59 · 1973 · 897019
|
||||
22160661629 − 1 = 2² · 7 · 19 · 41655379
|
||||
14923 − 1 = 2 · 3² · 829
|
||||
115603 − 1 = 2 · 3 · 19267
|
||||
1197907 − 1 = 2 · 3 · 53 · 3767
|
||||
325086459374267 − 1 = 2 · 509 · 413527 · 772231
|
||||
463 − 1 = 2 · 3 · 7 · 11
|
||||
2531 − 1 = 2 · 5 · 11 · 23
|
||||
-/
|
||||
import Mathlib.NumberTheory.LucasPrimality
|
||||
import Mathlib.Data.ZMod.Basic
|
||||
import Mathlib.Tactic.NormNum.Prime
|
||||
|
||||
set_option maxHeartbeats 8000000
|
||||
set_option maxRecDepth 8000
|
||||
|
||||
namespace PPallas
|
||||
|
||||
-- ═════════════════════════════════════════════════════════════════════════════
|
||||
-- Kernel-checkable modular exponentiation
|
||||
-- ═════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
/-- Fuel-based binary modular exponentiation, kernel-reducible (GMP-fast `decide`).
|
||||
|
||||
MATH (for sufficient fuel; made precise by `powModAux_eq`):
|
||||
`powModAux fuel a k n = a^k mod n`.
|
||||
Algorithm: square-and-multiply on binary digits of k. -/
|
||||
def powModAux : Nat → Nat → Nat → Nat → Nat
|
||||
| 0, _, _, n => 1 % n
|
||||
| fuel + 1, a, k, n =>
|
||||
if k = 0 then 1 % n
|
||||
else if k % 2 = 1 then powModAux fuel (a * a % n) (k / 2) n * a % n
|
||||
else powModAux fuel (a * a % n) (k / 2) n
|
||||
|
||||
/- Correctness of powModAux. k < 2^fuel ⇒ powModAux fuel a k n = a^k % n -/
|
||||
theorem powModAux_eq : ∀ (fuel a k n : ℕ), k < 2 ^ fuel → powModAux fuel a k n = a ^ k % n := by
|
||||
intro fuel
|
||||
induction fuel with
|
||||
| zero =>
|
||||
intro a k n hk
|
||||
rw [pow_zero] at hk
|
||||
have hk0 : k = 0 := by omega
|
||||
subst hk0
|
||||
simp [powModAux]
|
||||
| succ f ih =>
|
||||
intro a k n hk
|
||||
by_cases hk0 : k = 0
|
||||
· subst hk0; simp [powModAux]
|
||||
· have hk2 : k / 2 < 2 ^ f := by
|
||||
rw [pow_succ] at hk
|
||||
omega
|
||||
have hrec := ih (a * a % n) (k / 2) n hk2
|
||||
have haa : a * a = a ^ 2 := (pow_two a).symm
|
||||
simp only [powModAux, if_neg hk0]
|
||||
by_cases hodd : k % 2 = 1
|
||||
· rw [if_pos hodd, hrec, ← Nat.pow_mod, Nat.mod_mul_mod, haa, ← pow_mul, ← pow_succ,
|
||||
show 2 * (k / 2) + 1 = k by omega]
|
||||
· rw [if_neg hodd, hrec, ← Nat.pow_mod, haa, ← pow_mul,
|
||||
show 2 * (k / 2) = k by omega]
|
||||
|
||||
/-- powMod a k n = a^k % n for all k < 2^256. Fuel fixed at 256 — enough for
|
||||
all exponents in the certificate (n ≤ p < 2^255). -/
|
||||
def powMod (a k n : ℕ) : ℕ := powModAux 256 a k n
|
||||
|
||||
theorem cast_pow_eq (a k n : ℕ) (hk : k < 2 ^ 256) :
|
||||
(a : ZMod n) ^ k = ((powMod a k n : ℕ) : ZMod n) := by
|
||||
rw [powMod, powModAux_eq 256 a k n hk, ZMod.natCast_mod, Nat.cast_pow]
|
||||
|
||||
theorem pow_eq_one_of_powMod (a k n : ℕ) (hk : k < 2 ^ 256) (h : powMod a k n = 1) :
|
||||
(a : ZMod n) ^ k = 1 := by
|
||||
rw [cast_pow_eq a k n hk, h, Nat.cast_one]
|
||||
|
||||
theorem pow_ne_one_of_powMod (a k n : ℕ) (hk : k < 2 ^ 256) (hn : 1 < n)
|
||||
(h1 : powMod a k n ≠ 1) (h2 : powMod a k n < n) :
|
||||
(a : ZMod n) ^ k ≠ 1 := by
|
||||
rw [cast_pow_eq a k n hk]
|
||||
intro hcon
|
||||
rw [show (1 : ZMod n) = ((1 : ℕ) : ZMod n) by rw [Nat.cast_one],
|
||||
ZMod.natCast_eq_natCast_iff'] at hcon
|
||||
rw [Nat.mod_eq_of_lt h2, Nat.mod_eq_of_lt hn] at hcon
|
||||
exact h1 hcon
|
||||
|
||||
-- ═════════════════════════════════════════════════════════════════════════════
|
||||
-- The certificate chain (leaves first, building up to the root)
|
||||
-- ═════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
/-- Leaf: 14923 is prime. Witness g = 2. 14923−1 = 2 · 3² · 829 -/
|
||||
theorem prime_14923 : Nat.Prime 14923 := by
|
||||
refine lucas_primality 14923 ((2 : ℕ) : ZMod 14923) ?_ ?_
|
||||
· exact pow_eq_one_of_powMod 2 (14923 - 1) 14923 (by decide) (by decide)
|
||||
· intro q hq hqd
|
||||
have hfac : (14923 : ℕ) - 1 = 2 * (3 ^ 2 * (829)) := by decide
|
||||
rw [hfac] at hqd
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 2 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((14923 - 1) / 2) 14923 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 3 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp (hq.dvd_of_dvd_pow h)
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((14923 - 1) / 3) 14923 (by decide) (by decide) (by decide) (by decide)
|
||||
have he : q = 829 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp hqd
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((14923 - 1) / 829) 14923 (by decide) (by decide) (by decide) (by decide)
|
||||
|
||||
/-- Leaf: 115603 is prime. Witness g = 2. 115603−1 = 2 · 3 · 19267 -/
|
||||
theorem prime_115603 : Nat.Prime 115603 := by
|
||||
refine lucas_primality 115603 ((2 : ℕ) : ZMod 115603) ?_ ?_
|
||||
· exact pow_eq_one_of_powMod 2 (115603 - 1) 115603 (by decide) (by decide)
|
||||
· intro q hq hqd
|
||||
have hfac : (115603 : ℕ) - 1 = 2 * (3 * (19267)) := by decide
|
||||
rw [hfac] at hqd
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 2 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((115603 - 1) / 2) 115603 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 3 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((115603 - 1) / 3) 115603 (by decide) (by decide) (by decide) (by decide)
|
||||
have he : q = 19267 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp hqd
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((115603 - 1) / 19267) 115603 (by decide) (by decide) (by decide) (by decide)
|
||||
|
||||
/-- Leaf: 1197907 is prime. Witness g = 3. 1197907−1 = 2 · 3 · 53 · 3767 -/
|
||||
theorem prime_1197907 : Nat.Prime 1197907 := by
|
||||
refine lucas_primality 1197907 ((3 : ℕ) : ZMod 1197907) ?_ ?_
|
||||
· exact pow_eq_one_of_powMod 3 (1197907 - 1) 1197907 (by decide) (by decide)
|
||||
· intro q hq hqd
|
||||
have hfac : (1197907 : ℕ) - 1 = 2 * (3 * (53 * (3767))) := by decide
|
||||
rw [hfac] at hqd
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 2 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 3 ((1197907 - 1) / 2) 1197907 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 3 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 3 ((1197907 - 1) / 3) 1197907 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 53 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 3 ((1197907 - 1) / 53) 1197907 (by decide) (by decide) (by decide) (by decide)
|
||||
have he : q = 3767 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp hqd
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 3 ((1197907 - 1) / 3767) 1197907 (by decide) (by decide) (by decide) (by decide)
|
||||
|
||||
/-- Leaf: 463 is prime. Witness g = 3. 463−1 = 2 · 3 · 7 · 11 -/
|
||||
theorem prime_463 : Nat.Prime 463 := by
|
||||
refine lucas_primality 463 ((3 : ℕ) : ZMod 463) ?_ ?_
|
||||
· exact pow_eq_one_of_powMod 3 (463 - 1) 463 (by decide) (by decide)
|
||||
· intro q hq hqd
|
||||
have hfac : (463 : ℕ) - 1 = 2 * (3 * (7 * (11))) := by decide
|
||||
rw [hfac] at hqd
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 2 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 3 ((463 - 1) / 2) 463 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 3 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 3 ((463 - 1) / 3) 463 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 7 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 3 ((463 - 1) / 7) 463 (by decide) (by decide) (by decide) (by decide)
|
||||
have he : q = 11 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp hqd
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 3 ((463 - 1) / 11) 463 (by decide) (by decide) (by decide) (by decide)
|
||||
|
||||
/-- Leaf: 2531 is prime. Witness g = 2. 2531−1 = 2 · 5 · 11 · 23 -/
|
||||
theorem prime_2531 : Nat.Prime 2531 := by
|
||||
refine lucas_primality 2531 ((2 : ℕ) : ZMod 2531) ?_ ?_
|
||||
· exact pow_eq_one_of_powMod 2 (2531 - 1) 2531 (by decide) (by decide)
|
||||
· intro q hq hqd
|
||||
have hfac : (2531 : ℕ) - 1 = 2 * (5 * (11 * (23))) := by decide
|
||||
rw [hfac] at hqd
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 2 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((2531 - 1) / 2) 2531 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 5 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((2531 - 1) / 5) 2531 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 11 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((2531 - 1) / 11) 2531 (by decide) (by decide) (by decide) (by decide)
|
||||
have he : q = 23 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp hqd
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((2531 - 1) / 23) 2531 (by decide) (by decide) (by decide) (by decide)
|
||||
|
||||
/-- Node: 417677162933 is prime. Witness g = 2.
|
||||
417677162933−1 = 2² · 59 · 1973 · 897019 -/
|
||||
theorem prime_417677162933 : Nat.Prime 417677162933 := by
|
||||
refine lucas_primality 417677162933 ((2 : ℕ) : ZMod 417677162933) ?_ ?_
|
||||
· exact pow_eq_one_of_powMod 2 (417677162933 - 1) 417677162933 (by decide) (by decide)
|
||||
· intro q hq hqd
|
||||
have hfac : (417677162933 : ℕ) - 1 = 2 ^ 2 * (59 * (1973 * (897019))) := by decide
|
||||
rw [hfac] at hqd
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 2 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp (hq.dvd_of_dvd_pow h)
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((417677162933 - 1) / 2) 417677162933 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 59 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((417677162933 - 1) / 59) 417677162933 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 1973 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((417677162933 - 1) / 1973) 417677162933 (by decide) (by decide) (by decide) (by decide)
|
||||
have he : q = 897019 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp hqd
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((417677162933 - 1) / 897019) 417677162933 (by decide) (by decide) (by decide) (by decide)
|
||||
|
||||
/-- Node: 22160661629 is prime. Witness g = 3.
|
||||
22160661629−1 = 2² · 7 · 19 · 41655379 -/
|
||||
theorem prime_22160661629 : Nat.Prime 22160661629 := by
|
||||
refine lucas_primality 22160661629 ((3 : ℕ) : ZMod 22160661629) ?_ ?_
|
||||
· exact pow_eq_one_of_powMod 3 (22160661629 - 1) 22160661629 (by decide) (by decide)
|
||||
· intro q hq hqd
|
||||
have hfac : (22160661629 : ℕ) - 1 = 2 ^ 2 * (7 * (19 * (41655379))) := by decide
|
||||
rw [hfac] at hqd
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 2 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp (hq.dvd_of_dvd_pow h)
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 3 ((22160661629 - 1) / 2) 22160661629 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 7 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 3 ((22160661629 - 1) / 7) 22160661629 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 19 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 3 ((22160661629 - 1) / 19) 22160661629 (by decide) (by decide) (by decide) (by decide)
|
||||
have he : q = 41655379 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp hqd
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 3 ((22160661629 - 1) / 41655379) 22160661629 (by decide) (by decide) (by decide) (by decide)
|
||||
|
||||
/-- Node: 325086459374267 is prime. Witness g = 2.
|
||||
325086459374267−1 = 2 · 509 · 413527 · 772231 -/
|
||||
theorem prime_325086459374267 : Nat.Prime 325086459374267 := by
|
||||
refine lucas_primality 325086459374267 ((2 : ℕ) : ZMod 325086459374267) ?_ ?_
|
||||
· exact pow_eq_one_of_powMod 2 (325086459374267 - 1) 325086459374267 (by decide) (by decide)
|
||||
· intro q hq hqd
|
||||
have hfac : (325086459374267 : ℕ) - 1 = 2 * (509 * (413527 * (772231))) := by decide
|
||||
rw [hfac] at hqd
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 2 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((325086459374267 - 1) / 2) 325086459374267 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 509 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((325086459374267 - 1) / 509) 325086459374267 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 413527 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((325086459374267 - 1) / 413527) 325086459374267 (by decide) (by decide) (by decide) (by decide)
|
||||
have he : q = 772231 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp hqd
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((325086459374267 - 1) / 772231) 325086459374267 (by decide) (by decide) (by decide) (by decide)
|
||||
|
||||
/-- Node f1 = 539204044132271846773 (69 bits). Witness g = 5.
|
||||
f1−1 = 2² · 3⁵ · 89 · 14923 · 417677162933
|
||||
Recursive: 14923 and 417677162933 certified above. -/
|
||||
theorem prime_539204044132271846773 : Nat.Prime 539204044132271846773 := by
|
||||
refine lucas_primality 539204044132271846773 ((5 : ℕ) : ZMod 539204044132271846773) ?_ ?_
|
||||
· exact pow_eq_one_of_powMod 5 (539204044132271846773 - 1) 539204044132271846773 (by decide) (by decide)
|
||||
· intro q hq hqd
|
||||
have hfac : (539204044132271846773 : ℕ) - 1 = 2 ^ 2 * (3 ^ 5 * (89 * (14923 * (417677162933)))) := by decide
|
||||
rw [hfac] at hqd
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 2 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp (hq.dvd_of_dvd_pow h)
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 5 ((539204044132271846773 - 1) / 2) 539204044132271846773 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 3 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp (hq.dvd_of_dvd_pow h)
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 5 ((539204044132271846773 - 1) / 3) 539204044132271846773 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 89 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 5 ((539204044132271846773 - 1) / 89) 539204044132271846773 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 14923 := (Nat.prime_dvd_prime_iff_eq hq prime_14923).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 5 ((539204044132271846773 - 1) / 14923) 539204044132271846773 (by decide) (by decide) (by decide) (by decide)
|
||||
have he : q = 417677162933 := (Nat.prime_dvd_prime_iff_eq hq prime_417677162933).mp hqd
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 5 ((539204044132271846773 - 1) / 417677162933) 539204044132271846773 (by decide) (by decide) (by decide) (by decide)
|
||||
|
||||
/-- Node f2 = 8999194758858563409123804352480028797519453 (143 bits). Witness g = 2.
|
||||
f2−1 = 2² · 3⁴ · 11 · 2531 · 115603 · 1197907 · 22160661629 · 325086459374267
|
||||
Recursive: large factors certified above. -/
|
||||
theorem prime_8999194758858563409123804352480028797519453 : Nat.Prime 8999194758858563409123804352480028797519453 := by
|
||||
refine lucas_primality 8999194758858563409123804352480028797519453 ((2 : ℕ) : ZMod 8999194758858563409123804352480028797519453) ?_ ?_
|
||||
· exact pow_eq_one_of_powMod 2 (8999194758858563409123804352480028797519453 - 1) 8999194758858563409123804352480028797519453 (by decide) (by decide)
|
||||
· intro q hq hqd
|
||||
have hfac : (8999194758858563409123804352480028797519453 : ℕ) - 1 =
|
||||
2 ^ 2 * (3 ^ 4 * (11 * (2531 * (115603 * (1197907 * (22160661629 * (325086459374267))))))) := by decide
|
||||
rw [hfac] at hqd
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 2 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp (hq.dvd_of_dvd_pow h)
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((8999194758858563409123804352480028797519453 - 1) / 2) 8999194758858563409123804352480028797519453 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 3 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp (hq.dvd_of_dvd_pow h)
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((8999194758858563409123804352480028797519453 - 1) / 3) 8999194758858563409123804352480028797519453 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 11 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((8999194758858563409123804352480028797519453 - 1) / 11) 8999194758858563409123804352480028797519453 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 2531 := (Nat.prime_dvd_prime_iff_eq hq prime_2531).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((8999194758858563409123804352480028797519453 - 1) / 2531) 8999194758858563409123804352480028797519453 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 115603 := (Nat.prime_dvd_prime_iff_eq hq prime_115603).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((8999194758858563409123804352480028797519453 - 1) / 115603) 8999194758858563409123804352480028797519453 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 1197907 := (Nat.prime_dvd_prime_iff_eq hq prime_1197907).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((8999194758858563409123804352480028797519453 - 1) / 1197907) 8999194758858563409123804352480028797519453 (by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 22160661629 := (Nat.prime_dvd_prime_iff_eq hq prime_22160661629).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((8999194758858563409123804352480028797519453 - 1) / 22160661629) 8999194758858563409123804352480028797519453 (by decide) (by decide) (by decide) (by decide)
|
||||
have he : q = 325086459374267 := (Nat.prime_dvd_prime_iff_eq hq prime_325086459374267).mp hqd
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 2 ((8999194758858563409123804352480028797519453 - 1) / 325086459374267) 8999194758858563409123804352480028797519453 (by decide) (by decide) (by decide) (by decide)
|
||||
|
||||
/-- ROOT: Pallas base-field modulus P is prime. Witness g = 5.
|
||||
P−1 = 2³² · 3 · 463 · f1 · f2
|
||||
with f1, f2 certified recursively above. -/
|
||||
theorem prime_Pallas : Nat.Prime 28948022309329048855892746252171976963363056481941560715954676764349967630337 := by
|
||||
refine lucas_primality 28948022309329048855892746252171976963363056481941560715954676764349967630337
|
||||
((5 : ℕ) : ZMod 28948022309329048855892746252171976963363056481941560715954676764349967630337) ?_ ?_
|
||||
· exact pow_eq_one_of_powMod 5
|
||||
(28948022309329048855892746252171976963363056481941560715954676764349967630337 - 1)
|
||||
28948022309329048855892746252171976963363056481941560715954676764349967630337
|
||||
(by decide) (by decide)
|
||||
· intro q hq hqd
|
||||
have hfac : (28948022309329048855892746252171976963363056481941560715954676764349967630337 : ℕ) - 1 =
|
||||
2 ^ 32 * (3 * (463 * (539204044132271846773 * (8999194758858563409123804352480028797519453)))) := by decide
|
||||
rw [hfac] at hqd
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 2 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp (hq.dvd_of_dvd_pow h)
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 5
|
||||
((28948022309329048855892746252171976963363056481941560715954676764349967630337 - 1) / 2)
|
||||
28948022309329048855892746252171976963363056481941560715954676764349967630337
|
||||
(by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 3 := (Nat.prime_dvd_prime_iff_eq hq (by norm_num)).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 5
|
||||
((28948022309329048855892746252171976963363056481941560715954676764349967630337 - 1) / 3)
|
||||
28948022309329048855892746252171976963363056481941560715954676764349967630337
|
||||
(by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 463 := (Nat.prime_dvd_prime_iff_eq hq prime_463).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 5
|
||||
((28948022309329048855892746252171976963363056481941560715954676764349967630337 - 1) / 463)
|
||||
28948022309329048855892746252171976963363056481941560715954676764349967630337
|
||||
(by decide) (by decide) (by decide) (by decide)
|
||||
rcases (Nat.Prime.dvd_mul hq).mp hqd with h | hqd
|
||||
· have he : q = 539204044132271846773 := (Nat.prime_dvd_prime_iff_eq hq prime_539204044132271846773).mp h
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 5
|
||||
((28948022309329048855892746252171976963363056481941560715954676764349967630337 - 1) / 539204044132271846773)
|
||||
28948022309329048855892746252171976963363056481941560715954676764349967630337
|
||||
(by decide) (by decide) (by decide) (by decide)
|
||||
have he : q = 8999194758858563409123804352480028797519453 :=
|
||||
(Nat.prime_dvd_prime_iff_eq hq prime_8999194758858563409123804352480028797519453).mp hqd
|
||||
subst he
|
||||
exact pow_ne_one_of_powMod 5
|
||||
((28948022309329048855892746252171976963363056481941560715954676764349967630337 - 1) / 8999194758858563409123804352480028797519453)
|
||||
28948022309329048855892746252171976963363056481941560715954676764349967630337
|
||||
(by decide) (by decide) (by decide) (by decide)
|
||||
|
||||
end PPallas
|
||||
|
||||
-- ═════════════════════════════════════════════════════════════════════════════
|
||||
-- Exported result
|
||||
-- ═════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
/-- The Pallas curve base field modulus is prime.
|
||||
This is the only theorem from this file used downstream. -/
|
||||
theorem pallas_prime : Nat.Prime 28948022309329048855892746252171976963363056481941560715954676764349967630337 :=
|
||||
PPallas.prime_Pallas
|
||||
243
verification/Proofs/SubNegSpec.lean
Normal file
243
verification/Proofs/SubNegSpec.lean
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
/- ──────────────────────────────────────────────────────────────────────────────
|
||||
Proofs/SubNegSpec.lean — subtraction and negation of the transpiled Fp.
|
||||
|
||||
RUST ANALOG (src/fields/fp.rs):
|
||||
* `Fp::sub` (fp.rs:374-388): 4-limb sbb chain, then a conditional add-back
|
||||
of the modulus masked by the final borrow word (`MODULUS.0[i] & borrow`).
|
||||
* `Fp::neg` (fp.rs:405-...): computes p − a by a 4-limb sbb chain, then
|
||||
zeroes the result iff a = 0 (the `mask = −((a≠0) as u64)` trick).
|
||||
|
||||
THE SUB SPEC IS DELIBERATELY MORE GENERAL THAN Canon × Canon:
|
||||
hypotheses feVal b ≤ P and feVal a < feVal b + P
|
||||
conclusion Canon r ∧ (r + b = a ∨ r + b = a + P) (exact ℕ)
|
||||
This covers the two call shapes in the crate:
|
||||
* canonical x, y (x < P ≤ y + P): field subtraction;
|
||||
* `sub t MODULUS` with t < 2P: the final conditional reduction of
|
||||
`add` and `montgomery_reduce` (t ≥ P → t − P; t < P → borrow, add-back
|
||||
gives t itself).
|
||||
The additive phrasing avoids ℕ-subtraction entirely; casting to 𝔽_p kills
|
||||
the +P branch ((P : 𝔽_p) = 0), giving ⟪r⟫ = ⟪a⟫ − ⟪b⟫.
|
||||
|
||||
Imports: Proofs/HelperSpecs (adc/sbb/mac atoms).
|
||||
Imported by: AddSpec (add = adc chain ∘ sub · MODULUS), ReduceSpec
|
||||
(montgomery_reduce ends with the same call), ConstSpecs, FieldMain.
|
||||
────────────────────────────────────────────────────────────────────────────── -/
|
||||
import Proofs.HelperSpecs
|
||||
open Aeneas Aeneas.Std Result
|
||||
open pasta_curves
|
||||
|
||||
set_option maxHeartbeats 8000000
|
||||
set_option linter.unusedTactic false
|
||||
set_option linter.unreachableTactic false
|
||||
|
||||
namespace PastaProofs
|
||||
|
||||
open Aeneas.Std.WP
|
||||
|
||||
macro "dis" : tactic =>
|
||||
`(tactic| (subst_vars; try simp [Array.set_val_eq, *]; try scalar_tac))
|
||||
|
||||
/-- The transpiled MODULUS constant, as a limb list. -/
|
||||
theorem MODULUS_limbs :
|
||||
(↑fields.fp.MODULUS : List U64) =
|
||||
[11037532056220336129#u64, 2469829653914515739#u64, 0#u64,
|
||||
4611686018427387904#u64] := by
|
||||
unfold fields.fp.MODULUS
|
||||
rfl
|
||||
|
||||
/-- Its exact value is the Pallas prime. -/
|
||||
theorem feVal_MODULUS : feVal fields.fp.MODULUS = P := by
|
||||
rw [feVal_eq _ _ _ _ _ MODULUS_limbs]
|
||||
unfold limbsVal P
|
||||
norm_num
|
||||
|
||||
/-- `Fp::sub`: exact two-case value identity + canonicity (see file header). -/
|
||||
theorem sub_spec (a b : Fe) (hbP : feVal b ≤ P) (hab : feVal a < feVal b + P) :
|
||||
fields.fp.Fp.sub a b
|
||||
⦃ r => Canon r ∧
|
||||
(feVal r + feVal b = feVal a ∨
|
||||
feVal r + feVal b = feVal a + P) ⦄ := by
|
||||
obtain ⟨a0, a1, a2, a3, hla⟩ := Fe.exists_limbs a
|
||||
obtain ⟨b0, b1, b2, b3, hlb⟩ := Fe.exists_limbs b
|
||||
rw [feVal_eq b b0 b1 b2 b3 hlb] at hbP
|
||||
rw [feVal_eq a a0 a1 a2 a3 hla, feVal_eq b b0 b1 b2 b3 hlb] at hab
|
||||
unfold fields.fp.Fp.sub
|
||||
-- ── limb reads + the 4-step sbb chain ────────────────────────────────────
|
||||
let* ⟨ i, hi ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ i1, hi1 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ d0, borrow0, hsb0 ⟩ ← sbb_spec by dis
|
||||
let* ⟨ i2, hi2 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ i3, hi3 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ d1, borrow1, hsb1 ⟩ ← sbb_spec by dis
|
||||
let* ⟨ i4, hi4 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ i5, hi5 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ d2, borrow2, hsb2 ⟩ ← sbb_spec by dis
|
||||
let* ⟨ i6, hi6 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ i7, hi7 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ d3, borrow3, hsb3 ⟩ ← sbb_spec by dis
|
||||
-- ── conditional add-back: (MODULUS[i] & borrow) + adc chain ──────────────
|
||||
let* ⟨ i8, hi8 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ i9, hi9, hi9bv ⟩ ← UScalar.and_spec by dis
|
||||
let* ⟨ d01, carry0, hadc0 ⟩ ← adc_spec by dis
|
||||
let* ⟨ i10, hi10 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ i11, hi11, hi11bv ⟩ ← UScalar.and_spec by dis
|
||||
let* ⟨ d11, carry1, hadc1 ⟩ ← adc_spec by dis
|
||||
let* ⟨ i12, hi12 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ i13, hi13, hi13bv ⟩ ← UScalar.and_spec by dis
|
||||
let* ⟨ d21, carry2, hadc2 ⟩ ← adc_spec by dis
|
||||
let* ⟨ i14, hi14 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ i15, hi15, hi15bv ⟩ ← UScalar.and_spec by dis
|
||||
let* ⟨ d31, carry3, hadc3 ⟩ ← adc_spec by dis
|
||||
-- ── assemble ─────────────────────────────────────────────────────────────
|
||||
-- identify the reads with the named limbs / MODULUS literals
|
||||
-- val-level identifications of the reads (omega links through these)
|
||||
have hv_i : i.val = a0.val := by simp [hi, hla]
|
||||
have hv_i1 : i1.val = b0.val := by simp [hi1, hlb]
|
||||
have hv_i2 : i2.val = a1.val := by simp [hi2, hla]
|
||||
have hv_i3 : i3.val = b1.val := by simp [hi3, hlb]
|
||||
have hv_i4 : i4.val = a2.val := by simp [hi4, hla]
|
||||
have hv_i5 : i5.val = b2.val := by simp [hi5, hlb]
|
||||
have hv_i6 : i6.val = a3.val := by simp [hi6, hla]
|
||||
have hv_i7 : i7.val = b3.val := by simp [hi7, hlb]
|
||||
have hv_i8 : i8.val = 11037532056220336129 := by simp [hi8, MODULUS_limbs]
|
||||
have hv_i10 : i10.val = 2469829653914515739 := by simp [hi10, MODULUS_limbs]
|
||||
have hv_i12 : i12.val = 0 := by simp [hi12, MODULUS_limbs]
|
||||
have hv_i14 : i14.val = 4611686018427387904 := by simp [hi14, MODULUS_limbs]
|
||||
-- expose the ℕ-level land in the mask equations
|
||||
simp only [UScalar.val_and, hv_i8, hv_i10, hv_i12, hv_i14] at hi9 hi11 hi13 hi15
|
||||
-- limb bounds (make everything linear for omega)
|
||||
have hb_d0 : d0.val < 2^64 := by scalar_tac
|
||||
have hb_d1 : d1.val < 2^64 := by scalar_tac
|
||||
have hb_d2 : d2.val < 2^64 := by scalar_tac
|
||||
have hb_d3 : d3.val < 2^64 := by scalar_tac
|
||||
have hb_d01 : d01.val < 2^64 := by scalar_tac
|
||||
have hb_d11 : d11.val < 2^64 := by scalar_tac
|
||||
have hb_d21 : d21.val < 2^64 := by scalar_tac
|
||||
have hb_d31 : d31.val < 2^64 := by scalar_tac
|
||||
have hb_a0 : a0.val < 2^64 := by scalar_tac
|
||||
have hb_a1 : a1.val < 2^64 := by scalar_tac
|
||||
have hb_a2 : a2.val < 2^64 := by scalar_tac
|
||||
have hb_a3 : a3.val < 2^64 := by scalar_tac
|
||||
have hb_b0 : b0.val < 2^64 := by scalar_tac
|
||||
have hb_b1 : b1.val < 2^64 := by scalar_tac
|
||||
have hb_b2 : b2.val < 2^64 := by scalar_tac
|
||||
have hb_b3 : b3.val < 2^64 := by scalar_tac
|
||||
-- resolve the mask values in the two borrow3 cases
|
||||
rcases hsb3 with ⟨hbor3, hval3⟩ | ⟨hbor3, hval3⟩ <;>
|
||||
[ (simp only [hbor3, Nat.and_zero] at hi9 hi11 hi13 hi15);
|
||||
(simp only [hbor3, Nat.and_two_pow_sub_one_eq_mod] at hi9 hi11 hi13 hi15;
|
||||
norm_num at hi9 hi11 hi13 hi15) ] <;>
|
||||
· rw [feVal_eq a a0 a1 a2 a3 hla, feVal_eq b b0 b1 b2 b3 hlb]
|
||||
constructor
|
||||
· -- Canon: feVal r < P
|
||||
unfold Canon
|
||||
simp only [feVal_make]
|
||||
unfold limbsVal P at *
|
||||
trace_state
|
||||
omega
|
||||
· -- the two-case value identity
|
||||
simp only [feVal_make]
|
||||
unfold limbsVal P at *
|
||||
omega
|
||||
|
||||
/-- `Fp::neg`: total, canonical, and denotes −⟪a⟫ (for canonical input). -/
|
||||
theorem neg_spec (a : Fe) (ha : Canon a) :
|
||||
fields.fp.Fp.neg a
|
||||
⦃ r => Canon r ∧
|
||||
(feVal r + feVal a = P ∨ (feVal r = 0 ∧ feVal a = 0)) ⦄ := by
|
||||
obtain ⟨a0, a1, a2, a3, hla⟩ := Fe.exists_limbs a
|
||||
unfold Canon at ha
|
||||
rw [feVal_eq a a0 a1 a2 a3 hla] at ha
|
||||
unfold fields.fp.Fp.neg
|
||||
let* ⟨ i, hi ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ i1, hi1 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ d0, borrow0, hsb0 ⟩ ← sbb_spec by dis
|
||||
let* ⟨ i2, hi2 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ i3, hi3 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ d1, borrow1, hsb1 ⟩ ← sbb_spec by dis
|
||||
let* ⟨ i4, hi4 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ i5, hi5 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ d2, borrow2, hsb2 ⟩ ← sbb_spec by dis
|
||||
let* ⟨ i6, hi6 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ i7, hi7 ⟩ ← Array.index_usize_spec by dis
|
||||
let* ⟨ d3, borrow3, hsb3 ⟩ ← sbb_spec by dis
|
||||
-- the is-zero test: i8 = a0 ||| a1, i9 = i8 ||| a2, i10 = i9 ||| a3
|
||||
let* ⟨ i8, hi8, hi8bv ⟩ ← UScalar.or_spec by dis
|
||||
let* ⟨ i9, hi9, hi9bv ⟩ ← UScalar.or_spec by dis
|
||||
let* ⟨ i10, hi10, hi10bv ⟩ ← UScalar.or_spec by dis
|
||||
let* ⟨ i11, hi11 ⟩ ← lift_spec by dis
|
||||
let* ⟨ mask, hmask ⟩ ← lift_spec by dis
|
||||
let* ⟨ i12, hi12, hi12bv ⟩ ← UScalar.and_spec by dis
|
||||
let* ⟨ i13, hi13, hi13bv ⟩ ← UScalar.and_spec by dis
|
||||
let* ⟨ i14, hi14, hi14bv ⟩ ← UScalar.and_spec by dis
|
||||
let* ⟨ i15, hi15, hi15bv ⟩ ← UScalar.and_spec by dis
|
||||
have hv_i : i.val = 11037532056220336129 := by simp [hi, MODULUS_limbs]
|
||||
have hv_i1 : i1.val = a0.val := by simp [hi1, hla]
|
||||
have hv_i2 : i2.val = 2469829653914515739 := by simp [hi2, MODULUS_limbs]
|
||||
have hv_i3 : i3.val = a1.val := by simp [hi3, hla]
|
||||
have hv_i4 : i4.val = 0 := by simp [hi4, MODULUS_limbs]
|
||||
have hv_i5 : i5.val = a2.val := by simp [hi5, hla]
|
||||
have hv_i6 : i6.val = 4611686018427387904 := by simp [hi6, MODULUS_limbs]
|
||||
have hv_i7 : i7.val = a3.val := by simp [hi7, hla]
|
||||
simp only [UScalar.val_or, hv_i1, hv_i3, hv_i5, hv_i7] at hi8 hi9 hi10
|
||||
simp only [UScalar.val_and] at hi12 hi13 hi14 hi15
|
||||
have hb_a0 : a0.val < 2^64 := by scalar_tac
|
||||
have hb_a1 : a1.val < 2^64 := by scalar_tac
|
||||
have hb_a2 : a2.val < 2^64 := by scalar_tac
|
||||
have hb_a3 : a3.val < 2^64 := by scalar_tac
|
||||
have hb_d0 : d0.val < 2^64 := by scalar_tac
|
||||
have hb_d1 : d1.val < 2^64 := by scalar_tac
|
||||
have hb_d2 : d2.val < 2^64 := by scalar_tac
|
||||
have hb_d3 : d3.val < 2^64 := by scalar_tac
|
||||
-- case: is the input zero?
|
||||
by_cases hz : a0.val = 0 ∧ a1.val = 0 ∧ a2.val = 0 ∧ a3.val = 0
|
||||
· -- a = 0: or-chain is 0, i11 = 1, mask = 0, result limbs all 0
|
||||
obtain ⟨h0, h1, h2, h3⟩ := hz
|
||||
have hor : i10.val = 0 := by
|
||||
simp [hi10, hi9, hi8, h0, h1, h2, h3]
|
||||
have hz10 : i10 = 0#u64 := by scalar_tac
|
||||
have h11 : i11.val = 1 := by
|
||||
subst hi11
|
||||
simp [hz10]
|
||||
have hm : mask.val = 0 := by
|
||||
subst hmask
|
||||
simp only [core.num.U64.wrapping_sub_val_eq]
|
||||
simp [h11, U64.size, U64.numBits_def]
|
||||
simp only [hm, Nat.and_zero] at hi12 hi13 hi14 hi15
|
||||
constructor
|
||||
· unfold Canon; simp only [feVal_make]; unfold limbsVal P; omega
|
||||
· right
|
||||
constructor
|
||||
· simp only [feVal_make]; unfold limbsVal; omega
|
||||
· rw [feVal_eq a a0 a1 a2 a3 hla]; unfold limbsVal; omega
|
||||
· -- a ≠ 0: or-chain nonzero, i11 = 0, mask = all-ones, result = p − a
|
||||
have hor : i10.val ≠ 0 := by
|
||||
rw [hi10, hi9, hi8]
|
||||
intro hcon
|
||||
apply hz
|
||||
have c1 := nat_or_eq_zero hcon
|
||||
have c2 := nat_or_eq_zero c1.1
|
||||
have c3 := nat_or_eq_zero c2.1
|
||||
exact ⟨c3.1, c3.2, c2.2, c1.2⟩
|
||||
have hz10 : ¬ (i10 = 0#u64) := by scalar_tac
|
||||
have h11 : i11.val = 0 := by
|
||||
subst hi11
|
||||
simp [hz10]
|
||||
have hm : mask.val = 2^64 - 1 := by
|
||||
subst hmask
|
||||
simp only [core.num.U64.wrapping_sub_val_eq]
|
||||
simp [h11, U64.size, U64.numBits_def]
|
||||
rw [hm] at hi12 hi13 hi14 hi15
|
||||
simp only [Nat.and_two_pow_sub_one_eq_mod] at hi12 hi13 hi14 hi15
|
||||
rw [Nat.mod_eq_of_lt hb_d0] at hi12
|
||||
rw [Nat.mod_eq_of_lt hb_d1] at hi13
|
||||
rw [Nat.mod_eq_of_lt hb_d2] at hi14
|
||||
rw [Nat.mod_eq_of_lt hb_d3] at hi15
|
||||
constructor
|
||||
· unfold Canon; simp only [feVal_make]; unfold limbsVal P at *; omega
|
||||
· left
|
||||
simp only [feVal_make, feVal_eq a a0 a1 a2 a3 hla]
|
||||
unfold limbsVal P at *
|
||||
omega
|
||||
|
||||
end PastaProofs
|
||||
44
verification/extract.sh
Executable file
44
verification/extract.sh
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env bash
|
||||
# Regenerate the Lean model in gen/ from the Rust sources.
|
||||
#
|
||||
# SCOPE: Pallas base field 𝔽_p (src/fields/fp.rs) + the u64 helper primitives
|
||||
# (src/arithmetic/fields.rs: adc/sbb/mac — translated TRANSPARENTLY,
|
||||
# they are plain u128 arithmetic; no hand models).
|
||||
#
|
||||
# Rust --charon--> PallasFp.llbc --aeneas--> gen/PallasFp/*.lean
|
||||
#
|
||||
# Opaque items (documented in TRUSTED-BASE.md; all outside certificate cones):
|
||||
# * trait impls needing RNG / serde / GPU / iterator machinery
|
||||
# * sqrt (table-driven; out of scope for the field certificate)
|
||||
#
|
||||
# Usage: ./extract.sh
|
||||
set -euo pipefail
|
||||
|
||||
source ~/aeneas-toolchain/env.sh
|
||||
HERE="$(cd "$(dirname "$0")" && pwd)"
|
||||
CRATE=~/GitClone/FormalVerification/sources/pasta_curves-source
|
||||
|
||||
echo "[1/2] charon: Rust -> LLBC (fields::fp + arithmetic helpers)"
|
||||
cd "$CRATE"
|
||||
charon cargo --preset=aeneas \
|
||||
--start-from crate::fields::fp \
|
||||
--opaque 'crate::fields::fp::_::fmt' \
|
||||
--opaque 'crate::fields::fp::_::pow_by_t_minus1_over2' \
|
||||
--opaque 'crate::fields::fp::_::get_lower_32' \
|
||||
--opaque 'crate::fields::fp::_::ZETA' \
|
||||
--opaque 'crate::fields::fp::_::from_uniform_bytes' \
|
||||
--opaque 'crate::fields::fp::_::sqrt' \
|
||||
--opaque 'crate::fields::fp::_::sqrt_ratio' \
|
||||
--opaque 'crate::fields::fp::_::random' \
|
||||
--opaque 'crate::fields::fp::_::sum' \
|
||||
--opaque 'crate::fields::fp::_::product' \
|
||||
--opaque 'crate::fields::fp::_::cmp' \
|
||||
--opaque 'crate::fields::fp::_::partial_cmp' \
|
||||
--dest-file "$HERE/PallasFp.llbc" \
|
||||
-- --no-default-features
|
||||
|
||||
echo "[2/2] aeneas: LLBC -> Lean (split files, PallasFp.* modules)"
|
||||
cd "$HERE"
|
||||
aeneas -backend lean -split-files -subdir PallasFp -dest gen PallasFp.llbc
|
||||
|
||||
echo "Done. Now run ./check.sh to type-check the regenerated model."
|
||||
1501
verification/gen/PallasFp/Funs.lean
Normal file
1501
verification/gen/PallasFp/Funs.lean
Normal file
File diff suppressed because it is too large
Load diff
195
verification/gen/PallasFp/FunsExternal.lean
Normal file
195
verification/gen/PallasFp/FunsExternal.lean
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
-- Hand-written models for external functions (derived from FunsExternal_Template.lean).
|
||||
-- [pasta_curves]: external functions.
|
||||
--
|
||||
-- Modeling policy (same as the ed25519 repos):
|
||||
-- * `subtle` items whose Rust bodies are real bit math are modeled FAITHFULLY
|
||||
-- (ct_eq decides equality; select/bitand/not collapse to if-then-else /
|
||||
-- boolean algebra on the documented {0,1} Choice invariant).
|
||||
-- * `subtle` items whose Rust bodies are optimization barriers (black_box)
|
||||
-- are semantically the identity and modeled so (Choice::from, unwrap_u8).
|
||||
-- * core `as_ref`/`borrow` on arrays/references are the evident coercions.
|
||||
-- * Everything else stays an AXIOM: Debug fmt, Ord/cmp, Sum/Product folds,
|
||||
-- sqrt/sqrt_ratio/random and the sqrt-table helpers, ff trait defaults —
|
||||
-- all deliberately opaque, all outside every certificate cone
|
||||
-- (verified by the check.sh Phase-3 axiom audit).
|
||||
import Aeneas
|
||||
import PallasFp.Types
|
||||
open Aeneas Aeneas.Std Result ControlFlow Error
|
||||
set_option linter.dupNamespace false
|
||||
set_option linter.hashCommand false
|
||||
set_option linter.unusedVariables false
|
||||
|
||||
set_option maxHeartbeats 1000000
|
||||
set_option maxRecDepth 2048
|
||||
open pasta_curves
|
||||
|
||||
/-- [core::array::{impl core::convert::AsRef<[T]> for [T; N]}::as_ref]
|
||||
MODEL: an array viewed as a slice — `Array.to_slice`. Needed transparently
|
||||
by `pow_vartime` (`exp.as_ref()`). -/
|
||||
@[rust_fun "core::array::{core::convert::AsRef<[@T; @N], [@T]>}::as_ref"]
|
||||
def Array.Insts.CoreConvertAsRefSlice.as_ref
|
||||
{T : Type} {N : Std.Usize} : Array T N → Result (Slice T) :=
|
||||
fun a => ok a.to_slice
|
||||
|
||||
/-- [core::array::{impl core::convert::AsMut<[T]> for [T; N]}::as_mut]
|
||||
AXIOM: not reachable from any transparent function in this extraction. -/
|
||||
@[rust_fun "core::array::{core::convert::AsMut<[@T; @N], [@T]>}::as_mut"]
|
||||
axiom Array.Insts.CoreConvertAsMutSlice.as_mut
|
||||
{T : Type} {N : Std.Usize} :
|
||||
Array T N → Result ((Slice T) × (Slice T → Array T N))
|
||||
|
||||
/-- [core::borrow::{impl core::borrow::Borrow<T> for T}::borrow]
|
||||
MODEL: identity (Rust's blanket Borrow is `&self` — value semantics id). -/
|
||||
@[rust_fun "core::borrow::{core::borrow::Borrow<@T, @T>}::borrow"]
|
||||
def core.borrow.Borrow.Blanket.borrow {T : Type} : T → Result T := fun x => ok x
|
||||
|
||||
/-- [core::borrow::{impl core::borrow::Borrow<T> for &'_0 T}::borrow]
|
||||
MODEL: identity. -/
|
||||
@[rust_fun "core::borrow::{core::borrow::Borrow<&'0 @T, @T>}::borrow"]
|
||||
def Shared0T.Insts.CoreBorrowBorrow.borrow {T : Type} : T → Result T := fun x => ok x
|
||||
|
||||
/-- [core::convert::{impl core::convert::AsRef<U> for &'_0 T}::as_ref]
|
||||
MODEL: defer to the underlying instance (deref transparent). -/
|
||||
@[rust_fun "core::convert::{core::convert::AsRef<&'0 @T, @U>}::as_ref"]
|
||||
def Shared0T.Insts.CoreConvertAsRef.as_ref
|
||||
{T : Type} {U : Type} (AsRefInst : core.convert.AsRef T U) : T → Result U :=
|
||||
fun x => AsRefInst.as_ref x
|
||||
|
||||
/-- [ff::Field::sqrt] (trait DEFAULT method)
|
||||
AXIOM: dead — `Fp` overrides `sqrt`; the default body is never called. -/
|
||||
@[rust_fun "ff::Field::sqrt"]
|
||||
axiom ff.Field.sqrt.default
|
||||
{Self : Type} (FieldInst : ff.Field Self) :
|
||||
Self → Result (subtle.CtOption Self)
|
||||
|
||||
/-- [ff::Field::pow_vartime] (trait DEFAULT method)
|
||||
AXIOM: dead — `Fp` overrides `pow_vartime` (the patched index-loop version,
|
||||
translated transparently in Funs.lean); the default body is never called. -/
|
||||
@[rust_fun "ff::Field::pow_vartime"]
|
||||
axiom ff.Field.pow_vartime.default
|
||||
{Self : Type} {S : Type} (FieldInst : ff.Field Self)
|
||||
(coreconvertAsRefSSliceU64Inst : core.convert.AsRef S (Slice Std.U64)) :
|
||||
Self → S → Result Self
|
||||
|
||||
/-- [ff::PrimeField::from_u128] (trait DEFAULT method) — AXIOM: dead code here. -/
|
||||
@[rust_fun "ff::PrimeField::from_u128"]
|
||||
axiom ff.PrimeField.from_u128.default
|
||||
{Self : Type} {Clause0_Repr : Type} (PrimeFieldInst : ff.PrimeField Self
|
||||
Clause0_Repr) :
|
||||
Std.U128 → Result Self
|
||||
|
||||
/-- [subtle::{subtle::Choice}::unwrap_u8]
|
||||
MODEL: identity — Rust body is `self.0` behind a black_box fence. -/
|
||||
@[rust_fun "subtle::{subtle::Choice}::unwrap_u8"]
|
||||
def subtle.Choice.unwrap_u8 : subtle.Choice → Result Std.U8 := fun c => ok c
|
||||
|
||||
/-- [subtle::{impl BitAnd for Choice}::bitand]
|
||||
MODEL: u8 bitwise AND (on the {0,1} invariant this is boolean ∧). -/
|
||||
@[rust_fun
|
||||
"subtle::{core::ops::bit::BitAnd<subtle::Choice, subtle::Choice, subtle::Choice>}::bitand"]
|
||||
def subtle.Choice.Insts.CoreOpsBitBitAndChoiceChoice.bitand
|
||||
: subtle.Choice → subtle.Choice → Result subtle.Choice :=
|
||||
fun a b => ok (a &&& b)
|
||||
|
||||
/-- [subtle::{impl Not for Choice}::not]
|
||||
MODEL: `1 ^ c` — Rust body is `Choice(1u8 ^ self.0)`; on {0,1} this is ¬. -/
|
||||
@[rust_fun
|
||||
"subtle::{core::ops::bit::Not<subtle::Choice, subtle::Choice>}::not"]
|
||||
def subtle.Choice.Insts.CoreOpsBitNotChoice.not
|
||||
: subtle.Choice → Result subtle.Choice :=
|
||||
fun c => ok (1#u8 ^^^ c)
|
||||
|
||||
/-- [subtle::{impl From<u8> for Choice}::from]
|
||||
MODEL: identity — Rust body reads the byte through a volatile/black_box
|
||||
optimization fence; value semantics is id. (Callers uphold the {0,1}
|
||||
contract; the crate's ct_eq-style producers only ever pass 0 or 1.) -/
|
||||
@[rust_fun "subtle::{core::convert::From<subtle::Choice, u8>}::from"]
|
||||
def subtle.Choice.Insts.CoreConvertFromU8.from
|
||||
: Std.U8 → Result subtle.Choice := fun x => ok x
|
||||
|
||||
/-- [subtle::{impl ConstantTimeEq for u64}::ct_eq]
|
||||
MODEL: the SPECIFICATION of subtle's xor/wrapping-neg/shift bit trick,
|
||||
which returns 1 iff the two integers are equal (for ALL inputs): decide
|
||||
`a = b`. -/
|
||||
@[rust_fun "subtle::{subtle::ConstantTimeEq<u64>}::ct_eq"]
|
||||
def U64.Insts.SubtleConstantTimeEq.ct_eq
|
||||
: Std.U64 → Std.U64 → Result subtle.Choice :=
|
||||
fun a b => ok (if a.val = b.val then 1#u8 else 0#u8)
|
||||
|
||||
/-- [subtle::{impl ConditionallySelectable for u64}::conditional_select]
|
||||
MODEL: `a ^ (mask & (a ^ b))` with mask = −(c as u64): equals `a` when
|
||||
c = 0 and `b` when c = 1. Every Choice reaching this call is 0 or 1
|
||||
(see TypesExternal policy), so if-then-else is exact. -/
|
||||
@[rust_fun
|
||||
"subtle::{subtle::ConditionallySelectable<u64>}::conditional_select"]
|
||||
def U64.Insts.SubtleConditionallySelectable.conditional_select
|
||||
: Std.U64 → Std.U64 → subtle.Choice → Result Std.U64 :=
|
||||
fun a b c => ok (if c.val = 0 then a else b)
|
||||
|
||||
/-- [subtle::{subtle::CtOption<T>}::new]
|
||||
MODEL: the struct constructor — store (value, is_some) verbatim. -/
|
||||
@[rust_fun "subtle::{subtle::CtOption<@T>}::new"]
|
||||
def subtle.CtOption.new
|
||||
{T : Type} : T → subtle.Choice → Result (subtle.CtOption T) :=
|
||||
fun v c => ok ⟨v, c⟩
|
||||
|
||||
/-- [Fp Debug::fmt] — AXIOM: formatting, no proof depends on it. -/
|
||||
axiom fields.fp.Fp.Insts.CoreFmtDebug.fmt
|
||||
:
|
||||
fields.fp.Fp → core.fmt.Formatter → Result ((core.result.Result Unit
|
||||
core.fmt.Error) × core.fmt.Formatter)
|
||||
|
||||
/-- [Fp PartialOrd::partial_cmp] — AXIOM: deliberately opaque (iterator fold). -/
|
||||
axiom fields.fp.Fp.Insts.CoreCmpPartialOrdFp.partial_cmp
|
||||
: fields.fp.Fp → fields.fp.Fp → Result (Option Ordering)
|
||||
|
||||
/-- [Fp Ord::cmp] — AXIOM: deliberately opaque (iterator fold). -/
|
||||
axiom fields.fp.Fp.Insts.CoreCmpOrd.cmp
|
||||
: fields.fp.Fp → fields.fp.Fp → Result Ordering
|
||||
|
||||
/-- [Fp Sum::sum] — AXIOM: deliberately opaque (iterator fold). -/
|
||||
axiom fields.fp.Fp.Insts.CoreIterTraitsAccumSum.sum
|
||||
{T : Type} {I : Type} (coreborrowBorrowTFpInst : core.borrow.Borrow T
|
||||
fields.fp.Fp) (coreitertraitsiteratorIteratorInst :
|
||||
core.iter.traits.iterator.Iterator I T) :
|
||||
I → Result fields.fp.Fp
|
||||
|
||||
/-- [Fp Product::product] — AXIOM: deliberately opaque (iterator fold). -/
|
||||
axiom fields.fp.Fp.Insts.CoreIterTraitsAccumProduct.product
|
||||
{T : Type} {I : Type} (coreborrowBorrowTFpInst : core.borrow.Borrow T
|
||||
fields.fp.Fp) (coreitertraitsiteratorIteratorInst :
|
||||
core.iter.traits.iterator.Iterator I T) :
|
||||
I → Result fields.fp.Fp
|
||||
|
||||
/-- [Fp ff::Field::sqrt] — AXIOM: Tonelli–Shanks via helpers; out of scope
|
||||
for the field certificate (documented in TRUSTED-BASE.md). -/
|
||||
axiom fields.fp.Fp.Insts.FfField.sqrt
|
||||
: fields.fp.Fp → Result (subtle.CtOption fields.fp.Fp)
|
||||
|
||||
/-- [Fp ff::Field::sqrt_ratio] — AXIOM: out of scope (see sqrt). -/
|
||||
axiom fields.fp.Fp.Insts.FfField.sqrt_ratio
|
||||
: fields.fp.Fp → fields.fp.Fp → Result (subtle.Choice × fields.fp.Fp)
|
||||
|
||||
/-- [Fp ff::Field::random] — AXIOM: RNG plumbing, untranslatable and irrelevant. -/
|
||||
axiom fields.fp.Fp.Insts.FfField.random
|
||||
{T0 : Type} (rand_coreRngCoreInst : rand_core.RngCore T0) :
|
||||
T0 → Result fields.fp.Fp
|
||||
|
||||
/-- [Fp SqrtTableHelpers::get_lower_32] — AXIOM: sqrt-table helper, opaque. -/
|
||||
axiom
|
||||
fields.fp.Fp.Insts.Pasta_curvesArithmeticFieldsSqrtTableHelpersArrayU832.get_lower_32
|
||||
: fields.fp.Fp → Result Std.U32
|
||||
|
||||
/-- [Fp SqrtTableHelpers::pow_by_t_minus1_over2] — AXIOM: sqrt-table helper
|
||||
(closure-based), opaque. -/
|
||||
axiom
|
||||
fields.fp.Fp.Insts.Pasta_curvesArithmeticFieldsSqrtTableHelpersArrayU832.pow_by_t_minus1_over2
|
||||
: fields.fp.Fp → Result fields.fp.Fp
|
||||
|
||||
/-- [Fp WithSmallOrderMulGroup::ZETA] — AXIOM: constant of an opaque impl. -/
|
||||
axiom fields.fp.Fp.Insts.FfWithSmallOrderMulGroupArrayU8323.ZETA
|
||||
: Result fields.fp.Fp
|
||||
|
||||
/-- [Fp FromUniformBytes::from_uniform_bytes] — AXIOM: opaque impl. -/
|
||||
axiom fields.fp.Fp.Insts.FfFromUniformBytesArrayU83264.from_uniform_bytes
|
||||
: Array Std.U8 64#usize → Result fields.fp.Fp
|
||||
224
verification/gen/PallasFp/FunsExternal_Template.lean
Normal file
224
verification/gen/PallasFp/FunsExternal_Template.lean
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
-- THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS
|
||||
-- [pasta_curves]: external functions.
|
||||
-- This is a template file: rename it to "FunsExternal.lean" and fill the holes.
|
||||
import Aeneas
|
||||
import PallasFp.Types
|
||||
open Aeneas Aeneas.Std Result ControlFlow Error
|
||||
set_option linter.dupNamespace false
|
||||
set_option linter.hashCommand false
|
||||
set_option linter.unusedVariables false
|
||||
|
||||
/- You can set the `maxHeartbeats` value with the `-max-heartbeats` CLI option -/
|
||||
set_option maxHeartbeats 1000000
|
||||
|
||||
/- You can set the `maxRecDepth` value with the `-max-recdepth` CLI option -/
|
||||
set_option maxRecDepth 2048
|
||||
open pasta_curves
|
||||
|
||||
/-- [core::array::{impl core::convert::AsRef<[T]> for [T; N]}::as_ref]:
|
||||
Source: '/rustc/library/core/src/array/mod.rs', lines 208:4-208:28
|
||||
Name pattern: [core::array::{core::convert::AsRef<[@T; @N], [@T]>}::as_ref]
|
||||
Visibility: public -/
|
||||
@[rust_fun "core::array::{core::convert::AsRef<[@T; @N], [@T]>}::as_ref"]
|
||||
axiom Array.Insts.CoreConvertAsRefSlice.as_ref
|
||||
{T : Type} {N : Std.Usize} : Array T N → Result (Slice T)
|
||||
|
||||
/-- [core::array::{impl core::convert::AsMut<[T]> for [T; N]}::as_mut]:
|
||||
Source: '/rustc/library/core/src/array/mod.rs', lines 217:4-217:36
|
||||
Name pattern: [core::array::{core::convert::AsMut<[@T; @N], [@T]>}::as_mut]
|
||||
Visibility: public -/
|
||||
@[rust_fun "core::array::{core::convert::AsMut<[@T; @N], [@T]>}::as_mut"]
|
||||
axiom Array.Insts.CoreConvertAsMutSlice.as_mut
|
||||
{T : Type} {N : Std.Usize} :
|
||||
Array T N → Result ((Slice T) × (Slice T → Array T N))
|
||||
|
||||
/-- [core::borrow::{impl core::borrow::Borrow<T> for T}::borrow]:
|
||||
Source: '/rustc/library/core/src/borrow.rs', lines 214:4-214:26
|
||||
Name pattern: [core::borrow::{core::borrow::Borrow<@T, @T>}::borrow]
|
||||
Visibility: public -/
|
||||
@[rust_fun "core::borrow::{core::borrow::Borrow<@T, @T>}::borrow"]
|
||||
axiom core.borrow.Borrow.Blanket.borrow {T : Type} : T → Result T
|
||||
|
||||
/-- [core::borrow::{impl core::borrow::Borrow<T> for &'_0 T}::borrow]:
|
||||
Source: '/rustc/library/core/src/borrow.rs', lines 230:4-230:26
|
||||
Name pattern: [core::borrow::{core::borrow::Borrow<&'0 @T, @T>}::borrow]
|
||||
Visibility: public -/
|
||||
@[rust_fun "core::borrow::{core::borrow::Borrow<&'0 @T, @T>}::borrow"]
|
||||
axiom Shared0T.Insts.CoreBorrowBorrow.borrow {T : Type} : T → Result T
|
||||
|
||||
/-- [core::convert::{impl core::convert::AsRef<U> for &'_0 T}::as_ref]:
|
||||
Source: '/rustc/library/core/src/convert/mod.rs', lines 717:4-717:26
|
||||
Name pattern: [core::convert::{core::convert::AsRef<&'0 @T, @U>}::as_ref]
|
||||
Visibility: public -/
|
||||
@[rust_fun "core::convert::{core::convert::AsRef<&'0 @T, @U>}::as_ref"]
|
||||
axiom Shared0T.Insts.CoreConvertAsRef.as_ref
|
||||
{T : Type} {U : Type} (AsRefInst : core.convert.AsRef T U) : T → Result U
|
||||
|
||||
/-- [ff::Field::sqrt]:
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ff-0.13.1/src/lib.rs', lines 144:4-144:36
|
||||
Name pattern: [ff::Field::sqrt]
|
||||
Visibility: public -/
|
||||
@[rust_fun "ff::Field::sqrt"]
|
||||
axiom ff.Field.sqrt.default
|
||||
{Self : Type} (FieldInst : ff.Field Self) :
|
||||
Self → Result (subtle.CtOption Self)
|
||||
|
||||
/-- [ff::Field::pow_vartime]:
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ff-0.13.1/src/lib.rs', lines 178:4-178:58
|
||||
Name pattern: [ff::Field::pow_vartime]
|
||||
Visibility: public -/
|
||||
@[rust_fun "ff::Field::pow_vartime"]
|
||||
axiom ff.Field.pow_vartime.default
|
||||
{Self : Type} {S : Type} (FieldInst : ff.Field Self)
|
||||
(coreconvertAsRefSSliceU64Inst : core.convert.AsRef S (Slice Std.U64)) :
|
||||
Self → S → Result Self
|
||||
|
||||
/-- [ff::PrimeField::from_u128]:
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ff-0.13.1/src/lib.rs', lines 254:4-254:33
|
||||
Name pattern: [ff::PrimeField::from_u128]
|
||||
Visibility: public -/
|
||||
@[rust_fun "ff::PrimeField::from_u128"]
|
||||
axiom ff.PrimeField.from_u128.default
|
||||
{Self : Type} {Clause0_Repr : Type} (PrimeFieldInst : ff.PrimeField Self
|
||||
Clause0_Repr) :
|
||||
Std.U128 → Result Self
|
||||
|
||||
/-- [subtle::{subtle::Choice}::unwrap_u8]:
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs', lines 133:4-133:33
|
||||
Name pattern: [subtle::{subtle::Choice}::unwrap_u8]
|
||||
Visibility: public -/
|
||||
@[rust_fun "subtle::{subtle::Choice}::unwrap_u8"]
|
||||
axiom subtle.Choice.unwrap_u8 : subtle.Choice → Result Std.U8
|
||||
|
||||
/-- [subtle::{impl core::ops::bit::BitAnd<subtle::Choice, subtle::Choice> for subtle::Choice}::bitand]:
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs', lines 162:4-162:42
|
||||
Name pattern: [subtle::{core::ops::bit::BitAnd<subtle::Choice, subtle::Choice, subtle::Choice>}::bitand]
|
||||
Visibility: public -/
|
||||
@[rust_fun
|
||||
"subtle::{core::ops::bit::BitAnd<subtle::Choice, subtle::Choice, subtle::Choice>}::bitand"]
|
||||
axiom subtle.Choice.Insts.CoreOpsBitBitAndChoiceChoice.bitand
|
||||
: subtle.Choice → subtle.Choice → Result subtle.Choice
|
||||
|
||||
/-- [subtle::{impl core::ops::bit::Not<subtle::Choice> for subtle::Choice}::not]:
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs', lines 207:4-207:26
|
||||
Name pattern: [subtle::{core::ops::bit::Not<subtle::Choice, subtle::Choice>}::not]
|
||||
Visibility: public -/
|
||||
@[rust_fun
|
||||
"subtle::{core::ops::bit::Not<subtle::Choice, subtle::Choice>}::not"]
|
||||
axiom subtle.Choice.Insts.CoreOpsBitNotChoice.not
|
||||
: subtle.Choice → Result subtle.Choice
|
||||
|
||||
/-- [subtle::{impl core::convert::From<u8> for subtle::Choice}::from]:
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs', lines 238:4-238:32
|
||||
Name pattern: [subtle::{core::convert::From<subtle::Choice, u8>}::from]
|
||||
Visibility: public -/
|
||||
@[rust_fun "subtle::{core::convert::From<subtle::Choice, u8>}::from"]
|
||||
axiom subtle.Choice.Insts.CoreConvertFromU8.from
|
||||
: Std.U8 → Result subtle.Choice
|
||||
|
||||
/-- [subtle::{impl subtle::ConstantTimeEq for u64}::ct_eq]:
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs', lines 348:12-348:51
|
||||
Name pattern: [subtle::{subtle::ConstantTimeEq<u64>}::ct_eq]
|
||||
Visibility: public -/
|
||||
@[rust_fun "subtle::{subtle::ConstantTimeEq<u64>}::ct_eq"]
|
||||
axiom U64.Insts.SubtleConstantTimeEq.ct_eq
|
||||
: Std.U64 → Std.U64 → Result subtle.Choice
|
||||
|
||||
/-- [subtle::{impl subtle::ConditionallySelectable for u64}::conditional_select]:
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs', lines 513:12-513:77
|
||||
Name pattern: [subtle::{subtle::ConditionallySelectable<u64>}::conditional_select]
|
||||
Visibility: public -/
|
||||
@[rust_fun
|
||||
"subtle::{subtle::ConditionallySelectable<u64>}::conditional_select"]
|
||||
axiom U64.Insts.SubtleConditionallySelectable.conditional_select
|
||||
: Std.U64 → Std.U64 → subtle.Choice → Result Std.U64
|
||||
|
||||
/-- [subtle::{subtle::CtOption<T>}::new]:
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs', lines 678:4-678:56
|
||||
Name pattern: [subtle::{subtle::CtOption<@T>}::new]
|
||||
Visibility: public -/
|
||||
@[rust_fun "subtle::{subtle::CtOption<@T>}::new"]
|
||||
axiom subtle.CtOption.new
|
||||
{T : Type} : T → subtle.Choice → Result (subtle.CtOption T)
|
||||
|
||||
/-- [pasta_curves::fields::fp::{impl core::fmt::Debug for pasta_curves::fields::fp::Fp}::fmt]:
|
||||
Source: 'src/fields/fp.rs', lines 34:4-41:5
|
||||
Visibility: public -/
|
||||
axiom fields.fp.Fp.Insts.CoreFmtDebug.fmt
|
||||
:
|
||||
fields.fp.Fp → core.fmt.Formatter → Result ((core.result.Result Unit
|
||||
core.fmt.Error) × core.fmt.Formatter)
|
||||
|
||||
/-- [pasta_curves::fields::fp::{impl core::cmp::PartialOrd<pasta_curves::fields::fp::Fp> for pasta_curves::fields::fp::Fp}::partial_cmp]:
|
||||
Source: 'src/fields/fp.rs', lines 92:4-94:5
|
||||
Visibility: public -/
|
||||
axiom fields.fp.Fp.Insts.CoreCmpPartialOrdFp.partial_cmp
|
||||
: fields.fp.Fp → fields.fp.Fp → Result (Option Ordering)
|
||||
|
||||
/-- [pasta_curves::fields::fp::{impl core::cmp::Ord for pasta_curves::fields::fp::Fp}::cmp]:
|
||||
Source: 'src/fields/fp.rs', lines 77:4-88:5
|
||||
Visibility: public -/
|
||||
axiom fields.fp.Fp.Insts.CoreCmpOrd.cmp
|
||||
: fields.fp.Fp → fields.fp.Fp → Result Ordering
|
||||
|
||||
/-- [pasta_curves::fields::fp::{impl core::iter::traits::accum::Sum<T> for pasta_curves::fields::fp::Fp}::sum]:
|
||||
Source: 'src/fields/fp.rs', lines 179:4-181:5
|
||||
Visibility: public -/
|
||||
axiom fields.fp.Fp.Insts.CoreIterTraitsAccumSum.sum
|
||||
{T : Type} {I : Type} (coreborrowBorrowTFpInst : core.borrow.Borrow T
|
||||
fields.fp.Fp) (coreitertraitsiteratorIteratorInst :
|
||||
core.iter.traits.iterator.Iterator I T) :
|
||||
I → Result fields.fp.Fp
|
||||
|
||||
/-- [pasta_curves::fields::fp::{impl core::iter::traits::accum::Product<T> for pasta_curves::fields::fp::Fp}::product]:
|
||||
Source: 'src/fields/fp.rs', lines 185:4-187:5
|
||||
Visibility: public -/
|
||||
axiom fields.fp.Fp.Insts.CoreIterTraitsAccumProduct.product
|
||||
{T : Type} {I : Type} (coreborrowBorrowTFpInst : core.borrow.Borrow T
|
||||
fields.fp.Fp) (coreitertraitsiteratorIteratorInst :
|
||||
core.iter.traits.iterator.Iterator I T) :
|
||||
I → Result fields.fp.Fp
|
||||
|
||||
/-- [pasta_curves::fields::fp::{impl ff::Field for pasta_curves::fields::fp::Fp}::sqrt]:
|
||||
Source: 'src/fields/fp.rs', lines 566:4-575:5
|
||||
Visibility: public -/
|
||||
axiom fields.fp.Fp.Insts.FfField.sqrt
|
||||
: fields.fp.Fp → Result (subtle.CtOption fields.fp.Fp)
|
||||
|
||||
/-- [pasta_curves::fields::fp::{impl ff::Field for pasta_curves::fields::fp::Fp}::sqrt_ratio]:
|
||||
Source: 'src/fields/fp.rs', lines 550:4-558:5
|
||||
Visibility: public -/
|
||||
axiom fields.fp.Fp.Insts.FfField.sqrt_ratio
|
||||
: fields.fp.Fp → fields.fp.Fp → Result (subtle.Choice × fields.fp.Fp)
|
||||
|
||||
/-- [pasta_curves::fields::fp::{impl ff::Field for pasta_curves::fields::fp::Fp}::random]:
|
||||
Source: 'src/fields/fp.rs', lines 528:4-539:5
|
||||
Visibility: public -/
|
||||
axiom fields.fp.Fp.Insts.FfField.random
|
||||
{T0 : Type} (rand_coreRngCoreInst : rand_core.RngCore T0) :
|
||||
T0 → Result fields.fp.Fp
|
||||
|
||||
/-- [pasta_curves::fields::fp::{impl pasta_curves::arithmetic::fields::SqrtTableHelpers<[u8; 32usize]> for pasta_curves::fields::fp::Fp}::get_lower_32]:
|
||||
Source: 'src/fields/fp.rs', lines 780:4-785:5 -/
|
||||
axiom
|
||||
fields.fp.Fp.Insts.Pasta_curvesArithmeticFieldsSqrtTableHelpersArrayU832.get_lower_32
|
||||
: fields.fp.Fp → Result Std.U32
|
||||
|
||||
/-- [pasta_curves::fields::fp::{impl pasta_curves::arithmetic::fields::SqrtTableHelpers<[u8; 32usize]> for pasta_curves::fields::fp::Fp}::pow_by_t_minus1_over2]:
|
||||
Source: 'src/fields/fp.rs', lines 749:4-778:5 -/
|
||||
axiom
|
||||
fields.fp.Fp.Insts.Pasta_curvesArithmeticFieldsSqrtTableHelpersArrayU832.pow_by_t_minus1_over2
|
||||
: fields.fp.Fp → Result fields.fp.Fp
|
||||
|
||||
/-- [pasta_curves::fields::fp::{impl ff::WithSmallOrderMulGroup<[u8; 32usize], 3u8> for pasta_curves::fields::fp::Fp}::ZETA]
|
||||
Source: 'src/fields/fp.rs', lines 789:4-794:7
|
||||
Visibility: public -/
|
||||
axiom fields.fp.Fp.Insts.FfWithSmallOrderMulGroupArrayU8323.ZETA
|
||||
: Result fields.fp.Fp
|
||||
|
||||
/-- [pasta_curves::fields::fp::{impl ff::FromUniformBytes<[u8; 32usize], 64usize> for pasta_curves::fields::fp::Fp}::from_uniform_bytes]:
|
||||
Source: 'src/fields/fp.rs', lines 800:4-811:5
|
||||
Visibility: public -/
|
||||
axiom fields.fp.Fp.Insts.FfFromUniformBytesArrayU83264.from_uniform_bytes
|
||||
: Array Std.U8 64#usize → Result fields.fp.Fp
|
||||
|
||||
234
verification/gen/PallasFp/Types.lean
Normal file
234
verification/gen/PallasFp/Types.lean
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
-- THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS
|
||||
-- [pasta_curves]: type definitions
|
||||
import Aeneas
|
||||
import PallasFp.TypesExternal
|
||||
open Aeneas Aeneas.Std Result ControlFlow Error
|
||||
set_option linter.dupNamespace false
|
||||
set_option linter.hashCommand false
|
||||
set_option linter.unusedVariables false
|
||||
|
||||
/- You can set the `maxHeartbeats` value with the `-max-heartbeats` CLI option -/
|
||||
set_option maxHeartbeats 1000000
|
||||
|
||||
/- You can set the `maxRecDepth` value with the `-max-recdepth` CLI option -/
|
||||
set_option maxRecDepth 2048
|
||||
|
||||
namespace pasta_curves
|
||||
|
||||
/-- Trait declaration: [core::convert::AsRef]
|
||||
Source: '/rustc/library/core/src/convert/mod.rs', lines 219:0-219:52
|
||||
Name pattern: [core::convert::AsRef]
|
||||
Visibility: public -/
|
||||
@[rust_trait "core::convert::AsRef"]
|
||||
structure core.convert.AsRef (Self : Type) (T : Type) where
|
||||
as_ref : Self → Result T
|
||||
|
||||
/-- Trait declaration: [core::borrow::Borrow]
|
||||
Source: '/rustc/library/core/src/borrow.rs', lines 158:0-158:40
|
||||
Name pattern: [core::borrow::Borrow]
|
||||
Visibility: public -/
|
||||
@[rust_trait "core::borrow::Borrow"]
|
||||
structure core.borrow.Borrow (Self : Type) (Borrowed : Type) where
|
||||
borrow : Self → Result Borrowed
|
||||
|
||||
/-- Trait declaration: [core::ops::arith::Add]
|
||||
Source: '/rustc/library/core/src/ops/arith.rs', lines 76:0-76:31
|
||||
Name pattern: [core::ops::arith::Add]
|
||||
Visibility: public -/
|
||||
@[rust_trait "core::ops::arith::Add"]
|
||||
structure core.ops.arith.Add (Self : Type) (Rhs : Type) (Self_Output : Type)
|
||||
where
|
||||
add : Self → Rhs → Result Self_Output
|
||||
|
||||
/-- Trait declaration: [core::ops::arith::Sub]
|
||||
Source: '/rustc/library/core/src/ops/arith.rs', lines 188:0-188:31
|
||||
Name pattern: [core::ops::arith::Sub]
|
||||
Visibility: public -/
|
||||
@[rust_trait "core::ops::arith::Sub"]
|
||||
structure core.ops.arith.Sub (Self : Type) (Rhs : Type) (Self_Output : Type)
|
||||
where
|
||||
sub : Self → Rhs → Result Self_Output
|
||||
|
||||
/-- Trait declaration: [core::ops::arith::Mul]
|
||||
Source: '/rustc/library/core/src/ops/arith.rs', lines 322:0-322:31
|
||||
Name pattern: [core::ops::arith::Mul]
|
||||
Visibility: public -/
|
||||
@[rust_trait "core::ops::arith::Mul"]
|
||||
structure core.ops.arith.Mul (Self : Type) (Rhs : Type) (Self_Output : Type)
|
||||
where
|
||||
mul : Self → Rhs → Result Self_Output
|
||||
|
||||
/-- Trait declaration: [core::ops::arith::Neg]
|
||||
Source: '/rustc/library/core/src/ops/arith.rs', lines 690:0-690:19
|
||||
Name pattern: [core::ops::arith::Neg]
|
||||
Visibility: public -/
|
||||
@[rust_trait "core::ops::arith::Neg"]
|
||||
structure core.ops.arith.Neg (Self : Type) (Self_Output : Type) where
|
||||
neg : Self → Result Self_Output
|
||||
|
||||
/-- Trait declaration: [core::ops::arith::AddAssign]
|
||||
Source: '/rustc/library/core/src/ops/arith.rs', lines 768:0-768:37
|
||||
Name pattern: [core::ops::arith::AddAssign]
|
||||
Visibility: public -/
|
||||
@[rust_trait "core::ops::arith::AddAssign"]
|
||||
structure core.ops.arith.AddAssign (Self : Type) (Rhs : Type) where
|
||||
add_assign : Self → Rhs → Result Self
|
||||
|
||||
/-- Trait declaration: [core::ops::arith::SubAssign]
|
||||
Source: '/rustc/library/core/src/ops/arith.rs', lines 839:0-839:37
|
||||
Name pattern: [core::ops::arith::SubAssign]
|
||||
Visibility: public -/
|
||||
@[rust_trait "core::ops::arith::SubAssign"]
|
||||
structure core.ops.arith.SubAssign (Self : Type) (Rhs : Type) where
|
||||
sub_assign : Self → Rhs → Result Self
|
||||
|
||||
/-- Trait declaration: [core::ops::arith::MulAssign]
|
||||
Source: '/rustc/library/core/src/ops/arith.rs', lines 901:0-901:37
|
||||
Name pattern: [core::ops::arith::MulAssign]
|
||||
Visibility: public -/
|
||||
@[rust_trait "core::ops::arith::MulAssign"]
|
||||
structure core.ops.arith.MulAssign (Self : Type) (Rhs : Type) where
|
||||
mul_assign : Self → Rhs → Result Self
|
||||
|
||||
/-- Trait declaration: [subtle::ConditionallySelectable]
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs', lines 393:0-393:39
|
||||
Name pattern: [subtle::ConditionallySelectable]
|
||||
Visibility: public -/
|
||||
@[rust_trait "subtle::ConditionallySelectable"
|
||||
(parentClauses := ["coremarkerCopyInst"])]
|
||||
structure subtle.ConditionallySelectable (Self : Type) where
|
||||
coremarkerCopyInst : core.marker.Copy Self
|
||||
conditional_select : Self → Self → subtle.Choice → Result Self
|
||||
|
||||
/-- Trait declaration: [subtle::ConstantTimeEq]
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs', lines 262:0-262:24
|
||||
Name pattern: [subtle::ConstantTimeEq]
|
||||
Visibility: public -/
|
||||
@[rust_trait "subtle::ConstantTimeEq"]
|
||||
structure subtle.ConstantTimeEq (Self : Type) where
|
||||
ct_eq : Self → Self → Result subtle.Choice
|
||||
|
||||
/-- Trait declaration: [rand_core::RngCore]
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_core-0.6.4/src/lib.rs', lines 142:0-142:17
|
||||
Name pattern: [rand_core::RngCore]
|
||||
Visibility: public -/
|
||||
@[rust_trait "rand_core::RngCore"]
|
||||
structure rand_core.RngCore (Self : Type) where
|
||||
next_u32 : Self → Result (Std.U32 × Self)
|
||||
next_u64 : Self → Result (Std.U64 × Self)
|
||||
fill_bytes : Self → Slice Std.U8 → Result (Self × (Slice Std.U8))
|
||||
try_fill_bytes : Self → Slice Std.U8 → Result ((core.result.Result Unit
|
||||
rand_core.error.Error) × Self × (Slice Std.U8))
|
||||
|
||||
/-- Trait declaration: [ff::Field]
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ff-0.13.1/src/lib.rs', lines 41:0-69:33
|
||||
Name pattern: [ff::Field]
|
||||
Visibility: public -/
|
||||
@[rust_trait "ff::Field"
|
||||
(parentClauses := ["corecmpEqInst", "coremarkerCopyInst", "corecloneCloneInst", "coredefaultDefaultInst", "corefmtDebugInst", "subtleConditionallySelectableInst", "subtleConstantTimeEqInst", "coreopsarithNegInst", "coreopsarithAddInst", "coreopsarithSubInst", "coreopsarithMulInst", "coreitertraitsaccumSumInst", "coreitertraitsaccumProductInst", "coreopsarithAddSelfSharedSelfSelfInst", "coreopsarithSubSelfSharedSelfSelfInst", "coreopsarithMulSelfSharedSelfSelfInst", "coreitertraitsaccumSumSelfSharedSelfInst", "coreitertraitsaccumProductSelfSharedSelfInst", "coreopsarithAddAssignInst", "coreopsarithSubAssignInst", "coreopsarithMulAssignInst", "coreopsarithAddAssignSelfSharedSelfInst", "coreopsarithSubAssignSelfSharedSelfInst", "coreopsarithMulAssignSelfSharedSelfInst"])
|
||||
(consts := ["ZERO", "ONE"])]
|
||||
structure ff.Field (Self : Type) where
|
||||
ZERO : Result Self
|
||||
ONE : Result Self
|
||||
corecmpEqInst : core.cmp.Eq Self
|
||||
coremarkerCopyInst : core.marker.Copy Self
|
||||
corecloneCloneInst : core.clone.Clone Self
|
||||
coredefaultDefaultInst : core.default.Default Self
|
||||
corefmtDebugInst : core.fmt.Debug Self
|
||||
subtleConditionallySelectableInst : subtle.ConditionallySelectable Self
|
||||
subtleConstantTimeEqInst : subtle.ConstantTimeEq Self
|
||||
coreopsarithNegInst : core.ops.arith.Neg Self Self
|
||||
coreopsarithAddInst : core.ops.arith.Add Self Self Self
|
||||
coreopsarithSubInst : core.ops.arith.Sub Self Self Self
|
||||
coreopsarithMulInst : core.ops.arith.Mul Self Self Self
|
||||
coreitertraitsaccumSumInst : core.iter.traits.accum.Sum Self Self
|
||||
coreitertraitsaccumProductInst : core.iter.traits.accum.Product Self Self
|
||||
coreopsarithAddSelfSharedSelfSelfInst : core.ops.arith.Add Self Self Self
|
||||
coreopsarithSubSelfSharedSelfSelfInst : core.ops.arith.Sub Self Self Self
|
||||
coreopsarithMulSelfSharedSelfSelfInst : core.ops.arith.Mul Self Self Self
|
||||
coreitertraitsaccumSumSelfSharedSelfInst : core.iter.traits.accum.Sum Self
|
||||
Self
|
||||
coreitertraitsaccumProductSelfSharedSelfInst : core.iter.traits.accum.Product
|
||||
Self Self
|
||||
coreopsarithAddAssignInst : core.ops.arith.AddAssign Self Self
|
||||
coreopsarithSubAssignInst : core.ops.arith.SubAssign Self Self
|
||||
coreopsarithMulAssignInst : core.ops.arith.MulAssign Self Self
|
||||
coreopsarithAddAssignSelfSharedSelfInst : core.ops.arith.AddAssign Self Self
|
||||
coreopsarithSubAssignSelfSharedSelfInst : core.ops.arith.SubAssign Self Self
|
||||
coreopsarithMulAssignSelfSharedSelfInst : core.ops.arith.MulAssign Self Self
|
||||
random : forall {T1 : Type} (rand_coreRngCoreInst : rand_core.RngCore T1), T1
|
||||
→ Result Self
|
||||
square : Self → Result Self
|
||||
double : Self → Result Self
|
||||
invert : Self → Result (subtle.CtOption Self)
|
||||
sqrt_ratio : Self → Self → Result (subtle.Choice × Self)
|
||||
sqrt : Self → Result (subtle.CtOption Self)
|
||||
pow_vartime : forall {S : Type} (coreconvertAsRefPSliceU64Inst :
|
||||
core.convert.AsRef S (Slice Std.U64)), Self → S → Result Self
|
||||
|
||||
/-- Trait declaration: [ff::PrimeField]
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ff-0.13.1/src/lib.rs', lines 195:0-195:39
|
||||
Name pattern: [ff::PrimeField]
|
||||
Visibility: public -/
|
||||
@[rust_trait "ff::PrimeField"
|
||||
(parentClauses := ["FieldInst", "coreconvertFromSelfU64Inst", "coremarkerCopyInst", "coredefaultDefaultInst", "coreconvertAsRefSelf_ReprSliceU8Inst", "coreconvertAsMutSelf_ReprSliceU8Inst"])
|
||||
(consts := ["MODULUS", "NUM_BITS", "CAPACITY", "TWO_INV", "MULTIPLICATIVE_GENERATOR", "S", "ROOT_OF_UNITY", "ROOT_OF_UNITY_INV", "DELTA"])]
|
||||
structure ff.PrimeField (Self : Type) (Self_Repr : Type) where
|
||||
MODULUS : Result Str
|
||||
NUM_BITS : Result Std.U32
|
||||
CAPACITY : Result Std.U32
|
||||
TWO_INV : Result Self
|
||||
MULTIPLICATIVE_GENERATOR : Result Self
|
||||
S : Result Std.U32
|
||||
ROOT_OF_UNITY : Result Self
|
||||
ROOT_OF_UNITY_INV : Result Self
|
||||
DELTA : Result Self
|
||||
FieldInst : ff.Field Self
|
||||
coreconvertFromSelfU64Inst : core.convert.From Self Std.U64
|
||||
coremarkerCopyInst : core.marker.Copy Self_Repr
|
||||
coredefaultDefaultInst : core.default.Default Self_Repr
|
||||
coreconvertAsRefSelf_ReprSliceU8Inst : core.convert.AsRef Self_Repr (Slice
|
||||
Std.U8)
|
||||
coreconvertAsMutSelf_ReprSliceU8Inst : core.convert.AsMut Self_Repr (Slice
|
||||
Std.U8)
|
||||
from_u128 : Std.U128 → Result Self
|
||||
from_repr : Self_Repr → Result (subtle.CtOption Self)
|
||||
to_repr : Self → Result Self_Repr
|
||||
is_odd : Self → Result subtle.Choice
|
||||
|
||||
/-- Trait declaration: [ff::WithSmallOrderMulGroup]
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ff-0.13.1/src/lib.rs', lines 358:0-358:57
|
||||
Name pattern: [ff::WithSmallOrderMulGroup]
|
||||
Visibility: public -/
|
||||
@[rust_trait "ff::WithSmallOrderMulGroup" (parentClauses := ["PrimeFieldInst"])
|
||||
(consts := ["ZETA"])]
|
||||
structure ff.WithSmallOrderMulGroup (Self : Type) (Self_Clause0_Repr : Type) (N
|
||||
: Std.U8) where
|
||||
ZETA : Result Self
|
||||
PrimeFieldInst : ff.PrimeField Self Self_Clause0_Repr
|
||||
|
||||
/-- Trait declaration: [ff::FromUniformBytes]
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ff-0.13.1/src/lib.rs', lines 444:0-444:54
|
||||
Name pattern: [ff::FromUniformBytes]
|
||||
Visibility: public -/
|
||||
@[rust_trait "ff::FromUniformBytes" (parentClauses := ["PrimeFieldInst"])]
|
||||
structure ff.FromUniformBytes (Self : Type) (Self_Clause0_Repr : Type) (N :
|
||||
Std.Usize) where
|
||||
PrimeFieldInst : ff.PrimeField Self Self_Clause0_Repr
|
||||
from_uniform_bytes : Array Std.U8 N → Result Self
|
||||
|
||||
/-- Trait declaration: [pasta_curves::arithmetic::fields::SqrtTableHelpers]
|
||||
Source: 'src/arithmetic/fields.rs', lines 20:0-29:1 -/
|
||||
structure arithmetic.fields.SqrtTableHelpers (Self : Type) (Self_Clause0_Repr :
|
||||
Type) where
|
||||
ffPrimeFieldInst : ff.PrimeField Self Self_Clause0_Repr
|
||||
pow_by_t_minus1_over2 : Self → Result Self
|
||||
get_lower_32 : Self → Result Std.U32
|
||||
|
||||
/-- [pasta_curves::fields::fp::Fp]
|
||||
Source: 'src/fields/fp.rs', lines 31:0-31:35
|
||||
Visibility: public -/
|
||||
@[reducible]
|
||||
def fields.fp.Fp := Array Std.U64 4#usize
|
||||
|
||||
end pasta_curves
|
||||
34
verification/gen/PallasFp/TypesExternal.lean
Normal file
34
verification/gen/PallasFp/TypesExternal.lean
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
-- Hand-written models for external types (derived from TypesExternal_Template.lean).
|
||||
-- [pasta_curves]: external types.
|
||||
--
|
||||
-- Modeling policy (same as the ed25519 repos):
|
||||
-- * `subtle.Choice` is MODELED as `Std.U8`. Rust invariant: the wrapped u8 is
|
||||
-- always 0 or 1 (subtle's documented contract). Every Choice produced by
|
||||
-- the models in FunsExternal.lean is literally 0 or 1, so if-then-else on
|
||||
-- `c.val = 0` is exact for every value the transpiled code can construct.
|
||||
-- * `subtle.CtOption T` is MODELED as a pair (value, is_some flag) — exactly
|
||||
-- the Rust struct layout (`CtOption { value: T, is_some: Choice }`).
|
||||
-- * `rand_core.error.Error` stays an opaque axiom: it is only reachable from
|
||||
-- the (deliberately opaque) `random`, outside every certificate cone.
|
||||
import Aeneas
|
||||
open Aeneas Aeneas.Std Result ControlFlow Error
|
||||
set_option linter.dupNamespace false
|
||||
set_option linter.hashCommand false
|
||||
set_option linter.unusedVariables false
|
||||
|
||||
set_option maxHeartbeats 1000000
|
||||
set_option maxRecDepth 2048
|
||||
|
||||
/-- [subtle::Choice] — MODEL: a u8 carrying the {0,1} invariant. -/
|
||||
@[reducible, rust_type "subtle::Choice"]
|
||||
def subtle.Choice : Type := Std.U8
|
||||
|
||||
/-- [subtle::CtOption] — MODEL: the Rust struct `{ value: T, is_some: Choice }`. -/
|
||||
@[rust_type "subtle::CtOption"]
|
||||
structure subtle.CtOption (T : Type) where
|
||||
value : T
|
||||
is_some : subtle.Choice
|
||||
|
||||
/-- [rand_core::error::Error] — AXIOM: only reachable from the opaque `random`. -/
|
||||
@[rust_type "rand_core::error::Error"]
|
||||
axiom rand_core.error.Error : Type
|
||||
36
verification/gen/PallasFp/TypesExternal_Template.lean
Normal file
36
verification/gen/PallasFp/TypesExternal_Template.lean
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
-- THIS FILE WAS AUTOMATICALLY GENERATED BY AENEAS
|
||||
-- [pasta_curves]: external types.
|
||||
-- This is a template file: rename it to "TypesExternal.lean" and fill the holes.
|
||||
import Aeneas
|
||||
open Aeneas Aeneas.Std Result ControlFlow Error
|
||||
set_option linter.dupNamespace false
|
||||
set_option linter.hashCommand false
|
||||
set_option linter.unusedVariables false
|
||||
|
||||
/- You can set the `maxHeartbeats` value with the `-max-heartbeats` CLI option -/
|
||||
set_option maxHeartbeats 1000000
|
||||
|
||||
/- You can set the `maxRecDepth` value with the `-max-recdepth` CLI option -/
|
||||
set_option maxRecDepth 2048
|
||||
|
||||
/-- [subtle::CtOption]
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs', lines 647:0-647:22
|
||||
Name pattern: [subtle::CtOption]
|
||||
Visibility: public -/
|
||||
@[rust_type "subtle::CtOption"]
|
||||
axiom subtle.CtOption (T : Type) : Type
|
||||
|
||||
/-- [subtle::Choice]
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs', lines 120:0-120:17
|
||||
Name pattern: [subtle::Choice]
|
||||
Visibility: public -/
|
||||
@[rust_type "subtle::Choice"]
|
||||
axiom subtle.Choice : Type
|
||||
|
||||
/-- [rand_core::error::Error]
|
||||
Source: '/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_core-0.6.4/src/error.rs', lines 21:0-21:16
|
||||
Name pattern: [rand_core::error::Error]
|
||||
Visibility: public -/
|
||||
@[rust_type "rand_core::error::Error"]
|
||||
axiom rand_core.error.Error : Type
|
||||
|
||||
Loading…
Reference in a new issue