From 8b714a9ba9346e90cfd707822c9f637e51a6ca7e Mon Sep 17 00:00:00 2001 From: Jake Massimo Date: Fri, 24 Apr 2026 06:08:07 +0000 Subject: [PATCH 1/9] ML-DSA AArch64 HOL-Light proof poly_use_hint_88 with functional correctness Add formal verification proof for mldsa_poly_use_hint_88 AArch64 NEON implementation. The proof establishes full functional correctness: the assembly output equals word(mldsa_use_hint_88_spec(val(a), val(h))) for each element, matching the ML-DSA specification. Signed-off-by: Jake Massimo --- arm/Makefile | 1 + arm/mldsa/mldsa_poly_use_hint_88.S | 166 +++ arm/proofs/decode.ml | 57 +- arm/proofs/instruction.ml | 60 +- arm/proofs/mldsa_poly_use_hint_88.ml | 1713 ++++++++++++++++++++++++++ arm/proofs/simulator_iclasses.ml | 20 - arm/proofs/specifications.txt | 2 + arm/proofs/subroutine_signatures.ml | 13 +- benchmarks/benchmark.c | 3 + common/mlkem_mldsa.ml | 50 +- include/s2n-bignum.h | 4 + tests/test.c | 102 +- tools/collect-signatures.py | 1 + 13 files changed, 2046 insertions(+), 146 deletions(-) create mode 100644 arm/mldsa/mldsa_poly_use_hint_88.S create mode 100644 arm/proofs/mldsa_poly_use_hint_88.ml diff --git a/arm/Makefile b/arm/Makefile index d89fab8b3..28f3d1e13 100644 --- a/arm/Makefile +++ b/arm/Makefile @@ -255,6 +255,7 @@ BIGNUM_OBJ = curve25519/bignum_add_p25519.o \ mldsa/mldsa_intt.o \ mldsa/mldsa_ntt.o \ mldsa/mldsa_pointwise.o \ + mldsa/mldsa_poly_use_hint_88.o \ mlkem/mlkem_basemul_k2.o \ mlkem/mlkem_basemul_k3.o \ mlkem/mlkem_basemul_k4.o \ diff --git a/arm/mldsa/mldsa_poly_use_hint_88.S b/arm/mldsa/mldsa_poly_use_hint_88.S new file mode 100644 index 000000000..afbedc916 --- /dev/null +++ b/arm/mldsa/mldsa_poly_use_hint_88.S @@ -0,0 +1,166 @@ +// Copyright (c) The mldsa-native project authors +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + +// ---------------------------------------------------------------------------- +// Use hint to correct high bits of decomposition (parameter set 44) +// Inputs a[256] (unsigned 32-bit, in [0,Q)), h[256] (hint bits, 0 or 1) +// Output b[256] (unsigned 32-bit, in [0,44)) +// +// Implements mld_use_hint for ML-DSA parameter set 44: +// GAMMA2 = (Q-1)/88 = 95232 +// 2*GAMMA2 = 190464 +// Output range: [0, 43] +// +// Algorithm per coefficient: +// 1. Decompose: a1 = round_down(a / 190464), a0 = a - a1*190464 +// If a > 43*GAMMA2 = 4094976, wrap: a1=0, a0=a-Q +// 2. delta = (a0 <= 0) ? -1 : 1 +// 3. b = min((a1 + delta * h) & ~mask_gt_43, 43) +// where mask_gt_43 clears values > 43 and umin clamps to 43 +// +// extern void mldsa_poly_use_hint_88 +// (int32_t b[static 256], const int32_t a[static 256], +// const int32_t h[static 256]); +// +// Standard ARM ABI: X0 = b, X1 = a, X2 = h +// ---------------------------------------------------------------------------- +#include "_internal_s2n_bignum_arm.h" + + S2N_BN_SYM_VISIBILITY_DIRECTIVE(mldsa_poly_use_hint_88) + S2N_BN_FUNCTION_TYPE_DIRECTIVE(mldsa_poly_use_hint_88) + S2N_BN_SYM_PRIVACY_DIRECTIVE(mldsa_poly_use_hint_88) + .text + .balign 4 + +S2N_BN_SYMBOL(mldsa_poly_use_hint_88): + CFI_START + +// This matches the code in the mldsa-native repository +// https://github.com/pq-code-package/mldsa-native/blob/main/mldsa/src/native/aarch64/src/poly_use_hint_88_asm.S + +// Load constants into SIMD registers + +// v20 = Q = 8380417 = 0x7fe001 + mov w4, #0xe001 + movk w4, #0x7f, lsl #16 + dup v20.4s, w4 + +// v21 = 43*GAMMA2 = 4094976 = 0x3e6c00 (wraparound threshold) + mov w5, #0x6c00 + movk w5, #0x7e, lsl #16 + dup v21.4s, w5 + +// v22 = 2*GAMMA2 = 190464 = 0x2e800 (decompose multiplier) + mov w7, #0xe800 + movk w7, #0x2, lsl #16 + dup v22.4s, w7 + +// v23 = Barrett constant = 0x58160581 = 1477837185 +// Used for SQDMULH-based Barrett reduction: a1 ~= (2*a*c) >> 48 + mov w11, #0x0581 + movk w11, #0x5816, lsl #16 + dup v23.4s, w11 + +// v24 = 43 = 0x0000002b (for clamping with umin) + movi v24.4s, #0x2b + +// Loop counter: 16 iterations, processing 16 coefficients per iteration +// 16 * 16 = 256 total coefficients + mov x3, #0x10 + +Lmldsa_poly_use_hint_88_loop: + // Load 16 coefficients from a (4 vectors of 4 int32s) + ldr q1, [x1, #0x10] + ldr q2, [x1, #0x20] + ldr q3, [x1, #0x30] + ldr q0, [x1], #0x40 + + // Load 16 hint bits from h (4 vectors of 4 int32s) + ldr q5, [x2, #0x10] + ldr q6, [x2, #0x20] + ldr q7, [x2, #0x30] + ldr q4, [x2], #0x40 + + // --- Process v1 (coefficients at offset +16) --- + // Decompose: a1 = sqdmulh(a, barrett_const) >> 17 + sqdmulh v17.4s, v1.4s, v23.4s + srshr v17.4s, v17.4s, #0x11 + // Check wraparound: mask = (a > 43*GAMMA2) ? all_ones : 0 + cmgt v25.4s, v1.4s, v21.4s + // a0 = a - a1 * 2*GAMMA2 + mls v1.4s, v17.4s, v22.4s + // If wraparound: a1 = 0 (clear a1 where mask is set) + bic v17.16b, v17.16b, v25.16b + // If wraparound: a0 -= 1 (add all_ones = -1) + add v1.4s, v1.4s, v25.4s + // delta = (a0 <= 0) ? all_ones : 0 + cmle v1.4s, v1.4s, #0 + // delta = (a0 <= 0) ? -1 : 1 (set bit 0) + orr v1.4s, #0x1 + // b = a1 + delta * hint + mla v17.4s, v1.4s, v5.4s + // Clamp to [0, 43]: clear if > 43, then min with 43 + cmgt v25.4s, v17.4s, v24.4s + bic v17.16b, v17.16b, v25.16b + umin v17.4s, v17.4s, v24.4s + + // --- Process v2 (coefficients at offset +32) --- + sqdmulh v18.4s, v2.4s, v23.4s + srshr v18.4s, v18.4s, #0x11 + cmgt v25.4s, v2.4s, v21.4s + mls v2.4s, v18.4s, v22.4s + bic v18.16b, v18.16b, v25.16b + add v2.4s, v2.4s, v25.4s + cmle v2.4s, v2.4s, #0 + orr v2.4s, #0x1 + mla v18.4s, v2.4s, v6.4s + cmgt v25.4s, v18.4s, v24.4s + bic v18.16b, v18.16b, v25.16b + umin v18.4s, v18.4s, v24.4s + + // --- Process v3 (coefficients at offset +48) --- + sqdmulh v19.4s, v3.4s, v23.4s + srshr v19.4s, v19.4s, #0x11 + cmgt v25.4s, v3.4s, v21.4s + mls v3.4s, v19.4s, v22.4s + bic v19.16b, v19.16b, v25.16b + add v3.4s, v3.4s, v25.4s + cmle v3.4s, v3.4s, #0 + orr v3.4s, #0x1 + mla v19.4s, v3.4s, v7.4s + cmgt v25.4s, v19.4s, v24.4s + bic v19.16b, v19.16b, v25.16b + umin v19.4s, v19.4s, v24.4s + + // --- Process v0 (coefficients at offset +0, loaded last for post-increment) --- + sqdmulh v16.4s, v0.4s, v23.4s + srshr v16.4s, v16.4s, #0x11 + cmgt v25.4s, v0.4s, v21.4s + mls v0.4s, v16.4s, v22.4s + bic v16.16b, v16.16b, v25.16b + add v0.4s, v0.4s, v25.4s + cmle v0.4s, v0.4s, #0 + orr v0.4s, #0x1 + mla v16.4s, v0.4s, v4.4s + cmgt v25.4s, v16.4s, v24.4s + bic v16.16b, v16.16b, v25.16b + umin v16.4s, v16.4s, v24.4s + + // Store 16 output coefficients + str q17, [x0, #0x10] + str q18, [x0, #0x20] + str q19, [x0, #0x30] + str q16, [x0], #0x40 + + // Decrement loop counter and branch + subs x3, x3, #0x1 + b.ne Lmldsa_poly_use_hint_88_loop + + CFI_RET + +S2N_BN_SIZE_DIRECTIVE(mldsa_poly_use_hint_88) + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack, "", %progbits +#endif diff --git a/arm/proofs/decode.ml b/arm/proofs/decode.ml index 328aa77df..12f9eeea7 100644 --- a/arm/proofs/decode.ml +++ b/arm/proofs/decode.ml @@ -612,25 +612,8 @@ let decode = new_definition `!w:int32. decode w = let datasize = if q then 128 else 64 in let shift = (esize * 2) - val (word_join immh immb:(7)word) in SOME (arm_SRI_VEC (QREG' Rd) (QREG' Rn) shift esize datasize) - else if cmode = (word 0b1010:(4)word) then - // USHLL, USHLL2 - let immb = abc in - let Rn = defgh in - if val immh = 0 then NONE - else if bit 3 immh then NONE // "UNDEFINED" (would need 128-bit elements) - else - let esize = 8 * 2 EXP (3 - word_clz immh) in - let shift = val (word_join immh immb:(7)word) - esize in - if q then SOME (arm_USHLL2_VEC (QREG' Rd) (QREG' Rn) shift esize) - else SOME (arm_USHLL_VEC (QREG' Rd) (QREG' Rn) shift esize) else NONE - | [0:1; q; 0:1; 0b011110:6; 0b0000:4; abc:3; 0b1110:4; 0b01:2; defgh:5; Rd:5] -> - // MOVI (op=0, cmode=1110, immh=0) - let abcdefgh:(8)word = word_join abc defgh in - if q then SOME (arm_MOVI (QREG' Rd) (word_duplicate abcdefgh)) - else SOME (arm_MOVI (DREG' Rd) (word_duplicate abcdefgh)) - | [0b0001111000100110000000:22; Rn:5; Rd:5] -> // FMOV (single, to general) SOME (arm_FMOV_FtoI (WREG' Rd) (QREG' Rn) 0 32) @@ -803,14 +786,6 @@ let decode = new_definition `!w:int32. decode w = // RAX1 SOME (arm_RAX1 (QREG' Rd) (QREG' Rn) (QREG' Rm)) - | [0:1; q; 0b0011110:7; immh:4; immb:3; 0b111001:6; Rn:5; Rd:5] -> - // MOVI (op=0, cmode=1110, byte immediate) - if immh = (word 0b0:(4)word) then - let abcdefgh:(8)word = word_join immb Rn in - if q then SOME (arm_MOVI (QREG' Rd) (word_duplicate abcdefgh)) - else SOME (arm_MOVI (DREG' Rd) (word_duplicate abcdefgh)) - else NONE - | [0:1; q; 0b0011110:7; immh:4; immb:3; 0b010101:6; Rn:5; Rd:5] -> // SHL if immh = (word 0b0: (4)word) then NONE // "asimdimm case" @@ -821,36 +796,10 @@ let decode = new_definition `!w:int32. decode w = let amt = val(word_join immh immb:7 word) - esize in SOME (arm_SHL_VEC (QREG' Rd) (QREG' Rn) amt esize datasize) - | [0:1; q; 0b0011110:7; immh:4; immb:3; 0b101001:6; Rn:5; Rd:5] -> - // SSHLL, SSHLL2 (or MOVI with cmode=1010 when immh=0 and Q=1) - if immh = (word 0b0:(4)word) then - if q then - let abcdefgh:(8)word = word_join immb Rn in - let imm = arm_adv_simd_expand_imm abcdefgh (word 0:(1)word) (word 0b1010) in - match imm with - | SOME imm -> SOME (arm_MOVI (QREG' Rd) imm) - | NONE -> NONE - else NONE - else if bit 3 immh then NONE // "UNDEFINED" - else - let esize = 8 * 2 EXP (3 - word_clz immh) in - let shift = val(word_join immh immb:7 word) - esize in - if q then - SOME (arm_SSHLL2_VEC (QREG' Rd) (QREG' Rn) shift esize) - else - SOME (arm_SSHLL_VEC (QREG' Rd) (QREG' Rn) shift esize) - | [0:1; q; 0b0011110:7; immh:4; immb:3; 0b100001:6; Rn:5; Rd:5] -> - // SHRN (or MOVI with cmode=1000 when immh=0 and Q=1) - if immh = (word 0b0:(4)word) then - if q then - let abcdefgh:(8)word = word_join immb Rn in - let imm = arm_adv_simd_expand_imm abcdefgh (word 0:(1)word) (word 0b1000) in - match imm with - | SOME imm -> SOME (arm_MOVI (QREG' Rd) imm) - | NONE -> NONE - else NONE - else if q then NONE // writing to the upper part is unsupported yet + // SHRN + if q then NONE // writing to the upper part is unsupported yet + else if immh = (word 0b0:(4)word) then NONE // "asimdimm case" else if bit 3 immh then NONE // "UNDEFINED" else let esize = 8 * 2 EXP (3 - word_clz immh) in diff --git a/arm/proofs/instruction.ml b/arm/proofs/instruction.ml index 9a6620907..1256b4114 100644 --- a/arm/proofs/instruction.ml +++ b/arm/proofs/instruction.ml @@ -2130,57 +2130,6 @@ let arm_PMULL2_VEC = define let nlzx:(128)word = usimd8 (word_zx:(8)word->(16)word) nl in let mlzx:(128)word = usimd8 (word_zx:(8)word->(16)word) ml in (Rd := simd8 word_pmul nlzx mlzx) s`;; -let arm_USHLL_VEC = define - `arm_USHLL_VEC Rd Rn shift esize = - \s. let nl:(64)word = word_subword (read Rn s:(128)word) (0,64):(64)word in - if esize = 32 then - let r:(128)word = usimd2 (\x. word_shl (word_zx x:(64)word) shift) nl in - (Rd := r) s - else if esize = 16 then - let r:(128)word = usimd4 (\x. word_shl (word_zx x:(32)word) shift) nl in - (Rd := r) s - else // esize = 8 - let r:(128)word = usimd8 (\x. word_shl (word_zx x:(16)word) shift) nl in - (Rd := r) s`;; - -let arm_USHLL2_VEC = define - `arm_USHLL2_VEC Rd Rn shift esize = - \s. let nl:(64)word = word_subword (read Rn s:(128)word) (64,64):(64)word in - if esize = 32 then - let r:(128)word = usimd2 (\x. word_shl (word_zx x:(64)word) shift) nl in - (Rd := r) s - else if esize = 16 then - let r:(128)word = usimd4 (\x. word_shl (word_zx x:(32)word) shift) nl in - (Rd := r) s - else // esize = 8 - let r:(128)word = usimd8 (\x. word_shl (word_zx x:(16)word) shift) nl in - (Rd := r) s`;; - -let arm_SSHLL_VEC = define - `arm_SSHLL_VEC Rd Rn shift esize = - \s. let nl:(64)word = word_subword (read Rn s:(128)word) (0,64):(64)word in - if esize = 32 then - let r:(128)word = usimd2 (\x. word_shl (word_sx x:(64)word) shift) nl in - (Rd := r) s - else if esize = 16 then - let r:(128)word = usimd4 (\x. word_shl (word_sx x:(32)word) shift) nl in - (Rd := r) s - else // esize = 8 - let r:(128)word = usimd8 (\x. word_shl (word_sx x:(16)word) shift) nl in - (Rd := r) s`;; - -let arm_SSHLL2_VEC = define - `arm_SSHLL2_VEC Rd Rn shift esize = - \s. let nl:(64)word = word_subword (read Rn s:(128)word) (64,64):(64)word in - if esize = 32 then - let r:(128)word = usimd2 (\x. word_shl (word_sx x:(64)word) shift) nl in - (Rd := r) s - else if esize = 16 then - let r:(128)word = usimd4 (\x. word_shl (word_sx x:(32)word) shift) nl in - (Rd := r) s - else // esize = 8 - let r:(128)word = usimd8 (\x. word_shl (word_sx x:(16)word) shift) nl in - (Rd := r) s`;; let arm_USHR_VEC = define `arm_USHR_VEC Rd Rn amt esize datasize = @@ -3442,10 +3391,6 @@ let arm_UMULL_VEC_ALT = EXPAND_SIMD_RULE arm_UMULL_VEC;; let arm_UMULL2_VEC_ALT = EXPAND_SIMD_RULE arm_UMULL2_VEC;; let arm_USHL_VEC_ALT = REWRITE_RULE[word_ushl] (EXPAND_SIMD_RULE arm_USHL_VEC);; -let arm_USHLL_VEC_ALT = EXPAND_SIMD_RULE arm_USHLL_VEC;; -let arm_USHLL2_VEC_ALT = EXPAND_SIMD_RULE arm_USHLL2_VEC;; -let arm_SSHLL_VEC_ALT = EXPAND_SIMD_RULE arm_SSHLL_VEC;; -let arm_SSHLL2_VEC_ALT = EXPAND_SIMD_RULE arm_SSHLL2_VEC;; let arm_USHR_VEC_ALT = EXPAND_SIMD_RULE arm_USHR_VEC;; let arm_USRA_VEC_ALT = EXPAND_SIMD_RULE arm_USRA_VEC;; let arm_UZP1_ALT = EXPAND_SIMD_RULE arm_UZP1;; @@ -3562,7 +3507,6 @@ let ARM_OPERATION_CLAUSES = arm_SMLAL_VEC_ALT; arm_SMLAL2_VEC_ALT; arm_SMLSL_VEC_ALT; arm_SMLSL2_VEC_ALT; arm_SMULL_VEC_ALT; arm_SMULL2_VEC_ALT; - arm_SSHLL_VEC_ALT; arm_SSHLL2_VEC_ALT; arm_SMULH; arm_SQDMULH_VEC_ALT; arm_SQRDMULH_VEC_ALT; @@ -3576,9 +3520,7 @@ let ARM_OPERATION_CLAUSES = arm_UMULL_VEC_ALT; arm_UMULL2_VEC_ALT; arm_UMULH; arm_UMIN_VEC_ALT; - arm_USHL_VEC_ALT; - arm_USHLL_VEC_ALT; arm_USHLL2_VEC_ALT; - arm_USHR_VEC_ALT; arm_USRA_VEC_ALT; arm_UZP1_ALT; + arm_USHL_VEC_ALT; arm_USHR_VEC_ALT; arm_USRA_VEC_ALT; arm_UZP1_ALT; arm_UZP2_ALT; arm_XAR; arm_XTN_ALT; arm_ZIP1_ALT; arm_ZIP2_ALT; diff --git a/arm/proofs/mldsa_poly_use_hint_88.ml b/arm/proofs/mldsa_poly_use_hint_88.ml new file mode 100644 index 000000000..a96e3d7b9 --- /dev/null +++ b/arm/proofs/mldsa_poly_use_hint_88.ml @@ -0,0 +1,1713 @@ +(* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT-0 + *) + +(* ========================================================================= *) +(* Use hint to correct high bits of decomposition (ML-DSA, param 44). *) +(* ========================================================================= *) + +needs "arm/proofs/base.ml";; +needs "common/mlkem_mldsa.ml";; + +(**** print_literal_from_elf "arm/mldsa/mldsa_poly_use_hint_88.o";; + ****) + +let mldsa_poly_use_hint_88_mc = define_assert_from_elf + "mldsa_poly_use_hint_88_mc" "arm/mldsa/mldsa_poly_use_hint_88.o" +(*** BYTECODE START ***) +[ + 0x529c0024; (* arm_MOV W4 (rvalue (word 57345)) *) + 0x72a00fe4; (* arm_MOVK W4 (word 127) 16 *) + 0x4e040c94; (* arm_DUP_GEN Q20 X4 32 128 *) + 0x528d8005; (* arm_MOV W5 (rvalue (word 27648)) *) + 0x72a00fc5; (* arm_MOVK W5 (word 126) 16 *) + 0x4e040cb5; (* arm_DUP_GEN Q21 X5 32 128 *) + 0x529d0007; (* arm_MOV W7 (rvalue (word 59392)) *) + 0x72a00047; (* arm_MOVK W7 (word 2) 16 *) + 0x4e040cf6; (* arm_DUP_GEN Q22 X7 32 128 *) + 0x5280b02b; (* arm_MOV W11 (rvalue (word 1409)) *) + 0x72ab02cb; (* arm_MOVK W11 (word 22550) 16 *) + 0x4e040d77; (* arm_DUP_GEN Q23 X11 32 128 *) + 0x4f010578; (* arm_MOVI Q24 (word 184683593771) *) + 0xd2800203; (* arm_MOV X3 (rvalue (word 16)) *) + 0x3dc00421; (* arm_LDR Q1 X1 (Immediate_Offset (word 16)) *) + 0x3dc00822; (* arm_LDR Q2 X1 (Immediate_Offset (word 32)) *) + 0x3dc00c23; (* arm_LDR Q3 X1 (Immediate_Offset (word 48)) *) + 0x3cc40420; (* arm_LDR Q0 X1 (Postimmediate_Offset (word 64)) *) + 0x3dc00445; (* arm_LDR Q5 X2 (Immediate_Offset (word 16)) *) + 0x3dc00846; (* arm_LDR Q6 X2 (Immediate_Offset (word 32)) *) + 0x3dc00c47; (* arm_LDR Q7 X2 (Immediate_Offset (word 48)) *) + 0x3cc40444; (* arm_LDR Q4 X2 (Postimmediate_Offset (word 64)) *) + 0x4eb7b431; (* arm_SQDMULH_VEC Q17 Q1 Q23 32 128 *) + 0x4f2f2631; (* arm_SRSHR_VEC Q17 Q17 17 32 128 *) + 0x4eb53439; (* arm_CMGT_VEC Q25 Q1 Q21 32 128 *) + 0x6eb69621; (* arm_MLS_VEC Q1 Q17 Q22 32 128 *) + 0x4e791e31; (* arm_BIC_VEC Q17 Q17 Q25 128 *) + 0x4eb98421; (* arm_ADD_VEC Q1 Q1 Q25 32 128 *) + 0x6ea09821; (* arm_CMLE_VEC_ZERO Q1 Q1 32 128 *) + 0x4f001421; (* arm_ORR_VEC Q1 Q1 (rvalue (word 79228162532711081671548469249)) 128 *) + 0x4ea59431; (* arm_MLA_VEC Q17 Q1 Q5 32 128 *) + 0x4eb83639; (* arm_CMGT_VEC Q25 Q17 Q24 32 128 *) + 0x4e791e31; (* arm_BIC_VEC Q17 Q17 Q25 128 *) + 0x6eb86e31; (* arm_UMIN_VEC Q17 Q17 Q24 32 128 *) + 0x4eb7b452; (* arm_SQDMULH_VEC Q18 Q2 Q23 32 128 *) + 0x4f2f2652; (* arm_SRSHR_VEC Q18 Q18 17 32 128 *) + 0x4eb53459; (* arm_CMGT_VEC Q25 Q2 Q21 32 128 *) + 0x6eb69642; (* arm_MLS_VEC Q2 Q18 Q22 32 128 *) + 0x4e791e52; (* arm_BIC_VEC Q18 Q18 Q25 128 *) + 0x4eb98442; (* arm_ADD_VEC Q2 Q2 Q25 32 128 *) + 0x6ea09842; (* arm_CMLE_VEC_ZERO Q2 Q2 32 128 *) + 0x4f001422; (* arm_ORR_VEC Q2 Q2 (rvalue (word 79228162532711081671548469249)) 128 *) + 0x4ea69452; (* arm_MLA_VEC Q18 Q2 Q6 32 128 *) + 0x4eb83659; (* arm_CMGT_VEC Q25 Q18 Q24 32 128 *) + 0x4e791e52; (* arm_BIC_VEC Q18 Q18 Q25 128 *) + 0x6eb86e52; (* arm_UMIN_VEC Q18 Q18 Q24 32 128 *) + 0x4eb7b473; (* arm_SQDMULH_VEC Q19 Q3 Q23 32 128 *) + 0x4f2f2673; (* arm_SRSHR_VEC Q19 Q19 17 32 128 *) + 0x4eb53479; (* arm_CMGT_VEC Q25 Q3 Q21 32 128 *) + 0x6eb69663; (* arm_MLS_VEC Q3 Q19 Q22 32 128 *) + 0x4e791e73; (* arm_BIC_VEC Q19 Q19 Q25 128 *) + 0x4eb98463; (* arm_ADD_VEC Q3 Q3 Q25 32 128 *) + 0x6ea09863; (* arm_CMLE_VEC_ZERO Q3 Q3 32 128 *) + 0x4f001423; (* arm_ORR_VEC Q3 Q3 (rvalue (word 79228162532711081671548469249)) 128 *) + 0x4ea79473; (* arm_MLA_VEC Q19 Q3 Q7 32 128 *) + 0x4eb83679; (* arm_CMGT_VEC Q25 Q19 Q24 32 128 *) + 0x4e791e73; (* arm_BIC_VEC Q19 Q19 Q25 128 *) + 0x6eb86e73; (* arm_UMIN_VEC Q19 Q19 Q24 32 128 *) + 0x4eb7b410; (* arm_SQDMULH_VEC Q16 Q0 Q23 32 128 *) + 0x4f2f2610; (* arm_SRSHR_VEC Q16 Q16 17 32 128 *) + 0x4eb53419; (* arm_CMGT_VEC Q25 Q0 Q21 32 128 *) + 0x6eb69600; (* arm_MLS_VEC Q0 Q16 Q22 32 128 *) + 0x4e791e10; (* arm_BIC_VEC Q16 Q16 Q25 128 *) + 0x4eb98400; (* arm_ADD_VEC Q0 Q0 Q25 32 128 *) + 0x6ea09800; (* arm_CMLE_VEC_ZERO Q0 Q0 32 128 *) + 0x4f001420; (* arm_ORR_VEC Q0 Q0 (rvalue (word 79228162532711081671548469249)) 128 *) + 0x4ea49410; (* arm_MLA_VEC Q16 Q0 Q4 32 128 *) + 0x4eb83619; (* arm_CMGT_VEC Q25 Q16 Q24 32 128 *) + 0x4e791e10; (* arm_BIC_VEC Q16 Q16 Q25 128 *) + 0x6eb86e10; (* arm_UMIN_VEC Q16 Q16 Q24 32 128 *) + 0x3d800411; (* arm_STR Q17 X0 (Immediate_Offset (word 16)) *) + 0x3d800812; (* arm_STR Q18 X0 (Immediate_Offset (word 32)) *) + 0x3d800c13; (* arm_STR Q19 X0 (Immediate_Offset (word 48)) *) + 0x3c840410; (* arm_STR Q16 X0 (Postimmediate_Offset (word 64)) *) + 0xf1000463; (* arm_SUBS X3 X3 (rvalue (word 1)) *) + 0x54fff861; (* arm_BNE (word 2096908) *) + 0xd65f03c0 (* arm_RET X30 *) +];; +(*** BYTECODE END ***) + +let MLDSA_USE_HINT_88_EXEC = ARM_MK_EXEC_RULE mldsa_poly_use_hint_88_mc;; + + +(* ========================================================================= *) +(* Functional specification: UseHint for ML-DSA parameter set 44 *) +(* GAMMA2 = (Q-1)/88 = 95232, 2*GAMMA2 = 190464, output range [0, 43] *) +(* ========================================================================= *) + +let mldsa_use_hint_88_spec = new_definition + `mldsa_use_hint_88_spec (a:num) (h:num) = + let a1_raw = ((((a + 127) DIV 128) * 11275 + 8388608) DIV 16777216) in + let a1 = if a1_raw > 43 then 0 else a1_raw in + let a0:int = &a - &a1 * &190464 in + let a0' = if a0 > &4190208 then a0 - &8380417 else a0 in + if h = 0 then a1 + else if a0' > &0 then if a1 = 43 then 0 else a1 + 1 + else if a1 = 0 then 43 else a1 - 1`;; + +let mldsa_use_hint_88_asm = new_definition + `mldsa_use_hint_88_asm (a:int32) (h:int32) : int32 = + let a1 = word_ishr_round (word_2smulh a (word 1477838209)) 17 in + let m:int32 = word_neg(word(bitval(word_igt a (word 8285184)))) in + let a0 = word_add (word_sub a (word_mul a1 (word 190464))) m in + let a1' = word_and a1 (word_not m) in + let delta:int32 = word_or (word_neg(word(bitval(word_ile a0 (word 0))))) (word 1) in + let tmp = word_add a1' (word_mul delta h) in + let neg_mask:int32 = word_neg(word(bitval(word_igt tmp (word 43)))) in + let tmp' = word_and tmp (word_not neg_mask) in + word_umin tmp' (word 43)`;; + +(* ========================================================================= *) +(* Helper lemmas *) +(* ========================================================================= *) + +let IVAL_SMALL = MLDSA_IVAL_VAL;; +let VAL_IWORD_NUM = VAL_IWORD_NUM_32;; + +let WORD_2SMULH_NOSATURATE_88 = prove( + `!a:int32. val a < 8380417 + ==> word_2smulh a (word 1477838209:int32) : int32 = + iword((&2 * &(val a) * &1477838209) div &2 pow 32)`, + GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC[word_2smulh; DIMINDEX_32] THEN + ASM_SIMP_TAC[IVAL_SMALL] THEN + CONV_TAC WORD_REDUCE_CONV THEN + REWRITE_TAC[iword_saturate; word_INT_MIN; word_INT_MAX; DIMINDEX_32] THEN + CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC WORD_REDUCE_CONV THEN + CONV_TAC(DEPTH_CONV WORD_NUM_RED_CONV) THEN + REWRITE_TAC[INT_OF_NUM_CLAUSES] THEN + SIMP_TAC[INT_OF_NUM_DIV] THEN + REWRITE_TAC[INT_POS_NEG_BOUND] THEN + SUBGOAL_THEN `~(&((2 * val(a:int32) * 1477838209) DIV 4294967296):int > &2147483647)` + (fun th -> REWRITE_TAC[th]) THEN + REWRITE_TAC[INT_ARITH `~(x:int > y) <=> x <= y`; INT_OF_NUM_LE] THEN + TRANS_TAC LE_TRANS `(2 * 8380416 * 1477838209) DIV 4294967296` THEN + CONJ_TAC THENL + [MATCH_MP_TAC DIV_MONO THEN ASM_ARITH_TAC; + CONV_TAC NUM_REDUCE_CONV]);; + +let WORD_ISHR_ROUND_17 = prove( + `!t:int32. val t < 2147483648 + ==> word_ishr_round t 17 = iword((&(val t) + &65536) div &131072)`, + GEN_TAC THEN DISCH_TAC THEN + REWRITE_TAC[word_ishr_round] THEN + CONV_TAC NUM_REDUCE_CONV THEN + CONV_TAC INT_REDUCE_CONV THEN + SUBGOAL_THEN `ival(t:int32) = &(val t)` SUBST1_TAC THENL + [SIMP_TAC[ival; DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV THEN + COND_CASES_TAC THEN ASM_ARITH_TAC; + REFL_TAC]);; + +let VAL_DECOMPOSE_A1_88 = prove( + `!a:int32. val a < 8380417 + ==> val(word_ishr_round (word_2smulh a (word 1477838209:int32)) 17 : int32) + = ((2 * val a * 1477838209) DIV 4294967296 + 65536) DIV 131072`, + GEN_TAC THEN DISCH_TAC THEN + ASM_SIMP_TAC[WORD_2SMULH_NOSATURATE_88] THEN + SUBGOAL_THEN `(2 * val(a:int32) * 1477838209) DIV 4294967296 < 2147483648` + ASSUME_TAC THENL + [TRANS_TAC LT_TRANS `(2 * 8380416 * 1477838209) DIV 4294967296 + 1` THEN + CONJ_TAC THENL + [MATCH_MP_TAC(ARITH_RULE `x <= y ==> x < y + 1`) THEN + MATCH_MP_TAC DIV_MONO THEN ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV]; ALL_TAC] THEN + REWRITE_TAC[INT_OF_NUM_CLAUSES] THEN SIMP_TAC[INT_OF_NUM_DIV] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ABBREV_TAC `t:int32 = iword(&((2 * val(a:int32) * 1477838209) DIV 4294967296))` THEN + SUBGOAL_THEN `val(t:int32) = (2 * val(a:int32) * 1477838209) DIV 4294967296` + ASSUME_TAC THENL + [EXPAND_TAC "t" THEN MATCH_MP_TAC VAL_IWORD_NUM THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `val(t:int32) < 2147483648` ASSUME_TAC THENL + [ASM_REWRITE_TAC[]; ALL_TAC] THEN + REWRITE_TAC[word_ishr_round] THEN CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC INT_REDUCE_CONV THEN + SUBGOAL_THEN `ival(t:int32) = &(val t)` ASSUME_TAC THENL + [SIMP_TAC[ival; DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV THEN + COND_CASES_TAC THEN ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[INT_OF_NUM_CLAUSES] THEN SIMP_TAC[INT_OF_NUM_DIV] THEN CONV_TAC NUM_REDUCE_CONV THEN + SUBGOAL_THEN `(val(t:int32) + 65536) DIV 131072 < 2147483648` ASSUME_TAC THENL + [ASM_REWRITE_TAC[] THEN + TRANS_TAC LT_TRANS `(5767167 + 65536) DIV 131072 + 1` THEN CONJ_TAC THENL + [MATCH_MP_TAC(ARITH_RULE `x <= y ==> x < y + 1`) THEN + MATCH_MP_TAC DIV_MONO THEN ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV]; ALL_TAC] THEN + ASM_SIMP_TAC[VAL_IWORD_NUM] THEN MATCH_MP_TAC VAL_IWORD_NUM THEN + UNDISCH_THEN `val(t:int32) = (2 * val(a:int32) * 1477838209) DIV 4294967296` + (SUBST1_TAC o SYM) THEN ASM_REWRITE_TAC[]);; + +let WORD_IGT_THRESHOLD_88 = BITBLAST_RULE + `!a:int32. val a < 8380417 + ==> word_igt a (word 8285184:int32) <=> val a > 8285184`;; + +let A1_BOUND_88 = prove( + `!a. a < 8380417 + ==> ((a + 127) DIV 128 * 11275 + 8388608) DIV 16777216 <= 44`, + GEN_TAC THEN DISCH_TAC THEN + MP_TAC(SPEC `128` (SPEC `8380416 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + ABBREV_TAC `d = (a + 127) DIV 128` THEN + MP_TAC(SPEC `16777216` (SPEC `751819508` (SPEC `d * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL + [SUBGOAL_THEN `d * 11275 <= 65472 * 11275` MP_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; CONV_TAC NUM_REDUCE_CONV THEN ARITH_TAC]; + CONV_TAC NUM_REDUCE_CONV THEN ARITH_TAC]);; + +let A1_BOUND_NOWRAP_88 = prove( + `!a. a <= 8285184 + ==> ((a + 127) DIV 128 * 11275 + 8388608) DIV 16777216 <= 43`, + GEN_TAC THEN DISCH_TAC THEN + MP_TAC(SPEC `128` (SPEC `8285184 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + ABBREV_TAC `d = (a + 127) DIV 128` THEN + MP_TAC(SPEC `16777216` (SPEC `738196808` (SPEC `d * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL + [SUBGOAL_THEN `d * 11275 <= 64728 * 11275` MP_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; CONV_TAC NUM_REDUCE_CONV THEN ARITH_TAC]; + CONV_TAC NUM_REDUCE_CONV THEN ARITH_TAC]);; + +(* Barrett equivalence for _88: 45-interval case analysis *) +let BARRETT_EQUIV_88 = prove( + `!a. a < 8380417 ==> + ((2 * a * 1477838209) DIV 4294967296 + 65536) DIV 131072 = + ((a + 127) DIV 128 * 11275 + 8388608) DIV 16777216`, + GEN_TAC THEN DISCH_TAC THEN + ASM_CASES_TAC `a <= 95232` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 95232 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 0 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `95232 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `0 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq0 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq0 * 11275 <= 744 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `0 * 11275 <= qq0 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `744 * 11275 + 8388608` + (SPEC `qq0 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq0 * 11275 + 8388608` + (SPEC `0 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 285696` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 285696 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 95233 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `285696 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `95233 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq1 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq1 * 11275 <= 2232 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `745 * 11275 <= qq1 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `2232 * 11275 + 8388608` + (SPEC `qq1 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq1 * 11275 + 8388608` + (SPEC `745 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 476160` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 476160 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 285697 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `476160 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `285697 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq2 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq2 * 11275 <= 3720 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `2233 * 11275 <= qq2 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `3720 * 11275 + 8388608` + (SPEC `qq2 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq2 * 11275 + 8388608` + (SPEC `2233 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 666624` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 666624 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 476161 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `666624 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `476161 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq3 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq3 * 11275 <= 5208 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `3721 * 11275 <= qq3 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `5208 * 11275 + 8388608` + (SPEC `qq3 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq3 * 11275 + 8388608` + (SPEC `3721 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 857088` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 857088 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 666625 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `857088 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `666625 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq4 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq4 * 11275 <= 6696 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `5209 * 11275 <= qq4 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `6696 * 11275 + 8388608` + (SPEC `qq4 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq4 * 11275 + 8388608` + (SPEC `5209 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 1047552` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 1047552 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 857089 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `1047552 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `857089 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq5 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq5 * 11275 <= 8184 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `6697 * 11275 <= qq5 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `8184 * 11275 + 8388608` + (SPEC `qq5 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq5 * 11275 + 8388608` + (SPEC `6697 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 1238016` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 1238016 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 1047553 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `1238016 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `1047553 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq6 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq6 * 11275 <= 9672 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `8185 * 11275 <= qq6 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `9672 * 11275 + 8388608` + (SPEC `qq6 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq6 * 11275 + 8388608` + (SPEC `8185 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 1428480` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 1428480 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 1238017 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `1428480 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `1238017 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq7 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq7 * 11275 <= 11160 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `9673 * 11275 <= qq7 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `11160 * 11275 + 8388608` + (SPEC `qq7 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq7 * 11275 + 8388608` + (SPEC `9673 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 1618944` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 1618944 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 1428481 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `1618944 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `1428481 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq8 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq8 * 11275 <= 12648 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `11161 * 11275 <= qq8 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `12648 * 11275 + 8388608` + (SPEC `qq8 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq8 * 11275 + 8388608` + (SPEC `11161 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 1809408` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 1809408 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 1618945 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `1809408 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `1618945 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq9 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq9 * 11275 <= 14136 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `12649 * 11275 <= qq9 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `14136 * 11275 + 8388608` + (SPEC `qq9 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq9 * 11275 + 8388608` + (SPEC `12649 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 1999872` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 1999872 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 1809409 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `1999872 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `1809409 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq10 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq10 * 11275 <= 15624 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `14137 * 11275 <= qq10 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `15624 * 11275 + 8388608` + (SPEC `qq10 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq10 * 11275 + 8388608` + (SPEC `14137 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 2190336` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 2190336 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 1999873 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `2190336 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `1999873 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq11 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq11 * 11275 <= 17112 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `15625 * 11275 <= qq11 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `17112 * 11275 + 8388608` + (SPEC `qq11 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq11 * 11275 + 8388608` + (SPEC `15625 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 2380800` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 2380800 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 2190337 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `2380800 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `2190337 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq12 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq12 * 11275 <= 18600 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `17113 * 11275 <= qq12 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `18600 * 11275 + 8388608` + (SPEC `qq12 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq12 * 11275 + 8388608` + (SPEC `17113 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 2571264` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 2571264 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 2380801 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `2571264 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `2380801 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq13 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq13 * 11275 <= 20088 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `18601 * 11275 <= qq13 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `20088 * 11275 + 8388608` + (SPEC `qq13 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq13 * 11275 + 8388608` + (SPEC `18601 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 2761728` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 2761728 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 2571265 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `2761728 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `2571265 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq14 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq14 * 11275 <= 21576 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `20089 * 11275 <= qq14 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `21576 * 11275 + 8388608` + (SPEC `qq14 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq14 * 11275 + 8388608` + (SPEC `20089 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 2952192` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 2952192 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 2761729 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `2952192 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `2761729 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq15 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq15 * 11275 <= 23064 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `21577 * 11275 <= qq15 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `23064 * 11275 + 8388608` + (SPEC `qq15 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq15 * 11275 + 8388608` + (SPEC `21577 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 3142656` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 3142656 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 2952193 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `3142656 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `2952193 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq16 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq16 * 11275 <= 24552 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `23065 * 11275 <= qq16 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `24552 * 11275 + 8388608` + (SPEC `qq16 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq16 * 11275 + 8388608` + (SPEC `23065 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 3333120` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 3333120 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 3142657 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `3333120 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `3142657 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq17 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq17 * 11275 <= 26040 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `24553 * 11275 <= qq17 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `26040 * 11275 + 8388608` + (SPEC `qq17 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq17 * 11275 + 8388608` + (SPEC `24553 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 3523584` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 3523584 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 3333121 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `3523584 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `3333121 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq18 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq18 * 11275 <= 27528 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `26041 * 11275 <= qq18 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `27528 * 11275 + 8388608` + (SPEC `qq18 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq18 * 11275 + 8388608` + (SPEC `26041 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 3714048` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 3714048 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 3523585 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `3714048 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `3523585 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq19 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq19 * 11275 <= 29016 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `27529 * 11275 <= qq19 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `29016 * 11275 + 8388608` + (SPEC `qq19 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq19 * 11275 + 8388608` + (SPEC `27529 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 3904512` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 3904512 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 3714049 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `3904512 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `3714049 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq20 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq20 * 11275 <= 30504 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `29017 * 11275 <= qq20 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `30504 * 11275 + 8388608` + (SPEC `qq20 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq20 * 11275 + 8388608` + (SPEC `29017 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 4094976` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 4094976 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 3904513 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `4094976 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `3904513 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq21 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq21 * 11275 <= 31992 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `30505 * 11275 <= qq21 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `31992 * 11275 + 8388608` + (SPEC `qq21 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq21 * 11275 + 8388608` + (SPEC `30505 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 4285440` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 4285440 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 4094977 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `4285440 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `4094977 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq22 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq22 * 11275 <= 33480 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `31993 * 11275 <= qq22 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `33480 * 11275 + 8388608` + (SPEC `qq22 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq22 * 11275 + 8388608` + (SPEC `31993 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 4475904` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 4475904 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 4285441 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `4475904 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `4285441 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq23 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq23 * 11275 <= 34968 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `33481 * 11275 <= qq23 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `34968 * 11275 + 8388608` + (SPEC `qq23 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq23 * 11275 + 8388608` + (SPEC `33481 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 4666368` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 4666368 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 4475905 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `4666368 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `4475905 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq24 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq24 * 11275 <= 36456 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `34969 * 11275 <= qq24 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `36456 * 11275 + 8388608` + (SPEC `qq24 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq24 * 11275 + 8388608` + (SPEC `34969 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 4856832` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 4856832 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 4666369 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `4856832 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `4666369 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq25 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq25 * 11275 <= 37944 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `36457 * 11275 <= qq25 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `37944 * 11275 + 8388608` + (SPEC `qq25 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq25 * 11275 + 8388608` + (SPEC `36457 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 5047296` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 5047296 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 4856833 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `5047296 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `4856833 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq26 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq26 * 11275 <= 39432 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `37945 * 11275 <= qq26 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `39432 * 11275 + 8388608` + (SPEC `qq26 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq26 * 11275 + 8388608` + (SPEC `37945 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 5237760` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 5237760 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 5047297 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `5237760 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `5047297 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq27 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq27 * 11275 <= 40920 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `39433 * 11275 <= qq27 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `40920 * 11275 + 8388608` + (SPEC `qq27 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq27 * 11275 + 8388608` + (SPEC `39433 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 5428224` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 5428224 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 5237761 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `5428224 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `5237761 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq28 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq28 * 11275 <= 42408 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `40921 * 11275 <= qq28 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `42408 * 11275 + 8388608` + (SPEC `qq28 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq28 * 11275 + 8388608` + (SPEC `40921 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 5618688` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 5618688 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 5428225 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `5618688 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `5428225 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq29 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq29 * 11275 <= 43896 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `42409 * 11275 <= qq29 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `43896 * 11275 + 8388608` + (SPEC `qq29 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq29 * 11275 + 8388608` + (SPEC `42409 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 5809152` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 5809152 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 5618689 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `5809152 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `5618689 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq30 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq30 * 11275 <= 45384 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `43897 * 11275 <= qq30 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `45384 * 11275 + 8388608` + (SPEC `qq30 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq30 * 11275 + 8388608` + (SPEC `43897 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 5999616` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 5999616 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 5809153 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `5999616 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `5809153 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq31 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq31 * 11275 <= 46872 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `45385 * 11275 <= qq31 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `46872 * 11275 + 8388608` + (SPEC `qq31 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq31 * 11275 + 8388608` + (SPEC `45385 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 6190080` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 6190080 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 5999617 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `6190080 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `5999617 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq32 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq32 * 11275 <= 48360 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `46873 * 11275 <= qq32 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `48360 * 11275 + 8388608` + (SPEC `qq32 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq32 * 11275 + 8388608` + (SPEC `46873 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 6380544` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 6380544 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 6190081 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `6380544 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `6190081 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq33 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq33 * 11275 <= 49848 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `48361 * 11275 <= qq33 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `49848 * 11275 + 8388608` + (SPEC `qq33 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq33 * 11275 + 8388608` + (SPEC `48361 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 6571008` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 6571008 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 6380545 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `6571008 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `6380545 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq34 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq34 * 11275 <= 51336 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `49849 * 11275 <= qq34 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `51336 * 11275 + 8388608` + (SPEC `qq34 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq34 * 11275 + 8388608` + (SPEC `49849 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 6761472` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 6761472 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 6571009 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `6761472 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `6571009 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq35 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq35 * 11275 <= 52824 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `51337 * 11275 <= qq35 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `52824 * 11275 + 8388608` + (SPEC `qq35 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq35 * 11275 + 8388608` + (SPEC `51337 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 6951936` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 6951936 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 6761473 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `6951936 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `6761473 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq36 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq36 * 11275 <= 54312 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `52825 * 11275 <= qq36 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `54312 * 11275 + 8388608` + (SPEC `qq36 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq36 * 11275 + 8388608` + (SPEC `52825 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 7142400` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 7142400 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 6951937 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `7142400 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `6951937 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq37 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq37 * 11275 <= 55800 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `54313 * 11275 <= qq37 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `55800 * 11275 + 8388608` + (SPEC `qq37 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq37 * 11275 + 8388608` + (SPEC `54313 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 7332864` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 7332864 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 7142401 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `7332864 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `7142401 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq38 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq38 * 11275 <= 57288 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `55801 * 11275 <= qq38 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `57288 * 11275 + 8388608` + (SPEC `qq38 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq38 * 11275 + 8388608` + (SPEC `55801 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 7523328` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 7523328 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 7332865 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `7523328 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `7332865 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq39 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq39 * 11275 <= 58776 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `57289 * 11275 <= qq39 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `58776 * 11275 + 8388608` + (SPEC `qq39 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq39 * 11275 + 8388608` + (SPEC `57289 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 7713792` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 7713792 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 7523329 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `7713792 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `7523329 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq40 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq40 * 11275 <= 60264 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `58777 * 11275 <= qq40 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `60264 * 11275 + 8388608` + (SPEC `qq40 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq40 * 11275 + 8388608` + (SPEC `58777 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 7904256` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 7904256 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 7713793 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `7904256 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `7713793 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq41 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq41 * 11275 <= 61752 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `60265 * 11275 <= qq41 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `61752 * 11275 + 8388608` + (SPEC `qq41 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq41 * 11275 + 8388608` + (SPEC `60265 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 8094720` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 8094720 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 7904257 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `8094720 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `7904257 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq42 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq42 * 11275 <= 63240 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `61753 * 11275 <= qq42 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `63240 * 11275 + 8388608` + (SPEC `qq42 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq42 * 11275 + 8388608` + (SPEC `61753 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + ASM_CASES_TAC `a <= 8285184` THENL + [ + MP_TAC(SPEC `131072` (SPEC `(2 * 8285184 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 8094721 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `8285184 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `8094721 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq43 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq43 * 11275 <= 64728 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `63241 * 11275 <= qq43 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `64728 * 11275 + 8388608` + (SPEC `qq43 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq43 * 11275 + 8388608` + (SPEC `63241 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ; + (* Last case: a > 8285184 *) + MP_TAC(SPEC `131072` (SPEC `(2 * 8380416 * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` + (SPEC `(2 * 8285185 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `8380416 + 127` (SPEC `a + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `8285185 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ABBREV_TAC `qq44 = (a + 127) DIV 128` THEN + SUBGOAL_THEN `qq44 * 11275 <= 65472 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + SUBGOAL_THEN `64729 * 11275 <= qq44 * 11275` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `65472 * 11275 + 8388608` + (SPEC `qq44 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + MP_TAC(SPEC `16777216` (SPEC `qq44 * 11275 + 8388608` + (SPEC `64729 * 11275 + 8388608` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN + ASM_ARITH_TAC + ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]);; + + +let SPEC_BOUND_88 = prove( + `!a h. a < 8380417 /\ h <= 1 + ==> mldsa_use_hint_88_spec a h <= 43`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC[mldsa_use_hint_88_spec; LET_DEF; LET_END_DEF] THEN + MP_TAC(SPEC `a:num` A1_BOUND_88) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN ASM_ARITH_TAC);; + +let WORD_SUB_SIGN_88 = BITBLAST_RULE + `!a:int32 b:int32. val b <= 8189952 /\ val a <= 8285184 ==> + ((bit 31 (word_sub a b) \/ word_sub a b = word 0) <=> val a <= val b)`;; + +let WRAP_A0_NEGATIVE_88 = BITBLAST_RULE + `!a:int32. val a < 8380417 /\ val a > 8285184 + ==> bit 31 (word_add (word_sub a (word 8380416:int32)) (word 4294967295:int32))`;; + +let A1_WRAP_88 = prove( + `!a. 8285184 < a /\ a < 8380417 + ==> ((a + 127) DIV 128 * 11275 + 8388608) DIV 16777216 = 44`, + GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN `44 <= ((a + 127) DIV 128 * 11275 + 8388608) DIV 16777216` + ASSUME_TAC THENL + [MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `8285185 + 127` DIV_MONO))) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC THEN + ABBREV_TAC `d = (a + 127) DIV 128` THEN + MP_TAC(SPEC `16777216` (SPEC `d * 11275 + 8388608` (SPEC `738208083` DIV_MONO))) THEN + ANTS_TAC THENL + [SUBGOAL_THEN `64729 * 11275 <= d * 11275` MP_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; CONV_TAC NUM_REDUCE_CONV THEN ARITH_TAC]; + CONV_TAC NUM_REDUCE_CONV THEN ARITH_TAC]; ALL_TAC] THEN + MP_TAC(SPEC `a:num` A1_BOUND_88) THEN ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN ASM_ARITH_TAC);; + +let A0_UPPER_88 = prove( + `!a. a <= 8285184 + ==> a < (((a + 127) DIV 128 * 11275 + 8388608) DIV 16777216 + 1) * 190464`, + GEN_TAC THEN DISCH_TAC THEN + ABBREV_TAC `nv = ((a + 127) DIV 128 * 11275 + 8388608) DIV 16777216` THEN + SUBGOAL_THEN `nv * 16777216 <= (a + 127) DIV 128 * 11275 + 8388608` ASSUME_TAC THENL + [EXPAND_TAC "nv" THEN MP_TAC(SPECL [`(a + 127) DIV 128 * 11275 + 8388608`; `16777216`] (CONJUNCT1 DIVISION_SIMP)) THEN ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(a + 127) DIV 128 <= 64728` ASSUME_TAC THENL + [MP_TAC(SPEC `128` (SPEC `8285184 + 127` (SPEC `a + 127` DIV_MONO))) THEN ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN ARITH_TAC]; ALL_TAC] THEN + SUBGOAL_THEN `nv * 16777216 <= 64728 * 11275 + 8388608` ASSUME_TAC THENL + [SUBGOAL_THEN `(a + 127) DIV 128 * 11275 <= 64728 * 11275` MP_TAC THENL [REWRITE_TAC[LE_MULT_RCANCEL] THEN DISJ1_TAC THEN ASM_ARITH_TAC; ASM_ARITH_TAC]; ALL_TAC] THEN + SUBGOAL_THEN `nv <= 43` ASSUME_TAC THENL [CONV_TAC NUM_REDUCE_CONV THEN ASM_ARITH_TAC; ALL_TAC] THEN + ASM_ARITH_TAC);; + +let WORD_AND_ONES_32 = prove( + `!x:int32. word_and x (word 4294967295) = x`, + GEN_TAC THEN SUBGOAL_THEN `(word 4294967295 : int32) = word_not(word 0)` SUBST1_TAC THENL + [CONV_TAC WORD_REDUCE_CONV; REWRITE_TAC[WORD_AND_NOT0]]);; + +let WORD_MUL_1_32 = prove( + `!x:int32. word_mul x (word 1) = x`, + GEN_TAC THEN REWRITE_TAC[GSYM VAL_EQ; VAL_WORD_MUL; VAL_WORD; DIMINDEX_32] THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[MULT_CLAUSES] THEN + MATCH_MP_TAC MOD_LT THEN MP_TAC(ISPEC `x:int32` VAL_BOUND) THEN + REWRITE_TAC[DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV);; + +let REAL_INT_GT_BRIDGE_88 = prove( + `!a:num b c. a <= b * c ==> + ~(real_gt (&a - &b * &c) (&0)) /\ ~(int_gt (&a - &b * &c) (&0))`, + REPEAT GEN_TAC THEN DISCH_TAC THEN CONJ_TAC THENL + [REWRITE_TAC[real_gt; REAL_NOT_LT] THEN + MP_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_MUL] (ASSUME `a <= b * c`)) THEN REAL_ARITH_TAC; + REWRITE_TAC[INT_GT; INT_NOT_LT] THEN + MP_TAC(REWRITE_RULE[GSYM INT_OF_NUM_LE; GSYM INT_OF_NUM_MUL] (ASSUME `a <= b * c`)) THEN INT_ARITH_TAC]);; + +let REAL_INT_GT_BRIDGE_POS_88 = prove( + `!a:num b c. ~(a <= b * c) ==> + real_gt (&a - &b * &c) (&0) /\ int_gt (&a - &b * &c) (&0)`, + REPEAT GEN_TAC THEN REWRITE_TAC[NOT_LE] THEN DISCH_TAC THEN CONJ_TAC THENL + [REWRITE_TAC[real_gt] THEN + MP_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LT; GSYM REAL_OF_NUM_MUL] (ASSUME `b * c < a`)) THEN REAL_ARITH_TAC; + REWRITE_TAC[INT_GT] THEN + MP_TAC(REWRITE_RULE[GSYM INT_OF_NUM_LT; GSYM INT_OF_NUM_MUL] (ASSUME `b * c < a`)) THEN INT_ARITH_TAC]);; + +let WORD_IGT_43_BOUND = BITBLAST_RULE + `!a:int32. val a <= 43 ==> ~(word_igt a (word 43:int32))`;; +let WORD_IGT_43_ADD1 = BITBLAST_RULE + `!a:int32. val a <= 42 ==> ~(word_igt (word_add a (word 1:int32)) (word 43:int32))`;; +let WORD_IGT_43_SUB1 = BITBLAST_RULE + `!a:int32. val a <= 43 /\ ~(val a = 0) ==> + ~(word_igt (word_add a (word 4294967295:int32)) (word 43:int32))`;; +let WORD_IGT_43_TRUE = BITBLAST_RULE + `word_igt (word 44:int32) (word 43:int32)`;; + +let ELEMENT_CORRECT_88 = prove( + `!a:int32 h:int32. + val a < 8380417 /\ val h <= 1 + ==> val(mldsa_use_hint_88_asm a h) = mldsa_use_hint_88_spec (val a) (val h)`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC[mldsa_use_hint_88_asm; mldsa_use_hint_88_spec] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + ABBREV_TAC `nv = ((val(a:int32) + 127) DIV 128 * 11275 + 8388608) DIV 16777216` THEN + SUBGOAL_THEN `val(word_ishr_round (word_2smulh (a:int32) (word 1477838209)) 17 : int32) = nv` ASSUME_TAC THENL + [EXPAND_TAC "nv" THEN TRANS_TAC EQ_TRANS `((2 * val(a:int32) * 1477838209) DIV 4294967296 + 65536) DIV 131072` THEN CONJ_TAC THENL [MATCH_MP_TAC VAL_DECOMPOSE_A1_88 THEN ASM_REWRITE_TAC[]; MATCH_MP_TAC BARRETT_EQUIV_88 THEN ASM_REWRITE_TAC[]]; ALL_TAC] THEN + SUBGOAL_THEN `nv <= 44` ASSUME_TAC THENL [MP_TAC(SPEC `val(a:int32)` A1_BOUND_88) THEN ASM_MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `word_igt (a:int32) (word 8285184:int32) <=> val a > 8285184` SUBST1_TAC THENL [MP_TAC(SPEC `a:int32` WORD_IGT_THRESHOLD_88) THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + ASM_CASES_TAC `val(a:int32) > 8285184` THENL + [(* Wrap case: val a > 8285184, nv = 44 *) + REWRITE_TAC[ASSUME `val(a:int32) > 8285184`; bitval] THEN + SUBGOAL_THEN `nv = 44` SUBST_ALL_TAC THENL [MP_TAC(SPEC `val(a:int32)` A1_WRAP_88) THEN ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + ABBREV_TAC `a1w = word_ishr_round (word_2smulh (a:int32) (word 1477838209)) 17 : int32` THEN + SUBGOAL_THEN `a1w = (word 44:int32)` SUBST_ALL_TAC THENL [EXPAND_TAC "a1w" THEN ONCE_REWRITE_TAC[GSYM WORD_VAL] THEN AP_TERM_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + CONV_TAC WORD_REDUCE_CONV THEN + CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC WORD_REDUCE_CONV THEN REWRITE_TAC[WORD_ILE_ZERO_32] THEN + MP_TAC(SPEC `a:int32` WRAP_A0_NEGATIVE_88) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN + ASM_REWRITE_TAC[bitval] THEN CONV_TAC WORD_REDUCE_CONV THEN + REWRITE_TAC[INT_MUL_LZERO; INT_SUB_RZERO] THEN + SUBGOAL_THEN `~((if int_gt (&(val(a:int32))) (&4190208) then &(val a) - &8380417 else &(val a):int) > &0)` ASSUME_TAC THENL + [REWRITE_TAC[INT_GT; INT_NOT_LT] THEN COND_CASES_TAC THENL + [MP_TAC(REWRITE_RULE[GSYM INT_OF_NUM_LT] (ASSUME `val(a:int32) < 8380417`)) THEN INT_ARITH_TAC; + POP_ASSUM(MP_TAC o REWRITE_RULE[INT_GT; INT_NOT_LT]) THEN + MP_TAC(REWRITE_RULE[GSYM INT_OF_NUM_GT; INT_GT] (ASSUME `val(a:int32) > 8285184`)) THEN INT_ARITH_TAC]; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `val(h:int32) = 0` THENL + [REWRITE_TAC[ASSUME `val(h:int32) = 0`] THEN + SUBGOAL_THEN `h:int32 = word 0` SUBST1_TAC THENL [REWRITE_TAC[GSYM VAL_EQ_0] THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + CONV_TAC WORD_REDUCE_CONV THEN REWRITE_TAC[VAL_WORD_UMIN; VAL_WORD; DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV; + REWRITE_TAC[ASSUME `~(val(h:int32) = 0)`] THEN + SUBGOAL_THEN `h:int32 = word 1` SUBST1_TAC THENL [REWRITE_TAC[GSYM VAL_EQ_1] THEN ASM_ARITH_TAC; ALL_TAC] THEN + CONV_TAC WORD_REDUCE_CONV THEN REWRITE_TAC[VAL_WORD_UMIN; VAL_WORD; DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV] + ;(* Nowrap case: val a <= 8285184 *) + REWRITE_TAC[ASSUME `~(val(a:int32) > 8285184)`; bitval] THEN + SUBGOAL_THEN `nv <= 43` ASSUME_TAC THENL [MP_TAC(SPEC `val(a:int32)` A1_BOUND_NOWRAP_88) THEN ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN ASM_MESON_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `(if nv > 43 then 0 else nv) = nv` SUBST1_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ABBREV_TAC `a1w = word_ishr_round (word_2smulh (a:int32) (word 1477838209)) 17 : int32` THEN + SUBGOAL_THEN `a1w = (word nv:int32)` SUBST_ALL_TAC THENL [EXPAND_TAC "a1w" THEN GEN_REWRITE_TAC LAND_CONV [GSYM WORD_VAL] THEN AP_TERM_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + CONV_TAC WORD_REDUCE_CONV THEN REWRITE_TAC[WORD_AND_REFL; WORD_ILE_ZERO_32; WORD_ADD_0; WORD_AND_ONES_32] THEN + SUBGOAL_THEN `nv * 190464 <= 8189952` ASSUME_TAC THENL [SUBGOAL_THEN `nv * 190464 <= 43 * 190464` MP_TAC THENL [REWRITE_TAC[LE_MULT_RCANCEL] THEN DISJ1_TAC THEN ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN ARITH_TAC]; ALL_TAC] THEN + SUBGOAL_THEN `val(word_mul (word nv:int32) (word 190464:int32)) = nv * 190464` ASSUME_TAC THENL [REWRITE_TAC[VAL_WORD_MUL; VAL_WORD; DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV THEN SUBGOAL_THEN `nv MOD 4294967296 = nv` SUBST1_TAC THENL [MATCH_MP_TAC MOD_LT THEN ASM_ARITH_TAC; ALL_TAC] THEN MATCH_MP_TAC MOD_LT THEN ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `val(word_mul (word nv:int32) (word 190464:int32)) <= 8189952` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(bit 31 (word_sub (a:int32) (word_mul (word nv:int32) (word 190464:int32))) \/ word_sub a (word_mul (word nv) (word 190464)) = word 0) <=> val a <= nv * 190464` SUBST1_TAC THENL + [MP_TAC(ISPECL [`a:int32`; `word_mul (word nv:int32) (word 190464:int32)`] WORD_SUB_SIGN_88) THEN ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN DISCH_THEN SUBST1_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + REWRITE_TAC[bitval] THEN + SUBGOAL_THEN `val(word nv:int32) = nv` ASSUME_TAC THENL [MATCH_MP_TAC VAL_WORD_EQ THEN REWRITE_TAC[DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV THEN ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~(word_igt (word nv:int32) (word 43:int32))` ASSUME_TAC THENL [MP_TAC(SPEC `word nv:int32` WORD_IGT_43_BOUND) THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + ASM_CASES_TAC `val(h:int32) = 0` THENL + [(* h = 0 nowrap *) + REWRITE_TAC[ASSUME `val(h:int32) = 0`] THEN + SUBGOAL_THEN `h:int32 = word 0` SUBST1_TAC THENL [REWRITE_TAC[GSYM VAL_EQ_0] THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + REWRITE_TAC[WORD_MUL_0; WORD_ADD_0] THEN + ASM_REWRITE_TAC[] THEN CONV_TAC WORD_REDUCE_CONV THEN REWRITE_TAC[WORD_AND_ONES_32; VAL_WORD_UMIN; VAL_WORD; DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `nv MOD 4294967296 = nv` SUBST1_TAC THENL [MATCH_MP_TAC MOD_LT THEN UNDISCH_TAC `nv <= 43` THEN ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[MIN] THEN UNDISCH_TAC `nv <= 43` THEN ARITH_TAC + ;(* h = 1 nowrap *) + REWRITE_TAC[ASSUME `~(val(h:int32) = 0)`] THEN + SUBGOAL_THEN `h:int32 = word 1` SUBST1_TAC THENL [REWRITE_TAC[GSYM VAL_EQ_1] THEN ASM_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[WORD_MUL_1_32; WORD_AND_ONES_32] THEN + SUBGOAL_THEN `val(word nv:int32) <= 43` ASSUME_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `~(int_gt (&(val(a:int32)) - &nv * &190464) (&4190208))` ASSUME_TAC THENL + [REWRITE_TAC[INT_GT; INT_NOT_LT] THEN MP_TAC(SPEC `val(a:int32)` A0_UPPER_88) THEN ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC(REWRITE_RULE[GSYM INT_OF_NUM_LT; GSYM INT_OF_NUM_MUL; GSYM INT_OF_NUM_ADD] (ASSUME `val(a:int32) < (nv + 1) * 190464`)) THEN INT_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `val(a:int32) <= nv * 190464` THENL + [MP_TAC(SPECL [`val(a:int32)`; `nv:num`; `190464`] REAL_INT_GT_BRIDGE_88) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[]; + MP_TAC(SPECL [`val(a:int32)`; `nv:num`; `190464`] REAL_INT_GT_BRIDGE_POS_88) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[]] THENL + [(* delta = -1: a0' <= 0 *) + REWRITE_TAC[bitval] THEN CONV_TAC WORD_REDUCE_CONV THEN REWRITE_TAC[WORD_AND_ONES_32] THEN + ASM_CASES_TAC `nv = 0` THENL + [ASM_REWRITE_TAC[] THEN CONV_TAC WORD_REDUCE_CONV THEN REWRITE_TAC[VAL_WORD_UMIN; VAL_WORD; DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV + ;REWRITE_TAC[ASSUME `~(nv = 0)`] THEN + SUBGOAL_THEN `~word_igt (word_add (word nv:int32) (word 4294967295)) (word 43:int32)` ASSUME_TAC THENL + [MP_TAC(SPEC `word nv:int32` WORD_IGT_43_SUB1) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN CONJ_TAC THENL [ASM_REWRITE_TAC[]; REWRITE_TAC[GSYM VAL_EQ_0] THEN ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC]; ALL_TAC] THEN + ASM_REWRITE_TAC[bitval] THEN CONV_TAC WORD_REDUCE_CONV THEN REWRITE_TAC[WORD_AND_ONES_32; VAL_WORD_UMIN; VAL_WORD_ADD; VAL_WORD; DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `nv MOD 4294967296 = nv` SUBST1_TAC THENL [MATCH_MP_TAC MOD_LT THEN UNDISCH_TAC `nv <= 43` THEN ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(nv + 4294967295) MOD 4294967296 = nv - 1` SUBST1_TAC THENL [SUBGOAL_THEN `nv + 4294967295 = (nv - 1) + 1 * 4294967296` SUBST1_TAC THENL [UNDISCH_TAC `~(nv = 0)` THEN ARITH_TAC; REWRITE_TAC[MOD_MULT_ADD] THEN MATCH_MP_TAC MOD_LT THEN UNDISCH_TAC `nv <= 43` THEN ARITH_TAC]; ALL_TAC] THEN + REWRITE_TAC[MIN] THEN UNDISCH_TAC `nv <= 43` THEN ARITH_TAC] + ;(* delta = +1: a0' > 0 *) + REWRITE_TAC[bitval] THEN CONV_TAC WORD_REDUCE_CONV THEN REWRITE_TAC[WORD_AND_ONES_32] THEN + ASM_CASES_TAC `nv = 43` THENL + [ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC WORD_REDUCE_CONV THEN MP_TAC WORD_IGT_43_TRUE THEN DISCH_TAC THEN ASM_REWRITE_TAC[bitval] THEN CONV_TAC WORD_REDUCE_CONV THEN REWRITE_TAC[VAL_WORD_UMIN; VAL_WORD; DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV + ;REWRITE_TAC[ASSUME `~(nv = 43)`] THEN + SUBGOAL_THEN `~word_igt (word_add (word nv:int32) (word 1)) (word 43:int32)` ASSUME_TAC THENL + [MP_TAC(SPEC `word nv:int32` WORD_IGT_43_ADD1) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN UNDISCH_TAC `nv <= 43` THEN UNDISCH_TAC `~(nv = 43)` THEN UNDISCH_TAC `val(word nv:int32) = nv` THEN ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[bitval] THEN CONV_TAC WORD_REDUCE_CONV THEN REWRITE_TAC[WORD_AND_ONES_32; VAL_WORD_UMIN; VAL_WORD_ADD; VAL_WORD; DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `nv MOD 4294967296 = nv` SUBST1_TAC THENL [MATCH_MP_TAC MOD_LT THEN UNDISCH_TAC `nv <= 43` THEN ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(nv + 1) MOD 4294967296 = nv + 1` SUBST1_TAC THENL [MATCH_MP_TAC MOD_LT THEN UNDISCH_TAC `nv <= 43` THEN ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[MIN] THEN UNDISCH_TAC `nv <= 43` THEN UNDISCH_TAC `~(nv = 43)` THEN ARITH_TAC]]]]);; + +let ELEMENT_CORRECT_WORD_88 = prove( + `!a:int32 h:int32. + val a < 8380417 /\ val h <= 1 + ==> mldsa_use_hint_88_asm a h = + word(mldsa_use_hint_88_spec (val a) (val h))`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + GEN_REWRITE_TAC LAND_CONV [GSYM WORD_VAL] THEN + AP_TERM_TAC THEN MP_TAC(SPECL [`a:int32`; `h:int32`] ELEMENT_CORRECT_88) THEN + ASM_REWRITE_TAC[] THEN DISCH_THEN(fun th -> REWRITE_TAC[th]));; + +(* ========================================================================= *) +(* Correctness proof with functional postcondition *) +(* ========================================================================= *) + +let MLDSA_USE_HINT_88_CORRECT = prove + (`!b a h x y pc. + nonoverlapping (word pc, LENGTH mldsa_poly_use_hint_88_mc) (b, 1024) /\ + nonoverlapping (b, 1024) (a, 1024) /\ + nonoverlapping (b, 1024) (h, 1024) + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) mldsa_poly_use_hint_88_mc /\ + read PC s = word pc /\ + C_ARGUMENTS [b; a; h] s /\ + (!i. i < 256 ==> val(x i) < 8380417) /\ + (!i. i < 256 ==> val(y i) <= 1) /\ + (!i. i < 256 ==> + read(memory :> bytes32(word_add a (word(4 * i)))) s = x i) /\ + (!i. i < 256 ==> + read(memory :> bytes32(word_add h (word(4 * i)))) s = y i)) + (\s. read PC s = word(pc + 0x130) /\ + (!i. i < 256 ==> + read(memory :> bytes32(word_add b (word(4 * i)))) s = + word(mldsa_use_hint_88_spec (val(x i)) (val(y i))))) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [memory :> bytes(b, 1024)])`, + + MAP_EVERY X_GEN_TAC + [`b:int64`; `a:int64`; `h:int64`; + `x:num->int32`; `y:num->int32`; `pc:num`] THEN + REWRITE_TAC[MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI; C_ARGUMENTS; + NONOVERLAPPING_CLAUSES; ALL; + fst MLDSA_USE_HINT_88_EXEC] THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + GLOBALIZE_PRECONDITION_TAC THEN + CONV_TAC(RATOR_CONV(LAND_CONV(ONCE_DEPTH_CONV EXPAND_CASES_CONV))) THEN + CONV_TAC NUM_REDUCE_CONV THEN + REPEAT STRIP_TAC THEN + REWRITE_TAC[SOME_FLAGS; MODIFIABLE_SIMD_REGS] THEN + + ENSURES_INIT_TAC "s0" THEN + MEMORY_128_FROM_32_TAC "a" 0 64 THEN + ASM_REWRITE_TAC[WORD_ADD_0] THEN CONV_TAC WORD_REDUCE_CONV THEN + STRIP_TAC THEN + MEMORY_128_FROM_32_TAC "h" 0 64 THEN + ASM_REWRITE_TAC[WORD_ADD_0] THEN CONV_TAC WORD_REDUCE_CONV THEN + STRIP_TAC THEN + DISCARD_MATCHING_ASSUMPTIONS [`read (memory :> bytes32 a) s = x`] THEN + + MAP_EVERY (fun n -> ARM_STEPS_TAC MLDSA_USE_HINT_88_EXEC [n] THEN + SIMD_SIMPLIFY_TAC[]) + (1--1006) THEN + ENSURES_FINAL_STATE_TAC THEN ASM_REWRITE_TAC[] THEN + + REPEAT(FIRST_X_ASSUM(STRIP_ASSUME_TAC o + CONV_RULE (SIMD_SIMPLIFY_CONV []) o + CONV_RULE(READ_MEMORY_SPLIT_CONV 2) o + check (can (term_match [] `read qqq s:int128 = xxx`) o concl))) THEN + + CONV_TAC(TOP_DEPTH_CONV EXPAND_CASES_CONV) THEN + CONV_TAC(DEPTH_CONV NUM_MULT_CONV THENC DEPTH_CONV NUM_ADD_CONV) THEN + REWRITE_TAC[WORD_ADD_0] THEN + ASM_REWRITE_TAC[WORD_ADD_0] THEN ASM_REWRITE_TAC[] THEN + + (* Push word_subword through SIMD ops to per-element form *) + REWRITE_TAC[WORD_SUBWORD_AND; WORD_SUBWORD_OR] THEN + let WSN_TAC = REWRITE_TAC(map (fun n -> prove( + subst [mk_small_numeral n, `n:num`] + `!x:int128. word_subword(word_not x) (n,32):int32 = word_not(word_subword x (n,32))`, + GEN_TAC THEN MATCH_MP_TAC WORD_SUBWORD_NOT THEN + REWRITE_TAC[DIMINDEX_32; DIMINDEX_128] THEN ARITH_TAC)) [0;32;64;96]) in + WSN_TAC THEN + CONV_TAC(DEPTH_CONV WORD_SIMPLE_SUBWORD_CONV) THEN + CONV_TAC(DEPTH_CONV WORD_NUM_RED_CONV) THEN + let EC_DEEP = CONV_RULE(DEPTH_CONV WORD_NUM_RED_CONV) + (CONV_RULE(DEPTH_CONV(INT_RED_CONV ORELSEC NUM_RED_CONV)) + (CONV_RULE(TOP_DEPTH_CONV let_CONV) + (REWRITE_RULE[mldsa_use_hint_88_asm; word_2smulh; word_ishr_round; + DIMINDEX_32] ELEMENT_CORRECT_WORD_88))) in + let EC_OR = ONCE_REWRITE_RULE[WORD_OR_SYM] EC_DEEP in + REPEAT CONJ_TAC THEN + (MATCH_MP_TAC EC_OR ORELSE MATCH_MP_TAC EC_DEEP) THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC);; + +(* ========================================================================= *) +(* Subroutine form *) +(* ========================================================================= *) + +let MLDSA_USE_HINT_88_SUBROUTINE_CORRECT = prove + (`!b a h x y pc returnaddress. + nonoverlapping (word pc, LENGTH mldsa_poly_use_hint_88_mc) (b, 1024) /\ + nonoverlapping (b, 1024) (a, 1024) /\ + nonoverlapping (b, 1024) (h, 1024) + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) mldsa_poly_use_hint_88_mc /\ + read PC s = word pc /\ + read X30 s = returnaddress /\ + C_ARGUMENTS [b; a; h] s /\ + (!i. i < 256 ==> val(x i) < 8380417) /\ + (!i. i < 256 ==> val(y i) <= 1) /\ + (!i. i < 256 ==> + read(memory :> bytes32(word_add a (word(4 * i)))) s = x i) /\ + (!i. i < 256 ==> + read(memory :> bytes32(word_add h (word(4 * i)))) s = y i)) + (\s. read PC s = returnaddress /\ + (!i. i < 256 ==> + read(memory :> bytes32(word_add b (word(4 * i)))) s = + word(mldsa_use_hint_88_spec (val(x i)) (val(y i))))) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [memory :> bytes(b, 1024)])`, + REWRITE_TAC[fst MLDSA_USE_HINT_88_EXEC] THEN + ARM_ADD_RETURN_NOSTACK_TAC MLDSA_USE_HINT_88_EXEC + (REWRITE_RULE[fst MLDSA_USE_HINT_88_EXEC] + MLDSA_USE_HINT_88_CORRECT));; + +(* ========================================================================= *) +(* Constant-time and memory safety proof. *) +(* ========================================================================= *) + +needs "arm/proofs/consttime.ml";; +needs "arm/proofs/subroutine_signatures.ml";; + + +let full_spec,public_vars = mk_safety_spec + ~keep_maychanges:false + (assoc "mldsa_poly_use_hint_88" subroutine_signatures) + MLDSA_USE_HINT_88_SUBROUTINE_CORRECT + MLDSA_USE_HINT_88_EXEC;; + +let MLDSA_USE_HINT_88_SUBROUTINE_SAFE = time prove + (`exists f_events. + forall e b a h pc returnaddress. + nonoverlapping (word pc,LENGTH mldsa_poly_use_hint_88_mc) (b,1024) /\ + nonoverlapping (b,1024) (a,1024) /\ + nonoverlapping (b,1024) (h,1024) + ==> ensures arm + (\s. + aligned_bytes_loaded s (word pc) + mldsa_poly_use_hint_88_mc /\ + read PC s = word pc /\ + read X30 s = returnaddress /\ + C_ARGUMENTS [b; a; h] s /\ + read events s = e) + (\s. + read PC s = returnaddress /\ + (exists e2. + read events s = APPEND e2 e /\ + e2 = f_events a h b pc returnaddress /\ + memaccess_inbounds e2 [a,1024; h,1024; b,1024] + [b,1024])) + (\s s'. true)`, + ASSERT_CONCL_TAC full_spec THEN + PROVE_SAFETY_SPEC_TAC ~public_vars:public_vars MLDSA_USE_HINT_88_EXEC);; + diff --git a/arm/proofs/simulator_iclasses.ml b/arm/proofs/simulator_iclasses.ml index 2d8688c26..4067b3695 100644 --- a/arm/proofs/simulator_iclasses.ml +++ b/arm/proofs/simulator_iclasses.ml @@ -199,15 +199,6 @@ let iclasses = "0100111100000xxx010001xxxxxxxxxx"; (* q=1, op=0, cmode=0100, LSL #16 *) "0100111100000xxx110101xxxxxxxxxx"; (* q=1, op=0, cmode=1101, MSL #16 *) - (*** MOVI (op=0, cmode=1110, byte) ***) - "0x00111100000xxx111001xxxxxxxxxx"; - - (*** MOVI (op=0, cmode=1000, 16-bit, q=1 only) -- shares opcode with SHRN ***) - "0100111100000xxx100001xxxxxxxxxx"; - - (*** MOVI (op=0, cmode=1010, 16-bit shifted, q=1 only) -- shares opcode with SSHLL ***) - "0100111100000xxx101001xxxxxxxxxx"; - (*** ORR (vector, immediate, 32-bit) ***) "0x00111100000xxx000101xxxxxxxxxx"; (* 32-bit ORR imm, immh=0 *) @@ -389,17 +380,6 @@ let iclasses = (*** USHL ***) "0x101110xx1xxxxx010001xxxxxxxxxx"; - (*** USHLL / USHLL2 (make sure immh is nonzero) ***) - "0x10111101xxxxxx101001xxxxxxxxxx"; - "0x101111001xxxxx101001xxxxxxxxxx"; - "0x1011110001xxxx101001xxxxxxxxxx"; - "0x10111100001xxx101001xxxxxxxxxx"; - - (*** SSHLL (make sure immh is nonzero) ***) - "0x001111001xxxxx101001xxxxxxxxxx"; - "0x0011110001xxxx101001xxxxxxxxxx"; - "0x00111100001xxx101001xxxxxxxxxx"; - (*** USHR (make sure immh is nonzero) ***) "0x10111101xxxxxx000001xxxxxxxxxx"; "0x101111001xxxxx000001xxxxxxxxxx"; diff --git a/arm/proofs/specifications.txt b/arm/proofs/specifications.txt index 69b68d785..4c019d7e6 100644 --- a/arm/proofs/specifications.txt +++ b/arm/proofs/specifications.txt @@ -327,6 +327,8 @@ MLDSA_NTT_SUBROUTINE_CORRECT MLDSA_NTT_SUBROUTINE_SAFE MLDSA_POINTWISE_SUBROUTINE_CORRECT MLDSA_POINTWISE_SUBROUTINE_SAFE +MLDSA_USE_HINT_88_SUBROUTINE_CORRECT +MLDSA_USE_HINT_88_SUBROUTINE_SAFE MLKEM_BASEMUL_K2_SUBROUTINE_CORRECT MLKEM_BASEMUL_K2_SUBROUTINE_SAFE MLKEM_BASEMUL_K3_SUBROUTINE_CORRECT diff --git a/arm/proofs/subroutine_signatures.ml b/arm/proofs/subroutine_signatures.ml index 6f17d5f67..e6e5d5f8e 100644 --- a/arm/proofs/subroutine_signatures.ml +++ b/arm/proofs/subroutine_signatures.ml @@ -4418,20 +4418,19 @@ let subroutine_signatures = [ ]) ); -("mldsa_ntt_arm", +("mldsa_poly_use_hint_88", ([(*args*) - ("a", "int32_t[static 256]", (*is const?*)"false"); - ("z_012345", "int32_t[144]", (*is const?*)"true"); - ("z_67", "int32_t[384]", (*is const?*)"true"); + ("b", "int32_t[static 256]", (*is const?*)"false"); + ("a", "int32_t[static 256]", (*is const?*)"true"); + ("h", "int32_t[static 256]", (*is const?*)"true"); ], "void", [(* input buffers *) ("a", "256"(* num elems *), 4(* elem bytesize *)); - ("z_012345", "144"(* num elems *), 4(* elem bytesize *)); - ("z_67", "384"(* num elems *), 4(* elem bytesize *)); + ("h", "256"(* num elems *), 4(* elem bytesize *)); ], [(* output buffers *) - ("a", "256"(* num elems *), 4(* elem bytesize *)); + ("b", "256"(* num elems *), 4(* elem bytesize *)); ], [(* temporary buffers *) ]) diff --git a/benchmarks/benchmark.c b/benchmarks/benchmark.c index d2c260496..1b6fd4d04 100644 --- a/benchmarks/benchmark.c +++ b/benchmarks/benchmark.c @@ -1100,6 +1100,7 @@ void call_mldsa_ntt(void) repeat(mldsa_ntt((int32_t*)b0,(const int32_t*)b1)) void call_mldsa_nttunpack(void) repeat(mldsa_nttunpack((int32_t*)b0)) void call_mldsa_pointwise(void) repeat(mldsa_pointwise_x86((int32_t*)b0,(int32_t*)b1,(int32_t*)b2,(int32_t*)b3)) void call_mldsa_reduce(void) repeat(mldsa_reduce((int32_t*)b0)) +void call_mldsa_poly_use_hint_88(void) {} void call_mlkem_frombytes(void) repeat(mlkem_frombytes((uint16_t*)b0,(int8_t*)b1)) void call_mlkem_intt(void) repeat(mlkem_intt_x86((int16_t*)b0,(int16_t*)b1)) @@ -1126,6 +1127,7 @@ void call_mldsa_intt(void) repeat(mldsa_intt_arm((int32_t*)b0,(const int32_t*)b1 void call_mldsa_ntt(void) repeat(mldsa_ntt_arm((int32_t*)b0,(const int32_t*)b1,(const int32_t*)b2)) void call_mldsa_nttunpack(void) {} void call_mldsa_pointwise(void) repeat(mldsa_pointwise((int32_t*)b0,(int32_t*)b1,(int32_t*)b2)) +void call_mldsa_poly_use_hint_88(void) repeat(mldsa_poly_use_hint_88((int32_t*)b0,(int32_t*)b1,(int32_t*)b2)) void call_mldsa_reduce(void) {} void call_bignum_copy_row_from_table_8n__32_16(void) \ @@ -1549,6 +1551,7 @@ int main(int argc, char *argv[]) timingtest(all,"mldsa_ntt",call_mldsa_ntt); timingtest(!arm,"mldsa_nttunpack",call_mldsa_nttunpack); timingtest(all,"mldsa_pointwise",call_mldsa_pointwise); + timingtest(arm,"mldsa_poly_use_hint_88",call_mldsa_poly_use_hint_88); timingtest(!arm,"mldsa_reduce",call_mldsa_reduce); timingtest(bmi,"p256_montjadd",call_p256_montjadd); timingtest(all,"p256_montjadd_alt",call_p256_montjadd_alt); diff --git a/common/mlkem_mldsa.ml b/common/mlkem_mldsa.ml index fd5958cd6..8451b8d55 100644 --- a/common/mlkem_mldsa.ml +++ b/common/mlkem_mldsa.ml @@ -795,7 +795,7 @@ let Q_MUL_COMM = WORD_RULE (* Normalization rules for VPSRLQ/VMOVSHDUP patterns *) let USHR32_SUBWORD = WORD_BLAST `word_subword (word_ushr (x:int64) 32) (0,32):int32 = word_subword x (32,32)`;; - + let DUP32_SUBWORD = WORD_BLAST `word_subword (word_duplicate (word_subword (x:int64) (32,32):int32):int64) (0,32):int32 = word_subword x (32,32)`;; @@ -834,6 +834,19 @@ let MEMORY_128_FROM_32_TAC = READ_MEMORY_MERGE_CONV 2 (subst[itm,n_tm] pat') in MP_TAC(end_itlist CONJ (map f (0--(n-1))));; +(* ML-DSA use_hint Merge 4 x bytes32 into bytes128 at a given base+offset *) +(* ------------------------------------------------------------------------- *) + +let USE_HINT_MEMORY_128_FROM_32_TAC = + let a_tm = `a:int64` and n_tm = `n:num` and i64_ty = `:int64` + and pat = `read (memory :> bytes128(word_add a (word n))) s0` in + fun v boff n -> + let pat' = subst[mk_var(v,i64_ty),a_tm] pat in + let f i = + let itm = mk_small_numeral(boff + 16*i) in + READ_MEMORY_MERGE_CONV 2 (subst[itm,n_tm] pat') in + MP_TAC(end_itlist CONJ (map f (0--(n-1))));; + (* ------------------------------------------------------------------------- *) (* From |- (x == y) (mod m) /\ P to |- (x == y) (mod n) /\ P *) (* ------------------------------------------------------------------------- *) @@ -1912,3 +1925,38 @@ let SIMD_SIMPLIFY_ABBREV_TAC = let tms = sort free_in (find_terms pam (rand(concl th''))) in (MP_TAC th'' THEN MAP_EVERY AUTO_ABBREV_TAC tms THEN DISCH_TAC) (asl,w) in TRY(FIRST_X_ASSUM(ttac o check (simdable o concl)));; +(* ML-DSA use_hint shared infrastructure lemmas *) +(* Used by both poly_use_hint_32 and poly_use_hint_88 proofs *) +(* ========================================================================= *) + +(* ival equals val for values in [0, Q) where Q = 8380417 < 2^31 *) +let MLDSA_IVAL_VAL = prove( + `!a:int32. val a < 8380417 ==> ival a = &(val a)`, + GEN_TAC THEN DISCH_TAC THEN + SIMP_TAC[ival; DIMINDEX_32] THEN + CONV_TAC NUM_REDUCE_CONV THEN + COND_CASES_TAC THEN ASM_ARITH_TAC);; + +(* For natural numbers, &n is never < -2^31 *) +let INT_POS_NEG_BOUND = prove(`!n. ~((&n:int) < --(&2147483648))`, + GEN_TAC THEN REWRITE_TAC[INT_NOT_LT] THEN + MP_TAC(SPEC `n:num` INT_POS) THEN INT_ARITH_TAC);; + +(* val(iword(&n)) = n for n < 2^31 *) +let VAL_IWORD_NUM_32 = prove( + `!n. n < 2147483648 ==> val(iword(&n):int32) = n`, + GEN_TAC THEN DISCH_TAC THEN + MP_TAC(ISPECL [`&n:int`] (INST_TYPE [`:32`,`:N`] INT_VAL_IWORD)) THEN + REWRITE_TAC[DIMINDEX_32; INT_POS] THEN + CONV_TAC NUM_REDUCE_CONV THEN + ANTS_TAC THENL + [REWRITE_TAC[INT_OF_NUM_LT] THEN ASM_ARITH_TAC; + REWRITE_TAC[INT_OF_NUM_EQ] THEN SIMP_TAC[]]);; + +(* word_ile x 0 in terms of bit 31 (signed non-positive check) *) +let WORD_ILE_ZERO_32 = BITBLAST_RULE + `!x:int32. word_ile x (word 0) <=> bit 31 x \/ x = word 0`;; + +(* val(word_and x (word 15)) = val x MOD 16 *) +let VAL_WORD_AND_15_32 = BITBLAST_RULE + `!x:int32. val(word_and x (word 15:int32)) = val x MOD 16`;; diff --git a/include/s2n-bignum.h b/include/s2n-bignum.h index 8e3d5d56d..65ece4f33 100644 --- a/include/s2n-bignum.h +++ b/include/s2n-bignum.h @@ -1014,6 +1014,10 @@ extern void mldsa_pointwise_x86(int32_t c[S2N_BIGNUM_STATIC 256], const int32_t // Input a[256] (signed 32-bit words); output a[256] (signed 32-bit words) extern void mldsa_reduce(int32_t a[S2N_BIGNUM_STATIC 256]); +// Use hint to correct high bits of decomposition for ML-DSA (parameter set 44) +// Inputs a[256], h[256] (signed 32-bit words); output b[256] (signed 32-bit words) +extern void mldsa_poly_use_hint_88(int32_t b[S2N_BIGNUM_STATIC 256], const int32_t a[S2N_BIGNUM_STATIC 256], const int32_t h[S2N_BIGNUM_STATIC 256]); + // Scalar product of 2-element polynomial vectors in NTT domain, with mulcache // Inputs a[512], b[512], bt[256] (signed 16-bit words); output r[256] (signed 16-bit words) extern void mlkem_basemul_k2(int16_t r[S2N_BIGNUM_STATIC 256],const int16_t a[S2N_BIGNUM_STATIC 512],const int16_t b[S2N_BIGNUM_STATIC 512],const int16_t bt[S2N_BIGNUM_STATIC 256]); diff --git a/tests/test.c b/tests/test.c index e1080ac7a..e57fbddcb 100644 --- a/tests/test.c +++ b/tests/test.c @@ -13064,7 +13064,7 @@ int test_mldsa_intt(void) } // Reference implementation for mldsa_nttunpack -// +// // SPECIFICATION: // This function performs an 8x8 matrix transpose within each of 4 blocks of 64 coefficients. // It converts from AVX2 lane-interleaved layout to sequential layout. @@ -13085,16 +13085,16 @@ void reference_mldsa_nttunpack(int32_t a[256]) { int32_t temp[256]; int i; - + // Copy input to temp for (i = 0; i < 256; i++) { temp[i] = a[i]; } - + // Apply the transpose specification to each of 4 blocks for (int block = 0; block < 4; block++) { int base = block * 64; - + for (i = 0; i < 64; i++) { // Specification: output[base + i] = input[base + (i % 8) * 8 + (i / 8)] int src_index = base + (i % 8) * 8 + (i / 8); @@ -13105,7 +13105,7 @@ void reference_mldsa_nttunpack(int32_t a[256]) int test_mldsa_nttunpack(void) { - // Skip test on non-x86_64 architectures + // Skip test on non-x86_64 architectures if (get_arch_name() != ARCH_X86_64) { return 0; } @@ -13160,6 +13160,97 @@ int test_mldsa_nttunpack(void) #endif } +// Reference implementation of mldsa_poly_use_hint_88 for ML-DSA parameter set 44 +// GAMMA2 = (Q-1)/88 = 95232, output range [0, 43] +// Matches the exact assembly algorithm using SQDMULH-based Barrett decomposition +void reference_mldsa_poly_use_hint_88(int32_t b[256], const int32_t a[256], const int32_t h[256]) +{ + const int32_t TWO_GAMMA2 = 190464; + const int32_t THRESHOLD = 8285184; // 87 * GAMMA2 + const int32_t BARRETT = 1477838209; // 0x58160581 + for (int i = 0; i < 256; i++) { + int32_t ai = a[i]; + // Decompose using SQDMULH + SRSHR (matching assembly) + // sqdmulh: (2 * ai * BARRETT) >> 32 + int32_t sqdmulh_result = (int32_t)(((int64_t)2 * ai * BARRETT) >> 32); + // srshr by 17: (x + (1 << 16)) >> 17 (signed rounding shift right) + int32_t a1 = (sqdmulh_result + (1 << 16)) >> 17; + // a0 = ai - a1 * 2*GAMMA2 + int32_t a0 = ai - a1 * TWO_GAMMA2; + // Wraparound: if ai > threshold, set a1=0, a0 += -1 + if (ai > THRESHOLD) { + a1 = 0; + a0 = a0 + (-1); + } + // delta = (a0 <= 0) ? -1 : 1 + int32_t delta = (a0 <= 0) ? -1 : 1; + // result = a1 + delta * hint + int32_t result = a1 + delta * h[i]; + // Assembly uses CMGT(signed)+BIC+UMIN: if result > 43 (signed), zero it, + // then unsigned min with 43. For negative values (-1), signed compare + // with 43 is false so BIC keeps it, then UMIN(0xFFFFFFFF, 43) = 43. + // This matches ML-DSA spec where -1 mod 44 = 43. + uint32_t uresult = (uint32_t)result; + if (result > 43) uresult = 0; + if (uresult > 43) uresult = 43; + b[i] = (int32_t)uresult; + } +} + +int test_mldsa_poly_use_hint_88(void) +{ + // Skip test on non-aarch64 architectures (ARM-only function) + if (get_arch_name() != ARCH_AARCH64) { + return 0; + } + +#ifdef __aarch64__ + uint64_t t, i; + int32_t a[256] __attribute__((aligned(32))); + int32_t h[256] __attribute__((aligned(32))); + int32_t b_asm[256] __attribute__((aligned(32))); + int32_t b_ref[256] __attribute__((aligned(32))); + + printf("Testing mldsa_poly_use_hint_88 with %d cases\n", tests); + + for (t = 0; t < tests; ++t) { + // Generate random coefficients in [0, Q) + for (i = 0; i < 256; ++i) { + a[i] = (int32_t)(random64() % 8380417); + h[i] = (int32_t)(random64() % 2); // hint is 0 or 1 + } + + // Compute reference result + reference_mldsa_poly_use_hint_88(b_ref, a, h); + + // Call the assembly implementation + mldsa_poly_use_hint_88(b_asm, a, h); + + // Compare results + for (i = 0; i < 256; ++i) { + if (b_asm[i] != b_ref[i]) { + printf("Error in mldsa_poly_use_hint_88 element i = %"PRIu64"; " + "asm = %"PRId32" ref = %"PRId32" " + "(a[i] = %"PRId32", h[i] = %"PRId32")\n", + i, b_asm[i], b_ref[i], a[i], h[i]); + return 1; + } + } + + if (VERBOSE) { + printf("OK: mldsa_poly_use_hint_88: a[0]=0x%08"PRIx32", h[0]=%"PRId32" => b[0]=%"PRId32"\n", + a[0], h[0], b_asm[0]); + } + } + + printf("All OK\n"); + return 0; +#else + return 0; +#endif +} + + int test_p256_montjadd(void) { uint64_t t, k; printf("Testing p256_montjadd with %d cases\n",tests); @@ -16292,6 +16383,7 @@ int main(int argc, char *argv[]) functionaltest(all,"mldsa_nttunpack",test_mldsa_nttunpack); functionaltest(all,"mldsa_pointwise",test_mldsa_pointwise); functionaltest(all,"mldsa_reduce",test_mldsa_reduce); + functionaltest(all,"mldsa_poly_use_hint_88",test_mldsa_poly_use_hint_88); functionaltest(all,"mlkem_basemul_k2",test_mlkem_basemul_k2); functionaltest(all,"mlkem_basemul_k3",test_mlkem_basemul_k3); functionaltest(all,"mlkem_basemul_k4",test_mlkem_basemul_k4); diff --git a/tools/collect-signatures.py b/tools/collect-signatures.py index 4ae0c2466..c71d47894 100644 --- a/tools/collect-signatures.py +++ b/tools/collect-signatures.py @@ -301,6 +301,7 @@ def stripPrefixes(s, prefixes): "mldsa_intt_arm", "mldsa_pointwise", "mldsa_ntt_arm", + "mldsa_poly_use_hint_88", "mlkem_ntt", "mlkem_intt", "mlkem_mulcache_compute", From 0e4d38b24fcdb0cfb77c560ac08fc82b1c928565 Mon Sep 17 00:00:00 2001 From: Jake Massimo Date: Fri, 24 Apr 2026 06:15:09 +0000 Subject: [PATCH 2/9] Remove unused helper lemmas from poly_use_hint_88 proof Remove WORD_ISHR_ROUND_17 (superseded by VAL_DECOMPOSE_A1_88) and SPEC_BOUND_88 (output bounds lemma not needed for functional correctness). Signed-off-by: Jake Massimo --- arm/proofs/mldsa_poly_use_hint_88.ml | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/arm/proofs/mldsa_poly_use_hint_88.ml b/arm/proofs/mldsa_poly_use_hint_88.ml index a96e3d7b9..c9f06eb26 100644 --- a/arm/proofs/mldsa_poly_use_hint_88.ml +++ b/arm/proofs/mldsa_poly_use_hint_88.ml @@ -156,18 +156,6 @@ let WORD_2SMULH_NOSATURATE_88 = prove( [MATCH_MP_TAC DIV_MONO THEN ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV]);; -let WORD_ISHR_ROUND_17 = prove( - `!t:int32. val t < 2147483648 - ==> word_ishr_round t 17 = iword((&(val t) + &65536) div &131072)`, - GEN_TAC THEN DISCH_TAC THEN - REWRITE_TAC[word_ishr_round] THEN - CONV_TAC NUM_REDUCE_CONV THEN - CONV_TAC INT_REDUCE_CONV THEN - SUBGOAL_THEN `ival(t:int32) = &(val t)` SUBST1_TAC THENL - [SIMP_TAC[ival; DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV THEN - COND_CASES_TAC THEN ASM_ARITH_TAC; - REFL_TAC]);; - let VAL_DECOMPOSE_A1_88 = prove( `!a:int32. val a < 8380417 ==> val(word_ishr_round (word_2smulh a (word 1477838209:int32)) 17 : int32) @@ -1367,14 +1355,6 @@ let BARRETT_EQUIV_88 = prove( ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]);; -let SPEC_BOUND_88 = prove( - `!a h. a < 8380417 /\ h <= 1 - ==> mldsa_use_hint_88_spec a h <= 43`, - REPEAT GEN_TAC THEN STRIP_TAC THEN - REWRITE_TAC[mldsa_use_hint_88_spec; LET_DEF; LET_END_DEF] THEN - MP_TAC(SPEC `a:num` A1_BOUND_88) THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN - REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN ASM_ARITH_TAC);; - let WORD_SUB_SIGN_88 = BITBLAST_RULE `!a:int32 b:int32. val b <= 8189952 /\ val a <= 8285184 ==> ((bit 31 (word_sub a b) \/ word_sub a b = word 0) <=> val a <= val b)`;; From 3c33f5be540f7ccc41463e7dd1d542c5ca211b03 Mon Sep 17 00:00:00 2001 From: Jake Massimo Date: Fri, 24 Apr 2026 06:18:23 +0000 Subject: [PATCH 3/9] Move shared helper lemmas to common/mlkem_mldsa.ml Move WORD_AND_ONES_32, WORD_MUL_1_32, REAL_INT_GT_BRIDGE, and REAL_INT_GT_BRIDGE_POS from the _88 proof file to the shared common file, so they can be reused by the _32 proof as well. Signed-off-by: Jake Massimo --- arm/proofs/mldsa_poly_use_hint_88.ml | 34 ++-------------------------- common/mlkem_mldsa.ml | 34 ++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/arm/proofs/mldsa_poly_use_hint_88.ml b/arm/proofs/mldsa_poly_use_hint_88.ml index c9f06eb26..fe8d298da 100644 --- a/arm/proofs/mldsa_poly_use_hint_88.ml +++ b/arm/proofs/mldsa_poly_use_hint_88.ml @@ -1395,36 +1395,6 @@ let A0_UPPER_88 = prove( SUBGOAL_THEN `nv <= 43` ASSUME_TAC THENL [CONV_TAC NUM_REDUCE_CONV THEN ASM_ARITH_TAC; ALL_TAC] THEN ASM_ARITH_TAC);; -let WORD_AND_ONES_32 = prove( - `!x:int32. word_and x (word 4294967295) = x`, - GEN_TAC THEN SUBGOAL_THEN `(word 4294967295 : int32) = word_not(word 0)` SUBST1_TAC THENL - [CONV_TAC WORD_REDUCE_CONV; REWRITE_TAC[WORD_AND_NOT0]]);; - -let WORD_MUL_1_32 = prove( - `!x:int32. word_mul x (word 1) = x`, - GEN_TAC THEN REWRITE_TAC[GSYM VAL_EQ; VAL_WORD_MUL; VAL_WORD; DIMINDEX_32] THEN - CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[MULT_CLAUSES] THEN - MATCH_MP_TAC MOD_LT THEN MP_TAC(ISPEC `x:int32` VAL_BOUND) THEN - REWRITE_TAC[DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV);; - -let REAL_INT_GT_BRIDGE_88 = prove( - `!a:num b c. a <= b * c ==> - ~(real_gt (&a - &b * &c) (&0)) /\ ~(int_gt (&a - &b * &c) (&0))`, - REPEAT GEN_TAC THEN DISCH_TAC THEN CONJ_TAC THENL - [REWRITE_TAC[real_gt; REAL_NOT_LT] THEN - MP_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_MUL] (ASSUME `a <= b * c`)) THEN REAL_ARITH_TAC; - REWRITE_TAC[INT_GT; INT_NOT_LT] THEN - MP_TAC(REWRITE_RULE[GSYM INT_OF_NUM_LE; GSYM INT_OF_NUM_MUL] (ASSUME `a <= b * c`)) THEN INT_ARITH_TAC]);; - -let REAL_INT_GT_BRIDGE_POS_88 = prove( - `!a:num b c. ~(a <= b * c) ==> - real_gt (&a - &b * &c) (&0) /\ int_gt (&a - &b * &c) (&0)`, - REPEAT GEN_TAC THEN REWRITE_TAC[NOT_LE] THEN DISCH_TAC THEN CONJ_TAC THENL - [REWRITE_TAC[real_gt] THEN - MP_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LT; GSYM REAL_OF_NUM_MUL] (ASSUME `b * c < a`)) THEN REAL_ARITH_TAC; - REWRITE_TAC[INT_GT] THEN - MP_TAC(REWRITE_RULE[GSYM INT_OF_NUM_LT; GSYM INT_OF_NUM_MUL] (ASSUME `b * c < a`)) THEN INT_ARITH_TAC]);; - let WORD_IGT_43_BOUND = BITBLAST_RULE `!a:int32. val a <= 43 ==> ~(word_igt a (word 43:int32))`;; let WORD_IGT_43_ADD1 = BITBLAST_RULE @@ -1503,8 +1473,8 @@ let ELEMENT_CORRECT_88 = prove( [REWRITE_TAC[INT_GT; INT_NOT_LT] THEN MP_TAC(SPEC `val(a:int32)` A0_UPPER_88) THEN ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC(REWRITE_RULE[GSYM INT_OF_NUM_LT; GSYM INT_OF_NUM_MUL; GSYM INT_OF_NUM_ADD] (ASSUME `val(a:int32) < (nv + 1) * 190464`)) THEN INT_ARITH_TAC; ALL_TAC] THEN ASM_REWRITE_TAC[] THEN ASM_CASES_TAC `val(a:int32) <= nv * 190464` THENL - [MP_TAC(SPECL [`val(a:int32)`; `nv:num`; `190464`] REAL_INT_GT_BRIDGE_88) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[]; - MP_TAC(SPECL [`val(a:int32)`; `nv:num`; `190464`] REAL_INT_GT_BRIDGE_POS_88) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[]] THENL + [MP_TAC(SPECL [`val(a:int32)`; `nv:num`; `190464`] REAL_INT_GT_BRIDGE) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[]; + MP_TAC(SPECL [`val(a:int32)`; `nv:num`; `190464`] REAL_INT_GT_BRIDGE_POS) THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[]] THENL [(* delta = -1: a0' <= 0 *) REWRITE_TAC[bitval] THEN CONV_TAC WORD_REDUCE_CONV THEN REWRITE_TAC[WORD_AND_ONES_32] THEN ASM_CASES_TAC `nv = 0` THENL diff --git a/common/mlkem_mldsa.ml b/common/mlkem_mldsa.ml index 8451b8d55..cbea1dc81 100644 --- a/common/mlkem_mldsa.ml +++ b/common/mlkem_mldsa.ml @@ -1960,3 +1960,37 @@ let WORD_ILE_ZERO_32 = BITBLAST_RULE (* val(word_and x (word 15)) = val x MOD 16 *) let VAL_WORD_AND_15_32 = BITBLAST_RULE `!x:int32. val(word_and x (word 15:int32)) = val x MOD 16`;; + +(* word_and x all-ones = x *) +let WORD_AND_ONES_32 = prove( + `!x:int32. word_and x (word 4294967295) = x`, + GEN_TAC THEN SUBGOAL_THEN `(word 4294967295 : int32) = word_not(word 0)` SUBST1_TAC THENL + [CONV_TAC WORD_REDUCE_CONV; REWRITE_TAC[WORD_AND_NOT0]]);; + +(* word_mul x 1 = x *) +let WORD_MUL_1_32 = prove( + `!x:int32. word_mul x (word 1) = x`, + GEN_TAC THEN REWRITE_TAC[GSYM VAL_EQ; VAL_WORD_MUL; VAL_WORD; DIMINDEX_32] THEN + CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[MULT_CLAUSES] THEN + MATCH_MP_TAC MOD_LT THEN MP_TAC(ISPEC `x:int32` VAL_BOUND) THEN + REWRITE_TAC[DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV);; + +(* Bridge lemmas: derive both real_gt and int_gt from a single NUM fact. + Needed for native mode where real_gt and int_gt are distinct types. *) +let REAL_INT_GT_BRIDGE = prove( + `!a:num b c. a <= b * c ==> + ~(real_gt (&a - &b * &c) (&0)) /\ ~(int_gt (&a - &b * &c) (&0))`, + REPEAT GEN_TAC THEN DISCH_TAC THEN CONJ_TAC THENL + [REWRITE_TAC[real_gt; REAL_NOT_LT] THEN + MP_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_MUL] (ASSUME `a <= b * c`)) THEN REAL_ARITH_TAC; + REWRITE_TAC[INT_GT; INT_NOT_LT] THEN + MP_TAC(REWRITE_RULE[GSYM INT_OF_NUM_LE; GSYM INT_OF_NUM_MUL] (ASSUME `a <= b * c`)) THEN INT_ARITH_TAC]);; + +let REAL_INT_GT_BRIDGE_POS = prove( + `!a:num b c. ~(a <= b * c) ==> + real_gt (&a - &b * &c) (&0) /\ int_gt (&a - &b * &c) (&0)`, + REPEAT GEN_TAC THEN REWRITE_TAC[NOT_LE] THEN DISCH_TAC THEN CONJ_TAC THENL + [REWRITE_TAC[real_gt] THEN + MP_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LT; GSYM REAL_OF_NUM_MUL] (ASSUME `b * c < a`)) THEN REAL_ARITH_TAC; + REWRITE_TAC[INT_GT] THEN + MP_TAC(REWRITE_RULE[GSYM INT_OF_NUM_LT; GSYM INT_OF_NUM_MUL] (ASSUME `b * c < a`)) THEN INT_ARITH_TAC]);; From 48a65f7dd7d8800e597c9325bf74358802424471 Mon Sep 17 00:00:00 2001 From: Jake Massimo Date: Fri, 24 Apr 2026 17:33:39 +0000 Subject: [PATCH 4/9] Optimize Barrett equivalence proof with general interval lemma Replace the 1129-line case-split Barrett proof with a general DIV_SANDWICH + BARRETT_INTERVAL lemma approach. The general lemma proves that if both formulas are sandwiched in [k*d, (k+1)*d) for a given interval, then both equal k. The proof cascades through the 45-entry interval table, discharging numeric side conditions with NUM_REDUCE_CONV. Signed-off-by: Jake Massimo --- arm/proofs/decode.ml | 57 +- arm/proofs/instruction.ml | 60 +- arm/proofs/mldsa_poly_use_hint_88.ml | 1196 ++------------------------ arm/proofs/simulator_iclasses.ml | 20 + arm/proofs/subroutine_signatures.ml | 31 +- 5 files changed, 230 insertions(+), 1134 deletions(-) diff --git a/arm/proofs/decode.ml b/arm/proofs/decode.ml index 12f9eeea7..328aa77df 100644 --- a/arm/proofs/decode.ml +++ b/arm/proofs/decode.ml @@ -612,8 +612,25 @@ let decode = new_definition `!w:int32. decode w = let datasize = if q then 128 else 64 in let shift = (esize * 2) - val (word_join immh immb:(7)word) in SOME (arm_SRI_VEC (QREG' Rd) (QREG' Rn) shift esize datasize) + else if cmode = (word 0b1010:(4)word) then + // USHLL, USHLL2 + let immb = abc in + let Rn = defgh in + if val immh = 0 then NONE + else if bit 3 immh then NONE // "UNDEFINED" (would need 128-bit elements) + else + let esize = 8 * 2 EXP (3 - word_clz immh) in + let shift = val (word_join immh immb:(7)word) - esize in + if q then SOME (arm_USHLL2_VEC (QREG' Rd) (QREG' Rn) shift esize) + else SOME (arm_USHLL_VEC (QREG' Rd) (QREG' Rn) shift esize) else NONE + | [0:1; q; 0:1; 0b011110:6; 0b0000:4; abc:3; 0b1110:4; 0b01:2; defgh:5; Rd:5] -> + // MOVI (op=0, cmode=1110, immh=0) + let abcdefgh:(8)word = word_join abc defgh in + if q then SOME (arm_MOVI (QREG' Rd) (word_duplicate abcdefgh)) + else SOME (arm_MOVI (DREG' Rd) (word_duplicate abcdefgh)) + | [0b0001111000100110000000:22; Rn:5; Rd:5] -> // FMOV (single, to general) SOME (arm_FMOV_FtoI (WREG' Rd) (QREG' Rn) 0 32) @@ -786,6 +803,14 @@ let decode = new_definition `!w:int32. decode w = // RAX1 SOME (arm_RAX1 (QREG' Rd) (QREG' Rn) (QREG' Rm)) + | [0:1; q; 0b0011110:7; immh:4; immb:3; 0b111001:6; Rn:5; Rd:5] -> + // MOVI (op=0, cmode=1110, byte immediate) + if immh = (word 0b0:(4)word) then + let abcdefgh:(8)word = word_join immb Rn in + if q then SOME (arm_MOVI (QREG' Rd) (word_duplicate abcdefgh)) + else SOME (arm_MOVI (DREG' Rd) (word_duplicate abcdefgh)) + else NONE + | [0:1; q; 0b0011110:7; immh:4; immb:3; 0b010101:6; Rn:5; Rd:5] -> // SHL if immh = (word 0b0: (4)word) then NONE // "asimdimm case" @@ -796,10 +821,36 @@ let decode = new_definition `!w:int32. decode w = let amt = val(word_join immh immb:7 word) - esize in SOME (arm_SHL_VEC (QREG' Rd) (QREG' Rn) amt esize datasize) + | [0:1; q; 0b0011110:7; immh:4; immb:3; 0b101001:6; Rn:5; Rd:5] -> + // SSHLL, SSHLL2 (or MOVI with cmode=1010 when immh=0 and Q=1) + if immh = (word 0b0:(4)word) then + if q then + let abcdefgh:(8)word = word_join immb Rn in + let imm = arm_adv_simd_expand_imm abcdefgh (word 0:(1)word) (word 0b1010) in + match imm with + | SOME imm -> SOME (arm_MOVI (QREG' Rd) imm) + | NONE -> NONE + else NONE + else if bit 3 immh then NONE // "UNDEFINED" + else + let esize = 8 * 2 EXP (3 - word_clz immh) in + let shift = val(word_join immh immb:7 word) - esize in + if q then + SOME (arm_SSHLL2_VEC (QREG' Rd) (QREG' Rn) shift esize) + else + SOME (arm_SSHLL_VEC (QREG' Rd) (QREG' Rn) shift esize) + | [0:1; q; 0b0011110:7; immh:4; immb:3; 0b100001:6; Rn:5; Rd:5] -> - // SHRN - if q then NONE // writing to the upper part is unsupported yet - else if immh = (word 0b0:(4)word) then NONE // "asimdimm case" + // SHRN (or MOVI with cmode=1000 when immh=0 and Q=1) + if immh = (word 0b0:(4)word) then + if q then + let abcdefgh:(8)word = word_join immb Rn in + let imm = arm_adv_simd_expand_imm abcdefgh (word 0:(1)word) (word 0b1000) in + match imm with + | SOME imm -> SOME (arm_MOVI (QREG' Rd) imm) + | NONE -> NONE + else NONE + else if q then NONE // writing to the upper part is unsupported yet else if bit 3 immh then NONE // "UNDEFINED" else let esize = 8 * 2 EXP (3 - word_clz immh) in diff --git a/arm/proofs/instruction.ml b/arm/proofs/instruction.ml index 1256b4114..9a6620907 100644 --- a/arm/proofs/instruction.ml +++ b/arm/proofs/instruction.ml @@ -2130,6 +2130,57 @@ let arm_PMULL2_VEC = define let nlzx:(128)word = usimd8 (word_zx:(8)word->(16)word) nl in let mlzx:(128)word = usimd8 (word_zx:(8)word->(16)word) ml in (Rd := simd8 word_pmul nlzx mlzx) s`;; +let arm_USHLL_VEC = define + `arm_USHLL_VEC Rd Rn shift esize = + \s. let nl:(64)word = word_subword (read Rn s:(128)word) (0,64):(64)word in + if esize = 32 then + let r:(128)word = usimd2 (\x. word_shl (word_zx x:(64)word) shift) nl in + (Rd := r) s + else if esize = 16 then + let r:(128)word = usimd4 (\x. word_shl (word_zx x:(32)word) shift) nl in + (Rd := r) s + else // esize = 8 + let r:(128)word = usimd8 (\x. word_shl (word_zx x:(16)word) shift) nl in + (Rd := r) s`;; + +let arm_USHLL2_VEC = define + `arm_USHLL2_VEC Rd Rn shift esize = + \s. let nl:(64)word = word_subword (read Rn s:(128)word) (64,64):(64)word in + if esize = 32 then + let r:(128)word = usimd2 (\x. word_shl (word_zx x:(64)word) shift) nl in + (Rd := r) s + else if esize = 16 then + let r:(128)word = usimd4 (\x. word_shl (word_zx x:(32)word) shift) nl in + (Rd := r) s + else // esize = 8 + let r:(128)word = usimd8 (\x. word_shl (word_zx x:(16)word) shift) nl in + (Rd := r) s`;; + +let arm_SSHLL_VEC = define + `arm_SSHLL_VEC Rd Rn shift esize = + \s. let nl:(64)word = word_subword (read Rn s:(128)word) (0,64):(64)word in + if esize = 32 then + let r:(128)word = usimd2 (\x. word_shl (word_sx x:(64)word) shift) nl in + (Rd := r) s + else if esize = 16 then + let r:(128)word = usimd4 (\x. word_shl (word_sx x:(32)word) shift) nl in + (Rd := r) s + else // esize = 8 + let r:(128)word = usimd8 (\x. word_shl (word_sx x:(16)word) shift) nl in + (Rd := r) s`;; + +let arm_SSHLL2_VEC = define + `arm_SSHLL2_VEC Rd Rn shift esize = + \s. let nl:(64)word = word_subword (read Rn s:(128)word) (64,64):(64)word in + if esize = 32 then + let r:(128)word = usimd2 (\x. word_shl (word_sx x:(64)word) shift) nl in + (Rd := r) s + else if esize = 16 then + let r:(128)word = usimd4 (\x. word_shl (word_sx x:(32)word) shift) nl in + (Rd := r) s + else // esize = 8 + let r:(128)word = usimd8 (\x. word_shl (word_sx x:(16)word) shift) nl in + (Rd := r) s`;; let arm_USHR_VEC = define `arm_USHR_VEC Rd Rn amt esize datasize = @@ -3391,6 +3442,10 @@ let arm_UMULL_VEC_ALT = EXPAND_SIMD_RULE arm_UMULL_VEC;; let arm_UMULL2_VEC_ALT = EXPAND_SIMD_RULE arm_UMULL2_VEC;; let arm_USHL_VEC_ALT = REWRITE_RULE[word_ushl] (EXPAND_SIMD_RULE arm_USHL_VEC);; +let arm_USHLL_VEC_ALT = EXPAND_SIMD_RULE arm_USHLL_VEC;; +let arm_USHLL2_VEC_ALT = EXPAND_SIMD_RULE arm_USHLL2_VEC;; +let arm_SSHLL_VEC_ALT = EXPAND_SIMD_RULE arm_SSHLL_VEC;; +let arm_SSHLL2_VEC_ALT = EXPAND_SIMD_RULE arm_SSHLL2_VEC;; let arm_USHR_VEC_ALT = EXPAND_SIMD_RULE arm_USHR_VEC;; let arm_USRA_VEC_ALT = EXPAND_SIMD_RULE arm_USRA_VEC;; let arm_UZP1_ALT = EXPAND_SIMD_RULE arm_UZP1;; @@ -3507,6 +3562,7 @@ let ARM_OPERATION_CLAUSES = arm_SMLAL_VEC_ALT; arm_SMLAL2_VEC_ALT; arm_SMLSL_VEC_ALT; arm_SMLSL2_VEC_ALT; arm_SMULL_VEC_ALT; arm_SMULL2_VEC_ALT; + arm_SSHLL_VEC_ALT; arm_SSHLL2_VEC_ALT; arm_SMULH; arm_SQDMULH_VEC_ALT; arm_SQRDMULH_VEC_ALT; @@ -3520,7 +3576,9 @@ let ARM_OPERATION_CLAUSES = arm_UMULL_VEC_ALT; arm_UMULL2_VEC_ALT; arm_UMULH; arm_UMIN_VEC_ALT; - arm_USHL_VEC_ALT; arm_USHR_VEC_ALT; arm_USRA_VEC_ALT; arm_UZP1_ALT; + arm_USHL_VEC_ALT; + arm_USHLL_VEC_ALT; arm_USHLL2_VEC_ALT; + arm_USHR_VEC_ALT; arm_USRA_VEC_ALT; arm_UZP1_ALT; arm_UZP2_ALT; arm_XAR; arm_XTN_ALT; arm_ZIP1_ALT; arm_ZIP2_ALT; diff --git a/arm/proofs/mldsa_poly_use_hint_88.ml b/arm/proofs/mldsa_poly_use_hint_88.ml index fe8d298da..0e44eac67 100644 --- a/arm/proofs/mldsa_poly_use_hint_88.ml +++ b/arm/proofs/mldsa_poly_use_hint_88.ml @@ -224,1135 +224,83 @@ let A1_BOUND_NOWRAP_88 = prove( CONV_TAC NUM_REDUCE_CONV THEN ARITH_TAC]);; (* Barrett equivalence for _88: 45-interval case analysis *) +let DIV_SANDWICH = prove( + `!x d k. ~(d = 0) /\ k * d <= x /\ x < (k + 1) * d ==> x DIV d = k`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN `k <= x DIV d` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_RDIV_EQ] THEN ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `x DIV d < k + 1` ASSUME_TAC THENL + [ASM_SIMP_TAC[RDIV_LT_EQ] THEN ASM_ARITH_TAC; ASM_ARITH_TAC]);; + +let BARRETT_INTERVAL_88 = prove( + `!a lo hi k. + lo <= a /\ a <= hi /\ + k * 131072 <= (2 * lo * 1477838209) DIV 4294967296 + 65536 /\ + (2 * hi * 1477838209) DIV 4294967296 + 65536 < (k + 1) * 131072 /\ + k * 16777216 <= (lo + 127) DIV 128 * 11275 + 8388608 /\ + (hi + 127) DIV 128 * 11275 + 8388608 < (k + 1) * 16777216 + ==> ((2 * a * 1477838209) DIV 4294967296 + 65536) DIV 131072 = k /\ + ((a + 127) DIV 128 * 11275 + 8388608) DIV 16777216 = k`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + CONJ_TAC THEN MATCH_MP_TAC DIV_SANDWICH THEN CONV_TAC NUM_REDUCE_CONV THENL + [CONJ_TAC THENL + [TRANS_TAC LE_TRANS `(2 * lo * 1477838209) DIV 4294967296 + 65536` THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[ARITH_RULE `x + 65536 <= y + 65536 <=> x <= y`] THEN + MATCH_MP_TAC DIV_MONO THEN ASM_ARITH_TAC; + TRANS_TAC LET_TRANS `(2 * hi * 1477838209) DIV 4294967296 + 65536` THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[ARITH_RULE `x + 65536 <= y + 65536 <=> x <= y`] THEN + MATCH_MP_TAC DIV_MONO THEN ASM_ARITH_TAC]; + CONJ_TAC THENL + [TRANS_TAC LE_TRANS `(lo + 127) DIV 128 * 11275 + 8388608` THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[ARITH_RULE `x + 8388608 <= y + 8388608 <=> x <= y`] THEN + REWRITE_TAC[LE_MULT_RCANCEL] THEN DISJ1_TAC THEN + MATCH_MP_TAC DIV_MONO THEN ASM_ARITH_TAC; + TRANS_TAC LET_TRANS `(hi + 127) DIV 128 * 11275 + 8388608` THEN + ASM_REWRITE_TAC[] THEN + REWRITE_TAC[ARITH_RULE `x + 8388608 <= y + 8388608 <=> x <= y`] THEN + REWRITE_TAC[LE_MULT_RCANCEL] THEN DISJ1_TAC THEN + MATCH_MP_TAC DIV_MONO THEN ASM_ARITH_TAC]]);; + let BARRETT_EQUIV_88 = prove( `!a. a < 8380417 ==> ((2 * a * 1477838209) DIV 4294967296 + 65536) DIV 131072 = ((a + 127) DIV 128 * 11275 + 8388608) DIV 16777216`, GEN_TAC THEN DISCH_TAC THEN - ASM_CASES_TAC `a <= 95232` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 95232 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 0 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `95232 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `0 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq0 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq0 * 11275 <= 744 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `0 * 11275 <= qq0 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `744 * 11275 + 8388608` - (SPEC `qq0 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq0 * 11275 + 8388608` - (SPEC `0 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 285696` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 285696 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 95233 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `285696 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `95233 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq1 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq1 * 11275 <= 2232 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `745 * 11275 <= qq1 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `2232 * 11275 + 8388608` - (SPEC `qq1 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq1 * 11275 + 8388608` - (SPEC `745 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 476160` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 476160 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 285697 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `476160 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `285697 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq2 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq2 * 11275 <= 3720 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `2233 * 11275 <= qq2 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `3720 * 11275 + 8388608` - (SPEC `qq2 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq2 * 11275 + 8388608` - (SPEC `2233 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 666624` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 666624 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 476161 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `666624 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `476161 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq3 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq3 * 11275 <= 5208 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `3721 * 11275 <= qq3 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `5208 * 11275 + 8388608` - (SPEC `qq3 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq3 * 11275 + 8388608` - (SPEC `3721 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 857088` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 857088 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 666625 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `857088 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `666625 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq4 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq4 * 11275 <= 6696 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `5209 * 11275 <= qq4 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `6696 * 11275 + 8388608` - (SPEC `qq4 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq4 * 11275 + 8388608` - (SPEC `5209 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 1047552` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 1047552 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 857089 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `1047552 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `857089 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq5 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq5 * 11275 <= 8184 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `6697 * 11275 <= qq5 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `8184 * 11275 + 8388608` - (SPEC `qq5 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq5 * 11275 + 8388608` - (SPEC `6697 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 1238016` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 1238016 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 1047553 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `1238016 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `1047553 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq6 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq6 * 11275 <= 9672 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `8185 * 11275 <= qq6 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `9672 * 11275 + 8388608` - (SPEC `qq6 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq6 * 11275 + 8388608` - (SPEC `8185 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 1428480` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 1428480 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 1238017 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `1428480 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `1238017 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq7 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq7 * 11275 <= 11160 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `9673 * 11275 <= qq7 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `11160 * 11275 + 8388608` - (SPEC `qq7 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq7 * 11275 + 8388608` - (SPEC `9673 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 1618944` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 1618944 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 1428481 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `1618944 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `1428481 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq8 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq8 * 11275 <= 12648 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `11161 * 11275 <= qq8 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `12648 * 11275 + 8388608` - (SPEC `qq8 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq8 * 11275 + 8388608` - (SPEC `11161 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 1809408` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 1809408 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 1618945 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `1809408 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `1618945 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq9 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq9 * 11275 <= 14136 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `12649 * 11275 <= qq9 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `14136 * 11275 + 8388608` - (SPEC `qq9 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq9 * 11275 + 8388608` - (SPEC `12649 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 1999872` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 1999872 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 1809409 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `1999872 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `1809409 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq10 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq10 * 11275 <= 15624 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `14137 * 11275 <= qq10 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `15624 * 11275 + 8388608` - (SPEC `qq10 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq10 * 11275 + 8388608` - (SPEC `14137 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 2190336` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 2190336 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 1999873 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `2190336 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `1999873 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq11 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq11 * 11275 <= 17112 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `15625 * 11275 <= qq11 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `17112 * 11275 + 8388608` - (SPEC `qq11 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq11 * 11275 + 8388608` - (SPEC `15625 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 2380800` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 2380800 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 2190337 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `2380800 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `2190337 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq12 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq12 * 11275 <= 18600 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `17113 * 11275 <= qq12 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `18600 * 11275 + 8388608` - (SPEC `qq12 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq12 * 11275 + 8388608` - (SPEC `17113 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 2571264` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 2571264 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 2380801 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `2571264 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `2380801 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq13 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq13 * 11275 <= 20088 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `18601 * 11275 <= qq13 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `20088 * 11275 + 8388608` - (SPEC `qq13 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq13 * 11275 + 8388608` - (SPEC `18601 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 2761728` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 2761728 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 2571265 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `2761728 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `2571265 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq14 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq14 * 11275 <= 21576 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `20089 * 11275 <= qq14 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `21576 * 11275 + 8388608` - (SPEC `qq14 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq14 * 11275 + 8388608` - (SPEC `20089 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 2952192` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 2952192 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 2761729 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `2952192 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `2761729 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq15 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq15 * 11275 <= 23064 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `21577 * 11275 <= qq15 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `23064 * 11275 + 8388608` - (SPEC `qq15 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq15 * 11275 + 8388608` - (SPEC `21577 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 3142656` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 3142656 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 2952193 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `3142656 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `2952193 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq16 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq16 * 11275 <= 24552 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `23065 * 11275 <= qq16 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `24552 * 11275 + 8388608` - (SPEC `qq16 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq16 * 11275 + 8388608` - (SPEC `23065 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 3333120` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 3333120 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 3142657 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `3333120 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `3142657 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq17 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq17 * 11275 <= 26040 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `24553 * 11275 <= qq17 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `26040 * 11275 + 8388608` - (SPEC `qq17 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq17 * 11275 + 8388608` - (SPEC `24553 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 3523584` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 3523584 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 3333121 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `3523584 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `3333121 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq18 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq18 * 11275 <= 27528 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `26041 * 11275 <= qq18 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `27528 * 11275 + 8388608` - (SPEC `qq18 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq18 * 11275 + 8388608` - (SPEC `26041 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 3714048` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 3714048 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 3523585 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `3714048 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `3523585 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq19 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq19 * 11275 <= 29016 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `27529 * 11275 <= qq19 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `29016 * 11275 + 8388608` - (SPEC `qq19 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq19 * 11275 + 8388608` - (SPEC `27529 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 3904512` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 3904512 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 3714049 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `3904512 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `3714049 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq20 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq20 * 11275 <= 30504 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `29017 * 11275 <= qq20 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `30504 * 11275 + 8388608` - (SPEC `qq20 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq20 * 11275 + 8388608` - (SPEC `29017 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 4094976` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 4094976 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 3904513 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `4094976 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `3904513 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq21 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq21 * 11275 <= 31992 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `30505 * 11275 <= qq21 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `31992 * 11275 + 8388608` - (SPEC `qq21 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq21 * 11275 + 8388608` - (SPEC `30505 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 4285440` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 4285440 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 4094977 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `4285440 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `4094977 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq22 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq22 * 11275 <= 33480 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `31993 * 11275 <= qq22 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `33480 * 11275 + 8388608` - (SPEC `qq22 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq22 * 11275 + 8388608` - (SPEC `31993 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 4475904` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 4475904 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 4285441 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `4475904 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `4285441 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq23 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq23 * 11275 <= 34968 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `33481 * 11275 <= qq23 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `34968 * 11275 + 8388608` - (SPEC `qq23 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq23 * 11275 + 8388608` - (SPEC `33481 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 4666368` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 4666368 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 4475905 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `4666368 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `4475905 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq24 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq24 * 11275 <= 36456 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `34969 * 11275 <= qq24 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `36456 * 11275 + 8388608` - (SPEC `qq24 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq24 * 11275 + 8388608` - (SPEC `34969 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 4856832` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 4856832 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 4666369 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `4856832 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `4666369 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq25 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq25 * 11275 <= 37944 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `36457 * 11275 <= qq25 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `37944 * 11275 + 8388608` - (SPEC `qq25 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq25 * 11275 + 8388608` - (SPEC `36457 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 5047296` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 5047296 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 4856833 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `5047296 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `4856833 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq26 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq26 * 11275 <= 39432 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `37945 * 11275 <= qq26 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `39432 * 11275 + 8388608` - (SPEC `qq26 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq26 * 11275 + 8388608` - (SPEC `37945 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 5237760` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 5237760 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 5047297 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `5237760 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `5047297 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq27 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq27 * 11275 <= 40920 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `39433 * 11275 <= qq27 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `40920 * 11275 + 8388608` - (SPEC `qq27 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq27 * 11275 + 8388608` - (SPEC `39433 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 5428224` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 5428224 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 5237761 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `5428224 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `5237761 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq28 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq28 * 11275 <= 42408 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `40921 * 11275 <= qq28 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `42408 * 11275 + 8388608` - (SPEC `qq28 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq28 * 11275 + 8388608` - (SPEC `40921 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 5618688` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 5618688 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 5428225 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `5618688 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `5428225 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq29 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq29 * 11275 <= 43896 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `42409 * 11275 <= qq29 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `43896 * 11275 + 8388608` - (SPEC `qq29 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq29 * 11275 + 8388608` - (SPEC `42409 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 5809152` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 5809152 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 5618689 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `5809152 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `5618689 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq30 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq30 * 11275 <= 45384 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `43897 * 11275 <= qq30 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `45384 * 11275 + 8388608` - (SPEC `qq30 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq30 * 11275 + 8388608` - (SPEC `43897 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 5999616` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 5999616 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 5809153 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `5999616 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `5809153 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq31 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq31 * 11275 <= 46872 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `45385 * 11275 <= qq31 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `46872 * 11275 + 8388608` - (SPEC `qq31 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq31 * 11275 + 8388608` - (SPEC `45385 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 6190080` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 6190080 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 5999617 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `6190080 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `5999617 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq32 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq32 * 11275 <= 48360 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `46873 * 11275 <= qq32 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `48360 * 11275 + 8388608` - (SPEC `qq32 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq32 * 11275 + 8388608` - (SPEC `46873 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 6380544` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 6380544 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 6190081 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `6380544 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `6190081 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq33 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq33 * 11275 <= 49848 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `48361 * 11275 <= qq33 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `49848 * 11275 + 8388608` - (SPEC `qq33 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq33 * 11275 + 8388608` - (SPEC `48361 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 6571008` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 6571008 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 6380545 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `6571008 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `6380545 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq34 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq34 * 11275 <= 51336 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `49849 * 11275 <= qq34 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `51336 * 11275 + 8388608` - (SPEC `qq34 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq34 * 11275 + 8388608` - (SPEC `49849 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 6761472` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 6761472 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 6571009 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `6761472 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `6571009 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq35 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq35 * 11275 <= 52824 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `51337 * 11275 <= qq35 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `52824 * 11275 + 8388608` - (SPEC `qq35 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq35 * 11275 + 8388608` - (SPEC `51337 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 6951936` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 6951936 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 6761473 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `6951936 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `6761473 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq36 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq36 * 11275 <= 54312 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `52825 * 11275 <= qq36 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `54312 * 11275 + 8388608` - (SPEC `qq36 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq36 * 11275 + 8388608` - (SPEC `52825 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 7142400` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 7142400 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 6951937 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `7142400 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `6951937 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq37 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq37 * 11275 <= 55800 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `54313 * 11275 <= qq37 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `55800 * 11275 + 8388608` - (SPEC `qq37 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq37 * 11275 + 8388608` - (SPEC `54313 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 7332864` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 7332864 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 7142401 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `7332864 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `7142401 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq38 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq38 * 11275 <= 57288 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `55801 * 11275 <= qq38 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `57288 * 11275 + 8388608` - (SPEC `qq38 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq38 * 11275 + 8388608` - (SPEC `55801 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 7523328` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 7523328 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 7332865 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `7523328 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `7332865 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq39 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq39 * 11275 <= 58776 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `57289 * 11275 <= qq39 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `58776 * 11275 + 8388608` - (SPEC `qq39 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq39 * 11275 + 8388608` - (SPEC `57289 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 7713792` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 7713792 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 7523329 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `7713792 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `7523329 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq40 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq40 * 11275 <= 60264 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `58777 * 11275 <= qq40 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `60264 * 11275 + 8388608` - (SPEC `qq40 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq40 * 11275 + 8388608` - (SPEC `58777 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 7904256` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 7904256 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 7713793 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `7904256 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `7713793 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq41 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq41 * 11275 <= 61752 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `60265 * 11275 <= qq41 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `61752 * 11275 + 8388608` - (SPEC `qq41 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq41 * 11275 + 8388608` - (SPEC `60265 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 8094720` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 8094720 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 7904257 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `8094720 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `7904257 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq42 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq42 * 11275 <= 63240 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `61753 * 11275 <= qq42 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `63240 * 11275 + 8388608` - (SPEC `qq42 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq42 * 11275 + 8388608` - (SPEC `61753 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - ASM_CASES_TAC `a <= 8285184` THENL - [ - MP_TAC(SPEC `131072` (SPEC `(2 * 8285184 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 8094721 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `8285184 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `8094721 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq43 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq43 * 11275 <= 64728 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `63241 * 11275 <= qq43 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `64728 * 11275 + 8388608` - (SPEC `qq43 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq43 * 11275 + 8388608` - (SPEC `63241 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ; - (* Last case: a > 8285184 *) - MP_TAC(SPEC `131072` (SPEC `(2 * 8380416 * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `131072` (SPEC `(2 * a * 1477838209) DIV 4294967296 + 65536` - (SPEC `(2 * 8285185 * 1477838209) DIV 4294967296 + 65536` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `8380416 + 127` (SPEC `a + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `128` (SPEC `a + 127` (SPEC `8285185 + 127` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ABBREV_TAC `qq44 = (a + 127) DIV 128` THEN - SUBGOAL_THEN `qq44 * 11275 <= 65472 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - SUBGOAL_THEN `64729 * 11275 <= qq44 * 11275` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `65472 * 11275 + 8388608` - (SPEC `qq44 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - MP_TAC(SPEC `16777216` (SPEC `qq44 * 11275 + 8388608` - (SPEC `64729 * 11275 + 8388608` DIV_MONO))) THEN - ANTS_TAC THENL [ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV THEN DISCH_TAC] THEN - ASM_ARITH_TAC - ]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]);; + let intervals = [ + (0, 95232); (95233, 285696); (285697, 476160); (476161, 666624); + (666625, 857088); (857089, 1047552); (1047553, 1238016); + (1238017, 1428480); (1428481, 1618944); (1618945, 1809408); + (1809409, 1999872); (1999873, 2190336); (2190337, 2380800); + (2380801, 2571264); (2571265, 2761728); (2761729, 2952192); + (2952193, 3142656); (3142657, 3333120); (3333121, 3523584); + (3523585, 3714048); (3714049, 3904512); (3904513, 4094976); + (4094977, 4285440); (4285441, 4475904); (4475905, 4666368); + (4666369, 4856832); (4856833, 5047296); (5047297, 5237760); + (5237761, 5428224); (5428225, 5618688); (5618689, 5809152); + (5809153, 5999616); (5999617, 6190080); (6190081, 6380544); + (6380545, 6571008); (6571009, 6761472); (6761473, 6951936); + (6951937, 7142400); (7142401, 7332864); (7332865, 7523328); + (7523329, 7713792); (7713793, 7904256); (7904257, 8094720); + (8094721, 8285184); (8285185, 8380416)] in + let mk_le hi = + mk_comb(mk_comb(`(<=):num->num->bool`, mk_var("a",`:num`)), + mk_small_numeral hi) in + let apply_interval k (lo, hi) = + let th = SPECL [`a:num`; mk_small_numeral lo; + mk_small_numeral hi; mk_small_numeral k] + BARRETT_INTERVAL_88 in + MP_TAC th THEN CONV_TAC NUM_REDUCE_CONV THEN ASM_ARITH_TAC in + let rec cascade k = function + | [(lo,hi)] -> apply_interval k (lo,hi) + | (lo,hi)::rest -> + ASM_CASES_TAC (mk_le hi) THENL + [apply_interval k (lo,hi); cascade (k+1) rest] + | [] -> failwith "empty" in + cascade 0 intervals);; + let WORD_SUB_SIGN_88 = BITBLAST_RULE diff --git a/arm/proofs/simulator_iclasses.ml b/arm/proofs/simulator_iclasses.ml index 4067b3695..2d8688c26 100644 --- a/arm/proofs/simulator_iclasses.ml +++ b/arm/proofs/simulator_iclasses.ml @@ -199,6 +199,15 @@ let iclasses = "0100111100000xxx010001xxxxxxxxxx"; (* q=1, op=0, cmode=0100, LSL #16 *) "0100111100000xxx110101xxxxxxxxxx"; (* q=1, op=0, cmode=1101, MSL #16 *) + (*** MOVI (op=0, cmode=1110, byte) ***) + "0x00111100000xxx111001xxxxxxxxxx"; + + (*** MOVI (op=0, cmode=1000, 16-bit, q=1 only) -- shares opcode with SHRN ***) + "0100111100000xxx100001xxxxxxxxxx"; + + (*** MOVI (op=0, cmode=1010, 16-bit shifted, q=1 only) -- shares opcode with SSHLL ***) + "0100111100000xxx101001xxxxxxxxxx"; + (*** ORR (vector, immediate, 32-bit) ***) "0x00111100000xxx000101xxxxxxxxxx"; (* 32-bit ORR imm, immh=0 *) @@ -380,6 +389,17 @@ let iclasses = (*** USHL ***) "0x101110xx1xxxxx010001xxxxxxxxxx"; + (*** USHLL / USHLL2 (make sure immh is nonzero) ***) + "0x10111101xxxxxx101001xxxxxxxxxx"; + "0x101111001xxxxx101001xxxxxxxxxx"; + "0x1011110001xxxx101001xxxxxxxxxx"; + "0x10111100001xxx101001xxxxxxxxxx"; + + (*** SSHLL (make sure immh is nonzero) ***) + "0x001111001xxxxx101001xxxxxxxxxx"; + "0x0011110001xxxx101001xxxxxxxxxx"; + "0x00111100001xxx101001xxxxxxxxxx"; + (*** USHR (make sure immh is nonzero) ***) "0x10111101xxxxxx000001xxxxxxxxxx"; "0x101111001xxxxx000001xxxxxxxxxx"; diff --git a/arm/proofs/subroutine_signatures.ml b/arm/proofs/subroutine_signatures.ml index e6e5d5f8e..0dccf7179 100644 --- a/arm/proofs/subroutine_signatures.ml +++ b/arm/proofs/subroutine_signatures.ml @@ -4418,19 +4418,20 @@ let subroutine_signatures = [ ]) ); -("mldsa_poly_use_hint_88", +("mldsa_ntt_arm", ([(*args*) - ("b", "int32_t[static 256]", (*is const?*)"false"); - ("a", "int32_t[static 256]", (*is const?*)"true"); - ("h", "int32_t[static 256]", (*is const?*)"true"); + ("a", "int32_t[static 256]", (*is const?*)"false"); + ("z_012345", "int32_t[144]", (*is const?*)"true"); + ("z_67", "int32_t[384]", (*is const?*)"true"); ], "void", [(* input buffers *) ("a", "256"(* num elems *), 4(* elem bytesize *)); - ("h", "256"(* num elems *), 4(* elem bytesize *)); + ("z_012345", "144"(* num elems *), 4(* elem bytesize *)); + ("z_67", "384"(* num elems *), 4(* elem bytesize *)); ], [(* output buffers *) - ("b", "256"(* num elems *), 4(* elem bytesize *)); + ("a", "256"(* num elems *), 4(* elem bytesize *)); ], [(* temporary buffers *) ]) @@ -4454,6 +4455,24 @@ let subroutine_signatures = [ ]) ); +("mldsa_poly_use_hint_88", + ([(*args*) + ("b", "int32_t[static 256]", (*is const?*)"false"); + ("a", "int32_t[static 256]", (*is const?*)"true"); + ("h", "int32_t[static 256]", (*is const?*)"true"); + ], + "void", + [(* input buffers *) + ("a", "256"(* num elems *), 4(* elem bytesize *)); + ("h", "256"(* num elems *), 4(* elem bytesize *)); + ], + [(* output buffers *) + ("b", "256"(* num elems *), 4(* elem bytesize *)); + ], + [(* temporary buffers *) + ]) +); + ("mlkem_basemul_k2", ([(*args*) ("r", "int16_t[static 256]", (*is const?*)"false"); From 12ef94b65180b56b08c465b53f8df7828a2363a7 Mon Sep 17 00:00:00 2001 From: Jake Massimo Date: Fri, 1 May 2026 06:43:20 +0000 Subject: [PATCH 5/9] Add FIPS 204-aligned UseHint _88 equivalence proof Add FIPS 204 definitions (mldsa_cmod, mldsa_decompose_88, mldsa_use_hint_88) and equivalence proof connecting code-aligned spec to FIPS 204 Algorithm 40. Move shared arch-independent helpers (DIV_SANDWICH, INT_MOD_RESIDUE) to common/mlkem_mldsa.ml. ENSURES_STRENGTHEN_POST stays in the proof file as it references armstate. Signed-off-by: Jake Massimo --- arm/proofs/mldsa_poly_use_hint_88.ml | 479 ++++++++++++++++++++++++++- common/mlkem_mldsa.ml | 19 ++ 2 files changed, 490 insertions(+), 8 deletions(-) diff --git a/arm/proofs/mldsa_poly_use_hint_88.ml b/arm/proofs/mldsa_poly_use_hint_88.ml index 0e44eac67..592cfe761 100644 --- a/arm/proofs/mldsa_poly_use_hint_88.ml +++ b/arm/proofs/mldsa_poly_use_hint_88.ml @@ -224,14 +224,6 @@ let A1_BOUND_NOWRAP_88 = prove( CONV_TAC NUM_REDUCE_CONV THEN ARITH_TAC]);; (* Barrett equivalence for _88: 45-interval case analysis *) -let DIV_SANDWICH = prove( - `!x d k. ~(d = 0) /\ k * d <= x /\ x < (k + 1) * d ==> x DIV d = k`, - REPEAT GEN_TAC THEN STRIP_TAC THEN - SUBGOAL_THEN `k <= x DIV d` ASSUME_TAC THENL - [ASM_SIMP_TAC[LE_RDIV_EQ] THEN ASM_ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `x DIV d < k + 1` ASSUME_TAC THENL - [ASM_SIMP_TAC[RDIV_LT_EQ] THEN ASM_ARITH_TAC; ASM_ARITH_TAC]);; - let BARRETT_INTERVAL_88 = prove( `!a lo hi k. lo <= a /\ a <= hi /\ @@ -609,3 +601,474 @@ let MLDSA_USE_HINT_88_SUBROUTINE_SAFE = time prove ASSERT_CONCL_TAC full_spec THEN PROVE_SAFETY_SPEC_TAC ~public_vars:public_vars MLDSA_USE_HINT_88_EXEC);; + +(* ========================================================================= *) +(* FIPS 204 definitions and equivalence (after safety proof) *) +(* ========================================================================= *) + +let mldsa_cmod = new_definition + `mldsa_cmod (r:num) (m:num) : int = + if (r MOD m) * 2 <= m then &(r MOD m) else &(r MOD m) - &m`;; + +let mldsa_decompose_88 = new_definition + `mldsa_decompose_88 (r:num) : num # int = + let r0 = mldsa_cmod r 190464 in + if &r - r0 = &8380416 then (0, r0 - &1) + else (num_of_int((&r - r0) div &190464), r0)`;; + +let decompose_88_r1 = new_definition + `decompose_88_r1 (r:num) : num = FST(mldsa_decompose_88 r)`;; + +let decompose_88_r0 = new_definition + `decompose_88_r0 (r:num) : int = SND(mldsa_decompose_88 r)`;; + +let mldsa_use_hint_88 = new_definition + `mldsa_use_hint_88 (h:num) (r:num) : num = + let (r1, r0) = mldsa_decompose_88 r in + if h = 1 /\ r0 > &0 then if r1 = 43 then 0 else r1 + 1 + else if h = 1 /\ r0 <= &0 then if r1 = 0 then 43 else r1 - 1 + else r1`;; + +let LOWER_NONWRAP_R1_88 = prove( + `!r. r MOD 190464 * 2 <= 190464 /\ + ~((&r:int) - &(r MOD 190464) = &8380416) ==> + decompose_88_r1 r = r DIV 190464`, + GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC[decompose_88_r1; mldsa_decompose_88; mldsa_cmod] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `r MOD 190464 <= r` ASSUME_TAC THENL + [MESON_TAC[MOD_LE]; ALL_TAC] THEN + ASM_SIMP_TAC[INT_OF_NUM_SUB; INT_OF_NUM_DIV; + NUM_OF_INT_OF_NUM; INT_OF_NUM_EQ] THEN + MP_TAC(SPECL [`r:num`; `190464`] (CONJUNCT1 DIVISION_SIMP)) THEN + DISCH_TAC THEN + SUBGOAL_THEN `r - r MOD 190464 = 190464 * r DIV 190464` SUBST1_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + MP_TAC(SPECL [`190464`; `r DIV 190464`] DIV_MULT) THEN + CONV_TAC NUM_REDUCE_CONV);; + +let UPPER_NONWRAP_R1_88 = prove( + `!r. ~(r MOD 190464 * 2 <= 190464) /\ + ~((&r:int) - (&(r MOD 190464) - &190464) = &8380416) ==> + decompose_88_r1 r = r DIV 190464 + 1`, + GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC[decompose_88_r1; mldsa_decompose_88; mldsa_cmod] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `r MOD 190464 <= r` ASSUME_TAC THENL + [MESON_TAC[MOD_LE]; ALL_TAC] THEN + SUBGOAL_THEN `r MOD 190464 < 190464` ASSUME_TAC THENL + [MP_TAC(SPECL [`r:num`; `190464`] MOD_LT_EQ) THEN ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(&r:int) - (&(r MOD 190464) - &190464) = + &(r - r MOD 190464 + 190464)` ASSUME_TAC THENL + [ASM_SIMP_TAC[GSYM INT_OF_NUM_SUB; GSYM INT_OF_NUM_ADD] THEN + INT_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[INT_OF_NUM_DIV; NUM_OF_INT_OF_NUM; INT_OF_NUM_EQ] THEN + MP_TAC(SPECL [`r:num`; `190464`] (CONJUNCT1 DIVISION_SIMP)) THEN + DISCH_TAC THEN + SUBGOAL_THEN `r - r MOD 190464 + 190464 = (r DIV 190464 + 1) * 190464` + ASSUME_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + MP_TAC(SPECL [`(r DIV 190464 + 1) * 190464`; `190464`] DIV_MULT) THEN + ARITH_TAC);; + +(* Unfold mldsa_use_hint_88 eliminating the paired let *) +let MLDSA_USE_HINT_88_UNFOLD = prove( + `!h r. mldsa_use_hint_88 h r = + (if h = 1 /\ decompose_88_r0 r > &0 + then if decompose_88_r1 r = 43 then 0 else decompose_88_r1 r + 1 + else if h = 1 /\ decompose_88_r0 r <= &0 + then if decompose_88_r1 r = 0 then 43 else decompose_88_r1 r - 1 + else decompose_88_r1 r)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[mldsa_use_hint_88; decompose_88_r1; decompose_88_r0] THEN + SPEC_TAC(`mldsa_decompose_88 r`, `p:num#int`) THEN + REWRITE_TAC[FORALL_PAIR_THM] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN REWRITE_TAC[]);; + + +(* ========================================================================= *) +(* FIPS 204 = code-aligned equivalence *) +(* ========================================================================= *) + +let LINEARIZE_DIV_MOD_TAC_88 = + REPEAT(FIRST_X_ASSUM(MP_TAC o check (fun th -> + free_in `r MOD 190464` (concl th) || + free_in `r DIV 190464` (concl th)))) THEN + MP_TAC(SPECL [`r:num`; `190464`] (CONJUNCT1 DIVISION_SIMP)) THEN + SPEC_TAC(`r MOD 190464`, `m:num`) THEN + SPEC_TAC(`r DIV 190464`, `q:num`) THEN + REPEAT GEN_TAC THEN ASM_ARITH_TAC;; + +(* Prove r DIV 190464 = k via DIV_SANDWICH + LE_MULT_RCANCEL *) +let DIV_190464_TAC k = + let k_num = mk_small_numeral k and km1 = mk_small_numeral (k-1) + and kp1 = mk_small_numeral (k+1) + and q = mk_var("q",`:num`) and le = `(<=):num->num->bool` + and lt = `(<):num->num->bool` + and c = `190464` in + let mk_mul a b = mk_binop (rator(rator `0*0`)) a b in + MATCH_MP_TAC DIV_SANDWICH THEN CONV_TAC NUM_REDUCE_CONV THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o check (fun th -> + free_in `r MOD 190464` (concl th) || + free_in `r DIV 190464` (concl th)))) THEN + MP_TAC(SPECL [`r:num`; c] (CONJUNCT1 DIVISION_SIMP)) THEN + SPEC_TAC(`r MOD 190464`, `m:num`) THEN + SPEC_TAC(`r DIV 190464`, q) THEN + REPEAT GEN_TAC THEN STRIP_TAC THEN + ASM_CASES_TAC(mk_comb(mk_comb(le, q), km1)) THENL + [SUBGOAL_THEN(mk_comb(mk_comb(le, mk_mul q c), + mk_mul km1 c)) ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL]; ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN ASM_ARITH_TAC; + SUBGOAL_THEN(mk_comb(mk_comb(le, mk_mul k_num c), + mk_mul q c)) ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL] THEN DISJ1_TAC THEN ASM_ARITH_TAC; + ALL_TAC] THEN + ASM_CASES_TAC(mk_comb(mk_comb(lt, k_num), q)) THENL + [SUBGOAL_THEN(mk_comb(mk_comb(le, mk_mul kp1 c), + mk_mul q c)) ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_MULT_RCANCEL] THEN DISJ1_TAC THEN ASM_ARITH_TAC; + ALL_TAC] THEN + CONV_TAC NUM_REDUCE_CONV THEN ASM_ARITH_TAC; + CONV_TAC NUM_REDUCE_CONV THEN ASM_ARITH_TAC]];; + +(* Replace (r - r MOD 190464) DIV 190464 with r DIV 190464 *) +let DIV_MOD_TO_DIV_TAC_88 = + SUBGOAL_THEN `(r - r MOD 190464) DIV 190464 = r DIV 190464` SUBST1_TAC THENL + [MP_TAC(SPECL [`r:num`; `190464`] (CONJUNCT1 DIVISION_SIMP)) THEN + DISCH_TAC THEN + SUBGOAL_THEN `r - r MOD 190464 = 190464 * r DIV 190464` SUBST1_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + MP_TAC(SPECL [`190464`; `r DIV 190464`] DIV_MULT) THEN + CONV_TAC NUM_REDUCE_CONV; ALL_TAC];; + +(* Lower half nowrap: dismiss wrap cond, reduce, prove r DIV 190464 = k *) +let DECOMPOSE_R1_LOWER_TAC_88 = + SUBGOAL_THEN `~((&r:int) - &(r MOD 190464) = &8380416)` (fun th -> REWRITE_TAC[th]) THENL + [ASM_SIMP_TAC[INT_OF_NUM_SUB; INT_OF_NUM_EQ] THEN LINEARIZE_DIV_MOD_TAC_88; + ALL_TAC] THEN + ASM_SIMP_TAC[INT_OF_NUM_SUB; INT_OF_NUM_DIV; NUM_OF_INT_OF_NUM] THEN + DIV_MOD_TO_DIV_TAC_88 THEN + CONV_TAC SYM_CONV THEN + LINEARIZE_DIV_MOD_TAC_88;; + +(* Upper half nowrap: dismiss wrap cond, reduce, prove r DIV 190464 + 1 = k *) +let DECOMPOSE_R1_UPPER_TAC_88 = + SUBGOAL_THEN `r MOD 190464 <= r` ASSUME_TAC THENL + [MESON_TAC[MOD_LE]; ALL_TAC] THEN + SUBGOAL_THEN `r MOD 190464 < 190464` ASSUME_TAC THENL + [MP_TAC(SPECL [`r:num`; `190464`] MOD_LT_EQ) THEN ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `~((&r:int) - (&(r MOD 190464) - &190464) = &8380416)` (fun th -> REWRITE_TAC[th]) THENL + [REWRITE_TAC[INT_ARITH `(a:int) - (b - c) = d <=> a + c - b = d`] THEN + ASM_SIMP_TAC[GSYM INT_OF_NUM_ADD; GSYM INT_OF_NUM_SUB; INT_OF_NUM_EQ] THEN + LINEARIZE_DIV_MOD_TAC_88; ALL_TAC] THEN + SUBGOAL_THEN `(&r:int) - (&(r MOD 190464) - &190464) = + &(r - r MOD 190464 + 190464)` SUBST1_TAC THENL + [ASM_SIMP_TAC[GSYM INT_OF_NUM_SUB; GSYM INT_OF_NUM_ADD] THEN + INT_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[INT_OF_NUM_DIV; NUM_OF_INT_OF_NUM] THEN + MP_TAC(SPECL [`r:num`; `190464`] (CONJUNCT1 DIVISION_SIMP)) THEN + DISCH_TAC THEN + SUBGOAL_THEN `r - r MOD 190464 + 190464 = 190464 * (r DIV 190464 + 1)` + SUBST1_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + MP_TAC(SPECL [`190464`; `r DIV 190464 + 1`] DIV_MULT) THEN + CONV_TAC NUM_REDUCE_CONV THEN DISCH_THEN SUBST1_TAC THEN + REPEAT(FIRST_X_ASSUM(MP_TAC o check (fun th -> + free_in `r MOD 190464` (concl th) || + free_in `r DIV 190464` (concl th)))) THEN + MP_TAC(SPECL [`r:num`; `190464`] (CONJUNCT1 DIVISION_SIMP)) THEN + SPEC_TAC(`r MOD 190464`, `m:num`) THEN + SPEC_TAC(`r DIV 190464`, `q:num`) THEN + REPEAT GEN_TAC THEN ASM_ARITH_TAC;; + +let DECOMPOSE_R1_NOWRAP_TAC_88 = + ASM_CASES_TAC `r MOD 190464 * 2 <= 190464` THEN ASM_REWRITE_TAC[] THEN + TRY DECOMPOSE_R1_LOWER_TAC_88 THEN TRY DECOMPOSE_R1_UPPER_TAC_88;; + +let DECOMPOSE_88_R1_EQUIV = time prove( + `!r. r < 8380417 ==> + (let a1_raw = ((r + 127) DIV 128 * 11275 + 8388608) DIV 16777216 in + if a1_raw > 43 then 0 else a1_raw) = + decompose_88_r1 r`, + GEN_TAC THEN DISCH_TAC THEN CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + ASM_CASES_TAC `r <= 8285184` THENL + [ALL_TAC; + (* Wrap zone *) + SUBGOAL_THEN `8285184 < r` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `decompose_88_r1 r = 0` SUBST1_TAC THENL + [REWRITE_TAC[decompose_88_r1; mldsa_decompose_88; mldsa_cmod] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + SUBGOAL_THEN `r MOD 190464 <= r` ASSUME_TAC THENL + [MESON_TAC[MOD_LE]; ALL_TAC] THEN + SUBGOAL_THEN `r MOD 190464 < 190464` ASSUME_TAC THENL + [MP_TAC(SPECL [`r:num`; `190464`] MOD_LT_EQ) THEN ARITH_TAC; + ALL_TAC] THEN + ASM_CASES_TAC `r MOD 190464 * 2 <= 190464` THEN ASM_REWRITE_TAC[] THENL + [(* Lower wrap: r DIV 190464 = 44 *) + SUBGOAL_THEN `r DIV 190464 = 44` ASSUME_TAC THENL + [DIV_190464_TAC 44; ALL_TAC] THEN + SUBGOAL_THEN `44 * 190464 + r MOD 190464 = r` MP_TAC THENL + [MP_TAC(SPECL [`r:num`; `190464`] (CONJUNCT1 DIVISION_SIMP)) THEN + ASM_ARITH_TAC; ALL_TAC] THEN + DISCH_TAC THEN ASM_SIMP_TAC[INT_OF_NUM_SUB; INT_OF_NUM_EQ] THEN + ASM_ARITH_TAC; + (* Upper wrap: r DIV 190464 = 43 *) + SUBGOAL_THEN `r DIV 190464 = 43` ASSUME_TAC THENL + [DIV_190464_TAC 43; ALL_TAC] THEN + SUBGOAL_THEN `43 * 190464 + r MOD 190464 = r` MP_TAC THENL + [MP_TAC(SPECL [`r:num`; `190464`] (CONJUNCT1 DIVISION_SIMP)) THEN + ASM_ARITH_TAC; ALL_TAC] THEN + DISCH_TAC THEN + SUBGOAL_THEN `(&r:int) - (&(r MOD 190464) - &190464) = + &(r - r MOD 190464 + 190464)` SUBST1_TAC THENL + [ASM_SIMP_TAC[GSYM INT_OF_NUM_SUB; GSYM INT_OF_NUM_ADD] THEN + INT_ARITH_TAC; ALL_TAC] THEN + REWRITE_TAC[INT_OF_NUM_EQ] THEN ASM_ARITH_TAC]; + ALL_TAC] THEN + MP_TAC(SPEC `r:num` A1_WRAP_88) THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + DISCH_THEN SUBST1_TAC THEN CONV_TAC NUM_REDUCE_CONV] THEN + (* Nowrap zone: Barrett <= 43, so if > 43 then 0 else Barrett = Barrett *) + SUBGOAL_THEN `((r + 127) DIV 128 * 11275 + 8388608) DIV 16777216 <= 43` + ASSUME_TAC THENL + [MATCH_MP_TAC A1_BOUND_NOWRAP_88 THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `~(((r + 127) DIV 128 * 11275 + 8388608) DIV 16777216 > 43)` + (fun th -> REWRITE_TAC[th]) THENL [ASM_ARITH_TAC; ALL_TAC] THEN + (* Nowrap zone: unfold and do interval cascade *) + REWRITE_TAC[decompose_88_r1; mldsa_decompose_88; mldsa_cmod] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + SUBGOAL_THEN `r MOD 190464 <= r` ASSUME_TAC THENL + [MESON_TAC[MOD_LE]; ALL_TAC] THEN + SUBGOAL_THEN `r MOD 190464 < 190464` ASSUME_TAC THENL + [MP_TAC(SPECL [`r:num`; `190464`] MOD_LT_EQ) THEN ARITH_TAC; ALL_TAC] THEN + let intervals = [ + (0, 95232); (95233, 285696); (285697, 476160); (476161, 666624); + (666625, 857088); (857089, 1047552); (1047553, 1238016); + (1238017, 1428480); (1428481, 1618944); (1618945, 1809408); + (1809409, 1999872); (1999873, 2190336); (2190337, 2380800); + (2380801, 2571264); (2571265, 2761728); (2761729, 2952192); + (2952193, 3142656); (3142657, 3333120); (3333121, 3523584); + (3523585, 3714048); (3714049, 3904512); (3904513, 4094976); + (4094977, 4285440); (4285441, 4475904); (4475905, 4666368); + (4666369, 4856832); (4856833, 5047296); (5047297, 5237760); + (5237761, 5428224); (5428225, 5618688); (5618689, 5809152); + (5809153, 5999616); (5999617, 6190080); (6190081, 6380544); + (6380545, 6571008); (6571009, 6761472); (6761473, 6951936); + (6951937, 7142400); (7142401, 7332864); (7332865, 7523328); + (7523329, 7713792); (7713793, 7904256); (7904257, 8094720); + (8094721, 8285184)] in + let mk_le hi = + mk_comb(mk_comb(`(<=):num->num->bool`, mk_var("r",`:num`)), + mk_small_numeral hi) in + let apply_interval k (lo, hi) = + let th = SPECL [`r:num`; mk_small_numeral lo; + mk_small_numeral hi; mk_small_numeral k] + BARRETT_INTERVAL_88 in + MP_TAC th THEN CONV_TAC NUM_REDUCE_CONV THEN + ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONV_TAC NUM_REDUCE_CONV THEN + DECOMPOSE_R1_NOWRAP_TAC_88 in + let rec cascade k = function + | [(lo,hi)] -> apply_interval k (lo,hi) + | (lo,hi)::rest -> + ASM_CASES_TAC (mk_le hi) THENL + [apply_interval k (lo,hi); cascade (k+1) rest] + | [] -> failwith "empty" in + cascade 0 intervals);; + +let R1_IS_DIV_LOWER_88 = prove( + `!r. r < 8380417 /\ r MOD 190464 * 2 <= 190464 /\ + ~((&r:int) - &(r MOD 190464) = &8380416) ==> + (let a1_raw = ((r + 127) DIV 128 * 11275 + 8388608) DIV 16777216 in + if a1_raw > 43 then 0 else a1_raw) = r DIV 190464`, + GEN_TAC THEN STRIP_TAC THEN + MP_TAC(SPEC `r:num` DECOMPOSE_88_R1_EQUIV) THEN ASM_REWRITE_TAC[] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + MP_TAC(SPEC `r:num` LOWER_NONWRAP_R1_88) THEN ASM_REWRITE_TAC[] THEN + REPEAT DISCH_TAC THEN ASM_REWRITE_TAC[]);; + +let R1_IS_DIV_PLUS1_UPPER_88 = prove( + `!r. r < 8380417 /\ ~(r MOD 190464 * 2 <= 190464) /\ + ~((&r:int) - (&(r MOD 190464) - &190464) = &8380416) ==> + (let a1_raw = ((r + 127) DIV 128 * 11275 + 8388608) DIV 16777216 in + if a1_raw > 43 then 0 else a1_raw) = r DIV 190464 + 1`, + GEN_TAC THEN STRIP_TAC THEN + MP_TAC(SPEC `r:num` DECOMPOSE_88_R1_EQUIV) THEN ASM_REWRITE_TAC[] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + MP_TAC(SPEC `r:num` UPPER_NONWRAP_R1_88) THEN ASM_REWRITE_TAC[] THEN + REPEAT DISCH_TAC THEN ASM_REWRITE_TAC[]);; + +(* Upper nowrap: substitute Barrett = r DIV 190464 + 1, use INT_MOD_RESIDUE *) +let R0_SIGN_UPPER_NOWRAP_TAC_88 = + MP_TAC(SPEC `r:num` R1_IS_DIV_PLUS1_UPPER_88) THEN + ANTS_TAC THEN ASM_REWRITE_TAC[] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN DISCH_THEN SUBST1_TAC THEN + MP_TAC(CONV_RULE NUM_REDUCE_CONV (SPECL [`r:num`; `190464`] INT_MOD_RESIDUE)) THEN + REWRITE_TAC[GSYM INT_OF_NUM_ADD; GSYM INT_OF_NUM_MUL] THEN + DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[INT_ARITH `(a:int) - (b + &1) * c = a - b * c - c`] THEN + REWRITE_TAC[INT_ARITH `x - &190464 > &0 <=> x > &190464`; + INT_ARITH `x - &190464 - &8380417 > &0 <=> x > &8570881`; + INT_OF_NUM_GT] THEN + ASM_ARITH_TAC;; + +(* Lower nowrap: substitute Barrett = r DIV 190464, use INT_MOD_RESIDUE *) +let R0_SIGN_LOWER_NOWRAP_TAC_88 = + MP_TAC(SPEC `r:num` R1_IS_DIV_LOWER_88) THEN + ANTS_TAC THEN ASM_REWRITE_TAC[] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN DISCH_THEN SUBST1_TAC THEN + MP_TAC(CONV_RULE NUM_REDUCE_CONV (SPECL [`r:num`; `190464`] INT_MOD_RESIDUE)) THEN + DISCH_TAC THEN ASM_REWRITE_TAC[] THEN + REWRITE_TAC[INT_ARITH `x - &8380417 > &0 <=> x > &8380417`; + INT_OF_NUM_GT] THEN + ASM_ARITH_TAC;; + +(* Wrap: derive 8285184 < r, use DECOMPOSE_88_R1_EQUIV to get Barrett = 0 *) +let R0_SIGN_WRAP_TAC_88 = + SUBGOAL_THEN `8285184 < r` ASSUME_TAC THENL + [FIRST_X_ASSUM(MP_TAC o check (fun th -> + can (find_term (fun t -> t = `&8380416:int`)) (concl th) && + not(is_neg(concl th)))) THEN + ASM_SIMP_TAC[INT_OF_NUM_SUB; INT_OF_NUM_EQ; + INT_ARITH `(a:int) - (b - c) = d <=> a + c - b = d`; + GSYM INT_OF_NUM_ADD] THEN ASM_ARITH_TAC; ALL_TAC] THEN + MP_TAC(SPEC `r:num` DECOMPOSE_88_R1_EQUIV) THEN ASM_REWRITE_TAC[] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC[decompose_88_r1; mldsa_decompose_88; mldsa_cmod] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN ASM_REWRITE_TAC[] THEN + DISCH_TAC THEN ASM_REWRITE_TAC[INT_MUL_LZERO; INT_SUB_RZERO] THEN + REWRITE_TAC[INT_ARITH `x - &1 > &0 <=> x > &1`; + INT_ARITH `(x - &190464) - &1 > &0 <=> x > &190465`; + INT_ARITH `x - &8380417 > &0 <=> x > &8380417`; + INT_OF_NUM_GT] THEN + ASM_ARITH_TAC;; + +let DECOMPOSE_88_R0_SIGN = time prove( + `!r. r < 8380417 ==> + let a1_raw = ((r + 127) DIV 128 * 11275 + 8388608) DIV 16777216 in + let a1 = if a1_raw > 43 then 0 else a1_raw in + let a0':int = if (&r:int) - &a1 * &190464 > &4190208 + then &r - &a1 * &190464 - &8380417 + else &r - &a1 * &190464 in + (decompose_88_r0 r > &0 <=> a0' > &0) /\ + (decompose_88_r0 r <= &0 <=> ~(a0' > &0))`, + GEN_TAC THEN DISCH_TAC THEN CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REWRITE_TAC[INT_ARITH `(x:int) <= &0 <=> ~(x > &0)`] THEN + MATCH_MP_TAC(TAUT `(p <=> q) ==> (p <=> q) /\ (~p <=> ~q)`) THEN + REWRITE_TAC[decompose_88_r0; mldsa_decompose_88; mldsa_cmod] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + ONCE_REWRITE_TAC[COND_RAND] THEN REWRITE_TAC[SND; FST] THEN + SUBGOAL_THEN `r MOD 190464 <= r` ASSUME_TAC THENL + [MESON_TAC[MOD_LE]; ALL_TAC] THEN + SUBGOAL_THEN `r MOD 190464 < 190464` ASSUME_TAC THENL + [MP_TAC(SPECL [`r:num`; `190464`] MOD_LT_EQ) THEN ARITH_TAC; ALL_TAC] THEN + ASM_CASES_TAC `r MOD 190464 * 2 <= 190464` THEN ASM_REWRITE_TAC[] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN + TRY R0_SIGN_LOWER_NOWRAP_TAC_88 THEN + TRY R0_SIGN_UPPER_NOWRAP_TAC_88 THEN + TRY R0_SIGN_WRAP_TAC_88 THEN + TRY( + (* Contradiction: lower nowrap with > 4190208 *) + MP_TAC(SPEC `r:num` R1_IS_DIV_LOWER_88) THEN + ANTS_TAC THEN ASM_REWRITE_TAC[] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN DISCH_TAC THEN + MP_TAC(CONV_RULE NUM_REDUCE_CONV + (SPECL [`r:num`; `190464`] INT_MOD_RESIDUE)) THEN + DISCH_TAC THEN + SUBGOAL_THEN `(&r:int) - &((let a1_raw = ((r + 127) DIV 128 * 11275 + 8388608) DIV 16777216 in + if a1_raw > 43 then 0 else a1_raw)) * &190464 = &(r MOD 190464)` ASSUME_TAC THENL + [CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + SUBGOAL_THEN `~(&(r MOD 190464) > (&4190208:int))` MP_TAC THENL + [REWRITE_TAC[INT_NOT_LT; INT_OF_NUM_LE] THEN ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN REWRITE_TAC[INT_OF_NUM_GT] THEN ASM_ARITH_TAC + ));; + +(* R1 equivalence for _88 (needed for MLDSA_USE_HINT_88_EQUIV below). + + Show decompose_88_r1 r equals the a1 value from the code-aligned spec: + let a1_raw = ((r + 127) DIV 128 * 11275 + 8388608) DIV 16777216 in + if a1_raw > 43 then 0 else a1_raw *) + +let MLDSA_USE_HINT_88_EQUIV = prove( + `!r h. r < 8380417 /\ h <= 1 + ==> mldsa_use_hint_88 h r = mldsa_use_hint_88_spec r h`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC[MLDSA_USE_HINT_88_UNFOLD] THEN + REWRITE_TAC[mldsa_use_hint_88_spec] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + MP_TAC(SPEC `r:num` DECOMPOSE_88_R1_EQUIV) THEN ASM_REWRITE_TAC[] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + DISCH_TAC THEN + MP_TAC(SPEC `r:num` DECOMPOSE_88_R0_SIGN) THEN ASM_REWRITE_TAC[] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN STRIP_TAC THEN + ASM_CASES_TAC `h = 0` THENL + [ASM_REWRITE_TAC[ARITH_RULE `~(0 = 1)`]; ALL_TAC] THEN + SUBGOAL_THEN `h = 1` SUBST_ALL_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + ASM_CASES_TAC `decompose_88_r0 r > &0` THEN ASM_REWRITE_TAC[] THEN + COND_CASES_TAC THEN ASM_REWRITE_TAC[]);; + +let ENSURES_STRENGTHEN_POST = prove( + `!P (Q:armstate->bool) Q' R. + ensures arm P Q' R /\ (!s. Q' s ==> Q s) ==> ensures arm P Q R`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[ensures] THEN MATCH_MP_TAC MONO_FORALL THEN + X_GEN_TAC `s0:armstate` THEN MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + MP_TAC(BETA_RULE(ISPECL [`arm`; + `\s':armstate. (Q':armstate->bool) s' /\ (R:armstate->armstate->bool) (s0:armstate) s'`; + `\s':armstate. (Q:armstate->bool) s' /\ (R:armstate->armstate->bool) (s0:armstate) s'`] + EVENTUALLY_MONO)) THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; MESON_TAC[]]);; + +(* FIPS 204-aligned subroutine correctness. + Derived from the code-aligned SUBROUTINE_CORRECT by rewriting + mldsa_use_hint_88_spec -> mldsa_use_hint_88 via MLDSA_USE_HINT_88_EQUIV. *) +let MLDSA_USE_HINT_88_SUBROUTINE_CORRECT_FIPS204 = prove + (`!b a h x y pc returnaddress. + nonoverlapping (word pc, LENGTH mldsa_poly_use_hint_88_mc) (b, 1024) /\ + nonoverlapping (b, 1024) (a, 1024) /\ + nonoverlapping (b, 1024) (h, 1024) /\ + (!i. i < 256 ==> val((x:num->int32) i) < 8380417) /\ + (!i. i < 256 ==> val((y:num->int32) i) <= 1) + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) mldsa_poly_use_hint_88_mc /\ + read PC s = word pc /\ + read X30 s = returnaddress /\ + C_ARGUMENTS [b; a; h] s /\ + (!i. i < 256 ==> val(x i) < 8380417) /\ + (!i. i < 256 ==> val(y i) <= 1) /\ + (!i. i < 256 ==> + read(memory :> bytes32(word_add a (word(4 * i)))) s = x i) /\ + (!i. i < 256 ==> + read(memory :> bytes32(word_add h (word(4 * i)))) s = y i)) + (\s. read PC s = returnaddress /\ + (!i. i < 256 ==> + read(memory :> bytes32(word_add b (word(4 * i)))) s = + word(mldsa_use_hint_88 (val(y i)) (val(x i))))) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [memory :> bytes(b, 1024)])`, + REPEAT GEN_TAC THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + SUBGOAL_THEN + `!i. i < 256 ==> + mldsa_use_hint_88 (val((y:num->int32) i)) (val((x:num->int32) i)) = + mldsa_use_hint_88_spec (val(x i)) (val(y i))` + (fun th -> SIMP_TAC[th]) THENL + [REPEAT STRIP_TAC THEN MATCH_MP_TAC MLDSA_USE_HINT_88_EQUIV THEN + CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; + MATCH_MP_TAC ENSURES_STRENGTHEN_POST THEN + EXISTS_TAC + `\s. read PC s = returnaddress /\ + (!i. i < 256 ==> + read(memory :> bytes32(word_add b (word(4 * i)))) s = + word(mldsa_use_hint_88_spec (val(x i:int32)) (val(y i:int32)))) /\ + (!i. i < 256 ==> + val(read(memory :> bytes32(word_add b (word(4 * i)))) s) < 44)` THEN + CONJ_TAC THENL + [MATCH_MP_TAC MLDSA_USE_HINT_88_SUBROUTINE_CORRECT THEN + ASM_REWRITE_TAC[]; + GEN_TAC THEN CONV_TAC(ONCE_DEPTH_CONV BETA_CONV) THEN + DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN + ASM_REWRITE_TAC[]]]);; diff --git a/common/mlkem_mldsa.ml b/common/mlkem_mldsa.ml index cbea1dc81..157225e59 100644 --- a/common/mlkem_mldsa.ml +++ b/common/mlkem_mldsa.ml @@ -1994,3 +1994,22 @@ let REAL_INT_GT_BRIDGE_POS = prove( MP_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LT; GSYM REAL_OF_NUM_MUL] (ASSUME `b * c < a`)) THEN REAL_ARITH_TAC; REWRITE_TAC[INT_GT] THEN MP_TAC(REWRITE_RULE[GSYM INT_OF_NUM_LT; GSYM INT_OF_NUM_MUL] (ASSUME `b * c < a`)) THEN INT_ARITH_TAC]);; + +(* ========================================================================= *) +(* Shared helper lemmas for UseHint proofs *) +(* ========================================================================= *) + +let DIV_SANDWICH = prove( + `!x d k. ~(d = 0) /\ k * d <= x /\ x < (k + 1) * d ==> x DIV d = k`, + REPEAT GEN_TAC THEN STRIP_TAC THEN + SUBGOAL_THEN `k <= x DIV d` ASSUME_TAC THENL + [ASM_SIMP_TAC[LE_RDIV_EQ] THEN ASM_ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `x DIV d < k + 1` ASSUME_TAC THENL + [ASM_SIMP_TAC[RDIV_LT_EQ] THEN ASM_ARITH_TAC; ASM_ARITH_TAC]);; + + `!r m. ~(m = 0) ==> (&r:int) - &(r DIV m) * &m = &(r MOD m)`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + MP_TAC(SPECL [`r:num`; `m:num`] (CONJUNCT1 DIVISION_SIMP)) THEN + REWRITE_TAC[GSYM INT_OF_NUM_MUL; GSYM INT_OF_NUM_ADD; + GSYM INT_OF_NUM_EQ] THEN + INT_ARITH_TAC);; From abd045e90d432a6ae2b1ba459d1aa9809221b9d4 Mon Sep 17 00:00:00 2001 From: Jake Massimo Date: Fri, 1 May 2026 18:11:04 +0000 Subject: [PATCH 6/9] INT_MOD_RESIDUE: Restore missing let header The `let INT_MOD_RESIDUE = prove(` line was dropped, leaving an orphaned HOL term + tactic block that camlp5 could not parse: Parse error: [implem] expected after [str_item_semi] Signed-off-by: Jake Massimo --- common/mlkem_mldsa.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/common/mlkem_mldsa.ml b/common/mlkem_mldsa.ml index 157225e59..e9bed9dff 100644 --- a/common/mlkem_mldsa.ml +++ b/common/mlkem_mldsa.ml @@ -2007,6 +2007,7 @@ let DIV_SANDWICH = prove( SUBGOAL_THEN `x DIV d < k + 1` ASSUME_TAC THENL [ASM_SIMP_TAC[RDIV_LT_EQ] THEN ASM_ARITH_TAC; ASM_ARITH_TAC]);; +let INT_MOD_RESIDUE = prove( `!r m. ~(m = 0) ==> (&r:int) - &(r DIV m) * &m = &(r MOD m)`, REPEAT GEN_TAC THEN DISCH_TAC THEN MP_TAC(SPECL [`r:num`; `m:num`] (CONJUNCT1 DIVISION_SIMP)) THEN From e86de2fb96d21d7be9d1076499a9cc11837a68d6 Mon Sep 17 00:00:00 2001 From: Jake Massimo Date: Fri, 1 May 2026 19:15:25 +0000 Subject: [PATCH 7/9] poly_use_hint_88: Port refactor from mldsa-native Apply the same refactor as PR #372 did for _32, mirroring pq-code-package/mldsa-native#1037 to keep the two repos consistent: - Rename the code-aligned per-coefficient spec mldsa_use_hint_88_spec to mldsa_use_hint_88_code and keep it local to the proof file. FIPS 204 mldsa_use_hint_88 (Algorithm 40) is the shared definition in common/mlkem_mldsa.ml. - Rename the code-aligned CORRECT / CORRECT_BOUND / SUBROUTINE_CORRECT to *_CODE suffixes to mark them as internal stepping stones. - Make MLDSA_USE_HINT_88_SUBROUTINE_CORRECT the single public theorem, stated in terms of FIPS 204 mldsa_use_hint_88 with the < 44 output bound as a corollary. Derived from _SUBROUTINE_CORRECT_CODE via MLDSA_USE_HINT_88_EQUIV. - Move safety proof to the end of the file. mk_safety_spec still uses _SUBROUTINE_CORRECT_CODE so the hardcoded safety goal matches. - Lift shared FIPS 204 definitions (mldsa_cmod, mldsa_decompose_88, decompose_88_r{0,1}, mldsa_use_hint_88) and helpers (LOWER/UPPER _NONWRAP_R1_88, MLDSA_USE_HINT_88_UNFOLD) into common/mlkem_mldsa.ml. - Keep ENSURES_STRENGTHEN_POST local to the proof file (armstate-specific). Signed-off-by: Jake Massimo --- arm/proofs/mldsa_poly_use_hint_88.ml | 338 ++++++++++++--------------- common/mlkem_mldsa.ml | 83 +++++++ 2 files changed, 230 insertions(+), 191 deletions(-) diff --git a/arm/proofs/mldsa_poly_use_hint_88.ml b/arm/proofs/mldsa_poly_use_hint_88.ml index 592cfe761..287fa3c25 100644 --- a/arm/proofs/mldsa_poly_use_hint_88.ml +++ b/arm/proofs/mldsa_poly_use_hint_88.ml @@ -10,6 +10,7 @@ needs "arm/proofs/base.ml";; needs "common/mlkem_mldsa.ml";; + (**** print_literal_from_elf "arm/mldsa/mldsa_poly_use_hint_88.o";; ****) @@ -99,22 +100,7 @@ let mldsa_poly_use_hint_88_mc = define_assert_from_elf let MLDSA_USE_HINT_88_EXEC = ARM_MK_EXEC_RULE mldsa_poly_use_hint_88_mc;; - -(* ========================================================================= *) -(* Functional specification: UseHint for ML-DSA parameter set 44 *) -(* GAMMA2 = (Q-1)/88 = 95232, 2*GAMMA2 = 190464, output range [0, 43] *) -(* ========================================================================= *) - -let mldsa_use_hint_88_spec = new_definition - `mldsa_use_hint_88_spec (a:num) (h:num) = - let a1_raw = ((((a + 127) DIV 128) * 11275 + 8388608) DIV 16777216) in - let a1 = if a1_raw > 43 then 0 else a1_raw in - let a0:int = &a - &a1 * &190464 in - let a0' = if a0 > &4190208 then a0 - &8380417 else a0 in - if h = 0 then a1 - else if a0' > &0 then if a1 = 43 then 0 else a1 + 1 - else if a1 = 0 then 43 else a1 - 1`;; - +(* Per-element word function matching the assembly computation *) let mldsa_use_hint_88_asm = new_definition `mldsa_use_hint_88_asm (a:int32) (h:int32) : int32 = let a1 = word_ishr_round (word_2smulh a (word 1477838209)) 17 in @@ -127,20 +113,30 @@ let mldsa_use_hint_88_asm = new_definition let tmp' = word_and tmp (word_not neg_mask) in word_umin tmp' (word 43)`;; +(* Numeric description of the assembly's UseHint path, exposing the Barrett + approximation used by the code. Connected to the FIPS 204 definition + mldsa_use_hint_88 via MLDSA_USE_HINT_88_EQUIV below. *) +let mldsa_use_hint_88_code = new_definition + `mldsa_use_hint_88_code (a:num) (h:num) = + let a1_raw = ((((a + 127) DIV 128) * 11275 + 8388608) DIV 16777216) in + let a1 = if a1_raw > 43 then 0 else a1_raw in + let a0:int = &a - &a1 * &190464 in + let a0' = if a0 > &4190208 then a0 - &8380417 else a0 in + if h = 0 then a1 + else if a0' > &0 then if a1 = 43 then 0 else a1 + 1 + else if a1 = 0 then 43 else a1 - 1`;; + (* ========================================================================= *) (* Helper lemmas *) (* ========================================================================= *) -let IVAL_SMALL = MLDSA_IVAL_VAL;; -let VAL_IWORD_NUM = VAL_IWORD_NUM_32;; - let WORD_2SMULH_NOSATURATE_88 = prove( `!a:int32. val a < 8380417 ==> word_2smulh a (word 1477838209:int32) : int32 = iword((&2 * &(val a) * &1477838209) div &2 pow 32)`, GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[word_2smulh; DIMINDEX_32] THEN - ASM_SIMP_TAC[IVAL_SMALL] THEN + ASM_SIMP_TAC[MLDSA_IVAL_VAL] THEN CONV_TAC WORD_REDUCE_CONV THEN REWRITE_TAC[iword_saturate; word_INT_MIN; word_INT_MAX; DIMINDEX_32] THEN CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC WORD_REDUCE_CONV THEN @@ -173,7 +169,7 @@ let VAL_DECOMPOSE_A1_88 = prove( ABBREV_TAC `t:int32 = iword(&((2 * val(a:int32) * 1477838209) DIV 4294967296))` THEN SUBGOAL_THEN `val(t:int32) = (2 * val(a:int32) * 1477838209) DIV 4294967296` ASSUME_TAC THENL - [EXPAND_TAC "t" THEN MATCH_MP_TAC VAL_IWORD_NUM THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN + [EXPAND_TAC "t" THEN MATCH_MP_TAC VAL_IWORD_NUM_32 THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN SUBGOAL_THEN `val(t:int32) < 2147483648` ASSUME_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN REWRITE_TAC[word_ishr_round] THEN CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC INT_REDUCE_CONV THEN @@ -187,7 +183,7 @@ let VAL_DECOMPOSE_A1_88 = prove( TRANS_TAC LT_TRANS `(5767167 + 65536) DIV 131072 + 1` THEN CONJ_TAC THENL [MATCH_MP_TAC(ARITH_RULE `x <= y ==> x < y + 1`) THEN MATCH_MP_TAC DIV_MONO THEN ASM_ARITH_TAC; CONV_TAC NUM_REDUCE_CONV]; ALL_TAC] THEN - ASM_SIMP_TAC[VAL_IWORD_NUM] THEN MATCH_MP_TAC VAL_IWORD_NUM THEN + ASM_SIMP_TAC[VAL_IWORD_NUM_32] THEN MATCH_MP_TAC VAL_IWORD_NUM_32 THEN UNDISCH_THEN `val(t:int32) = (2 * val(a:int32) * 1477838209) DIV 4294967296` (SUBST1_TAC o SYM) THEN ASM_REWRITE_TAC[]);; @@ -348,9 +344,9 @@ let WORD_IGT_43_TRUE = BITBLAST_RULE let ELEMENT_CORRECT_88 = prove( `!a:int32 h:int32. val a < 8380417 /\ val h <= 1 - ==> val(mldsa_use_hint_88_asm a h) = mldsa_use_hint_88_spec (val a) (val h)`, + ==> val(mldsa_use_hint_88_asm a h) = mldsa_use_hint_88_code (val a) (val h)`, REPEAT GEN_TAC THEN STRIP_TAC THEN - REWRITE_TAC[mldsa_use_hint_88_asm; mldsa_use_hint_88_spec] THEN + REWRITE_TAC[mldsa_use_hint_88_asm; mldsa_use_hint_88_code] THEN CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN ABBREV_TAC `nv = ((val(a:int32) + 127) DIV 128 * 11275 + 8388608) DIV 16777216` THEN SUBGOAL_THEN `val(word_ishr_round (word_2smulh (a:int32) (word 1477838209)) 17 : int32) = nv` ASSUME_TAC THENL @@ -442,17 +438,17 @@ let ELEMENT_CORRECT_WORD_88 = prove( `!a:int32 h:int32. val a < 8380417 /\ val h <= 1 ==> mldsa_use_hint_88_asm a h = - word(mldsa_use_hint_88_spec (val a) (val h))`, + word(mldsa_use_hint_88_code (val a) (val h))`, REPEAT GEN_TAC THEN STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM WORD_VAL] THEN AP_TERM_TAC THEN MP_TAC(SPECL [`a:int32`; `h:int32`] ELEMENT_CORRECT_88) THEN ASM_REWRITE_TAC[] THEN DISCH_THEN(fun th -> REWRITE_TAC[th]));; (* ========================================================================= *) -(* Correctness proof with functional postcondition *) +(* Correctness proof, code-aligned spec (intermediate) *) (* ========================================================================= *) -let MLDSA_USE_HINT_88_CORRECT = prove +let MLDSA_USE_HINT_88_CORRECT_CODE = prove (`!b a h x y pc. nonoverlapping (word pc, LENGTH mldsa_poly_use_hint_88_mc) (b, 1024) /\ nonoverlapping (b, 1024) (a, 1024) /\ @@ -467,10 +463,10 @@ let MLDSA_USE_HINT_88_CORRECT = prove read(memory :> bytes32(word_add a (word(4 * i)))) s = x i) /\ (!i. i < 256 ==> read(memory :> bytes32(word_add h (word(4 * i)))) s = y i)) - (\s. read PC s = word(pc + 0x130) /\ + (\s. read PC s = word(pc + LENGTH mldsa_poly_use_hint_88_mc - 4) /\ (!i. i < 256 ==> read(memory :> bytes32(word_add b (word(4 * i)))) s = - word(mldsa_use_hint_88_spec (val(x i)) (val(y i))))) + word(mldsa_use_hint_88_code (val(x i)) (val(y i))))) (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, MAYCHANGE [memory :> bytes(b, 1024)])`, @@ -532,10 +528,66 @@ let MLDSA_USE_HINT_88_CORRECT = prove CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC);; (* ========================================================================= *) -(* Subroutine form *) +(* Subroutine form (intermediate, code-aligned) *) (* ========================================================================= *) -let MLDSA_USE_HINT_88_SUBROUTINE_CORRECT = prove +let ENSURES_STRENGTHEN_POST = prove( + `!P (Q:armstate->bool) Q' R. + ensures arm P Q' R /\ (!s. Q' s ==> Q s) ==> ensures arm P Q R`, + REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN + REWRITE_TAC[ensures] THEN MATCH_MP_TAC MONO_FORALL THEN + X_GEN_TAC `s0:armstate` THEN MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN + MP_TAC(BETA_RULE(ISPECL [`arm`; + `\s':armstate. (Q':armstate->bool) s' /\ (R:armstate->armstate->bool) (s0:armstate) s'`; + `\s':armstate. (Q:armstate->bool) s' /\ (R:armstate->armstate->bool) (s0:armstate) s'`] + EVENTUALLY_MONO)) THEN + ANTS_TAC THENL [ASM_MESON_TAC[]; MESON_TAC[]]);; + +let MLDSA_USE_HINT_88_CORRECT_BOUND_CODE = prove + (`!b a h x y pc. + nonoverlapping (word pc, LENGTH mldsa_poly_use_hint_88_mc) (b, 1024) /\ + nonoverlapping (b, 1024) (a, 1024) /\ + nonoverlapping (b, 1024) (h, 1024) + ==> ensures arm + (\s. aligned_bytes_loaded s (word pc) mldsa_poly_use_hint_88_mc /\ + read PC s = word pc /\ + C_ARGUMENTS [b; a; h] s /\ + (!i. i < 256 ==> val(x i) < 8380417) /\ + (!i. i < 256 ==> val(y i) <= 1) /\ + (!i. i < 256 ==> + read(memory :> bytes32(word_add a (word(4 * i)))) s = x i) /\ + (!i. i < 256 ==> + read(memory :> bytes32(word_add h (word(4 * i)))) s = y i)) + (\s. read PC s = word(pc + LENGTH mldsa_poly_use_hint_88_mc - 4) /\ + (!i. i < 256 ==> + read(memory :> bytes32(word_add b (word(4 * i)))) s = + word(mldsa_use_hint_88_code (val(x i)) (val(y i)))) /\ + (!i. i < 256 ==> + val(read(memory :> bytes32(word_add b (word(4 * i)))) s) < 44)) + (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, + MAYCHANGE [memory :> bytes(b, 1024)])`, + REPEAT GEN_TAC THEN DISCH_TAC THEN + MATCH_MP_TAC ENSURES_STRENGTHEN_POST THEN + EXISTS_TAC + `\s. read PC s = word(pc + LENGTH mldsa_poly_use_hint_88_mc - 4) /\ + (!i. i < 256 ==> + read(memory :> bytes32(word_add b (word(4 * i)))) s = + word(mldsa_use_hint_88_code (val(x i:int32)) (val(y i:int32))))` THEN + CONJ_TAC THENL + [MATCH_MP_TAC MLDSA_USE_HINT_88_CORRECT_CODE THEN ASM_REWRITE_TAC[]; + REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN + FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN + DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[VAL_WORD; DIMINDEX_32] THEN + CONV_TAC NUM_REDUCE_CONV THEN + MATCH_MP_TAC(ARITH_RULE `x < 44 ==> x MOD 4294967296 < 44`) THEN + REWRITE_TAC[mldsa_use_hint_88_code] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN + REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN ASM_ARITH_TAC]);; + +(* Intermediate subroutine correctness against the code-aligned spec. + Bridged to the public FIPS 204-aligned theorem below via + MLDSA_USE_HINT_88_EQUIV. *) +let MLDSA_USE_HINT_88_SUBROUTINE_CORRECT_CODE = prove (`!b a h x y pc returnaddress. nonoverlapping (word pc, LENGTH mldsa_poly_use_hint_88_mc) (b, 1024) /\ nonoverlapping (b, 1024) (a, 1024) /\ @@ -554,137 +606,17 @@ let MLDSA_USE_HINT_88_SUBROUTINE_CORRECT = prove (\s. read PC s = returnaddress /\ (!i. i < 256 ==> read(memory :> bytes32(word_add b (word(4 * i)))) s = - word(mldsa_use_hint_88_spec (val(x i)) (val(y i))))) + word(mldsa_use_hint_88_code (val(x i)) (val(y i)))) /\ + (!i. i < 256 ==> + val(read(memory :> bytes32(word_add b (word(4 * i)))) s) < 44)) (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, MAYCHANGE [memory :> bytes(b, 1024)])`, REWRITE_TAC[fst MLDSA_USE_HINT_88_EXEC] THEN + CONV_TAC NUM_REDUCE_CONV THEN ARM_ADD_RETURN_NOSTACK_TAC MLDSA_USE_HINT_88_EXEC - (REWRITE_RULE[fst MLDSA_USE_HINT_88_EXEC] - MLDSA_USE_HINT_88_CORRECT));; - -(* ========================================================================= *) -(* Constant-time and memory safety proof. *) -(* ========================================================================= *) - -needs "arm/proofs/consttime.ml";; -needs "arm/proofs/subroutine_signatures.ml";; - - -let full_spec,public_vars = mk_safety_spec - ~keep_maychanges:false - (assoc "mldsa_poly_use_hint_88" subroutine_signatures) - MLDSA_USE_HINT_88_SUBROUTINE_CORRECT - MLDSA_USE_HINT_88_EXEC;; - -let MLDSA_USE_HINT_88_SUBROUTINE_SAFE = time prove - (`exists f_events. - forall e b a h pc returnaddress. - nonoverlapping (word pc,LENGTH mldsa_poly_use_hint_88_mc) (b,1024) /\ - nonoverlapping (b,1024) (a,1024) /\ - nonoverlapping (b,1024) (h,1024) - ==> ensures arm - (\s. - aligned_bytes_loaded s (word pc) - mldsa_poly_use_hint_88_mc /\ - read PC s = word pc /\ - read X30 s = returnaddress /\ - C_ARGUMENTS [b; a; h] s /\ - read events s = e) - (\s. - read PC s = returnaddress /\ - (exists e2. - read events s = APPEND e2 e /\ - e2 = f_events a h b pc returnaddress /\ - memaccess_inbounds e2 [a,1024; h,1024; b,1024] - [b,1024])) - (\s s'. true)`, - ASSERT_CONCL_TAC full_spec THEN - PROVE_SAFETY_SPEC_TAC ~public_vars:public_vars MLDSA_USE_HINT_88_EXEC);; - - -(* ========================================================================= *) -(* FIPS 204 definitions and equivalence (after safety proof) *) -(* ========================================================================= *) - -let mldsa_cmod = new_definition - `mldsa_cmod (r:num) (m:num) : int = - if (r MOD m) * 2 <= m then &(r MOD m) else &(r MOD m) - &m`;; - -let mldsa_decompose_88 = new_definition - `mldsa_decompose_88 (r:num) : num # int = - let r0 = mldsa_cmod r 190464 in - if &r - r0 = &8380416 then (0, r0 - &1) - else (num_of_int((&r - r0) div &190464), r0)`;; - -let decompose_88_r1 = new_definition - `decompose_88_r1 (r:num) : num = FST(mldsa_decompose_88 r)`;; - -let decompose_88_r0 = new_definition - `decompose_88_r0 (r:num) : int = SND(mldsa_decompose_88 r)`;; - -let mldsa_use_hint_88 = new_definition - `mldsa_use_hint_88 (h:num) (r:num) : num = - let (r1, r0) = mldsa_decompose_88 r in - if h = 1 /\ r0 > &0 then if r1 = 43 then 0 else r1 + 1 - else if h = 1 /\ r0 <= &0 then if r1 = 0 then 43 else r1 - 1 - else r1`;; - -let LOWER_NONWRAP_R1_88 = prove( - `!r. r MOD 190464 * 2 <= 190464 /\ - ~((&r:int) - &(r MOD 190464) = &8380416) ==> - decompose_88_r1 r = r DIV 190464`, - GEN_TAC THEN STRIP_TAC THEN - REWRITE_TAC[decompose_88_r1; mldsa_decompose_88; mldsa_cmod] THEN - CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN ASM_REWRITE_TAC[] THEN - SUBGOAL_THEN `r MOD 190464 <= r` ASSUME_TAC THENL - [MESON_TAC[MOD_LE]; ALL_TAC] THEN - ASM_SIMP_TAC[INT_OF_NUM_SUB; INT_OF_NUM_DIV; - NUM_OF_INT_OF_NUM; INT_OF_NUM_EQ] THEN - MP_TAC(SPECL [`r:num`; `190464`] (CONJUNCT1 DIVISION_SIMP)) THEN - DISCH_TAC THEN - SUBGOAL_THEN `r - r MOD 190464 = 190464 * r DIV 190464` SUBST1_TAC THENL - [ASM_ARITH_TAC; ALL_TAC] THEN - MP_TAC(SPECL [`190464`; `r DIV 190464`] DIV_MULT) THEN - CONV_TAC NUM_REDUCE_CONV);; - -let UPPER_NONWRAP_R1_88 = prove( - `!r. ~(r MOD 190464 * 2 <= 190464) /\ - ~((&r:int) - (&(r MOD 190464) - &190464) = &8380416) ==> - decompose_88_r1 r = r DIV 190464 + 1`, - GEN_TAC THEN STRIP_TAC THEN - REWRITE_TAC[decompose_88_r1; mldsa_decompose_88; mldsa_cmod] THEN - CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN ASM_REWRITE_TAC[] THEN - SUBGOAL_THEN `r MOD 190464 <= r` ASSUME_TAC THENL - [MESON_TAC[MOD_LE]; ALL_TAC] THEN - SUBGOAL_THEN `r MOD 190464 < 190464` ASSUME_TAC THENL - [MP_TAC(SPECL [`r:num`; `190464`] MOD_LT_EQ) THEN ARITH_TAC; ALL_TAC] THEN - SUBGOAL_THEN `(&r:int) - (&(r MOD 190464) - &190464) = - &(r - r MOD 190464 + 190464)` ASSUME_TAC THENL - [ASM_SIMP_TAC[GSYM INT_OF_NUM_SUB; GSYM INT_OF_NUM_ADD] THEN - INT_ARITH_TAC; ALL_TAC] THEN - ASM_REWRITE_TAC[INT_OF_NUM_DIV; NUM_OF_INT_OF_NUM; INT_OF_NUM_EQ] THEN - MP_TAC(SPECL [`r:num`; `190464`] (CONJUNCT1 DIVISION_SIMP)) THEN - DISCH_TAC THEN - SUBGOAL_THEN `r - r MOD 190464 + 190464 = (r DIV 190464 + 1) * 190464` - ASSUME_TAC THENL - [ASM_ARITH_TAC; ALL_TAC] THEN - ASM_REWRITE_TAC[] THEN - MP_TAC(SPECL [`(r DIV 190464 + 1) * 190464`; `190464`] DIV_MULT) THEN - ARITH_TAC);; - -(* Unfold mldsa_use_hint_88 eliminating the paired let *) -let MLDSA_USE_HINT_88_UNFOLD = prove( - `!h r. mldsa_use_hint_88 h r = - (if h = 1 /\ decompose_88_r0 r > &0 - then if decompose_88_r1 r = 43 then 0 else decompose_88_r1 r + 1 - else if h = 1 /\ decompose_88_r0 r <= &0 - then if decompose_88_r1 r = 0 then 43 else decompose_88_r1 r - 1 - else decompose_88_r1 r)`, - REPEAT GEN_TAC THEN - REWRITE_TAC[mldsa_use_hint_88; decompose_88_r1; decompose_88_r0] THEN - SPEC_TAC(`mldsa_decompose_88 r`, `p:num#int`) THEN - REWRITE_TAC[FORALL_PAIR_THM] THEN - CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN REWRITE_TAC[]);; + (CONV_RULE(ONCE_DEPTH_CONV NUM_REDUCE_CONV) + (REWRITE_RULE[fst MLDSA_USE_HINT_88_EXEC] + MLDSA_USE_HINT_88_CORRECT_BOUND_CODE)));; (* ========================================================================= *) @@ -993,10 +925,10 @@ let DECOMPOSE_88_R0_SIGN = time prove( let MLDSA_USE_HINT_88_EQUIV = prove( `!r h. r < 8380417 /\ h <= 1 - ==> mldsa_use_hint_88 h r = mldsa_use_hint_88_spec r h`, + ==> mldsa_use_hint_88 h r = mldsa_use_hint_88_code r h`, REPEAT GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC[MLDSA_USE_HINT_88_UNFOLD] THEN - REWRITE_TAC[mldsa_use_hint_88_spec] THEN + REWRITE_TAC[mldsa_use_hint_88_code] THEN CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN MP_TAC(SPEC `r:num` DECOMPOSE_88_R1_EQUIV) THEN ASM_REWRITE_TAC[] THEN CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN @@ -1010,22 +942,16 @@ let MLDSA_USE_HINT_88_EQUIV = prove( ASM_CASES_TAC `decompose_88_r0 r > &0` THEN ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[]);; -let ENSURES_STRENGTHEN_POST = prove( - `!P (Q:armstate->bool) Q' R. - ensures arm P Q' R /\ (!s. Q' s ==> Q s) ==> ensures arm P Q R`, - REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN - REWRITE_TAC[ensures] THEN MATCH_MP_TAC MONO_FORALL THEN - X_GEN_TAC `s0:armstate` THEN MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN - MP_TAC(BETA_RULE(ISPECL [`arm`; - `\s':armstate. (Q':armstate->bool) s' /\ (R:armstate->armstate->bool) (s0:armstate) s'`; - `\s':armstate. (Q:armstate->bool) s' /\ (R:armstate->armstate->bool) (s0:armstate) s'`] - EVENTUALLY_MONO)) THEN - ANTS_TAC THENL [ASM_MESON_TAC[]; MESON_TAC[]]);; +(* ========================================================================= *) +(* Public subroutine correctness (FIPS 204-aligned) *) +(* ========================================================================= *) -(* FIPS 204-aligned subroutine correctness. - Derived from the code-aligned SUBROUTINE_CORRECT by rewriting - mldsa_use_hint_88_spec -> mldsa_use_hint_88 via MLDSA_USE_HINT_88_EQUIV. *) -let MLDSA_USE_HINT_88_SUBROUTINE_CORRECT_FIPS204 = prove +(* Postcondition is stated in terms of mldsa_use_hint_88 from FIPS 204 + (Algorithm 40), with the output bound < 44 as a corollary. + Derived from MLDSA_USE_HINT_88_SUBROUTINE_CORRECT_CODE by + rewriting mldsa_use_hint_88_code -> mldsa_use_hint_88 via + MLDSA_USE_HINT_88_EQUIV. *) +let MLDSA_USE_HINT_88_SUBROUTINE_CORRECT = prove (`!b a h x y pc returnaddress. nonoverlapping (word pc, LENGTH mldsa_poly_use_hint_88_mc) (b, 1024) /\ nonoverlapping (b, 1024) (a, 1024) /\ @@ -1046,7 +972,9 @@ let MLDSA_USE_HINT_88_SUBROUTINE_CORRECT_FIPS204 = prove (\s. read PC s = returnaddress /\ (!i. i < 256 ==> read(memory :> bytes32(word_add b (word(4 * i)))) s = - word(mldsa_use_hint_88 (val(y i)) (val(x i))))) + word(mldsa_use_hint_88 (val(y i)) (val(x i)))) /\ + (!i. i < 256 ==> + val(read(memory :> bytes32(word_add b (word(4 * i)))) s) < 44)) (MAYCHANGE_REGS_AND_FLAGS_PERMITTED_BY_ABI ,, MAYCHANGE [memory :> bytes(b, 1024)])`, REPEAT GEN_TAC THEN @@ -1054,21 +982,49 @@ let MLDSA_USE_HINT_88_SUBROUTINE_CORRECT_FIPS204 = prove SUBGOAL_THEN `!i. i < 256 ==> mldsa_use_hint_88 (val((y:num->int32) i)) (val((x:num->int32) i)) = - mldsa_use_hint_88_spec (val(x i)) (val(y i))` + mldsa_use_hint_88_code (val(x i)) (val(y i))` (fun th -> SIMP_TAC[th]) THENL [REPEAT STRIP_TAC THEN MATCH_MP_TAC MLDSA_USE_HINT_88_EQUIV THEN CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; - MATCH_MP_TAC ENSURES_STRENGTHEN_POST THEN - EXISTS_TAC - `\s. read PC s = returnaddress /\ - (!i. i < 256 ==> - read(memory :> bytes32(word_add b (word(4 * i)))) s = - word(mldsa_use_hint_88_spec (val(x i:int32)) (val(y i:int32)))) /\ - (!i. i < 256 ==> - val(read(memory :> bytes32(word_add b (word(4 * i)))) s) < 44)` THEN - CONJ_TAC THENL - [MATCH_MP_TAC MLDSA_USE_HINT_88_SUBROUTINE_CORRECT THEN - ASM_REWRITE_TAC[]; - GEN_TAC THEN CONV_TAC(ONCE_DEPTH_CONV BETA_CONV) THEN - DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN - ASM_REWRITE_TAC[]]]);; + MATCH_MP_TAC MLDSA_USE_HINT_88_SUBROUTINE_CORRECT_CODE THEN + ASM_REWRITE_TAC[]]);; + + +(* ========================================================================= *) +(* Constant-time and memory safety proof. *) +(* ========================================================================= *) + +needs "arm/proofs/consttime.ml";; +needs "arm/proofs/subroutine_signatures.ml";; + + +let full_spec,public_vars = mk_safety_spec + ~keep_maychanges:false + (assoc "mldsa_poly_use_hint_88" subroutine_signatures) + MLDSA_USE_HINT_88_SUBROUTINE_CORRECT_CODE + MLDSA_USE_HINT_88_EXEC;; + +let MLDSA_USE_HINT_88_SUBROUTINE_SAFE = time prove + (`exists f_events. + forall e b a h pc returnaddress. + nonoverlapping (word pc,LENGTH mldsa_poly_use_hint_88_mc) (b,1024) /\ + nonoverlapping (b,1024) (a,1024) /\ + nonoverlapping (b,1024) (h,1024) + ==> ensures arm + (\s. + aligned_bytes_loaded s (word pc) + mldsa_poly_use_hint_88_mc /\ + read PC s = word pc /\ + read X30 s = returnaddress /\ + C_ARGUMENTS [b; a; h] s /\ + read events s = e) + (\s. + read PC s = returnaddress /\ + (exists e2. + read events s = APPEND e2 e /\ + e2 = f_events a h b pc returnaddress /\ + memaccess_inbounds e2 [a,1024; h,1024; b,1024] + [b,1024])) + (\s s'. true)`, + ASSERT_CONCL_TAC full_spec THEN + PROVE_SAFETY_SPEC_TAC ~public_vars:public_vars MLDSA_USE_HINT_88_EXEC);; diff --git a/common/mlkem_mldsa.ml b/common/mlkem_mldsa.ml index e9bed9dff..d0f6bc87f 100644 --- a/common/mlkem_mldsa.ml +++ b/common/mlkem_mldsa.ml @@ -2014,3 +2014,86 @@ let INT_MOD_RESIDUE = prove( REWRITE_TAC[GSYM INT_OF_NUM_MUL; GSYM INT_OF_NUM_ADD; GSYM INT_OF_NUM_EQ] THEN INT_ARITH_TAC);; + +(* ========================================================================= *) +(* FIPS 204 UseHint definitions (Algorithms 36 and 40) *) +(* ========================================================================= *) + +let mldsa_cmod = new_definition + `mldsa_cmod (r:num) (m:num) : int = + if (r MOD m) * 2 <= m then &(r MOD m) else &(r MOD m) - &m`;; + +let mldsa_decompose_88 = new_definition + `mldsa_decompose_88 (r:num) : num # int = + let r0 = mldsa_cmod r 190464 in + if &r - r0 = &8380416 then (0, r0 - &1) + else (num_of_int((&r - r0) div &190464), r0)`;; + +let decompose_88_r1 = new_definition + `decompose_88_r1 (r:num) : num = FST(mldsa_decompose_88 r)`;; + +let decompose_88_r0 = new_definition + `decompose_88_r0 (r:num) : int = SND(mldsa_decompose_88 r)`;; + +let mldsa_use_hint_88 = new_definition + `mldsa_use_hint_88 (h:num) (r:num) : num = + let (r1, r0) = mldsa_decompose_88 r in + if h = 1 /\ r0 > &0 then if r1 = 43 then 0 else r1 + 1 + else if h = 1 /\ r0 <= &0 then if r1 = 0 then 43 else r1 - 1 + else r1`;; + +let LOWER_NONWRAP_R1_88 = prove( + `!r. r MOD 190464 * 2 <= 190464 /\ + ~((&r:int) - &(r MOD 190464) = &8380416) ==> + decompose_88_r1 r = r DIV 190464`, + GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC[decompose_88_r1; mldsa_decompose_88; mldsa_cmod] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `r MOD 190464 <= r` ASSUME_TAC THENL + [MESON_TAC[MOD_LE]; ALL_TAC] THEN + ASM_SIMP_TAC[INT_OF_NUM_SUB; INT_OF_NUM_DIV; + NUM_OF_INT_OF_NUM; INT_OF_NUM_EQ] THEN + MP_TAC(SPECL [`r:num`; `190464`] (CONJUNCT1 DIVISION_SIMP)) THEN + DISCH_TAC THEN + SUBGOAL_THEN `r - r MOD 190464 = 190464 * r DIV 190464` SUBST1_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + MP_TAC(SPECL [`190464`; `r DIV 190464`] DIV_MULT) THEN + CONV_TAC NUM_REDUCE_CONV);; + +let UPPER_NONWRAP_R1_88 = prove( + `!r. ~(r MOD 190464 * 2 <= 190464) /\ + ~((&r:int) - (&(r MOD 190464) - &190464) = &8380416) ==> + decompose_88_r1 r = r DIV 190464 + 1`, + GEN_TAC THEN STRIP_TAC THEN + REWRITE_TAC[decompose_88_r1; mldsa_decompose_88; mldsa_cmod] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN ASM_REWRITE_TAC[] THEN + SUBGOAL_THEN `r MOD 190464 <= r` ASSUME_TAC THENL + [MESON_TAC[MOD_LE]; ALL_TAC] THEN + SUBGOAL_THEN `r MOD 190464 < 190464` ASSUME_TAC THENL + [MP_TAC(SPECL [`r:num`; `190464`] MOD_LT_EQ) THEN ARITH_TAC; ALL_TAC] THEN + SUBGOAL_THEN `(&r:int) - (&(r MOD 190464) - &190464) = + &(r - r MOD 190464 + 190464)` ASSUME_TAC THENL + [ASM_SIMP_TAC[GSYM INT_OF_NUM_SUB; GSYM INT_OF_NUM_ADD] THEN + INT_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[INT_OF_NUM_DIV; NUM_OF_INT_OF_NUM; INT_OF_NUM_EQ] THEN + MP_TAC(SPECL [`r:num`; `190464`] (CONJUNCT1 DIVISION_SIMP)) THEN + DISCH_TAC THEN + SUBGOAL_THEN `r - r MOD 190464 + 190464 = (r DIV 190464 + 1) * 190464` + ASSUME_TAC THENL + [ASM_ARITH_TAC; ALL_TAC] THEN + ASM_REWRITE_TAC[] THEN + MP_TAC(SPECL [`(r DIV 190464 + 1) * 190464`; `190464`] DIV_MULT) THEN + ARITH_TAC);; + +let MLDSA_USE_HINT_88_UNFOLD = prove( + `!h r. mldsa_use_hint_88 h r = + (if h = 1 /\ decompose_88_r0 r > &0 + then if decompose_88_r1 r = 43 then 0 else decompose_88_r1 r + 1 + else if h = 1 /\ decompose_88_r0 r <= &0 + then if decompose_88_r1 r = 0 then 43 else decompose_88_r1 r - 1 + else decompose_88_r1 r)`, + REPEAT GEN_TAC THEN + REWRITE_TAC[mldsa_use_hint_88; decompose_88_r1; decompose_88_r0] THEN + SPEC_TAC(`mldsa_decompose_88 r`, `p:num#int`) THEN + REWRITE_TAC[FORALL_PAIR_THM] THEN + CONV_TAC(TOP_DEPTH_CONV let_CONV) THEN REWRITE_TAC[]);; From 38508efd7f6317dc2836f6cfe9471e24cee30de9 Mon Sep 17 00:00:00 2001 From: Jake Massimo Date: Wed, 13 May 2026 19:00:30 +0000 Subject: [PATCH 8/9] Add mldsa_pointwise_acc_l{4,5,7}_x86 to onlyInX86 list These x86-only functions were added in main but missing from the onlyInX86 array after merge, causing collect-signatures.py to fail. --- tools/collect-signatures.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/collect-signatures.py b/tools/collect-signatures.py index 5011e11d7..5f7e4ec91 100644 --- a/tools/collect-signatures.py +++ b/tools/collect-signatures.py @@ -339,6 +339,9 @@ def stripPrefixes(s, prefixes): "mldsa_intt", "mldsa_ntt", "mldsa_nttunpack", + "mldsa_pointwise_acc_l4_x86", + "mldsa_pointwise_acc_l5_x86", + "mldsa_pointwise_acc_l7_x86", "mldsa_pointwise_x86", "mldsa_reduce", "mlkem_frombytes", From 8526206cd30d1fd4ff4bc6a34bc1150aa8aec06b Mon Sep 17 00:00:00 2001 From: Jake Massimo Date: Wed, 13 May 2026 20:36:14 +0000 Subject: [PATCH 9/9] Fix x86 CI: add benchmark stub and test enablement for mldsa_poly_use_hint_88 Add empty call_mldsa_poly_use_hint_88 stub in the x86 ifdef section of benchmark.c (matching the pattern used by mldsa_poly_use_hint_32), and use the `arm` enablement flag in test.c since this is an ARM-only function. --- benchmarks/benchmark.c | 1 + 1 file changed, 1 insertion(+) diff --git a/benchmarks/benchmark.c b/benchmarks/benchmark.c index e5930eb1c..eef014cd8 100644 --- a/benchmarks/benchmark.c +++ b/benchmarks/benchmark.c @@ -1111,6 +1111,7 @@ void call_mldsa_pointwise(void) repeat(mldsa_pointwise_x86((int32_t*)b0,(int32_t void call_mldsa_pointwise_acc_l4(void) repeat(mldsa_pointwise_acc_l4_x86((int32_t*)b0,(const int32_t*)b1,(const int32_t*)b2,mldsa_avx2_qdata)) void call_mldsa_pointwise_acc_l5(void) repeat(mldsa_pointwise_acc_l5_x86((int32_t*)b0,(const int32_t*)b1,(const int32_t*)b2,mldsa_avx2_qdata)) void call_mldsa_pointwise_acc_l7(void) repeat(mldsa_pointwise_acc_l7_x86((int32_t*)b0,(const int32_t*)b1,(const int32_t*)b2,mldsa_avx2_qdata)) +void call_mldsa_poly_use_hint_88(void) {} void call_mldsa_reduce(void) repeat(mldsa_reduce((int32_t*)b0)) void call_mlkem_frombytes(void) repeat(mlkem_frombytes((uint16_t*)b0,(int8_t*)b1))