diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b2f5756..fb55e25 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,6 +72,10 @@ jobs: python3 scripts/gen_jubjub.py > CompElliptic/Fields/Jubjub.lean - name: Fail if the regenerated files differ from the committed ones run: git diff --exit-code CompElliptic/Fields/Pasta.lean CompElliptic/Fields/Jubjub.lean + # The AArch64 transcription is generated the same way, from the vendored assembly and + # reference vectors; the script also checks their recorded hashes. + - name: Check the AArch64 Pasta transcription is current + run: scripts/check_aarch64_pasta_mul.sh sage-checks: name: sage checks - Vélu certificates and Weil-derivation identities diff --git a/CompElliptic/Asm/AArch64/PastaMul.lean b/CompElliptic/Asm/AArch64/PastaMul.lean new file mode 100644 index 0000000..37ef609 --- /dev/null +++ b/CompElliptic/Asm/AArch64/PastaMul.lean @@ -0,0 +1,590 @@ +/- +Copyright (c) 2026 CompElliptic Contributors. +Released under the Apache License, Version 2.0, or the MIT license, at your option, +as described in the files LICENSE-APACHE and LICENSE-MIT. +Authors: Daira-Emma Hopwood +-/ +import CompElliptic.Asm.AArch64.Semantics + +/-! +# The Pasta Montgomery routines of `pasta_mul-armv8.S`, transcribed + +GENERATED by `scripts/gen_aarch64_pasta_mul.py` from +`CompElliptic/Asm/AArch64/vendor/pasta_mul-armv8.S`; do not edit by hand. Each definition +follows its routine instruction by instruction (the instruction is the trailing comment), +over the semantics of `CompElliptic.Asm.AArch64.Semantics`: registers are rebound by the +instructions that write them, `c` is the carry flag, `s` is the (result, carry) pair of the +instruction that last set both, argument limbs are read where the assembly loads them, and +the output limbs are bound where the assembly stores them. Bindings that nothing reads are +left as comments; the stack frame and the return address are not part of the model. See the +generator's docstring for what it checks. +-/ + +namespace CompElliptic.Asm.AArch64 + +/-- The shared reduction helper (`L$pasta_curves_mul_by_1_mont_pasta`): four Montgomery cancellation +steps on `t`, returning `(t + Q * p) / 2^256` for the `Q` they choose, without a final conditional +subtraction. `x10`-`x13` hold `t` and `x4` holds `inv` on entry; the modulus limbs are loaded +through `x2`. -/ +def mulBy1 (t modulus : Limbs) (inv : Nat) : Limbs := + let x10 := t.l0 -- argument + let x11 := t.l1 -- argument + let x12 := t.l2 -- argument + let x13 := t.l3 -- argument + let x4 := inv -- argument + let x3 := mulLo x4 x10 -- mul x3,x4,x10 + let x5 := modulus.l0 -- ldp x5,x6,[x2] + let x6 := modulus.l1 -- ldp x5,x6,[x2] + -- ldp x7,x8,[x2,#16]: x7 = modulus.l2 is never read + -- ldp x7,x8,[x2,#16]: x8 = modulus.l3 is never read + let x15 := mulLo x6 x3 -- mul x15,x6,x3 + let x17 := lsl x3 62 -- lsl x17,x3,#62 + let c := (subc x10 1 1).2 -- subs xzr,x10,#1 + let x14 := umulh x5 x3 -- umulh x14,x5,x3 + let s := addc x11 x15 c -- adcs x11,x11,x15 + let x11 := s.1 -- adcs x11,x11,x15 + let c := s.2 -- adcs x11,x11,x15 + let x15 := umulh x6 x3 -- umulh x15,x6,x3 + let s := addc x12 0 c -- adcs x12,x12,xzr + let x12 := s.1 -- adcs x12,x12,xzr + let c := s.2 -- adcs x12,x12,xzr + let s := addc x13 x17 c -- adcs x13,x13,x17 + let x13 := s.1 -- adcs x13,x13,x17 + let c := s.2 -- adcs x13,x13,x17 + let x17 := lsr x3 2 -- lsr x17,x3,#2 + let x9 := (addc 0 0 c).1 -- adc x9,xzr,xzr + let s := addc x11 x14 0 -- adds x10,x11,x14 + let x10 := s.1 -- adds x10,x11,x14 + let c := s.2 -- adds x10,x11,x14 + let s := addc x12 x15 c -- adcs x11,x12,x15 + let x11 := s.1 -- adcs x11,x12,x15 + let c := s.2 -- adcs x11,x12,x15 + let s := addc x13 0 c -- adcs x12,x13,xzr + let x12 := s.1 -- adcs x12,x13,xzr + let c := s.2 -- adcs x12,x13,xzr + let x3 := mulLo x4 x10 -- mul x3,x4,x10 + let x13 := (addc x9 x17 c).1 -- adc x13,x9,x17 + let x15 := mulLo x6 x3 -- mul x15,x6,x3 + let x17 := lsl x3 62 -- lsl x17,x3,#62 + let c := (subc x10 1 1).2 -- subs xzr,x10,#1 + let x14 := umulh x5 x3 -- umulh x14,x5,x3 + let s := addc x11 x15 c -- adcs x11,x11,x15 + let x11 := s.1 -- adcs x11,x11,x15 + let c := s.2 -- adcs x11,x11,x15 + let x15 := umulh x6 x3 -- umulh x15,x6,x3 + let s := addc x12 0 c -- adcs x12,x12,xzr + let x12 := s.1 -- adcs x12,x12,xzr + let c := s.2 -- adcs x12,x12,xzr + let s := addc x13 x17 c -- adcs x13,x13,x17 + let x13 := s.1 -- adcs x13,x13,x17 + let c := s.2 -- adcs x13,x13,x17 + let x17 := lsr x3 2 -- lsr x17,x3,#2 + let x9 := (addc 0 0 c).1 -- adc x9,xzr,xzr + let s := addc x11 x14 0 -- adds x10,x11,x14 + let x10 := s.1 -- adds x10,x11,x14 + let c := s.2 -- adds x10,x11,x14 + let s := addc x12 x15 c -- adcs x11,x12,x15 + let x11 := s.1 -- adcs x11,x12,x15 + let c := s.2 -- adcs x11,x12,x15 + let s := addc x13 0 c -- adcs x12,x13,xzr + let x12 := s.1 -- adcs x12,x13,xzr + let c := s.2 -- adcs x12,x13,xzr + let x3 := mulLo x4 x10 -- mul x3,x4,x10 + let x13 := (addc x9 x17 c).1 -- adc x13,x9,x17 + let x15 := mulLo x6 x3 -- mul x15,x6,x3 + let x17 := lsl x3 62 -- lsl x17,x3,#62 + let c := (subc x10 1 1).2 -- subs xzr,x10,#1 + let x14 := umulh x5 x3 -- umulh x14,x5,x3 + let s := addc x11 x15 c -- adcs x11,x11,x15 + let x11 := s.1 -- adcs x11,x11,x15 + let c := s.2 -- adcs x11,x11,x15 + let x15 := umulh x6 x3 -- umulh x15,x6,x3 + let s := addc x12 0 c -- adcs x12,x12,xzr + let x12 := s.1 -- adcs x12,x12,xzr + let c := s.2 -- adcs x12,x12,xzr + let s := addc x13 x17 c -- adcs x13,x13,x17 + let x13 := s.1 -- adcs x13,x13,x17 + let c := s.2 -- adcs x13,x13,x17 + let x17 := lsr x3 2 -- lsr x17,x3,#2 + let x9 := (addc 0 0 c).1 -- adc x9,xzr,xzr + let s := addc x11 x14 0 -- adds x10,x11,x14 + let x10 := s.1 -- adds x10,x11,x14 + let c := s.2 -- adds x10,x11,x14 + let s := addc x12 x15 c -- adcs x11,x12,x15 + let x11 := s.1 -- adcs x11,x12,x15 + let c := s.2 -- adcs x11,x12,x15 + let s := addc x13 0 c -- adcs x12,x13,xzr + let x12 := s.1 -- adcs x12,x13,xzr + let c := s.2 -- adcs x12,x13,xzr + let x3 := mulLo x4 x10 -- mul x3,x4,x10 + let x13 := (addc x9 x17 c).1 -- adc x13,x9,x17 + let x15 := mulLo x6 x3 -- mul x15,x6,x3 + let x17 := lsl x3 62 -- lsl x17,x3,#62 + let c := (subc x10 1 1).2 -- subs xzr,x10,#1 + let x14 := umulh x5 x3 -- umulh x14,x5,x3 + let s := addc x11 x15 c -- adcs x11,x11,x15 + let x11 := s.1 -- adcs x11,x11,x15 + let c := s.2 -- adcs x11,x11,x15 + let x15 := umulh x6 x3 -- umulh x15,x6,x3 + let s := addc x12 0 c -- adcs x12,x12,xzr + let x12 := s.1 -- adcs x12,x12,xzr + let c := s.2 -- adcs x12,x12,xzr + let s := addc x13 x17 c -- adcs x13,x13,x17 + let x13 := s.1 -- adcs x13,x13,x17 + let c := s.2 -- adcs x13,x13,x17 + let x17 := lsr x3 2 -- lsr x17,x3,#2 + let x9 := (addc 0 0 c).1 -- adc x9,xzr,xzr + let s := addc x11 x14 0 -- adds x10,x11,x14 + let x10 := s.1 -- adds x10,x11,x14 + let c := s.2 -- adds x10,x11,x14 + let s := addc x12 x15 c -- adcs x11,x12,x15 + let x11 := s.1 -- adcs x11,x12,x15 + let c := s.2 -- adcs x11,x12,x15 + let s := addc x13 0 c -- adcs x12,x13,xzr + let x12 := s.1 -- adcs x12,x13,xzr + let c := s.2 -- adcs x12,x13,xzr + let x13 := (addc x9 x17 c).1 -- adc x13,x9,x17 + ⟨x10, x11, x12, x13⟩ + +/-- `_pasta_curves_mul_mont_pasta`: Montgomery multiplication, `lhs * rhs * 2^-256 mod p`, with the +result stored through `x0`. -/ +def mulMont (lhs rhs modulus : Limbs) (inv : Nat) : Limbs := + let x4 := inv -- argument + let x10 := lhs.l0 -- ldp x10,x11,[x1] + let x11 := lhs.l1 -- ldp x10,x11,[x1] + let x9 := rhs.l0 -- ldr x9,[x2] + let x12 := lhs.l2 -- ldp x12,x13,[x1,#16] + let x13 := lhs.l3 -- ldp x12,x13,[x1,#16] + let x19 := mulLo x10 x9 -- mul x19,x10,x9 + let x5 := modulus.l0 -- ldp x5,x6,[x3] + let x6 := modulus.l1 -- ldp x5,x6,[x3] + let x20 := mulLo x11 x9 -- mul x20,x11,x9 + -- ldp x7,x8,[x3,#16]: x7 = modulus.l2 is never read + let x8 := modulus.l3 -- ldp x7,x8,[x3,#16] + let x21 := mulLo x12 x9 -- mul x21,x12,x9 + let x22 := mulLo x13 x9 -- mul x22,x13,x9 + let x14 := umulh x10 x9 -- umulh x14,x10,x9 + let x15 := umulh x11 x9 -- umulh x15,x11,x9 + let x3 := mulLo x4 x19 -- mul x3,x4,x19 + let x16 := umulh x12 x9 -- umulh x16,x12,x9 + let x17 := umulh x13 x9 -- umulh x17,x13,x9 + let s := addc x20 x14 0 -- adds x20,x20,x14 + let x20 := s.1 -- adds x20,x20,x14 + let c := s.2 -- adds x20,x20,x14 + let s := addc x21 x15 c -- adcs x21,x21,x15 + let x21 := s.1 -- adcs x21,x21,x15 + let c := s.2 -- adcs x21,x21,x15 + let x15 := mulLo x6 x3 -- mul x15,x6,x3 + let s := addc x22 x16 c -- adcs x22,x22,x16 + let x22 := s.1 -- adcs x22,x22,x16 + let c := s.2 -- adcs x22,x22,x16 + let x23 := (addc 0 x17 c).1 -- adc x23,xzr,x17 + let x17 := lsl x3 62 -- lsl x17,x3,#62 + let x9 := rhs.l1 -- ldr x9,[x2,8*1] + let c := (subc x19 1 1).2 -- subs xzr,x19,#1 + let x14 := umulh x5 x3 -- umulh x14,x5,x3 + let s := addc x20 x15 c -- adcs x20,x20,x15 + let x20 := s.1 -- adcs x20,x20,x15 + let c := s.2 -- adcs x20,x20,x15 + let x15 := umulh x6 x3 -- umulh x15,x6,x3 + let s := addc x21 0 c -- adcs x21,x21,xzr + let x21 := s.1 -- adcs x21,x21,xzr + let c := s.2 -- adcs x21,x21,xzr + let s := addc x22 x17 c -- adcs x22,x22,x17 + let x22 := s.1 -- adcs x22,x22,x17 + let c := s.2 -- adcs x22,x22,x17 + let x17 := lsr x3 2 -- lsr x17,x3,#2 + let x23 := (addc x23 0 c).1 -- adc x23,x23,xzr + let s := addc x20 x14 0 -- adds x19,x20,x14 + let x19 := s.1 -- adds x19,x20,x14 + let c := s.2 -- adds x19,x20,x14 + let x14 := mulLo x10 x9 -- mul x14,x10,x9 + let s := addc x21 x15 c -- adcs x20,x21,x15 + let x20 := s.1 -- adcs x20,x21,x15 + let c := s.2 -- adcs x20,x21,x15 + let x15 := mulLo x11 x9 -- mul x15,x11,x9 + let s := addc x22 0 c -- adcs x21,x22,xzr + let x21 := s.1 -- adcs x21,x22,xzr + let c := s.2 -- adcs x21,x22,xzr + let x16 := mulLo x12 x9 -- mul x16,x12,x9 + let s := addc x23 x17 c -- adcs x22,x23,x17 + let x22 := s.1 -- adcs x22,x23,x17 + let c := s.2 -- adcs x22,x23,x17 + let x17 := mulLo x13 x9 -- mul x17,x13,x9 + let x23 := (addc 0 0 c).1 -- adc x23,xzr,xzr + let s := addc x19 x14 0 -- adds x19,x19,x14 + let x19 := s.1 -- adds x19,x19,x14 + let c := s.2 -- adds x19,x19,x14 + let x14 := umulh x10 x9 -- umulh x14,x10,x9 + let s := addc x20 x15 c -- adcs x20,x20,x15 + let x20 := s.1 -- adcs x20,x20,x15 + let c := s.2 -- adcs x20,x20,x15 + let x15 := umulh x11 x9 -- umulh x15,x11,x9 + let s := addc x21 x16 c -- adcs x21,x21,x16 + let x21 := s.1 -- adcs x21,x21,x16 + let c := s.2 -- adcs x21,x21,x16 + let x3 := mulLo x4 x19 -- mul x3,x4,x19 + let x16 := umulh x12 x9 -- umulh x16,x12,x9 + let s := addc x22 x17 c -- adcs x22,x22,x17 + let x22 := s.1 -- adcs x22,x22,x17 + let c := s.2 -- adcs x22,x22,x17 + let x17 := umulh x13 x9 -- umulh x17,x13,x9 + let x23 := (addc x23 0 c).1 -- adc x23,x23,xzr + let s := addc x20 x14 0 -- adds x20,x20,x14 + let x20 := s.1 -- adds x20,x20,x14 + let c := s.2 -- adds x20,x20,x14 + let s := addc x21 x15 c -- adcs x21,x21,x15 + let x21 := s.1 -- adcs x21,x21,x15 + let c := s.2 -- adcs x21,x21,x15 + let x15 := mulLo x6 x3 -- mul x15,x6,x3 + let s := addc x22 x16 c -- adcs x22,x22,x16 + let x22 := s.1 -- adcs x22,x22,x16 + let c := s.2 -- adcs x22,x22,x16 + let x23 := (addc x23 x17 c).1 -- adc x23,x23,x17 + let x17 := lsl x3 62 -- lsl x17,x3,#62 + let x9 := rhs.l2 -- ldr x9,[x2,8*2] + let c := (subc x19 1 1).2 -- subs xzr,x19,#1 + let x14 := umulh x5 x3 -- umulh x14,x5,x3 + let s := addc x20 x15 c -- adcs x20,x20,x15 + let x20 := s.1 -- adcs x20,x20,x15 + let c := s.2 -- adcs x20,x20,x15 + let x15 := umulh x6 x3 -- umulh x15,x6,x3 + let s := addc x21 0 c -- adcs x21,x21,xzr + let x21 := s.1 -- adcs x21,x21,xzr + let c := s.2 -- adcs x21,x21,xzr + let s := addc x22 x17 c -- adcs x22,x22,x17 + let x22 := s.1 -- adcs x22,x22,x17 + let c := s.2 -- adcs x22,x22,x17 + let x17 := lsr x3 2 -- lsr x17,x3,#2 + let x23 := (addc x23 0 c).1 -- adc x23,x23,xzr + let s := addc x20 x14 0 -- adds x19,x20,x14 + let x19 := s.1 -- adds x19,x20,x14 + let c := s.2 -- adds x19,x20,x14 + let x14 := mulLo x10 x9 -- mul x14,x10,x9 + let s := addc x21 x15 c -- adcs x20,x21,x15 + let x20 := s.1 -- adcs x20,x21,x15 + let c := s.2 -- adcs x20,x21,x15 + let x15 := mulLo x11 x9 -- mul x15,x11,x9 + let s := addc x22 0 c -- adcs x21,x22,xzr + let x21 := s.1 -- adcs x21,x22,xzr + let c := s.2 -- adcs x21,x22,xzr + let x16 := mulLo x12 x9 -- mul x16,x12,x9 + let s := addc x23 x17 c -- adcs x22,x23,x17 + let x22 := s.1 -- adcs x22,x23,x17 + let c := s.2 -- adcs x22,x23,x17 + let x17 := mulLo x13 x9 -- mul x17,x13,x9 + let x23 := (addc 0 0 c).1 -- adc x23,xzr,xzr + let s := addc x19 x14 0 -- adds x19,x19,x14 + let x19 := s.1 -- adds x19,x19,x14 + let c := s.2 -- adds x19,x19,x14 + let x14 := umulh x10 x9 -- umulh x14,x10,x9 + let s := addc x20 x15 c -- adcs x20,x20,x15 + let x20 := s.1 -- adcs x20,x20,x15 + let c := s.2 -- adcs x20,x20,x15 + let x15 := umulh x11 x9 -- umulh x15,x11,x9 + let s := addc x21 x16 c -- adcs x21,x21,x16 + let x21 := s.1 -- adcs x21,x21,x16 + let c := s.2 -- adcs x21,x21,x16 + let x3 := mulLo x4 x19 -- mul x3,x4,x19 + let x16 := umulh x12 x9 -- umulh x16,x12,x9 + let s := addc x22 x17 c -- adcs x22,x22,x17 + let x22 := s.1 -- adcs x22,x22,x17 + let c := s.2 -- adcs x22,x22,x17 + let x17 := umulh x13 x9 -- umulh x17,x13,x9 + let x23 := (addc x23 0 c).1 -- adc x23,x23,xzr + let s := addc x20 x14 0 -- adds x20,x20,x14 + let x20 := s.1 -- adds x20,x20,x14 + let c := s.2 -- adds x20,x20,x14 + let s := addc x21 x15 c -- adcs x21,x21,x15 + let x21 := s.1 -- adcs x21,x21,x15 + let c := s.2 -- adcs x21,x21,x15 + let x15 := mulLo x6 x3 -- mul x15,x6,x3 + let s := addc x22 x16 c -- adcs x22,x22,x16 + let x22 := s.1 -- adcs x22,x22,x16 + let c := s.2 -- adcs x22,x22,x16 + let x23 := (addc x23 x17 c).1 -- adc x23,x23,x17 + let x17 := lsl x3 62 -- lsl x17,x3,#62 + let x9 := rhs.l3 -- ldr x9,[x2,8*3] + let c := (subc x19 1 1).2 -- subs xzr,x19,#1 + let x14 := umulh x5 x3 -- umulh x14,x5,x3 + let s := addc x20 x15 c -- adcs x20,x20,x15 + let x20 := s.1 -- adcs x20,x20,x15 + let c := s.2 -- adcs x20,x20,x15 + let x15 := umulh x6 x3 -- umulh x15,x6,x3 + let s := addc x21 0 c -- adcs x21,x21,xzr + let x21 := s.1 -- adcs x21,x21,xzr + let c := s.2 -- adcs x21,x21,xzr + let s := addc x22 x17 c -- adcs x22,x22,x17 + let x22 := s.1 -- adcs x22,x22,x17 + let c := s.2 -- adcs x22,x22,x17 + let x17 := lsr x3 2 -- lsr x17,x3,#2 + let x23 := (addc x23 0 c).1 -- adc x23,x23,xzr + let s := addc x20 x14 0 -- adds x19,x20,x14 + let x19 := s.1 -- adds x19,x20,x14 + let c := s.2 -- adds x19,x20,x14 + let x14 := mulLo x10 x9 -- mul x14,x10,x9 + let s := addc x21 x15 c -- adcs x20,x21,x15 + let x20 := s.1 -- adcs x20,x21,x15 + let c := s.2 -- adcs x20,x21,x15 + let x15 := mulLo x11 x9 -- mul x15,x11,x9 + let s := addc x22 0 c -- adcs x21,x22,xzr + let x21 := s.1 -- adcs x21,x22,xzr + let c := s.2 -- adcs x21,x22,xzr + let x16 := mulLo x12 x9 -- mul x16,x12,x9 + let s := addc x23 x17 c -- adcs x22,x23,x17 + let x22 := s.1 -- adcs x22,x23,x17 + let c := s.2 -- adcs x22,x23,x17 + let x17 := mulLo x13 x9 -- mul x17,x13,x9 + let x23 := (addc 0 0 c).1 -- adc x23,xzr,xzr + let s := addc x19 x14 0 -- adds x19,x19,x14 + let x19 := s.1 -- adds x19,x19,x14 + let c := s.2 -- adds x19,x19,x14 + let x14 := umulh x10 x9 -- umulh x14,x10,x9 + let s := addc x20 x15 c -- adcs x20,x20,x15 + let x20 := s.1 -- adcs x20,x20,x15 + let c := s.2 -- adcs x20,x20,x15 + let x15 := umulh x11 x9 -- umulh x15,x11,x9 + let s := addc x21 x16 c -- adcs x21,x21,x16 + let x21 := s.1 -- adcs x21,x21,x16 + let c := s.2 -- adcs x21,x21,x16 + let x3 := mulLo x4 x19 -- mul x3,x4,x19 + let x16 := umulh x12 x9 -- umulh x16,x12,x9 + let s := addc x22 x17 c -- adcs x22,x22,x17 + let x22 := s.1 -- adcs x22,x22,x17 + let c := s.2 -- adcs x22,x22,x17 + let x17 := umulh x13 x9 -- umulh x17,x13,x9 + let x23 := (addc x23 0 c).1 -- adc x23,x23,xzr + let s := addc x20 x14 0 -- adds x20,x20,x14 + let x20 := s.1 -- adds x20,x20,x14 + let c := s.2 -- adds x20,x20,x14 + let s := addc x21 x15 c -- adcs x21,x21,x15 + let x21 := s.1 -- adcs x21,x21,x15 + let c := s.2 -- adcs x21,x21,x15 + let x15 := mulLo x6 x3 -- mul x15,x6,x3 + let s := addc x22 x16 c -- adcs x22,x22,x16 + let x22 := s.1 -- adcs x22,x22,x16 + let c := s.2 -- adcs x22,x22,x16 + let x23 := (addc x23 x17 c).1 -- adc x23,x23,x17 + let x17 := lsl x3 62 -- lsl x17,x3,#62 + let c := (subc x19 1 1).2 -- subs xzr,x19,#1 + let x14 := umulh x5 x3 -- umulh x14,x5,x3 + let s := addc x20 x15 c -- adcs x20,x20,x15 + let x20 := s.1 -- adcs x20,x20,x15 + let c := s.2 -- adcs x20,x20,x15 + let x15 := umulh x6 x3 -- umulh x15,x6,x3 + let s := addc x21 0 c -- adcs x21,x21,xzr + let x21 := s.1 -- adcs x21,x21,xzr + let c := s.2 -- adcs x21,x21,xzr + let s := addc x22 x17 c -- adcs x22,x22,x17 + let x22 := s.1 -- adcs x22,x22,x17 + let c := s.2 -- adcs x22,x22,x17 + let x17 := lsr x3 2 -- lsr x17,x3,#2 + let x23 := (addc x23 0 c).1 -- adc x23,x23,xzr + let s := addc x20 x14 0 -- adds x19,x20,x14 + let x19 := s.1 -- adds x19,x20,x14 + let c := s.2 -- adds x19,x20,x14 + let s := addc x21 x15 c -- adcs x20,x21,x15 + let x20 := s.1 -- adcs x20,x21,x15 + let c := s.2 -- adcs x20,x21,x15 + let s := addc x22 0 c -- adcs x21,x22,xzr + let x21 := s.1 -- adcs x21,x22,xzr + let c := s.2 -- adcs x21,x22,xzr + let s := addc x23 x17 c -- adcs x22,x23,x17 + let x22 := s.1 -- adcs x22,x23,x17 + let c := s.2 -- adcs x22,x23,x17 + let x23 := (addc 0 0 c).1 -- adc x23,xzr,xzr + let s := subc x19 x5 1 -- subs x14,x19,x5 + let x14 := s.1 -- subs x14,x19,x5 + let c := s.2 -- subs x14,x19,x5 + let s := subc x20 x6 c -- sbcs x15,x20,x6 + let x15 := s.1 -- sbcs x15,x20,x6 + let c := s.2 -- sbcs x15,x20,x6 + let s := subc x21 0 c -- sbcs x16,x21,xzr + let x16 := s.1 -- sbcs x16,x21,xzr + let c := s.2 -- sbcs x16,x21,xzr + let s := subc x22 x8 c -- sbcs x17,x22,x8 + let x17 := s.1 -- sbcs x17,x22,x8 + let c := s.2 -- sbcs x17,x22,x8 + let c := (subc x23 0 c).2 -- sbcs xzr,x23,xzr + let x19 := cselLo c x19 x14 -- csel x19,x19,x14,lo + let x20 := cselLo c x20 x15 -- csel x20,x20,x15,lo + let x21 := cselLo c x21 x16 -- csel x21,x21,x16,lo + let x22 := cselLo c x22 x17 -- csel x22,x22,x17,lo + let out0 := x19 -- stp x19,x20,[x0] + let out1 := x20 -- stp x19,x20,[x0] + let out2 := x21 -- stp x21,x22,[x0,#16] + let out3 := x22 -- stp x21,x22,[x0,#16] + ⟨out0, out1, out2, out3⟩ + +/-- `_pasta_curves_sqr_mont_pasta`: Montgomery squaring, `value^2 * 2^-256 mod p`. -/ +def sqrMont (value modulus : Limbs) (inv : Nat) : Limbs := + let x3 := inv -- argument + let x5 := value.l0 -- ldp x5,x6,[x1] + let x6 := value.l1 -- ldp x5,x6,[x1] + let x7 := value.l2 -- ldp x7,x8,[x1,#16] + let x8 := value.l3 -- ldp x7,x8,[x1,#16] + let x4 := x3 -- mov x4,x3 + let x11 := mulLo x6 x5 -- mul x11,x6,x5 + let x15 := umulh x6 x5 -- umulh x15,x6,x5 + let x12 := mulLo x7 x5 -- mul x12,x7,x5 + let x16 := umulh x7 x5 -- umulh x16,x7,x5 + let x13 := mulLo x8 x5 -- mul x13,x8,x5 + let x19 := umulh x8 x5 -- umulh x19,x8,x5 + let s := addc x12 x15 0 -- adds x12,x12,x15 + let x12 := s.1 -- adds x12,x12,x15 + let c := s.2 -- adds x12,x12,x15 + let x14 := mulLo x7 x6 -- mul x14,x7,x6 + let x15 := umulh x7 x6 -- umulh x15,x7,x6 + let s := addc x13 x16 c -- adcs x13,x13,x16 + let x13 := s.1 -- adcs x13,x13,x16 + let c := s.2 -- adcs x13,x13,x16 + let x16 := mulLo x8 x6 -- mul x16,x8,x6 + let x17 := umulh x8 x6 -- umulh x17,x8,x6 + let x19 := (addc x19 0 c).1 -- adc x19,x19,xzr + let x20 := mulLo x8 x7 -- mul x20,x8,x7 + let x21 := umulh x8 x7 -- umulh x21,x8,x7 + let s := addc x15 x16 0 -- adds x15,x15,x16 + let x15 := s.1 -- adds x15,x15,x16 + let c := s.2 -- adds x15,x15,x16 + let x10 := mulLo x5 x5 -- mul x10,x5,x5 + let x16 := (addc x17 0 c).1 -- adc x16,x17,xzr + let s := addc x13 x14 0 -- adds x13,x13,x14 + let x13 := s.1 -- adds x13,x13,x14 + let c := s.2 -- adds x13,x13,x14 + let x5 := umulh x5 x5 -- umulh x5,x5,x5 + let s := addc x19 x15 c -- adcs x19,x19,x15 + let x19 := s.1 -- adcs x19,x19,x15 + let c := s.2 -- adcs x19,x19,x15 + let x15 := mulLo x6 x6 -- mul x15,x6,x6 + let s := addc x20 x16 c -- adcs x20,x20,x16 + let x20 := s.1 -- adcs x20,x20,x16 + let c := s.2 -- adcs x20,x20,x16 + let x6 := umulh x6 x6 -- umulh x6,x6,x6 + let x21 := (addc x21 0 c).1 -- adc x21,x21,xzr + let s := addc x11 x11 0 -- adds x11,x11,x11 + let x11 := s.1 -- adds x11,x11,x11 + let c := s.2 -- adds x11,x11,x11 + let x16 := mulLo x7 x7 -- mul x16,x7,x7 + let s := addc x12 x12 c -- adcs x12,x12,x12 + let x12 := s.1 -- adcs x12,x12,x12 + let c := s.2 -- adcs x12,x12,x12 + let x7 := umulh x7 x7 -- umulh x7,x7,x7 + let s := addc x13 x13 c -- adcs x13,x13,x13 + let x13 := s.1 -- adcs x13,x13,x13 + let c := s.2 -- adcs x13,x13,x13 + let x17 := mulLo x8 x8 -- mul x17,x8,x8 + let s := addc x19 x19 c -- adcs x19,x19,x19 + let x19 := s.1 -- adcs x19,x19,x19 + let c := s.2 -- adcs x19,x19,x19 + let x8 := umulh x8 x8 -- umulh x8,x8,x8 + let s := addc x20 x20 c -- adcs x20,x20,x20 + let x20 := s.1 -- adcs x20,x20,x20 + let c := s.2 -- adcs x20,x20,x20 + let s := addc x21 x21 c -- adcs x21,x21,x21 + let x21 := s.1 -- adcs x21,x21,x21 + let c := s.2 -- adcs x21,x21,x21 + let x22 := (addc 0 0 c).1 -- adc x22,xzr,xzr + let s := addc x11 x5 0 -- adds x11,x11,x5 + let x11 := s.1 -- adds x11,x11,x5 + let c := s.2 -- adds x11,x11,x5 + let s := addc x12 x15 c -- adcs x12,x12,x15 + let x12 := s.1 -- adcs x12,x12,x15 + let c := s.2 -- adcs x12,x12,x15 + let s := addc x13 x6 c -- adcs x13,x13,x6 + let x13 := s.1 -- adcs x13,x13,x6 + let c := s.2 -- adcs x13,x13,x6 + let s := addc x19 x16 c -- adcs x19,x19,x16 + let x19 := s.1 -- adcs x19,x19,x16 + let c := s.2 -- adcs x19,x19,x16 + let s := addc x20 x7 c -- adcs x20,x20,x7 + let x20 := s.1 -- adcs x20,x20,x7 + let c := s.2 -- adcs x20,x20,x7 + let s := addc x21 x17 c -- adcs x21,x21,x17 + let x21 := s.1 -- adcs x21,x21,x17 + let c := s.2 -- adcs x21,x21,x17 + let x22 := (addc x22 x8 c).1 -- adc x22,x22,x8 + let r := mulBy1 ⟨x10, x11, x12, x13⟩ modulus x4 -- bl L$pasta_curves_mul_by_1_mont_pasta + let x10 := r.l0 -- helper output + let x11 := r.l1 -- helper output + let x12 := r.l2 -- helper output + let x13 := r.l3 -- helper output + let x5 := modulus.l0 -- loaded by the helper + let x6 := modulus.l1 -- loaded by the helper + let x7 := modulus.l2 -- loaded by the helper + let x8 := modulus.l3 -- loaded by the helper + let s := addc x10 x19 0 -- adds x10,x10,x19 + let x10 := s.1 -- adds x10,x10,x19 + let c := s.2 -- adds x10,x10,x19 + let s := addc x11 x20 c -- adcs x11,x11,x20 + let x11 := s.1 -- adcs x11,x11,x20 + let c := s.2 -- adcs x11,x11,x20 + let s := addc x12 x21 c -- adcs x12,x12,x21 + let x12 := s.1 -- adcs x12,x12,x21 + let c := s.2 -- adcs x12,x12,x21 + let s := addc x13 x22 c -- adcs x13,x13,x22 + let x13 := s.1 -- adcs x13,x13,x22 + let c := s.2 -- adcs x13,x13,x22 + let x19 := (addc 0 0 c).1 -- adc x19,xzr,xzr + let s := subc x10 x5 1 -- subs x14,x10,x5 + let x14 := s.1 -- subs x14,x10,x5 + let c := s.2 -- subs x14,x10,x5 + let s := subc x11 x6 c -- sbcs x15,x11,x6 + let x15 := s.1 -- sbcs x15,x11,x6 + let c := s.2 -- sbcs x15,x11,x6 + let s := subc x12 x7 c -- sbcs x16,x12,x7 + let x16 := s.1 -- sbcs x16,x12,x7 + let c := s.2 -- sbcs x16,x12,x7 + let s := subc x13 x8 c -- sbcs x17,x13,x8 + let x17 := s.1 -- sbcs x17,x13,x8 + let c := s.2 -- sbcs x17,x13,x8 + let c := (subc x19 0 c).2 -- sbcs xzr,x19,xzr + let x10 := cselLo c x10 x14 -- csel x10,x10,x14,lo + let x11 := cselLo c x11 x15 -- csel x11,x11,x15,lo + let x12 := cselLo c x12 x16 -- csel x12,x12,x16,lo + let x13 := cselLo c x13 x17 -- csel x13,x13,x17,lo + let out0 := x10 -- stp x10,x11,[x0] + let out1 := x11 -- stp x10,x11,[x0] + let out2 := x12 -- stp x12,x13,[x0,#16] + let out3 := x13 -- stp x12,x13,[x0,#16] + ⟨out0, out1, out2, out3⟩ + +/-- `_pasta_curves_from_mont_pasta`: conversion out of Montgomery form, `value * 2^-256 mod p`. -/ +def fromMont (value modulus : Limbs) (inv : Nat) : Limbs := + let x3 := inv -- argument + let x4 := x3 -- mov x4,x3 + let x10 := value.l0 -- ldp x10,x11,[x1] + let x11 := value.l1 -- ldp x10,x11,[x1] + let x12 := value.l2 -- ldp x12,x13,[x1,#16] + let x13 := value.l3 -- ldp x12,x13,[x1,#16] + let r := mulBy1 ⟨x10, x11, x12, x13⟩ modulus x4 -- bl L$pasta_curves_mul_by_1_mont_pasta + let x10 := r.l0 -- helper output + let x11 := r.l1 -- helper output + let x12 := r.l2 -- helper output + let x13 := r.l3 -- helper output + let x5 := modulus.l0 -- loaded by the helper + let x6 := modulus.l1 -- loaded by the helper + let x7 := modulus.l2 -- loaded by the helper + let x8 := modulus.l3 -- loaded by the helper + let s := subc x10 x5 1 -- subs x14,x10,x5 + let x14 := s.1 -- subs x14,x10,x5 + let c := s.2 -- subs x14,x10,x5 + let s := subc x11 x6 c -- sbcs x15,x11,x6 + let x15 := s.1 -- sbcs x15,x11,x6 + let c := s.2 -- sbcs x15,x11,x6 + let s := subc x12 x7 c -- sbcs x16,x12,x7 + let x16 := s.1 -- sbcs x16,x12,x7 + let c := s.2 -- sbcs x16,x12,x7 + let s := subc x13 x8 c -- sbcs x17,x13,x8 + let x17 := s.1 -- sbcs x17,x13,x8 + let c := s.2 -- sbcs x17,x13,x8 + let x10 := cselLo c x10 x14 -- csel x10,x10,x14,lo + let x11 := cselLo c x11 x15 -- csel x11,x11,x15,lo + let x12 := cselLo c x12 x16 -- csel x12,x12,x16,lo + let x13 := cselLo c x13 x17 -- csel x13,x13,x17,lo + let out0 := x10 -- stp x10,x11,[x0] + let out1 := x11 -- stp x10,x11,[x0] + let out2 := x12 -- stp x12,x13,[x0,#16] + let out3 := x13 -- stp x12,x13,[x0,#16] + ⟨out0, out1, out2, out3⟩ + +end CompElliptic.Asm.AArch64 diff --git a/CompElliptic/Asm/AArch64/PastaMulSpec.lean b/CompElliptic/Asm/AArch64/PastaMulSpec.lean new file mode 100644 index 0000000..22973cb --- /dev/null +++ b/CompElliptic/Asm/AArch64/PastaMulSpec.lean @@ -0,0 +1,2737 @@ +/- +Copyright (c) 2026 CompElliptic Contributors. +Released under the Apache License, Version 2.0, or the MIT license, at your option, +as described in the files LICENSE-APACHE and LICENSE-MIT. +Authors: Daira-Emma Hopwood +-/ +import CompElliptic.Asm.AArch64.PastaMul +import Mathlib.Data.Nat.ModEq +import Mathlib.Tactic.Ring +import Mathlib.Tactic.NormNum +import Mathlib.Tactic.ClearExcept + +/-! +# Correctness of the transcribed Pasta Montgomery routines + +Each theorem here is proved over the transcription in `PastaMul.lean`, instruction by +instruction. The proof of a routine begins by unfolding it in the hypothesis that names its +result; then, for every instruction, its `let`s are extracted from that hypothesis under unique +names, the defining equation of its result (by `rfl`, in `%`/`/` form) and the linear facts that +follow from it (each an instance of one lemma) are recorded, and the locals' values are cleared. +Those lines are generated by +`scripts/gen_aarch64_pasta_mul.py --skeleton ` and must not be edited; the +hand-written parts are the theorem statements and the `-- BEGIN ... -- END` blocks, which +supply what the instruction stream alone does not: the Montgomery round invariants where they +hold, the contract of a called routine, and the final case analysis. +`scripts/check_aarch64_pasta_mul.sh` strips the blocks and checks that what remains is the +current skeleton. + +The moduli are assumed in the shape the code hard-codes: limbs `[p0, p1, 0, 2^62]`, with +`inv * p0 ≡ -1 (mod 2^64)`. +-/ + +namespace CompElliptic.Asm.AArch64 + +-- BEGIN cancel_low +/-- The Montgomery cancellation: with `inv * p0 ≡ -1 (mod 2^64)` and `q = inv * t0 mod 2^64`, the +low limb of `t0 + p0 * q` is zero. -/ +theorem cancel_low (t0 inv p0 : Nat) (h : (inv * p0 + 1) % 2^64 = 0) : + (t0 + p0 * (inv * t0 % 2^64) % 2^64) % 2^64 = 0 := by + have key : (t0 + p0 * (inv * t0)) % 2^64 = 0 := by + have : t0 + p0 * (inv * t0) = t0 * (inv * p0 + 1) := by ring + rw [this, Nat.mul_mod, h]; simp + have h1 : inv * t0 % 2^64 ≡ inv * t0 [MOD 2^64] := Nat.mod_modEq _ _ + have h2 : p0 * (inv * t0 % 2^64) % 2^64 ≡ p0 * (inv * t0) [MOD 2^64] := + (Nat.mod_modEq _ _).trans (Nat.ModEq.mul_left p0 h1) + have h3 : t0 + p0 * (inv * t0 % 2^64) % 2^64 ≡ t0 + p0 * (inv * t0) [MOD 2^64] := + Nat.ModEq.add_left t0 h2 + exact Eq.trans h3 key +-- END cancel_low + +-- BEGIN skeleton lemmas +/-! The generated skeleton derives its per-instruction facts from these lemmas and from +`Nat.mod_add_div`, `Nat.mod_lt`, and `Nat.div_lt_of_lt_mul`. -/ + +/-- The carry out of an addition of two limbs and a carry is at most `1`. -/ +theorem addc_carry_le_one (a b cin : Nat) (ha : a < 2^64) (hb : b < 2^64) (hc : cin ≤ 1) : + (a + b + cin) / 2^64 ≤ 1 := by omega + +/-- A subtraction with borrow, as the assembly's `subs`/`sbcs` form it: its result and carry +satisfy `result + 2^64 * carry + b + 1 = a + 2^64 + cin`, since `b + (1 - cin) ≤ a + 2^64` keeps +the difference from truncating. -/ +theorem subc_lin (a b cin : Nat) (hb : b < 2^64) (hc : cin ≤ 1) : + (a + 2^64 - b - (1 - cin)) % 2^64 + 2^64 * ((a + 2^64 - b - (1 - cin)) / 2^64) + b + 1 + = a + 2^64 + cin := by omega + +/-- The carry (no-borrow flag) of a subtraction is at most `1`. -/ +theorem subc_carry_le_one (a b cin : Nat) (ha : a < 2^64) : + (a + 2^64 - b - (1 - cin)) / 2^64 ≤ 1 := by omega + +/-- The carry of a subtraction is set exactly when no borrow occurs. -/ +theorem subc_carry_cases (a b cin c : Nat) (hc : c = (a + 2^64 - b - (1 - cin)) / 2^64) + (ha : a < 2^64) (hb : b < 2^64) (hcin : cin ≤ 1) : + (c = 1 ∧ b + 1 ≤ a + cin) ∨ (c = 0 ∧ a + cin < b + 1) := by omega + +/-- `lsl #62` and `lsr #2` split a limb at its second bit. -/ +theorem lsl62_lsr2_split (a : Nat) : a * 2^62 % 2^64 + 2^64 * (a / 2^2) = a * 2^62 := by omega +-- END skeleton lemmas + +-- BEGIN mulBy1_spec statement +/-- The shared reduction helper computes `(t + Q * p) / 2^256` for some `Q < 2^256`, with the +result in range, for any four-limb `t`. Since `Q < 2^256`, the result is congruent to +`t * 2^-256` modulo `p` and is below `p + t / 2^256 < p + 1`. -/ +theorem mulBy1_spec (t modulus : Limbs) (inv : Nat) (ht : t.Bounded) (hm : modulus.Bounded) + (hshape : modulus.l2 = 0 ∧ modulus.l3 = 2^62) + (hinv_lt : inv < 2^64) (hinv : (inv * modulus.l0 + 1) % 2^64 = 0) : + ∀ r, r = mulBy1 t modulus inv → + r.Bounded ∧ ∃ Q, Q < 2^256 ∧ 2^256 * r.toNat = t.toNat + Q * modulus.toNat := by + intro r hr +-- END mulBy1_spec statement + -- generated skeleton for `mulBy1`: do not edit between the annotations + unfold mulBy1 at hr + lift_lets at hr + -- x10: argument + extract_lets +onlyGivenNames x10 at hr + have e_x10 : x10 = t.l0 := rfl + clear_value x10 + have b_x10 : x10 < 2^64 := by rw [e_x10]; exact ht.1 + -- x11: argument + extract_lets +onlyGivenNames x11 at hr + have e_x11 : x11 = t.l1 := rfl + clear_value x11 + have b_x11 : x11 < 2^64 := by rw [e_x11]; exact ht.2.1 + -- x12: argument + extract_lets +onlyGivenNames x12 at hr + have e_x12 : x12 = t.l2 := rfl + clear_value x12 + have b_x12 : x12 < 2^64 := by rw [e_x12]; exact ht.2.2.1 + -- x13: argument + extract_lets +onlyGivenNames x13 at hr + have e_x13 : x13 = t.l3 := rfl + clear_value x13 + have b_x13 : x13 < 2^64 := by rw [e_x13]; exact ht.2.2.2 + -- x4: argument + extract_lets +onlyGivenNames x4 at hr + have e_x4 : x4 = inv := rfl + clear_value x4 + have b_x4 : x4 < 2^64 := by rw [e_x4]; exact hinv_lt + -- x3: mul x3,x4,x10 + extract_lets +onlyGivenNames x3 at hr + have e_x3 : x3 = x4 * x10 % 2^64 := rfl + clear_value x3 + have b_x3 : x3 < 2^64 := by rw [e_x3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x5: ldp x5,x6,[x2] + extract_lets +onlyGivenNames x5 at hr + have e_x5 : x5 = modulus.l0 := rfl + clear_value x5 + have b_x5 : x5 < 2^64 := by rw [e_x5]; exact hm.1 + -- x6: ldp x5,x6,[x2] + extract_lets +onlyGivenNames x6 at hr + have e_x6 : x6 = modulus.l1 := rfl + clear_value x6 + have b_x6 : x6 < 2^64 := by rw [e_x6]; exact hm.2.1 + -- x15: mul x15,x6,x3 + extract_lets +onlyGivenNames x15 at hr + have e_x15 : x15 = x6 * x3 % 2^64 := rfl + clear_value x15 + have b_x15 : x15 < 2^64 := by rw [e_x15]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x17: lsl x17,x3,#62 + extract_lets +onlyGivenNames x17 at hr + have e_x17 : x17 = x3 * 2^62 % 2^64 := rfl + clear_value x17 + have b_x17 : x17 < 2^64 := by rw [e_x17]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- c: subs xzr,x10,#1 + extract_lets +onlyGivenNames c at hr + have e_c : c = (x10 + 2^64 - 1 - (1 - 1)) / 2^64 := rfl + clear_value c + have b_c : c ≤ 1 := by rw [e_c]; exact subc_carry_le_one x10 1 1 b_x10 + have l_c : (c = 1 ∧ 1 + 1 ≤ x10 + 1) ∨ (c = 0 ∧ x10 + 1 < 1 + 1) := + subc_carry_cases x10 1 1 _ e_c b_x10 (by decide) (by decide) + clear e_c + -- x14: umulh x14,x5,x3 + extract_lets +onlyGivenNames x14 at hr + have e_x14 : x14 = x5 * x3 / 2^64 := rfl + clear_value x14 + have p_x14 : x5 * x3 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x5 b_x3 + have b_x14 : x14 < 2^64 := by rw [e_x14]; exact Nat.div_lt_of_lt_mul p_x14 + obtain ⟨lo_x14, b_lo_x14, d_x14⟩ : + ∃ lo, lo < 2^64 ∧ lo + 2^64 * x14 = x5 * x3 := + ⟨x5 * x3 % 2^64, Nat.mod_lt _ (Nat.two_pow_pos _), + by rw [e_x14]; exact Nat.mod_add_div _ _⟩ + clear e_x14 + -- x11_1: adcs x11,x11,x15 + extract_lets +onlyGivenNames s x11_1 c_1 at hr + have e_x11_1 : x11_1 = (x11 + x15 + c) % 2^64 := rfl + have e_c_1 : c_1 = (x11 + x15 + c) / 2^64 := rfl + clear_value s x11_1 c_1 + have l_x11_1 : x11_1 + 2^64 * c_1 = x11 + x15 + c := by + rw [e_x11_1, e_c_1]; exact Nat.mod_add_div _ _ + have b_x11_1 : x11_1 < 2^64 := by rw [e_x11_1]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_1 : c_1 ≤ 1 := by + rw [e_c_1]; exact addc_carry_le_one x11 x15 c b_x11 b_x15 b_c + clear e_x11_1 e_c_1 + -- x15_1: umulh x15,x6,x3 + extract_lets +onlyGivenNames x15_1 at hr + have e_x15_1 : x15_1 = x6 * x3 / 2^64 := rfl + clear_value x15_1 + have p_x15_1 : x6 * x3 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x6 b_x3 + have b_x15_1 : x15_1 < 2^64 := by rw [e_x15_1]; exact Nat.div_lt_of_lt_mul p_x15_1 + have d_x15_1 : x15 + 2^64 * x15_1 = x6 * x3 := by + rw [e_x15, e_x15_1]; exact Nat.mod_add_div _ _ + clear e_x15 e_x15_1 + -- x12_1: adcs x12,x12,xzr + extract_lets +onlyGivenNames s_1 x12_1 c_2 at hr + have e_x12_1 : x12_1 = (x12 + 0 + c_1) % 2^64 := rfl + have e_c_2 : c_2 = (x12 + 0 + c_1) / 2^64 := rfl + clear_value s_1 x12_1 c_2 + have l_x12_1 : x12_1 + 2^64 * c_2 = x12 + 0 + c_1 := by + rw [e_x12_1, e_c_2]; exact Nat.mod_add_div _ _ + have b_x12_1 : x12_1 < 2^64 := by rw [e_x12_1]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_2 : c_2 ≤ 1 := by + rw [e_c_2]; exact addc_carry_le_one x12 0 c_1 b_x12 (by decide) b_c_1 + clear e_x12_1 e_c_2 + -- x13_1: adcs x13,x13,x17 + extract_lets +onlyGivenNames s_2 x13_1 c_3 at hr + have e_x13_1 : x13_1 = (x13 + x17 + c_2) % 2^64 := rfl + have e_c_3 : c_3 = (x13 + x17 + c_2) / 2^64 := rfl + clear_value s_2 x13_1 c_3 + have l_x13_1 : x13_1 + 2^64 * c_3 = x13 + x17 + c_2 := by + rw [e_x13_1, e_c_3]; exact Nat.mod_add_div _ _ + have b_x13_1 : x13_1 < 2^64 := by rw [e_x13_1]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_3 : c_3 ≤ 1 := by + rw [e_c_3]; exact addc_carry_le_one x13 x17 c_2 b_x13 b_x17 b_c_2 + clear e_x13_1 e_c_3 + -- x17_1: lsr x17,x3,#2 + extract_lets +onlyGivenNames x17_1 at hr + have e_x17_1 : x17_1 = x3 / 2^2 := rfl + clear_value x17_1 + have b_x17_1 : x17_1 < 2^62 := by + rw [e_x17_1]; exact Nat.div_lt_of_lt_mul (lt_of_lt_of_eq b_x3 (by norm_num)) + have sh_x17_1 : x17 + 2^64 * x17_1 = x3 * 2^62 := by + rw [e_x17, e_x17_1]; exact lsl62_lsr2_split _ + clear e_x17 e_x17_1 + -- x9: adc x9,xzr,xzr + extract_lets +onlyGivenNames x9 at hr + have e_x9 : x9 = (0 + 0 + c_3) % 2^64 := rfl + clear_value x9 + have b_x9 : x9 < 2^64 := by rw [e_x9]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x9, b_k_x9, l_x9⟩ : + ∃ k, k ≤ 1 ∧ x9 + 2^64 * k = 0 + 0 + c_3 := + ⟨(0 + 0 + c_3) / 2^64, addc_carry_le_one 0 0 c_3 (by decide) (by decide) b_c_3, + by rw [e_x9]; exact Nat.mod_add_div _ _⟩ + clear e_x9 + -- x10_1: adds x10,x11,x14 + extract_lets +onlyGivenNames s_3 x10_1 c_4 at hr + have e_x10_1 : x10_1 = (x11_1 + x14 + 0) % 2^64 := rfl + have e_c_4 : c_4 = (x11_1 + x14 + 0) / 2^64 := rfl + clear_value s_3 x10_1 c_4 + have l_x10_1 : x10_1 + 2^64 * c_4 = x11_1 + x14 + 0 := by + rw [e_x10_1, e_c_4]; exact Nat.mod_add_div _ _ + have b_x10_1 : x10_1 < 2^64 := by rw [e_x10_1]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_4 : c_4 ≤ 1 := by + rw [e_c_4]; exact addc_carry_le_one x11_1 x14 0 b_x11_1 b_x14 (by decide) + clear e_x10_1 e_c_4 + -- x11_2: adcs x11,x12,x15 + extract_lets +onlyGivenNames s_4 x11_2 c_5 at hr + have e_x11_2 : x11_2 = (x12_1 + x15_1 + c_4) % 2^64 := rfl + have e_c_5 : c_5 = (x12_1 + x15_1 + c_4) / 2^64 := rfl + clear_value s_4 x11_2 c_5 + have l_x11_2 : x11_2 + 2^64 * c_5 = x12_1 + x15_1 + c_4 := by + rw [e_x11_2, e_c_5]; exact Nat.mod_add_div _ _ + have b_x11_2 : x11_2 < 2^64 := by rw [e_x11_2]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_5 : c_5 ≤ 1 := by + rw [e_c_5]; exact addc_carry_le_one x12_1 x15_1 c_4 b_x12_1 b_x15_1 b_c_4 + clear e_x11_2 e_c_5 + -- x12_2: adcs x12,x13,xzr + extract_lets +onlyGivenNames s_5 x12_2 c_6 at hr + have e_x12_2 : x12_2 = (x13_1 + 0 + c_5) % 2^64 := rfl + have e_c_6 : c_6 = (x13_1 + 0 + c_5) / 2^64 := rfl + clear_value s_5 x12_2 c_6 + have l_x12_2 : x12_2 + 2^64 * c_6 = x13_1 + 0 + c_5 := by + rw [e_x12_2, e_c_6]; exact Nat.mod_add_div _ _ + have b_x12_2 : x12_2 < 2^64 := by rw [e_x12_2]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_6 : c_6 ≤ 1 := by + rw [e_c_6]; exact addc_carry_le_one x13_1 0 c_5 b_x13_1 (by decide) b_c_5 + clear e_x12_2 e_c_6 + -- x3_1: mul x3,x4,x10 + extract_lets +onlyGivenNames x3_1 at hr + have e_x3_1 : x3_1 = x4 * x10_1 % 2^64 := rfl + clear_value x3_1 + have b_x3_1 : x3_1 < 2^64 := by rw [e_x3_1]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x13_2: adc x13,x9,x17 + extract_lets +onlyGivenNames x13_2 at hr + have e_x13_2 : x13_2 = (x9 + x17_1 + c_6) % 2^64 := rfl + clear_value x13_2 + have b_x13_2 : x13_2 < 2^64 := by rw [e_x13_2]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x13_2, b_k_x13_2, l_x13_2⟩ : + ∃ k, k ≤ 1 ∧ x13_2 + 2^64 * k = x9 + x17_1 + c_6 := + ⟨(x9 + x17_1 + c_6) / 2^64, addc_carry_le_one x9 x17_1 c_6 b_x9 (lt_of_lt_of_le b_x17_1 (by norm_num)) b_c_6, + by rw [e_x13_2]; exact Nat.mod_add_div _ _⟩ + clear e_x13_2 + -- BEGIN round 0 + -- Cancellation: the low limb of `x10 + p0 * x3` is zero, so `x10 + lo_x14` is + -- `0` or `2^64`, and `subs xzr, x10, #1` set the carry exactly when it is `2^64`. + have hc_0 : x10 + lo_x14 = 2^64 * c := by + have h := cancel_low x10 inv modulus.l0 hinv + rw [← e_x5, ← e_x4, ← e_x3, ← d_x14, Nat.add_mul_mod_self_left, + Nat.mod_eq_of_lt b_lo_x14] at h + clear * - h b_x10 b_lo_x14 l_c + omega + -- Neither `adc` wraps: the fifth limb is at most `1`, and the shifted quotient is below + -- `2^62`. + have hk_0 : k_x9 = 0 ∧ k_x13_2 = 0 := by + clear * - l_x9 b_c_3 l_x13_2 b_x17_1 b_c_6 + omega + -- The round invariant is a linear combination of the instruction equations. + have I_0 : 2^64 * (x10_1 + 2^64 * x11_2 + 2^128 * x12_2 + 2^192 * x13_2) + = (x10 + 2^64 * x11 + 2^128 * x12 + 2^192 * x13) + + (x5 * x3 + 2^64 * (x6 * x3) + 2^254 * x3) := by + clear * - hc_0 d_x14 d_x15_1 l_x11_1 l_x12_1 l_x13_1 l_x10_1 l_x11_2 l_x12_2 sh_x17_1 l_x9 + l_x13_2 hk_0 + omega + -- END round 0 + -- x15_2: mul x15,x6,x3 + extract_lets +onlyGivenNames x15_2 at hr + have e_x15_2 : x15_2 = x6 * x3_1 % 2^64 := rfl + clear_value x15_2 + have b_x15_2 : x15_2 < 2^64 := by rw [e_x15_2]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x17_2: lsl x17,x3,#62 + extract_lets +onlyGivenNames x17_2 at hr + have e_x17_2 : x17_2 = x3_1 * 2^62 % 2^64 := rfl + clear_value x17_2 + have b_x17_2 : x17_2 < 2^64 := by rw [e_x17_2]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- c_7: subs xzr,x10,#1 + extract_lets +onlyGivenNames c_7 at hr + have e_c_7 : c_7 = (x10_1 + 2^64 - 1 - (1 - 1)) / 2^64 := rfl + clear_value c_7 + have b_c_7 : c_7 ≤ 1 := by rw [e_c_7]; exact subc_carry_le_one x10_1 1 1 b_x10_1 + have l_c_7 : (c_7 = 1 ∧ 1 + 1 ≤ x10_1 + 1) ∨ (c_7 = 0 ∧ x10_1 + 1 < 1 + 1) := + subc_carry_cases x10_1 1 1 _ e_c_7 b_x10_1 (by decide) (by decide) + clear e_c_7 + -- x14_1: umulh x14,x5,x3 + extract_lets +onlyGivenNames x14_1 at hr + have e_x14_1 : x14_1 = x5 * x3_1 / 2^64 := rfl + clear_value x14_1 + have p_x14_1 : x5 * x3_1 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x5 b_x3_1 + have b_x14_1 : x14_1 < 2^64 := by rw [e_x14_1]; exact Nat.div_lt_of_lt_mul p_x14_1 + obtain ⟨lo_x14_1, b_lo_x14_1, d_x14_1⟩ : + ∃ lo, lo < 2^64 ∧ lo + 2^64 * x14_1 = x5 * x3_1 := + ⟨x5 * x3_1 % 2^64, Nat.mod_lt _ (Nat.two_pow_pos _), + by rw [e_x14_1]; exact Nat.mod_add_div _ _⟩ + clear e_x14_1 + -- x11_3: adcs x11,x11,x15 + extract_lets +onlyGivenNames s_6 x11_3 c_8 at hr + have e_x11_3 : x11_3 = (x11_2 + x15_2 + c_7) % 2^64 := rfl + have e_c_8 : c_8 = (x11_2 + x15_2 + c_7) / 2^64 := rfl + clear_value s_6 x11_3 c_8 + have l_x11_3 : x11_3 + 2^64 * c_8 = x11_2 + x15_2 + c_7 := by + rw [e_x11_3, e_c_8]; exact Nat.mod_add_div _ _ + have b_x11_3 : x11_3 < 2^64 := by rw [e_x11_3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_8 : c_8 ≤ 1 := by + rw [e_c_8]; exact addc_carry_le_one x11_2 x15_2 c_7 b_x11_2 b_x15_2 b_c_7 + clear e_x11_3 e_c_8 + -- x15_3: umulh x15,x6,x3 + extract_lets +onlyGivenNames x15_3 at hr + have e_x15_3 : x15_3 = x6 * x3_1 / 2^64 := rfl + clear_value x15_3 + have p_x15_3 : x6 * x3_1 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x6 b_x3_1 + have b_x15_3 : x15_3 < 2^64 := by rw [e_x15_3]; exact Nat.div_lt_of_lt_mul p_x15_3 + have d_x15_3 : x15_2 + 2^64 * x15_3 = x6 * x3_1 := by + rw [e_x15_2, e_x15_3]; exact Nat.mod_add_div _ _ + clear e_x15_2 e_x15_3 + -- x12_3: adcs x12,x12,xzr + extract_lets +onlyGivenNames s_7 x12_3 c_9 at hr + have e_x12_3 : x12_3 = (x12_2 + 0 + c_8) % 2^64 := rfl + have e_c_9 : c_9 = (x12_2 + 0 + c_8) / 2^64 := rfl + clear_value s_7 x12_3 c_9 + have l_x12_3 : x12_3 + 2^64 * c_9 = x12_2 + 0 + c_8 := by + rw [e_x12_3, e_c_9]; exact Nat.mod_add_div _ _ + have b_x12_3 : x12_3 < 2^64 := by rw [e_x12_3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_9 : c_9 ≤ 1 := by + rw [e_c_9]; exact addc_carry_le_one x12_2 0 c_8 b_x12_2 (by decide) b_c_8 + clear e_x12_3 e_c_9 + -- x13_3: adcs x13,x13,x17 + extract_lets +onlyGivenNames s_8 x13_3 c_10 at hr + have e_x13_3 : x13_3 = (x13_2 + x17_2 + c_9) % 2^64 := rfl + have e_c_10 : c_10 = (x13_2 + x17_2 + c_9) / 2^64 := rfl + clear_value s_8 x13_3 c_10 + have l_x13_3 : x13_3 + 2^64 * c_10 = x13_2 + x17_2 + c_9 := by + rw [e_x13_3, e_c_10]; exact Nat.mod_add_div _ _ + have b_x13_3 : x13_3 < 2^64 := by rw [e_x13_3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_10 : c_10 ≤ 1 := by + rw [e_c_10]; exact addc_carry_le_one x13_2 x17_2 c_9 b_x13_2 b_x17_2 b_c_9 + clear e_x13_3 e_c_10 + -- x17_3: lsr x17,x3,#2 + extract_lets +onlyGivenNames x17_3 at hr + have e_x17_3 : x17_3 = x3_1 / 2^2 := rfl + clear_value x17_3 + have b_x17_3 : x17_3 < 2^62 := by + rw [e_x17_3]; exact Nat.div_lt_of_lt_mul (lt_of_lt_of_eq b_x3_1 (by norm_num)) + have sh_x17_3 : x17_2 + 2^64 * x17_3 = x3_1 * 2^62 := by + rw [e_x17_2, e_x17_3]; exact lsl62_lsr2_split _ + clear e_x17_2 e_x17_3 + -- x9_1: adc x9,xzr,xzr + extract_lets +onlyGivenNames x9_1 at hr + have e_x9_1 : x9_1 = (0 + 0 + c_10) % 2^64 := rfl + clear_value x9_1 + have b_x9_1 : x9_1 < 2^64 := by rw [e_x9_1]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x9_1, b_k_x9_1, l_x9_1⟩ : + ∃ k, k ≤ 1 ∧ x9_1 + 2^64 * k = 0 + 0 + c_10 := + ⟨(0 + 0 + c_10) / 2^64, addc_carry_le_one 0 0 c_10 (by decide) (by decide) b_c_10, + by rw [e_x9_1]; exact Nat.mod_add_div _ _⟩ + clear e_x9_1 + -- x10_2: adds x10,x11,x14 + extract_lets +onlyGivenNames s_9 x10_2 c_11 at hr + have e_x10_2 : x10_2 = (x11_3 + x14_1 + 0) % 2^64 := rfl + have e_c_11 : c_11 = (x11_3 + x14_1 + 0) / 2^64 := rfl + clear_value s_9 x10_2 c_11 + have l_x10_2 : x10_2 + 2^64 * c_11 = x11_3 + x14_1 + 0 := by + rw [e_x10_2, e_c_11]; exact Nat.mod_add_div _ _ + have b_x10_2 : x10_2 < 2^64 := by rw [e_x10_2]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_11 : c_11 ≤ 1 := by + rw [e_c_11]; exact addc_carry_le_one x11_3 x14_1 0 b_x11_3 b_x14_1 (by decide) + clear e_x10_2 e_c_11 + -- x11_4: adcs x11,x12,x15 + extract_lets +onlyGivenNames s_10 x11_4 c_12 at hr + have e_x11_4 : x11_4 = (x12_3 + x15_3 + c_11) % 2^64 := rfl + have e_c_12 : c_12 = (x12_3 + x15_3 + c_11) / 2^64 := rfl + clear_value s_10 x11_4 c_12 + have l_x11_4 : x11_4 + 2^64 * c_12 = x12_3 + x15_3 + c_11 := by + rw [e_x11_4, e_c_12]; exact Nat.mod_add_div _ _ + have b_x11_4 : x11_4 < 2^64 := by rw [e_x11_4]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_12 : c_12 ≤ 1 := by + rw [e_c_12]; exact addc_carry_le_one x12_3 x15_3 c_11 b_x12_3 b_x15_3 b_c_11 + clear e_x11_4 e_c_12 + -- x12_4: adcs x12,x13,xzr + extract_lets +onlyGivenNames s_11 x12_4 c_13 at hr + have e_x12_4 : x12_4 = (x13_3 + 0 + c_12) % 2^64 := rfl + have e_c_13 : c_13 = (x13_3 + 0 + c_12) / 2^64 := rfl + clear_value s_11 x12_4 c_13 + have l_x12_4 : x12_4 + 2^64 * c_13 = x13_3 + 0 + c_12 := by + rw [e_x12_4, e_c_13]; exact Nat.mod_add_div _ _ + have b_x12_4 : x12_4 < 2^64 := by rw [e_x12_4]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_13 : c_13 ≤ 1 := by + rw [e_c_13]; exact addc_carry_le_one x13_3 0 c_12 b_x13_3 (by decide) b_c_12 + clear e_x12_4 e_c_13 + -- x3_2: mul x3,x4,x10 + extract_lets +onlyGivenNames x3_2 at hr + have e_x3_2 : x3_2 = x4 * x10_2 % 2^64 := rfl + clear_value x3_2 + have b_x3_2 : x3_2 < 2^64 := by rw [e_x3_2]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x13_4: adc x13,x9,x17 + extract_lets +onlyGivenNames x13_4 at hr + have e_x13_4 : x13_4 = (x9_1 + x17_3 + c_13) % 2^64 := rfl + clear_value x13_4 + have b_x13_4 : x13_4 < 2^64 := by rw [e_x13_4]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x13_4, b_k_x13_4, l_x13_4⟩ : + ∃ k, k ≤ 1 ∧ x13_4 + 2^64 * k = x9_1 + x17_3 + c_13 := + ⟨(x9_1 + x17_3 + c_13) / 2^64, addc_carry_le_one x9_1 x17_3 c_13 b_x9_1 (lt_of_lt_of_le b_x17_3 (by norm_num)) b_c_13, + by rw [e_x13_4]; exact Nat.mod_add_div _ _⟩ + clear e_x13_4 + -- BEGIN round 1 + -- Cancellation: the low limb of `x10_1 + p0 * x3_1` is zero, so `x10_1 + lo_x14_1` is + -- `0` or `2^64`, and `subs xzr, x10_1, #1` set the carry exactly when it is `2^64`. + have hc_1 : x10_1 + lo_x14_1 = 2^64 * c_7 := by + have h := cancel_low x10_1 inv modulus.l0 hinv + rw [← e_x5, ← e_x4, ← e_x3_1, ← d_x14_1, Nat.add_mul_mod_self_left, + Nat.mod_eq_of_lt b_lo_x14_1] at h + clear * - h b_x10_1 b_lo_x14_1 l_c_7 + omega + -- Neither `adc` wraps: the fifth limb is at most `1`, and the shifted quotient is below + -- `2^62`. + have hk_1 : k_x9_1 = 0 ∧ k_x13_4 = 0 := by + clear * - l_x9_1 b_c_10 l_x13_4 b_x17_3 b_c_13 + omega + -- The round invariant is a linear combination of the instruction equations. + have I_1 : 2^64 * (x10_2 + 2^64 * x11_4 + 2^128 * x12_4 + 2^192 * x13_4) + = (x10_1 + 2^64 * x11_2 + 2^128 * x12_2 + 2^192 * x13_2) + + (x5 * x3_1 + 2^64 * (x6 * x3_1) + 2^254 * x3_1) := by + clear * - hc_1 d_x14_1 d_x15_3 l_x11_3 l_x12_3 l_x13_3 l_x10_2 l_x11_4 l_x12_4 sh_x17_3 l_x9_1 + l_x13_4 hk_1 + omega + -- END round 1 + -- x15_4: mul x15,x6,x3 + extract_lets +onlyGivenNames x15_4 at hr + have e_x15_4 : x15_4 = x6 * x3_2 % 2^64 := rfl + clear_value x15_4 + have b_x15_4 : x15_4 < 2^64 := by rw [e_x15_4]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x17_4: lsl x17,x3,#62 + extract_lets +onlyGivenNames x17_4 at hr + have e_x17_4 : x17_4 = x3_2 * 2^62 % 2^64 := rfl + clear_value x17_4 + have b_x17_4 : x17_4 < 2^64 := by rw [e_x17_4]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- c_14: subs xzr,x10,#1 + extract_lets +onlyGivenNames c_14 at hr + have e_c_14 : c_14 = (x10_2 + 2^64 - 1 - (1 - 1)) / 2^64 := rfl + clear_value c_14 + have b_c_14 : c_14 ≤ 1 := by rw [e_c_14]; exact subc_carry_le_one x10_2 1 1 b_x10_2 + have l_c_14 : (c_14 = 1 ∧ 1 + 1 ≤ x10_2 + 1) ∨ (c_14 = 0 ∧ x10_2 + 1 < 1 + 1) := + subc_carry_cases x10_2 1 1 _ e_c_14 b_x10_2 (by decide) (by decide) + clear e_c_14 + -- x14_2: umulh x14,x5,x3 + extract_lets +onlyGivenNames x14_2 at hr + have e_x14_2 : x14_2 = x5 * x3_2 / 2^64 := rfl + clear_value x14_2 + have p_x14_2 : x5 * x3_2 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x5 b_x3_2 + have b_x14_2 : x14_2 < 2^64 := by rw [e_x14_2]; exact Nat.div_lt_of_lt_mul p_x14_2 + obtain ⟨lo_x14_2, b_lo_x14_2, d_x14_2⟩ : + ∃ lo, lo < 2^64 ∧ lo + 2^64 * x14_2 = x5 * x3_2 := + ⟨x5 * x3_2 % 2^64, Nat.mod_lt _ (Nat.two_pow_pos _), + by rw [e_x14_2]; exact Nat.mod_add_div _ _⟩ + clear e_x14_2 + -- x11_5: adcs x11,x11,x15 + extract_lets +onlyGivenNames s_12 x11_5 c_15 at hr + have e_x11_5 : x11_5 = (x11_4 + x15_4 + c_14) % 2^64 := rfl + have e_c_15 : c_15 = (x11_4 + x15_4 + c_14) / 2^64 := rfl + clear_value s_12 x11_5 c_15 + have l_x11_5 : x11_5 + 2^64 * c_15 = x11_4 + x15_4 + c_14 := by + rw [e_x11_5, e_c_15]; exact Nat.mod_add_div _ _ + have b_x11_5 : x11_5 < 2^64 := by rw [e_x11_5]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_15 : c_15 ≤ 1 := by + rw [e_c_15]; exact addc_carry_le_one x11_4 x15_4 c_14 b_x11_4 b_x15_4 b_c_14 + clear e_x11_5 e_c_15 + -- x15_5: umulh x15,x6,x3 + extract_lets +onlyGivenNames x15_5 at hr + have e_x15_5 : x15_5 = x6 * x3_2 / 2^64 := rfl + clear_value x15_5 + have p_x15_5 : x6 * x3_2 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x6 b_x3_2 + have b_x15_5 : x15_5 < 2^64 := by rw [e_x15_5]; exact Nat.div_lt_of_lt_mul p_x15_5 + have d_x15_5 : x15_4 + 2^64 * x15_5 = x6 * x3_2 := by + rw [e_x15_4, e_x15_5]; exact Nat.mod_add_div _ _ + clear e_x15_4 e_x15_5 + -- x12_5: adcs x12,x12,xzr + extract_lets +onlyGivenNames s_13 x12_5 c_16 at hr + have e_x12_5 : x12_5 = (x12_4 + 0 + c_15) % 2^64 := rfl + have e_c_16 : c_16 = (x12_4 + 0 + c_15) / 2^64 := rfl + clear_value s_13 x12_5 c_16 + have l_x12_5 : x12_5 + 2^64 * c_16 = x12_4 + 0 + c_15 := by + rw [e_x12_5, e_c_16]; exact Nat.mod_add_div _ _ + have b_x12_5 : x12_5 < 2^64 := by rw [e_x12_5]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_16 : c_16 ≤ 1 := by + rw [e_c_16]; exact addc_carry_le_one x12_4 0 c_15 b_x12_4 (by decide) b_c_15 + clear e_x12_5 e_c_16 + -- x13_5: adcs x13,x13,x17 + extract_lets +onlyGivenNames s_14 x13_5 c_17 at hr + have e_x13_5 : x13_5 = (x13_4 + x17_4 + c_16) % 2^64 := rfl + have e_c_17 : c_17 = (x13_4 + x17_4 + c_16) / 2^64 := rfl + clear_value s_14 x13_5 c_17 + have l_x13_5 : x13_5 + 2^64 * c_17 = x13_4 + x17_4 + c_16 := by + rw [e_x13_5, e_c_17]; exact Nat.mod_add_div _ _ + have b_x13_5 : x13_5 < 2^64 := by rw [e_x13_5]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_17 : c_17 ≤ 1 := by + rw [e_c_17]; exact addc_carry_le_one x13_4 x17_4 c_16 b_x13_4 b_x17_4 b_c_16 + clear e_x13_5 e_c_17 + -- x17_5: lsr x17,x3,#2 + extract_lets +onlyGivenNames x17_5 at hr + have e_x17_5 : x17_5 = x3_2 / 2^2 := rfl + clear_value x17_5 + have b_x17_5 : x17_5 < 2^62 := by + rw [e_x17_5]; exact Nat.div_lt_of_lt_mul (lt_of_lt_of_eq b_x3_2 (by norm_num)) + have sh_x17_5 : x17_4 + 2^64 * x17_5 = x3_2 * 2^62 := by + rw [e_x17_4, e_x17_5]; exact lsl62_lsr2_split _ + clear e_x17_4 e_x17_5 + -- x9_2: adc x9,xzr,xzr + extract_lets +onlyGivenNames x9_2 at hr + have e_x9_2 : x9_2 = (0 + 0 + c_17) % 2^64 := rfl + clear_value x9_2 + have b_x9_2 : x9_2 < 2^64 := by rw [e_x9_2]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x9_2, b_k_x9_2, l_x9_2⟩ : + ∃ k, k ≤ 1 ∧ x9_2 + 2^64 * k = 0 + 0 + c_17 := + ⟨(0 + 0 + c_17) / 2^64, addc_carry_le_one 0 0 c_17 (by decide) (by decide) b_c_17, + by rw [e_x9_2]; exact Nat.mod_add_div _ _⟩ + clear e_x9_2 + -- x10_3: adds x10,x11,x14 + extract_lets +onlyGivenNames s_15 x10_3 c_18 at hr + have e_x10_3 : x10_3 = (x11_5 + x14_2 + 0) % 2^64 := rfl + have e_c_18 : c_18 = (x11_5 + x14_2 + 0) / 2^64 := rfl + clear_value s_15 x10_3 c_18 + have l_x10_3 : x10_3 + 2^64 * c_18 = x11_5 + x14_2 + 0 := by + rw [e_x10_3, e_c_18]; exact Nat.mod_add_div _ _ + have b_x10_3 : x10_3 < 2^64 := by rw [e_x10_3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_18 : c_18 ≤ 1 := by + rw [e_c_18]; exact addc_carry_le_one x11_5 x14_2 0 b_x11_5 b_x14_2 (by decide) + clear e_x10_3 e_c_18 + -- x11_6: adcs x11,x12,x15 + extract_lets +onlyGivenNames s_16 x11_6 c_19 at hr + have e_x11_6 : x11_6 = (x12_5 + x15_5 + c_18) % 2^64 := rfl + have e_c_19 : c_19 = (x12_5 + x15_5 + c_18) / 2^64 := rfl + clear_value s_16 x11_6 c_19 + have l_x11_6 : x11_6 + 2^64 * c_19 = x12_5 + x15_5 + c_18 := by + rw [e_x11_6, e_c_19]; exact Nat.mod_add_div _ _ + have b_x11_6 : x11_6 < 2^64 := by rw [e_x11_6]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_19 : c_19 ≤ 1 := by + rw [e_c_19]; exact addc_carry_le_one x12_5 x15_5 c_18 b_x12_5 b_x15_5 b_c_18 + clear e_x11_6 e_c_19 + -- x12_6: adcs x12,x13,xzr + extract_lets +onlyGivenNames s_17 x12_6 c_20 at hr + have e_x12_6 : x12_6 = (x13_5 + 0 + c_19) % 2^64 := rfl + have e_c_20 : c_20 = (x13_5 + 0 + c_19) / 2^64 := rfl + clear_value s_17 x12_6 c_20 + have l_x12_6 : x12_6 + 2^64 * c_20 = x13_5 + 0 + c_19 := by + rw [e_x12_6, e_c_20]; exact Nat.mod_add_div _ _ + have b_x12_6 : x12_6 < 2^64 := by rw [e_x12_6]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_20 : c_20 ≤ 1 := by + rw [e_c_20]; exact addc_carry_le_one x13_5 0 c_19 b_x13_5 (by decide) b_c_19 + clear e_x12_6 e_c_20 + -- x3_3: mul x3,x4,x10 + extract_lets +onlyGivenNames x3_3 at hr + have e_x3_3 : x3_3 = x4 * x10_3 % 2^64 := rfl + clear_value x3_3 + have b_x3_3 : x3_3 < 2^64 := by rw [e_x3_3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x13_6: adc x13,x9,x17 + extract_lets +onlyGivenNames x13_6 at hr + have e_x13_6 : x13_6 = (x9_2 + x17_5 + c_20) % 2^64 := rfl + clear_value x13_6 + have b_x13_6 : x13_6 < 2^64 := by rw [e_x13_6]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x13_6, b_k_x13_6, l_x13_6⟩ : + ∃ k, k ≤ 1 ∧ x13_6 + 2^64 * k = x9_2 + x17_5 + c_20 := + ⟨(x9_2 + x17_5 + c_20) / 2^64, addc_carry_le_one x9_2 x17_5 c_20 b_x9_2 (lt_of_lt_of_le b_x17_5 (by norm_num)) b_c_20, + by rw [e_x13_6]; exact Nat.mod_add_div _ _⟩ + clear e_x13_6 + -- BEGIN round 2 + -- Cancellation: the low limb of `x10_2 + p0 * x3_2` is zero, so `x10_2 + lo_x14_2` is + -- `0` or `2^64`, and `subs xzr, x10_2, #1` set the carry exactly when it is `2^64`. + have hc_2 : x10_2 + lo_x14_2 = 2^64 * c_14 := by + have h := cancel_low x10_2 inv modulus.l0 hinv + rw [← e_x5, ← e_x4, ← e_x3_2, ← d_x14_2, Nat.add_mul_mod_self_left, + Nat.mod_eq_of_lt b_lo_x14_2] at h + clear * - h b_x10_2 b_lo_x14_2 l_c_14 + omega + -- Neither `adc` wraps: the fifth limb is at most `1`, and the shifted quotient is below + -- `2^62`. + have hk_2 : k_x9_2 = 0 ∧ k_x13_6 = 0 := by + clear * - l_x9_2 b_c_17 l_x13_6 b_x17_5 b_c_20 + omega + -- The round invariant is a linear combination of the instruction equations. + have I_2 : 2^64 * (x10_3 + 2^64 * x11_6 + 2^128 * x12_6 + 2^192 * x13_6) + = (x10_2 + 2^64 * x11_4 + 2^128 * x12_4 + 2^192 * x13_4) + + (x5 * x3_2 + 2^64 * (x6 * x3_2) + 2^254 * x3_2) := by + clear * - hc_2 d_x14_2 d_x15_5 l_x11_5 l_x12_5 l_x13_5 l_x10_3 l_x11_6 l_x12_6 sh_x17_5 l_x9_2 + l_x13_6 hk_2 + omega + -- END round 2 + -- x15_6: mul x15,x6,x3 + extract_lets +onlyGivenNames x15_6 at hr + have e_x15_6 : x15_6 = x6 * x3_3 % 2^64 := rfl + clear_value x15_6 + have b_x15_6 : x15_6 < 2^64 := by rw [e_x15_6]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x17_6: lsl x17,x3,#62 + extract_lets +onlyGivenNames x17_6 at hr + have e_x17_6 : x17_6 = x3_3 * 2^62 % 2^64 := rfl + clear_value x17_6 + have b_x17_6 : x17_6 < 2^64 := by rw [e_x17_6]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- c_21: subs xzr,x10,#1 + extract_lets +onlyGivenNames c_21 at hr + have e_c_21 : c_21 = (x10_3 + 2^64 - 1 - (1 - 1)) / 2^64 := rfl + clear_value c_21 + have b_c_21 : c_21 ≤ 1 := by rw [e_c_21]; exact subc_carry_le_one x10_3 1 1 b_x10_3 + have l_c_21 : (c_21 = 1 ∧ 1 + 1 ≤ x10_3 + 1) ∨ (c_21 = 0 ∧ x10_3 + 1 < 1 + 1) := + subc_carry_cases x10_3 1 1 _ e_c_21 b_x10_3 (by decide) (by decide) + clear e_c_21 + -- x14_3: umulh x14,x5,x3 + extract_lets +onlyGivenNames x14_3 at hr + have e_x14_3 : x14_3 = x5 * x3_3 / 2^64 := rfl + clear_value x14_3 + have p_x14_3 : x5 * x3_3 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x5 b_x3_3 + have b_x14_3 : x14_3 < 2^64 := by rw [e_x14_3]; exact Nat.div_lt_of_lt_mul p_x14_3 + obtain ⟨lo_x14_3, b_lo_x14_3, d_x14_3⟩ : + ∃ lo, lo < 2^64 ∧ lo + 2^64 * x14_3 = x5 * x3_3 := + ⟨x5 * x3_3 % 2^64, Nat.mod_lt _ (Nat.two_pow_pos _), + by rw [e_x14_3]; exact Nat.mod_add_div _ _⟩ + clear e_x14_3 + -- x11_7: adcs x11,x11,x15 + extract_lets +onlyGivenNames s_18 x11_7 c_22 at hr + have e_x11_7 : x11_7 = (x11_6 + x15_6 + c_21) % 2^64 := rfl + have e_c_22 : c_22 = (x11_6 + x15_6 + c_21) / 2^64 := rfl + clear_value s_18 x11_7 c_22 + have l_x11_7 : x11_7 + 2^64 * c_22 = x11_6 + x15_6 + c_21 := by + rw [e_x11_7, e_c_22]; exact Nat.mod_add_div _ _ + have b_x11_7 : x11_7 < 2^64 := by rw [e_x11_7]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_22 : c_22 ≤ 1 := by + rw [e_c_22]; exact addc_carry_le_one x11_6 x15_6 c_21 b_x11_6 b_x15_6 b_c_21 + clear e_x11_7 e_c_22 + -- x15_7: umulh x15,x6,x3 + extract_lets +onlyGivenNames x15_7 at hr + have e_x15_7 : x15_7 = x6 * x3_3 / 2^64 := rfl + clear_value x15_7 + have p_x15_7 : x6 * x3_3 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x6 b_x3_3 + have b_x15_7 : x15_7 < 2^64 := by rw [e_x15_7]; exact Nat.div_lt_of_lt_mul p_x15_7 + have d_x15_7 : x15_6 + 2^64 * x15_7 = x6 * x3_3 := by + rw [e_x15_6, e_x15_7]; exact Nat.mod_add_div _ _ + clear e_x15_6 e_x15_7 + -- x12_7: adcs x12,x12,xzr + extract_lets +onlyGivenNames s_19 x12_7 c_23 at hr + have e_x12_7 : x12_7 = (x12_6 + 0 + c_22) % 2^64 := rfl + have e_c_23 : c_23 = (x12_6 + 0 + c_22) / 2^64 := rfl + clear_value s_19 x12_7 c_23 + have l_x12_7 : x12_7 + 2^64 * c_23 = x12_6 + 0 + c_22 := by + rw [e_x12_7, e_c_23]; exact Nat.mod_add_div _ _ + have b_x12_7 : x12_7 < 2^64 := by rw [e_x12_7]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_23 : c_23 ≤ 1 := by + rw [e_c_23]; exact addc_carry_le_one x12_6 0 c_22 b_x12_6 (by decide) b_c_22 + clear e_x12_7 e_c_23 + -- x13_7: adcs x13,x13,x17 + extract_lets +onlyGivenNames s_20 x13_7 c_24 at hr + have e_x13_7 : x13_7 = (x13_6 + x17_6 + c_23) % 2^64 := rfl + have e_c_24 : c_24 = (x13_6 + x17_6 + c_23) / 2^64 := rfl + clear_value s_20 x13_7 c_24 + have l_x13_7 : x13_7 + 2^64 * c_24 = x13_6 + x17_6 + c_23 := by + rw [e_x13_7, e_c_24]; exact Nat.mod_add_div _ _ + have b_x13_7 : x13_7 < 2^64 := by rw [e_x13_7]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_24 : c_24 ≤ 1 := by + rw [e_c_24]; exact addc_carry_le_one x13_6 x17_6 c_23 b_x13_6 b_x17_6 b_c_23 + clear e_x13_7 e_c_24 + -- x17_7: lsr x17,x3,#2 + extract_lets +onlyGivenNames x17_7 at hr + have e_x17_7 : x17_7 = x3_3 / 2^2 := rfl + clear_value x17_7 + have b_x17_7 : x17_7 < 2^62 := by + rw [e_x17_7]; exact Nat.div_lt_of_lt_mul (lt_of_lt_of_eq b_x3_3 (by norm_num)) + have sh_x17_7 : x17_6 + 2^64 * x17_7 = x3_3 * 2^62 := by + rw [e_x17_6, e_x17_7]; exact lsl62_lsr2_split _ + clear e_x17_6 e_x17_7 + -- x9_3: adc x9,xzr,xzr + extract_lets +onlyGivenNames x9_3 at hr + have e_x9_3 : x9_3 = (0 + 0 + c_24) % 2^64 := rfl + clear_value x9_3 + have b_x9_3 : x9_3 < 2^64 := by rw [e_x9_3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x9_3, b_k_x9_3, l_x9_3⟩ : + ∃ k, k ≤ 1 ∧ x9_3 + 2^64 * k = 0 + 0 + c_24 := + ⟨(0 + 0 + c_24) / 2^64, addc_carry_le_one 0 0 c_24 (by decide) (by decide) b_c_24, + by rw [e_x9_3]; exact Nat.mod_add_div _ _⟩ + clear e_x9_3 + -- x10_4: adds x10,x11,x14 + extract_lets +onlyGivenNames s_21 x10_4 c_25 at hr + have e_x10_4 : x10_4 = (x11_7 + x14_3 + 0) % 2^64 := rfl + have e_c_25 : c_25 = (x11_7 + x14_3 + 0) / 2^64 := rfl + clear_value s_21 x10_4 c_25 + have l_x10_4 : x10_4 + 2^64 * c_25 = x11_7 + x14_3 + 0 := by + rw [e_x10_4, e_c_25]; exact Nat.mod_add_div _ _ + have b_x10_4 : x10_4 < 2^64 := by rw [e_x10_4]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_25 : c_25 ≤ 1 := by + rw [e_c_25]; exact addc_carry_le_one x11_7 x14_3 0 b_x11_7 b_x14_3 (by decide) + clear e_x10_4 e_c_25 + -- x11_8: adcs x11,x12,x15 + extract_lets +onlyGivenNames s_22 x11_8 c_26 at hr + have e_x11_8 : x11_8 = (x12_7 + x15_7 + c_25) % 2^64 := rfl + have e_c_26 : c_26 = (x12_7 + x15_7 + c_25) / 2^64 := rfl + clear_value s_22 x11_8 c_26 + have l_x11_8 : x11_8 + 2^64 * c_26 = x12_7 + x15_7 + c_25 := by + rw [e_x11_8, e_c_26]; exact Nat.mod_add_div _ _ + have b_x11_8 : x11_8 < 2^64 := by rw [e_x11_8]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_26 : c_26 ≤ 1 := by + rw [e_c_26]; exact addc_carry_le_one x12_7 x15_7 c_25 b_x12_7 b_x15_7 b_c_25 + clear e_x11_8 e_c_26 + -- x12_8: adcs x12,x13,xzr + extract_lets +onlyGivenNames s_23 x12_8 c_27 at hr + have e_x12_8 : x12_8 = (x13_7 + 0 + c_26) % 2^64 := rfl + have e_c_27 : c_27 = (x13_7 + 0 + c_26) / 2^64 := rfl + clear_value s_23 x12_8 c_27 + have l_x12_8 : x12_8 + 2^64 * c_27 = x13_7 + 0 + c_26 := by + rw [e_x12_8, e_c_27]; exact Nat.mod_add_div _ _ + have b_x12_8 : x12_8 < 2^64 := by rw [e_x12_8]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_27 : c_27 ≤ 1 := by + rw [e_c_27]; exact addc_carry_le_one x13_7 0 c_26 b_x13_7 (by decide) b_c_26 + clear e_x12_8 e_c_27 + -- x13_8: adc x13,x9,x17 + extract_lets +onlyGivenNames x13_8 at hr + have e_x13_8 : x13_8 = (x9_3 + x17_7 + c_27) % 2^64 := rfl + clear_value x13_8 + have b_x13_8 : x13_8 < 2^64 := by rw [e_x13_8]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x13_8, b_k_x13_8, l_x13_8⟩ : + ∃ k, k ≤ 1 ∧ x13_8 + 2^64 * k = x9_3 + x17_7 + c_27 := + ⟨(x9_3 + x17_7 + c_27) / 2^64, addc_carry_le_one x9_3 x17_7 c_27 b_x9_3 (lt_of_lt_of_le b_x17_7 (by norm_num)) b_c_27, + by rw [e_x13_8]; exact Nat.mod_add_div _ _⟩ + clear e_x13_8 + subst hr + -- BEGIN round 3 + -- Cancellation: the low limb of `x10_3 + p0 * x3_3` is zero, so `x10_3 + lo_x14_3` is + -- `0` or `2^64`, and `subs xzr, x10_3, #1` set the carry exactly when it is `2^64`. + have hc_3 : x10_3 + lo_x14_3 = 2^64 * c_21 := by + have h := cancel_low x10_3 inv modulus.l0 hinv + rw [← e_x5, ← e_x4, ← e_x3_3, ← d_x14_3, Nat.add_mul_mod_self_left, + Nat.mod_eq_of_lt b_lo_x14_3] at h + clear * - h b_x10_3 b_lo_x14_3 l_c_21 + omega + -- Neither `adc` wraps: the fifth limb is at most `1`, and the shifted quotient is below + -- `2^62`. + have hk_3 : k_x9_3 = 0 ∧ k_x13_8 = 0 := by + clear * - l_x9_3 b_c_24 l_x13_8 b_x17_7 b_c_27 + omega + -- The round invariant is a linear combination of the instruction equations. + have I_3 : 2^64 * (x10_4 + 2^64 * x11_8 + 2^128 * x12_8 + 2^192 * x13_8) + = (x10_3 + 2^64 * x11_6 + 2^128 * x12_6 + 2^192 * x13_6) + + (x5 * x3_3 + 2^64 * (x6 * x3_3) + 2^254 * x3_3) := by + clear * - hc_3 d_x14_3 d_x15_7 l_x11_7 l_x12_7 l_x13_7 l_x10_4 l_x11_8 l_x12_8 sh_x17_7 l_x9_3 + l_x13_8 hk_3 + omega + -- END round 3 + -- BEGIN conclusion + subst e_x5 e_x6 + refine ⟨⟨b_x10_4, b_x11_8, b_x12_8, b_x13_8⟩, x3 + 2^64 * x3_1 + 2^128 * x3_2 + 2^192 * x3_3, + by clear * - b_x3 b_x3_1 b_x3_2 b_x3_3; omega, ?_⟩ + -- `Q * p`, with the modulus in the shape the code assumes, as the sum of the four rounds' + -- contributions. + have hQp : (x3 + 2^64 * x3_1 + 2^128 * x3_2 + 2^192 * x3_3) * modulus.toNat + = (modulus.l0 * x3 + 2^64 * (modulus.l1 * x3) + 2^254 * x3) + + 2^64 * (modulus.l0 * x3_1 + 2^64 * (modulus.l1 * x3_1) + 2^254 * x3_1) + + 2^128 * (modulus.l0 * x3_2 + 2^64 * (modulus.l1 * x3_2) + 2^254 * x3_2) + + 2^192 * (modulus.l0 * x3_3 + 2^64 * (modulus.l1 * x3_3) + 2^254 * x3_3) := by + simp only [Limbs.toNat, hshape.1, hshape.2]; ring + simp only [Limbs.toNat] at hQp ⊢ + clear * - I_0 I_1 I_2 I_3 hQp e_x10 e_x11 e_x12 e_x13 + omega + -- END conclusion + +-- BEGIN modEq_of_add_mul +/-- `a ≡ b (mod n)` from `a + k * n = b + l * n`, the form in which a final conditional +subtraction leaves a result. -/ +theorem modEq_of_add_mul (a b k l n : Nat) (h : a + k * n = b + l * n) : a ≡ b [MOD n] := by + unfold Nat.ModEq + rw [← Nat.add_mul_mod_self_right a k n, h, Nat.add_mul_mod_self_right] +-- END modEq_of_add_mul + +-- BEGIN fromMont_spec statement +/-- Conversion out of Montgomery form: for any four-limb `value`, the result is below `p` and +`2^256 * result ≡ value (mod p)`. The helper returns at most `p` for any four-limb input and the +conditional subtraction removes the one excess case, so `value` need not be below `p`. -/ +theorem fromMont_spec (value modulus : Limbs) (inv : Nat) (hv : value.Bounded) + (hm : modulus.Bounded) (hshape : modulus.l2 = 0 ∧ modulus.l3 = 2^62) + (hinv_lt : inv < 2^64) (hinv : (inv * modulus.l0 + 1) % 2^64 = 0) : + ∀ r, r = fromMont value modulus inv → + r.Bounded ∧ r.toNat < modulus.toNat ∧ 2^256 * r.toNat ≡ value.toNat [MOD modulus.toNat] := by + intro r hr +-- END fromMont_spec statement + -- generated skeleton for `fromMont`: do not edit between the annotations + unfold fromMont at hr + lift_lets at hr + -- x3: argument + extract_lets +onlyGivenNames x3 at hr + have e_x3 : x3 = inv := rfl + clear_value x3 + have b_x3 : x3 < 2^64 := by rw [e_x3]; exact hinv_lt + -- x4: mov x4,x3 + extract_lets +onlyGivenNames x4 at hr + have e_x4 : x4 = x3 := rfl + clear_value x4 + have b_x4 : x4 < 2^64 := by rw [e_x4]; exact b_x3 + -- x10: ldp x10,x11,[x1] + extract_lets +onlyGivenNames x10 at hr + have e_x10 : x10 = value.l0 := rfl + clear_value x10 + have b_x10 : x10 < 2^64 := by rw [e_x10]; exact hv.1 + -- x11: ldp x10,x11,[x1] + extract_lets +onlyGivenNames x11 at hr + have e_x11 : x11 = value.l1 := rfl + clear_value x11 + have b_x11 : x11 < 2^64 := by rw [e_x11]; exact hv.2.1 + -- x12: ldp x12,x13,[x1,#16] + extract_lets +onlyGivenNames x12 at hr + have e_x12 : x12 = value.l2 := rfl + clear_value x12 + have b_x12 : x12 < 2^64 := by rw [e_x12]; exact hv.2.2.1 + -- x13: ldp x12,x13,[x1,#16] + extract_lets +onlyGivenNames x13 at hr + have e_x13 : x13 = value.l3 := rfl + clear_value x13 + have b_x13 : x13 < 2^64 := by rw [e_x13]; exact hv.2.2.2 + -- r: bl L$pasta_curves_mul_by_1_mont_pasta + extract_lets +onlyGivenNames r at hr + have e_r : r = mulBy1 ⟨x10, x11, x12, x13⟩ modulus x4 := rfl + clear_value r + -- x10_1: helper output + extract_lets +onlyGivenNames x10_1 at hr + have e_x10_1 : x10_1 = r.l0 := rfl + clear_value x10_1 + -- x11_1: helper output + extract_lets +onlyGivenNames x11_1 at hr + have e_x11_1 : x11_1 = r.l1 := rfl + clear_value x11_1 + -- x12_1: helper output + extract_lets +onlyGivenNames x12_1 at hr + have e_x12_1 : x12_1 = r.l2 := rfl + clear_value x12_1 + -- x13_1: helper output + extract_lets +onlyGivenNames x13_1 at hr + have e_x13_1 : x13_1 = r.l3 := rfl + clear_value x13_1 + -- x5: loaded by the helper + extract_lets +onlyGivenNames x5 at hr + have e_x5 : x5 = modulus.l0 := rfl + clear_value x5 + have b_x5 : x5 < 2^64 := by rw [e_x5]; exact hm.1 + -- x6: loaded by the helper + extract_lets +onlyGivenNames x6 at hr + have e_x6 : x6 = modulus.l1 := rfl + clear_value x6 + have b_x6 : x6 < 2^64 := by rw [e_x6]; exact hm.2.1 + -- x7: loaded by the helper + extract_lets +onlyGivenNames x7 at hr + have e_x7 : x7 = modulus.l2 := rfl + clear_value x7 + have b_x7 : x7 < 2^64 := by rw [e_x7]; exact hm.2.2.1 + -- x8: loaded by the helper + extract_lets +onlyGivenNames x8 at hr + have e_x8 : x8 = modulus.l3 := rfl + clear_value x8 + have b_x8 : x8 < 2^64 := by rw [e_x8]; exact hm.2.2.2 + -- BEGIN helper + -- The helper's contract on `t = value`: its result limbs are bounded, and `2^256 * r = t + Q * p` + -- for some `Q < 2^256`. + obtain ⟨⟨b_x10_1, b_x11_1, b_x12_1, b_x13_1⟩, Q, hQ, hmain⟩ : + (x10_1 < 2^64 ∧ x11_1 < 2^64 ∧ x12_1 < 2^64 ∧ x13_1 < 2^64) ∧ ∃ Q, Q < 2^256 ∧ + 2^256 * (x10_1 + 2^64 * x11_1 + 2^128 * x12_1 + 2^192 * x13_1) + = (x10 + 2^64 * x11 + 2^128 * x12 + 2^192 * x13) + Q * modulus.toNat := by + have hr : r = ⟨x10_1, x11_1, x12_1, x13_1⟩ := by rw [e_x10_1, e_x11_1, e_x12_1, e_x13_1] + subst hr + exact mulBy1_spec ⟨x10, x11, x12, x13⟩ modulus x4 ⟨b_x10, b_x11, b_x12, b_x13⟩ hm hshape b_x4 + (by rw [e_x4, e_x3]; exact hinv) _ e_r + clear e_r e_x10_1 e_x11_1 e_x12_1 e_x13_1 + -- END helper + -- x14: subs x14,x10,x5 + extract_lets +onlyGivenNames s x14 c at hr + have e_x14 : x14 = (x10_1 + 2^64 - x5 - (1 - 1)) % 2^64 := rfl + have e_c : c = (x10_1 + 2^64 - x5 - (1 - 1)) / 2^64 := rfl + clear_value s x14 c + have l_x14 : x14 + 2^64 * c + x5 + 1 = x10_1 + 2^64 + 1 := by + rw [e_x14, e_c]; exact subc_lin x10_1 x5 1 b_x5 (by decide) + have b_x14 : x14 < 2^64 := by rw [e_x14]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c : c ≤ 1 := by + rw [e_c]; exact subc_carry_le_one x10_1 x5 1 b_x10_1 + clear e_x14 e_c + -- x15: sbcs x15,x11,x6 + extract_lets +onlyGivenNames s_1 x15 c_1 at hr + have e_x15 : x15 = (x11_1 + 2^64 - x6 - (1 - c)) % 2^64 := rfl + have e_c_1 : c_1 = (x11_1 + 2^64 - x6 - (1 - c)) / 2^64 := rfl + clear_value s_1 x15 c_1 + have l_x15 : x15 + 2^64 * c_1 + x6 + 1 = x11_1 + 2^64 + c := by + rw [e_x15, e_c_1]; exact subc_lin x11_1 x6 c b_x6 b_c + have b_x15 : x15 < 2^64 := by rw [e_x15]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_1 : c_1 ≤ 1 := by + rw [e_c_1]; exact subc_carry_le_one x11_1 x6 c b_x11_1 + clear e_x15 e_c_1 + -- x16: sbcs x16,x12,x7 + extract_lets +onlyGivenNames s_2 x16 c_2 at hr + have e_x16 : x16 = (x12_1 + 2^64 - x7 - (1 - c_1)) % 2^64 := rfl + have e_c_2 : c_2 = (x12_1 + 2^64 - x7 - (1 - c_1)) / 2^64 := rfl + clear_value s_2 x16 c_2 + have l_x16 : x16 + 2^64 * c_2 + x7 + 1 = x12_1 + 2^64 + c_1 := by + rw [e_x16, e_c_2]; exact subc_lin x12_1 x7 c_1 b_x7 b_c_1 + have b_x16 : x16 < 2^64 := by rw [e_x16]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_2 : c_2 ≤ 1 := by + rw [e_c_2]; exact subc_carry_le_one x12_1 x7 c_1 b_x12_1 + clear e_x16 e_c_2 + -- x17: sbcs x17,x13,x8 + extract_lets +onlyGivenNames s_3 x17 c_3 at hr + have e_x17 : x17 = (x13_1 + 2^64 - x8 - (1 - c_2)) % 2^64 := rfl + have e_c_3 : c_3 = (x13_1 + 2^64 - x8 - (1 - c_2)) / 2^64 := rfl + clear_value s_3 x17 c_3 + have l_x17 : x17 + 2^64 * c_3 + x8 + 1 = x13_1 + 2^64 + c_2 := by + rw [e_x17, e_c_3]; exact subc_lin x13_1 x8 c_2 b_x8 b_c_2 + have b_x17 : x17 < 2^64 := by rw [e_x17]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_3 : c_3 ≤ 1 := by + rw [e_c_3]; exact subc_carry_le_one x13_1 x8 c_2 b_x13_1 + clear e_x17 e_c_3 + -- x10_2: csel x10,x10,x14,lo + extract_lets +onlyGivenNames x10_2 at hr + have e_x10_2 : x10_2 = (if c_3 = 0 then x10_1 else x14) := rfl + clear_value x10_2 + have b_x10_2 : x10_2 < 2^64 := by + rw [e_x10_2]; split <;> first | exact b_x10_1 | exact b_x14 + -- x11_2: csel x11,x11,x15,lo + extract_lets +onlyGivenNames x11_2 at hr + have e_x11_2 : x11_2 = (if c_3 = 0 then x11_1 else x15) := rfl + clear_value x11_2 + have b_x11_2 : x11_2 < 2^64 := by + rw [e_x11_2]; split <;> first | exact b_x11_1 | exact b_x15 + -- x12_2: csel x12,x12,x16,lo + extract_lets +onlyGivenNames x12_2 at hr + have e_x12_2 : x12_2 = (if c_3 = 0 then x12_1 else x16) := rfl + clear_value x12_2 + have b_x12_2 : x12_2 < 2^64 := by + rw [e_x12_2]; split <;> first | exact b_x12_1 | exact b_x16 + -- x13_2: csel x13,x13,x17,lo + extract_lets +onlyGivenNames x13_2 at hr + have e_x13_2 : x13_2 = (if c_3 = 0 then x13_1 else x17) := rfl + clear_value x13_2 + have b_x13_2 : x13_2 < 2^64 := by + rw [e_x13_2]; split <;> first | exact b_x13_1 | exact b_x17 + -- out0: stp x10,x11,[x0] + extract_lets +onlyGivenNames out0 at hr + have e_out0 : out0 = x10_2 := rfl + clear_value out0 + -- out1: stp x10,x11,[x0] + extract_lets +onlyGivenNames out1 at hr + have e_out1 : out1 = x11_2 := rfl + clear_value out1 + -- out2: stp x12,x13,[x0,#16] + extract_lets +onlyGivenNames out2 at hr + have e_out2 : out2 = x12_2 := rfl + clear_value out2 + -- out3: stp x12,x13,[x0,#16] + extract_lets +onlyGivenNames out3 at hr + have e_out3 : out3 = x13_2 := rfl + clear_value out3 + subst hr + -- BEGIN conclusion + subst out0 out1 out2 out3 + have hV : value.toNat = x10 + 2^64 * x11 + 2^128 * x12 + 2^192 * x13 := by + simp only [Limbs.toNat, e_x10, e_x11, e_x12, e_x13] + have hP : modulus.toNat = x5 + 2^64 * x6 + 2^128 * x7 + 2^192 * x8 := by + simp only [Limbs.toNat, e_x5, e_x6, e_x7, e_x8] + have hP_pos : 0 < modulus.toNat := by simp only [Limbs.toNat, hshape.2]; omega + -- `Q < 2^256` bounds `Q * p` linearly; with `t < 2^256` it puts the helper's result at + -- most `p`. + have hQP : Q * modulus.toNat + modulus.toNat ≤ 2^256 * modulus.toNat := by + rw [← Nat.succ_mul]; exact Nat.mul_le_mul_right _ hQ + refine ⟨⟨b_x10_2, b_x11_2, b_x12_2, b_x13_2⟩, ?_⟩ + show x10_2 + 2^64 * x11_2 + 2^128 * x12_2 + 2^192 * x13_2 < modulus.toNat ∧ + 2^256 * (x10_2 + 2^64 * x11_2 + 2^128 * x12_2 + 2^192 * x13_2) ≡ value.toNat [MOD modulus.toNat] + -- The subtraction chain computes `r - p`, and its final borrow is set (`c_3 = 0`) exactly when + -- `r < p`. Then the result is `r`; otherwise it is `r - p`, which is `0` because `r ≤ p`. + obtain hc | hc : c_3 = 0 ∨ c_3 = 1 := by omega + · rw [if_pos hc] at e_x10_2 e_x11_2 e_x12_2 e_x13_2 + exact ⟨by omega, modEq_of_add_mul _ _ 0 Q _ (by omega)⟩ + · rw [if_neg (by omega)] at e_x10_2 e_x11_2 e_x12_2 e_x13_2 + exact ⟨by omega, modEq_of_add_mul _ _ (2^256) Q _ (by omega)⟩ + -- END conclusion + +-- BEGIN mulMont_spec statement +-- The proof is about 1600 lines of small steps: the generated skeleton is cheap, but its +-- annotation blocks run some sixty `clear * -` calls in a context of a thousand hypotheses, +-- and their total exceeds the default per-declaration budget. +set_option maxHeartbeats 1000000 in +/-- Montgomery multiplication: the result is below `p` and `2^256 * result ≡ lhs * rhs (mod p)`, +under two arithmetic conditions that each operand contract implies (`mulMont_spec_of_lhs_lt` and +`mulMont_spec_of_rhs_lt`). `hsafe` keeps the five-limb accumulator below `2^320` in rounds 1 to 3, +where it holds the previous round's result (below `lhs + p`) plus `lhs * rhs_i`, and then the low +limbs of the reduction; without it the `adc` that closes each fold can drop a carry. `hfinal` keeps +the final accumulator below `2 * p`, which one conditional subtraction reduces. -/ +theorem mulMont_spec (lhs rhs modulus : Limbs) (inv : Nat) (hlhs : lhs.Bounded) + (hrhs : rhs.Bounded) (hm : modulus.Bounded) (hshape : modulus.l2 = 0 ∧ modulus.l3 = 2^62) + (hinv_lt : inv < 2^64) (hinv : (inv * modulus.l0 + 1) % 2^64 = 0) + (hsafe : lhs.toNat * (rhs.l1 + 1) + modulus.toNat + 3 * 2^254 + 2^128 ≤ 2^320 ∧ + lhs.toNat * (rhs.l2 + 1) + modulus.toNat + 3 * 2^254 + 2^128 ≤ 2^320 ∧ + lhs.toNat * (rhs.l3 + 1) + modulus.toNat + 3 * 2^254 + 2^128 ≤ 2^320) + (hfinal : lhs.toNat * rhs.toNat < 2^256 * modulus.toNat) : + ∀ r, r = mulMont lhs rhs modulus inv → + r.Bounded ∧ r.toNat < modulus.toNat ∧ + 2^256 * r.toNat ≡ lhs.toNat * rhs.toNat [MOD modulus.toNat] := by + intro r hr +-- END mulMont_spec statement + -- generated skeleton for `mulMont`: do not edit between the annotations + unfold mulMont at hr + lift_lets at hr + -- x4: argument + extract_lets +onlyGivenNames x4 at hr + have e_x4 : x4 = inv := rfl + clear_value x4 + have b_x4 : x4 < 2^64 := by rw [e_x4]; exact hinv_lt + -- x10: ldp x10,x11,[x1] + extract_lets +onlyGivenNames x10 at hr + have e_x10 : x10 = lhs.l0 := rfl + clear_value x10 + have b_x10 : x10 < 2^64 := by rw [e_x10]; exact hlhs.1 + -- x11: ldp x10,x11,[x1] + extract_lets +onlyGivenNames x11 at hr + have e_x11 : x11 = lhs.l1 := rfl + clear_value x11 + have b_x11 : x11 < 2^64 := by rw [e_x11]; exact hlhs.2.1 + -- x9: ldr x9,[x2] + extract_lets +onlyGivenNames x9 at hr + have e_x9 : x9 = rhs.l0 := rfl + clear_value x9 + have b_x9 : x9 < 2^64 := by rw [e_x9]; exact hrhs.1 + -- x12: ldp x12,x13,[x1,#16] + extract_lets +onlyGivenNames x12 at hr + have e_x12 : x12 = lhs.l2 := rfl + clear_value x12 + have b_x12 : x12 < 2^64 := by rw [e_x12]; exact hlhs.2.2.1 + -- x13: ldp x12,x13,[x1,#16] + extract_lets +onlyGivenNames x13 at hr + have e_x13 : x13 = lhs.l3 := rfl + clear_value x13 + have b_x13 : x13 < 2^64 := by rw [e_x13]; exact hlhs.2.2.2 + -- x19: mul x19,x10,x9 + extract_lets +onlyGivenNames x19 at hr + have e_x19 : x19 = x10 * x9 % 2^64 := rfl + clear_value x19 + have b_x19 : x19 < 2^64 := by rw [e_x19]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x5: ldp x5,x6,[x3] + extract_lets +onlyGivenNames x5 at hr + have e_x5 : x5 = modulus.l0 := rfl + clear_value x5 + have b_x5 : x5 < 2^64 := by rw [e_x5]; exact hm.1 + -- x6: ldp x5,x6,[x3] + extract_lets +onlyGivenNames x6 at hr + have e_x6 : x6 = modulus.l1 := rfl + clear_value x6 + have b_x6 : x6 < 2^64 := by rw [e_x6]; exact hm.2.1 + -- x20: mul x20,x11,x9 + extract_lets +onlyGivenNames x20 at hr + have e_x20 : x20 = x11 * x9 % 2^64 := rfl + clear_value x20 + have b_x20 : x20 < 2^64 := by rw [e_x20]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x8: ldp x7,x8,[x3,#16] + extract_lets +onlyGivenNames x8 at hr + have e_x8 : x8 = modulus.l3 := rfl + clear_value x8 + have b_x8 : x8 < 2^64 := by rw [e_x8]; exact hm.2.2.2 + -- x21: mul x21,x12,x9 + extract_lets +onlyGivenNames x21 at hr + have e_x21 : x21 = x12 * x9 % 2^64 := rfl + clear_value x21 + have b_x21 : x21 < 2^64 := by rw [e_x21]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x22: mul x22,x13,x9 + extract_lets +onlyGivenNames x22 at hr + have e_x22 : x22 = x13 * x9 % 2^64 := rfl + clear_value x22 + have b_x22 : x22 < 2^64 := by rw [e_x22]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x14: umulh x14,x10,x9 + extract_lets +onlyGivenNames x14 at hr + have e_x14 : x14 = x10 * x9 / 2^64 := rfl + clear_value x14 + have p_x14 : x10 * x9 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x10 b_x9 + have b_x14 : x14 < 2^64 := by rw [e_x14]; exact Nat.div_lt_of_lt_mul p_x14 + have d_x14 : x19 + 2^64 * x14 = x10 * x9 := by + rw [e_x19, e_x14]; exact Nat.mod_add_div _ _ + clear e_x19 e_x14 + -- x15: umulh x15,x11,x9 + extract_lets +onlyGivenNames x15 at hr + have e_x15 : x15 = x11 * x9 / 2^64 := rfl + clear_value x15 + have p_x15 : x11 * x9 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x11 b_x9 + have b_x15 : x15 < 2^64 := by rw [e_x15]; exact Nat.div_lt_of_lt_mul p_x15 + have d_x15 : x20 + 2^64 * x15 = x11 * x9 := by + rw [e_x20, e_x15]; exact Nat.mod_add_div _ _ + clear e_x20 e_x15 + -- x3: mul x3,x4,x19 + extract_lets +onlyGivenNames x3 at hr + have e_x3 : x3 = x4 * x19 % 2^64 := rfl + clear_value x3 + have b_x3 : x3 < 2^64 := by rw [e_x3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x16: umulh x16,x12,x9 + extract_lets +onlyGivenNames x16 at hr + have e_x16 : x16 = x12 * x9 / 2^64 := rfl + clear_value x16 + have p_x16 : x12 * x9 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x12 b_x9 + have b_x16 : x16 < 2^64 := by rw [e_x16]; exact Nat.div_lt_of_lt_mul p_x16 + have d_x16 : x21 + 2^64 * x16 = x12 * x9 := by + rw [e_x21, e_x16]; exact Nat.mod_add_div _ _ + clear e_x21 e_x16 + -- x17: umulh x17,x13,x9 + extract_lets +onlyGivenNames x17 at hr + have e_x17 : x17 = x13 * x9 / 2^64 := rfl + clear_value x17 + have p_x17 : x13 * x9 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x13 b_x9 + have b_x17 : x17 < 2^64 := by rw [e_x17]; exact Nat.div_lt_of_lt_mul p_x17 + have d_x17 : x22 + 2^64 * x17 = x13 * x9 := by + rw [e_x22, e_x17]; exact Nat.mod_add_div _ _ + clear e_x22 e_x17 + -- x20_1: adds x20,x20,x14 + extract_lets +onlyGivenNames s x20_1 c at hr + have e_x20_1 : x20_1 = (x20 + x14 + 0) % 2^64 := rfl + have e_c : c = (x20 + x14 + 0) / 2^64 := rfl + clear_value s x20_1 c + have l_x20_1 : x20_1 + 2^64 * c = x20 + x14 + 0 := by + rw [e_x20_1, e_c]; exact Nat.mod_add_div _ _ + have b_x20_1 : x20_1 < 2^64 := by rw [e_x20_1]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c : c ≤ 1 := by + rw [e_c]; exact addc_carry_le_one x20 x14 0 b_x20 b_x14 (by decide) + clear e_x20_1 e_c + -- x21_1: adcs x21,x21,x15 + extract_lets +onlyGivenNames s_1 x21_1 c_1 at hr + have e_x21_1 : x21_1 = (x21 + x15 + c) % 2^64 := rfl + have e_c_1 : c_1 = (x21 + x15 + c) / 2^64 := rfl + clear_value s_1 x21_1 c_1 + have l_x21_1 : x21_1 + 2^64 * c_1 = x21 + x15 + c := by + rw [e_x21_1, e_c_1]; exact Nat.mod_add_div _ _ + have b_x21_1 : x21_1 < 2^64 := by rw [e_x21_1]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_1 : c_1 ≤ 1 := by + rw [e_c_1]; exact addc_carry_le_one x21 x15 c b_x21 b_x15 b_c + clear e_x21_1 e_c_1 + -- x15_1: mul x15,x6,x3 + extract_lets +onlyGivenNames x15_1 at hr + have e_x15_1 : x15_1 = x6 * x3 % 2^64 := rfl + clear_value x15_1 + have b_x15_1 : x15_1 < 2^64 := by rw [e_x15_1]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x22_1: adcs x22,x22,x16 + extract_lets +onlyGivenNames s_2 x22_1 c_2 at hr + have e_x22_1 : x22_1 = (x22 + x16 + c_1) % 2^64 := rfl + have e_c_2 : c_2 = (x22 + x16 + c_1) / 2^64 := rfl + clear_value s_2 x22_1 c_2 + have l_x22_1 : x22_1 + 2^64 * c_2 = x22 + x16 + c_1 := by + rw [e_x22_1, e_c_2]; exact Nat.mod_add_div _ _ + have b_x22_1 : x22_1 < 2^64 := by rw [e_x22_1]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_2 : c_2 ≤ 1 := by + rw [e_c_2]; exact addc_carry_le_one x22 x16 c_1 b_x22 b_x16 b_c_1 + clear e_x22_1 e_c_2 + -- x23: adc x23,xzr,x17 + extract_lets +onlyGivenNames x23 at hr + have e_x23 : x23 = (0 + x17 + c_2) % 2^64 := rfl + clear_value x23 + have b_x23 : x23 < 2^64 := by rw [e_x23]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x23, b_k_x23, l_x23⟩ : + ∃ k, k ≤ 1 ∧ x23 + 2^64 * k = 0 + x17 + c_2 := + ⟨(0 + x17 + c_2) / 2^64, addc_carry_le_one 0 x17 c_2 (by decide) b_x17 b_c_2, + by rw [e_x23]; exact Nat.mod_add_div _ _⟩ + clear e_x23 + -- BEGIN round 0 fold + have hP : modulus.toNat = x5 + 2^64 * x6 + 2^192 * 2^62 := by + rw [e_x5, e_x6]; simp only [Limbs.toNat, hshape.1, hshape.2, Nat.mul_zero, Nat.add_zero] + have hP_lt : modulus.toNat < 2^255 := by clear * - hP b_x5 b_x6; omega + have hL256 : lhs.toNat < 2^256 := by + clear * - e_x10 e_x11 e_x12 e_x13 b_x10 b_x11 b_x12 b_x13 + simp only [Limbs.toNat]; omega + -- `lhs * rhs_0` as the sum of the limb products. + have hL_0 : lhs.toNat * x9 + = x10 * x9 + 2^64 * (x11 * x9) + 2^128 * (x12 * x9) + 2^192 * (x13 * x9) := by + rw [e_x10, e_x11, e_x12, e_x13]; simp only [Limbs.toNat]; ring + -- The one `adc` of this round's fold cannot wrap: the high half of a product of two limbs + -- is at most `2^64 - 2`. + have hx17 : x13 * x9 ≤ (2^64 - 1) * (2^64 - 1) := + Nat.mul_le_mul (Nat.le_sub_one_of_lt b_x13) (Nat.le_sub_one_of_lt b_x9) + norm_num at hx17 + have hk_0 : k_x23 = 0 := by + clear * - l_x23 d_x17 hx17 b_c_2 + omega + have F_0 : x19 + 2^64 * x20_1 + 2^128 * x21_1 + 2^192 * x22_1 + 2^256 * x23 = lhs.toNat * x9 := by + clear * - l_x20_1 l_x21_1 l_x22_1 l_x23 d_x14 d_x15 d_x16 d_x17 hL_0 hk_0 + omega + -- END round 0 fold + -- x17_1: lsl x17,x3,#62 + extract_lets +onlyGivenNames x17_1 at hr + have e_x17_1 : x17_1 = x3 * 2^62 % 2^64 := rfl + clear_value x17_1 + have b_x17_1 : x17_1 < 2^64 := by rw [e_x17_1]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x9_1: ldr x9,[x2,8*1] + extract_lets +onlyGivenNames x9_1 at hr + have e_x9_1 : x9_1 = rhs.l1 := rfl + clear_value x9_1 + have b_x9_1 : x9_1 < 2^64 := by rw [e_x9_1]; exact hrhs.2.1 + -- c_3: subs xzr,x19,#1 + extract_lets +onlyGivenNames c_3 at hr + have e_c_3 : c_3 = (x19 + 2^64 - 1 - (1 - 1)) / 2^64 := rfl + clear_value c_3 + have b_c_3 : c_3 ≤ 1 := by rw [e_c_3]; exact subc_carry_le_one x19 1 1 b_x19 + have l_c_3 : (c_3 = 1 ∧ 1 + 1 ≤ x19 + 1) ∨ (c_3 = 0 ∧ x19 + 1 < 1 + 1) := + subc_carry_cases x19 1 1 _ e_c_3 b_x19 (by decide) (by decide) + clear e_c_3 + -- x14_1: umulh x14,x5,x3 + extract_lets +onlyGivenNames x14_1 at hr + have e_x14_1 : x14_1 = x5 * x3 / 2^64 := rfl + clear_value x14_1 + have p_x14_1 : x5 * x3 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x5 b_x3 + have b_x14_1 : x14_1 < 2^64 := by rw [e_x14_1]; exact Nat.div_lt_of_lt_mul p_x14_1 + obtain ⟨lo_x14_1, b_lo_x14_1, d_x14_1⟩ : + ∃ lo, lo < 2^64 ∧ lo + 2^64 * x14_1 = x5 * x3 := + ⟨x5 * x3 % 2^64, Nat.mod_lt _ (Nat.two_pow_pos _), + by rw [e_x14_1]; exact Nat.mod_add_div _ _⟩ + clear e_x14_1 + -- x20_2: adcs x20,x20,x15 + extract_lets +onlyGivenNames s_3 x20_2 c_4 at hr + have e_x20_2 : x20_2 = (x20_1 + x15_1 + c_3) % 2^64 := rfl + have e_c_4 : c_4 = (x20_1 + x15_1 + c_3) / 2^64 := rfl + clear_value s_3 x20_2 c_4 + have l_x20_2 : x20_2 + 2^64 * c_4 = x20_1 + x15_1 + c_3 := by + rw [e_x20_2, e_c_4]; exact Nat.mod_add_div _ _ + have b_x20_2 : x20_2 < 2^64 := by rw [e_x20_2]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_4 : c_4 ≤ 1 := by + rw [e_c_4]; exact addc_carry_le_one x20_1 x15_1 c_3 b_x20_1 b_x15_1 b_c_3 + clear e_x20_2 e_c_4 + -- x15_2: umulh x15,x6,x3 + extract_lets +onlyGivenNames x15_2 at hr + have e_x15_2 : x15_2 = x6 * x3 / 2^64 := rfl + clear_value x15_2 + have p_x15_2 : x6 * x3 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x6 b_x3 + have b_x15_2 : x15_2 < 2^64 := by rw [e_x15_2]; exact Nat.div_lt_of_lt_mul p_x15_2 + have d_x15_2 : x15_1 + 2^64 * x15_2 = x6 * x3 := by + rw [e_x15_1, e_x15_2]; exact Nat.mod_add_div _ _ + clear e_x15_1 e_x15_2 + -- x21_2: adcs x21,x21,xzr + extract_lets +onlyGivenNames s_4 x21_2 c_5 at hr + have e_x21_2 : x21_2 = (x21_1 + 0 + c_4) % 2^64 := rfl + have e_c_5 : c_5 = (x21_1 + 0 + c_4) / 2^64 := rfl + clear_value s_4 x21_2 c_5 + have l_x21_2 : x21_2 + 2^64 * c_5 = x21_1 + 0 + c_4 := by + rw [e_x21_2, e_c_5]; exact Nat.mod_add_div _ _ + have b_x21_2 : x21_2 < 2^64 := by rw [e_x21_2]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_5 : c_5 ≤ 1 := by + rw [e_c_5]; exact addc_carry_le_one x21_1 0 c_4 b_x21_1 (by decide) b_c_4 + clear e_x21_2 e_c_5 + -- x22_2: adcs x22,x22,x17 + extract_lets +onlyGivenNames s_5 x22_2 c_6 at hr + have e_x22_2 : x22_2 = (x22_1 + x17_1 + c_5) % 2^64 := rfl + have e_c_6 : c_6 = (x22_1 + x17_1 + c_5) / 2^64 := rfl + clear_value s_5 x22_2 c_6 + have l_x22_2 : x22_2 + 2^64 * c_6 = x22_1 + x17_1 + c_5 := by + rw [e_x22_2, e_c_6]; exact Nat.mod_add_div _ _ + have b_x22_2 : x22_2 < 2^64 := by rw [e_x22_2]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_6 : c_6 ≤ 1 := by + rw [e_c_6]; exact addc_carry_le_one x22_1 x17_1 c_5 b_x22_1 b_x17_1 b_c_5 + clear e_x22_2 e_c_6 + -- x17_2: lsr x17,x3,#2 + extract_lets +onlyGivenNames x17_2 at hr + have e_x17_2 : x17_2 = x3 / 2^2 := rfl + clear_value x17_2 + have b_x17_2 : x17_2 < 2^62 := by + rw [e_x17_2]; exact Nat.div_lt_of_lt_mul (lt_of_lt_of_eq b_x3 (by norm_num)) + have sh_x17_2 : x17_1 + 2^64 * x17_2 = x3 * 2^62 := by + rw [e_x17_1, e_x17_2]; exact lsl62_lsr2_split _ + clear e_x17_1 e_x17_2 + -- x23_1: adc x23,x23,xzr + extract_lets +onlyGivenNames x23_1 at hr + have e_x23_1 : x23_1 = (x23 + 0 + c_6) % 2^64 := rfl + clear_value x23_1 + have b_x23_1 : x23_1 < 2^64 := by rw [e_x23_1]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x23_1, b_k_x23_1, l_x23_1⟩ : + ∃ k, k ≤ 1 ∧ x23_1 + 2^64 * k = x23 + 0 + c_6 := + ⟨(x23 + 0 + c_6) / 2^64, addc_carry_le_one x23 0 c_6 b_x23 (by decide) b_c_6, + by rw [e_x23_1]; exact Nat.mod_add_div _ _⟩ + clear e_x23_1 + -- x19_1: adds x19,x20,x14 + extract_lets +onlyGivenNames s_6 x19_1 c_7 at hr + have e_x19_1 : x19_1 = (x20_2 + x14_1 + 0) % 2^64 := rfl + have e_c_7 : c_7 = (x20_2 + x14_1 + 0) / 2^64 := rfl + clear_value s_6 x19_1 c_7 + have l_x19_1 : x19_1 + 2^64 * c_7 = x20_2 + x14_1 + 0 := by + rw [e_x19_1, e_c_7]; exact Nat.mod_add_div _ _ + have b_x19_1 : x19_1 < 2^64 := by rw [e_x19_1]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_7 : c_7 ≤ 1 := by + rw [e_c_7]; exact addc_carry_le_one x20_2 x14_1 0 b_x20_2 b_x14_1 (by decide) + clear e_x19_1 e_c_7 + -- x14_2: mul x14,x10,x9 + extract_lets +onlyGivenNames x14_2 at hr + have e_x14_2 : x14_2 = x10 * x9_1 % 2^64 := rfl + clear_value x14_2 + have b_x14_2 : x14_2 < 2^64 := by rw [e_x14_2]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x20_3: adcs x20,x21,x15 + extract_lets +onlyGivenNames s_7 x20_3 c_8 at hr + have e_x20_3 : x20_3 = (x21_2 + x15_2 + c_7) % 2^64 := rfl + have e_c_8 : c_8 = (x21_2 + x15_2 + c_7) / 2^64 := rfl + clear_value s_7 x20_3 c_8 + have l_x20_3 : x20_3 + 2^64 * c_8 = x21_2 + x15_2 + c_7 := by + rw [e_x20_3, e_c_8]; exact Nat.mod_add_div _ _ + have b_x20_3 : x20_3 < 2^64 := by rw [e_x20_3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_8 : c_8 ≤ 1 := by + rw [e_c_8]; exact addc_carry_le_one x21_2 x15_2 c_7 b_x21_2 b_x15_2 b_c_7 + clear e_x20_3 e_c_8 + -- x15_3: mul x15,x11,x9 + extract_lets +onlyGivenNames x15_3 at hr + have e_x15_3 : x15_3 = x11 * x9_1 % 2^64 := rfl + clear_value x15_3 + have b_x15_3 : x15_3 < 2^64 := by rw [e_x15_3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x21_3: adcs x21,x22,xzr + extract_lets +onlyGivenNames s_8 x21_3 c_9 at hr + have e_x21_3 : x21_3 = (x22_2 + 0 + c_8) % 2^64 := rfl + have e_c_9 : c_9 = (x22_2 + 0 + c_8) / 2^64 := rfl + clear_value s_8 x21_3 c_9 + have l_x21_3 : x21_3 + 2^64 * c_9 = x22_2 + 0 + c_8 := by + rw [e_x21_3, e_c_9]; exact Nat.mod_add_div _ _ + have b_x21_3 : x21_3 < 2^64 := by rw [e_x21_3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_9 : c_9 ≤ 1 := by + rw [e_c_9]; exact addc_carry_le_one x22_2 0 c_8 b_x22_2 (by decide) b_c_8 + clear e_x21_3 e_c_9 + -- x16_1: mul x16,x12,x9 + extract_lets +onlyGivenNames x16_1 at hr + have e_x16_1 : x16_1 = x12 * x9_1 % 2^64 := rfl + clear_value x16_1 + have b_x16_1 : x16_1 < 2^64 := by rw [e_x16_1]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x22_3: adcs x22,x23,x17 + extract_lets +onlyGivenNames s_9 x22_3 c_10 at hr + have e_x22_3 : x22_3 = (x23_1 + x17_2 + c_9) % 2^64 := rfl + have e_c_10 : c_10 = (x23_1 + x17_2 + c_9) / 2^64 := rfl + clear_value s_9 x22_3 c_10 + have l_x22_3 : x22_3 + 2^64 * c_10 = x23_1 + x17_2 + c_9 := by + rw [e_x22_3, e_c_10]; exact Nat.mod_add_div _ _ + have b_x22_3 : x22_3 < 2^64 := by rw [e_x22_3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_10 : c_10 ≤ 1 := by + rw [e_c_10]; exact addc_carry_le_one x23_1 x17_2 c_9 b_x23_1 (lt_of_lt_of_le b_x17_2 (by norm_num)) b_c_9 + clear e_x22_3 e_c_10 + -- x17_3: mul x17,x13,x9 + extract_lets +onlyGivenNames x17_3 at hr + have e_x17_3 : x17_3 = x13 * x9_1 % 2^64 := rfl + clear_value x17_3 + have b_x17_3 : x17_3 < 2^64 := by rw [e_x17_3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x23_2: adc x23,xzr,xzr + extract_lets +onlyGivenNames x23_2 at hr + have e_x23_2 : x23_2 = (0 + 0 + c_10) % 2^64 := rfl + clear_value x23_2 + have b_x23_2 : x23_2 < 2^64 := by rw [e_x23_2]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x23_2, b_k_x23_2, l_x23_2⟩ : + ∃ k, k ≤ 1 ∧ x23_2 + 2^64 * k = 0 + 0 + c_10 := + ⟨(0 + 0 + c_10) / 2^64, addc_carry_le_one 0 0 c_10 (by decide) (by decide) b_c_10, + by rw [e_x23_2]; exact Nat.mod_add_div _ _⟩ + clear e_x23_2 + -- BEGIN round 0 reduction + -- Cancellation: the low limb of `x19 + p0 * x3` is zero, so `x19 + lo_x14_1` is + -- `0` or `2^64`, and `subs xzr, x19, #1` set the carry exactly when it is `2^64`. + have hc_0 : x19 + lo_x14_1 = 2^64 * c_3 := by + have h := cancel_low x19 inv modulus.l0 hinv + rw [← e_x5, ← e_x4, ← e_x3, ← d_x14_1, Nat.add_mul_mod_self_left, + Nat.mod_eq_of_lt b_lo_x14_1] at h + clear * - h b_x19 b_lo_x14_1 l_c_3 + omega + have bc_0 : c_3 ≤ 1 := by clear * - l_c_3; omega + have hPq_0 : x3 * modulus.toNat = x5 * x3 + 2^64 * (x6 * x3) + 2^254 * x3 := by + rw [hP]; ring + -- `x17_1` is the low two bits of `x3` at the top of a limb. + have hsh_0 : x17_1 ≤ 3 * 2^62 := by + clear * - sh_x17_2 b_x17_1 b_x17_2; omega + -- The reduction's carry chain, summed with the limb weights. + have hsum'_0 : x19 + 2^64 * x20_2 + 2^128 * x21_2 + 2^192 * x22_2 + 2^256 * x23_1 + + 2^320 * k_x23_1 + = x19 + 2^64 * x20_1 + 2^128 * x21_1 + 2^192 * x22_1 + 2^256 * x23 + + 2^64 * x15_1 + 2^64 * c_3 + 2^192 * x17_1 := by + clear * - l_x20_2 l_x21_2 l_x22_2 l_x23_1 + omega + -- Neither `adc` of the reduction wraps: `lhs * rhs_0` is below `2^320 - 2^256`, and the + -- reduction adds less than `2^256` to the five-limb accumulator before the shift. + have hF0b : lhs.toNat * x9 ≤ (2^256 - 1) * (2^64 - 1) := + Nat.mul_le_mul (Nat.le_sub_one_of_lt hL256) (Nat.le_sub_one_of_lt b_x9) + norm_num at hF0b + have hkr_0 : k_x23_1 = 0 := by + clear * - hsum'_0 F_0 hF0b b_x15_1 bc_0 hsh_0 + omega + have hks_0 : k_x23_2 = 0 := by clear * - l_x23_2 b_c_10; omega + have I_0 : 2^64 * (x19_1 + 2^64 * x20_3 + 2^128 * x21_3 + 2^192 * x22_3 + 2^256 * x23_2) + = x19 + 2^64 * x20_1 + 2^128 * x21_1 + 2^192 * x22_1 + 2^256 * x23 + + x3 * modulus.toNat := by + clear * - hc_0 d_x14_1 d_x15_2 sh_x17_2 l_x20_2 l_x21_2 l_x22_2 l_x23_1 l_x19_1 l_x20_3 l_x21_3 + l_x22_3 l_x23_2 hkr_0 hks_0 hPq_0 + omega + -- The shifted accumulator stays below `lhs + p`. + have hLx_0 : lhs.toNat * x9 + lhs.toNat ≤ lhs.toNat * 2^64 := by + rw [← Nat.mul_succ]; exact Nat.mul_le_mul_left _ b_x9 + have hqP_0 : x3 * modulus.toNat + modulus.toNat ≤ 2^64 * modulus.toNat := by + rw [← Nat.succ_mul]; exact Nat.mul_le_mul_right _ b_x3 + have B_0 : x19_1 + 2^64 * x20_3 + 2^128 * x21_3 + 2^192 * x22_3 + 2^256 * x23_2 + < lhs.toNat + modulus.toNat := by + clear * - I_0 F_0 hLx_0 hqP_0 hP + omega + have t_0 : x23_2 ≤ 1 := by clear * - l_x23_2 hks_0 b_c_10; omega + -- END round 0 reduction + -- x19_2: adds x19,x19,x14 + extract_lets +onlyGivenNames s_10 x19_2 c_11 at hr + have e_x19_2 : x19_2 = (x19_1 + x14_2 + 0) % 2^64 := rfl + have e_c_11 : c_11 = (x19_1 + x14_2 + 0) / 2^64 := rfl + clear_value s_10 x19_2 c_11 + have l_x19_2 : x19_2 + 2^64 * c_11 = x19_1 + x14_2 + 0 := by + rw [e_x19_2, e_c_11]; exact Nat.mod_add_div _ _ + have b_x19_2 : x19_2 < 2^64 := by rw [e_x19_2]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_11 : c_11 ≤ 1 := by + rw [e_c_11]; exact addc_carry_le_one x19_1 x14_2 0 b_x19_1 b_x14_2 (by decide) + clear e_x19_2 e_c_11 + -- x14_3: umulh x14,x10,x9 + extract_lets +onlyGivenNames x14_3 at hr + have e_x14_3 : x14_3 = x10 * x9_1 / 2^64 := rfl + clear_value x14_3 + have p_x14_3 : x10 * x9_1 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x10 b_x9_1 + have b_x14_3 : x14_3 < 2^64 := by rw [e_x14_3]; exact Nat.div_lt_of_lt_mul p_x14_3 + have d_x14_3 : x14_2 + 2^64 * x14_3 = x10 * x9_1 := by + rw [e_x14_2, e_x14_3]; exact Nat.mod_add_div _ _ + clear e_x14_2 e_x14_3 + -- x20_4: adcs x20,x20,x15 + extract_lets +onlyGivenNames s_11 x20_4 c_12 at hr + have e_x20_4 : x20_4 = (x20_3 + x15_3 + c_11) % 2^64 := rfl + have e_c_12 : c_12 = (x20_3 + x15_3 + c_11) / 2^64 := rfl + clear_value s_11 x20_4 c_12 + have l_x20_4 : x20_4 + 2^64 * c_12 = x20_3 + x15_3 + c_11 := by + rw [e_x20_4, e_c_12]; exact Nat.mod_add_div _ _ + have b_x20_4 : x20_4 < 2^64 := by rw [e_x20_4]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_12 : c_12 ≤ 1 := by + rw [e_c_12]; exact addc_carry_le_one x20_3 x15_3 c_11 b_x20_3 b_x15_3 b_c_11 + clear e_x20_4 e_c_12 + -- x15_4: umulh x15,x11,x9 + extract_lets +onlyGivenNames x15_4 at hr + have e_x15_4 : x15_4 = x11 * x9_1 / 2^64 := rfl + clear_value x15_4 + have p_x15_4 : x11 * x9_1 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x11 b_x9_1 + have b_x15_4 : x15_4 < 2^64 := by rw [e_x15_4]; exact Nat.div_lt_of_lt_mul p_x15_4 + have d_x15_4 : x15_3 + 2^64 * x15_4 = x11 * x9_1 := by + rw [e_x15_3, e_x15_4]; exact Nat.mod_add_div _ _ + clear e_x15_3 e_x15_4 + -- x21_4: adcs x21,x21,x16 + extract_lets +onlyGivenNames s_12 x21_4 c_13 at hr + have e_x21_4 : x21_4 = (x21_3 + x16_1 + c_12) % 2^64 := rfl + have e_c_13 : c_13 = (x21_3 + x16_1 + c_12) / 2^64 := rfl + clear_value s_12 x21_4 c_13 + have l_x21_4 : x21_4 + 2^64 * c_13 = x21_3 + x16_1 + c_12 := by + rw [e_x21_4, e_c_13]; exact Nat.mod_add_div _ _ + have b_x21_4 : x21_4 < 2^64 := by rw [e_x21_4]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_13 : c_13 ≤ 1 := by + rw [e_c_13]; exact addc_carry_le_one x21_3 x16_1 c_12 b_x21_3 b_x16_1 b_c_12 + clear e_x21_4 e_c_13 + -- x3_1: mul x3,x4,x19 + extract_lets +onlyGivenNames x3_1 at hr + have e_x3_1 : x3_1 = x4 * x19_2 % 2^64 := rfl + clear_value x3_1 + have b_x3_1 : x3_1 < 2^64 := by rw [e_x3_1]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x16_2: umulh x16,x12,x9 + extract_lets +onlyGivenNames x16_2 at hr + have e_x16_2 : x16_2 = x12 * x9_1 / 2^64 := rfl + clear_value x16_2 + have p_x16_2 : x12 * x9_1 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x12 b_x9_1 + have b_x16_2 : x16_2 < 2^64 := by rw [e_x16_2]; exact Nat.div_lt_of_lt_mul p_x16_2 + have d_x16_2 : x16_1 + 2^64 * x16_2 = x12 * x9_1 := by + rw [e_x16_1, e_x16_2]; exact Nat.mod_add_div _ _ + clear e_x16_1 e_x16_2 + -- x22_4: adcs x22,x22,x17 + extract_lets +onlyGivenNames s_13 x22_4 c_14 at hr + have e_x22_4 : x22_4 = (x22_3 + x17_3 + c_13) % 2^64 := rfl + have e_c_14 : c_14 = (x22_3 + x17_3 + c_13) / 2^64 := rfl + clear_value s_13 x22_4 c_14 + have l_x22_4 : x22_4 + 2^64 * c_14 = x22_3 + x17_3 + c_13 := by + rw [e_x22_4, e_c_14]; exact Nat.mod_add_div _ _ + have b_x22_4 : x22_4 < 2^64 := by rw [e_x22_4]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_14 : c_14 ≤ 1 := by + rw [e_c_14]; exact addc_carry_le_one x22_3 x17_3 c_13 b_x22_3 b_x17_3 b_c_13 + clear e_x22_4 e_c_14 + -- x17_4: umulh x17,x13,x9 + extract_lets +onlyGivenNames x17_4 at hr + have e_x17_4 : x17_4 = x13 * x9_1 / 2^64 := rfl + clear_value x17_4 + have p_x17_4 : x13 * x9_1 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x13 b_x9_1 + have b_x17_4 : x17_4 < 2^64 := by rw [e_x17_4]; exact Nat.div_lt_of_lt_mul p_x17_4 + have d_x17_4 : x17_3 + 2^64 * x17_4 = x13 * x9_1 := by + rw [e_x17_3, e_x17_4]; exact Nat.mod_add_div _ _ + clear e_x17_3 e_x17_4 + -- x23_3: adc x23,x23,xzr + extract_lets +onlyGivenNames x23_3 at hr + have e_x23_3 : x23_3 = (x23_2 + 0 + c_14) % 2^64 := rfl + clear_value x23_3 + have b_x23_3 : x23_3 < 2^64 := by rw [e_x23_3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x23_3, b_k_x23_3, l_x23_3⟩ : + ∃ k, k ≤ 1 ∧ x23_3 + 2^64 * k = x23_2 + 0 + c_14 := + ⟨(x23_2 + 0 + c_14) / 2^64, addc_carry_le_one x23_2 0 c_14 b_x23_2 (by decide) b_c_14, + by rw [e_x23_3]; exact Nat.mod_add_div _ _⟩ + clear e_x23_3 + -- x20_5: adds x20,x20,x14 + extract_lets +onlyGivenNames s_14 x20_5 c_15 at hr + have e_x20_5 : x20_5 = (x20_4 + x14_3 + 0) % 2^64 := rfl + have e_c_15 : c_15 = (x20_4 + x14_3 + 0) / 2^64 := rfl + clear_value s_14 x20_5 c_15 + have l_x20_5 : x20_5 + 2^64 * c_15 = x20_4 + x14_3 + 0 := by + rw [e_x20_5, e_c_15]; exact Nat.mod_add_div _ _ + have b_x20_5 : x20_5 < 2^64 := by rw [e_x20_5]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_15 : c_15 ≤ 1 := by + rw [e_c_15]; exact addc_carry_le_one x20_4 x14_3 0 b_x20_4 b_x14_3 (by decide) + clear e_x20_5 e_c_15 + -- x21_5: adcs x21,x21,x15 + extract_lets +onlyGivenNames s_15 x21_5 c_16 at hr + have e_x21_5 : x21_5 = (x21_4 + x15_4 + c_15) % 2^64 := rfl + have e_c_16 : c_16 = (x21_4 + x15_4 + c_15) / 2^64 := rfl + clear_value s_15 x21_5 c_16 + have l_x21_5 : x21_5 + 2^64 * c_16 = x21_4 + x15_4 + c_15 := by + rw [e_x21_5, e_c_16]; exact Nat.mod_add_div _ _ + have b_x21_5 : x21_5 < 2^64 := by rw [e_x21_5]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_16 : c_16 ≤ 1 := by + rw [e_c_16]; exact addc_carry_le_one x21_4 x15_4 c_15 b_x21_4 b_x15_4 b_c_15 + clear e_x21_5 e_c_16 + -- x15_5: mul x15,x6,x3 + extract_lets +onlyGivenNames x15_5 at hr + have e_x15_5 : x15_5 = x6 * x3_1 % 2^64 := rfl + clear_value x15_5 + have b_x15_5 : x15_5 < 2^64 := by rw [e_x15_5]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x22_5: adcs x22,x22,x16 + extract_lets +onlyGivenNames s_16 x22_5 c_17 at hr + have e_x22_5 : x22_5 = (x22_4 + x16_2 + c_16) % 2^64 := rfl + have e_c_17 : c_17 = (x22_4 + x16_2 + c_16) / 2^64 := rfl + clear_value s_16 x22_5 c_17 + have l_x22_5 : x22_5 + 2^64 * c_17 = x22_4 + x16_2 + c_16 := by + rw [e_x22_5, e_c_17]; exact Nat.mod_add_div _ _ + have b_x22_5 : x22_5 < 2^64 := by rw [e_x22_5]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_17 : c_17 ≤ 1 := by + rw [e_c_17]; exact addc_carry_le_one x22_4 x16_2 c_16 b_x22_4 b_x16_2 b_c_16 + clear e_x22_5 e_c_17 + -- x23_4: adc x23,x23,x17 + extract_lets +onlyGivenNames x23_4 at hr + have e_x23_4 : x23_4 = (x23_3 + x17_4 + c_17) % 2^64 := rfl + clear_value x23_4 + have b_x23_4 : x23_4 < 2^64 := by rw [e_x23_4]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x23_4, b_k_x23_4, l_x23_4⟩ : + ∃ k, k ≤ 1 ∧ x23_4 + 2^64 * k = x23_3 + x17_4 + c_17 := + ⟨(x23_3 + x17_4 + c_17) / 2^64, addc_carry_le_one x23_3 x17_4 c_17 b_x23_3 b_x17_4 b_c_17, + by rw [e_x23_4]; exact Nat.mod_add_div _ _⟩ + clear e_x23_4 + -- BEGIN round 1 fold + -- `lhs * rhs_1` as the sum of the limb products. + have hL_1 : lhs.toNat * x9_1 + = x10 * x9_1 + 2^64 * (x11 * x9_1) + 2^128 * (x12 * x9_1) + 2^192 * (x13 * x9_1) := by + rw [e_x10, e_x11, e_x12, e_x13]; simp only [Limbs.toNat]; ring + have hs_1 : lhs.toNat * x9_1 + lhs.toNat + modulus.toNat + 3 * 2^254 + 2^128 ≤ 2^320 := by + rw [e_x9_1, ← Nat.mul_add_one]; exact hsafe.1 + -- The fold's two carry chains, summed with the limb weights. + have hsum_1 : x19_2 + 2^64 * x20_5 + 2^128 * x21_5 + 2^192 * x22_5 + 2^256 * x23_4 + + 2^320 * (k_x23_3 + k_x23_4) + = x19_1 + 2^64 * x20_3 + 2^128 * x21_3 + 2^192 * x22_3 + 2^256 * x23_2 + + lhs.toNat * x9_1 := by + clear * - l_x19_2 l_x20_4 l_x21_4 l_x22_4 l_x23_3 l_x20_5 l_x21_5 l_x22_5 l_x23_4 d_x14_3 + d_x15_4 d_x16_2 d_x17_4 hL_1 + omega + -- Neither `adc` of the fold wraps: the accumulator entering the round is below + -- `lhs + p`, and `hs_1` bounds it plus `lhs * rhs_1` below `2^320`. + have hk_1 : k_x23_3 = 0 ∧ k_x23_4 = 0 := by + clear * - hsum_1 B_0 hs_1 + omega + have F_1 : x19_2 + 2^64 * x20_5 + 2^128 * x21_5 + 2^192 * x22_5 + 2^256 * x23_4 + = x19_1 + 2^64 * x20_3 + 2^128 * x21_3 + 2^192 * x22_3 + 2^256 * x23_2 + + lhs.toNat * x9_1 := by + clear * - hsum_1 hk_1 + omega + -- END round 1 fold + -- x17_5: lsl x17,x3,#62 + extract_lets +onlyGivenNames x17_5 at hr + have e_x17_5 : x17_5 = x3_1 * 2^62 % 2^64 := rfl + clear_value x17_5 + have b_x17_5 : x17_5 < 2^64 := by rw [e_x17_5]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x9_2: ldr x9,[x2,8*2] + extract_lets +onlyGivenNames x9_2 at hr + have e_x9_2 : x9_2 = rhs.l2 := rfl + clear_value x9_2 + have b_x9_2 : x9_2 < 2^64 := by rw [e_x9_2]; exact hrhs.2.2.1 + -- c_18: subs xzr,x19,#1 + extract_lets +onlyGivenNames c_18 at hr + have e_c_18 : c_18 = (x19_2 + 2^64 - 1 - (1 - 1)) / 2^64 := rfl + clear_value c_18 + have b_c_18 : c_18 ≤ 1 := by rw [e_c_18]; exact subc_carry_le_one x19_2 1 1 b_x19_2 + have l_c_18 : (c_18 = 1 ∧ 1 + 1 ≤ x19_2 + 1) ∨ (c_18 = 0 ∧ x19_2 + 1 < 1 + 1) := + subc_carry_cases x19_2 1 1 _ e_c_18 b_x19_2 (by decide) (by decide) + clear e_c_18 + -- x14_4: umulh x14,x5,x3 + extract_lets +onlyGivenNames x14_4 at hr + have e_x14_4 : x14_4 = x5 * x3_1 / 2^64 := rfl + clear_value x14_4 + have p_x14_4 : x5 * x3_1 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x5 b_x3_1 + have b_x14_4 : x14_4 < 2^64 := by rw [e_x14_4]; exact Nat.div_lt_of_lt_mul p_x14_4 + obtain ⟨lo_x14_4, b_lo_x14_4, d_x14_4⟩ : + ∃ lo, lo < 2^64 ∧ lo + 2^64 * x14_4 = x5 * x3_1 := + ⟨x5 * x3_1 % 2^64, Nat.mod_lt _ (Nat.two_pow_pos _), + by rw [e_x14_4]; exact Nat.mod_add_div _ _⟩ + clear e_x14_4 + -- x20_6: adcs x20,x20,x15 + extract_lets +onlyGivenNames s_17 x20_6 c_19 at hr + have e_x20_6 : x20_6 = (x20_5 + x15_5 + c_18) % 2^64 := rfl + have e_c_19 : c_19 = (x20_5 + x15_5 + c_18) / 2^64 := rfl + clear_value s_17 x20_6 c_19 + have l_x20_6 : x20_6 + 2^64 * c_19 = x20_5 + x15_5 + c_18 := by + rw [e_x20_6, e_c_19]; exact Nat.mod_add_div _ _ + have b_x20_6 : x20_6 < 2^64 := by rw [e_x20_6]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_19 : c_19 ≤ 1 := by + rw [e_c_19]; exact addc_carry_le_one x20_5 x15_5 c_18 b_x20_5 b_x15_5 b_c_18 + clear e_x20_6 e_c_19 + -- x15_6: umulh x15,x6,x3 + extract_lets +onlyGivenNames x15_6 at hr + have e_x15_6 : x15_6 = x6 * x3_1 / 2^64 := rfl + clear_value x15_6 + have p_x15_6 : x6 * x3_1 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x6 b_x3_1 + have b_x15_6 : x15_6 < 2^64 := by rw [e_x15_6]; exact Nat.div_lt_of_lt_mul p_x15_6 + have d_x15_6 : x15_5 + 2^64 * x15_6 = x6 * x3_1 := by + rw [e_x15_5, e_x15_6]; exact Nat.mod_add_div _ _ + clear e_x15_5 e_x15_6 + -- x21_6: adcs x21,x21,xzr + extract_lets +onlyGivenNames s_18 x21_6 c_20 at hr + have e_x21_6 : x21_6 = (x21_5 + 0 + c_19) % 2^64 := rfl + have e_c_20 : c_20 = (x21_5 + 0 + c_19) / 2^64 := rfl + clear_value s_18 x21_6 c_20 + have l_x21_6 : x21_6 + 2^64 * c_20 = x21_5 + 0 + c_19 := by + rw [e_x21_6, e_c_20]; exact Nat.mod_add_div _ _ + have b_x21_6 : x21_6 < 2^64 := by rw [e_x21_6]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_20 : c_20 ≤ 1 := by + rw [e_c_20]; exact addc_carry_le_one x21_5 0 c_19 b_x21_5 (by decide) b_c_19 + clear e_x21_6 e_c_20 + -- x22_6: adcs x22,x22,x17 + extract_lets +onlyGivenNames s_19 x22_6 c_21 at hr + have e_x22_6 : x22_6 = (x22_5 + x17_5 + c_20) % 2^64 := rfl + have e_c_21 : c_21 = (x22_5 + x17_5 + c_20) / 2^64 := rfl + clear_value s_19 x22_6 c_21 + have l_x22_6 : x22_6 + 2^64 * c_21 = x22_5 + x17_5 + c_20 := by + rw [e_x22_6, e_c_21]; exact Nat.mod_add_div _ _ + have b_x22_6 : x22_6 < 2^64 := by rw [e_x22_6]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_21 : c_21 ≤ 1 := by + rw [e_c_21]; exact addc_carry_le_one x22_5 x17_5 c_20 b_x22_5 b_x17_5 b_c_20 + clear e_x22_6 e_c_21 + -- x17_6: lsr x17,x3,#2 + extract_lets +onlyGivenNames x17_6 at hr + have e_x17_6 : x17_6 = x3_1 / 2^2 := rfl + clear_value x17_6 + have b_x17_6 : x17_6 < 2^62 := by + rw [e_x17_6]; exact Nat.div_lt_of_lt_mul (lt_of_lt_of_eq b_x3_1 (by norm_num)) + have sh_x17_6 : x17_5 + 2^64 * x17_6 = x3_1 * 2^62 := by + rw [e_x17_5, e_x17_6]; exact lsl62_lsr2_split _ + clear e_x17_5 e_x17_6 + -- x23_5: adc x23,x23,xzr + extract_lets +onlyGivenNames x23_5 at hr + have e_x23_5 : x23_5 = (x23_4 + 0 + c_21) % 2^64 := rfl + clear_value x23_5 + have b_x23_5 : x23_5 < 2^64 := by rw [e_x23_5]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x23_5, b_k_x23_5, l_x23_5⟩ : + ∃ k, k ≤ 1 ∧ x23_5 + 2^64 * k = x23_4 + 0 + c_21 := + ⟨(x23_4 + 0 + c_21) / 2^64, addc_carry_le_one x23_4 0 c_21 b_x23_4 (by decide) b_c_21, + by rw [e_x23_5]; exact Nat.mod_add_div _ _⟩ + clear e_x23_5 + -- x19_3: adds x19,x20,x14 + extract_lets +onlyGivenNames s_20 x19_3 c_22 at hr + have e_x19_3 : x19_3 = (x20_6 + x14_4 + 0) % 2^64 := rfl + have e_c_22 : c_22 = (x20_6 + x14_4 + 0) / 2^64 := rfl + clear_value s_20 x19_3 c_22 + have l_x19_3 : x19_3 + 2^64 * c_22 = x20_6 + x14_4 + 0 := by + rw [e_x19_3, e_c_22]; exact Nat.mod_add_div _ _ + have b_x19_3 : x19_3 < 2^64 := by rw [e_x19_3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_22 : c_22 ≤ 1 := by + rw [e_c_22]; exact addc_carry_le_one x20_6 x14_4 0 b_x20_6 b_x14_4 (by decide) + clear e_x19_3 e_c_22 + -- x14_5: mul x14,x10,x9 + extract_lets +onlyGivenNames x14_5 at hr + have e_x14_5 : x14_5 = x10 * x9_2 % 2^64 := rfl + clear_value x14_5 + have b_x14_5 : x14_5 < 2^64 := by rw [e_x14_5]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x20_7: adcs x20,x21,x15 + extract_lets +onlyGivenNames s_21 x20_7 c_23 at hr + have e_x20_7 : x20_7 = (x21_6 + x15_6 + c_22) % 2^64 := rfl + have e_c_23 : c_23 = (x21_6 + x15_6 + c_22) / 2^64 := rfl + clear_value s_21 x20_7 c_23 + have l_x20_7 : x20_7 + 2^64 * c_23 = x21_6 + x15_6 + c_22 := by + rw [e_x20_7, e_c_23]; exact Nat.mod_add_div _ _ + have b_x20_7 : x20_7 < 2^64 := by rw [e_x20_7]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_23 : c_23 ≤ 1 := by + rw [e_c_23]; exact addc_carry_le_one x21_6 x15_6 c_22 b_x21_6 b_x15_6 b_c_22 + clear e_x20_7 e_c_23 + -- x15_7: mul x15,x11,x9 + extract_lets +onlyGivenNames x15_7 at hr + have e_x15_7 : x15_7 = x11 * x9_2 % 2^64 := rfl + clear_value x15_7 + have b_x15_7 : x15_7 < 2^64 := by rw [e_x15_7]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x21_7: adcs x21,x22,xzr + extract_lets +onlyGivenNames s_22 x21_7 c_24 at hr + have e_x21_7 : x21_7 = (x22_6 + 0 + c_23) % 2^64 := rfl + have e_c_24 : c_24 = (x22_6 + 0 + c_23) / 2^64 := rfl + clear_value s_22 x21_7 c_24 + have l_x21_7 : x21_7 + 2^64 * c_24 = x22_6 + 0 + c_23 := by + rw [e_x21_7, e_c_24]; exact Nat.mod_add_div _ _ + have b_x21_7 : x21_7 < 2^64 := by rw [e_x21_7]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_24 : c_24 ≤ 1 := by + rw [e_c_24]; exact addc_carry_le_one x22_6 0 c_23 b_x22_6 (by decide) b_c_23 + clear e_x21_7 e_c_24 + -- x16_3: mul x16,x12,x9 + extract_lets +onlyGivenNames x16_3 at hr + have e_x16_3 : x16_3 = x12 * x9_2 % 2^64 := rfl + clear_value x16_3 + have b_x16_3 : x16_3 < 2^64 := by rw [e_x16_3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x22_7: adcs x22,x23,x17 + extract_lets +onlyGivenNames s_23 x22_7 c_25 at hr + have e_x22_7 : x22_7 = (x23_5 + x17_6 + c_24) % 2^64 := rfl + have e_c_25 : c_25 = (x23_5 + x17_6 + c_24) / 2^64 := rfl + clear_value s_23 x22_7 c_25 + have l_x22_7 : x22_7 + 2^64 * c_25 = x23_5 + x17_6 + c_24 := by + rw [e_x22_7, e_c_25]; exact Nat.mod_add_div _ _ + have b_x22_7 : x22_7 < 2^64 := by rw [e_x22_7]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_25 : c_25 ≤ 1 := by + rw [e_c_25]; exact addc_carry_le_one x23_5 x17_6 c_24 b_x23_5 (lt_of_lt_of_le b_x17_6 (by norm_num)) b_c_24 + clear e_x22_7 e_c_25 + -- x17_7: mul x17,x13,x9 + extract_lets +onlyGivenNames x17_7 at hr + have e_x17_7 : x17_7 = x13 * x9_2 % 2^64 := rfl + clear_value x17_7 + have b_x17_7 : x17_7 < 2^64 := by rw [e_x17_7]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x23_6: adc x23,xzr,xzr + extract_lets +onlyGivenNames x23_6 at hr + have e_x23_6 : x23_6 = (0 + 0 + c_25) % 2^64 := rfl + clear_value x23_6 + have b_x23_6 : x23_6 < 2^64 := by rw [e_x23_6]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x23_6, b_k_x23_6, l_x23_6⟩ : + ∃ k, k ≤ 1 ∧ x23_6 + 2^64 * k = 0 + 0 + c_25 := + ⟨(0 + 0 + c_25) / 2^64, addc_carry_le_one 0 0 c_25 (by decide) (by decide) b_c_25, + by rw [e_x23_6]; exact Nat.mod_add_div _ _⟩ + clear e_x23_6 + -- BEGIN round 1 reduction + -- Cancellation: the low limb of `x19_2 + p0 * x3_1` is zero, so `x19_2 + lo_x14_4` is + -- `0` or `2^64`, and `subs xzr, x19_2, #1` set the carry exactly when it is `2^64`. + have hc_1 : x19_2 + lo_x14_4 = 2^64 * c_18 := by + have h := cancel_low x19_2 inv modulus.l0 hinv + rw [← e_x5, ← e_x4, ← e_x3_1, ← d_x14_4, Nat.add_mul_mod_self_left, + Nat.mod_eq_of_lt b_lo_x14_4] at h + clear * - h b_x19_2 b_lo_x14_4 l_c_18 + omega + have bc_1 : c_18 ≤ 1 := by clear * - l_c_18; omega + have hPq_1 : x3_1 * modulus.toNat = x5 * x3_1 + 2^64 * (x6 * x3_1) + 2^254 * x3_1 := by + rw [hP]; ring + -- `x17_5` is the low two bits of `x3_1` at the top of a limb. + have hsh_1 : x17_5 ≤ 3 * 2^62 := by + clear * - sh_x17_6 b_x17_5 b_x17_6; omega + -- The reduction's carry chain, summed with the limb weights. + have hsum'_1 : x19_2 + 2^64 * x20_6 + 2^128 * x21_6 + 2^192 * x22_6 + 2^256 * x23_5 + + 2^320 * k_x23_5 + = x19_2 + 2^64 * x20_5 + 2^128 * x21_5 + 2^192 * x22_5 + 2^256 * x23_4 + + 2^64 * x15_5 + 2^64 * c_18 + 2^192 * x17_5 := by + clear * - l_x20_6 l_x21_6 l_x22_6 l_x23_5 + omega + -- Neither `adc` of the reduction wraps: the five-limb accumulator is below + -- `2^320 - 3 * 2^254 - 2^128` by `hs_1`, and the reduction adds less than that before + -- the shift. + have hkr_1 : k_x23_5 = 0 := by + clear * - hsum'_1 F_1 B_0 hs_1 b_x15_5 bc_1 hsh_1 + omega + have hks_1 : k_x23_6 = 0 := by clear * - l_x23_6 b_c_25; omega + have I_1 : 2^64 * (x19_3 + 2^64 * x20_7 + 2^128 * x21_7 + 2^192 * x22_7 + 2^256 * x23_6) + = x19_2 + 2^64 * x20_5 + 2^128 * x21_5 + 2^192 * x22_5 + 2^256 * x23_4 + + x3_1 * modulus.toNat := by + clear * - hc_1 d_x14_4 d_x15_6 sh_x17_6 l_x20_6 l_x21_6 l_x22_6 l_x23_5 l_x19_3 l_x20_7 l_x21_7 + l_x22_7 l_x23_6 hkr_1 hks_1 hPq_1 + omega + -- The shifted accumulator stays below `lhs + p`. + have hLx_1 : lhs.toNat * x9_1 + lhs.toNat ≤ lhs.toNat * 2^64 := by + rw [← Nat.mul_succ]; exact Nat.mul_le_mul_left _ b_x9_1 + have hqP_1 : x3_1 * modulus.toNat + modulus.toNat ≤ 2^64 * modulus.toNat := by + rw [← Nat.succ_mul]; exact Nat.mul_le_mul_right _ b_x3_1 + have B_1 : x19_3 + 2^64 * x20_7 + 2^128 * x21_7 + 2^192 * x22_7 + 2^256 * x23_6 + < lhs.toNat + modulus.toNat := by + clear * - I_1 F_1 hLx_1 hqP_1 B_0 + omega + have t_1 : x23_6 ≤ 1 := by clear * - l_x23_6 hks_1 b_c_25; omega + -- END round 1 reduction + -- x19_4: adds x19,x19,x14 + extract_lets +onlyGivenNames s_24 x19_4 c_26 at hr + have e_x19_4 : x19_4 = (x19_3 + x14_5 + 0) % 2^64 := rfl + have e_c_26 : c_26 = (x19_3 + x14_5 + 0) / 2^64 := rfl + clear_value s_24 x19_4 c_26 + have l_x19_4 : x19_4 + 2^64 * c_26 = x19_3 + x14_5 + 0 := by + rw [e_x19_4, e_c_26]; exact Nat.mod_add_div _ _ + have b_x19_4 : x19_4 < 2^64 := by rw [e_x19_4]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_26 : c_26 ≤ 1 := by + rw [e_c_26]; exact addc_carry_le_one x19_3 x14_5 0 b_x19_3 b_x14_5 (by decide) + clear e_x19_4 e_c_26 + -- x14_6: umulh x14,x10,x9 + extract_lets +onlyGivenNames x14_6 at hr + have e_x14_6 : x14_6 = x10 * x9_2 / 2^64 := rfl + clear_value x14_6 + have p_x14_6 : x10 * x9_2 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x10 b_x9_2 + have b_x14_6 : x14_6 < 2^64 := by rw [e_x14_6]; exact Nat.div_lt_of_lt_mul p_x14_6 + have d_x14_6 : x14_5 + 2^64 * x14_6 = x10 * x9_2 := by + rw [e_x14_5, e_x14_6]; exact Nat.mod_add_div _ _ + clear e_x14_5 e_x14_6 + -- x20_8: adcs x20,x20,x15 + extract_lets +onlyGivenNames s_25 x20_8 c_27 at hr + have e_x20_8 : x20_8 = (x20_7 + x15_7 + c_26) % 2^64 := rfl + have e_c_27 : c_27 = (x20_7 + x15_7 + c_26) / 2^64 := rfl + clear_value s_25 x20_8 c_27 + have l_x20_8 : x20_8 + 2^64 * c_27 = x20_7 + x15_7 + c_26 := by + rw [e_x20_8, e_c_27]; exact Nat.mod_add_div _ _ + have b_x20_8 : x20_8 < 2^64 := by rw [e_x20_8]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_27 : c_27 ≤ 1 := by + rw [e_c_27]; exact addc_carry_le_one x20_7 x15_7 c_26 b_x20_7 b_x15_7 b_c_26 + clear e_x20_8 e_c_27 + -- x15_8: umulh x15,x11,x9 + extract_lets +onlyGivenNames x15_8 at hr + have e_x15_8 : x15_8 = x11 * x9_2 / 2^64 := rfl + clear_value x15_8 + have p_x15_8 : x11 * x9_2 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x11 b_x9_2 + have b_x15_8 : x15_8 < 2^64 := by rw [e_x15_8]; exact Nat.div_lt_of_lt_mul p_x15_8 + have d_x15_8 : x15_7 + 2^64 * x15_8 = x11 * x9_2 := by + rw [e_x15_7, e_x15_8]; exact Nat.mod_add_div _ _ + clear e_x15_7 e_x15_8 + -- x21_8: adcs x21,x21,x16 + extract_lets +onlyGivenNames s_26 x21_8 c_28 at hr + have e_x21_8 : x21_8 = (x21_7 + x16_3 + c_27) % 2^64 := rfl + have e_c_28 : c_28 = (x21_7 + x16_3 + c_27) / 2^64 := rfl + clear_value s_26 x21_8 c_28 + have l_x21_8 : x21_8 + 2^64 * c_28 = x21_7 + x16_3 + c_27 := by + rw [e_x21_8, e_c_28]; exact Nat.mod_add_div _ _ + have b_x21_8 : x21_8 < 2^64 := by rw [e_x21_8]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_28 : c_28 ≤ 1 := by + rw [e_c_28]; exact addc_carry_le_one x21_7 x16_3 c_27 b_x21_7 b_x16_3 b_c_27 + clear e_x21_8 e_c_28 + -- x3_2: mul x3,x4,x19 + extract_lets +onlyGivenNames x3_2 at hr + have e_x3_2 : x3_2 = x4 * x19_4 % 2^64 := rfl + clear_value x3_2 + have b_x3_2 : x3_2 < 2^64 := by rw [e_x3_2]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x16_4: umulh x16,x12,x9 + extract_lets +onlyGivenNames x16_4 at hr + have e_x16_4 : x16_4 = x12 * x9_2 / 2^64 := rfl + clear_value x16_4 + have p_x16_4 : x12 * x9_2 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x12 b_x9_2 + have b_x16_4 : x16_4 < 2^64 := by rw [e_x16_4]; exact Nat.div_lt_of_lt_mul p_x16_4 + have d_x16_4 : x16_3 + 2^64 * x16_4 = x12 * x9_2 := by + rw [e_x16_3, e_x16_4]; exact Nat.mod_add_div _ _ + clear e_x16_3 e_x16_4 + -- x22_8: adcs x22,x22,x17 + extract_lets +onlyGivenNames s_27 x22_8 c_29 at hr + have e_x22_8 : x22_8 = (x22_7 + x17_7 + c_28) % 2^64 := rfl + have e_c_29 : c_29 = (x22_7 + x17_7 + c_28) / 2^64 := rfl + clear_value s_27 x22_8 c_29 + have l_x22_8 : x22_8 + 2^64 * c_29 = x22_7 + x17_7 + c_28 := by + rw [e_x22_8, e_c_29]; exact Nat.mod_add_div _ _ + have b_x22_8 : x22_8 < 2^64 := by rw [e_x22_8]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_29 : c_29 ≤ 1 := by + rw [e_c_29]; exact addc_carry_le_one x22_7 x17_7 c_28 b_x22_7 b_x17_7 b_c_28 + clear e_x22_8 e_c_29 + -- x17_8: umulh x17,x13,x9 + extract_lets +onlyGivenNames x17_8 at hr + have e_x17_8 : x17_8 = x13 * x9_2 / 2^64 := rfl + clear_value x17_8 + have p_x17_8 : x13 * x9_2 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x13 b_x9_2 + have b_x17_8 : x17_8 < 2^64 := by rw [e_x17_8]; exact Nat.div_lt_of_lt_mul p_x17_8 + have d_x17_8 : x17_7 + 2^64 * x17_8 = x13 * x9_2 := by + rw [e_x17_7, e_x17_8]; exact Nat.mod_add_div _ _ + clear e_x17_7 e_x17_8 + -- x23_7: adc x23,x23,xzr + extract_lets +onlyGivenNames x23_7 at hr + have e_x23_7 : x23_7 = (x23_6 + 0 + c_29) % 2^64 := rfl + clear_value x23_7 + have b_x23_7 : x23_7 < 2^64 := by rw [e_x23_7]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x23_7, b_k_x23_7, l_x23_7⟩ : + ∃ k, k ≤ 1 ∧ x23_7 + 2^64 * k = x23_6 + 0 + c_29 := + ⟨(x23_6 + 0 + c_29) / 2^64, addc_carry_le_one x23_6 0 c_29 b_x23_6 (by decide) b_c_29, + by rw [e_x23_7]; exact Nat.mod_add_div _ _⟩ + clear e_x23_7 + -- x20_9: adds x20,x20,x14 + extract_lets +onlyGivenNames s_28 x20_9 c_30 at hr + have e_x20_9 : x20_9 = (x20_8 + x14_6 + 0) % 2^64 := rfl + have e_c_30 : c_30 = (x20_8 + x14_6 + 0) / 2^64 := rfl + clear_value s_28 x20_9 c_30 + have l_x20_9 : x20_9 + 2^64 * c_30 = x20_8 + x14_6 + 0 := by + rw [e_x20_9, e_c_30]; exact Nat.mod_add_div _ _ + have b_x20_9 : x20_9 < 2^64 := by rw [e_x20_9]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_30 : c_30 ≤ 1 := by + rw [e_c_30]; exact addc_carry_le_one x20_8 x14_6 0 b_x20_8 b_x14_6 (by decide) + clear e_x20_9 e_c_30 + -- x21_9: adcs x21,x21,x15 + extract_lets +onlyGivenNames s_29 x21_9 c_31 at hr + have e_x21_9 : x21_9 = (x21_8 + x15_8 + c_30) % 2^64 := rfl + have e_c_31 : c_31 = (x21_8 + x15_8 + c_30) / 2^64 := rfl + clear_value s_29 x21_9 c_31 + have l_x21_9 : x21_9 + 2^64 * c_31 = x21_8 + x15_8 + c_30 := by + rw [e_x21_9, e_c_31]; exact Nat.mod_add_div _ _ + have b_x21_9 : x21_9 < 2^64 := by rw [e_x21_9]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_31 : c_31 ≤ 1 := by + rw [e_c_31]; exact addc_carry_le_one x21_8 x15_8 c_30 b_x21_8 b_x15_8 b_c_30 + clear e_x21_9 e_c_31 + -- x15_9: mul x15,x6,x3 + extract_lets +onlyGivenNames x15_9 at hr + have e_x15_9 : x15_9 = x6 * x3_2 % 2^64 := rfl + clear_value x15_9 + have b_x15_9 : x15_9 < 2^64 := by rw [e_x15_9]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x22_9: adcs x22,x22,x16 + extract_lets +onlyGivenNames s_30 x22_9 c_32 at hr + have e_x22_9 : x22_9 = (x22_8 + x16_4 + c_31) % 2^64 := rfl + have e_c_32 : c_32 = (x22_8 + x16_4 + c_31) / 2^64 := rfl + clear_value s_30 x22_9 c_32 + have l_x22_9 : x22_9 + 2^64 * c_32 = x22_8 + x16_4 + c_31 := by + rw [e_x22_9, e_c_32]; exact Nat.mod_add_div _ _ + have b_x22_9 : x22_9 < 2^64 := by rw [e_x22_9]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_32 : c_32 ≤ 1 := by + rw [e_c_32]; exact addc_carry_le_one x22_8 x16_4 c_31 b_x22_8 b_x16_4 b_c_31 + clear e_x22_9 e_c_32 + -- x23_8: adc x23,x23,x17 + extract_lets +onlyGivenNames x23_8 at hr + have e_x23_8 : x23_8 = (x23_7 + x17_8 + c_32) % 2^64 := rfl + clear_value x23_8 + have b_x23_8 : x23_8 < 2^64 := by rw [e_x23_8]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x23_8, b_k_x23_8, l_x23_8⟩ : + ∃ k, k ≤ 1 ∧ x23_8 + 2^64 * k = x23_7 + x17_8 + c_32 := + ⟨(x23_7 + x17_8 + c_32) / 2^64, addc_carry_le_one x23_7 x17_8 c_32 b_x23_7 b_x17_8 b_c_32, + by rw [e_x23_8]; exact Nat.mod_add_div _ _⟩ + clear e_x23_8 + -- BEGIN round 2 fold + -- `lhs * rhs_2` as the sum of the limb products. + have hL_2 : lhs.toNat * x9_2 + = x10 * x9_2 + 2^64 * (x11 * x9_2) + 2^128 * (x12 * x9_2) + 2^192 * (x13 * x9_2) := by + rw [e_x10, e_x11, e_x12, e_x13]; simp only [Limbs.toNat]; ring + have hs_2 : lhs.toNat * x9_2 + lhs.toNat + modulus.toNat + 3 * 2^254 + 2^128 ≤ 2^320 := by + rw [e_x9_2, ← Nat.mul_add_one]; exact hsafe.2.1 + -- The fold's two carry chains, summed with the limb weights. + have hsum_2 : x19_4 + 2^64 * x20_9 + 2^128 * x21_9 + 2^192 * x22_9 + 2^256 * x23_8 + + 2^320 * (k_x23_7 + k_x23_8) + = x19_3 + 2^64 * x20_7 + 2^128 * x21_7 + 2^192 * x22_7 + 2^256 * x23_6 + + lhs.toNat * x9_2 := by + clear * - l_x19_4 l_x20_8 l_x21_8 l_x22_8 l_x23_7 l_x20_9 l_x21_9 l_x22_9 l_x23_8 d_x14_6 + d_x15_8 d_x16_4 d_x17_8 hL_2 + omega + -- Neither `adc` of the fold wraps: the accumulator entering the round is below + -- `lhs + p`, and `hs_2` bounds it plus `lhs * rhs_2` below `2^320`. + have hk_2 : k_x23_7 = 0 ∧ k_x23_8 = 0 := by + clear * - hsum_2 B_1 hs_2 + omega + have F_2 : x19_4 + 2^64 * x20_9 + 2^128 * x21_9 + 2^192 * x22_9 + 2^256 * x23_8 + = x19_3 + 2^64 * x20_7 + 2^128 * x21_7 + 2^192 * x22_7 + 2^256 * x23_6 + + lhs.toNat * x9_2 := by + clear * - hsum_2 hk_2 + omega + -- END round 2 fold + -- x17_9: lsl x17,x3,#62 + extract_lets +onlyGivenNames x17_9 at hr + have e_x17_9 : x17_9 = x3_2 * 2^62 % 2^64 := rfl + clear_value x17_9 + have b_x17_9 : x17_9 < 2^64 := by rw [e_x17_9]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x9_3: ldr x9,[x2,8*3] + extract_lets +onlyGivenNames x9_3 at hr + have e_x9_3 : x9_3 = rhs.l3 := rfl + clear_value x9_3 + have b_x9_3 : x9_3 < 2^64 := by rw [e_x9_3]; exact hrhs.2.2.2 + -- c_33: subs xzr,x19,#1 + extract_lets +onlyGivenNames c_33 at hr + have e_c_33 : c_33 = (x19_4 + 2^64 - 1 - (1 - 1)) / 2^64 := rfl + clear_value c_33 + have b_c_33 : c_33 ≤ 1 := by rw [e_c_33]; exact subc_carry_le_one x19_4 1 1 b_x19_4 + have l_c_33 : (c_33 = 1 ∧ 1 + 1 ≤ x19_4 + 1) ∨ (c_33 = 0 ∧ x19_4 + 1 < 1 + 1) := + subc_carry_cases x19_4 1 1 _ e_c_33 b_x19_4 (by decide) (by decide) + clear e_c_33 + -- x14_7: umulh x14,x5,x3 + extract_lets +onlyGivenNames x14_7 at hr + have e_x14_7 : x14_7 = x5 * x3_2 / 2^64 := rfl + clear_value x14_7 + have p_x14_7 : x5 * x3_2 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x5 b_x3_2 + have b_x14_7 : x14_7 < 2^64 := by rw [e_x14_7]; exact Nat.div_lt_of_lt_mul p_x14_7 + obtain ⟨lo_x14_7, b_lo_x14_7, d_x14_7⟩ : + ∃ lo, lo < 2^64 ∧ lo + 2^64 * x14_7 = x5 * x3_2 := + ⟨x5 * x3_2 % 2^64, Nat.mod_lt _ (Nat.two_pow_pos _), + by rw [e_x14_7]; exact Nat.mod_add_div _ _⟩ + clear e_x14_7 + -- x20_10: adcs x20,x20,x15 + extract_lets +onlyGivenNames s_31 x20_10 c_34 at hr + have e_x20_10 : x20_10 = (x20_9 + x15_9 + c_33) % 2^64 := rfl + have e_c_34 : c_34 = (x20_9 + x15_9 + c_33) / 2^64 := rfl + clear_value s_31 x20_10 c_34 + have l_x20_10 : x20_10 + 2^64 * c_34 = x20_9 + x15_9 + c_33 := by + rw [e_x20_10, e_c_34]; exact Nat.mod_add_div _ _ + have b_x20_10 : x20_10 < 2^64 := by rw [e_x20_10]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_34 : c_34 ≤ 1 := by + rw [e_c_34]; exact addc_carry_le_one x20_9 x15_9 c_33 b_x20_9 b_x15_9 b_c_33 + clear e_x20_10 e_c_34 + -- x15_10: umulh x15,x6,x3 + extract_lets +onlyGivenNames x15_10 at hr + have e_x15_10 : x15_10 = x6 * x3_2 / 2^64 := rfl + clear_value x15_10 + have p_x15_10 : x6 * x3_2 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x6 b_x3_2 + have b_x15_10 : x15_10 < 2^64 := by rw [e_x15_10]; exact Nat.div_lt_of_lt_mul p_x15_10 + have d_x15_10 : x15_9 + 2^64 * x15_10 = x6 * x3_2 := by + rw [e_x15_9, e_x15_10]; exact Nat.mod_add_div _ _ + clear e_x15_9 e_x15_10 + -- x21_10: adcs x21,x21,xzr + extract_lets +onlyGivenNames s_32 x21_10 c_35 at hr + have e_x21_10 : x21_10 = (x21_9 + 0 + c_34) % 2^64 := rfl + have e_c_35 : c_35 = (x21_9 + 0 + c_34) / 2^64 := rfl + clear_value s_32 x21_10 c_35 + have l_x21_10 : x21_10 + 2^64 * c_35 = x21_9 + 0 + c_34 := by + rw [e_x21_10, e_c_35]; exact Nat.mod_add_div _ _ + have b_x21_10 : x21_10 < 2^64 := by rw [e_x21_10]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_35 : c_35 ≤ 1 := by + rw [e_c_35]; exact addc_carry_le_one x21_9 0 c_34 b_x21_9 (by decide) b_c_34 + clear e_x21_10 e_c_35 + -- x22_10: adcs x22,x22,x17 + extract_lets +onlyGivenNames s_33 x22_10 c_36 at hr + have e_x22_10 : x22_10 = (x22_9 + x17_9 + c_35) % 2^64 := rfl + have e_c_36 : c_36 = (x22_9 + x17_9 + c_35) / 2^64 := rfl + clear_value s_33 x22_10 c_36 + have l_x22_10 : x22_10 + 2^64 * c_36 = x22_9 + x17_9 + c_35 := by + rw [e_x22_10, e_c_36]; exact Nat.mod_add_div _ _ + have b_x22_10 : x22_10 < 2^64 := by rw [e_x22_10]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_36 : c_36 ≤ 1 := by + rw [e_c_36]; exact addc_carry_le_one x22_9 x17_9 c_35 b_x22_9 b_x17_9 b_c_35 + clear e_x22_10 e_c_36 + -- x17_10: lsr x17,x3,#2 + extract_lets +onlyGivenNames x17_10 at hr + have e_x17_10 : x17_10 = x3_2 / 2^2 := rfl + clear_value x17_10 + have b_x17_10 : x17_10 < 2^62 := by + rw [e_x17_10]; exact Nat.div_lt_of_lt_mul (lt_of_lt_of_eq b_x3_2 (by norm_num)) + have sh_x17_10 : x17_9 + 2^64 * x17_10 = x3_2 * 2^62 := by + rw [e_x17_9, e_x17_10]; exact lsl62_lsr2_split _ + clear e_x17_9 e_x17_10 + -- x23_9: adc x23,x23,xzr + extract_lets +onlyGivenNames x23_9 at hr + have e_x23_9 : x23_9 = (x23_8 + 0 + c_36) % 2^64 := rfl + clear_value x23_9 + have b_x23_9 : x23_9 < 2^64 := by rw [e_x23_9]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x23_9, b_k_x23_9, l_x23_9⟩ : + ∃ k, k ≤ 1 ∧ x23_9 + 2^64 * k = x23_8 + 0 + c_36 := + ⟨(x23_8 + 0 + c_36) / 2^64, addc_carry_le_one x23_8 0 c_36 b_x23_8 (by decide) b_c_36, + by rw [e_x23_9]; exact Nat.mod_add_div _ _⟩ + clear e_x23_9 + -- x19_5: adds x19,x20,x14 + extract_lets +onlyGivenNames s_34 x19_5 c_37 at hr + have e_x19_5 : x19_5 = (x20_10 + x14_7 + 0) % 2^64 := rfl + have e_c_37 : c_37 = (x20_10 + x14_7 + 0) / 2^64 := rfl + clear_value s_34 x19_5 c_37 + have l_x19_5 : x19_5 + 2^64 * c_37 = x20_10 + x14_7 + 0 := by + rw [e_x19_5, e_c_37]; exact Nat.mod_add_div _ _ + have b_x19_5 : x19_5 < 2^64 := by rw [e_x19_5]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_37 : c_37 ≤ 1 := by + rw [e_c_37]; exact addc_carry_le_one x20_10 x14_7 0 b_x20_10 b_x14_7 (by decide) + clear e_x19_5 e_c_37 + -- x14_8: mul x14,x10,x9 + extract_lets +onlyGivenNames x14_8 at hr + have e_x14_8 : x14_8 = x10 * x9_3 % 2^64 := rfl + clear_value x14_8 + have b_x14_8 : x14_8 < 2^64 := by rw [e_x14_8]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x20_11: adcs x20,x21,x15 + extract_lets +onlyGivenNames s_35 x20_11 c_38 at hr + have e_x20_11 : x20_11 = (x21_10 + x15_10 + c_37) % 2^64 := rfl + have e_c_38 : c_38 = (x21_10 + x15_10 + c_37) / 2^64 := rfl + clear_value s_35 x20_11 c_38 + have l_x20_11 : x20_11 + 2^64 * c_38 = x21_10 + x15_10 + c_37 := by + rw [e_x20_11, e_c_38]; exact Nat.mod_add_div _ _ + have b_x20_11 : x20_11 < 2^64 := by rw [e_x20_11]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_38 : c_38 ≤ 1 := by + rw [e_c_38]; exact addc_carry_le_one x21_10 x15_10 c_37 b_x21_10 b_x15_10 b_c_37 + clear e_x20_11 e_c_38 + -- x15_11: mul x15,x11,x9 + extract_lets +onlyGivenNames x15_11 at hr + have e_x15_11 : x15_11 = x11 * x9_3 % 2^64 := rfl + clear_value x15_11 + have b_x15_11 : x15_11 < 2^64 := by rw [e_x15_11]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x21_11: adcs x21,x22,xzr + extract_lets +onlyGivenNames s_36 x21_11 c_39 at hr + have e_x21_11 : x21_11 = (x22_10 + 0 + c_38) % 2^64 := rfl + have e_c_39 : c_39 = (x22_10 + 0 + c_38) / 2^64 := rfl + clear_value s_36 x21_11 c_39 + have l_x21_11 : x21_11 + 2^64 * c_39 = x22_10 + 0 + c_38 := by + rw [e_x21_11, e_c_39]; exact Nat.mod_add_div _ _ + have b_x21_11 : x21_11 < 2^64 := by rw [e_x21_11]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_39 : c_39 ≤ 1 := by + rw [e_c_39]; exact addc_carry_le_one x22_10 0 c_38 b_x22_10 (by decide) b_c_38 + clear e_x21_11 e_c_39 + -- x16_5: mul x16,x12,x9 + extract_lets +onlyGivenNames x16_5 at hr + have e_x16_5 : x16_5 = x12 * x9_3 % 2^64 := rfl + clear_value x16_5 + have b_x16_5 : x16_5 < 2^64 := by rw [e_x16_5]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x22_11: adcs x22,x23,x17 + extract_lets +onlyGivenNames s_37 x22_11 c_40 at hr + have e_x22_11 : x22_11 = (x23_9 + x17_10 + c_39) % 2^64 := rfl + have e_c_40 : c_40 = (x23_9 + x17_10 + c_39) / 2^64 := rfl + clear_value s_37 x22_11 c_40 + have l_x22_11 : x22_11 + 2^64 * c_40 = x23_9 + x17_10 + c_39 := by + rw [e_x22_11, e_c_40]; exact Nat.mod_add_div _ _ + have b_x22_11 : x22_11 < 2^64 := by rw [e_x22_11]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_40 : c_40 ≤ 1 := by + rw [e_c_40]; exact addc_carry_le_one x23_9 x17_10 c_39 b_x23_9 (lt_of_lt_of_le b_x17_10 (by norm_num)) b_c_39 + clear e_x22_11 e_c_40 + -- x17_11: mul x17,x13,x9 + extract_lets +onlyGivenNames x17_11 at hr + have e_x17_11 : x17_11 = x13 * x9_3 % 2^64 := rfl + clear_value x17_11 + have b_x17_11 : x17_11 < 2^64 := by rw [e_x17_11]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x23_10: adc x23,xzr,xzr + extract_lets +onlyGivenNames x23_10 at hr + have e_x23_10 : x23_10 = (0 + 0 + c_40) % 2^64 := rfl + clear_value x23_10 + have b_x23_10 : x23_10 < 2^64 := by rw [e_x23_10]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x23_10, b_k_x23_10, l_x23_10⟩ : + ∃ k, k ≤ 1 ∧ x23_10 + 2^64 * k = 0 + 0 + c_40 := + ⟨(0 + 0 + c_40) / 2^64, addc_carry_le_one 0 0 c_40 (by decide) (by decide) b_c_40, + by rw [e_x23_10]; exact Nat.mod_add_div _ _⟩ + clear e_x23_10 + -- BEGIN round 2 reduction + -- Cancellation: the low limb of `x19_4 + p0 * x3_2` is zero, so `x19_4 + lo_x14_7` is + -- `0` or `2^64`, and `subs xzr, x19_4, #1` set the carry exactly when it is `2^64`. + have hc_2 : x19_4 + lo_x14_7 = 2^64 * c_33 := by + have h := cancel_low x19_4 inv modulus.l0 hinv + rw [← e_x5, ← e_x4, ← e_x3_2, ← d_x14_7, Nat.add_mul_mod_self_left, + Nat.mod_eq_of_lt b_lo_x14_7] at h + clear * - h b_x19_4 b_lo_x14_7 l_c_33 + omega + have bc_2 : c_33 ≤ 1 := by clear * - l_c_33; omega + have hPq_2 : x3_2 * modulus.toNat = x5 * x3_2 + 2^64 * (x6 * x3_2) + 2^254 * x3_2 := by + rw [hP]; ring + -- `x17_9` is the low two bits of `x3_2` at the top of a limb. + have hsh_2 : x17_9 ≤ 3 * 2^62 := by + clear * - sh_x17_10 b_x17_9 b_x17_10; omega + -- The reduction's carry chain, summed with the limb weights. + have hsum'_2 : x19_4 + 2^64 * x20_10 + 2^128 * x21_10 + 2^192 * x22_10 + 2^256 * x23_9 + + 2^320 * k_x23_9 + = x19_4 + 2^64 * x20_9 + 2^128 * x21_9 + 2^192 * x22_9 + 2^256 * x23_8 + + 2^64 * x15_9 + 2^64 * c_33 + 2^192 * x17_9 := by + clear * - l_x20_10 l_x21_10 l_x22_10 l_x23_9 + omega + -- Neither `adc` of the reduction wraps: the five-limb accumulator is below + -- `2^320 - 3 * 2^254 - 2^128` by `hs_2`, and the reduction adds less than that before + -- the shift. + have hkr_2 : k_x23_9 = 0 := by + clear * - hsum'_2 F_2 B_1 hs_2 b_x15_9 bc_2 hsh_2 + omega + have hks_2 : k_x23_10 = 0 := by clear * - l_x23_10 b_c_40; omega + have I_2 : 2^64 * (x19_5 + 2^64 * x20_11 + 2^128 * x21_11 + 2^192 * x22_11 + 2^256 * x23_10) + = x19_4 + 2^64 * x20_9 + 2^128 * x21_9 + 2^192 * x22_9 + 2^256 * x23_8 + + x3_2 * modulus.toNat := by + clear * - hc_2 d_x14_7 d_x15_10 sh_x17_10 l_x20_10 l_x21_10 l_x22_10 l_x23_9 l_x19_5 l_x20_11 + l_x21_11 l_x22_11 l_x23_10 hkr_2 hks_2 hPq_2 + omega + -- The shifted accumulator stays below `lhs + p`. + have hLx_2 : lhs.toNat * x9_2 + lhs.toNat ≤ lhs.toNat * 2^64 := by + rw [← Nat.mul_succ]; exact Nat.mul_le_mul_left _ b_x9_2 + have hqP_2 : x3_2 * modulus.toNat + modulus.toNat ≤ 2^64 * modulus.toNat := by + rw [← Nat.succ_mul]; exact Nat.mul_le_mul_right _ b_x3_2 + have B_2 : x19_5 + 2^64 * x20_11 + 2^128 * x21_11 + 2^192 * x22_11 + 2^256 * x23_10 + < lhs.toNat + modulus.toNat := by + clear * - I_2 F_2 hLx_2 hqP_2 B_1 + omega + have t_2 : x23_10 ≤ 1 := by clear * - l_x23_10 hks_2 b_c_40; omega + -- END round 2 reduction + -- x19_6: adds x19,x19,x14 + extract_lets +onlyGivenNames s_38 x19_6 c_41 at hr + have e_x19_6 : x19_6 = (x19_5 + x14_8 + 0) % 2^64 := rfl + have e_c_41 : c_41 = (x19_5 + x14_8 + 0) / 2^64 := rfl + clear_value s_38 x19_6 c_41 + have l_x19_6 : x19_6 + 2^64 * c_41 = x19_5 + x14_8 + 0 := by + rw [e_x19_6, e_c_41]; exact Nat.mod_add_div _ _ + have b_x19_6 : x19_6 < 2^64 := by rw [e_x19_6]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_41 : c_41 ≤ 1 := by + rw [e_c_41]; exact addc_carry_le_one x19_5 x14_8 0 b_x19_5 b_x14_8 (by decide) + clear e_x19_6 e_c_41 + -- x14_9: umulh x14,x10,x9 + extract_lets +onlyGivenNames x14_9 at hr + have e_x14_9 : x14_9 = x10 * x9_3 / 2^64 := rfl + clear_value x14_9 + have p_x14_9 : x10 * x9_3 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x10 b_x9_3 + have b_x14_9 : x14_9 < 2^64 := by rw [e_x14_9]; exact Nat.div_lt_of_lt_mul p_x14_9 + have d_x14_9 : x14_8 + 2^64 * x14_9 = x10 * x9_3 := by + rw [e_x14_8, e_x14_9]; exact Nat.mod_add_div _ _ + clear e_x14_8 e_x14_9 + -- x20_12: adcs x20,x20,x15 + extract_lets +onlyGivenNames s_39 x20_12 c_42 at hr + have e_x20_12 : x20_12 = (x20_11 + x15_11 + c_41) % 2^64 := rfl + have e_c_42 : c_42 = (x20_11 + x15_11 + c_41) / 2^64 := rfl + clear_value s_39 x20_12 c_42 + have l_x20_12 : x20_12 + 2^64 * c_42 = x20_11 + x15_11 + c_41 := by + rw [e_x20_12, e_c_42]; exact Nat.mod_add_div _ _ + have b_x20_12 : x20_12 < 2^64 := by rw [e_x20_12]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_42 : c_42 ≤ 1 := by + rw [e_c_42]; exact addc_carry_le_one x20_11 x15_11 c_41 b_x20_11 b_x15_11 b_c_41 + clear e_x20_12 e_c_42 + -- x15_12: umulh x15,x11,x9 + extract_lets +onlyGivenNames x15_12 at hr + have e_x15_12 : x15_12 = x11 * x9_3 / 2^64 := rfl + clear_value x15_12 + have p_x15_12 : x11 * x9_3 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x11 b_x9_3 + have b_x15_12 : x15_12 < 2^64 := by rw [e_x15_12]; exact Nat.div_lt_of_lt_mul p_x15_12 + have d_x15_12 : x15_11 + 2^64 * x15_12 = x11 * x9_3 := by + rw [e_x15_11, e_x15_12]; exact Nat.mod_add_div _ _ + clear e_x15_11 e_x15_12 + -- x21_12: adcs x21,x21,x16 + extract_lets +onlyGivenNames s_40 x21_12 c_43 at hr + have e_x21_12 : x21_12 = (x21_11 + x16_5 + c_42) % 2^64 := rfl + have e_c_43 : c_43 = (x21_11 + x16_5 + c_42) / 2^64 := rfl + clear_value s_40 x21_12 c_43 + have l_x21_12 : x21_12 + 2^64 * c_43 = x21_11 + x16_5 + c_42 := by + rw [e_x21_12, e_c_43]; exact Nat.mod_add_div _ _ + have b_x21_12 : x21_12 < 2^64 := by rw [e_x21_12]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_43 : c_43 ≤ 1 := by + rw [e_c_43]; exact addc_carry_le_one x21_11 x16_5 c_42 b_x21_11 b_x16_5 b_c_42 + clear e_x21_12 e_c_43 + -- x3_3: mul x3,x4,x19 + extract_lets +onlyGivenNames x3_3 at hr + have e_x3_3 : x3_3 = x4 * x19_6 % 2^64 := rfl + clear_value x3_3 + have b_x3_3 : x3_3 < 2^64 := by rw [e_x3_3]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x16_6: umulh x16,x12,x9 + extract_lets +onlyGivenNames x16_6 at hr + have e_x16_6 : x16_6 = x12 * x9_3 / 2^64 := rfl + clear_value x16_6 + have p_x16_6 : x12 * x9_3 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x12 b_x9_3 + have b_x16_6 : x16_6 < 2^64 := by rw [e_x16_6]; exact Nat.div_lt_of_lt_mul p_x16_6 + have d_x16_6 : x16_5 + 2^64 * x16_6 = x12 * x9_3 := by + rw [e_x16_5, e_x16_6]; exact Nat.mod_add_div _ _ + clear e_x16_5 e_x16_6 + -- x22_12: adcs x22,x22,x17 + extract_lets +onlyGivenNames s_41 x22_12 c_44 at hr + have e_x22_12 : x22_12 = (x22_11 + x17_11 + c_43) % 2^64 := rfl + have e_c_44 : c_44 = (x22_11 + x17_11 + c_43) / 2^64 := rfl + clear_value s_41 x22_12 c_44 + have l_x22_12 : x22_12 + 2^64 * c_44 = x22_11 + x17_11 + c_43 := by + rw [e_x22_12, e_c_44]; exact Nat.mod_add_div _ _ + have b_x22_12 : x22_12 < 2^64 := by rw [e_x22_12]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_44 : c_44 ≤ 1 := by + rw [e_c_44]; exact addc_carry_le_one x22_11 x17_11 c_43 b_x22_11 b_x17_11 b_c_43 + clear e_x22_12 e_c_44 + -- x17_12: umulh x17,x13,x9 + extract_lets +onlyGivenNames x17_12 at hr + have e_x17_12 : x17_12 = x13 * x9_3 / 2^64 := rfl + clear_value x17_12 + have p_x17_12 : x13 * x9_3 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x13 b_x9_3 + have b_x17_12 : x17_12 < 2^64 := by rw [e_x17_12]; exact Nat.div_lt_of_lt_mul p_x17_12 + have d_x17_12 : x17_11 + 2^64 * x17_12 = x13 * x9_3 := by + rw [e_x17_11, e_x17_12]; exact Nat.mod_add_div _ _ + clear e_x17_11 e_x17_12 + -- x23_11: adc x23,x23,xzr + extract_lets +onlyGivenNames x23_11 at hr + have e_x23_11 : x23_11 = (x23_10 + 0 + c_44) % 2^64 := rfl + clear_value x23_11 + have b_x23_11 : x23_11 < 2^64 := by rw [e_x23_11]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x23_11, b_k_x23_11, l_x23_11⟩ : + ∃ k, k ≤ 1 ∧ x23_11 + 2^64 * k = x23_10 + 0 + c_44 := + ⟨(x23_10 + 0 + c_44) / 2^64, addc_carry_le_one x23_10 0 c_44 b_x23_10 (by decide) b_c_44, + by rw [e_x23_11]; exact Nat.mod_add_div _ _⟩ + clear e_x23_11 + -- x20_13: adds x20,x20,x14 + extract_lets +onlyGivenNames s_42 x20_13 c_45 at hr + have e_x20_13 : x20_13 = (x20_12 + x14_9 + 0) % 2^64 := rfl + have e_c_45 : c_45 = (x20_12 + x14_9 + 0) / 2^64 := rfl + clear_value s_42 x20_13 c_45 + have l_x20_13 : x20_13 + 2^64 * c_45 = x20_12 + x14_9 + 0 := by + rw [e_x20_13, e_c_45]; exact Nat.mod_add_div _ _ + have b_x20_13 : x20_13 < 2^64 := by rw [e_x20_13]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_45 : c_45 ≤ 1 := by + rw [e_c_45]; exact addc_carry_le_one x20_12 x14_9 0 b_x20_12 b_x14_9 (by decide) + clear e_x20_13 e_c_45 + -- x21_13: adcs x21,x21,x15 + extract_lets +onlyGivenNames s_43 x21_13 c_46 at hr + have e_x21_13 : x21_13 = (x21_12 + x15_12 + c_45) % 2^64 := rfl + have e_c_46 : c_46 = (x21_12 + x15_12 + c_45) / 2^64 := rfl + clear_value s_43 x21_13 c_46 + have l_x21_13 : x21_13 + 2^64 * c_46 = x21_12 + x15_12 + c_45 := by + rw [e_x21_13, e_c_46]; exact Nat.mod_add_div _ _ + have b_x21_13 : x21_13 < 2^64 := by rw [e_x21_13]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_46 : c_46 ≤ 1 := by + rw [e_c_46]; exact addc_carry_le_one x21_12 x15_12 c_45 b_x21_12 b_x15_12 b_c_45 + clear e_x21_13 e_c_46 + -- x15_13: mul x15,x6,x3 + extract_lets +onlyGivenNames x15_13 at hr + have e_x15_13 : x15_13 = x6 * x3_3 % 2^64 := rfl + clear_value x15_13 + have b_x15_13 : x15_13 < 2^64 := by rw [e_x15_13]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- x22_13: adcs x22,x22,x16 + extract_lets +onlyGivenNames s_44 x22_13 c_47 at hr + have e_x22_13 : x22_13 = (x22_12 + x16_6 + c_46) % 2^64 := rfl + have e_c_47 : c_47 = (x22_12 + x16_6 + c_46) / 2^64 := rfl + clear_value s_44 x22_13 c_47 + have l_x22_13 : x22_13 + 2^64 * c_47 = x22_12 + x16_6 + c_46 := by + rw [e_x22_13, e_c_47]; exact Nat.mod_add_div _ _ + have b_x22_13 : x22_13 < 2^64 := by rw [e_x22_13]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_47 : c_47 ≤ 1 := by + rw [e_c_47]; exact addc_carry_le_one x22_12 x16_6 c_46 b_x22_12 b_x16_6 b_c_46 + clear e_x22_13 e_c_47 + -- x23_12: adc x23,x23,x17 + extract_lets +onlyGivenNames x23_12 at hr + have e_x23_12 : x23_12 = (x23_11 + x17_12 + c_47) % 2^64 := rfl + clear_value x23_12 + have b_x23_12 : x23_12 < 2^64 := by rw [e_x23_12]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x23_12, b_k_x23_12, l_x23_12⟩ : + ∃ k, k ≤ 1 ∧ x23_12 + 2^64 * k = x23_11 + x17_12 + c_47 := + ⟨(x23_11 + x17_12 + c_47) / 2^64, addc_carry_le_one x23_11 x17_12 c_47 b_x23_11 b_x17_12 b_c_47, + by rw [e_x23_12]; exact Nat.mod_add_div _ _⟩ + clear e_x23_12 + -- BEGIN round 3 fold + -- `lhs * rhs_3` as the sum of the limb products. + have hL_3 : lhs.toNat * x9_3 + = x10 * x9_3 + 2^64 * (x11 * x9_3) + 2^128 * (x12 * x9_3) + 2^192 * (x13 * x9_3) := by + rw [e_x10, e_x11, e_x12, e_x13]; simp only [Limbs.toNat]; ring + have hs_3 : lhs.toNat * x9_3 + lhs.toNat + modulus.toNat + 3 * 2^254 + 2^128 ≤ 2^320 := by + rw [e_x9_3, ← Nat.mul_add_one]; exact hsafe.2.2 + -- The fold's two carry chains, summed with the limb weights. + have hsum_3 : x19_6 + 2^64 * x20_13 + 2^128 * x21_13 + 2^192 * x22_13 + 2^256 * x23_12 + + 2^320 * (k_x23_11 + k_x23_12) + = x19_5 + 2^64 * x20_11 + 2^128 * x21_11 + 2^192 * x22_11 + 2^256 * x23_10 + + lhs.toNat * x9_3 := by + clear * - l_x19_6 l_x20_12 l_x21_12 l_x22_12 l_x23_11 l_x20_13 l_x21_13 l_x22_13 l_x23_12 + d_x14_9 d_x15_12 d_x16_6 d_x17_12 hL_3 + omega + -- Neither `adc` of the fold wraps: the accumulator entering the round is below + -- `lhs + p`, and `hs_3` bounds it plus `lhs * rhs_3` below `2^320`. + have hk_3 : k_x23_11 = 0 ∧ k_x23_12 = 0 := by + clear * - hsum_3 B_2 hs_3 + omega + have F_3 : x19_6 + 2^64 * x20_13 + 2^128 * x21_13 + 2^192 * x22_13 + 2^256 * x23_12 + = x19_5 + 2^64 * x20_11 + 2^128 * x21_11 + 2^192 * x22_11 + 2^256 * x23_10 + + lhs.toNat * x9_3 := by + clear * - hsum_3 hk_3 + omega + -- END round 3 fold + -- x17_13: lsl x17,x3,#62 + extract_lets +onlyGivenNames x17_13 at hr + have e_x17_13 : x17_13 = x3_3 * 2^62 % 2^64 := rfl + clear_value x17_13 + have b_x17_13 : x17_13 < 2^64 := by rw [e_x17_13]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + -- c_48: subs xzr,x19,#1 + extract_lets +onlyGivenNames c_48 at hr + have e_c_48 : c_48 = (x19_6 + 2^64 - 1 - (1 - 1)) / 2^64 := rfl + clear_value c_48 + have b_c_48 : c_48 ≤ 1 := by rw [e_c_48]; exact subc_carry_le_one x19_6 1 1 b_x19_6 + have l_c_48 : (c_48 = 1 ∧ 1 + 1 ≤ x19_6 + 1) ∨ (c_48 = 0 ∧ x19_6 + 1 < 1 + 1) := + subc_carry_cases x19_6 1 1 _ e_c_48 b_x19_6 (by decide) (by decide) + clear e_c_48 + -- x14_10: umulh x14,x5,x3 + extract_lets +onlyGivenNames x14_10 at hr + have e_x14_10 : x14_10 = x5 * x3_3 / 2^64 := rfl + clear_value x14_10 + have p_x14_10 : x5 * x3_3 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x5 b_x3_3 + have b_x14_10 : x14_10 < 2^64 := by rw [e_x14_10]; exact Nat.div_lt_of_lt_mul p_x14_10 + obtain ⟨lo_x14_10, b_lo_x14_10, d_x14_10⟩ : + ∃ lo, lo < 2^64 ∧ lo + 2^64 * x14_10 = x5 * x3_3 := + ⟨x5 * x3_3 % 2^64, Nat.mod_lt _ (Nat.two_pow_pos _), + by rw [e_x14_10]; exact Nat.mod_add_div _ _⟩ + clear e_x14_10 + -- x20_14: adcs x20,x20,x15 + extract_lets +onlyGivenNames s_45 x20_14 c_49 at hr + have e_x20_14 : x20_14 = (x20_13 + x15_13 + c_48) % 2^64 := rfl + have e_c_49 : c_49 = (x20_13 + x15_13 + c_48) / 2^64 := rfl + clear_value s_45 x20_14 c_49 + have l_x20_14 : x20_14 + 2^64 * c_49 = x20_13 + x15_13 + c_48 := by + rw [e_x20_14, e_c_49]; exact Nat.mod_add_div _ _ + have b_x20_14 : x20_14 < 2^64 := by rw [e_x20_14]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_49 : c_49 ≤ 1 := by + rw [e_c_49]; exact addc_carry_le_one x20_13 x15_13 c_48 b_x20_13 b_x15_13 b_c_48 + clear e_x20_14 e_c_49 + -- x15_14: umulh x15,x6,x3 + extract_lets +onlyGivenNames x15_14 at hr + have e_x15_14 : x15_14 = x6 * x3_3 / 2^64 := rfl + clear_value x15_14 + have p_x15_14 : x6 * x3_3 < 2^64 * 2^64 := Nat.mul_lt_mul'' b_x6 b_x3_3 + have b_x15_14 : x15_14 < 2^64 := by rw [e_x15_14]; exact Nat.div_lt_of_lt_mul p_x15_14 + have d_x15_14 : x15_13 + 2^64 * x15_14 = x6 * x3_3 := by + rw [e_x15_13, e_x15_14]; exact Nat.mod_add_div _ _ + clear e_x15_13 e_x15_14 + -- x21_14: adcs x21,x21,xzr + extract_lets +onlyGivenNames s_46 x21_14 c_50 at hr + have e_x21_14 : x21_14 = (x21_13 + 0 + c_49) % 2^64 := rfl + have e_c_50 : c_50 = (x21_13 + 0 + c_49) / 2^64 := rfl + clear_value s_46 x21_14 c_50 + have l_x21_14 : x21_14 + 2^64 * c_50 = x21_13 + 0 + c_49 := by + rw [e_x21_14, e_c_50]; exact Nat.mod_add_div _ _ + have b_x21_14 : x21_14 < 2^64 := by rw [e_x21_14]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_50 : c_50 ≤ 1 := by + rw [e_c_50]; exact addc_carry_le_one x21_13 0 c_49 b_x21_13 (by decide) b_c_49 + clear e_x21_14 e_c_50 + -- x22_14: adcs x22,x22,x17 + extract_lets +onlyGivenNames s_47 x22_14 c_51 at hr + have e_x22_14 : x22_14 = (x22_13 + x17_13 + c_50) % 2^64 := rfl + have e_c_51 : c_51 = (x22_13 + x17_13 + c_50) / 2^64 := rfl + clear_value s_47 x22_14 c_51 + have l_x22_14 : x22_14 + 2^64 * c_51 = x22_13 + x17_13 + c_50 := by + rw [e_x22_14, e_c_51]; exact Nat.mod_add_div _ _ + have b_x22_14 : x22_14 < 2^64 := by rw [e_x22_14]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_51 : c_51 ≤ 1 := by + rw [e_c_51]; exact addc_carry_le_one x22_13 x17_13 c_50 b_x22_13 b_x17_13 b_c_50 + clear e_x22_14 e_c_51 + -- x17_14: lsr x17,x3,#2 + extract_lets +onlyGivenNames x17_14 at hr + have e_x17_14 : x17_14 = x3_3 / 2^2 := rfl + clear_value x17_14 + have b_x17_14 : x17_14 < 2^62 := by + rw [e_x17_14]; exact Nat.div_lt_of_lt_mul (lt_of_lt_of_eq b_x3_3 (by norm_num)) + have sh_x17_14 : x17_13 + 2^64 * x17_14 = x3_3 * 2^62 := by + rw [e_x17_13, e_x17_14]; exact lsl62_lsr2_split _ + clear e_x17_13 e_x17_14 + -- x23_13: adc x23,x23,xzr + extract_lets +onlyGivenNames x23_13 at hr + have e_x23_13 : x23_13 = (x23_12 + 0 + c_51) % 2^64 := rfl + clear_value x23_13 + have b_x23_13 : x23_13 < 2^64 := by rw [e_x23_13]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x23_13, b_k_x23_13, l_x23_13⟩ : + ∃ k, k ≤ 1 ∧ x23_13 + 2^64 * k = x23_12 + 0 + c_51 := + ⟨(x23_12 + 0 + c_51) / 2^64, addc_carry_le_one x23_12 0 c_51 b_x23_12 (by decide) b_c_51, + by rw [e_x23_13]; exact Nat.mod_add_div _ _⟩ + clear e_x23_13 + -- x19_7: adds x19,x20,x14 + extract_lets +onlyGivenNames s_48 x19_7 c_52 at hr + have e_x19_7 : x19_7 = (x20_14 + x14_10 + 0) % 2^64 := rfl + have e_c_52 : c_52 = (x20_14 + x14_10 + 0) / 2^64 := rfl + clear_value s_48 x19_7 c_52 + have l_x19_7 : x19_7 + 2^64 * c_52 = x20_14 + x14_10 + 0 := by + rw [e_x19_7, e_c_52]; exact Nat.mod_add_div _ _ + have b_x19_7 : x19_7 < 2^64 := by rw [e_x19_7]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_52 : c_52 ≤ 1 := by + rw [e_c_52]; exact addc_carry_le_one x20_14 x14_10 0 b_x20_14 b_x14_10 (by decide) + clear e_x19_7 e_c_52 + -- x20_15: adcs x20,x21,x15 + extract_lets +onlyGivenNames s_49 x20_15 c_53 at hr + have e_x20_15 : x20_15 = (x21_14 + x15_14 + c_52) % 2^64 := rfl + have e_c_53 : c_53 = (x21_14 + x15_14 + c_52) / 2^64 := rfl + clear_value s_49 x20_15 c_53 + have l_x20_15 : x20_15 + 2^64 * c_53 = x21_14 + x15_14 + c_52 := by + rw [e_x20_15, e_c_53]; exact Nat.mod_add_div _ _ + have b_x20_15 : x20_15 < 2^64 := by rw [e_x20_15]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_53 : c_53 ≤ 1 := by + rw [e_c_53]; exact addc_carry_le_one x21_14 x15_14 c_52 b_x21_14 b_x15_14 b_c_52 + clear e_x20_15 e_c_53 + -- x21_15: adcs x21,x22,xzr + extract_lets +onlyGivenNames s_50 x21_15 c_54 at hr + have e_x21_15 : x21_15 = (x22_14 + 0 + c_53) % 2^64 := rfl + have e_c_54 : c_54 = (x22_14 + 0 + c_53) / 2^64 := rfl + clear_value s_50 x21_15 c_54 + have l_x21_15 : x21_15 + 2^64 * c_54 = x22_14 + 0 + c_53 := by + rw [e_x21_15, e_c_54]; exact Nat.mod_add_div _ _ + have b_x21_15 : x21_15 < 2^64 := by rw [e_x21_15]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_54 : c_54 ≤ 1 := by + rw [e_c_54]; exact addc_carry_le_one x22_14 0 c_53 b_x22_14 (by decide) b_c_53 + clear e_x21_15 e_c_54 + -- x22_15: adcs x22,x23,x17 + extract_lets +onlyGivenNames s_51 x22_15 c_55 at hr + have e_x22_15 : x22_15 = (x23_13 + x17_14 + c_54) % 2^64 := rfl + have e_c_55 : c_55 = (x23_13 + x17_14 + c_54) / 2^64 := rfl + clear_value s_51 x22_15 c_55 + have l_x22_15 : x22_15 + 2^64 * c_55 = x23_13 + x17_14 + c_54 := by + rw [e_x22_15, e_c_55]; exact Nat.mod_add_div _ _ + have b_x22_15 : x22_15 < 2^64 := by rw [e_x22_15]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_55 : c_55 ≤ 1 := by + rw [e_c_55]; exact addc_carry_le_one x23_13 x17_14 c_54 b_x23_13 (lt_of_lt_of_le b_x17_14 (by norm_num)) b_c_54 + clear e_x22_15 e_c_55 + -- x23_14: adc x23,xzr,xzr + extract_lets +onlyGivenNames x23_14 at hr + have e_x23_14 : x23_14 = (0 + 0 + c_55) % 2^64 := rfl + clear_value x23_14 + have b_x23_14 : x23_14 < 2^64 := by rw [e_x23_14]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + obtain ⟨k_x23_14, b_k_x23_14, l_x23_14⟩ : + ∃ k, k ≤ 1 ∧ x23_14 + 2^64 * k = 0 + 0 + c_55 := + ⟨(0 + 0 + c_55) / 2^64, addc_carry_le_one 0 0 c_55 (by decide) (by decide) b_c_55, + by rw [e_x23_14]; exact Nat.mod_add_div _ _⟩ + clear e_x23_14 + -- BEGIN round 3 reduction + -- Cancellation: the low limb of `x19_6 + p0 * x3_3` is zero, so `x19_6 + lo_x14_10` is + -- `0` or `2^64`, and `subs xzr, x19_6, #1` set the carry exactly when it is `2^64`. + have hc_3 : x19_6 + lo_x14_10 = 2^64 * c_48 := by + have h := cancel_low x19_6 inv modulus.l0 hinv + rw [← e_x5, ← e_x4, ← e_x3_3, ← d_x14_10, Nat.add_mul_mod_self_left, + Nat.mod_eq_of_lt b_lo_x14_10] at h + clear * - h b_x19_6 b_lo_x14_10 l_c_48 + omega + have bc_3 : c_48 ≤ 1 := by clear * - l_c_48; omega + have hPq_3 : x3_3 * modulus.toNat = x5 * x3_3 + 2^64 * (x6 * x3_3) + 2^254 * x3_3 := by + rw [hP]; ring + -- `x17_13` is the low two bits of `x3_3` at the top of a limb. + have hsh_3 : x17_13 ≤ 3 * 2^62 := by + clear * - sh_x17_14 b_x17_13 b_x17_14; omega + -- The reduction's carry chain, summed with the limb weights. + have hsum'_3 : x19_6 + 2^64 * x20_14 + 2^128 * x21_14 + 2^192 * x22_14 + 2^256 * x23_13 + + 2^320 * k_x23_13 + = x19_6 + 2^64 * x20_13 + 2^128 * x21_13 + 2^192 * x22_13 + 2^256 * x23_12 + + 2^64 * x15_13 + 2^64 * c_48 + 2^192 * x17_13 := by + clear * - l_x20_14 l_x21_14 l_x22_14 l_x23_13 + omega + -- Neither `adc` of the reduction wraps: the five-limb accumulator is below + -- `2^320 - 3 * 2^254 - 2^128` by `hs_3`, and the reduction adds less than that before + -- the shift. + have hkr_3 : k_x23_13 = 0 := by + clear * - hsum'_3 F_3 B_2 hs_3 b_x15_13 bc_3 hsh_3 + omega + have hks_3 : k_x23_14 = 0 := by clear * - l_x23_14 b_c_55; omega + have I_3 : 2^64 * (x19_7 + 2^64 * x20_15 + 2^128 * x21_15 + 2^192 * x22_15 + 2^256 * x23_14) + = x19_6 + 2^64 * x20_13 + 2^128 * x21_13 + 2^192 * x22_13 + 2^256 * x23_12 + + x3_3 * modulus.toNat := by + clear * - hc_3 d_x14_10 d_x15_14 sh_x17_14 l_x20_14 l_x21_14 l_x22_14 l_x23_13 l_x19_7 l_x20_15 + l_x21_15 l_x22_15 l_x23_14 hkr_3 hks_3 hPq_3 + omega + -- The shifted accumulator stays below `lhs + p`. + have hLx_3 : lhs.toNat * x9_3 + lhs.toNat ≤ lhs.toNat * 2^64 := by + rw [← Nat.mul_succ]; exact Nat.mul_le_mul_left _ b_x9_3 + have hqP_3 : x3_3 * modulus.toNat + modulus.toNat ≤ 2^64 * modulus.toNat := by + rw [← Nat.succ_mul]; exact Nat.mul_le_mul_right _ b_x3_3 + have B_3 : x19_7 + 2^64 * x20_15 + 2^128 * x21_15 + 2^192 * x22_15 + 2^256 * x23_14 + < lhs.toNat + modulus.toNat := by + clear * - I_3 F_3 hLx_3 hqP_3 B_2 + omega + have t_3 : x23_14 ≤ 1 := by clear * - l_x23_14 hks_3 b_c_55; omega + -- END round 3 reduction + -- x14_11: subs x14,x19,x5 + extract_lets +onlyGivenNames s_52 x14_11 c_56 at hr + have e_x14_11 : x14_11 = (x19_7 + 2^64 - x5 - (1 - 1)) % 2^64 := rfl + have e_c_56 : c_56 = (x19_7 + 2^64 - x5 - (1 - 1)) / 2^64 := rfl + clear_value s_52 x14_11 c_56 + have l_x14_11 : x14_11 + 2^64 * c_56 + x5 + 1 = x19_7 + 2^64 + 1 := by + rw [e_x14_11, e_c_56]; exact subc_lin x19_7 x5 1 b_x5 (by decide) + have b_x14_11 : x14_11 < 2^64 := by rw [e_x14_11]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_56 : c_56 ≤ 1 := by + rw [e_c_56]; exact subc_carry_le_one x19_7 x5 1 b_x19_7 + clear e_x14_11 e_c_56 + -- x15_15: sbcs x15,x20,x6 + extract_lets +onlyGivenNames s_53 x15_15 c_57 at hr + have e_x15_15 : x15_15 = (x20_15 + 2^64 - x6 - (1 - c_56)) % 2^64 := rfl + have e_c_57 : c_57 = (x20_15 + 2^64 - x6 - (1 - c_56)) / 2^64 := rfl + clear_value s_53 x15_15 c_57 + have l_x15_15 : x15_15 + 2^64 * c_57 + x6 + 1 = x20_15 + 2^64 + c_56 := by + rw [e_x15_15, e_c_57]; exact subc_lin x20_15 x6 c_56 b_x6 b_c_56 + have b_x15_15 : x15_15 < 2^64 := by rw [e_x15_15]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_57 : c_57 ≤ 1 := by + rw [e_c_57]; exact subc_carry_le_one x20_15 x6 c_56 b_x20_15 + clear e_x15_15 e_c_57 + -- x16_7: sbcs x16,x21,xzr + extract_lets +onlyGivenNames s_54 x16_7 c_58 at hr + have e_x16_7 : x16_7 = (x21_15 + 2^64 - 0 - (1 - c_57)) % 2^64 := rfl + have e_c_58 : c_58 = (x21_15 + 2^64 - 0 - (1 - c_57)) / 2^64 := rfl + clear_value s_54 x16_7 c_58 + have l_x16_7 : x16_7 + 2^64 * c_58 + 0 + 1 = x21_15 + 2^64 + c_57 := by + rw [e_x16_7, e_c_58]; exact subc_lin x21_15 0 c_57 (by decide) b_c_57 + have b_x16_7 : x16_7 < 2^64 := by rw [e_x16_7]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_58 : c_58 ≤ 1 := by + rw [e_c_58]; exact subc_carry_le_one x21_15 0 c_57 b_x21_15 + clear e_x16_7 e_c_58 + -- x17_15: sbcs x17,x22,x8 + extract_lets +onlyGivenNames s_55 x17_15 c_59 at hr + have e_x17_15 : x17_15 = (x22_15 + 2^64 - x8 - (1 - c_58)) % 2^64 := rfl + have e_c_59 : c_59 = (x22_15 + 2^64 - x8 - (1 - c_58)) / 2^64 := rfl + clear_value s_55 x17_15 c_59 + have l_x17_15 : x17_15 + 2^64 * c_59 + x8 + 1 = x22_15 + 2^64 + c_58 := by + rw [e_x17_15, e_c_59]; exact subc_lin x22_15 x8 c_58 b_x8 b_c_58 + have b_x17_15 : x17_15 < 2^64 := by rw [e_x17_15]; exact Nat.mod_lt _ (Nat.two_pow_pos _) + have b_c_59 : c_59 ≤ 1 := by + rw [e_c_59]; exact subc_carry_le_one x22_15 x8 c_58 b_x22_15 + clear e_x17_15 e_c_59 + -- c_60: sbcs xzr,x23,xzr + extract_lets +onlyGivenNames c_60 at hr + have e_c_60 : c_60 = (x23_14 + 2^64 - 0 - (1 - c_59)) / 2^64 := rfl + clear_value c_60 + have b_c_60 : c_60 ≤ 1 := by rw [e_c_60]; exact subc_carry_le_one x23_14 0 c_59 b_x23_14 + have l_c_60 : (c_60 = 1 ∧ 0 + 1 ≤ x23_14 + c_59) ∨ (c_60 = 0 ∧ x23_14 + c_59 < 0 + 1) := + subc_carry_cases x23_14 0 c_59 _ e_c_60 b_x23_14 (by decide) b_c_59 + clear e_c_60 + -- x19_8: csel x19,x19,x14,lo + extract_lets +onlyGivenNames x19_8 at hr + have e_x19_8 : x19_8 = (if c_60 = 0 then x19_7 else x14_11) := rfl + clear_value x19_8 + have b_x19_8 : x19_8 < 2^64 := by + rw [e_x19_8]; split <;> first | exact b_x19_7 | exact b_x14_11 + -- x20_16: csel x20,x20,x15,lo + extract_lets +onlyGivenNames x20_16 at hr + have e_x20_16 : x20_16 = (if c_60 = 0 then x20_15 else x15_15) := rfl + clear_value x20_16 + have b_x20_16 : x20_16 < 2^64 := by + rw [e_x20_16]; split <;> first | exact b_x20_15 | exact b_x15_15 + -- x21_16: csel x21,x21,x16,lo + extract_lets +onlyGivenNames x21_16 at hr + have e_x21_16 : x21_16 = (if c_60 = 0 then x21_15 else x16_7) := rfl + clear_value x21_16 + have b_x21_16 : x21_16 < 2^64 := by + rw [e_x21_16]; split <;> first | exact b_x21_15 | exact b_x16_7 + -- x22_16: csel x22,x22,x17,lo + extract_lets +onlyGivenNames x22_16 at hr + have e_x22_16 : x22_16 = (if c_60 = 0 then x22_15 else x17_15) := rfl + clear_value x22_16 + have b_x22_16 : x22_16 < 2^64 := by + rw [e_x22_16]; split <;> first | exact b_x22_15 | exact b_x17_15 + -- out0: stp x19,x20,[x0] + extract_lets +onlyGivenNames out0 at hr + have e_out0 : out0 = x19_8 := rfl + clear_value out0 + -- out1: stp x19,x20,[x0] + extract_lets +onlyGivenNames out1 at hr + have e_out1 : out1 = x20_16 := rfl + clear_value out1 + -- out2: stp x21,x22,[x0,#16] + extract_lets +onlyGivenNames out2 at hr + have e_out2 : out2 = x21_16 := rfl + clear_value out2 + -- out3: stp x21,x22,[x0,#16] + extract_lets +onlyGivenNames out3 at hr + have e_out3 : out3 = x22_16 := rfl + clear_value out3 + subst hr + -- BEGIN conclusion + subst out0 out1 out2 out3 + have hLR : lhs.toNat * rhs.toNat + = lhs.toNat * x9 + 2^64 * (lhs.toNat * x9_1) + 2^128 * (lhs.toNat * x9_2) + + 2^192 * (lhs.toNat * x9_3) := by + rw [e_x9, e_x9_1, e_x9_2, e_x9_3]; simp only [Limbs.toNat]; ring + have hQ : x3 + 2^64 * x3_1 + 2^128 * x3_2 + 2^192 * x3_3 < 2^256 := by + clear * - b_x3 b_x3_1 b_x3_2 b_x3_3; omega + have hQP : (x3 + 2^64 * x3_1 + 2^128 * x3_2 + 2^192 * x3_3) * modulus.toNat + = x3 * modulus.toNat + 2^64 * (x3_1 * modulus.toNat) + 2^128 * (x3_2 * modulus.toNat) + + 2^192 * (x3_3 * modulus.toNat) := by + ring + -- The four rounds compose to `2^256 * acc = lhs * rhs + Q * p`. + have hmain : 2^256 * (x19_7 + 2^64 * x20_15 + 2^128 * x21_15 + 2^192 * x22_15 + 2^256 * x23_14) + = lhs.toNat * rhs.toNat + + (x3 + 2^64 * x3_1 + 2^128 * x3_2 + 2^192 * x3_3) * modulus.toNat := by + clear * - F_0 F_1 F_2 F_3 I_0 I_1 I_2 I_3 hLR hQP + omega + have hQPle : (x3 + 2^64 * x3_1 + 2^128 * x3_2 + 2^192 * x3_3) * modulus.toNat + modulus.toNat + ≤ 2^256 * modulus.toNat := by + rw [← Nat.succ_mul]; exact Nat.mul_le_mul_right _ hQ + -- `hfinal` puts the accumulator below `2 * p`, hence below `2^256`: its fifth limb is `0` and the + -- five-limb comparison is the four-limb one. The carry is set (`c_60 = 1`) exactly when the + -- accumulator is at least `p`; then the result is the difference, otherwise the accumulator. + have hA : x19_7 + 2^64 * x20_15 + 2^128 * x21_15 + 2^192 * x22_15 + 2^256 * x23_14 + < 2 * modulus.toNat := by + clear * - hmain hfinal hQPle; omega + have hx23 : x23_14 = 0 := by clear * - hA hP_lt; omega + have e_x8' : x8 = 2^62 := by rw [e_x8]; exact hshape.2 + have hD : x14_11 + 2^64 * x15_15 + 2^128 * x16_7 + 2^192 * x17_15 + + (x5 + 2^64 * x6 + 2^192 * x8) + 2^256 * c_59 + = x19_7 + 2^64 * x20_15 + 2^128 * x21_15 + 2^192 * x22_15 + 2^256 := by + clear * - l_x14_11 l_x15_15 l_x16_7 l_x17_15; omega + have hc59 : c_59 = c_60 := by clear * - l_c_60 hx23 b_c_59; omega + refine ⟨⟨b_x19_8, b_x20_16, b_x21_16, b_x22_16⟩, ?_⟩ + show x19_8 + 2^64 * x20_16 + 2^128 * x21_16 + 2^192 * x22_16 < modulus.toNat ∧ + 2^256 * (x19_8 + 2^64 * x20_16 + 2^128 * x21_16 + 2^192 * x22_16) + ≡ lhs.toNat * rhs.toNat [MOD modulus.toNat] + obtain hc | hc : c_60 = 0 ∨ c_60 = 1 := by clear * - l_c_60; omega + · rw [if_pos hc] at e_x19_8 e_x20_16 e_x21_16 e_x22_16 + refine ⟨?_, modEq_of_add_mul _ _ 0 (x3 + 2^64 * x3_1 + 2^128 * x3_2 + 2^192 * x3_3) _ (by + clear * - hmain hx23 e_x19_8 e_x20_16 e_x21_16 e_x22_16 + omega)⟩ + · clear * - hD hc59 hc hx23 hP e_x8' b_x14_11 b_x15_15 b_x16_7 b_x17_15 e_x19_8 e_x20_16 + e_x21_16 e_x22_16 + omega + · rw [if_neg (by clear * - hc; omega)] at e_x19_8 e_x20_16 e_x21_16 e_x22_16 + refine ⟨?_, modEq_of_add_mul _ _ (2^256) (x3 + 2^64 * x3_1 + 2^128 * x3_2 + 2^192 * x3_3) _ (by + clear * - hmain hD hc59 hc hx23 hP e_x8' e_x19_8 e_x20_16 e_x21_16 e_x22_16 + omega)⟩ + · clear * - hD hc59 hc hx23 hA hP e_x8' e_x19_8 e_x20_16 e_x21_16 e_x22_16 + omega + -- END conclusion + +-- BEGIN mulMont_spec corollaries +/-- Below `2^256`, by the limb bounds. -/ +theorem Limbs.toNat_lt (x : Limbs) (hx : x.Bounded) : x.toNat < 2^256 := by + obtain ⟨h0, h1, h2, h3⟩ := hx + simp only [Limbs.toNat]; omega + +/-- With the modulus in the shape the code assumes, `p < 2^255`. -/ +theorem Limbs.toNat_lt_of_shape (modulus : Limbs) (hm : modulus.Bounded) + (hshape : modulus.l2 = 0 ∧ modulus.l3 = 2^62) : modulus.toNat < 2^255 := by + obtain ⟨h0, h1, _, _⟩ := hm + simp only [Limbs.toNat, hshape.1, hshape.2]; omega + +/-- The contract the crate's callers use: a canonical left operand and any four-limb right +operand. -/ +theorem mulMont_spec_of_lhs_lt (lhs rhs modulus : Limbs) (inv : Nat) (hlhs : lhs.Bounded) + (hrhs : rhs.Bounded) (hm : modulus.Bounded) (hshape : modulus.l2 = 0 ∧ modulus.l3 = 2^62) + (hinv_lt : inv < 2^64) (hinv : (inv * modulus.l0 + 1) % 2^64 = 0) + (hlt : lhs.toNat < modulus.toNat) : + ∀ r, r = mulMont lhs rhs modulus inv → + r.Bounded ∧ r.toNat < modulus.toNat ∧ + 2^256 * r.toNat ≡ lhs.toNat * rhs.toNat [MOD modulus.toNat] := by + have hP := Limbs.toNat_lt_of_shape modulus hm hshape + have hR := Limbs.toNat_lt rhs hrhs + -- `lhs * (rhs_i + 1) ≤ (p - 1) * 2^64`, and `lhs * rhs < p * 2^256`. + have s1 : lhs.toNat * (rhs.l1 + 1) ≤ (modulus.toNat - 1) * 2^64 := + Nat.mul_le_mul (Nat.le_sub_one_of_lt hlt) hrhs.2.1 + have s2 : lhs.toNat * (rhs.l2 + 1) ≤ (modulus.toNat - 1) * 2^64 := + Nat.mul_le_mul (Nat.le_sub_one_of_lt hlt) hrhs.2.2.1 + have s3 : lhs.toNat * (rhs.l3 + 1) ≤ (modulus.toNat - 1) * 2^64 := + Nat.mul_le_mul (Nat.le_sub_one_of_lt hlt) hrhs.2.2.2 + have f : (lhs.toNat + 1) * (rhs.toNat + 1) ≤ modulus.toNat * 2^256 := Nat.mul_le_mul hlt hR + rw [Nat.add_one_mul, Nat.mul_add_one] at f + exact mulMont_spec lhs rhs modulus inv hlhs hrhs hm hshape hinv_lt hinv + ⟨by omega, by omega, by omega⟩ (by omega) + +/-- The other safe contract: any four-limb left operand, a canonical right operand whose limbs 1 +to 3 are at most `2^64 - 3`. -/ +theorem mulMont_spec_of_rhs_lt (lhs rhs modulus : Limbs) (inv : Nat) (hlhs : lhs.Bounded) + (hrhs : rhs.Bounded) (hm : modulus.Bounded) (hshape : modulus.l2 = 0 ∧ modulus.l3 = 2^62) + (hinv_lt : inv < 2^64) (hinv : (inv * modulus.l0 + 1) % 2^64 = 0) + (hlt : rhs.toNat < modulus.toNat) + (hlimbs : rhs.l1 + 3 ≤ 2^64 ∧ rhs.l2 + 3 ≤ 2^64 ∧ rhs.l3 + 3 ≤ 2^64) : + ∀ r, r = mulMont lhs rhs modulus inv → + r.Bounded ∧ r.toNat < modulus.toNat ∧ + 2^256 * r.toNat ≡ lhs.toNat * rhs.toNat [MOD modulus.toNat] := by + have hP := Limbs.toNat_lt_of_shape modulus hm hshape + have hL := Limbs.toNat_lt lhs hlhs + -- `lhs * (rhs_i + 1) ≤ (2^256 - 1) * (2^64 - 2)`, and `lhs * rhs < 2^256 * p`. + have c1 : rhs.l1 + 1 ≤ 2^64 - 2 := by omega + have c2 : rhs.l2 + 1 ≤ 2^64 - 2 := by omega + have c3 : rhs.l3 + 1 ≤ 2^64 - 2 := by omega + have s1 : lhs.toNat * (rhs.l1 + 1) ≤ (2^256 - 1) * (2^64 - 2) := + Nat.mul_le_mul (Nat.le_sub_one_of_lt hL) c1 + have s2 : lhs.toNat * (rhs.l2 + 1) ≤ (2^256 - 1) * (2^64 - 2) := + Nat.mul_le_mul (Nat.le_sub_one_of_lt hL) c2 + have s3 : lhs.toNat * (rhs.l3 + 1) ≤ (2^256 - 1) * (2^64 - 2) := + Nat.mul_le_mul (Nat.le_sub_one_of_lt hL) c3 + norm_num at s1 s2 s3 + have f : (lhs.toNat + 1) * (rhs.toNat + 1) ≤ 2^256 * modulus.toNat := Nat.mul_le_mul hL hlt + rw [Nat.add_one_mul, Nat.mul_add_one] at f + exact mulMont_spec lhs rhs modulus inv hlhs hrhs hm hshape hinv_lt hinv + ⟨by omega, by omega, by omega⟩ (by omega) +-- END mulMont_spec corollaries + +end CompElliptic.Asm.AArch64 diff --git a/CompElliptic/Asm/AArch64/PastaMulVectors.lean b/CompElliptic/Asm/AArch64/PastaMulVectors.lean new file mode 100644 index 0000000..b792a11 --- /dev/null +++ b/CompElliptic/Asm/AArch64/PastaMulVectors.lean @@ -0,0 +1,8392 @@ +/- +Copyright (c) 2026 CompElliptic Contributors. +Released under the Apache License, Version 2.0, or the MIT license, at your option, +as described in the files LICENSE-APACHE and LICENSE-MIT. +Authors: Daira-Emma Hopwood +-/ +import CompElliptic.Asm.AArch64.PastaMul + +/-! +# Reference vectors for the transcribed routines + +GENERATED by `scripts/gen_aarch64_pasta_mul.py` from +`CompElliptic/Asm/AArch64/vendor/pasta_mul-armv8-vectors.txt`; do not edit by hand. Each +vector is the output of the real assembly (pasta_curves `8ad85e9fab7929f6236960e472f432a4bd9ccd74`, +run on an Apple M-series machine) on the given operands, and each example asks the kernel +to evaluate the transcription on the same operands. The vectors cover boundary operands +(zero, one, `R`, `R2`, `R3`, `p - 1`, single all-ones limbs), random canonical operands, +and unreduced operands in both positions, so they also record the routines' behaviour +outside their operand contracts. + +The modulus limbs and `inv` are the crate's constants for its `Fp` (the Pallas base field) +and `Fq` (the Vesta base field). +-/ + +namespace CompElliptic.Asm.AArch64 + +/-- The Pallas base field modulus, as the crate's `MODULUS` limbs. -/ +def pallasBaseModulus : Limbs := ⟨0x992d30ed00000001, 0x224698fc094cf91b, 0, 0x4000000000000000⟩ + +/-- `-p^-1 mod 2^64` for the Pallas base field, the crate's `INV`. -/ +def pallasBaseInv : Nat := 0x992d30ecffffffff + +/-- The Vesta base field modulus, as the crate's `MODULUS` limbs. -/ +def vestaBaseModulus : Limbs := ⟨0x8c46eb2100000001, 0x224698fc0994a8dd, 0, 0x4000000000000000⟩ + +/-- `-p^-1 mod 2^64` for the Vesta base field, the crate's `INV`. -/ +def vestaBaseInv : Nat := 0x8c46eb20ffffffff + +example : + fromMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589658) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0ed96497d1a6219029a6ae9870dfb50713cd52c155d255e973c0f7cb33ceb302) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x388013304285d697358022a45037659a43d08525ed8bafae6abb1c2bed362cc2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0e0e3b00e1dd872a8f34d6691037659a6d153852c681be7ce3a2562a6c589658) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02533e46e64b4c3b40000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x38a026e0c48e71f73ae41fe20afd7333e0aa9a82f9f1a38bd4422d02de3d4125) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x057f2b054a45df575e9e6a328d598a1a2bd9ec5993f125a8b1efd019b9ccd6d0) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x23d1b7add4cc7721af5216f2e0da32ec8835dbecf358fccdf19780a4b1d41685) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x336bd3ea8db1d5ac64f8300ae87e52a81e5b765b2faa215d8dfb1b0d25b6b271) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1b13887e1a1429f16e4161a915c9cb2099813c8a1d8cc439f2f1f0773efd541d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0417a27f9647ed737c71f702e127cf999f5644b7dd769aac7d70f04b3ca33a4f) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x21cce888a6cab566710d6cd04c692c9784379b4cc10e927b1dfc65f6ad0492ae) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000891a63f02533e46e64b4c3b400000004) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffff76e59c0fdacc1b9246ac39382e80dd85fde1f4a100000005) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x125b506bdee72dc51de5ea66f0f257463e8669ae6516b680c969876800000004) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x36e59c0fdacc1b919b4b3c4bfffffffcefee2ee4411acfc1303c567b00000007) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x125b506bdee72dc51de5ea66f0f25746c7a0cd9e8a4a9aef2e1e4b1c00000008) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2da4af942118d23ae21a15990f0da8b9e3c02f4da436429acfc3a984fffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3031b67010dc5f33e1768c975480689a91ad57216c5706a8810c3c6089daf8b6) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3b22a80cd2c81a0c889a01873458140ef909266c546d35f5014930b21f53b554) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x10548582022977317020e583ebc9e08237f899a30131ff72b3387ebd971aec55) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x348bf875968510c9c9602914af00483e46f3b5921d2c02b91578ba31cf7bad4c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0791f325de14e664b4aa62282e98a644f50840433dbfc7626da70eaaf58145f5) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x08102d3c3c95a063e1e6c2328bbd8e7ed2a208c993640dc0c477d288cfba797a) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0662a11d61e1a30f915945eff265faff24953adafa8636a3c01ff3639e2aed4c) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x21cce888a6cab566710d6cd04c692c9784379b4cc10e927b1dfc65f6ad0492ae) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0662a11d61e1a30f915945eff265faff24953adafa8636a3c01ff3639e2aed4c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3692be50846348eb886856643c36a2e74a738b3e7e3f18340cb44439fffffff2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2e2a67ec482ca6045b2ef3341a17f2ecf6a3c75cc8bdaf33e0efe592118d23a0) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3ab8c2488b4b664437e344050d4ff50b575e968be1ab27492f434e180ea7843f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x09595b20624498f13919469f2d8f1ea91d1e34d0388bbd88e9421d36f0da8b8e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x314b80990faeaf2fc04b9a69498697f27f8b88ce569d4661a2ca61650ea78430) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x05473db774b499bbc81cbbfaf2b00af4cae8027027a1d1d269e9e2d4f1587bc2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x11059dda0a0984a24c432eaa84cb8a47e785e51edefe7cefa723d05be7cd96b1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2a8c68e806154a62330fa85f54dedea8453b7a0d756f7860ca191c12c6265afb) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x28b001b79faac705f426b23ca533d40220e19e6209f724ada5c28c17b9f0d326) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3c2c602b7bf8fbf1790afd71b3e16fad0c5531d44cf930398f831a05338f2444) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3d679a6b16f9788e6430d173a58607f8d5e7ec854b246cf10a63c8d6170c9008) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x096a1374bdff44bcdb81d15301f0d099d8fc397f7e24afe149933c9ef8a6efe3) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589658) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589658) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000891a63f02533e46e64b4c3b400000004) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3692be50846348eb886856643c36a2e74a738b3e7e3f18340cb44439fffffff2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x31269b682e59de6fd65951678f204af90e79463ab37aa332256c3921cc314cff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02533e46e64b4c3b40000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x077feccfbd7a2968ca7fdd5bafc89a65de7613d61bc1496d2e7214c112c9d33f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x31f1c4ff1e2278d570cb2996efc89a65b53160a942cb3a9eb58adac293a769a9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x075fd91f3b718e08c51be01df5028ccc419bfe790f5b558fc4eb03ea21c2bedc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3a80d4fab5ba20a8a16195cd72a675e5f66caca2755bd372e73d60d346332931) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1c2e48522b3388de50ade90d1f25cd139a10bd0f15f3fc4da795b0484e2be97c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0c942c15724e2a539b07cff51781ad5803eb22a0d9a2d7be0b3215dfda494d90) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x24ec7781e5ebd60e91be9e56ea3634df88c55c71ebc034e1a63b4075c102abe4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3be85d8069b8128c838e08fd1ed8306682f054442bd65e6f1bbc40a1c35cc5b2) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1acd4a009f399376e232c5736e77fb8c1c35dfa341e703db83392c958598c6be) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0ed96497d1a6219029a6ae9870dfb50713cd52c155d255e973c0f7cb33ceb302) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0ed96497d1a6219029a6ae9870dfb50713cd52c155d255e973c0f7cb33ceb302) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffff76e59c0fdacc1b9246ac39382e80dd85fde1f4a100000005) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2e2a67ec482ca6045b2ef3341a17f2ecf6a3c75cc8bdaf33e0efe592118d23a0) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x31269b682e59de6fd65951678f204af90e79463ab37aa332256c3921cc314cff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1acd4a009f399376e232c5736e77fb8c1c35dfa341e703db83392c958598c6be) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02533e47264b4c3b40000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3d000f740db18f02f00e052c4f204af954d1de0b0cab76c3b5b5e0d408b278e3) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x01269b682e59de6fd65951678f204af8f4c4537dac80e85db28a54700c314cfe) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd06f9bad472e1e4b1c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0243f901466f013c8772ef73a588001a8cfd085e39574506f699f0ce0f88f6ff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x191f3f2d4313aac2ca49e3117da6cccc88309e28da5f78ff277a04b81d1babd3) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0b805f450c0dbbcac5b4d865b01cc2cfdf8b1a0da5a185b347115895fafa0cf5) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x318c5c205acc7cfb9dd944e14c01dc9dc04c7e3f598fcdcf20995458a381f6df) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x132dd92afbb5a12f1cbf9c47baf77e853f10c4c3988db021b3feac2f58b2041e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x385a54834adfe22620b33bbf39551c1ebe43143dccc4fe9a83b5c6ed6a3d0fe4) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x125b506bdee72dc51de5ea66f0f257463e8669ae6516b680c969876800000004) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3ab8c2488b4b664437e344050d4ff50b575e968be1ab27492f434e180ea7843f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02533e46e64b4c3b40000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02533e47264b4c3b40000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000004891a63f02533e46e64b4c3b40000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x200000000000000000000000000000000891a63f02533e46e64b4c3b40000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x30000000000000000000000000000000224698fc094cf91b992d30ed00000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1f0f0f09f84f08783843fdf0cf348dc097a0b54e3aa246c5b55a5622784f0e97) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3b5460f6403423b40d9318fd6638bebd8e6eef198af3853ff6d6f357647edda2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x08a3454c5f8ed6682cc97fccfbfe6debb4b8745fecf3f0e50dfb5b6dd8bafe75) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x352c1aa827cc3842bae5326c6b8c0507b63abda4f5381c1fba0caf01e03ae083) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x049a2bd27b9b331284522c7cbc8a91687e2221820bee830d4de6a0df5e838533) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x02bf53bdc23a2a747c90e3e3ed389e5d8e77d8428bb6a45fe99705d8bcb3fbfa) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2d0e14a05cd1d9fc243491206fc89a663293063e00578f9e26d1cbe7d1ec3cd7) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x388013304285d697358022a45037659a43d08525ed8bafae6abb1c2bed362cc2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x388013304285d697358022a45037659a43d08525ed8bafae6abb1c2bed362cc2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x36e59c0fdacc1b919b4b3c4bfffffffcefee2ee4411acfc1303c567b00000007) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x09595b20624498f13919469f2d8f1ea91d1e34d0388bbd88e9421d36f0da8b8e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x077feccfbd7a2968ca7fdd5bafc89a65de7613d61bc1496d2e7214c112c9d33f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3d000f740db18f02f00e052c4f204af954d1de0b0cab76c3b5b5e0d408b278e3) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000004891a63f02533e46e64b4c3b40000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2d0e14a05cd1d9fc243491206fc89a663293063e00578f9e26d1cbe7d1ec3cd7) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x177feccfbd7a2968ca7fdd5bafc89a662707ba151e1487b414bd60fc52c9d33f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2fffffffffffffffffffffffffffffffd9b4f2bd06f9bad4b2e1e4b1c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x09b6e874ebf7015713395bc67cb37e35bf190f9737a661f2590218bef5ccf20d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2369223ec0ba778f450631700e279844d7602068e54753affa279ed410cd00c8) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x113537aabc2a7e9a9f170ff0466ace9eb6bd66c2ac39a2cb6bcd60b2cac31dca) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0f65a101a6ce5999439c8a3a3746ccd5da1def3365e774fd07693f94385002f0) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2fed7572b6ad1fb4518addae8bb2afaca112b6073915376d60bf257769db7f62) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x190d90428434fe44c0c829966224346c7b42f390ed1288f2ffb94f3b3ebd874b) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x11f1c4ff1e2278d570cb2996efc89a659b7c6dec3bd17fca02a8f610d3a769a8) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0e0e3b00e1dd872a8f34d6691037659a6d153852c681be7ce3a2562a6c589658) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0e0e3b00e1dd872a8f34d6691037659a6d153852c681be7ce3a2562a6c589658) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x125b506bdee72dc51de5ea66f0f25746c7a0cd9e8a4a9aef2e1e4b1c00000008) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x314b80990faeaf2fc04b9a69498697f27f8b88ce569d4661a2ca61650ea78430) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x31f1c4ff1e2278d570cb2996efc89a65b53160a942cb3a9eb58adac293a769a9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x01269b682e59de6fd65951678f204af8f4c4537dac80e85db28a54700c314cfe) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x200000000000000000000000000000000891a63f02533e46e64b4c3b40000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x177feccfbd7a2968ca7fdd5bafc89a662707ba151e1487b414bd60fc52c9d33f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x11f1c4ff1e2278d570cb2996efc89a659b7c6dec3bd17fca02a8f610d3a769a8) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x266ee82933c09680fd5fde0ec4371a8cd93cb3c749fd9c557a455a0c9a11cd73) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x35d535f0f5ee445caef4aecad8df34a3629502bff7025f9744e7233daab206d2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x24d18d9e8ac25f467d7768da1b243aff4ec9316f02e7ed32b5910bb626e6e7f1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x01c046bd9a1a629655ed0261830db25f97df4749c58dfac22c1193f4ba842e12) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2986a354618709211610cad3a6c0c64806e77df3f7aeb7eef421e1551f863117) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3ea7b13e2bf23d01001eece10c10cec411682c86b78d02cf0553467a8010c1ac) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02533e46e64b4c3b40000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02533e46e64b4c3b40000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2da4af942118d23ae21a15990f0da8b9e3c02f4da436429acfc3a984fffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x05473db774b499bbc81cbbfaf2b00af4cae8027027a1d1d269e9e2d4f1587bc2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd06f9bad472e1e4b1c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x30000000000000000000000000000000224698fc094cf91b992d30ed00000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2fffffffffffffffffffffffffffffffd9b4f2bd06f9bad4b2e1e4b1c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x20f0f0f607b0f787c7bc020f30cb723f8aa5e3adceaab255e3d2daca87b0f16a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x04ab9f09bfcbdc4bf26ce70299c7414293d7a9e27e5973dba2563d959b81225f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x375cbab3a0712997d3368033040192146d8e249c1c5908368b31d57f2745018c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0ad3e557d833c7bd451acd939473faf86c0bdb571414dcfbdf2081eb1fc51f7e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3b65d42d8464cced7badd38343756e97a4247779fd5e760e4b46900da17c7ace) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3d40ac423dc5d58b836f1c1c12c761a293cec0b97d9654bbaf962b14434c0407) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3e3eab736edbf3946567e005720448fa968090b33ceae01c4381bc2109eeaf68) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x38a026e0c48e71f73ae41fe20afd7333e0aa9a82f9f1a38bd4422d02de3d4125) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x38a026e0c48e71f73ae41fe20afd7333e0aa9a82f9f1a38bd4422d02de3d4125) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3031b67010dc5f33e1768c975480689a91ad57216c5706a8810c3c6089daf8b6) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x11059dda0a0984a24c432eaa84cb8a47e785e51edefe7cefa723d05be7cd96b1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x075fd91f3b718e08c51be01df5028ccc419bfe790f5b558fc4eb03ea21c2bedc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0243f901466f013c8772ef73a588001a8cfd085e39574506f699f0ce0f88f6ff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1f0f0f09f84f08783843fdf0cf348dc097a0b54e3aa246c5b55a5622784f0e97) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x09b6e874ebf7015713395bc67cb37e35bf190f9737a661f2590218bef5ccf20d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x266ee82933c09680fd5fde0ec4371a8cd93cb3c749fd9c557a455a0c9a11cd73) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x20f0f0f607b0f787c7bc020f30cb723f8aa5e3adceaab255e3d2daca87b0f16a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3e3eab736edbf3946567e005720448fa968090b33ceae01c4381bc2109eeaf68) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3a9fa1eab51f114925de48e933973c839a851f8d16897802cce98a6267201387) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2433c132353f7a7f730575508359403919905b802503b90d7f4089fc0acd1e2a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x18a27a96677cebda48524b4f66ca32081b52f70b717294b8645d87743ef435db) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1b1d201950d04201d5a13d2f40f232fcf3da86444bfbdd96a840d51974c1a9d7) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0fe1bce271b680a3432473b59a47a1c89bb3fa7f9abd3fc2582838316659e21a) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x23e2d584e303750afbe701cc135a158c167f8e478e3e5fc5d9a12bd944145437) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x057f2b054a45df575e9e6a328d598a1a2bd9ec5993f125a8b1efd019b9ccd6d0) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x057f2b054a45df575e9e6a328d598a1a2bd9ec5993f125a8b1efd019b9ccd6d0) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3b22a80cd2c81a0c889a01873458140ef909266c546d35f5014930b21f53b554) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2a8c68e806154a62330fa85f54dedea8453b7a0d756f7860ca191c12c6265afb) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3a80d4fab5ba20a8a16195cd72a675e5f66caca2755bd372e73d60d346332931) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x191f3f2d4313aac2ca49e3117da6cccc88309e28da5f78ff277a04b81d1babd3) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3b5460f6403423b40d9318fd6638bebd8e6eef198af3853ff6d6f357647edda2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2369223ec0ba778f450631700e279844d7602068e54753affa279ed410cd00c8) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x35d535f0f5ee445caef4aecad8df34a3629502bff7025f9744e7233daab206d2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x04ab9f09bfcbdc4bf26ce70299c7414293d7a9e27e5973dba2563d959b81225f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3a9fa1eab51f114925de48e933973c839a851f8d16897802cce98a6267201387) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x23e2d584e303750afbe701cc135a158c167f8e478e3e5fc5d9a12bd944145437) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3ce872d15beb15e7588f5de133d0911cd1c2e096c89f9f45c5e09880d85839c5) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3259897b8dc9480ee45a3263849a285c4956e607a01e8d672e92443b91d4af79) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x13b5bc4323ef673b7d2ebb04dc796bcc0595773c37288657aa1b5b21897e52d4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x241142522c7e16f6adc74f23033257a67598c7dbd63840792ffe83c6b9c1e770) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x101375a000c3fbfa17d36b7a1e49055624cd7677331a60db2cc29f483741ff50) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x23d1b7add4cc7721af5216f2e0da32ec8835dbecf358fccdf19780a4b1d41685) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x23d1b7add4cc7721af5216f2e0da32ec8835dbecf358fccdf19780a4b1d41685) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x10548582022977317020e583ebc9e08237f899a30131ff72b3387ebd971aec55) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x28b001b79faac705f426b23ca533d40220e19e6209f724ada5c28c17b9f0d326) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1c2e48522b3388de50ade90d1f25cd139a10bd0f15f3fc4da795b0484e2be97c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0b805f450c0dbbcac5b4d865b01cc2cfdf8b1a0da5a185b347115895fafa0cf5) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x08a3454c5f8ed6682cc97fccfbfe6debb4b8745fecf3f0e50dfb5b6dd8bafe75) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x113537aabc2a7e9a9f170ff0466ace9eb6bd66c2ac39a2cb6bcd60b2cac31dca) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x24d18d9e8ac25f467d7768da1b243aff4ec9316f02e7ed32b5910bb626e6e7f1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x375cbab3a0712997d3368033040192146d8e249c1c5908368b31d57f2745018c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2433c132353f7a7f730575508359403919905b802503b90d7f4089fc0acd1e2a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3ce872d15beb15e7588f5de133d0911cd1c2e096c89f9f45c5e09880d85839c5) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x101375a000c3fbfa17d36b7a1e49055624cd7677331a60db2cc29f483741ff50) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x216088e1212a7e3fc1f7dec7525eecdf393fe793f52a875cf043848ad8095cc3) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x35c5000bc6c052e6674d650b37e06a3a0a4fba0c34fd24ce261a45452089bc46) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2565d74b6f42ec480e49fae1cd43df66bbb7502f0cef496c28f6c4879667d453) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1677ce27814b54d771a091ab04eef7ad2cdf503fcfe6b9e8dad6ba85e7d8fbc9) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x336bd3ea8db1d5ac64f8300ae87e52a81e5b765b2faa215d8dfb1b0d25b6b271) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x336bd3ea8db1d5ac64f8300ae87e52a81e5b765b2faa215d8dfb1b0d25b6b271) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x348bf875968510c9c9602914af00483e46f3b5921d2c02b91578ba31cf7bad4c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3c2c602b7bf8fbf1790afd71b3e16fad0c5531d44cf930398f831a05338f2444) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0c942c15724e2a539b07cff51781ad5803eb22a0d9a2d7be0b3215dfda494d90) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x318c5c205acc7cfb9dd944e14c01dc9dc04c7e3f598fcdcf20995458a381f6df) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x352c1aa827cc3842bae5326c6b8c0507b63abda4f5381c1fba0caf01e03ae083) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0f65a101a6ce5999439c8a3a3746ccd5da1def3365e774fd07693f94385002f0) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x01c046bd9a1a629655ed0261830db25f97df4749c58dfac22c1193f4ba842e12) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0ad3e557d833c7bd451acd939473faf86c0bdb571414dcfbdf2081eb1fc51f7e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x18a27a96677cebda48524b4f66ca32081b52f70b717294b8645d87743ef435db) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3259897b8dc9480ee45a3263849a285c4956e607a01e8d672e92443b91d4af79) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x216088e1212a7e3fc1f7dec7525eecdf393fe793f52a875cf043848ad8095cc3) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1677ce27814b54d771a091ab04eef7ad2cdf503fcfe6b9e8dad6ba85e7d8fbc9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x360e55958d8e8464a1fd7990b64f92ffbfae77cba35ea31dc8f26d8c0274ce1f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x12d5679fd842c0fae489e6f8fd950712a6801d77da2000d2e180e73af156d5b3) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3ce69b158811c2f8acefdc7b0e5a9df4c9bd80d3b24d8f94654a3efada3cf581) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1b13887e1a1429f16e4161a915c9cb2099813c8a1d8cc439f2f1f0773efd541d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1b13887e1a1429f16e4161a915c9cb2099813c8a1d8cc439f2f1f0773efd541d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0791f325de14e664b4aa62282e98a644f50840433dbfc7626da70eaaf58145f5) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3d679a6b16f9788e6430d173a58607f8d5e7ec854b246cf10a63c8d6170c9008) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x24ec7781e5ebd60e91be9e56ea3634df88c55c71ebc034e1a63b4075c102abe4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x132dd92afbb5a12f1cbf9c47baf77e853f10c4c3988db021b3feac2f58b2041e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x049a2bd27b9b331284522c7cbc8a91687e2221820bee830d4de6a0df5e838533) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2fed7572b6ad1fb4518addae8bb2afaca112b6073915376d60bf257769db7f62) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2986a354618709211610cad3a6c0c64806e77df3f7aeb7eef421e1551f863117) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3b65d42d8464cced7badd38343756e97a4247779fd5e760e4b46900da17c7ace) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1b1d201950d04201d5a13d2f40f232fcf3da86444bfbdd96a840d51974c1a9d7) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x13b5bc4323ef673b7d2ebb04dc796bcc0595773c37288657aa1b5b21897e52d4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x35c5000bc6c052e6674d650b37e06a3a0a4fba0c34fd24ce261a45452089bc46) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x360e55958d8e8464a1fd7990b64f92ffbfae77cba35ea31dc8f26d8c0274ce1f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3ce69b158811c2f8acefdc7b0e5a9df4c9bd80d3b24d8f94654a3efada3cf581) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0ce2105c41fe09975371bc977a9cacd087001027e8f2f0eebb02070709dbc6cd) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0b67e1cebd614788846394194b77a658559fe5bf4d14fa7d808af326b918255d) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0417a27f9647ed737c71f702e127cf999f5644b7dd769aac7d70f04b3ca33a4f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0417a27f9647ed737c71f702e127cf999f5644b7dd769aac7d70f04b3ca33a4f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x08102d3c3c95a063e1e6c2328bbd8e7ed2a208c993640dc0c477d288cfba797a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x096a1374bdff44bcdb81d15301f0d099d8fc397f7e24afe149933c9ef8a6efe3) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3be85d8069b8128c838e08fd1ed8306682f054442bd65e6f1bbc40a1c35cc5b2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x385a54834adfe22620b33bbf39551c1ebe43143dccc4fe9a83b5c6ed6a3d0fe4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x02bf53bdc23a2a747c90e3e3ed389e5d8e77d8428bb6a45fe99705d8bcb3fbfa) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x190d90428434fe44c0c829966224346c7b42f390ed1288f2ffb94f3b3ebd874b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3ea7b13e2bf23d01001eece10c10cec411682c86b78d02cf0553467a8010c1ac) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3d40ac423dc5d58b836f1c1c12c761a293cec0b97d9654bbaf962b14434c0407) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0fe1bce271b680a3432473b59a47a1c89bb3fa7f9abd3fc2582838316659e21a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x241142522c7e16f6adc74f23033257a67598c7dbd63840792ffe83c6b9c1e770) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2565d74b6f42ec480e49fae1cd43df66bbb7502f0cef496c28f6c4879667d453) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x12d5679fd842c0fae489e6f8fd950712a6801d77da2000d2e180e73af156d5b3) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0ce2105c41fe09975371bc977a9cacd087001027e8f2f0eebb02070709dbc6cd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0b67e1cebd614788846394194b77a658559fe5bf4d14fa7d808af326b918255d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589659) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589659) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3ffffffffffffffeffffffffffffffff992c350be41914ad34786d38fffffffc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d1960ed71adb041c555f12db06700000013) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d1960ed71adb041c555f12db06700000013) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2175c772b190e1fc67f56678717677141ed3817ddfb7d0ea650cb8e63a9e10ea) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2175c772b190e1fc67f56678717677141ed3817ddfb7d0ea650cb8e63a9e10ea) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a8) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a8) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x31269b682e59de6fd65951678f204af90e79463ab37aa333256c3921cc314cfe) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x31269b682e59de6fd65951678f204af90e79463ab37aa333256c3921cc314cfe) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0fffffffffffffffffffffffffffffffe64b0d42f906452b4d1e1b4e3fffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0fffffffffffffffffffffffffffffffe64b0d42f906452b4d1e1b4e3fffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x077feccfbd7a2968ca7fdd5bafc89a65de7613d61bc1496d2e7214c112c9d33e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x077feccfbd7a2968ca7fdd5bafc89a66de7613d61bc1496d2e7214c112c9d33e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x31f1c4ff1e2278d570cb2996efc89a6492eac7ad397e41831c5da9d593a769a7) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x31f1c4ff1e2278d570cb2996efc89a6592eac7ad397e41831c5da9d593a769a7) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x300000000000000000000000000000003bfb8bb91046b3f04c0f159ec0000002) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x300000000000000000000000000000003bfb8bb91046b3f04c0f159ec0000002) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x21f1c4ff1e2278d570cb2996efc89a64ac9fba6a4077fc57cf3f8e8753a769a7) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x21f1c4ff1e2278d570cb2996efc89a64ac9fba6a4077fc57cf3f8e8753a769a7) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xf0cb2996efc89a649a71d82f60a84f6c9e26742f8cfd5924a9d3556587761ca9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x30cb2996efc89a659a71d82f60a84f6bc06d0d2b964a52404300865287761caa) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xc83d113a5e2278d430cb2996efc89a647c94c6d6abc5909ccdfc4e25d1062bf3) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xc83d113a5e2278d430cb2996efc89a657c94c6d6abc5909ccdfc4e25d1062bf3) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xe64b4c3b3ffffffebffffffffffffffff23ba568749a8d6097e9f08b7d5ec24c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xe64b4c3b3ffffffebffffffffffffffff23ba568749a8d6097e9f08b7d5ec24c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589659) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589659) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0f34d6691037659a658e27d09f57b09361d98bd07302a6da562caa9a7889e357) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0f34d6691037659a658e27d09f57b09361d98bd07302a6da562caa9a7889e357) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3ffffffffffffffeffffffffffffffff992c350be41914ac34786d38fffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ac34786d38fffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x096d41af7b9cb71500b20d8be8fd41873c87d1718b0de0eb8c78ecb30000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x096d41af7b9cb71500b20d8be8fd41873c87d1718b0de0eb8c78ecb30000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x334b5f8669643bf80cc67344575e84274a76531d20471ad21d4a04412910ed4b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x334b5f8669643bf80cc67344575e84274a76531d20471ad21d4a04412910ed4b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x30cb2996efc89a659a71d82f60a84f6cc06d0d2b964a52414300865287761caa) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x30cb2996efc89a659a71d82f60a84f6cc06d0d2b964a52414300865287761caa) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x165951678f204af8f4268bf420a84f6cf243669771939f57a2330c8c46988640) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x165951678f204af8f4268bf420a84f6cf243669771939f57a2330c8c46988640) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffc000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffc000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0a7fdd5bafc89a65da71d82f60a84f6cabeacec71862cbc511e964da0a175a5c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0a7fdd5bafc89a65da71d82f60a84f6dabeacec71862cbc511e964da0a175a5c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x30cb2996efc89a659a71d82f60a84f6b9e26742f8cfd592569d3556587761ca9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x30cb2996efc89a659a71d82f60a84f6c9e26742f8cfd592569d3556587761ca9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91bd92d30ed00000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91bd92d30ed00000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x30cb2996efc89a659a71d82f60a84f6bc06d0d2b964a52404300865287761caa) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xf0cb2996efc89a649a71d82f60a84f6c9e26742f8cfd5924a9d3556587761ca9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xda71d82f60a84f6ba64b4c3b3fffffffabe30d981b69b9cd07a048d940dd9669) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xda71d82f60a84f6ba64b4c3b3fffffffabe30d981b69b9cd07a048d940dd9669) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xf0cb2996efc89a649a71d82f60a84f6b9e26742f8cfd5924a9d3556587761caa) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xf0cb2996efc89a649a71d82f60a84f6c9e26742f8cfd5924a9d3556587761caa) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xbffffffffffffffeffffffffffffffffddb96703f6b306e366d2cf1300000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xbffffffffffffffeffffffffffffffffddb96703f6b306e366d2cf1300000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0f34d6691037659a658e27d09f57b09361d98bd07302a6da562caa9a7889e357) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0f34d6691037659a658e27d09f57b09361d98bd07302a6da562caa9a7889e357) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x37c2eec5a1dd872acf34d6691037659a836b3929543a6f633203b1da2ef9d40c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x37c2eec5a1dd872acf34d6691037659a836b3929543a6f633203b1da2ef9d40c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3ffffffffffffffeffffffffffffffff992c350be41914ad34786d38fffffffc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3ffffffffffffffeffffffffffffffff992c350be41914ad34786d38fffffffc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2e2205637b9cb7182e2a67ec482ca604fcfe4d7d773c0e0beec288616b306e5a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2e2205637b9cb7182e2a67ec482ca604fcfe4d7d773c0e0beec288616b306e5a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x30c4d737c038663a7d125d564448de03477954dba8c4a49f5592d170b2235101) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x30c4d737c038663a7d125d564448de03477954dba8c4a49f5592d170b2235101) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x083d113a5e2278d530cb2996efc89a659edb5fd2b51289b867297f12d1062bf5) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x083d113a5e2278d530cb2996efc89a659edb5fd2b51289b867297f12d1062bf5) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1771e7a36e59de6f965951678f204af900b4eba328153093bd5629ad49900f4a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1771e7a36e59de6f965951678f204af900b4eba328153093bd5629ad49900f4a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0fffffffffffffffbfffffffffffffffe64b0d42f906452b4d1e1b4e3fffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0fffffffffffffffbfffffffffffffffe64b0d42f906452b4d1e1b4e3fffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2dcb390afd7a29688a7fdd5bafc89a66f2f8523a99a8cfe85f8936399028958c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2dcb390afd7a29688a7fdd5bafc89a66f2f8523a99a8cfe85f8936399028958c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x183d113a5e2278d4f0cb2996efc89a6585266d15ae18cee3b4479a6111062bf4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x183d113a5e2278d4f0cb2996efc89a6585266d15ae18cee3b4479a6111062bf4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x300000000000000040000000000000003bfb8bb91046b3f04c0f159ec0000002) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x300000000000000040000000000000003bfb8bb91046b3f04c0f159ec0000002) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xc83d113a5e2278d430cb2996efc89a657c94c6d6abc5909ccdfc4e25d1062bf3) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xc83d113a5e2278d430cb2996efc89a647c94c6d6abc5909ccdfc4e25d1062bf3) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xf0cb2996efc89a649a71d82f60a84f6c9e26742f8cfd5924a9d3556587761caa) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xf0cb2996efc89a649a71d82f60a84f6b9e26742f8cfd5924a9d3556587761caa) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xee885d759e2278d2f0cb2996efc89a669117053b29ad1718ff136f9e4e64ee41) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xee885d759e2278d2f0cb2996efc89a669117053b29ad1718ff136f9e4e64ee41) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xe64b4c3b3ffffffdc000000000000000f23ba568749a8d6097e9f08b7d5ec24c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xe64b4c3b3ffffffdc000000000000000f23ba568749a8d6097e9f08b7d5ec24c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x37c2eec5a1dd872acf34d6691037659a836b3929543a6f633203b1da2ef9d40c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x37c2eec5a1dd872acf34d6691037659a836b3929543a6f633203b1da2ef9d40c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x19b4b3c4c000000040000000000000000dc45a978b65729f68160f7482a13db4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x19b4b3c4c000000040000000000000000dc45a978b65729f68160f7482a13db4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3ffffffffffffffeffffffffffffffff992c350be41914ad34786d38fffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3ffffffffffffffeffffffffffffffff992c350be41914ad34786d38fffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2e2205637b9cb7182e2a67ec482ca60473e3e98d5208299d8a0dc4ad6b306e56) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x2e2205637b9cb7182e2a67ec482ca60473e3e98d5208299d8a0dc4ad6b306e56) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3a3218e73bd51d4ef4aa06f208123b1c1f4c629933d28586e20bbe23b2235110) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3a3218e73bd51d4ef4aa06f208123b1c1f4c629933d28586e20bbe23b2235110) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x264b4c3b3fffffffc00000000000000014823e647de7867c311721787d5ec24d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x264b4c3b3fffffffc00000000000000014823e647de7867c311721787d5ec24d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x264b4c3b3fffffffc00000000000000014823e647de7867d311721787d5ec24c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x264b4c3b3fffffffc00000000000000014823e647de7867d311721787d5ec24c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffffc00000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffffc00000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x264b4c3b3fffffffc00000000000000114823e647de7867b311721787d5ec24d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x264b4c3b3fffffffc00000000000000114823e647de7867b311721787d5ec24d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x264b4c3b3fffffff7ffffffffffffffff23ba568749a8d6097e9f08b7d5ec24c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x264b4c3b3fffffff7ffffffffffffffff23ba568749a8d6097e9f08b7d5ec24c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x00000000000000004000000000000000224698fc094cf91b992d30ed00000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x00000000000000004000000000000000224698fc094cf91b992d30ed00000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xe64b4c3b3ffffffebffffffffffffffff23ba568749a8d6097e9f08b7d5ec24c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xe64b4c3b3ffffffebffffffffffffffff23ba568749a8d6097e9f08b7d5ec24c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xbffffffffffffffeffffffffffffffffddb96703f6b306e366d2cf1300000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xbffffffffffffffeffffffffffffffffddb96703f6b306e366d2cf1300000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xe64b4c3b3ffffffdc000000000000000f23ba568749a8d6097e9f08b7d5ec24c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xe64b4c3b3ffffffdc000000000000000f23ba568749a8d6097e9f08b7d5ec24c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xbffffffffffffffe0000000000000000ddb96703f6b306e466d2cf12ffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0xbffffffffffffffe0000000000000000ddb96703f6b306e466d2cf12ffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x19b4b3c4c000000040000000000000000dc45a978b65729f68160f7482a13db4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x19b4b3c4c000000040000000000000000dc45a978b65729f68160f7482a13db4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589658) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589658) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0ed96497d1a6219029a6ae9870dfb50713cd52c155d255e973c0f7cb33ceb302) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0ed96497d1a6219029a6ae9870dfb50713cd52c155d255e973c0f7cb33ceb302) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x388013304285d697358022a45037659a43d08525ed8bafae6abb1c2bed362cc2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x388013304285d697358022a45037659a43d08525ed8bafae6abb1c2bed362cc2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0e0e3b00e1dd872a8f34d6691037659a6d153852c681be7ce3a2562a6c589658) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0e0e3b00e1dd872a8f34d6691037659a6d153852c681be7ce3a2562a6c589658) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02533e46e64b4c3b40000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02533e46e64b4c3b40000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589659) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589659) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0f34d6691037659a658e27d09f57b09361d98bd07302a6da562caa9a7889e357) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0f34d6691037659a658e27d09f57b09361d98bd07302a6da562caa9a7889e357) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x37c2eec5a1dd872acf34d6691037659a836b3929543a6f633203b1da2ef9d40c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x37c2eec5a1dd872acf34d6691037659a836b3929543a6f633203b1da2ef9d40c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x19b4b3c4c000000040000000000000000dc45a978b65729f68160f7482a13db4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x19b4b3c4c000000040000000000000000dc45a978b65729f68160f7482a13db4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000002) + pallasBaseModulus pallasBaseInv = + (Limbs.ofNat 0x21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59082) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3816347ba8ec65c05e21504ba093e4938b695660949353c7e0e8e1e21453ab35) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd072f7ea629353058c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x163784c749804a53cb80fc6f7faf20ec1633f1ba116751167e80c2b170a21433) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x10857622e89b86aca86f41a73faf20ec5327119569697cbac81b8c7b31e59082) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02652a376311bac840000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x371c0e53d3137a561429e3ed1dbe7811c2ffdda533172cebb2a7f9c727e0d817) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d97c561772695bd2dadabbb0f08d03b56bd2afbac9508560507cb1ee03ccf55) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2473c7bb10837eccbb207ca6f8db4fa2adc85c3d551040c82ad95da5f68d3953) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x35bdc74821d8c770c380105be46417165d290f24bcb0a284255d20860f98655d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x25ea051264f6374dacdf8cb0da3ef5e1f7f05de4a4e1dc32d723436978cfe238) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d85627c34d2eae5be810b80707f6b2b0298cf948bd293c575c04f6327c7fd37) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2c37a71489ba60888d0f36071632bdabf7abe57547cfa14c569bba29179df5c1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000891a63f02652a376311bac8400000004) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffff76e59c0fd9ad5c8a7a4550682fe74c4fbd6297a500000005) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x125b506bdf33f6aa5feb88c401333d642280770e64abaff06237590800000004) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x36e59c0fd9ad5c89cee4537bfffffffcefee2ee443109e0ed5f06de700000007) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x125b506bdf33f6aa5feb88c401333d64ab9adafe8afe53669353058c00000008) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2da4af9420cc0955a014773bfeccc29bffc621eda4e8f8ed2a0f9218fffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x20479a657a172f2bd053df0b7b5acf61f516940d35cc6f334c3e480121ca423e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x16fba5370a930060cff5e6c18f3efbc1986f687608a3b3fcf657e3356e1c9356) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x16a094a2dd10d63d2c60481914864a53c49d67e2fff2361ddc8141f24bcb8913) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2ac11d8d47008bf94cf18afe7fd17c31bea8fcfadd1b069daf58145a6c87f0c3) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x07945afd7e00a6ecaae30dbeb11ac138e9070a556c84c5f4aef2f319fb865fa2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0fea57e1d7583502228891684693b1965d038faf2fd53ebf2dc9e5ec41ca2ca0) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x038c4c2cb8c23f053299d52676a921b7dd1364fa0ac2fcf0fc84cc799aab7c2c) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2c37a71489ba60888d0f36071632bdabf7abe57547cfa14c569bba29179df5c1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x038c4c2cb8c23f053299d52676a921b7dd1364fa0ac2fcf0fc84cc799aab7c2c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3692be50833025568051dceffb330a6fba8b55be807a91f98fb07221fffffff2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3640e16087fd1ae6e300af3fd67183a566437c7da4492248e68449fe0cc0954c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x01f765e81b99e4b2223fb3b2e38572d8f84ef69436e904c98022d08709276b93) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x194190a05e6e9e8c2c35db5bf20b9edcb2b5763b2229611dd38eb15feccc29b0) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x388a24389eca0a08a29190a2deb87d48b2da4c52b76396c30fd342a909276b85) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3e089a17e4661b4dddc04c4d1c7a8d2729f7a267d2aba4140c241a99f6d8946e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x10e39b4454685a50cda5f68d7421d880290d079f1b2efeff5236de2f12b9584d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3b69e9ea6b3ef352ce65cb0486bf9ee41c235797a8223a9b07f2158afdc4df11) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x30ad74e124fe0fd490a54db31012ffb9eae004a5908bc2fa359cb7410d8e104d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x091036f343941ce36cbd9dae1bb6b5b9d052a05d8cf4c1e9768fce3835f5853b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x11a0830b593802f951f6f8fe756548c8d841da513ea0771876a98bb914291f34) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x015fc1fe4f6bc49f7f332185abed51d9d68235db8e6e529e7701dbe27fe1cd65) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59082) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59082) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000891a63f02652a376311bac8400000004) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3692be50833025568051dceffb330a6fba8b55be807a91f98fb07221fffffff2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x07e9cb8457139a3fa1deafb45f6c1b6c96dd429b75015515ab5e093eebac54cc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02652a376311bac840000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x29c87b38b67fb5ac347f03908050df140c12a741f82d57c70dc6286f8f5debce) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2f7a89dd176479535790be58c050df13cf1f8766a02b2c22c42b5ea5ce1a6f7f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd072f7ea629353058c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x08e3f1ac2cec85a9ebd61c12e24187ee5f46bb56d67d7bf1d99ef159d81f27ea) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x02683a9e88d96a42d2525444f0f72fc4cb896e005cffa087873f20021fc330ac) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1b8c3844ef7c813344df83590724b05d747e3cbeb4846815616d8d7b0972c6ae) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0a4238b7de27388f3c7fefa41b9be8e9c51d89d74ce4065966e9ca9af0679aa4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1a15faed9b09c8b25320734f25c10a1e2a563b1764b2ccaab523a7b787301dc9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x027a9d83cb2d151a417ef47f8f8094d51fadc9677dc2151816869bbdd83802ca) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x260b1bcff7a77ed30f3e5bd83e8757c543ee76f0fb69fb41d53cd52f47fabdcb) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3816347ba8ec65c05e21504ba093e4938b695660949353c7e0e8e1e21453ab35) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3816347ba8ec65c05e21504ba093e4938b695660949353c7e0e8e1e21453ab35) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffff76e59c0fd9ad5c8a7a4550682fe74c4fbd6297a500000005) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3640e16087fd1ae6e300af3fd67183a566437c7da4492248e68449fe0cc0954c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x07e9cb8457139a3fa1deafb45f6c1b6c96dd429b75015515ab5e093eebac54cc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x260b1bcff7a77ed30f3e5bd83e8757c543ee76f0fb69fb41d53cd52f47fabdcb) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02652a37a311bac840000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x354977a8362ed6983eccf4ec1f6c1b6cef2a2328b319ab393e3c3d23695cc27f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x17e9cb8457139a3fa1deafb45f6c1b6c9f6ee8da77667f4d4e6fc4072bac54cc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd072f7ea5e9353058c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1d0dd5994aaafdbb915247b038c80ae3ddd1f438869d7be1b3dfdbb28bd13e92) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3015e65997e23a7e0812ed29f00c525c12f01d43879cddb33c70d9084328d9b8) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x16acb4ebe857d0d5df2227b5ff215a2a8b94f780dddabc16e2473bfbc764cb7b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0dc24913c28b4fa57ce0e4e232d4db48921ea6321220eb845887d65769047ce1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x06f5879e7548be9436c2abeb5db509810c5d405277106fec6a6b9256f3574092) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x00fba9043bac804523250acf5718e5fa5f27a4762881d669ede2565604ec5733) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd072f7ea629353058c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd072f7ea629353058c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x125b506bdf33f6aa5feb88c401333d642280770e64abaff06237590800000004) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x01f765e81b99e4b2223fb3b2e38572d8f84ef69436e904c98022d08709276b93) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02652a376311bac840000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02652a37a311bac840000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000004891a63f02652a376311bac840000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x200000000000000000000000000000000891a63f02652a376311bac840000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x30000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1f0f0f09f84f08783843fdf0cf348dc097a0b54e3ab432b63220c4af784f0e97) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3b5460f6403423b40d9318fd6638bebd8e6eef198b2949116d2a3efe647edda2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x08a3454c5f8ed6682cc97fccfbfe6debb4b8745fecf3f0e50dfb5b6dd8bafe75) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x352c1aa827cc3842bae5326c6b8c0507b63abda4f56ddff1305ffaa8e03ae083) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x049a2bd27b9b331284522c7cbc8a91687e2221820bee830d4de6a0df5e838533) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x02bf53bdc23a2a747c90e3e3ed389e5d8e77d8428bb6a45fe99705d8bcb3fbfa) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x34166c94559af205116d48c84050df1451976d5c5294ada2ba72ad0190a1681e) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x163784c749804a53cb80fc6f7faf20ec1633f1ba116751167e80c2b170a21433) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x163784c749804a53cb80fc6f7faf20ec1633f1ba116751167e80c2b170a21433) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x36e59c0fd9ad5c89cee4537bfffffffcefee2ee443109e0ed5f06de700000007) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x194190a05e6e9e8c2c35db5bf20b9edcb2b5763b2229611dd38eb15feccc29b0) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x29c87b38b67fb5ac347f03908050df140c12a741f82d57c70dc6286f8f5debce) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x354977a8362ed6983eccf4ec1f6c1b6cef2a2328b319ab393e3c3d23695cc27f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000004891a63f02652a376311bac840000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x34166c94559af205116d48c84050df1451976d5c5294ada2ba72ad0190a1681e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x39c87b38b67fb5ac347f03908050df1454a44d80fa9281fe70d7e337cf5debce) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2fffffffffffffffffffffffffffffffd9b4f2bd072f7ea629353058c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2e601d498373089f5f94d5da69f27957ef96481487e5a7b736bd369f612547a4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3828d38387ee8cda01425d288c785223d5a48e3759503d09e2dc6ea9e39fefc0) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x35cedca1e7792b005e925c002e69b1e8a51bb0eb0cdf91d049b1dd1526058824) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0aa32df5f5602aee07a126de3b6108679a01e1b4e89c2dc62431eeb25ed73e4b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3db83389d2fdc8153f65cf02c73d84eb4fd4670fd63dec9e876bbf8d1e344642) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2420b3d392c5663f81c5e7e0d2cc98db3cb0725047f4d0c9828c32b1163a561f) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0f7a89dd176479535790be58c050df13b56a94a998fbad7c9af62e4d0e1a6f7e) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x10857622e89b86aca86f41a73faf20ec5327119569697cbac81b8c7b31e59082) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x10857622e89b86aca86f41a73faf20ec5327119569697cbac81b8c7b31e59082) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x125b506bdf33f6aa5feb88c401333d64ab9adafe8afe53669353058c00000008) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x388a24389eca0a08a29190a2deb87d48b2da4c52b76396c30fd342a909276b85) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2f7a89dd176479535790be58c050df13cf1f8766a02b2c22c42b5ea5ce1a6f7f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x17e9cb8457139a3fa1deafb45f6c1b6c9f6ee8da77667f4d4e6fc4072bac54cc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x200000000000000000000000000000000891a63f02652a376311bac840000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x39c87b38b67fb5ac347f03908050df1454a44d80fa9281fe70d7e337cf5debce) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0f7a89dd176479535790be58c050df13b56a94a998fbad7c9af62e4d0e1a6f7e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2000000000000000000000000000000019b4f2bd072f7ea629353058c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x27f300b6253b8e22241a1a03b17615aef6e770a51131aea80bbfb609506e3681) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3dbc9b94c90d8df6dfe56d42572fee8259f85d19e828e998f4695f0084420e4e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x242f7d914f0b579b71a9032603231e492936b11ea17858fa6f68e8e8e22dc523) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3f6e536005f370d1f76522108727edf17b58477c4251e64a9749c543d0a27b27) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1eb026c016a4fbc4d7729fcbe24b9b86a8785c9970a14fb8030a4896e5b3a2fc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0539f1418d673f8ebe0fd8637cb93332ae25a1aa0978b978001da19694ebfec4) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02652a376311bac840000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02652a376311bac840000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2da4af9420cc0955a014773bfeccc29bffc621eda4e8f8ed2a0f9218fffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3e089a17e4661b4dddc04c4d1c7a8d2729f7a267d2aba4140c241a99f6d8946e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd072f7ea629353058c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd072f7ea5e9353058c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x30000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2fffffffffffffffffffffffffffffffd9b4f2bd072f7ea629353058c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2000000000000000000000000000000019b4f2bd072f7ea629353058c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x20f0f0f607b0f787c7bc020f30cb723f8aa5e3adcee076275a26267187b0f16a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x04ab9f09bfcbdc4bf26ce70299c7414293d7a9e27e6b5fcc1f1cac229b81225f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x375cbab3a0712997d3368033040192146d8e249c1ca0b7f87e4b8fb32745018c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0ad3e557d833c7bd451acd939473faf86c0bdb571426c8ec5be6f0781fc51f7e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3b65d42d8464cced7badd38343756e97a4247779fda625d03e604a41a17c7ace) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d40ac423dc5d58b836f1c1c12c761a293cec0b97dde047da2afe548434c0407) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3c826e4b14082aff58fa381b66ebb31ffc424a9827324372300385a712a3af71) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x371c0e53d3137a561429e3ed1dbe7811c2ffdda533172cebb2a7f9c727e0d817) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x371c0e53d3137a561429e3ed1dbe7811c2ffdda533172cebb2a7f9c727e0d817) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x20479a657a172f2bd053df0b7b5acf61f516940d35cc6f334c3e480121ca423e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x10e39b4454685a50cda5f68d7421d880290d079f1b2efeff5236de2f12b9584d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x08e3f1ac2cec85a9ebd61c12e24187ee5f46bb56d67d7bf1d99ef159d81f27ea) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1d0dd5994aaafdbb915247b038c80ae3ddd1f438869d7be1b3dfdbb28bd13e92) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1f0f0f09f84f08783843fdf0cf348dc097a0b54e3ab432b63220c4af784f0e97) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2e601d498373089f5f94d5da69f27957ef96481487e5a7b736bd369f612547a4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x27f300b6253b8e22241a1a03b17615aef6e770a51131aea80bbfb609506e3681) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x20f0f0f607b0f787c7bc020f30cb723f8aa5e3adcee076275a26267187b0f16a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3c826e4b14082aff58fa381b66ebb31ffc424a9827324372300385a712a3af71) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1cc98a7c4a2f2d1577731209ca0bb4345acf26d96e40b1a3621c4b697c1f89a7) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3af6ee59b3b4c38b0c54be9896161e88bd2a6b3048071d6589bd19dad1f26ffb) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1abad769c6cbad4123a911553b6e7852138fc045cf42b1fb85534fd5c8b7cddd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0ee9cb3f0c351f50055b7dd7ae3544e2a01c48185ebf81b388f231fab7cab006) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d32c8fb7d3d545107b4a69a4c5b2e75eab93d6f80b3cd86eee20d43663e5339) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x071895d90ab40b08c4b42617ac1cdd5513304a1aff12e439c017aaa5c9466628) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d97c561772695bd2dadabbb0f08d03b56bd2afbac9508560507cb1ee03ccf55) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d97c561772695bd2dadabbb0f08d03b56bd2afbac9508560507cb1ee03ccf55) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x16fba5370a930060cff5e6c18f3efbc1986f687608a3b3fcf657e3356e1c9356) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3b69e9ea6b3ef352ce65cb0486bf9ee41c235797a8223a9b07f2158afdc4df11) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x02683a9e88d96a42d2525444f0f72fc4cb896e005cffa087873f20021fc330ac) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3015e65997e23a7e0812ed29f00c525c12f01d43879cddb33c70d9084328d9b8) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3b5460f6403423b40d9318fd6638bebd8e6eef198b2949116d2a3efe647edda2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3828d38387ee8cda01425d288c785223d5a48e3759503d09e2dc6ea9e39fefc0) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3dbc9b94c90d8df6dfe56d42572fee8259f85d19e828e998f4695f0084420e4e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x04ab9f09bfcbdc4bf26ce70299c7414293d7a9e27e6b5fcc1f1cac229b81225f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1cc98a7c4a2f2d1577731209ca0bb4345acf26d96e40b1a3621c4b697c1f89a7) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x071895d90ab40b08c4b42617ac1cdd5513304a1aff12e439c017aaa5c9466628) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x246419a4981faaddc27e8d0019c448456fd856014fa4b0db941ae20af878ac3a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3b6909a05dbf22befee2b044abcd8be253ec04353872409056b582ed8ab676e9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x193b8747b4746b70f877067f44e731bdfa6932f2e629d4909748eb6234c0a751) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0209da84c6f912d00000b696ba1b54f5ca8ef4ab4e7d28f5b128d1b75aa555cb) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x28435f86f478c99d44fc0ad902afe026c9368241bbf2fd91c20583bd78c314ef) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2473c7bb10837eccbb207ca6f8db4fa2adc85c3d551040c82ad95da5f68d3953) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2473c7bb10837eccbb207ca6f8db4fa2adc85c3d551040c82ad95da5f68d3953) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x16a094a2dd10d63d2c60481914864a53c49d67e2fff2361ddc8141f24bcb8913) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x30ad74e124fe0fd490a54db31012ffb9eae004a5908bc2fa359cb7410d8e104d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1b8c3844ef7c813344df83590724b05d747e3cbeb4846815616d8d7b0972c6ae) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x16acb4ebe857d0d5df2227b5ff215a2a8b94f780dddabc16e2473bfbc764cb7b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x08a3454c5f8ed6682cc97fccfbfe6debb4b8745fecf3f0e50dfb5b6dd8bafe75) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x35cedca1e7792b005e925c002e69b1e8a51bb0eb0cdf91d049b1dd1526058824) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x242f7d914f0b579b71a9032603231e492936b11ea17858fa6f68e8e8e22dc523) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x375cbab3a0712997d3368033040192146d8e249c1ca0b7f87e4b8fb32745018c) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3af6ee59b3b4c38b0c54be9896161e88bd2a6b3048071d6589bd19dad1f26ffb) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x246419a4981faaddc27e8d0019c448456fd856014fa4b0db941ae20af878ac3a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x28435f86f478c99d44fc0ad902afe026c9368241bbf2fd91c20583bd78c314ef) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3f744b5a1aea28e70d8ad46f3327904a134f8a4051fd9dfa111fd1f5d5c938c9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x03efd48ce6c15c4f257ad17a20e64d1c1a6215ad1e97f54e0f7e2ce750c5441a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3eb73a2da6c346e9eefbb70091ae4f358ab2d0eef6bed877e8232e30747a4648) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d5449b2fe7e68a890240a11344fe522edcaea8796292af2d0d8fb99b79db040) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x35bdc74821d8c770c380105be46417165d290f24bcb0a284255d20860f98655d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x35bdc74821d8c770c380105be46417165d290f24bcb0a284255d20860f98655d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2ac11d8d47008bf94cf18afe7fd17c31bea8fcfadd1b069daf58145a6c87f0c3) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x091036f343941ce36cbd9dae1bb6b5b9d052a05d8cf4c1e9768fce3835f5853b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0a4238b7de27388f3c7fefa41b9be8e9c51d89d74ce4065966e9ca9af0679aa4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0dc24913c28b4fa57ce0e4e232d4db48921ea6321220eb845887d65769047ce1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x352c1aa827cc3842bae5326c6b8c0507b63abda4f56ddff1305ffaa8e03ae083) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0aa32df5f5602aee07a126de3b6108679a01e1b4e89c2dc62431eeb25ed73e4b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3f6e536005f370d1f76522108727edf17b58477c4251e64a9749c543d0a27b27) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0ad3e557d833c7bd451acd939473faf86c0bdb571426c8ec5be6f0781fc51f7e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1abad769c6cbad4123a911553b6e7852138fc045cf42b1fb85534fd5c8b7cddd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3b6909a05dbf22befee2b044abcd8be253ec04353872409056b582ed8ab676e9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3f744b5a1aea28e70d8ad46f3327904a134f8a4051fd9dfa111fd1f5d5c938c9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d5449b2fe7e68a890240a11344fe522edcaea8796292af2d0d8fb99b79db040) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3b3fabae42dffc45164e657541c6b93696e8f3fcdfb4760f33ce254e2256c55b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2d7db430e8803ea69f052e2842768f1b94f4de6d72a0fd3c4daac60d51d4d068) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x04a79fe0cdfaa798f1a3dd8da208e41b79987431a7264d941832206dceae62b2) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x25ea051264f6374dacdf8cb0da3ef5e1f7f05de4a4e1dc32d723436978cfe238) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x25ea051264f6374dacdf8cb0da3ef5e1f7f05de4a4e1dc32d723436978cfe238) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x07945afd7e00a6ecaae30dbeb11ac138e9070a556c84c5f4aef2f319fb865fa2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x11a0830b593802f951f6f8fe756548c8d841da513ea0771876a98bb914291f34) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1a15faed9b09c8b25320734f25c10a1e2a563b1764b2ccaab523a7b787301dc9) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x06f5879e7548be9436c2abeb5db509810c5d405277106fec6a6b9256f3574092) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x049a2bd27b9b331284522c7cbc8a91687e2221820bee830d4de6a0df5e838533) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3db83389d2fdc8153f65cf02c73d84eb4fd4670fd63dec9e876bbf8d1e344642) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1eb026c016a4fbc4d7729fcbe24b9b86a8785c9970a14fb8030a4896e5b3a2fc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3b65d42d8464cced7badd38343756e97a4247779fda625d03e604a41a17c7ace) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0ee9cb3f0c351f50055b7dd7ae3544e2a01c48185ebf81b388f231fab7cab006) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x193b8747b4746b70f877067f44e731bdfa6932f2e629d4909748eb6234c0a751) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x03efd48ce6c15c4f257ad17a20e64d1c1a6215ad1e97f54e0f7e2ce750c5441a) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3b3fabae42dffc45164e657541c6b93696e8f3fcdfb4760f33ce254e2256c55b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x04a79fe0cdfaa798f1a3dd8da208e41b79987431a7264d941832206dceae62b2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fbc4473858d96888a4cf4f26122be6d5452e97f2372b0740ea8da1591130845) := by + decide +kernel + +example : + sqrMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3e0a34d529799ca3bb2cd3d706454717da0139fab7c3ec1918efdc79a0f7527f) := by + decide +kernel + +example : + fromMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d85627c34d2eae5be810b80707f6b2b0298cf948bd293c575c04f6327c7fd37) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d85627c34d2eae5be810b80707f6b2b0298cf948bd293c575c04f6327c7fd37) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0fea57e1d7583502228891684693b1965d038faf2fd53ebf2dc9e5ec41ca2ca0) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x015fc1fe4f6bc49f7f332185abed51d9d68235db8e6e529e7701dbe27fe1cd65) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x027a9d83cb2d151a417ef47f8f8094d51fadc9677dc2151816869bbdd83802ca) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x00fba9043bac804523250acf5718e5fa5f27a4762881d669ede2565604ec5733) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x02bf53bdc23a2a747c90e3e3ed389e5d8e77d8428bb6a45fe99705d8bcb3fbfa) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2420b3d392c5663f81c5e7e0d2cc98db3cb0725047f4d0c9828c32b1163a561f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0539f1418d673f8ebe0fd8637cb93332ae25a1aa0978b978001da19694ebfec4) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d40ac423dc5d58b836f1c1c12c761a293cec0b97dde047da2afe548434c0407) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d32c8fb7d3d545107b4a69a4c5b2e75eab93d6f80b3cd86eee20d43663e5339) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0209da84c6f912d00000b696ba1b54f5ca8ef4ab4e7d28f5b128d1b75aa555cb) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3eb73a2da6c346e9eefbb70091ae4f358ab2d0eef6bed877e8232e30747a4648) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2d7db430e8803ea69f052e2842768f1b94f4de6d72a0fd3c4daac60d51d4d068) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fbc4473858d96888a4cf4f26122be6d5452e97f2372b0740ea8da1591130845) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + (Limbs.ofNat 0x0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3e0a34d529799ca3bb2cd3d706454717da0139fab7c3ec1918efdc79a0f7527f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59083) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59083) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3ffffffffffffffeffffffffffffffff992c350be34205675b2b3e9cfffffffc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf590f0d5a72daf6cba5a2db2258300000013) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf590f0d5a72daf6cba5a2db2258300000013) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3e7055f0f197b81f0950abbb8948d5d39bc7300f5c1ea51f903bb43e249dae3e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3e7055f0f197b81f0950abbb8948d5d39bc7300f5c1ea51f903bb43e249dae3e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x07e9cb8457139a3fa1deafb45f6c1b6c96dd429b75015516ab5e093eebac54cb) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x07e9cb8457139a3fa1deafb45f6c1b6c96dd429b75015516ab5e093eebac54cb) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0fffffffffffffffffffffffffffffffe64b0d42f8d08159d6cacfa73fffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0fffffffffffffffffffffffffffffffe64b0d42f8d08159d6cacfa73fffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x29c87b38b67fb5ac347f03908050df140c12a741f82d57c70dc6286f8f5debcd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x29c87b38b67fb5ac347f03908050df150c12a741f82d57c70dc6286f8f5debcd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2f7a89dd176479535790be58c050df12acd8ee6a9696834537e47384ce1a6f7d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2f7a89dd176479535790be58c050df13acd8ee6a9696834537e47384ce1a6f7d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x300000000000000000000000000000003bfb8bb910c42783b57c1b79c0000002) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x300000000000000000000000000000003bfb8bb910c42783b57c1b79c0000002) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1f7a89dd176479535790be58c050df12c68de1279dc601eb6119a3dd8e1a6f7d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1f7a89dd176479535790be58c050df12c68de1279dc601eb6119a3dd8e1a6f7d) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xd790be58c050df12b5b20ea460e4c3a70d6a05901f3003f72974af7da26e1ab1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1790be58c050df13b5b20ea460e4c3a62fb09e8c28c4acd4b5bb9a9ea26e1ab2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xc28c44a5576479521790be58c050df1294c8c9a26e4db0782ebd7cee0a8760df) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xc28c44a5576479521790be58c050df1394c8c9a26e4db0782ebd7cee0a8760df) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xe311bac83ffffffebffffffffffffffff0818176da1c576a59eac4317c6cf162) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xe311bac83ffffffebffffffffffffffff0818176da1c576a59eac4317c6cf162) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59083) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59083) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x286f41a73faf20ec4a4df15b9f1b3c58f295fa6fe0cffc07d68b50825d91e54f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x286f41a73faf20ec4a4df15b9f1b3c58f295fa6fe0cffc07d68b50825d91e54f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3ffffffffffffffeffffffffffffffff992c350be34205665b2b3e9cfffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205665b2b3e9cfffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x096d41af7ccfdaaa08c887002b1f990698d6efc1891a16e7fc9678ff0000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x096d41af7ccfdaaa08c887002b1f990698d6efc1891a16e7fc9678ff0000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x082f7490699a9d38264ffc7bb2d7522e3583b391b7d582d6a9b76a4017dd18f2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x082f7490699a9d38264ffc7bb2d7522e3583b391b7d582d6a9b76a4017dd18f2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1790be58c050df13b5b20ea460e4c3a72fb09e8c28c4acd5b5bb9a9ea26e1ab2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1790be58c050df13b5b20ea460e4c3a72fb09e8c28c4acd5b5bb9a9ea26e1ab2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x21deafb45f6c1b6c92a053dc20e4c3a7753564a6832c02b262681f30a3b19701) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x21deafb45f6c1b6c92a053dc20e4c3a7753564a6832c02b262681f30a3b19701) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffc000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffc000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x347f03908050df13f5b20ea460e4c3a73f2f1d154ea8556b5bd0d66d2601294f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x347f03908050df13f5b20ea460e4c3a83f2f1d154ea8556b5bd0d66d2601294f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1790be58c050df13b5b20ea460e4c3a60d6a05901f3003f7e974af7da26e1ab1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1790be58c050df13b5b20ea460e4c3a70d6a05901f3003f7e974af7da26e1ab1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8ddcc46eb2100000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8ddcc46eb2100000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1790be58c050df13b5b20ea460e4c3a62fb09e8c28c4acd4b5bb9a9ea26e1ab2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xd790be58c050df12b5b20ea460e4c3a70d6a05901f3003f72974af7da26e1ab1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xf5b20ea460e4c3a62311bac83fffffffba7b39e5a598aa2253537b6dfebc83b1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xf5b20ea460e4c3a62311bac83fffffffba7b39e5a598aa2253537b6dfebc83b1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xd790be58c050df12b5b20ea460e4c3a60d6a05901f3003f72974af7da26e1ab2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xd790be58c050df12b5b20ea460e4c3a70d6a05901f3003f72974af7da26e1ab2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xbffffffffffffffeffffffffffffffffddb96703f66b572173b914df00000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xbffffffffffffffeffffffffffffffffddb96703f66b572173b914df00000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x286f41a73faf20ec4a4df15b9f1b3c58f295fa6fe0cffc07d68b50825d91e54f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x286f41a73faf20ec4a4df15b9f1b3c58f295fa6fe0cffc07d68b50825d91e54f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d73bb5aa89b86ace86f41a73faf20ec6b37365d91b24f87d1428311f5789f20) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d73bb5aa89b86ace86f41a73faf20ec6b37365d91b24f87d1428311f5789f20) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3ffffffffffffffeffffffffffffffff992c350be34205675b2b3e9cfffffffc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3ffffffffffffffeffffffffffffffff992c350be34205675b2b3e9cfffffffc) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3a88ee337ccfdaad3640e16087fd1ae78b74636b990a825fed6704ea66b5723b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3a88ee337ccfdaad3640e16087fd1ae78b74636b990a825fed6704ea66b5723b) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x128c5784fabf23b20173141b1ae1430afb46d7d1d84397cf26c1ef1391979314) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x128c5784fabf23b20173141b1ae1430afb46d7d1d84397cf26c1ef1391979314) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x028c44a5576479531790be58c050df13b70f629e77e25955bb04680f0a8760e1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x028c44a5576479531790be58c050df13b70f629e77e25955bb04680f0a8760e1) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2afb864c97139a3f61deafb45f6c1b6ca9a55d0e58b2555e918fb8916819462e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2afb864c97139a3f61deafb45f6c1b6ca9a55d0e58b2555e918fb8916819462e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0fffffffffffffffbfffffffffffffffe64b0d42f8d08159d6cacfa73fffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0fffffffffffffffbfffffffffffffffe64b0d42f8d08159d6cacfa73fffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0cda3600f67fb5abf47f03908050df14fc9428b8d249af3067b0eca10bcadd30) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0cda3600f67fb5abf47f03908050df14fc9428b8d249af3067b0eca10bcadd30) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x128c44a557647952d790be58c050df139d5a6fe170b2daaf91cf37b64a8760e0) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x128c44a557647952d790be58c050df139d5a6fe170b2daaf91cf37b64a8760e0) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x300000000000000040000000000000003bfb8bb910c42783b57c1b79c0000002) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x300000000000000040000000000000003bfb8bb910c42783b57c1b79c0000002) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xc28c44a5576479521790be58c050df1394c8c9a26e4db0782ebd7cee0a8760df) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xc28c44a5576479521790be58c050df1294c8c9a26e4db0782ebd7cee0a8760df) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xd790be58c050df12b5b20ea460e4c3a70d6a05901f3003f72974af7da26e1ab2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xd790be58c050df12b5b20ea460e4c3a60d6a05901f3003f72974af7da26e1ab2) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xe59dff6d97647950d790be58c050df14a790e41551feb0c014ef2c4086f45243) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xe59dff6d97647950d790be58c050df14a790e41551feb0c014ef2c4086f45243) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xe311bac83ffffffdc000000000000000f0818176da1c576a59eac4317c6cf162) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xe311bac83ffffffdc000000000000000f0818176da1c576a59eac4317c6cf162) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d73bb5aa89b86ace86f41a73faf20ec6b37365d91b24f87d1428311f5789f20) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d73bb5aa89b86ace86f41a73faf20ec6b37365d91b24f87d1428311f5789f20) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1cee4537c000000040000000000000000f7e7e8925e3a895a6153bce83930e9e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1cee4537c000000040000000000000000f7e7e8925e3a895a6153bce83930e9e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3ffffffffffffffeffffffffffffffff992c350be34205675b2b3e9cfffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3ffffffffffffffeffffffffffffffff992c350be34205675b2b3e9cfffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3a88ee337ccfdaad3640e16087fd1ae70259ff7b72b7dee9bc4b586666b57237) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3a88ee337ccfdaad3640e16087fd1ae70259ff7b72b7dee9bc4b586666b57237) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1bf99934778efe5b8121372b1fae389b63021b0f615daeb32358681291979323) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1bf99934778efe5b8121372b1fae389b63021b0f615daeb32358681291979323) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2311bac83fffffffc00000000000000012c81a72e3b10047e631af527c6cf163) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2311bac83fffffffc00000000000000012c81a72e3b10047e631af527c6cf163) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2311bac83fffffffc00000000000000012c81a72e3b10048e631af527c6cf162) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2311bac83fffffffc00000000000000012c81a72e3b10048e631af527c6cf162) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffffc00000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffffc00000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2311bac83fffffffc00000000000000112c81a72e3b10046e631af527c6cf163) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2311bac83fffffffc00000000000000112c81a72e3b10046e631af527c6cf163) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2311bac83fffffff7ffffffffffffffff0818176da1c576a59eac4317c6cf162) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x2311bac83fffffff7ffffffffffffffff0818176da1c576a59eac4317c6cf162) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x00000000000000004000000000000000224698fc0994a8dd8c46eb2100000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x00000000000000004000000000000000224698fc0994a8dd8c46eb2100000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xe311bac83ffffffebffffffffffffffff0818176da1c576a59eac4317c6cf162) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xe311bac83ffffffebffffffffffffffff0818176da1c576a59eac4317c6cf162) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xbffffffffffffffeffffffffffffffffddb96703f66b572173b914df00000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xbffffffffffffffeffffffffffffffffddb96703f66b572173b914df00000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xe311bac83ffffffdc000000000000000f0818176da1c576a59eac4317c6cf162) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xe311bac83ffffffdc000000000000000f0818176da1c576a59eac4317c6cf162) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xbffffffffffffffe0000000000000000ddb96703f66b572273b914deffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0xbffffffffffffffe0000000000000000ddb96703f66b572273b914deffffffff) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1cee4537c000000040000000000000000f7e7e8925e3a895a6153bce83930e9e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1cee4537c000000040000000000000000f7e7e8925e3a895a6153bce83930e9e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59082) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59082) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3816347ba8ec65c05e21504ba093e4938b695660949353c7e0e8e1e21453ab35) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x000000000000000000000000000000000000000000000000ffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3816347ba8ec65c05e21504ba093e4938b695660949353c7e0e8e1e21453ab35) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd072f7ea629353058c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x4000000000000000000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3000000000000000000000000000000019b4f2bd072f7ea629353058c0000001) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x163784c749804a53cb80fc6f7faf20ec1633f1ba116751167e80c2b170a21433) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x163784c749804a53cb80fc6f7faf20ec1633f1ba116751167e80c2b170a21433) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x10857622e89b86aca86f41a73faf20ec5327119569697cbac81b8c7b31e59082) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x10857622e89b86aca86f41a73faf20ec5327119569697cbac81b8c7b31e59082) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02652a376311bac840000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x100000000000000000000000000000000891a63f02652a376311bac840000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59083) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59083) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x286f41a73faf20ec4a4df15b9f1b3c58f295fa6fe0cffc07d68b50825d91e54f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x286f41a73faf20ec4a4df15b9f1b3c58f295fa6fe0cffc07d68b50825d91e54f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d73bb5aa89b86ace86f41a73faf20ec6b37365d91b24f87d1428311f5789f20) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xfffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x3d73bb5aa89b86ace86f41a73faf20ec6b37365d91b24f87d1428311f5789f20) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1cee4537c000000040000000000000000f7e7e8925e3a895a6153bce83930e9e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0xffffffffffffffff000000000000000000000000000000000000000000000000) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1cee4537c000000040000000000000000f7e7e8925e3a895a6153bce83930e9e) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x0000000000000000000000000000000000000000000000000000000000000000) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f) := by + decide +kernel + +example : + mulMont + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + (Limbs.ofNat 0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002) + vestaBaseModulus vestaBaseInv = + (Limbs.ofNat 0x1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f) := by + decide +kernel + + +-- 1052 vectors. + +end CompElliptic.Asm.AArch64 diff --git a/CompElliptic/Asm/AArch64/Semantics.lean b/CompElliptic/Asm/AArch64/Semantics.lean new file mode 100644 index 0000000..c67b3f2 --- /dev/null +++ b/CompElliptic/Asm/AArch64/Semantics.lean @@ -0,0 +1,84 @@ +/- +Copyright (c) 2026 CompElliptic Contributors. +Released under the Apache License, Version 2.0, or the MIT license, at your option, +as described in the files LICENSE-APACHE and LICENSE-MIT. +Authors: Daira-Emma Hopwood +-/ + +/-! +# AArch64 instruction semantics for the Pasta Montgomery routines + +The subset of AArch64 that `pasta_mul-armv8.S` uses: `mul`, `umulh`, `adds`/`adcs`/`adc`, +`subs`/`sbcs`, `lsl`/`lsr` by an immediate, `csel` on the `lo` condition, and `mov`. Loads and +stores are not modelled as memory operations: the generated programs read their operand limbs +where the assembly loads them and return the limbs the assembly stores. + +A register value is a natural number below `2^64`. The bound is maintained by construction: +every instruction reduces its result modulo `2^64`, and the carry flag is the quotient of the +same sum by `2^64`, so it is `0` or `1` whenever the inputs are in range. Working in `Nat` +rather than a fixed-width type keeps the proofs in `omega`'s fragment (`%` and `/` by +literals) and lets the reference vectors be checked by the kernel with `decide`. + +AArch64's carry convention for subtraction is the one modelled here: after `subs`/`sbcs` the +carry is set exactly when no borrow occurred, so `sbcs` subtracts `1 - carry` and `subs` +behaves as `sbcs` with the carry set. The `lo` condition of `csel` is "carry clear". +-/ + +namespace CompElliptic.Asm.AArch64 + +/-- The register width, as the modulus of every register write. -/ +abbrev regMod : Nat := 2^64 + +/-- `mul`: the low 64 bits of the product. -/ +def mulLo (a b : Nat) : Nat := a * b % regMod + +/-- `umulh`: the high 64 bits of the product. -/ +def umulh (a b : Nat) : Nat := a * b / regMod + +/-- `adds`, `adcs`, and `adc`: the low 64 bits of `a + b + c` and the carry-out. `adds` passes +carry-in `0`; `adc` discards the carry-out. -/ +def addc (a b c : Nat) : Nat × Nat := ((a + b + c) % regMod, (a + b + c) / regMod) + +/-- `subs` and `sbcs`: the low 64 bits of `a - b - (1 - c)` and the carry-out, where a carry of +`1` means that no borrow occurred. `subs` passes carry-in `1`. The difference is formed as +`a + 2^64 - b - (1 - c)`, which is nonnegative for in-range operands, so the quotient by `2^64` +is `1` exactly when `a ≥ b + (1 - c)`. -/ +def subc (a b c : Nat) : Nat × Nat := + ((a + regMod - b - (1 - c)) % regMod, (a + regMod - b - (1 - c)) / regMod) + +/-- `lsl` by an immediate. -/ +def lsl (a k : Nat) : Nat := a * 2^k % regMod + +/-- `lsr` by an immediate. -/ +def lsr (a k : Nat) : Nat := a / 2^k + +/-- `csel d, x, y, lo`: `x` when the carry is clear, else `y`. -/ +def cselLo (c x y : Nat) : Nat := if c = 0 then x else y + +/-- Four little-endian 64-bit limbs, the shape of every operand of the routines. -/ +structure Limbs where + /-- Limb of weight `2^0`. -/ + l0 : Nat + /-- Limb of weight `2^64`. -/ + l1 : Nat + /-- Limb of weight `2^128`. -/ + l2 : Nat + /-- Limb of weight `2^192`. -/ + l3 : Nat + deriving DecidableEq, Repr + +namespace Limbs + +/-- The integer that a limb vector represents. -/ +def toNat (x : Limbs) : Nat := x.l0 + 2^64 * x.l1 + 2^128 * x.l2 + 2^192 * x.l3 + +/-- The limbs of a natural number; bits at and above `2^256` are dropped. -/ +def ofNat (n : Nat) : Limbs := + ⟨n % 2^64, n / 2^64 % 2^64, n / 2^128 % 2^64, n / 2^192 % 2^64⟩ + +/-- Every limb is below `2^64`. -/ +def Bounded (x : Limbs) : Prop := x.l0 < 2^64 ∧ x.l1 < 2^64 ∧ x.l2 < 2^64 ∧ x.l3 < 2^64 + +end Limbs + +end CompElliptic.Asm.AArch64 diff --git a/CompElliptic/Asm/AArch64/vendor/SHA256SUMS b/CompElliptic/Asm/AArch64/vendor/SHA256SUMS new file mode 100644 index 0000000..629d149 --- /dev/null +++ b/CompElliptic/Asm/AArch64/vendor/SHA256SUMS @@ -0,0 +1,2 @@ +0bcd5fa67d4aef5043eb536fdefd41ce16e6f7fbac3e5e6ac4f7619b35fd5e85 pasta_mul-armv8.S +4c82813b609fe04a195fcfc6dfaf0ee0396f8dd579f568b9e418a20f0a8dfae8 pasta_mul-armv8-vectors.txt diff --git a/CompElliptic/Asm/AArch64/vendor/pasta_mul-armv8-vectors.txt b/CompElliptic/Asm/AArch64/vendor/pasta_mul-armv8-vectors.txt new file mode 100644 index 0000000..cda570f --- /dev/null +++ b/CompElliptic/Asm/AArch64/vendor/pasta_mul-armv8-vectors.txt @@ -0,0 +1,1052 @@ +FROM Fp 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000ffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 4000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0000000000000000000000000000000000000000000000000000000000000000 +SQR Fp 0000000000000000000000000000000000000000000000000000000000000001 21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9 +FROM Fp 0000000000000000000000000000000000000000000000000000000000000001 21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000001 21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 0000000000000000000000000000000000000000000000000000000000000001 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589658 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 000000000000000000000000000000000000000000000000ffffffffffffffff 0ed96497d1a6219029a6ae9870dfb50713cd52c155d255e973c0f7cb33ceb302 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 4000000000000000000000000000000000000000000000000000000000000000 3000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 388013304285d697358022a45037659a43d08525ed8bafae6abb1c2bed362cc2 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0e0e3b00e1dd872a8f34d6691037659a6d153852c681be7ce3a2562a6c589658 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 100000000000000000000000000000000891a63f02533e46e64b4c3b40000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 38a026e0c48e71f73ae41fe20afd7333e0aa9a82f9f1a38bd4422d02de3d4125 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 057f2b054a45df575e9e6a328d598a1a2bd9ec5993f125a8b1efd019b9ccd6d0 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 23d1b7add4cc7721af5216f2e0da32ec8835dbecf358fccdf19780a4b1d41685 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 336bd3ea8db1d5ac64f8300ae87e52a81e5b765b2faa215d8dfb1b0d25b6b271 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 1b13887e1a1429f16e4161a915c9cb2099813c8a1d8cc439f2f1f0773efd541d +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0417a27f9647ed737c71f702e127cf999f5644b7dd769aac7d70f04b3ca33a4f +SQR Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd +FROM Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 0000000000000000000000000000000000000000000000000000000000000001 +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000001 +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 000000000000000000000000000000000000000000000000ffffffffffffffff 000000000000000000000000000000000000000000000000ffffffffffffffff +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 4000000000000000000000000000000000000000000000000000000000000000 4000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 00000000000000000000000000000000ffffffffffffffffffffffffffffffff +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 +SQR Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 +FROM Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 0000000000000000000000000000000000000000000000000000000000000001 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 21cce888a6cab566710d6cd04c692c9784379b4cc10e927b1dfc65f6ad0492ae +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 00000000000000000000000000000000891a63f02533e46e64b4c3b400000004 +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 000000000000000000000000000000000000000000000000ffffffffffffffff 3fffffffffffffff76e59c0fdacc1b9246ac39382e80dd85fde1f4a100000005 +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 4000000000000000000000000000000000000000000000000000000000000000 125b506bdee72dc51de5ea66f0f257463e8669ae6516b680c969876800000004 +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 36e59c0fdacc1b919b4b3c4bfffffffcefee2ee4411acfc1303c567b00000007 +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 125b506bdee72dc51de5ea66f0f25746c7a0cd9e8a4a9aef2e1e4b1c00000008 +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 2da4af942118d23ae21a15990f0da8b9e3c02f4da436429acfc3a984fffffffd +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3031b67010dc5f33e1768c975480689a91ad57216c5706a8810c3c6089daf8b6 +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3b22a80cd2c81a0c889a01873458140ef909266c546d35f5014930b21f53b554 +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 10548582022977317020e583ebc9e08237f899a30131ff72b3387ebd971aec55 +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 348bf875968510c9c9602914af00483e46f3b5921d2c02b91578ba31cf7bad4c +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 0791f325de14e664b4aa62282e98a644f50840433dbfc7626da70eaaf58145f5 +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 08102d3c3c95a063e1e6c2328bbd8e7ed2a208c993640dc0c477d288cfba797a +SQR Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 0662a11d61e1a30f915945eff265faff24953adafa8636a3c01ff3639e2aed4c +FROM Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 0000000000000000000000000000000000000000000000000000000000000001 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 21cce888a6cab566710d6cd04c692c9784379b4cc10e927b1dfc65f6ad0492ae +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 0662a11d61e1a30f915945eff265faff24953adafa8636a3c01ff3639e2aed4c +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 3692be50846348eb886856643c36a2e74a738b3e7e3f18340cb44439fffffff2 +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 000000000000000000000000000000000000000000000000ffffffffffffffff 2e2a67ec482ca6045b2ef3341a17f2ecf6a3c75cc8bdaf33e0efe592118d23a0 +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 4000000000000000000000000000000000000000000000000000000000000000 3ab8c2488b4b664437e344050d4ff50b575e968be1ab27492f434e180ea7843f +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 09595b20624498f13919469f2d8f1ea91d1e34d0388bbd88e9421d36f0da8b8e +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 314b80990faeaf2fc04b9a69498697f27f8b88ce569d4661a2ca61650ea78430 +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 05473db774b499bbc81cbbfaf2b00af4cae8027027a1d1d269e9e2d4f1587bc2 +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 11059dda0a0984a24c432eaa84cb8a47e785e51edefe7cefa723d05be7cd96b1 +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 2a8c68e806154a62330fa85f54dedea8453b7a0d756f7860ca191c12c6265afb +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 28b001b79faac705f426b23ca533d40220e19e6209f724ada5c28c17b9f0d326 +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 3c2c602b7bf8fbf1790afd71b3e16fad0c5531d44cf930398f831a05338f2444 +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 3d679a6b16f9788e6430d173a58607f8d5e7ec854b246cf10a63c8d6170c9008 +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 096a1374bdff44bcdb81d15301f0d099d8fc397f7e24afe149933c9ef8a6efe3 +SQR Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9 +FROM Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589658 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 0000000000000000000000000000000000000000000000000000000000000001 1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589658 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 00000000000000000000000000000000891a63f02533e46e64b4c3b400000004 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 3692be50846348eb886856643c36a2e74a738b3e7e3f18340cb44439fffffff2 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 000000000000000000000000000000000000000000000000ffffffffffffffff 31269b682e59de6fd65951678f204af90e79463ab37aa332256c3921cc314cff +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 4000000000000000000000000000000000000000000000000000000000000000 100000000000000000000000000000000891a63f02533e46e64b4c3b40000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 077feccfbd7a2968ca7fdd5bafc89a65de7613d61bc1496d2e7214c112c9d33f +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 31f1c4ff1e2278d570cb2996efc89a65b53160a942cb3a9eb58adac293a769a9 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 3000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 075fd91f3b718e08c51be01df5028ccc419bfe790f5b558fc4eb03ea21c2bedc +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3a80d4fab5ba20a8a16195cd72a675e5f66caca2755bd372e73d60d346332931 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 1c2e48522b3388de50ade90d1f25cd139a10bd0f15f3fc4da795b0484e2be97c +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 0c942c15724e2a539b07cff51781ad5803eb22a0d9a2d7be0b3215dfda494d90 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 24ec7781e5ebd60e91be9e56ea3634df88c55c71ebc034e1a63b4075c102abe4 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3be85d8069b8128c838e08fd1ed8306682f054442bd65e6f1bbc40a1c35cc5b2 +SQR Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 1acd4a009f399376e232c5736e77fb8c1c35dfa341e703db83392c958598c6be +FROM Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 0ed96497d1a6219029a6ae9870dfb50713cd52c155d255e973c0f7cb33ceb302 +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000001 0ed96497d1a6219029a6ae9870dfb50713cd52c155d255e973c0f7cb33ceb302 +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 000000000000000000000000000000000000000000000000ffffffffffffffff +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 3fffffffffffffff76e59c0fdacc1b9246ac39382e80dd85fde1f4a100000005 +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 2e2a67ec482ca6045b2ef3341a17f2ecf6a3c75cc8bdaf33e0efe592118d23a0 +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 31269b682e59de6fd65951678f204af90e79463ab37aa332256c3921cc314cff +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 000000000000000000000000000000000000000000000000ffffffffffffffff 1acd4a009f399376e232c5736e77fb8c1c35dfa341e703db83392c958598c6be +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 4000000000000000000000000000000000000000000000000000000000000000 100000000000000000000000000000000891a63f02533e47264b4c3b40000000 +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 3d000f740db18f02f00e052c4f204af954d1de0b0cab76c3b5b5e0d408b278e3 +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 01269b682e59de6fd65951678f204af8f4c4537dac80e85db28a54700c314cfe +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 3000000000000000000000000000000019b4f2bd06f9bad472e1e4b1c0000001 +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 0243f901466f013c8772ef73a588001a8cfd085e39574506f699f0ce0f88f6ff +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 191f3f2d4313aac2ca49e3117da6cccc88309e28da5f78ff277a04b81d1babd3 +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 0b805f450c0dbbcac5b4d865b01cc2cfdf8b1a0da5a185b347115895fafa0cf5 +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 318c5c205acc7cfb9dd944e14c01dc9dc04c7e3f598fcdcf20995458a381f6df +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 132dd92afbb5a12f1cbf9c47baf77e853f10c4c3988db021b3feac2f58b2041e +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 385a54834adfe22620b33bbf39551c1ebe43143dccc4fe9a83b5c6ed6a3d0fe4 +SQR Fp 4000000000000000000000000000000000000000000000000000000000000000 1000000000000000000000000000000000000000000000000000000000000000 +FROM Fp 4000000000000000000000000000000000000000000000000000000000000000 3000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000001 3000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 4000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 125b506bdee72dc51de5ea66f0f257463e8669ae6516b680c969876800000004 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 3ab8c2488b4b664437e344050d4ff50b575e968be1ab27492f434e180ea7843f +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 100000000000000000000000000000000891a63f02533e46e64b4c3b40000000 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000ffffffffffffffff 100000000000000000000000000000000891a63f02533e47264b4c3b40000000 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 4000000000000000000000000000000000000000000000000000000000000000 1000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 100000000000000000000000000000004891a63f02533e46e64b4c3b40000000 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 200000000000000000000000000000000891a63f02533e46e64b4c3b40000000 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 30000000000000000000000000000000224698fc094cf91b992d30ed00000001 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 1f0f0f09f84f08783843fdf0cf348dc097a0b54e3aa246c5b55a5622784f0e97 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3b5460f6403423b40d9318fd6638bebd8e6eef198af3853ff6d6f357647edda2 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 08a3454c5f8ed6682cc97fccfbfe6debb4b8745fecf3f0e50dfb5b6dd8bafe75 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 352c1aa827cc3842bae5326c6b8c0507b63abda4f5381c1fba0caf01e03ae083 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 049a2bd27b9b331284522c7cbc8a91687e2221820bee830d4de6a0df5e838533 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 02bf53bdc23a2a747c90e3e3ed389e5d8e77d8428bb6a45fe99705d8bcb3fbfa +SQR Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 2d0e14a05cd1d9fc243491206fc89a663293063e00578f9e26d1cbe7d1ec3cd7 +FROM Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 388013304285d697358022a45037659a43d08525ed8bafae6abb1c2bed362cc2 +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000001 388013304285d697358022a45037659a43d08525ed8bafae6abb1c2bed362cc2 +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 00000000000000000000000000000000ffffffffffffffffffffffffffffffff +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 36e59c0fdacc1b919b4b3c4bfffffffcefee2ee4411acfc1303c567b00000007 +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 09595b20624498f13919469f2d8f1ea91d1e34d0388bbd88e9421d36f0da8b8e +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 077feccfbd7a2968ca7fdd5bafc89a65de7613d61bc1496d2e7214c112c9d33f +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 000000000000000000000000000000000000000000000000ffffffffffffffff 3d000f740db18f02f00e052c4f204af954d1de0b0cab76c3b5b5e0d408b278e3 +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 4000000000000000000000000000000000000000000000000000000000000000 100000000000000000000000000000004891a63f02533e46e64b4c3b40000000 +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 2d0e14a05cd1d9fc243491206fc89a663293063e00578f9e26d1cbe7d1ec3cd7 +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 177feccfbd7a2968ca7fdd5bafc89a662707ba151e1487b414bd60fc52c9d33f +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 2fffffffffffffffffffffffffffffffd9b4f2bd06f9bad4b2e1e4b1c0000001 +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 09b6e874ebf7015713395bc67cb37e35bf190f9737a661f2590218bef5ccf20d +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 2369223ec0ba778f450631700e279844d7602068e54753affa279ed410cd00c8 +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 113537aabc2a7e9a9f170ff0466ace9eb6bd66c2ac39a2cb6bcd60b2cac31dca +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 0f65a101a6ce5999439c8a3a3746ccd5da1def3365e774fd07693f94385002f0 +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 2fed7572b6ad1fb4518addae8bb2afaca112b6073915376d60bf257769db7f62 +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 190d90428434fe44c0c829966224346c7b42f390ed1288f2ffb94f3b3ebd874b +SQR Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 11f1c4ff1e2278d570cb2996efc89a659b7c6dec3bd17fca02a8f610d3a769a8 +FROM Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0e0e3b00e1dd872a8f34d6691037659a6d153852c681be7ce3a2562a6c589658 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000001 0e0e3b00e1dd872a8f34d6691037659a6d153852c681be7ce3a2562a6c589658 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 125b506bdee72dc51de5ea66f0f25746c7a0cd9e8a4a9aef2e1e4b1c00000008 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 314b80990faeaf2fc04b9a69498697f27f8b88ce569d4661a2ca61650ea78430 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 31f1c4ff1e2278d570cb2996efc89a65b53160a942cb3a9eb58adac293a769a9 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000000000000000000000ffffffffffffffff 01269b682e59de6fd65951678f204af8f4c4537dac80e85db28a54700c314cfe +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 4000000000000000000000000000000000000000000000000000000000000000 200000000000000000000000000000000891a63f02533e46e64b4c3b40000000 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 177feccfbd7a2968ca7fdd5bafc89a662707ba151e1487b414bd60fc52c9d33f +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 11f1c4ff1e2278d570cb2996efc89a659b7c6dec3bd17fca02a8f610d3a769a8 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 2000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 266ee82933c09680fd5fde0ec4371a8cd93cb3c749fd9c557a455a0c9a11cd73 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 35d535f0f5ee445caef4aecad8df34a3629502bff7025f9744e7233daab206d2 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 24d18d9e8ac25f467d7768da1b243aff4ec9316f02e7ed32b5910bb626e6e7f1 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 01c046bd9a1a629655ed0261830db25f97df4749c58dfac22c1193f4ba842e12 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 2986a354618709211610cad3a6c0c64806e77df3f7aeb7eef421e1551f863117 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3ea7b13e2bf23d01001eece10c10cec411682c86b78d02cf0553467a8010c1ac +SQR Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 1000000000000000000000000000000000000000000000000000000000000000 +FROM Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 100000000000000000000000000000000891a63f02533e46e64b4c3b40000000 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000001 100000000000000000000000000000000891a63f02533e46e64b4c3b40000000 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 2da4af942118d23ae21a15990f0da8b9e3c02f4da436429acfc3a984fffffffd +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 05473db774b499bbc81cbbfaf2b00af4cae8027027a1d1d269e9e2d4f1587bc2 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 3000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 000000000000000000000000000000000000000000000000ffffffffffffffff 3000000000000000000000000000000019b4f2bd06f9bad472e1e4b1c0000001 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 4000000000000000000000000000000000000000000000000000000000000000 30000000000000000000000000000000224698fc094cf91b992d30ed00000001 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 2fffffffffffffffffffffffffffffffd9b4f2bd06f9bad4b2e1e4b1c0000001 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 2000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 1000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 20f0f0f607b0f787c7bc020f30cb723f8aa5e3adceaab255e3d2daca87b0f16a +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 04ab9f09bfcbdc4bf26ce70299c7414293d7a9e27e5973dba2563d959b81225f +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 375cbab3a0712997d3368033040192146d8e249c1c5908368b31d57f2745018c +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 0ad3e557d833c7bd451acd939473faf86c0bdb571414dcfbdf2081eb1fc51f7e +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 3b65d42d8464cced7badd38343756e97a4247779fd5e760e4b46900da17c7ace +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3d40ac423dc5d58b836f1c1c12c761a293cec0b97d9654bbaf962b14434c0407 +SQR Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3e3eab736edbf3946567e005720448fa968090b33ceae01c4381bc2109eeaf68 +FROM Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 38a026e0c48e71f73ae41fe20afd7333e0aa9a82f9f1a38bd4422d02de3d4125 +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 0000000000000000000000000000000000000000000000000000000000000001 38a026e0c48e71f73ae41fe20afd7333e0aa9a82f9f1a38bd4422d02de3d4125 +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 3031b67010dc5f33e1768c975480689a91ad57216c5706a8810c3c6089daf8b6 +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 11059dda0a0984a24c432eaa84cb8a47e785e51edefe7cefa723d05be7cd96b1 +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 075fd91f3b718e08c51be01df5028ccc419bfe790f5b558fc4eb03ea21c2bedc +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 000000000000000000000000000000000000000000000000ffffffffffffffff 0243f901466f013c8772ef73a588001a8cfd085e39574506f699f0ce0f88f6ff +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 4000000000000000000000000000000000000000000000000000000000000000 1f0f0f09f84f08783843fdf0cf348dc097a0b54e3aa246c5b55a5622784f0e97 +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 09b6e874ebf7015713395bc67cb37e35bf190f9737a661f2590218bef5ccf20d +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 266ee82933c09680fd5fde0ec4371a8cd93cb3c749fd9c557a455a0c9a11cd73 +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 20f0f0f607b0f787c7bc020f30cb723f8aa5e3adceaab255e3d2daca87b0f16a +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3e3eab736edbf3946567e005720448fa968090b33ceae01c4381bc2109eeaf68 +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3a9fa1eab51f114925de48e933973c839a851f8d16897802cce98a6267201387 +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 2433c132353f7a7f730575508359403919905b802503b90d7f4089fc0acd1e2a +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 18a27a96677cebda48524b4f66ca32081b52f70b717294b8645d87743ef435db +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 1b1d201950d04201d5a13d2f40f232fcf3da86444bfbdd96a840d51974c1a9d7 +MUL Fp 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0fe1bce271b680a3432473b59a47a1c89bb3fa7f9abd3fc2582838316659e21a +SQR Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 23e2d584e303750afbe701cc135a158c167f8e478e3e5fc5d9a12bd944145437 +FROM Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 057f2b054a45df575e9e6a328d598a1a2bd9ec5993f125a8b1efd019b9ccd6d0 +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 0000000000000000000000000000000000000000000000000000000000000001 057f2b054a45df575e9e6a328d598a1a2bd9ec5993f125a8b1efd019b9ccd6d0 +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 3b22a80cd2c81a0c889a01873458140ef909266c546d35f5014930b21f53b554 +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 2a8c68e806154a62330fa85f54dedea8453b7a0d756f7860ca191c12c6265afb +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 3a80d4fab5ba20a8a16195cd72a675e5f66caca2755bd372e73d60d346332931 +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 000000000000000000000000000000000000000000000000ffffffffffffffff 191f3f2d4313aac2ca49e3117da6cccc88309e28da5f78ff277a04b81d1babd3 +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 4000000000000000000000000000000000000000000000000000000000000000 3b5460f6403423b40d9318fd6638bebd8e6eef198af3853ff6d6f357647edda2 +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 2369223ec0ba778f450631700e279844d7602068e54753affa279ed410cd00c8 +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 35d535f0f5ee445caef4aecad8df34a3629502bff7025f9744e7233daab206d2 +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 04ab9f09bfcbdc4bf26ce70299c7414293d7a9e27e5973dba2563d959b81225f +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3a9fa1eab51f114925de48e933973c839a851f8d16897802cce98a6267201387 +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 23e2d584e303750afbe701cc135a158c167f8e478e3e5fc5d9a12bd944145437 +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 3ce872d15beb15e7588f5de133d0911cd1c2e096c89f9f45c5e09880d85839c5 +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 3259897b8dc9480ee45a3263849a285c4956e607a01e8d672e92443b91d4af79 +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 13b5bc4323ef673b7d2ebb04dc796bcc0595773c37288657aa1b5b21897e52d4 +MUL Fp 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 241142522c7e16f6adc74f23033257a67598c7dbd63840792ffe83c6b9c1e770 +SQR Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 101375a000c3fbfa17d36b7a1e49055624cd7677331a60db2cc29f483741ff50 +FROM Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 23d1b7add4cc7721af5216f2e0da32ec8835dbecf358fccdf19780a4b1d41685 +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 0000000000000000000000000000000000000000000000000000000000000001 23d1b7add4cc7721af5216f2e0da32ec8835dbecf358fccdf19780a4b1d41685 +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 10548582022977317020e583ebc9e08237f899a30131ff72b3387ebd971aec55 +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 28b001b79faac705f426b23ca533d40220e19e6209f724ada5c28c17b9f0d326 +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 1c2e48522b3388de50ade90d1f25cd139a10bd0f15f3fc4da795b0484e2be97c +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 000000000000000000000000000000000000000000000000ffffffffffffffff 0b805f450c0dbbcac5b4d865b01cc2cfdf8b1a0da5a185b347115895fafa0cf5 +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 4000000000000000000000000000000000000000000000000000000000000000 08a3454c5f8ed6682cc97fccfbfe6debb4b8745fecf3f0e50dfb5b6dd8bafe75 +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 113537aabc2a7e9a9f170ff0466ace9eb6bd66c2ac39a2cb6bcd60b2cac31dca +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 24d18d9e8ac25f467d7768da1b243aff4ec9316f02e7ed32b5910bb626e6e7f1 +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 375cbab3a0712997d3368033040192146d8e249c1c5908368b31d57f2745018c +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 2433c132353f7a7f730575508359403919905b802503b90d7f4089fc0acd1e2a +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3ce872d15beb15e7588f5de133d0911cd1c2e096c89f9f45c5e09880d85839c5 +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 101375a000c3fbfa17d36b7a1e49055624cd7677331a60db2cc29f483741ff50 +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 216088e1212a7e3fc1f7dec7525eecdf393fe793f52a875cf043848ad8095cc3 +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 35c5000bc6c052e6674d650b37e06a3a0a4fba0c34fd24ce261a45452089bc46 +MUL Fp 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 2565d74b6f42ec480e49fae1cd43df66bbb7502f0cef496c28f6c4879667d453 +SQR Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 1677ce27814b54d771a091ab04eef7ad2cdf503fcfe6b9e8dad6ba85e7d8fbc9 +FROM Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 336bd3ea8db1d5ac64f8300ae87e52a81e5b765b2faa215d8dfb1b0d25b6b271 +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 0000000000000000000000000000000000000000000000000000000000000001 336bd3ea8db1d5ac64f8300ae87e52a81e5b765b2faa215d8dfb1b0d25b6b271 +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 348bf875968510c9c9602914af00483e46f3b5921d2c02b91578ba31cf7bad4c +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 3c2c602b7bf8fbf1790afd71b3e16fad0c5531d44cf930398f831a05338f2444 +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 0c942c15724e2a539b07cff51781ad5803eb22a0d9a2d7be0b3215dfda494d90 +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 000000000000000000000000000000000000000000000000ffffffffffffffff 318c5c205acc7cfb9dd944e14c01dc9dc04c7e3f598fcdcf20995458a381f6df +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 4000000000000000000000000000000000000000000000000000000000000000 352c1aa827cc3842bae5326c6b8c0507b63abda4f5381c1fba0caf01e03ae083 +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 0f65a101a6ce5999439c8a3a3746ccd5da1def3365e774fd07693f94385002f0 +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 01c046bd9a1a629655ed0261830db25f97df4749c58dfac22c1193f4ba842e12 +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 0ad3e557d833c7bd451acd939473faf86c0bdb571414dcfbdf2081eb1fc51f7e +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 18a27a96677cebda48524b4f66ca32081b52f70b717294b8645d87743ef435db +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3259897b8dc9480ee45a3263849a285c4956e607a01e8d672e92443b91d4af79 +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 216088e1212a7e3fc1f7dec7525eecdf393fe793f52a875cf043848ad8095cc3 +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 1677ce27814b54d771a091ab04eef7ad2cdf503fcfe6b9e8dad6ba85e7d8fbc9 +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 360e55958d8e8464a1fd7990b64f92ffbfae77cba35ea31dc8f26d8c0274ce1f +MUL Fp 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 12d5679fd842c0fae489e6f8fd950712a6801d77da2000d2e180e73af156d5b3 +SQR Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 3ce69b158811c2f8acefdc7b0e5a9df4c9bd80d3b24d8f94654a3efada3cf581 +FROM Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 1b13887e1a1429f16e4161a915c9cb2099813c8a1d8cc439f2f1f0773efd541d +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 0000000000000000000000000000000000000000000000000000000000000001 1b13887e1a1429f16e4161a915c9cb2099813c8a1d8cc439f2f1f0773efd541d +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 0791f325de14e664b4aa62282e98a644f50840433dbfc7626da70eaaf58145f5 +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 3d679a6b16f9788e6430d173a58607f8d5e7ec854b246cf10a63c8d6170c9008 +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 24ec7781e5ebd60e91be9e56ea3634df88c55c71ebc034e1a63b4075c102abe4 +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 000000000000000000000000000000000000000000000000ffffffffffffffff 132dd92afbb5a12f1cbf9c47baf77e853f10c4c3988db021b3feac2f58b2041e +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 4000000000000000000000000000000000000000000000000000000000000000 049a2bd27b9b331284522c7cbc8a91687e2221820bee830d4de6a0df5e838533 +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 2fed7572b6ad1fb4518addae8bb2afaca112b6073915376d60bf257769db7f62 +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 2986a354618709211610cad3a6c0c64806e77df3f7aeb7eef421e1551f863117 +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 3b65d42d8464cced7badd38343756e97a4247779fd5e760e4b46900da17c7ace +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 1b1d201950d04201d5a13d2f40f232fcf3da86444bfbdd96a840d51974c1a9d7 +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 13b5bc4323ef673b7d2ebb04dc796bcc0595773c37288657aa1b5b21897e52d4 +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 35c5000bc6c052e6674d650b37e06a3a0a4fba0c34fd24ce261a45452089bc46 +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 360e55958d8e8464a1fd7990b64f92ffbfae77cba35ea31dc8f26d8c0274ce1f +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 3ce69b158811c2f8acefdc7b0e5a9df4c9bd80d3b24d8f94654a3efada3cf581 +MUL Fp 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0ce2105c41fe09975371bc977a9cacd087001027e8f2f0eebb02070709dbc6cd +SQR Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0b67e1cebd614788846394194b77a658559fe5bf4d14fa7d808af326b918255d +FROM Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0417a27f9647ed737c71f702e127cf999f5644b7dd769aac7d70f04b3ca33a4f +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0000000000000000000000000000000000000000000000000000000000000001 0417a27f9647ed737c71f702e127cf999f5644b7dd769aac7d70f04b3ca33a4f +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 08102d3c3c95a063e1e6c2328bbd8e7ed2a208c993640dc0c477d288cfba797a +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 096a1374bdff44bcdb81d15301f0d099d8fc397f7e24afe149933c9ef8a6efe3 +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 3be85d8069b8128c838e08fd1ed8306682f054442bd65e6f1bbc40a1c35cc5b2 +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 000000000000000000000000000000000000000000000000ffffffffffffffff 385a54834adfe22620b33bbf39551c1ebe43143dccc4fe9a83b5c6ed6a3d0fe4 +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 4000000000000000000000000000000000000000000000000000000000000000 02bf53bdc23a2a747c90e3e3ed389e5d8e77d8428bb6a45fe99705d8bcb3fbfa +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 190d90428434fe44c0c829966224346c7b42f390ed1288f2ffb94f3b3ebd874b +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3ea7b13e2bf23d01001eece10c10cec411682c86b78d02cf0553467a8010c1ac +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 3d40ac423dc5d58b836f1c1c12c761a293cec0b97d9654bbaf962b14434c0407 +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 0fe1bce271b680a3432473b59a47a1c89bb3fa7f9abd3fc2582838316659e21a +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 241142522c7e16f6adc74f23033257a67598c7dbd63840792ffe83c6b9c1e770 +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 2565d74b6f42ec480e49fae1cd43df66bbb7502f0cef496c28f6c4879667d453 +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 12d5679fd842c0fae489e6f8fd950712a6801d77da2000d2e180e73af156d5b3 +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 0ce2105c41fe09975371bc977a9cacd087001027e8f2f0eebb02070709dbc6cd +MUL Fp 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0b67e1cebd614788846394194b77a658559fe5bf4d14fa7d808af326b918255d +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000001 1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589659 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589659 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 3ffffffffffffffeffffffffffffffff992c350be41914ad34786d38fffffffc +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffc +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 096d41af7b9cb7147797a99bc3c95d1960ed71adb041c555f12db06700000013 +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 096d41af7b9cb7147797a99bc3c95d1960ed71adb041c555f12db06700000013 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 2175c772b190e1fc67f56678717677141ed3817ddfb7d0ea650cb8e63a9e10ea +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 2175c772b190e1fc67f56678717677141ed3817ddfb7d0ea650cb8e63a9e10ea +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a8 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a8 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000000000000000000000ffffffffffffffff 31269b682e59de6fd65951678f204af90e79463ab37aa333256c3921cc314cfe +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 31269b682e59de6fd65951678f204af90e79463ab37aa333256c3921cc314cfe +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 4000000000000000000000000000000000000000000000000000000000000000 0fffffffffffffffffffffffffffffffe64b0d42f906452b4d1e1b4e3fffffff +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0fffffffffffffffffffffffffffffffe64b0d42f906452b4d1e1b4e3fffffff +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 077feccfbd7a2968ca7fdd5bafc89a65de7613d61bc1496d2e7214c112c9d33e +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 077feccfbd7a2968ca7fdd5bafc89a66de7613d61bc1496d2e7214c112c9d33e +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 31f1c4ff1e2278d570cb2996efc89a6492eac7ad397e41831c5da9d593a769a7 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 31f1c4ff1e2278d570cb2996efc89a6592eac7ad397e41831c5da9d593a769a7 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 300000000000000000000000000000003bfb8bb91046b3f04c0f159ec0000002 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 300000000000000000000000000000003bfb8bb91046b3f04c0f159ec0000002 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21f1c4ff1e2278d570cb2996efc89a64ac9fba6a4077fc57cf3f8e8753a769a7 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21f1c4ff1e2278d570cb2996efc89a64ac9fba6a4077fc57cf3f8e8753a769a7 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 f0cb2996efc89a649a71d82f60a84f6c9e26742f8cfd5924a9d3556587761ca9 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 30cb2996efc89a659a71d82f60a84f6bc06d0d2b964a52404300865287761caa +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff c83d113a5e2278d430cb2996efc89a647c94c6d6abc5909ccdfc4e25d1062bf3 +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff c83d113a5e2278d430cb2996efc89a657c94c6d6abc5909ccdfc4e25d1062bf3 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000000000000000000000000000000000000000000000 e64b4c3b3ffffffebffffffffffffffff23ba568749a8d6097e9f08b7d5ec24c +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e64b4c3b3ffffffebffffffffffffffff23ba568749a8d6097e9f08b7d5ec24c +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589659 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589659 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 0000000000000000000000000000000000000000000000000000000000000001 0f34d6691037659a658e27d09f57b09361d98bd07302a6da562caa9a7889e357 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 0f34d6691037659a658e27d09f57b09361d98bd07302a6da562caa9a7889e357 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 3ffffffffffffffeffffffffffffffff992c350be41914ac34786d38fffffffd +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 3fffffffffffffffffffffffffffffff992c350be41914ac34786d38fffffffd +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 096d41af7b9cb71500b20d8be8fd41873c87d1718b0de0eb8c78ecb30000000f +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 096d41af7b9cb71500b20d8be8fd41873c87d1718b0de0eb8c78ecb30000000f +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 334b5f8669643bf80cc67344575e84274a76531d20471ad21d4a04412910ed4b +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 334b5f8669643bf80cc67344575e84274a76531d20471ad21d4a04412910ed4b +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 30cb2996efc89a659a71d82f60a84f6cc06d0d2b964a52414300865287761caa +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 30cb2996efc89a659a71d82f60a84f6cc06d0d2b964a52414300865287761caa +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 000000000000000000000000000000000000000000000000ffffffffffffffff 165951678f204af8f4268bf420a84f6cf243669771939f57a2330c8c46988640 +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 165951678f204af8f4268bf420a84f6cf243669771939f57a2330c8c46988640 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 4000000000000000000000000000000000000000000000000000000000000000 3fffffffffffffffffffffffffffffffffffffffffffffffc000000000000000 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 3fffffffffffffffffffffffffffffffffffffffffffffffc000000000000000 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 0a7fdd5bafc89a65da71d82f60a84f6cabeacec71862cbc511e964da0a175a5c +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 0a7fdd5bafc89a65da71d82f60a84f6dabeacec71862cbc511e964da0a175a5c +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 30cb2996efc89a659a71d82f60a84f6b9e26742f8cfd592569d3556587761ca9 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 30cb2996efc89a659a71d82f60a84f6c9e26742f8cfd592569d3556587761ca9 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 00000000000000000000000000000000224698fc094cf91bd92d30ed00000001 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 00000000000000000000000000000000224698fc094cf91bd92d30ed00000001 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 30cb2996efc89a659a71d82f60a84f6bc06d0d2b964a52404300865287761caa +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 f0cb2996efc89a649a71d82f60a84f6c9e26742f8cfd5924a9d3556587761ca9 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 da71d82f60a84f6ba64b4c3b3fffffffabe30d981b69b9cd07a048d940dd9669 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 da71d82f60a84f6ba64b4c3b3fffffffabe30d981b69b9cd07a048d940dd9669 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff f0cb2996efc89a649a71d82f60a84f6b9e26742f8cfd5924a9d3556587761caa +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 f0cb2996efc89a649a71d82f60a84f6c9e26742f8cfd5924a9d3556587761caa +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 ffffffffffffffff000000000000000000000000000000000000000000000000 bffffffffffffffeffffffffffffffffddb96703f6b306e366d2cf1300000000 +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 bffffffffffffffeffffffffffffffffddb96703f6b306e366d2cf1300000000 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 0f34d6691037659a658e27d09f57b09361d98bd07302a6da562caa9a7889e357 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 0f34d6691037659a658e27d09f57b09361d98bd07302a6da562caa9a7889e357 +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000001 37c2eec5a1dd872acf34d6691037659a836b3929543a6f633203b1da2ef9d40c +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 37c2eec5a1dd872acf34d6691037659a836b3929543a6f633203b1da2ef9d40c +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 3ffffffffffffffeffffffffffffffff992c350be41914ad34786d38fffffffc +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 3ffffffffffffffeffffffffffffffff992c350be41914ad34786d38fffffffc +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 2e2205637b9cb7182e2a67ec482ca604fcfe4d7d773c0e0beec288616b306e5a +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 2e2205637b9cb7182e2a67ec482ca604fcfe4d7d773c0e0beec288616b306e5a +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 30c4d737c038663a7d125d564448de03477954dba8c4a49f5592d170b2235101 +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 30c4d737c038663a7d125d564448de03477954dba8c4a49f5592d170b2235101 +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 083d113a5e2278d530cb2996efc89a659edb5fd2b51289b867297f12d1062bf5 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 083d113a5e2278d530cb2996efc89a659edb5fd2b51289b867297f12d1062bf5 +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000000000000000000000ffffffffffffffff 1771e7a36e59de6f965951678f204af900b4eba328153093bd5629ad49900f4a +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 1771e7a36e59de6f965951678f204af900b4eba328153093bd5629ad49900f4a +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 4000000000000000000000000000000000000000000000000000000000000000 0fffffffffffffffbfffffffffffffffe64b0d42f906452b4d1e1b4e3fffffff +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 0fffffffffffffffbfffffffffffffffe64b0d42f906452b4d1e1b4e3fffffff +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 2dcb390afd7a29688a7fdd5bafc89a66f2f8523a99a8cfe85f8936399028958c +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 2dcb390afd7a29688a7fdd5bafc89a66f2f8523a99a8cfe85f8936399028958c +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 183d113a5e2278d4f0cb2996efc89a6585266d15ae18cee3b4479a6111062bf4 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 183d113a5e2278d4f0cb2996efc89a6585266d15ae18cee3b4479a6111062bf4 +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 300000000000000040000000000000003bfb8bb91046b3f04c0f159ec0000002 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 300000000000000040000000000000003bfb8bb91046b3f04c0f159ec0000002 +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff c83d113a5e2278d430cb2996efc89a657c94c6d6abc5909ccdfc4e25d1062bf3 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff c83d113a5e2278d430cb2996efc89a647c94c6d6abc5909ccdfc4e25d1062bf3 +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 f0cb2996efc89a649a71d82f60a84f6c9e26742f8cfd5924a9d3556587761caa +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff f0cb2996efc89a649a71d82f60a84f6b9e26742f8cfd5924a9d3556587761caa +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff ee885d759e2278d2f0cb2996efc89a669117053b29ad1718ff136f9e4e64ee41 +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff ee885d759e2278d2f0cb2996efc89a669117053b29ad1718ff136f9e4e64ee41 +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000000000000000000000000000000000000000000000 e64b4c3b3ffffffdc000000000000000f23ba568749a8d6097e9f08b7d5ec24c +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff e64b4c3b3ffffffdc000000000000000f23ba568749a8d6097e9f08b7d5ec24c +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 37c2eec5a1dd872acf34d6691037659a836b3929543a6f633203b1da2ef9d40c +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 37c2eec5a1dd872acf34d6691037659a836b3929543a6f633203b1da2ef9d40c +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 ffffffffffffffff000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000001 19b4b3c4c000000040000000000000000dc45a978b65729f68160f7482a13db4 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 ffffffffffffffff000000000000000000000000000000000000000000000000 19b4b3c4c000000040000000000000000dc45a978b65729f68160f7482a13db4 +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 3ffffffffffffffeffffffffffffffff992c350be41914ad34786d38fffffffd +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd ffffffffffffffff000000000000000000000000000000000000000000000000 3ffffffffffffffeffffffffffffffff992c350be41914ad34786d38fffffffd +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 2e2205637b9cb7182e2a67ec482ca60473e3e98d5208299d8a0dc4ad6b306e56 +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f ffffffffffffffff000000000000000000000000000000000000000000000000 2e2205637b9cb7182e2a67ec482ca60473e3e98d5208299d8a0dc4ad6b306e56 +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 3a3218e73bd51d4ef4aa06f208123b1c1f4c629933d28586e20bbe23b2235110 +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 ffffffffffffffff000000000000000000000000000000000000000000000000 3a3218e73bd51d4ef4aa06f208123b1c1f4c629933d28586e20bbe23b2235110 +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 264b4c3b3fffffffc00000000000000014823e647de7867c311721787d5ec24d +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 ffffffffffffffff000000000000000000000000000000000000000000000000 264b4c3b3fffffffc00000000000000014823e647de7867c311721787d5ec24d +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000ffffffffffffffff 264b4c3b3fffffffc00000000000000014823e647de7867d311721787d5ec24c +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff ffffffffffffffff000000000000000000000000000000000000000000000000 264b4c3b3fffffffc00000000000000014823e647de7867d311721787d5ec24c +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 4000000000000000000000000000000000000000000000000000000000000000 3fffffffffffffffc00000000000000000000000000000000000000000000000 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 ffffffffffffffff000000000000000000000000000000000000000000000000 3fffffffffffffffc00000000000000000000000000000000000000000000000 +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 264b4c3b3fffffffc00000000000000114823e647de7867b311721787d5ec24d +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff ffffffffffffffff000000000000000000000000000000000000000000000000 264b4c3b3fffffffc00000000000000114823e647de7867b311721787d5ec24d +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 264b4c3b3fffffff7ffffffffffffffff23ba568749a8d6097e9f08b7d5ec24c +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000000000000000000000000000000000000000000000 264b4c3b3fffffff7ffffffffffffffff23ba568749a8d6097e9f08b7d5ec24c +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 00000000000000004000000000000000224698fc094cf91b992d30ed00000001 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 ffffffffffffffff000000000000000000000000000000000000000000000000 00000000000000004000000000000000224698fc094cf91b992d30ed00000001 +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e64b4c3b3ffffffebffffffffffffffff23ba568749a8d6097e9f08b7d5ec24c +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000000000000000000000000000000000000000000000 e64b4c3b3ffffffebffffffffffffffff23ba568749a8d6097e9f08b7d5ec24c +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 bffffffffffffffeffffffffffffffffddb96703f6b306e366d2cf1300000000 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 ffffffffffffffff000000000000000000000000000000000000000000000000 bffffffffffffffeffffffffffffffffddb96703f6b306e366d2cf1300000000 +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff e64b4c3b3ffffffdc000000000000000f23ba568749a8d6097e9f08b7d5ec24c +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000000000000000000000000000000000000000000000 e64b4c3b3ffffffdc000000000000000f23ba568749a8d6097e9f08b7d5ec24c +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 ffffffffffffffff000000000000000000000000000000000000000000000000 bffffffffffffffe0000000000000000ddb96703f6b306e466d2cf12ffffffff +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 ffffffffffffffff000000000000000000000000000000000000000000000000 bffffffffffffffe0000000000000000ddb96703f6b306e466d2cf12ffffffff +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 ffffffffffffffff000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 19b4b3c4c000000040000000000000000dc45a978b65729f68160f7482a13db4 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 ffffffffffffffff000000000000000000000000000000000000000000000000 19b4b3c4c000000040000000000000000dc45a978b65729f68160f7482a13db4 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 000000000000000000000000000000000000000000000000ffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 4000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 ffffffffffffffff000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 0000000000000000000000000000000000000000000000000000000000000001 21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9 +MUL Fp 0000000000000000000000000000000000000000000000000000000000000001 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 0000000000000000000000000000000000000000000000000000000000000001 +MUL Fp 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 0000000000000000000000000000000000000000000000000000000000000001 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd +MUL Fp 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 3fffffffffffffffffffffffffffffff992c350be41914ad34786d38fffffffd +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f +MUL Fp 2ae309222d2d9910df8d1014353fd42cf6a68f3b6ac5b1d1f185a5993a9e10f9 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 096d41af7b9cb7147797a99bc3c95d18d7d30dbd8b0de0e78c78ecb30000000f +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589658 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589658 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 000000000000000000000000000000000000000000000000ffffffffffffffff 0ed96497d1a6219029a6ae9870dfb50713cd52c155d255e973c0f7cb33ceb302 +MUL Fp 000000000000000000000000000000000000000000000000ffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 0ed96497d1a6219029a6ae9870dfb50713cd52c155d255e973c0f7cb33ceb302 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 4000000000000000000000000000000000000000000000000000000000000000 3000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001 +MUL Fp 4000000000000000000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 3000000000000000000000000000000019b4f2bd06f9bad4b2e1e4b1c0000001 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 388013304285d697358022a45037659a43d08525ed8bafae6abb1c2bed362cc2 +MUL Fp 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 388013304285d697358022a45037659a43d08525ed8bafae6abb1c2bed362cc2 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0e0e3b00e1dd872a8f34d6691037659a6d153852c681be7ce3a2562a6c589658 +MUL Fp 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 0e0e3b00e1dd872a8f34d6691037659a6d153852c681be7ce3a2562a6c589658 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 100000000000000000000000000000000891a63f02533e46e64b4c3b40000000 +MUL Fp 00000000000000000000000000000000224698fc094cf91b992d30ed00000001 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 100000000000000000000000000000000891a63f02533e46e64b4c3b40000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589659 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 1e0e3b00e1dd872a8f34d6691037659a75a6de91c8d4fcc3c9eda265ac589659 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 0f34d6691037659a658e27d09f57b09361d98bd07302a6da562caa9a7889e357 +MUL Fp ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 0f34d6691037659a658e27d09f57b09361d98bd07302a6da562caa9a7889e357 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 37c2eec5a1dd872acf34d6691037659a836b3929543a6f633203b1da2ef9d40c +MUL Fp fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 37c2eec5a1dd872acf34d6691037659a836b3929543a6f633203b1da2ef9d40c +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 ffffffffffffffff000000000000000000000000000000000000000000000000 19b4b3c4c000000040000000000000000dc45a978b65729f68160f7482a13db4 +MUL Fp ffffffffffffffff000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 19b4b3c4c000000040000000000000000dc45a978b65729f68160f7482a13db4 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000001 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9 +MUL Fp 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 40000000000000000000000000000000224698fc094cf91b992d30ed00000002 21f1c4ff1e2278d570cb2996efc89a65ac9fba6a4077fc57cf3f8e8753a769a9 +FROM Fq 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000ffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 4000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0000000000000000000000000000000000000000000000000000000000000000 +SQR Fq 0000000000000000000000000000000000000000000000000000000000000001 1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f +FROM Fq 0000000000000000000000000000000000000000000000000000000000000001 1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000001 1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 0000000000000000000000000000000000000000000000000000000000000001 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59082 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 000000000000000000000000000000000000000000000000ffffffffffffffff 3816347ba8ec65c05e21504ba093e4938b695660949353c7e0e8e1e21453ab35 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 4000000000000000000000000000000000000000000000000000000000000000 3000000000000000000000000000000019b4f2bd072f7ea629353058c0000001 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 163784c749804a53cb80fc6f7faf20ec1633f1ba116751167e80c2b170a21433 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 10857622e89b86aca86f41a73faf20ec5327119569697cbac81b8c7b31e59082 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 100000000000000000000000000000000891a63f02652a376311bac840000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 371c0e53d3137a561429e3ed1dbe7811c2ffdda533172cebb2a7f9c727e0d817 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3d97c561772695bd2dadabbb0f08d03b56bd2afbac9508560507cb1ee03ccf55 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 2473c7bb10837eccbb207ca6f8db4fa2adc85c3d551040c82ad95da5f68d3953 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 35bdc74821d8c770c380105be46417165d290f24bcb0a284255d20860f98655d +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 25ea051264f6374dacdf8cb0da3ef5e1f7f05de4a4e1dc32d723436978cfe238 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3d85627c34d2eae5be810b80707f6b2b0298cf948bd293c575c04f6327c7fd37 +SQR Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd +FROM Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 0000000000000000000000000000000000000000000000000000000000000001 +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000001 +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 000000000000000000000000000000000000000000000000ffffffffffffffff 000000000000000000000000000000000000000000000000ffffffffffffffff +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 4000000000000000000000000000000000000000000000000000000000000000 4000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 00000000000000000000000000000000ffffffffffffffffffffffffffffffff +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 +SQR Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c +FROM Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 0000000000000000000000000000000000000000000000000000000000000001 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 2c37a71489ba60888d0f36071632bdabf7abe57547cfa14c569bba29179df5c1 +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 00000000000000000000000000000000891a63f02652a376311bac8400000004 +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 000000000000000000000000000000000000000000000000ffffffffffffffff 3fffffffffffffff76e59c0fd9ad5c8a7a4550682fe74c4fbd6297a500000005 +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 4000000000000000000000000000000000000000000000000000000000000000 125b506bdf33f6aa5feb88c401333d642280770e64abaff06237590800000004 +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 36e59c0fd9ad5c89cee4537bfffffffcefee2ee443109e0ed5f06de700000007 +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 125b506bdf33f6aa5feb88c401333d64ab9adafe8afe53669353058c00000008 +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 2da4af9420cc0955a014773bfeccc29bffc621eda4e8f8ed2a0f9218fffffffd +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 20479a657a172f2bd053df0b7b5acf61f516940d35cc6f334c3e480121ca423e +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 16fba5370a930060cff5e6c18f3efbc1986f687608a3b3fcf657e3356e1c9356 +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 16a094a2dd10d63d2c60481914864a53c49d67e2fff2361ddc8141f24bcb8913 +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 2ac11d8d47008bf94cf18afe7fd17c31bea8fcfadd1b069daf58145a6c87f0c3 +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 07945afd7e00a6ecaae30dbeb11ac138e9070a556c84c5f4aef2f319fb865fa2 +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0fea57e1d7583502228891684693b1965d038faf2fd53ebf2dc9e5ec41ca2ca0 +SQR Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 038c4c2cb8c23f053299d52676a921b7dd1364fa0ac2fcf0fc84cc799aab7c2c +FROM Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 0000000000000000000000000000000000000000000000000000000000000001 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 2c37a71489ba60888d0f36071632bdabf7abe57547cfa14c569bba29179df5c1 +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 038c4c2cb8c23f053299d52676a921b7dd1364fa0ac2fcf0fc84cc799aab7c2c +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 3692be50833025568051dceffb330a6fba8b55be807a91f98fb07221fffffff2 +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 000000000000000000000000000000000000000000000000ffffffffffffffff 3640e16087fd1ae6e300af3fd67183a566437c7da4492248e68449fe0cc0954c +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 4000000000000000000000000000000000000000000000000000000000000000 01f765e81b99e4b2223fb3b2e38572d8f84ef69436e904c98022d08709276b93 +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 194190a05e6e9e8c2c35db5bf20b9edcb2b5763b2229611dd38eb15feccc29b0 +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 388a24389eca0a08a29190a2deb87d48b2da4c52b76396c30fd342a909276b85 +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 3e089a17e4661b4dddc04c4d1c7a8d2729f7a267d2aba4140c241a99f6d8946e +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 10e39b4454685a50cda5f68d7421d880290d079f1b2efeff5236de2f12b9584d +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3b69e9ea6b3ef352ce65cb0486bf9ee41c235797a8223a9b07f2158afdc4df11 +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 30ad74e124fe0fd490a54db31012ffb9eae004a5908bc2fa359cb7410d8e104d +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 091036f343941ce36cbd9dae1bb6b5b9d052a05d8cf4c1e9768fce3835f5853b +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 11a0830b593802f951f6f8fe756548c8d841da513ea0771876a98bb914291f34 +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 015fc1fe4f6bc49f7f332185abed51d9d68235db8e6e529e7701dbe27fe1cd65 +SQR Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f +FROM Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59082 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 0000000000000000000000000000000000000000000000000000000000000001 20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59082 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 00000000000000000000000000000000891a63f02652a376311bac8400000004 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 3692be50833025568051dceffb330a6fba8b55be807a91f98fb07221fffffff2 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 000000000000000000000000000000000000000000000000ffffffffffffffff 07e9cb8457139a3fa1deafb45f6c1b6c96dd429b75015515ab5e093eebac54cc +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 4000000000000000000000000000000000000000000000000000000000000000 100000000000000000000000000000000891a63f02652a376311bac840000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 29c87b38b67fb5ac347f03908050df140c12a741f82d57c70dc6286f8f5debce +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 2f7a89dd176479535790be58c050df13cf1f8766a02b2c22c42b5ea5ce1a6f7f +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 3000000000000000000000000000000019b4f2bd072f7ea629353058c0000001 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 08e3f1ac2cec85a9ebd61c12e24187ee5f46bb56d67d7bf1d99ef159d81f27ea +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 02683a9e88d96a42d2525444f0f72fc4cb896e005cffa087873f20021fc330ac +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 1b8c3844ef7c813344df83590724b05d747e3cbeb4846815616d8d7b0972c6ae +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 0a4238b7de27388f3c7fefa41b9be8e9c51d89d74ce4065966e9ca9af0679aa4 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 1a15faed9b09c8b25320734f25c10a1e2a563b1764b2ccaab523a7b787301dc9 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 027a9d83cb2d151a417ef47f8f8094d51fadc9677dc2151816869bbdd83802ca +SQR Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 260b1bcff7a77ed30f3e5bd83e8757c543ee76f0fb69fb41d53cd52f47fabdcb +FROM Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 3816347ba8ec65c05e21504ba093e4938b695660949353c7e0e8e1e21453ab35 +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000001 3816347ba8ec65c05e21504ba093e4938b695660949353c7e0e8e1e21453ab35 +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 000000000000000000000000000000000000000000000000ffffffffffffffff +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 3fffffffffffffff76e59c0fd9ad5c8a7a4550682fe74c4fbd6297a500000005 +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 3640e16087fd1ae6e300af3fd67183a566437c7da4492248e68449fe0cc0954c +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 07e9cb8457139a3fa1deafb45f6c1b6c96dd429b75015515ab5e093eebac54cc +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 000000000000000000000000000000000000000000000000ffffffffffffffff 260b1bcff7a77ed30f3e5bd83e8757c543ee76f0fb69fb41d53cd52f47fabdcb +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 4000000000000000000000000000000000000000000000000000000000000000 100000000000000000000000000000000891a63f02652a37a311bac840000000 +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 354977a8362ed6983eccf4ec1f6c1b6cef2a2328b319ab393e3c3d23695cc27f +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 17e9cb8457139a3fa1deafb45f6c1b6c9f6ee8da77667f4d4e6fc4072bac54cc +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 3000000000000000000000000000000019b4f2bd072f7ea5e9353058c0000001 +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 1d0dd5994aaafdbb915247b038c80ae3ddd1f438869d7be1b3dfdbb28bd13e92 +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3015e65997e23a7e0812ed29f00c525c12f01d43879cddb33c70d9084328d9b8 +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 16acb4ebe857d0d5df2227b5ff215a2a8b94f780dddabc16e2473bfbc764cb7b +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 0dc24913c28b4fa57ce0e4e232d4db48921ea6321220eb845887d65769047ce1 +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 06f5879e7548be9436c2abeb5db509810c5d405277106fec6a6b9256f3574092 +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 00fba9043bac804523250acf5718e5fa5f27a4762881d669ede2565604ec5733 +SQR Fq 4000000000000000000000000000000000000000000000000000000000000000 1000000000000000000000000000000000000000000000000000000000000000 +FROM Fq 4000000000000000000000000000000000000000000000000000000000000000 3000000000000000000000000000000019b4f2bd072f7ea629353058c0000001 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000001 3000000000000000000000000000000019b4f2bd072f7ea629353058c0000001 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 4000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 125b506bdf33f6aa5feb88c401333d642280770e64abaff06237590800000004 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 01f765e81b99e4b2223fb3b2e38572d8f84ef69436e904c98022d08709276b93 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 100000000000000000000000000000000891a63f02652a376311bac840000000 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000ffffffffffffffff 100000000000000000000000000000000891a63f02652a37a311bac840000000 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 4000000000000000000000000000000000000000000000000000000000000000 1000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 100000000000000000000000000000004891a63f02652a376311bac840000000 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 200000000000000000000000000000000891a63f02652a376311bac840000000 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 30000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 1f0f0f09f84f08783843fdf0cf348dc097a0b54e3ab432b63220c4af784f0e97 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3b5460f6403423b40d9318fd6638bebd8e6eef198b2949116d2a3efe647edda2 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 08a3454c5f8ed6682cc97fccfbfe6debb4b8745fecf3f0e50dfb5b6dd8bafe75 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 352c1aa827cc3842bae5326c6b8c0507b63abda4f56ddff1305ffaa8e03ae083 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 049a2bd27b9b331284522c7cbc8a91687e2221820bee830d4de6a0df5e838533 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 02bf53bdc23a2a747c90e3e3ed389e5d8e77d8428bb6a45fe99705d8bcb3fbfa +SQR Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 34166c94559af205116d48c84050df1451976d5c5294ada2ba72ad0190a1681e +FROM Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 163784c749804a53cb80fc6f7faf20ec1633f1ba116751167e80c2b170a21433 +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000001 163784c749804a53cb80fc6f7faf20ec1633f1ba116751167e80c2b170a21433 +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 00000000000000000000000000000000ffffffffffffffffffffffffffffffff +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 36e59c0fd9ad5c89cee4537bfffffffcefee2ee443109e0ed5f06de700000007 +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 194190a05e6e9e8c2c35db5bf20b9edcb2b5763b2229611dd38eb15feccc29b0 +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 29c87b38b67fb5ac347f03908050df140c12a741f82d57c70dc6286f8f5debce +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 000000000000000000000000000000000000000000000000ffffffffffffffff 354977a8362ed6983eccf4ec1f6c1b6cef2a2328b319ab393e3c3d23695cc27f +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 4000000000000000000000000000000000000000000000000000000000000000 100000000000000000000000000000004891a63f02652a376311bac840000000 +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 34166c94559af205116d48c84050df1451976d5c5294ada2ba72ad0190a1681e +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 39c87b38b67fb5ac347f03908050df1454a44d80fa9281fe70d7e337cf5debce +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 2fffffffffffffffffffffffffffffffd9b4f2bd072f7ea629353058c0000001 +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 2e601d498373089f5f94d5da69f27957ef96481487e5a7b736bd369f612547a4 +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3828d38387ee8cda01425d288c785223d5a48e3759503d09e2dc6ea9e39fefc0 +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 35cedca1e7792b005e925c002e69b1e8a51bb0eb0cdf91d049b1dd1526058824 +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 0aa32df5f5602aee07a126de3b6108679a01e1b4e89c2dc62431eeb25ed73e4b +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 3db83389d2fdc8153f65cf02c73d84eb4fd4670fd63dec9e876bbf8d1e344642 +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 2420b3d392c5663f81c5e7e0d2cc98db3cb0725047f4d0c9828c32b1163a561f +SQR Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0f7a89dd176479535790be58c050df13b56a94a998fbad7c9af62e4d0e1a6f7e +FROM Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 10857622e89b86aca86f41a73faf20ec5327119569697cbac81b8c7b31e59082 +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000001 10857622e89b86aca86f41a73faf20ec5327119569697cbac81b8c7b31e59082 +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 125b506bdf33f6aa5feb88c401333d64ab9adafe8afe53669353058c00000008 +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 388a24389eca0a08a29190a2deb87d48b2da4c52b76396c30fd342a909276b85 +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 2f7a89dd176479535790be58c050df13cf1f8766a02b2c22c42b5ea5ce1a6f7f +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000000000000000000000ffffffffffffffff 17e9cb8457139a3fa1deafb45f6c1b6c9f6ee8da77667f4d4e6fc4072bac54cc +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 4000000000000000000000000000000000000000000000000000000000000000 200000000000000000000000000000000891a63f02652a376311bac840000000 +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 39c87b38b67fb5ac347f03908050df1454a44d80fa9281fe70d7e337cf5debce +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0f7a89dd176479535790be58c050df13b56a94a998fbad7c9af62e4d0e1a6f7e +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 2000000000000000000000000000000019b4f2bd072f7ea629353058c0000001 +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 27f300b6253b8e22241a1a03b17615aef6e770a51131aea80bbfb609506e3681 +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3dbc9b94c90d8df6dfe56d42572fee8259f85d19e828e998f4695f0084420e4e +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 242f7d914f0b579b71a9032603231e492936b11ea17858fa6f68e8e8e22dc523 +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 3f6e536005f370d1f76522108727edf17b58477c4251e64a9749c543d0a27b27 +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 1eb026c016a4fbc4d7729fcbe24b9b86a8785c9970a14fb8030a4896e5b3a2fc +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0539f1418d673f8ebe0fd8637cb93332ae25a1aa0978b978001da19694ebfec4 +SQR Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 1000000000000000000000000000000000000000000000000000000000000000 +FROM Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 100000000000000000000000000000000891a63f02652a376311bac840000000 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000001 100000000000000000000000000000000891a63f02652a376311bac840000000 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 2da4af9420cc0955a014773bfeccc29bffc621eda4e8f8ed2a0f9218fffffffd +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 3e089a17e4661b4dddc04c4d1c7a8d2729f7a267d2aba4140c241a99f6d8946e +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 3000000000000000000000000000000019b4f2bd072f7ea629353058c0000001 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 000000000000000000000000000000000000000000000000ffffffffffffffff 3000000000000000000000000000000019b4f2bd072f7ea5e9353058c0000001 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 4000000000000000000000000000000000000000000000000000000000000000 30000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 2fffffffffffffffffffffffffffffffd9b4f2bd072f7ea629353058c0000001 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 2000000000000000000000000000000019b4f2bd072f7ea629353058c0000001 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 1000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 20f0f0f607b0f787c7bc020f30cb723f8aa5e3adcee076275a26267187b0f16a +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 04ab9f09bfcbdc4bf26ce70299c7414293d7a9e27e6b5fcc1f1cac229b81225f +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 375cbab3a0712997d3368033040192146d8e249c1ca0b7f87e4b8fb32745018c +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 0ad3e557d833c7bd451acd939473faf86c0bdb571426c8ec5be6f0781fc51f7e +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 3b65d42d8464cced7badd38343756e97a4247779fda625d03e604a41a17c7ace +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3d40ac423dc5d58b836f1c1c12c761a293cec0b97dde047da2afe548434c0407 +SQR Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3c826e4b14082aff58fa381b66ebb31ffc424a9827324372300385a712a3af71 +FROM Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 371c0e53d3137a561429e3ed1dbe7811c2ffdda533172cebb2a7f9c727e0d817 +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 0000000000000000000000000000000000000000000000000000000000000001 371c0e53d3137a561429e3ed1dbe7811c2ffdda533172cebb2a7f9c727e0d817 +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 20479a657a172f2bd053df0b7b5acf61f516940d35cc6f334c3e480121ca423e +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 10e39b4454685a50cda5f68d7421d880290d079f1b2efeff5236de2f12b9584d +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 08e3f1ac2cec85a9ebd61c12e24187ee5f46bb56d67d7bf1d99ef159d81f27ea +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 000000000000000000000000000000000000000000000000ffffffffffffffff 1d0dd5994aaafdbb915247b038c80ae3ddd1f438869d7be1b3dfdbb28bd13e92 +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 4000000000000000000000000000000000000000000000000000000000000000 1f0f0f09f84f08783843fdf0cf348dc097a0b54e3ab432b63220c4af784f0e97 +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 2e601d498373089f5f94d5da69f27957ef96481487e5a7b736bd369f612547a4 +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 27f300b6253b8e22241a1a03b17615aef6e770a51131aea80bbfb609506e3681 +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 20f0f0f607b0f787c7bc020f30cb723f8aa5e3adcee076275a26267187b0f16a +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3c826e4b14082aff58fa381b66ebb31ffc424a9827324372300385a712a3af71 +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 1cc98a7c4a2f2d1577731209ca0bb4345acf26d96e40b1a3621c4b697c1f89a7 +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 3af6ee59b3b4c38b0c54be9896161e88bd2a6b3048071d6589bd19dad1f26ffb +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 1abad769c6cbad4123a911553b6e7852138fc045cf42b1fb85534fd5c8b7cddd +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 0ee9cb3f0c351f50055b7dd7ae3544e2a01c48185ebf81b388f231fab7cab006 +MUL Fq 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3d32c8fb7d3d545107b4a69a4c5b2e75eab93d6f80b3cd86eee20d43663e5339 +SQR Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 071895d90ab40b08c4b42617ac1cdd5513304a1aff12e439c017aaa5c9466628 +FROM Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3d97c561772695bd2dadabbb0f08d03b56bd2afbac9508560507cb1ee03ccf55 +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 0000000000000000000000000000000000000000000000000000000000000001 3d97c561772695bd2dadabbb0f08d03b56bd2afbac9508560507cb1ee03ccf55 +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 16fba5370a930060cff5e6c18f3efbc1986f687608a3b3fcf657e3356e1c9356 +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 3b69e9ea6b3ef352ce65cb0486bf9ee41c235797a8223a9b07f2158afdc4df11 +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 02683a9e88d96a42d2525444f0f72fc4cb896e005cffa087873f20021fc330ac +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 000000000000000000000000000000000000000000000000ffffffffffffffff 3015e65997e23a7e0812ed29f00c525c12f01d43879cddb33c70d9084328d9b8 +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 4000000000000000000000000000000000000000000000000000000000000000 3b5460f6403423b40d9318fd6638bebd8e6eef198b2949116d2a3efe647edda2 +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 3828d38387ee8cda01425d288c785223d5a48e3759503d09e2dc6ea9e39fefc0 +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3dbc9b94c90d8df6dfe56d42572fee8259f85d19e828e998f4695f0084420e4e +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 04ab9f09bfcbdc4bf26ce70299c7414293d7a9e27e6b5fcc1f1cac229b81225f +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 1cc98a7c4a2f2d1577731209ca0bb4345acf26d96e40b1a3621c4b697c1f89a7 +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 071895d90ab40b08c4b42617ac1cdd5513304a1aff12e439c017aaa5c9466628 +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 246419a4981faaddc27e8d0019c448456fd856014fa4b0db941ae20af878ac3a +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 3b6909a05dbf22befee2b044abcd8be253ec04353872409056b582ed8ab676e9 +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 193b8747b4746b70f877067f44e731bdfa6932f2e629d4909748eb6234c0a751 +MUL Fq 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0209da84c6f912d00000b696ba1b54f5ca8ef4ab4e7d28f5b128d1b75aa555cb +SQR Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 28435f86f478c99d44fc0ad902afe026c9368241bbf2fd91c20583bd78c314ef +FROM Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 2473c7bb10837eccbb207ca6f8db4fa2adc85c3d551040c82ad95da5f68d3953 +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 0000000000000000000000000000000000000000000000000000000000000001 2473c7bb10837eccbb207ca6f8db4fa2adc85c3d551040c82ad95da5f68d3953 +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 16a094a2dd10d63d2c60481914864a53c49d67e2fff2361ddc8141f24bcb8913 +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 30ad74e124fe0fd490a54db31012ffb9eae004a5908bc2fa359cb7410d8e104d +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 1b8c3844ef7c813344df83590724b05d747e3cbeb4846815616d8d7b0972c6ae +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 000000000000000000000000000000000000000000000000ffffffffffffffff 16acb4ebe857d0d5df2227b5ff215a2a8b94f780dddabc16e2473bfbc764cb7b +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 4000000000000000000000000000000000000000000000000000000000000000 08a3454c5f8ed6682cc97fccfbfe6debb4b8745fecf3f0e50dfb5b6dd8bafe75 +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 35cedca1e7792b005e925c002e69b1e8a51bb0eb0cdf91d049b1dd1526058824 +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 242f7d914f0b579b71a9032603231e492936b11ea17858fa6f68e8e8e22dc523 +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 375cbab3a0712997d3368033040192146d8e249c1ca0b7f87e4b8fb32745018c +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3af6ee59b3b4c38b0c54be9896161e88bd2a6b3048071d6589bd19dad1f26ffb +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 246419a4981faaddc27e8d0019c448456fd856014fa4b0db941ae20af878ac3a +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 28435f86f478c99d44fc0ad902afe026c9368241bbf2fd91c20583bd78c314ef +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 3f744b5a1aea28e70d8ad46f3327904a134f8a4051fd9dfa111fd1f5d5c938c9 +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 03efd48ce6c15c4f257ad17a20e64d1c1a6215ad1e97f54e0f7e2ce750c5441a +MUL Fq 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3eb73a2da6c346e9eefbb70091ae4f358ab2d0eef6bed877e8232e30747a4648 +SQR Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 3d5449b2fe7e68a890240a11344fe522edcaea8796292af2d0d8fb99b79db040 +FROM Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 35bdc74821d8c770c380105be46417165d290f24bcb0a284255d20860f98655d +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 0000000000000000000000000000000000000000000000000000000000000001 35bdc74821d8c770c380105be46417165d290f24bcb0a284255d20860f98655d +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 2ac11d8d47008bf94cf18afe7fd17c31bea8fcfadd1b069daf58145a6c87f0c3 +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 091036f343941ce36cbd9dae1bb6b5b9d052a05d8cf4c1e9768fce3835f5853b +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 0a4238b7de27388f3c7fefa41b9be8e9c51d89d74ce4065966e9ca9af0679aa4 +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 000000000000000000000000000000000000000000000000ffffffffffffffff 0dc24913c28b4fa57ce0e4e232d4db48921ea6321220eb845887d65769047ce1 +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 4000000000000000000000000000000000000000000000000000000000000000 352c1aa827cc3842bae5326c6b8c0507b63abda4f56ddff1305ffaa8e03ae083 +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 0aa32df5f5602aee07a126de3b6108679a01e1b4e89c2dc62431eeb25ed73e4b +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3f6e536005f370d1f76522108727edf17b58477c4251e64a9749c543d0a27b27 +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0ad3e557d833c7bd451acd939473faf86c0bdb571426c8ec5be6f0781fc51f7e +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 1abad769c6cbad4123a911553b6e7852138fc045cf42b1fb85534fd5c8b7cddd +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 3b6909a05dbf22befee2b044abcd8be253ec04353872409056b582ed8ab676e9 +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 3f744b5a1aea28e70d8ad46f3327904a134f8a4051fd9dfa111fd1f5d5c938c9 +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 3d5449b2fe7e68a890240a11344fe522edcaea8796292af2d0d8fb99b79db040 +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 3b3fabae42dffc45164e657541c6b93696e8f3fcdfb4760f33ce254e2256c55b +MUL Fq 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 2d7db430e8803ea69f052e2842768f1b94f4de6d72a0fd3c4daac60d51d4d068 +SQR Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 04a79fe0cdfaa798f1a3dd8da208e41b79987431a7264d941832206dceae62b2 +FROM Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 25ea051264f6374dacdf8cb0da3ef5e1f7f05de4a4e1dc32d723436978cfe238 +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 0000000000000000000000000000000000000000000000000000000000000001 25ea051264f6374dacdf8cb0da3ef5e1f7f05de4a4e1dc32d723436978cfe238 +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 07945afd7e00a6ecaae30dbeb11ac138e9070a556c84c5f4aef2f319fb865fa2 +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 11a0830b593802f951f6f8fe756548c8d841da513ea0771876a98bb914291f34 +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 1a15faed9b09c8b25320734f25c10a1e2a563b1764b2ccaab523a7b787301dc9 +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 000000000000000000000000000000000000000000000000ffffffffffffffff 06f5879e7548be9436c2abeb5db509810c5d405277106fec6a6b9256f3574092 +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 4000000000000000000000000000000000000000000000000000000000000000 049a2bd27b9b331284522c7cbc8a91687e2221820bee830d4de6a0df5e838533 +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 3db83389d2fdc8153f65cf02c73d84eb4fd4670fd63dec9e876bbf8d1e344642 +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1eb026c016a4fbc4d7729fcbe24b9b86a8785c9970a14fb8030a4896e5b3a2fc +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 3b65d42d8464cced7badd38343756e97a4247779fda625d03e604a41a17c7ace +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 0ee9cb3f0c351f50055b7dd7ae3544e2a01c48185ebf81b388f231fab7cab006 +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 193b8747b4746b70f877067f44e731bdfa6932f2e629d4909748eb6234c0a751 +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 03efd48ce6c15c4f257ad17a20e64d1c1a6215ad1e97f54e0f7e2ce750c5441a +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 3b3fabae42dffc45164e657541c6b93696e8f3fcdfb4760f33ce254e2256c55b +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 04a79fe0cdfaa798f1a3dd8da208e41b79987431a7264d941832206dceae62b2 +MUL Fq 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3fbc4473858d96888a4cf4f26122be6d5452e97f2372b0740ea8da1591130845 +SQR Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3e0a34d529799ca3bb2cd3d706454717da0139fab7c3ec1918efdc79a0f7527f +FROM Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3d85627c34d2eae5be810b80707f6b2b0298cf948bd293c575c04f6327c7fd37 +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0000000000000000000000000000000000000000000000000000000000000001 3d85627c34d2eae5be810b80707f6b2b0298cf948bd293c575c04f6327c7fd37 +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 0fea57e1d7583502228891684693b1965d038faf2fd53ebf2dc9e5ec41ca2ca0 +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 015fc1fe4f6bc49f7f332185abed51d9d68235db8e6e529e7701dbe27fe1cd65 +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 027a9d83cb2d151a417ef47f8f8094d51fadc9677dc2151816869bbdd83802ca +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 000000000000000000000000000000000000000000000000ffffffffffffffff 00fba9043bac804523250acf5718e5fa5f27a4762881d669ede2565604ec5733 +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 4000000000000000000000000000000000000000000000000000000000000000 02bf53bdc23a2a747c90e3e3ed389e5d8e77d8428bb6a45fe99705d8bcb3fbfa +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 2420b3d392c5663f81c5e7e0d2cc98db3cb0725047f4d0c9828c32b1163a561f +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0539f1418d673f8ebe0fd8637cb93332ae25a1aa0978b978001da19694ebfec4 +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 3d40ac423dc5d58b836f1c1c12c761a293cec0b97dde047da2afe548434c0407 +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3c3c3c27e13c21e0e10ff7c33cd237023c3c3c3ce13c21fb3c3c279ce13c3a5b 3d32c8fb7d3d545107b4a69a4c5b2e75eab93d6f80b3cd86eee20d43663e5339 +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 2d5183d900d08ed0364c63f598e2faf5d2e7f1720fe729ad0fd43a9691fb7685 0209da84c6f912d00000b696ba1b54f5ca8ef4ab4e7d28f5b128d1b75aa555cb +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 228d15317e3b59a0b325ff33eff9b7aed2e1d17fb3cfc39437ed6db762ebf9d4 3eb73a2da6c346e9eefbb70091ae4f358ab2d0eef6bed877e8232e30747a4648 +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 14b06aa09f30e10aeb94c9b1ae30141e72172b9fb8f9852c1cab294080eb8209 2d7db430e8803ea69f052e2842768f1b94f4de6d72a0fd3c4daac60d51d4d068 +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 1268af49ee6ccc4a1148b1f2f22a45a1f88886082fba0c35379a837d7a0e14cc 3fbc4473858d96888a4cf4f26122be6d5452e97f2372b0740ea8da1591130845 +MUL Fq 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 0afd4ef708e8a9d1f2438f8fb4e2797639df610a2eda917fa65c1762f2cfefe8 3e0a34d529799ca3bb2cd3d706454717da0139fab7c3ec1918efdc79a0f7527f +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000001 20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59083 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59083 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 3ffffffffffffffeffffffffffffffff992c350be34205675b2b3e9cfffffffc +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffc +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 096d41af7ccfdaa97fae231004ccf590f0d5a72daf6cba5a2db2258300000013 +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 096d41af7ccfdaa97fae231004ccf590f0d5a72daf6cba5a2db2258300000013 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 3e7055f0f197b81f0950abbb8948d5d39bc7300f5c1ea51f903bb43e249dae3e +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3e7055f0f197b81f0950abbb8948d5d39bc7300f5c1ea51f903bb43e249dae3e +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7e +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7e +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000000000000000000000ffffffffffffffff 07e9cb8457139a3fa1deafb45f6c1b6c96dd429b75015516ab5e093eebac54cb +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 07e9cb8457139a3fa1deafb45f6c1b6c96dd429b75015516ab5e093eebac54cb +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 4000000000000000000000000000000000000000000000000000000000000000 0fffffffffffffffffffffffffffffffe64b0d42f8d08159d6cacfa73fffffff +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0fffffffffffffffffffffffffffffffe64b0d42f8d08159d6cacfa73fffffff +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 29c87b38b67fb5ac347f03908050df140c12a741f82d57c70dc6286f8f5debcd +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 29c87b38b67fb5ac347f03908050df150c12a741f82d57c70dc6286f8f5debcd +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 2f7a89dd176479535790be58c050df12acd8ee6a9696834537e47384ce1a6f7d +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 2f7a89dd176479535790be58c050df13acd8ee6a9696834537e47384ce1a6f7d +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 300000000000000000000000000000003bfb8bb910c42783b57c1b79c0000002 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 300000000000000000000000000000003bfb8bb910c42783b57c1b79c0000002 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1f7a89dd176479535790be58c050df12c68de1279dc601eb6119a3dd8e1a6f7d +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1f7a89dd176479535790be58c050df12c68de1279dc601eb6119a3dd8e1a6f7d +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 d790be58c050df12b5b20ea460e4c3a70d6a05901f3003f72974af7da26e1ab1 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1790be58c050df13b5b20ea460e4c3a62fb09e8c28c4acd4b5bb9a9ea26e1ab2 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff c28c44a5576479521790be58c050df1294c8c9a26e4db0782ebd7cee0a8760df +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff c28c44a5576479521790be58c050df1394c8c9a26e4db0782ebd7cee0a8760df +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000000000000000000000000000000000000000000000 e311bac83ffffffebffffffffffffffff0818176da1c576a59eac4317c6cf162 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e311bac83ffffffebffffffffffffffff0818176da1c576a59eac4317c6cf162 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59083 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59083 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 0000000000000000000000000000000000000000000000000000000000000001 286f41a73faf20ec4a4df15b9f1b3c58f295fa6fe0cffc07d68b50825d91e54f +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 286f41a73faf20ec4a4df15b9f1b3c58f295fa6fe0cffc07d68b50825d91e54f +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 3ffffffffffffffeffffffffffffffff992c350be34205665b2b3e9cfffffffd +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 3fffffffffffffffffffffffffffffff992c350be34205665b2b3e9cfffffffd +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 096d41af7ccfdaaa08c887002b1f990698d6efc1891a16e7fc9678ff0000000f +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 096d41af7ccfdaaa08c887002b1f990698d6efc1891a16e7fc9678ff0000000f +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 082f7490699a9d38264ffc7bb2d7522e3583b391b7d582d6a9b76a4017dd18f2 +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 082f7490699a9d38264ffc7bb2d7522e3583b391b7d582d6a9b76a4017dd18f2 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 1790be58c050df13b5b20ea460e4c3a72fb09e8c28c4acd5b5bb9a9ea26e1ab2 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 1790be58c050df13b5b20ea460e4c3a72fb09e8c28c4acd5b5bb9a9ea26e1ab2 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 000000000000000000000000000000000000000000000000ffffffffffffffff 21deafb45f6c1b6c92a053dc20e4c3a7753564a6832c02b262681f30a3b19701 +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 21deafb45f6c1b6c92a053dc20e4c3a7753564a6832c02b262681f30a3b19701 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 4000000000000000000000000000000000000000000000000000000000000000 3fffffffffffffffffffffffffffffffffffffffffffffffc000000000000000 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 3fffffffffffffffffffffffffffffffffffffffffffffffc000000000000000 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 347f03908050df13f5b20ea460e4c3a73f2f1d154ea8556b5bd0d66d2601294f +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 347f03908050df13f5b20ea460e4c3a83f2f1d154ea8556b5bd0d66d2601294f +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1790be58c050df13b5b20ea460e4c3a60d6a05901f3003f7e974af7da26e1ab1 +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 1790be58c050df13b5b20ea460e4c3a70d6a05901f3003f7e974af7da26e1ab1 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 00000000000000000000000000000000224698fc0994a8ddcc46eb2100000001 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 00000000000000000000000000000000224698fc0994a8ddcc46eb2100000001 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1790be58c050df13b5b20ea460e4c3a62fb09e8c28c4acd4b5bb9a9ea26e1ab2 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 d790be58c050df12b5b20ea460e4c3a70d6a05901f3003f72974af7da26e1ab1 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 f5b20ea460e4c3a62311bac83fffffffba7b39e5a598aa2253537b6dfebc83b1 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 f5b20ea460e4c3a62311bac83fffffffba7b39e5a598aa2253537b6dfebc83b1 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff d790be58c050df12b5b20ea460e4c3a60d6a05901f3003f72974af7da26e1ab2 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 d790be58c050df12b5b20ea460e4c3a70d6a05901f3003f72974af7da26e1ab2 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 ffffffffffffffff000000000000000000000000000000000000000000000000 bffffffffffffffeffffffffffffffffddb96703f66b572173b914df00000000 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 bffffffffffffffeffffffffffffffffddb96703f66b572173b914df00000000 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 286f41a73faf20ec4a4df15b9f1b3c58f295fa6fe0cffc07d68b50825d91e54f +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 286f41a73faf20ec4a4df15b9f1b3c58f295fa6fe0cffc07d68b50825d91e54f +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000001 3d73bb5aa89b86ace86f41a73faf20ec6b37365d91b24f87d1428311f5789f20 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 3d73bb5aa89b86ace86f41a73faf20ec6b37365d91b24f87d1428311f5789f20 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 3ffffffffffffffeffffffffffffffff992c350be34205675b2b3e9cfffffffc +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 3ffffffffffffffeffffffffffffffff992c350be34205675b2b3e9cfffffffc +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 3a88ee337ccfdaad3640e16087fd1ae78b74636b990a825fed6704ea66b5723b +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 3a88ee337ccfdaad3640e16087fd1ae78b74636b990a825fed6704ea66b5723b +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 128c5784fabf23b20173141b1ae1430afb46d7d1d84397cf26c1ef1391979314 +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 128c5784fabf23b20173141b1ae1430afb46d7d1d84397cf26c1ef1391979314 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 028c44a5576479531790be58c050df13b70f629e77e25955bb04680f0a8760e1 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 028c44a5576479531790be58c050df13b70f629e77e25955bb04680f0a8760e1 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 000000000000000000000000000000000000000000000000ffffffffffffffff 2afb864c97139a3f61deafb45f6c1b6ca9a55d0e58b2555e918fb8916819462e +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 2afb864c97139a3f61deafb45f6c1b6ca9a55d0e58b2555e918fb8916819462e +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 4000000000000000000000000000000000000000000000000000000000000000 0fffffffffffffffbfffffffffffffffe64b0d42f8d08159d6cacfa73fffffff +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 0fffffffffffffffbfffffffffffffffe64b0d42f8d08159d6cacfa73fffffff +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 0cda3600f67fb5abf47f03908050df14fc9428b8d249af3067b0eca10bcadd30 +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 0cda3600f67fb5abf47f03908050df14fc9428b8d249af3067b0eca10bcadd30 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 128c44a557647952d790be58c050df139d5a6fe170b2daaf91cf37b64a8760e0 +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 128c44a557647952d790be58c050df139d5a6fe170b2daaf91cf37b64a8760e0 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 300000000000000040000000000000003bfb8bb910c42783b57c1b79c0000002 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 300000000000000040000000000000003bfb8bb910c42783b57c1b79c0000002 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff c28c44a5576479521790be58c050df1394c8c9a26e4db0782ebd7cee0a8760df +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff c28c44a5576479521790be58c050df1294c8c9a26e4db0782ebd7cee0a8760df +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 d790be58c050df12b5b20ea460e4c3a70d6a05901f3003f72974af7da26e1ab2 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff d790be58c050df12b5b20ea460e4c3a60d6a05901f3003f72974af7da26e1ab2 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff e59dff6d97647950d790be58c050df14a790e41551feb0c014ef2c4086f45243 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff e59dff6d97647950d790be58c050df14a790e41551feb0c014ef2c4086f45243 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000000000000000000000000000000000000000000000 e311bac83ffffffdc000000000000000f0818176da1c576a59eac4317c6cf162 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff e311bac83ffffffdc000000000000000f0818176da1c576a59eac4317c6cf162 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 3d73bb5aa89b86ace86f41a73faf20ec6b37365d91b24f87d1428311f5789f20 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 3d73bb5aa89b86ace86f41a73faf20ec6b37365d91b24f87d1428311f5789f20 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 ffffffffffffffff000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000001 1cee4537c000000040000000000000000f7e7e8925e3a895a6153bce83930e9e +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 ffffffffffffffff000000000000000000000000000000000000000000000000 1cee4537c000000040000000000000000f7e7e8925e3a895a6153bce83930e9e +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 3ffffffffffffffeffffffffffffffff992c350be34205675b2b3e9cfffffffd +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd ffffffffffffffff000000000000000000000000000000000000000000000000 3ffffffffffffffeffffffffffffffff992c350be34205675b2b3e9cfffffffd +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 3a88ee337ccfdaad3640e16087fd1ae70259ff7b72b7dee9bc4b586666b57237 +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f ffffffffffffffff000000000000000000000000000000000000000000000000 3a88ee337ccfdaad3640e16087fd1ae70259ff7b72b7dee9bc4b586666b57237 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 1bf99934778efe5b8121372b1fae389b63021b0f615daeb32358681291979323 +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c ffffffffffffffff000000000000000000000000000000000000000000000000 1bf99934778efe5b8121372b1fae389b63021b0f615daeb32358681291979323 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 2311bac83fffffffc00000000000000012c81a72e3b10047e631af527c6cf163 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 ffffffffffffffff000000000000000000000000000000000000000000000000 2311bac83fffffffc00000000000000012c81a72e3b10047e631af527c6cf163 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000ffffffffffffffff 2311bac83fffffffc00000000000000012c81a72e3b10048e631af527c6cf162 +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff ffffffffffffffff000000000000000000000000000000000000000000000000 2311bac83fffffffc00000000000000012c81a72e3b10048e631af527c6cf162 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 4000000000000000000000000000000000000000000000000000000000000000 3fffffffffffffffc00000000000000000000000000000000000000000000000 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 ffffffffffffffff000000000000000000000000000000000000000000000000 3fffffffffffffffc00000000000000000000000000000000000000000000000 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 2311bac83fffffffc00000000000000112c81a72e3b10046e631af527c6cf163 +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff ffffffffffffffff000000000000000000000000000000000000000000000000 2311bac83fffffffc00000000000000112c81a72e3b10046e631af527c6cf163 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 2311bac83fffffff7ffffffffffffffff0818176da1c576a59eac4317c6cf162 +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000000000000000000000000000000000000000000000 2311bac83fffffff7ffffffffffffffff0818176da1c576a59eac4317c6cf162 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 00000000000000004000000000000000224698fc0994a8dd8c46eb2100000001 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 ffffffffffffffff000000000000000000000000000000000000000000000000 00000000000000004000000000000000224698fc0994a8dd8c46eb2100000001 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff e311bac83ffffffebffffffffffffffff0818176da1c576a59eac4317c6cf162 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000000000000000000000000000000000000000000000 e311bac83ffffffebffffffffffffffff0818176da1c576a59eac4317c6cf162 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 bffffffffffffffeffffffffffffffffddb96703f66b572173b914df00000000 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 ffffffffffffffff000000000000000000000000000000000000000000000000 bffffffffffffffeffffffffffffffffddb96703f66b572173b914df00000000 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff e311bac83ffffffdc000000000000000f0818176da1c576a59eac4317c6cf162 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffff000000000000000000000000000000000000000000000000 e311bac83ffffffdc000000000000000f0818176da1c576a59eac4317c6cf162 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 ffffffffffffffff000000000000000000000000000000000000000000000000 bffffffffffffffe0000000000000000ddb96703f66b572273b914deffffffff +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 ffffffffffffffff000000000000000000000000000000000000000000000000 bffffffffffffffe0000000000000000ddb96703f66b572273b914deffffffff +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 ffffffffffffffff000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 1cee4537c000000040000000000000000f7e7e8925e3a895a6153bce83930e9e +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 ffffffffffffffff000000000000000000000000000000000000000000000000 1cee4537c000000040000000000000000f7e7e8925e3a895a6153bce83930e9e +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 000000000000000000000000000000000000000000000000ffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 4000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 ffffffffffffffff000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 0000000000000000000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 0000000000000000000000000000000000000000000000000000000000000001 1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f +MUL Fq 0000000000000000000000000000000000000000000000000000000000000001 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 0000000000000000000000000000000000000000000000000000000000000001 +MUL Fq 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 0000000000000000000000000000000000000000000000000000000000000001 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd +MUL Fq 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 3fffffffffffffffffffffffffffffff992c350be34205675b2b3e9cfffffffd +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f +MUL Fq 07dd97a06e6792c888fececb8e15cb63e13bda50dba41326008b421c249dae4c 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 096d41af7ccfdaa97fae231004ccf59067bb433d891a16e3fc9678ff0000000f +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59082 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59082 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 000000000000000000000000000000000000000000000000ffffffffffffffff 3816347ba8ec65c05e21504ba093e4938b695660949353c7e0e8e1e21453ab35 +MUL Fq 000000000000000000000000000000000000000000000000ffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 3816347ba8ec65c05e21504ba093e4938b695660949353c7e0e8e1e21453ab35 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 4000000000000000000000000000000000000000000000000000000000000000 3000000000000000000000000000000019b4f2bd072f7ea629353058c0000001 +MUL Fq 4000000000000000000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 3000000000000000000000000000000019b4f2bd072f7ea629353058c0000001 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 163784c749804a53cb80fc6f7faf20ec1633f1ba116751167e80c2b170a21433 +MUL Fq 00000000000000000000000000000000ffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 163784c749804a53cb80fc6f7faf20ec1633f1ba116751167e80c2b170a21433 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 10857622e89b86aca86f41a73faf20ec5327119569697cbac81b8c7b31e59082 +MUL Fq 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 10857622e89b86aca86f41a73faf20ec5327119569697cbac81b8c7b31e59082 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 100000000000000000000000000000000891a63f02652a376311bac840000000 +MUL Fq 00000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 100000000000000000000000000000000891a63f02652a376311bac840000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59083 +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 20857622e89b86aca86f41a73faf20ec5bb8b7d46bcea6f22b2d474371e59083 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 286f41a73faf20ec4a4df15b9f1b3c58f295fa6fe0cffc07d68b50825d91e54f +MUL Fq ffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 286f41a73faf20ec4a4df15b9f1b3c58f295fa6fe0cffc07d68b50825d91e54f +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 3d73bb5aa89b86ace86f41a73faf20ec6b37365d91b24f87d1428311f5789f20 +MUL Fq fffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 3d73bb5aa89b86ace86f41a73faf20ec6b37365d91b24f87d1428311f5789f20 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 ffffffffffffffff000000000000000000000000000000000000000000000000 1cee4537c000000040000000000000000f7e7e8925e3a895a6153bce83930e9e +MUL Fq ffffffffffffffff000000000000000000000000000000000000000000000000 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 1cee4537c000000040000000000000000f7e7e8925e3a895a6153bce83930e9e +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 0000000000000000000000000000000000000000000000000000000000000000 +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f +MUL Fq 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 40000000000000000000000000000000224698fc0994a8dd8c46eb2100000002 1f7a89dd176479535790be58c050df13c68de1279dc601eb6119a3dd8e1a6f7f diff --git a/CompElliptic/Asm/AArch64/vendor/pasta_mul-armv8.S b/CompElliptic/Asm/AArch64/vendor/pasta_mul-armv8.S new file mode 100644 index 0000000..4321cf1 --- /dev/null +++ b/CompElliptic/Asm/AArch64/vendor/pasta_mul-armv8.S @@ -0,0 +1,474 @@ +// Copyright Supranational LLC +// Licensed under the Apache License, Version 2.0, see LICENSE-APACHE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Adapted from the pre-generated Mach-O assembly in Semolina v0.1.4: +// https://github.com/supranational/semolina/blob/v0.1.4/src/mach-o/pasta_mul-armv8.S +// +// Only Montgomery multiplication, squaring, conversion, and their shared +// reduction helper are retained. Symbols are renamed for this crate. The +// implementation relies on both Pasta moduli having limb 2 equal to zero and +// limb 3 equal to 2^62. + +// All field elements and moduli are four little-endian 64-bit limbs. `inv` is +// -modulus[0]^-1 mod 2^64. The routines implement Montgomery reduction with +// R = 2^256. Registers named as limbs below always list the least-significant +// limb first. +// +// Apple AArch64 argument registers: +// +// - mul: x0 = out, x1 = lhs, x2 = rhs, x3 = modulus, x4 = inv +// - square: x0 = out, x1 = value, x2 = modulus, x3 = inv +// - from_mont: x0 = out, x1 = value, x2 = modulus, x3 = inv +// +// The code has no secret-dependent branches or memory accesses. Conditional +// reductions use `csel` after a full-width subtraction. + +.text + +.globl _pasta_curves_mul_mont_pasta +.private_extern _pasta_curves_mul_mont_pasta + +.align 5 +_pasta_curves_mul_mont_pasta: + stp x29,x30,[sp,#-64]! // Allocate frame; save frame pointer and LR. + add x29,sp,#0 // Set the frame pointer to the new stack top. + stp x19,x20,[sp,#16] // Preserve callee-saved accumulator limbs 0-1. + stp x21,x22,[sp,#32] // Preserve callee-saved accumulator limbs 2-3. + stp x23,x24,[sp,#48] // Preserve the carry limb and paired x24. + + ldp x10,x11,[x1] // Load lhs limbs a[0] and a[1]. + ldr x9,[x2] // Load rhs limb b[0]. + ldp x12,x13,[x1,#16] // Load lhs limbs a[2] and a[3]. + + // Form the five-limb product a * b[0] in x19..x23. + mul x19,x10,x9 // x19 = low(a[0] * b[0]). + ldp x5,x6,[x3] // Load modulus limbs p[0] and p[1]. + mul x20,x11,x9 // x20 = low(a[1] * b[0]). + ldp x7,x8,[x3,#16] // Load p[2] = 0 and p[3] = 2^62. + mul x21,x12,x9 // x21 = low(a[2] * b[0]). + mul x22,x13,x9 // x22 = low(a[3] * b[0]). + + umulh x14,x10,x9 // x14 = high(a[0] * b[0]). + umulh x15,x11,x9 // x15 = high(a[1] * b[0]). + mul x3,x4,x19 // q = x19 * inv mod 2^64. + umulh x16,x12,x9 // x16 = high(a[2] * b[0]). + umulh x17,x13,x9 // x17 = high(a[3] * b[0]). + adds x20,x20,x14 // Add high(a[0] * b[0]) into limb 1. + // low(q * p[0]) cancels x19 and is discarded by the limb shift. + adcs x21,x21,x15 // Add high(a[1] * b[0]) and carry. + mul x15,x6,x3 // x15 = low(q * p[1]). + adcs x22,x22,x16 // Add high(a[2] * b[0]) and carry. + // q * p[2] is zero because p[2] = 0. + adc x23,xzr,x17 // Finish a * b[0] with its fifth limb. + lsl x17,x3,#62 // x17 = low(q * p[3]). + ldr x9,[x2,8*1] // Load rhs limb b[1] for the next round. + // Carry from x19 + low(q*p[0]) is one exactly when x19 is nonzero. + subs xzr,x19,#1 // Set that carry without computing the zero sum. + umulh x14,x5,x3 // x14 = high(q * p[0]). + adcs x20,x20,x15 // Add low(q * p[1]) and cancellation carry. + umulh x15,x6,x3 // x15 = high(q * p[1]). + adcs x21,x21,xzr // Propagate carry; p[2]'s product is zero. + // high(q * p[2]) is zero. + adcs x22,x22,x17 // Add low(q * p[3]) and carry. + lsr x17,x3,#2 // x17 = high(q * p[3]). + adc x23,x23,xzr // Propagate carry into the fifth limb. + + // Drop the cancelled low limb: (a*b[0] + q*p) / 2^64. + adds x19,x20,x14 // New limb 0 includes high(q * p[0]). + mul x14,x10,x9 // x14 = low(a[0] * b[1]). + adcs x20,x21,x15 // New limb 1 includes high(q * p[1]). + mul x15,x11,x9 // x15 = low(a[1] * b[1]). + adcs x21,x22,xzr // New limb 2; p[2] contributes zero. + mul x16,x12,x9 // x16 = low(a[2] * b[1]). + adcs x22,x23,x17 // New limb 3 includes high(q * p[3]). + mul x17,x13,x9 // x17 = low(a[3] * b[1]). + adc x23,xzr,xzr // Capture the reduction carry as limb 4. + + // Round 1: add a * b[1] to the reduced accumulator. + adds x19,x19,x14 // Add low(a[0] * b[1]) to limb 0. + umulh x14,x10,x9 // x14 = high(a[0] * b[1]). + adcs x20,x20,x15 // Add low(a[1] * b[1]) and carry. + umulh x15,x11,x9 // x15 = high(a[1] * b[1]). + adcs x21,x21,x16 // Add low(a[2] * b[1]) and carry. + mul x3,x4,x19 // q = current limb 0 * inv mod 2^64. + umulh x16,x12,x9 // x16 = high(a[2] * b[1]). + adcs x22,x22,x17 // Add low(a[3] * b[1]) and carry. + umulh x17,x13,x9 // x17 = high(a[3] * b[1]). + adc x23,x23,xzr // Propagate multiplication carry to limb 4. + + adds x20,x20,x14 // Add high(a[0] * b[1]) to limb 1. + // low(q * p[0]) cancels x19. + adcs x21,x21,x15 // Add high(a[1] * b[1]) and carry. + mul x15,x6,x3 // x15 = low(q * p[1]). + adcs x22,x22,x16 // Add high(a[2] * b[1]) and carry. + // low(q * p[2]) is zero. + adc x23,x23,x17 // Add high(a[3] * b[1]) and final carry. + lsl x17,x3,#62 // x17 = low(q * p[3]). + ldr x9,[x2,8*2] // Load rhs limb b[2] for the next round. + subs xzr,x19,#1 // Set the low-limb cancellation carry. + umulh x14,x5,x3 // x14 = high(q * p[0]). + adcs x20,x20,x15 // Add low(q * p[1]) and cancellation carry. + umulh x15,x6,x3 // x15 = high(q * p[1]). + adcs x21,x21,xzr // Propagate carry across zero p[2]. + // high(q * p[2]) is zero. + adcs x22,x22,x17 // Add low(q * p[3]) and carry. + lsr x17,x3,#2 // x17 = high(q * p[3]). + adc x23,x23,xzr // Propagate carry to limb 4. + + // Shift after round 1 while starting a * b[2]. + adds x19,x20,x14 // New limb 0 includes high(q * p[0]). + mul x14,x10,x9 // x14 = low(a[0] * b[2]). + adcs x20,x21,x15 // New limb 1 includes high(q * p[1]). + mul x15,x11,x9 // x15 = low(a[1] * b[2]). + adcs x21,x22,xzr // New limb 2; p[2] contributes zero. + mul x16,x12,x9 // x16 = low(a[2] * b[2]). + adcs x22,x23,x17 // New limb 3 includes high(q * p[3]). + mul x17,x13,x9 // x17 = low(a[3] * b[2]). + adc x23,xzr,xzr // Capture the reduction carry as limb 4. + + // Round 2: add a * b[2] and cancel the resulting low limb. + adds x19,x19,x14 // Add low(a[0] * b[2]) to limb 0. + umulh x14,x10,x9 // x14 = high(a[0] * b[2]). + adcs x20,x20,x15 // Add low(a[1] * b[2]) and carry. + umulh x15,x11,x9 // x15 = high(a[1] * b[2]). + adcs x21,x21,x16 // Add low(a[2] * b[2]) and carry. + mul x3,x4,x19 // q = current limb 0 * inv mod 2^64. + umulh x16,x12,x9 // x16 = high(a[2] * b[2]). + adcs x22,x22,x17 // Add low(a[3] * b[2]) and carry. + umulh x17,x13,x9 // x17 = high(a[3] * b[2]). + adc x23,x23,xzr // Propagate multiplication carry to limb 4. + + adds x20,x20,x14 // Add high(a[0] * b[2]) to limb 1. + // low(q * p[0]) cancels x19. + adcs x21,x21,x15 // Add high(a[1] * b[2]) and carry. + mul x15,x6,x3 // x15 = low(q * p[1]). + adcs x22,x22,x16 // Add high(a[2] * b[2]) and carry. + // low(q * p[2]) is zero. + adc x23,x23,x17 // Add high(a[3] * b[2]) and final carry. + lsl x17,x3,#62 // x17 = low(q * p[3]). + ldr x9,[x2,8*3] // Load rhs limb b[3] for the last round. + subs xzr,x19,#1 // Set the low-limb cancellation carry. + umulh x14,x5,x3 // x14 = high(q * p[0]). + adcs x20,x20,x15 // Add low(q * p[1]) and cancellation carry. + umulh x15,x6,x3 // x15 = high(q * p[1]). + adcs x21,x21,xzr // Propagate carry across zero p[2]. + // high(q * p[2]) is zero. + adcs x22,x22,x17 // Add low(q * p[3]) and carry. + lsr x17,x3,#2 // x17 = high(q * p[3]). + adc x23,x23,xzr // Propagate carry to limb 4. + + // Shift after round 2 while starting a * b[3]. + adds x19,x20,x14 // New limb 0 includes high(q * p[0]). + mul x14,x10,x9 // x14 = low(a[0] * b[3]). + adcs x20,x21,x15 // New limb 1 includes high(q * p[1]). + mul x15,x11,x9 // x15 = low(a[1] * b[3]). + adcs x21,x22,xzr // New limb 2; p[2] contributes zero. + mul x16,x12,x9 // x16 = low(a[2] * b[3]). + adcs x22,x23,x17 // New limb 3 includes high(q * p[3]). + mul x17,x13,x9 // x17 = low(a[3] * b[3]). + adc x23,xzr,xzr // Capture the reduction carry as limb 4. + + // Round 3: add a * b[3] and perform the last Montgomery cancellation. + adds x19,x19,x14 // Add low(a[0] * b[3]) to limb 0. + umulh x14,x10,x9 // x14 = high(a[0] * b[3]). + adcs x20,x20,x15 // Add low(a[1] * b[3]) and carry. + umulh x15,x11,x9 // x15 = high(a[1] * b[3]). + adcs x21,x21,x16 // Add low(a[2] * b[3]) and carry. + mul x3,x4,x19 // q = current limb 0 * inv mod 2^64. + umulh x16,x12,x9 // x16 = high(a[2] * b[3]). + adcs x22,x22,x17 // Add low(a[3] * b[3]) and carry. + umulh x17,x13,x9 // x17 = high(a[3] * b[3]). + adc x23,x23,xzr // Propagate multiplication carry to limb 4. + + adds x20,x20,x14 // Add high(a[0] * b[3]) to limb 1. + // low(q * p[0]) cancels x19. + adcs x21,x21,x15 // Add high(a[1] * b[3]) and carry. + mul x15,x6,x3 // x15 = low(q * p[1]). + adcs x22,x22,x16 // Add high(a[2] * b[3]) and carry. + // low(q * p[2]) is zero. + adc x23,x23,x17 // Add high(a[3] * b[3]) and final carry. + lsl x17,x3,#62 // x17 = low(q * p[3]). + subs xzr,x19,#1 // Set the low-limb cancellation carry. + umulh x14,x5,x3 // x14 = high(q * p[0]). + adcs x20,x20,x15 // Add low(q * p[1]) and cancellation carry. + umulh x15,x6,x3 // x15 = high(q * p[1]). + adcs x21,x21,xzr // Propagate carry across zero p[2]. + // high(q * p[2]) is zero. + adcs x22,x22,x17 // Add low(q * p[3]) and carry. + lsr x17,x3,#2 // x17 = high(q * p[3]). + adc x23,x23,xzr // Propagate carry to limb 4. + + // Shift out the fourth cancelled limb. x23 records any 257th bit. + adds x19,x20,x14 // Final candidate limb 0. + adcs x20,x21,x15 // Final candidate limb 1. + adcs x21,x22,xzr // Final candidate limb 2. + adcs x22,x23,x17 // Final candidate limb 3. + adc x23,xzr,xzr // Final candidate carry limb. + + // Subtract the five-limb value p = [p0,p1,0,p3,0]. + subs x14,x19,x5 // Tentative result limb 0 = candidate - p[0]. + sbcs x15,x20,x6 // Tentative result limb 1 minus p[1]. + sbcs x16,x21,xzr // Tentative result limb 2; p[2] is zero. + sbcs x17,x22,x8 // Tentative result limb 3 minus p[3]. + sbcs xzr,x23,xzr // Include the carry limb in the comparison. + + // `lo` means subtraction borrowed, so retain the original candidate. + csel x19,x19,x14,lo // Select canonical output limb 0. + csel x20,x20,x15,lo // Select canonical output limb 1. + csel x21,x21,x16,lo // Select canonical output limb 2. + csel x22,x22,x17,lo // Select canonical output limb 3. + + stp x19,x20,[x0] // Store output limbs 0 and 1. + stp x21,x22,[x0,#16] // Store output limbs 2 and 3. + + ldp x19,x20,[x29,#16] // Restore callee-saved x19 and x20. + ldp x21,x22,[x29,#32] // Restore callee-saved x21 and x22. + ldp x23,x24,[x29,#48] // Restore callee-saved x23 and x24. + ldr x29,[sp],#64 // Restore frame pointer and release the frame. + ret // Return; x30 still holds the caller's address. + +.globl _pasta_curves_sqr_mont_pasta +.private_extern _pasta_curves_sqr_mont_pasta + +.align 5 +_pasta_curves_sqr_mont_pasta: + .long 3573752639 // `paciasp`: sign LR with the entry stack pointer. + stp x29,x30,[sp,#-48]! // Allocate frame; save frame pointer and signed LR. + add x29,sp,#0 // Set the frame pointer to the new stack top. + stp x19,x20,[sp,#16] // Preserve callee-saved product limbs 4 and 5. + stp x21,x22,[sp,#32] // Preserve callee-saved product limbs 6 and 7. + + ldp x5,x6,[x1] // Load value limbs a[0] and a[1]. + ldp x7,x8,[x1,#16] // Load value limbs a[2] and a[3]. + mov x4,x3 // Move inv into the helper's expected register. + + //////////////////////////////////////////////////////////////// + // | | | | | |a1*a0| | + // | | | | |a2*a0| | | + // | |a3*a2|a3*a0| | | | + // | | | |a2*a1| | | | + // | | |a3*a1| | | | | + // *| | | | | | | | 2| + // +|a3*a3|a2*a2|a1*a1|a0*a0| + // |--+--+--+--+--+--+--+--| + // |A7|A6|A5|A4|A3|A2|A1|A0| + // A0..A7 map to x10,x11,x12,x13,x19,x20,x21,x22. + // + // "can't overflow" below mark carrying into high part of + // multiplication result, which can't overflow, because it + // can never be all ones. + + mul x11,x6,x5 // x11 = low(a[1] * a[0]). + umulh x15,x6,x5 // x15 = high(a[1] * a[0]). + mul x12,x7,x5 // x12 = low(a[2] * a[0]). + umulh x16,x7,x5 // x16 = high(a[2] * a[0]). + mul x13,x8,x5 // x13 = low(a[3] * a[0]). + umulh x19,x8,x5 // x19 = high(a[3] * a[0]). + + adds x12,x12,x15 // Fold high(a[1] * a[0]) into product limb 2. + mul x14,x7,x6 // x14 = low(a[2] * a[1]). + umulh x15,x7,x6 // x15 = high(a[2] * a[1]). + adcs x13,x13,x16 // Fold high(a[2] * a[0]) into product limb 3. + mul x16,x8,x6 // x16 = low(a[3] * a[1]). + umulh x17,x8,x6 // x17 = high(a[3] * a[1]). + adc x19,x19,xzr // Propagate carry into product limb 4. + + mul x20,x8,x7 // x20 = low(a[3] * a[2]). + umulh x21,x8,x7 // x21 = high(a[3] * a[2]). + + adds x15,x15,x16 // Combine terms contributing to product limb 4. + mul x10,x5,x5 // x10 = low(a[0]^2), product limb 0. + adc x16,x17,xzr // Combine terms contributing to product limb 5. + + adds x13,x13,x14 // Add low(a[2] * a[1]) into product limb 3. + umulh x5,x5,x5 // x5 = high(a[0]^2). + adcs x19,x19,x15 // Accumulate cross terms into product limb 4. + mul x15,x6,x6 // x15 = low(a[1]^2). + adcs x20,x20,x16 // Accumulate cross terms into product limb 5. + umulh x6,x6,x6 // x6 = high(a[1]^2). + adc x21,x21,xzr // Propagate carry into product limb 6. + + adds x11,x11,x11 // Double cross-term product limb 1. + mul x16,x7,x7 // x16 = low(a[2]^2). + adcs x12,x12,x12 // Double cross-term product limb 2. + umulh x7,x7,x7 // x7 = high(a[2]^2). + adcs x13,x13,x13 // Double cross-term product limb 3. + mul x17,x8,x8 // x17 = low(a[3]^2). + adcs x19,x19,x19 // Double cross-term product limb 4. + umulh x8,x8,x8 // x8 = high(a[3]^2). + adcs x20,x20,x20 // Double cross-term product limb 5. + adcs x21,x21,x21 // Double cross-term product limb 6. + adc x22,xzr,xzr // Capture the doubled cross-term carry in limb 7. + + // Add diagonal squares to obtain a^2 in x10,x11,x12,x13,x19..x22. + adds x11,x11,x5 // Add high(a[0]^2) to product limb 1. + adcs x12,x12,x15 // Add low(a[1]^2) to product limb 2. + adcs x13,x13,x6 // Add high(a[1]^2) to product limb 3. + adcs x19,x19,x16 // Add low(a[2]^2) to product limb 4. + adcs x20,x20,x7 // Add high(a[2]^2) to product limb 5. + adcs x21,x21,x17 // Add low(a[3]^2) to product limb 6. + adc x22,x22,x8 // Add high(a[3]^2) to product limb 7. + + // Reduce the lower four limbs; upper limbs remain in callee-saved regs. + bl L$pasta_curves_mul_by_1_mont_pasta // Reduce x10..x13 by R. + ldr x30,[x29,#8] // Restore signed LR clobbered by `bl`. + + // Add the untouched upper half, completing reduction of the 512-bit square. + adds x10,x10,x19 // Add original product limb 4 to result limb 0. + adcs x11,x11,x20 // Add original product limb 5 and carry. + adcs x12,x12,x21 // Add original product limb 6 and carry. + adcs x13,x13,x22 // Add original product limb 7 and carry. + adc x19,xzr,xzr // Capture a possible 257th candidate bit. + + // Tentatively subtract p as a five-limb value. + subs x14,x10,x5 // Tentative result limb 0 = candidate - p[0]. + sbcs x15,x11,x6 // Tentative result limb 1 minus p[1]. + sbcs x16,x12,x7 // Tentative result limb 2 minus p[2] = 0. + sbcs x17,x13,x8 // Tentative result limb 3 minus p[3]. + sbcs xzr,x19,xzr // Include the candidate carry in the comparison. + + // If subtraction borrowed (`lo`), keep the original candidate. + csel x10,x10,x14,lo // Select canonical output limb 0. + csel x11,x11,x15,lo // Select canonical output limb 1. + csel x12,x12,x16,lo // Select canonical output limb 2. + csel x13,x13,x17,lo // Select canonical output limb 3. + + stp x10,x11,[x0] // Store output limbs 0 and 1. + stp x12,x13,[x0,#16] // Store output limbs 2 and 3. + + ldp x19,x20,[x29,#16] // Restore callee-saved x19 and x20. + ldp x21,x22,[x29,#32] // Restore callee-saved x21 and x22. + ldr x29,[sp],#48 // Restore frame pointer and entry stack pointer. + .long 3573752767 // `autiasp`: authenticate LR with entry SP. + ret // Return through the authenticated address. + +.globl _pasta_curves_from_mont_pasta +.private_extern _pasta_curves_from_mont_pasta + +.align 5 +_pasta_curves_from_mont_pasta: + .long 3573752639 // `paciasp`: sign LR with the entry stack pointer. + stp x29,x30,[sp,#-16]! // Allocate frame; save frame pointer and signed LR. + add x29,sp,#0 // Set the frame pointer to the new stack top. + + mov x4,x3 // Move inv into the helper's expected register. + ldp x10,x11,[x1] // Load Montgomery residue limbs 0 and 1. + ldp x12,x13,[x1,#16] // Load Montgomery residue limbs 2 and 3. + + // Montgomery-reduce an implicit zero upper half: value * R^-1 mod p. + bl L$pasta_curves_mul_by_1_mont_pasta // Reduce x10..x13 by R. + ldr x30,[x29,#8] // Restore signed LR clobbered by `bl`. + + // The helper leaves p in x5..x8; one subtraction canonicalizes the result. + subs x14,x10,x5 // Tentative result limb 0 = candidate - p[0]. + sbcs x15,x11,x6 // Tentative result limb 1 minus p[1]. + sbcs x16,x12,x7 // Tentative result limb 2 minus p[2] = 0. + sbcs x17,x13,x8 // Tentative result limb 3 minus p[3]. + + // If subtraction borrowed (`lo`), keep the original candidate. + csel x10,x10,x14,lo // Select canonical integer limb 0. + csel x11,x11,x15,lo // Select canonical integer limb 1. + csel x12,x12,x16,lo // Select canonical integer limb 2. + csel x13,x13,x17,lo // Select canonical integer limb 3. + + stp x10,x11,[x0] // Store canonical integer limbs 0 and 1. + stp x12,x13,[x0,#16] // Store canonical integer limbs 2 and 3. + + ldr x29,[sp],#16 // Restore frame pointer and entry stack pointer. + .long 3573752767 // `autiasp`: authenticate LR with entry SP. + ret // Return through the authenticated address. + +.align 5 +L$pasta_curves_mul_by_1_mont_pasta: + // Entry: x10..x13 = t, x2 = p, x4 = inv. Each iteration chooses q_i + // so the current low limb plus q_i*p[0] is zero modulo 2^64, adds + // q_i*p, and discards that zero limb. On exit, x10..x13 contain + // (t + Q*p) / R, where Q has the four q_i as little-endian limbs. + + // Montgomery cancellation 0. + mul x3,x4,x10 // q = t[0] * inv mod 2^64. + ldp x5,x6,[x2] // Load modulus limbs p[0] and p[1]. + ldp x7,x8,[x2,#16] // Load p[2] = 0 and p[3] = 2^62. + // low(q * p[0]) cancels x10 and is discarded. + mul x15,x6,x3 // x15 = low(q * p[1]). + // q * p[2] is zero because p[2] = 0. + lsl x17,x3,#62 // x17 = low(q * p[3]). + // Carry from x10 + low(q*p[0]) is one exactly when x10 is nonzero. + subs xzr,x10,#1 // Set that cancellation carry. + umulh x14,x5,x3 // x14 = high(q * p[0]). + adcs x11,x11,x15 // Add low(q * p[1]) and cancellation carry. + umulh x15,x6,x3 // x15 = high(q * p[1]). + adcs x12,x12,xzr // Propagate carry across zero p[2]. + // high(q * p[2]) is zero. + adcs x13,x13,x17 // Add low(q * p[3]) and carry. + lsr x17,x3,#2 // x17 = high(q * p[3]). + adc x9,xzr,xzr // Save the carry above limb 3. + + // Shift out cancelled limb 0 and start cancellation 1. + adds x10,x11,x14 // New limb 0 includes high(q * p[0]). + adcs x11,x12,x15 // New limb 1 includes high(q * p[1]). + adcs x12,x13,xzr // New limb 2; p[2] contributes zero. + mul x3,x4,x10 // Next q = new limb 0 * inv mod 2^64. + adc x13,x9,x17 // New limb 3 includes high(q * p[3]). + // low(q * p[0]) cancels x10 and is discarded. + mul x15,x6,x3 // x15 = low(next q * p[1]). + // next q * p[2] is zero. + lsl x17,x3,#62 // x17 = low(next q * p[3]). + subs xzr,x10,#1 // Set the low-limb cancellation carry. + umulh x14,x5,x3 // x14 = high(next q * p[0]). + adcs x11,x11,x15 // Add low(next q * p[1]) and carry. + umulh x15,x6,x3 // x15 = high(next q * p[1]). + adcs x12,x12,xzr // Propagate carry across zero p[2]. + // high(next q * p[2]) is zero. + adcs x13,x13,x17 // Add low(next q * p[3]) and carry. + lsr x17,x3,#2 // x17 = high(next q * p[3]). + adc x9,xzr,xzr // Save the carry above limb 3. + + // Shift out cancelled limb 1 and start cancellation 2. + adds x10,x11,x14 // New limb 0 includes high(q * p[0]). + adcs x11,x12,x15 // New limb 1 includes high(q * p[1]). + adcs x12,x13,xzr // New limb 2; p[2] contributes zero. + mul x3,x4,x10 // Next q = new limb 0 * inv mod 2^64. + adc x13,x9,x17 // New limb 3 includes high(q * p[3]). + // low(q * p[0]) cancels x10 and is discarded. + mul x15,x6,x3 // x15 = low(next q * p[1]). + // next q * p[2] is zero. + lsl x17,x3,#62 // x17 = low(next q * p[3]). + subs xzr,x10,#1 // Set the low-limb cancellation carry. + umulh x14,x5,x3 // x14 = high(next q * p[0]). + adcs x11,x11,x15 // Add low(next q * p[1]) and carry. + umulh x15,x6,x3 // x15 = high(next q * p[1]). + adcs x12,x12,xzr // Propagate carry across zero p[2]. + // high(next q * p[2]) is zero. + adcs x13,x13,x17 // Add low(next q * p[3]) and carry. + lsr x17,x3,#2 // x17 = high(next q * p[3]). + adc x9,xzr,xzr // Save the carry above limb 3. + + // Shift out cancelled limb 2 and start cancellation 3. + adds x10,x11,x14 // New limb 0 includes high(q * p[0]). + adcs x11,x12,x15 // New limb 1 includes high(q * p[1]). + adcs x12,x13,xzr // New limb 2; p[2] contributes zero. + mul x3,x4,x10 // Final q = new limb 0 * inv mod 2^64. + adc x13,x9,x17 // New limb 3 includes high(q * p[3]). + // low(q * p[0]) cancels x10 and is discarded. + mul x15,x6,x3 // x15 = low(final q * p[1]). + // final q * p[2] is zero. + lsl x17,x3,#62 // x17 = low(final q * p[3]). + subs xzr,x10,#1 // Set the low-limb cancellation carry. + umulh x14,x5,x3 // x14 = high(final q * p[0]). + adcs x11,x11,x15 // Add low(final q * p[1]) and carry. + umulh x15,x6,x3 // x15 = high(final q * p[1]). + adcs x12,x12,xzr // Propagate carry across zero p[2]. + // high(final q * p[2]) is zero. + adcs x13,x13,x17 // Add low(final q * p[3]) and carry. + lsr x17,x3,#2 // x17 = high(final q * p[3]). + adc x9,xzr,xzr // Save the carry above limb 3. + + // Shift out cancelled limb 3 to finish division by R = 2^256. + adds x10,x11,x14 // Output limb 0 includes high(q * p[0]). + adcs x11,x12,x15 // Output limb 1 includes high(q * p[1]). + adcs x12,x13,xzr // Output limb 2; p[2] contributes zero. + adc x13,x9,x17 // Output limb 3 includes high(q * p[3]). + + ret // Return to square or from_mont through x30. diff --git a/README.md b/README.md index e450750..4a5ab9f 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,14 @@ Early work in progress. Present so far: together with a natively compilable Montgomery-limb kernel proven against them (`CompElliptic/Curves/Pasta/Fast/`, not imported by `CompElliptic.lean`). These interfaces are provisional: they are not guaranteed to remain public, and may be folded into the existing API - or otherwise changed incompatibly. + or otherwise changed incompatibly; +- a transcription of the AArch64 Pasta Montgomery routines that pasta_curves vendors from + Semolina, generated from the assembly over a small instruction-semantics module, with + reference vectors from the real routines checked by the kernel, and instruction-by-instruction + correctness proofs of the multiplication, of its shared reduction helper, and of the conversion + out of Montgomery form, the multiplication under each of its two operand contracts + (`CompElliptic/Asm/AArch64/`; `design/aarch64-pasta-mul-verification.md` states the remaining + correctness theorems). The library's general theorems depend only on the standard `propext` / `Classical.choice` / `Quot.sound` axioms. Facts specific to concrete fields and curves additionally depend on diff --git a/design/aarch64-pasta-mul-verification.md b/design/aarch64-pasta-mul-verification.md new file mode 100644 index 0000000..5d139ba --- /dev/null +++ b/design/aarch64-pasta-mul-verification.md @@ -0,0 +1,144 @@ +# Design: verifying pasta_curves' AArch64 Montgomery routines in CompElliptic + + +## Goal + +A machine-checked proof that the three routines zcash/pasta_curves#100 vendors from +Semolina v0.1.4 (`mul_mont_pasta`, `sqr_mont_pasta`, `from_mont_pasta`, plus their +shared `mul_by_1` helper) compute Montgomery multiplication, squaring, and conversion +on the Pasta fields, under the operand contracts they actually have. The proof is +about the instruction stream of `src/asm/pasta_mul-armv8.S` (310 instructions, blob +`4321cf159d9814a14afbdc5cf42265384150822f`, sha256 +`0bcd5fa67d4aef5043eb536fdefd41ce16e6f7fbac3e5e6ac4f7619b35fd5e85`), not about a +re-derivation of the algorithm. + +## Trust story + +What is trusted, beyond Lean's kernel and standard axioms: + +1. The instruction semantics module (`Semantics.lean`): about a dozen AArch64 + instructions modelled over 64-bit registers and the carry flag. Small, reviewable, + and cross-checked by executing the model on vectors produced by the real binary. +2. The transcription of the `.S` into Lean. Generated by a script from the vendored + file, never hand-typed; CI regenerates and diffs (same pattern as the field-file + generators). The generator is the same parser as the Python simulator that found + the accumulator wrap, so it has already been exercised against the hardware. +3. The reference vectors: outputs of the real assembly on an Apple M-series machine + at pasta_curves commit `8ad85e9fab7929f6236960e472f432a4bd9ccd74`, embedded as + kernel-checked examples (`decide +kernel`). These are concrete closed facts in + the sense of the README's trust discipline, and any independent run of the binary + reproduces them. + +Not modelled formally: the calling convention, stack frame, and memory-safety of +the FFI boundary. The model treats loads and stores as limb inputs and outputs. +Those aspects were reviewed by hand and are recorded as such in the module doc. + +## Layout + +``` +CompElliptic/Asm/AArch64/Semantics.lean registers, carry, instruction functions +CompElliptic/Asm/AArch64/PastaMul.lean GENERATED: the four routines as Lean defs +CompElliptic/Asm/AArch64/PastaMulVectors.lean GENERATED: reference vectors, kernel-checked +CompElliptic/Asm/AArch64/PastaMulSpec.lean the theorems +CompElliptic/Asm/AArch64/Pasta.lean instantiation at the two Pasta primes +CompElliptic/Asm/AArch64/vendor/pasta_mul-armv8.S vendored, Apache-2.0, hash pinned +scripts/gen_aarch64_pasta_mul.py parser + Lean emitter (+ simulator) +scripts/check_aarch64_pasta_mul.sh regenerate and diff, hash check (CI) +``` + +Namespace `CompElliptic.Asm.AArch64`, mirroring the path. + +## Value representation + +Registers are natural numbers, reduced modulo `2^64` by every instruction, and the +carry is a natural number that is `0` or `1`; each instruction is a function on `Nat` +(`mulLo a b = a * b % 2^64`, `umulh a b = a * b / 2^64`, `addc a b c = ((a+b+c) % 2^64, +(a+b+c) / 2^64)`, `subc` with AArch64's carry-means-no-borrow convention, `cselLo`). +Two reasons over `UInt64`. The reference vectors become kernel-checked theorems +(`by decide +kernel`, the kernel's GMP-accelerated `Nat` arithmetic), which is the +tier the README prefers over evaluation. And the proofs stay in `Nat`: `omega` +understands `%` and `/` by literals, so each carry chain is closed with no `toNat` +plumbing, the products `a * b` being the only atoms it does not see through; the limb +recompositions that relate those atoms are `ring` facts. No native execution speed is +needed, and the modules stay outside the precompiled lane. + +## Program shape and proof method + +The generator emits each routine as a chain of `let`s in a single function from the +input limbs (and modulus limbs and `inv`) to the output limbs. The proofs in +`PastaMulSpec.lean` follow that chain instruction by instruction, and their mechanical +part is generated too (`gen_aarch64_pasta_mul.py --skeleton `). The skeleton +unfolds the routine in the hypothesis that names its result. Then, for every +instruction, it extracts that instruction's `let`s from the hypothesis under unique +names, records the defining equation of the result (by `rfl`, in `%`/`/` form), makes +the locals opaque with `clear_value`, and derives from the equation the facts that later +steps need (the carry-chain equation `x + 2^64 * c = a + b + cin`, the range facts, the +product decomposition `lo + 2^64 * hi = a * b`), each an instance of one lemma, clearing +the `%`/`/` equation when nothing later needs it. The hand-written parts are the theorem +statements and the `-- BEGIN ... -- END` annotation blocks between instructions. A +block states the Montgomery round invariant that holds at that point and derives it +from the facts it names. `gen_aarch64_pasta_mul.py --check-spec` strips the blocks and +requires the rest of the proof to be the current skeleton, so an edit to the `.S` +regenerates the skeleton and the check fails loudly until the annotations are moved. + +Three measurements fixed this shape. `omega` given a whole reduction round at once, or +given the cancellation fact with its `%` terms still in it, runs for minutes without +finishing; given one carry step at a time, or linear equations only, it answers in +milliseconds. So each round block first rewrites the cancellation fact +`(t0 + p0 * q % 2^64) % 2^64 = 0` to the linear `t0 + lo = 2^64 * c`, using the ghost +low limb and the carry of `subs xzr, t0, #1`; it then shows that neither `adc` wraps; +and the invariant is a linear combination of the instruction equations, proved by +`omega` in a context cleared down to exactly those equations. `clear_value` reverts +every later local and re-checks the reverted context, so extracting all the `let`s up +front made each clear quadratic in the chain's length; the multiplication routine's 264 +locals exhausted the heartbeat budget, and extracting one instruction at a time, with +the rest of the chain still folded in the hypothesis, is what keeps every clear cheap. +What remains of the multiplication's cost is its sixty-odd `clear * -` calls in a +context of a thousand hypotheses, so that theorem raises its heartbeat budget. + +## Theorems + +With `p = p0 + 2^64 p1 + 2^192 · 2^62` (the modulus limbs are `[p0, p1, 0, 2^62]`, as +the code assumes) and `inv · p0 ≡ −1 (mod 2^64)`: + +* `mulBy1_spec` (proved): for every four-limb `t`, the shared reduction helper returns + limbs `r` below `2^64` with `2^256 · r = t + Q · p` for some `Q < 2^256`. So `r` is + congruent to `t · 2^−256` modulo `p`, and `r ≤ p`. +* `mulMont_spec` (proved): the output is below `p` and `output · 2^256 ≡ lhs · rhs (mod p)` + under two arithmetic conditions: `lhs · (rhs_i + 1) + p + 3 · 2^254 + 2^128 ≤ 2^320` + for each of `rhs_1`, `rhs_2`, `rhs_3` (the five-limb accumulator, which enters each + round below `lhs + p`, stays below `2^320` through the round's `adc`s), and + `lhs · rhs < 2^256 · p` (the final accumulator is below `2 · p`, which one conditional + subtraction reduces). Its two corollaries are the operand contracts: + `mulMont_spec_of_lhs_lt`, for `lhs < p` and any four-limb `rhs`, and + `mulMont_spec_of_rhs_lt`, for any four-limb `lhs` and `rhs < p` whose limbs 1 to 3 are + at most `2^64 − 3`. Whether `2^64 − 2` can wrap is not settled by these conditions. +* `sqr_spec` (to prove): if `a < p`, the output is below `p` and `output · 2^256 ≡ a² (mod p)`. +* `fromMont_spec` (proved): for every four-limb `a`, the output is below `p` and + `output · 2^256 ≡ a (mod p)`. No bound on `a` below `p` is needed: the helper's result is + at most `p`, and the conditional subtraction removes the one excess case. + +`Pasta.lean` instantiates these at `PALLAS_BASE_CARD` and `PALLAS_SCALAR_CARD` with +the crate's `MODULUS`, `INV`, `R2`, `R3` limbs pinned by `decide`, and states the +corollary the crate relies on: `mul lhs R2` and `mul lhs R3` are correct for every +256-bit `lhs`, because no limb 1 to 3 of `R2`/`R3` is above `2^64 − 3`. It also states +the negative: the witness pair is inside `lhs · rhs < 2^256 · p` and the model's output +is not the Montgomery product (by evaluation), documenting why #108's contract is +wrong. + +## Status + +Present: the semantics, the generator, the generated program, the vendored `.S` with its +hash, the vectors, and the CI check; the proofs of the helper (four reduction rounds), of +`from_mont` (the helper and a conditional subtraction), and of `mul` (four rounds of +schoolbook fold and reduction, the accumulator no-wrap conditions, the final comparison, +and the two operand contracts as corollaries). + +Remaining, in order: + +1. `sqr`: the cross-term schoolbook, the doubling, and the "can't overflow" claims. +2. The Pasta instantiation and the census entries in `TrustBoundary.lean`. + +Out of scope for now: Zakura's inline-`asm!` transcription (provable later by +instruction-by-instruction correspondence), `sqr_n_mul` (zakura-core/common#65), and +the carry-limb drop (zakura-core/common#132). diff --git a/scripts/check_aarch64_pasta_mul.sh b/scripts/check_aarch64_pasta_mul.sh new file mode 100755 index 0000000..6e0902d --- /dev/null +++ b/scripts/check_aarch64_pasta_mul.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# Check that the transcription of pasta_curves' AArch64 Pasta Montgomery routines is +# current: the vendored assembly and reference vectors match their recorded hashes, +# regenerating the Lean files from them reproduces the committed files exactly, and the +# generated parts of the proofs in PastaMulSpec.lean are the ones the generator produces. +# +# Run from the repository root; exits non-zero on violation. +set -euo pipefail +cd "$(dirname "$0")/.." + +(cd CompElliptic/Asm/AArch64/vendor && shasum -a 256 -c SHA256SUMS) + +python3 scripts/gen_aarch64_pasta_mul.py +git diff --exit-code -- \ + CompElliptic/Asm/AArch64/PastaMul.lean CompElliptic/Asm/AArch64/PastaMulVectors.lean +python3 scripts/gen_aarch64_pasta_mul.py --check-spec CompElliptic/Asm/AArch64/PastaMulSpec.lean +echo "AArch64 Pasta transcription: current." diff --git a/scripts/gen_aarch64_pasta_mul.py b/scripts/gen_aarch64_pasta_mul.py new file mode 100755 index 0000000..d931c71 --- /dev/null +++ b/scripts/gen_aarch64_pasta_mul.py @@ -0,0 +1,725 @@ +#!/usr/bin/env python3 +"""Generate the Lean transcription of pasta_curves' AArch64 Pasta Montgomery routines. + +Reads the vendored `CompElliptic/Asm/AArch64/vendor/pasta_mul-armv8.S` and writes + +- `CompElliptic/Asm/AArch64/PastaMul.lean`: each routine as a Lean definition over the + instruction semantics of `CompElliptic.Asm.AArch64.Semantics`, one `let` per + instruction, in the assembly's order, with the instruction as a trailing comment; +- `CompElliptic/Asm/AArch64/PastaMulVectors.lean`: one kernel-checked example per line of + `vendor/pasta_mul-armv8-vectors.txt`, the outputs of the real routines on an Apple + M-series machine. + +The transcription is deliberately mechanical. Registers become Lean variables of the +same name, rebound by each instruction that writes them. Loads through an argument +pointer become reads of that argument's limbs; stores through the output pointer bind +the result limbs; the stack frame, the return address, and the pointer-authentication +words are not modelled, and the script checks that no instruction depends on them +(a register restored from the frame is treated as unknown, and reading an unknown +register is an error). The `bl` to the shared reduction helper becomes a call of the +helper's own definition, after which the registers the helper clobbers are unknown. + +A binding that nothing later reads is not emitted. For a load this records that the +assembly reads a limb it never uses (it hard-codes `p[2] = 0` and `p[3] = 2^62`), and +the dropped load is left as a comment; for a carry flag it is an ordinary unread flag +write. A computed register that is never read would be dead code in the routine and is +reported as an error, since none is expected. + +Run from the repository root: + + python3 scripts/gen_aarch64_pasta_mul.py + +`scripts/check_aarch64_pasta_mul.sh` regenerates and fails if the output differs from +the committed files. + +The script also generates the mechanical part of each routine's correctness proof in +`CompElliptic/Asm/AArch64/PastaMulSpec.lean`: `--skeleton NAME` prints it (see +`skeleton`), and `--check-spec FILE` checks that FILE contains every routine's skeleton +verbatim once its `-- BEGIN ... -- END` annotation blocks are removed; the check script +runs that too. Python 3.9+; stdlib only. +""" +import re +import sys +import textwrap +from pathlib import Path + +ASM = Path("CompElliptic/Asm/AArch64/vendor/pasta_mul-armv8.S") +VECTORS = Path("CompElliptic/Asm/AArch64/vendor/pasta_mul-armv8-vectors.txt") +OUT_PROGRAM = Path("CompElliptic/Asm/AArch64/PastaMul.lean") +OUT_VECTORS = Path("CompElliptic/Asm/AArch64/PastaMulVectors.lean") + +HEADER = """/- +Copyright (c) 2026 CompElliptic Contributors. +Released under the Apache License, Version 2.0, or the MIT license, at your option, +as described in the files LICENSE-APACHE and LICENSE-MIT. +Authors: Daira-Emma Hopwood +-/ +""" + +HELPER_LABEL = "L$pasta_curves_mul_by_1_mont_pasta" + +# Code longer than this does not set the instruction-comment column (see `Routine.text`). +COMMENT_COLUMN_MAX = 40 + +# Registers the helper writes without restoring; after a `bl` they hold nothing the +# caller may read. `x5`-`x8` are also written, to the modulus limbs, and are rebound. +HELPER_CLOBBERS = ["x3", "x9", "x14", "x15", "x17"] + +ROUTINES = [ + # (label, Lean name, docstring, pointer arguments in register order, inv register) + ("_pasta_curves_mul_mont_pasta", "mulMont", + "`_pasta_curves_mul_mont_pasta`: Montgomery multiplication, `lhs * rhs * 2^-256 mod p`, " + "with the result stored through `x0`.", + [("x1", "lhs"), ("x2", "rhs"), ("x3", "modulus")], "x4"), + ("_pasta_curves_sqr_mont_pasta", "sqrMont", + "`_pasta_curves_sqr_mont_pasta`: Montgomery squaring, `value^2 * 2^-256 mod p`.", + [("x1", "value"), ("x2", "modulus")], "x3"), + ("_pasta_curves_from_mont_pasta", "fromMont", + "`_pasta_curves_from_mont_pasta`: conversion out of Montgomery form, " + "`value * 2^-256 mod p`.", + [("x1", "value"), ("x2", "modulus")], "x3"), +] + + +def tokenize(rest): + return re.findall(r"\[[^\]]*\]!?|[^,\s]+", rest) + + +def parse(path): + """The instruction list and the label table; directives and comments dropped.""" + ins, labels = [], {} + for line in path.read_text().splitlines(): + text = line.split("//")[0].strip() + if not text or text.startswith("."): + continue + if text.endswith(":"): + labels[text[:-1]] = len(ins) + continue + m = re.match(r"(\S+)\s*(.*)", text) + assert m is not None + ins.append((m.group(1), tokenize(m.group(2)), re.sub(r"\s+", " ", text))) + return ins, labels + + +def imm(tok): + """An immediate operand such as `#62` or `8*1`, as an integer.""" + s = tok.lstrip("#") + if not re.fullmatch(r"-?[0-9]+(\*[0-9]+)?", s): + raise ValueError(f"unexpected immediate {tok}") + return eval(s) + + +class Emitter: + """Transcribes one routine, from its label to its `ret`, into Lean `let` bindings.""" + + def __init__(self, ins, labels, helper_name): + self.ins, self.labels, self.helper_name = ins, labels, helper_name + self.entries = [] # dicts: name, expr, comment, reads, load (bool) + self.ptrs = {} # register -> argument name it points to + self.known = set() # names holding a value the program may read + self.outputs = {} # output limb index -> bound name + self.cur_reads = set() + + # -- operands ---------------------------------------------------------------- + + def read(self, tok): + if tok == "xzr": + return "0" + if tok.startswith("#"): + return str(imm(tok)) + if tok in self.ptrs: + raise ValueError(f"{tok} is a pointer, read as a value") + if tok not in self.known: + raise ValueError(f"{tok} read before being written") + self.cur_reads.add(tok) + return tok + + def bind(self, name, expr, comment, reads=None, load=False, fact=None): + """Record a binding. `fact` is the skeleton's description of it: a tuple whose head + names the kind of instruction and whose remaining items are the operand names.""" + if name == "xzr": + return + self.ptrs.pop(name, None) + self.known.add(name) + self.entries.append(dict(name=name, expr=expr, comment=comment, + reads=set(self.cur_reads) if reads is None else set(reads), + load=load, fact=fact)) + + def mem(self, tok): + """(base register, byte offset) of a memory operand, or None for the frame.""" + inner = tok.strip("!").strip("[]") + parts = inner.split(",") + base = parts[0] + off = imm(parts[1]) if len(parts) > 1 else 0 + if base in ("sp", "x29"): + return None + return base, off + + def limb(self, base, off): + if base not in self.ptrs: + raise ValueError(f"load through {base}, which is not an argument pointer") + if off % 8: + raise ValueError(f"unaligned offset {off}") + return f"{self.ptrs[base]}.l{off // 8}" + + # -- instructions -------------------------------------------------------------- + + def step(self, op, t, text): + self.cur_reads = set() + if op in ("ldp", "ldr"): + if len(t) == 3 and op == "ldr": # post-indexed frame release + return + m = self.mem(t[-1]) + if m is None: # restore from the frame: the value is not modelled + for r in t[:-1]: + self.known.discard(r) + self.ptrs.pop(r, None) + return + base, off = m + for i, r in enumerate(t[:-1]): + self.bind(r, self.limb(base, off + 8 * i), text, reads=(), load=True, + fact=("load", self.ptrs[base], (off + 8 * i) // 8)) + elif op in ("stp", "str"): + m = self.mem(t[-1]) + if m is None: # spill to the frame + return + base, off = m + if self.ptrs.get(base) != "out": + raise ValueError(f"store through {base}, which is not the output pointer") + for i, r in enumerate(t[:-1]): + idx = off // 8 + i + self.cur_reads = set() + self.bind(f"out{idx}", self.read(r), text, fact=("out", r)) + self.outputs[idx] = f"out{idx}" + elif op == "add": + if t[1] == "sp": # frame pointer setup + return + raise ValueError(f"unexpected add: {text}") + elif op == "mov": + a = self.read(t[1]) + self.bind(t[0], a, text, fact=("mov", a)) + elif op == "mul": + a, b = self.read(t[1]), self.read(t[2]) + self.bind(t[0], f"mulLo {a} {b}", text, fact=("mul", a, b)) + elif op == "umulh": + a, b = self.read(t[1]), self.read(t[2]) + self.bind(t[0], f"umulh {a} {b}", text, fact=("umulh", a, b)) + elif op == "lsl": + a, k = self.read(t[1]), imm(t[2]) + self.bind(t[0], f"lsl {a} {k}", text, fact=("lsl", a, k)) + elif op == "lsr": + a, k = self.read(t[1]), imm(t[2]) + self.bind(t[0], f"lsr {a} {k}", text, fact=("lsr", a, k)) + elif op in ("adds", "adcs", "adc"): + cin = "0" if op == "adds" else self.read("c") + a, b = self.read(t[1]), self.read(t[2]) + expr = f"addc {a} {b} {cin}" + if op == "adc": + self.bind(t[0], f"({expr}).1", text, fact=("adc", a, b, cin)) + else: + self.bind("s", expr, text, fact=("adds", a, b, cin)) + self.bind(t[0], "s.1", text, reads=("s",), fact=("fst",)) + self.bind("c", "s.2", text, reads=("s",), fact=("snd",)) + elif op in ("subs", "sbcs"): + cin = "1" if op == "subs" else self.read("c") + a, b = self.read(t[1]), self.read(t[2]) + expr = f"subc {a} {b} {cin}" + if t[0] == "xzr": + self.bind("c", f"({expr}).2", text, fact=("subs_carry", a, b, cin)) + else: + self.bind("s", expr, text, fact=("subs", a, b, cin)) + self.bind(t[0], "s.1", text, reads=("s",), fact=("fst",)) + self.bind("c", "s.2", text, reads=("s",), fact=("snd",)) + elif op == "csel": + if t[3] != "lo": + raise ValueError(f"unexpected condition: {text}") + c, a, b = self.read("c"), self.read(t[1]), self.read(t[2]) + self.bind(t[0], f"cselLo {c} {a} {b}", text, fact=("csel", c, a, b)) + elif op == "bl": + if t[0] != HELPER_LABEL: + raise ValueError(f"unexpected call: {text}") + if self.ptrs.get("x2") != "modulus": + raise ValueError("helper called without the modulus pointer in x2") + targs = [self.read(r) for r in ("x10", "x11", "x12", "x13")] + inv = self.read("x4") + self.bind("r", f"{self.helper_name} ⟨{', '.join(targs)}⟩ modulus {inv}", text, + fact=("call", *targs, inv)) + for i, r in enumerate(("x10", "x11", "x12", "x13")): + self.bind(r, f"r.l{i}", "helper output", reads=("r",), fact=("callout", i)) + for i, r in enumerate(("x5", "x6", "x7", "x8")): + self.bind(r, f"modulus.l{i}", "loaded by the helper", reads=(), load=True, + fact=("load", "modulus", i)) + for r in HELPER_CLOBBERS: + self.known.discard(r) + self.ptrs.pop(r, None) + self.known.discard("c") + else: + raise ValueError(f"unhandled instruction: {text}") + + def run(self, start): + pc = start + while True: + op, t, text = self.ins[pc] + if op == "ret": + return + self.step(op, t, text) + pc += 1 + + # -- output ------------------------------------------------------------------------ + + def liveness(self, result_names): + """Which entries something later reads, by a backward pass from the result names.""" + needed = set(result_names) + live = [False] * len(self.entries) + for i in range(len(self.entries) - 1, -1, -1): + e = self.entries[i] + if e["name"] in needed: + live[i] = True + needed.discard(e["name"]) + needed |= e["reads"] + return live + + def render(self, result_names): + """The `let` lines, with bindings that nothing reads dropped (see the module doc).""" + live = self.liveness(result_names) + lines = [] # (code, comment): a `let` with its instruction, or (None, whole-line comment) + for e, keep in zip(self.entries, live): + if keep: + lines.append((f" let {e['name']} := {e['expr']}", e["comment"])) + elif e["load"]: + lines.append((None, f" -- {e['comment']}: {e['name']} = {e['expr']} is never read")) + elif e["name"] != "c": + raise ValueError(f"dead computation: {e['name']} := {e['expr']} ({e['comment']})") + return lines + + +def emit_helper(ins, labels): + e = Emitter(ins, labels, "mulBy1") + e.ptrs["x2"] = "modulus" + for i, r in enumerate(("x10", "x11", "x12", "x13")): + e.bind(r, f"t.l{i}", "argument", reads=(), fact=("load", "t", i)) + e.bind("x4", "inv", "argument", reads=(), fact=("inv",)) + e.run(labels[HELPER_LABEL]) + e.cur_reads = set() + result = [e.read(r) for r in ("x10", "x11", "x12", "x13")] + doc = ("The shared reduction helper (`L$pasta_curves_mul_by_1_mont_pasta`): four Montgomery " + "cancellation steps on `t`, returning `(t + Q * p) / 2^256` for the `Q` they choose, " + "without a final conditional subtraction. `x10`-`x13` hold `t` and `x4` holds `inv` on " + "entry; the modulus limbs are loaded through `x2`.") + return Routine(doc, "def mulBy1 (t modulus : Limbs) (inv : Nat) : Limbs :=", e.render(result), + f" ⟨{', '.join(result)}⟩", "mulBy1", e, result) + + +def emit_routine(ins, labels, label, name, doc, ptr_args, inv_reg): + e = Emitter(ins, labels, "mulBy1") + e.ptrs["x0"] = "out" + for reg, arg in ptr_args: + e.ptrs[reg] = arg + e.bind(inv_reg, "inv", "argument", reads=(), fact=("inv",)) + e.run(labels[label]) + if sorted(e.outputs) != [0, 1, 2, 3]: + raise ValueError(f"{name}: outputs stored: {sorted(e.outputs)}") + result = [e.outputs[i] for i in range(4)] + params = " ".join(arg for _, arg in ptr_args) + return Routine(doc, f"def {name} ({params} : Limbs) (inv : Nat) : Limbs :=", e.render(result), + f" ⟨{', '.join(result)}⟩", name, e, result) + + +class Routine: + """A transcribed routine: docstring, signature line, body lines, and result line, plus the + emitter and result names for the proof skeleton.""" + + def __init__(self, doc, signature, lines, result, name, emitter, result_names): + self.doc, self.signature, self.lines, self.result = doc, signature, lines, result + self.name, self.emitter, self.result_names = name, emitter, result_names + + def text(self, column): + """The definition, with the instruction comments aligned at `column`; a line whose code + reaches the column (an outlier, such as the helper call) gets its comment two spaces + after the code instead.""" + body = [] + for code, comment in self.lines: + if code is None: + body.append(comment) + else: + body.append(f"{code.ljust(column) if len(code) + 2 <= column else code + ' '}-- {comment}") + return f"{docstring(self.doc)}\n{self.signature}\n" + "\n".join(body) + f"\n{self.result}\n" + + +def docstring(text, width=100): + """A `/-- ... -/` docstring wrapped to the repository's line width.""" + lines = textwrap.TextWrapper(width=width, break_long_words=False, break_on_hyphens=False, + initial_indent="/-- ").wrap(text) + if len(lines[-1]) + 3 <= width: + lines[-1] += " -/" + else: + lines.append("-/") + return "\n".join(lines) + + +def gen_program(ins, labels): + parts = [HEADER, "import CompElliptic.Asm.AArch64.Semantics\n", """ +/-! +# The Pasta Montgomery routines of `pasta_mul-armv8.S`, transcribed + +GENERATED by `scripts/gen_aarch64_pasta_mul.py` from +`CompElliptic/Asm/AArch64/vendor/pasta_mul-armv8.S`; do not edit by hand. Each definition +follows its routine instruction by instruction (the instruction is the trailing comment), +over the semantics of `CompElliptic.Asm.AArch64.Semantics`: registers are rebound by the +instructions that write them, `c` is the carry flag, `s` is the (result, carry) pair of the +instruction that last set both, argument limbs are read where the assembly loads them, and +the output limbs are bound where the assembly stores them. Bindings that nothing reads are +left as comments; the stack frame and the return address are not part of the model. See the +generator's docstring for what it checks. +-/ + +namespace CompElliptic.Asm.AArch64 + +"""] + routines = all_routines(ins, labels) + # One comment column for the whole file: two spaces past the widest ordinary `let`. Lines + # longer than COMMENT_COLUMN_MAX are outliers (the helper call) and do not set the column. + column = 2 + max(len(code) for r in routines for code, _ in r.lines + if code is not None and len(code) <= COMMENT_COLUMN_MAX) + parts.append("\n".join(r.text(column) for r in routines)) + parts.append("\nend CompElliptic.Asm.AArch64\n") + return "".join(parts) + + +FIELDS = { + "Fp": ("pallasBase", "⟨0x992d30ed00000001, 0x224698fc094cf91b, 0, 0x4000000000000000⟩", + "0x992d30ecffffffff"), + "Fq": ("vestaBase", "⟨0x8c46eb2100000001, 0x224698fc0994a8dd, 0, 0x4000000000000000⟩", + "0x8c46eb20ffffffff"), +} + + +def gen_vectors(lines): + out = [HEADER, "import CompElliptic.Asm.AArch64.PastaMul\n", """ +/-! +# Reference vectors for the transcribed routines + +GENERATED by `scripts/gen_aarch64_pasta_mul.py` from +`CompElliptic/Asm/AArch64/vendor/pasta_mul-armv8-vectors.txt`; do not edit by hand. Each +vector is the output of the real assembly (pasta_curves `8ad85e9fab7929f6236960e472f432a4bd9ccd74`, +run on an Apple M-series machine) on the given operands, and each example asks the kernel +to evaluate the transcription on the same operands. The vectors cover boundary operands +(zero, one, `R`, `R2`, `R3`, `p - 1`, single all-ones limbs), random canonical operands, +and unreduced operands in both positions, so they also record the routines' behaviour +outside their operand contracts. + +The modulus limbs and `inv` are the crate's constants for its `Fp` (the Pallas base field) +and `Fq` (the Vesta base field). +-/ + +namespace CompElliptic.Asm.AArch64 + +"""] + for key, (prefix, limbs, inv) in FIELDS.items(): + field = "Pallas" if key == "Fp" else "Vesta" + out.append(f"/-- The {field} base field modulus, as the crate's `MODULUS` limbs. -/\n") + out.append(f"def {prefix}Modulus : Limbs := {limbs}\n\n") + out.append(f"/-- `-p^-1 mod 2^64` for the {field} base field, the crate's `INV`. -/\n") + out.append(f"def {prefix}Inv : Nat := {inv}\n\n") + n = 0 + for line in lines: + parts = line.split() + if not parts: + continue + op, key, *vals = parts + prefix = FIELDS[key][0] + vals = [f"(Limbs.ofNat 0x{v})" for v in vals] + fn = {"MUL": "mulMont", "SQR": "sqrMont", "FROM": "fromMont"}.get(op) + if fn is None: + raise ValueError(line) + *operands, r = vals + # One operand per line keeps every line within the repository's width. + out.append(f"example :\n {fn}\n") + for v in operands: + out.append(f" {v}\n") + out.append(f" {prefix}Modulus {prefix}Inv =\n {r} := by\n decide +kernel\n\n") + n += 1 + out.append(f"\n-- {n} vectors.\n\nend CompElliptic.Asm.AArch64\n") + return "".join(out) + + +# --- proof skeletons -------------------------------------------------------------------- + +# Bounds hypotheses the annotated spec theorems must provide, by argument name. +BOUND_HYPS = {"t": "ht", "modulus": "hm", "lhs": "hlhs", "rhs": "hrhs", "value": "hv"} +INV_BOUND_HYP = "hinv_lt" +PROJ = ["1", "2.1", "2.2.1", "2.2.2"] +SKELETON_WIDTH = 100 + + +def ssa_names(entries): + """Unique names for the live bindings: the first binding of a register keeps its name, + later ones get `_1`, `_2`, ...""" + counts, names = {}, [] + for e in entries: + n = counts.get(e["name"], 0) + counts[e["name"]] = n + 1 + names.append(e["name"] if n == 0 else f"{e['name']}_{n}") + return names + + +def wrap_tactic(head, words, tail, indent=" "): + """`head w1 w2 ... tail`, broken over lines at SKELETON_WIDTH with a 4-space continuation.""" + lines, cur = [], indent + head + for w in words: + if len(cur) + 1 + len(w) > SKELETON_WIDTH: + lines.append(cur) + cur = indent + " " + w + else: + cur += " " + w + lines.append(cur + tail) + return lines + + +def skeleton(routine): + """The generated part of the correctness proof of `routine`: unfold the routine in `hr` and + lift its lets to the top; then, instruction by instruction, extract that instruction's lets + from `hr` under SSA names, record their defining equations (by `rfl`, in `%`/`/` form), make + the locals opaque, and derive the linear facts from the equations, clearing the equations + the later steps do not need. Each derived fact is an instance of one lemma + (`Nat.mod_add_div`, `Nat.mod_lt`, `Nat.div_lt_of_lt_mul`, or a carry lemma from the spec + file's preamble), so a step costs nothing wherever it sits and names the facts it rests on; + `omega` is left to the hand-written annotations, which go after the facts of the group whose + marker (`-- : `) names the register they need. + + Extracting one instruction at a time (`extract_lets +onlyGivenNames`) keeps the rest of the + chain folded inside `hr`, so that `clear_value` has one hypothesis to revert and re-check. + With every let extracted up front, each `clear_value` re-checks all the later locals and + equations, which is quadratic in the chain's length and exhausted the heartbeat budget on + the multiplication routine's 264 locals.""" + e = routine.emitter + live = e.liveness(routine.result_names) + entries = [en for en, keep in zip(e.entries, live) if keep] + names = ssa_names(entries) + ren = {} # current SSA name of each register at each point: resolved while walking + bnd = {} # SSA name -> the fact bounding it below 2^64 (registers) or by 1 (carries) + narrow = set() # `lsr` results, whose bound is below 2^64 and needs weakening + out = [f" -- generated skeleton for `{routine.name}`: do not edit between the annotations", + f" unfold {routine.name} at hr", " lift_lets at hr"] + products, shifts = {}, {} + eqs = [] # the current group's `have e_… := rfl` lines + + def r(op): # operand as written in the entry, renamed to its SSA name at that point + return ren.get(op, op) + + def lt64(op): # a proof that the operand is below 2^64 + if re.fullmatch(r"[0-9]+", op): + return "(by decide)" + if op in narrow: + return f"(lt_of_lt_of_le {bnd[op]} (by norm_num))" + return bnd[op] + + def le1(op): # a proof that the carry operand is at most 1 + return "(by decide)" if re.fullmatch(r"[0-9]+", op) else bnd[op] + + def eq(nm, rhs): + eqs.append(f" have e_{nm} : {nm} = {rhs} := rfl") + + i = 0 + while i < len(entries): + en, nm = entries[i], names[i] + kind, *ops = en["fact"] + ops = [r(o) if isinstance(o, str) else o for o in ops] + # The group's marker: the register it writes, then the instruction. Annotation blocks + # are placed after the group they name. + label = names[i + 1] if kind in ("adds", "subs") else nm + group = names[i:i + 3] if kind in ("adds", "subs") else [nm] + eqs, lines = [], [] + # Every step records only facts `omega` handles cheaply later: linear equations, bounds, + # and at most a disjunction. The `%`/`/` equations are derived by `rfl`, used to prove + # those facts, and cleared. + if kind == "load": + arg, idx = ops + hyp = BOUND_HYPS[arg] + eq(nm, f"{arg}.l{idx}") + lines.append(f" have b_{nm} : {nm} < 2^64 := by rw [e_{nm}]; exact {hyp}.{PROJ[idx]}") + bnd[nm] = f"b_{nm}" + elif kind == "inv": + eq(nm, "inv") + lines.append(f" have b_{nm} : {nm} < 2^64 := by rw [e_{nm}]; exact {INV_BOUND_HYP}") + bnd[nm] = f"b_{nm}" + elif kind == "mov": + (a,) = ops + eq(nm, a) + lines.append(f" have b_{nm} : {nm} < 2^64 := by rw [e_{nm}]; exact {lt64(a)}") + bnd[nm] = f"b_{nm}" + elif kind == "mul": + a, b = ops + eq(nm, f"{a} * {b} % 2^64") + lines.append(f" have b_{nm} : {nm} < 2^64 := by rw [e_{nm}]; exact Nat.mod_lt _ (Nat.two_pow_pos _)") + bnd[nm] = f"b_{nm}" + products[(a, b)] = nm # its `%` equation is cleared at the matching `umulh` + elif kind == "umulh": + a, b = ops + eq(nm, f"{a} * {b} / 2^64") + lines.append(f" have p_{nm} : {a} * {b} < 2^64 * 2^64 := Nat.mul_lt_mul'' {lt64(a)} {lt64(b)}") + lines.append(f" have b_{nm} : {nm} < 2^64 := by rw [e_{nm}]; exact Nat.div_lt_of_lt_mul p_{nm}") + bnd[nm] = f"b_{nm}" + if (a, b) in products: + lo = products.pop((a, b)) + lines.append(f" have d_{nm} : {lo} + 2^64 * {nm} = {a} * {b} := by") + lines.append(f" rw [e_{lo}, e_{nm}]; exact Nat.mod_add_div _ _") + lines.append(f" clear e_{lo} e_{nm}") + else: + # The low half is never computed (its cancellation is arranged by `subs`); name + # it as a ghost so that later steps need no `%`. + lines.append(f" obtain ⟨lo_{nm}, b_lo_{nm}, d_{nm}⟩ :") + lines.append(f" ∃ lo, lo < 2^64 ∧ lo + 2^64 * {nm} = {a} * {b} :=") + lines.append(f" ⟨{a} * {b} % 2^64, Nat.mod_lt _ (Nat.two_pow_pos _),") + lines.append(f" by rw [e_{nm}]; exact Nat.mod_add_div _ _⟩") + lines.append(f" clear e_{nm}") + elif kind == "lsl": + a, k = ops + eq(nm, f"{a} * 2^{k} % 2^64") + lines.append(f" have b_{nm} : {nm} < 2^64 := by rw [e_{nm}]; exact Nat.mod_lt _ (Nat.two_pow_pos _)") + bnd[nm] = f"b_{nm}" + shifts[(a, k)] = nm + elif kind == "lsr": + a, k = ops + eq(nm, f"{a} / 2^{k}") + lines.append(f" have b_{nm} : {nm} < 2^{64 - k} := by") + lines.append(f" rw [e_{nm}]; exact Nat.div_lt_of_lt_mul (lt_of_lt_of_eq {lt64(a)} (by norm_num))") + bnd[nm] = f"b_{nm}" + narrow.add(nm) + if (a, 64 - k) in shifts: + lo = shifts.pop((a, 64 - k)) + if k != 2: + raise ValueError(f"lsl/lsr split by {64 - k}/{k}: add a lemma to the spec preamble") + lines.append(f" have sh_{nm} : {lo} + 2^64 * {nm} = {a} * 2^{64 - k} := by") + lines.append(f" rw [e_{lo}, e_{nm}]; exact lsl62_lsr2_split _") + lines.append(f" clear e_{lo} e_{nm}") + elif kind in ("adds", "subs"): + a, b, cin = ops + xn, cn = names[i + 1], names[i + 2] + if kind == "adds": + val = f"({a} + {b} + {cin})" + lin = f"{xn} + 2^64 * {cn} = {a} + {b} + {cin}" + lin_proof = "Nat.mod_add_div _ _" + carry_proof = f"addc_carry_le_one {a} {b} {cin} {lt64(a)} {lt64(b)} {le1(cin)}" + else: + val = f"({a} + 2^64 - {b} - (1 - {cin}))" + lin = f"{xn} + 2^64 * {cn} + {b} + 1 = {a} + 2^64 + {cin}" + lin_proof = f"subc_lin {a} {b} {cin} {lt64(b)} {le1(cin)}" + carry_proof = f"subc_carry_le_one {a} {b} {cin} {lt64(a)}" + eq(xn, f"{val} % 2^64") + eq(cn, f"{val} / 2^64") + lines.append(f" have l_{xn} : {lin} := by") + lines.append(f" rw [e_{xn}, e_{cn}]; exact {lin_proof}") + lines.append(f" have b_{xn} : {xn} < 2^64 := by rw [e_{xn}]; exact Nat.mod_lt _ (Nat.two_pow_pos _)") + lines.append(f" have b_{cn} : {cn} ≤ 1 := by") + lines.append(f" rw [e_{cn}]; exact {carry_proof}") + lines.append(f" clear e_{xn} e_{cn}") + ren[entries[i + 1]["name"]] = xn + ren[entries[i + 2]["name"]] = cn + bnd[xn], bnd[cn] = f"b_{xn}", f"b_{cn}" + i += 2 + elif kind == "adc": + a, b, cin = ops + eq(nm, f"({a} + {b} + {cin}) % 2^64") + lines.append(f" have b_{nm} : {nm} < 2^64 := by rw [e_{nm}]; exact Nat.mod_lt _ (Nat.two_pow_pos _)") + lines.append(f" obtain ⟨k_{nm}, b_k_{nm}, l_{nm}⟩ :") + lines.append(f" ∃ k, k ≤ 1 ∧ {nm} + 2^64 * k = {a} + {b} + {cin} :=") + lines.append(f" ⟨({a} + {b} + {cin}) / 2^64, addc_carry_le_one {a} {b} {cin} {lt64(a)} {lt64(b)} {le1(cin)},") + lines.append(f" by rw [e_{nm}]; exact Nat.mod_add_div _ _⟩") + lines.append(f" clear e_{nm}") + bnd[nm] = f"b_{nm}" + elif kind == "subs_carry": + a, b, cin = ops + eq(nm, f"({a} + 2^64 - {b} - (1 - {cin})) / 2^64") + lines.append(f" have b_{nm} : {nm} ≤ 1 := by rw [e_{nm}]; exact subc_carry_le_one {a} {b} {cin} {lt64(a)}") + lines.append(f" have l_{nm} : ({nm} = 1 ∧ {b} + 1 ≤ {a} + {cin}) ∨ ({nm} = 0 ∧ {a} + {cin} < {b} + 1) :=") + lines.append(f" subc_carry_cases {a} {b} {cin} _ e_{nm} {lt64(a)} {lt64(b)} {le1(cin)}") + lines.append(f" clear e_{nm}") + bnd[nm] = f"b_{nm}" + elif kind == "csel": + c, a, b = ops + eq(nm, f"(if {c} = 0 then {a} else {b})") + lines.append(f" have b_{nm} : {nm} < 2^64 := by") + lines.append(f" rw [e_{nm}]; split <;> first | exact {lt64(a)} | exact {lt64(b)}") + bnd[nm] = f"b_{nm}" + elif kind == "call": + *targs, inv = ops + eq(nm, f"mulBy1 ⟨{', '.join(targs)}⟩ modulus {inv}") + elif kind == "callout": + (idx,) = ops + eq(nm, f"{r('r')}.l{idx}") + bnd[nm] = f"b_{nm}" # supplied by the annotation that applies the callee's theorem + elif kind == "out": + (x,) = ops + eq(nm, x) + else: + raise ValueError(kind) + ren[en["name"]] = nm + out.append(f" -- {label}: {en['comment']}") + out += wrap_tactic("extract_lets +onlyGivenNames", group, " at hr") + out += eqs + out.append(f" clear_value {' '.join(group)}") + out += lines + i += 1 + out.append(" subst hr") + return out + +def check_spec(path, routines): + """Verify that each routine's skeleton appears verbatim and contiguously in `path` once its + `-- BEGIN ... -- END` annotation blocks are removed and blank lines dropped. Text outside the + skeletons (theorem statements, lemmas, the closing steps) is free; text between two + skeleton lines must be inside an annotation block.""" + text = Path(path).read_text() + stripped = re.sub(r"(?ms)^\s*-- BEGIN[^\n]*\n.*?^\s*-- END[^\n]*\n", "", text) + remaining = [l for l in stripped.splitlines() if l.strip()] + ok = True + for rt in routines: + sk = [l for l in skeleton(rt) if l.strip()] + n = len(sk) + if sk[1] not in remaining: # `unfold at hr`: the theorem is not in this file + continue + for start in range(len(remaining) - n + 1): + if remaining[start:start + n] == sk: + del remaining[start:start + n] + break + else: + i = remaining.index(sk[1]) + for j, l in enumerate(sk): + if i + j >= len(remaining) or remaining[i + j] != l: + print(f"{path}: skeleton of {rt.name} diverges at skeleton line {j}:", + file=sys.stderr) + print(f" expected: {l}", file=sys.stderr) + print(f" found: {remaining[i + j] if i + j < len(remaining) else ''}", + file=sys.stderr) + break + ok = False + return ok + + +def all_routines(ins, labels): + routines = [emit_helper(ins, labels)] + for label, name, doc, ptr_args, inv_reg in ROUTINES: + routines.append(emit_routine(ins, labels, label, name, doc, ptr_args, inv_reg)) + return routines + + +def main(): + ins, labels = parse(ASM) + if len(sys.argv) >= 3 and sys.argv[1] == "--skeleton": + for rt in all_routines(ins, labels): + if rt.name == sys.argv[2]: + print("\n".join(skeleton(rt))) + return 0 + print(f"no routine {sys.argv[2]}", file=sys.stderr) + return 1 + if len(sys.argv) >= 3 and sys.argv[1] == "--check-spec": + ok = check_spec(sys.argv[2], all_routines(ins, labels)) + print(f"{sys.argv[2]}: skeletons {'current' if ok else 'STALE'}") + return 0 if ok else 1 + OUT_PROGRAM.write_text(gen_program(ins, labels)) + OUT_VECTORS.write_text(gen_vectors(VECTORS.read_text().splitlines())) + print(f"wrote {OUT_PROGRAM} ({len(ins)} instructions parsed) and {OUT_VECTORS}") + + +if __name__ == "__main__": + sys.exit(main())