hex

8.4. Principal operations🔗

The ring operations add, subtract, negate, and multiply residues, re-reducing each result so the output is again a standard representative. The standard Add, Sub, Neg, and Mul instances on Hex.ZMod64 dispatch to these, so a + b, a - b, -a, and a * b work directly, and a Lean.Grind.CommRing instance lets the grind tactic reason about them.

🔗def

Add two reduced residues using wrapped machine-word addition plus one correction step when p < 2^64.

🔗def

Subtract two residues by adding the modular complement of the second and reducing mod p.

🔗def

The additive inverse represented by the complementary residue mod p.

🔗def

Multiply two reduced residues and reduce the product mod p.

The trusted runtime contract is the lean_hex_zmod64_mul extern, whose C body must agree with this pure Lean fallback.

Exponentiation uses repeated squaring, and inversion runs the extended-GCD helper from HexArith. For an element coprime to the modulus the result is the modular inverse.

🔗def
Hex.ZMod64.pow {p : } [Hex.ZMod64.Bounds p] (a : Hex.ZMod64 p) (n : ) : Hex.ZMod64 p
Hex.ZMod64.pow {p : } [Hex.ZMod64.Bounds p] (a : Hex.ZMod64 p) (n : ) : Hex.ZMod64 p

Raise a residue to a natural power using exponentiation by squaring.

The accumulator form keeps the executable path close to the intended downstream runtime usage while preserving a simple semantic contract.

🔗def

Compute a modular inverse candidate via the integer extended-GCD helper from hex-arith.

When a is coprime to p, this is the canonical inverse mod p; otherwise it still exposes the executable Bezout-derived residue needed by later algebraic layers.

8.4.1. Worked example: ring arithmetic🔗

The block below works in ZMod64 7. After supplying the Bounds 7 instance it builds two residues and runs the ring operations on them.

open Hex Hex.ZMod64 namespace HexModArithChapterRing instance : Bounds 7 := 0 < 7 All goals completed! 🐙, 7 UInt64.word All goals completed! 🐙 -- a = 3 and b = 5 as residues mod 7. def a : ZMod64 7 := ofNat 7 3 def b : ZMod64 7 := ofNat 7 5 -- Literals reduce: 10 ≡ 3 (mod 7). #guard a.toNat = 3 #guard (10 : ZMod64 7).toNat = 3 -- 3 + 5 = 8 ≡ 1. #guard (a + b).toNat = 1 -- 3 - 5 ≡ -2 ≡ 5. #guard (a - b).toNat = 5 -- 3 · 5 = 15 ≡ 1. #guard (a * b).toNat = 1 -- 3^5 = 243 ≡ 5. #guard (a ^ 5).toNat = 5 -- 3⁻¹ ≡ 5, since 3 · 5 ≡ 1. #guard (inv a).toNat = 5 #guard (inv a * a).toNat = 1 end HexModArithChapterRing