Documentation

HexArith.Montgomery.Context

Compute R^2 mod p by repeated doubling in native-word arithmetic.

Equations
Instances For

    The R^2 mod p constant used to enter Montgomery form.

    Equations
    Instances For

      The executable r2OfModulus computes R^2 mod p for positive moduli.

      def MontCtx.mk (p : UInt64) (hp : p % 2 = 1) :

      Build the executable Montgomery context for an odd UInt64 modulus.

      Equations
      Instances For
        @[simp]
        theorem MontCtx.mk_p_odd (p : UInt64) (hp : p % 2 = 1) :
        = hp

        The oddness witness stored by MontCtx.mk.

        @[simp]
        theorem MontCtx.mk_p' (p : UInt64) (hp : p % 2 = 1) :
        (mk p hp).p' = montInv p

        The Montgomery inverse word stored by MontCtx.mk.

        @[simp]
        theorem MontCtx.mk_p'_eq (p : UInt64) (hp : p % 2 = 1) :

        The inverse-word correctness fact specialized to MontCtx.mk.

        @[simp]
        theorem MontCtx.mk_r2 (p : UInt64) (hp : p % 2 = 1) :
        (mk p hp).r2 = r2OfModulus p

        The R^2 mod p word stored by MontCtx.mk.

        @[simp]
        theorem MontCtx.mk_r2_eq (p : UInt64) (hp : p % 2 = 1) :

        The R^2 mod p correctness fact specialized to MontCtx.mk.

        @[simp]
        theorem MontCtx.p_odd_nat {p : UInt64} (ctx : MontCtx p) :
        p.toNat % 2 = 1

        View the odd-modulus assumption as a Nat-level parity fact.

        @[simp]
        theorem MontCtx.p_pos {p : UInt64} (ctx : MontCtx p) :
        0 < p.toNat

        An odd UInt64 modulus is positive at the Nat level.

        @[simp]
        theorem MontCtx.p_lt_R {p : UInt64} (_ctx : MontCtx p) :

        Every UInt64 modulus is below the Montgomery radix R = 2^64.

        @[simp]
        theorem MontCtx.mk_p_odd_nat (p : UInt64) (hp : p % 2 = 1) :
        p.toNat % 2 = 1

        The Nat-level oddness fact specialized to MontCtx.mk.

        @[simp]
        theorem MontCtx.mk_p_pos (p : UInt64) (hp : p % 2 = 1) :
        0 < p.toNat

        Positivity of a modulus equipped with MontCtx.mk.

        @[simp]
        theorem MontCtx.mk_p_lt_R (p : UInt64) (hp : p % 2 = 1) :

        The radix bound for a modulus equipped with MontCtx.mk.

        @[extern lean_hex_mont_to]
        def MontCtx.toMont {p : UInt64} (ctx : MontCtx p) (a : UInt64) :

        Convert a standard residue into Montgomery form.

        Equations
        Instances For
          @[extern lean_hex_mont_from]
          def MontCtx.fromMont {p : UInt64} (ctx : MontCtx p) (a : UInt64) :

          Convert a Montgomery residue back to the standard representation.

          Equations
          Instances For
            @[extern lean_hex_mont_mul]
            def MontCtx.mulMont {p : UInt64} (ctx : MontCtx p) (a b : UInt64) :

            Multiply two Montgomery residues, staying inside the Montgomery domain.

            Equations
            Instances For
              theorem MontCtx.cancel_word_mod_of_lt {p : UInt64} (ctx : MontCtx p) {x y : Nat} (hx : x < p.toNat) (hy : y < p.toNat) (h : x * UInt64.word % p.toNat = y * UInt64.word % p.toNat) :
              x = y

              Multiplication by word is injective on residues modulo p: since p is odd it is coprime to word = 2 ^ 64, so two reduced values x, y < p with x * word ≡ y * word (mod p) are equal. This is what lets the representative-mod-word characterisation pin down a unique mulMont value.

              Public because any word-modular residue layer built on this context (for example a Montgomery-form residue ring) needs the same cancellation to prove that its additive operations preserve the represented value.

              theorem MontCtx.fromMont_lt {p : UInt64} (ctx : MontCtx p) (a : UInt64) (ha : a < p) :
              ctx.fromMont a < p

              Converting a reduced Montgomery residue back to standard form is canonical.

              theorem MontCtx.fromMont_repr {p : UInt64} (ctx : MontCtx p) (a : UInt64) (ha : a < p) :

              fromMont removes one Montgomery radix factor from a reduced Montgomery residue.

              @[simp]
              theorem MontCtx.toNat_toMont {p : UInt64} (ctx : MontCtx p) (a : UInt64) (ha : a < p) :

              The Nat value of toMont is multiplication by the Montgomery radix.

              theorem MontCtx.toMont_lt {p : UInt64} (ctx : MontCtx p) (a : UInt64) (ha : a < p) :
              ctx.toMont a < p

              Montgomery conversion returns a canonical residue.

              theorem MontCtx.mulMont_lt {p : UInt64} (ctx : MontCtx p) (a b : UInt64) (ha : a < p) (hb : b < p) :
              ctx.mulMont a b < p

              Montgomery multiplication returns a canonical residue.

              theorem MontCtx.mulMont_repr {p : UInt64} (ctx : MontCtx p) (a b : UInt64) (ha : a < p) (hb : b < p) :
              (ctx.fromMont (ctx.mulMont a b)).toNat = (ctx.fromMont a).toNat * (ctx.fromMont b).toNat % p.toNat

              Montgomery multiplication preserves the represented residue product.

              @[simp]
              theorem MontCtx.fromMont_toMont {p : UInt64} (ctx : MontCtx p) (a : UInt64) (ha : a < p) :
              ctx.fromMont (ctx.toMont a) = a

              Converting into Montgomery form and back is the identity on reduced inputs.

              @[simp]
              theorem MontCtx.toNat_mulMont {p : UInt64} (ctx : MontCtx p) (a b : UInt64) (ha : a < p) (hb : b < p) :
              (ctx.fromMont (ctx.mulMont (ctx.toMont a) (ctx.toMont b))).toNat = a.toNat * b.toNat % p.toNat

              Montgomery multiplication computes modular multiplication after conversion.

              theorem MontCtx.mulMont_eq {p : UInt64} (ctx : MontCtx p) (a b : UInt64) (ha : a < p) (hb : b < p) :
              ctx.fromMont (ctx.mulMont (ctx.toMont a) (ctx.toMont b)) = UInt64.ofNat (a.toNat * b.toNat % p.toNat)

              User-facing equality form of Montgomery multiplication.

              @[simp]
              theorem MontCtx.fromMont_mulMont_toMont_zero_left {p : UInt64} (ctx : MontCtx p) (a : UInt64) (ha : a < p) :
              ctx.fromMont (ctx.mulMont (ctx.toMont 0) (ctx.toMont a)) = 0

              Multiplying by zero on the left in Montgomery form converts back to zero.

              @[simp]
              theorem MontCtx.fromMont_mulMont_toMont_zero_right {p : UInt64} (ctx : MontCtx p) (a : UInt64) (ha : a < p) :
              ctx.fromMont (ctx.mulMont (ctx.toMont a) (ctx.toMont 0)) = 0

              Multiplying by zero on the right in Montgomery form converts back to zero.

              Number of binary digits in a natural number.

              Equations
              Instances For
                def HexArith.powMont {p : UInt64} (ctx : MontCtx p) (base : UInt64) (n : Nat) :

                Exponentiate a Montgomery-form base by repeated squaring.

                Equations
                Instances For
                  def HexArith.powModWordOdd (a n : Nat) (p : UInt64) (hp : p % 2 = 1) :

                  Word-sized odd-modulus modular exponentiation via Montgomery arithmetic.

                  Equations
                  Instances For
                    def HexArith.powModNatGo (n p : Nat) :
                    NatNatNatNatNat

                    Tail-recursive Nat fallback for modular exponentiation.

                    Equations
                    Instances For
                      def HexArith.powModNat (a n p : Nat) :

                      Nat-level modular exponentiation by repeated squaring, with the same zero-modulus convention as powMod.

                      This is the kernel-facing specification of modular exponentiation: it and its recursion are @[expose], so proof terms that replay it (decide-style certificate checkers) reduce in the kernel. powMod is its runtime twin via powModNat_eq_powMod, so compiled callers of powModNat still take the Montgomery path for odd word-sized moduli.

                      Equations
                      Instances For
                        @[simp]

                        powModNat modulo zero returns zero, matching powMod.

                        theorem HexArith.powModNat_eq (a n p : Nat) (hp : 0 < p) :
                        powModNat a n p = a ^ n % p

                        powModNat_eq: for a positive modulus, powModNat a n p computes a ^ n % p.

                        def HexArith.powMod (a n p : Nat) :

                        Modular exponentiation by repeated squaring, using Montgomery arithmetic for odd UInt64 moduli and a direct Nat fallback otherwise.

                        This is the runtime twin of powModNat, the kernel-facing specification; powModNat_eq_powMod is the @[csimp] equality relating them.

                        Equations
                        • One or more equations did not get rendered due to their size.
                        Instances For
                          theorem HexArith.powMod_eq (a n p : Nat) (hp : p > 0) :
                          powMod a n p = a ^ n % p

                          powMod agrees with ordinary modular exponentiation.

                          @[simp]
                          theorem HexArith.powMod_modulus_zero (a n : Nat) :
                          powMod a n 0 = 0

                          Modular exponentiation modulo zero returns zero.

                          theorem HexArith.powMod_eq_powModNat (a n p : Nat) :
                          powMod a n p = powModNat a n p

                          The dispatching powMod and the Nat-level powModNat agree at every input, including modulus zero.

                          @[csimp]

                          powModNat is the kernel-facing specification and powMod its runtime twin: compiled code evaluating powModNat dispatches through powMod, taking the Montgomery path for odd word-sized moduli.

                          @[simp]
                          theorem HexArith.powMod_zero_exp (a p : Nat) (hp : p > 0) :
                          powMod a 0 p = 1 % p

                          Modular exponentiation with exponent zero returns the residue of 1.

                          @[simp]
                          theorem HexArith.powMod_one_exp (a p : Nat) (hp : p > 0) :
                          powMod a 1 p = a % p

                          Modular exponentiation with exponent one returns the reduced base.

                          @[simp]
                          theorem HexArith.powMod_zero_base (n p : Nat) (hp : p > 0) :
                          powMod 0 n p = 0 ^ n % p

                          Modular exponentiation with base zero returns the residue of 0 ^ n.

                          @[simp]
                          theorem HexArith.powMod_zero_base_of_pos_exp (n p : Nat) (hn : n > 0) (hp : p > 0) :
                          powMod 0 n p = 0

                          A positive power of zero is zero modulo any positive modulus.

                          @[simp]
                          theorem HexArith.powMod_one_base (n p : Nat) (hp : p > 0) :
                          powMod 1 n p = 1 % p

                          Modular exponentiation with base one returns the residue of 1.

                          @[simp]
                          theorem HexArith.powMod_modulus_one (a n : Nat) :
                          powMod a n 1 = 0

                          Modular exponentiation modulo one returns zero.

                          theorem HexArith.powMod_succ (a n p : Nat) (hp : p > 0) :
                          powMod a (n + 1) p = a * powMod a n p % p

                          Successor-exponent expansion for powMod: multiply by the base on the left and reduce.

                          @[simp]
                          theorem HexArith.powMod_mod_base (a n p : Nat) (hp : p > 0) :
                          powMod (a % p) n p = powMod a n p

                          Reducing the base before modular exponentiation does not change powMod.

                          theorem HexArith.powMod_mul_base (a b n p : Nat) (hp : p > 0) :
                          powMod (a * b) n p = powMod a n p * powMod b n p % p

                          Modular exponentiation is compatible with multiplying bases.

                          theorem HexArith.powMod_add_exp (a m n p : Nat) (hp : p > 0) :
                          powMod a (m + n) p = powMod a m p * powMod a n p % p

                          Exponent-addition expansion for powMod: combine two exponentiation steps by multiplying their reduced results.

                          theorem HexArith.powMod_add_exp_left (a m n p : Nat) (hp : p > 0) :
                          powMod a (m + n) p = powMod a n p * powMod a m p % p

                          Left-oriented companion of powMod_add_exp.

                          theorem HexArith.powMod_mul_exp (a m n p : Nat) (hp : p > 0) :
                          powMod a (m * n) p = powMod (powMod a m p) n p

                          Exponent-multiplication composition for powMod: an exponent product is a two-stage modular exponentiation.

                          theorem HexArith.powMod_mul_exp_swap (a m n p : Nat) (hp : p > 0) :
                          powMod a (m * n) p = powMod (powMod a n p) m p

                          Swap-oriented companion of powMod_mul_exp.