From 9383cb10b3791a9c2c5b8f862150029ae8152ba4 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 1 Oct 2026 21:46:49 +0000 Subject: [PATCH] Verify ARMv7 Triple DES ECB and enable the public API --- README.md | 2 +- bench/benches/primitives/triple_des_ecb.rs | 4 +- .../Artifacts/TripleDes/Arm.lean | 56 + .../Impl/TripleDes/Arm/Block.lean | 66 + .../Impl/TripleDes/Arm/Common.lean | 29 + .../Impl/TripleDes/Arm/Ecb.lean | 18 + .../Impl/TripleDes/Arm/ExpandKey.lean | 38 + .../Impl/TripleDes/Arm/Permutation.lean | 9 + .../Impl/TripleDes/Arm/Sbox.lean | 30 + .../Proof/TripleDes/Arm/Block.lean | 92 + .../Proof/TripleDes/Arm/BlockIO.lean | 69 + .../Proof/TripleDes/Arm/Body.lean | 74 + .../Proof/TripleDes/Arm/Box.lean | 55 + .../Proof/TripleDes/Arm/Bytes.lean | 61 + .../Proof/TripleDes/Arm/ConstantTime.lean | 45 + .../Proof/TripleDes/Arm/Ecb/Body.lean | 56 + .../Proof/TripleDes/Arm/Ecb/Call.lean | 88 + .../Proof/TripleDes/Arm/Ecb/Contract.lean | 24 + .../Proof/TripleDes/Arm/Ecb/Correct.lean | 83 + .../Proof/TripleDes/Arm/Ecb/IO.lean | 75 + .../Proof/TripleDes/Arm/Ecb/Loop.lean | 92 + .../Proof/TripleDes/Arm/Ecb/LoopFrame.lean | 70 + .../Proof/TripleDes/Arm/Ecb/Pre.lean | 65 + .../Proof/TripleDes/Arm/Ecb/Slice.lean | 54 + .../Proof/TripleDes/Arm/Ecb/Steps.lean | 45 + .../Proof/TripleDes/Arm/Ecb/Verified.lean | 52 + .../Proof/TripleDes/Arm/FunctionsLit.lean | 13 + .../Proof/TripleDes/Arm/Head.lean | 85 + .../Proof/TripleDes/Arm/Initial.lean | 42 + .../Proof/TripleDes/Arm/Key/Body.lean | 69 + .../Proof/TripleDes/Arm/Key/Component.lean | 52 + .../Proof/TripleDes/Arm/Key/Composition.lean | 168 + .../Proof/TripleDes/Arm/Key/Contract.lean | 24 + .../Proof/TripleDes/Arm/Key/Copy.lean | 122 + .../Proof/TripleDes/Arm/Key/Correct.lean | 82 + .../Proof/TripleDes/Arm/Key/Load.lean | 112 + .../Proof/TripleDes/Arm/Key/Loop.lean | 134 + .../Proof/TripleDes/Arm/Key/Permutation.lean | 39 + .../Proof/TripleDes/Arm/Key/Rotation.lean | 135 + .../Proof/TripleDes/Arm/Key/Save.lean | 57 + .../Proof/TripleDes/Arm/Key/Store.lean | 91 + .../Proof/TripleDes/Arm/Key/Verified.lean | 35 + .../Proof/TripleDes/Arm/KeySteps.lean | 32 + .../Proof/TripleDes/Arm/Lit.lean | 22 + .../Proof/TripleDes/Arm/Loop.lean | 160 + .../Proof/TripleDes/Arm/Pass.lean | 86 + .../Proof/TripleDes/Arm/PassStart.lean | 27 + .../Proof/TripleDes/Arm/Permutation.lean | 138 + .../Proof/TripleDes/Arm/Pre.lean | 106 + .../Proof/TripleDes/Arm/Ready.lean | 67 + .../Proof/TripleDes/Arm/Round.lean | 295 + .../Proof/TripleDes/Arm/RoundBody.lean | 116 + .../Proof/TripleDes/Arm/RoundFunction.lean | 72 + .../Proof/TripleDes/Arm/RoundLit.lean | 25 + .../Proof/TripleDes/Arm/RoundStep.lean | 67 + .../Proof/TripleDes/Arm/Save.lean | 77 + .../Proof/TripleDes/Arm/Sbox.lean | 114 + .../Proof/TripleDes/Arm/Spills.lean | 83 + .../Proof/TripleDes/Arm/Store.lean | 71 + .../Proof/TripleDes/Arm/Tail.lean | 67 + .../Proof/TripleDes/Arm/VerifiedBlock.lean | 70 + .../Proof/TripleDes/Arm/Word.lean | 60 + .../Proof/TripleDes/Arm/WordState.lean | 28 + .../Proof/TripleDes/Arm/WordStore.lean | 70 + src/asm/arm/mod.rs | 3 + src/asm/arm/triple_des.rs | 14167 ++++++++++++++++ src/triple_des_ecb.rs | 2 +- tests/cavp/triple_des_ecb.rs | 2 +- 68 files changed, 18634 insertions(+), 5 deletions(-) create mode 100644 lean/VerifiedGarbage/Artifacts/TripleDes/Arm.lean create mode 100644 lean/VerifiedGarbage/Impl/TripleDes/Arm/Block.lean create mode 100644 lean/VerifiedGarbage/Impl/TripleDes/Arm/Common.lean create mode 100644 lean/VerifiedGarbage/Impl/TripleDes/Arm/Ecb.lean create mode 100644 lean/VerifiedGarbage/Impl/TripleDes/Arm/ExpandKey.lean create mode 100644 lean/VerifiedGarbage/Impl/TripleDes/Arm/Permutation.lean create mode 100644 lean/VerifiedGarbage/Impl/TripleDes/Arm/Sbox.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Block.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/BlockIO.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Body.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Box.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Bytes.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/ConstantTime.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Body.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Call.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Contract.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Correct.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/IO.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Loop.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/LoopFrame.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Pre.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Slice.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Steps.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Verified.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/FunctionsLit.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Head.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Initial.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Body.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Component.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Composition.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Contract.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Copy.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Correct.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Load.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Loop.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Permutation.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Rotation.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Save.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Store.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Verified.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/KeySteps.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Lit.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Loop.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Pass.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/PassStart.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Permutation.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Pre.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Ready.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Round.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundBody.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundFunction.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundLit.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundStep.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Save.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Sbox.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Spills.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Store.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Tail.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/VerifiedBlock.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/Word.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/WordState.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/Arm/WordStore.lean create mode 100644 src/asm/arm/triple_des.rs diff --git a/README.md b/README.md index 3b7117e76..5c70568b4 100644 --- a/README.md +++ b/README.md @@ -401,7 +401,7 @@ yours to keep: ✅ -❌ +✅ ❌ diff --git a/bench/benches/primitives/triple_des_ecb.rs b/bench/benches/primitives/triple_des_ecb.rs index ced6a1ed7..629bd70a7 100644 --- a/bench/benches/primitives/triple_des_ecb.rs +++ b/bench/benches/primitives/triple_des_ecb.rs @@ -5,7 +5,7 @@ use criterion::Criterion; /// The library modules whose code these benchmarks run. pub const USES: &[&str] = &["triple_des_ecb", "triple_des"]; -#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "arm"))] pub fn bench(c: &mut Criterion) { use std::hint::black_box; @@ -59,5 +59,5 @@ pub fn bench(c: &mut Criterion) { } } -#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] +#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "arm")))] pub fn bench(_: &mut Criterion) {} diff --git a/lean/VerifiedGarbage/Artifacts/TripleDes/Arm.lean b/lean/VerifiedGarbage/Artifacts/TripleDes/Arm.lean new file mode 100644 index 000000000..7fdcd0ea2 --- /dev/null +++ b/lean/VerifiedGarbage/Artifacts/TripleDes/Arm.lean @@ -0,0 +1,56 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.VerifiedBlock +import VerifiedGarbage.Proof.TripleDes.Arm.Key.Verified +import VerifiedGarbage.Proof.TripleDes.Arm.Ecb.Verified + +namespace VG.Artifacts.TripleDes.Arm + +def artifacts : List Artifact := [ + { Spec.TripleDes.expandKeyApi with + target := Arm.target + doc := Spec.TripleDes.expandKeyApi.doc + (notes := ["Baseline ARMv7 scalar key expansion with fixed permutations and public round-count branches."]) + code := Impl.TripleDes.Arm.Key.expandKey + contract := Spec.TripleDes.expandKeyContract Arm.abi + stack := 0 + verified := Proof.TripleDes.Arm.Key.verified + spSafe := Code.all_of_forall (fun _ => rfl) _ }, + { Spec.TripleDes.encryptBlockApi with + target := Arm.target + doc := Spec.TripleDes.encryptBlockApi.doc + (notes := ["Baseline ARMv7 scalar Boolean S-box circuits; IP and FP shared across all three DES passes."]) + code := Impl.TripleDes.Arm.encryptBlock + contract := Spec.TripleDes.encryptBlockContract Arm.abi + stack := 0 + verified := Proof.TripleDes.Arm.encrypt_verified + spSafe := Code.all_of_forall (fun _ => rfl) _ }, + { Spec.TripleDes.decryptBlockApi with + target := Arm.target + doc := Spec.TripleDes.decryptBlockApi.doc + (notes := ["Baseline ARMv7 scalar Boolean S-box circuits with reverse EDE key order."]) + code := Impl.TripleDes.Arm.decryptBlock + contract := Spec.TripleDes.decryptBlockContract Arm.abi + stack := 0 + verified := Proof.TripleDes.Arm.decrypt_verified + spSafe := Code.all_of_forall (fun _ => rfl) _ }, + { Spec.TripleDes.ecbEncryptApi with + target := Arm.target + doc := Spec.TripleDes.ecbEncryptApi.doc + (notes := ["Baseline ARMv7, calling the verified Triple DES block primitive for each complete block."]) + code := Impl.TripleDes.Arm.Ecb.encrypt + contract := Spec.TripleDes.ecbEncryptContract Arm.abi 0 + stack := 0 + ofSig := ⟨_, _, _, by unfold Spec.TripleDes.ecbEncryptContract Spec.TripleDes.ecbContract; rfl⟩ + verified := Proof.TripleDes.Arm.Ecb.encrypt_verified + spSafe := Code.all_of_forall (fun _ => rfl) _ }, + { Spec.TripleDes.ecbDecryptApi with + target := Arm.target + doc := Spec.TripleDes.ecbDecryptApi.doc + (notes := ["Baseline ARMv7, calling the verified Triple DES block primitive for each complete block."]) + code := Impl.TripleDes.Arm.Ecb.decrypt + contract := Spec.TripleDes.ecbDecryptContract Arm.abi 0 + stack := 0 + ofSig := ⟨_, _, _, by unfold Spec.TripleDes.ecbDecryptContract Spec.TripleDes.ecbContract; rfl⟩ + verified := Proof.TripleDes.Arm.Ecb.decrypt_verified + spSafe := Code.all_of_forall (fun _ => rfl) _ }] + +end VG.Artifacts.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Impl/TripleDes/Arm/Block.lean b/lean/VerifiedGarbage/Impl/TripleDes/Arm/Block.lean new file mode 100644 index 000000000..c29ecfbaa --- /dev/null +++ b/lean/VerifiedGarbage/Impl/TripleDes/Arm/Block.lean @@ -0,0 +1,66 @@ +import VerifiedGarbage.Impl.TripleDes.Arm.Common +import VerifiedGarbage.Impl.TripleDes.Arm.Sbox + +namespace VG.Impl.TripleDes.Arm +open VG.Arm +open VG.Spec.TripleDes (Direction) + +def savedRegs : List Reg := [.r4, .r5, .r6, .r7, .r8, .r9, .r10, .r11, .lr] +def blockSave : List Instr := savedRegs.zipIdx.map fun (r, i) => .str r .r2 (4 * i) +def blockRestore : List Instr := savedRegs.zipIdx.map fun (r, i) => .ldr r .r2 (4 * i) + +def blockLoad : List Instr := + [.ldr .r4 .r1 0, .ldr .r5 .r1 4, .rev .r4 .r4, .rev .r5 .r5] ++ + permuteCode Spec.TripleDes.ip 64 32 32 .r11 .r10 .r5 .r4 .r12 .r9 + +def sboxInputs (i : Nat) : List Instr := + (List.range 6).flatMap fun j => + let k := 6 * i + 5 - j + let bit := 47 - k + [.ldr .lr .r0 (if bit < 32 then 0 else 4), rr (q j) .r11] ++ + shr (q j) (32 - Spec.TripleDes.expansion.getD k 1) ++ + [.dp .eor (q j) (q j) + (if bit % 32 = 0 then .reg .lr else .shifted .lr .lsr (bit % 32)), + .dp .and (q j) (q j) (.imm 1)] + +def sboxOutputs (i : Nat) : List Instr := + (List.range 4).flatMap fun j => + let position := 4 * i + 4 - j + let dst := (Spec.TripleDes.p.toList.findIdx? (· == position)).getD 0 + [.dp .and (q j) (q j) (.imm 1)] ++ placeBit (q j) (31 - dst) ++ + [.dp .eor .r10 .r10 (.reg (q j))] + +def box (i : Nat) : List Instr := sboxInputs i ++ sboxCode i ++ sboxOutputs i + +def swapHalves : List Instr := [rr .lr .r10, rr .r10 .r11, rr .r11 .lr] +def roundBody : List Instr := (List.range 8).flatMap box ++ swapHalves + +def roundAdvance (d : Direction) : List Instr := + [.dp (if d = .encrypt then .add else .sub) .r0 .r0 (.imm 8), .subs .r9 .r9 (.imm 1)] + +/-- Each offset is relative to the pointer left by the preceding pass. -/ +def passStart (offset : Int) : List Instr := + [.dp (if offset < 0 then .sub else .add) .r0 .r0 + (.imm (BitVec.ofNat 32 offset.natAbs)), imm .r9 16] + +def pass (offset : Int) (d : Direction) : Prog isa := + .seq (.block (passStart offset)) + (.seq (.loop (.block (roundBody ++ roundAdvance d)) .ne) (.block swapHalves)) + +def blockBody (d : Direction) : Prog isa := + match d with + | .encrypt => .seq (pass 0 .encrypt) (.seq (pass 120 .decrypt) (pass 136 .encrypt)) + | .decrypt => .seq (pass 376 .decrypt) (.seq (pass (-120) .encrypt) (pass (-136) .decrypt)) + +def blockStore (d : Direction) : List Instr := + permuteCode Spec.TripleDes.fp 64 32 32 .r5 .r4 .r11 .r10 .r12 .r9 ++ + [.rev .r4 .r4, .rev .r5 .r5, .str .r4 .r1 0, .str .r5 .r1 4, + .dp (if d = .encrypt then .sub else .add) .r0 .r0 + (.imm (if d = .encrypt then 384 else 8))] + +def block (d : Direction) : Prog isa := + .seq (.block (blockSave ++ blockLoad)) + (.seq (blockBody d) (.block (blockStore d ++ blockRestore))) +def encryptBlock : Prog isa := block .encrypt +def decryptBlock : Prog isa := block .decrypt +end VG.Impl.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Impl/TripleDes/Arm/Common.lean b/lean/VerifiedGarbage/Impl/TripleDes/Arm/Common.lean new file mode 100644 index 000000000..c9434f925 --- /dev/null +++ b/lean/VerifiedGarbage/Impl/TripleDes/Arm/Common.lean @@ -0,0 +1,29 @@ +import VerifiedGarbage.Spec.TripleDes +import VerifiedGarbage.TCB.Arm.Isa + +namespace VG.Impl.TripleDes.Arm +open VG.Arm + +def rr (d n : Reg) : Instr := .mov d (.reg n) +def imm (d : Reg) (n : Nat) : Instr := .mov d (.imm (BitVec.ofNat 32 n)) +def shr (r : Reg) (n : Nat) : List Instr := + if n = 0 then [] else [.mov r (.shifted r .lsr n)] +def placeBit (r : Reg) (n : Nat) : List Instr := + if n = 0 then [] else [.mov r (.shifted r .ror (32 - n))] +def mask (r : Reg) (n : Nat) : List Instr := + [.mov r (.shifted r .lsl (32 - n)), .mov r (.shifted r .lsr (32 - n))] + +/-- A fixed bit permutation across two words. Each split is the width of +its low word; unused high bits are zero. -/ +def permuteCode {m : Nat} (positions : Vector Nat m) (n srcSplit dstSplit : Nat) + (lo hi srcLo srcHi tmp bit : Reg) : List Instr := + [imm lo 0, imm hi 0, imm bit 1] ++ (List.range m).flatMap fun k => + let source := n - positions.getD k 1 + let output := m - 1 - k + [rr tmp (if source < srcSplit then srcLo else srcHi)] ++ + shr tmp (if source < srcSplit then source else source - srcSplit) ++ + [.dp .and tmp tmp (.reg bit)] ++ + placeBit tmp (if output < dstSplit then output else output - dstSplit) ++ + [.dp .eor (if output < dstSplit then lo else hi) + (if output < dstSplit then lo else hi) (.reg tmp)] +end VG.Impl.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Impl/TripleDes/Arm/Ecb.lean b/lean/VerifiedGarbage/Impl/TripleDes/Arm/Ecb.lean new file mode 100644 index 000000000..7c9dcb560 --- /dev/null +++ b/lean/VerifiedGarbage/Impl/TripleDes/Arm/Ecb.lean @@ -0,0 +1,18 @@ +import VerifiedGarbage.Impl.TripleDes.Arm.Block +namespace VG.Impl.TripleDes.Arm.Ecb +open VG.Arm VG.Impl.TripleDes.Arm +open VG.Spec.TripleDes (Direction) +def save : List Instr := [.str .lr .r3 512] +def setup : List Instr := [rr .r12 .r3, rr .r3 .r2, rr .r2 .r12, .cmp .r3 (.imm 0)] +def restore : List Instr := [.ldr .lr .r2 512] +def blockCall (d : Direction) : Prog isa := + match d with + | .encrypt => .call "vg_triple_des_encrypt_block" encryptBlock + | .decrypt => .call "vg_triple_des_decrypt_block" decryptBlock +def advance : List Instr := [.dp .add .r1 .r1 (.imm 8), .subs .r3 .r3 (.imm 1)] +def ecb (d : Direction) : Prog isa := + .seq (.block (save ++ setup)) (.seq (.ite .eq (.block []) + (.loop (.seq (blockCall d) (.block advance)) .ne)) (.block restore)) +def encrypt : Prog isa := ecb .encrypt +def decrypt : Prog isa := ecb .decrypt +end VG.Impl.TripleDes.Arm.Ecb diff --git a/lean/VerifiedGarbage/Impl/TripleDes/Arm/ExpandKey.lean b/lean/VerifiedGarbage/Impl/TripleDes/Arm/ExpandKey.lean new file mode 100644 index 000000000..b231f32bd --- /dev/null +++ b/lean/VerifiedGarbage/Impl/TripleDes/Arm/ExpandKey.lean @@ -0,0 +1,38 @@ +import VerifiedGarbage.Impl.TripleDes.Arm.Common +namespace VG.Impl.TripleDes.Arm.Key +open VG.Arm VG.Impl.TripleDes.Arm + +def savedRegs : List Reg := [.r4, .r5, .r6, .r7, .r8, .r9, .r10, .r11, .lr] +def save : List Instr := savedRegs.zipIdx.map fun (r, i) => .str r .r3 (4 * i) +def restore : List Instr := savedRegs.zipIdx.map fun (r, i) => .ldr r .r3 (4 * i) + +def load (offset component : Nat) : List Instr := + [.ldr .r4 .r0 offset, .ldr .r5 .r0 (offset + 4), .rev .r4 .r4, .rev .r5 .r5] ++ + permuteCode Spec.TripleDes.pc1 64 32 28 .r11 .r10 .r5 .r4 .r12 .lr ++ + [imm .r9 0, .dp .add .r8 .r2 (.imm (BitVec.ofNat 32 (128 * component)))] + +def rotate28 (r : Reg) (n : Nat) : List Instr := + [.mov .r4 (.shifted r .lsr (28 - n)), .mov r (.shifted r .ror (32 - n)), + .dp .eor r r (.reg .r4)] ++ mask r 28 + +def rotate (n : Nat) : Prog isa := .block (rotate28 .r10 n ++ rotate28 .r11 n) +def rotation : Prog isa := + .seq (.block [.mov .r4 (.shifted .r9 .lsr 1), .cmp .r4 (.imm 0)]) (.ite .eq (rotate 1) + (.seq (.block [.cmp .r9 (.imm 8)]) (.ite .eq (rotate 1) + (.seq (.block [.cmp .r9 (.imm 15)]) (.ite .eq (rotate 1) (rotate 2)))))) + +def storeRound : List Instr := + permuteCode Spec.TripleDes.pc2 56 28 32 .r4 .r5 .r11 .r10 .r12 .lr ++ + [.str .r4 .r8 0, .str .r5 .r8 4, .dp .add .r8 .r8 (.imm 8), + .dp .add .r9 .r9 (.imm 1), .cmp .r9 (.imm 16)] +def component (offset index : Nat) : Prog isa := + .seq (.block (load offset index)) (.loop (.seq rotation (.block storeRound)) .ne) +def copyThird : List Instr := + (List.range 16).flatMap fun j => + [.ldr .r4 .r2 (8 * j), .ldr .r5 .r2 (8 * j + 4), + .str .r4 .r2 (256 + 8 * j), .str .r5 .r2 (256 + 8 * j + 4)] +def expandKey : Prog isa := + .seq (.block save) (.seq (component 0 0) (.seq (component 8 1) + (.seq (.block [.cmp .r1 (.imm 16)]) + (.seq (.ite .eq (.block copyThird) (component 16 2)) (.block restore))))) +end VG.Impl.TripleDes.Arm.Key diff --git a/lean/VerifiedGarbage/Impl/TripleDes/Arm/Permutation.lean b/lean/VerifiedGarbage/Impl/TripleDes/Arm/Permutation.lean new file mode 100644 index 000000000..8e33ea26b --- /dev/null +++ b/lean/VerifiedGarbage/Impl/TripleDes/Arm/Permutation.lean @@ -0,0 +1,9 @@ +import VerifiedGarbage.Impl.TripleDes.Arm.Common +namespace VG.Impl.TripleDes.Arm +open VG.Arm + +def initialPermutation : Prog isa := .block (permuteCode Spec.TripleDes.ip 64 32 32 .r11 .r10 .r5 .r4 .r12 .r9) +def finalPermutation : Prog isa := .block (permuteCode Spec.TripleDes.fp 64 32 32 .r5 .r4 .r11 .r10 .r12 .r9) +def keyPermutation1 : Prog isa := .block (permuteCode Spec.TripleDes.pc1 64 32 28 .r11 .r10 .r5 .r4 .r12 .lr) +def keyPermutation2 : Prog isa := .block (permuteCode Spec.TripleDes.pc2 56 28 32 .r4 .r5 .r11 .r10 .r12 .lr) +end VG.Impl.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Impl/TripleDes/Arm/Sbox.lean b/lean/VerifiedGarbage/Impl/TripleDes/Arm/Sbox.lean new file mode 100644 index 000000000..2564fd534 --- /dev/null +++ b/lean/VerifiedGarbage/Impl/TripleDes/Arm/Sbox.lean @@ -0,0 +1,30 @@ +import VerifiedGarbage.Impl.TripleDes.Circuit +import VerifiedGarbage.Impl.Aes.Arm.Alloc + +namespace VG.Impl.TripleDes.Arm + +open VG.Arm + +def q : Nat → Reg + | 0 => .r4 | 1 => .r5 | 2 => .r6 | 3 => .r7 | 4 => .r8 | _ => .r12 + +def sboxIns : List (Nat × Reg) := (List.range 6).map fun i => (i, q i) + +def sboxOuts (i : Nat) : List (Nat × Reg) := + (List.range 4).map fun j => ((Circuit.outputs i).getD j 0, q j) + +/-- Six input planes and one temporary; slots below 16 hold saved registers and control state. -/ +def sboxCode (i : Nat) : List Instr := + VG.Impl.Aes.Arm.compile .r2 (Circuit.gates i) sboxIns (sboxOuts i) + [.lr] 15 10000 10001 (List.range' 16 96) + +def sbox0 : Prog isa := .block (sboxCode 0) +def sbox1 : Prog isa := .block (sboxCode 1) +def sbox2 : Prog isa := .block (sboxCode 2) +def sbox3 : Prog isa := .block (sboxCode 3) +def sbox4 : Prog isa := .block (sboxCode 4) +def sbox5 : Prog isa := .block (sboxCode 5) +def sbox6 : Prog isa := .block (sboxCode 6) +def sbox7 : Prog isa := .block (sboxCode 7) + +end VG.Impl.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Block.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Block.lean new file mode 100644 index 000000000..cdfb897c0 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Block.lean @@ -0,0 +1,92 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Head +import VerifiedGarbage.Proof.TripleDes.Arm.Tail + +namespace VG.Proof.TripleDes.Arm + +open VG VG.Arm VG.Impl.TripleDes.Arm +open VG.Spec.TripleDes (Direction Schedule) + +def blockResult (keys : Schedule) (direction : Direction) (b : Spec.TripleDes.Block) : + Spec.TripleDes.Block := + match direction with + | .encrypt => Spec.TripleDes.encryptBlock keys b + | .decrypt => Spec.TripleDes.decryptBlock keys b + +theorem blockResult_core (keys : Schedule) (direction : Direction) (b : Spec.TripleDes.Block) : + Spec.TripleDes.encodeBlock (Spec.TripleDes.permute Spec.TripleDes.fp + (blockCore (Spec.TripleDes.componentSchedule keys) direction + (Spec.TripleDes.permute Spec.TripleDes.ip (Spec.TripleDes.decodeBlock b)))) = + blockResult keys direction b := by + cases direction + · exact (VG.Proof.TripleDes.encryptBlock_eq_cores keys b).symm + · exact (VG.Proof.TripleDes.decryptBlock_eq_cores keys b).symm + +def blockRegions (s : State) : List Region := [⟨State.addr (s.gpr .r1), 8⟩, ⟨State.addr (s.gpr .r2), 512⟩] + +structure BlockPost (keys : Schedule) (direction : Direction) (original s : State) : Prop where + result : Spec.TripleDes.blockAt s.mem (State.addr (original.gpr .r1)) = + blockResult keys direction (Spec.TripleDes.blockAt original.mem (State.addr (original.gpr .r1))) + pointer : s.gpr .r0 = original.gpr .r0 + saved : ∀ r ∈ savedRegs, s.gpr r = original.gpr r + rd : s.rd = original.rd + wr : s.wr = original.wr + sp : s.sp = original.sp + regs : ∀ q ∈ roundStepKept, s.gpr q = original.gpr q + frame : Frame (blockRegions original) original.mem s.mem + +theorem block_ok (keys : Schedule) (base : BitVec 32) (direction : Direction) (s : State) + (hp : HeadPre (Spec.TripleDes.componentSchedule keys) base s) + (hwrite : ∀ t < 2, InRegions s.wr (State.addr (s.gpr .r1 + BitVec.ofNat 32 (4 * t))) 4) : + WP isa (block direction) s (BlockPost keys direction s) := by + apply WP.seq + apply WP.mono (blockHead_ok (Spec.TripleDes.componentSchedule keys) base s hp) + intro s₁ hs₁ + apply WP.seq + apply WP.mono (blockBody_ok (Spec.TripleDes.componentSchedule keys) base s₁ _ direction ((hs₁.regs .r0 (by decide)).trans hp.pointer) hs₁.ready hs₁.word) + intro s₂ hs₂ + have hregs₂ : ∀ q ∈ roundStepKept, s₂.gpr q = s.gpr q := by + intro q hq + have hkeep : ∀ r ∈ roundStepKept, r ∈ loadKept := by decide + exact (hs₂.2.2.1.regs q hq).trans (hs₁.regs q (hkeep q hq)) + have saved₂ := hs₁.saved.congr (hs₂.2.2.1.regs .r2 (by decide)) hs₂.2.2.1.frame + have savedRead₂ : ∀ i < 9, InRegions (s₂.rd ++ s₂.wr) (State.addr (s₂.gpr .r2) + BitVec.ofNat 64 (4 * i)) 4 := by + rw [hs₂.2.2.1.rd, hs₂.2.2.1.wr, hs₁.rd, hs₁.wr, hregs₂ .r2 (by decide)] + exact hp.saveRead + have hwrite₂ : ∀ t < 2, InRegions s₂.wr (State.addr (s₂.gpr .r1 + BitVec.ofNat 32 (4 * t))) 4 := by + rw [hs₂.2.2.1.wr, hs₁.wr, hregs₂ .r1 (by decide)] + exact hwrite + apply WP.mono (blockTail_ok s s₂ direction _ hs₂.1 saved₂ + (by rw [hregs₂ .r2 (by decide)]; exact hp.scratchFit) + (by rw [hregs₂ .r1 (by decide)]; exact hp.dataFit) savedRead₂ hwrite₂ + (by rw [saveRegion, hregs₂ .r1 (by decide), hregs₂ .r2 (by decide)]; exact hp.dataSeparate)) + intro s₃ hs₃ + refine ⟨?_, ?_, hs₃.saved, hs₃.rd.trans (hs₂.2.2.1.rd.trans hs₁.rd), + hs₃.wr.trans (hs₂.2.2.1.wr.trans hs₁.wr), + hs₃.sp.trans (hs₂.2.2.1.sp.trans hs₁.sp), + fun q hq => (hs₃.regs q hq).trans (hregs₂ q hq), ?_⟩ + · have hresult := hs₃.result + rw [hregs₂ .r1 (by decide)] at hresult + exact hresult.trans (blockResult_core keys direction _) + · rw [hs₃.pointer, hs₂.2.2.2, hp.pointer] + cases direction <;> simp only [reduceCtorEq, ite_true, ite_false, + BitVec.add_sub_cancel, BitVec.sub_add_cancel] + · have hf₁ : Frame (blockRegions s) s.mem s₁.mem := hs₁.frame.sub (by + intro r hr + obtain rfl := List.mem_singleton.mp hr + exact ⟨⟨State.addr (s.gpr .r2), 512⟩, by simp [blockRegions], Region.sub_prefix (by decide)⟩) + have hf₂ : Frame (blockRegions s) s₁.mem s₂.mem := hs₂.2.2.1.frame.sub (by + intro r hr + obtain rfl := List.mem_singleton.mp hr + refine ⟨⟨State.addr (s.gpr .r2), 512⟩, by simp [blockRegions], ?_⟩ + have hbase := hs₁.regs .r2 (by decide) + change Region.Sub ⟨State.addr (s₁.gpr .r2) + BitVec.ofNat 64 60, 388⟩ ⟨State.addr (s.gpr .r2), 512⟩ + rw [hbase] + exact Offset.sub_base _ (by decide)) + have hf₃ : Frame (blockRegions s) s₂.mem s₃.mem := hs₃.frame.sub (by + intro r hr + obtain rfl := List.mem_singleton.mp hr + rw [hregs₂ .r1 (by decide)] + exact ⟨⟨State.addr (s.gpr .r1), 8⟩, by simp [blockRegions], fun _ h => h⟩) + exact hf₁.trans (hf₂.trans hf₃) + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/BlockIO.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/BlockIO.lean new file mode 100644 index 000000000..c1fbb34cc --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/BlockIO.lean @@ -0,0 +1,69 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Bytes +import VerifiedGarbage.Proof.TripleDes.Arm.Initial +import VerifiedGarbage.Proof.TripleDes.Arm.RoundBody +import VerifiedGarbage.Proof.Framework.Arm.RegUpd +import VerifiedGarbage.Proof.Framework.Omega + +namespace VG.Proof.TripleDes.Arm +open VG VG.Arm VG.Arm.RegUpd VG.Impl.TripleDes.Arm + +def loadKept : List Reg := [.r0, .r1, .r2, .r3] + +theorem readDataWords_ok (s : State) (offset : Nat) (ho : offset + 4 < 4096) + (hr : ∀ t < 2, InRegions (s.rd ++ s.wr) + (State.addr (s.gpr .r1 + BitVec.ofNat 32 (offset + 4 * t))) 4) : + ∃ s', runBlock isa [.ldr .r4 .r1 offset, .ldr .r5 .r1 (offset + 4), + .rev .r4 .r4, .rev .r5 .r5] s = some s' ∧ + s'.gpr .r4 = rev (s.mem.readW (State.addr (s.gpr .r1 + BitVec.ofNat 32 offset)) 32) ∧ + s'.gpr .r5 = rev (s.mem.readW (State.addr (s.gpr .r1 + BitVec.ofNat 32 (offset + 4))) 32) ∧ + s'.mem = s.mem ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ + (∀ r, r ≠ .r4 → r ≠ .r5 → s'.gpr r = s.gpr r) := by + have h0 : InRegions (s.rd ++ s.wr) (State.addr (s.gpr .r1 + BitVec.ofNat 32 offset)) 4 := by + simpa only [Nat.mul_zero, Nat.add_zero] using hr 0 (by decide) + have h1 : InRegions (s.rd ++ s.wr) (State.addr (s.gpr .r1 + BitVec.ofNat 32 (offset + 4))) 4 := by + simpa only [Nat.mul_one] using hr 1 (by decide) + refine ⟨_, by + simp only [runBlock_cons, runStep_some, runBlock_nil, exec, show offset < 4096 from by omega, h0, show offset + 4 < 4096 from ho, ite_true, State.load32, + gpr_setReg, reduceCtorEq, ite_false, rd_setReg, wr_setReg, h1, + Option.map_some, mem_setReg, ite_true] + rfl, ?_, ?_, ?_, ?_, ?_, ?_, ?_⟩ + · simp only [gpr_setReg, reduceCtorEq, ite_true, ite_false] + · simp only [gpr_setReg, reduceCtorEq, ite_true, ite_false] + · simp only [mem_setReg] + · simp only [rd_setReg] + · simp only [wr_setReg] + · simp only [sp_setReg] + · intro r h4 h5; simp only [gpr_setReg, h4, h5, ite_false] + + +theorem blockLoad_ok (s : State) + (fit : (s.gpr .r1).toNat + 8 ≤ 2 ^ 32) + (hread : ∀ t < 2, InRegions (s.rd ++ s.wr) + (State.addr (s.gpr .r1 + BitVec.ofNat 32 (4 * t))) 4) : + ∃ s', runBlock isa blockLoad s = some s' ∧ + s'.gpr .r10 = ((Spec.TripleDes.permute Spec.TripleDes.ip + (Spec.TripleDes.decodeBlock (Spec.TripleDes.blockAt s.mem (State.addr (s.gpr .r1))))) >>> 32).setWidth 32 ∧ + s'.gpr .r11 = (Spec.TripleDes.permute Spec.TripleDes.ip + (Spec.TripleDes.decodeBlock (Spec.TripleDes.blockAt s.mem (State.addr (s.gpr .r1))))).setWidth 32 ∧ + s'.mem = s.mem ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ + (∀ r ∈ loadKept, s'.gpr r = s.gpr r) := by + obtain ⟨s₁, run₁, hi₁, lo₁, mem₁, rd₁, wr₁, sp₁, reg₁⟩ := readDataWords_ok s 0 (by decide) + (by simpa only [Nat.zero_add] using hread) + obtain ⟨s₂, run₂, lo₂, hi₂, rd₂, wr₂, sp₂, mem₂, reg₂⟩ := initial_raw_ok s₁ + have input : s₁.gpr .r4 ++ s₁.gpr .r5 = + Spec.TripleDes.decodeBlock (Spec.TripleDes.blockAt s.mem (State.addr (s.gpr .r1))) := by + rw [hi₁, lo₁, decodeBlock_readW] + simp only [BitVec.add_zero, Nat.zero_add] + rw [addr_add (by omega_using [fit])] + rfl + rw [input] at lo₂ hi₂ + refine ⟨s₂, ?_, hi₂, lo₂, mem₂.trans mem₁, rd₂.trans rd₁, wr₂.trans wr₁, ?_, ?_⟩ + · rw [blockLoad, runBoxes_append, run₁, Option.bind_some, run₂] + · exact sp₂.trans sp₁ + · intro r hr + have checks : ∀ r ∈ loadKept, + ((instrs initialPermutation.lit).all fun op => dstOf op != some r) = true := by decide +kernel + have unused : ∀ r ∈ loadKept, r ≠ .r4 ∧ r ≠ .r5 := by decide + exact (reg₂ r (checks r hr)).trans (reg₁ r (unused r hr).1 (unused r hr).2) + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Body.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Body.lean new file mode 100644 index 000000000..2641cfaab --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Body.lean @@ -0,0 +1,74 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Ready +namespace VG.Proof.TripleDes.Arm +open VG VG.Arm VG.Impl.TripleDes.Arm +open VG.Spec.TripleDes (Direction DesSchedule) +open VG.Proof.TripleDes (desCore) + +theorem threePasses_ok (keys : Nat → DesSchedule) (base : BitVec 32) (s : State) (x : BitVec 64) + (c₀ c₁ c₂ : Nat) (h₀ : c₀ < 3) (h₁ : c₁ < 3) (h₂ : c₂ < 3) + (d₀ d₁ d₂ : Direction) (o₀ o₁ o₂ : Int) + (e₀ : encodable (BitVec.ofNat 32 o₀.natAbs) = true) + (e₁ : encodable (BitVec.ofNat 32 o₁.natAbs) = true) + (e₂ : encodable (BitVec.ofNat 32 o₂.natAbs) = true) + (p₀ : startPointer (s.gpr .r0) o₀ = keyAddr (componentBase base c₀) d₀ 0) + (p₁ : startPointer (endPointer (componentBase base c₀) d₀) o₁ = keyAddr (componentBase base c₁) d₁ 0) + (p₂ : startPointer (endPointer (componentBase base c₁) d₁) o₂ = keyAddr (componentBase base c₂) d₂ 0) + (hready : Ready keys base s) (hword : WordState x s) : + WP isa (.seq (pass o₀ d₀) (.seq (pass o₁ d₁) (pass o₂ d₂))) s + (fun t => WordState (desCore (keys c₂) d₂ (desCore (keys c₁) d₁ (desCore (keys c₀) d₀ x))) t ∧ + Ready keys base t ∧ Stable s t ∧ t.gpr .r0 = endPointer (componentBase base c₂) d₂) := by + apply WP.seq + apply WP.mono (pass_word_ok keys base s x c₀ h₀ d₀ o₀ e₀ p₀ hready hword) + intro s₁ hs₁ + apply WP.seq + apply WP.mono (pass_word_ok keys base s₁ _ c₁ h₁ d₁ o₁ e₁ + (by rw [hs₁.2.2.2]; exact p₁) hs₁.2.1 hs₁.1) + intro s₂ hs₂ + apply WP.mono (pass_word_ok keys base s₂ _ c₂ h₂ d₂ o₂ e₂ + (by rw [hs₂.2.2.2]; exact p₂) hs₂.2.1 hs₂.1) + intro s₃ hs₃ + exact ⟨hs₃.1, hs₃.2.1, + hs₁.2.2.1.trans (hs₂.2.2.1.trans hs₃.2.2.1), hs₃.2.2.2⟩ + +theorem passPointers (base : BitVec 32) : + startPointer base 0 = keyAddr (componentBase base 0) .encrypt 0 ∧ + startPointer (endPointer (componentBase base 0) .encrypt) 120 = keyAddr (componentBase base 1) .decrypt 0 ∧ + startPointer (endPointer (componentBase base 1) .decrypt) 136 = keyAddr (componentBase base 2) .encrypt 0 ∧ + startPointer base 376 = keyAddr (componentBase base 2) .decrypt 0 ∧ + startPointer (endPointer (componentBase base 2) .decrypt) (-120) = keyAddr (componentBase base 1) .encrypt 0 ∧ + startPointer (endPointer (componentBase base 1) .encrypt) (-136) = keyAddr (componentBase base 0) .decrypt 0 := by + simp only [startPointer, endPointer, componentBase, keyAddr, + Int.reduceLT, Int.natAbs_neg, ite_true, ite_false, reduceCtorEq, + Nat.reduceMul, Nat.reduceSub] + repeat' constructor <;> bv_omega + +def blockCore (keys : Nat → DesSchedule) (direction : Direction) (x : BitVec 64) : BitVec 64 := + match direction with + | .encrypt => desCore (keys 2) .encrypt (desCore (keys 1) .decrypt (desCore (keys 0) .encrypt x)) + | .decrypt => desCore (keys 0) .decrypt (desCore (keys 1) .encrypt (desCore (keys 2) .decrypt x)) + +theorem blockBody_ok (keys : Nat → DesSchedule) (base : BitVec 32) (s : State) (x : BitVec 64) + (direction : Direction) (hptr : s.gpr .r0 = base) + (hready : Ready keys base s) (hword : WordState x s) : + WP isa (blockBody direction) s + (fun t => WordState (blockCore keys direction x) t ∧ Ready keys base t ∧ Stable s t ∧ + t.gpr .r0 = (if direction = .encrypt then base + 384 else base - 8)) := by + obtain ⟨p₀, p₁, p₂, p₃, p₄, p₅⟩ := passPointers base + cases direction + · apply WP.mono (threePasses_ok keys base s x 0 1 2 (by decide) (by decide) (by decide) + .encrypt .decrypt .encrypt 0 120 136 (by decide) (by decide) (by decide) + (by rw [hptr]; exact p₀) p₁ p₂ hready hword) + intro t ht + refine ⟨ht.1, ht.2.1, ht.2.2.1, ?_⟩ + rw [ht.2.2.2] + change base + BitVec.ofNat 32 256 + BitVec.ofNat 32 128 = base + BitVec.ofNat 32 384 + rw [Offset.add_ofNat_add_ofNat] + · apply WP.mono (threePasses_ok keys base s x 2 1 0 (by decide) (by decide) (by decide) + .decrypt .encrypt .decrypt 376 (-120) (-136) (by decide) (by decide) (by decide) + (by rw [hptr]; exact p₃) p₄ p₅ hready hword) + intro t ht + refine ⟨ht.1, ht.2.1, ht.2.2.1, ?_⟩ + rw [ht.2.2.2] + change (base + 0) - 8 = base - 8 + exact congrArg (· - (8 : BitVec 32)) (BitVec.add_zero base) +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Box.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Box.lean new file mode 100644 index 000000000..25265c34e --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Box.lean @@ -0,0 +1,55 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Round +import VerifiedGarbage.Proof.TripleDes.Arm.Spills + +namespace VG.Proof.TripleDes.Arm + +open VG VG.Arm VG.Arm.Straight VG.Impl.TripleDes.Arm + +theorem runBoxes_append (a b : List Instr) (s : State) : + runBlock isa (a ++ b) s = (runBlock isa a s).bind (runBlock isa b) := by + induction a generalizing s with + | nil => rw [List.nil_append, runBlock_nil]; rfl + | cons i is ih => + show (isa.exec i s).bind _ = ((isa.exec i s).bind _).bind _ + cases isa.exec i s with + | none => rfl + | some s' => exact ih s' + +/-- One complete DES S-box contribution, including E/key input extraction, +the Boolean circuit, and P output placement. -/ +theorem box_ok (i : Nat) (hi : i < 8) (s : State) (hok : Ok sboxCfg s) + (hread : ∀ j < 2, InRegions (s.rd ++ s.wr) (wordAddr (s.gpr .r0) j) 4) : + ∃ s', runBlock isa (box i) s = some s' ∧ + s'.gpr .r10 = s.gpr .r10 ^^^ + (boxPiece i (Spec.TripleDes.sBox i + (roundChunk i ((s.gpr .r11).setWidth 32) + ((keyWord s).setWidth 48)))).zeroExtend 32 ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ + (∀ r ∈ roundKept, s'.gpr r = s.gpr r) ∧ + Frame [spillRegion s] s.mem s'.mem := by + obtain ⟨s₁, run₁, chunk, rd₁, wr₁, sp₁, mem₁, keep₁⟩ := roundInput_chunk i hi s hread + have kept₁ : ∀ r ∈ .r10 :: roundKept, s₁.gpr r = s.gpr r := + fun r hr => keep₁ r (roundInput_keep i hi r hr) + have hok₁ : Ok sboxCfg s₁ := hok.congr + (kept₁ .r2 (by decide)) (kept₁ .r2 (by decide)) rd₁ wr₁ + obtain ⟨s₂, run₂, bits, rd₂, wr₂, sp₂, keep₂, _⟩ := sbox_ok i hi hok₁ + have hbits : ∀ j < 4, (s₂.gpr (q j)).getLsbD 0 = + (Spec.TripleDes.sBox i (roundChunk i ((s.gpr .r11).setWidth 32) + ((keyWord s).setWidth 48))).getLsbD j := by + intro j hj + rw [bits j hj 0 (by decide), chunk] + obtain ⟨s₃, run₃, value, rd₃, wr₃, sp₃, mem₃, keep₃⟩ := roundOutput_piece i hi s₂ _ hbits + refine ⟨s₃, ?_, ?_, rd₃.trans (rd₂.trans rd₁), wr₃.trans (wr₂.trans wr₁), sp₃.trans (sp₂.trans sp₁), ?_, ?_⟩ + · simp only [box, runBoxes_append, run₁, Option.bind_some, run₂, run₃] + · rw [value, keep₂ .r10 (by decide), kept₁ .r10 (by decide)] + · intro r hr + rw [keep₃ r (roundOutput_keep i hi r hr), keep₂ r ?_, kept₁ r (List.mem_cons_of_mem _ hr)] + revert hr; cases r <;> decide + · have hf := sbox_spillFrame i hi s₁ s₂ hok₁.slots run₂ + have hregion : spillRegion s₁ = spillRegion s := by + simp only [spillRegion, kept₁ .r2 (by decide)] + rw [hregion, mem₁] at hf + rw [mem₃] + exact hf + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Bytes.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Bytes.lean new file mode 100644 index 000000000..52865cd39 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Bytes.lean @@ -0,0 +1,61 @@ +import VerifiedGarbage.Proof.TripleDes.Bytes +import VerifiedGarbage.Proof.TripleDes.Arm.Permutation +import VerifiedGarbage.Proof.Framework.Arm.Exec + +namespace VG.Proof.TripleDes.Arm +open VG VG.Arm VG.Spec.TripleDes + +theorem decodeBlock_readW (m : Mem) (p : Addr) : + decodeBlock (blockAt m p) = rev (m.readW p 32) ++ rev (m.readW (p + 4) 32) := by + rw [VG.Proof.TripleDes.decodeBlock_cat, rev_readW, rev_readW] + simp only [VG.Proof.TripleDes.catBlock, blockAt, Vector.getElem_ofFn, + BitVec.add_assoc, BitVec.add_zero, + show (1 : Addr) + 1 = 2 from by decide, + show (2 : Addr) + 1 = 3 from by decide, + show (4 : Addr) + 1 = 5 from by decide, + show (5 : Addr) + 1 = 6 from by decide, + show (6 : Addr) + 1 = 7 from by decide] + apply BitVec.eq_of_getLsbD_eq + intro i hi + have ranges : i < 8 ∨ (8 ≤ i ∧ i < 16) ∨ (16 ≤ i ∧ i < 24) ∨ + (24 ≤ i ∧ i < 32) ∨ (32 ≤ i ∧ i < 40) ∨ (40 ≤ i ∧ i < 48) ∨ + (48 ≤ i ∧ i < 56) ∨ 56 ≤ i := by omega + rcases ranges with h | h | h | h | h | h | h | h <;> + simp (disch := omega) only [BitVec.getLsbD_append, ite_eq_left, ite_eq_right, + Nat.sub_sub] <;> rfl + +theorem packed28 (c d : BitVec 28) : + packedInput 56 28 (d.setWidth 32) (c.setWidth 32) = c ++ d := by + simp only [packedInput, BitVec.setWidth_setWidth_of_le _ (by decide : 28 ≤ 32), + BitVec.setWidth_eq] + +theorem byteRev64_byte (x : BitVec 64) (i : Nat) (hi : i < 8) : + (byteRev64 x).extractLsb' (8 * i) 8 = (x >>> (8 * (7 - i))).setWidth 8 := by + have cases8 : ∀ k < 8, k = 0 ∨ k = 1 ∨ k = 2 ∨ k = 3 ∨ + k = 4 ∨ k = 5 ∨ k = 6 ∨ k = 7 := by decide + rcases cases8 i hi with rfl | rfl | rfl | rfl | rfl | rfl | rfl | rfl + all_goals simp (disch := decide) only [byteRev64, extractLsb'_append_byte_hi, + extractLsb'_append_byte_lo, Nat.reduceMul, Nat.reduceSub, + BitVec.setWidth_ushiftRight_eq_extractLsb, BitVec.extractLsb'_eq_self] + +theorem blockAt_writeW (m : Mem) (p : Addr) (x : BitVec 64) : + blockAt (m.writeW p (byteRev64 x)) p = encodeBlock x := by + apply Vector.ext + intro i hi + simp only [blockAt, encodeBlock, Vector.getElem_ofFn, Mem.writeW, Mem.write, + Mem.sub_ofNat_toNat p (by omega : i < 2 ^ 64), BitVec.setWidth_eq, + hi, ite_true] + exact byteRev64_byte x i hi + +theorem revPair (l r : BitVec 32) : rev r ++ rev l = byteRev64 (l ++ r) := by + apply BitVec.eq_of_getLsbD_eq + intro i hi + have ranges : i < 8 ∨ (8 ≤ i ∧ i < 16) ∨ (16 ≤ i ∧ i < 24) ∨ + (24 ≤ i ∧ i < 32) ∨ (32 ≤ i ∧ i < 40) ∨ (40 ≤ i ∧ i < 48) ∨ + (48 ≤ i ∧ i < 56) ∨ 56 ≤ i := by omega + rcases ranges with h | h | h | h | h | h | h | h <;> + simp (disch := omega) only [rev, byteRev64, BitVec.getLsbD_append, + BitVec.getLsbD_extractLsb', ite_eq_left, ite_eq_right, Nat.sub_sub] <;> + congr 2 <;> omega + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/ConstantTime.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/ConstantTime.lean new file mode 100644 index 000000000..cfb1052b7 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/ConstantTime.lean @@ -0,0 +1,45 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.FunctionsLit +import VerifiedGarbage.Proof.Framework.Arm.Taint + +/-! # Constant-time Triple DES block and key-expansion programs -/ + +namespace VG.Proof.TripleDes.Arm + +open VG VG.Arm VG.Impl.TripleDes.Arm + +/-- Only argument pointers and explicitly public integer parameters agree; +all memory contents, including the key, schedule, and data, may differ. -/ +def PublicRegs (rs : List Reg) (s₁ s₂ : State) : Prop := + s₁.sp = s₂.sp ∧ ∀ r ∈ rs, s₁.gpr r = s₂.gpr r + +theorem encryptBlock_constantTime (pre : State → Prop) : + ConstantTime isa pre (PublicRegs [.r0, .r1, .r2]) encryptBlock := by + refine VG.Taint.constantTime (A := taint) (Taint.ofRegs [.r0, .r1, .r2]) ?_ (by taint_decide) + intro s₁ s₂ _ _ hp + exact Taint.agree_ofRegs hp.2 + +theorem decryptBlock_constantTime (pre : State → Prop) : + ConstantTime isa pre (PublicRegs [.r0, .r1, .r2]) decryptBlock := by + refine VG.Taint.constantTime (A := taint) (Taint.ofRegs [.r0, .r1, .r2]) ?_ (by taint_decide) + intro s₁ s₂ _ _ hp + exact Taint.agree_ofRegs hp.2 + +theorem expandKey_constantTime (pre : State → Prop) : + ConstantTime isa pre (PublicRegs [.r0, .r1, .r2, .r3]) Key.expandKey := by + refine VG.Taint.constantTime (A := taint) (Taint.ofRegs [.r0, .r1, .r2, .r3]) ?_ (by taint_decide) + intro s₁ s₂ _ _ hp + exact Taint.agree_ofRegs hp.2 + +theorem ecbEncrypt_constantTime (pre : State → Prop) : + ConstantTime isa pre (PublicRegs [.r0, .r1, .r2, .r3]) Ecb.encrypt := by + refine VG.Taint.constantTime (A := taint) (Taint.ofRegs [.r0, .r1, .r2, .r3]) ?_ (by taint_decide) + intro s₁ s₂ _ _ hp + exact Taint.agree_ofRegs hp.2 + +theorem ecbDecrypt_constantTime (pre : State → Prop) : + ConstantTime isa pre (PublicRegs [.r0, .r1, .r2, .r3]) Ecb.decrypt := by + refine VG.Taint.constantTime (A := taint) (Taint.ofRegs [.r0, .r1, .r2, .r3]) ?_ (by taint_decide) + intro s₁ s₂ _ _ hp + exact Taint.agree_ofRegs hp.2 + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Body.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Body.lean new file mode 100644 index 000000000..8b7d3993f --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Body.lean @@ -0,0 +1,56 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Ecb.Slice +import VerifiedGarbage.Proof.TripleDes.Arm.Ecb.Steps +import VerifiedGarbage.Proof.TripleDes.EcbMemory + +namespace VG.Proof.TripleDes.Arm.Ecb + +open VG VG.Arm VG.Spec.TripleDes + +structure BodyPost (d : Direction) (s : State) (n : Nat) (s' : State) : Prop where + ptr : s'.gpr .r1 = s.gpr .r1 + 8 + count : s'.gpr .r3 = BitVec.ofNat 32 (n - 1) + flag : zeroCount s' = some (decide (n = 1)) + reg : ∀ r ∈ kept, r ≠ .r1 → r ≠ .r3 → s'.gpr r = s.gpr r + callee : ∀ r ∈ savedAcrossCall, r ≠ .r3 → s'.gpr r = s.gpr r + rd : s'.rd = s.rd + wr : s'.wr = s.wr + mem : Frame ([dataR s, ⟨State.addr (s.gpr .r2), 512⟩]) s.mem s'.mem + data : Spec.TripleDes.blockAt s'.mem (State.addr (s.gpr .r1)) = + blockResult (Spec.TripleDes.scheduleAt s.mem (State.addr (s.gpr .r0))) d + (Spec.TripleDes.blockAt s.mem (State.addr (s.gpr .r1))) + +theorem body_ok (d : Direction) (s : State) (n : Nat) (hn : 1 ≤ n) (bound : n < 2 ^ 32) + (count : s.gpr .r3 = BitVec.ofNat 32 n) (hp : StepPre s) : + WP isa (.seq (Impl.TripleDes.Arm.Ecb.blockCall d) (.block Impl.TripleDes.Arm.Ecb.advance)) s (BodyPost d s n) := by + apply WP.seq + apply WP.mono (call_ok d s hp.call) + intro s₁ h₁ + obtain ⟨s₂, run₂, ptr₂, count₂, flag₂, keep₂⟩ := advance_ok s₁ + refine WP.of_runBlock ⟨s₂, run₂, ?_⟩ + have count' : s₁.gpr .r3 - 1 = BitVec.ofNat 32 (n - 1) := by + rw [h₁.reg .r3 (by decide), count] + exact Offset.ofNat_sub_ofNat hn + refine ⟨by rw [ptr₂, h₁.reg .r1 (by decide)], count₂.trans count', ?_, ?_, ?_, + keep₂.rd.trans h₁.rd, keep₂.wr.trans h₁.wr, ?_, ?_⟩ + · rw [flag₂, count'] + rw [counter_zero (n - 1) (by omega)] + have he : n - 1 = 0 ↔ n = 1 := by omega + simp only [he] + · intro r hr hs hb + exact (keep₂.reg r (by simp [hs, hb])).trans (h₁.reg r hr) + · intro r hr hb + have hs : r ≠ .r1 := by + have fact : ∀ r ∈ savedAcrossCall, r ≠ .r1 := by decide + exact fact r hr + exact (keep₂.reg r (by simp [hs, hb])).trans (h₁.callee r hr) + · rw [keep₂.mem]; exact h₁.mem + · rw [keep₂.mem]; exact h₁.output + +theorem BodyPost.tail {d : Direction} {s s' : State} {n : Nat} + (h : BodyPost d s (n + 1) s') (hp : StepPre s (n + 1)) (hn : 1 ≤ n) : StepPre s' n := + hp.slice (i := 1) (by omega) hn h.rd h.wr + (h.reg .r0 (by decide) (by decide) (by decide)) + (h.reg .r2 (by decide) (by decide) (by decide)) + h.ptr + +end VG.Proof.TripleDes.Arm.Ecb diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Call.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Call.lean new file mode 100644 index 000000000..c8d4d387b --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Call.lean @@ -0,0 +1,88 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.VerifiedBlock +import VerifiedGarbage.Impl.TripleDes.Arm.Ecb +import VerifiedGarbage.Proof.Framework.Arm.Call + +namespace VG.Proof.TripleDes.Arm.Ecb +open VG VG.Arm VG.Impl.TripleDes.Arm + +def kept : List Reg := [.r0, .r1, .r2, .r3] +def savedAcrossCall : List Reg := [.r4, .r5, .r6, .r7, .r8, .r9, .r10, .r11] + +def callContract (d : Spec.TripleDes.Direction) : Contract isa := + { blockContract d with + post := fun s s' => (blockContract d).post s s' ∧ ∀ r ∈ kept, s'.gpr r = s.gpr r } + +theorem block_correct' (d : Spec.TripleDes.Direction) (s : State) (hs : (callContract d).pre s) : + ∃ t s', Exec isa (block d) s t s' ∧ abiPreserved s s' ∧ (callContract d).post s s' := by + have hp := headPre_of_contract d s hs + have writes : ∀ t < 2, InRegions s.wr (State.addr (s.gpr .r1 + BitVec.ofNat 32 (4 * t))) 4 := by + intro t ht + have fit := hs.2.2.2.2.2.1 + rw [addr_add (by omega_using [fit, ht]), hs.2.1] + exact ⟨⟨State.addr (s.gpr .r1), 8⟩, by simp, + Offset.contains_base _ (by omega_using [ht]) (by omega_using [ht])⟩ + obtain ⟨t, s', he, post⟩ := block_ok (Spec.TripleDes.scheduleAt s.mem (State.addr (s.gpr .r0))) + (s.gpr .r0) d s hp writes + refine ⟨t, s', he, ⟨?_, post.sp⟩, post.result, ?_⟩ + · intro r hr + have covered : ∀ r ∈ preserved, r ∈ savedRegs := by decide + exact post.saved r (covered r hr) + · intro r hr + simp only [kept, List.mem_cons, List.not_mem_nil, or_false] at hr + rcases hr with rfl | rfl | rfl | rfl + · exact post.pointer + · exact post.regs .r1 (by decide) + · exact post.regs .r2 (by decide) + · exact post.regs .r3 (by decide) + +theorem blockCall_eq (d : Spec.TripleDes.Direction) : Impl.TripleDes.Arm.Ecb.blockCall d = + .call (match d with | .encrypt => "vg_triple_des_encrypt_block" | .decrypt => "vg_triple_des_decrypt_block") + (block d) := by cases d <;> rfl + +structure CallPre (s : State) : Prop where + reads : Covers [⟨State.addr (s.gpr .r0), 384⟩, ⟨State.addr (s.gpr .r1), 8⟩, + ⟨State.addr (s.gpr .r2), 512⟩] (s.rd ++ s.wr) + writes : Covers [⟨State.addr (s.gpr .r1), 8⟩, ⟨State.addr (s.gpr .r2), 512⟩] s.wr + keyScratch : (Region.mk (State.addr (s.gpr .r0)) 384).Disjoint ⟨State.addr (s.gpr .r2), 512⟩ + dataScratch : (Region.mk (State.addr (s.gpr .r1)) 8).Disjoint ⟨State.addr (s.gpr .r2), 512⟩ + keyFit : (s.gpr .r0).toNat + 384 ≤ 2 ^ 32 + dataFit : (s.gpr .r1).toNat + 8 ≤ 2 ^ 32 + scratchFit : (s.gpr .r2).toNat + 512 ≤ 2 ^ 32 + +structure CallPost (d : Spec.TripleDes.Direction) (s s' : State) : Prop where + reg : ∀ r ∈ kept, s'.gpr r = s.gpr r + callee : ∀ r ∈ savedAcrossCall, s'.gpr r = s.gpr r + rd : s'.rd = s.rd + wr : s'.wr = s.wr + mem : Frame [⟨State.addr (s.gpr .r1), 8⟩, ⟨State.addr (s.gpr .r2), 512⟩] s.mem s'.mem + output : Spec.TripleDes.blockAt s'.mem (State.addr (s.gpr .r1)) = + blockResult (Spec.TripleDes.scheduleAt s.mem (State.addr (s.gpr .r0))) d + (Spec.TripleDes.blockAt s.mem (State.addr (s.gpr .r1))) + +theorem call_ok (d : Spec.TripleDes.Direction) (s : State) (hp : CallPre s) : + WP isa (Impl.TripleDes.Arm.Ecb.blockCall d) s (CallPost d s) := by + rw [blockCall_eq] + refine WP.call (k := callContract d) (block_correct' d) + (rd := [⟨State.addr (s.gpr .r0), 384⟩]) + (wr := [⟨State.addr (s.gpr .r1), 8⟩, ⟨State.addr (s.gpr .r2), 512⟩]) + ?_ hp.reads hp.writes ?_ (by cases d <;> rfl) + · simp only [callContract, blockContract, State.withRegions_gpr, State.withRegions_rd, State.withRegions_wr, + State.callEntry_gpr _ (by decide : Reg.r0 ∉ linkRegs), + State.callEntry_gpr _ (by decide : Reg.r1 ∉ linkRegs), State.callEntry_gpr _ (by decide : Reg.r2 ∉ linkRegs)] + exact ⟨trivial, trivial, hp.keyScratch, hp.dataScratch, hp.keyFit, hp.dataFit, hp.scratchFit⟩ + · intro s' rd wr sp frame callee regs out + have sep : ∀ r ∈ kept, r ∉ linkRegs := by decide + have saved : ∀ r ∈ savedAcrossCall, r ∈ preserved ∧ r ≠ .lr := by decide + refine ⟨?_, fun r hr => callee r (saved r hr).1 (saved r hr).2, rd, wr, frame, ?_⟩ + · intro r hr + have h := out.2 r hr + simp only [State.withRegions_gpr, State.callEntry_gpr _ (sep r hr)] at h + exact h + · have h := out.1 + change Spec.TripleDes.blockAt s'.mem _ = blockResult _ d _ at h + simp only [State.withRegions_gpr, State.withRegions_mem, State.callEntry_mem, + State.callEntry_gpr _ (by decide : Reg.r0 ∉ linkRegs), + State.callEntry_gpr _ (by decide : Reg.r1 ∉ linkRegs)] at h + exact h + +end VG.Proof.TripleDes.Arm.Ecb diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Contract.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Contract.lean new file mode 100644 index 000000000..0f8910b6d --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Contract.lean @@ -0,0 +1,24 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Ecb.IO +import VerifiedGarbage.Proof.Framework.Contract +import VerifiedGarbage.Spec.TripleDes.Contract + +namespace VG.Proof.TripleDes.Arm.Ecb + +open VG VG.Arm + +def contract (d : Spec.TripleDes.Direction) : Contract isa where + pre s := + let key : Region := ⟨State.addr (s.gpr .r0), 384⟩ + let data : Region := ⟨State.addr (s.gpr .r1), 8 * (s.gpr .r2).toNat⟩ + let buf : Region := ⟨State.addr (s.gpr .r3), 1024⟩ + s.rd = [key] ∧ s.wr = [data, buf] ∧ key.Disjoint data ∧ key.Disjoint buf ∧ + data.Disjoint buf ∧ + (s.gpr .r1).toNat + 8 * (s.gpr .r2).toNat ≤ 2 ^ 32 ∧ (s.gpr .r0).toNat + 384 ≤ 2 ^ 32 ∧ + (s.gpr .r3).toNat + 1024 ≤ 2 ^ 32 + post s s' := + Spec.TripleDes.blocksAt s'.mem (State.addr (s.gpr .r1)) (s.gpr .r2).toNat = + Spec.TripleDes.ecb (Spec.TripleDes.scheduleAt s.mem (State.addr (s.gpr .r0))) d + (Spec.TripleDes.blocksAt s.mem (State.addr (s.gpr .r1)) (s.gpr .r2).toNat) + pub := PublicRegs [.r0, .r1, .r2, .r3] + +end VG.Proof.TripleDes.Arm.Ecb diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Correct.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Correct.lean new file mode 100644 index 000000000..b2abd7e52 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Correct.lean @@ -0,0 +1,83 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Ecb.Contract + +namespace VG.Proof.TripleDes.Arm.Ecb +open VG VG.Arm + +theorem ecb_correct (d : Spec.TripleDes.Direction) (s : State) (hs : (contract d).pre s) : + WP isa (Impl.TripleDes.Arm.Ecb.ecb d) s + (fun s' => (∀ r ∈ preserved, s'.gpr r = s.gpr r) ∧ (contract d).post s s') := by + obtain ⟨hrd, hwr, keyData, keyBuf, dataBuf, fit, keyFit, bufFit⟩ := hs + have writes (i : Nat) (hi : i + 4 ≤ 1024) : + InRegions s.wr (State.addr (s.gpr .r3) + BitVec.ofNat 64 i) 4 := by + rw [hwr] + exact ⟨⟨State.addr (s.gpr .r3), 1024⟩, by simp, Offset.contains_base _ hi (by omega)⟩ + rw [Impl.TripleDes.Arm.Ecb.ecb] + apply WP.seq + rw [WP.block_append_iff] + obtain ⟨s₁, run₁, keep₁⟩ := save_ok s bufFit (writes 512 (by decide)) + refine WP.of_runBlock ⟨s₁, run₁, ?_⟩ + obtain ⟨s₂, run₂, count₂, buf₂, flag₂, keep₂⟩ := setup_ok s₁ + refine WP.of_runBlock ⟨s₂, run₂, ?_⟩ + have g₁ (r : Reg) : s₁.gpr r = s.gpr r := keep₁.reg r (by simp) + rw [g₁] at count₂ buf₂ flag₂ + have key₂ := (keep₂.reg .r0 (by decide)).trans (g₁ .r0) + have data₂ := (keep₂.reg .r1 (by decide)).trans (g₁ .r1) + have rd₂ := keep₂.rd.trans keep₁.rd + have wr₂ := keep₂.wr.trans keep₁.wr + have mem₂ : s₂.mem = savedMem s := keep₂.mem.trans keep₁.mem + have scratchFrame : Frame [⟨State.addr (s.gpr .r3), 1024⟩] s.mem s₂.mem := by + rw [mem₂]; exact savedMem_frame s + have initialKey := VG.Proof.TripleDes.scheduleAt_eq_of_frame (State.addr (s.gpr .r0)) scratchFrame + (by simpa using keyBuf) + have initialData := VG.Proof.TripleDes.blocksAt_frame scratchFrame (State.addr (s.gpr .r1)) (s.gpr .r2).toNat + (by simpa using dataBuf) + have hp₂ : StepPre s₂ (s.gpr .r2).toNat := by + constructor + · simp only [keyR, dataR, bufR, key₂, data₂, buf₂, rd₂, wr₂, hrd, hwr] + exact fun _ _ h => h + · simp only [dataR, bufR, data₂, buf₂, wr₂, hwr] + exact fun _ _ h => h + · simpa only [keyR, dataR, key₂, data₂] using keyData + · simpa only [keyR, bufR, key₂, buf₂] using keyBuf + · simpa only [dataR, bufR, data₂, buf₂] using dataBuf + · rw [key₂]; exact keyFit + · rw [data₂]; exact fit + · rw [buf₂]; exact bufFit + have flag : zeroCount s₂ = some (decide ((s.gpr .r2).toNat = 0)) := by + have hz := counter_zero (s.gpr .r2).toNat (s.gpr .r2).isLt + simp only [BitVec.ofNat_toNat, BitVec.setWidth_eq] at hz + exact flag₂.trans (congrArg some hz) + apply WP.seq + apply WP.mono (maybeLoop_ok d s₂ (s.gpr .r2).toNat (by omega_using [fit]) hp₂ + (by simpa only [BitVec.ofNat_toNat, BitVec.setWidth_eq] using count₂) flag) + intro s₃ h₃ + have rd₃ := h₃.rd.trans rd₂ + have wr₃ := h₃.wr.trans wr₂ + have buf₃ := (h₃.reg .r2 (by decide) (by decide) (by decide)).trans buf₂ + have readable : InRegions (s₃.rd ++ s₃.wr) + (State.addr (s₃.gpr .r2) + BitVec.ofNat 64 512) 4 := by + rw [rd₃, wr₃, buf₃] + obtain ⟨r, hr, hc⟩ := writes 512 (by decide) + exact ⟨r, List.mem_append_right _ hr, hc⟩ + have link : s₃.mem.readW (State.addr (s₃.gpr .r2) + BitVec.ofNat 64 512) 32 = s.gpr .lr := by + have h := h₃.scratchRead hp₂ 512 (by decide) + rw [buf₂, mem₂, savedMem_link] at h + rw [buf₃]; exact h + obtain ⟨s₄, run₄, link₄, keep₄⟩ := restore_ok s₃ (s.gpr .lr) + (by rw [buf₃]; exact bufFit) readable link + refine WP.of_runBlock ⟨s₄, run₄, ?_⟩ + constructor + · intro r hr + by_cases hl : r = .lr + · subst r; exact link₄ + have saved : ∀ r ∈ preserved, r ≠ .lr → r ∈ savedAcrossCall ∧ r ≠ .r3 := by decide + rw [keep₄.reg r (by simpa only [List.mem_singleton] using hl), + h₃.callee r (saved r hr hl).1 (saved r hr hl).2] + have sep : ∀ r ∈ preserved, r ≠ .lr → r ∉ [.r12, .r3, .r2] := by decide + exact (keep₂.reg r (sep r hr hl)).trans (g₁ r) + · have out := h₃.data + rw [key₂, data₂, initialKey, initialData] at out + change Spec.TripleDes.blocksAt s₄.mem (State.addr (s.gpr .r1)) (s.gpr .r2).toNat = _ + rw [keep₄.mem]; exact out + +end VG.Proof.TripleDes.Arm.Ecb diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/IO.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/IO.lean new file mode 100644 index 000000000..936743af5 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/IO.lean @@ -0,0 +1,75 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Ecb.Loop + +namespace VG.Proof.TripleDes.Arm.Ecb +open VG VG.Arm VG.Arm.RegUpd VG.Impl.TripleDes.Arm +open VG.Proof.Rc2.Arm (Keep gpr_subFlags mem_subFlags rd_subFlags wr_subFlags) + +def savedMem (s : State) : Mem := + s.mem.writeW (State.addr (s.gpr .r3) + BitVec.ofNat 64 512) (s.gpr .lr) + +theorem save_ok (s : State) (fit : (s.gpr .r3).toNat + 1024 ≤ 2 ^ 32) + (hw : InRegions s.wr (State.addr (s.gpr .r3) + BitVec.ofNat 64 512) 4) : + ∃ s', runBlock isa Impl.TripleDes.Arm.Ecb.save s = some s' ∧ Keep [] {s with mem := savedMem s} s' := by + refine ⟨_, by + simp only [Impl.TripleDes.Arm.Ecb.save, runBlock_cons, runStep_some, runBlock_nil, + exec, show (512 : Nat) < 4096 from by decide, ite_true, State.store32, + addr_add (a := s.gpr .r3) (k := 512) (by omega_using [fit]), hw] + rfl, ?_⟩ + exact ⟨fun _ _ => rfl, rfl, rfl, rfl⟩ + +theorem savedMem_frame (s : State) : Frame [⟨State.addr (s.gpr .r3), 1024⟩] s.mem (savedMem s) := + (Frame.refl _ _).writeW List.mem_cons_self _ + (Offset.contains_base _ (by decide : 512 + 4 ≤ 1024) (by decide)) + +theorem savedMem_link (s : State) : + (savedMem s).readW (State.addr (s.gpr .r3) + BitVec.ofNat 64 512) 32 = s.gpr .lr := by + rw [savedMem, Mem.readW_writeW_self32] + +theorem setup_ok (s : State) : + ∃ s', runBlock isa Impl.TripleDes.Arm.Ecb.setup s = some s' ∧ + s'.gpr .r3 = s.gpr .r2 ∧ s'.gpr .r2 = s.gpr .r3 ∧ + zeroCount s' = some (s.gpr .r2 == 0) ∧ Keep [.r12, .r3, .r2] s s' := by + refine ⟨_, by + simp (config := {decide := true}) only [Impl.TripleDes.Arm.Ecb.setup, rr, + runBlock_cons, runStep_some, runBlock_nil, exec, Op2.eval, ite_true, + Option.map_some, gpr_setReg, ite_false] + rfl, ?_, ?_, ?_, ?_⟩ + · simp only [gpr_subFlags, gpr_setReg, reduceCtorEq, ite_false, ite_true] + · simp only [gpr_subFlags, gpr_setReg, reduceCtorEq, ite_false, ite_true] + · change some (s.gpr .r2 - 0 == 0) = _ + exact congrArg (fun v : BitVec 32 => some (v == 0)) (by bv_omega) + · refine ⟨?_, ?_, ?_, ?_⟩ + · intro r hr + simp only [List.mem_cons, List.not_mem_nil, or_false, not_or] at hr + simp only [gpr_subFlags, gpr_setReg, hr.1, hr.2.1, hr.2.2, ite_false] + · simp only [mem_subFlags, mem_setReg] + · simp only [rd_subFlags, rd_setReg] + · simp only [wr_subFlags, wr_setReg] + +theorem restore_ok (s : State) (lr : BitVec 32) + (fit : (s.gpr .r2).toNat + 1024 ≤ 2 ^ 32) + (hr : InRegions (s.rd ++ s.wr) (State.addr (s.gpr .r2) + BitVec.ofNat 64 512) 4) + (hv : s.mem.readW (State.addr (s.gpr .r2) + BitVec.ofNat 64 512) 32 = lr) : + ∃ s', runBlock isa Impl.TripleDes.Arm.Ecb.restore s = some s' ∧ + s'.gpr .lr = lr ∧ Keep [.lr] s s' := by + refine ⟨_, by + simp only [Impl.TripleDes.Arm.Ecb.restore, runBlock_cons, runStep_some, runBlock_nil, + exec, show (512 : Nat) < 4096 from by decide, ite_true, State.load32, + addr_add (a := s.gpr .r2) (k := 512) (by omega_using [fit]), hr, Option.map_some, hv] + rfl, gpr_setReg_self _ _ _, ?_⟩ + exact ⟨fun r h => gpr_setReg_of_ne _ _ (by simpa only [List.mem_singleton] using h), rfl, rfl, rfl⟩ + +theorem LoopPost.scratchRead {d : Spec.TripleDes.Direction} {s s' : State} {n : Nat} + (h : LoopPost d s n s') (hp : StepPre s n) (i : Nat) (hi : 512 ≤ i ∧ i + 4 ≤ 1024) : + s'.mem.readW (State.addr (s.gpr .r2) + BitVec.ofNat 64 i) 32 = + s.mem.readW (State.addr (s.gpr .r2) + BitVec.ofNat 64 i) 32 := by + have sub : Region.Sub ⟨State.addr (s.gpr .r2) + BitVec.ofNat 64 i, 4⟩ (bufR s) := + Offset.sub_base _ hi.2 + have sep : (Region.mk (State.addr (s.gpr .r2) + BitVec.ofNat 64 i) 4).Disjoint + ⟨State.addr (s.gpr .r2), 512⟩ := Offset.disjoint_base _ (by omega) (by omega) + apply h.mem.readW (r := ⟨State.addr (s.gpr .r2) + BitVec.ofNat 64 i, 4⟩) (Region.contains_self _ _) + (hn := by decide) + simpa only [loopWrites, List.mem_cons, List.not_mem_nil, or_false, forall_eq_or_imp, forall_eq] using + And.intro ((hp.dataBuf.sub_right sub).symm) sep + +end VG.Proof.TripleDes.Arm.Ecb diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Loop.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Loop.lean new file mode 100644 index 000000000..a7bc66ce5 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Loop.lean @@ -0,0 +1,92 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Ecb.LoopFrame + +/-! # Correctness of the ECB loop on complete blocks -/ + +namespace VG.Proof.TripleDes.Arm.Ecb + +open VG VG.Arm +open VG.Proof.TripleDes (blocksAt_cons) + +structure LoopPost (d : Spec.TripleDes.Direction) (s : State) (n : Nat) (s' : State) : Prop where + ptr : s'.gpr .r1 = s.gpr .r1 + BitVec.ofNat 32 (8 * n) + count : s'.gpr .r3 = 0 + reg : ∀ r ∈ kept, r ≠ .r1 → r ≠ .r3 → s'.gpr r = s.gpr r + callee : ∀ r ∈ savedAcrossCall, r ≠ .r3 → s'.gpr r = s.gpr r + rd : s'.rd = s.rd + wr : s'.wr = s.wr + mem : Frame (loopWrites s n) s.mem s'.mem + data : Spec.TripleDes.blocksAt s'.mem (State.addr (s.gpr .r1)) n = + Spec.TripleDes.ecb (Spec.TripleDes.scheduleAt s.mem (State.addr (s.gpr .r0))) d + (Spec.TripleDes.blocksAt s.mem (State.addr (s.gpr .r1)) n) + +theorem ecb_cons (keys : Spec.TripleDes.Schedule) (d : Spec.TripleDes.Direction) + (b : Spec.TripleDes.Block) (bs : List Spec.TripleDes.Block) : + Spec.TripleDes.ecb keys d (b :: bs) = blockResult keys d b :: Spec.TripleDes.ecb keys d bs := by + cases d <;> rfl + +theorem loop_ok (d : Spec.TripleDes.Direction) (n : Nat) : + ∀ s : State, 1 ≤ n → 8 * n ≤ 2 ^ 32 → StepPre s n → s.gpr .r3 = BitVec.ofNat 32 n → + WP isa (.loop (.seq (Impl.TripleDes.Arm.Ecb.blockCall d) (.block Impl.TripleDes.Arm.Ecb.advance)) .ne) s (LoopPost d s n) := by + induction n with + | zero => intro s hn; omega + | succ n ih => + intro s hn bound hp count + obtain ⟨t₁, s₁, exec₁, h₁⟩ := body_ok d s (n + 1) hn (by omega) count (hp.head hn) + by_cases hz : n = 0 + · subst n + refine ⟨_, s₁, Exec.loopExit exec₁ ?_, ?_⟩ + · simp only [eval_nonzeroCount, h₁.flag, decide_true, Option.map_some, Bool.not_true] + · refine ⟨h₁.ptr, h₁.count, h₁.reg, h₁.callee, h₁.rd, h₁.wr, h₁.frame (by decide), ?_⟩ + · rw [blocksAt_cons, blocksAt_cons, ecb_cons] + simp only [Spec.TripleDes.blocksAt, List.range_zero, List.map_nil, + Spec.TripleDes.ecb, List.map_nil] + exact congrArg (· :: []) h₁.data + · have hp₁ := h₁.tail hp (by omega) + obtain ⟨t₂, s₂, exec₂, h₂⟩ := ih s₁ (by omega) (by omega) hp₁ (by simpa using h₁.count) + refine ⟨_, s₂, Exec.loopNext exec₁ ?_ exec₂, ?_⟩ + · have he : n + 1 ≠ 1 := by omega + simp only [eval_nonzeroCount, h₁.flag, he, decide_false, Option.map_some, Bool.not_false] + · have key := h₁.schedule (hp.head hn) + have tail := h₁.tailData hp (by omega_using [bound]) + have data := h₂.data + have ki := h₁.reg .r0 (by decide) (by decide) (by decide) + have bi := h₁.reg .r2 (by decide) (by decide) (by decide) + have ptrAddr : State.addr (s₁.gpr .r1) = State.addr (s.gpr .r1) + 8 := by + rw [h₁.ptr] + exact addr_add (k := 8) (by omega_using [hp.dataFit, hz]) + rw [ki, ptrAddr, key, tail] at data + refine ⟨?_, h₂.count, ?_, ?_, h₂.rd.trans h₁.rd, h₂.wr.trans h₁.wr, ?_, ?_⟩ + · rw [h₂.ptr, h₁.ptr, BitVec.add_assoc] + exact congrArg (s.gpr .r1 + ·) (by + change BitVec.ofNat 32 8 + BitVec.ofNat 32 (8 * n) = _ + rw [← BitVec.ofNat_add] + exact congrArg (BitVec.ofNat 32) (by omega)) + · intro r hr hs hb + exact (h₂.reg r hr hs hb).trans (h₁.reg r hr hs hb) + · intro r hr hb + exact (h₂.callee r hr hb).trans (h₁.callee r hr hb) + · exact (h₁.frame hn).trans (loopFrame_slice (i := 1) h₂.mem (by omega) (by omega_using [hp.dataFit, hz]) bi h₁.ptr) + · have first := firstBlock_frame h₁ hp (by omega_using [bound]) h₂.mem (by omega) + rw [blocksAt_cons, first, h₁.data, data, blocksAt_cons, ecb_cons] + +theorem maybeLoop_ok (d : Spec.TripleDes.Direction) (s : State) (n : Nat) (bound : 8 * n ≤ 2 ^ 32) + (hp : StepPre s n) (count : s.gpr .r3 = BitVec.ofNat 32 n) + (initialFlag : zeroCount s = some (decide (n = 0))) + : + WP isa (.ite .eq (.block []) (.loop (.seq (Impl.TripleDes.Arm.Ecb.blockCall d) (.block Impl.TripleDes.Arm.Ecb.advance)) .ne)) s (LoopPost d s n) := by + have flag' := initialFlag + by_cases hz : n = 0 + · subst n + apply WP.ite true (by simp only [eval_zeroCount, flag', decide_true]) + · intro _ + apply WP.block_nil + refine ⟨by simp, count, fun _ _ _ _ => rfl, fun _ _ _ => rfl, rfl, rfl, Frame.refl _ _, ?_⟩ + · rfl + · simp + · apply WP.ite false (by simp only [eval_zeroCount, flag', hz, decide_false]) + · simp + · intro _ + exact loop_ok d n s (by omega) bound hp count + + +end VG.Proof.TripleDes.Arm.Ecb diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/LoopFrame.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/LoopFrame.lean new file mode 100644 index 000000000..581f6fec2 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/LoopFrame.lean @@ -0,0 +1,70 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Ecb.Body + +/-! # Frames for successive ECB blocks -/ + +namespace VG.Proof.TripleDes.Arm.Ecb + +open VG VG.Arm + +def stepWrites (s : State) : List Region := [dataR s, ⟨State.addr (s.gpr .r2), 512⟩] + +def loopWrites (s : State) (n : Nat) : List Region := [dataR s n, ⟨State.addr (s.gpr .r2), 512⟩] + +theorem loopFrame_slice {s s' : State} {n m i : Nat} {a b : Mem} + (h : Frame (loopWrites s' m) a b) (bound : i + m ≤ n) (fit : (s.gpr .r1).toNat + 8 * i < 2 ^ 32) + (buf : s'.gpr .r2 = s.gpr .r2) + (ptr : s'.gpr .r1 = s.gpr .r1 + BitVec.ofNat 32 (8 * i)) : + Frame (loopWrites s n) a b := by + apply h.sub + intro r hr + simp only [loopWrites, List.mem_cons, List.not_mem_nil, or_false] at hr + rcases hr with rfl | rfl + · refine ⟨dataR s n, by simp [loopWrites], ?_⟩ + change Region.Sub ⟨State.addr (s'.gpr .r1), 8 * m⟩ ⟨State.addr (s.gpr .r1), 8 * n⟩ + rw [ptr, addr_add fit] + exact Offset.sub_base _ (by omega) + · refine ⟨⟨State.addr (s.gpr .r2), 512⟩, by simp [loopWrites], ?_⟩ + rw [buf]; exact fun _ h => h + +theorem BodyPost.frame {d : Spec.TripleDes.Direction} {s s' : State} {n : Nat} + (h : BodyPost d s n s') (hn : 1 ≤ n) : Frame (loopWrites s n) s.mem s'.mem := + loopFrame_slice (m := 1) (i := 0) h.mem hn (s.gpr .r1).isLt rfl (by simp) + +theorem BodyPost.schedule {d : Spec.TripleDes.Direction} {s s' : State} {n : Nat} + (h : BodyPost d s n s') (hp : StepPre s) : + Spec.TripleDes.scheduleAt s'.mem (State.addr (s.gpr .r0)) = Spec.TripleDes.scheduleAt s.mem (State.addr (s.gpr .r0)) := by + apply VG.Proof.TripleDes.scheduleAt_eq_of_frame _ h.mem + simpa only [stepWrites, List.mem_cons, List.not_mem_nil, or_false, forall_eq_or_imp, forall_eq] using + And.intro hp.keyData + (hp.keyBuf.sub_right (Region.sub_prefix (by decide : 512 ≤ 1024))) + +theorem BodyPost.tailData {d : Spec.TripleDes.Direction} {s s' : State} {n : Nat} + (h : BodyPost d s (n + 1) s') (hp : StepPre s (n + 1)) (bound : 8 * (n + 1) ≤ 2 ^ 64) : + Spec.TripleDes.blocksAt s'.mem (State.addr (s.gpr .r1) + 8) n = Spec.TripleDes.blocksAt s.mem (State.addr (s.gpr .r1) + 8) n := by + have sub : Region.Sub ⟨State.addr (s.gpr .r1) + 8, 8 * n⟩ (dataR s (n + 1)) := + Offset.sub_base _ (by change 8 + 8 * n ≤ 8 * (n + 1); omega) + have sep : (Region.mk (State.addr (s.gpr .r1) + 8) (8 * n)).Disjoint (dataR s) := + Offset.disjoint_base _ (d := 8) (n := 8 * n) (k := 8) (by decide) (by omega) + apply VG.Proof.TripleDes.blocksAt_frame h.mem + simpa only [stepWrites, List.mem_cons, List.not_mem_nil, or_false, forall_eq_or_imp, forall_eq] using + And.intro sep + ((hp.dataBuf.sub_left sub).sub_right (Region.sub_prefix (by decide : 512 ≤ 1024))) + +theorem firstBlock_frame {d : Spec.TripleDes.Direction} {s s' : State} {n : Nat} {m : Mem} + (h : BodyPost d s (n + 1) s') (hp : StepPre s (n + 1)) (bound : 8 * (n + 1) ≤ 2 ^ 64) + (frame : Frame (loopWrites s' n) s'.mem m) (hn : 1 ≤ n) : + Spec.TripleDes.blockAt m (State.addr (s.gpr .r1)) = Spec.TripleDes.blockAt s'.mem (State.addr (s.gpr .r1)) := by + have first : Region.Sub (dataR s) (dataR s (n + 1)) := Region.sub_prefix (by change 8 ≤ 8 * (n + 1); omega) + have sep : (dataR s).Disjoint ⟨State.addr (s.gpr .r1) + 8, 8 * n⟩ := + Offset.base_disjoint _ (e := 8) (n := 8 * n) (k := 8) (by decide) (by omega) + apply VG.Proof.TripleDes.blockAt_eq_of_frame _ frame + have buf := h.reg .r2 (by decide) (by decide) (by decide) + have ptrAddr : State.addr (s'.gpr .r1) = State.addr (s.gpr .r1) + 8 := by + rw [h.ptr] + exact addr_add (k := 8) (by omega_using [hp.dataFit, hn]) + simpa only [loopWrites, dataR, buf, ptrAddr, + List.mem_cons, List.not_mem_nil, or_false, forall_eq_or_imp, forall_eq] using + And.intro sep + ((hp.dataBuf.sub_left first).sub_right (Region.sub_prefix (by decide : 512 ≤ 1024))) + +end VG.Proof.TripleDes.Arm.Ecb diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Pre.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Pre.lean new file mode 100644 index 000000000..123f4e1d0 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Pre.lean @@ -0,0 +1,65 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Ecb.Call + +/-! # Permissions and separation for one ECB step -/ + +namespace VG.Proof.TripleDes.Arm.Ecb + +open VG VG.Arm + +abbrev keyR (s : State) : Region := ⟨State.addr (s.gpr .r0), 384⟩ +abbrev dataR (s : State) (n : Nat := 1) : Region := ⟨State.addr (s.gpr .r1), 8 * n⟩ +abbrev bufR (s : State) : Region := ⟨State.addr (s.gpr .r2), 1024⟩ + +structure StepPre (s : State) (n : Nat := 1) : Prop where + reads : Covers [keyR s, dataR s n, bufR s] (s.rd ++ s.wr) + writes : Covers [dataR s n, bufR s] s.wr + keyData : (keyR s).Disjoint (dataR s n) + keyBuf : (keyR s).Disjoint (bufR s) + dataBuf : (dataR s n).Disjoint (bufR s) + keyFit : (s.gpr .r0).toNat + 384 ≤ 2 ^ 32 + dataFit : (s.gpr .r1).toNat + 8 * n ≤ 2 ^ 32 + bufFit : (s.gpr .r2).toNat + 1024 ≤ 2 ^ 32 + +theorem StepPre.transport {s s' : State} {n : Nat} (hp : StepPre s n) + (rd : s'.rd = s.rd) (wr : s'.wr = s.wr) (regs : ∀ r ∈ kept, s'.gpr r = s.gpr r) : StepPre s' n := by + have a := regs .r0 (by decide) + have c := regs .r1 (by decide) + have d := regs .r2 (by decide) + constructor + · simpa only [keyR, dataR, bufR, rd, wr, a, c, d] using hp.reads + · simpa only [keyR, dataR, bufR, rd, wr, a, c, d] using hp.writes + · simpa only [keyR, dataR, bufR, rd, wr, a, c, d] using hp.keyData + · simpa only [keyR, dataR, bufR, rd, wr, a, c, d] using hp.keyBuf + · simpa only [keyR, dataR, bufR, rd, wr, a, c, d] using hp.dataBuf + · simpa only [a] using hp.keyFit + · simpa only [c] using hp.dataFit + · simpa only [d] using hp.bufFit + +theorem StepPre.call {s : State} (hp : StepPre s) : CallPre s := by + constructor + · have hc : Covers [⟨State.addr (s.gpr .r0), 384⟩, ⟨State.addr (s.gpr .r1), 8⟩, ⟨State.addr (s.gpr .r2), 512⟩] + [keyR s, dataR s, bufR s] := by + apply Covers.of_sub + intro r hr + simp only [List.mem_cons, List.not_mem_nil, or_false] at hr + rcases hr with rfl | rfl | rfl + · exact ⟨keyR s, by simp, 0, by simp, by simp⟩ + · exact ⟨dataR s, by simp, 0, by simp, by simp⟩ + · exact ⟨bufR s, by simp, 0, by simp, by simp⟩ + exact fun a n h => hp.reads a n (hc a n h) + · have hc : Covers [⟨State.addr (s.gpr .r1), 8⟩, ⟨State.addr (s.gpr .r2), 512⟩] [dataR s, bufR s] := by + apply Covers.of_sub + intro r hr + simp only [List.mem_cons, List.not_mem_nil, or_false] at hr + rcases hr with rfl | rfl + · exact ⟨dataR s, by simp, 0, by simp, by simp⟩ + · exact ⟨bufR s, by simp, 0, by simp, by simp⟩ + exact fun a n h => hp.writes a n (hc a n h) + · exact hp.keyBuf.sub_right (Region.sub_prefix (by decide)) + · exact hp.dataBuf.sub_right (Region.sub_prefix (by decide)) + · exact hp.keyFit + · exact hp.dataFit + · omega_using [hp.bufFit] + + +end VG.Proof.TripleDes.Arm.Ecb diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Slice.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Slice.lean new file mode 100644 index 000000000..85f0b7f77 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Slice.lean @@ -0,0 +1,54 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Ecb.Pre + +/-! # Restricting ECB permissions to a consecutive subrange -/ + +namespace VG.Proof.TripleDes.Arm.Ecb + +open VG VG.Arm + +theorem StepPre.slice {s s' : State} {n m i : Nat} (hp : StepPre s n) (bound : i + m ≤ n) (hm : 1 ≤ m) + (rd : s'.rd = s.rd) (wr : s'.wr = s.wr) + (key : s'.gpr .r0 = s.gpr .r0) + (buf : s'.gpr .r2 = s.gpr .r2) + (ptr : s'.gpr .r1 = s.gpr .r1 + BitVec.ofNat 32 (8 * i)) : StepPre s' m := by + have fit : (s.gpr .r1).toNat + 8 * i < 2 ^ 32 := by omega_using [hp.dataFit, bound, hm] + have ptrAddr : State.addr (s'.gpr .r1) = State.addr (s.gpr .r1) + BitVec.ofNat 64 (8 * i) := by + rw [ptr, addr_add fit] + have sub : Region.Sub (dataR s' m) (dataR s n) := by + change Region.Sub ⟨State.addr (s'.gpr .r1), 8 * m⟩ ⟨State.addr (s.gpr .r1), 8 * n⟩ + rw [ptrAddr] + exact Offset.sub_base _ (by omega) + constructor + · have hc : Covers [keyR s', dataR s' m, bufR s'] [keyR s, dataR s n, bufR s] := by + apply Covers.of_sub + intro r hr + simp only [List.mem_cons, List.not_mem_nil, or_false] at hr + rcases hr with rfl | rfl | rfl + · exact ⟨keyR s, by simp, 0, by simp [key], by simp⟩ + · exact ⟨dataR s n, by simp, 8 * i, ptrAddr, by change 8 * i + 8 * m ≤ 8 * n; omega⟩ + · exact ⟨bufR s, by simp, 0, by simp [buf], by simp⟩ + rw [rd, wr] + exact fun a k h => hp.reads a k (hc a k h) + · have hc : Covers [dataR s' m, bufR s'] [dataR s n, bufR s] := by + apply Covers.of_sub + intro r hr + simp only [List.mem_cons, List.not_mem_nil, or_false] at hr + rcases hr with rfl | rfl + · exact ⟨dataR s n, by simp, 8 * i, ptrAddr, by change 8 * i + 8 * m ≤ 8 * n; omega⟩ + · exact ⟨bufR s, by simp, 0, by simp [buf], by simp⟩ + rw [wr] + exact fun a k h => hp.writes a k (hc a k h) + · simpa only [keyR, key] using hp.keyData.sub_right sub + · simpa only [keyR, bufR, key, buf] using hp.keyBuf + · simpa only [bufR, buf] using hp.dataBuf.sub_left sub + · rw [key]; exact hp.keyFit + · rw [ptr] + simp only [BitVec.toNat_add, BitVec.toNat_ofNat] + rw [Nat.mod_eq_of_lt (by omega_using [fit] : 8 * i < 2 ^ 32), Nat.mod_eq_of_lt fit] + omega_using [hp.dataFit, bound] + · rw [buf]; exact hp.bufFit + +theorem StepPre.head {s : State} {n : Nat} (hp : StepPre s n) (hn : 1 ≤ n) : StepPre s := + hp.slice (i := 0) hn (by decide) rfl rfl rfl rfl (by simp) + +end VG.Proof.TripleDes.Arm.Ecb diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Steps.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Steps.lean new file mode 100644 index 000000000..f84c3ae4c --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Steps.lean @@ -0,0 +1,45 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Ecb.Call +import VerifiedGarbage.Proof.TripleDes.EcbMemory +import VerifiedGarbage.Proof.Rc2.Arm.KeySteps + +namespace VG.Proof.TripleDes.Arm.Ecb +open VG VG.Arm VG.Arm.RegUpd VG.Impl.TripleDes.Arm +open VG.Proof.Rc2.Arm (Keep gpr_subFlags mem_subFlags rd_subFlags wr_subFlags) + +def zeroCount (s : State) : Option Bool := some s.z + +theorem eval_zeroCount (s : State) : eval .eq s = zeroCount s := rfl +theorem eval_nonzeroCount (s : State) : eval .ne s = (zeroCount s).map (! ·) := rfl + +theorem advance_ok (s : State) : + ∃ s', runBlock isa Impl.TripleDes.Arm.Ecb.advance s = some s' ∧ + s'.gpr .r1 = s.gpr .r1 + 8 ∧ s'.gpr .r3 = s.gpr .r3 - 1 ∧ + zeroCount s' = some ((s.gpr .r3 - 1) == 0) ∧ Keep [.r1, .r3] s s' := by + refine ⟨_, by + simp (config := {decide := true}) only [Impl.TripleDes.Arm.Ecb.advance, + runBlock_cons, runStep_some, runBlock_nil, exec, Op2.eval, ite_true, Option.map_some, + gpr_setReg, ite_false] + rfl, ?_, ?_, ?_, ?_⟩ + · simp only [gpr_subFlags, gpr_setReg, reduceCtorEq, ite_false, ite_true] + · simp only [gpr_subFlags, gpr_setReg, reduceCtorEq, ite_false, ite_true] + · rfl + · refine ⟨?_, ?_, ?_, ?_⟩ + · intro r hr + simp only [List.mem_cons, List.not_mem_nil, or_false, not_or] at hr + simp only [gpr_subFlags, gpr_setReg, hr.1, hr.2, ite_false] + · simp only [mem_subFlags, mem_setReg] + · simp only [rd_subFlags, rd_setReg] + · simp only [wr_subFlags, wr_setReg] + +theorem counter_zero (n : Nat) (hn : n < 2 ^ 32) : + ((BitVec.ofNat 32 n) == (0 : BitVec 32)) = decide (n = 0) := by + apply Bool.eq_iff_iff.mpr + simp only [beq_iff_eq, decide_eq_true_eq] + constructor + · intro h + have ht := congrArg BitVec.toNat h + simp only [BitVec.toNat_ofNat, Nat.mod_eq_of_lt hn] at ht + exact ht + · intro h; rw [h]; rfl + +end VG.Proof.TripleDes.Arm.Ecb diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Verified.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Verified.lean new file mode 100644 index 000000000..4877986c7 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ecb/Verified.lean @@ -0,0 +1,52 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Ecb.Correct + +namespace VG.Proof.TripleDes.Arm.Ecb + +open VG VG.Arm + +def satState : State where + gpr r := match r with + | .r0 => 0x1000 | .r1 => 0x2000 | .r3 => 0x3000 | _ => 0 + sp := 0x4000 + n := false + z := false + c := false + v := false + mem _ := 0 + rd := [⟨0x1000, 384⟩] + wr := [⟨0x2000, 0⟩, ⟨0x3000, 1024⟩] + +theorem encrypt_correct (s : State) (hs : (contract .encrypt).pre s) : + ∃ t s', Exec isa Impl.TripleDes.Arm.Ecb.encrypt s t s' ∧ abiPreserved s s' ∧ + (contract .encrypt).post s s' := by + obtain ⟨t, s', he, ha, hp⟩ := ecb_correct .encrypt s hs + change Exec isa Impl.TripleDes.Arm.Ecb.encrypt s t s' at he + exact ⟨t, s', he, ⟨ha, VG.Arm.Exec.sp he⟩, hp⟩ + +theorem decrypt_correct (s : State) (hs : (contract .decrypt).pre s) : + ∃ t s', Exec isa Impl.TripleDes.Arm.Ecb.decrypt s t s' ∧ abiPreserved s s' ∧ + (contract .decrypt).post s s' := by + obtain ⟨t, s', he, ha, hp⟩ := ecb_correct .decrypt s hs + change Exec isa Impl.TripleDes.Arm.Ecb.decrypt s t s' at he + exact ⟨t, s', he, ⟨ha, VG.Arm.Exec.sp he⟩, hp⟩ + +theorem publicRegs_four (s₁ s₂ : State) : PublicRegs [.r0, .r1, .r2, .r3] s₁ s₂ ↔ + s₁.sp = s₂.sp ∧ s₁.gpr .r0 = s₂.gpr .r0 ∧ s₁.gpr .r1 = s₂.gpr .r1 ∧ + s₁.gpr .r2 = s₂.gpr .r2 ∧ s₁.gpr .r3 = s₂.gpr .r3 := by + simp [PublicRegs] + +theorem encrypt_verified : Verified target Impl.TripleDes.Arm.Ecb.encrypt + (Spec.TripleDes.ecbEncryptContract abi 0) := by + refine Verified.of_correct encrypt_correct + (ecbEncrypt_constantTime _) ?_ + sig_implies [Spec.TripleDes.ecbEncryptContract, Spec.TripleDes.ecbContract, + Spec.TripleDes.ecbSig, abi, argRegs, Arm.reduceClassify, Arm.Loc.val, State.addr, contract, publicRegs_four] [satState] using satState + +theorem decrypt_verified : Verified target Impl.TripleDes.Arm.Ecb.decrypt + (Spec.TripleDes.ecbDecryptContract abi 0) := by + refine Verified.of_correct decrypt_correct + (ecbDecrypt_constantTime _) ?_ + sig_implies [Spec.TripleDes.ecbDecryptContract, Spec.TripleDes.ecbContract, + Spec.TripleDes.ecbSig, abi, argRegs, Arm.reduceClassify, Arm.Loc.val, State.addr, contract, publicRegs_four] [satState] using satState + +end VG.Proof.TripleDes.Arm.Ecb diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/FunctionsLit.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/FunctionsLit.lean new file mode 100644 index 000000000..f0158ce18 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/FunctionsLit.lean @@ -0,0 +1,13 @@ +import VerifiedGarbage.Proof.Framework.Arm.Lit +import VerifiedGarbage.Impl.TripleDes.Arm.ExpandKey +import VerifiedGarbage.Impl.TripleDes.Arm.Ecb + +namespace VG + +materialize_code Impl.TripleDes.Arm.encryptBlock +materialize_code Impl.TripleDes.Arm.decryptBlock +materialize_code Impl.TripleDes.Arm.Key.expandKey +materialize_code Impl.TripleDes.Arm.Ecb.encrypt +materialize_code Impl.TripleDes.Arm.Ecb.decrypt + +end VG diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Head.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Head.lean new file mode 100644 index 000000000..e1bd3c882 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Head.lean @@ -0,0 +1,85 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Body +import VerifiedGarbage.Proof.TripleDes.Arm.BlockIO +import VerifiedGarbage.Proof.TripleDes.Arm.Save + +namespace VG.Proof.TripleDes.Arm +open VG VG.Arm VG.Arm.Straight VG.Impl.TripleDes.Arm +open VG.Spec.TripleDes (Direction DesSchedule) +open VG.Proof.TripleDes (roundKey) + +def saveRegion (s : State) : Region := ⟨State.addr (s.gpr .r2), 36⟩ + +structure HeadPre (keys : Nat → DesSchedule) (base : BitVec 32) (s : State) : Prop where + spills : Ok sboxCfg s + scratchFit : (s.gpr .r2).toNat + 256 ≤ 2 ^ 32 + dataFit : (s.gpr .r1).toNat + 8 ≤ 2 ^ 32 + pointer : s.gpr .r0 = base + saveRead : ∀ i < 9, InRegions (s.rd ++ s.wr) (State.addr (s.gpr .r2) + BitVec.ofNat 64 (4 * i)) 4 + saveWrite : ∀ i < 9, InRegions s.wr (State.addr (s.gpr .r2) + BitVec.ofNat 64 (4 * i)) 4 + dataRead : ∀ t < 2, InRegions (s.rd ++ s.wr) (State.addr (s.gpr .r1 + BitVec.ofNat 32 (4 * t))) 4 + dataSeparate : (⟨State.addr (s.gpr .r1), 8⟩ : Region).Disjoint (saveRegion s) + read : ∀ c < 3, ∀ d : Direction, ∀ j < 16, ∀ t < 2, + InRegions (s.rd ++ s.wr) (wordAddr (keyAddr (componentBase base c) d j) t) 4 + separateWork : ∀ c < 3, ∀ d : Direction, ∀ j < 16, ∀ t < 2, + (⟨wordAddr (keyAddr (componentBase base c) d j) t, 4⟩ : Region).Disjoint (spillRegion s) + separateSave : ∀ c < 3, ∀ d : Direction, ∀ j < 16, ∀ t < 2, + (⟨wordAddr (keyAddr (componentBase base c) d j) t, 4⟩ : Region).Disjoint (saveRegion s) + values : ∀ c < 3, ∀ d : Direction, ∀ j < 16, + (readKey s.mem (keyAddr (componentBase base c) d j)).setWidth 48 = roundKey (keys c) d j + +structure HeadPost (keys : Nat → DesSchedule) (base : BitVec 32) (original s : State) : Prop where + word : WordState (Spec.TripleDes.permute Spec.TripleDes.ip + (Spec.TripleDes.decodeBlock (Spec.TripleDes.blockAt original.mem (State.addr (original.gpr .r1))))) s + ready : Ready keys base s + saved : Saved original s + rd : s.rd = original.rd + wr : s.wr = original.wr + sp : s.sp = original.sp + regs : ∀ q ∈ loadKept, s.gpr q = original.gpr q + frame : Frame [saveRegion original] original.mem s.mem + +theorem ready_afterSave {keys : Nat → DesSchedule} {base : BitVec 32} {s t : State} + (hp : HeadPre keys base s) (hg : t.gpr = s.gpr) (hrd : t.rd = s.rd) + (hwr : t.wr = s.wr) (hf : Frame [saveRegion s] s.mem t.mem) : Ready keys base t := by + have hbase : t.gpr .r2 = s.gpr .r2 := congrFun hg .r2 + refine ⟨hp.spills.congr hbase hbase hrd hwr, ?_, ?_, ?_⟩ + · rw [hrd, hwr]; exact hp.read + · rw [show spillRegion t = spillRegion s from + congrArg (fun p => (⟨State.addr p + BitVec.ofNat 64 60, 388⟩ : Region)) hbase] + exact hp.separateWork + · intro c hc d j hj + have hm := readKey_frame hf (ptr := keyAddr (componentBase base c) d j) + (fun t ht q hq => by obtain rfl := List.mem_singleton.mp hq; exact hp.separateSave c hc d j hj t ht) + exact (congrArg (BitVec.setWidth 48) hm).trans (hp.values c hc d j hj) + +theorem blockHead_ok (keys : Nat → DesSchedule) (base : BitVec 32) (s : State) + (hp : HeadPre keys base s) : WP isa (.block (blockSave ++ blockLoad)) s (HeadPost keys base s) := by + apply WP.block_append + apply WP.mono (blockSave_ok s hp.scratchFit hp.saveWrite) + intro s₁ hs₁ + have hready := ready_afterSave hp hs₁.gpr hs₁.rd hs₁.wr hs₁.frame + have hread₁ : ∀ t < 2, InRegions (s₁.rd ++ s₁.wr) + (State.addr (s₁.gpr .r1 + BitVec.ofNat 32 (4 * t))) 4 := by + rw [hs₁.rd, hs₁.wr, hs₁.gpr]; exact hp.dataRead + have hdata : Spec.TripleDes.blockAt s₁.mem (State.addr (s₁.gpr .r1)) = + Spec.TripleDes.blockAt s.mem (State.addr (s.gpr .r1)) := by + rw [hs₁.gpr] + exact VG.Proof.TripleDes.blockAt_eq_of_frame _ hs₁.frame + (fun q hq => by obtain rfl := List.mem_singleton.mp hq; exact hp.dataSeparate) + obtain ⟨s₂, run₂, left₂, right₂, mem₂, rd₂, wr₂, sp₂, regs₂⟩ := + blockLoad_ok s₁ (by rw [hs₁.gpr]; exact hp.dataFit) hread₁ + have hframe : Frame [spillRegion s₁] s₁.mem s₂.mem := by + rw [mem₂]; exact Frame.refl _ _ + have hinput := congrArg (fun b => Spec.TripleDes.permute Spec.TripleDes.ip + (Spec.TripleDes.decodeBlock b)) hdata + apply WP.of_runBlock + refine ⟨s₂, run₂, ?_, hready.congr (regs₂ .r2 (by decide)) rd₂ wr₂ hframe, + hs₁.saved.congr (regs₂ .r2 (by decide)) hframe, + rd₂.trans hs₁.rd, wr₂.trans hs₁.wr, sp₂.trans hs₁.sp, ?_, ?_⟩ + · exact ⟨left₂.trans (congrArg (fun x : BitVec 64 => (x >>> 32).setWidth 32) hinput), + right₂.trans (congrArg (fun x : BitVec 64 => x.setWidth 32) hinput)⟩ + · intro q hq + exact (regs₂ q hq).trans (congrFun hs₁.gpr q) + · rw [mem₂]; exact hs₁.frame + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Initial.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Initial.lean new file mode 100644 index 000000000..261a0f78c --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Initial.lean @@ -0,0 +1,42 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Permutation +import VerifiedGarbage.Proof.TripleDes.Core + +namespace VG.Proof.TripleDes.Arm +open VG VG.Arm VG.Impl.TripleDes.Arm + +theorem initial_raw_ok (s : State) : + ∃ s', runBlock isa (permuteCode Spec.TripleDes.ip 64 32 32 .r11 .r10 .r5 .r4 .r12 .r9) s = some s' ∧ + s'.gpr .r11 = (Spec.TripleDes.permute Spec.TripleDes.ip (s.gpr .r4 ++ s.gpr .r5)).setWidth 32 ∧ + s'.gpr .r10 = ((Spec.TripleDes.permute Spec.TripleDes.ip (s.gpr .r4 ++ s.gpr .r5)) >>> 32).setWidth 32 ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ s'.mem = s.mem ∧ + (∀ r, ((instrs initialPermutation.lit).all fun op => dstOf op != some r) = true → + s'.gpr r = s.gpr r) := by + obtain ⟨s', run, lo, hi, rd, wr, sp, mem, regs⟩ := + fixedPermutation_ok Spec.TripleDes.ip (by decide) 32 32 + (by decide) (by decide) (by decide) (by decide) VG.Proof.TripleDes.ip_bounds + .r5 .r4 .r11 .r10 (instrs initialPermutation.lit) initialPermutation_check s + have hcode : permuteCode Spec.TripleDes.ip 64 32 32 .r11 .r10 .r5 .r4 .r12 .r9 = instrs initialPermutation.lit := + congrArg instrs initialPermutation.lit_eq + refine ⟨s', (congrArg (fun is => runBlock isa is s) hcode).trans run, ?_, ?_, rd, wr, sp, mem, regs⟩ + · simpa only [packedInput, BitVec.setWidth_eq] using lo + · simpa only [packedInput, BitVec.setWidth_eq] using hi + + +theorem final_raw_ok (s : State) : + ∃ s', runBlock isa (permuteCode Spec.TripleDes.fp 64 32 32 .r5 .r4 .r11 .r10 .r12 .r9) s = some s' ∧ + s'.gpr .r5 = (Spec.TripleDes.permute Spec.TripleDes.fp (s.gpr .r10 ++ s.gpr .r11)).setWidth 32 ∧ + s'.gpr .r4 = ((Spec.TripleDes.permute Spec.TripleDes.fp (s.gpr .r10 ++ s.gpr .r11)) >>> 32).setWidth 32 ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ s'.mem = s.mem ∧ + (∀ r, ((instrs finalPermutation.lit).all fun op => dstOf op != some r) = true → + s'.gpr r = s.gpr r) := by + obtain ⟨s', run, lo, hi, rd, wr, sp, mem, regs⟩ := + fixedPermutation_ok Spec.TripleDes.fp (by decide) 32 32 + (by decide) (by decide) (by decide) (by decide) VG.Proof.TripleDes.fp_bounds + .r11 .r10 .r5 .r4 (instrs finalPermutation.lit) finalPermutation_check s + have hcode : permuteCode Spec.TripleDes.fp 64 32 32 .r5 .r4 .r11 .r10 .r12 .r9 = instrs finalPermutation.lit := + congrArg instrs finalPermutation.lit_eq + refine ⟨s', (congrArg (fun is => runBlock isa is s) hcode).trans run, ?_, ?_, rd, wr, sp, mem, regs⟩ + · simpa only [packedInput, BitVec.setWidth_eq] using lo + · simpa only [packedInput, BitVec.setWidth_eq] using hi + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Body.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Body.lean new file mode 100644 index 000000000..6e4e77de6 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Body.lean @@ -0,0 +1,69 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Key.Composition + +namespace VG.Proof.TripleDes.Arm.Key + +open VG VG.Arm VG.Arm.RegUpd +open VG.Proof.Rc2.Arm (Keep) + +theorem cmpLength_ok (s : State) : + ∃ s', runBlock isa [.cmp .r1 (.imm 16)] s = some s' ∧ + isa.eval .eq s' = some (s.gpr .r1 == 16) ∧ Keep [.r4] s s' := by + refine ⟨subFlags s (s.gpr .r1) 16, ?_, ?_, ⟨fun _ _ => rfl, rfl, rfl, rfl⟩⟩ + · simp (config := {decide := true}) only [runBlock_cons, runStep_some, runBlock_nil, + exec, Op2.eval, ite_true, Option.map_some] + · change some (s.gpr .r1 - 16 == 0) = _ + exact congrArg some (by + apply Bool.eq_iff_iff.mpr + simp only [beq_iff_eq] + bv_omega) + +theorem Components.keep {origin s t : State} {n : Nat} (hs : Components origin s n) + (ht : Keep [.r4] s t) : Components origin t n := + ⟨fun c hc j hj => by rw [ht.mem]; exact hs.keys c hc j hj, + ht.rd.trans hs.rd, ht.wr.trans hs.wr, + fun r hr => (ht.reg r (by revert hr; cases r <;> decide)).trans (hs.reg r hr), by rw [ht.mem]; exact hs.frame⟩ + +theorem beq16_toNat (x : BitVec 32) : (x == 16) = decide (x.toNat = 16) := by + apply Bool.eq_iff_iff.mpr + simp only [beq_iff_eq, decide_eq_true_eq] + constructor + · intro h; rw [h]; rfl + · intro h + apply BitVec.eq_of_toNat_eq + exact h + +theorem body_ok (origin s : State) (hp : Permissions origin) (hs : Components origin s 0) + (Q : State → Prop) + (finish : ∀ t, Components origin t 3 → WP isa (.block Impl.TripleDes.Arm.Key.restore) t Q) : + WP isa (.seq (Impl.TripleDes.Arm.Key.component 0 0) + (.seq (Impl.TripleDes.Arm.Key.component 8 1) + (.seq (.block [.cmp .r1 (.imm 16)]) + (.seq (.ite .eq (.block Impl.TripleDes.Arm.Key.copyThird) + (Impl.TripleDes.Arm.Key.component 16 2)) (.block Impl.TripleDes.Arm.Key.restore))))) s Q := by + apply WP.seq + apply WP.mono (componentStep_ok origin s 0 (by decide) hp hs (by rfl)) + intro s₁ hs₁ + apply WP.seq + apply WP.mono (componentStep_ok origin s₁ 1 (by decide) hp hs₁ (by rfl)) + intro s₂ hs₂ + apply WP.seq + obtain ⟨s₃, run₃, flag₃, keep₃⟩ := cmpLength_ok s₂ + refine WP.of_runBlock ⟨s₃, run₃, ?_⟩ + have hs₃ := hs₂.keep keep₃ + apply WP.seq + apply WP.mono (Q := (Components origin · 3)) ?_ + · intro t ht + exact finish t ht + have flag : isa.eval .eq s₃ = some (decide ((origin.gpr .r1).toNat = 16)) := by + rw [flag₃, hs₂.reg .r1 (by decide), beq16_toNat] + by_cases h16 : (origin.gpr .r1).toNat = 16 + · apply WP.ite true (by simpa only [h16, decide_true] using flag) + · intro _; exact copyThird_ok origin s₃ hp hs₃ h16 + · simp + · apply WP.ite false (by simpa only [h16, decide_false] using flag) + · simp + · intro _ + exact componentStep_ok origin s₃ 2 (by decide) hp hs₃ + (by simp only [VG.Proof.TripleDes.componentOffset, h16, and_false, ite_false]) + +end VG.Proof.TripleDes.Arm.Key diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Component.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Component.lean new file mode 100644 index 000000000..7e1748620 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Component.lean @@ -0,0 +1,52 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Key.Loop +import VerifiedGarbage.Proof.TripleDes.Schedule + +namespace VG.Proof.TripleDes.Arm.Key + +open VG VG.Arm +open VG.Proof.TripleDes.Arm.Key (keyKept) + +structure ComponentPost (keys : Spec.TripleDes.DesSchedule) (base : Addr) (s s' : State) : Prop where + keys : ∀ i < 16, s'.mem.readW (base + BitVec.ofNat 64 (8 * i)) 64 = (keys.getD i 0).setWidth 64 + rd : s'.rd = s.rd + wr : s'.wr = s.wr + reg : ∀ r ∈ keyKept, s'.gpr r = s.gpr r + frame : Frame [⟨base, 128⟩] s.mem s'.mem + +theorem component_ok (s : State) (offset component : Nat) (hc : component < 3) + (ho : offset + 4 < 4096) + (keyFit : (s.gpr .r0).toNat + offset + 8 ≤ 2 ^ 32) + (scheduleFit : (s.gpr .r2).toNat + 384 ≤ 2 ^ 32) + (hr : ∀ t < 2, InRegions (s.rd ++ s.wr) + (State.addr (s.gpr .r0 + BitVec.ofNat 32 (offset + 4 * t))) 4) + (hw : ∀ j < 16, ∀ t < 2, InRegions s.wr + (State.addr (s.gpr .r2 + BitVec.ofNat 32 (128 * component) + + BitVec.ofNat 32 (8 * j) + BitVec.ofNat 32 (4 * t))) 4) : + WP isa (Impl.TripleDes.Arm.Key.component offset component) s + (ComponentPost (Spec.TripleDes.expandDesKey (Spec.TripleDes.decodeBlock + (Spec.TripleDes.blockAt s.mem (State.addr (s.gpr .r0 + BitVec.ofNat 32 offset))))) + (State.addr (s.gpr .r2 + BitVec.ofNat 32 (128 * component))) s) := by + rw [Impl.TripleDes.Arm.Key.component] + apply WP.seq + apply WP.mono (load_ok s offset component hc ho keyFit hr) + intro s₁ h₁ + have writes : ∀ j < 16, ∀ t < 2, InRegions s₁.wr + (State.addr (s.gpr .r2 + BitVec.ofNat 32 (128 * component) + + BitVec.ofNat 32 (8 * j) + BitVec.ofNat 32 (4 * t))) 4 := by + rw [h₁.wr]; exact hw + have fit : (s.gpr .r2 + BitVec.ofNat 32 (128 * component)).toNat + 128 ≤ 2 ^ 32 := by + simp only [BitVec.toNat_add, BitVec.toNat_ofNat] + rw [Nat.mod_eq_of_lt (by omega_using [hc] : 128 * component < 2 ^ 32), + Nat.mod_eq_of_lt (by omega_using [scheduleFit, hc] : (s.gpr .r2).toNat + 128 * component < 2 ^ 32)] + omega_using [scheduleFit, hc] + apply WP.mono (loop_ok _ _ s₁ fit writes h₁.c h₁.d h₁.counter h₁.ptr) + intro s₂ h₂ + refine ⟨?_, h₂.rd.trans h₁.rd, h₂.wr.trans h₁.wr, + fun r hr => (h₂.reg r hr).trans (h₁.reg r hr), ?_⟩ + · intro i hi + rw [VG.Proof.TripleDes.expandDesKey_prefix, VG.Proof.TripleDes.vector_getD _ i hi 0] + exact h₂.keys i hi hi + · rw [← h₁.mem] + exact h₂.frame + +end VG.Proof.TripleDes.Arm.Key diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Composition.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Composition.lean new file mode 100644 index 000000000..bcf8b57ad --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Composition.lean @@ -0,0 +1,168 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Key.Copy +import VerifiedGarbage.Proof.TripleDes.KeyMemory + +namespace VG.Proof.TripleDes.Arm.Key + +open VG VG.Arm +open VG.Proof.TripleDes (componentKeys componentOffset) + +abbrev keyR (s : State) : Region := ⟨(State.addr (s.gpr .r0)), (s.gpr .r1).toNat⟩ +abbrev outputR (s : State) : Region := ⟨(State.addr (s.gpr .r2)), 384⟩ + +def slot (base : Addr) (c j : Nat) : Addr := base + BitVec.ofNat 64 (128 * c + 8 * j) + +structure Components (origin s : State) (done : Nat) : Prop where + keys : ∀ c < done, ∀ j < 16, s.mem.readW (slot ((State.addr (origin.gpr .r2))) c j) 64 = + ((componentKeys origin.mem ((State.addr (origin.gpr .r0))) (origin.gpr .r1).toNat c).getD j 0).setWidth 64 + rd : s.rd = origin.rd + wr : s.wr = origin.wr + reg : ∀ r ∈ keyKept, s.gpr r = origin.gpr r + frame : Frame [outputR origin] origin.mem s.mem + +structure Permissions (s : State) : Prop where + reads : ∀ offset, offset + 4 ≤ (s.gpr .r1).toNat → + InRegions (s.rd ++ s.wr) ((State.addr (s.gpr .r0)) + BitVec.ofNat 64 offset) 4 + writes : ∀ offset, offset + 4 ≤ 384 → InRegions s.wr ((State.addr (s.gpr .r2)) + BitVec.ofNat 64 offset) 4 + keyOutput : (keyR s).Disjoint (outputR s) + valid : Spec.TripleDes.validKey (s.gpr .r1).toNat + keyFit : (s.gpr .r0).toNat + (s.gpr .r1).toNat ≤ 2 ^ 32 + outputFit : (s.gpr .r2).toNat + 384 ≤ 2 ^ 32 + +theorem componentStep_ok (origin s : State) (c : Nat) (hc : c < 3) + (hp : Permissions origin) (hs : Components origin s c) + (hoff : componentOffset (origin.gpr .r1).toNat c = 8 * c) : + WP isa (Impl.TripleDes.Arm.Key.component (8 * c) c) s + (Components origin · (c + 1)) := by + have offsetBound := VG.Proof.TripleDes.componentOffset_bound _ c hp.valid hc + rw [hoff] at offsetBound + have keyFit : (s.gpr .r0).toNat + 8 * c + 8 ≤ 2 ^ 32 := by + rw [hs.reg .r0 (by decide)] + omega_using [hp.keyFit, offsetBound] + have outputFit : (s.gpr .r2).toNat + 384 ≤ 2 ^ 32 := by + rw [hs.reg .r2 (by decide)]; exact hp.outputFit + have read : ∀ t < 2, InRegions (s.rd ++ s.wr) + (State.addr (s.gpr .r0 + BitVec.ofNat 32 (8 * c + 4 * t))) 4 := by + intro t ht + rw [hs.rd, hs.wr, hs.reg .r0 (by decide), addr_add (by omega_using [hp.keyFit, offsetBound, ht])] + exact hp.reads _ (by omega_using [offsetBound, ht]) + have write : ∀ j < 16, ∀ t < 2, InRegions s.wr + (State.addr (s.gpr .r2 + BitVec.ofNat 32 (128 * c) + + BitVec.ofNat 32 (8 * j) + BitVec.ofNat 32 (4 * t))) 4 := by + intro j hj t ht + rw [hs.wr, hs.reg .r2 (by decide), Offset.add_ofNat_add_ofNat, + Offset.add_ofNat_add_ofNat, addr_add (by omega_using [hp.outputFit, hc, hj, ht])] + exact hp.writes _ (by omega_using [hc, hj, ht]) + apply WP.mono (component_ok s (8 * c) c hc (by omega) keyFit outputFit read write) + intro t ht + have frame : Frame [⟨(State.addr (origin.gpr .r2)) + BitVec.ofNat 64 (128 * c), 128⟩] s.mem t.mem := by + have hf := ht.frame + rw [hs.reg .r2 (by decide), addr_add (by omega_using [hp.outputFit, hc])] at hf + exact hf + have key : Spec.TripleDes.blockAt s.mem ((State.addr (s.gpr .r0)) + BitVec.ofNat 64 (8 * c)) = + Spec.TripleDes.blockAt origin.mem ((State.addr (origin.gpr .r0)) + BitVec.ofNat 64 (8 * c)) := by + rw [hs.reg .r0 (by decide)] + apply VG.Proof.TripleDes.blockAt_eq_of_frame _ hs.frame + intro r hr + obtain rfl := List.mem_singleton.mp hr + exact hp.keyOutput.sub_left (Offset.sub_base _ offsetBound) + refine ⟨?_, ht.rd.trans hs.rd, ht.wr.trans hs.wr, + fun r hr => (ht.reg r hr).trans (hs.reg r hr), hs.frame.trans (frame.sub ?_)⟩ + · intro k hk j hj + by_cases he : k = c + · subst k + have h := ht.keys j hj + rw [addr_add (a := s.gpr .r0) (k := 8 * c) (by omega_using [keyFit]), key, hs.reg .r2 (by decide), + addr_add (by omega_using [hp.outputFit, hc]), Offset.add_ofNat_add_ofNat] at h + unfold componentKeys + rw [hoff] + exact h + · have before : k < c := by omega_using [hk, he] + have sep : (Region.mk (slot ((State.addr (origin.gpr .r2))) k j) 8).Disjoint + ⟨(State.addr (origin.gpr .r2)) + BitVec.ofNat 64 (128 * c), 128⟩ := + Offset.disjoint _ (by omega_using [before, hj]) + (by omega_using [hk, hc, hj]) (by omega_using [hc]) + have hmem := frame.readW (a := slot ((State.addr (origin.gpr .r2))) k j) (w := 64) (r := ⟨slot ((State.addr (origin.gpr .r2))) k j, 8⟩) + (Region.contains_self _ _) (fun r hr => by obtain rfl := List.mem_singleton.mp hr; exact sep) + (by decide) + exact hmem.trans (hs.keys k before j hj) + · intro r hr + obtain rfl := List.mem_singleton.mp hr + exact ⟨outputR origin, by simp, Offset.sub_base _ (by omega_using [hc])⟩ + +theorem copyThird_ok (origin s : State) (hp : Permissions origin) + (hs : Components origin s 2) (hn : (origin.gpr .r1).toNat = 16) : + WP isa (.block Impl.TripleDes.Arm.Key.copyThird) s (Components origin · 3) := by + have fit : (s.gpr .r2).toNat + 384 ≤ 2 ^ 32 := by + rw [hs.reg .r2 (by decide)]; exact hp.outputFit + have reads : ∀ i < 16, ∀ t < 2, InRegions (s.rd ++ s.wr) + (State.addr (s.gpr .r2 + BitVec.ofNat 32 (8 * i + 4 * t))) 4 := by + intro i hi t ht + rw [hs.rd, hs.wr, hs.reg .r2 (by decide), addr_add (by omega_using [hp.outputFit, hi, ht])] + obtain ⟨r, hr, hc⟩ := hp.writes (8 * i + 4 * t) (by omega_using [hi, ht]) + exact ⟨r, List.mem_append_right _ hr, hc⟩ + have writes : ∀ i < 16, ∀ t < 2, InRegions s.wr + (State.addr (s.gpr .r2 + BitVec.ofNat 32 (256 + 8 * i + 4 * t))) 4 := by + intro i hi t ht + rw [hs.wr, hs.reg .r2 (by decide), addr_add (by omega_using [hp.outputFit, hi, ht])] + exact hp.writes _ (by omega_using [hi, ht]) + have code : Impl.TripleDes.Arm.Key.copyThird = copyCode 16 := rfl + rw [code] + apply WP.mono (copy_ok s 16 (by decide) fit reads writes) + intro t ht + have frame : Frame [⟨(State.addr (origin.gpr .r2)) + BitVec.ofNat 64 256, 128⟩] s.mem t.mem := by + have h := ht.frame + rw [hs.reg .r2 (by decide)] at h + exact h + refine ⟨?_, ht.rd.trans hs.rd, ht.wr.trans hs.wr, ?_, hs.frame.trans (frame.sub ?_)⟩ + · intro c hc j hj + by_cases he : c = 2 + · subst c + have hRepeat : componentKeys origin.mem ((State.addr (origin.gpr .r0))) (origin.gpr .r1).toNat 2 = + componentKeys origin.mem ((State.addr (origin.gpr .r0))) (origin.gpr .r1).toNat 0 := by + rw [hn]; rfl + have h := ht.keys j hj + rw [hs.reg .r2 (by decide)] at h + change t.mem.readW ((State.addr (origin.gpr .r2)) + BitVec.ofNat 64 (256 + 8 * j)) 64 = _ + rw [hRepeat] + have first := hs.keys 0 (by decide) j hj + simp only [slot, Nat.mul_zero, Nat.zero_add] at first + exact h.trans first + · have before : c < 2 := by omega_using [hc, he] + have sep : (Region.mk (slot ((State.addr (origin.gpr .r2))) c j) 8).Disjoint + ⟨(State.addr (origin.gpr .r2)) + BitVec.ofNat 64 256, 128⟩ := + Offset.disjoint _ (by omega_using [before, hj]) + (by omega_using [before, hj]) (by decide) + have hmem := frame.readW (a := slot ((State.addr (origin.gpr .r2))) c j) (w := 64) (r := ⟨slot ((State.addr (origin.gpr .r2))) c j, 8⟩) + (Region.contains_self _ _) (fun r hr => by obtain rfl := List.mem_singleton.mp hr; exact sep) + (by decide) + exact hmem.trans (hs.keys c before j hj) + · intro r hr + have unused : ∀ r ∈ keyKept, r ≠ .r4 ∧ r ≠ .r5 := by decide + exact (ht.reg r (unused r hr).1 (unused r hr).2).trans (hs.reg r hr) + · intro r hr + obtain rfl := List.mem_singleton.mp hr + exact ⟨outputR origin, by simp, Offset.sub_base _ (by decide)⟩ + +def componentIndex (i : Nat) : Nat := if i < 16 then 0 else if i < 32 then 1 else 2 + +theorem index_partition : ∀ i < 48, componentIndex i < 3 ∧ i % 16 < 16 ∧ + 8 * i = 128 * componentIndex i + 8 * (i % 16) := by decide + +theorem Components.schedule {origin s : State} (h : Components origin s 3) : + Spec.TripleDes.scheduleAt s.mem ((State.addr (origin.gpr .r2))) = + VG.Proof.TripleDes.expandedMemory origin.mem ((State.addr (origin.gpr .r0))) (origin.gpr .r1).toNat := by + apply Vector.ext + intro i hi + have fact := index_partition i hi + have keys := h.keys (componentIndex i) fact.1 (i % 16) fact.2.1 + rw [slot, ← fact.2.2] at keys + rw [VG.Proof.TripleDes.scheduleAt_readW s.mem ((State.addr (origin.gpr .r2))) i hi] + simp only [VG.Proof.TripleDes.expandedMemory, Vector.getElem_ofFn] + by_cases h16 : i < 16 + · simpa only [componentIndex, h16, ite_true] using keys + · by_cases h32 : i < 32 + · simpa only [componentIndex, h16, h32, ite_false, ite_true] using keys + · simpa only [componentIndex, h16, h32, ite_false] using keys + + +end VG.Proof.TripleDes.Arm.Key diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Contract.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Contract.lean new file mode 100644 index 000000000..929cd0a27 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Contract.lean @@ -0,0 +1,24 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Key.Body +import VerifiedGarbage.Proof.TripleDes.Arm.Key.Save +import VerifiedGarbage.Proof.TripleDes.Arm.ConstantTime +import VerifiedGarbage.Spec.TripleDes.Contract + +namespace VG.Proof.TripleDes.Arm.Key + +open VG VG.Arm + +def contract : Contract isa where + pre s := + let key : Region := ⟨(State.addr (s.gpr .r0)), (s.gpr .r1).toNat⟩ + let output : Region := ⟨(State.addr (s.gpr .r2)), 384⟩ + let scratch : Region := ⟨(State.addr (s.gpr .r3)), 512⟩ + s.rd = [key] ∧ s.wr = [output, scratch] ∧ key.Disjoint output ∧ key.Disjoint scratch ∧ + output.Disjoint scratch ∧ + Spec.TripleDes.validKey (s.gpr .r1).toNat ∧ + (s.gpr .r0).toNat + (s.gpr .r1).toNat ≤ 2 ^ 32 ∧ + (s.gpr .r2).toNat + 384 ≤ 2 ^ 32 ∧ (s.gpr .r3).toNat + 512 ≤ 2 ^ 32 + post s s' := Spec.TripleDes.scheduleAt s'.mem ((State.addr (s.gpr .r2))) = + Spec.TripleDes.expandKey (Spec.TripleDes.bytesAt s.mem ((State.addr (s.gpr .r0))) (s.gpr .r1).toNat) + pub := PublicRegs [.r0, .r1, .r2, .r3] + +end VG.Proof.TripleDes.Arm.Key diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Copy.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Copy.lean new file mode 100644 index 000000000..e18d49772 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Copy.lean @@ -0,0 +1,122 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Key.Component +import VerifiedGarbage.Proof.TripleDes.Arm.WordStore +import VerifiedGarbage.Proof.Rc2.Arm.Lookup + +namespace VG.Proof.TripleDes.Arm.Key +open VG VG.Arm VG.Arm.RegUpd VG.Impl.TripleDes.Arm +open VG.Proof.Rc2.Arm (Keep) + +def copyPair (a b : Nat) : List Instr := + [.ldr .r4 .r2 a, .ldr .r5 .r2 (a + 4), .str .r4 .r2 b, .str .r5 .r2 (b + 4)] + +theorem copyPair_ok (s : State) (a b : Nat) (ha : a + 4 < 4096) (hb : b + 4 < 4096) + (fit : (s.gpr .r2).toNat + max a b + 8 ≤ 2 ^ 32) + (hr : ∀ t < 2, InRegions (s.rd ++ s.wr) + (State.addr (s.gpr .r2 + BitVec.ofNat 32 (a + 4 * t))) 4) + (hw : ∀ t < 2, InRegions s.wr + (State.addr (s.gpr .r2 + BitVec.ofNat 32 (b + 4 * t))) 4) : + ∃ s', runBlock isa (copyPair a b) s = some s' ∧ + Keep [.r4, .r5] {s with + mem := s.mem.writeW (State.addr (s.gpr .r2 + BitVec.ofNat 32 b)) + (s.mem.readW (State.addr (s.gpr .r2 + BitVec.ofNat 32 a)) 64)} s' := by + have hr0 := hr 0 (by decide) + have hr1 := hr 1 (by decide) + have hw0 := hw 0 (by decide) + have hw1 := hw 1 (by decide) + simp only [Nat.mul_zero, Nat.add_zero] at hr0 hw0 + simp only [Nat.mul_one] at hr1 hw1 + refine ⟨_, by + simp only [copyPair, runBlock_cons, runStep_some, runBlock_nil, exec, + show a < 4096 from by omega, ha, show b < 4096 from by omega, hb, + ite_true, State.load32, State.store32, hr0, hr1, hw0, hw1, Option.map_some, + gpr_setReg, reduceCtorEq, ite_true, ite_false, mem_setReg, rd_setReg, wr_setReg] + rfl, ?_⟩ + refine ⟨?_, ?_, ?_, ?_⟩ + · intro r hr + simp only [List.mem_cons, List.not_mem_nil, or_false, not_or] at hr + simp only [gpr_setReg, hr.1, hr.2, ite_false] + · have ea : State.addr (s.gpr .r2 + BitVec.ofNat 32 (a + 4)) = + State.addr (s.gpr .r2 + BitVec.ofNat 32 a) + 4 := by + rw [addr_add (by omega_using [fit, Nat.le_max_left a b]), + addr_add (by omega_using [fit, Nat.le_max_left a b]), ← Offset.add_ofNat_add_ofNat] + rfl + have eb : State.addr (s.gpr .r2 + BitVec.ofNat 32 (b + 4)) = + State.addr (s.gpr .r2 + BitVec.ofNat 32 b) + 4 := by + rw [addr_add (by omega_using [fit, Nat.le_max_right a b]), + addr_add (by omega_using [fit, Nat.le_max_right a b]), ← Offset.add_ofNat_add_ofNat] + rfl + rw [ea, eb, writeW_pair, readW_pair] + · rfl + · rfl + + def copyCode (n : Nat) : List Instr := + (List.range n).flatMap fun j => + copyPair (8 * j) (256 + 8 * j) + +structure CopyPost (base : Addr) (s : State) (n : Nat) (s' : State) : Prop where + keys : ∀ i < n, s'.mem.readW (base + BitVec.ofNat 64 (256 + 8 * i)) 64 = + s.mem.readW (base + BitVec.ofNat 64 (8 * i)) 64 + rd : s'.rd = s.rd + wr : s'.wr = s.wr + reg : ∀ r, r ≠ .r4 → r ≠ .r5 → s'.gpr r = s.gpr r + frame : Frame [⟨base + BitVec.ofNat 64 256, 128⟩] s.mem s'.mem + +theorem copy_ok (s : State) (n : Nat) (hn : n ≤ 16) + (fit : (s.gpr .r2).toNat + 384 ≤ 2 ^ 32) + (hr : ∀ i < 16, ∀ t < 2, InRegions (s.rd ++ s.wr) + (State.addr (s.gpr .r2 + BitVec.ofNat 32 (8 * i + 4 * t))) 4) + (hw : ∀ i < 16, ∀ t < 2, InRegions s.wr + (State.addr (s.gpr .r2 + BitVec.ofNat 32 (256 + 8 * i + 4 * t))) 4) : + WP isa (.block (copyCode n)) s (CopyPost (State.addr (s.gpr .r2)) s n) := by + induction n with + | zero => + apply WP.block_nil + exact ⟨fun _ hi => by omega, rfl, rfl, fun _ _ _ => rfl, Frame.refl _ _⟩ + | succ n ih => + rw [copyCode, List.range_succ, List.flatMap_append, List.flatMap_cons, List.flatMap_nil, + List.append_nil, WP.block_append_iff] + apply WP.mono (ih (by omega)) + intro s₁ h₁ + have hbase : s₁.gpr .r2 = s.gpr .r2 := h₁.reg .r2 (by decide) (by decide) + have readable : ∀ t < 2, InRegions (s₁.rd ++ s₁.wr) + (State.addr (s₁.gpr .r2 + BitVec.ofNat 32 (8 * n + 4 * t))) 4 := by + rw [h₁.rd, h₁.wr, hbase]; exact hr n (by omega) + have writable : ∀ t < 2, InRegions s₁.wr + (State.addr (s₁.gpr .r2 + BitVec.ofNat 32 (256 + 8 * n + 4 * t))) 4 := by + rw [h₁.wr, hbase]; exact hw n (by omega) + have fit₁ : (s₁.gpr .r2).toNat + max (8 * n) (256 + 8 * n) + 8 ≤ 2 ^ 32 := by + rw [hbase, Nat.max_eq_right (by omega : 8 * n ≤ 256 + 8 * n)] + omega_using [fit, hn] + obtain ⟨s₂, run₂, keep₂⟩ := copyPair_ok s₁ (8 * n) (256 + 8 * n) + (by omega) (by omega) fit₁ readable writable + have source : s₁.mem.readW (State.addr (s.gpr .r2) + BitVec.ofNat 64 (8 * n)) 64 = + s.mem.readW (State.addr (s.gpr .r2) + BitVec.ofNat 64 (8 * n)) 64 := by + apply h₁.frame.readW (r := ⟨State.addr (s.gpr .r2) + BitVec.ofNat 64 (8 * n), 8⟩) + (Region.contains_self _ _) _ (by decide) + intro r h + obtain rfl := List.mem_singleton.mp h + exact Offset.disjoint (State.addr (s.gpr .r2)) (by omega) (by omega) (by decide) + have mem₂ : s₂.mem = s₁.mem.writeW (State.addr (s.gpr .r2) + BitVec.ofNat 64 (256 + 8 * n)) + (s.mem.readW (State.addr (s.gpr .r2) + BitVec.ofNat 64 (8 * n)) 64) := by + have hm := keep₂.mem + rw [hbase, addr_add (by omega_using [fit, hn]), + addr_add (by omega_using [fit, hn]), source] at hm + exact hm + refine WP.of_runBlock ⟨s₂, run₂, ⟨?_, keep₂.rd.trans h₁.rd, keep₂.wr.trans h₁.wr, + fun r h4 h5 => (keep₂.reg r (by + simpa only [List.mem_cons, List.not_mem_nil, or_false, not_or] using And.intro h4 h5)).trans (h₁.reg r h4 h5), ?_⟩⟩ + · intro i hi + rw [mem₂] + by_cases he : i = n + · subst i; exact Mem.readW_writeW_self64 _ _ _ + · rw [Mem.readW_writeW_sep (Offset.sep (State.addr (s.gpr .r2)) (by omega) (by omega) (by omega)) (by decide)] + exact h₁.keys i (by omega) + · rw [mem₂] + apply h₁.frame.writeW (List.mem_singleton_self _) _ + have hc := Offset.contains_base (State.addr (s.gpr .r2) + BitVec.ofNat 64 256) + (d := 8 * n) (n := 8) (k := 128) (by omega) (by omega) + rw [Offset.add_ofNat_add_ofNat] at hc + exact hc + + +end VG.Proof.TripleDes.Arm.Key diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Correct.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Correct.lean new file mode 100644 index 000000000..ef2fd97d8 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Correct.lean @@ -0,0 +1,82 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Key.Contract + +namespace VG.Proof.TripleDes.Arm.Key + +open VG VG.Arm + + theorem expand_correct (s : State) (hs : contract.pre s) : + WP isa Impl.TripleDes.Arm.Key.expandKey s (fun s' => (∀ r ∈ preserved, s'.gpr r = s.gpr r) ∧ contract.post s s') := by + obtain ⟨hrd, hwr, keyOutput, keyScratch, outputScratch, valid, keyFit, outputFit, scratchFit⟩ := hs + have scratchWrites : ∀ i < 9, InRegions s.wr ((State.addr (s.gpr .r3)) + BitVec.ofNat 64 (4 * i)) 4 := by + intro i hi + rw [hwr] + exact ⟨⟨(State.addr (s.gpr .r3)), 512⟩, by simp, Offset.contains_base _ (by omega_using [hi]) (by omega_using [hi])⟩ + rw [Impl.TripleDes.Arm.Key.expandKey] + apply WP.seq + apply WP.mono (save_ok s (by omega_using [scratchFit]) scratchWrites) + intro s₁ h₁ + have g₁ (r : Reg) : s₁.gpr r = s.gpr r := congrFun h₁.1 r + have hp : Permissions s₁ := by + constructor + · intro offset hoff + rw [h₁.2.1, h₁.2.2.1, g₁, hrd, hwr] + exact ⟨⟨(State.addr (s.gpr .r0)), (s.gpr .r1).toNat⟩, by simp, + Offset.contains_base _ (by simpa only [g₁] using hoff) (by + have bound := BitVec.isLt (s.gpr .r1) + rw [g₁] at hoff + omega_using [hoff, bound])⟩ + · intro offset hoff + rw [h₁.2.2.1, g₁, hwr] + exact ⟨⟨(State.addr (s.gpr .r2)), 384⟩, by simp, Offset.contains_base _ hoff (by omega_using [hoff])⟩ + · simpa only [keyR, outputR, g₁] using keyOutput + · simpa only [g₁] using valid + · simpa only [g₁] using keyFit + · simpa only [g₁] using outputFit + apply body_ok s₁ s₁ hp ⟨fun _ h => by omega, rfl, rfl, fun _ _ => rfl, Frame.refl _ _⟩ + intro s₂ h₂ + have g₂ (r : Reg) (hr : r ∈ keyKept) : s₂.gpr r = s.gpr r := + (h₂.reg r hr).trans (g₁ r) + have frame₂ : Frame [⟨(State.addr (s.gpr .r2)), 384⟩] s₁.mem s₂.mem := by + have h := h₂.frame + rw [outputR, g₁] at h + exact h + have saved₂ : Saved s s₂ := by + intro i hi + have sub : Region.Sub ⟨(State.addr (s.gpr .r3)) + BitVec.ofNat 64 (4 * i), 4⟩ ⟨(State.addr (s.gpr .r3)), 512⟩ := + Offset.sub_base _ (by omega_using [hi]) + have mem := frame₂.readW (a := (State.addr (s.gpr .r3)) + BitVec.ofNat 64 (4 * i)) (w := 32) + (r := ⟨(State.addr (s.gpr .r3)) + BitVec.ofNat 64 (4 * i), 4⟩) (Region.contains_self _ _) + (fun r hr => by obtain rfl := List.mem_singleton.mp hr; exact (outputScratch.sub_right sub).symm) + (by decide) + rw [g₂ .r3 (by decide)] + have saved₁ := h₁.2.2.2.1 i hi + rw [g₁] at saved₁ + exact mem.trans saved₁ + have scratchReads : ∀ i < 9, InRegions (s₂.rd ++ s₂.wr) ((State.addr (s₂.gpr .r3)) + BitVec.ofNat 64 (4 * i)) 4 := by + intro i hi + rw [h₂.rd, h₂.wr, h₁.2.1, h₁.2.2.1, g₂ .r3 (by decide)] + obtain ⟨r, hr, hc⟩ := scratchWrites i hi + exact ⟨r, List.mem_append_right _ hr, hc⟩ + apply WP.mono (restore_ok s s₂ saved₂ (by rw [g₂ .r3 (by decide)]; omega_using [scratchFit]) scratchReads) + intro s₃ h₃ + have scratchFrame : Frame [⟨(State.addr (s.gpr .r3)), 512⟩] s.mem s₁.mem := h₁.2.2.2.2.sub (by + intro r hr + obtain rfl := List.mem_singleton.mp hr + exact ⟨⟨(State.addr (s.gpr .r3)), 512⟩, by simp, Region.sub_prefix (by decide)⟩) + have initialBytes := VG.Proof.TripleDes.bytesAt_eq_of_frame ((State.addr (s.gpr .r0))) (s.gpr .r1).toNat + scratchFrame (by have bound := (s.gpr .r1).isLt; omega_using [bound]) (by simpa using keyScratch) + constructor + · intro r hr + have kept : ∀ r ∈ preserved, r ∈ Impl.TripleDes.Arm.Key.savedRegs ∨ r ∈ keyKept := by decide + rcases kept r hr with saved | other + · exact h₃.1 r saved + · exact (h₃.2.reg r (by revert other; cases r <;> decide)).trans (g₂ r other) + · have result := h₂.schedule + simp only [g₁] at result + rw [← VG.Proof.TripleDes.expandKey_memory s₁.mem ((State.addr (s.gpr .r0))) (s.gpr .r1).toNat valid, + initialBytes] at result + change Spec.TripleDes.scheduleAt s₃.mem ((State.addr (s.gpr .r2))) = _ + rw [h₃.2.mem] + exact result + +end VG.Proof.TripleDes.Arm.Key diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Load.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Load.lean new file mode 100644 index 000000000..3b2094b21 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Load.lean @@ -0,0 +1,112 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Key.Permutation +import VerifiedGarbage.Proof.TripleDes.Arm.Bytes +import VerifiedGarbage.Impl.TripleDes.Arm.ExpandKey +import VerifiedGarbage.Proof.Framework.Arm.RegUpd +import VerifiedGarbage.Proof.Framework.Omega + +namespace VG.Proof.TripleDes.Arm.Key +open VG VG.Arm VG.Arm.RegUpd VG.Impl.TripleDes.Arm + +def keyKept : List Reg := [.r0, .r1, .r2, .r3] + +theorem readKey_ok (s : State) (offset : Nat) (ho : offset + 4 < 4096) + (hr : ∀ t < 2, InRegions (s.rd ++ s.wr) + (State.addr (s.gpr .r0 + BitVec.ofNat 32 (offset + 4 * t))) 4) : + ∃ s', runBlock isa [.ldr .r4 .r0 offset, .ldr .r5 .r0 (offset + 4), + .rev .r4 .r4, .rev .r5 .r5] s = some s' ∧ + s'.gpr .r4 = rev (s.mem.readW (State.addr (s.gpr .r0 + BitVec.ofNat 32 offset)) 32) ∧ + s'.gpr .r5 = rev (s.mem.readW (State.addr (s.gpr .r0 + BitVec.ofNat 32 (offset + 4))) 32) ∧ + s'.mem = s.mem ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧ + (∀ r, r ≠ .r4 → r ≠ .r5 → s'.gpr r = s.gpr r) := by + have h0 : InRegions (s.rd ++ s.wr) (State.addr (s.gpr .r0 + BitVec.ofNat 32 offset)) 4 := by + simpa only [Nat.mul_zero, Nat.add_zero] using hr 0 (by decide) + have h1 : InRegions (s.rd ++ s.wr) (State.addr (s.gpr .r0 + BitVec.ofNat 32 (offset + 4))) 4 := by + simpa only [Nat.mul_one] using hr 1 (by decide) + refine ⟨_, by + simp only [runBlock_cons, runStep_some, runBlock_nil, exec, show offset < 4096 from by omega, h0, show offset + 4 < 4096 from ho, ite_true, State.load32, + gpr_setReg, reduceCtorEq, ite_false, rd_setReg, wr_setReg, h1, + Option.map_some, mem_setReg, ite_true] + rfl, ?_, ?_, ?_, ?_, ?_, ?_⟩ + · simp only [gpr_setReg, reduceCtorEq, ite_true, ite_false] + · simp only [gpr_setReg, reduceCtorEq, ite_true, ite_false] + · simp only [mem_setReg] + · simp only [rd_setReg] + · simp only [wr_setReg] + · intro r h4 h5; simp only [gpr_setReg, h4, h5, ite_false] + +def loadTail (component : Nat) : List Instr := + [imm .r9 0, .dp .add .r8 .r2 (.imm (BitVec.ofNat 32 (128 * component)))] + +theorem loadTail_ok (s : State) (component : Nat) (hc : component < 3) : + ∃ s', runBlock isa (loadTail component) s = some s' ∧ + s'.gpr .r9 = 0 ∧ s'.gpr .r8 = s.gpr .r2 + BitVec.ofNat 32 (128 * component) ∧ + s'.mem = s.mem ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧ + (∀ r, r ≠ .r9 → r ≠ .r8 → s'.gpr r = s.gpr r) := by + have henc : encodable (BitVec.ofNat 32 (128 * component)) = true := by + have finite : ∀ c < 3, encodable (BitVec.ofNat 32 (128 * c)) = true := by decide + exact finite component hc + refine ⟨_, by + simp (config := {decide := true}) only [loadTail, imm, runBlock_cons, runStep_some, + runBlock_nil, exec, Op2.eval, Option.map_some, henc, ite_true, gpr_setReg, + ite_false] + rfl, ?_, ?_, ?_, ?_, ?_, ?_⟩ + · simp only [gpr_setReg, reduceCtorEq, ite_false, ite_true]; rfl + · simp only [gpr_setReg_self] + · simp only [mem_setReg] + · simp only [rd_setReg] + · simp only [wr_setReg] + · intro r h9 h8; simp only [gpr_setReg, h9, h8, ite_false] + +structure LoadPost (x : BitVec 56) (component : Nat) (s s' : State) : Prop where + c : s'.gpr .r10 = ((x >>> 28).setWidth 28).setWidth 32 + d : s'.gpr .r11 = (x.setWidth 28).setWidth 32 + counter : s'.gpr .r9 = 0 + ptr : s'.gpr .r8 = s.gpr .r2 + BitVec.ofNat 32 (128 * component) + mem : s'.mem = s.mem + rd : s'.rd = s.rd + wr : s'.wr = s.wr + reg : ∀ r ∈ keyKept, s'.gpr r = s.gpr r + +theorem load_ok (s : State) (offset component : Nat) (hc : component < 3) + (ho : offset + 4 < 4096) + (fit : (s.gpr .r0).toNat + offset + 8 ≤ 2 ^ 32) + (hr : ∀ t < 2, InRegions (s.rd ++ s.wr) + (State.addr (s.gpr .r0 + BitVec.ofNat 32 (offset + 4 * t))) 4) : + WP isa (.block (Impl.TripleDes.Arm.Key.load offset component)) s + (LoadPost (Spec.TripleDes.permute Spec.TripleDes.pc1 (Spec.TripleDes.decodeBlock + (Spec.TripleDes.blockAt s.mem (State.addr (s.gpr .r0 + BitVec.ofNat 32 offset))))) component s) := by + have code : Impl.TripleDes.Arm.Key.load offset component = + (([.ldr .r4 .r0 offset, .ldr .r5 .r0 (offset + 4), + .rev .r4 .r4, .rev .r5 .r5] : List Instr) ++ + permuteCode Spec.TripleDes.pc1 64 32 28 .r11 .r10 .r5 .r4 .r12 .lr) ++ loadTail component := by + simp only [Impl.TripleDes.Arm.Key.load, loadTail, List.append_assoc] + rw [code, WP.block_append_iff, WP.block_append_iff] + obtain ⟨s₁, run₁, hi₁, lo₁, mem₁, rd₁, wr₁, reg₁⟩ := readKey_ok s offset ho hr + refine WP.of_runBlock ⟨s₁, run₁, ?_⟩ + obtain ⟨s₂, run₂, lo₂, hi₂, rd₂, wr₂, _, mem₂, reg₂⟩ := pc1_ok s₁ + refine WP.of_runBlock ⟨s₂, run₂, ?_⟩ + have key₁ : packedInput 64 32 (s₁.gpr .r5) (s₁.gpr .r4) = + Spec.TripleDes.decodeBlock (Spec.TripleDes.blockAt s.mem + (State.addr (s.gpr .r0 + BitVec.ofNat 32 offset))) := by + rw [packedInput, lo₁, hi₁, decodeBlock_readW] + simp only [BitVec.setWidth_eq] + have ha : State.addr (s.gpr .r0 + BitVec.ofNat 32 (offset + 4)) = + State.addr (s.gpr .r0 + BitVec.ofNat 32 offset) + 4 := by + rw [addr_add (by omega_using [fit]), addr_add (by omega_using [fit]), + ← VG.Offset.add_ofNat_add_ofNat] + rfl + rw [ha] + rw [key₁] at lo₂ hi₂ + obtain ⟨s₃, run₃, counter₃, ptr₃, mem₃, rd₃, wr₃, reg₃⟩ := loadTail_ok s₂ component hc + refine WP.of_runBlock ⟨s₃, run₃, ⟨(reg₃ .r10 (by decide) (by decide)).trans hi₂, + (reg₃ .r11 (by decide) (by decide)).trans lo₂, counter₃, ?_, + mem₃.trans (mem₂.trans mem₁), rd₃.trans (rd₂.trans rd₁), wr₃.trans (wr₂.trans wr₁), ?_⟩⟩ + · rw [ptr₃, reg₂ .r2 (by decide +kernel), reg₁ .r2 (by decide) (by decide)] + · intro r hr + have unused : ∀ r ∈ keyKept, r ≠ .r9 ∧ r ≠ .r8 ∧ r ≠ .r4 ∧ r ≠ .r5 := by decide + have hcheck : ∀ r ∈ keyKept, + ((instrs keyPermutation1.lit).all fun op => dstOf op != some r) = true := by decide +kernel + exact (reg₃ r (unused r hr).1 (unused r hr).2.1).trans + ((reg₂ r (hcheck r hr)).trans (reg₁ r (unused r hr).2.2.1 (unused r hr).2.2.2)) + +end VG.Proof.TripleDes.Arm.Key diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Loop.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Loop.lean new file mode 100644 index 000000000..62b75e96f --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Loop.lean @@ -0,0 +1,134 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Key.Rotation +import VerifiedGarbage.Proof.TripleDes.Arm.Key.Store +import VerifiedGarbage.Proof.Framework.Offset +import VerifiedGarbage.Proof.Framework.Omega + +namespace VG.Proof.TripleDes.Arm.Key + +open VG VG.Arm +open VG.Proof.TripleDes.Arm.Key (keyKept) +open VG.Proof.TripleDes (keyPrefix keyInitial keyStep keyPrefix_succ) + +theorem pointer_fit (base : BitVec 32) (fit : base.toNat + 128 ≤ 2 ^ 32) + (j : Nat) (hj : j < 16) : (base + BitVec.ofNat 32 (8 * j)).toNat + 8 ≤ 2 ^ 32 := by + simp only [BitVec.toNat_add, BitVec.toNat_ofNat] + rw [Nat.mod_eq_of_lt (by omega_using [hj] : 8 * j < 2 ^ 32), + Nat.mod_eq_of_lt (by omega_using [fit, hj] : base.toNat + 8 * j < 2 ^ 32)] + omega_using [fit, hj] + +structure LoopState (key : BitVec 64) (base : BitVec 32) (origin : State) (j : Nat) (s : State) : Prop where + c : s.gpr .r10 = (keyPrefix key j).1.setWidth 32 + d : s.gpr .r11 = (keyPrefix key j).2.1.setWidth 32 + counter : s.gpr .r9 = BitVec.ofNat 32 j + pointer : s.gpr .r8 = base + BitVec.ofNat 32 (8 * j) + keys : ∀ i < j, ∀ hi : i < 16, s.mem.readW (State.addr base + BitVec.ofNat 64 (8 * i)) 64 = + ((keyPrefix key j).2.2[i]'hi).setWidth 64 + rd : s.rd = origin.rd + wr : s.wr = origin.wr + reg : ∀ r ∈ keyKept, s.gpr r = origin.gpr r + frame : Frame [⟨State.addr base, 128⟩] origin.mem s.mem + +def LoopInv (key : BitVec 64) (base : BitVec 32) (origin : State) (n : Nat) (s : State) : Prop := + 1 ≤ n ∧ n ≤ 16 ∧ LoopState key base origin (16 - n) s + +theorem loopBody_ok (key : BitVec 64) (base : BitVec 32) (origin : State) + (fit : base.toNat + 128 ≤ 2 ^ 32) + (hw : ∀ j < 16, ∀ t < 2, InRegions origin.wr + (State.addr (base + BitVec.ofNat 32 (8 * j) + BitVec.ofNat 32 (4 * t))) 4) + (j : Nat) (hj : j < 16) (s : State) (hs : LoopState key base origin j s) : + WP isa (.seq Impl.TripleDes.Arm.Key.rotation (.block Impl.TripleDes.Arm.Key.storeRound)) s + (fun s' => isa.eval .ne s' = some (decide (j ≠ 15)) ∧ LoopState key base origin (j + 1) s') := by + apply WP.seq + apply WP.mono (rotation_ok s _ _ j hj hs.c hs.d hs.counter) + intro s₁ h₁ + have unused : ∀ r ∈ (keyKept ++ [.r9, .r8]), + r ≠ .r4 ∧ r ≠ .r10 ∧ r ≠ .r11 := by decide + have reg₁ : ∀ r ∈ (keyKept ++ [.r9, .r8]), s₁.gpr r = s.gpr r := by + intro r hr + exact h₁.reg r (unused r hr).1 (unused r hr).2.1 (unused r hr).2.2 + have fit₁ : (s₁.gpr .r8).toNat + 8 ≤ 2 ^ 32 := by + rw [reg₁ .r8 (by decide), hs.pointer] + exact pointer_fit base fit j hj + have write₁ : ∀ t < 2, InRegions s₁.wr + (State.addr (s₁.gpr .r8 + BitVec.ofNat 32 (4 * t))) 4 := by + rw [h₁.wr, hs.wr, reg₁ .r8 (by decide), hs.pointer] + exact hw j hj + apply WP.mono (storeRound_ok s₁ _ _ j hj h₁.c h₁.d + ((reg₁ .r9 (by decide)).trans hs.counter) fit₁ write₁) + intro s₂ h₂ + have hmem : s₂.mem = s.mem.writeW (State.addr base + BitVec.ofNat 64 (8 * j)) + ((Spec.TripleDes.permute Spec.TripleDes.pc2 + ((keyPrefix key j).1.rotateLeft (Spec.TripleDes.rotations.getD j 0) ++ + (keyPrefix key j).2.1.rotateLeft (Spec.TripleDes.rotations.getD j 0))).setWidth 64) := by + rw [h₂.mem, h₁.mem, reg₁ .r8 (by decide), hs.pointer, addr_add (by omega_using [fit, hj])] + refine ⟨h₂.flag, ⟨?_, ?_, h₂.counter, ?_, ?_, h₂.rd.trans (h₁.rd.trans hs.rd), + h₂.wr.trans (h₁.wr.trans hs.wr), ?_, ?_⟩⟩ + · rw [keyPrefix_succ] + exact (h₂.reg .r10 (by decide)).trans h₁.c + · rw [keyPrefix_succ] + exact (h₂.reg .r11 (by decide)).trans h₁.d + · rw [h₂.ptr, reg₁ .r8 (by decide), hs.pointer] + change base + BitVec.ofNat 32 (8 * j) + BitVec.ofNat 32 8 = _ + rw [Offset.add_ofNat_add_ofNat] + exact congrArg (fun n => base + BitVec.ofNat 32 n) (by omega) + · intro i hi hi16 + rw [hmem, keyPrefix_succ] + by_cases he : i = j + · subst i + rw [Mem.readW_writeW_self64] + exact congrArg (BitVec.setWidth 64) (Vector.getElem_set!_self hj).symm + · rw [Mem.readW_writeW_sep (Offset.sep (State.addr base) (by omega_using [hi, he]) + (by omega_using [hi16]) (by omega_using [hj])) (by decide), hs.keys i (by omega_using [hi, he]) hi16] + exact congrArg (BitVec.setWidth 64) (Vector.getElem_set!_ne hi16 (Ne.symm he)).symm + · intro r hr + have incl : ∀ r ∈ keyKept, + r ∈ (keyKept ++ [.r10, .r11]) ∧ + r ∈ (keyKept ++ [.r9, .r8]) := by decide + exact (h₂.reg r (incl r hr).1).trans ((reg₁ r (incl r hr).2).trans (hs.reg r hr)) + · rw [hmem] + exact hs.frame.writeW (List.mem_singleton_self _) _ + (Offset.contains_base (State.addr base) (by omega_using [hj]) (by omega_using [hj])) + +theorem loopStep (key : BitVec 64) (base : BitVec 32) (origin : State) + (fit : base.toNat + 128 ≤ 2 ^ 32) + (hw : ∀ j < 16, ∀ t < 2, InRegions origin.wr + (State.addr (base + BitVec.ofNat 32 (8 * j) + BitVec.ofNat 32 (4 * t))) 4) + (n : Nat) (s : State) (hs : LoopInv key base origin n s) : + WP isa (.seq Impl.TripleDes.Arm.Key.rotation (.block Impl.TripleDes.Arm.Key.storeRound)) s + (fun s' => (isa.eval .ne s' = some false ∧ LoopState key base origin 16 s') ∨ + (isa.eval .ne s' = some true ∧ ∃ m < n, LoopInv key base origin m s')) := by + apply WP.mono (loopBody_ok key base origin fit hw (16 - n) (by omega_using [hs.1]) s hs.2.2) + intro s' h + by_cases last : n = 1 + · left + have idx : 16 - n = 15 := by omega_using [last] + refine ⟨?_, ?_⟩ + · simpa only [idx, ne_eq, not_true_eq_false, decide_false] using h.1 + · simpa only [idx] using h.2 + · right + have idx : ¬16 - n = 15 := by omega_using [hs.1, hs.2.1, last] + refine ⟨?_, n - 1, by omega_using [hs.1], ?_⟩ + · simpa only [idx, ne_eq, not_false_eq_true, decide_true] using h.1 + · refine ⟨by omega_using [hs.1, last], by omega_using [hs.2.1], ?_⟩ + have eq : 16 - n + 1 = 16 - (n - 1) := by omega_using [hs.1, hs.2.1] + rw [← eq] + exact h.2 + +theorem loop_ok (key : BitVec 64) (base : BitVec 32) (s : State) + (fit : base.toNat + 128 ≤ 2 ^ 32) + (hw : ∀ j < 16, ∀ t < 2, InRegions s.wr + (State.addr (base + BitVec.ofNat 32 (8 * j) + BitVec.ofNat 32 (4 * t))) 4) + (hc : s.gpr .r10 = (keyInitial key).1.setWidth 32) + (hd : s.gpr .r11 = (keyInitial key).2.1.setWidth 32) + (hcount : s.gpr .r9 = 0) (hptr : s.gpr .r8 = base) : + WP isa (.loop (.seq Impl.TripleDes.Arm.Key.rotation + (.block Impl.TripleDes.Arm.Key.storeRound)) .ne) s (LoopState key base s 16) := by + apply WP.loop (M := isa) (body := .seq Impl.TripleDes.Arm.Key.rotation + (.block Impl.TripleDes.Arm.Key.storeRound)) (c := .ne) + (Q := LoopState key base s 16) (LoopInv key base s) (loopStep key base s fit hw) 16 s + refine ⟨by decide, by decide, hc, hd, hcount, ?_, ?_, rfl, rfl, fun _ _ => rfl, Frame.refl _ _⟩ + · exact hptr.trans (BitVec.add_zero base).symm + · intro i hi + omega + +end VG.Proof.TripleDes.Arm.Key diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Permutation.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Permutation.lean new file mode 100644 index 000000000..cf766b922 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Permutation.lean @@ -0,0 +1,39 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Permutation + +namespace VG.Proof.TripleDes.Arm.Key +open VG VG.Arm VG.Impl.TripleDes.Arm + +theorem pc1_ok (s : State) : + ∃ s', runBlock isa (permuteCode Spec.TripleDes.pc1 64 32 28 .r11 .r10 .r5 .r4 .r12 .lr) s = some s' ∧ + s'.gpr .r11 = ((Spec.TripleDes.permute Spec.TripleDes.pc1 (packedInput 64 32 (s.gpr .r5) (s.gpr .r4))).setWidth 28).setWidth 32 ∧ + s'.gpr .r10 = (((Spec.TripleDes.permute Spec.TripleDes.pc1 (packedInput 64 32 (s.gpr .r5) (s.gpr .r4))) >>> 28).setWidth 28).setWidth 32 ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ s'.mem = s.mem ∧ + (∀ r, ((instrs keyPermutation1.lit).all fun op => dstOf op != some r) = true → + s'.gpr r = s.gpr r) := by + obtain ⟨s', run, lo, hi, rd, wr, sp, mem, regs⟩ := + fixedPermutation_ok Spec.TripleDes.pc1 (by decide) 32 28 + (by decide) (by decide) (by decide) (by decide) (by decide) + .r5 .r4 .r11 .r10 (instrs keyPermutation1.lit) keyPermutation1_check s + have hcode : permuteCode Spec.TripleDes.pc1 64 32 28 .r11 .r10 .r5 .r4 .r12 .lr = instrs keyPermutation1.lit := + congrArg instrs keyPermutation1.lit_eq + exact ⟨s', (congrArg (fun is => runBlock isa is s) hcode).trans run, + lo, hi, rd, wr, sp, mem, regs⟩ + + +theorem pc2_ok (s : State) : + ∃ s', runBlock isa (permuteCode Spec.TripleDes.pc2 56 28 32 .r4 .r5 .r11 .r10 .r12 .lr) s = some s' ∧ + s'.gpr .r4 = ((Spec.TripleDes.permute Spec.TripleDes.pc2 (packedInput 56 28 (s.gpr .r11) (s.gpr .r10))).setWidth 32).setWidth 32 ∧ + s'.gpr .r5 = (((Spec.TripleDes.permute Spec.TripleDes.pc2 (packedInput 56 28 (s.gpr .r11) (s.gpr .r10))) >>> 32).setWidth 16).setWidth 32 ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ s'.mem = s.mem ∧ + (∀ r, ((instrs keyPermutation2.lit).all fun op => dstOf op != some r) = true → + s'.gpr r = s.gpr r) := by + obtain ⟨s', run, lo, hi, rd, wr, sp, mem, regs⟩ := + fixedPermutation_ok Spec.TripleDes.pc2 (by decide) 28 32 + (by decide) (by decide) (by decide) (by decide) (by decide) + .r11 .r10 .r4 .r5 (instrs keyPermutation2.lit) keyPermutation2_check s + have hcode : permuteCode Spec.TripleDes.pc2 56 28 32 .r4 .r5 .r11 .r10 .r12 .lr = instrs keyPermutation2.lit := + congrArg instrs keyPermutation2.lit_eq + exact ⟨s', (congrArg (fun is => runBlock isa is s) hcode).trans run, + lo, hi, rd, wr, sp, mem, regs⟩ + +end VG.Proof.TripleDes.Arm.Key diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Rotation.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Rotation.lean new file mode 100644 index 000000000..2692d3b44 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Rotation.lean @@ -0,0 +1,135 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.KeySteps +import VerifiedGarbage.Proof.TripleDes.KeySchedule +import VerifiedGarbage.Proof.Rc2.Arm.Lookup +import VerifiedGarbage.Proof.Rc2.Arm.KeySteps + +namespace VG.Proof.TripleDes.Arm.Key + +open VG VG.Arm VG.Arm.RegUpd VG.Impl.TripleDes.Arm +open VG.Proof.Rc2.Arm (Keep) + +structure RotatePost (c d : BitVec 28) (n : Nat) (s s' : State) : Prop where + c : s'.gpr .r10 = (c.rotateLeft n).setWidth 32 + d : s'.gpr .r11 = (d.rotateLeft n).setWidth 32 + mem : s'.mem = s.mem + rd : s'.rd = s.rd + wr : s'.wr = s.wr + reg : ∀ r, r ≠ .r4 → r ≠ .r10 → r ≠ .r11 → s'.gpr r = s.gpr r + +theorem rotate_ok (s : State) (c d : BitVec 28) + (hc : s.gpr .r10 = c.setWidth 32) (hd : s.gpr .r11 = d.setWidth 32) + (n : Nat) (hn : 1 ≤ n) (hn' : n < 5) : + WP isa (Impl.TripleDes.Arm.Key.rotate n) s (RotatePost c d n s) := by + rw [Impl.TripleDes.Arm.Key.rotate, WP.block_append_iff] + obtain ⟨s₁, run₁, c₁, mem₁, rd₁, wr₁, _, reg₁⟩ := rotate28_ok s .r10 (by decide) c hc n hn hn' + refine WP.of_runBlock ⟨s₁, run₁, ?_⟩ + have d₁ : s₁.gpr .r11 = d.setWidth 32 := (reg₁ .r11 (by decide) (by decide)).trans hd + obtain ⟨s₂, run₂, d₂, mem₂, rd₂, wr₂, _, reg₂⟩ := rotate28_ok s₁ .r11 (by decide) d d₁ n hn hn' + refine WP.of_runBlock ⟨s₂, run₂, ⟨(reg₂ .r10 (by decide) (by decide)).trans c₁, d₂, + mem₂.trans mem₁, rd₂.trans rd₁, wr₂.trans wr₁, ?_⟩⟩ + intro r ha hc hd + exact (reg₂ r hd ha).trans (reg₁ r hc ha) + +theorem comparison_values : ∀ j < 16, ∀ k < 16, + ((BitVec.ofNat 32 j >>> 1) == (0 : BitVec 32)) = decide (j < 2) ∧ + ((BitVec.ofNat 32 j - BitVec.ofNat 32 k) == (0 : BitVec 32)) = decide (j = k) := by + decide + +theorem lowTest_ok (s : State) (j : Nat) (hj : j < 16) + (hv : s.gpr .r9 = BitVec.ofNat 32 j) : + ∃ s', runBlock isa [.mov .r4 (.shifted .r9 .lsr 1), .cmp .r4 (.imm 0)] s = some s' ∧ + isa.eval .eq s' = some (decide (j < 2)) ∧ Keep [.r4] s s' := by + refine ⟨_, by + simp (config := {decide := true}) only [runBlock_cons, runStep_some, runBlock_nil, + exec, Op2.eval, Option.map_some, gpr_setReg, ite_true] + rfl, ?_, ?_⟩ + · change some (((s.gpr .r9 >>> 1) - 0) == 0) = _ + have hz : (s.gpr .r9 >>> 1) - (0 : BitVec 32) = s.gpr .r9 >>> 1 := by bv_omega + rw [hz, hv] + exact congrArg some (comparison_values j hj 0 (by decide)).1 + · refine ⟨?_, ?_, ?_, ?_⟩ + · intro r hr + simp only [List.mem_singleton] at hr + simp only [VG.Proof.Rc2.Arm.gpr_subFlags, gpr_setReg, hr, ite_false] + · rfl + · rfl + · rfl + +theorem eqTest_ok (s : State) (j k : Nat) (hj : j < 16) (hk : k < 16) + (hv : s.gpr .r9 = BitVec.ofNat 32 j) : + ∃ s', runBlock isa [.cmp .r9 (.imm (BitVec.ofNat 32 k))] s = some s' ∧ + isa.eval .eq s' = some (decide (j = k)) ∧ Keep [.r4] s s' := by + have henc : encodable (BitVec.ofNat 32 k) = true := by + have hfinite : ∀ k < 16, encodable (BitVec.ofNat 32 k) = true := by decide + exact hfinite k hk + refine ⟨_, by + simp only [runBlock_cons, runStep_some, runBlock_nil, exec, Op2.eval, + henc, ite_true, Option.map_some] + rfl, ?_, ?_⟩ + · change some ((s.gpr .r9 - BitVec.ofNat 32 k) == 0) = _ + rw [hv] + exact congrArg some (comparison_values j hj k hk).2 + · exact ⟨fun _ _ => rfl, rfl, rfl, rfl⟩ + +theorem rotation_ok (s : State) (c d : BitVec 28) (j : Nat) (hj : j < 16) + (hc : s.gpr .r10 = c.setWidth 32) (hd : s.gpr .r11 = d.setWidth 32) + (hjreg : s.gpr .r9 = BitVec.ofNat 32 j) : + WP isa Impl.TripleDes.Arm.Key.rotation s + (RotatePost c d (Spec.TripleDes.rotations.getD j 0) s) := by + rw [Impl.TripleDes.Arm.Key.rotation] + apply WP.seq + obtain ⟨s₁, run₁, cond₁, keep₁⟩ := lowTest_ok s j hj hjreg + refine WP.of_runBlock ⟨s₁, run₁, ?_⟩ + have hrot (s' : State) (h : Keep [.r4] s s') (n : Nat) (hn : 1 ≤ n) (hn' : n < 5) + (hv : Spec.TripleDes.rotations.getD j 0 = n) : + WP isa (Impl.TripleDes.Arm.Key.rotate n) s' (RotatePost c d (Spec.TripleDes.rotations.getD j 0) s) := by + apply WP.mono (rotate_ok s' c d ((h.reg .r10 (by simp)).trans hc) + ((h.reg .r11 (by simp)).trans hd) n hn hn') + intro t ht + rw [hv] + exact ⟨ht.c, ht.d, ht.mem.trans h.mem, ht.rd.trans h.rd, ht.wr.trans h.wr, + fun r ha hc hd => (ht.reg r ha hc hd).trans (h.reg r (by simpa only [List.mem_singleton] using ha))⟩ + have combine {a b : State} (ha : Keep [.r4] s a) (hb : Keep [.r4] a b) : Keep [.r4] s b := + ⟨fun r hr => (hb.reg r hr).trans (ha.reg r hr), hb.mem.trans ha.mem, + hb.rd.trans ha.rd, hb.wr.trans ha.wr⟩ + by_cases h2 : j < 2 + · apply WP.ite true (by simpa only [h2, decide_true] using cond₁) + · intro _ + exact hrot s₁ keep₁ 1 (by decide) (by decide) + (by rw [VG.Proof.TripleDes.rotation_value j hj, ite_eq_left (Or.inl h2)]) + · simp + · apply WP.ite false (by simpa only [h2, decide_false] using cond₁) + · simp + · intro _ + apply WP.seq + obtain ⟨s₂, run₂, cond₂, keep₂⟩ := eqTest_ok s₁ j 8 hj (by decide) + ((keep₁.reg .r9 (by simp)).trans hjreg) + refine WP.of_runBlock ⟨s₂, run₂, ?_⟩ + have keep₂' := combine keep₁ keep₂ + by_cases h8 : j = 8 + · apply WP.ite true (by simpa only [h8, decide_true] using cond₂) + · intro _ + exact hrot s₂ keep₂' 1 (by decide) (by decide) + (by rw [VG.Proof.TripleDes.rotation_value j hj, ite_eq_left (Or.inr (Or.inl h8))]) + · simp + · apply WP.ite false (by simpa only [h8, decide_false] using cond₂) + · simp + · intro _ + apply WP.seq + obtain ⟨s₃, run₃, cond₃, keep₃⟩ := eqTest_ok s₂ j 15 hj (by decide) + ((keep₂'.reg .r9 (by simp)).trans hjreg) + refine WP.of_runBlock ⟨s₃, run₃, ?_⟩ + have keep₃' := combine keep₂' keep₃ + by_cases h15 : j = 15 + · apply WP.ite true (by simpa only [h15, decide_true] using cond₃) + · intro _ + exact hrot s₃ keep₃' 1 (by decide) (by decide) + (by rw [VG.Proof.TripleDes.rotation_value j hj, ite_eq_left (Or.inr (Or.inr h15))]) + · simp + · apply WP.ite false (by simpa only [h15, decide_false] using cond₃) + · simp + · intro _ + exact hrot s₃ keep₃' 2 (by decide) (by decide) + (by rw [VG.Proof.TripleDes.rotation_value j hj, ite_eq_right (by simp only [h2, h8, h15, or_self, not_false_eq_true])]) + +end VG.Proof.TripleDes.Arm.Key diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Save.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Save.lean new file mode 100644 index 000000000..16feabb50 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Save.lean @@ -0,0 +1,57 @@ +import VerifiedGarbage.Proof.Rc2.Arm.Save +import VerifiedGarbage.Impl.TripleDes.Arm.ExpandKey + +namespace VG.Proof.TripleDes.Arm.Key + +open VG VG.Arm VG.Impl.TripleDes.Arm + +/-- The nine callee-saved registers, in slot order. -/ +def savedReg (i : Nat) : Reg := (Impl.TripleDes.Arm.Key.savedRegs).getD i .r4 + +theorem save_eq : Impl.TripleDes.Arm.Key.save = VG.Proof.Rc2.Arm.saveCode .r3 savedReg 9 := by + decide +kernel + +theorem restore_eq : Impl.TripleDes.Arm.Key.restore = VG.Proof.Rc2.Arm.restoreCode .r3 savedReg (List.range 9) := by + decide +kernel + +def Saved (original current : State) : Prop := + ∀ i < 9, current.mem.readW (State.addr (current.gpr .r3) + BitVec.ofNat 64 (4 * i)) 32 = + original.gpr (savedReg i) + +theorem save_ok (s : State) + (fit : (s.gpr .r3).toNat + 256 ≤ 2 ^ 32) + (hw : ∀ i < 9, InRegions s.wr (State.addr (s.gpr .r3) + BitVec.ofNat 64 (4 * i)) 4) : + WP isa (.block Impl.TripleDes.Arm.Key.save) s (fun s' => + s'.gpr = s.gpr ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧ Saved s s' ∧ + Frame [⟨State.addr (s.gpr .r3), 36⟩] s.mem s'.mem) := by + rw [save_eq] + apply WP.mono (VG.Proof.Rc2.Arm.saveCode_ok s .r3 savedReg 9 (by decide) fit hw) + intro s' hs + refine ⟨hs.1, hs.2.1, hs.2.2.1, ?_, ?_⟩ + · intro i hi + rw [hs.1, hs.2.2.2] + exact VG.Proof.Rc2.Arm.saveMem_read _ _ _ 9 (by decide) i hi + · rw [hs.2.2.2] + exact VG.Proof.Rc2.Arm.saveMem_frame _ _ _ 9 (by decide) + +theorem savedReg_separate : ∀ i < 9, savedReg i ≠ .r3 := by decide +kernel + +theorem restore_ok (original s : State) (hsaved : Saved original s) + (fit : (s.gpr .r3).toNat + 256 ≤ 2 ^ 32) + (hread : ∀ i < 9, InRegions (s.rd ++ s.wr) (State.addr (s.gpr .r3) + BitVec.ofNat 64 (4 * i)) 4) : + WP isa (.block Impl.TripleDes.Arm.Key.restore) s (fun s' => + (∀ r ∈ Impl.TripleDes.Arm.Key.savedRegs, s'.gpr r = original.gpr r) ∧ + VG.Proof.Rc2.Arm.Keep (Impl.TripleDes.Arm.Key.savedRegs) s s') := by + rw [restore_eq] + have hregs : (List.range 9).map savedReg = Impl.TripleDes.Arm.Key.savedRegs := by decide +kernel + have h := VG.Proof.Rc2.Arm.restoreCode_ok s .r3 savedReg (List.range 9) original.gpr fit + (fun i hi => by have := List.mem_range.mp hi; omega) + (fun i hi => savedReg_separate i (List.mem_range.mp hi)) + (fun i hi => hread i (List.mem_range.mp hi)) + (fun i hi => hsaved i (List.mem_range.mp hi)) + rw [hregs] at h + exact h + + + +end VG.Proof.TripleDes.Arm.Key diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Store.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Store.lean new file mode 100644 index 000000000..eb6b84b1e --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Store.lean @@ -0,0 +1,91 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Key.Load +import VerifiedGarbage.Proof.TripleDes.Arm.WordStore +import VerifiedGarbage.Proof.TripleDes.Arm.Word +import VerifiedGarbage.Proof.Rc2.Arm.KeySteps + +namespace VG.Proof.TripleDes.Arm.Key +open VG VG.Arm VG.Arm.RegUpd VG.Impl.TripleDes.Arm +open VG.Proof.Rc2.Arm (gpr_subFlags mem_subFlags rd_subFlags wr_subFlags) + +def tail : List Instr := [.str .r4 .r8 0, .str .r5 .r8 4, + .dp .add .r8 .r8 (.imm 8), .dp .add .r9 .r9 (.imm 1), .cmp .r9 (.imm 16)] + +theorem nextRound_values : ∀ j < 16, + BitVec.ofNat 32 j + 1 = BitVec.ofNat 32 (j + 1) ∧ + (!(BitVec.ofNat 32 j + 1 - (16 : BitVec 32) == 0)) = decide (j ≠ 15) := by decide + +theorem tail_ok (s : State) (j : Nat) (hj : j < 16) + (hc : s.gpr .r9 = BitVec.ofNat 32 j) + (fit : (s.gpr .r8).toNat + 8 ≤ 2 ^ 32) + (hw : ∀ t < 2, InRegions s.wr (State.addr (s.gpr .r8 + BitVec.ofNat 32 (4 * t))) 4) : + ∃ s', runBlock isa tail s = some s' ∧ + s'.mem = s.mem.writeW (State.addr (s.gpr .r8)) (s.gpr .r5 ++ s.gpr .r4) ∧ + s'.gpr .r8 = s.gpr .r8 + 8 ∧ s'.gpr .r9 = BitVec.ofNat 32 (j + 1) ∧ + isa.eval .ne s' = some (decide (j ≠ 15)) ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ + (∀ r, r ≠ .r9 → r ≠ .r8 → s'.gpr r = s.gpr r) := by + have h0 : InRegions s.wr (State.addr (s.gpr .r8 + BitVec.ofNat 32 0)) 4 := by + simpa only [Nat.mul_zero] using hw 0 (by decide) + have h1 : InRegions s.wr (State.addr (s.gpr .r8 + BitVec.ofNat 32 4)) 4 := by + simpa only [Nat.mul_one] using hw 1 (by decide) + refine ⟨_, by + simp (config := {decide := true}) only [tail, runBlock_cons, runStep_some, runBlock_nil, + exec, State.store32, h0, h1, ite_true, Op2.eval, Option.map_some, + gpr_setReg, ite_false, ite_true] + rfl, ?_, ?_, ?_, ?_, ?_, ?_, ?_⟩ + · simp only [mem_subFlags, mem_setReg, BitVec.add_zero] + rw [addr_add (by omega_using [fit])] + exact writeW_pair s.mem _ _ _ + · simp only [gpr_subFlags, gpr_setReg, reduceCtorEq, ite_false, ite_true] + · simp only [gpr_subFlags, gpr_setReg, reduceCtorEq, ite_false, ite_true] + rw [hc]; exact (nextRound_values j hj).1 + · change VG.Arm.eval .ne _ = _ + simp only [VG.Arm.eval, subFlags, hc] + exact congrArg some (nextRound_values j hj).2 + · simp only [rd_subFlags, rd_setReg] + · simp only [wr_subFlags, wr_setReg] + · intro r h9 h8; simp only [gpr_subFlags, gpr_setReg, h9, h8, ite_false] + +structure StorePost (c d : BitVec 28) (j : Nat) (s s' : State) : Prop where + mem : s'.mem = s.mem.writeW (State.addr (s.gpr .r8)) + ((Spec.TripleDes.permute Spec.TripleDes.pc2 (c ++ d)).setWidth 64) + ptr : s'.gpr .r8 = s.gpr .r8 + 8 + counter : s'.gpr .r9 = BitVec.ofNat 32 (j + 1) + flag : isa.eval .ne s' = some (decide (j ≠ 15)) + rd : s'.rd = s.rd + wr : s'.wr = s.wr + reg : ∀ r ∈ (keyKept ++ [.r10, .r11]), s'.gpr r = s.gpr r + +theorem storeRound_ok (s : State) (c d : BitVec 28) (j : Nat) (hj : j < 16) + (hc : s.gpr .r10 = c.setWidth 32) (hd : s.gpr .r11 = d.setWidth 32) + (hjreg : s.gpr .r9 = BitVec.ofNat 32 j) + (fit : (s.gpr .r8).toNat + 8 ≤ 2 ^ 32) + (hw : ∀ t < 2, InRegions s.wr (State.addr (s.gpr .r8 + BitVec.ofNat 32 (4 * t))) 4) : + WP isa (.block Impl.TripleDes.Arm.Key.storeRound) s (StorePost c d j s) := by + have code : Impl.TripleDes.Arm.Key.storeRound = + permuteCode Spec.TripleDes.pc2 56 28 32 .r4 .r5 .r11 .r10 .r12 .lr ++ tail := rfl + rw [code, WP.block_append_iff] + obtain ⟨s₁, run₁, lo₁, hi₁, rd₁, wr₁, _, mem₁, reg₁⟩ := pc2_ok s + refine WP.of_runBlock ⟨s₁, run₁, ?_⟩ + have input : packedInput 56 28 (s.gpr .r11) (s.gpr .r10) = c ++ d := by + rw [hd, hc]; exact packed28 c d + rw [input] at lo₁ hi₁ + have checks : ∀ r ∈ (keyKept ++ [.r10, .r11, .r9, .r8]), + ((instrs keyPermutation2.lit).all fun op => dstOf op != some r) = true := by decide +kernel + have keep₁ : ∀ r ∈ (keyKept ++ [.r10, .r11, .r9, .r8]), s₁.gpr r = s.gpr r := + fun r hr => reg₁ r (checks r hr) + have write₁ : ∀ t < 2, InRegions s₁.wr (State.addr (s₁.gpr .r8 + BitVec.ofNat 32 (4 * t))) 4 := by + rw [wr₁, keep₁ .r8 (by decide)]; exact hw + have fit₁ : (s₁.gpr .r8).toNat + 8 ≤ 2 ^ 32 := by + rw [keep₁ .r8 (by decide)]; exact fit + obtain ⟨s₂, run₂, mem₂, ptr₂, counter₂, flag₂, rd₂, wr₂, reg₂⟩ := + tail_ok s₁ j hj ((keep₁ .r9 (by decide)).trans hjreg) fit₁ write₁ + refine WP.of_runBlock ⟨s₂, run₂, ⟨?_, ?_, counter₂, flag₂, rd₂.trans rd₁, wr₂.trans wr₁, ?_⟩⟩ + · rw [mem₂, mem₁, keep₁ .r8 (by decide), lo₁, hi₁, BitVec.setWidth_eq, packed48] + · rw [ptr₂, keep₁ .r8 (by decide)] + · intro r hr + have incl : ∀ r ∈ (keyKept ++ [.r10, .r11]), + r ≠ .r9 ∧ r ≠ .r8 ∧ r ∈ (keyKept ++ [.r10, .r11, .r9, .r8]) := by decide + exact (reg₂ r (incl r hr).1 (incl r hr).2.1).trans (keep₁ r (incl r hr).2.2) + +end VG.Proof.TripleDes.Arm.Key diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Verified.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Verified.lean new file mode 100644 index 000000000..ab5ddd393 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Key/Verified.lean @@ -0,0 +1,35 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Key.Correct +import VerifiedGarbage.Proof.Framework.Contract + +namespace VG.Proof.TripleDes.Arm.Key + +open VG VG.Arm + +def satState : State where + gpr r := match r with + | .r0 => 0x1000 | .r1 => 16 | .r2 => 0x2000 | .r3 => 0x3000 | _ => 0 + sp := 0x4000 + n := false + z := false + c := false + v := false + mem _ := 0 + rd := [⟨0x1000, 16⟩] + wr := [⟨0x2000, 384⟩, ⟨0x3000, 512⟩] + +theorem correct (s : State) (hs : contract.pre s) : + ∃ t s', Exec isa Impl.TripleDes.Arm.Key.expandKey s t s' ∧ abiPreserved s s' ∧ contract.post s s' := by + obtain ⟨t, s', he, ha, hp⟩ := expand_correct s hs + exact ⟨t, s', he, ⟨ha, VG.Arm.Exec.sp he⟩, hp⟩ + +theorem publicRegs_four (s₁ s₂ : State) : PublicRegs [.r0, .r1, .r2, .r3] s₁ s₂ ↔ + s₁.sp = s₂.sp ∧ s₁.gpr .r0 = s₂.gpr .r0 ∧ s₁.gpr .r1 = s₂.gpr .r1 ∧ s₁.gpr .r2 = s₂.gpr .r2 ∧ + s₁.gpr .r3 = s₂.gpr .r3 := by simp [PublicRegs] + +theorem verified : Verified target Impl.TripleDes.Arm.Key.expandKey + (Spec.TripleDes.expandKeyContract abi) := by + refine Verified.of_correct correct (expandKey_constantTime _) ?_ + sig_implies [Spec.TripleDes.expandKeyContract, Spec.TripleDes.expandKeySig, abi, argRegs, Arm.reduceClassify, Arm.Loc.val, State.addr, + contract, publicRegs_four] [satState] using satState + +end VG.Proof.TripleDes.Arm.Key diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/KeySteps.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/KeySteps.lean new file mode 100644 index 000000000..8eabef7d3 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/KeySteps.lean @@ -0,0 +1,32 @@ +import VerifiedGarbage.Impl.TripleDes.Arm.ExpandKey +import VerifiedGarbage.Proof.TripleDes.Arm.Word +import VerifiedGarbage.Proof.Framework.Arm.Exec +import VerifiedGarbage.Proof.Framework.Arm.RegUpd + +namespace VG.Proof.TripleDes.Arm +open VG VG.Arm VG.Arm.RegUpd VG.Impl.TripleDes.Arm + +theorem rotate28_ok (s : State) (r : Reg) (hr : r ≠ .r4) + (x : BitVec 28) (hx : s.gpr r = x.setWidth 32) + (n : Nat) (hn : 1 ≤ n) (hn' : n < 5) : + ∃ s', runBlock isa (Key.rotate28 r n) s = some s' ∧ + s'.gpr r = (x.rotateLeft n).setWidth 32 ∧ + s'.mem = s.mem ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ + (∀ r', r' ≠ r → r' ≠ .r4 → s'.gpr r' = s.gpr r') := by + have hleft : 1 ≤ 32 - n ∧ 32 - n ≤ 31 := by omega + have hright : 1 ≤ 28 - n ∧ 28 - n ≤ 31 := by omega + refine ⟨_, by + simp only [Key.rotate28, mask, List.cons_append, List.nil_append, + runBlock_cons, runStep_some, runBlock_nil, exec, Op2.eval, hleft.1, hleft.2, hright.1, hright.2, + show 1 ≤ (4 : Nat) from by decide, show (4 : Nat) ≤ 31 from by decide, and_self, ite_true, Option.map_some, + hr, Ne.symm hr, gpr_setReg, ite_false] + rfl, ?_, ?_, ?_, ?_, ?_, ?_⟩ + · simp only [gpr_setReg, ite_true, hr, ite_false] + rw [hx, mask_word _ 28 (by decide) (by decide)] + exact (mask28 _).symm.trans (rotate28_word x n hn hn') + · simp only [mem_setReg] + · simp only [rd_setReg] + · simp only [wr_setReg] + · simp only [sp_setReg] + · intro r' h1 h2; simp only [gpr_setReg, h1, h2, ite_false] +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Lit.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Lit.lean new file mode 100644 index 000000000..674f1a19c --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Lit.lean @@ -0,0 +1,22 @@ +import VerifiedGarbage.Impl.TripleDes.Arm.Sbox +import VerifiedGarbage.Impl.TripleDes.Arm.Permutation +import VerifiedGarbage.Proof.Framework.Arm.Lit + +namespace VG.Impl.TripleDes.Arm + +materialize_code sbox0 +materialize_code sbox1 +materialize_code sbox2 +materialize_code sbox3 +materialize_code sbox4 +materialize_code sbox5 +materialize_code sbox6 +materialize_code sbox7 + + +materialize_code initialPermutation +materialize_code finalPermutation +materialize_code keyPermutation1 +materialize_code keyPermutation2 + +end VG.Impl.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Loop.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Loop.lean new file mode 100644 index 000000000..a61f44ef1 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Loop.lean @@ -0,0 +1,160 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.RoundStep +import VerifiedGarbage.Proof.TripleDes.Core +import VerifiedGarbage.Proof.Framework.Omega + +namespace VG.Proof.TripleDes.Arm + +open VG VG.Arm VG.Arm.Straight VG.Impl.TripleDes.Arm +open VG.Spec.TripleDes (Direction DesSchedule) +open VG.Proof.TripleDes (roundKey roundPrefix feistelStep) + +def keyAddr (base : BitVec 32) (direction : Direction) (j : Nat) : BitVec 32 := + base + BitVec.ofNat 32 (8 * (if direction = .encrypt then j else 15 - j)) + +def readKey (m : Mem) (ptr : BitVec 32) : BitVec 64 := + m.readW (wordAddr ptr 1) 32 ++ m.readW (wordAddr ptr 0) 32 + +theorem readKey_frame {m m' : Mem} {ptr : BitVec 32} {regions : List Region} + (hf : Frame regions m m') + (sep : ∀ j < 2, ∀ r ∈ regions, (⟨wordAddr ptr j, 4⟩ : Region).Disjoint r) : + readKey m' ptr = readKey m ptr := by + exact congrArg₂ (fun hi lo : BitVec 32 => hi ++ lo) + (hf.readW (a := wordAddr ptr 1) (w := 32) (r := ⟨wordAddr ptr 1, 4⟩) + (Region.contains_self _ _) (sep 1 (by decide)) (by decide)) + (hf.readW (a := wordAddr ptr 0) (w := 32) (r := ⟨wordAddr ptr 0, 4⟩) + (Region.contains_self _ _) (sep 0 (by decide)) (by decide)) + +theorem keyAddr_step (base : BitVec 32) (direction : Direction) (j : Nat) (hj : j < 15) : + (if direction = .encrypt then keyAddr base direction j + 8 + else keyAddr base direction j - 8) = keyAddr base direction (j + 1) := by + cases direction + · change base + BitVec.ofNat 32 (8 * j) + BitVec.ofNat 32 8 = base + BitVec.ofNat 32 (8 * (j + 1)) + rw [Offset.add_ofNat_add_ofNat] + exact congrArg (fun n => base + BitVec.ofNat 32 n) (by omega) + · change base + BitVec.ofNat 32 (8 * (15 - j)) - BitVec.ofNat 32 8 = base + BitVec.ofNat 32 (8 * (15 - (j + 1))) + rw [BitVec.sub_eq_add_neg, BitVec.add_assoc, ← BitVec.sub_eq_add_neg, + Offset.ofNat_sub_ofNat (by omega)] + exact congrArg (fun n => base + BitVec.ofNat 32 n) (by omega) + +def endPointer (base : BitVec 32) (d : Direction) : BitVec 32 := + if d = .encrypt then base + 128 else base - 8 + +theorem keyAddr_end (base : BitVec 32) (d : Direction) : + (if d = .encrypt then keyAddr base d 15 + 8 else keyAddr base d 15 - 8) = endPointer base d := by + cases d <;> simp only [endPointer, keyAddr, reduceCtorEq, ite_true, ite_false, Nat.reduceSub, Nat.reduceMul] + · change base + BitVec.ofNat 32 120 + BitVec.ofNat 32 8 = base + BitVec.ofNat 32 128 + rw [Offset.add_ofNat_add_ofNat] + · rw [BitVec.add_zero] + +structure LoopInv (keys : DesSchedule) (direction : Direction) (base : BitVec 32) + (origin : State) (v : BitVec 32 × BitVec 32) (n : Nat) (s : State) : Prop where + positive : 1 ≤ n + bounded : n ≤ 16 + left : s.gpr .r10 = (roundPrefix keys direction (16 - n) v).1 + right : s.gpr .r11 = (roundPrefix keys direction (16 - n) v).2 + counter : s.gpr .r9 = BitVec.ofNat 32 n + pointer : s.gpr .r0 = keyAddr base direction (16 - n) + rd : s.rd = origin.rd + wr : s.wr = origin.wr + sp : s.sp = origin.sp + regs : ∀ q ∈ roundStepKept, s.gpr q = origin.gpr q + frame : Frame [spillRegion origin] origin.mem s.mem + +structure LoopPost (keys : DesSchedule) (direction : Direction) (base : BitVec 32) + (origin : State) (v : BitVec 32 × BitVec 32) (s : State) : Prop where + left : s.gpr .r10 = (roundPrefix keys direction 16 v).1 + right : s.gpr .r11 = (roundPrefix keys direction 16 v).2 + counter : s.gpr .r9 = 0 + pointer : s.gpr .r0 = endPointer base direction + rd : s.rd = origin.rd + wr : s.wr = origin.wr + sp : s.sp = origin.sp + regs : ∀ q ∈ roundStepKept, s.gpr q = origin.gpr q + frame : Frame [spillRegion origin] origin.mem s.mem + +theorem loopStep (keys : DesSchedule) (direction : Direction) (base : BitVec 32) + (origin : State) (v : BitVec 32 × BitVec 32) + (hok : Ok sboxCfg origin) + (hread : ∀ j < 16, ∀ t < 2, InRegions (origin.rd ++ origin.wr) (wordAddr (keyAddr base direction j) t) 4) + (hsep : ∀ j < 16, ∀ t < 2, (⟨wordAddr (keyAddr base direction j) t, 4⟩ : Region).Disjoint (spillRegion origin)) + (hkeys : ∀ j < 16, (readKey origin.mem (keyAddr base direction j)).setWidth 48 = + roundKey keys direction j) + (n : Nat) (s : State) (hs : LoopInv keys direction base origin v n s) : + WP isa (.block (roundBody ++ roundAdvance direction)) s (fun s' => + (isa.eval .ne s' = some false ∧ LoopPost keys direction base origin v s') ∨ + (isa.eval .ne s' = some true ∧ ∃ m < n, LoopInv keys direction base origin v m s')) := by + have hj : 16 - n < 16 := by omega_using [hs.positive] + have hwork : spillRegion s = spillRegion origin := by + simp only [spillRegion, hs.regs .r2 (by decide)] + have hokS : Ok sboxCfg s := hok.congr + (hs.regs .r2 (by decide)) (hs.regs .r2 (by decide)) hs.rd hs.wr + have hreadS : ∀ t < 2, InRegions (s.rd ++ s.wr) (wordAddr (s.gpr .r0) t) 4 := by + rw [hs.rd, hs.wr, hs.pointer]; exact hread _ hj + have hsepS : ∀ t < 2, (⟨wordAddr (s.gpr .r0) t, 4⟩ : Region).Disjoint (spillRegion s) := by + rw [hs.pointer, hwork]; exact hsep _ hj + have hk : (keyWord s).setWidth 48 = roundKey keys direction (16 - n) := by + change (readKey s.mem (s.gpr .r0)).setWidth 48 = _ + rw [hs.pointer] + have hmem := readKey_frame hs.frame (ptr := keyAddr base direction (16 - n)) + (fun t ht q hq => by obtain rfl := List.mem_singleton.mp hq; exact hsep _ hj t ht) + exact (congrArg (BitVec.setWidth 48) hmem).trans (hkeys _ hj) + obtain ⟨s', run, left, right, ptr, count, flag, rd, wr, sp, regs, frame⟩ := + roundStep_ok direction s _ _ (keyWord s) n hs.positive + (by omega_using [hs.bounded]) hs.left hs.right rfl hokS hreadS hsepS + hs.counter + have hidx : 16 - (n - 1) = 16 - n + 1 := by + omega_using [hs.positive, hs.bounded] + have hleft : s'.gpr .r10 = (roundPrefix keys direction (16 - (n - 1)) v).1 := by + rw [hidx] + exact left.trans (congrArg (fun pair => pair.1) + (VG.Proof.TripleDes.roundPrefix_succ keys direction (16 - n) v).symm) + have hright : s'.gpr .r11 = (roundPrefix keys direction (16 - (n - 1)) v).2 := by + rw [hidx] + have hval := congrArg (fun key => + ((roundPrefix keys direction (16 - n) v).1 ^^^ + Spec.TripleDes.roundFunction (roundPrefix keys direction (16 - n) v).2 key)) hk + exact (right.trans hval).trans (congrArg (fun pair => pair.2) + (VG.Proof.TripleDes.roundPrefix_succ keys direction (16 - n) v).symm) + have hframe : Frame [spillRegion origin] origin.mem s'.mem := by + rw [hwork] at frame + exact hs.frame.trans frame + have hregs : ∀ q ∈ roundStepKept, s'.gpr q = origin.gpr q := + fun q hq => (regs q hq).trans (hs.regs q hq) + refine WP.of_runBlock ⟨s', run, ?_⟩ + by_cases hlast : n = 1 + · left + refine ⟨?_, ?_⟩ + · simpa only [hlast, ne_eq, not_true_eq_false, decide_false] using flag + · subst n + exact ⟨hleft, hright, count, by + rw [ptr, hs.pointer] + exact keyAddr_end base direction, rd.trans hs.rd, wr.trans hs.wr, sp.trans hs.sp, hregs, hframe⟩ + · right + refine ⟨?_, n - 1, by omega_using [hs.positive], ?_⟩ + · simpa only [hlast, ne_eq, not_false_eq_true, decide_true] using flag + · refine ⟨by omega_using [hs.positive, hlast], by omega_using [hs.bounded], + hleft, hright, count, ?_, rd.trans hs.rd, wr.trans hs.wr, sp.trans hs.sp, hregs, hframe⟩ + rw [ptr, hs.pointer, keyAddr_step base direction (16 - n) (by + omega_using [hs.positive, hlast]), ← hidx] + +/-- The complete sixteen-round loop, in either key order. -/ +theorem roundsLoop_ok (keys : DesSchedule) (direction : Direction) (base : BitVec 32) + (origin : State) (v : BitVec 32 × BitVec 32) + (hok : Ok sboxCfg origin) + (hl : origin.gpr .r10 = v.1) (hr : origin.gpr .r11 = v.2) + (hptr : origin.gpr .r0 = keyAddr base direction 0) + (hcount : origin.gpr .r9 = BitVec.ofNat 32 16) + (hread : ∀ j < 16, ∀ t < 2, InRegions (origin.rd ++ origin.wr) (wordAddr (keyAddr base direction j) t) 4) + (hsep : ∀ j < 16, ∀ t < 2, (⟨wordAddr (keyAddr base direction j) t, 4⟩ : Region).Disjoint (spillRegion origin)) + (hkeys : ∀ j < 16, (readKey origin.mem (keyAddr base direction j)).setWidth 48 = + roundKey keys direction j) : + WP isa (.loop (.block (roundBody ++ roundAdvance direction)) .ne) + origin (LoopPost keys direction base origin v) := by + apply WP.loop (M := isa) (body := .block (roundBody ++ roundAdvance direction)) + (c := .ne) (Q := LoopPost keys direction base origin v) (LoopInv keys direction base origin v) + (loopStep keys direction base origin v hok hread hsep hkeys) + 16 origin + exact ⟨by decide, by decide, hl, hr, hcount, hptr, rfl, rfl, rfl, + fun _ _ => rfl, Frame.refl _ _⟩ + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Pass.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Pass.lean new file mode 100644 index 000000000..f09affb88 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Pass.lean @@ -0,0 +1,86 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.PassStart + +namespace VG.Proof.TripleDes.Arm + +open VG VG.Arm VG.Arm.Straight VG.Impl.TripleDes.Arm +open VG.Spec.TripleDes (Direction DesSchedule) +open VG.Proof.TripleDes (roundKey roundPrefix) + +structure PassPost (keys : DesSchedule) (direction : Direction) (base : BitVec 32) + (origin : State) (v : BitVec 32 × BitVec 32) (s : State) : Prop where + left : s.gpr .r10 = (roundPrefix keys direction 16 v).2 + right : s.gpr .r11 = (roundPrefix keys direction 16 v).1 + pointer : s.gpr .r0 = endPointer base direction + rd : s.rd = origin.rd + wr : s.wr = origin.wr + sp : s.sp = origin.sp + regs : ∀ q ∈ roundStepKept, s.gpr q = origin.gpr q + frame : Frame [spillRegion origin] origin.mem s.mem + +/-- The sixteen-round loop and final DES half swap. -/ +theorem roundsWithSwap_ok (keys : DesSchedule) (direction : Direction) (base : BitVec 32) + (origin : State) (v : BitVec 32 × BitVec 32) + (hok : Ok sboxCfg origin) + (hl : origin.gpr .r10 = v.1) (hr : origin.gpr .r11 = v.2) + (hptr : origin.gpr .r0 = keyAddr base direction 0) + (hcount : origin.gpr .r9 = BitVec.ofNat 32 16) + (hread : ∀ j < 16, ∀ t < 2, InRegions (origin.rd ++ origin.wr) (wordAddr (keyAddr base direction j) t) 4) + (hsep : ∀ j < 16, ∀ t < 2, (⟨wordAddr (keyAddr base direction j) t, 4⟩ : Region).Disjoint (spillRegion origin)) + (hkeys : ∀ j < 16, (readKey origin.mem (keyAddr base direction j)).setWidth 48 = + roundKey keys direction j) : + WP isa (.seq (.loop (.block (roundBody ++ roundAdvance direction)) .ne) + (.block swapHalves)) origin (PassPost keys direction base origin v) := by + apply WP.seq + apply WP.mono (roundsLoop_ok keys direction base origin v hok hl hr hptr hcount + hread hsep hkeys) + intro s hs + obtain ⟨s', run, left, right, rd, wr, sp, mem, regs⟩ := swapHalves_ok s + apply WP.of_runBlock + refine ⟨s', run, left.trans hs.right, right.trans hs.left, (regs .r0 (by decide)).trans hs.pointer, + rd.trans hs.rd, wr.trans hs.wr, sp.trans hs.sp, ?_, ?_⟩ + · intro q hq + have hkeep : ∀ r ∈ roundStepKept, r ∈ roundOuterKept := by decide + exact (regs q (hkeep q hq)).trans (hs.regs q hq) + · rw [mem] + exact hs.frame + + +theorem pass_ok (offset : Int) (ho : encodable (BitVec.ofNat 32 offset.natAbs) = true) + (keys : DesSchedule) (direction : Direction) (base : BitVec 32) + (origin : State) (v : BitVec 32 × BitVec 32) + (hok : Ok sboxCfg origin) + (hl : origin.gpr .r10 = v.1) (hr : origin.gpr .r11 = v.2) + (hptr : startPointer (origin.gpr .r0) offset = + keyAddr base direction 0) + (hread : ∀ j < 16, ∀ t < 2, InRegions (origin.rd ++ origin.wr) (wordAddr (keyAddr base direction j) t) 4) + (hsep : ∀ j < 16, ∀ t < 2, (⟨wordAddr (keyAddr base direction j) t, 4⟩ : Region).Disjoint (spillRegion origin)) + (hkeys : ∀ j < 16, (readKey origin.mem (keyAddr base direction j)).setWidth 48 = + roundKey keys direction j) : + WP isa (pass offset direction) origin (PassPost keys direction base origin v) := by + obtain ⟨s, run, ptr, count, mem, rd, wr, sp, regs⟩ := passStart_ok offset origin ho + have hbase : s.gpr .r2 = origin.gpr .r2 := regs .r2 (by decide) (by decide) + have hwork : spillRegion s = spillRegion origin := by simp only [spillRegion, hbase] + have hkeysS : ∀ j < 16, (readKey s.mem (keyAddr base direction j)).setWidth 48 = + roundKey keys direction j := by rw [mem]; exact hkeys + have hreadS : ∀ j < 16, ∀ t < 2, InRegions (s.rd ++ s.wr) (wordAddr (keyAddr base direction j) t) 4 := by + rw [rd, wr]; exact hread + have hsepS : ∀ j < 16, ∀ t < 2, (⟨wordAddr (keyAddr base direction j) t, 4⟩ : Region).Disjoint (spillRegion s) := by + rw [hwork]; exact hsep + have htail := roundsWithSwap_ok keys direction base s v + (hok.congr hbase hbase rd wr) + ((regs .r10 (by decide) (by decide)).trans hl) + ((regs .r11 (by decide) (by decide)).trans hr) + (ptr.trans hptr) count hreadS hsepS hkeysS + apply WP.seq + apply WP.of_runBlock + refine ⟨s, run, WP.mono htail ?_⟩ + intro s' hs + refine ⟨hs.left, hs.right, hs.pointer, hs.rd.trans rd, hs.wr.trans wr, hs.sp.trans sp, ?_, ?_⟩ + · intro q hq + have hneq : ∀ r ∈ roundStepKept, r ≠ .r9 ∧ r ≠ .r0 := by decide + exact (hs.regs q hq).trans (regs q (hneq q hq).2 (hneq q hq).1) + · have hf := hs.frame + rw [hwork, mem] at hf + exact hf + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/PassStart.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/PassStart.lean new file mode 100644 index 000000000..d1534cd7d --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/PassStart.lean @@ -0,0 +1,27 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Loop +namespace VG.Proof.TripleDes.Arm +open VG VG.Arm VG.Arm.RegUpd VG.Impl.TripleDes.Arm + +def startPointer (ptr : BitVec 32) (offset : Int) : BitVec 32 := + if offset < 0 then ptr - BitVec.ofNat 32 offset.natAbs else ptr + BitVec.ofNat 32 offset.natAbs + +theorem passOffset_encodable : ∀ offset ∈ ([0, 120, 136, 376, -120, -136] : List Int), + encodable (BitVec.ofNat 32 offset.natAbs) = true := by decide +kernel + +theorem passStart_ok (offset : Int) (s : State) + (ho : encodable (BitVec.ofNat 32 offset.natAbs) = true) : + ∃ s', runBlock isa (passStart offset) s = some s' ∧ + s'.gpr .r0 = startPointer (s.gpr .r0) offset ∧ s'.gpr .r9 = 16 ∧ + s'.mem = s.mem ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ + (∀ r, r ≠ .r0 → r ≠ .r9 → s'.gpr r = s.gpr r) := by + by_cases h : offset < 0 + all_goals refine ⟨(s.setReg .r0 (startPointer (s.gpr .r0) offset)).setReg .r9 16, by + simp only [passStart, h, ite_true, ite_false, runBlock_cons, exec, Op2.eval, ho, ite_true, + Option.map_some, imm, runStep_some, startPointer] + rfl, ?_, ?_, rfl, rfl, rfl, rfl, ?_⟩ + all_goals try simp only [gpr_setReg, startPointer, h, ite_true, ite_false, reduceCtorEq] + all_goals try rfl + all_goals + intro r hr₀ hr₉ + simp only [hr₀, hr₉, ite_false] +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Permutation.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Permutation.lean new file mode 100644 index 000000000..d2b17b5a2 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Permutation.lean @@ -0,0 +1,138 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Lit +import VerifiedGarbage.Proof.TripleDes.Permutation +import VerifiedGarbage.Proof.Framework.Arm.Linear + +namespace VG.Proof.TripleDes.Arm +open VG VG.Arm VG.Arm.Straight VG.Bitslice VG.Impl.TripleDes.Arm + +def permutationCfg : Cfg := { base := .r2, slots := 0, ext := .r2, exts := 0 } +def permutationInputs (lo hi : Reg) : List (Reg × Nat) := [(lo, 0), (hi, 1)] +def permutationBits {m : Nat} (positions : Vector Nat m) (n srcSplit dstSplit start p : Nat) : List Nat := + if p < dstSplit ∧ start + p < m then + let source := n - positions.getD (m - 1 - (start + p)) 1 + [if source < srcSplit then source else 32 + source - srcSplit] + else [] +def permutationOutputs {m : Nat} (positions : Vector Nat m) (n srcSplit dstSplit : Nat) (lo hi : Reg) : + List (Reg × (Nat → List Nat)) := + [(lo, permutationBits positions n srcSplit dstSplit 0), + (hi, permutationBits positions n srcSplit (m - dstSplit) dstSplit)] + +theorem initialPermutation_check : + check (lanes 32 6) permutationCfg (linExt 2) (instrs initialPermutation.lit) + (linEnv (permutationInputs .r5 .r4)) (linPost 6 (permutationOutputs Spec.TripleDes.ip 64 32 32 .r11 .r10)) = true := by + decide +kernel + +theorem finalPermutation_check : + check (lanes 32 6) permutationCfg (linExt 2) (instrs finalPermutation.lit) + (linEnv (permutationInputs .r11 .r10)) (linPost 6 (permutationOutputs Spec.TripleDes.fp 64 32 32 .r5 .r4)) = true := by + decide +kernel + +theorem keyPermutation1_check : + check (lanes 32 6) permutationCfg (linExt 2) (instrs keyPermutation1.lit) + (linEnv (permutationInputs .r5 .r4)) (linPost 6 (permutationOutputs Spec.TripleDes.pc1 64 32 28 .r11 .r10)) = true := by + decide +kernel + +theorem keyPermutation2_check : + check (lanes 32 6) permutationCfg (linExt 2) (instrs keyPermutation2.lit) + (linEnv (permutationInputs .r11 .r10)) (linPost 6 (permutationOutputs Spec.TripleDes.pc2 56 28 32 .r4 .r5)) = true := by + decide +kernel + +def packedInput (n split : Nat) (lo hi : BitVec 32) : BitVec n := + ((hi.setWidth (n - split)) ++ lo.setWidth split).setWidth n + +theorem packedInput_bit (n split : Nat) (lo hi : BitVec 32) (k : Nat) + (hk : k < n) (hs : split ≤ n) : + (packedInput n split lo hi).getLsbD k = + if k < split then lo.getLsbD k else hi.getLsbD (k - split) := by + simp only [packedInput, BitVec.getLsbD_setWidth, hk, decide_true, Bool.true_and, + BitVec.getLsbD_append] + by_cases h : k < split + · simp only [h, ite_true, decide_true, Bool.true_and] + · have hb : k - split < n - split := by omega + simp only [h, ite_false, hb, decide_true, Bool.true_and] + +theorem permutationBits_ok {m n : Nat} (positions : Vector Nat m) + (hn : 0 < n) (split width start : Nat) + (hs : split ≤ n) (hlo : split ≤ 32) (hhi : n - split ≤ 32) + (hw : width + start ≤ m) + (bounds : ∀ k < m, 1 ≤ positions.getD k 1 ∧ positions.getD k 1 ≤ n) + (lo hi : BitVec 32) (p : Nat) (hp : p < 32) : + xorBits (fun i => if i = 0 then lo else hi) + (permutationBits positions n split width start p) = + (((Spec.TripleDes.permute positions (packedInput n split lo hi) >>> start).setWidth width).setWidth 32).getLsbD p := by + simp only [BitVec.getLsbD_setWidth, hp, decide_true, Bool.true_and, BitVec.getLsbD_ushiftRight] + by_cases hw' : p < width + · have hm : start + p < m := by omega + simp only [hw', decide_true, Bool.true_and] + have hk : m - 1 - (start + p) < m := by omega + obtain ⟨hb, ht⟩ := bounds _ hk + have hn' : n - positions.getD (m - 1 - (start + p)) 1 < n := by omega + rw [VG.Proof.TripleDes.permute_bit positions _ hn _ hm, packedInput_bit _ _ _ _ _ hn' hs] + simp only [permutationBits, hw', hm, and_self, ite_true, xorBits_cons, xorBits_nil, Bool.xor_false] + let k := n - positions.getD (m - 1 - (start + p)) 1 + change bitOf (fun i => if i = 0 then lo else hi) (if k < split then k else 32 + k - split) = + if k < split then lo.getLsbD k else hi.getLsbD (k - split) + by_cases h : k < split + · have h32 : k < 32 := by omega + simp only [h, ite_true, bitOf, Nat.div_eq_of_lt h32, Nat.mod_eq_of_lt h32] + · have h32 : k - split < 32 := by change n - positions.getD (m - 1 - (start + p)) 1 < n at hn'; dsimp [k]; omega + have he : 32 + k - split = 32 * 1 + (k - split) := by omega + simp only [h, ite_false, he, bitOf_word _ _ _ h32] + rfl + · simp only [hw', decide_false, Bool.false_and, permutationBits, false_and, ite_false, xorBits_nil] + +theorem permutationCfg_ok (s : State) : Ok permutationCfg s := by + refine ⟨?_, ?_, ?_, ?_⟩ + · intro k hk; simp [permutationCfg] at hk + · intro k hk; simp [permutationCfg] at hk + · change (s.gpr .r2).toNat + 4 * 0 ≤ 2 ^ 32 + have h := (s.gpr .r2).isLt + omega + · intro k hk; simp [permutationCfg] at hk + +theorem fixedPermutation_ok {m n : Nat} (positions : Vector Nat m) + (hn : 0 < n) (split dstSplit : Nat) + (hs : split ≤ n) (hlo : split ≤ 32) (hhi : n - split ≤ 32) (hd : dstSplit ≤ m) + (bounds : ∀ k < m, 1 ≤ positions.getD k 1 ∧ positions.getD k 1 ≤ n) + (srcLo srcHi dstLo dstHi : Reg) (is : List Instr) + (hchk : check (lanes 32 6) permutationCfg (linExt 2) is + (linEnv (permutationInputs srcLo srcHi)) + (linPost 6 (permutationOutputs positions n split dstSplit dstLo dstHi)) = true) + (s : State) : + ∃ s', runBlock isa is s = some s' ∧ + s'.gpr dstLo = ((Spec.TripleDes.permute positions + (packedInput n split (s.gpr srcLo) (s.gpr srcHi))).setWidth dstSplit).setWidth 32 ∧ + s'.gpr dstHi = ((Spec.TripleDes.permute positions + (packedInput n split (s.gpr srcLo) (s.gpr srcHi)) >>> dstSplit).setWidth (m - dstSplit)).setWidth 32 ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ s'.mem = s.mem ∧ + (∀ r, (is.all fun op => dstOf op != some r) = true → s'.gpr r = s.gpr r) := by + let W : Nat → BitVec 32 := fun i => if i = 0 then s.gpr srcLo else s.gpr srcHi + obtain ⟨s', hs', out, rd, wr, sp, keep, frame⟩ := + linear_ok hchk (permutationCfg_ok s) W (fun r i h => by + simp only [permutationInputs, List.mem_cons, List.not_mem_nil, or_false] at h + rcases h with h | h + · obtain ⟨rfl, rfl⟩ := Prod.mk.inj h; exact ⟨by decide, rfl⟩ + · obtain ⟨rfl, rfl⟩ := Prod.mk.inj h; exact ⟨by decide, rfl⟩) + (fun j hj => by simp [permutationCfg] at hj) + refine ⟨s', hs', ?_, ?_, rd, wr, sp, ?_, keep⟩ + · apply BitVec.eq_of_getLsbD_eq + intro p hp + have h := out dstLo (permutationBits positions n split dstSplit 0) (by simp [permutationOutputs]) p hp + rw [h] + have hbits := permutationBits_ok positions hn split dstSplit 0 hs hlo hhi (by omega) bounds (s.gpr srcLo) (s.gpr srcHi) p hp + simpa only [BitVec.ushiftRight_zero] using hbits + · apply BitVec.eq_of_getLsbD_eq + intro p hp + have h := out dstHi (permutationBits positions n split (m - dstSplit) dstSplit) + (by simp [permutationOutputs]) p hp + rw [h] + exact permutationBits_ok positions hn split (m - dstSplit) dstSplit hs hlo hhi + (by omega) bounds _ _ p hp + · funext a + apply frame a + intro r hr hc + simp only [slotRegion, permutationCfg, List.mem_singleton] at hr + subst r + simp [Region.Contains] at hc + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Pre.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Pre.lean new file mode 100644 index 000000000..19ed97b9e --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Pre.lean @@ -0,0 +1,106 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Block +import VerifiedGarbage.Proof.TripleDes.Schedule +import VerifiedGarbage.Proof.TripleDes.Arm.ConstantTime +import VerifiedGarbage.Proof.TripleDes.Arm.WordStore + +namespace VG.Proof.TripleDes.Arm + +open VG VG.Arm VG.Arm.Straight VG.Impl.TripleDes.Arm +open VG.Spec.TripleDes (Direction) + +def blockContract (d : Direction) : Contract isa where + pre s := + let key : Region := ⟨State.addr (s.gpr .r0), 384⟩ + let data : Region := ⟨State.addr (s.gpr .r1), 8⟩ + let scratch : Region := ⟨State.addr (s.gpr .r2), 512⟩ + s.rd = [key] ∧ s.wr = [data, scratch] ∧ key.Disjoint scratch ∧ data.Disjoint scratch ∧ + (s.gpr .r0).toNat + 384 ≤ 2 ^ 32 ∧ (s.gpr .r1).toNat + 8 ≤ 2 ^ 32 ∧ + (s.gpr .r2).toNat + 512 ≤ 2 ^ 32 + post s s' := Spec.TripleDes.blockAt s'.mem (State.addr (s.gpr .r1)) = + blockResult (Spec.TripleDes.scheduleAt s.mem (State.addr (s.gpr .r0))) d (Spec.TripleDes.blockAt s.mem (State.addr (s.gpr .r1))) + pub := PublicRegs [.r0, .r1, .r2] + +def selectedRound (d : Direction) (j : Nat) : Nat := if d = .encrypt then j else 15 - j + +theorem selectedRound_bound (d : Direction) (j : Nat) (hj : j < 16) : selectedRound d j < 16 := by + cases d <;> simp only [selectedRound, reduceCtorEq, ite_true, ite_false] <;> omega + +theorem keyAddr_component (base : BitVec 32) (c : Nat) (d : Direction) (j : Nat) : + keyAddr (componentBase base c) d j = base + BitVec.ofNat 32 (8 * (16 * c + selectedRound d j)) := by + unfold keyAddr componentBase selectedRound + rw [Offset.add_ofNat_add_ofNat] + exact congrArg (fun n => base + BitVec.ofNat 32 n) (by omega) + +theorem keyWordAddress (base : BitVec 32) (fit : base.toNat + 384 ≤ 2 ^ 32) + (c j t : Nat) (hc : c < 3) (hj : j < 16) (ht : t < 2) (d : Direction) : + wordAddr (keyAddr (componentBase base c) d j) t = + State.addr base + BitVec.ofNat 64 (8 * (16 * c + selectedRound d j) + 4 * t) := by + have bound := selectedRound_bound d j hj + rw [wordAddr, keyAddr_component, Offset.add_ofNat_add_ofNat, + addr_add (by omega_using [fit, hc, bound, ht])] + +theorem readKey_component (m : Mem) (base : BitVec 32) + (fit : base.toNat + 384 ≤ 2 ^ 32) (c j : Nat) (hc : c < 3) (hj : j < 16) (d : Direction) : + readKey m (keyAddr (componentBase base c) d j) = + m.readW (State.addr base + BitVec.ofNat 64 (8 * (16 * c + selectedRound d j))) 64 := by + rw [readKey, keyWordAddress base fit c j 1 hc hj (by decide) d, + keyWordAddress base fit c j 0 hc hj (by decide) d] + simp only [Nat.mul_zero, Nat.add_zero, Nat.mul_one] + rw [← Offset.add_ofNat_add_ofNat] + exact readW_pair m _ + +theorem headPre_of_contract (d : Direction) (s : State) (hs : (blockContract d).pre s) : + HeadPre (Spec.TripleDes.componentSchedule (Spec.TripleDes.scheduleAt s.mem (State.addr (s.gpr .r0)))) + (s.gpr .r0) s := by + obtain ⟨hrd, hwr, keySep, dataSep, keyFit, dataFit, scratchFit⟩ := hs + have scratchWrites : ∀ i < 128, InRegions s.wr (wordAddr (s.gpr .r2) i) 4 := by + intro i hi + rw [wordAddr, addr_add (by omega_using [scratchFit, hi]), hwr] + exact ⟨⟨State.addr (s.gpr .r2), 512⟩, by simp, + Offset.contains_base _ (by omega_using [hi]) (by omega_using [hi])⟩ + have scratchSaveWrites : ∀ i < 9, InRegions s.wr (State.addr (s.gpr .r2) + BitVec.ofNat 64 (4 * i)) 4 := by + intro i hi + rw [hwr] + exact ⟨⟨State.addr (s.gpr .r2), 512⟩, by simp, + Offset.contains_base _ (by omega_using [hi]) (by omega_using [hi])⟩ + have scratchSaveReads : ∀ i < 9, InRegions (s.rd ++ s.wr) + (State.addr (s.gpr .r2) + BitVec.ofNat 64 (4 * i)) 4 := by + intro i hi + obtain ⟨r, hr, hc⟩ := scratchSaveWrites i hi + exact ⟨r, List.mem_append_right _ hr, hc⟩ + have spills : Ok sboxCfg s := by + refine ⟨scratchWrites, ?_, scratchFit, ?_⟩ + · intro k hk; change k < 0 at hk; omega + · intro k hk j hj; change j < 0 at hj; omega + have keySub : ∀ c < 3, ∀ direction : Direction, ∀ j < 16, ∀ t < 2, + Region.Sub ⟨wordAddr (keyAddr (componentBase (s.gpr .r0) c) direction j) t, 4⟩ + ⟨State.addr (s.gpr .r0), 384⟩ := by + intro c hc direction j hj t ht + rw [keyWordAddress _ keyFit c j t hc hj ht direction] + have bound := selectedRound_bound direction j hj + exact Offset.sub_base _ (by omega_using [hc, bound, ht]) + have workSub : Region.Sub (spillRegion s) ⟨State.addr (s.gpr .r2), 512⟩ := + Offset.sub_base _ (by decide) + have saveSub : Region.Sub (saveRegion s) ⟨State.addr (s.gpr .r2), 512⟩ := + Region.sub_prefix (by decide) + refine ⟨spills, by omega_using [scratchFit], dataFit, rfl, scratchSaveReads, + scratchSaveWrites, ?_, dataSep.sub_right saveSub, ?_, ?_, ?_, ?_⟩ + · intro t ht + rw [addr_add (by omega_using [dataFit, ht]), hrd, hwr] + exact ⟨⟨State.addr (s.gpr .r1), 8⟩, by simp, + Offset.contains_base _ (by omega_using [ht]) (by omega_using [ht])⟩ + · intro c hc direction j hj t ht + rw [keyWordAddress _ keyFit c j t hc hj ht direction, hrd, hwr] + have bound := selectedRound_bound direction j hj + exact ⟨⟨State.addr (s.gpr .r0), 384⟩, by simp, + Offset.contains_base _ (by omega_using [hc, bound, ht]) (by omega_using [hc, bound, ht])⟩ + · intro c hc direction j hj t ht + exact (keySep.sub_left (keySub c hc direction j hj t ht)).sub_right workSub + · intro c hc direction j hj t ht + exact (keySep.sub_left (keySub c hc direction j hj t ht)).sub_right saveSub + · intro c hc direction j hj + rw [readKey_component s.mem _ keyFit c j hc hj direction] + exact (VG.Proof.TripleDes.componentSchedule_readW s.mem (State.addr (s.gpr .r0)) c + (selectedRound direction j) hc (selectedRound_bound direction j hj)).symm + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ready.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ready.lean new file mode 100644 index 000000000..87c05f70d --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Ready.lean @@ -0,0 +1,67 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.WordState + +namespace VG.Proof.TripleDes.Arm + +open VG VG.Arm VG.Arm.Straight VG.Impl.TripleDes.Arm +open VG.Spec.TripleDes (Direction DesSchedule) +open VG.Proof.TripleDes (roundKey) + +def componentBase (base : BitVec 32) (component : Nat) : BitVec 32 := + base + BitVec.ofNat 32 (128 * component) + +structure Ready (keys : Nat → DesSchedule) (base : BitVec 32) (s : State) : Prop where + spills : Ok sboxCfg s + read : ∀ c < 3, ∀ d : Direction, ∀ j < 16, ∀ t < 2, + InRegions (s.rd ++ s.wr) (wordAddr (keyAddr (componentBase base c) d j) t) 4 + separate : ∀ c < 3, ∀ d : Direction, ∀ j < 16, ∀ t < 2, + (⟨wordAddr (keyAddr (componentBase base c) d j) t, 4⟩ : Region).Disjoint (spillRegion s) + values : ∀ c < 3, ∀ d : Direction, ∀ j < 16, + (readKey s.mem (keyAddr (componentBase base c) d j)).setWidth 48 = roundKey (keys c) d j + +theorem Ready.congr {keys : Nat → DesSchedule} {base : BitVec 32} {s t : State} + (hs : Ready keys base s) (hbase : t.gpr .r2 = s.gpr .r2) + (hrd : t.rd = s.rd) (hwr : t.wr = s.wr) + (hf : Frame [spillRegion s] s.mem t.mem) : Ready keys base t := by + have hwork : spillRegion t = spillRegion s := + congrArg (fun p => (⟨State.addr p + BitVec.ofNat 64 60, 388⟩ : Region)) hbase + refine ⟨hs.spills.congr hbase hbase hrd hwr, ?_, ?_, ?_⟩ + · rw [hrd, hwr]; exact hs.read + · rw [hwork]; exact hs.separate + · intro c hc d j hj + have hmem := readKey_frame hf (ptr := keyAddr (componentBase base c) d j) + (fun t ht q hq => by obtain rfl := List.mem_singleton.mp hq; exact hs.separate c hc d j hj t ht) + exact (congrArg (BitVec.setWidth 48) hmem).trans (hs.values c hc d j hj) + +structure Stable (origin s : State) : Prop where + rd : s.rd = origin.rd + wr : s.wr = origin.wr + sp : s.sp = origin.sp + regs : ∀ q ∈ roundStepKept, s.gpr q = origin.gpr q + frame : Frame [spillRegion origin] origin.mem s.mem + +theorem Stable.refl (s : State) : Stable s s := + ⟨rfl, rfl, rfl, fun _ _ => rfl, Frame.refl _ _⟩ + +theorem Stable.trans {s t u : State} (hs : Stable s t) (ht : Stable t u) : Stable s u := by + have hwork : spillRegion t = spillRegion s := + congrArg (fun p => (⟨State.addr p + BitVec.ofNat 64 60, 388⟩ : Region)) (hs.regs .r2 (by decide)) + have hf := ht.frame + rw [hwork] at hf + exact ⟨ht.rd.trans hs.rd, ht.wr.trans hs.wr, ht.sp.trans hs.sp, + fun q hq => (ht.regs q hq).trans (hs.regs q hq), hs.frame.trans hf⟩ + +theorem pass_word_ok (keys : Nat → DesSchedule) (base : BitVec 32) (s : State) (x : BitVec 64) + (c : Nat) (hc : c < 3) (d : Direction) (offset : Int) + (ho : encodable (BitVec.ofNat 32 offset.natAbs) = true) + (hptr : startPointer (s.gpr .r0) offset = keyAddr (componentBase base c) d 0) + (hready : Ready keys base s) (hword : WordState x s) : + WP isa (pass offset d) s (fun t => WordState (VG.Proof.TripleDes.desCore (keys c) d x) t ∧ + Ready keys base t ∧ Stable s t ∧ t.gpr .r0 = endPointer (componentBase base c) d) := by + apply WP.mono (pass_ok offset ho (keys c) d (componentBase base c) s + ((x >>> 32).setWidth 32, x.setWidth 32) hready.spills hword.left hword.right + hptr (hready.read c hc d) (hready.separate c hc d) (hready.values c hc d)) + intro t ht + exact ⟨ht.wordState, hready.congr (ht.regs .r2 (by decide)) ht.rd ht.wr ht.frame, + ⟨ht.rd, ht.wr, ht.sp, ht.regs, ht.frame⟩, ht.pointer⟩ + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Round.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Round.lean new file mode 100644 index 000000000..dd90c34c3 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Round.lean @@ -0,0 +1,295 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.RoundLit +import VerifiedGarbage.Proof.TripleDes.Arm.Sbox +import VerifiedGarbage.Proof.TripleDes.Permutation +import VerifiedGarbage.Proof.Framework.Arm.Linear + +namespace VG.Proof.TripleDes.Arm + +open VG VG.Arm VG.Arm.Straight VG.Bitslice VG.Impl.TripleDes.Arm + +noncomputable def sboxInputsLiterals : Array (Prog isa) := + #[sboxInputs0.lit, sboxInputs1.lit, sboxInputs2.lit, sboxInputs3.lit, sboxInputs4.lit, sboxInputs5.lit, sboxInputs6.lit, sboxInputs7.lit] + +noncomputable def sboxInputsLiteral (i : Nat) : Prog isa := + sboxInputsLiterals.getD i (.block []) + +noncomputable def sboxOutputsLiterals : Array (Prog isa) := + #[sboxOutputs0.lit, sboxOutputs1.lit, sboxOutputs2.lit, sboxOutputs3.lit, sboxOutputs4.lit, sboxOutputs5.lit, sboxOutputs6.lit, sboxOutputs7.lit] + +noncomputable def sboxOutputsLiteral (i : Nat) : Prog isa := + sboxOutputsLiterals.getD i (.block []) + +def roundInputCfg : Cfg := { base := .r2, slots := 0, ext := .r0, exts := 2 } +def roundInputRegs : List (Reg × Nat) := [(.r11, 0)] + +def roundInputBits (i j p : Nat) : List Nat := + if p = 0 then + let k := 6 * i + 5 - j + [32 - Spec.TripleDes.expansion.getD k 1, 32 + (47 - k)] + else [] + +def roundInputPost (i : Nat) : List (Reg × (Nat → List Nat)) := + (List.range 6).map fun j => (q j, roundInputBits i j) + +theorem roundInput_check : ∀ i < 8, + check (lanes 32 7) roundInputCfg (linExt 1) (instrs (sboxInputsLiteral i)) + (linEnv roundInputRegs) (linPost 7 (roundInputPost i)) = true := by + decide +kernel + +def roundOutputCfg : Cfg := { base := .r2, slots := 0, ext := .r2, exts := 0 } +def roundOutputRegs : List (Reg × Nat) := + [(.r10, 0)] ++ (List.range 4).map fun j => (q j, j + 1) + +def roundOutputBits (i p : Nat) : List Nat := + [p] ++ ((List.range 4).filterMap fun j => + let position := 4 * i + 4 - j + let dst := (Spec.TripleDes.p.toList.findIdx? (· == position)).getD 0 + if p = 31 - dst then some (32 * (j + 1)) else none) + +theorem roundOutput_check : ∀ i < 8, + check (lanes 32 9) roundOutputCfg (linExt 5) (instrs (sboxOutputsLiteral i)) + (linEnv roundOutputRegs) (linPost 9 [(.r10, roundOutputBits i)]) = true := by + decide +kernel + +theorem sboxInputsLiteral_eq : ∀ i < 8, + sboxInputsLiteral i = .block (sboxInputs i) + | 0, _ => sboxInputs0.lit_eq.symm + | 1, _ => sboxInputs1.lit_eq.symm + | 2, _ => sboxInputs2.lit_eq.symm + | 3, _ => sboxInputs3.lit_eq.symm + | 4, _ => sboxInputs4.lit_eq.symm + | 5, _ => sboxInputs5.lit_eq.symm + | 6, _ => sboxInputs6.lit_eq.symm + | 7, _ => sboxInputs7.lit_eq.symm + | n + 8, h => by omega + +theorem roundInputCfg_ok (s : State) + (hread : ∀ j < 2, InRegions (s.rd ++ s.wr) (wordAddr (s.gpr .r0) j) 4) : Ok roundInputCfg s := by + refine ⟨?_, ?_, ?_, ?_⟩ + · intro k hk; simp [roundInputCfg] at hk + · exact hread + · change (s.gpr .r2).toNat + 4 * 0 ≤ 2 ^ 32 + have h := (s.gpr .r2).isLt + omega + · intro k hk; simp [roundInputCfg] at hk + +/-- The extraction block reads just one round key and forms six Boolean +input words. It does not change memory, access permissions or other registers. -/ +theorem roundInput_ok (i : Nat) (hi : i < 8) (s : State) + (hread : ∀ j < 2, InRegions (s.rd ++ s.wr) (wordAddr (s.gpr .r0) j) 4) : + ∃ s', runBlock isa (sboxInputs i) s = some s' ∧ + (∀ j < 6, ∀ p < 32, (s'.gpr (q j)).getLsbD p = + xorBits (fun k => if k = 0 then s.gpr .r11 + else s.mem.readW (wordAddr (s.gpr .r0) (k - 1)) 32) (roundInputBits i j p)) ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ s'.mem = s.mem ∧ + (∀ r, ((sboxInputs i).all fun op => dstOf op != some r) = true → + s'.gpr r = s.gpr r) := by + have hchk := roundInput_check i hi + rw [sboxInputsLiteral_eq i hi] at hchk + let W : Nat → BitVec 32 := fun k => + if k = 0 then s.gpr .r11 else s.mem.readW (wordAddr (s.gpr .r0) (k - 1)) 32 + obtain ⟨s', hs', out, rd, wr, sp, keep, frame⟩ := linear_ok hchk + (roundInputCfg_ok s hread) W (fun r k h => by + simp only [roundInputRegs, List.mem_singleton, Prod.mk.injEq] at h + obtain ⟨rfl, rfl⟩ := h + exact ⟨by decide, rfl⟩) (fun j hj => by + have hb : j < 2 := hj + refine ⟨by omega, ?_⟩ + simp only [W, Nat.add_eq_zero_iff, Nat.one_ne_zero, false_and, ite_false, Nat.add_sub_cancel_left, roundInputCfg]) + refine ⟨s', hs', fun j hj p hp => ?_, rd, wr, sp, ?_, keep⟩ + · exact out (q j) (roundInputBits i j) + (List.mem_map.mpr ⟨j, List.mem_range.mpr hj, rfl⟩) p hp + · funext a + apply frame a + intro r hr hc + simp only [slotRegion, roundInputCfg, List.mem_singleton] at hr + subst r + simp [Region.Contains] at hc + +theorem roundInput_bounds : ∀ i < 8, ∀ j < 6, + 32 - Spec.TripleDes.expansion.getD (6 * i + 5 - j) 1 < 32 ∧ + 47 - (6 * i + 5 - j) < 64 := by + decide +kernel + +theorem bitOf_low (W : Nat → BitVec 32) (a : Nat) (ha : a < 32) : + bitOf W a = (W 0).getLsbD a := by + simp only [bitOf, Nat.div_eq_of_lt ha, Nat.mod_eq_of_lt ha] + +def keyWord (s : State) : BitVec 64 := + s.mem.readW (wordAddr (s.gpr .r0) 1) 32 ++ s.mem.readW (wordAddr (s.gpr .r0) 0) 32 + +theorem bitOf_key (s : State) (a : Nat) (ha : a < 64) : + bitOf (fun k => if k = 0 then s.gpr .r11 else + s.mem.readW (wordAddr (s.gpr .r0) (k - 1)) 32) (32 + a) = + (keyWord s).getLsbD a := by + simp only [bitOf, keyWord, BitVec.getLsbD_append] + by_cases h : a < 32 + · have hd : (32 + a) / 32 = 1 := by omega + simp only [h, ite_true, hd, Nat.add_mod_left, Nat.mod_eq_of_lt h] + rfl + · have hd : (32 + a) / 32 = 2 := by omega + have hm : (32 + a) % 32 = a - 32 := by omega + simp only [h, ite_false, hd, hm] + rfl + +def roundChunk (i : Nat) (r : BitVec 32) (k : BitVec 48) : BitVec 6 := + ((Spec.TripleDes.permute Spec.TripleDes.expansion r ^^^ k) >>> (6 * (7 - i))).setWidth 6 + +theorem roundChunk_bit (i j : Nat) (hi : i < 8) (hj : j < 6) + (r : BitVec 32) (k : BitVec 64) : + (roundChunk i (r.setWidth 32) (k.setWidth 48)).getLsbD j = + (r.getLsbD (32 - Spec.TripleDes.expansion.getD (6 * i + 5 - j) 1) ^^ + k.getLsbD (47 - (6 * i + 5 - j))) := by + have ht : 6 * (7 - i) + j < 48 := by omega + have heq : 48 - 1 - (6 * (7 - i) + j) = 6 * i + 5 - j := by omega + have hkey : 6 * (7 - i) + j = 47 - (6 * i + 5 - j) := by omega + have hsource : 32 - Spec.TripleDes.expansion.getD (6 * i + 5 - j) 1 < 32 := by + have hb : ∀ t < 48, 1 ≤ Spec.TripleDes.expansion.getD t 1 := by decide +kernel + have hpos : 6 * i + 5 - j < 48 := by omega + have := hb _ hpos + omega + simp only [roundChunk, BitVec.getLsbD_setWidth, hj, decide_true, Bool.true_and, + BitVec.getLsbD_ushiftRight, BitVec.getLsbD_xor] + rw [VG.Proof.TripleDes.permute_bit _ _ (by decide) _ ht] + rw [heq] + simp only [BitVec.getLsbD_setWidth, hsource, ht, decide_true, Bool.true_and] + rw [hkey] + +theorem roundInput_chunk (i : Nat) (hi : i < 8) (s : State) + (hread : ∀ j < 2, InRegions (s.rd ++ s.wr) (wordAddr (s.gpr .r0) j) 4) : + ∃ s', runBlock isa (sboxInputs i) s = some s' ∧ + inputAt s' 0 = roundChunk i ((s.gpr .r11).setWidth 32) + ((keyWord s).setWidth 48) ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ s'.mem = s.mem ∧ + (∀ r, ((sboxInputs i).all fun op => dstOf op != some r) = true → + s'.gpr r = s.gpr r) := by + obtain ⟨s', run, bits, rd, wr, sp, mem, keep⟩ := roundInput_ok i hi s hread + refine ⟨s', run, ?_, rd, wr, sp, mem, keep⟩ + apply BitVec.eq_of_getLsbD_eq + intro j hj + simp only [inputAt, getLsbD_ofBits, hj, decide_true, Bool.true_and] + rw [bits j hj 0 (by decide), roundChunk_bit i j hi hj] + obtain ⟨hr, hk⟩ := roundInput_bounds i hi j hj + simp only [roundInputBits, ite_true, xorBits_cons, xorBits_nil, Bool.xor_false, + bitOf_low _ _ hr, bitOf_key s _ hk, ite_true] + +def boxSource (p : Nat) : Nat := Spec.TripleDes.p.getD (31 - p) 1 - 1 + +def boxPiece (i : Nat) (b : BitVec 4) : BitVec 32 := + ofBits 32 fun p => if boxSource p / 4 = i then + b.getLsbD (3 - boxSource p % 4) else false + +theorem roundOutputBits_shape : ∀ i < 8, ∀ p < 32, + roundOutputBits i p = [p] ++ + (if p < 32 ∧ boxSource p / 4 = i then + [32 * (4 - boxSource p % 4)] else []) := by + decide +kernel + +theorem sboxOutputsLiteral_eq : ∀ i < 8, + sboxOutputsLiteral i = .block (sboxOutputs i) + | 0, _ => sboxOutputs0.lit_eq.symm + | 1, _ => sboxOutputs1.lit_eq.symm + | 2, _ => sboxOutputs2.lit_eq.symm + | 3, _ => sboxOutputs3.lit_eq.symm + | 4, _ => sboxOutputs4.lit_eq.symm + | 5, _ => sboxOutputs5.lit_eq.symm + | 6, _ => sboxOutputs6.lit_eq.symm + | 7, _ => sboxOutputs7.lit_eq.symm + | n + 8, h => by omega + +theorem roundOutputCfg_ok (s : State) : Ok roundOutputCfg s := by + refine ⟨?_, ?_, ?_, ?_⟩ + · intro k hk; simp [roundOutputCfg] at hk + · intro k hk; simp [roundOutputCfg] at hk + · change (s.gpr .r2).toNat + 4 * 0 ≤ 2 ^ 32 + have h := (s.gpr .r2).isLt + omega + · intro k hk; simp [roundOutputCfg] at hk + +/-- Deposit the four low S-box bits into L, at P's fixed destinations. -/ +theorem roundOutput_ok (i : Nat) (hi : i < 8) (s : State) : + ∃ s', runBlock isa (sboxOutputs i) s = some s' ∧ + (∀ p < 32, (s'.gpr .r10).getLsbD p = + xorBits (fun k => if k = 0 then s.gpr .r10 else s.gpr (q (k - 1))) + (roundOutputBits i p)) ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ s'.mem = s.mem ∧ + (∀ r, ((sboxOutputs i).all fun op => dstOf op != some r) = true → + s'.gpr r = s.gpr r) := by + have hchk := roundOutput_check i hi + rw [sboxOutputsLiteral_eq i hi] at hchk + let W : Nat → BitVec 32 := fun k => + if k = 0 then s.gpr .r10 else s.gpr (q (k - 1)) + obtain ⟨s', hs', out, rd, wr, sp, keep, frame⟩ := linear_ok hchk + (roundOutputCfg_ok s) W (fun r k h => by + simp only [roundOutputRegs, List.mem_append, List.mem_singleton, + Prod.mk.injEq, List.mem_map, List.mem_range] at h + rcases h with ⟨rfl, rfl⟩ | ⟨j, hj, heq⟩ + · exact ⟨by decide, rfl⟩ + · obtain ⟨rfl, rfl⟩ := heq + refine ⟨by omega, ?_⟩ + simp [W]) (fun j hj => by simp [roundOutputCfg] at hj) + refine ⟨s', hs', fun p hp => ?_, rd, wr, sp, ?_, keep⟩ + · exact out .r10 (roundOutputBits i) (by simp) p hp + · funext a + apply frame a + intro r hr hc + simp only [slotRegion, roundOutputCfg, List.mem_singleton] at hr + subst r + simp [Region.Contains] at hc + +theorem bitOf_word (W : Nat → BitVec 32) (j : Nat) : + bitOf W (32 * j) = (W j).getLsbD 0 := by + simp [bitOf] + +theorem roundOutput_piece (i : Nat) (hi : i < 8) (s : State) (b : BitVec 4) + (hb : ∀ j < 4, (s.gpr (q j)).getLsbD 0 = b.getLsbD j) : + ∃ s', runBlock isa (sboxOutputs i) s = some s' ∧ + s'.gpr .r10 = s.gpr .r10 ^^^ (boxPiece i b).zeroExtend 32 ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ s'.mem = s.mem ∧ + (∀ r, ((sboxOutputs i).all fun op => dstOf op != some r) = true → + s'.gpr r = s.gpr r) := by + obtain ⟨s', run, bits, rd, wr, sp, mem, keep⟩ := roundOutput_ok i hi s + refine ⟨s', run, ?_, rd, wr, sp, mem, keep⟩ + apply BitVec.eq_of_getLsbD_eq + intro p hp + rw [bits p hp, roundOutputBits_shape i hi p hp] + simp only [BitVec.getLsbD_xor, BitVec.zeroExtend_eq_setWidth, + BitVec.getLsbD_setWidth, hp, decide_true, Bool.true_and] + simp only [List.cons_append, List.nil_append, xorBits_cons, bitOf_low _ _ hp, ite_true] + by_cases h : p < 32 ∧ boxSource p / 4 = i + · simp only [h] + have hj : 3 - boxSource p % 4 < 4 := by omega + simp + rw [bitOf_word] + have hn : 4 - boxSource p % 4 ≠ 0 := by omega + have heq : 4 - boxSource p % 4 - 1 = 3 - boxSource p % 4 := by omega + simp only [hn, ite_false, heq] + rw [hb _ hj] + simp only [boxPiece, getLsbD_ofBits, h.1, h.2, decide_true, Bool.true_and, ite_true] + · have hs : boxSource p / 4 ≠ i := by omega + simp only [hs, ite_false, xorBits_nil, boxPiece, getLsbD_ofBits, + hp, decide_true, Bool.true_and, and_false] + +def roundKept : List Reg := [.r0, .r1, .r2, .r3, .r9, .r11] + +theorem roundInput_keeps : ∀ i < 8, (.r10 :: roundKept).all + (fun r => (instrs (sboxInputsLiteral i)).all fun op => dstOf op != some r) = true := by + decide +kernel + +theorem roundOutput_keeps : ∀ i < 8, roundKept.all + (fun r => (instrs (sboxOutputsLiteral i)).all fun op => dstOf op != some r) = true := by + decide +kernel + +theorem roundInput_keep (i : Nat) (hi : i < 8) (r : Reg) (hr : r ∈ .r10 :: roundKept) : + (sboxInputs i).all (fun op => dstOf op != some r) = true := by + have h := List.all_eq_true.mp (roundInput_keeps i hi) r hr + rw [sboxInputsLiteral_eq i hi] at h + exact h + +theorem roundOutput_keep (i : Nat) (hi : i < 8) (r : Reg) (hr : r ∈ roundKept) : + (sboxOutputs i).all (fun op => dstOf op != some r) = true := by + have h := List.all_eq_true.mp (roundOutput_keeps i hi) r hr + rw [sboxOutputsLiteral_eq i hi] at h + exact h + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundBody.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundBody.lean new file mode 100644 index 000000000..88e552eb7 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundBody.lean @@ -0,0 +1,116 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Box +import VerifiedGarbage.Proof.TripleDes.Arm.RoundFunction +import VerifiedGarbage.Proof.Framework.Arm.RegUpd + +namespace VG.Proof.TripleDes.Arm + +open VG VG.Arm VG.Arm.Straight VG.Impl.TripleDes.Arm + +def contribution (r : BitVec 32) (k : BitVec 64) (i : Nat) : BitVec 32 := + (boxPiece i (Spec.TripleDes.sBox i + (roundChunk i (r.setWidth 32) (k.setWidth 48)))).zeroExtend 32 + +/-- Compose any ordered list of S-boxes. The schedule word and Feistel +right half stay fixed; each contribution is XORed into the left half. -/ +theorem boxes_ok (indices : List Nat) (hindices : ∀ i ∈ indices, i < 8) + (r : BitVec 32) (k : BitVec 64) (s : State) (hok : Ok sboxCfg s) + (hr : s.gpr .r11 = r) (hk : keyWord s = k) + (hread : ∀ j < 2, InRegions (s.rd ++ s.wr) (wordAddr (s.gpr .r0) j) 4) + (hsep : ∀ j < 2, (⟨wordAddr (s.gpr .r0) j, 4⟩ : Region).Disjoint (spillRegion s)) : + ∃ s', runBlock isa (indices.flatMap box) s = some s' ∧ + s'.gpr .r10 = indices.foldl (fun out i => out ^^^ contribution r k i) (s.gpr .r10) ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ + (∀ q ∈ roundKept, s'.gpr q = s.gpr q) ∧ + Frame [spillRegion s] s.mem s'.mem := by + induction indices generalizing s with + | nil => + exact ⟨s, runBlock_nil, rfl, rfl, rfl, rfl, fun _ _ => rfl, Frame.refl _ _⟩ + | cons i indices ih => + have hi : i < 8 := hindices i (List.mem_cons_self) + obtain ⟨s₁, run₁, value₁, rd₁, wr₁, sp₁, keep₁, frame₁⟩ := box_ok i hi s hok hread + have hregion : spillRegion s₁ = spillRegion s := by + simp only [spillRegion, keep₁ .r2 (by decide)] + have hr₁ : s₁.gpr .r11 = r := (keep₁ .r11 (by decide)).trans hr + have hword (j : Nat) (hj : j < 2) : + s₁.mem.readW (wordAddr (s₁.gpr .r0) j) 32 = s.mem.readW (wordAddr (s.gpr .r0) j) 32 := by + rw [keep₁ .r0 (by decide)] + apply frame₁.readW (r := ⟨wordAddr (s.gpr .r0) j, 4⟩) (Region.contains_self _ _) + (fun q hq => by obtain rfl := List.mem_singleton.mp hq; exact hsep j hj) (by decide) + have hk₁ : keyWord s₁ = k := by + unfold keyWord + rw [hword 0 (by decide), hword 1 (by decide)] + exact hk + have hread₁ : ∀ j < 2, InRegions (s₁.rd ++ s₁.wr) (wordAddr (s₁.gpr .r0) j) 4 := by + rw [rd₁, wr₁, keep₁ .r0 (by decide)] + exact hread + have hsep₁ : ∀ j < 2, (⟨wordAddr (s₁.gpr .r0) j, 4⟩ : Region).Disjoint (spillRegion s₁) := by + rw [keep₁ .r0 (by decide), hregion] + exact hsep + have hok₁ : Ok sboxCfg s₁ := hok.congr + (keep₁ .r2 (by decide)) (keep₁ .r2 (by decide)) rd₁ wr₁ + obtain ⟨s₂, run₂, value₂, rd₂, wr₂, sp₂, keep₂, frame₂⟩ := ih + (fun j hj => hindices j (List.mem_cons_of_mem _ hj)) s₁ hok₁ hr₁ hk₁ hread₁ hsep₁ + refine ⟨s₂, ?_, ?_, rd₂.trans rd₁, wr₂.trans wr₁, sp₂.trans sp₁, ?_, ?_⟩ + · simp only [List.flatMap_cons, runBoxes_append, run₁, Option.bind_some, run₂] + · rw [hr, hk] at value₁ + change s₁.gpr .r10 = s.gpr .r10 ^^^ contribution r k i at value₁ + simpa only [List.foldl_cons, ← value₁] using value₂ + · exact fun q hq => (keep₂ q hq).trans (keep₁ q hq) + · rw [hregion] at frame₂ + exact frame₁.trans frame₂ + +theorem contributions_roundFunction (r : BitVec 32) (k : BitVec 64) (l : BitVec 32) : + (List.range 8).foldl (fun out i => out ^^^ contribution r k i) l = + l ^^^ Spec.TripleDes.roundFunction r (k.setWidth 48) := by + rw [foldl_xor_start] + exact congrArg (l ^^^ ·) (by + simpa only [contribution, BitVec.zeroExtend_eq_setWidth, BitVec.setWidth_eq] using + boxPieces_eq_roundFunction r (k.setWidth 48)) + +def roundOuterKept : List Reg := [.r0, .r1, .r2, .r3, .r9] + +theorem swapHalves_ok (s : State) : + ∃ s', runBlock isa swapHalves s = some s' ∧ + s'.gpr .r10 = s.gpr .r11 ∧ s'.gpr .r11 = s.gpr .r10 ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ s'.mem = s.mem ∧ + (∀ q ∈ roundOuterKept, s'.gpr q = s.gpr q) := by + open VG.Arm.RegUpd in + refine ⟨_, by + simp only [swapHalves, rr, runBlock_cons, runStep_some, runBlock_nil, exec, Op2.eval, Option.map_some] + rfl, ?_, ?_, ?_, ?_, ?_, ?_, ?_⟩ + · simp only [gpr_setReg, reduceCtorEq, ite_false, ite_true] + · simp only [gpr_setReg, reduceCtorEq, ite_false, ite_true] + · simp only [rd_setReg] + · simp only [wr_setReg] + · simp only [sp_setReg] + · simp only [mem_setReg] + · intro q hq + have hneq : q ≠ .lr ∧ q ≠ .r10 ∧ q ≠ .r11 := by revert hq; cases q <;> decide + simp only [gpr_setReg, hneq.1, hneq.2.1, hneq.2.2, ite_false] + +/-- One full Feistel round, with all eight S-boxes and the half swap. -/ +theorem roundBody_ok (s : State) (l r : BitVec 32) (k : BitVec 64) + (hl : s.gpr .r10 = l) (hr : s.gpr .r11 = r) + (hk : keyWord s = k) (hok : Ok sboxCfg s) + (hread : ∀ j < 2, InRegions (s.rd ++ s.wr) (wordAddr (s.gpr .r0) j) 4) + (hsep : ∀ j < 2, (⟨wordAddr (s.gpr .r0) j, 4⟩ : Region).Disjoint (spillRegion s)) : + ∃ s', runBlock isa roundBody s = some s' ∧ + s'.gpr .r10 = r ∧ + s'.gpr .r11 = (l ^^^ Spec.TripleDes.roundFunction r (k.setWidth 48)) ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ + (∀ q ∈ roundOuterKept, s'.gpr q = s.gpr q) ∧ + Frame [spillRegion s] s.mem s'.mem := by + obtain ⟨s₁, run₁, value, rd₁, wr₁, sp₁, keep₁, frame₁⟩ := boxes_ok (List.range 8) + (fun i hi => List.mem_range.mp hi) (r) k s hok hr hk hread hsep + obtain ⟨s₂, run₂, left, right, rd₂, wr₂, sp₂, mem₂, keep₂⟩ := swapHalves_ok s₁ + refine ⟨s₂, ?_, ?_, ?_, rd₂.trans rd₁, wr₂.trans wr₁, sp₂.trans sp₁, ?_, ?_⟩ + · simp only [roundBody, runBoxes_append, run₁, Option.bind_some, run₂] + · exact left.trans ((keep₁ .r11 (by decide)).trans hr) + · rw [right, value, contributions_roundFunction, hl] + · intro q hq + have hq' : q ∈ roundKept := by revert hq; cases q <;> decide + exact (keep₂ q hq).trans (keep₁ q hq') + · rw [mem₂] + exact frame₁ + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundFunction.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundFunction.lean new file mode 100644 index 000000000..ea09243c7 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundFunction.lean @@ -0,0 +1,72 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Round +import VerifiedGarbage.Proof.TripleDes.Round + +namespace VG.Proof.TripleDes.Arm + +open VG VG.Bitslice VG.Spec.TripleDes + +theorem boxSource_shape : ∀ j < 32, + 7 - (32 - p.getD (31 - j) 1) / 4 = boxSource j / 4 ∧ + (32 - p.getD (31 - j) 1) % 4 = 3 - boxSource j % 4 ∧ + boxSource j / 4 < 8 := by + decide +kernel + +theorem boxPiece_round_bit (i : Nat) (r : BitVec 32) (k : BitVec 48) + (j : Nat) (hj : j < 32) : + (boxPiece i (sBox i (roundChunk i r k))).getLsbD j = + if boxSource j / 4 = i then (roundFunction r k).getLsbD j else false := by + simp only [boxPiece, getLsbD_ofBits, hj, decide_true, Bool.true_and] + by_cases heq : boxSource j / 4 = i + · simp only [heq, ite_true] + rw [VG.Proof.TripleDes.roundFunction_bit r k j hj] + obtain ⟨hidx, hbit, _⟩ := boxSource_shape j hj + simp only [hidx, hbit, heq, roundChunk] + · simp only [heq, ite_false] + +theorem foldl_xor_bits (xs : List Nat) (f : Nat → BitVec 32) (a : BitVec 32) (j : Nat) : + (xs.foldl (fun out i => out ^^^ f i) a).getLsbD j = + xs.foldl (fun out i => out ^^ (f i).getLsbD j) (a.getLsbD j) := by + induction xs generalizing a with + | nil => rfl + | cons i xs ih => + simp only [List.foldl_cons, ih, BitVec.getLsbD_xor] + +theorem select_xor : ∀ n < 8, ∀ b : Bool, + (List.range 8).foldl (fun out i => out ^^ (if n = i then b else false)) false = b := by + decide +kernel + +/-- The eight S-box contributions give the standard DES round function. -/ +theorem boxPieces_eq_roundFunction (r : BitVec 32) (k : BitVec 48) : + (List.range 8).foldl (fun out i => out ^^^ boxPiece i (sBox i (roundChunk i r k))) + (0 : BitVec 32) = roundFunction r k := by + apply BitVec.eq_of_getLsbD_eq + intro j hj + have hfold : (fun (out : Bool) i => out ^^ + (boxPiece i (sBox i (roundChunk i r k))).getLsbD j) = + (fun out i => out ^^ (if boxSource j / 4 = i then + (roundFunction r k).getLsbD j else false)) := by + funext out i + exact congrArg (fun b => out ^^ b) (boxPiece_round_bit i r k j hj) + have hbits := foldl_xor_bits (List.range 8) + (fun i => boxPiece i (sBox i (roundChunk i r k))) 0 j + have hz : (0 : BitVec 32).getLsbD j = false := by + change (BitVec.ofNat 32 0).getLsbD j = false + exact BitVec.getLsbD_zero + have hinit := congrArg (fun b : Bool => (List.range 8).foldl + (fun out i => out ^^ (boxPiece i (sBox i (roundChunk i r k))).getLsbD j) b) hz + have hchange := congrArg + (fun f : Bool → Nat → Bool => (List.range 8).foldl f false) hfold + exact hbits.trans (hinit.trans (hchange.trans (select_xor _ (boxSource_shape j hj).2.2 _))) + +theorem foldl_xor_start (xs : List Nat) (f : Nat → BitVec 32) (a : BitVec 32) : + xs.foldl (fun out i => out ^^^ f i) a = + a ^^^ xs.foldl (fun out i => out ^^^ f i) 0 := by + induction xs generalizing a with + | nil => simp + | cons i xs ih => + simp only [List.foldl_cons] + have hz : (0 : BitVec 32) ^^^ f i = f i := BitVec.zero_xor + rw [hz, ih (a ^^^ f i), ih (f i)] + exact BitVec.xor_assoc _ _ _ + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundLit.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundLit.lean new file mode 100644 index 000000000..0435715b2 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundLit.lean @@ -0,0 +1,25 @@ +import VerifiedGarbage.Impl.TripleDes.Arm.Block +import VerifiedGarbage.Proof.Framework.Arm.Lit + +namespace VG.Impl.TripleDes.Arm + +open VG.Arm + +materialize_code sboxInputs0 := (.block (sboxInputs 0) : Prog isa) +materialize_code sboxInputs1 := (.block (sboxInputs 1) : Prog isa) +materialize_code sboxInputs2 := (.block (sboxInputs 2) : Prog isa) +materialize_code sboxInputs3 := (.block (sboxInputs 3) : Prog isa) +materialize_code sboxInputs4 := (.block (sboxInputs 4) : Prog isa) +materialize_code sboxInputs5 := (.block (sboxInputs 5) : Prog isa) +materialize_code sboxInputs6 := (.block (sboxInputs 6) : Prog isa) +materialize_code sboxInputs7 := (.block (sboxInputs 7) : Prog isa) +materialize_code sboxOutputs0 := (.block (sboxOutputs 0) : Prog isa) +materialize_code sboxOutputs1 := (.block (sboxOutputs 1) : Prog isa) +materialize_code sboxOutputs2 := (.block (sboxOutputs 2) : Prog isa) +materialize_code sboxOutputs3 := (.block (sboxOutputs 3) : Prog isa) +materialize_code sboxOutputs4 := (.block (sboxOutputs 4) : Prog isa) +materialize_code sboxOutputs5 := (.block (sboxOutputs 5) : Prog isa) +materialize_code sboxOutputs6 := (.block (sboxOutputs 6) : Prog isa) +materialize_code sboxOutputs7 := (.block (sboxOutputs 7) : Prog isa) + +end VG.Impl.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundStep.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundStep.lean new file mode 100644 index 000000000..d1f64d92f --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/RoundStep.lean @@ -0,0 +1,67 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.RoundBody +import VerifiedGarbage.Proof.Rc2.Arm.KeySteps + +namespace VG.Proof.TripleDes.Arm +open VG VG.Arm VG.Arm.Straight VG.Arm.RegUpd VG.Impl.TripleDes.Arm +open VG.Proof.Rc2.Arm (gpr_subFlags mem_subFlags) + +def roundStepKept : List Reg := [.r1, .r2, .r3] + +theorem countDown_rules : ∀ n < 17, 1 ≤ n → + (BitVec.ofNat 32 n - 1 = BitVec.ofNat 32 (n - 1)) ∧ + (!(BitVec.ofNat 32 n - 1 == 0)) = decide (n ≠ 1) := by decide +kernel + +theorem roundAdvance_ok (d : Spec.TripleDes.Direction) (s : State) : + ∃ s', runBlock isa (roundAdvance d) s = some s' ∧ + s'.gpr .r0 = (if d = .encrypt then s.gpr .r0 + 8 else s.gpr .r0 - 8) ∧ + s'.gpr .r9 = s.gpr .r9 - 1 ∧ + s'.z = ((s.gpr .r9 - 1) == 0) ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ s'.mem = s.mem ∧ + (∀ r, r ≠ .r9 → r ≠ .r0 → s'.gpr r = s.gpr r) := by + cases d <;> refine ⟨_, by + simp only [roundAdvance, ite_true, reduceCtorEq, ite_false, runBlock_cons, + exec, Op2.eval, encodable, reduceCtorEq, ite_false] + rfl, ?_, ?_, ?_, ?_, ?_, ?_, ?_, ?_⟩ + all_goals try simp only [gpr_setReg, reduceCtorEq, ite_true, ite_false, + z_setReg, subFlags, rd_setReg, wr_setReg, sp_setReg, mem_setReg] + all_goals try rfl + all_goals + intro r hr₁ hr₂ + simp only [hr₁, hr₂, ite_false] + +theorem roundStep_ok (d : Spec.TripleDes.Direction) (s : State) + (l r : BitVec 32) (k : BitVec 64) (n : Nat) (hn : 1 ≤ n) (hn' : n < 17) + (hl : s.gpr .r10 = l) (hr : s.gpr .r11 = r) + (hk : keyWord s = k) (hok : Ok sboxCfg s) + (hread : ∀ j < 2, InRegions (s.rd ++ s.wr) (wordAddr (s.gpr .r0) j) 4) + (hsep : ∀ j < 2, (⟨wordAddr (s.gpr .r0) j, 4⟩ : Region).Disjoint (spillRegion s)) + (hcount : s.gpr .r9 = BitVec.ofNat 32 n) : + ∃ s', runBlock isa (roundBody ++ roundAdvance d) s = some s' ∧ + s'.gpr .r10 = r ∧ + s'.gpr .r11 = (l ^^^ Spec.TripleDes.roundFunction r (k.setWidth 48)) ∧ + s'.gpr .r0 = (if d = .encrypt then s.gpr .r0 + 8 else s.gpr .r0 - 8) ∧ + s'.gpr .r9 = BitVec.ofNat 32 (n - 1) ∧ + isa.eval .ne s' = some (decide (n ≠ 1)) ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ + (∀ q ∈ roundStepKept, s'.gpr q = s.gpr q) ∧ + Frame [spillRegion s] s.mem s'.mem := by + obtain ⟨s₁, run₁, left₁, right₁, rd₁, wr₁, sp₁, keep₁, frame₁⟩ := + roundBody_ok s l r k hl hr hk hok hread hsep + obtain ⟨s₂, run₂, ptr₂, count₂, z₂, rd₂, wr₂, sp₂, mem₂, keep₂⟩ := roundAdvance_ok d s₁ + obtain ⟨hsub, hzero⟩ := countDown_rules n hn' hn + have hcount₁ : s₁.gpr .r9 = BitVec.ofNat 32 n := (keep₁ .r9 (by decide)).trans hcount + refine ⟨s₂, ?_, ?_, ?_, ?_, ?_, ?_, rd₂.trans rd₁, wr₂.trans wr₁, sp₂.trans sp₁, ?_, ?_⟩ + · simp only [runBoxes_append, run₁, Option.bind_some, run₂] + · exact (keep₂ .r10 (by decide) (by decide)).trans left₁ + · exact (keep₂ .r11 (by decide) (by decide)).trans right₁ + · rw [ptr₂, keep₁ .r0 (by decide)] + · rw [count₂, hcount₁, hsub] + · change VG.Arm.eval .ne s₂ = _ + simp only [VG.Arm.eval, z₂, hcount₁, hzero] + · intro q hq + have hq' : q ∈ roundOuterKept := by revert hq; cases q <;> decide + have hneq : q ≠ .r9 ∧ q ≠ .r0 := by revert hq; cases q <;> decide + exact (keep₂ q hneq.1 hneq.2).trans (keep₁ q hq') + · rw [mem₂]; exact frame₁ + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Save.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Save.lean new file mode 100644 index 000000000..0028ac245 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Save.lean @@ -0,0 +1,77 @@ +import VerifiedGarbage.Proof.Rc2.Arm.Save +import VerifiedGarbage.Proof.TripleDes.Arm.RoundStep + +namespace VG.Proof.TripleDes.Arm + +open VG VG.Arm VG.Impl.TripleDes.Arm + +def savedReg (i : Nat) : Reg := savedRegs.getD i .r4 + +theorem blockSave_eq : blockSave = VG.Proof.Rc2.Arm.saveCode .r2 savedReg 9 := by + decide +kernel + +theorem blockRestore_eq : blockRestore = VG.Proof.Rc2.Arm.restoreCode .r2 savedReg (List.range 9) := by + decide +kernel + +def Saved (original current : State) : Prop := + ∀ i < 9, current.mem.readW (State.addr (current.gpr .r2) + BitVec.ofNat 64 (4 * i)) 32 = + original.gpr (savedReg i) + +structure SavePost (original current : State) : Prop where + gpr : current.gpr = original.gpr + rd : current.rd = original.rd + wr : current.wr = original.wr + sp : current.sp = original.sp + saved : Saved original current + frame : Frame [⟨State.addr (original.gpr .r2), 36⟩] original.mem current.mem + +theorem blockSave_ok (s : State) + (fit : (s.gpr .r2).toNat + 256 ≤ 2 ^ 32) + (hw : ∀ i < 9, InRegions s.wr (State.addr (s.gpr .r2) + BitVec.ofNat 64 (4 * i)) 4) : + WP isa (.block blockSave) s (SavePost s) := by + rw [blockSave_eq] + obtain ⟨t, s', he, hs⟩ := VG.Proof.Rc2.Arm.saveCode_ok s .r2 savedReg 9 (by decide) fit hw + refine ⟨t, s', he, hs.1, hs.2.1, hs.2.2.1, VG.Arm.Exec.sp he, ?_, ?_⟩ + · intro i hi + rw [hs.1, hs.2.2.2] + exact VG.Proof.Rc2.Arm.saveMem_read _ _ _ 9 (by decide) i hi + · rw [hs.2.2.2] + exact VG.Proof.Rc2.Arm.saveMem_frame _ _ _ 9 (by decide) + +theorem savedReg_separate : ∀ i < 9, savedReg i ≠ .r2 := by decide +kernel + +structure RestorePost (original origin current : State) : Prop where + saved : ∀ r ∈ savedRegs, current.gpr r = original.gpr r + keep : VG.Proof.Rc2.Arm.Keep savedRegs origin current + sp : current.sp = origin.sp + +theorem blockRestore_ok (original s : State) (hsaved : Saved original s) + (fit : (s.gpr .r2).toNat + 256 ≤ 2 ^ 32) + (hread : ∀ i < 9, InRegions (s.rd ++ s.wr) (State.addr (s.gpr .r2) + BitVec.ofNat 64 (4 * i)) 4) : + WP isa (.block blockRestore) s (RestorePost original s) := by + rw [blockRestore_eq] + have hregs : (List.range 9).map savedReg = savedRegs := by decide +kernel + obtain ⟨t, s', he, hs⟩ := VG.Proof.Rc2.Arm.restoreCode_ok s .r2 savedReg (List.range 9) original.gpr fit + (fun i hi => by have := List.mem_range.mp hi; omega) + (fun i hi => savedReg_separate i (List.mem_range.mp hi)) + (fun i hi => hread i (List.mem_range.mp hi)) + (fun i hi => hsaved i (List.mem_range.mp hi)) + rw [hregs] at hs + exact ⟨t, s', he, hs.1, hs.2, VG.Arm.Exec.sp he⟩ + +theorem savedSlot_spill_disjoint (s : State) (i : Nat) (hi : i < 9) : + (⟨State.addr (s.gpr .r2) + BitVec.ofNat 64 (4 * i), 4⟩ : Region).Disjoint (spillRegion s) := + Offset.disjoint (State.addr (s.gpr .r2)) (by omega) (by omega) (by decide) + +theorem Saved.congr {original s t : State} (hs : Saved original s) + (hbase : t.gpr .r2 = s.gpr .r2) (hf : Frame [spillRegion s] s.mem t.mem) : + Saved original t := by + intro i hi + have hmem := hf.readW (a := State.addr (s.gpr .r2) + BitVec.ofNat 64 (4 * i)) (w := 32) + (r := ⟨State.addr (s.gpr .r2) + BitVec.ofNat 64 (4 * i), 4⟩) (Region.contains_self _ _) + (fun q hq => by obtain rfl := List.mem_singleton.mp hq; exact savedSlot_spill_disjoint s i hi) + (by decide) + rw [hbase] + exact hmem.trans (hs i hi) + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Sbox.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Sbox.lean new file mode 100644 index 000000000..3fcb07171 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Sbox.lean @@ -0,0 +1,114 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Lit +import VerifiedGarbage.Spec.TripleDes +import VerifiedGarbage.Proof.Framework.Arm.Straight +import VerifiedGarbage.Proof.Framework.Bitslice.Table + +/-! +# DES S-box machine-code correctness + +Untrusted. The kernel checks each allocated scalar circuit on all 64 +inputs, then the sound truth-table evaluator lifts that check to every +bit position of arbitrary 32-bit words. This verifies both the circuits +and the allocator's output, including spills. +-/ + +namespace VG.Proof.TripleDes.Arm + +open VG VG.Arm VG.Arm.Straight VG.Bitslice VG.Impl.TripleDes.Arm + +noncomputable def sboxLiterals : Array (Prog isa) := + #[sbox0.lit, sbox1.lit, sbox2.lit, sbox3.lit, sbox4.lit, sbox5.lit, sbox6.lit, sbox7.lit] + +noncomputable def sboxLiteral (i : Nat) : Prog isa := sboxLiterals.getD i (.block []) + +def sboxCfg : Cfg := { base := .r2, slots := 128, ext := .r2, exts := 0 } +def inputTable (k : Nat) : Nat := tableOf (fun c => c.testBit k) 64 +def outputTable (i j : Nat) : Nat := + tableOf (fun c => (Spec.TripleDes.sBox i (BitVec.ofNat 6 c)).getLsbD j) 64 + +def sboxEnv : Env Nat := + { reg := fun r => ((List.range 6).find? (fun k => q k == r)).map inputTable, + slot := fun _ => none } + +def sboxPost (i : Nat) (e : Env Nat) : Bool := + (List.range 4).all fun j => e.reg (q j) == some (outputTable i j) + +theorem sbox_check : ∀ i < 8, + check (table 32 64) sboxCfg (fun _ => none) (instrs (sboxLiteral i)) + sboxEnv (sboxPost i) = true := by + decide +kernel + +def sboxWrites : List Reg := [.r4, .r5, .r6, .r7, .r8, .r12, .lr] + +theorem sbox_preserves : ∀ i < 8, + [Reg.r0, .r1, .r2, .r3, .r9, .r10, .r11].all + (fun r => (instrs (sboxLiteral i)).all fun op => dstOf op != some r) = true := by + decide +kernel + +def inputAt (s : State) (p : Nat) : BitVec 6 := + ofBits 6 fun j => (s.gpr (q j)).getLsbD p + +theorem inputAt_bit (s : State) (p k : Nat) (hk : k < 6) : + (inputAt s p).toNat.testBit k = (s.gpr (q k)).getLsbD p := by + simp only [inputAt, BitVec.testBit_toNat, getLsbD_ofBits, hk, decide_true, Bool.true_and] + +theorem sboxLiteral_eq : ∀ i < 8, sboxLiteral i = .block (sboxCode i) + | 0, _ => sbox0.lit_eq.symm + | 1, _ => sbox1.lit_eq.symm + | 2, _ => sbox2.lit_eq.symm + | 3, _ => sbox3.lit_eq.symm + | 4, _ => sbox4.lit_eq.symm + | 5, _ => sbox5.lit_eq.symm + | 6, _ => sbox6.lit_eq.symm + | 7, _ => sbox7.lit_eq.symm + | n + 8, h => by omega + +/-- Every S-box output bit, for arbitrary input words and any readable/ +writable scratch state. Only the fixed scratch region can change. -/ +theorem sbox_ok (i : Nat) (hi : i < 8) {s : State} (hok : Ok sboxCfg s) : + ∃ s', runBlock isa (sboxCode i) s = some s' ∧ + (∀ j < 4, ∀ p < 32, (s'.gpr (q j)).getLsbD p = + (Spec.TripleDes.sBox i (inputAt s p)).getLsbD j) ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ + (∀ r, r ∉ sboxWrites → s'.gpr r = s.gpr r) ∧ + Frame [slotRegion sboxCfg s] s.mem s'.mem := by + have codeEq : instrs (sboxLiteral i) = sboxCode i := by rw [sboxLiteral_eq i hi]; rfl + obtain ⟨e', he, hpost⟩ := of_check _ _ _ (sbox_check i hi) + rw [codeEq] at he + have hout : ∀ j < 4, e'.reg (q j) = some (outputTable i j) := by + intro j hj + have h := List.all_eq_true.mp hpost j (List.mem_range.mpr hj) + exact beq_iff_eq.mp h + have key : ∀ p < 32, ∃ s', runBlock isa (sboxCode i) s = some s' ∧ + Post (TableRel p (inputAt s p).toNat) sboxCfg (fun _ => none) e' s s' + (fun r => ((sboxCode i).all fun op => dstOf op != some r) = false) := by + intro p hp + have hc := (inputAt s p).isLt + refine run (table_sound hp hc) hok ⟨fun r a h => ?_, + (fun _ _ _ h => by cases h), (fun _ _ _ h => by cases h), + (fun _ _ h => by cases h)⟩ he + simp only [sboxEnv, Option.map_eq_some_iff] at h + obtain ⟨k, hk, rfl⟩ := h + have hqr := List.find?_some hk + have hk6 := List.mem_range.mp (List.mem_of_find?_eq_some hk) + simp only [beq_iff_eq] at hqr + subst hqr + simp only [TableRel, inputTable, testBit_tableOf, hc, decide_true, Bool.true_and, + inputAt_bit s p k hk6] + obtain ⟨s', hs', p₀⟩ := key 0 (by decide) + refine ⟨s', hs', fun j hj p hp => ?_, p₀.rd, p₀.wr, p₀.sp, fun r hr => ?_, p₀.frame⟩ + · obtain ⟨s'', hs'', p₁⟩ := key p hp + obtain rfl := run_unique hs'' hs' + have h := p₁.rel.reg (q j) _ (hout j hj) + simp only [TableRel, outputTable, testBit_tableOf, (inputAt s p).isLt, + decide_true, Bool.true_and] at h + rw [BitVec.ofNat_toNat] at h + exact h.symm + · apply p₀.other r + have hrest : r ∈ [Reg.r0, .r1, .r2, .r3, .r9, .r10, .r11] := by + revert hr; cases r <;> decide + have h := List.all_eq_true.mp (sbox_preserves i hi) r hrest + rw [codeEq] at h + simp [h] + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Spills.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Spills.lean new file mode 100644 index 000000000..ab609e3e9 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Spills.lean @@ -0,0 +1,83 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Sbox +import VerifiedGarbage.Proof.Framework.Arm.RegUpd +import VerifiedGarbage.Proof.Framework.Offset +import VerifiedGarbage.Proof.Framework.Omega + +namespace VG.Proof.TripleDes.Arm +open VG VG.Arm VG.Arm.RegUpd VG.Impl.TripleDes.Arm + +def spillRegion (s : State) : Region := ⟨State.addr (s.gpr .r2) + BitVec.ofNat 64 60, 388⟩ +def spillSafe : Instr → Bool + | .mov d _ | .dp _ d _ _ | .ldr d _ _ => d != .r2 + | .str _ n off => decide (n = .r2 ∧ 60 ≤ off ∧ off + 4 ≤ 448) + | _ => false + +theorem spillSafe_check : ∀ i < 8, + (instrs (sboxLiteral i)).all spillSafe = true := by decide +kernel + +theorem write_frame (s : State) (d : Reg) (v : BitVec 32) (hd : d ≠ .r2) : + (s.setReg d v).gpr .r2 = s.gpr .r2 ∧ Frame [spillRegion s] s.mem (s.setReg d v).mem := + ⟨gpr_setReg_of_ne _ _ (Ne.symm hd), by rw [mem_setReg]; exact Frame.refl _ _⟩ + +theorem spillStep_frame (i : Instr) (s s' : State) + (fit : (s.gpr .r2).toNat + 512 ≤ 2 ^ 32) + (h : spillSafe i = true) (he : exec i s = some s') : + s'.gpr .r2 = s.gpr .r2 ∧ Frame [spillRegion s] s.mem s'.mem := by + cases i <;> simp only [spillSafe, Bool.false_eq_true] at h + case mov d op2 => + have hd : d ≠ .r2 := by simpa using h + simp only [exec, Option.map_eq_some_iff] at he + obtain ⟨v, _, rfl⟩ := he + exact write_frame _ _ _ hd + case dp op d n op2 => + have hd : d ≠ .r2 := by simpa using h + simp only [exec, Option.map_eq_some_iff] at he + obtain ⟨v, _, rfl⟩ := he + exact write_frame _ _ _ hd + case ldr d n off => + have hd : d ≠ .r2 := by simpa using h + simp only [exec] at he + split at he <;> [skip; cases he] + simp only [Option.map_eq_some_iff] at he + obtain ⟨v, _, rfl⟩ := he + exact write_frame _ _ _ hd + case str t n off => + obtain ⟨rfl, hlo, hhi⟩ := of_decide_eq_true h + simp only [exec] at he + split at he <;> [skip; cases he] + simp only [State.store32] at he + split at he <;> [skip; cases he] + obtain rfl := Option.some.inj he + refine ⟨rfl, ?_⟩ + rw [addr_add (by omega_using [fit, hhi])] + exact (Frame.refl _ _).writeW (List.mem_singleton_self _) _ + (Offset.contains (State.addr (s.gpr .r2)) (by omega) (by omega) (by decide)) + +theorem spillBlock_frame (is : List Instr) (s s' : State) + (fit : (s.gpr .r2).toNat + 512 ≤ 2 ^ 32) + (hsafe : is.all spillSafe = true) (he : runBlock isa is s = some s') : + s'.gpr .r2 = s.gpr .r2 ∧ Frame [spillRegion s] s.mem s'.mem := by + induction is generalizing s with + | nil => + rw [runBlock_nil] at he + obtain rfl := Option.some.inj he + exact ⟨rfl, Frame.refl _ _⟩ + | cons i is ih => + simp only [List.all_cons, Bool.and_eq_true] at hsafe + rw [runBlock_cons] at he + change (exec i s).bind (runBlock isa is) = some s' at he + obtain ⟨s₁, hi, hrest⟩ := Option.bind_eq_some_iff.mp he + obtain ⟨hg, hf⟩ := spillStep_frame i s s₁ fit hsafe.1 hi + obtain ⟨hg', hf'⟩ := ih s₁ (by rw [hg]; exact fit) hsafe.2 hrest + refine ⟨hg'.trans hg, hf.trans ?_⟩ + have hr : spillRegion s₁ = spillRegion s := by simp only [spillRegion, hg] + rw [hr] at hf' + exact hf' + +theorem sbox_spillFrame (i : Nat) (hi : i < 8) (s s' : State) + (fit : (s.gpr .r2).toNat + 512 ≤ 2 ^ 32) + (he : runBlock isa (sboxCode i) s = some s') : Frame [spillRegion s] s.mem s'.mem := by + have h := spillSafe_check i hi + rw [sboxLiteral_eq i hi] at h + exact (spillBlock_frame _ _ _ fit h he).2 +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Store.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Store.lean new file mode 100644 index 000000000..cbc2201e5 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Store.lean @@ -0,0 +1,71 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.BlockIO +import VerifiedGarbage.Proof.TripleDes.Arm.WordStore +import VerifiedGarbage.Proof.TripleDes.Word + +namespace VG.Proof.TripleDes.Arm +open VG VG.Arm VG.Arm.RegUpd VG.Impl.TripleDes.Arm +open VG.Spec.TripleDes (Direction) + +def storeTail (d : Direction) : List Instr := + [.rev .r4 .r4, .rev .r5 .r5, .str .r4 .r1 0, .str .r5 .r1 4, + .dp (if d = .encrypt then .sub else .add) .r0 .r0 + (.imm (if d = .encrypt then 384 else 8))] + +theorem storeTail_ok (d : Direction) (s : State) + (fit : (s.gpr .r1).toNat + 8 ≤ 2 ^ 32) + (hw : ∀ t < 2, InRegions s.wr (State.addr (s.gpr .r1 + BitVec.ofNat 32 (4 * t))) 4) : + ∃ s', runBlock isa (storeTail d) s = some s' ∧ + s'.mem = s.mem.writeW (State.addr (s.gpr .r1)) + (byteRev64 (s.gpr .r4 ++ s.gpr .r5)) ∧ + s'.gpr .r0 = (if d = .encrypt then s.gpr .r0 - 384 else s.gpr .r0 + 8) ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ + (∀ r, r ≠ .r0 → r ≠ .r4 → r ≠ .r5 → s'.gpr r = s.gpr r) := by + have h0 : InRegions s.wr (State.addr (s.gpr .r1 + BitVec.ofNat 32 0)) 4 := by + simpa only [Nat.mul_zero] using hw 0 (by decide) + have h1 : InRegions s.wr (State.addr (s.gpr .r1 + BitVec.ofNat 32 4)) 4 := by + simpa only [Nat.mul_one] using hw 1 (by decide) + cases d <;> refine ⟨_, by + simp (config := {decide := true}) only [storeTail, ite_true, ite_false, + runBlock_cons, runStep_some, runBlock_nil, exec, State.store32, h0, h1, + Op2.eval, Option.map_some, gpr_setReg, mem_setReg, wr_setReg] + rfl, ?_, ?_, ?_, ?_, ?_, ?_⟩ + all_goals try simp only [gpr_setReg, reduceCtorEq, ite_true, ite_false, + rd_setReg, wr_setReg, sp_setReg] + all_goals try + simp only [mem_setReg, BitVec.add_zero] + rw [addr_add (by omega_using [fit])] + exact (writeW_pair s.mem _ _ _).trans (congrArg (s.mem.writeW _) (revPair _ _)) + all_goals + intro r h0 h4 h5 + simp only [h0, h4, h5, ite_false] + +theorem blockStore_ok (d : Direction) (s : State) (l r : BitVec 32) + (hl : s.gpr .r10 = l) (hr : s.gpr .r11 = r) + (fit : (s.gpr .r1).toNat + 8 ≤ 2 ^ 32) + (hw : ∀ t < 2, InRegions s.wr (State.addr (s.gpr .r1 + BitVec.ofNat 32 (4 * t))) 4) : + ∃ s', runBlock isa (blockStore d) s = some s' ∧ + s'.mem = s.mem.writeW (State.addr (s.gpr .r1)) + (byteRev64 (Spec.TripleDes.permute Spec.TripleDes.fp (l ++ r))) ∧ + s'.gpr .r0 = (if d = .encrypt then s.gpr .r0 - 384 else s.gpr .r0 + 8) ∧ + s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ + (∀ q ∈ loadKept, q ≠ .r0 → s'.gpr q = s.gpr q) := by + obtain ⟨s₁, run₁, lo₁, hi₁, rd₁, wr₁, sp₁, mem₁, reg₁⟩ := final_raw_ok s + rw [hl, hr] at lo₁ hi₁ + have keeps : ∀ q ∈ loadKept, s₁.gpr q = s.gpr q := by + intro q hq + have checks : ∀ q ∈ loadKept, + ((instrs finalPermutation.lit).all fun op => dstOf op != some q) = true := by decide +kernel + exact reg₁ q (checks q hq) + have fit₁ : (s₁.gpr .r1).toNat + 8 ≤ 2 ^ 32 := by rw [keeps .r1 (by decide)]; exact fit + have hw₁ : ∀ t < 2, InRegions s₁.wr (State.addr (s₁.gpr .r1 + BitVec.ofNat 32 (4 * t))) 4 := by + rw [wr₁, keeps .r1 (by decide)]; exact hw + obtain ⟨s₂, run₂, mem₂, ptr₂, rd₂, wr₂, sp₂, reg₂⟩ := storeTail_ok d s₁ fit₁ hw₁ + refine ⟨s₂, ?_, ?_, ?_, rd₂.trans rd₁, wr₂.trans wr₁, sp₂.trans sp₁, ?_⟩ + · rw [blockStore, ← storeTail, runBoxes_append, run₁, Option.bind_some, run₂] + · rw [mem₂, mem₁, keeps .r1 (by decide), hi₁, lo₁, VG.Proof.TripleDes.halves_append] + · rw [ptr₂, keeps .r0 (by decide)] + · intro q hq h0 + have unused : ∀ q ∈ loadKept, q ≠ .r4 ∧ q ≠ .r5 := by decide + exact (reg₂ q h0 (unused q hq).1 (unused q hq).2).trans (keeps q hq) + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Tail.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Tail.lean new file mode 100644 index 000000000..96f30c6c5 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Tail.lean @@ -0,0 +1,67 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Store +import VerifiedGarbage.Proof.TripleDes.Arm.Head + +namespace VG.Proof.TripleDes.Arm +open VG VG.Arm VG.Impl.TripleDes.Arm +open VG.Spec.TripleDes (Direction) + +structure TailPost (original origin : State) (d : Direction) (x : BitVec 64) (s : State) : Prop where + result : Spec.TripleDes.blockAt s.mem (State.addr (origin.gpr .r1)) = + Spec.TripleDes.encodeBlock (Spec.TripleDes.permute Spec.TripleDes.fp x) + saved : ∀ r ∈ savedRegs, s.gpr r = original.gpr r + pointer : s.gpr .r0 = (if d = .encrypt then origin.gpr .r0 - 384 else origin.gpr .r0 + 8) + rd : s.rd = origin.rd + wr : s.wr = origin.wr + sp : s.sp = origin.sp + regs : ∀ q ∈ roundStepKept, s.gpr q = origin.gpr q + frame : Frame [⟨State.addr (origin.gpr .r1), 8⟩] origin.mem s.mem + +theorem blockTail_ok (original s : State) (d : Direction) (x : BitVec 64) + (hword : WordState x s) (hsaved : Saved original s) + (scratchFit : (s.gpr .r2).toNat + 256 ≤ 2 ^ 32) + (dataFit : (s.gpr .r1).toNat + 8 ≤ 2 ^ 32) + (hsavedRead : ∀ i < 9, InRegions (s.rd ++ s.wr) + (State.addr (s.gpr .r2) + BitVec.ofNat 64 (4 * i)) 4) + (hwrite : ∀ t < 2, InRegions s.wr (State.addr (s.gpr .r1 + BitVec.ofNat 32 (4 * t))) 4) + (hsep : (⟨State.addr (s.gpr .r1), 8⟩ : Region).Disjoint (saveRegion s)) : + WP isa (.block (blockStore d ++ blockRestore)) s (TailPost original s d x) := by + rw [WP.block_append_iff] + obtain ⟨s₁, run₁, mem₁, ptr₁, rd₁, wr₁, sp₁, reg₁⟩ := blockStore_ok d s + ((x >>> 32).setWidth 32) (x.setWidth 32) hword.left hword.right dataFit hwrite + rw [VG.Proof.TripleDes.halves_append] at mem₁ + have regs₁ : ∀ q ∈ roundStepKept, s₁.gpr q = s.gpr q := by + intro q hq + have incl : ∀ q ∈ roundStepKept, q ∈ loadKept ∧ q ≠ .r0 := by decide + exact reg₁ q (incl q hq).1 (incl q hq).2 + have frame₁ : Frame [⟨State.addr (s.gpr .r1), 8⟩] s.mem s₁.mem := by + rw [mem₁] + exact (Frame.refl _ _).writeW (List.mem_singleton_self _) _ (Region.contains_self _ _) + have saved₁ : Saved original s₁ := by + intro i hi + rw [regs₁ .r2 (by decide)] + have sub : Region.Sub ⟨State.addr (s.gpr .r2) + BitVec.ofNat 64 (4 * i), 4⟩ (saveRegion s) := + Offset.sub_base _ (by omega_using [hi]) + have mem := frame₁.readW (a := State.addr (s.gpr .r2) + BitVec.ofNat 64 (4 * i)) (w := 32) + (r := ⟨State.addr (s.gpr .r2) + BitVec.ofNat 64 (4 * i), 4⟩) (Region.contains_self _ _) + (fun r hr => by obtain rfl := List.mem_singleton.mp hr; exact (hsep.sub_right sub).symm) + (by decide) + exact mem.trans (hsaved i hi) + have reads₁ : ∀ i < 9, InRegions (s₁.rd ++ s₁.wr) + (State.addr (s₁.gpr .r2) + BitVec.ofNat 64 (4 * i)) 4 := by + rw [rd₁, wr₁, regs₁ .r2 (by decide)]; exact hsavedRead + apply WP.of_runBlock + refine ⟨s₁, run₁, ?_⟩ + apply WP.mono (blockRestore_ok original s₁ saved₁ + (by rw [regs₁ .r2 (by decide)]; exact scratchFit) reads₁) + intro s₂ hs₂ + refine ⟨?_, hs₂.saved, ?_, hs₂.keep.rd.trans rd₁, hs₂.keep.wr.trans wr₁, + hs₂.sp.trans sp₁, ?_, ?_⟩ + · rw [hs₂.keep.mem, mem₁] + exact blockAt_writeW s.mem _ _ + · exact (hs₂.keep.reg .r0 (by decide)).trans ptr₁ + · intro q hq + have unused : ∀ q ∈ roundStepKept, q ∉ savedRegs := by decide + exact (hs₂.keep.reg q (unused q hq)).trans (regs₁ q hq) + · rw [hs₂.keep.mem]; exact frame₁ + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/VerifiedBlock.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/VerifiedBlock.lean new file mode 100644 index 000000000..7de08a909 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/VerifiedBlock.lean @@ -0,0 +1,70 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Pre +import VerifiedGarbage.Proof.Framework.Contract +import VerifiedGarbage.Spec.TripleDes.Contract + +namespace VG.Proof.TripleDes.Arm + +open VG VG.Arm VG.Impl.TripleDes.Arm +open VG.Spec.TripleDes (Direction) + +theorem block_gprCorrect (d : Direction) (s : State) (hs : (blockContract d).pre s) : + WP isa (block d) s (fun s' => ((∀ r ∈ preserved, s'.gpr r = s.gpr r) ∧ s'.sp = s.sp) ∧ (blockContract d).post s s') := by + have hp := headPre_of_contract d s hs + have hwrite : ∀ t < 2, InRegions s.wr (State.addr (s.gpr .r1 + BitVec.ofNat 32 (4 * t))) 4 := by + intro t ht + have fit := hs.2.2.2.2.2.1 + rw [addr_add (by omega_using [fit, ht]), hs.2.1] + exact ⟨⟨State.addr (s.gpr .r1), 8⟩, by simp, + Offset.contains_base _ (by omega_using [ht]) (by omega_using [ht])⟩ + apply WP.mono (block_ok (Spec.TripleDes.scheduleAt s.mem (State.addr (s.gpr .r0))) (s.gpr .r0) d s hp hwrite) + intro s' hpost + refine ⟨⟨?_, hpost.sp⟩, hpost.result⟩ + intro r hr + have hkeep : ∀ q ∈ preserved, q ∈ savedRegs ∨ q ∈ roundStepKept := by decide + rcases hkeep r hr with h | h + · exact hpost.saved r h + · exact hpost.regs r h + +theorem encrypt_correct (s : State) (hs : (blockContract .encrypt).pre s) : + ∃ t s', Exec isa encryptBlock s t s' ∧ abiPreserved s s' ∧ + (blockContract .encrypt).post s s' := by + obtain ⟨t, s', he, ha, hp⟩ := block_gprCorrect .encrypt s hs + change Exec isa encryptBlock s t s' at he + exact ⟨t, s', he, ⟨ha.1, ha.2⟩, hp⟩ + +theorem decrypt_correct (s : State) (hs : (blockContract .decrypt).pre s) : + ∃ t s', Exec isa decryptBlock s t s' ∧ abiPreserved s s' ∧ + (blockContract .decrypt).post s s' := by + obtain ⟨t, s', he, ha, hp⟩ := block_gprCorrect .decrypt s hs + change Exec isa decryptBlock s t s' at he + exact ⟨t, s', he, ⟨ha.1, ha.2⟩, hp⟩ + +def satState : State where + gpr r := match r with + | .r0 => 0x1000 | .r1 => 0x2000 | .r2 => 0x3000 | _ => 0 + sp := 0x4000 + n := false + z := false + c := false + v := false + mem _ := 0 + rd := [⟨0x1000, 384⟩] + wr := [⟨0x2000, 8⟩, ⟨0x3000, 512⟩] + +theorem publicRegs_three (s t : State) : PublicRegs [.r0, .r1, .r2] s t ↔ + s.sp = t.sp ∧ s.gpr .r0 = t.gpr .r0 ∧ s.gpr .r1 = t.gpr .r1 ∧ s.gpr .r2 = t.gpr .r2 := by + simp [PublicRegs] + +theorem encrypt_verified : Verified target encryptBlock (Spec.TripleDes.encryptBlockContract abi) := by + refine Verified.of_correct encrypt_correct + (encryptBlock_constantTime _) ?_ + sig_implies [Spec.TripleDes.encryptBlockContract, Spec.TripleDes.blockSig, abi, argRegs, Arm.reduceClassify, Arm.Loc.val, State.addr, + blockContract, publicRegs_three, blockResult] [satState] using satState + +theorem decrypt_verified : Verified target decryptBlock (Spec.TripleDes.decryptBlockContract abi) := by + refine Verified.of_correct decrypt_correct + (decryptBlock_constantTime _) ?_ + sig_implies [Spec.TripleDes.decryptBlockContract, Spec.TripleDes.blockSig, abi, argRegs, Arm.reduceClassify, Arm.Loc.val, State.addr, + blockContract, publicRegs_three, blockResult] [satState] using satState + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/Word.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Word.lean new file mode 100644 index 000000000..803427878 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/Word.lean @@ -0,0 +1,60 @@ +import VerifiedGarbage.Proof.TripleDes.Word + +namespace VG.Proof.TripleDes.Arm + +theorem mask28 (x : BitVec 32) : x &&& 0x0fffffff = (x.setWidth 28).setWidth 32 := by + apply BitVec.eq_of_toNat_eq + simp only [BitVec.toNat_and, BitVec.toNat_setWidth] + change x.toNat &&& (2 ^ 28 - 1) = x.toNat % 268435456 % 4294967296 + rw [Nat.and_two_pow_sub_one_eq_mod] + omega + +theorem rotate28_word (x : BitVec 28) (n : Nat) (hn : 1 ≤ n) (hn' : n < 5) : + ((x.setWidth 32).rotateRight (32 - n) ^^^ (x.setWidth 32) >>> (28 - n)) &&& 0x0fffffff = + (x.rotateLeft n).setWidth 32 := by + rw [mask28] + apply congrArg (BitVec.setWidth 32) + apply BitVec.eq_of_getLsbD_eq + intro j hj + simp only [BitVec.getLsbD_setWidth, BitVec.getLsbD_xor, BitVec.getLsbD_rotateRight, + BitVec.getLsbD_ushiftRight, BitVec.getLsbD_rotateLeft] + have n32 : (32 - n) % 32 = 32 - n := Nat.mod_eq_of_lt (by omega) + have n28 : n % 28 = n := Nat.mod_eq_of_lt (by omega) + rw [n32, n28] + rw [show 32 - (32 - n) = n by omega] + by_cases h : j < n + · simp (disch := omega) [h, hj, + show j + (28 - n) < 32 by omega, BitVec.getLsbD_of_ge, Nat.add_comm] + · simp (disch := omega) [h, hj, show j < 32 by omega, + show j - n < 32 by omega, BitVec.getLsbD_of_ge] + + +theorem mask_word (x : BitVec 32) (n : Nat) (hn : 0 < n) (hn32 : n ≤ 32) : + (x <<< (32 - n)) >>> (32 - n) = (x.setWidth n).setWidth 32 := by + apply BitVec.eq_of_getLsbD_eq + intro j hj + simp only [BitVec.getLsbD_ushiftRight, BitVec.getLsbD_shiftLeft, BitVec.getLsbD_setWidth] + by_cases h : j < n + · have hi : 32 - n + j < 32 := by omega + have hlo : ¬32 - n + j < 32 - n := by omega + simp only [hi, hlo, h, hj, decide_true, decide_false, Bool.not_false, + Bool.true_and, show 32 - n + j - (32 - n) = j by omega] + · have ho : ¬32 - n + j < 32 := by omega + simp only [ho, h, hj, decide_true, decide_false, Bool.false_and, Bool.true_and] + +theorem packed48 (x : BitVec 48) : + ((x >>> 32).setWidth 16).setWidth 32 ++ x.setWidth 32 = x.setWidth 64 := by + apply BitVec.eq_of_getLsbD_eq + intro i hi + simp only [BitVec.getLsbD_append, BitVec.getLsbD_setWidth, BitVec.getLsbD_ushiftRight, + hi, decide_true, Bool.true_and] + by_cases hlo : i < 32 + · simp only [hlo, ite_true, decide_true, Bool.true_and] + · simp (disch := omega) only [hlo, ite_false, decide_true, Bool.true_and, + show i - 32 < 32 by omega, show 32 + (i - 32) = i by omega] + by_cases h48 : i < 48 + · simp only [show i - 32 < 16 by omega, decide_true, Bool.true_and] + · simp only [show ¬i - 32 < 16 by omega, decide_false, Bool.false_and, + BitVec.getLsbD_of_ge x i (by omega)] + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/WordState.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/WordState.lean new file mode 100644 index 000000000..d765633d4 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/WordState.lean @@ -0,0 +1,28 @@ +import VerifiedGarbage.Proof.TripleDes.Arm.Pass +import VerifiedGarbage.Proof.TripleDes.Word + +namespace VG.Proof.TripleDes.Arm + +open VG VG.Arm VG.Impl.TripleDes.Arm +open VG.Proof.TripleDes (desCore roundPrefix) + +/-- A DES word held as two 32-bit Feistel registers. -/ +structure WordState (x : BitVec 64) (s : State) : Prop where + left : s.gpr .r10 = ((x >>> 32).setWidth 32) + right : s.gpr .r11 = (x.setWidth 32) + +theorem PassPost.wordState {keys : Spec.TripleDes.DesSchedule} + {direction : Spec.TripleDes.Direction} {base : BitVec 32} {origin s : State} {x : BitVec 64} + (hs : PassPost keys direction base origin ((x >>> 32).setWidth 32, x.setWidth 32) s) : + WordState (desCore keys direction x) s := by + have hcore := VG.Proof.TripleDes.desCore_roundPrefix keys direction x + let halves := roundPrefix keys direction 16 ((x >>> 32).setWidth 32, x.setWidth 32) + have hleft : ((desCore keys direction x >>> 32).setWidth 32) = halves.2 := + (congrArg (fun v : BitVec 64 => ((v >>> 32).setWidth 32)) hcore).trans + (VG.Proof.TripleDes.appended_left halves.2 halves.1) + have hright : ((desCore keys direction x).setWidth 32) = halves.1 := + (congrArg (fun v : BitVec 64 => (v.setWidth 32)) hcore).trans + (VG.Proof.TripleDes.appended_right halves.2 halves.1) + exact ⟨hs.left.trans hleft.symm, hs.right.trans hright.symm⟩ + +end VG.Proof.TripleDes.Arm diff --git a/lean/VerifiedGarbage/Proof/TripleDes/Arm/WordStore.lean b/lean/VerifiedGarbage/Proof/TripleDes/Arm/WordStore.lean new file mode 100644 index 000000000..0a245a441 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/Arm/WordStore.lean @@ -0,0 +1,70 @@ +import VerifiedGarbage.Proof.Framework.Mem + +namespace VG.Proof.TripleDes.Arm +open VG + +theorem getLsbD_read (m : Mem) : ∀ (n : Nat) (a : Addr) (i : Nat), i < 8 * n → + (m.read a n).getLsbD i = (m (a + BitVec.ofNat 64 (i / 8))).getLsbD (i % 8) + | 0, _, _, h => absurd h (by omega) + | n + 1, a, i, h => by + simp only [Mem.read, BitVec.getLsbD_append] + by_cases hi : i < 8 + · simp [hi, Nat.div_eq_of_lt hi, Nat.mod_eq_of_lt hi] + · simp only [hi, ite_false] + rw [getLsbD_read m n (a + 1) (i - 8) (by omega)] + have e1 : (i - 8) / 8 = i / 8 - 1 := by omega + have e2 : (i - 8) % 8 = i % 8 := by omega + rw [e1, e2] + congr 2 + rw [BitVec.add_assoc]; congr 1 + apply BitVec.eq_of_toNat_eq + simp only [BitVec.toNat_add, BitVec.toNat_ofNat, show (1 : BitVec 64).toNat = 1 from rfl] + omega + +theorem readW_pair (m : Mem) (p : Addr) : + m.readW (p + 4) 32 ++ m.readW p 32 = m.readW p 64 := by + apply BitVec.eq_of_getLsbD_eq + intro i hi + simp only [BitVec.getLsbD_append] + by_cases hlo : i < 32 + · rw [ite_eq_left hlo] + simp only [Mem.readW, BitVec.getLsbD_setWidth, hlo, hi, decide_true, Bool.true_and] + rw [getLsbD_read m 4 p i (by omega), getLsbD_read m 8 p i (by omega)] + · rw [ite_eq_right hlo] + simp only [Mem.readW, BitVec.getLsbD_setWidth, hi, + show i - 32 < 32 by omega, decide_true, Bool.true_and] + rw [getLsbD_read m 4 (p + 4) (i - 32) (by omega), getLsbD_read m 8 p i (by omega)] + have ha : 4 + (i - 32) / 8 = i / 8 := by omega + have hb : (i - 32) % 8 = i % 8 := by omega + rw [hb] + exact congrArg (fun q => (m q).getLsbD (i % 8)) + ((VG.Offset.add_ofNat_add_ofNat p 4 ((i - 32) / 8)).trans + (congrArg (fun j => p + BitVec.ofNat 64 j) ha)) + +theorem writeW_pair (m : Mem) (p : Addr) (lo hi : BitVec 32) : + (m.writeW p lo).writeW (p + 4) hi = m.writeW p (hi ++ lo) := by + funext a + simp only [Mem.writeW, Mem.write, BitVec.setWidth_eq] + by_cases hhi : (a - (p + 4)).toNat < 4 + · have he : (a - p).toNat = (a - (p + 4)).toNat + 4 := by bv_omega + have hb : (a - p).toNat < 8 := by omega + rw [ite_eq_left hhi, ite_eq_left hb] + apply BitVec.eq_of_getLsbD_eq + intro i hi' + simp only [BitVec.getLsbD_extractLsb', BitVec.getLsbD_append] + simp (disch := omega) only [ite_eq_right, he] + apply congrArg (fun b => decide (i < 8) && b) + apply congrArg hi.getLsbD + omega + · rw [ite_eq_right hhi] + by_cases hlo : (a - p).toNat < 4 + · have hb : (a - p).toNat < 8 := by omega + rw [ite_eq_left hlo, ite_eq_left hb] + apply BitVec.eq_of_getLsbD_eq + intro i hi' + simp (disch := omega) only [BitVec.getLsbD_extractLsb', BitVec.getLsbD_append, + ite_eq_left] + · have hb : ¬ (a - p).toNat < 8 := by bv_omega + rw [ite_eq_right hlo, ite_eq_right hb] + +end VG.Proof.TripleDes.Arm diff --git a/src/asm/arm/mod.rs b/src/asm/arm/mod.rs index d157c1ca8..387f0efa4 100644 --- a/src/asm/arm/mod.rs +++ b/src/asm/arm/mod.rs @@ -115,6 +115,9 @@ pub(crate) mod sha3; #[rustfmt::skip] pub(crate) mod sha512; +#[rustfmt::skip] +pub(crate) mod triple_des; + #[rustfmt::skip] pub(crate) mod x25519; diff --git a/src/asm/arm/triple_des.rs b/src/asm/arm/triple_des.rs new file mode 100644 index 000000000..fa2a2561c --- /dev/null +++ b/src/asm/arm/triple_des.rs @@ -0,0 +1,14167 @@ +// @generated from lean/VerifiedGarbage/Artifacts.lean by lean/Emit.lean. DO NOT EDIT. +//! Verified `triple_des` functions for `arm`. +#![allow(dead_code)] + +/// Triple DES key expansion (FIPS 46-3 Appendix 1): expands a 16- or 24-byte key into three encryption-order DES schedules, each containing sixteen 48-bit round keys zero-extended into little-endian 64-bit slots. For a 16-byte key, K3 repeats K1. Parity bits are ignored and weak or repeated component keys are accepted. +/// +/// Contract: `VG.Spec.TripleDes.expandKeyContract`. Constant time: only pointers and `key_len` may affect timing, not key bytes. +/// +/// Baseline ARMv7 scalar key expansion with fixed permutations and public round-count branches. +/// +/// # Safety +/// +/// * `key` must be valid for reads of `key_len` bytes. +/// * `schedule` must be valid for reads and writes of 384 bytes. +/// * `scratch` must be valid for reads and writes of 512 bytes. +/// * `key_len` must be 16 or 24. +/// * The contents of `scratch` on return are unspecified. +/// * `schedule` and `scratch` must not overlap each other or `key` (distinct Rust objects never do). +/// * None of `key`, `schedule` and `scratch` may wrap around the end of the address space (no Rust object does). +#[unsafe(naked)] +pub(crate) unsafe extern "C" fn vg_triple_des_expand_key(key: *const u8, key_len: usize, schedule: *mut [u8; 384], scratch: *mut [u64; 64]) { + core::arch::naked_asm!( + "str r4, [r3, #0]", + "str r5, [r3, #4]", + "str r6, [r3, #8]", + "str r7, [r3, #12]", + "str r8, [r3, #16]", + "str r9, [r3, #20]", + "str r10, [r3, #24]", + "str r11, [r3, #28]", + "str lr, [r3, #32]", + "ldr r4, [r0, #0]", + "ldr r5, [r0, #4]", + "rev r4, r4", + "rev r5, r5", + "mov r11, #0", + "mov r10, #0", + "mov lr, #1", + "mov r12, r5", + "lsr r12, r12, #7", + "and r12, r12, lr", + "ror r12, r12, #5", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #15", + "and r12, r12, lr", + "ror r12, r12, #6", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #23", + "and r12, r12, lr", + "ror r12, r12, #7", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #31", + "and r12, r12, lr", + "ror r12, r12, #8", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #7", + "and r12, r12, lr", + "ror r12, r12, #9", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #15", + "and r12, r12, lr", + "ror r12, r12, #10", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #23", + "and r12, r12, lr", + "ror r12, r12, #11", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #31", + "and r12, r12, lr", + "ror r12, r12, #12", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #6", + "and r12, r12, lr", + "ror r12, r12, #13", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #14", + "and r12, r12, lr", + "ror r12, r12, #14", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #22", + "and r12, r12, lr", + "ror r12, r12, #15", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #30", + "and r12, r12, lr", + "ror r12, r12, #16", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #6", + "and r12, r12, lr", + "ror r12, r12, #17", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #14", + "and r12, r12, lr", + "ror r12, r12, #18", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #22", + "and r12, r12, lr", + "ror r12, r12, #19", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #30", + "and r12, r12, lr", + "ror r12, r12, #20", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #5", + "and r12, r12, lr", + "ror r12, r12, #21", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #13", + "and r12, r12, lr", + "ror r12, r12, #22", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #21", + "and r12, r12, lr", + "ror r12, r12, #23", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #29", + "and r12, r12, lr", + "ror r12, r12, #24", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #5", + "and r12, r12, lr", + "ror r12, r12, #25", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #13", + "and r12, r12, lr", + "ror r12, r12, #26", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #21", + "and r12, r12, lr", + "ror r12, r12, #27", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #29", + "and r12, r12, lr", + "ror r12, r12, #28", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #4", + "and r12, r12, lr", + "ror r12, r12, #29", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #12", + "and r12, r12, lr", + "ror r12, r12, #30", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #20", + "and r12, r12, lr", + "ror r12, r12, #31", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #28", + "and r12, r12, lr", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #1", + "and r12, r12, lr", + "ror r12, r12, #5", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #9", + "and r12, r12, lr", + "ror r12, r12, #6", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #17", + "and r12, r12, lr", + "ror r12, r12, #7", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #25", + "and r12, r12, lr", + "ror r12, r12, #8", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #1", + "and r12, r12, lr", + "ror r12, r12, #9", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #9", + "and r12, r12, lr", + "ror r12, r12, #10", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #17", + "and r12, r12, lr", + "ror r12, r12, #11", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #25", + "and r12, r12, lr", + "ror r12, r12, #12", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #2", + "and r12, r12, lr", + "ror r12, r12, #13", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #10", + "and r12, r12, lr", + "ror r12, r12, #14", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #18", + "and r12, r12, lr", + "ror r12, r12, #15", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #26", + "and r12, r12, lr", + "ror r12, r12, #16", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #2", + "and r12, r12, lr", + "ror r12, r12, #17", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #10", + "and r12, r12, lr", + "ror r12, r12, #18", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #18", + "and r12, r12, lr", + "ror r12, r12, #19", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #26", + "and r12, r12, lr", + "ror r12, r12, #20", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #3", + "and r12, r12, lr", + "ror r12, r12, #21", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #11", + "and r12, r12, lr", + "ror r12, r12, #22", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #19", + "and r12, r12, lr", + "ror r12, r12, #23", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #27", + "and r12, r12, lr", + "ror r12, r12, #24", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #3", + "and r12, r12, lr", + "ror r12, r12, #25", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #11", + "and r12, r12, lr", + "ror r12, r12, #26", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #19", + "and r12, r12, lr", + "ror r12, r12, #27", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #27", + "and r12, r12, lr", + "ror r12, r12, #28", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #4", + "and r12, r12, lr", + "ror r12, r12, #29", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #12", + "and r12, r12, lr", + "ror r12, r12, #30", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #20", + "and r12, r12, lr", + "ror r12, r12, #31", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #28", + "and r12, r12, lr", + "eor r11, r11, r12", + "mov r9, #0", + "add r8, r2, #0", + "20:", + "lsr r4, r9, #1", + "cmp r4, #0", + "beq 21f", + "cmp r9, #8", + "beq 23f", + "cmp r9, #15", + "beq 25f", + "lsr r4, r10, #26", + "ror r10, r10, #30", + "eor r10, r10, r4", + "lsl r10, r10, #4", + "lsr r10, r10, #4", + "lsr r4, r11, #26", + "ror r11, r11, #30", + "eor r11, r11, r4", + "lsl r11, r11, #4", + "lsr r11, r11, #4", + "b 26f", + "25:", + "lsr r4, r10, #27", + "ror r10, r10, #31", + "eor r10, r10, r4", + "lsl r10, r10, #4", + "lsr r10, r10, #4", + "lsr r4, r11, #27", + "ror r11, r11, #31", + "eor r11, r11, r4", + "lsl r11, r11, #4", + "lsr r11, r11, #4", + "26:", + "b 24f", + "23:", + "lsr r4, r10, #27", + "ror r10, r10, #31", + "eor r10, r10, r4", + "lsl r10, r10, #4", + "lsr r10, r10, #4", + "lsr r4, r11, #27", + "ror r11, r11, #31", + "eor r11, r11, r4", + "lsl r11, r11, #4", + "lsr r11, r11, #4", + "24:", + "b 22f", + "21:", + "lsr r4, r10, #27", + "ror r10, r10, #31", + "eor r10, r10, r4", + "lsl r10, r10, #4", + "lsr r10, r10, #4", + "lsr r4, r11, #27", + "ror r11, r11, #31", + "eor r11, r11, r4", + "lsl r11, r11, #4", + "lsr r11, r11, #4", + "22:", + "mov r4, #0", + "mov r5, #0", + "mov lr, #1", + "mov r12, r10", + "lsr r12, r12, #14", + "and r12, r12, lr", + "ror r12, r12, #17", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #11", + "and r12, r12, lr", + "ror r12, r12, #18", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #17", + "and r12, r12, lr", + "ror r12, r12, #19", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #4", + "and r12, r12, lr", + "ror r12, r12, #20", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #27", + "and r12, r12, lr", + "ror r12, r12, #21", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #23", + "and r12, r12, lr", + "ror r12, r12, #22", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #25", + "and r12, r12, lr", + "ror r12, r12, #23", + "eor r5, r5, r12", + "mov r12, r10", + "and r12, r12, lr", + "ror r12, r12, #24", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #13", + "and r12, r12, lr", + "ror r12, r12, #25", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #22", + "and r12, r12, lr", + "ror r12, r12, #26", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #7", + "and r12, r12, lr", + "ror r12, r12, #27", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #18", + "and r12, r12, lr", + "ror r12, r12, #28", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #5", + "and r12, r12, lr", + "ror r12, r12, #29", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #9", + "and r12, r12, lr", + "ror r12, r12, #30", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #16", + "and r12, r12, lr", + "ror r12, r12, #31", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #24", + "and r12, r12, lr", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #2", + "and r12, r12, lr", + "ror r12, r12, #1", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #20", + "and r12, r12, lr", + "ror r12, r12, #2", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #12", + "and r12, r12, lr", + "ror r12, r12, #3", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #21", + "and r12, r12, lr", + "ror r12, r12, #4", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #1", + "and r12, r12, lr", + "ror r12, r12, #5", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #8", + "and r12, r12, lr", + "ror r12, r12, #6", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #15", + "and r12, r12, lr", + "ror r12, r12, #7", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #26", + "and r12, r12, lr", + "ror r12, r12, #8", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #15", + "and r12, r12, lr", + "ror r12, r12, #9", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #4", + "and r12, r12, lr", + "ror r12, r12, #10", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #25", + "and r12, r12, lr", + "ror r12, r12, #11", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #19", + "and r12, r12, lr", + "ror r12, r12, #12", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #9", + "and r12, r12, lr", + "ror r12, r12, #13", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #1", + "and r12, r12, lr", + "ror r12, r12, #14", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #26", + "and r12, r12, lr", + "ror r12, r12, #15", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #16", + "and r12, r12, lr", + "ror r12, r12, #16", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #5", + "and r12, r12, lr", + "ror r12, r12, #17", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #11", + "and r12, r12, lr", + "ror r12, r12, #18", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #23", + "and r12, r12, lr", + "ror r12, r12, #19", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #8", + "and r12, r12, lr", + "ror r12, r12, #20", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #12", + "and r12, r12, lr", + "ror r12, r12, #21", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #7", + "and r12, r12, lr", + "ror r12, r12, #22", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #17", + "and r12, r12, lr", + "ror r12, r12, #23", + "eor r4, r4, r12", + "mov r12, r11", + "and r12, r12, lr", + "ror r12, r12, #24", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #22", + "and r12, r12, lr", + "ror r12, r12, #25", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #3", + "and r12, r12, lr", + "ror r12, r12, #26", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #10", + "and r12, r12, lr", + "ror r12, r12, #27", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #14", + "and r12, r12, lr", + "ror r12, r12, #28", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #6", + "and r12, r12, lr", + "ror r12, r12, #29", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #20", + "and r12, r12, lr", + "ror r12, r12, #30", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #27", + "and r12, r12, lr", + "ror r12, r12, #31", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #24", + "and r12, r12, lr", + "eor r4, r4, r12", + "str r4, [r8, #0]", + "str r5, [r8, #4]", + "add r8, r8, #8", + "add r9, r9, #1", + "cmp r9, #16", + "bne 20b", + "ldr r4, [r0, #8]", + "ldr r5, [r0, #12]", + "rev r4, r4", + "rev r5, r5", + "mov r11, #0", + "mov r10, #0", + "mov lr, #1", + "mov r12, r5", + "lsr r12, r12, #7", + "and r12, r12, lr", + "ror r12, r12, #5", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #15", + "and r12, r12, lr", + "ror r12, r12, #6", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #23", + "and r12, r12, lr", + "ror r12, r12, #7", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #31", + "and r12, r12, lr", + "ror r12, r12, #8", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #7", + "and r12, r12, lr", + "ror r12, r12, #9", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #15", + "and r12, r12, lr", + "ror r12, r12, #10", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #23", + "and r12, r12, lr", + "ror r12, r12, #11", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #31", + "and r12, r12, lr", + "ror r12, r12, #12", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #6", + "and r12, r12, lr", + "ror r12, r12, #13", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #14", + "and r12, r12, lr", + "ror r12, r12, #14", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #22", + "and r12, r12, lr", + "ror r12, r12, #15", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #30", + "and r12, r12, lr", + "ror r12, r12, #16", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #6", + "and r12, r12, lr", + "ror r12, r12, #17", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #14", + "and r12, r12, lr", + "ror r12, r12, #18", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #22", + "and r12, r12, lr", + "ror r12, r12, #19", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #30", + "and r12, r12, lr", + "ror r12, r12, #20", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #5", + "and r12, r12, lr", + "ror r12, r12, #21", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #13", + "and r12, r12, lr", + "ror r12, r12, #22", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #21", + "and r12, r12, lr", + "ror r12, r12, #23", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #29", + "and r12, r12, lr", + "ror r12, r12, #24", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #5", + "and r12, r12, lr", + "ror r12, r12, #25", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #13", + "and r12, r12, lr", + "ror r12, r12, #26", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #21", + "and r12, r12, lr", + "ror r12, r12, #27", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #29", + "and r12, r12, lr", + "ror r12, r12, #28", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #4", + "and r12, r12, lr", + "ror r12, r12, #29", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #12", + "and r12, r12, lr", + "ror r12, r12, #30", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #20", + "and r12, r12, lr", + "ror r12, r12, #31", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #28", + "and r12, r12, lr", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #1", + "and r12, r12, lr", + "ror r12, r12, #5", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #9", + "and r12, r12, lr", + "ror r12, r12, #6", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #17", + "and r12, r12, lr", + "ror r12, r12, #7", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #25", + "and r12, r12, lr", + "ror r12, r12, #8", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #1", + "and r12, r12, lr", + "ror r12, r12, #9", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #9", + "and r12, r12, lr", + "ror r12, r12, #10", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #17", + "and r12, r12, lr", + "ror r12, r12, #11", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #25", + "and r12, r12, lr", + "ror r12, r12, #12", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #2", + "and r12, r12, lr", + "ror r12, r12, #13", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #10", + "and r12, r12, lr", + "ror r12, r12, #14", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #18", + "and r12, r12, lr", + "ror r12, r12, #15", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #26", + "and r12, r12, lr", + "ror r12, r12, #16", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #2", + "and r12, r12, lr", + "ror r12, r12, #17", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #10", + "and r12, r12, lr", + "ror r12, r12, #18", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #18", + "and r12, r12, lr", + "ror r12, r12, #19", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #26", + "and r12, r12, lr", + "ror r12, r12, #20", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #3", + "and r12, r12, lr", + "ror r12, r12, #21", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #11", + "and r12, r12, lr", + "ror r12, r12, #22", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #19", + "and r12, r12, lr", + "ror r12, r12, #23", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #27", + "and r12, r12, lr", + "ror r12, r12, #24", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #3", + "and r12, r12, lr", + "ror r12, r12, #25", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #11", + "and r12, r12, lr", + "ror r12, r12, #26", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #19", + "and r12, r12, lr", + "ror r12, r12, #27", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #27", + "and r12, r12, lr", + "ror r12, r12, #28", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #4", + "and r12, r12, lr", + "ror r12, r12, #29", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #12", + "and r12, r12, lr", + "ror r12, r12, #30", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #20", + "and r12, r12, lr", + "ror r12, r12, #31", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #28", + "and r12, r12, lr", + "eor r11, r11, r12", + "mov r9, #0", + "add r8, r2, #128", + "27:", + "lsr r4, r9, #1", + "cmp r4, #0", + "beq 28f", + "cmp r9, #8", + "beq 210f", + "cmp r9, #15", + "beq 212f", + "lsr r4, r10, #26", + "ror r10, r10, #30", + "eor r10, r10, r4", + "lsl r10, r10, #4", + "lsr r10, r10, #4", + "lsr r4, r11, #26", + "ror r11, r11, #30", + "eor r11, r11, r4", + "lsl r11, r11, #4", + "lsr r11, r11, #4", + "b 213f", + "212:", + "lsr r4, r10, #27", + "ror r10, r10, #31", + "eor r10, r10, r4", + "lsl r10, r10, #4", + "lsr r10, r10, #4", + "lsr r4, r11, #27", + "ror r11, r11, #31", + "eor r11, r11, r4", + "lsl r11, r11, #4", + "lsr r11, r11, #4", + "213:", + "b 211f", + "210:", + "lsr r4, r10, #27", + "ror r10, r10, #31", + "eor r10, r10, r4", + "lsl r10, r10, #4", + "lsr r10, r10, #4", + "lsr r4, r11, #27", + "ror r11, r11, #31", + "eor r11, r11, r4", + "lsl r11, r11, #4", + "lsr r11, r11, #4", + "211:", + "b 29f", + "28:", + "lsr r4, r10, #27", + "ror r10, r10, #31", + "eor r10, r10, r4", + "lsl r10, r10, #4", + "lsr r10, r10, #4", + "lsr r4, r11, #27", + "ror r11, r11, #31", + "eor r11, r11, r4", + "lsl r11, r11, #4", + "lsr r11, r11, #4", + "29:", + "mov r4, #0", + "mov r5, #0", + "mov lr, #1", + "mov r12, r10", + "lsr r12, r12, #14", + "and r12, r12, lr", + "ror r12, r12, #17", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #11", + "and r12, r12, lr", + "ror r12, r12, #18", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #17", + "and r12, r12, lr", + "ror r12, r12, #19", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #4", + "and r12, r12, lr", + "ror r12, r12, #20", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #27", + "and r12, r12, lr", + "ror r12, r12, #21", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #23", + "and r12, r12, lr", + "ror r12, r12, #22", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #25", + "and r12, r12, lr", + "ror r12, r12, #23", + "eor r5, r5, r12", + "mov r12, r10", + "and r12, r12, lr", + "ror r12, r12, #24", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #13", + "and r12, r12, lr", + "ror r12, r12, #25", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #22", + "and r12, r12, lr", + "ror r12, r12, #26", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #7", + "and r12, r12, lr", + "ror r12, r12, #27", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #18", + "and r12, r12, lr", + "ror r12, r12, #28", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #5", + "and r12, r12, lr", + "ror r12, r12, #29", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #9", + "and r12, r12, lr", + "ror r12, r12, #30", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #16", + "and r12, r12, lr", + "ror r12, r12, #31", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #24", + "and r12, r12, lr", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #2", + "and r12, r12, lr", + "ror r12, r12, #1", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #20", + "and r12, r12, lr", + "ror r12, r12, #2", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #12", + "and r12, r12, lr", + "ror r12, r12, #3", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #21", + "and r12, r12, lr", + "ror r12, r12, #4", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #1", + "and r12, r12, lr", + "ror r12, r12, #5", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #8", + "and r12, r12, lr", + "ror r12, r12, #6", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #15", + "and r12, r12, lr", + "ror r12, r12, #7", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #26", + "and r12, r12, lr", + "ror r12, r12, #8", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #15", + "and r12, r12, lr", + "ror r12, r12, #9", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #4", + "and r12, r12, lr", + "ror r12, r12, #10", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #25", + "and r12, r12, lr", + "ror r12, r12, #11", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #19", + "and r12, r12, lr", + "ror r12, r12, #12", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #9", + "and r12, r12, lr", + "ror r12, r12, #13", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #1", + "and r12, r12, lr", + "ror r12, r12, #14", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #26", + "and r12, r12, lr", + "ror r12, r12, #15", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #16", + "and r12, r12, lr", + "ror r12, r12, #16", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #5", + "and r12, r12, lr", + "ror r12, r12, #17", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #11", + "and r12, r12, lr", + "ror r12, r12, #18", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #23", + "and r12, r12, lr", + "ror r12, r12, #19", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #8", + "and r12, r12, lr", + "ror r12, r12, #20", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #12", + "and r12, r12, lr", + "ror r12, r12, #21", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #7", + "and r12, r12, lr", + "ror r12, r12, #22", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #17", + "and r12, r12, lr", + "ror r12, r12, #23", + "eor r4, r4, r12", + "mov r12, r11", + "and r12, r12, lr", + "ror r12, r12, #24", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #22", + "and r12, r12, lr", + "ror r12, r12, #25", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #3", + "and r12, r12, lr", + "ror r12, r12, #26", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #10", + "and r12, r12, lr", + "ror r12, r12, #27", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #14", + "and r12, r12, lr", + "ror r12, r12, #28", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #6", + "and r12, r12, lr", + "ror r12, r12, #29", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #20", + "and r12, r12, lr", + "ror r12, r12, #30", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #27", + "and r12, r12, lr", + "ror r12, r12, #31", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #24", + "and r12, r12, lr", + "eor r4, r4, r12", + "str r4, [r8, #0]", + "str r5, [r8, #4]", + "add r8, r8, #8", + "add r9, r9, #1", + "cmp r9, #16", + "bne 27b", + "cmp r1, #16", + "beq 214f", + "ldr r4, [r0, #16]", + "ldr r5, [r0, #20]", + "rev r4, r4", + "rev r5, r5", + "mov r11, #0", + "mov r10, #0", + "mov lr, #1", + "mov r12, r5", + "lsr r12, r12, #7", + "and r12, r12, lr", + "ror r12, r12, #5", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #15", + "and r12, r12, lr", + "ror r12, r12, #6", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #23", + "and r12, r12, lr", + "ror r12, r12, #7", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #31", + "and r12, r12, lr", + "ror r12, r12, #8", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #7", + "and r12, r12, lr", + "ror r12, r12, #9", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #15", + "and r12, r12, lr", + "ror r12, r12, #10", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #23", + "and r12, r12, lr", + "ror r12, r12, #11", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #31", + "and r12, r12, lr", + "ror r12, r12, #12", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #6", + "and r12, r12, lr", + "ror r12, r12, #13", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #14", + "and r12, r12, lr", + "ror r12, r12, #14", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #22", + "and r12, r12, lr", + "ror r12, r12, #15", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #30", + "and r12, r12, lr", + "ror r12, r12, #16", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #6", + "and r12, r12, lr", + "ror r12, r12, #17", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #14", + "and r12, r12, lr", + "ror r12, r12, #18", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #22", + "and r12, r12, lr", + "ror r12, r12, #19", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #30", + "and r12, r12, lr", + "ror r12, r12, #20", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #5", + "and r12, r12, lr", + "ror r12, r12, #21", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #13", + "and r12, r12, lr", + "ror r12, r12, #22", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #21", + "and r12, r12, lr", + "ror r12, r12, #23", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #29", + "and r12, r12, lr", + "ror r12, r12, #24", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #5", + "and r12, r12, lr", + "ror r12, r12, #25", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #13", + "and r12, r12, lr", + "ror r12, r12, #26", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #21", + "and r12, r12, lr", + "ror r12, r12, #27", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #29", + "and r12, r12, lr", + "ror r12, r12, #28", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #4", + "and r12, r12, lr", + "ror r12, r12, #29", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #12", + "and r12, r12, lr", + "ror r12, r12, #30", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #20", + "and r12, r12, lr", + "ror r12, r12, #31", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #28", + "and r12, r12, lr", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #1", + "and r12, r12, lr", + "ror r12, r12, #5", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #9", + "and r12, r12, lr", + "ror r12, r12, #6", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #17", + "and r12, r12, lr", + "ror r12, r12, #7", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #25", + "and r12, r12, lr", + "ror r12, r12, #8", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #1", + "and r12, r12, lr", + "ror r12, r12, #9", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #9", + "and r12, r12, lr", + "ror r12, r12, #10", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #17", + "and r12, r12, lr", + "ror r12, r12, #11", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #25", + "and r12, r12, lr", + "ror r12, r12, #12", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #2", + "and r12, r12, lr", + "ror r12, r12, #13", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #10", + "and r12, r12, lr", + "ror r12, r12, #14", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #18", + "and r12, r12, lr", + "ror r12, r12, #15", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #26", + "and r12, r12, lr", + "ror r12, r12, #16", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #2", + "and r12, r12, lr", + "ror r12, r12, #17", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #10", + "and r12, r12, lr", + "ror r12, r12, #18", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #18", + "and r12, r12, lr", + "ror r12, r12, #19", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #26", + "and r12, r12, lr", + "ror r12, r12, #20", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #3", + "and r12, r12, lr", + "ror r12, r12, #21", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #11", + "and r12, r12, lr", + "ror r12, r12, #22", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #19", + "and r12, r12, lr", + "ror r12, r12, #23", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #27", + "and r12, r12, lr", + "ror r12, r12, #24", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #3", + "and r12, r12, lr", + "ror r12, r12, #25", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #11", + "and r12, r12, lr", + "ror r12, r12, #26", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #19", + "and r12, r12, lr", + "ror r12, r12, #27", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #27", + "and r12, r12, lr", + "ror r12, r12, #28", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #4", + "and r12, r12, lr", + "ror r12, r12, #29", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #12", + "and r12, r12, lr", + "ror r12, r12, #30", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #20", + "and r12, r12, lr", + "ror r12, r12, #31", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #28", + "and r12, r12, lr", + "eor r11, r11, r12", + "mov r9, #0", + "add r8, r2, #256", + "216:", + "lsr r4, r9, #1", + "cmp r4, #0", + "beq 217f", + "cmp r9, #8", + "beq 219f", + "cmp r9, #15", + "beq 221f", + "lsr r4, r10, #26", + "ror r10, r10, #30", + "eor r10, r10, r4", + "lsl r10, r10, #4", + "lsr r10, r10, #4", + "lsr r4, r11, #26", + "ror r11, r11, #30", + "eor r11, r11, r4", + "lsl r11, r11, #4", + "lsr r11, r11, #4", + "b 222f", + "221:", + "lsr r4, r10, #27", + "ror r10, r10, #31", + "eor r10, r10, r4", + "lsl r10, r10, #4", + "lsr r10, r10, #4", + "lsr r4, r11, #27", + "ror r11, r11, #31", + "eor r11, r11, r4", + "lsl r11, r11, #4", + "lsr r11, r11, #4", + "222:", + "b 220f", + "219:", + "lsr r4, r10, #27", + "ror r10, r10, #31", + "eor r10, r10, r4", + "lsl r10, r10, #4", + "lsr r10, r10, #4", + "lsr r4, r11, #27", + "ror r11, r11, #31", + "eor r11, r11, r4", + "lsl r11, r11, #4", + "lsr r11, r11, #4", + "220:", + "b 218f", + "217:", + "lsr r4, r10, #27", + "ror r10, r10, #31", + "eor r10, r10, r4", + "lsl r10, r10, #4", + "lsr r10, r10, #4", + "lsr r4, r11, #27", + "ror r11, r11, #31", + "eor r11, r11, r4", + "lsl r11, r11, #4", + "lsr r11, r11, #4", + "218:", + "mov r4, #0", + "mov r5, #0", + "mov lr, #1", + "mov r12, r10", + "lsr r12, r12, #14", + "and r12, r12, lr", + "ror r12, r12, #17", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #11", + "and r12, r12, lr", + "ror r12, r12, #18", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #17", + "and r12, r12, lr", + "ror r12, r12, #19", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #4", + "and r12, r12, lr", + "ror r12, r12, #20", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #27", + "and r12, r12, lr", + "ror r12, r12, #21", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #23", + "and r12, r12, lr", + "ror r12, r12, #22", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #25", + "and r12, r12, lr", + "ror r12, r12, #23", + "eor r5, r5, r12", + "mov r12, r10", + "and r12, r12, lr", + "ror r12, r12, #24", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #13", + "and r12, r12, lr", + "ror r12, r12, #25", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #22", + "and r12, r12, lr", + "ror r12, r12, #26", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #7", + "and r12, r12, lr", + "ror r12, r12, #27", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #18", + "and r12, r12, lr", + "ror r12, r12, #28", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #5", + "and r12, r12, lr", + "ror r12, r12, #29", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #9", + "and r12, r12, lr", + "ror r12, r12, #30", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #16", + "and r12, r12, lr", + "ror r12, r12, #31", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #24", + "and r12, r12, lr", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #2", + "and r12, r12, lr", + "ror r12, r12, #1", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #20", + "and r12, r12, lr", + "ror r12, r12, #2", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #12", + "and r12, r12, lr", + "ror r12, r12, #3", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #21", + "and r12, r12, lr", + "ror r12, r12, #4", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #1", + "and r12, r12, lr", + "ror r12, r12, #5", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #8", + "and r12, r12, lr", + "ror r12, r12, #6", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #15", + "and r12, r12, lr", + "ror r12, r12, #7", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #26", + "and r12, r12, lr", + "ror r12, r12, #8", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #15", + "and r12, r12, lr", + "ror r12, r12, #9", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #4", + "and r12, r12, lr", + "ror r12, r12, #10", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #25", + "and r12, r12, lr", + "ror r12, r12, #11", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #19", + "and r12, r12, lr", + "ror r12, r12, #12", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #9", + "and r12, r12, lr", + "ror r12, r12, #13", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #1", + "and r12, r12, lr", + "ror r12, r12, #14", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #26", + "and r12, r12, lr", + "ror r12, r12, #15", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #16", + "and r12, r12, lr", + "ror r12, r12, #16", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #5", + "and r12, r12, lr", + "ror r12, r12, #17", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #11", + "and r12, r12, lr", + "ror r12, r12, #18", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #23", + "and r12, r12, lr", + "ror r12, r12, #19", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #8", + "and r12, r12, lr", + "ror r12, r12, #20", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #12", + "and r12, r12, lr", + "ror r12, r12, #21", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #7", + "and r12, r12, lr", + "ror r12, r12, #22", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #17", + "and r12, r12, lr", + "ror r12, r12, #23", + "eor r4, r4, r12", + "mov r12, r11", + "and r12, r12, lr", + "ror r12, r12, #24", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #22", + "and r12, r12, lr", + "ror r12, r12, #25", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #3", + "and r12, r12, lr", + "ror r12, r12, #26", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #10", + "and r12, r12, lr", + "ror r12, r12, #27", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #14", + "and r12, r12, lr", + "ror r12, r12, #28", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #6", + "and r12, r12, lr", + "ror r12, r12, #29", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #20", + "and r12, r12, lr", + "ror r12, r12, #30", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #27", + "and r12, r12, lr", + "ror r12, r12, #31", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #24", + "and r12, r12, lr", + "eor r4, r4, r12", + "str r4, [r8, #0]", + "str r5, [r8, #4]", + "add r8, r8, #8", + "add r9, r9, #1", + "cmp r9, #16", + "bne 216b", + "b 215f", + "214:", + "ldr r4, [r2, #0]", + "ldr r5, [r2, #4]", + "str r4, [r2, #256]", + "str r5, [r2, #260]", + "ldr r4, [r2, #8]", + "ldr r5, [r2, #12]", + "str r4, [r2, #264]", + "str r5, [r2, #268]", + "ldr r4, [r2, #16]", + "ldr r5, [r2, #20]", + "str r4, [r2, #272]", + "str r5, [r2, #276]", + "ldr r4, [r2, #24]", + "ldr r5, [r2, #28]", + "str r4, [r2, #280]", + "str r5, [r2, #284]", + "ldr r4, [r2, #32]", + "ldr r5, [r2, #36]", + "str r4, [r2, #288]", + "str r5, [r2, #292]", + "ldr r4, [r2, #40]", + "ldr r5, [r2, #44]", + "str r4, [r2, #296]", + "str r5, [r2, #300]", + "ldr r4, [r2, #48]", + "ldr r5, [r2, #52]", + "str r4, [r2, #304]", + "str r5, [r2, #308]", + "ldr r4, [r2, #56]", + "ldr r5, [r2, #60]", + "str r4, [r2, #312]", + "str r5, [r2, #316]", + "ldr r4, [r2, #64]", + "ldr r5, [r2, #68]", + "str r4, [r2, #320]", + "str r5, [r2, #324]", + "ldr r4, [r2, #72]", + "ldr r5, [r2, #76]", + "str r4, [r2, #328]", + "str r5, [r2, #332]", + "ldr r4, [r2, #80]", + "ldr r5, [r2, #84]", + "str r4, [r2, #336]", + "str r5, [r2, #340]", + "ldr r4, [r2, #88]", + "ldr r5, [r2, #92]", + "str r4, [r2, #344]", + "str r5, [r2, #348]", + "ldr r4, [r2, #96]", + "ldr r5, [r2, #100]", + "str r4, [r2, #352]", + "str r5, [r2, #356]", + "ldr r4, [r2, #104]", + "ldr r5, [r2, #108]", + "str r4, [r2, #360]", + "str r5, [r2, #364]", + "ldr r4, [r2, #112]", + "ldr r5, [r2, #116]", + "str r4, [r2, #368]", + "str r5, [r2, #372]", + "ldr r4, [r2, #120]", + "ldr r5, [r2, #124]", + "str r4, [r2, #376]", + "str r5, [r2, #380]", + "215:", + "ldr r4, [r3, #0]", + "ldr r5, [r3, #4]", + "ldr r6, [r3, #8]", + "ldr r7, [r3, #12]", + "ldr r8, [r3, #16]", + "ldr r9, [r3, #20]", + "ldr r10, [r3, #24]", + "ldr r11, [r3, #28]", + "ldr lr, [r3, #32]", + "bx lr", + ) +} + +/// Triple DES block encryption (FIPS 46-3): transforms the 8 bytes at `data` in place under the three DES schedules at `schedule`. Each schedule contains sixteen encryption-order 48-bit round keys in little-endian 64-bit slots; upper bits are ignored. +/// +/// Contract: `VG.Spec.TripleDes.encryptBlockContract`. Constant time: only pointers may affect timing, not the schedule or data, including S-box inputs. +/// +/// Baseline ARMv7 scalar Boolean S-box circuits; IP and FP shared across all three DES passes. +/// +/// # Safety +/// +/// * `schedule` must be valid for reads of 384 bytes. +/// * `data` must be valid for reads and writes of 8 bytes. +/// * `scratch` must be valid for reads and writes of 512 bytes. +/// * The contents of `scratch` on return are unspecified. +/// * `data` and `scratch` must not overlap each other or `schedule` (distinct Rust objects never do). +/// * None of `schedule`, `data` and `scratch` may wrap around the end of the address space (no Rust object does). +#[unsafe(naked)] +pub(crate) unsafe extern "C" fn vg_triple_des_encrypt_block(schedule: *const [u8; 384], data: *mut [u8; 8], scratch: *mut [u64; 64]) { + core::arch::naked_asm!( + "str r4, [r2, #0]", + "str r5, [r2, #4]", + "str r6, [r2, #8]", + "str r7, [r2, #12]", + "str r8, [r2, #16]", + "str r9, [r2, #20]", + "str r10, [r2, #24]", + "str r11, [r2, #28]", + "str lr, [r2, #32]", + "ldr r4, [r1, #0]", + "ldr r5, [r1, #4]", + "rev r4, r4", + "rev r5, r5", + "mov r11, #0", + "mov r10, #0", + "mov r9, #1", + "mov r12, r5", + "lsr r12, r12, #6", + "and r12, r12, r9", + "ror r12, r12, #1", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #14", + "and r12, r12, r9", + "ror r12, r12, #2", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #22", + "and r12, r12, r9", + "ror r12, r12, #3", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #30", + "and r12, r12, r9", + "ror r12, r12, #4", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #6", + "and r12, r12, r9", + "ror r12, r12, #5", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #14", + "and r12, r12, r9", + "ror r12, r12, #6", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #22", + "and r12, r12, r9", + "ror r12, r12, #7", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #30", + "and r12, r12, r9", + "ror r12, r12, #8", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #4", + "and r12, r12, r9", + "ror r12, r12, #9", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #12", + "and r12, r12, r9", + "ror r12, r12, #10", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #20", + "and r12, r12, r9", + "ror r12, r12, #11", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #28", + "and r12, r12, r9", + "ror r12, r12, #12", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #4", + "and r12, r12, r9", + "ror r12, r12, #13", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #12", + "and r12, r12, r9", + "ror r12, r12, #14", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #20", + "and r12, r12, r9", + "ror r12, r12, #15", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #28", + "and r12, r12, r9", + "ror r12, r12, #16", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #2", + "and r12, r12, r9", + "ror r12, r12, #17", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #10", + "and r12, r12, r9", + "ror r12, r12, #18", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #18", + "and r12, r12, r9", + "ror r12, r12, #19", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #26", + "and r12, r12, r9", + "ror r12, r12, #20", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #2", + "and r12, r12, r9", + "ror r12, r12, #21", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #10", + "and r12, r12, r9", + "ror r12, r12, #22", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #18", + "and r12, r12, r9", + "ror r12, r12, #23", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #26", + "and r12, r12, r9", + "ror r12, r12, #24", + "eor r10, r10, r12", + "mov r12, r5", + "and r12, r12, r9", + "ror r12, r12, #25", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #8", + "and r12, r12, r9", + "ror r12, r12, #26", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #16", + "and r12, r12, r9", + "ror r12, r12, #27", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #24", + "and r12, r12, r9", + "ror r12, r12, #28", + "eor r10, r10, r12", + "mov r12, r4", + "and r12, r12, r9", + "ror r12, r12, #29", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #8", + "and r12, r12, r9", + "ror r12, r12, #30", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #16", + "and r12, r12, r9", + "ror r12, r12, #31", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #24", + "and r12, r12, r9", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #7", + "and r12, r12, r9", + "ror r12, r12, #1", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #15", + "and r12, r12, r9", + "ror r12, r12, #2", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #23", + "and r12, r12, r9", + "ror r12, r12, #3", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #31", + "and r12, r12, r9", + "ror r12, r12, #4", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #7", + "and r12, r12, r9", + "ror r12, r12, #5", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #15", + "and r12, r12, r9", + "ror r12, r12, #6", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #23", + "and r12, r12, r9", + "ror r12, r12, #7", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #31", + "and r12, r12, r9", + "ror r12, r12, #8", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #5", + "and r12, r12, r9", + "ror r12, r12, #9", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #13", + "and r12, r12, r9", + "ror r12, r12, #10", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #21", + "and r12, r12, r9", + "ror r12, r12, #11", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #29", + "and r12, r12, r9", + "ror r12, r12, #12", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #5", + "and r12, r12, r9", + "ror r12, r12, #13", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #13", + "and r12, r12, r9", + "ror r12, r12, #14", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #21", + "and r12, r12, r9", + "ror r12, r12, #15", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #29", + "and r12, r12, r9", + "ror r12, r12, #16", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #3", + "and r12, r12, r9", + "ror r12, r12, #17", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #11", + "and r12, r12, r9", + "ror r12, r12, #18", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #19", + "and r12, r12, r9", + "ror r12, r12, #19", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #27", + "and r12, r12, r9", + "ror r12, r12, #20", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #3", + "and r12, r12, r9", + "ror r12, r12, #21", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #11", + "and r12, r12, r9", + "ror r12, r12, #22", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #19", + "and r12, r12, r9", + "ror r12, r12, #23", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #27", + "and r12, r12, r9", + "ror r12, r12, #24", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #1", + "and r12, r12, r9", + "ror r12, r12, #25", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #9", + "and r12, r12, r9", + "ror r12, r12, #26", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #17", + "and r12, r12, r9", + "ror r12, r12, #27", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #25", + "and r12, r12, r9", + "ror r12, r12, #28", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #1", + "and r12, r12, r9", + "ror r12, r12, #29", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #9", + "and r12, r12, r9", + "ror r12, r12, #30", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #17", + "and r12, r12, r9", + "ror r12, r12, #31", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #25", + "and r12, r12, r9", + "eor r11, r11, r12", + "add r0, r0, #0", + "mov r9, #16", + "20:", + "ldr lr, [r0, #4]", + "mov r4, r11", + "lsr r4, r4, #27", + "eor r4, r4, lr, lsr #10", + "and r4, r4, #1", + "ldr lr, [r0, #4]", + "mov r5, r11", + "lsr r5, r5, #28", + "eor r5, r5, lr, lsr #11", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #29", + "eor r6, r6, lr, lsr #12", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #30", + "eor r7, r7, lr, lsr #13", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #31", + "eor r8, r8, lr, lsr #14", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "eor r12, r12, lr, lsr #15", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, lr", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "and r7, r8, r6", + "str lr, [r2, #72]", + "eor lr, r4, r8", + "str r8, [r2, #76]", + "and r8, r5, lr", + "eor r8, r7, r8", + "str lr, [r2, #80]", + "eor lr, r6, r7", + "str r7, [r2, #84]", + "and r7, r5, lr", + "eor r7, r4, r7", + "and r7, r12, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #76]", + "str lr, [r2, #88]", + "and lr, r7, r4", + "str r4, [r2, #92]", + "ldr r4, [r2, #72]", + "str r6, [r2, #96]", + "eor r6, lr, r4", + "str r8, [r2, #100]", + "ldr r8, [r2, #60]", + "eor r6, r6, r8", + "str r12, [r2, #104]", + "and r12, r5, r6", + "str r6, [r2, #108]", + "eor r6, lr, r12", + "str lr, [r2, #112]", + "eor lr, r7, r4", + "eor lr, lr, r8", + "eor r8, lr, r12", + "str r12, [r2, #116]", + "ldr r12, [r2, #104]", + "and r4, r12, r8", + "eor r6, r6, r4", + "ldr r4, [r2, #68]", + "and r6, r4, r6", + "str r8, [r2, #120]", + "ldr r8, [r2, #100]", + "eor r8, r8, r6", + "and r7, r5, r7", + "ldr r6, [r2, #108]", + "str r8, [r2, #76]", + "eor r8, r6, r7", + "str r7, [r2, #100]", + "and r7, r5, lr", + "str lr, [r2, #124]", + "ldr lr, [r2, #96]", + "eor r6, lr, r7", + "and r6, r12, r6", + "eor r8, r8, r6", + "and r6, r5, lr", + "str r5, [r2, #128]", + "ldr r5, [r2, #88]", + "str r7, [r2, #132]", + "eor r7, r5, r6", + "and r7, r12, r7", + "and r7, r4, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r8, r7, r8", + "str r6, [r2, #136]", + "ldr r6, [r2, #76]", + "eor r6, r6, r8", + "ldr r8, [r2, #112]", + "eor lr, lr, r8", + "ldr r8, [r2, #132]", + "str r6, [r2, #112]", + "eor r6, lr, r8", + "ldr r7, [r2, #84]", + "ldr r4, [r2, #72]", + "eor r8, r7, r4", + "ldr r7, [r2, #60]", + "eor r8, r8, r7", + "ldr r7, [r2, #128]", + "and lr, r7, lr", + "eor lr, r8, lr", + "str r8, [r2, #96]", + "and r8, r12, lr", + "eor r6, r6, r8", + "eor r8, r5, r4", + "ldr r4, [r2, #60]", + "eor r8, r8, r4", + "ldr r4, [r2, #132]", + "eor r4, r8, r4", + "str r8, [r2, #132]", + "ldr r8, [r2, #84]", + "and r5, r7, r8", + "eor r8, r8, r5", + "and r8, r12, r8", + "eor r5, r4, r8", + "str r4, [r2, #84]", + "ldr r4, [r2, #68]", + "and r5, r4, r5", + "eor r6, r6, r5", + "eor lr, lr, r8", + "ldr r8, [r2, #92]", + "and r5, r7, r8", + "ldr r8, [r2, #96]", + "eor r7, r8, r5", + "and r7, r12, r7", + "ldr r8, [r2, #88]", + "eor r12, r8, r7", + "and r12, r4, r12", + "eor lr, lr, r12", + "ldr r12, [r2, #64]", + "and lr, r12, lr", + "eor r6, r6, lr", + "eor lr, r8, r5", + "str r6, [r2, #76]", + "ldr r6, [r2, #104]", + "ldr r8, [r2, #84]", + "and r12, r6, r8", + "eor lr, lr, r12", + "ldr r12, [r2, #108]", + "str r7, [r2, #140]", + "ldr r7, [r2, #136]", + "eor r12, r12, r7", + "ldr r7, [r2, #128]", + "str r5, [r2, #136]", + "ldr r5, [r2, #132]", + "and r5, r7, r5", + "ldr r7, [r2, #96]", + "eor r7, r7, r5", + "and r7, r6, r7", + "eor r12, r12, r7", + "and r12, r4, r12", + "eor lr, lr, r12", + "ldr r12, [r2, #116]", + "and r7, r6, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #92]", + "ldr r5, [r2, #136]", + "eor r7, r7, r5", + "ldr r5, [r2, #140]", + "eor r7, r7, r5", + "and r7, r4, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r8, r7, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #80]", + "ldr r5, [r2, #72]", + "eor r8, r8, r5", + "str lr, [r2, #80]", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "ldr r7, [r2, #128]", + "eor r8, r8, r7", + "eor r12, r12, r5", + "eor r12, r12, lr", + "and r12, r6, r12", + "eor r12, r8, r12", + "str r8, [r2, #116]", + "ldr r8, [r2, #120]", + "eor r8, r8, r5", + "eor r8, r8, lr", + "and r8, r6, r8", + "ldr lr, [r2, #124]", + "eor lr, lr, r8", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #88]", + "ldr r8, [r2, #100]", + "eor r8, lr, r8", + "and r8, r6, r8", + "ldr r5, [r2, #136]", + "eor r5, r5, r8", + "eor lr, lr, r7", + "and r6, r6, lr", + "ldr lr, [r2, #116]", + "eor lr, lr, r6", + "and r4, r4, lr", + "eor r5, r5, r4", + "ldr r4, [r2, #64]", + "and r4, r4, r5", + "eor r7, r12, r4", + "ldr r4, [r2, #112]", + "ldr r5, [r2, #76]", + "ldr r6, [r2, #80]", + "and r4, r4, #1", + "ror r4, r4, #31", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #23", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #17", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #9", + "eor r10, r10, r7", + "ldr lr, [r0, #4]", + "mov r4, r11", + "lsr r4, r4, #23", + "eor r4, r4, lr, lsr #4", + "and r4, r4, #1", + "ldr lr, [r0, #4]", + "mov r5, r11", + "lsr r5, r5, #24", + "eor r5, r5, lr, lsr #5", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #25", + "eor r6, r6, lr, lsr #6", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #26", + "eor r7, r7, lr, lsr #7", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #27", + "eor r8, r8, lr, lsr #8", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "lsr r12, r12, #28", + "eor r12, r12, lr, lsr #9", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "str r6, [r2, #72]", + "eor r6, r12, lr", + "eor r6, r6, r7", + "str r8, [r2, #76]", + "and r8, r5, r12", + "str r5, [r2, #80]", + "eor r5, r12, r8", + "str r12, [r2, #84]", + "and r12, r4, r5", + "eor r12, r6, r12", + "str r6, [r2, #88]", + "eor r6, r8, lr", + "eor r6, r6, r7", + "str r8, [r2, #92]", + "and r8, r4, r6", + "str r6, [r2, #96]", + "eor r6, r5, r8", + "str r8, [r2, #100]", + "ldr r8, [r2, #76]", + "and r6, r8, r6", + "eor r12, r12, r6", + "str r6, [r2, #104]", + "ldr r6, [r2, #80]", + "str r12, [r2, #108]", + "ldr r12, [r2, #88]", + "and r8, r6, r12", + "eor r6, r12, r8", + "eor r5, r5, lr", + "eor r5, r5, r7", + "and r12, r4, r5", + "str r5, [r2, #112]", + "eor r5, r6, r12", + "str r12, [r2, #116]", + "eor r12, r6, lr", + "eor r12, r12, r7", + "str r6, [r2, #120]", + "and r6, r4, r12", + "str r12, [r2, #124]", + "ldr r12, [r2, #80]", + "eor r6, r12, r6", + "ldr r7, [r2, #76]", + "and r6, r7, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #68]", + "and r5, r6, r5", + "ldr r6, [r2, #108]", + "eor r6, r6, r5", + "and r5, r4, r8", + "str r8, [r2, #108]", + "ldr r8, [r2, #72]", + "eor r5, r8, r5", + "ldr r8, [r2, #84]", + "str lr, [r2, #128]", + "eor lr, r8, r12", + "and r8, r4, lr", + "str r4, [r2, #132]", + "eor r4, r12, r8", + "and r4, r7, r4", + "eor r5, r5, r4", + "ldr r4, [r2, #64]", + "and r5, r4, r5", + "eor r6, r6, r5", + "ldr r5, [r2, #128]", + "eor lr, lr, r5", + "str r6, [r2, #136]", + "ldr r6, [r2, #60]", + "eor lr, lr, r6", + "ldr r6, [r2, #132]", + "ldr r5, [r2, #92]", + "and r5, r6, r5", + "eor r12, lr, r5", + "str r5, [r2, #92]", + "ldr r5, [r2, #112]", + "eor r5, r5, r8", + "and r5, r7, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #124]", + "ldr r8, [r2, #104]", + "eor r5, r5, r8", + "ldr r8, [r2, #68]", + "and r5, r8, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #120]", + "str lr, [r2, #104]", + "and lr, r6, r5", + "str r12, [r2, #124]", + "ldr r12, [r2, #84]", + "eor lr, r12, lr", + "and lr, r7, lr", + "ldr r4, [r2, #96]", + "eor lr, r4, lr", + "ldr r4, [r2, #88]", + "str lr, [r2, #112]", + "and lr, r6, r4", + "eor r5, r5, lr", + "and r12, r7, r12", + "eor r5, r5, r12", + "and r5, r8, r5", + "ldr r12, [r2, #112]", + "eor r12, r12, r5", + "ldr r5, [r2, #64]", + "and r12, r5, r12", + "str lr, [r2, #112]", + "ldr lr, [r2, #124]", + "eor lr, lr, r12", + "ldr r12, [r2, #104]", + "str lr, [r2, #124]", + "eor lr, r12, r6", + "eor lr, lr, r7", + "ldr r4, [r2, #96]", + "ldr r12, [r2, #92]", + "eor r5, r4, r12", + "and r5, r7, r5", + "eor r5, r6, r5", + "and r5, r8, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #80]", + "and r6, r6, r5", + "ldr r5, [r2, #72]", + "eor r5, r5, r6", + "ldr r12, [r2, #100]", + "eor r4, r4, r12", + "and r4, r7, r4", + "eor r5, r5, r4", + "and r6, r8, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #64]", + "and r5, r6, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #104]", + "eor r5, r5, r12", + "ldr r12, [r2, #116]", + "and r12, r7, r12", + "eor r5, r5, r12", + "ldr r12, [r2, #92]", + "ldr r4, [r2, #128]", + "str lr, [r2, #116]", + "eor lr, r12, r4", + "ldr r6, [r2, #60]", + "eor lr, lr, r6", + "ldr r6, [r2, #88]", + "ldr r4, [r2, #112]", + "eor r6, r6, r4", + "and r6, r7, r6", + "eor lr, lr, r6", + "and r8, r8, lr", + "eor r5, r5, r8", + "ldr r8, [r2, #108]", + "eor r8, r8, r12", + "ldr r12, [r2, #128]", + "eor r12, r8, r12", + "ldr lr, [r2, #60]", + "eor r12, r12, lr", + "and r7, r7, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r7, r7, r8", + "eor r7, r5, r7", + "ldr r4, [r2, #136]", + "ldr r5, [r2, #124]", + "ldr r6, [r2, #116]", + "and r4, r4, #1", + "ror r4, r4, #18", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #2", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #28", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #13", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #19", + "eor r4, r4, lr, lsr #30", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #20", + "eor r5, r5, lr, lsr #31", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #21", + "eor r6, r6, lr", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #22", + "eor r7, r7, lr, lsr #1", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #23", + "eor r8, r8, lr, lsr #2", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "lsr r12, r12, #24", + "eor r12, r12, lr, lsr #3", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "str r6, [r2, #72]", + "eor r6, r12, lr", + "eor r6, r6, r7", + "str r5, [r2, #76]", + "and r5, r8, r6", + "eor r7, r12, r5", + "str r5, [r2, #80]", + "and r5, r8, r12", + "str r8, [r2, #84]", + "eor r8, r6, r5", + "str r6, [r2, #88]", + "and r6, r4, r8", + "str r12, [r2, #92]", + "eor r12, r7, r6", + "str r7, [r2, #96]", + "eor r7, r8, lr", + "str lr, [r2, #100]", + "ldr lr, [r2, #60]", + "eor r7, r7, lr", + "and r5, r4, r5", + "eor lr, r7, r5", + "str r7, [r2, #104]", + "ldr r7, [r2, #76]", + "str r6, [r2, #108]", + "and r6, r7, lr", + "eor r6, r12, r6", + "str r12, [r2, #112]", + "and r12, r7, r8", + "eor lr, lr, r12", + "ldr r12, [r2, #68]", + "and lr, r12, lr", + "eor r6, r6, lr", + "ldr lr, [r2, #92]", + "and lr, r4, lr", + "str r8, [r2, #92]", + "ldr r8, [r2, #72]", + "eor r8, r8, lr", + "str lr, [r2, #72]", + "ldr lr, [r2, #88]", + "str r4, [r2, #116]", + "and r4, r7, lr", + "eor r8, r8, r4", + "and r5, r12, r5", + "eor r8, r8, r5", + "ldr r5, [r2, #64]", + "and r8, r5, r8", + "eor r4, r6, r8", + "ldr r8, [r2, #84]", + "eor r6, lr, r8", + "str r4, [r2, #120]", + "ldr r4, [r2, #108]", + "eor r4, r6, r4", + "str r6, [r2, #108]", + "ldr r6, [r2, #80]", + "ldr r5, [r2, #100]", + "eor r12, r6, r5", + "ldr lr, [r2, #60]", + "eor r12, r12, lr", + "ldr lr, [r2, #116]", + "and r5, lr, r6", + "eor r5, r12, r5", + "and r6, r7, r5", + "str r5, [r2, #124]", + "eor r5, r4, r6", + "str r6, [r2, #128]", + "ldr r6, [r2, #100]", + "str r12, [r2, #132]", + "eor r12, r8, r6", + "str r4, [r2, #136]", + "ldr r4, [r2, #60]", + "eor r12, r12, r4", + "and r4, lr, r12", + "eor r8, r8, r4", + "str r12, [r2, #84]", + "ldr r12, [r2, #88]", + "str r4, [r2, #140]", + "and r4, lr, r12", + "eor r12, r12, r4", + "and r12, r7, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #68]", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "eor r8, r8, r6", + "str r5, [r2, #112]", + "ldr r5, [r2, #60]", + "eor r8, r8, r5", + "ldr r12, [r2, #136]", + "eor r12, r12, r6", + "eor r12, r12, r5", + "and r12, r7, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #96]", + "str r8, [r2, #136]", + "eor r8, r12, r6", + "eor r8, r8, r5", + "and r12, lr, r8", + "str r8, [r2, #88]", + "ldr r8, [r2, #132]", + "eor lr, r8, r12", + "str r12, [r2, #144]", + "eor r12, r4, r6", + "eor r12, r12, r5", + "and r12, r7, r12", + "eor lr, lr, r12", + "str r4, [r2, #148]", + "ldr r4, [r2, #68]", + "and lr, r4, lr", + "str r12, [r2, #152]", + "ldr r12, [r2, #136]", + "eor r12, r12, lr", + "ldr lr, [r2, #64]", + "and r12, lr, r12", + "ldr lr, [r2, #112]", + "eor lr, lr, r12", + "ldr r12, [r2, #116]", + "str lr, [r2, #112]", + "and lr, r12, r8", + "ldr r12, [r2, #104]", + "eor r12, r12, lr", + "ldr lr, [r2, #124]", + "eor r8, lr, r6", + "eor r8, r8, r5", + "and r8, r7, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #128]", + "eor lr, lr, r8", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #80]", + "ldr r8, [r2, #140]", + "eor r8, lr, r8", + "ldr r5, [r2, #152]", + "eor r8, r8, r5", + "ldr r5, [r2, #72]", + "and r6, r7, r5", + "eor lr, lr, r6", + "and lr, r4, lr", + "eor r8, r8, lr", + "ldr lr, [r2, #64]", + "and r8, lr, r8", + "eor r6, r12, r8", + "ldr r8, [r2, #132]", + "eor r8, r8, r5", + "eor r8, r8, r7", + "ldr r5, [r2, #108]", + "ldr r12, [r2, #100]", + "eor r5, r5, r12", + "ldr r12, [r2, #60]", + "eor r5, r5, r12", + "ldr r12, [r2, #116]", + "and r12, r12, r5", + "ldr r5, [r2, #84]", + "eor r5, r5, r12", + "and r5, r7, r5", + "ldr r12, [r2, #92]", + "eor r12, r12, r5", + "and r12, r4, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #96]", + "ldr r5, [r2, #148]", + "eor r12, r12, r5", + "str r6, [r2, #96]", + "ldr r6, [r2, #88]", + "str r8, [r2, #92]", + "ldr r8, [r2, #144]", + "eor r8, r6, r8", + "and r8, r7, r8", + "eor r12, r12, r8", + "and r7, r7, r5", + "eor r6, r6, r7", + "and r4, r4, r6", + "eor r12, r12, r4", + "and lr, lr, r12", + "ldr r12, [r2, #92]", + "eor r7, r12, lr", + "ldr r4, [r2, #120]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #96]", + "and r4, r4, #1", + "ror r4, r4, #6", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #30", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #16", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #24", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #15", + "eor r4, r4, lr, lsr #24", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #16", + "eor r5, r5, lr, lsr #25", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #17", + "eor r6, r6, lr, lsr #26", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #18", + "eor r7, r7, lr, lsr #27", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #19", + "eor r8, r8, lr, lsr #28", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #20", + "eor r12, r12, lr, lsr #29", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r4, [r2, #68]", + "ldr r4, [r2, #60]", + "eor r6, r6, r4", + "str r6, [r2, #72]", + "eor r6, r7, lr", + "eor r6, r6, r4", + "str r8, [r2, #76]", + "and r8, r5, r7", + "eor r4, r6, r8", + "str r8, [r2, #80]", + "and r8, r12, r4", + "str r4, [r2, #84]", + "eor r4, r6, r8", + "str r8, [r2, #88]", + "eor r8, r7, r5", + "str r7, [r2, #92]", + "eor r7, r8, lr", + "str r6, [r2, #96]", + "ldr r6, [r2, #60]", + "eor r7, r7, r6", + "and r6, r12, r7", + "str r7, [r2, #100]", + "eor r7, r8, r6", + "str r8, [r2, #104]", + "ldr r8, [r2, #76]", + "and r7, r8, r7", + "eor r4, r4, r7", + "eor r7, r5, lr", + "str r12, [r2, #108]", + "ldr r12, [r2, #60]", + "eor r7, r7, r12", + "eor r12, r5, r6", + "str r6, [r2, #112]", + "and r6, r8, r12", + "str r5, [r2, #116]", + "eor r5, r7, r6", + "str r6, [r2, #120]", + "ldr r6, [r2, #64]", + "and r5, r6, r5", + "eor r4, r4, r5", + "ldr r5, [r2, #84]", + "str r7, [r2, #124]", + "eor r7, r5, lr", + "ldr r5, [r2, #60]", + "eor r7, r7, r5", + "str r4, [r2, #128]", + "ldr r4, [r2, #108]", + "and r7, r4, r7", + "ldr r6, [r2, #100]", + "eor r7, r6, r7", + "and r7, r8, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #80]", + "eor r7, r7, lr", + "eor r7, r7, r5", + "ldr r5, [r2, #116]", + "str lr, [r2, #80]", + "ldr lr, [r2, #96]", + "and r6, r5, lr", + "ldr r5, [r2, #72]", + "eor r5, r5, r6", + "and lr, r4, r5", + "eor r7, r7, lr", + "str r5, [r2, #72]", + "ldr r5, [r2, #104]", + "and r5, r8, r5", + "eor r7, r7, r5", + "str r5, [r2, #104]", + "ldr r5, [r2, #64]", + "and r7, r5, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #68]", + "and r5, r7, r12", + "ldr r7, [r2, #128]", + "eor r7, r7, r5", + "and r5, r4, r6", + "str r7, [r2, #128]", + "ldr r7, [r2, #100]", + "eor r7, r7, r5", + "ldr r4, [r2, #80]", + "str r5, [r2, #100]", + "eor r5, lr, r4", + "ldr r4, [r2, #60]", + "eor r5, r5, r4", + "and r5, r8, r5", + "eor r5, r7, r5", + "str r7, [r2, #132]", + "eor r7, r6, lr", + "str r6, [r2, #136]", + "ldr r6, [r2, #92]", + "str lr, [r2, #140]", + "ldr lr, [r2, #112]", + "eor lr, r6, lr", + "and lr, r8, lr", + "eor r7, r7, lr", + "ldr r6, [r2, #64]", + "and r7, r6, r7", + "eor r5, r5, r7", + "ldr r7, [r2, #80]", + "eor r12, r12, r7", + "eor r12, r12, r4", + "ldr r4, [r2, #68]", + "and r12, r4, r12", + "eor r5, r5, r12", + "ldr r12, [r2, #84]", + "str r5, [r2, #112]", + "ldr r5, [r2, #140]", + "eor r12, r12, r5", + "ldr r5, [r2, #96]", + "and r5, r8, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #116]", + "eor r5, r5, lr", + "and r5, r6, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #132]", + "eor r5, r5, r7", + "ldr lr, [r2, #60]", + "eor r5, r5, lr", + "ldr lr, [r2, #72]", + "ldr r7, [r2, #100]", + "eor lr, lr, r7", + "and lr, r8, lr", + "eor r5, r5, lr", + "ldr lr, [r2, #124]", + "ldr r8, [r2, #88]", + "eor lr, lr, r8", + "ldr r8, [r2, #104]", + "eor lr, lr, r8", + "and lr, r6, lr", + "eor r5, r5, lr", + "and lr, r4, r5", + "eor r12, r12, lr", + "ldr lr, [r2, #136]", + "ldr r8, [r2, #108]", + "eor r8, lr, r8", + "str r12, [r2, #108]", + "ldr r12, [r2, #92]", + "eor r12, r12, lr", + "eor r12, r12, r7", + "ldr r7, [r2, #76]", + "and r7, r7, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #88]", + "ldr r12, [r2, #80]", + "eor r7, r7, r12", + "ldr lr, [r2, #60]", + "eor r7, r7, lr", + "ldr r4, [r2, #120]", + "eor r7, r7, r4", + "and r6, r6, r7", + "eor r8, r8, r6", + "eor r5, r5, r12", + "eor r5, r5, lr", + "ldr lr, [r2, #68]", + "and lr, lr, r5", + "eor r7, r8, lr", + "ldr r4, [r2, #128]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #108]", + "and r4, r4, #1", + "ror r4, r4, #1", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #10", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #20", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #26", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #11", + "eor r4, r4, lr, lsr #18", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #12", + "eor r5, r5, lr, lsr #19", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #13", + "eor r6, r6, lr, lsr #20", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #14", + "eor r7, r7, lr, lsr #21", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #15", + "eor r8, r8, lr, lsr #22", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #16", + "eor r12, r12, lr, lsr #23", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r5, [r2, #64]", + "eor r5, r4, r4", + "str r6, [r2, #68]", + "ldr r6, [r2, #60]", + "eor r5, r5, r6", + "str r8, [r2, #72]", + "eor r8, r7, lr", + "eor r8, r8, r6", + "str r7, [r2, #76]", + "and r7, r8, r12", + "str r8, [r2, #80]", + "eor r8, r5, r7", + "eor r4, r4, lr", + "eor r4, r4, r6", + "str r5, [r2, #84]", + "and r5, r4, r8", + "str r8, [r2, #88]", + "eor r8, r12, r5", + "str r5, [r2, #92]", + "eor r5, r12, lr", + "eor r5, r5, r6", + "str r12, [r2, #96]", + "ldr r12, [r2, #80]", + "str r4, [r2, #100]", + "and r4, r12, r5", + "eor r12, r5, r4", + "str r4, [r2, #104]", + "ldr r4, [r2, #72]", + "eor r4, r4, lr", + "eor r4, r4, r6", + "and r6, r4, r12", + "eor r6, r8, r6", + "str r8, [r2, #72]", + "eor r8, r5, r7", + "str r12, [r2, #108]", + "and r12, r4, r8", + "str r8, [r2, #112]", + "ldr r8, [r2, #76]", + "eor r12, r8, r12", + "ldr r8, [r2, #68]", + "eor r8, r8, lr", + "str lr, [r2, #68]", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "and r12, r8, r12", + "eor r6, r6, r12", + "ldr r12, [r2, #100]", + "str r6, [r2, #116]", + "and r6, r12, r5", + "str r8, [r2, #120]", + "ldr r8, [r2, #80]", + "eor r6, r8, r6", + "str r5, [r2, #124]", + "ldr r5, [r2, #96]", + "eor lr, r5, r8", + "and r7, r12, r7", + "eor r7, lr, r7", + "and r7, r4, r7", + "eor r6, r6, r7", + "ldr r7, [r2, #108]", + "ldr r8, [r2, #68]", + "str lr, [r2, #128]", + "eor lr, r7, r8", + "ldr r5, [r2, #60]", + "eor lr, lr, r5", + "and lr, r12, lr", + "ldr r7, [r2, #124]", + "eor r5, r7, r12", + "and r5, r4, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #120]", + "and lr, r5, lr", + "eor r6, r6, lr", + "ldr lr, [r2, #64]", + "eor lr, lr, r8", + "ldr r7, [r2, #60]", + "eor lr, lr, r7", + "and r6, lr, r6", + "str lr, [r2, #64]", + "ldr lr, [r2, #116]", + "eor lr, lr, r6", + "ldr r6, [r2, #108]", + "str lr, [r2, #116]", + "and lr, r12, r6", + "ldr r6, [r2, #88]", + "eor r5, r6, lr", + "eor r5, r5, r4", + "ldr r6, [r2, #104]", + "str lr, [r2, #132]", + "eor lr, r6, r8", + "eor lr, lr, r7", + "and r7, r12, lr", + "ldr r8, [r2, #84]", + "eor r8, r8, r7", + "and r6, r12, r6", + "str lr, [r2, #104]", + "and lr, r4, r6", + "eor r8, r8, lr", + "ldr lr, [r2, #120]", + "and r8, lr, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "eor r6, r8, r6", + "and r6, r4, r6", + "ldr r8, [r2, #76]", + "eor r6, r8, r6", + "ldr r8, [r2, #96]", + "and r8, r12, r8", + "ldr r12, [r2, #124]", + "eor r12, r12, r8", + "str r8, [r2, #124]", + "and r8, r4, r12", + "eor r8, r7, r8", + "and r8, lr, r8", + "eor r6, r6, r8", + "ldr r8, [r2, #64]", + "and r6, r8, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #108]", + "str r5, [r2, #96]", + "ldr r5, [r2, #100]", + "str r12, [r2, #84]", + "eor r12, r6, r5", + "eor r12, r12, r4", + "ldr r8, [r2, #104]", + "ldr r6, [r2, #132]", + "eor r8, r8, r6", + "ldr r6, [r2, #128]", + "eor r5, r6, r7", + "and r5, r4, r5", + "eor r8, r8, r5", + "and r8, lr, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #68]", + "eor r5, r6, r8", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "ldr r8, [r2, #100]", + "and r6, r8, r5", + "str r5, [r2, #132]", + "ldr r5, [r2, #108]", + "eor r5, r5, r6", + "and r5, lr, r5", + "str r6, [r2, #108]", + "ldr r6, [r2, #88]", + "eor r6, r6, r5", + "ldr r5, [r2, #64]", + "and r6, r5, r6", + "eor r6, r12, r6", + "ldr r12, [r2, #80]", + "eor r12, r12, r7", + "ldr r7, [r2, #72]", + "and r7, r4, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #112]", + "str r6, [r2, #72]", + "eor r6, r7, r8", + "and r6, r4, r6", + "ldr r5, [r2, #84]", + "eor r5, r5, r6", + "and r5, lr, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #132]", + "ldr r6, [r2, #92]", + "eor r5, r5, r6", + "ldr r6, [r2, #76]", + "and r8, r8, r6", + "ldr r6, [r2, #128]", + "eor r6, r6, r8", + "and r6, r4, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #68]", + "eor r7, r7, r6", + "ldr r8, [r2, #60]", + "eor r7, r7, r8", + "str r12, [r2, #112]", + "ldr r12, [r2, #108]", + "eor r7, r7, r12", + "ldr r12, [r2, #124]", + "eor r12, r12, r6", + "eor r12, r12, r8", + "and r4, r4, r12", + "eor r7, r7, r4", + "and lr, lr, r7", + "eor r5, r5, lr", + "ldr lr, [r2, #64]", + "and lr, lr, r5", + "ldr r5, [r2, #112]", + "eor r7, r5, lr", + "ldr r4, [r2, #116]", + "ldr r5, [r2, #96]", + "ldr r6, [r2, #72]", + "and r4, r4, #1", + "ror r4, r4, #3", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #25", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #14", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #8", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #7", + "eor r4, r4, lr, lsr #12", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #8", + "eor r5, r5, lr, lsr #13", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #9", + "eor r6, r6, lr, lsr #14", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #10", + "eor r7, r7, lr, lsr #15", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #11", + "eor r8, r8, lr, lsr #16", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #12", + "eor r12, r12, lr, lsr #17", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r12, [r2, #64]", + "eor r12, r4, r4", + "str r4, [r2, #68]", + "ldr r4, [r2, #60]", + "eor r12, r12, r4", + "str r12, [r2, #72]", + "eor r12, r8, lr", + "eor r12, r12, r4", + "and r4, r7, r12", + "str r12, [r2, #76]", + "eor r12, r4, r5", + "str lr, [r2, #80]", + "eor lr, r8, r4", + "str r8, [r2, #84]", + "and r8, r5, r7", + "str r4, [r2, #88]", + "eor r4, lr, r8", + "and r4, r6, r4", + "eor r12, r12, r4", + "ldr r4, [r2, #80]", + "str lr, [r2, #92]", + "eor lr, r8, r4", + "str r8, [r2, #96]", + "ldr r8, [r2, #60]", + "eor lr, lr, r8", + "str r12, [r2, #100]", + "eor r12, r7, r4", + "eor r12, r12, r8", + "and r8, r5, r12", + "str r12, [r2, #104]", + "eor r12, r7, r8", + "str r8, [r2, #108]", + "and r8, r6, r12", + "eor lr, lr, r8", + "str r12, [r2, #112]", + "ldr r12, [r2, #64]", + "and lr, r12, lr", + "str r8, [r2, #116]", + "ldr r8, [r2, #100]", + "eor r8, r8, lr", + "ldr lr, [r2, #76]", + "str r8, [r2, #100]", + "eor r8, lr, r7", + "and r12, r5, r8", + "str r5, [r2, #120]", + "ldr r5, [r2, #88]", + "str r8, [r2, #124]", + "eor r8, r5, r12", + "and r8, r6, r8", + "ldr r5, [r2, #84]", + "and r7, r7, r5", + "eor r5, lr, r7", + "ldr lr, [r2, #124]", + "str r7, [r2, #128]", + "eor r7, lr, r4", + "ldr r4, [r2, #60]", + "eor r7, r7, r4", + "eor r7, r7, r12", + "and r7, r6, r7", + "eor r7, r5, r7", + "str r5, [r2, #132]", + "ldr r5, [r2, #64]", + "and r7, r5, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #68]", + "and r8, r7, r8", + "str r12, [r2, #136]", + "ldr r12, [r2, #100]", + "eor r12, r12, r8", + "ldr r8, [r2, #120]", + "str r12, [r2, #100]", + "ldr r12, [r2, #88]", + "and r4, r8, r12", + "ldr r12, [r2, #128]", + "eor lr, r12, r4", + "ldr r12, [r2, #84]", + "and r12, r8, r12", + "ldr r7, [r2, #72]", + "eor r7, r7, r12", + "str r4, [r2, #72]", + "and r4, r6, r7", + "eor lr, lr, r4", + "ldr r4, [r2, #92]", + "str r7, [r2, #84]", + "ldr r7, [r2, #108]", + "eor r4, r4, r7", + "and r12, r6, r12", + "eor r4, r4, r12", + "and r4, r5, r4", + "eor lr, lr, r4", + "and r4, r6, r8", + "str r12, [r2, #92]", + "ldr r12, [r2, #84]", + "eor r12, r12, r4", + "ldr r4, [r2, #104]", + "ldr r7, [r2, #72]", + "eor r4, r4, r7", + "ldr r7, [r2, #76]", + "str lr, [r2, #104]", + "and lr, r8, r7", + "and r8, r6, lr", + "eor r4, r4, r8", + "and r4, r5, r4", + "eor r12, r12, r4", + "ldr r4, [r2, #68]", + "and r12, r4, r12", + "ldr r8, [r2, #104]", + "eor r8, r8, r12", + "ldr r12, [r2, #124]", + "str r8, [r2, #104]", + "ldr r8, [r2, #108]", + "eor r12, r12, r8", + "str lr, [r2, #124]", + "ldr lr, [r2, #96]", + "eor r7, r7, lr", + "and r7, r6, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #88]", + "ldr lr, [r2, #80]", + "eor r8, r7, lr", + "ldr r4, [r2, #60]", + "eor r8, r8, r4", + "ldr r7, [r2, #120]", + "ldr r4, [r2, #128]", + "and lr, r7, r4", + "eor lr, r8, lr", + "str r8, [r2, #96]", + "ldr r8, [r2, #136]", + "and r8, r6, r8", + "eor lr, lr, r8", + "and lr, r5, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #92]", + "ldr r8, [r2, #80]", + "eor lr, lr, r8", + "ldr r8, [r2, #60]", + "eor lr, lr, r8", + "ldr r8, [r2, #88]", + "str r12, [r2, #60]", + "ldr r12, [r2, #72]", + "eor r8, r8, r12", + "eor r4, r4, r7", + "and r4, r6, r4", + "eor r8, r8, r4", + "and r8, r5, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #68]", + "and lr, r8, lr", + "ldr r4, [r2, #60]", + "eor r4, r4, lr", + "ldr lr, [r2, #132]", + "eor r12, lr, r7", + "str r4, [r2, #60]", + "ldr r4, [r2, #116]", + "eor r12, r12, r4", + "ldr r4, [r2, #112]", + "and r8, r5, r4", + "eor r12, r12, r8", + "ldr r8, [r2, #96]", + "str r12, [r2, #116]", + "ldr r12, [r2, #108]", + "eor r12, r8, r12", + "and r12, r6, r12", + "eor r4, r4, r12", + "and r7, r7, r8", + "eor r8, r8, r7", + "ldr r7, [r2, #124]", + "eor lr, lr, r7", + "and r6, r6, lr", + "eor r8, r8, r6", + "and r5, r5, r8", + "eor r4, r4, r5", + "ldr r5, [r2, #68]", + "and r5, r5, r4", + "ldr r4, [r2, #116]", + "eor r7, r4, r5", + "ldr r4, [r2, #100]", + "ldr r5, [r2, #104]", + "ldr r6, [r2, #60]", + "and r4, r4, #1", + "ror r4, r4, #19", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #11", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #29", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #4", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #3", + "eor r4, r4, lr, lsr #6", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #4", + "eor r5, r5, lr, lsr #7", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #5", + "eor r6, r6, lr, lsr #8", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #6", + "eor r7, r7, lr, lsr #9", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #7", + "eor r8, r8, lr, lsr #10", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #8", + "eor r12, r12, lr, lsr #11", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r5, [r2, #64]", + "eor r5, r4, r4", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "str r7, [r2, #72]", + "eor r7, r12, r4", + "str r5, [r2, #76]", + "and r5, r4, r12", + "str r4, [r2, #80]", + "and r4, r6, r5", + "str r12, [r2, #84]", + "eor r12, r7, r4", + "str r4, [r2, #88]", + "eor r4, r5, lr", + "eor r4, r4, r8", + "str r7, [r2, #92]", + "and r7, r6, r4", + "str r5, [r2, #96]", + "ldr r5, [r2, #76]", + "str r4, [r2, #100]", + "eor r4, r5, r7", + "str r7, [r2, #104]", + "ldr r7, [r2, #72]", + "and r5, r7, r4", + "eor r12, r12, r5", + "ldr r5, [r2, #84]", + "str r4, [r2, #108]", + "eor r4, r5, lr", + "eor r4, r4, r8", + "ldr r5, [r2, #80]", + "and r8, r5, r4", + "str r4, [r2, #112]", + "and r4, r6, r8", + "str r8, [r2, #116]", + "ldr r8, [r2, #76]", + "str lr, [r2, #120]", + "eor lr, r8, r4", + "ldr r8, [r2, #100]", + "str r4, [r2, #124]", + "and r4, r7, r8", + "eor lr, lr, r4", + "str r4, [r2, #128]", + "ldr r4, [r2, #68]", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #104]", + "and r8, r7, lr", + "ldr lr, [r2, #108]", + "eor lr, lr, r8", + "and r8, r6, r5", + "ldr r5, [r2, #96]", + "eor r8, r5, r8", + "and r8, r4, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #64]", + "and lr, r8, lr", + "eor r12, r12, lr", + "eor lr, r5, r6", + "str r12, [r2, #108]", + "ldr r12, [r2, #92]", + "ldr r8, [r2, #120]", + "eor r4, r12, r8", + "ldr r12, [r2, #60]", + "eor r4, r4, r12", + "ldr r12, [r2, #124]", + "eor r8, r4, r12", + "and r8, r7, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #84]", + "str r4, [r2, #132]", + "and r4, r6, r8", + "str r6, [r2, #136]", + "ldr r6, [r2, #76]", + "str lr, [r2, #140]", + "eor lr, r6, r4", + "eor r5, r8, r5", + "eor r6, r5, r12", + "and r6, r7, r6", + "eor lr, lr, r6", + "ldr r12, [r2, #68]", + "and lr, r12, lr", + "str r4, [r2, #96]", + "ldr r4, [r2, #140]", + "eor r4, r4, lr", + "ldr lr, [r2, #112]", + "ldr r8, [r2, #116]", + "str r4, [r2, #140]", + "eor r4, lr, r8", + "ldr r8, [r2, #80]", + "ldr lr, [r2, #120]", + "eor r8, r8, lr", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "ldr lr, [r2, #136]", + "and r8, lr, r8", + "eor r8, r4, r8", + "eor r8, r8, r6", + "ldr r6, [r2, #132]", + "str r4, [r2, #80]", + "and r4, lr, r6", + "and r6, r7, r5", + "eor r4, r4, r6", + "and r4, r12, r4", + "eor r8, r8, r4", + "ldr r4, [r2, #64]", + "and r8, r4, r8", + "ldr r6, [r2, #140]", + "eor r6, r6, r8", + "ldr r8, [r2, #120]", + "eor r5, r5, r8", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "and r8, lr, r8", + "str r6, [r2, #112]", + "eor r6, r5, r8", + "str r5, [r2, #60]", + "ldr r5, [r2, #84]", + "str r8, [r2, #120]", + "and r8, r7, r5", + "eor r6, r6, r8", + "str r8, [r2, #140]", + "ldr r8, [r2, #132]", + "ldr r5, [r2, #104]", + "eor r8, r8, r5", + "ldr r5, [r2, #100]", + "ldr r4, [r2, #96]", + "eor r5, r5, r4", + "and r5, r7, r5", + "eor r8, r8, r5", + "and r8, r12, r8", + "eor r6, r6, r8", + "ldr r8, [r2, #92]", + "and r8, lr, r8", + "and r8, r7, r8", + "ldr r5, [r2, #76]", + "eor r5, r5, r8", + "ldr r8, [r2, #124]", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #64]", + "and r5, r8, r5", + "eor r6, r6, r5", + "ldr r5, [r2, #116]", + "eor r5, r5, r4", + "str r6, [r2, #116]", + "ldr r6, [r2, #128]", + "eor r5, r5, r6", + "ldr r6, [r2, #84]", + "ldr r8, [r2, #120]", + "eor r8, r6, r8", + "ldr r4, [r2, #80]", + "and lr, lr, r4", + "eor r4, r4, lr", + "and r4, r7, r4", + "eor r8, r8, r4", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #60]", + "ldr r4, [r2, #88]", + "eor r8, r8, r4", + "eor r6, r6, lr", + "and r7, r7, r6", + "eor r8, r8, r7", + "ldr r7, [r2, #96]", + "ldr r6, [r2, #140]", + "eor r7, r7, r6", + "and r12, r12, r7", + "eor r8, r8, r12", + "ldr r12, [r2, #64]", + "and r12, r12, r8", + "eor r7, r5, r12", + "ldr r4, [r2, #108]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #116]", + "and r4, r4, #1", + "ror r4, r4, #7", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #22", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #12", + "eor r10, r10, r6", + "and r7, r7, #1", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #31", + "eor r4, r4, lr", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "eor r5, r5, lr, lsr #1", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #1", + "eor r6, r6, lr, lsr #2", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #2", + "eor r7, r7, lr, lsr #3", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #3", + "eor r8, r8, lr, lsr #4", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #4", + "eor r12, r12, lr, lsr #5", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r6, r6, r8", + "str r6, [r2, #72]", + "eor r6, r4, lr", + "eor r6, r6, r8", + "str r4, [r2, #76]", + "eor r4, r12, r6", + "eor r7, r7, lr", + "eor r7, r7, r8", + "str r6, [r2, #80]", + "eor r6, r4, r7", + "eor r5, r5, lr", + "eor r5, r5, r8", + "eor r6, r6, r5", + "str r4, [r2, #84]", + "ldr r4, [r2, #76]", + "str r6, [r2, #88]", + "and r6, r7, r4", + "ldr r4, [r2, #80]", + "and r8, r4, r12", + "str r12, [r2, #92]", + "and r12, r7, r8", + "str r7, [r2, #96]", + "eor r7, r4, r12", + "and r7, r5, r7", + "eor r7, r6, r7", + "str r12, [r2, #100]", + "ldr r12, [r2, #68]", + "eor r12, r12, lr", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r12, r12, r8", + "and r7, r12, r7", + "str r12, [r2, #104]", + "ldr r12, [r2, #88]", + "eor r12, r12, r7", + "ldr r7, [r2, #92]", + "str r12, [r2, #88]", + "eor r12, r7, lr", + "eor r12, r12, r8", + "and r8, r4, r12", + "str lr, [r2, #108]", + "ldr lr, [r2, #72]", + "str r12, [r2, #112]", + "eor r12, lr, r8", + "str r8, [r2, #116]", + "eor r8, r12, r6", + "and r8, r5, r8", + "eor r4, r4, r8", + "ldr r8, [r2, #68]", + "str r12, [r2, #80]", + "eor r12, r7, r8", + "str r6, [r2, #120]", + "ldr r6, [r2, #96]", + "and r7, r6, r12", + "eor lr, lr, r7", + "ldr r6, [r2, #112]", + "str r12, [r2, #72]", + "and r12, r5, r6", + "eor lr, lr, r12", + "str r12, [r2, #124]", + "ldr r12, [r2, #104]", + "and lr, r12, lr", + "eor r4, r4, lr", + "ldr lr, [r2, #64]", + "ldr r12, [r2, #108]", + "eor lr, lr, r12", + "str r5, [r2, #64]", + "ldr r5, [r2, #60]", + "eor lr, lr, r5", + "and r4, lr, r4", + "str lr, [r2, #128]", + "ldr lr, [r2, #88]", + "eor r4, lr, r4", + "eor lr, r8, r12", + "eor lr, lr, r5", + "str r4, [r2, #88]", + "eor r4, lr, r7", + "str r7, [r2, #132]", + "ldr r7, [r2, #72]", + "eor r7, r7, r12", + "eor r7, r7, r5", + "ldr r8, [r2, #96]", + "str lr, [r2, #72]", + "and lr, r8, r7", + "eor r6, r6, lr", + "str r7, [r2, #112]", + "ldr r7, [r2, #64]", + "and r6, r7, r6", + "eor r4, r4, r6", + "ldr r6, [r2, #100]", + "str lr, [r2, #136]", + "eor lr, r6, r12", + "eor lr, lr, r5", + "and r8, r7, r6", + "eor r8, lr, r8", + "str lr, [r2, #140]", + "ldr lr, [r2, #104]", + "and r8, lr, r8", + "eor r4, r4, r8", + "ldr r8, [r2, #92]", + "ldr r6, [r2, #116]", + "str r4, [r2, #144]", + "eor r4, r8, r6", + "ldr r8, [r2, #120]", + "eor r8, r4, r8", + "ldr r6, [r2, #84]", + "and r6, r7, r6", + "eor lr, r8, r6", + "eor r8, r8, r12", + "eor r8, r8, r5", + "eor r4, r4, r12", + "eor r4, r4, r5", + "and r4, r7, r4", + "eor r8, r8, r4", + "ldr r4, [r2, #104]", + "and r8, r4, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #128]", + "and lr, r8, lr", + "ldr r5, [r2, #144]", + "eor r5, r5, lr", + "ldr lr, [r2, #116]", + "str r5, [r2, #144]", + "ldr r5, [r2, #100]", + "eor r12, lr, r5", + "str r6, [r2, #84]", + "ldr r6, [r2, #96]", + "ldr lr, [r2, #72]", + "and r8, r6, lr", + "ldr r6, [r2, #92]", + "eor r6, r6, r8", + "and r8, r7, r6", + "eor r12, r12, r8", + "ldr r8, [r2, #136]", + "eor r8, lr, r8", + "and r8, r4, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #124]", + "eor lr, lr, r8", + "str r6, [r2, #72]", + "ldr r6, [r2, #68]", + "eor r5, r6, r5", + "eor r5, r5, r8", + "and r5, r4, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #128]", + "and lr, r5, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #140]", + "and lr, r7, lr", + "ldr r8, [r2, #72]", + "eor r8, r8, lr", + "ldr lr, [r2, #96]", + "str r12, [r2, #72]", + "ldr r12, [r2, #116]", + "and lr, lr, r12", + "eor r6, r6, lr", + "ldr lr, [r2, #76]", + "ldr r12, [r2, #132]", + "eor lr, lr, r12", + "and lr, r7, lr", + "eor lr, r6, lr", + "and lr, r4, lr", + "eor r8, r8, lr", + "ldr lr, [r2, #80]", + "ldr r12, [r2, #84]", + "eor lr, lr, r12", + "ldr r12, [r2, #108]", + "eor r6, r6, r12", + "ldr r12, [r2, #60]", + "eor r6, r6, r12", + "ldr r12, [r2, #112]", + "and r7, r7, r12", + "eor r6, r6, r7", + "and r4, r4, r6", + "eor lr, lr, r4", + "and r5, r5, lr", + "eor r7, r8, r5", + "ldr r4, [r2, #88]", + "ldr r5, [r2, #144]", + "ldr r6, [r2, #72]", + "and r4, r4, #1", + "ror r4, r4, #21", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #15", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #27", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #5", + "eor r10, r10, r7", + "mov lr, r10", + "mov r10, r11", + "mov r11, lr", + "add r0, r0, #8", + "subs r9, r9, #1", + "bne 20b", + "mov lr, r10", + "mov r10, r11", + "mov r11, lr", + "add r0, r0, #120", + "mov r9, #16", + "21:", + "ldr lr, [r0, #4]", + "mov r4, r11", + "lsr r4, r4, #27", + "eor r4, r4, lr, lsr #10", + "and r4, r4, #1", + "ldr lr, [r0, #4]", + "mov r5, r11", + "lsr r5, r5, #28", + "eor r5, r5, lr, lsr #11", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #29", + "eor r6, r6, lr, lsr #12", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #30", + "eor r7, r7, lr, lsr #13", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #31", + "eor r8, r8, lr, lsr #14", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "eor r12, r12, lr, lsr #15", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, lr", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "and r7, r8, r6", + "str lr, [r2, #72]", + "eor lr, r4, r8", + "str r8, [r2, #76]", + "and r8, r5, lr", + "eor r8, r7, r8", + "str lr, [r2, #80]", + "eor lr, r6, r7", + "str r7, [r2, #84]", + "and r7, r5, lr", + "eor r7, r4, r7", + "and r7, r12, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #76]", + "str lr, [r2, #88]", + "and lr, r7, r4", + "str r4, [r2, #92]", + "ldr r4, [r2, #72]", + "str r6, [r2, #96]", + "eor r6, lr, r4", + "str r8, [r2, #100]", + "ldr r8, [r2, #60]", + "eor r6, r6, r8", + "str r12, [r2, #104]", + "and r12, r5, r6", + "str r6, [r2, #108]", + "eor r6, lr, r12", + "str lr, [r2, #112]", + "eor lr, r7, r4", + "eor lr, lr, r8", + "eor r8, lr, r12", + "str r12, [r2, #116]", + "ldr r12, [r2, #104]", + "and r4, r12, r8", + "eor r6, r6, r4", + "ldr r4, [r2, #68]", + "and r6, r4, r6", + "str r8, [r2, #120]", + "ldr r8, [r2, #100]", + "eor r8, r8, r6", + "and r7, r5, r7", + "ldr r6, [r2, #108]", + "str r8, [r2, #76]", + "eor r8, r6, r7", + "str r7, [r2, #100]", + "and r7, r5, lr", + "str lr, [r2, #124]", + "ldr lr, [r2, #96]", + "eor r6, lr, r7", + "and r6, r12, r6", + "eor r8, r8, r6", + "and r6, r5, lr", + "str r5, [r2, #128]", + "ldr r5, [r2, #88]", + "str r7, [r2, #132]", + "eor r7, r5, r6", + "and r7, r12, r7", + "and r7, r4, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r8, r7, r8", + "str r6, [r2, #136]", + "ldr r6, [r2, #76]", + "eor r6, r6, r8", + "ldr r8, [r2, #112]", + "eor lr, lr, r8", + "ldr r8, [r2, #132]", + "str r6, [r2, #112]", + "eor r6, lr, r8", + "ldr r7, [r2, #84]", + "ldr r4, [r2, #72]", + "eor r8, r7, r4", + "ldr r7, [r2, #60]", + "eor r8, r8, r7", + "ldr r7, [r2, #128]", + "and lr, r7, lr", + "eor lr, r8, lr", + "str r8, [r2, #96]", + "and r8, r12, lr", + "eor r6, r6, r8", + "eor r8, r5, r4", + "ldr r4, [r2, #60]", + "eor r8, r8, r4", + "ldr r4, [r2, #132]", + "eor r4, r8, r4", + "str r8, [r2, #132]", + "ldr r8, [r2, #84]", + "and r5, r7, r8", + "eor r8, r8, r5", + "and r8, r12, r8", + "eor r5, r4, r8", + "str r4, [r2, #84]", + "ldr r4, [r2, #68]", + "and r5, r4, r5", + "eor r6, r6, r5", + "eor lr, lr, r8", + "ldr r8, [r2, #92]", + "and r5, r7, r8", + "ldr r8, [r2, #96]", + "eor r7, r8, r5", + "and r7, r12, r7", + "ldr r8, [r2, #88]", + "eor r12, r8, r7", + "and r12, r4, r12", + "eor lr, lr, r12", + "ldr r12, [r2, #64]", + "and lr, r12, lr", + "eor r6, r6, lr", + "eor lr, r8, r5", + "str r6, [r2, #76]", + "ldr r6, [r2, #104]", + "ldr r8, [r2, #84]", + "and r12, r6, r8", + "eor lr, lr, r12", + "ldr r12, [r2, #108]", + "str r7, [r2, #140]", + "ldr r7, [r2, #136]", + "eor r12, r12, r7", + "ldr r7, [r2, #128]", + "str r5, [r2, #136]", + "ldr r5, [r2, #132]", + "and r5, r7, r5", + "ldr r7, [r2, #96]", + "eor r7, r7, r5", + "and r7, r6, r7", + "eor r12, r12, r7", + "and r12, r4, r12", + "eor lr, lr, r12", + "ldr r12, [r2, #116]", + "and r7, r6, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #92]", + "ldr r5, [r2, #136]", + "eor r7, r7, r5", + "ldr r5, [r2, #140]", + "eor r7, r7, r5", + "and r7, r4, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r8, r7, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #80]", + "ldr r5, [r2, #72]", + "eor r8, r8, r5", + "str lr, [r2, #80]", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "ldr r7, [r2, #128]", + "eor r8, r8, r7", + "eor r12, r12, r5", + "eor r12, r12, lr", + "and r12, r6, r12", + "eor r12, r8, r12", + "str r8, [r2, #116]", + "ldr r8, [r2, #120]", + "eor r8, r8, r5", + "eor r8, r8, lr", + "and r8, r6, r8", + "ldr lr, [r2, #124]", + "eor lr, lr, r8", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #88]", + "ldr r8, [r2, #100]", + "eor r8, lr, r8", + "and r8, r6, r8", + "ldr r5, [r2, #136]", + "eor r5, r5, r8", + "eor lr, lr, r7", + "and r6, r6, lr", + "ldr lr, [r2, #116]", + "eor lr, lr, r6", + "and r4, r4, lr", + "eor r5, r5, r4", + "ldr r4, [r2, #64]", + "and r4, r4, r5", + "eor r7, r12, r4", + "ldr r4, [r2, #112]", + "ldr r5, [r2, #76]", + "ldr r6, [r2, #80]", + "and r4, r4, #1", + "ror r4, r4, #31", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #23", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #17", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #9", + "eor r10, r10, r7", + "ldr lr, [r0, #4]", + "mov r4, r11", + "lsr r4, r4, #23", + "eor r4, r4, lr, lsr #4", + "and r4, r4, #1", + "ldr lr, [r0, #4]", + "mov r5, r11", + "lsr r5, r5, #24", + "eor r5, r5, lr, lsr #5", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #25", + "eor r6, r6, lr, lsr #6", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #26", + "eor r7, r7, lr, lsr #7", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #27", + "eor r8, r8, lr, lsr #8", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "lsr r12, r12, #28", + "eor r12, r12, lr, lsr #9", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "str r6, [r2, #72]", + "eor r6, r12, lr", + "eor r6, r6, r7", + "str r8, [r2, #76]", + "and r8, r5, r12", + "str r5, [r2, #80]", + "eor r5, r12, r8", + "str r12, [r2, #84]", + "and r12, r4, r5", + "eor r12, r6, r12", + "str r6, [r2, #88]", + "eor r6, r8, lr", + "eor r6, r6, r7", + "str r8, [r2, #92]", + "and r8, r4, r6", + "str r6, [r2, #96]", + "eor r6, r5, r8", + "str r8, [r2, #100]", + "ldr r8, [r2, #76]", + "and r6, r8, r6", + "eor r12, r12, r6", + "str r6, [r2, #104]", + "ldr r6, [r2, #80]", + "str r12, [r2, #108]", + "ldr r12, [r2, #88]", + "and r8, r6, r12", + "eor r6, r12, r8", + "eor r5, r5, lr", + "eor r5, r5, r7", + "and r12, r4, r5", + "str r5, [r2, #112]", + "eor r5, r6, r12", + "str r12, [r2, #116]", + "eor r12, r6, lr", + "eor r12, r12, r7", + "str r6, [r2, #120]", + "and r6, r4, r12", + "str r12, [r2, #124]", + "ldr r12, [r2, #80]", + "eor r6, r12, r6", + "ldr r7, [r2, #76]", + "and r6, r7, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #68]", + "and r5, r6, r5", + "ldr r6, [r2, #108]", + "eor r6, r6, r5", + "and r5, r4, r8", + "str r8, [r2, #108]", + "ldr r8, [r2, #72]", + "eor r5, r8, r5", + "ldr r8, [r2, #84]", + "str lr, [r2, #128]", + "eor lr, r8, r12", + "and r8, r4, lr", + "str r4, [r2, #132]", + "eor r4, r12, r8", + "and r4, r7, r4", + "eor r5, r5, r4", + "ldr r4, [r2, #64]", + "and r5, r4, r5", + "eor r6, r6, r5", + "ldr r5, [r2, #128]", + "eor lr, lr, r5", + "str r6, [r2, #136]", + "ldr r6, [r2, #60]", + "eor lr, lr, r6", + "ldr r6, [r2, #132]", + "ldr r5, [r2, #92]", + "and r5, r6, r5", + "eor r12, lr, r5", + "str r5, [r2, #92]", + "ldr r5, [r2, #112]", + "eor r5, r5, r8", + "and r5, r7, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #124]", + "ldr r8, [r2, #104]", + "eor r5, r5, r8", + "ldr r8, [r2, #68]", + "and r5, r8, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #120]", + "str lr, [r2, #104]", + "and lr, r6, r5", + "str r12, [r2, #124]", + "ldr r12, [r2, #84]", + "eor lr, r12, lr", + "and lr, r7, lr", + "ldr r4, [r2, #96]", + "eor lr, r4, lr", + "ldr r4, [r2, #88]", + "str lr, [r2, #112]", + "and lr, r6, r4", + "eor r5, r5, lr", + "and r12, r7, r12", + "eor r5, r5, r12", + "and r5, r8, r5", + "ldr r12, [r2, #112]", + "eor r12, r12, r5", + "ldr r5, [r2, #64]", + "and r12, r5, r12", + "str lr, [r2, #112]", + "ldr lr, [r2, #124]", + "eor lr, lr, r12", + "ldr r12, [r2, #104]", + "str lr, [r2, #124]", + "eor lr, r12, r6", + "eor lr, lr, r7", + "ldr r4, [r2, #96]", + "ldr r12, [r2, #92]", + "eor r5, r4, r12", + "and r5, r7, r5", + "eor r5, r6, r5", + "and r5, r8, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #80]", + "and r6, r6, r5", + "ldr r5, [r2, #72]", + "eor r5, r5, r6", + "ldr r12, [r2, #100]", + "eor r4, r4, r12", + "and r4, r7, r4", + "eor r5, r5, r4", + "and r6, r8, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #64]", + "and r5, r6, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #104]", + "eor r5, r5, r12", + "ldr r12, [r2, #116]", + "and r12, r7, r12", + "eor r5, r5, r12", + "ldr r12, [r2, #92]", + "ldr r4, [r2, #128]", + "str lr, [r2, #116]", + "eor lr, r12, r4", + "ldr r6, [r2, #60]", + "eor lr, lr, r6", + "ldr r6, [r2, #88]", + "ldr r4, [r2, #112]", + "eor r6, r6, r4", + "and r6, r7, r6", + "eor lr, lr, r6", + "and r8, r8, lr", + "eor r5, r5, r8", + "ldr r8, [r2, #108]", + "eor r8, r8, r12", + "ldr r12, [r2, #128]", + "eor r12, r8, r12", + "ldr lr, [r2, #60]", + "eor r12, r12, lr", + "and r7, r7, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r7, r7, r8", + "eor r7, r5, r7", + "ldr r4, [r2, #136]", + "ldr r5, [r2, #124]", + "ldr r6, [r2, #116]", + "and r4, r4, #1", + "ror r4, r4, #18", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #2", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #28", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #13", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #19", + "eor r4, r4, lr, lsr #30", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #20", + "eor r5, r5, lr, lsr #31", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #21", + "eor r6, r6, lr", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #22", + "eor r7, r7, lr, lsr #1", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #23", + "eor r8, r8, lr, lsr #2", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "lsr r12, r12, #24", + "eor r12, r12, lr, lsr #3", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "str r6, [r2, #72]", + "eor r6, r12, lr", + "eor r6, r6, r7", + "str r5, [r2, #76]", + "and r5, r8, r6", + "eor r7, r12, r5", + "str r5, [r2, #80]", + "and r5, r8, r12", + "str r8, [r2, #84]", + "eor r8, r6, r5", + "str r6, [r2, #88]", + "and r6, r4, r8", + "str r12, [r2, #92]", + "eor r12, r7, r6", + "str r7, [r2, #96]", + "eor r7, r8, lr", + "str lr, [r2, #100]", + "ldr lr, [r2, #60]", + "eor r7, r7, lr", + "and r5, r4, r5", + "eor lr, r7, r5", + "str r7, [r2, #104]", + "ldr r7, [r2, #76]", + "str r6, [r2, #108]", + "and r6, r7, lr", + "eor r6, r12, r6", + "str r12, [r2, #112]", + "and r12, r7, r8", + "eor lr, lr, r12", + "ldr r12, [r2, #68]", + "and lr, r12, lr", + "eor r6, r6, lr", + "ldr lr, [r2, #92]", + "and lr, r4, lr", + "str r8, [r2, #92]", + "ldr r8, [r2, #72]", + "eor r8, r8, lr", + "str lr, [r2, #72]", + "ldr lr, [r2, #88]", + "str r4, [r2, #116]", + "and r4, r7, lr", + "eor r8, r8, r4", + "and r5, r12, r5", + "eor r8, r8, r5", + "ldr r5, [r2, #64]", + "and r8, r5, r8", + "eor r4, r6, r8", + "ldr r8, [r2, #84]", + "eor r6, lr, r8", + "str r4, [r2, #120]", + "ldr r4, [r2, #108]", + "eor r4, r6, r4", + "str r6, [r2, #108]", + "ldr r6, [r2, #80]", + "ldr r5, [r2, #100]", + "eor r12, r6, r5", + "ldr lr, [r2, #60]", + "eor r12, r12, lr", + "ldr lr, [r2, #116]", + "and r5, lr, r6", + "eor r5, r12, r5", + "and r6, r7, r5", + "str r5, [r2, #124]", + "eor r5, r4, r6", + "str r6, [r2, #128]", + "ldr r6, [r2, #100]", + "str r12, [r2, #132]", + "eor r12, r8, r6", + "str r4, [r2, #136]", + "ldr r4, [r2, #60]", + "eor r12, r12, r4", + "and r4, lr, r12", + "eor r8, r8, r4", + "str r12, [r2, #84]", + "ldr r12, [r2, #88]", + "str r4, [r2, #140]", + "and r4, lr, r12", + "eor r12, r12, r4", + "and r12, r7, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #68]", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "eor r8, r8, r6", + "str r5, [r2, #112]", + "ldr r5, [r2, #60]", + "eor r8, r8, r5", + "ldr r12, [r2, #136]", + "eor r12, r12, r6", + "eor r12, r12, r5", + "and r12, r7, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #96]", + "str r8, [r2, #136]", + "eor r8, r12, r6", + "eor r8, r8, r5", + "and r12, lr, r8", + "str r8, [r2, #88]", + "ldr r8, [r2, #132]", + "eor lr, r8, r12", + "str r12, [r2, #144]", + "eor r12, r4, r6", + "eor r12, r12, r5", + "and r12, r7, r12", + "eor lr, lr, r12", + "str r4, [r2, #148]", + "ldr r4, [r2, #68]", + "and lr, r4, lr", + "str r12, [r2, #152]", + "ldr r12, [r2, #136]", + "eor r12, r12, lr", + "ldr lr, [r2, #64]", + "and r12, lr, r12", + "ldr lr, [r2, #112]", + "eor lr, lr, r12", + "ldr r12, [r2, #116]", + "str lr, [r2, #112]", + "and lr, r12, r8", + "ldr r12, [r2, #104]", + "eor r12, r12, lr", + "ldr lr, [r2, #124]", + "eor r8, lr, r6", + "eor r8, r8, r5", + "and r8, r7, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #128]", + "eor lr, lr, r8", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #80]", + "ldr r8, [r2, #140]", + "eor r8, lr, r8", + "ldr r5, [r2, #152]", + "eor r8, r8, r5", + "ldr r5, [r2, #72]", + "and r6, r7, r5", + "eor lr, lr, r6", + "and lr, r4, lr", + "eor r8, r8, lr", + "ldr lr, [r2, #64]", + "and r8, lr, r8", + "eor r6, r12, r8", + "ldr r8, [r2, #132]", + "eor r8, r8, r5", + "eor r8, r8, r7", + "ldr r5, [r2, #108]", + "ldr r12, [r2, #100]", + "eor r5, r5, r12", + "ldr r12, [r2, #60]", + "eor r5, r5, r12", + "ldr r12, [r2, #116]", + "and r12, r12, r5", + "ldr r5, [r2, #84]", + "eor r5, r5, r12", + "and r5, r7, r5", + "ldr r12, [r2, #92]", + "eor r12, r12, r5", + "and r12, r4, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #96]", + "ldr r5, [r2, #148]", + "eor r12, r12, r5", + "str r6, [r2, #96]", + "ldr r6, [r2, #88]", + "str r8, [r2, #92]", + "ldr r8, [r2, #144]", + "eor r8, r6, r8", + "and r8, r7, r8", + "eor r12, r12, r8", + "and r7, r7, r5", + "eor r6, r6, r7", + "and r4, r4, r6", + "eor r12, r12, r4", + "and lr, lr, r12", + "ldr r12, [r2, #92]", + "eor r7, r12, lr", + "ldr r4, [r2, #120]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #96]", + "and r4, r4, #1", + "ror r4, r4, #6", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #30", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #16", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #24", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #15", + "eor r4, r4, lr, lsr #24", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #16", + "eor r5, r5, lr, lsr #25", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #17", + "eor r6, r6, lr, lsr #26", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #18", + "eor r7, r7, lr, lsr #27", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #19", + "eor r8, r8, lr, lsr #28", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #20", + "eor r12, r12, lr, lsr #29", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r4, [r2, #68]", + "ldr r4, [r2, #60]", + "eor r6, r6, r4", + "str r6, [r2, #72]", + "eor r6, r7, lr", + "eor r6, r6, r4", + "str r8, [r2, #76]", + "and r8, r5, r7", + "eor r4, r6, r8", + "str r8, [r2, #80]", + "and r8, r12, r4", + "str r4, [r2, #84]", + "eor r4, r6, r8", + "str r8, [r2, #88]", + "eor r8, r7, r5", + "str r7, [r2, #92]", + "eor r7, r8, lr", + "str r6, [r2, #96]", + "ldr r6, [r2, #60]", + "eor r7, r7, r6", + "and r6, r12, r7", + "str r7, [r2, #100]", + "eor r7, r8, r6", + "str r8, [r2, #104]", + "ldr r8, [r2, #76]", + "and r7, r8, r7", + "eor r4, r4, r7", + "eor r7, r5, lr", + "str r12, [r2, #108]", + "ldr r12, [r2, #60]", + "eor r7, r7, r12", + "eor r12, r5, r6", + "str r6, [r2, #112]", + "and r6, r8, r12", + "str r5, [r2, #116]", + "eor r5, r7, r6", + "str r6, [r2, #120]", + "ldr r6, [r2, #64]", + "and r5, r6, r5", + "eor r4, r4, r5", + "ldr r5, [r2, #84]", + "str r7, [r2, #124]", + "eor r7, r5, lr", + "ldr r5, [r2, #60]", + "eor r7, r7, r5", + "str r4, [r2, #128]", + "ldr r4, [r2, #108]", + "and r7, r4, r7", + "ldr r6, [r2, #100]", + "eor r7, r6, r7", + "and r7, r8, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #80]", + "eor r7, r7, lr", + "eor r7, r7, r5", + "ldr r5, [r2, #116]", + "str lr, [r2, #80]", + "ldr lr, [r2, #96]", + "and r6, r5, lr", + "ldr r5, [r2, #72]", + "eor r5, r5, r6", + "and lr, r4, r5", + "eor r7, r7, lr", + "str r5, [r2, #72]", + "ldr r5, [r2, #104]", + "and r5, r8, r5", + "eor r7, r7, r5", + "str r5, [r2, #104]", + "ldr r5, [r2, #64]", + "and r7, r5, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #68]", + "and r5, r7, r12", + "ldr r7, [r2, #128]", + "eor r7, r7, r5", + "and r5, r4, r6", + "str r7, [r2, #128]", + "ldr r7, [r2, #100]", + "eor r7, r7, r5", + "ldr r4, [r2, #80]", + "str r5, [r2, #100]", + "eor r5, lr, r4", + "ldr r4, [r2, #60]", + "eor r5, r5, r4", + "and r5, r8, r5", + "eor r5, r7, r5", + "str r7, [r2, #132]", + "eor r7, r6, lr", + "str r6, [r2, #136]", + "ldr r6, [r2, #92]", + "str lr, [r2, #140]", + "ldr lr, [r2, #112]", + "eor lr, r6, lr", + "and lr, r8, lr", + "eor r7, r7, lr", + "ldr r6, [r2, #64]", + "and r7, r6, r7", + "eor r5, r5, r7", + "ldr r7, [r2, #80]", + "eor r12, r12, r7", + "eor r12, r12, r4", + "ldr r4, [r2, #68]", + "and r12, r4, r12", + "eor r5, r5, r12", + "ldr r12, [r2, #84]", + "str r5, [r2, #112]", + "ldr r5, [r2, #140]", + "eor r12, r12, r5", + "ldr r5, [r2, #96]", + "and r5, r8, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #116]", + "eor r5, r5, lr", + "and r5, r6, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #132]", + "eor r5, r5, r7", + "ldr lr, [r2, #60]", + "eor r5, r5, lr", + "ldr lr, [r2, #72]", + "ldr r7, [r2, #100]", + "eor lr, lr, r7", + "and lr, r8, lr", + "eor r5, r5, lr", + "ldr lr, [r2, #124]", + "ldr r8, [r2, #88]", + "eor lr, lr, r8", + "ldr r8, [r2, #104]", + "eor lr, lr, r8", + "and lr, r6, lr", + "eor r5, r5, lr", + "and lr, r4, r5", + "eor r12, r12, lr", + "ldr lr, [r2, #136]", + "ldr r8, [r2, #108]", + "eor r8, lr, r8", + "str r12, [r2, #108]", + "ldr r12, [r2, #92]", + "eor r12, r12, lr", + "eor r12, r12, r7", + "ldr r7, [r2, #76]", + "and r7, r7, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #88]", + "ldr r12, [r2, #80]", + "eor r7, r7, r12", + "ldr lr, [r2, #60]", + "eor r7, r7, lr", + "ldr r4, [r2, #120]", + "eor r7, r7, r4", + "and r6, r6, r7", + "eor r8, r8, r6", + "eor r5, r5, r12", + "eor r5, r5, lr", + "ldr lr, [r2, #68]", + "and lr, lr, r5", + "eor r7, r8, lr", + "ldr r4, [r2, #128]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #108]", + "and r4, r4, #1", + "ror r4, r4, #1", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #10", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #20", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #26", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #11", + "eor r4, r4, lr, lsr #18", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #12", + "eor r5, r5, lr, lsr #19", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #13", + "eor r6, r6, lr, lsr #20", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #14", + "eor r7, r7, lr, lsr #21", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #15", + "eor r8, r8, lr, lsr #22", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #16", + "eor r12, r12, lr, lsr #23", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r5, [r2, #64]", + "eor r5, r4, r4", + "str r6, [r2, #68]", + "ldr r6, [r2, #60]", + "eor r5, r5, r6", + "str r8, [r2, #72]", + "eor r8, r7, lr", + "eor r8, r8, r6", + "str r7, [r2, #76]", + "and r7, r8, r12", + "str r8, [r2, #80]", + "eor r8, r5, r7", + "eor r4, r4, lr", + "eor r4, r4, r6", + "str r5, [r2, #84]", + "and r5, r4, r8", + "str r8, [r2, #88]", + "eor r8, r12, r5", + "str r5, [r2, #92]", + "eor r5, r12, lr", + "eor r5, r5, r6", + "str r12, [r2, #96]", + "ldr r12, [r2, #80]", + "str r4, [r2, #100]", + "and r4, r12, r5", + "eor r12, r5, r4", + "str r4, [r2, #104]", + "ldr r4, [r2, #72]", + "eor r4, r4, lr", + "eor r4, r4, r6", + "and r6, r4, r12", + "eor r6, r8, r6", + "str r8, [r2, #72]", + "eor r8, r5, r7", + "str r12, [r2, #108]", + "and r12, r4, r8", + "str r8, [r2, #112]", + "ldr r8, [r2, #76]", + "eor r12, r8, r12", + "ldr r8, [r2, #68]", + "eor r8, r8, lr", + "str lr, [r2, #68]", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "and r12, r8, r12", + "eor r6, r6, r12", + "ldr r12, [r2, #100]", + "str r6, [r2, #116]", + "and r6, r12, r5", + "str r8, [r2, #120]", + "ldr r8, [r2, #80]", + "eor r6, r8, r6", + "str r5, [r2, #124]", + "ldr r5, [r2, #96]", + "eor lr, r5, r8", + "and r7, r12, r7", + "eor r7, lr, r7", + "and r7, r4, r7", + "eor r6, r6, r7", + "ldr r7, [r2, #108]", + "ldr r8, [r2, #68]", + "str lr, [r2, #128]", + "eor lr, r7, r8", + "ldr r5, [r2, #60]", + "eor lr, lr, r5", + "and lr, r12, lr", + "ldr r7, [r2, #124]", + "eor r5, r7, r12", + "and r5, r4, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #120]", + "and lr, r5, lr", + "eor r6, r6, lr", + "ldr lr, [r2, #64]", + "eor lr, lr, r8", + "ldr r7, [r2, #60]", + "eor lr, lr, r7", + "and r6, lr, r6", + "str lr, [r2, #64]", + "ldr lr, [r2, #116]", + "eor lr, lr, r6", + "ldr r6, [r2, #108]", + "str lr, [r2, #116]", + "and lr, r12, r6", + "ldr r6, [r2, #88]", + "eor r5, r6, lr", + "eor r5, r5, r4", + "ldr r6, [r2, #104]", + "str lr, [r2, #132]", + "eor lr, r6, r8", + "eor lr, lr, r7", + "and r7, r12, lr", + "ldr r8, [r2, #84]", + "eor r8, r8, r7", + "and r6, r12, r6", + "str lr, [r2, #104]", + "and lr, r4, r6", + "eor r8, r8, lr", + "ldr lr, [r2, #120]", + "and r8, lr, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "eor r6, r8, r6", + "and r6, r4, r6", + "ldr r8, [r2, #76]", + "eor r6, r8, r6", + "ldr r8, [r2, #96]", + "and r8, r12, r8", + "ldr r12, [r2, #124]", + "eor r12, r12, r8", + "str r8, [r2, #124]", + "and r8, r4, r12", + "eor r8, r7, r8", + "and r8, lr, r8", + "eor r6, r6, r8", + "ldr r8, [r2, #64]", + "and r6, r8, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #108]", + "str r5, [r2, #96]", + "ldr r5, [r2, #100]", + "str r12, [r2, #84]", + "eor r12, r6, r5", + "eor r12, r12, r4", + "ldr r8, [r2, #104]", + "ldr r6, [r2, #132]", + "eor r8, r8, r6", + "ldr r6, [r2, #128]", + "eor r5, r6, r7", + "and r5, r4, r5", + "eor r8, r8, r5", + "and r8, lr, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #68]", + "eor r5, r6, r8", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "ldr r8, [r2, #100]", + "and r6, r8, r5", + "str r5, [r2, #132]", + "ldr r5, [r2, #108]", + "eor r5, r5, r6", + "and r5, lr, r5", + "str r6, [r2, #108]", + "ldr r6, [r2, #88]", + "eor r6, r6, r5", + "ldr r5, [r2, #64]", + "and r6, r5, r6", + "eor r6, r12, r6", + "ldr r12, [r2, #80]", + "eor r12, r12, r7", + "ldr r7, [r2, #72]", + "and r7, r4, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #112]", + "str r6, [r2, #72]", + "eor r6, r7, r8", + "and r6, r4, r6", + "ldr r5, [r2, #84]", + "eor r5, r5, r6", + "and r5, lr, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #132]", + "ldr r6, [r2, #92]", + "eor r5, r5, r6", + "ldr r6, [r2, #76]", + "and r8, r8, r6", + "ldr r6, [r2, #128]", + "eor r6, r6, r8", + "and r6, r4, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #68]", + "eor r7, r7, r6", + "ldr r8, [r2, #60]", + "eor r7, r7, r8", + "str r12, [r2, #112]", + "ldr r12, [r2, #108]", + "eor r7, r7, r12", + "ldr r12, [r2, #124]", + "eor r12, r12, r6", + "eor r12, r12, r8", + "and r4, r4, r12", + "eor r7, r7, r4", + "and lr, lr, r7", + "eor r5, r5, lr", + "ldr lr, [r2, #64]", + "and lr, lr, r5", + "ldr r5, [r2, #112]", + "eor r7, r5, lr", + "ldr r4, [r2, #116]", + "ldr r5, [r2, #96]", + "ldr r6, [r2, #72]", + "and r4, r4, #1", + "ror r4, r4, #3", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #25", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #14", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #8", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #7", + "eor r4, r4, lr, lsr #12", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #8", + "eor r5, r5, lr, lsr #13", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #9", + "eor r6, r6, lr, lsr #14", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #10", + "eor r7, r7, lr, lsr #15", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #11", + "eor r8, r8, lr, lsr #16", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #12", + "eor r12, r12, lr, lsr #17", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r12, [r2, #64]", + "eor r12, r4, r4", + "str r4, [r2, #68]", + "ldr r4, [r2, #60]", + "eor r12, r12, r4", + "str r12, [r2, #72]", + "eor r12, r8, lr", + "eor r12, r12, r4", + "and r4, r7, r12", + "str r12, [r2, #76]", + "eor r12, r4, r5", + "str lr, [r2, #80]", + "eor lr, r8, r4", + "str r8, [r2, #84]", + "and r8, r5, r7", + "str r4, [r2, #88]", + "eor r4, lr, r8", + "and r4, r6, r4", + "eor r12, r12, r4", + "ldr r4, [r2, #80]", + "str lr, [r2, #92]", + "eor lr, r8, r4", + "str r8, [r2, #96]", + "ldr r8, [r2, #60]", + "eor lr, lr, r8", + "str r12, [r2, #100]", + "eor r12, r7, r4", + "eor r12, r12, r8", + "and r8, r5, r12", + "str r12, [r2, #104]", + "eor r12, r7, r8", + "str r8, [r2, #108]", + "and r8, r6, r12", + "eor lr, lr, r8", + "str r12, [r2, #112]", + "ldr r12, [r2, #64]", + "and lr, r12, lr", + "str r8, [r2, #116]", + "ldr r8, [r2, #100]", + "eor r8, r8, lr", + "ldr lr, [r2, #76]", + "str r8, [r2, #100]", + "eor r8, lr, r7", + "and r12, r5, r8", + "str r5, [r2, #120]", + "ldr r5, [r2, #88]", + "str r8, [r2, #124]", + "eor r8, r5, r12", + "and r8, r6, r8", + "ldr r5, [r2, #84]", + "and r7, r7, r5", + "eor r5, lr, r7", + "ldr lr, [r2, #124]", + "str r7, [r2, #128]", + "eor r7, lr, r4", + "ldr r4, [r2, #60]", + "eor r7, r7, r4", + "eor r7, r7, r12", + "and r7, r6, r7", + "eor r7, r5, r7", + "str r5, [r2, #132]", + "ldr r5, [r2, #64]", + "and r7, r5, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #68]", + "and r8, r7, r8", + "str r12, [r2, #136]", + "ldr r12, [r2, #100]", + "eor r12, r12, r8", + "ldr r8, [r2, #120]", + "str r12, [r2, #100]", + "ldr r12, [r2, #88]", + "and r4, r8, r12", + "ldr r12, [r2, #128]", + "eor lr, r12, r4", + "ldr r12, [r2, #84]", + "and r12, r8, r12", + "ldr r7, [r2, #72]", + "eor r7, r7, r12", + "str r4, [r2, #72]", + "and r4, r6, r7", + "eor lr, lr, r4", + "ldr r4, [r2, #92]", + "str r7, [r2, #84]", + "ldr r7, [r2, #108]", + "eor r4, r4, r7", + "and r12, r6, r12", + "eor r4, r4, r12", + "and r4, r5, r4", + "eor lr, lr, r4", + "and r4, r6, r8", + "str r12, [r2, #92]", + "ldr r12, [r2, #84]", + "eor r12, r12, r4", + "ldr r4, [r2, #104]", + "ldr r7, [r2, #72]", + "eor r4, r4, r7", + "ldr r7, [r2, #76]", + "str lr, [r2, #104]", + "and lr, r8, r7", + "and r8, r6, lr", + "eor r4, r4, r8", + "and r4, r5, r4", + "eor r12, r12, r4", + "ldr r4, [r2, #68]", + "and r12, r4, r12", + "ldr r8, [r2, #104]", + "eor r8, r8, r12", + "ldr r12, [r2, #124]", + "str r8, [r2, #104]", + "ldr r8, [r2, #108]", + "eor r12, r12, r8", + "str lr, [r2, #124]", + "ldr lr, [r2, #96]", + "eor r7, r7, lr", + "and r7, r6, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #88]", + "ldr lr, [r2, #80]", + "eor r8, r7, lr", + "ldr r4, [r2, #60]", + "eor r8, r8, r4", + "ldr r7, [r2, #120]", + "ldr r4, [r2, #128]", + "and lr, r7, r4", + "eor lr, r8, lr", + "str r8, [r2, #96]", + "ldr r8, [r2, #136]", + "and r8, r6, r8", + "eor lr, lr, r8", + "and lr, r5, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #92]", + "ldr r8, [r2, #80]", + "eor lr, lr, r8", + "ldr r8, [r2, #60]", + "eor lr, lr, r8", + "ldr r8, [r2, #88]", + "str r12, [r2, #60]", + "ldr r12, [r2, #72]", + "eor r8, r8, r12", + "eor r4, r4, r7", + "and r4, r6, r4", + "eor r8, r8, r4", + "and r8, r5, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #68]", + "and lr, r8, lr", + "ldr r4, [r2, #60]", + "eor r4, r4, lr", + "ldr lr, [r2, #132]", + "eor r12, lr, r7", + "str r4, [r2, #60]", + "ldr r4, [r2, #116]", + "eor r12, r12, r4", + "ldr r4, [r2, #112]", + "and r8, r5, r4", + "eor r12, r12, r8", + "ldr r8, [r2, #96]", + "str r12, [r2, #116]", + "ldr r12, [r2, #108]", + "eor r12, r8, r12", + "and r12, r6, r12", + "eor r4, r4, r12", + "and r7, r7, r8", + "eor r8, r8, r7", + "ldr r7, [r2, #124]", + "eor lr, lr, r7", + "and r6, r6, lr", + "eor r8, r8, r6", + "and r5, r5, r8", + "eor r4, r4, r5", + "ldr r5, [r2, #68]", + "and r5, r5, r4", + "ldr r4, [r2, #116]", + "eor r7, r4, r5", + "ldr r4, [r2, #100]", + "ldr r5, [r2, #104]", + "ldr r6, [r2, #60]", + "and r4, r4, #1", + "ror r4, r4, #19", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #11", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #29", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #4", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #3", + "eor r4, r4, lr, lsr #6", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #4", + "eor r5, r5, lr, lsr #7", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #5", + "eor r6, r6, lr, lsr #8", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #6", + "eor r7, r7, lr, lsr #9", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #7", + "eor r8, r8, lr, lsr #10", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #8", + "eor r12, r12, lr, lsr #11", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r5, [r2, #64]", + "eor r5, r4, r4", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "str r7, [r2, #72]", + "eor r7, r12, r4", + "str r5, [r2, #76]", + "and r5, r4, r12", + "str r4, [r2, #80]", + "and r4, r6, r5", + "str r12, [r2, #84]", + "eor r12, r7, r4", + "str r4, [r2, #88]", + "eor r4, r5, lr", + "eor r4, r4, r8", + "str r7, [r2, #92]", + "and r7, r6, r4", + "str r5, [r2, #96]", + "ldr r5, [r2, #76]", + "str r4, [r2, #100]", + "eor r4, r5, r7", + "str r7, [r2, #104]", + "ldr r7, [r2, #72]", + "and r5, r7, r4", + "eor r12, r12, r5", + "ldr r5, [r2, #84]", + "str r4, [r2, #108]", + "eor r4, r5, lr", + "eor r4, r4, r8", + "ldr r5, [r2, #80]", + "and r8, r5, r4", + "str r4, [r2, #112]", + "and r4, r6, r8", + "str r8, [r2, #116]", + "ldr r8, [r2, #76]", + "str lr, [r2, #120]", + "eor lr, r8, r4", + "ldr r8, [r2, #100]", + "str r4, [r2, #124]", + "and r4, r7, r8", + "eor lr, lr, r4", + "str r4, [r2, #128]", + "ldr r4, [r2, #68]", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #104]", + "and r8, r7, lr", + "ldr lr, [r2, #108]", + "eor lr, lr, r8", + "and r8, r6, r5", + "ldr r5, [r2, #96]", + "eor r8, r5, r8", + "and r8, r4, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #64]", + "and lr, r8, lr", + "eor r12, r12, lr", + "eor lr, r5, r6", + "str r12, [r2, #108]", + "ldr r12, [r2, #92]", + "ldr r8, [r2, #120]", + "eor r4, r12, r8", + "ldr r12, [r2, #60]", + "eor r4, r4, r12", + "ldr r12, [r2, #124]", + "eor r8, r4, r12", + "and r8, r7, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #84]", + "str r4, [r2, #132]", + "and r4, r6, r8", + "str r6, [r2, #136]", + "ldr r6, [r2, #76]", + "str lr, [r2, #140]", + "eor lr, r6, r4", + "eor r5, r8, r5", + "eor r6, r5, r12", + "and r6, r7, r6", + "eor lr, lr, r6", + "ldr r12, [r2, #68]", + "and lr, r12, lr", + "str r4, [r2, #96]", + "ldr r4, [r2, #140]", + "eor r4, r4, lr", + "ldr lr, [r2, #112]", + "ldr r8, [r2, #116]", + "str r4, [r2, #140]", + "eor r4, lr, r8", + "ldr r8, [r2, #80]", + "ldr lr, [r2, #120]", + "eor r8, r8, lr", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "ldr lr, [r2, #136]", + "and r8, lr, r8", + "eor r8, r4, r8", + "eor r8, r8, r6", + "ldr r6, [r2, #132]", + "str r4, [r2, #80]", + "and r4, lr, r6", + "and r6, r7, r5", + "eor r4, r4, r6", + "and r4, r12, r4", + "eor r8, r8, r4", + "ldr r4, [r2, #64]", + "and r8, r4, r8", + "ldr r6, [r2, #140]", + "eor r6, r6, r8", + "ldr r8, [r2, #120]", + "eor r5, r5, r8", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "and r8, lr, r8", + "str r6, [r2, #112]", + "eor r6, r5, r8", + "str r5, [r2, #60]", + "ldr r5, [r2, #84]", + "str r8, [r2, #120]", + "and r8, r7, r5", + "eor r6, r6, r8", + "str r8, [r2, #140]", + "ldr r8, [r2, #132]", + "ldr r5, [r2, #104]", + "eor r8, r8, r5", + "ldr r5, [r2, #100]", + "ldr r4, [r2, #96]", + "eor r5, r5, r4", + "and r5, r7, r5", + "eor r8, r8, r5", + "and r8, r12, r8", + "eor r6, r6, r8", + "ldr r8, [r2, #92]", + "and r8, lr, r8", + "and r8, r7, r8", + "ldr r5, [r2, #76]", + "eor r5, r5, r8", + "ldr r8, [r2, #124]", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #64]", + "and r5, r8, r5", + "eor r6, r6, r5", + "ldr r5, [r2, #116]", + "eor r5, r5, r4", + "str r6, [r2, #116]", + "ldr r6, [r2, #128]", + "eor r5, r5, r6", + "ldr r6, [r2, #84]", + "ldr r8, [r2, #120]", + "eor r8, r6, r8", + "ldr r4, [r2, #80]", + "and lr, lr, r4", + "eor r4, r4, lr", + "and r4, r7, r4", + "eor r8, r8, r4", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #60]", + "ldr r4, [r2, #88]", + "eor r8, r8, r4", + "eor r6, r6, lr", + "and r7, r7, r6", + "eor r8, r8, r7", + "ldr r7, [r2, #96]", + "ldr r6, [r2, #140]", + "eor r7, r7, r6", + "and r12, r12, r7", + "eor r8, r8, r12", + "ldr r12, [r2, #64]", + "and r12, r12, r8", + "eor r7, r5, r12", + "ldr r4, [r2, #108]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #116]", + "and r4, r4, #1", + "ror r4, r4, #7", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #22", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #12", + "eor r10, r10, r6", + "and r7, r7, #1", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #31", + "eor r4, r4, lr", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "eor r5, r5, lr, lsr #1", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #1", + "eor r6, r6, lr, lsr #2", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #2", + "eor r7, r7, lr, lsr #3", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #3", + "eor r8, r8, lr, lsr #4", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #4", + "eor r12, r12, lr, lsr #5", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r6, r6, r8", + "str r6, [r2, #72]", + "eor r6, r4, lr", + "eor r6, r6, r8", + "str r4, [r2, #76]", + "eor r4, r12, r6", + "eor r7, r7, lr", + "eor r7, r7, r8", + "str r6, [r2, #80]", + "eor r6, r4, r7", + "eor r5, r5, lr", + "eor r5, r5, r8", + "eor r6, r6, r5", + "str r4, [r2, #84]", + "ldr r4, [r2, #76]", + "str r6, [r2, #88]", + "and r6, r7, r4", + "ldr r4, [r2, #80]", + "and r8, r4, r12", + "str r12, [r2, #92]", + "and r12, r7, r8", + "str r7, [r2, #96]", + "eor r7, r4, r12", + "and r7, r5, r7", + "eor r7, r6, r7", + "str r12, [r2, #100]", + "ldr r12, [r2, #68]", + "eor r12, r12, lr", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r12, r12, r8", + "and r7, r12, r7", + "str r12, [r2, #104]", + "ldr r12, [r2, #88]", + "eor r12, r12, r7", + "ldr r7, [r2, #92]", + "str r12, [r2, #88]", + "eor r12, r7, lr", + "eor r12, r12, r8", + "and r8, r4, r12", + "str lr, [r2, #108]", + "ldr lr, [r2, #72]", + "str r12, [r2, #112]", + "eor r12, lr, r8", + "str r8, [r2, #116]", + "eor r8, r12, r6", + "and r8, r5, r8", + "eor r4, r4, r8", + "ldr r8, [r2, #68]", + "str r12, [r2, #80]", + "eor r12, r7, r8", + "str r6, [r2, #120]", + "ldr r6, [r2, #96]", + "and r7, r6, r12", + "eor lr, lr, r7", + "ldr r6, [r2, #112]", + "str r12, [r2, #72]", + "and r12, r5, r6", + "eor lr, lr, r12", + "str r12, [r2, #124]", + "ldr r12, [r2, #104]", + "and lr, r12, lr", + "eor r4, r4, lr", + "ldr lr, [r2, #64]", + "ldr r12, [r2, #108]", + "eor lr, lr, r12", + "str r5, [r2, #64]", + "ldr r5, [r2, #60]", + "eor lr, lr, r5", + "and r4, lr, r4", + "str lr, [r2, #128]", + "ldr lr, [r2, #88]", + "eor r4, lr, r4", + "eor lr, r8, r12", + "eor lr, lr, r5", + "str r4, [r2, #88]", + "eor r4, lr, r7", + "str r7, [r2, #132]", + "ldr r7, [r2, #72]", + "eor r7, r7, r12", + "eor r7, r7, r5", + "ldr r8, [r2, #96]", + "str lr, [r2, #72]", + "and lr, r8, r7", + "eor r6, r6, lr", + "str r7, [r2, #112]", + "ldr r7, [r2, #64]", + "and r6, r7, r6", + "eor r4, r4, r6", + "ldr r6, [r2, #100]", + "str lr, [r2, #136]", + "eor lr, r6, r12", + "eor lr, lr, r5", + "and r8, r7, r6", + "eor r8, lr, r8", + "str lr, [r2, #140]", + "ldr lr, [r2, #104]", + "and r8, lr, r8", + "eor r4, r4, r8", + "ldr r8, [r2, #92]", + "ldr r6, [r2, #116]", + "str r4, [r2, #144]", + "eor r4, r8, r6", + "ldr r8, [r2, #120]", + "eor r8, r4, r8", + "ldr r6, [r2, #84]", + "and r6, r7, r6", + "eor lr, r8, r6", + "eor r8, r8, r12", + "eor r8, r8, r5", + "eor r4, r4, r12", + "eor r4, r4, r5", + "and r4, r7, r4", + "eor r8, r8, r4", + "ldr r4, [r2, #104]", + "and r8, r4, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #128]", + "and lr, r8, lr", + "ldr r5, [r2, #144]", + "eor r5, r5, lr", + "ldr lr, [r2, #116]", + "str r5, [r2, #144]", + "ldr r5, [r2, #100]", + "eor r12, lr, r5", + "str r6, [r2, #84]", + "ldr r6, [r2, #96]", + "ldr lr, [r2, #72]", + "and r8, r6, lr", + "ldr r6, [r2, #92]", + "eor r6, r6, r8", + "and r8, r7, r6", + "eor r12, r12, r8", + "ldr r8, [r2, #136]", + "eor r8, lr, r8", + "and r8, r4, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #124]", + "eor lr, lr, r8", + "str r6, [r2, #72]", + "ldr r6, [r2, #68]", + "eor r5, r6, r5", + "eor r5, r5, r8", + "and r5, r4, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #128]", + "and lr, r5, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #140]", + "and lr, r7, lr", + "ldr r8, [r2, #72]", + "eor r8, r8, lr", + "ldr lr, [r2, #96]", + "str r12, [r2, #72]", + "ldr r12, [r2, #116]", + "and lr, lr, r12", + "eor r6, r6, lr", + "ldr lr, [r2, #76]", + "ldr r12, [r2, #132]", + "eor lr, lr, r12", + "and lr, r7, lr", + "eor lr, r6, lr", + "and lr, r4, lr", + "eor r8, r8, lr", + "ldr lr, [r2, #80]", + "ldr r12, [r2, #84]", + "eor lr, lr, r12", + "ldr r12, [r2, #108]", + "eor r6, r6, r12", + "ldr r12, [r2, #60]", + "eor r6, r6, r12", + "ldr r12, [r2, #112]", + "and r7, r7, r12", + "eor r6, r6, r7", + "and r4, r4, r6", + "eor lr, lr, r4", + "and r5, r5, lr", + "eor r7, r8, r5", + "ldr r4, [r2, #88]", + "ldr r5, [r2, #144]", + "ldr r6, [r2, #72]", + "and r4, r4, #1", + "ror r4, r4, #21", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #15", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #27", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #5", + "eor r10, r10, r7", + "mov lr, r10", + "mov r10, r11", + "mov r11, lr", + "sub r0, r0, #8", + "subs r9, r9, #1", + "bne 21b", + "mov lr, r10", + "mov r10, r11", + "mov r11, lr", + "add r0, r0, #136", + "mov r9, #16", + "22:", + "ldr lr, [r0, #4]", + "mov r4, r11", + "lsr r4, r4, #27", + "eor r4, r4, lr, lsr #10", + "and r4, r4, #1", + "ldr lr, [r0, #4]", + "mov r5, r11", + "lsr r5, r5, #28", + "eor r5, r5, lr, lsr #11", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #29", + "eor r6, r6, lr, lsr #12", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #30", + "eor r7, r7, lr, lsr #13", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #31", + "eor r8, r8, lr, lsr #14", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "eor r12, r12, lr, lsr #15", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, lr", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "and r7, r8, r6", + "str lr, [r2, #72]", + "eor lr, r4, r8", + "str r8, [r2, #76]", + "and r8, r5, lr", + "eor r8, r7, r8", + "str lr, [r2, #80]", + "eor lr, r6, r7", + "str r7, [r2, #84]", + "and r7, r5, lr", + "eor r7, r4, r7", + "and r7, r12, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #76]", + "str lr, [r2, #88]", + "and lr, r7, r4", + "str r4, [r2, #92]", + "ldr r4, [r2, #72]", + "str r6, [r2, #96]", + "eor r6, lr, r4", + "str r8, [r2, #100]", + "ldr r8, [r2, #60]", + "eor r6, r6, r8", + "str r12, [r2, #104]", + "and r12, r5, r6", + "str r6, [r2, #108]", + "eor r6, lr, r12", + "str lr, [r2, #112]", + "eor lr, r7, r4", + "eor lr, lr, r8", + "eor r8, lr, r12", + "str r12, [r2, #116]", + "ldr r12, [r2, #104]", + "and r4, r12, r8", + "eor r6, r6, r4", + "ldr r4, [r2, #68]", + "and r6, r4, r6", + "str r8, [r2, #120]", + "ldr r8, [r2, #100]", + "eor r8, r8, r6", + "and r7, r5, r7", + "ldr r6, [r2, #108]", + "str r8, [r2, #76]", + "eor r8, r6, r7", + "str r7, [r2, #100]", + "and r7, r5, lr", + "str lr, [r2, #124]", + "ldr lr, [r2, #96]", + "eor r6, lr, r7", + "and r6, r12, r6", + "eor r8, r8, r6", + "and r6, r5, lr", + "str r5, [r2, #128]", + "ldr r5, [r2, #88]", + "str r7, [r2, #132]", + "eor r7, r5, r6", + "and r7, r12, r7", + "and r7, r4, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r8, r7, r8", + "str r6, [r2, #136]", + "ldr r6, [r2, #76]", + "eor r6, r6, r8", + "ldr r8, [r2, #112]", + "eor lr, lr, r8", + "ldr r8, [r2, #132]", + "str r6, [r2, #112]", + "eor r6, lr, r8", + "ldr r7, [r2, #84]", + "ldr r4, [r2, #72]", + "eor r8, r7, r4", + "ldr r7, [r2, #60]", + "eor r8, r8, r7", + "ldr r7, [r2, #128]", + "and lr, r7, lr", + "eor lr, r8, lr", + "str r8, [r2, #96]", + "and r8, r12, lr", + "eor r6, r6, r8", + "eor r8, r5, r4", + "ldr r4, [r2, #60]", + "eor r8, r8, r4", + "ldr r4, [r2, #132]", + "eor r4, r8, r4", + "str r8, [r2, #132]", + "ldr r8, [r2, #84]", + "and r5, r7, r8", + "eor r8, r8, r5", + "and r8, r12, r8", + "eor r5, r4, r8", + "str r4, [r2, #84]", + "ldr r4, [r2, #68]", + "and r5, r4, r5", + "eor r6, r6, r5", + "eor lr, lr, r8", + "ldr r8, [r2, #92]", + "and r5, r7, r8", + "ldr r8, [r2, #96]", + "eor r7, r8, r5", + "and r7, r12, r7", + "ldr r8, [r2, #88]", + "eor r12, r8, r7", + "and r12, r4, r12", + "eor lr, lr, r12", + "ldr r12, [r2, #64]", + "and lr, r12, lr", + "eor r6, r6, lr", + "eor lr, r8, r5", + "str r6, [r2, #76]", + "ldr r6, [r2, #104]", + "ldr r8, [r2, #84]", + "and r12, r6, r8", + "eor lr, lr, r12", + "ldr r12, [r2, #108]", + "str r7, [r2, #140]", + "ldr r7, [r2, #136]", + "eor r12, r12, r7", + "ldr r7, [r2, #128]", + "str r5, [r2, #136]", + "ldr r5, [r2, #132]", + "and r5, r7, r5", + "ldr r7, [r2, #96]", + "eor r7, r7, r5", + "and r7, r6, r7", + "eor r12, r12, r7", + "and r12, r4, r12", + "eor lr, lr, r12", + "ldr r12, [r2, #116]", + "and r7, r6, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #92]", + "ldr r5, [r2, #136]", + "eor r7, r7, r5", + "ldr r5, [r2, #140]", + "eor r7, r7, r5", + "and r7, r4, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r8, r7, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #80]", + "ldr r5, [r2, #72]", + "eor r8, r8, r5", + "str lr, [r2, #80]", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "ldr r7, [r2, #128]", + "eor r8, r8, r7", + "eor r12, r12, r5", + "eor r12, r12, lr", + "and r12, r6, r12", + "eor r12, r8, r12", + "str r8, [r2, #116]", + "ldr r8, [r2, #120]", + "eor r8, r8, r5", + "eor r8, r8, lr", + "and r8, r6, r8", + "ldr lr, [r2, #124]", + "eor lr, lr, r8", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #88]", + "ldr r8, [r2, #100]", + "eor r8, lr, r8", + "and r8, r6, r8", + "ldr r5, [r2, #136]", + "eor r5, r5, r8", + "eor lr, lr, r7", + "and r6, r6, lr", + "ldr lr, [r2, #116]", + "eor lr, lr, r6", + "and r4, r4, lr", + "eor r5, r5, r4", + "ldr r4, [r2, #64]", + "and r4, r4, r5", + "eor r7, r12, r4", + "ldr r4, [r2, #112]", + "ldr r5, [r2, #76]", + "ldr r6, [r2, #80]", + "and r4, r4, #1", + "ror r4, r4, #31", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #23", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #17", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #9", + "eor r10, r10, r7", + "ldr lr, [r0, #4]", + "mov r4, r11", + "lsr r4, r4, #23", + "eor r4, r4, lr, lsr #4", + "and r4, r4, #1", + "ldr lr, [r0, #4]", + "mov r5, r11", + "lsr r5, r5, #24", + "eor r5, r5, lr, lsr #5", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #25", + "eor r6, r6, lr, lsr #6", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #26", + "eor r7, r7, lr, lsr #7", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #27", + "eor r8, r8, lr, lsr #8", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "lsr r12, r12, #28", + "eor r12, r12, lr, lsr #9", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "str r6, [r2, #72]", + "eor r6, r12, lr", + "eor r6, r6, r7", + "str r8, [r2, #76]", + "and r8, r5, r12", + "str r5, [r2, #80]", + "eor r5, r12, r8", + "str r12, [r2, #84]", + "and r12, r4, r5", + "eor r12, r6, r12", + "str r6, [r2, #88]", + "eor r6, r8, lr", + "eor r6, r6, r7", + "str r8, [r2, #92]", + "and r8, r4, r6", + "str r6, [r2, #96]", + "eor r6, r5, r8", + "str r8, [r2, #100]", + "ldr r8, [r2, #76]", + "and r6, r8, r6", + "eor r12, r12, r6", + "str r6, [r2, #104]", + "ldr r6, [r2, #80]", + "str r12, [r2, #108]", + "ldr r12, [r2, #88]", + "and r8, r6, r12", + "eor r6, r12, r8", + "eor r5, r5, lr", + "eor r5, r5, r7", + "and r12, r4, r5", + "str r5, [r2, #112]", + "eor r5, r6, r12", + "str r12, [r2, #116]", + "eor r12, r6, lr", + "eor r12, r12, r7", + "str r6, [r2, #120]", + "and r6, r4, r12", + "str r12, [r2, #124]", + "ldr r12, [r2, #80]", + "eor r6, r12, r6", + "ldr r7, [r2, #76]", + "and r6, r7, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #68]", + "and r5, r6, r5", + "ldr r6, [r2, #108]", + "eor r6, r6, r5", + "and r5, r4, r8", + "str r8, [r2, #108]", + "ldr r8, [r2, #72]", + "eor r5, r8, r5", + "ldr r8, [r2, #84]", + "str lr, [r2, #128]", + "eor lr, r8, r12", + "and r8, r4, lr", + "str r4, [r2, #132]", + "eor r4, r12, r8", + "and r4, r7, r4", + "eor r5, r5, r4", + "ldr r4, [r2, #64]", + "and r5, r4, r5", + "eor r6, r6, r5", + "ldr r5, [r2, #128]", + "eor lr, lr, r5", + "str r6, [r2, #136]", + "ldr r6, [r2, #60]", + "eor lr, lr, r6", + "ldr r6, [r2, #132]", + "ldr r5, [r2, #92]", + "and r5, r6, r5", + "eor r12, lr, r5", + "str r5, [r2, #92]", + "ldr r5, [r2, #112]", + "eor r5, r5, r8", + "and r5, r7, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #124]", + "ldr r8, [r2, #104]", + "eor r5, r5, r8", + "ldr r8, [r2, #68]", + "and r5, r8, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #120]", + "str lr, [r2, #104]", + "and lr, r6, r5", + "str r12, [r2, #124]", + "ldr r12, [r2, #84]", + "eor lr, r12, lr", + "and lr, r7, lr", + "ldr r4, [r2, #96]", + "eor lr, r4, lr", + "ldr r4, [r2, #88]", + "str lr, [r2, #112]", + "and lr, r6, r4", + "eor r5, r5, lr", + "and r12, r7, r12", + "eor r5, r5, r12", + "and r5, r8, r5", + "ldr r12, [r2, #112]", + "eor r12, r12, r5", + "ldr r5, [r2, #64]", + "and r12, r5, r12", + "str lr, [r2, #112]", + "ldr lr, [r2, #124]", + "eor lr, lr, r12", + "ldr r12, [r2, #104]", + "str lr, [r2, #124]", + "eor lr, r12, r6", + "eor lr, lr, r7", + "ldr r4, [r2, #96]", + "ldr r12, [r2, #92]", + "eor r5, r4, r12", + "and r5, r7, r5", + "eor r5, r6, r5", + "and r5, r8, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #80]", + "and r6, r6, r5", + "ldr r5, [r2, #72]", + "eor r5, r5, r6", + "ldr r12, [r2, #100]", + "eor r4, r4, r12", + "and r4, r7, r4", + "eor r5, r5, r4", + "and r6, r8, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #64]", + "and r5, r6, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #104]", + "eor r5, r5, r12", + "ldr r12, [r2, #116]", + "and r12, r7, r12", + "eor r5, r5, r12", + "ldr r12, [r2, #92]", + "ldr r4, [r2, #128]", + "str lr, [r2, #116]", + "eor lr, r12, r4", + "ldr r6, [r2, #60]", + "eor lr, lr, r6", + "ldr r6, [r2, #88]", + "ldr r4, [r2, #112]", + "eor r6, r6, r4", + "and r6, r7, r6", + "eor lr, lr, r6", + "and r8, r8, lr", + "eor r5, r5, r8", + "ldr r8, [r2, #108]", + "eor r8, r8, r12", + "ldr r12, [r2, #128]", + "eor r12, r8, r12", + "ldr lr, [r2, #60]", + "eor r12, r12, lr", + "and r7, r7, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r7, r7, r8", + "eor r7, r5, r7", + "ldr r4, [r2, #136]", + "ldr r5, [r2, #124]", + "ldr r6, [r2, #116]", + "and r4, r4, #1", + "ror r4, r4, #18", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #2", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #28", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #13", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #19", + "eor r4, r4, lr, lsr #30", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #20", + "eor r5, r5, lr, lsr #31", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #21", + "eor r6, r6, lr", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #22", + "eor r7, r7, lr, lsr #1", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #23", + "eor r8, r8, lr, lsr #2", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "lsr r12, r12, #24", + "eor r12, r12, lr, lsr #3", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "str r6, [r2, #72]", + "eor r6, r12, lr", + "eor r6, r6, r7", + "str r5, [r2, #76]", + "and r5, r8, r6", + "eor r7, r12, r5", + "str r5, [r2, #80]", + "and r5, r8, r12", + "str r8, [r2, #84]", + "eor r8, r6, r5", + "str r6, [r2, #88]", + "and r6, r4, r8", + "str r12, [r2, #92]", + "eor r12, r7, r6", + "str r7, [r2, #96]", + "eor r7, r8, lr", + "str lr, [r2, #100]", + "ldr lr, [r2, #60]", + "eor r7, r7, lr", + "and r5, r4, r5", + "eor lr, r7, r5", + "str r7, [r2, #104]", + "ldr r7, [r2, #76]", + "str r6, [r2, #108]", + "and r6, r7, lr", + "eor r6, r12, r6", + "str r12, [r2, #112]", + "and r12, r7, r8", + "eor lr, lr, r12", + "ldr r12, [r2, #68]", + "and lr, r12, lr", + "eor r6, r6, lr", + "ldr lr, [r2, #92]", + "and lr, r4, lr", + "str r8, [r2, #92]", + "ldr r8, [r2, #72]", + "eor r8, r8, lr", + "str lr, [r2, #72]", + "ldr lr, [r2, #88]", + "str r4, [r2, #116]", + "and r4, r7, lr", + "eor r8, r8, r4", + "and r5, r12, r5", + "eor r8, r8, r5", + "ldr r5, [r2, #64]", + "and r8, r5, r8", + "eor r4, r6, r8", + "ldr r8, [r2, #84]", + "eor r6, lr, r8", + "str r4, [r2, #120]", + "ldr r4, [r2, #108]", + "eor r4, r6, r4", + "str r6, [r2, #108]", + "ldr r6, [r2, #80]", + "ldr r5, [r2, #100]", + "eor r12, r6, r5", + "ldr lr, [r2, #60]", + "eor r12, r12, lr", + "ldr lr, [r2, #116]", + "and r5, lr, r6", + "eor r5, r12, r5", + "and r6, r7, r5", + "str r5, [r2, #124]", + "eor r5, r4, r6", + "str r6, [r2, #128]", + "ldr r6, [r2, #100]", + "str r12, [r2, #132]", + "eor r12, r8, r6", + "str r4, [r2, #136]", + "ldr r4, [r2, #60]", + "eor r12, r12, r4", + "and r4, lr, r12", + "eor r8, r8, r4", + "str r12, [r2, #84]", + "ldr r12, [r2, #88]", + "str r4, [r2, #140]", + "and r4, lr, r12", + "eor r12, r12, r4", + "and r12, r7, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #68]", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "eor r8, r8, r6", + "str r5, [r2, #112]", + "ldr r5, [r2, #60]", + "eor r8, r8, r5", + "ldr r12, [r2, #136]", + "eor r12, r12, r6", + "eor r12, r12, r5", + "and r12, r7, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #96]", + "str r8, [r2, #136]", + "eor r8, r12, r6", + "eor r8, r8, r5", + "and r12, lr, r8", + "str r8, [r2, #88]", + "ldr r8, [r2, #132]", + "eor lr, r8, r12", + "str r12, [r2, #144]", + "eor r12, r4, r6", + "eor r12, r12, r5", + "and r12, r7, r12", + "eor lr, lr, r12", + "str r4, [r2, #148]", + "ldr r4, [r2, #68]", + "and lr, r4, lr", + "str r12, [r2, #152]", + "ldr r12, [r2, #136]", + "eor r12, r12, lr", + "ldr lr, [r2, #64]", + "and r12, lr, r12", + "ldr lr, [r2, #112]", + "eor lr, lr, r12", + "ldr r12, [r2, #116]", + "str lr, [r2, #112]", + "and lr, r12, r8", + "ldr r12, [r2, #104]", + "eor r12, r12, lr", + "ldr lr, [r2, #124]", + "eor r8, lr, r6", + "eor r8, r8, r5", + "and r8, r7, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #128]", + "eor lr, lr, r8", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #80]", + "ldr r8, [r2, #140]", + "eor r8, lr, r8", + "ldr r5, [r2, #152]", + "eor r8, r8, r5", + "ldr r5, [r2, #72]", + "and r6, r7, r5", + "eor lr, lr, r6", + "and lr, r4, lr", + "eor r8, r8, lr", + "ldr lr, [r2, #64]", + "and r8, lr, r8", + "eor r6, r12, r8", + "ldr r8, [r2, #132]", + "eor r8, r8, r5", + "eor r8, r8, r7", + "ldr r5, [r2, #108]", + "ldr r12, [r2, #100]", + "eor r5, r5, r12", + "ldr r12, [r2, #60]", + "eor r5, r5, r12", + "ldr r12, [r2, #116]", + "and r12, r12, r5", + "ldr r5, [r2, #84]", + "eor r5, r5, r12", + "and r5, r7, r5", + "ldr r12, [r2, #92]", + "eor r12, r12, r5", + "and r12, r4, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #96]", + "ldr r5, [r2, #148]", + "eor r12, r12, r5", + "str r6, [r2, #96]", + "ldr r6, [r2, #88]", + "str r8, [r2, #92]", + "ldr r8, [r2, #144]", + "eor r8, r6, r8", + "and r8, r7, r8", + "eor r12, r12, r8", + "and r7, r7, r5", + "eor r6, r6, r7", + "and r4, r4, r6", + "eor r12, r12, r4", + "and lr, lr, r12", + "ldr r12, [r2, #92]", + "eor r7, r12, lr", + "ldr r4, [r2, #120]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #96]", + "and r4, r4, #1", + "ror r4, r4, #6", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #30", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #16", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #24", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #15", + "eor r4, r4, lr, lsr #24", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #16", + "eor r5, r5, lr, lsr #25", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #17", + "eor r6, r6, lr, lsr #26", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #18", + "eor r7, r7, lr, lsr #27", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #19", + "eor r8, r8, lr, lsr #28", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #20", + "eor r12, r12, lr, lsr #29", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r4, [r2, #68]", + "ldr r4, [r2, #60]", + "eor r6, r6, r4", + "str r6, [r2, #72]", + "eor r6, r7, lr", + "eor r6, r6, r4", + "str r8, [r2, #76]", + "and r8, r5, r7", + "eor r4, r6, r8", + "str r8, [r2, #80]", + "and r8, r12, r4", + "str r4, [r2, #84]", + "eor r4, r6, r8", + "str r8, [r2, #88]", + "eor r8, r7, r5", + "str r7, [r2, #92]", + "eor r7, r8, lr", + "str r6, [r2, #96]", + "ldr r6, [r2, #60]", + "eor r7, r7, r6", + "and r6, r12, r7", + "str r7, [r2, #100]", + "eor r7, r8, r6", + "str r8, [r2, #104]", + "ldr r8, [r2, #76]", + "and r7, r8, r7", + "eor r4, r4, r7", + "eor r7, r5, lr", + "str r12, [r2, #108]", + "ldr r12, [r2, #60]", + "eor r7, r7, r12", + "eor r12, r5, r6", + "str r6, [r2, #112]", + "and r6, r8, r12", + "str r5, [r2, #116]", + "eor r5, r7, r6", + "str r6, [r2, #120]", + "ldr r6, [r2, #64]", + "and r5, r6, r5", + "eor r4, r4, r5", + "ldr r5, [r2, #84]", + "str r7, [r2, #124]", + "eor r7, r5, lr", + "ldr r5, [r2, #60]", + "eor r7, r7, r5", + "str r4, [r2, #128]", + "ldr r4, [r2, #108]", + "and r7, r4, r7", + "ldr r6, [r2, #100]", + "eor r7, r6, r7", + "and r7, r8, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #80]", + "eor r7, r7, lr", + "eor r7, r7, r5", + "ldr r5, [r2, #116]", + "str lr, [r2, #80]", + "ldr lr, [r2, #96]", + "and r6, r5, lr", + "ldr r5, [r2, #72]", + "eor r5, r5, r6", + "and lr, r4, r5", + "eor r7, r7, lr", + "str r5, [r2, #72]", + "ldr r5, [r2, #104]", + "and r5, r8, r5", + "eor r7, r7, r5", + "str r5, [r2, #104]", + "ldr r5, [r2, #64]", + "and r7, r5, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #68]", + "and r5, r7, r12", + "ldr r7, [r2, #128]", + "eor r7, r7, r5", + "and r5, r4, r6", + "str r7, [r2, #128]", + "ldr r7, [r2, #100]", + "eor r7, r7, r5", + "ldr r4, [r2, #80]", + "str r5, [r2, #100]", + "eor r5, lr, r4", + "ldr r4, [r2, #60]", + "eor r5, r5, r4", + "and r5, r8, r5", + "eor r5, r7, r5", + "str r7, [r2, #132]", + "eor r7, r6, lr", + "str r6, [r2, #136]", + "ldr r6, [r2, #92]", + "str lr, [r2, #140]", + "ldr lr, [r2, #112]", + "eor lr, r6, lr", + "and lr, r8, lr", + "eor r7, r7, lr", + "ldr r6, [r2, #64]", + "and r7, r6, r7", + "eor r5, r5, r7", + "ldr r7, [r2, #80]", + "eor r12, r12, r7", + "eor r12, r12, r4", + "ldr r4, [r2, #68]", + "and r12, r4, r12", + "eor r5, r5, r12", + "ldr r12, [r2, #84]", + "str r5, [r2, #112]", + "ldr r5, [r2, #140]", + "eor r12, r12, r5", + "ldr r5, [r2, #96]", + "and r5, r8, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #116]", + "eor r5, r5, lr", + "and r5, r6, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #132]", + "eor r5, r5, r7", + "ldr lr, [r2, #60]", + "eor r5, r5, lr", + "ldr lr, [r2, #72]", + "ldr r7, [r2, #100]", + "eor lr, lr, r7", + "and lr, r8, lr", + "eor r5, r5, lr", + "ldr lr, [r2, #124]", + "ldr r8, [r2, #88]", + "eor lr, lr, r8", + "ldr r8, [r2, #104]", + "eor lr, lr, r8", + "and lr, r6, lr", + "eor r5, r5, lr", + "and lr, r4, r5", + "eor r12, r12, lr", + "ldr lr, [r2, #136]", + "ldr r8, [r2, #108]", + "eor r8, lr, r8", + "str r12, [r2, #108]", + "ldr r12, [r2, #92]", + "eor r12, r12, lr", + "eor r12, r12, r7", + "ldr r7, [r2, #76]", + "and r7, r7, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #88]", + "ldr r12, [r2, #80]", + "eor r7, r7, r12", + "ldr lr, [r2, #60]", + "eor r7, r7, lr", + "ldr r4, [r2, #120]", + "eor r7, r7, r4", + "and r6, r6, r7", + "eor r8, r8, r6", + "eor r5, r5, r12", + "eor r5, r5, lr", + "ldr lr, [r2, #68]", + "and lr, lr, r5", + "eor r7, r8, lr", + "ldr r4, [r2, #128]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #108]", + "and r4, r4, #1", + "ror r4, r4, #1", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #10", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #20", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #26", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #11", + "eor r4, r4, lr, lsr #18", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #12", + "eor r5, r5, lr, lsr #19", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #13", + "eor r6, r6, lr, lsr #20", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #14", + "eor r7, r7, lr, lsr #21", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #15", + "eor r8, r8, lr, lsr #22", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #16", + "eor r12, r12, lr, lsr #23", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r5, [r2, #64]", + "eor r5, r4, r4", + "str r6, [r2, #68]", + "ldr r6, [r2, #60]", + "eor r5, r5, r6", + "str r8, [r2, #72]", + "eor r8, r7, lr", + "eor r8, r8, r6", + "str r7, [r2, #76]", + "and r7, r8, r12", + "str r8, [r2, #80]", + "eor r8, r5, r7", + "eor r4, r4, lr", + "eor r4, r4, r6", + "str r5, [r2, #84]", + "and r5, r4, r8", + "str r8, [r2, #88]", + "eor r8, r12, r5", + "str r5, [r2, #92]", + "eor r5, r12, lr", + "eor r5, r5, r6", + "str r12, [r2, #96]", + "ldr r12, [r2, #80]", + "str r4, [r2, #100]", + "and r4, r12, r5", + "eor r12, r5, r4", + "str r4, [r2, #104]", + "ldr r4, [r2, #72]", + "eor r4, r4, lr", + "eor r4, r4, r6", + "and r6, r4, r12", + "eor r6, r8, r6", + "str r8, [r2, #72]", + "eor r8, r5, r7", + "str r12, [r2, #108]", + "and r12, r4, r8", + "str r8, [r2, #112]", + "ldr r8, [r2, #76]", + "eor r12, r8, r12", + "ldr r8, [r2, #68]", + "eor r8, r8, lr", + "str lr, [r2, #68]", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "and r12, r8, r12", + "eor r6, r6, r12", + "ldr r12, [r2, #100]", + "str r6, [r2, #116]", + "and r6, r12, r5", + "str r8, [r2, #120]", + "ldr r8, [r2, #80]", + "eor r6, r8, r6", + "str r5, [r2, #124]", + "ldr r5, [r2, #96]", + "eor lr, r5, r8", + "and r7, r12, r7", + "eor r7, lr, r7", + "and r7, r4, r7", + "eor r6, r6, r7", + "ldr r7, [r2, #108]", + "ldr r8, [r2, #68]", + "str lr, [r2, #128]", + "eor lr, r7, r8", + "ldr r5, [r2, #60]", + "eor lr, lr, r5", + "and lr, r12, lr", + "ldr r7, [r2, #124]", + "eor r5, r7, r12", + "and r5, r4, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #120]", + "and lr, r5, lr", + "eor r6, r6, lr", + "ldr lr, [r2, #64]", + "eor lr, lr, r8", + "ldr r7, [r2, #60]", + "eor lr, lr, r7", + "and r6, lr, r6", + "str lr, [r2, #64]", + "ldr lr, [r2, #116]", + "eor lr, lr, r6", + "ldr r6, [r2, #108]", + "str lr, [r2, #116]", + "and lr, r12, r6", + "ldr r6, [r2, #88]", + "eor r5, r6, lr", + "eor r5, r5, r4", + "ldr r6, [r2, #104]", + "str lr, [r2, #132]", + "eor lr, r6, r8", + "eor lr, lr, r7", + "and r7, r12, lr", + "ldr r8, [r2, #84]", + "eor r8, r8, r7", + "and r6, r12, r6", + "str lr, [r2, #104]", + "and lr, r4, r6", + "eor r8, r8, lr", + "ldr lr, [r2, #120]", + "and r8, lr, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "eor r6, r8, r6", + "and r6, r4, r6", + "ldr r8, [r2, #76]", + "eor r6, r8, r6", + "ldr r8, [r2, #96]", + "and r8, r12, r8", + "ldr r12, [r2, #124]", + "eor r12, r12, r8", + "str r8, [r2, #124]", + "and r8, r4, r12", + "eor r8, r7, r8", + "and r8, lr, r8", + "eor r6, r6, r8", + "ldr r8, [r2, #64]", + "and r6, r8, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #108]", + "str r5, [r2, #96]", + "ldr r5, [r2, #100]", + "str r12, [r2, #84]", + "eor r12, r6, r5", + "eor r12, r12, r4", + "ldr r8, [r2, #104]", + "ldr r6, [r2, #132]", + "eor r8, r8, r6", + "ldr r6, [r2, #128]", + "eor r5, r6, r7", + "and r5, r4, r5", + "eor r8, r8, r5", + "and r8, lr, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #68]", + "eor r5, r6, r8", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "ldr r8, [r2, #100]", + "and r6, r8, r5", + "str r5, [r2, #132]", + "ldr r5, [r2, #108]", + "eor r5, r5, r6", + "and r5, lr, r5", + "str r6, [r2, #108]", + "ldr r6, [r2, #88]", + "eor r6, r6, r5", + "ldr r5, [r2, #64]", + "and r6, r5, r6", + "eor r6, r12, r6", + "ldr r12, [r2, #80]", + "eor r12, r12, r7", + "ldr r7, [r2, #72]", + "and r7, r4, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #112]", + "str r6, [r2, #72]", + "eor r6, r7, r8", + "and r6, r4, r6", + "ldr r5, [r2, #84]", + "eor r5, r5, r6", + "and r5, lr, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #132]", + "ldr r6, [r2, #92]", + "eor r5, r5, r6", + "ldr r6, [r2, #76]", + "and r8, r8, r6", + "ldr r6, [r2, #128]", + "eor r6, r6, r8", + "and r6, r4, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #68]", + "eor r7, r7, r6", + "ldr r8, [r2, #60]", + "eor r7, r7, r8", + "str r12, [r2, #112]", + "ldr r12, [r2, #108]", + "eor r7, r7, r12", + "ldr r12, [r2, #124]", + "eor r12, r12, r6", + "eor r12, r12, r8", + "and r4, r4, r12", + "eor r7, r7, r4", + "and lr, lr, r7", + "eor r5, r5, lr", + "ldr lr, [r2, #64]", + "and lr, lr, r5", + "ldr r5, [r2, #112]", + "eor r7, r5, lr", + "ldr r4, [r2, #116]", + "ldr r5, [r2, #96]", + "ldr r6, [r2, #72]", + "and r4, r4, #1", + "ror r4, r4, #3", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #25", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #14", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #8", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #7", + "eor r4, r4, lr, lsr #12", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #8", + "eor r5, r5, lr, lsr #13", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #9", + "eor r6, r6, lr, lsr #14", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #10", + "eor r7, r7, lr, lsr #15", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #11", + "eor r8, r8, lr, lsr #16", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #12", + "eor r12, r12, lr, lsr #17", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r12, [r2, #64]", + "eor r12, r4, r4", + "str r4, [r2, #68]", + "ldr r4, [r2, #60]", + "eor r12, r12, r4", + "str r12, [r2, #72]", + "eor r12, r8, lr", + "eor r12, r12, r4", + "and r4, r7, r12", + "str r12, [r2, #76]", + "eor r12, r4, r5", + "str lr, [r2, #80]", + "eor lr, r8, r4", + "str r8, [r2, #84]", + "and r8, r5, r7", + "str r4, [r2, #88]", + "eor r4, lr, r8", + "and r4, r6, r4", + "eor r12, r12, r4", + "ldr r4, [r2, #80]", + "str lr, [r2, #92]", + "eor lr, r8, r4", + "str r8, [r2, #96]", + "ldr r8, [r2, #60]", + "eor lr, lr, r8", + "str r12, [r2, #100]", + "eor r12, r7, r4", + "eor r12, r12, r8", + "and r8, r5, r12", + "str r12, [r2, #104]", + "eor r12, r7, r8", + "str r8, [r2, #108]", + "and r8, r6, r12", + "eor lr, lr, r8", + "str r12, [r2, #112]", + "ldr r12, [r2, #64]", + "and lr, r12, lr", + "str r8, [r2, #116]", + "ldr r8, [r2, #100]", + "eor r8, r8, lr", + "ldr lr, [r2, #76]", + "str r8, [r2, #100]", + "eor r8, lr, r7", + "and r12, r5, r8", + "str r5, [r2, #120]", + "ldr r5, [r2, #88]", + "str r8, [r2, #124]", + "eor r8, r5, r12", + "and r8, r6, r8", + "ldr r5, [r2, #84]", + "and r7, r7, r5", + "eor r5, lr, r7", + "ldr lr, [r2, #124]", + "str r7, [r2, #128]", + "eor r7, lr, r4", + "ldr r4, [r2, #60]", + "eor r7, r7, r4", + "eor r7, r7, r12", + "and r7, r6, r7", + "eor r7, r5, r7", + "str r5, [r2, #132]", + "ldr r5, [r2, #64]", + "and r7, r5, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #68]", + "and r8, r7, r8", + "str r12, [r2, #136]", + "ldr r12, [r2, #100]", + "eor r12, r12, r8", + "ldr r8, [r2, #120]", + "str r12, [r2, #100]", + "ldr r12, [r2, #88]", + "and r4, r8, r12", + "ldr r12, [r2, #128]", + "eor lr, r12, r4", + "ldr r12, [r2, #84]", + "and r12, r8, r12", + "ldr r7, [r2, #72]", + "eor r7, r7, r12", + "str r4, [r2, #72]", + "and r4, r6, r7", + "eor lr, lr, r4", + "ldr r4, [r2, #92]", + "str r7, [r2, #84]", + "ldr r7, [r2, #108]", + "eor r4, r4, r7", + "and r12, r6, r12", + "eor r4, r4, r12", + "and r4, r5, r4", + "eor lr, lr, r4", + "and r4, r6, r8", + "str r12, [r2, #92]", + "ldr r12, [r2, #84]", + "eor r12, r12, r4", + "ldr r4, [r2, #104]", + "ldr r7, [r2, #72]", + "eor r4, r4, r7", + "ldr r7, [r2, #76]", + "str lr, [r2, #104]", + "and lr, r8, r7", + "and r8, r6, lr", + "eor r4, r4, r8", + "and r4, r5, r4", + "eor r12, r12, r4", + "ldr r4, [r2, #68]", + "and r12, r4, r12", + "ldr r8, [r2, #104]", + "eor r8, r8, r12", + "ldr r12, [r2, #124]", + "str r8, [r2, #104]", + "ldr r8, [r2, #108]", + "eor r12, r12, r8", + "str lr, [r2, #124]", + "ldr lr, [r2, #96]", + "eor r7, r7, lr", + "and r7, r6, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #88]", + "ldr lr, [r2, #80]", + "eor r8, r7, lr", + "ldr r4, [r2, #60]", + "eor r8, r8, r4", + "ldr r7, [r2, #120]", + "ldr r4, [r2, #128]", + "and lr, r7, r4", + "eor lr, r8, lr", + "str r8, [r2, #96]", + "ldr r8, [r2, #136]", + "and r8, r6, r8", + "eor lr, lr, r8", + "and lr, r5, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #92]", + "ldr r8, [r2, #80]", + "eor lr, lr, r8", + "ldr r8, [r2, #60]", + "eor lr, lr, r8", + "ldr r8, [r2, #88]", + "str r12, [r2, #60]", + "ldr r12, [r2, #72]", + "eor r8, r8, r12", + "eor r4, r4, r7", + "and r4, r6, r4", + "eor r8, r8, r4", + "and r8, r5, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #68]", + "and lr, r8, lr", + "ldr r4, [r2, #60]", + "eor r4, r4, lr", + "ldr lr, [r2, #132]", + "eor r12, lr, r7", + "str r4, [r2, #60]", + "ldr r4, [r2, #116]", + "eor r12, r12, r4", + "ldr r4, [r2, #112]", + "and r8, r5, r4", + "eor r12, r12, r8", + "ldr r8, [r2, #96]", + "str r12, [r2, #116]", + "ldr r12, [r2, #108]", + "eor r12, r8, r12", + "and r12, r6, r12", + "eor r4, r4, r12", + "and r7, r7, r8", + "eor r8, r8, r7", + "ldr r7, [r2, #124]", + "eor lr, lr, r7", + "and r6, r6, lr", + "eor r8, r8, r6", + "and r5, r5, r8", + "eor r4, r4, r5", + "ldr r5, [r2, #68]", + "and r5, r5, r4", + "ldr r4, [r2, #116]", + "eor r7, r4, r5", + "ldr r4, [r2, #100]", + "ldr r5, [r2, #104]", + "ldr r6, [r2, #60]", + "and r4, r4, #1", + "ror r4, r4, #19", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #11", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #29", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #4", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #3", + "eor r4, r4, lr, lsr #6", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #4", + "eor r5, r5, lr, lsr #7", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #5", + "eor r6, r6, lr, lsr #8", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #6", + "eor r7, r7, lr, lsr #9", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #7", + "eor r8, r8, lr, lsr #10", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #8", + "eor r12, r12, lr, lsr #11", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r5, [r2, #64]", + "eor r5, r4, r4", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "str r7, [r2, #72]", + "eor r7, r12, r4", + "str r5, [r2, #76]", + "and r5, r4, r12", + "str r4, [r2, #80]", + "and r4, r6, r5", + "str r12, [r2, #84]", + "eor r12, r7, r4", + "str r4, [r2, #88]", + "eor r4, r5, lr", + "eor r4, r4, r8", + "str r7, [r2, #92]", + "and r7, r6, r4", + "str r5, [r2, #96]", + "ldr r5, [r2, #76]", + "str r4, [r2, #100]", + "eor r4, r5, r7", + "str r7, [r2, #104]", + "ldr r7, [r2, #72]", + "and r5, r7, r4", + "eor r12, r12, r5", + "ldr r5, [r2, #84]", + "str r4, [r2, #108]", + "eor r4, r5, lr", + "eor r4, r4, r8", + "ldr r5, [r2, #80]", + "and r8, r5, r4", + "str r4, [r2, #112]", + "and r4, r6, r8", + "str r8, [r2, #116]", + "ldr r8, [r2, #76]", + "str lr, [r2, #120]", + "eor lr, r8, r4", + "ldr r8, [r2, #100]", + "str r4, [r2, #124]", + "and r4, r7, r8", + "eor lr, lr, r4", + "str r4, [r2, #128]", + "ldr r4, [r2, #68]", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #104]", + "and r8, r7, lr", + "ldr lr, [r2, #108]", + "eor lr, lr, r8", + "and r8, r6, r5", + "ldr r5, [r2, #96]", + "eor r8, r5, r8", + "and r8, r4, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #64]", + "and lr, r8, lr", + "eor r12, r12, lr", + "eor lr, r5, r6", + "str r12, [r2, #108]", + "ldr r12, [r2, #92]", + "ldr r8, [r2, #120]", + "eor r4, r12, r8", + "ldr r12, [r2, #60]", + "eor r4, r4, r12", + "ldr r12, [r2, #124]", + "eor r8, r4, r12", + "and r8, r7, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #84]", + "str r4, [r2, #132]", + "and r4, r6, r8", + "str r6, [r2, #136]", + "ldr r6, [r2, #76]", + "str lr, [r2, #140]", + "eor lr, r6, r4", + "eor r5, r8, r5", + "eor r6, r5, r12", + "and r6, r7, r6", + "eor lr, lr, r6", + "ldr r12, [r2, #68]", + "and lr, r12, lr", + "str r4, [r2, #96]", + "ldr r4, [r2, #140]", + "eor r4, r4, lr", + "ldr lr, [r2, #112]", + "ldr r8, [r2, #116]", + "str r4, [r2, #140]", + "eor r4, lr, r8", + "ldr r8, [r2, #80]", + "ldr lr, [r2, #120]", + "eor r8, r8, lr", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "ldr lr, [r2, #136]", + "and r8, lr, r8", + "eor r8, r4, r8", + "eor r8, r8, r6", + "ldr r6, [r2, #132]", + "str r4, [r2, #80]", + "and r4, lr, r6", + "and r6, r7, r5", + "eor r4, r4, r6", + "and r4, r12, r4", + "eor r8, r8, r4", + "ldr r4, [r2, #64]", + "and r8, r4, r8", + "ldr r6, [r2, #140]", + "eor r6, r6, r8", + "ldr r8, [r2, #120]", + "eor r5, r5, r8", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "and r8, lr, r8", + "str r6, [r2, #112]", + "eor r6, r5, r8", + "str r5, [r2, #60]", + "ldr r5, [r2, #84]", + "str r8, [r2, #120]", + "and r8, r7, r5", + "eor r6, r6, r8", + "str r8, [r2, #140]", + "ldr r8, [r2, #132]", + "ldr r5, [r2, #104]", + "eor r8, r8, r5", + "ldr r5, [r2, #100]", + "ldr r4, [r2, #96]", + "eor r5, r5, r4", + "and r5, r7, r5", + "eor r8, r8, r5", + "and r8, r12, r8", + "eor r6, r6, r8", + "ldr r8, [r2, #92]", + "and r8, lr, r8", + "and r8, r7, r8", + "ldr r5, [r2, #76]", + "eor r5, r5, r8", + "ldr r8, [r2, #124]", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #64]", + "and r5, r8, r5", + "eor r6, r6, r5", + "ldr r5, [r2, #116]", + "eor r5, r5, r4", + "str r6, [r2, #116]", + "ldr r6, [r2, #128]", + "eor r5, r5, r6", + "ldr r6, [r2, #84]", + "ldr r8, [r2, #120]", + "eor r8, r6, r8", + "ldr r4, [r2, #80]", + "and lr, lr, r4", + "eor r4, r4, lr", + "and r4, r7, r4", + "eor r8, r8, r4", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #60]", + "ldr r4, [r2, #88]", + "eor r8, r8, r4", + "eor r6, r6, lr", + "and r7, r7, r6", + "eor r8, r8, r7", + "ldr r7, [r2, #96]", + "ldr r6, [r2, #140]", + "eor r7, r7, r6", + "and r12, r12, r7", + "eor r8, r8, r12", + "ldr r12, [r2, #64]", + "and r12, r12, r8", + "eor r7, r5, r12", + "ldr r4, [r2, #108]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #116]", + "and r4, r4, #1", + "ror r4, r4, #7", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #22", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #12", + "eor r10, r10, r6", + "and r7, r7, #1", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #31", + "eor r4, r4, lr", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "eor r5, r5, lr, lsr #1", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #1", + "eor r6, r6, lr, lsr #2", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #2", + "eor r7, r7, lr, lsr #3", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #3", + "eor r8, r8, lr, lsr #4", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #4", + "eor r12, r12, lr, lsr #5", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r6, r6, r8", + "str r6, [r2, #72]", + "eor r6, r4, lr", + "eor r6, r6, r8", + "str r4, [r2, #76]", + "eor r4, r12, r6", + "eor r7, r7, lr", + "eor r7, r7, r8", + "str r6, [r2, #80]", + "eor r6, r4, r7", + "eor r5, r5, lr", + "eor r5, r5, r8", + "eor r6, r6, r5", + "str r4, [r2, #84]", + "ldr r4, [r2, #76]", + "str r6, [r2, #88]", + "and r6, r7, r4", + "ldr r4, [r2, #80]", + "and r8, r4, r12", + "str r12, [r2, #92]", + "and r12, r7, r8", + "str r7, [r2, #96]", + "eor r7, r4, r12", + "and r7, r5, r7", + "eor r7, r6, r7", + "str r12, [r2, #100]", + "ldr r12, [r2, #68]", + "eor r12, r12, lr", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r12, r12, r8", + "and r7, r12, r7", + "str r12, [r2, #104]", + "ldr r12, [r2, #88]", + "eor r12, r12, r7", + "ldr r7, [r2, #92]", + "str r12, [r2, #88]", + "eor r12, r7, lr", + "eor r12, r12, r8", + "and r8, r4, r12", + "str lr, [r2, #108]", + "ldr lr, [r2, #72]", + "str r12, [r2, #112]", + "eor r12, lr, r8", + "str r8, [r2, #116]", + "eor r8, r12, r6", + "and r8, r5, r8", + "eor r4, r4, r8", + "ldr r8, [r2, #68]", + "str r12, [r2, #80]", + "eor r12, r7, r8", + "str r6, [r2, #120]", + "ldr r6, [r2, #96]", + "and r7, r6, r12", + "eor lr, lr, r7", + "ldr r6, [r2, #112]", + "str r12, [r2, #72]", + "and r12, r5, r6", + "eor lr, lr, r12", + "str r12, [r2, #124]", + "ldr r12, [r2, #104]", + "and lr, r12, lr", + "eor r4, r4, lr", + "ldr lr, [r2, #64]", + "ldr r12, [r2, #108]", + "eor lr, lr, r12", + "str r5, [r2, #64]", + "ldr r5, [r2, #60]", + "eor lr, lr, r5", + "and r4, lr, r4", + "str lr, [r2, #128]", + "ldr lr, [r2, #88]", + "eor r4, lr, r4", + "eor lr, r8, r12", + "eor lr, lr, r5", + "str r4, [r2, #88]", + "eor r4, lr, r7", + "str r7, [r2, #132]", + "ldr r7, [r2, #72]", + "eor r7, r7, r12", + "eor r7, r7, r5", + "ldr r8, [r2, #96]", + "str lr, [r2, #72]", + "and lr, r8, r7", + "eor r6, r6, lr", + "str r7, [r2, #112]", + "ldr r7, [r2, #64]", + "and r6, r7, r6", + "eor r4, r4, r6", + "ldr r6, [r2, #100]", + "str lr, [r2, #136]", + "eor lr, r6, r12", + "eor lr, lr, r5", + "and r8, r7, r6", + "eor r8, lr, r8", + "str lr, [r2, #140]", + "ldr lr, [r2, #104]", + "and r8, lr, r8", + "eor r4, r4, r8", + "ldr r8, [r2, #92]", + "ldr r6, [r2, #116]", + "str r4, [r2, #144]", + "eor r4, r8, r6", + "ldr r8, [r2, #120]", + "eor r8, r4, r8", + "ldr r6, [r2, #84]", + "and r6, r7, r6", + "eor lr, r8, r6", + "eor r8, r8, r12", + "eor r8, r8, r5", + "eor r4, r4, r12", + "eor r4, r4, r5", + "and r4, r7, r4", + "eor r8, r8, r4", + "ldr r4, [r2, #104]", + "and r8, r4, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #128]", + "and lr, r8, lr", + "ldr r5, [r2, #144]", + "eor r5, r5, lr", + "ldr lr, [r2, #116]", + "str r5, [r2, #144]", + "ldr r5, [r2, #100]", + "eor r12, lr, r5", + "str r6, [r2, #84]", + "ldr r6, [r2, #96]", + "ldr lr, [r2, #72]", + "and r8, r6, lr", + "ldr r6, [r2, #92]", + "eor r6, r6, r8", + "and r8, r7, r6", + "eor r12, r12, r8", + "ldr r8, [r2, #136]", + "eor r8, lr, r8", + "and r8, r4, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #124]", + "eor lr, lr, r8", + "str r6, [r2, #72]", + "ldr r6, [r2, #68]", + "eor r5, r6, r5", + "eor r5, r5, r8", + "and r5, r4, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #128]", + "and lr, r5, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #140]", + "and lr, r7, lr", + "ldr r8, [r2, #72]", + "eor r8, r8, lr", + "ldr lr, [r2, #96]", + "str r12, [r2, #72]", + "ldr r12, [r2, #116]", + "and lr, lr, r12", + "eor r6, r6, lr", + "ldr lr, [r2, #76]", + "ldr r12, [r2, #132]", + "eor lr, lr, r12", + "and lr, r7, lr", + "eor lr, r6, lr", + "and lr, r4, lr", + "eor r8, r8, lr", + "ldr lr, [r2, #80]", + "ldr r12, [r2, #84]", + "eor lr, lr, r12", + "ldr r12, [r2, #108]", + "eor r6, r6, r12", + "ldr r12, [r2, #60]", + "eor r6, r6, r12", + "ldr r12, [r2, #112]", + "and r7, r7, r12", + "eor r6, r6, r7", + "and r4, r4, r6", + "eor lr, lr, r4", + "and r5, r5, lr", + "eor r7, r8, r5", + "ldr r4, [r2, #88]", + "ldr r5, [r2, #144]", + "ldr r6, [r2, #72]", + "and r4, r4, #1", + "ror r4, r4, #21", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #15", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #27", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #5", + "eor r10, r10, r7", + "mov lr, r10", + "mov r10, r11", + "mov r11, lr", + "add r0, r0, #8", + "subs r9, r9, #1", + "bne 22b", + "mov lr, r10", + "mov r10, r11", + "mov r11, lr", + "mov r5, #0", + "mov r4, #0", + "mov r9, #1", + "mov r12, r11", + "lsr r12, r12, #24", + "and r12, r12, r9", + "ror r12, r12, #1", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #24", + "and r12, r12, r9", + "ror r12, r12, #2", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #16", + "and r12, r12, r9", + "ror r12, r12, #3", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #16", + "and r12, r12, r9", + "ror r12, r12, #4", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #8", + "and r12, r12, r9", + "ror r12, r12, #5", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #8", + "and r12, r12, r9", + "ror r12, r12, #6", + "eor r4, r4, r12", + "mov r12, r11", + "and r12, r12, r9", + "ror r12, r12, #7", + "eor r4, r4, r12", + "mov r12, r10", + "and r12, r12, r9", + "ror r12, r12, #8", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #25", + "and r12, r12, r9", + "ror r12, r12, #9", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #25", + "and r12, r12, r9", + "ror r12, r12, #10", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #17", + "and r12, r12, r9", + "ror r12, r12, #11", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #17", + "and r12, r12, r9", + "ror r12, r12, #12", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #9", + "and r12, r12, r9", + "ror r12, r12, #13", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #9", + "and r12, r12, r9", + "ror r12, r12, #14", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #1", + "and r12, r12, r9", + "ror r12, r12, #15", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #1", + "and r12, r12, r9", + "ror r12, r12, #16", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #26", + "and r12, r12, r9", + "ror r12, r12, #17", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #26", + "and r12, r12, r9", + "ror r12, r12, #18", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #18", + "and r12, r12, r9", + "ror r12, r12, #19", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #18", + "and r12, r12, r9", + "ror r12, r12, #20", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #10", + "and r12, r12, r9", + "ror r12, r12, #21", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #10", + "and r12, r12, r9", + "ror r12, r12, #22", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #2", + "and r12, r12, r9", + "ror r12, r12, #23", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #2", + "and r12, r12, r9", + "ror r12, r12, #24", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #27", + "and r12, r12, r9", + "ror r12, r12, #25", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #27", + "and r12, r12, r9", + "ror r12, r12, #26", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #19", + "and r12, r12, r9", + "ror r12, r12, #27", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #19", + "and r12, r12, r9", + "ror r12, r12, #28", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #11", + "and r12, r12, r9", + "ror r12, r12, #29", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #11", + "and r12, r12, r9", + "ror r12, r12, #30", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #3", + "and r12, r12, r9", + "ror r12, r12, #31", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #3", + "and r12, r12, r9", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #28", + "and r12, r12, r9", + "ror r12, r12, #1", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #28", + "and r12, r12, r9", + "ror r12, r12, #2", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #20", + "and r12, r12, r9", + "ror r12, r12, #3", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #20", + "and r12, r12, r9", + "ror r12, r12, #4", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #12", + "and r12, r12, r9", + "ror r12, r12, #5", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #12", + "and r12, r12, r9", + "ror r12, r12, #6", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #4", + "and r12, r12, r9", + "ror r12, r12, #7", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #4", + "and r12, r12, r9", + "ror r12, r12, #8", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #29", + "and r12, r12, r9", + "ror r12, r12, #9", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #29", + "and r12, r12, r9", + "ror r12, r12, #10", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #21", + "and r12, r12, r9", + "ror r12, r12, #11", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #21", + "and r12, r12, r9", + "ror r12, r12, #12", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #13", + "and r12, r12, r9", + "ror r12, r12, #13", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #13", + "and r12, r12, r9", + "ror r12, r12, #14", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #5", + "and r12, r12, r9", + "ror r12, r12, #15", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #5", + "and r12, r12, r9", + "ror r12, r12, #16", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #30", + "and r12, r12, r9", + "ror r12, r12, #17", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #30", + "and r12, r12, r9", + "ror r12, r12, #18", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #22", + "and r12, r12, r9", + "ror r12, r12, #19", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #22", + "and r12, r12, r9", + "ror r12, r12, #20", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #14", + "and r12, r12, r9", + "ror r12, r12, #21", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #14", + "and r12, r12, r9", + "ror r12, r12, #22", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #6", + "and r12, r12, r9", + "ror r12, r12, #23", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #6", + "and r12, r12, r9", + "ror r12, r12, #24", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #31", + "and r12, r12, r9", + "ror r12, r12, #25", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #31", + "and r12, r12, r9", + "ror r12, r12, #26", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #23", + "and r12, r12, r9", + "ror r12, r12, #27", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #23", + "and r12, r12, r9", + "ror r12, r12, #28", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #15", + "and r12, r12, r9", + "ror r12, r12, #29", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #15", + "and r12, r12, r9", + "ror r12, r12, #30", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #7", + "and r12, r12, r9", + "ror r12, r12, #31", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #7", + "and r12, r12, r9", + "eor r5, r5, r12", + "rev r4, r4", + "rev r5, r5", + "str r4, [r1, #0]", + "str r5, [r1, #4]", + "sub r0, r0, #384", + "ldr r4, [r2, #0]", + "ldr r5, [r2, #4]", + "ldr r6, [r2, #8]", + "ldr r7, [r2, #12]", + "ldr r8, [r2, #16]", + "ldr r9, [r2, #20]", + "ldr r10, [r2, #24]", + "ldr r11, [r2, #28]", + "ldr lr, [r2, #32]", + "bx lr", + ) +} + +/// Triple DES block decryption (FIPS 46-3): transforms the 8 bytes at `data` in place under the three DES schedules at `schedule`. Each schedule contains sixteen encryption-order 48-bit round keys in little-endian 64-bit slots; upper bits are ignored. +/// +/// Contract: `VG.Spec.TripleDes.decryptBlockContract`. Constant time: only pointers may affect timing, not the schedule or data, including S-box inputs. +/// +/// Baseline ARMv7 scalar Boolean S-box circuits with reverse EDE key order. +/// +/// # Safety +/// +/// * `schedule` must be valid for reads of 384 bytes. +/// * `data` must be valid for reads and writes of 8 bytes. +/// * `scratch` must be valid for reads and writes of 512 bytes. +/// * The contents of `scratch` on return are unspecified. +/// * `data` and `scratch` must not overlap each other or `schedule` (distinct Rust objects never do). +/// * None of `schedule`, `data` and `scratch` may wrap around the end of the address space (no Rust object does). +#[unsafe(naked)] +pub(crate) unsafe extern "C" fn vg_triple_des_decrypt_block(schedule: *const [u8; 384], data: *mut [u8; 8], scratch: *mut [u64; 64]) { + core::arch::naked_asm!( + "str r4, [r2, #0]", + "str r5, [r2, #4]", + "str r6, [r2, #8]", + "str r7, [r2, #12]", + "str r8, [r2, #16]", + "str r9, [r2, #20]", + "str r10, [r2, #24]", + "str r11, [r2, #28]", + "str lr, [r2, #32]", + "ldr r4, [r1, #0]", + "ldr r5, [r1, #4]", + "rev r4, r4", + "rev r5, r5", + "mov r11, #0", + "mov r10, #0", + "mov r9, #1", + "mov r12, r5", + "lsr r12, r12, #6", + "and r12, r12, r9", + "ror r12, r12, #1", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #14", + "and r12, r12, r9", + "ror r12, r12, #2", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #22", + "and r12, r12, r9", + "ror r12, r12, #3", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #30", + "and r12, r12, r9", + "ror r12, r12, #4", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #6", + "and r12, r12, r9", + "ror r12, r12, #5", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #14", + "and r12, r12, r9", + "ror r12, r12, #6", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #22", + "and r12, r12, r9", + "ror r12, r12, #7", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #30", + "and r12, r12, r9", + "ror r12, r12, #8", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #4", + "and r12, r12, r9", + "ror r12, r12, #9", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #12", + "and r12, r12, r9", + "ror r12, r12, #10", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #20", + "and r12, r12, r9", + "ror r12, r12, #11", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #28", + "and r12, r12, r9", + "ror r12, r12, #12", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #4", + "and r12, r12, r9", + "ror r12, r12, #13", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #12", + "and r12, r12, r9", + "ror r12, r12, #14", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #20", + "and r12, r12, r9", + "ror r12, r12, #15", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #28", + "and r12, r12, r9", + "ror r12, r12, #16", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #2", + "and r12, r12, r9", + "ror r12, r12, #17", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #10", + "and r12, r12, r9", + "ror r12, r12, #18", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #18", + "and r12, r12, r9", + "ror r12, r12, #19", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #26", + "and r12, r12, r9", + "ror r12, r12, #20", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #2", + "and r12, r12, r9", + "ror r12, r12, #21", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #10", + "and r12, r12, r9", + "ror r12, r12, #22", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #18", + "and r12, r12, r9", + "ror r12, r12, #23", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #26", + "and r12, r12, r9", + "ror r12, r12, #24", + "eor r10, r10, r12", + "mov r12, r5", + "and r12, r12, r9", + "ror r12, r12, #25", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #8", + "and r12, r12, r9", + "ror r12, r12, #26", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #16", + "and r12, r12, r9", + "ror r12, r12, #27", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #24", + "and r12, r12, r9", + "ror r12, r12, #28", + "eor r10, r10, r12", + "mov r12, r4", + "and r12, r12, r9", + "ror r12, r12, #29", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #8", + "and r12, r12, r9", + "ror r12, r12, #30", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #16", + "and r12, r12, r9", + "ror r12, r12, #31", + "eor r10, r10, r12", + "mov r12, r4", + "lsr r12, r12, #24", + "and r12, r12, r9", + "eor r10, r10, r12", + "mov r12, r5", + "lsr r12, r12, #7", + "and r12, r12, r9", + "ror r12, r12, #1", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #15", + "and r12, r12, r9", + "ror r12, r12, #2", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #23", + "and r12, r12, r9", + "ror r12, r12, #3", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #31", + "and r12, r12, r9", + "ror r12, r12, #4", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #7", + "and r12, r12, r9", + "ror r12, r12, #5", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #15", + "and r12, r12, r9", + "ror r12, r12, #6", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #23", + "and r12, r12, r9", + "ror r12, r12, #7", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #31", + "and r12, r12, r9", + "ror r12, r12, #8", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #5", + "and r12, r12, r9", + "ror r12, r12, #9", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #13", + "and r12, r12, r9", + "ror r12, r12, #10", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #21", + "and r12, r12, r9", + "ror r12, r12, #11", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #29", + "and r12, r12, r9", + "ror r12, r12, #12", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #5", + "and r12, r12, r9", + "ror r12, r12, #13", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #13", + "and r12, r12, r9", + "ror r12, r12, #14", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #21", + "and r12, r12, r9", + "ror r12, r12, #15", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #29", + "and r12, r12, r9", + "ror r12, r12, #16", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #3", + "and r12, r12, r9", + "ror r12, r12, #17", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #11", + "and r12, r12, r9", + "ror r12, r12, #18", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #19", + "and r12, r12, r9", + "ror r12, r12, #19", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #27", + "and r12, r12, r9", + "ror r12, r12, #20", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #3", + "and r12, r12, r9", + "ror r12, r12, #21", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #11", + "and r12, r12, r9", + "ror r12, r12, #22", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #19", + "and r12, r12, r9", + "ror r12, r12, #23", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #27", + "and r12, r12, r9", + "ror r12, r12, #24", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #1", + "and r12, r12, r9", + "ror r12, r12, #25", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #9", + "and r12, r12, r9", + "ror r12, r12, #26", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #17", + "and r12, r12, r9", + "ror r12, r12, #27", + "eor r11, r11, r12", + "mov r12, r5", + "lsr r12, r12, #25", + "and r12, r12, r9", + "ror r12, r12, #28", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #1", + "and r12, r12, r9", + "ror r12, r12, #29", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #9", + "and r12, r12, r9", + "ror r12, r12, #30", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #17", + "and r12, r12, r9", + "ror r12, r12, #31", + "eor r11, r11, r12", + "mov r12, r4", + "lsr r12, r12, #25", + "and r12, r12, r9", + "eor r11, r11, r12", + "add r0, r0, #376", + "mov r9, #16", + "20:", + "ldr lr, [r0, #4]", + "mov r4, r11", + "lsr r4, r4, #27", + "eor r4, r4, lr, lsr #10", + "and r4, r4, #1", + "ldr lr, [r0, #4]", + "mov r5, r11", + "lsr r5, r5, #28", + "eor r5, r5, lr, lsr #11", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #29", + "eor r6, r6, lr, lsr #12", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #30", + "eor r7, r7, lr, lsr #13", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #31", + "eor r8, r8, lr, lsr #14", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "eor r12, r12, lr, lsr #15", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, lr", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "and r7, r8, r6", + "str lr, [r2, #72]", + "eor lr, r4, r8", + "str r8, [r2, #76]", + "and r8, r5, lr", + "eor r8, r7, r8", + "str lr, [r2, #80]", + "eor lr, r6, r7", + "str r7, [r2, #84]", + "and r7, r5, lr", + "eor r7, r4, r7", + "and r7, r12, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #76]", + "str lr, [r2, #88]", + "and lr, r7, r4", + "str r4, [r2, #92]", + "ldr r4, [r2, #72]", + "str r6, [r2, #96]", + "eor r6, lr, r4", + "str r8, [r2, #100]", + "ldr r8, [r2, #60]", + "eor r6, r6, r8", + "str r12, [r2, #104]", + "and r12, r5, r6", + "str r6, [r2, #108]", + "eor r6, lr, r12", + "str lr, [r2, #112]", + "eor lr, r7, r4", + "eor lr, lr, r8", + "eor r8, lr, r12", + "str r12, [r2, #116]", + "ldr r12, [r2, #104]", + "and r4, r12, r8", + "eor r6, r6, r4", + "ldr r4, [r2, #68]", + "and r6, r4, r6", + "str r8, [r2, #120]", + "ldr r8, [r2, #100]", + "eor r8, r8, r6", + "and r7, r5, r7", + "ldr r6, [r2, #108]", + "str r8, [r2, #76]", + "eor r8, r6, r7", + "str r7, [r2, #100]", + "and r7, r5, lr", + "str lr, [r2, #124]", + "ldr lr, [r2, #96]", + "eor r6, lr, r7", + "and r6, r12, r6", + "eor r8, r8, r6", + "and r6, r5, lr", + "str r5, [r2, #128]", + "ldr r5, [r2, #88]", + "str r7, [r2, #132]", + "eor r7, r5, r6", + "and r7, r12, r7", + "and r7, r4, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r8, r7, r8", + "str r6, [r2, #136]", + "ldr r6, [r2, #76]", + "eor r6, r6, r8", + "ldr r8, [r2, #112]", + "eor lr, lr, r8", + "ldr r8, [r2, #132]", + "str r6, [r2, #112]", + "eor r6, lr, r8", + "ldr r7, [r2, #84]", + "ldr r4, [r2, #72]", + "eor r8, r7, r4", + "ldr r7, [r2, #60]", + "eor r8, r8, r7", + "ldr r7, [r2, #128]", + "and lr, r7, lr", + "eor lr, r8, lr", + "str r8, [r2, #96]", + "and r8, r12, lr", + "eor r6, r6, r8", + "eor r8, r5, r4", + "ldr r4, [r2, #60]", + "eor r8, r8, r4", + "ldr r4, [r2, #132]", + "eor r4, r8, r4", + "str r8, [r2, #132]", + "ldr r8, [r2, #84]", + "and r5, r7, r8", + "eor r8, r8, r5", + "and r8, r12, r8", + "eor r5, r4, r8", + "str r4, [r2, #84]", + "ldr r4, [r2, #68]", + "and r5, r4, r5", + "eor r6, r6, r5", + "eor lr, lr, r8", + "ldr r8, [r2, #92]", + "and r5, r7, r8", + "ldr r8, [r2, #96]", + "eor r7, r8, r5", + "and r7, r12, r7", + "ldr r8, [r2, #88]", + "eor r12, r8, r7", + "and r12, r4, r12", + "eor lr, lr, r12", + "ldr r12, [r2, #64]", + "and lr, r12, lr", + "eor r6, r6, lr", + "eor lr, r8, r5", + "str r6, [r2, #76]", + "ldr r6, [r2, #104]", + "ldr r8, [r2, #84]", + "and r12, r6, r8", + "eor lr, lr, r12", + "ldr r12, [r2, #108]", + "str r7, [r2, #140]", + "ldr r7, [r2, #136]", + "eor r12, r12, r7", + "ldr r7, [r2, #128]", + "str r5, [r2, #136]", + "ldr r5, [r2, #132]", + "and r5, r7, r5", + "ldr r7, [r2, #96]", + "eor r7, r7, r5", + "and r7, r6, r7", + "eor r12, r12, r7", + "and r12, r4, r12", + "eor lr, lr, r12", + "ldr r12, [r2, #116]", + "and r7, r6, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #92]", + "ldr r5, [r2, #136]", + "eor r7, r7, r5", + "ldr r5, [r2, #140]", + "eor r7, r7, r5", + "and r7, r4, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r8, r7, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #80]", + "ldr r5, [r2, #72]", + "eor r8, r8, r5", + "str lr, [r2, #80]", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "ldr r7, [r2, #128]", + "eor r8, r8, r7", + "eor r12, r12, r5", + "eor r12, r12, lr", + "and r12, r6, r12", + "eor r12, r8, r12", + "str r8, [r2, #116]", + "ldr r8, [r2, #120]", + "eor r8, r8, r5", + "eor r8, r8, lr", + "and r8, r6, r8", + "ldr lr, [r2, #124]", + "eor lr, lr, r8", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #88]", + "ldr r8, [r2, #100]", + "eor r8, lr, r8", + "and r8, r6, r8", + "ldr r5, [r2, #136]", + "eor r5, r5, r8", + "eor lr, lr, r7", + "and r6, r6, lr", + "ldr lr, [r2, #116]", + "eor lr, lr, r6", + "and r4, r4, lr", + "eor r5, r5, r4", + "ldr r4, [r2, #64]", + "and r4, r4, r5", + "eor r7, r12, r4", + "ldr r4, [r2, #112]", + "ldr r5, [r2, #76]", + "ldr r6, [r2, #80]", + "and r4, r4, #1", + "ror r4, r4, #31", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #23", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #17", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #9", + "eor r10, r10, r7", + "ldr lr, [r0, #4]", + "mov r4, r11", + "lsr r4, r4, #23", + "eor r4, r4, lr, lsr #4", + "and r4, r4, #1", + "ldr lr, [r0, #4]", + "mov r5, r11", + "lsr r5, r5, #24", + "eor r5, r5, lr, lsr #5", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #25", + "eor r6, r6, lr, lsr #6", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #26", + "eor r7, r7, lr, lsr #7", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #27", + "eor r8, r8, lr, lsr #8", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "lsr r12, r12, #28", + "eor r12, r12, lr, lsr #9", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "str r6, [r2, #72]", + "eor r6, r12, lr", + "eor r6, r6, r7", + "str r8, [r2, #76]", + "and r8, r5, r12", + "str r5, [r2, #80]", + "eor r5, r12, r8", + "str r12, [r2, #84]", + "and r12, r4, r5", + "eor r12, r6, r12", + "str r6, [r2, #88]", + "eor r6, r8, lr", + "eor r6, r6, r7", + "str r8, [r2, #92]", + "and r8, r4, r6", + "str r6, [r2, #96]", + "eor r6, r5, r8", + "str r8, [r2, #100]", + "ldr r8, [r2, #76]", + "and r6, r8, r6", + "eor r12, r12, r6", + "str r6, [r2, #104]", + "ldr r6, [r2, #80]", + "str r12, [r2, #108]", + "ldr r12, [r2, #88]", + "and r8, r6, r12", + "eor r6, r12, r8", + "eor r5, r5, lr", + "eor r5, r5, r7", + "and r12, r4, r5", + "str r5, [r2, #112]", + "eor r5, r6, r12", + "str r12, [r2, #116]", + "eor r12, r6, lr", + "eor r12, r12, r7", + "str r6, [r2, #120]", + "and r6, r4, r12", + "str r12, [r2, #124]", + "ldr r12, [r2, #80]", + "eor r6, r12, r6", + "ldr r7, [r2, #76]", + "and r6, r7, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #68]", + "and r5, r6, r5", + "ldr r6, [r2, #108]", + "eor r6, r6, r5", + "and r5, r4, r8", + "str r8, [r2, #108]", + "ldr r8, [r2, #72]", + "eor r5, r8, r5", + "ldr r8, [r2, #84]", + "str lr, [r2, #128]", + "eor lr, r8, r12", + "and r8, r4, lr", + "str r4, [r2, #132]", + "eor r4, r12, r8", + "and r4, r7, r4", + "eor r5, r5, r4", + "ldr r4, [r2, #64]", + "and r5, r4, r5", + "eor r6, r6, r5", + "ldr r5, [r2, #128]", + "eor lr, lr, r5", + "str r6, [r2, #136]", + "ldr r6, [r2, #60]", + "eor lr, lr, r6", + "ldr r6, [r2, #132]", + "ldr r5, [r2, #92]", + "and r5, r6, r5", + "eor r12, lr, r5", + "str r5, [r2, #92]", + "ldr r5, [r2, #112]", + "eor r5, r5, r8", + "and r5, r7, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #124]", + "ldr r8, [r2, #104]", + "eor r5, r5, r8", + "ldr r8, [r2, #68]", + "and r5, r8, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #120]", + "str lr, [r2, #104]", + "and lr, r6, r5", + "str r12, [r2, #124]", + "ldr r12, [r2, #84]", + "eor lr, r12, lr", + "and lr, r7, lr", + "ldr r4, [r2, #96]", + "eor lr, r4, lr", + "ldr r4, [r2, #88]", + "str lr, [r2, #112]", + "and lr, r6, r4", + "eor r5, r5, lr", + "and r12, r7, r12", + "eor r5, r5, r12", + "and r5, r8, r5", + "ldr r12, [r2, #112]", + "eor r12, r12, r5", + "ldr r5, [r2, #64]", + "and r12, r5, r12", + "str lr, [r2, #112]", + "ldr lr, [r2, #124]", + "eor lr, lr, r12", + "ldr r12, [r2, #104]", + "str lr, [r2, #124]", + "eor lr, r12, r6", + "eor lr, lr, r7", + "ldr r4, [r2, #96]", + "ldr r12, [r2, #92]", + "eor r5, r4, r12", + "and r5, r7, r5", + "eor r5, r6, r5", + "and r5, r8, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #80]", + "and r6, r6, r5", + "ldr r5, [r2, #72]", + "eor r5, r5, r6", + "ldr r12, [r2, #100]", + "eor r4, r4, r12", + "and r4, r7, r4", + "eor r5, r5, r4", + "and r6, r8, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #64]", + "and r5, r6, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #104]", + "eor r5, r5, r12", + "ldr r12, [r2, #116]", + "and r12, r7, r12", + "eor r5, r5, r12", + "ldr r12, [r2, #92]", + "ldr r4, [r2, #128]", + "str lr, [r2, #116]", + "eor lr, r12, r4", + "ldr r6, [r2, #60]", + "eor lr, lr, r6", + "ldr r6, [r2, #88]", + "ldr r4, [r2, #112]", + "eor r6, r6, r4", + "and r6, r7, r6", + "eor lr, lr, r6", + "and r8, r8, lr", + "eor r5, r5, r8", + "ldr r8, [r2, #108]", + "eor r8, r8, r12", + "ldr r12, [r2, #128]", + "eor r12, r8, r12", + "ldr lr, [r2, #60]", + "eor r12, r12, lr", + "and r7, r7, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r7, r7, r8", + "eor r7, r5, r7", + "ldr r4, [r2, #136]", + "ldr r5, [r2, #124]", + "ldr r6, [r2, #116]", + "and r4, r4, #1", + "ror r4, r4, #18", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #2", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #28", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #13", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #19", + "eor r4, r4, lr, lsr #30", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #20", + "eor r5, r5, lr, lsr #31", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #21", + "eor r6, r6, lr", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #22", + "eor r7, r7, lr, lsr #1", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #23", + "eor r8, r8, lr, lsr #2", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "lsr r12, r12, #24", + "eor r12, r12, lr, lsr #3", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "str r6, [r2, #72]", + "eor r6, r12, lr", + "eor r6, r6, r7", + "str r5, [r2, #76]", + "and r5, r8, r6", + "eor r7, r12, r5", + "str r5, [r2, #80]", + "and r5, r8, r12", + "str r8, [r2, #84]", + "eor r8, r6, r5", + "str r6, [r2, #88]", + "and r6, r4, r8", + "str r12, [r2, #92]", + "eor r12, r7, r6", + "str r7, [r2, #96]", + "eor r7, r8, lr", + "str lr, [r2, #100]", + "ldr lr, [r2, #60]", + "eor r7, r7, lr", + "and r5, r4, r5", + "eor lr, r7, r5", + "str r7, [r2, #104]", + "ldr r7, [r2, #76]", + "str r6, [r2, #108]", + "and r6, r7, lr", + "eor r6, r12, r6", + "str r12, [r2, #112]", + "and r12, r7, r8", + "eor lr, lr, r12", + "ldr r12, [r2, #68]", + "and lr, r12, lr", + "eor r6, r6, lr", + "ldr lr, [r2, #92]", + "and lr, r4, lr", + "str r8, [r2, #92]", + "ldr r8, [r2, #72]", + "eor r8, r8, lr", + "str lr, [r2, #72]", + "ldr lr, [r2, #88]", + "str r4, [r2, #116]", + "and r4, r7, lr", + "eor r8, r8, r4", + "and r5, r12, r5", + "eor r8, r8, r5", + "ldr r5, [r2, #64]", + "and r8, r5, r8", + "eor r4, r6, r8", + "ldr r8, [r2, #84]", + "eor r6, lr, r8", + "str r4, [r2, #120]", + "ldr r4, [r2, #108]", + "eor r4, r6, r4", + "str r6, [r2, #108]", + "ldr r6, [r2, #80]", + "ldr r5, [r2, #100]", + "eor r12, r6, r5", + "ldr lr, [r2, #60]", + "eor r12, r12, lr", + "ldr lr, [r2, #116]", + "and r5, lr, r6", + "eor r5, r12, r5", + "and r6, r7, r5", + "str r5, [r2, #124]", + "eor r5, r4, r6", + "str r6, [r2, #128]", + "ldr r6, [r2, #100]", + "str r12, [r2, #132]", + "eor r12, r8, r6", + "str r4, [r2, #136]", + "ldr r4, [r2, #60]", + "eor r12, r12, r4", + "and r4, lr, r12", + "eor r8, r8, r4", + "str r12, [r2, #84]", + "ldr r12, [r2, #88]", + "str r4, [r2, #140]", + "and r4, lr, r12", + "eor r12, r12, r4", + "and r12, r7, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #68]", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "eor r8, r8, r6", + "str r5, [r2, #112]", + "ldr r5, [r2, #60]", + "eor r8, r8, r5", + "ldr r12, [r2, #136]", + "eor r12, r12, r6", + "eor r12, r12, r5", + "and r12, r7, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #96]", + "str r8, [r2, #136]", + "eor r8, r12, r6", + "eor r8, r8, r5", + "and r12, lr, r8", + "str r8, [r2, #88]", + "ldr r8, [r2, #132]", + "eor lr, r8, r12", + "str r12, [r2, #144]", + "eor r12, r4, r6", + "eor r12, r12, r5", + "and r12, r7, r12", + "eor lr, lr, r12", + "str r4, [r2, #148]", + "ldr r4, [r2, #68]", + "and lr, r4, lr", + "str r12, [r2, #152]", + "ldr r12, [r2, #136]", + "eor r12, r12, lr", + "ldr lr, [r2, #64]", + "and r12, lr, r12", + "ldr lr, [r2, #112]", + "eor lr, lr, r12", + "ldr r12, [r2, #116]", + "str lr, [r2, #112]", + "and lr, r12, r8", + "ldr r12, [r2, #104]", + "eor r12, r12, lr", + "ldr lr, [r2, #124]", + "eor r8, lr, r6", + "eor r8, r8, r5", + "and r8, r7, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #128]", + "eor lr, lr, r8", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #80]", + "ldr r8, [r2, #140]", + "eor r8, lr, r8", + "ldr r5, [r2, #152]", + "eor r8, r8, r5", + "ldr r5, [r2, #72]", + "and r6, r7, r5", + "eor lr, lr, r6", + "and lr, r4, lr", + "eor r8, r8, lr", + "ldr lr, [r2, #64]", + "and r8, lr, r8", + "eor r6, r12, r8", + "ldr r8, [r2, #132]", + "eor r8, r8, r5", + "eor r8, r8, r7", + "ldr r5, [r2, #108]", + "ldr r12, [r2, #100]", + "eor r5, r5, r12", + "ldr r12, [r2, #60]", + "eor r5, r5, r12", + "ldr r12, [r2, #116]", + "and r12, r12, r5", + "ldr r5, [r2, #84]", + "eor r5, r5, r12", + "and r5, r7, r5", + "ldr r12, [r2, #92]", + "eor r12, r12, r5", + "and r12, r4, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #96]", + "ldr r5, [r2, #148]", + "eor r12, r12, r5", + "str r6, [r2, #96]", + "ldr r6, [r2, #88]", + "str r8, [r2, #92]", + "ldr r8, [r2, #144]", + "eor r8, r6, r8", + "and r8, r7, r8", + "eor r12, r12, r8", + "and r7, r7, r5", + "eor r6, r6, r7", + "and r4, r4, r6", + "eor r12, r12, r4", + "and lr, lr, r12", + "ldr r12, [r2, #92]", + "eor r7, r12, lr", + "ldr r4, [r2, #120]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #96]", + "and r4, r4, #1", + "ror r4, r4, #6", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #30", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #16", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #24", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #15", + "eor r4, r4, lr, lsr #24", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #16", + "eor r5, r5, lr, lsr #25", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #17", + "eor r6, r6, lr, lsr #26", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #18", + "eor r7, r7, lr, lsr #27", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #19", + "eor r8, r8, lr, lsr #28", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #20", + "eor r12, r12, lr, lsr #29", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r4, [r2, #68]", + "ldr r4, [r2, #60]", + "eor r6, r6, r4", + "str r6, [r2, #72]", + "eor r6, r7, lr", + "eor r6, r6, r4", + "str r8, [r2, #76]", + "and r8, r5, r7", + "eor r4, r6, r8", + "str r8, [r2, #80]", + "and r8, r12, r4", + "str r4, [r2, #84]", + "eor r4, r6, r8", + "str r8, [r2, #88]", + "eor r8, r7, r5", + "str r7, [r2, #92]", + "eor r7, r8, lr", + "str r6, [r2, #96]", + "ldr r6, [r2, #60]", + "eor r7, r7, r6", + "and r6, r12, r7", + "str r7, [r2, #100]", + "eor r7, r8, r6", + "str r8, [r2, #104]", + "ldr r8, [r2, #76]", + "and r7, r8, r7", + "eor r4, r4, r7", + "eor r7, r5, lr", + "str r12, [r2, #108]", + "ldr r12, [r2, #60]", + "eor r7, r7, r12", + "eor r12, r5, r6", + "str r6, [r2, #112]", + "and r6, r8, r12", + "str r5, [r2, #116]", + "eor r5, r7, r6", + "str r6, [r2, #120]", + "ldr r6, [r2, #64]", + "and r5, r6, r5", + "eor r4, r4, r5", + "ldr r5, [r2, #84]", + "str r7, [r2, #124]", + "eor r7, r5, lr", + "ldr r5, [r2, #60]", + "eor r7, r7, r5", + "str r4, [r2, #128]", + "ldr r4, [r2, #108]", + "and r7, r4, r7", + "ldr r6, [r2, #100]", + "eor r7, r6, r7", + "and r7, r8, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #80]", + "eor r7, r7, lr", + "eor r7, r7, r5", + "ldr r5, [r2, #116]", + "str lr, [r2, #80]", + "ldr lr, [r2, #96]", + "and r6, r5, lr", + "ldr r5, [r2, #72]", + "eor r5, r5, r6", + "and lr, r4, r5", + "eor r7, r7, lr", + "str r5, [r2, #72]", + "ldr r5, [r2, #104]", + "and r5, r8, r5", + "eor r7, r7, r5", + "str r5, [r2, #104]", + "ldr r5, [r2, #64]", + "and r7, r5, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #68]", + "and r5, r7, r12", + "ldr r7, [r2, #128]", + "eor r7, r7, r5", + "and r5, r4, r6", + "str r7, [r2, #128]", + "ldr r7, [r2, #100]", + "eor r7, r7, r5", + "ldr r4, [r2, #80]", + "str r5, [r2, #100]", + "eor r5, lr, r4", + "ldr r4, [r2, #60]", + "eor r5, r5, r4", + "and r5, r8, r5", + "eor r5, r7, r5", + "str r7, [r2, #132]", + "eor r7, r6, lr", + "str r6, [r2, #136]", + "ldr r6, [r2, #92]", + "str lr, [r2, #140]", + "ldr lr, [r2, #112]", + "eor lr, r6, lr", + "and lr, r8, lr", + "eor r7, r7, lr", + "ldr r6, [r2, #64]", + "and r7, r6, r7", + "eor r5, r5, r7", + "ldr r7, [r2, #80]", + "eor r12, r12, r7", + "eor r12, r12, r4", + "ldr r4, [r2, #68]", + "and r12, r4, r12", + "eor r5, r5, r12", + "ldr r12, [r2, #84]", + "str r5, [r2, #112]", + "ldr r5, [r2, #140]", + "eor r12, r12, r5", + "ldr r5, [r2, #96]", + "and r5, r8, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #116]", + "eor r5, r5, lr", + "and r5, r6, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #132]", + "eor r5, r5, r7", + "ldr lr, [r2, #60]", + "eor r5, r5, lr", + "ldr lr, [r2, #72]", + "ldr r7, [r2, #100]", + "eor lr, lr, r7", + "and lr, r8, lr", + "eor r5, r5, lr", + "ldr lr, [r2, #124]", + "ldr r8, [r2, #88]", + "eor lr, lr, r8", + "ldr r8, [r2, #104]", + "eor lr, lr, r8", + "and lr, r6, lr", + "eor r5, r5, lr", + "and lr, r4, r5", + "eor r12, r12, lr", + "ldr lr, [r2, #136]", + "ldr r8, [r2, #108]", + "eor r8, lr, r8", + "str r12, [r2, #108]", + "ldr r12, [r2, #92]", + "eor r12, r12, lr", + "eor r12, r12, r7", + "ldr r7, [r2, #76]", + "and r7, r7, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #88]", + "ldr r12, [r2, #80]", + "eor r7, r7, r12", + "ldr lr, [r2, #60]", + "eor r7, r7, lr", + "ldr r4, [r2, #120]", + "eor r7, r7, r4", + "and r6, r6, r7", + "eor r8, r8, r6", + "eor r5, r5, r12", + "eor r5, r5, lr", + "ldr lr, [r2, #68]", + "and lr, lr, r5", + "eor r7, r8, lr", + "ldr r4, [r2, #128]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #108]", + "and r4, r4, #1", + "ror r4, r4, #1", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #10", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #20", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #26", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #11", + "eor r4, r4, lr, lsr #18", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #12", + "eor r5, r5, lr, lsr #19", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #13", + "eor r6, r6, lr, lsr #20", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #14", + "eor r7, r7, lr, lsr #21", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #15", + "eor r8, r8, lr, lsr #22", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #16", + "eor r12, r12, lr, lsr #23", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r5, [r2, #64]", + "eor r5, r4, r4", + "str r6, [r2, #68]", + "ldr r6, [r2, #60]", + "eor r5, r5, r6", + "str r8, [r2, #72]", + "eor r8, r7, lr", + "eor r8, r8, r6", + "str r7, [r2, #76]", + "and r7, r8, r12", + "str r8, [r2, #80]", + "eor r8, r5, r7", + "eor r4, r4, lr", + "eor r4, r4, r6", + "str r5, [r2, #84]", + "and r5, r4, r8", + "str r8, [r2, #88]", + "eor r8, r12, r5", + "str r5, [r2, #92]", + "eor r5, r12, lr", + "eor r5, r5, r6", + "str r12, [r2, #96]", + "ldr r12, [r2, #80]", + "str r4, [r2, #100]", + "and r4, r12, r5", + "eor r12, r5, r4", + "str r4, [r2, #104]", + "ldr r4, [r2, #72]", + "eor r4, r4, lr", + "eor r4, r4, r6", + "and r6, r4, r12", + "eor r6, r8, r6", + "str r8, [r2, #72]", + "eor r8, r5, r7", + "str r12, [r2, #108]", + "and r12, r4, r8", + "str r8, [r2, #112]", + "ldr r8, [r2, #76]", + "eor r12, r8, r12", + "ldr r8, [r2, #68]", + "eor r8, r8, lr", + "str lr, [r2, #68]", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "and r12, r8, r12", + "eor r6, r6, r12", + "ldr r12, [r2, #100]", + "str r6, [r2, #116]", + "and r6, r12, r5", + "str r8, [r2, #120]", + "ldr r8, [r2, #80]", + "eor r6, r8, r6", + "str r5, [r2, #124]", + "ldr r5, [r2, #96]", + "eor lr, r5, r8", + "and r7, r12, r7", + "eor r7, lr, r7", + "and r7, r4, r7", + "eor r6, r6, r7", + "ldr r7, [r2, #108]", + "ldr r8, [r2, #68]", + "str lr, [r2, #128]", + "eor lr, r7, r8", + "ldr r5, [r2, #60]", + "eor lr, lr, r5", + "and lr, r12, lr", + "ldr r7, [r2, #124]", + "eor r5, r7, r12", + "and r5, r4, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #120]", + "and lr, r5, lr", + "eor r6, r6, lr", + "ldr lr, [r2, #64]", + "eor lr, lr, r8", + "ldr r7, [r2, #60]", + "eor lr, lr, r7", + "and r6, lr, r6", + "str lr, [r2, #64]", + "ldr lr, [r2, #116]", + "eor lr, lr, r6", + "ldr r6, [r2, #108]", + "str lr, [r2, #116]", + "and lr, r12, r6", + "ldr r6, [r2, #88]", + "eor r5, r6, lr", + "eor r5, r5, r4", + "ldr r6, [r2, #104]", + "str lr, [r2, #132]", + "eor lr, r6, r8", + "eor lr, lr, r7", + "and r7, r12, lr", + "ldr r8, [r2, #84]", + "eor r8, r8, r7", + "and r6, r12, r6", + "str lr, [r2, #104]", + "and lr, r4, r6", + "eor r8, r8, lr", + "ldr lr, [r2, #120]", + "and r8, lr, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "eor r6, r8, r6", + "and r6, r4, r6", + "ldr r8, [r2, #76]", + "eor r6, r8, r6", + "ldr r8, [r2, #96]", + "and r8, r12, r8", + "ldr r12, [r2, #124]", + "eor r12, r12, r8", + "str r8, [r2, #124]", + "and r8, r4, r12", + "eor r8, r7, r8", + "and r8, lr, r8", + "eor r6, r6, r8", + "ldr r8, [r2, #64]", + "and r6, r8, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #108]", + "str r5, [r2, #96]", + "ldr r5, [r2, #100]", + "str r12, [r2, #84]", + "eor r12, r6, r5", + "eor r12, r12, r4", + "ldr r8, [r2, #104]", + "ldr r6, [r2, #132]", + "eor r8, r8, r6", + "ldr r6, [r2, #128]", + "eor r5, r6, r7", + "and r5, r4, r5", + "eor r8, r8, r5", + "and r8, lr, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #68]", + "eor r5, r6, r8", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "ldr r8, [r2, #100]", + "and r6, r8, r5", + "str r5, [r2, #132]", + "ldr r5, [r2, #108]", + "eor r5, r5, r6", + "and r5, lr, r5", + "str r6, [r2, #108]", + "ldr r6, [r2, #88]", + "eor r6, r6, r5", + "ldr r5, [r2, #64]", + "and r6, r5, r6", + "eor r6, r12, r6", + "ldr r12, [r2, #80]", + "eor r12, r12, r7", + "ldr r7, [r2, #72]", + "and r7, r4, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #112]", + "str r6, [r2, #72]", + "eor r6, r7, r8", + "and r6, r4, r6", + "ldr r5, [r2, #84]", + "eor r5, r5, r6", + "and r5, lr, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #132]", + "ldr r6, [r2, #92]", + "eor r5, r5, r6", + "ldr r6, [r2, #76]", + "and r8, r8, r6", + "ldr r6, [r2, #128]", + "eor r6, r6, r8", + "and r6, r4, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #68]", + "eor r7, r7, r6", + "ldr r8, [r2, #60]", + "eor r7, r7, r8", + "str r12, [r2, #112]", + "ldr r12, [r2, #108]", + "eor r7, r7, r12", + "ldr r12, [r2, #124]", + "eor r12, r12, r6", + "eor r12, r12, r8", + "and r4, r4, r12", + "eor r7, r7, r4", + "and lr, lr, r7", + "eor r5, r5, lr", + "ldr lr, [r2, #64]", + "and lr, lr, r5", + "ldr r5, [r2, #112]", + "eor r7, r5, lr", + "ldr r4, [r2, #116]", + "ldr r5, [r2, #96]", + "ldr r6, [r2, #72]", + "and r4, r4, #1", + "ror r4, r4, #3", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #25", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #14", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #8", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #7", + "eor r4, r4, lr, lsr #12", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #8", + "eor r5, r5, lr, lsr #13", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #9", + "eor r6, r6, lr, lsr #14", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #10", + "eor r7, r7, lr, lsr #15", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #11", + "eor r8, r8, lr, lsr #16", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #12", + "eor r12, r12, lr, lsr #17", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r12, [r2, #64]", + "eor r12, r4, r4", + "str r4, [r2, #68]", + "ldr r4, [r2, #60]", + "eor r12, r12, r4", + "str r12, [r2, #72]", + "eor r12, r8, lr", + "eor r12, r12, r4", + "and r4, r7, r12", + "str r12, [r2, #76]", + "eor r12, r4, r5", + "str lr, [r2, #80]", + "eor lr, r8, r4", + "str r8, [r2, #84]", + "and r8, r5, r7", + "str r4, [r2, #88]", + "eor r4, lr, r8", + "and r4, r6, r4", + "eor r12, r12, r4", + "ldr r4, [r2, #80]", + "str lr, [r2, #92]", + "eor lr, r8, r4", + "str r8, [r2, #96]", + "ldr r8, [r2, #60]", + "eor lr, lr, r8", + "str r12, [r2, #100]", + "eor r12, r7, r4", + "eor r12, r12, r8", + "and r8, r5, r12", + "str r12, [r2, #104]", + "eor r12, r7, r8", + "str r8, [r2, #108]", + "and r8, r6, r12", + "eor lr, lr, r8", + "str r12, [r2, #112]", + "ldr r12, [r2, #64]", + "and lr, r12, lr", + "str r8, [r2, #116]", + "ldr r8, [r2, #100]", + "eor r8, r8, lr", + "ldr lr, [r2, #76]", + "str r8, [r2, #100]", + "eor r8, lr, r7", + "and r12, r5, r8", + "str r5, [r2, #120]", + "ldr r5, [r2, #88]", + "str r8, [r2, #124]", + "eor r8, r5, r12", + "and r8, r6, r8", + "ldr r5, [r2, #84]", + "and r7, r7, r5", + "eor r5, lr, r7", + "ldr lr, [r2, #124]", + "str r7, [r2, #128]", + "eor r7, lr, r4", + "ldr r4, [r2, #60]", + "eor r7, r7, r4", + "eor r7, r7, r12", + "and r7, r6, r7", + "eor r7, r5, r7", + "str r5, [r2, #132]", + "ldr r5, [r2, #64]", + "and r7, r5, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #68]", + "and r8, r7, r8", + "str r12, [r2, #136]", + "ldr r12, [r2, #100]", + "eor r12, r12, r8", + "ldr r8, [r2, #120]", + "str r12, [r2, #100]", + "ldr r12, [r2, #88]", + "and r4, r8, r12", + "ldr r12, [r2, #128]", + "eor lr, r12, r4", + "ldr r12, [r2, #84]", + "and r12, r8, r12", + "ldr r7, [r2, #72]", + "eor r7, r7, r12", + "str r4, [r2, #72]", + "and r4, r6, r7", + "eor lr, lr, r4", + "ldr r4, [r2, #92]", + "str r7, [r2, #84]", + "ldr r7, [r2, #108]", + "eor r4, r4, r7", + "and r12, r6, r12", + "eor r4, r4, r12", + "and r4, r5, r4", + "eor lr, lr, r4", + "and r4, r6, r8", + "str r12, [r2, #92]", + "ldr r12, [r2, #84]", + "eor r12, r12, r4", + "ldr r4, [r2, #104]", + "ldr r7, [r2, #72]", + "eor r4, r4, r7", + "ldr r7, [r2, #76]", + "str lr, [r2, #104]", + "and lr, r8, r7", + "and r8, r6, lr", + "eor r4, r4, r8", + "and r4, r5, r4", + "eor r12, r12, r4", + "ldr r4, [r2, #68]", + "and r12, r4, r12", + "ldr r8, [r2, #104]", + "eor r8, r8, r12", + "ldr r12, [r2, #124]", + "str r8, [r2, #104]", + "ldr r8, [r2, #108]", + "eor r12, r12, r8", + "str lr, [r2, #124]", + "ldr lr, [r2, #96]", + "eor r7, r7, lr", + "and r7, r6, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #88]", + "ldr lr, [r2, #80]", + "eor r8, r7, lr", + "ldr r4, [r2, #60]", + "eor r8, r8, r4", + "ldr r7, [r2, #120]", + "ldr r4, [r2, #128]", + "and lr, r7, r4", + "eor lr, r8, lr", + "str r8, [r2, #96]", + "ldr r8, [r2, #136]", + "and r8, r6, r8", + "eor lr, lr, r8", + "and lr, r5, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #92]", + "ldr r8, [r2, #80]", + "eor lr, lr, r8", + "ldr r8, [r2, #60]", + "eor lr, lr, r8", + "ldr r8, [r2, #88]", + "str r12, [r2, #60]", + "ldr r12, [r2, #72]", + "eor r8, r8, r12", + "eor r4, r4, r7", + "and r4, r6, r4", + "eor r8, r8, r4", + "and r8, r5, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #68]", + "and lr, r8, lr", + "ldr r4, [r2, #60]", + "eor r4, r4, lr", + "ldr lr, [r2, #132]", + "eor r12, lr, r7", + "str r4, [r2, #60]", + "ldr r4, [r2, #116]", + "eor r12, r12, r4", + "ldr r4, [r2, #112]", + "and r8, r5, r4", + "eor r12, r12, r8", + "ldr r8, [r2, #96]", + "str r12, [r2, #116]", + "ldr r12, [r2, #108]", + "eor r12, r8, r12", + "and r12, r6, r12", + "eor r4, r4, r12", + "and r7, r7, r8", + "eor r8, r8, r7", + "ldr r7, [r2, #124]", + "eor lr, lr, r7", + "and r6, r6, lr", + "eor r8, r8, r6", + "and r5, r5, r8", + "eor r4, r4, r5", + "ldr r5, [r2, #68]", + "and r5, r5, r4", + "ldr r4, [r2, #116]", + "eor r7, r4, r5", + "ldr r4, [r2, #100]", + "ldr r5, [r2, #104]", + "ldr r6, [r2, #60]", + "and r4, r4, #1", + "ror r4, r4, #19", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #11", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #29", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #4", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #3", + "eor r4, r4, lr, lsr #6", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #4", + "eor r5, r5, lr, lsr #7", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #5", + "eor r6, r6, lr, lsr #8", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #6", + "eor r7, r7, lr, lsr #9", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #7", + "eor r8, r8, lr, lsr #10", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #8", + "eor r12, r12, lr, lsr #11", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r5, [r2, #64]", + "eor r5, r4, r4", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "str r7, [r2, #72]", + "eor r7, r12, r4", + "str r5, [r2, #76]", + "and r5, r4, r12", + "str r4, [r2, #80]", + "and r4, r6, r5", + "str r12, [r2, #84]", + "eor r12, r7, r4", + "str r4, [r2, #88]", + "eor r4, r5, lr", + "eor r4, r4, r8", + "str r7, [r2, #92]", + "and r7, r6, r4", + "str r5, [r2, #96]", + "ldr r5, [r2, #76]", + "str r4, [r2, #100]", + "eor r4, r5, r7", + "str r7, [r2, #104]", + "ldr r7, [r2, #72]", + "and r5, r7, r4", + "eor r12, r12, r5", + "ldr r5, [r2, #84]", + "str r4, [r2, #108]", + "eor r4, r5, lr", + "eor r4, r4, r8", + "ldr r5, [r2, #80]", + "and r8, r5, r4", + "str r4, [r2, #112]", + "and r4, r6, r8", + "str r8, [r2, #116]", + "ldr r8, [r2, #76]", + "str lr, [r2, #120]", + "eor lr, r8, r4", + "ldr r8, [r2, #100]", + "str r4, [r2, #124]", + "and r4, r7, r8", + "eor lr, lr, r4", + "str r4, [r2, #128]", + "ldr r4, [r2, #68]", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #104]", + "and r8, r7, lr", + "ldr lr, [r2, #108]", + "eor lr, lr, r8", + "and r8, r6, r5", + "ldr r5, [r2, #96]", + "eor r8, r5, r8", + "and r8, r4, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #64]", + "and lr, r8, lr", + "eor r12, r12, lr", + "eor lr, r5, r6", + "str r12, [r2, #108]", + "ldr r12, [r2, #92]", + "ldr r8, [r2, #120]", + "eor r4, r12, r8", + "ldr r12, [r2, #60]", + "eor r4, r4, r12", + "ldr r12, [r2, #124]", + "eor r8, r4, r12", + "and r8, r7, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #84]", + "str r4, [r2, #132]", + "and r4, r6, r8", + "str r6, [r2, #136]", + "ldr r6, [r2, #76]", + "str lr, [r2, #140]", + "eor lr, r6, r4", + "eor r5, r8, r5", + "eor r6, r5, r12", + "and r6, r7, r6", + "eor lr, lr, r6", + "ldr r12, [r2, #68]", + "and lr, r12, lr", + "str r4, [r2, #96]", + "ldr r4, [r2, #140]", + "eor r4, r4, lr", + "ldr lr, [r2, #112]", + "ldr r8, [r2, #116]", + "str r4, [r2, #140]", + "eor r4, lr, r8", + "ldr r8, [r2, #80]", + "ldr lr, [r2, #120]", + "eor r8, r8, lr", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "ldr lr, [r2, #136]", + "and r8, lr, r8", + "eor r8, r4, r8", + "eor r8, r8, r6", + "ldr r6, [r2, #132]", + "str r4, [r2, #80]", + "and r4, lr, r6", + "and r6, r7, r5", + "eor r4, r4, r6", + "and r4, r12, r4", + "eor r8, r8, r4", + "ldr r4, [r2, #64]", + "and r8, r4, r8", + "ldr r6, [r2, #140]", + "eor r6, r6, r8", + "ldr r8, [r2, #120]", + "eor r5, r5, r8", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "and r8, lr, r8", + "str r6, [r2, #112]", + "eor r6, r5, r8", + "str r5, [r2, #60]", + "ldr r5, [r2, #84]", + "str r8, [r2, #120]", + "and r8, r7, r5", + "eor r6, r6, r8", + "str r8, [r2, #140]", + "ldr r8, [r2, #132]", + "ldr r5, [r2, #104]", + "eor r8, r8, r5", + "ldr r5, [r2, #100]", + "ldr r4, [r2, #96]", + "eor r5, r5, r4", + "and r5, r7, r5", + "eor r8, r8, r5", + "and r8, r12, r8", + "eor r6, r6, r8", + "ldr r8, [r2, #92]", + "and r8, lr, r8", + "and r8, r7, r8", + "ldr r5, [r2, #76]", + "eor r5, r5, r8", + "ldr r8, [r2, #124]", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #64]", + "and r5, r8, r5", + "eor r6, r6, r5", + "ldr r5, [r2, #116]", + "eor r5, r5, r4", + "str r6, [r2, #116]", + "ldr r6, [r2, #128]", + "eor r5, r5, r6", + "ldr r6, [r2, #84]", + "ldr r8, [r2, #120]", + "eor r8, r6, r8", + "ldr r4, [r2, #80]", + "and lr, lr, r4", + "eor r4, r4, lr", + "and r4, r7, r4", + "eor r8, r8, r4", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #60]", + "ldr r4, [r2, #88]", + "eor r8, r8, r4", + "eor r6, r6, lr", + "and r7, r7, r6", + "eor r8, r8, r7", + "ldr r7, [r2, #96]", + "ldr r6, [r2, #140]", + "eor r7, r7, r6", + "and r12, r12, r7", + "eor r8, r8, r12", + "ldr r12, [r2, #64]", + "and r12, r12, r8", + "eor r7, r5, r12", + "ldr r4, [r2, #108]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #116]", + "and r4, r4, #1", + "ror r4, r4, #7", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #22", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #12", + "eor r10, r10, r6", + "and r7, r7, #1", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #31", + "eor r4, r4, lr", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "eor r5, r5, lr, lsr #1", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #1", + "eor r6, r6, lr, lsr #2", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #2", + "eor r7, r7, lr, lsr #3", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #3", + "eor r8, r8, lr, lsr #4", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #4", + "eor r12, r12, lr, lsr #5", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r6, r6, r8", + "str r6, [r2, #72]", + "eor r6, r4, lr", + "eor r6, r6, r8", + "str r4, [r2, #76]", + "eor r4, r12, r6", + "eor r7, r7, lr", + "eor r7, r7, r8", + "str r6, [r2, #80]", + "eor r6, r4, r7", + "eor r5, r5, lr", + "eor r5, r5, r8", + "eor r6, r6, r5", + "str r4, [r2, #84]", + "ldr r4, [r2, #76]", + "str r6, [r2, #88]", + "and r6, r7, r4", + "ldr r4, [r2, #80]", + "and r8, r4, r12", + "str r12, [r2, #92]", + "and r12, r7, r8", + "str r7, [r2, #96]", + "eor r7, r4, r12", + "and r7, r5, r7", + "eor r7, r6, r7", + "str r12, [r2, #100]", + "ldr r12, [r2, #68]", + "eor r12, r12, lr", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r12, r12, r8", + "and r7, r12, r7", + "str r12, [r2, #104]", + "ldr r12, [r2, #88]", + "eor r12, r12, r7", + "ldr r7, [r2, #92]", + "str r12, [r2, #88]", + "eor r12, r7, lr", + "eor r12, r12, r8", + "and r8, r4, r12", + "str lr, [r2, #108]", + "ldr lr, [r2, #72]", + "str r12, [r2, #112]", + "eor r12, lr, r8", + "str r8, [r2, #116]", + "eor r8, r12, r6", + "and r8, r5, r8", + "eor r4, r4, r8", + "ldr r8, [r2, #68]", + "str r12, [r2, #80]", + "eor r12, r7, r8", + "str r6, [r2, #120]", + "ldr r6, [r2, #96]", + "and r7, r6, r12", + "eor lr, lr, r7", + "ldr r6, [r2, #112]", + "str r12, [r2, #72]", + "and r12, r5, r6", + "eor lr, lr, r12", + "str r12, [r2, #124]", + "ldr r12, [r2, #104]", + "and lr, r12, lr", + "eor r4, r4, lr", + "ldr lr, [r2, #64]", + "ldr r12, [r2, #108]", + "eor lr, lr, r12", + "str r5, [r2, #64]", + "ldr r5, [r2, #60]", + "eor lr, lr, r5", + "and r4, lr, r4", + "str lr, [r2, #128]", + "ldr lr, [r2, #88]", + "eor r4, lr, r4", + "eor lr, r8, r12", + "eor lr, lr, r5", + "str r4, [r2, #88]", + "eor r4, lr, r7", + "str r7, [r2, #132]", + "ldr r7, [r2, #72]", + "eor r7, r7, r12", + "eor r7, r7, r5", + "ldr r8, [r2, #96]", + "str lr, [r2, #72]", + "and lr, r8, r7", + "eor r6, r6, lr", + "str r7, [r2, #112]", + "ldr r7, [r2, #64]", + "and r6, r7, r6", + "eor r4, r4, r6", + "ldr r6, [r2, #100]", + "str lr, [r2, #136]", + "eor lr, r6, r12", + "eor lr, lr, r5", + "and r8, r7, r6", + "eor r8, lr, r8", + "str lr, [r2, #140]", + "ldr lr, [r2, #104]", + "and r8, lr, r8", + "eor r4, r4, r8", + "ldr r8, [r2, #92]", + "ldr r6, [r2, #116]", + "str r4, [r2, #144]", + "eor r4, r8, r6", + "ldr r8, [r2, #120]", + "eor r8, r4, r8", + "ldr r6, [r2, #84]", + "and r6, r7, r6", + "eor lr, r8, r6", + "eor r8, r8, r12", + "eor r8, r8, r5", + "eor r4, r4, r12", + "eor r4, r4, r5", + "and r4, r7, r4", + "eor r8, r8, r4", + "ldr r4, [r2, #104]", + "and r8, r4, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #128]", + "and lr, r8, lr", + "ldr r5, [r2, #144]", + "eor r5, r5, lr", + "ldr lr, [r2, #116]", + "str r5, [r2, #144]", + "ldr r5, [r2, #100]", + "eor r12, lr, r5", + "str r6, [r2, #84]", + "ldr r6, [r2, #96]", + "ldr lr, [r2, #72]", + "and r8, r6, lr", + "ldr r6, [r2, #92]", + "eor r6, r6, r8", + "and r8, r7, r6", + "eor r12, r12, r8", + "ldr r8, [r2, #136]", + "eor r8, lr, r8", + "and r8, r4, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #124]", + "eor lr, lr, r8", + "str r6, [r2, #72]", + "ldr r6, [r2, #68]", + "eor r5, r6, r5", + "eor r5, r5, r8", + "and r5, r4, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #128]", + "and lr, r5, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #140]", + "and lr, r7, lr", + "ldr r8, [r2, #72]", + "eor r8, r8, lr", + "ldr lr, [r2, #96]", + "str r12, [r2, #72]", + "ldr r12, [r2, #116]", + "and lr, lr, r12", + "eor r6, r6, lr", + "ldr lr, [r2, #76]", + "ldr r12, [r2, #132]", + "eor lr, lr, r12", + "and lr, r7, lr", + "eor lr, r6, lr", + "and lr, r4, lr", + "eor r8, r8, lr", + "ldr lr, [r2, #80]", + "ldr r12, [r2, #84]", + "eor lr, lr, r12", + "ldr r12, [r2, #108]", + "eor r6, r6, r12", + "ldr r12, [r2, #60]", + "eor r6, r6, r12", + "ldr r12, [r2, #112]", + "and r7, r7, r12", + "eor r6, r6, r7", + "and r4, r4, r6", + "eor lr, lr, r4", + "and r5, r5, lr", + "eor r7, r8, r5", + "ldr r4, [r2, #88]", + "ldr r5, [r2, #144]", + "ldr r6, [r2, #72]", + "and r4, r4, #1", + "ror r4, r4, #21", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #15", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #27", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #5", + "eor r10, r10, r7", + "mov lr, r10", + "mov r10, r11", + "mov r11, lr", + "sub r0, r0, #8", + "subs r9, r9, #1", + "bne 20b", + "mov lr, r10", + "mov r10, r11", + "mov r11, lr", + "sub r0, r0, #120", + "mov r9, #16", + "21:", + "ldr lr, [r0, #4]", + "mov r4, r11", + "lsr r4, r4, #27", + "eor r4, r4, lr, lsr #10", + "and r4, r4, #1", + "ldr lr, [r0, #4]", + "mov r5, r11", + "lsr r5, r5, #28", + "eor r5, r5, lr, lsr #11", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #29", + "eor r6, r6, lr, lsr #12", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #30", + "eor r7, r7, lr, lsr #13", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #31", + "eor r8, r8, lr, lsr #14", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "eor r12, r12, lr, lsr #15", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, lr", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "and r7, r8, r6", + "str lr, [r2, #72]", + "eor lr, r4, r8", + "str r8, [r2, #76]", + "and r8, r5, lr", + "eor r8, r7, r8", + "str lr, [r2, #80]", + "eor lr, r6, r7", + "str r7, [r2, #84]", + "and r7, r5, lr", + "eor r7, r4, r7", + "and r7, r12, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #76]", + "str lr, [r2, #88]", + "and lr, r7, r4", + "str r4, [r2, #92]", + "ldr r4, [r2, #72]", + "str r6, [r2, #96]", + "eor r6, lr, r4", + "str r8, [r2, #100]", + "ldr r8, [r2, #60]", + "eor r6, r6, r8", + "str r12, [r2, #104]", + "and r12, r5, r6", + "str r6, [r2, #108]", + "eor r6, lr, r12", + "str lr, [r2, #112]", + "eor lr, r7, r4", + "eor lr, lr, r8", + "eor r8, lr, r12", + "str r12, [r2, #116]", + "ldr r12, [r2, #104]", + "and r4, r12, r8", + "eor r6, r6, r4", + "ldr r4, [r2, #68]", + "and r6, r4, r6", + "str r8, [r2, #120]", + "ldr r8, [r2, #100]", + "eor r8, r8, r6", + "and r7, r5, r7", + "ldr r6, [r2, #108]", + "str r8, [r2, #76]", + "eor r8, r6, r7", + "str r7, [r2, #100]", + "and r7, r5, lr", + "str lr, [r2, #124]", + "ldr lr, [r2, #96]", + "eor r6, lr, r7", + "and r6, r12, r6", + "eor r8, r8, r6", + "and r6, r5, lr", + "str r5, [r2, #128]", + "ldr r5, [r2, #88]", + "str r7, [r2, #132]", + "eor r7, r5, r6", + "and r7, r12, r7", + "and r7, r4, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r8, r7, r8", + "str r6, [r2, #136]", + "ldr r6, [r2, #76]", + "eor r6, r6, r8", + "ldr r8, [r2, #112]", + "eor lr, lr, r8", + "ldr r8, [r2, #132]", + "str r6, [r2, #112]", + "eor r6, lr, r8", + "ldr r7, [r2, #84]", + "ldr r4, [r2, #72]", + "eor r8, r7, r4", + "ldr r7, [r2, #60]", + "eor r8, r8, r7", + "ldr r7, [r2, #128]", + "and lr, r7, lr", + "eor lr, r8, lr", + "str r8, [r2, #96]", + "and r8, r12, lr", + "eor r6, r6, r8", + "eor r8, r5, r4", + "ldr r4, [r2, #60]", + "eor r8, r8, r4", + "ldr r4, [r2, #132]", + "eor r4, r8, r4", + "str r8, [r2, #132]", + "ldr r8, [r2, #84]", + "and r5, r7, r8", + "eor r8, r8, r5", + "and r8, r12, r8", + "eor r5, r4, r8", + "str r4, [r2, #84]", + "ldr r4, [r2, #68]", + "and r5, r4, r5", + "eor r6, r6, r5", + "eor lr, lr, r8", + "ldr r8, [r2, #92]", + "and r5, r7, r8", + "ldr r8, [r2, #96]", + "eor r7, r8, r5", + "and r7, r12, r7", + "ldr r8, [r2, #88]", + "eor r12, r8, r7", + "and r12, r4, r12", + "eor lr, lr, r12", + "ldr r12, [r2, #64]", + "and lr, r12, lr", + "eor r6, r6, lr", + "eor lr, r8, r5", + "str r6, [r2, #76]", + "ldr r6, [r2, #104]", + "ldr r8, [r2, #84]", + "and r12, r6, r8", + "eor lr, lr, r12", + "ldr r12, [r2, #108]", + "str r7, [r2, #140]", + "ldr r7, [r2, #136]", + "eor r12, r12, r7", + "ldr r7, [r2, #128]", + "str r5, [r2, #136]", + "ldr r5, [r2, #132]", + "and r5, r7, r5", + "ldr r7, [r2, #96]", + "eor r7, r7, r5", + "and r7, r6, r7", + "eor r12, r12, r7", + "and r12, r4, r12", + "eor lr, lr, r12", + "ldr r12, [r2, #116]", + "and r7, r6, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #92]", + "ldr r5, [r2, #136]", + "eor r7, r7, r5", + "ldr r5, [r2, #140]", + "eor r7, r7, r5", + "and r7, r4, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r8, r7, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #80]", + "ldr r5, [r2, #72]", + "eor r8, r8, r5", + "str lr, [r2, #80]", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "ldr r7, [r2, #128]", + "eor r8, r8, r7", + "eor r12, r12, r5", + "eor r12, r12, lr", + "and r12, r6, r12", + "eor r12, r8, r12", + "str r8, [r2, #116]", + "ldr r8, [r2, #120]", + "eor r8, r8, r5", + "eor r8, r8, lr", + "and r8, r6, r8", + "ldr lr, [r2, #124]", + "eor lr, lr, r8", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #88]", + "ldr r8, [r2, #100]", + "eor r8, lr, r8", + "and r8, r6, r8", + "ldr r5, [r2, #136]", + "eor r5, r5, r8", + "eor lr, lr, r7", + "and r6, r6, lr", + "ldr lr, [r2, #116]", + "eor lr, lr, r6", + "and r4, r4, lr", + "eor r5, r5, r4", + "ldr r4, [r2, #64]", + "and r4, r4, r5", + "eor r7, r12, r4", + "ldr r4, [r2, #112]", + "ldr r5, [r2, #76]", + "ldr r6, [r2, #80]", + "and r4, r4, #1", + "ror r4, r4, #31", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #23", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #17", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #9", + "eor r10, r10, r7", + "ldr lr, [r0, #4]", + "mov r4, r11", + "lsr r4, r4, #23", + "eor r4, r4, lr, lsr #4", + "and r4, r4, #1", + "ldr lr, [r0, #4]", + "mov r5, r11", + "lsr r5, r5, #24", + "eor r5, r5, lr, lsr #5", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #25", + "eor r6, r6, lr, lsr #6", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #26", + "eor r7, r7, lr, lsr #7", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #27", + "eor r8, r8, lr, lsr #8", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "lsr r12, r12, #28", + "eor r12, r12, lr, lsr #9", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "str r6, [r2, #72]", + "eor r6, r12, lr", + "eor r6, r6, r7", + "str r8, [r2, #76]", + "and r8, r5, r12", + "str r5, [r2, #80]", + "eor r5, r12, r8", + "str r12, [r2, #84]", + "and r12, r4, r5", + "eor r12, r6, r12", + "str r6, [r2, #88]", + "eor r6, r8, lr", + "eor r6, r6, r7", + "str r8, [r2, #92]", + "and r8, r4, r6", + "str r6, [r2, #96]", + "eor r6, r5, r8", + "str r8, [r2, #100]", + "ldr r8, [r2, #76]", + "and r6, r8, r6", + "eor r12, r12, r6", + "str r6, [r2, #104]", + "ldr r6, [r2, #80]", + "str r12, [r2, #108]", + "ldr r12, [r2, #88]", + "and r8, r6, r12", + "eor r6, r12, r8", + "eor r5, r5, lr", + "eor r5, r5, r7", + "and r12, r4, r5", + "str r5, [r2, #112]", + "eor r5, r6, r12", + "str r12, [r2, #116]", + "eor r12, r6, lr", + "eor r12, r12, r7", + "str r6, [r2, #120]", + "and r6, r4, r12", + "str r12, [r2, #124]", + "ldr r12, [r2, #80]", + "eor r6, r12, r6", + "ldr r7, [r2, #76]", + "and r6, r7, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #68]", + "and r5, r6, r5", + "ldr r6, [r2, #108]", + "eor r6, r6, r5", + "and r5, r4, r8", + "str r8, [r2, #108]", + "ldr r8, [r2, #72]", + "eor r5, r8, r5", + "ldr r8, [r2, #84]", + "str lr, [r2, #128]", + "eor lr, r8, r12", + "and r8, r4, lr", + "str r4, [r2, #132]", + "eor r4, r12, r8", + "and r4, r7, r4", + "eor r5, r5, r4", + "ldr r4, [r2, #64]", + "and r5, r4, r5", + "eor r6, r6, r5", + "ldr r5, [r2, #128]", + "eor lr, lr, r5", + "str r6, [r2, #136]", + "ldr r6, [r2, #60]", + "eor lr, lr, r6", + "ldr r6, [r2, #132]", + "ldr r5, [r2, #92]", + "and r5, r6, r5", + "eor r12, lr, r5", + "str r5, [r2, #92]", + "ldr r5, [r2, #112]", + "eor r5, r5, r8", + "and r5, r7, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #124]", + "ldr r8, [r2, #104]", + "eor r5, r5, r8", + "ldr r8, [r2, #68]", + "and r5, r8, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #120]", + "str lr, [r2, #104]", + "and lr, r6, r5", + "str r12, [r2, #124]", + "ldr r12, [r2, #84]", + "eor lr, r12, lr", + "and lr, r7, lr", + "ldr r4, [r2, #96]", + "eor lr, r4, lr", + "ldr r4, [r2, #88]", + "str lr, [r2, #112]", + "and lr, r6, r4", + "eor r5, r5, lr", + "and r12, r7, r12", + "eor r5, r5, r12", + "and r5, r8, r5", + "ldr r12, [r2, #112]", + "eor r12, r12, r5", + "ldr r5, [r2, #64]", + "and r12, r5, r12", + "str lr, [r2, #112]", + "ldr lr, [r2, #124]", + "eor lr, lr, r12", + "ldr r12, [r2, #104]", + "str lr, [r2, #124]", + "eor lr, r12, r6", + "eor lr, lr, r7", + "ldr r4, [r2, #96]", + "ldr r12, [r2, #92]", + "eor r5, r4, r12", + "and r5, r7, r5", + "eor r5, r6, r5", + "and r5, r8, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #80]", + "and r6, r6, r5", + "ldr r5, [r2, #72]", + "eor r5, r5, r6", + "ldr r12, [r2, #100]", + "eor r4, r4, r12", + "and r4, r7, r4", + "eor r5, r5, r4", + "and r6, r8, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #64]", + "and r5, r6, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #104]", + "eor r5, r5, r12", + "ldr r12, [r2, #116]", + "and r12, r7, r12", + "eor r5, r5, r12", + "ldr r12, [r2, #92]", + "ldr r4, [r2, #128]", + "str lr, [r2, #116]", + "eor lr, r12, r4", + "ldr r6, [r2, #60]", + "eor lr, lr, r6", + "ldr r6, [r2, #88]", + "ldr r4, [r2, #112]", + "eor r6, r6, r4", + "and r6, r7, r6", + "eor lr, lr, r6", + "and r8, r8, lr", + "eor r5, r5, r8", + "ldr r8, [r2, #108]", + "eor r8, r8, r12", + "ldr r12, [r2, #128]", + "eor r12, r8, r12", + "ldr lr, [r2, #60]", + "eor r12, r12, lr", + "and r7, r7, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r7, r7, r8", + "eor r7, r5, r7", + "ldr r4, [r2, #136]", + "ldr r5, [r2, #124]", + "ldr r6, [r2, #116]", + "and r4, r4, #1", + "ror r4, r4, #18", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #2", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #28", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #13", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #19", + "eor r4, r4, lr, lsr #30", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #20", + "eor r5, r5, lr, lsr #31", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #21", + "eor r6, r6, lr", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #22", + "eor r7, r7, lr, lsr #1", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #23", + "eor r8, r8, lr, lsr #2", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "lsr r12, r12, #24", + "eor r12, r12, lr, lsr #3", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "str r6, [r2, #72]", + "eor r6, r12, lr", + "eor r6, r6, r7", + "str r5, [r2, #76]", + "and r5, r8, r6", + "eor r7, r12, r5", + "str r5, [r2, #80]", + "and r5, r8, r12", + "str r8, [r2, #84]", + "eor r8, r6, r5", + "str r6, [r2, #88]", + "and r6, r4, r8", + "str r12, [r2, #92]", + "eor r12, r7, r6", + "str r7, [r2, #96]", + "eor r7, r8, lr", + "str lr, [r2, #100]", + "ldr lr, [r2, #60]", + "eor r7, r7, lr", + "and r5, r4, r5", + "eor lr, r7, r5", + "str r7, [r2, #104]", + "ldr r7, [r2, #76]", + "str r6, [r2, #108]", + "and r6, r7, lr", + "eor r6, r12, r6", + "str r12, [r2, #112]", + "and r12, r7, r8", + "eor lr, lr, r12", + "ldr r12, [r2, #68]", + "and lr, r12, lr", + "eor r6, r6, lr", + "ldr lr, [r2, #92]", + "and lr, r4, lr", + "str r8, [r2, #92]", + "ldr r8, [r2, #72]", + "eor r8, r8, lr", + "str lr, [r2, #72]", + "ldr lr, [r2, #88]", + "str r4, [r2, #116]", + "and r4, r7, lr", + "eor r8, r8, r4", + "and r5, r12, r5", + "eor r8, r8, r5", + "ldr r5, [r2, #64]", + "and r8, r5, r8", + "eor r4, r6, r8", + "ldr r8, [r2, #84]", + "eor r6, lr, r8", + "str r4, [r2, #120]", + "ldr r4, [r2, #108]", + "eor r4, r6, r4", + "str r6, [r2, #108]", + "ldr r6, [r2, #80]", + "ldr r5, [r2, #100]", + "eor r12, r6, r5", + "ldr lr, [r2, #60]", + "eor r12, r12, lr", + "ldr lr, [r2, #116]", + "and r5, lr, r6", + "eor r5, r12, r5", + "and r6, r7, r5", + "str r5, [r2, #124]", + "eor r5, r4, r6", + "str r6, [r2, #128]", + "ldr r6, [r2, #100]", + "str r12, [r2, #132]", + "eor r12, r8, r6", + "str r4, [r2, #136]", + "ldr r4, [r2, #60]", + "eor r12, r12, r4", + "and r4, lr, r12", + "eor r8, r8, r4", + "str r12, [r2, #84]", + "ldr r12, [r2, #88]", + "str r4, [r2, #140]", + "and r4, lr, r12", + "eor r12, r12, r4", + "and r12, r7, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #68]", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "eor r8, r8, r6", + "str r5, [r2, #112]", + "ldr r5, [r2, #60]", + "eor r8, r8, r5", + "ldr r12, [r2, #136]", + "eor r12, r12, r6", + "eor r12, r12, r5", + "and r12, r7, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #96]", + "str r8, [r2, #136]", + "eor r8, r12, r6", + "eor r8, r8, r5", + "and r12, lr, r8", + "str r8, [r2, #88]", + "ldr r8, [r2, #132]", + "eor lr, r8, r12", + "str r12, [r2, #144]", + "eor r12, r4, r6", + "eor r12, r12, r5", + "and r12, r7, r12", + "eor lr, lr, r12", + "str r4, [r2, #148]", + "ldr r4, [r2, #68]", + "and lr, r4, lr", + "str r12, [r2, #152]", + "ldr r12, [r2, #136]", + "eor r12, r12, lr", + "ldr lr, [r2, #64]", + "and r12, lr, r12", + "ldr lr, [r2, #112]", + "eor lr, lr, r12", + "ldr r12, [r2, #116]", + "str lr, [r2, #112]", + "and lr, r12, r8", + "ldr r12, [r2, #104]", + "eor r12, r12, lr", + "ldr lr, [r2, #124]", + "eor r8, lr, r6", + "eor r8, r8, r5", + "and r8, r7, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #128]", + "eor lr, lr, r8", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #80]", + "ldr r8, [r2, #140]", + "eor r8, lr, r8", + "ldr r5, [r2, #152]", + "eor r8, r8, r5", + "ldr r5, [r2, #72]", + "and r6, r7, r5", + "eor lr, lr, r6", + "and lr, r4, lr", + "eor r8, r8, lr", + "ldr lr, [r2, #64]", + "and r8, lr, r8", + "eor r6, r12, r8", + "ldr r8, [r2, #132]", + "eor r8, r8, r5", + "eor r8, r8, r7", + "ldr r5, [r2, #108]", + "ldr r12, [r2, #100]", + "eor r5, r5, r12", + "ldr r12, [r2, #60]", + "eor r5, r5, r12", + "ldr r12, [r2, #116]", + "and r12, r12, r5", + "ldr r5, [r2, #84]", + "eor r5, r5, r12", + "and r5, r7, r5", + "ldr r12, [r2, #92]", + "eor r12, r12, r5", + "and r12, r4, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #96]", + "ldr r5, [r2, #148]", + "eor r12, r12, r5", + "str r6, [r2, #96]", + "ldr r6, [r2, #88]", + "str r8, [r2, #92]", + "ldr r8, [r2, #144]", + "eor r8, r6, r8", + "and r8, r7, r8", + "eor r12, r12, r8", + "and r7, r7, r5", + "eor r6, r6, r7", + "and r4, r4, r6", + "eor r12, r12, r4", + "and lr, lr, r12", + "ldr r12, [r2, #92]", + "eor r7, r12, lr", + "ldr r4, [r2, #120]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #96]", + "and r4, r4, #1", + "ror r4, r4, #6", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #30", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #16", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #24", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #15", + "eor r4, r4, lr, lsr #24", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #16", + "eor r5, r5, lr, lsr #25", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #17", + "eor r6, r6, lr, lsr #26", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #18", + "eor r7, r7, lr, lsr #27", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #19", + "eor r8, r8, lr, lsr #28", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #20", + "eor r12, r12, lr, lsr #29", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r4, [r2, #68]", + "ldr r4, [r2, #60]", + "eor r6, r6, r4", + "str r6, [r2, #72]", + "eor r6, r7, lr", + "eor r6, r6, r4", + "str r8, [r2, #76]", + "and r8, r5, r7", + "eor r4, r6, r8", + "str r8, [r2, #80]", + "and r8, r12, r4", + "str r4, [r2, #84]", + "eor r4, r6, r8", + "str r8, [r2, #88]", + "eor r8, r7, r5", + "str r7, [r2, #92]", + "eor r7, r8, lr", + "str r6, [r2, #96]", + "ldr r6, [r2, #60]", + "eor r7, r7, r6", + "and r6, r12, r7", + "str r7, [r2, #100]", + "eor r7, r8, r6", + "str r8, [r2, #104]", + "ldr r8, [r2, #76]", + "and r7, r8, r7", + "eor r4, r4, r7", + "eor r7, r5, lr", + "str r12, [r2, #108]", + "ldr r12, [r2, #60]", + "eor r7, r7, r12", + "eor r12, r5, r6", + "str r6, [r2, #112]", + "and r6, r8, r12", + "str r5, [r2, #116]", + "eor r5, r7, r6", + "str r6, [r2, #120]", + "ldr r6, [r2, #64]", + "and r5, r6, r5", + "eor r4, r4, r5", + "ldr r5, [r2, #84]", + "str r7, [r2, #124]", + "eor r7, r5, lr", + "ldr r5, [r2, #60]", + "eor r7, r7, r5", + "str r4, [r2, #128]", + "ldr r4, [r2, #108]", + "and r7, r4, r7", + "ldr r6, [r2, #100]", + "eor r7, r6, r7", + "and r7, r8, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #80]", + "eor r7, r7, lr", + "eor r7, r7, r5", + "ldr r5, [r2, #116]", + "str lr, [r2, #80]", + "ldr lr, [r2, #96]", + "and r6, r5, lr", + "ldr r5, [r2, #72]", + "eor r5, r5, r6", + "and lr, r4, r5", + "eor r7, r7, lr", + "str r5, [r2, #72]", + "ldr r5, [r2, #104]", + "and r5, r8, r5", + "eor r7, r7, r5", + "str r5, [r2, #104]", + "ldr r5, [r2, #64]", + "and r7, r5, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #68]", + "and r5, r7, r12", + "ldr r7, [r2, #128]", + "eor r7, r7, r5", + "and r5, r4, r6", + "str r7, [r2, #128]", + "ldr r7, [r2, #100]", + "eor r7, r7, r5", + "ldr r4, [r2, #80]", + "str r5, [r2, #100]", + "eor r5, lr, r4", + "ldr r4, [r2, #60]", + "eor r5, r5, r4", + "and r5, r8, r5", + "eor r5, r7, r5", + "str r7, [r2, #132]", + "eor r7, r6, lr", + "str r6, [r2, #136]", + "ldr r6, [r2, #92]", + "str lr, [r2, #140]", + "ldr lr, [r2, #112]", + "eor lr, r6, lr", + "and lr, r8, lr", + "eor r7, r7, lr", + "ldr r6, [r2, #64]", + "and r7, r6, r7", + "eor r5, r5, r7", + "ldr r7, [r2, #80]", + "eor r12, r12, r7", + "eor r12, r12, r4", + "ldr r4, [r2, #68]", + "and r12, r4, r12", + "eor r5, r5, r12", + "ldr r12, [r2, #84]", + "str r5, [r2, #112]", + "ldr r5, [r2, #140]", + "eor r12, r12, r5", + "ldr r5, [r2, #96]", + "and r5, r8, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #116]", + "eor r5, r5, lr", + "and r5, r6, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #132]", + "eor r5, r5, r7", + "ldr lr, [r2, #60]", + "eor r5, r5, lr", + "ldr lr, [r2, #72]", + "ldr r7, [r2, #100]", + "eor lr, lr, r7", + "and lr, r8, lr", + "eor r5, r5, lr", + "ldr lr, [r2, #124]", + "ldr r8, [r2, #88]", + "eor lr, lr, r8", + "ldr r8, [r2, #104]", + "eor lr, lr, r8", + "and lr, r6, lr", + "eor r5, r5, lr", + "and lr, r4, r5", + "eor r12, r12, lr", + "ldr lr, [r2, #136]", + "ldr r8, [r2, #108]", + "eor r8, lr, r8", + "str r12, [r2, #108]", + "ldr r12, [r2, #92]", + "eor r12, r12, lr", + "eor r12, r12, r7", + "ldr r7, [r2, #76]", + "and r7, r7, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #88]", + "ldr r12, [r2, #80]", + "eor r7, r7, r12", + "ldr lr, [r2, #60]", + "eor r7, r7, lr", + "ldr r4, [r2, #120]", + "eor r7, r7, r4", + "and r6, r6, r7", + "eor r8, r8, r6", + "eor r5, r5, r12", + "eor r5, r5, lr", + "ldr lr, [r2, #68]", + "and lr, lr, r5", + "eor r7, r8, lr", + "ldr r4, [r2, #128]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #108]", + "and r4, r4, #1", + "ror r4, r4, #1", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #10", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #20", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #26", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #11", + "eor r4, r4, lr, lsr #18", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #12", + "eor r5, r5, lr, lsr #19", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #13", + "eor r6, r6, lr, lsr #20", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #14", + "eor r7, r7, lr, lsr #21", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #15", + "eor r8, r8, lr, lsr #22", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #16", + "eor r12, r12, lr, lsr #23", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r5, [r2, #64]", + "eor r5, r4, r4", + "str r6, [r2, #68]", + "ldr r6, [r2, #60]", + "eor r5, r5, r6", + "str r8, [r2, #72]", + "eor r8, r7, lr", + "eor r8, r8, r6", + "str r7, [r2, #76]", + "and r7, r8, r12", + "str r8, [r2, #80]", + "eor r8, r5, r7", + "eor r4, r4, lr", + "eor r4, r4, r6", + "str r5, [r2, #84]", + "and r5, r4, r8", + "str r8, [r2, #88]", + "eor r8, r12, r5", + "str r5, [r2, #92]", + "eor r5, r12, lr", + "eor r5, r5, r6", + "str r12, [r2, #96]", + "ldr r12, [r2, #80]", + "str r4, [r2, #100]", + "and r4, r12, r5", + "eor r12, r5, r4", + "str r4, [r2, #104]", + "ldr r4, [r2, #72]", + "eor r4, r4, lr", + "eor r4, r4, r6", + "and r6, r4, r12", + "eor r6, r8, r6", + "str r8, [r2, #72]", + "eor r8, r5, r7", + "str r12, [r2, #108]", + "and r12, r4, r8", + "str r8, [r2, #112]", + "ldr r8, [r2, #76]", + "eor r12, r8, r12", + "ldr r8, [r2, #68]", + "eor r8, r8, lr", + "str lr, [r2, #68]", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "and r12, r8, r12", + "eor r6, r6, r12", + "ldr r12, [r2, #100]", + "str r6, [r2, #116]", + "and r6, r12, r5", + "str r8, [r2, #120]", + "ldr r8, [r2, #80]", + "eor r6, r8, r6", + "str r5, [r2, #124]", + "ldr r5, [r2, #96]", + "eor lr, r5, r8", + "and r7, r12, r7", + "eor r7, lr, r7", + "and r7, r4, r7", + "eor r6, r6, r7", + "ldr r7, [r2, #108]", + "ldr r8, [r2, #68]", + "str lr, [r2, #128]", + "eor lr, r7, r8", + "ldr r5, [r2, #60]", + "eor lr, lr, r5", + "and lr, r12, lr", + "ldr r7, [r2, #124]", + "eor r5, r7, r12", + "and r5, r4, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #120]", + "and lr, r5, lr", + "eor r6, r6, lr", + "ldr lr, [r2, #64]", + "eor lr, lr, r8", + "ldr r7, [r2, #60]", + "eor lr, lr, r7", + "and r6, lr, r6", + "str lr, [r2, #64]", + "ldr lr, [r2, #116]", + "eor lr, lr, r6", + "ldr r6, [r2, #108]", + "str lr, [r2, #116]", + "and lr, r12, r6", + "ldr r6, [r2, #88]", + "eor r5, r6, lr", + "eor r5, r5, r4", + "ldr r6, [r2, #104]", + "str lr, [r2, #132]", + "eor lr, r6, r8", + "eor lr, lr, r7", + "and r7, r12, lr", + "ldr r8, [r2, #84]", + "eor r8, r8, r7", + "and r6, r12, r6", + "str lr, [r2, #104]", + "and lr, r4, r6", + "eor r8, r8, lr", + "ldr lr, [r2, #120]", + "and r8, lr, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "eor r6, r8, r6", + "and r6, r4, r6", + "ldr r8, [r2, #76]", + "eor r6, r8, r6", + "ldr r8, [r2, #96]", + "and r8, r12, r8", + "ldr r12, [r2, #124]", + "eor r12, r12, r8", + "str r8, [r2, #124]", + "and r8, r4, r12", + "eor r8, r7, r8", + "and r8, lr, r8", + "eor r6, r6, r8", + "ldr r8, [r2, #64]", + "and r6, r8, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #108]", + "str r5, [r2, #96]", + "ldr r5, [r2, #100]", + "str r12, [r2, #84]", + "eor r12, r6, r5", + "eor r12, r12, r4", + "ldr r8, [r2, #104]", + "ldr r6, [r2, #132]", + "eor r8, r8, r6", + "ldr r6, [r2, #128]", + "eor r5, r6, r7", + "and r5, r4, r5", + "eor r8, r8, r5", + "and r8, lr, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #68]", + "eor r5, r6, r8", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "ldr r8, [r2, #100]", + "and r6, r8, r5", + "str r5, [r2, #132]", + "ldr r5, [r2, #108]", + "eor r5, r5, r6", + "and r5, lr, r5", + "str r6, [r2, #108]", + "ldr r6, [r2, #88]", + "eor r6, r6, r5", + "ldr r5, [r2, #64]", + "and r6, r5, r6", + "eor r6, r12, r6", + "ldr r12, [r2, #80]", + "eor r12, r12, r7", + "ldr r7, [r2, #72]", + "and r7, r4, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #112]", + "str r6, [r2, #72]", + "eor r6, r7, r8", + "and r6, r4, r6", + "ldr r5, [r2, #84]", + "eor r5, r5, r6", + "and r5, lr, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #132]", + "ldr r6, [r2, #92]", + "eor r5, r5, r6", + "ldr r6, [r2, #76]", + "and r8, r8, r6", + "ldr r6, [r2, #128]", + "eor r6, r6, r8", + "and r6, r4, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #68]", + "eor r7, r7, r6", + "ldr r8, [r2, #60]", + "eor r7, r7, r8", + "str r12, [r2, #112]", + "ldr r12, [r2, #108]", + "eor r7, r7, r12", + "ldr r12, [r2, #124]", + "eor r12, r12, r6", + "eor r12, r12, r8", + "and r4, r4, r12", + "eor r7, r7, r4", + "and lr, lr, r7", + "eor r5, r5, lr", + "ldr lr, [r2, #64]", + "and lr, lr, r5", + "ldr r5, [r2, #112]", + "eor r7, r5, lr", + "ldr r4, [r2, #116]", + "ldr r5, [r2, #96]", + "ldr r6, [r2, #72]", + "and r4, r4, #1", + "ror r4, r4, #3", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #25", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #14", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #8", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #7", + "eor r4, r4, lr, lsr #12", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #8", + "eor r5, r5, lr, lsr #13", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #9", + "eor r6, r6, lr, lsr #14", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #10", + "eor r7, r7, lr, lsr #15", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #11", + "eor r8, r8, lr, lsr #16", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #12", + "eor r12, r12, lr, lsr #17", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r12, [r2, #64]", + "eor r12, r4, r4", + "str r4, [r2, #68]", + "ldr r4, [r2, #60]", + "eor r12, r12, r4", + "str r12, [r2, #72]", + "eor r12, r8, lr", + "eor r12, r12, r4", + "and r4, r7, r12", + "str r12, [r2, #76]", + "eor r12, r4, r5", + "str lr, [r2, #80]", + "eor lr, r8, r4", + "str r8, [r2, #84]", + "and r8, r5, r7", + "str r4, [r2, #88]", + "eor r4, lr, r8", + "and r4, r6, r4", + "eor r12, r12, r4", + "ldr r4, [r2, #80]", + "str lr, [r2, #92]", + "eor lr, r8, r4", + "str r8, [r2, #96]", + "ldr r8, [r2, #60]", + "eor lr, lr, r8", + "str r12, [r2, #100]", + "eor r12, r7, r4", + "eor r12, r12, r8", + "and r8, r5, r12", + "str r12, [r2, #104]", + "eor r12, r7, r8", + "str r8, [r2, #108]", + "and r8, r6, r12", + "eor lr, lr, r8", + "str r12, [r2, #112]", + "ldr r12, [r2, #64]", + "and lr, r12, lr", + "str r8, [r2, #116]", + "ldr r8, [r2, #100]", + "eor r8, r8, lr", + "ldr lr, [r2, #76]", + "str r8, [r2, #100]", + "eor r8, lr, r7", + "and r12, r5, r8", + "str r5, [r2, #120]", + "ldr r5, [r2, #88]", + "str r8, [r2, #124]", + "eor r8, r5, r12", + "and r8, r6, r8", + "ldr r5, [r2, #84]", + "and r7, r7, r5", + "eor r5, lr, r7", + "ldr lr, [r2, #124]", + "str r7, [r2, #128]", + "eor r7, lr, r4", + "ldr r4, [r2, #60]", + "eor r7, r7, r4", + "eor r7, r7, r12", + "and r7, r6, r7", + "eor r7, r5, r7", + "str r5, [r2, #132]", + "ldr r5, [r2, #64]", + "and r7, r5, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #68]", + "and r8, r7, r8", + "str r12, [r2, #136]", + "ldr r12, [r2, #100]", + "eor r12, r12, r8", + "ldr r8, [r2, #120]", + "str r12, [r2, #100]", + "ldr r12, [r2, #88]", + "and r4, r8, r12", + "ldr r12, [r2, #128]", + "eor lr, r12, r4", + "ldr r12, [r2, #84]", + "and r12, r8, r12", + "ldr r7, [r2, #72]", + "eor r7, r7, r12", + "str r4, [r2, #72]", + "and r4, r6, r7", + "eor lr, lr, r4", + "ldr r4, [r2, #92]", + "str r7, [r2, #84]", + "ldr r7, [r2, #108]", + "eor r4, r4, r7", + "and r12, r6, r12", + "eor r4, r4, r12", + "and r4, r5, r4", + "eor lr, lr, r4", + "and r4, r6, r8", + "str r12, [r2, #92]", + "ldr r12, [r2, #84]", + "eor r12, r12, r4", + "ldr r4, [r2, #104]", + "ldr r7, [r2, #72]", + "eor r4, r4, r7", + "ldr r7, [r2, #76]", + "str lr, [r2, #104]", + "and lr, r8, r7", + "and r8, r6, lr", + "eor r4, r4, r8", + "and r4, r5, r4", + "eor r12, r12, r4", + "ldr r4, [r2, #68]", + "and r12, r4, r12", + "ldr r8, [r2, #104]", + "eor r8, r8, r12", + "ldr r12, [r2, #124]", + "str r8, [r2, #104]", + "ldr r8, [r2, #108]", + "eor r12, r12, r8", + "str lr, [r2, #124]", + "ldr lr, [r2, #96]", + "eor r7, r7, lr", + "and r7, r6, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #88]", + "ldr lr, [r2, #80]", + "eor r8, r7, lr", + "ldr r4, [r2, #60]", + "eor r8, r8, r4", + "ldr r7, [r2, #120]", + "ldr r4, [r2, #128]", + "and lr, r7, r4", + "eor lr, r8, lr", + "str r8, [r2, #96]", + "ldr r8, [r2, #136]", + "and r8, r6, r8", + "eor lr, lr, r8", + "and lr, r5, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #92]", + "ldr r8, [r2, #80]", + "eor lr, lr, r8", + "ldr r8, [r2, #60]", + "eor lr, lr, r8", + "ldr r8, [r2, #88]", + "str r12, [r2, #60]", + "ldr r12, [r2, #72]", + "eor r8, r8, r12", + "eor r4, r4, r7", + "and r4, r6, r4", + "eor r8, r8, r4", + "and r8, r5, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #68]", + "and lr, r8, lr", + "ldr r4, [r2, #60]", + "eor r4, r4, lr", + "ldr lr, [r2, #132]", + "eor r12, lr, r7", + "str r4, [r2, #60]", + "ldr r4, [r2, #116]", + "eor r12, r12, r4", + "ldr r4, [r2, #112]", + "and r8, r5, r4", + "eor r12, r12, r8", + "ldr r8, [r2, #96]", + "str r12, [r2, #116]", + "ldr r12, [r2, #108]", + "eor r12, r8, r12", + "and r12, r6, r12", + "eor r4, r4, r12", + "and r7, r7, r8", + "eor r8, r8, r7", + "ldr r7, [r2, #124]", + "eor lr, lr, r7", + "and r6, r6, lr", + "eor r8, r8, r6", + "and r5, r5, r8", + "eor r4, r4, r5", + "ldr r5, [r2, #68]", + "and r5, r5, r4", + "ldr r4, [r2, #116]", + "eor r7, r4, r5", + "ldr r4, [r2, #100]", + "ldr r5, [r2, #104]", + "ldr r6, [r2, #60]", + "and r4, r4, #1", + "ror r4, r4, #19", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #11", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #29", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #4", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #3", + "eor r4, r4, lr, lsr #6", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #4", + "eor r5, r5, lr, lsr #7", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #5", + "eor r6, r6, lr, lsr #8", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #6", + "eor r7, r7, lr, lsr #9", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #7", + "eor r8, r8, lr, lsr #10", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #8", + "eor r12, r12, lr, lsr #11", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r5, [r2, #64]", + "eor r5, r4, r4", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "str r7, [r2, #72]", + "eor r7, r12, r4", + "str r5, [r2, #76]", + "and r5, r4, r12", + "str r4, [r2, #80]", + "and r4, r6, r5", + "str r12, [r2, #84]", + "eor r12, r7, r4", + "str r4, [r2, #88]", + "eor r4, r5, lr", + "eor r4, r4, r8", + "str r7, [r2, #92]", + "and r7, r6, r4", + "str r5, [r2, #96]", + "ldr r5, [r2, #76]", + "str r4, [r2, #100]", + "eor r4, r5, r7", + "str r7, [r2, #104]", + "ldr r7, [r2, #72]", + "and r5, r7, r4", + "eor r12, r12, r5", + "ldr r5, [r2, #84]", + "str r4, [r2, #108]", + "eor r4, r5, lr", + "eor r4, r4, r8", + "ldr r5, [r2, #80]", + "and r8, r5, r4", + "str r4, [r2, #112]", + "and r4, r6, r8", + "str r8, [r2, #116]", + "ldr r8, [r2, #76]", + "str lr, [r2, #120]", + "eor lr, r8, r4", + "ldr r8, [r2, #100]", + "str r4, [r2, #124]", + "and r4, r7, r8", + "eor lr, lr, r4", + "str r4, [r2, #128]", + "ldr r4, [r2, #68]", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #104]", + "and r8, r7, lr", + "ldr lr, [r2, #108]", + "eor lr, lr, r8", + "and r8, r6, r5", + "ldr r5, [r2, #96]", + "eor r8, r5, r8", + "and r8, r4, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #64]", + "and lr, r8, lr", + "eor r12, r12, lr", + "eor lr, r5, r6", + "str r12, [r2, #108]", + "ldr r12, [r2, #92]", + "ldr r8, [r2, #120]", + "eor r4, r12, r8", + "ldr r12, [r2, #60]", + "eor r4, r4, r12", + "ldr r12, [r2, #124]", + "eor r8, r4, r12", + "and r8, r7, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #84]", + "str r4, [r2, #132]", + "and r4, r6, r8", + "str r6, [r2, #136]", + "ldr r6, [r2, #76]", + "str lr, [r2, #140]", + "eor lr, r6, r4", + "eor r5, r8, r5", + "eor r6, r5, r12", + "and r6, r7, r6", + "eor lr, lr, r6", + "ldr r12, [r2, #68]", + "and lr, r12, lr", + "str r4, [r2, #96]", + "ldr r4, [r2, #140]", + "eor r4, r4, lr", + "ldr lr, [r2, #112]", + "ldr r8, [r2, #116]", + "str r4, [r2, #140]", + "eor r4, lr, r8", + "ldr r8, [r2, #80]", + "ldr lr, [r2, #120]", + "eor r8, r8, lr", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "ldr lr, [r2, #136]", + "and r8, lr, r8", + "eor r8, r4, r8", + "eor r8, r8, r6", + "ldr r6, [r2, #132]", + "str r4, [r2, #80]", + "and r4, lr, r6", + "and r6, r7, r5", + "eor r4, r4, r6", + "and r4, r12, r4", + "eor r8, r8, r4", + "ldr r4, [r2, #64]", + "and r8, r4, r8", + "ldr r6, [r2, #140]", + "eor r6, r6, r8", + "ldr r8, [r2, #120]", + "eor r5, r5, r8", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "and r8, lr, r8", + "str r6, [r2, #112]", + "eor r6, r5, r8", + "str r5, [r2, #60]", + "ldr r5, [r2, #84]", + "str r8, [r2, #120]", + "and r8, r7, r5", + "eor r6, r6, r8", + "str r8, [r2, #140]", + "ldr r8, [r2, #132]", + "ldr r5, [r2, #104]", + "eor r8, r8, r5", + "ldr r5, [r2, #100]", + "ldr r4, [r2, #96]", + "eor r5, r5, r4", + "and r5, r7, r5", + "eor r8, r8, r5", + "and r8, r12, r8", + "eor r6, r6, r8", + "ldr r8, [r2, #92]", + "and r8, lr, r8", + "and r8, r7, r8", + "ldr r5, [r2, #76]", + "eor r5, r5, r8", + "ldr r8, [r2, #124]", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #64]", + "and r5, r8, r5", + "eor r6, r6, r5", + "ldr r5, [r2, #116]", + "eor r5, r5, r4", + "str r6, [r2, #116]", + "ldr r6, [r2, #128]", + "eor r5, r5, r6", + "ldr r6, [r2, #84]", + "ldr r8, [r2, #120]", + "eor r8, r6, r8", + "ldr r4, [r2, #80]", + "and lr, lr, r4", + "eor r4, r4, lr", + "and r4, r7, r4", + "eor r8, r8, r4", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #60]", + "ldr r4, [r2, #88]", + "eor r8, r8, r4", + "eor r6, r6, lr", + "and r7, r7, r6", + "eor r8, r8, r7", + "ldr r7, [r2, #96]", + "ldr r6, [r2, #140]", + "eor r7, r7, r6", + "and r12, r12, r7", + "eor r8, r8, r12", + "ldr r12, [r2, #64]", + "and r12, r12, r8", + "eor r7, r5, r12", + "ldr r4, [r2, #108]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #116]", + "and r4, r4, #1", + "ror r4, r4, #7", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #22", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #12", + "eor r10, r10, r6", + "and r7, r7, #1", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #31", + "eor r4, r4, lr", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "eor r5, r5, lr, lsr #1", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #1", + "eor r6, r6, lr, lsr #2", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #2", + "eor r7, r7, lr, lsr #3", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #3", + "eor r8, r8, lr, lsr #4", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #4", + "eor r12, r12, lr, lsr #5", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r6, r6, r8", + "str r6, [r2, #72]", + "eor r6, r4, lr", + "eor r6, r6, r8", + "str r4, [r2, #76]", + "eor r4, r12, r6", + "eor r7, r7, lr", + "eor r7, r7, r8", + "str r6, [r2, #80]", + "eor r6, r4, r7", + "eor r5, r5, lr", + "eor r5, r5, r8", + "eor r6, r6, r5", + "str r4, [r2, #84]", + "ldr r4, [r2, #76]", + "str r6, [r2, #88]", + "and r6, r7, r4", + "ldr r4, [r2, #80]", + "and r8, r4, r12", + "str r12, [r2, #92]", + "and r12, r7, r8", + "str r7, [r2, #96]", + "eor r7, r4, r12", + "and r7, r5, r7", + "eor r7, r6, r7", + "str r12, [r2, #100]", + "ldr r12, [r2, #68]", + "eor r12, r12, lr", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r12, r12, r8", + "and r7, r12, r7", + "str r12, [r2, #104]", + "ldr r12, [r2, #88]", + "eor r12, r12, r7", + "ldr r7, [r2, #92]", + "str r12, [r2, #88]", + "eor r12, r7, lr", + "eor r12, r12, r8", + "and r8, r4, r12", + "str lr, [r2, #108]", + "ldr lr, [r2, #72]", + "str r12, [r2, #112]", + "eor r12, lr, r8", + "str r8, [r2, #116]", + "eor r8, r12, r6", + "and r8, r5, r8", + "eor r4, r4, r8", + "ldr r8, [r2, #68]", + "str r12, [r2, #80]", + "eor r12, r7, r8", + "str r6, [r2, #120]", + "ldr r6, [r2, #96]", + "and r7, r6, r12", + "eor lr, lr, r7", + "ldr r6, [r2, #112]", + "str r12, [r2, #72]", + "and r12, r5, r6", + "eor lr, lr, r12", + "str r12, [r2, #124]", + "ldr r12, [r2, #104]", + "and lr, r12, lr", + "eor r4, r4, lr", + "ldr lr, [r2, #64]", + "ldr r12, [r2, #108]", + "eor lr, lr, r12", + "str r5, [r2, #64]", + "ldr r5, [r2, #60]", + "eor lr, lr, r5", + "and r4, lr, r4", + "str lr, [r2, #128]", + "ldr lr, [r2, #88]", + "eor r4, lr, r4", + "eor lr, r8, r12", + "eor lr, lr, r5", + "str r4, [r2, #88]", + "eor r4, lr, r7", + "str r7, [r2, #132]", + "ldr r7, [r2, #72]", + "eor r7, r7, r12", + "eor r7, r7, r5", + "ldr r8, [r2, #96]", + "str lr, [r2, #72]", + "and lr, r8, r7", + "eor r6, r6, lr", + "str r7, [r2, #112]", + "ldr r7, [r2, #64]", + "and r6, r7, r6", + "eor r4, r4, r6", + "ldr r6, [r2, #100]", + "str lr, [r2, #136]", + "eor lr, r6, r12", + "eor lr, lr, r5", + "and r8, r7, r6", + "eor r8, lr, r8", + "str lr, [r2, #140]", + "ldr lr, [r2, #104]", + "and r8, lr, r8", + "eor r4, r4, r8", + "ldr r8, [r2, #92]", + "ldr r6, [r2, #116]", + "str r4, [r2, #144]", + "eor r4, r8, r6", + "ldr r8, [r2, #120]", + "eor r8, r4, r8", + "ldr r6, [r2, #84]", + "and r6, r7, r6", + "eor lr, r8, r6", + "eor r8, r8, r12", + "eor r8, r8, r5", + "eor r4, r4, r12", + "eor r4, r4, r5", + "and r4, r7, r4", + "eor r8, r8, r4", + "ldr r4, [r2, #104]", + "and r8, r4, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #128]", + "and lr, r8, lr", + "ldr r5, [r2, #144]", + "eor r5, r5, lr", + "ldr lr, [r2, #116]", + "str r5, [r2, #144]", + "ldr r5, [r2, #100]", + "eor r12, lr, r5", + "str r6, [r2, #84]", + "ldr r6, [r2, #96]", + "ldr lr, [r2, #72]", + "and r8, r6, lr", + "ldr r6, [r2, #92]", + "eor r6, r6, r8", + "and r8, r7, r6", + "eor r12, r12, r8", + "ldr r8, [r2, #136]", + "eor r8, lr, r8", + "and r8, r4, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #124]", + "eor lr, lr, r8", + "str r6, [r2, #72]", + "ldr r6, [r2, #68]", + "eor r5, r6, r5", + "eor r5, r5, r8", + "and r5, r4, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #128]", + "and lr, r5, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #140]", + "and lr, r7, lr", + "ldr r8, [r2, #72]", + "eor r8, r8, lr", + "ldr lr, [r2, #96]", + "str r12, [r2, #72]", + "ldr r12, [r2, #116]", + "and lr, lr, r12", + "eor r6, r6, lr", + "ldr lr, [r2, #76]", + "ldr r12, [r2, #132]", + "eor lr, lr, r12", + "and lr, r7, lr", + "eor lr, r6, lr", + "and lr, r4, lr", + "eor r8, r8, lr", + "ldr lr, [r2, #80]", + "ldr r12, [r2, #84]", + "eor lr, lr, r12", + "ldr r12, [r2, #108]", + "eor r6, r6, r12", + "ldr r12, [r2, #60]", + "eor r6, r6, r12", + "ldr r12, [r2, #112]", + "and r7, r7, r12", + "eor r6, r6, r7", + "and r4, r4, r6", + "eor lr, lr, r4", + "and r5, r5, lr", + "eor r7, r8, r5", + "ldr r4, [r2, #88]", + "ldr r5, [r2, #144]", + "ldr r6, [r2, #72]", + "and r4, r4, #1", + "ror r4, r4, #21", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #15", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #27", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #5", + "eor r10, r10, r7", + "mov lr, r10", + "mov r10, r11", + "mov r11, lr", + "add r0, r0, #8", + "subs r9, r9, #1", + "bne 21b", + "mov lr, r10", + "mov r10, r11", + "mov r11, lr", + "sub r0, r0, #136", + "mov r9, #16", + "22:", + "ldr lr, [r0, #4]", + "mov r4, r11", + "lsr r4, r4, #27", + "eor r4, r4, lr, lsr #10", + "and r4, r4, #1", + "ldr lr, [r0, #4]", + "mov r5, r11", + "lsr r5, r5, #28", + "eor r5, r5, lr, lsr #11", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #29", + "eor r6, r6, lr, lsr #12", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #30", + "eor r7, r7, lr, lsr #13", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #31", + "eor r8, r8, lr, lsr #14", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "eor r12, r12, lr, lsr #15", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, lr", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "and r7, r8, r6", + "str lr, [r2, #72]", + "eor lr, r4, r8", + "str r8, [r2, #76]", + "and r8, r5, lr", + "eor r8, r7, r8", + "str lr, [r2, #80]", + "eor lr, r6, r7", + "str r7, [r2, #84]", + "and r7, r5, lr", + "eor r7, r4, r7", + "and r7, r12, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #76]", + "str lr, [r2, #88]", + "and lr, r7, r4", + "str r4, [r2, #92]", + "ldr r4, [r2, #72]", + "str r6, [r2, #96]", + "eor r6, lr, r4", + "str r8, [r2, #100]", + "ldr r8, [r2, #60]", + "eor r6, r6, r8", + "str r12, [r2, #104]", + "and r12, r5, r6", + "str r6, [r2, #108]", + "eor r6, lr, r12", + "str lr, [r2, #112]", + "eor lr, r7, r4", + "eor lr, lr, r8", + "eor r8, lr, r12", + "str r12, [r2, #116]", + "ldr r12, [r2, #104]", + "and r4, r12, r8", + "eor r6, r6, r4", + "ldr r4, [r2, #68]", + "and r6, r4, r6", + "str r8, [r2, #120]", + "ldr r8, [r2, #100]", + "eor r8, r8, r6", + "and r7, r5, r7", + "ldr r6, [r2, #108]", + "str r8, [r2, #76]", + "eor r8, r6, r7", + "str r7, [r2, #100]", + "and r7, r5, lr", + "str lr, [r2, #124]", + "ldr lr, [r2, #96]", + "eor r6, lr, r7", + "and r6, r12, r6", + "eor r8, r8, r6", + "and r6, r5, lr", + "str r5, [r2, #128]", + "ldr r5, [r2, #88]", + "str r7, [r2, #132]", + "eor r7, r5, r6", + "and r7, r12, r7", + "and r7, r4, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r8, r7, r8", + "str r6, [r2, #136]", + "ldr r6, [r2, #76]", + "eor r6, r6, r8", + "ldr r8, [r2, #112]", + "eor lr, lr, r8", + "ldr r8, [r2, #132]", + "str r6, [r2, #112]", + "eor r6, lr, r8", + "ldr r7, [r2, #84]", + "ldr r4, [r2, #72]", + "eor r8, r7, r4", + "ldr r7, [r2, #60]", + "eor r8, r8, r7", + "ldr r7, [r2, #128]", + "and lr, r7, lr", + "eor lr, r8, lr", + "str r8, [r2, #96]", + "and r8, r12, lr", + "eor r6, r6, r8", + "eor r8, r5, r4", + "ldr r4, [r2, #60]", + "eor r8, r8, r4", + "ldr r4, [r2, #132]", + "eor r4, r8, r4", + "str r8, [r2, #132]", + "ldr r8, [r2, #84]", + "and r5, r7, r8", + "eor r8, r8, r5", + "and r8, r12, r8", + "eor r5, r4, r8", + "str r4, [r2, #84]", + "ldr r4, [r2, #68]", + "and r5, r4, r5", + "eor r6, r6, r5", + "eor lr, lr, r8", + "ldr r8, [r2, #92]", + "and r5, r7, r8", + "ldr r8, [r2, #96]", + "eor r7, r8, r5", + "and r7, r12, r7", + "ldr r8, [r2, #88]", + "eor r12, r8, r7", + "and r12, r4, r12", + "eor lr, lr, r12", + "ldr r12, [r2, #64]", + "and lr, r12, lr", + "eor r6, r6, lr", + "eor lr, r8, r5", + "str r6, [r2, #76]", + "ldr r6, [r2, #104]", + "ldr r8, [r2, #84]", + "and r12, r6, r8", + "eor lr, lr, r12", + "ldr r12, [r2, #108]", + "str r7, [r2, #140]", + "ldr r7, [r2, #136]", + "eor r12, r12, r7", + "ldr r7, [r2, #128]", + "str r5, [r2, #136]", + "ldr r5, [r2, #132]", + "and r5, r7, r5", + "ldr r7, [r2, #96]", + "eor r7, r7, r5", + "and r7, r6, r7", + "eor r12, r12, r7", + "and r12, r4, r12", + "eor lr, lr, r12", + "ldr r12, [r2, #116]", + "and r7, r6, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #92]", + "ldr r5, [r2, #136]", + "eor r7, r7, r5", + "ldr r5, [r2, #140]", + "eor r7, r7, r5", + "and r7, r4, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r8, r7, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #80]", + "ldr r5, [r2, #72]", + "eor r8, r8, r5", + "str lr, [r2, #80]", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "ldr r7, [r2, #128]", + "eor r8, r8, r7", + "eor r12, r12, r5", + "eor r12, r12, lr", + "and r12, r6, r12", + "eor r12, r8, r12", + "str r8, [r2, #116]", + "ldr r8, [r2, #120]", + "eor r8, r8, r5", + "eor r8, r8, lr", + "and r8, r6, r8", + "ldr lr, [r2, #124]", + "eor lr, lr, r8", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #88]", + "ldr r8, [r2, #100]", + "eor r8, lr, r8", + "and r8, r6, r8", + "ldr r5, [r2, #136]", + "eor r5, r5, r8", + "eor lr, lr, r7", + "and r6, r6, lr", + "ldr lr, [r2, #116]", + "eor lr, lr, r6", + "and r4, r4, lr", + "eor r5, r5, r4", + "ldr r4, [r2, #64]", + "and r4, r4, r5", + "eor r7, r12, r4", + "ldr r4, [r2, #112]", + "ldr r5, [r2, #76]", + "ldr r6, [r2, #80]", + "and r4, r4, #1", + "ror r4, r4, #31", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #23", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #17", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #9", + "eor r10, r10, r7", + "ldr lr, [r0, #4]", + "mov r4, r11", + "lsr r4, r4, #23", + "eor r4, r4, lr, lsr #4", + "and r4, r4, #1", + "ldr lr, [r0, #4]", + "mov r5, r11", + "lsr r5, r5, #24", + "eor r5, r5, lr, lsr #5", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #25", + "eor r6, r6, lr, lsr #6", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #26", + "eor r7, r7, lr, lsr #7", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #27", + "eor r8, r8, lr, lsr #8", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "lsr r12, r12, #28", + "eor r12, r12, lr, lsr #9", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "str r6, [r2, #72]", + "eor r6, r12, lr", + "eor r6, r6, r7", + "str r8, [r2, #76]", + "and r8, r5, r12", + "str r5, [r2, #80]", + "eor r5, r12, r8", + "str r12, [r2, #84]", + "and r12, r4, r5", + "eor r12, r6, r12", + "str r6, [r2, #88]", + "eor r6, r8, lr", + "eor r6, r6, r7", + "str r8, [r2, #92]", + "and r8, r4, r6", + "str r6, [r2, #96]", + "eor r6, r5, r8", + "str r8, [r2, #100]", + "ldr r8, [r2, #76]", + "and r6, r8, r6", + "eor r12, r12, r6", + "str r6, [r2, #104]", + "ldr r6, [r2, #80]", + "str r12, [r2, #108]", + "ldr r12, [r2, #88]", + "and r8, r6, r12", + "eor r6, r12, r8", + "eor r5, r5, lr", + "eor r5, r5, r7", + "and r12, r4, r5", + "str r5, [r2, #112]", + "eor r5, r6, r12", + "str r12, [r2, #116]", + "eor r12, r6, lr", + "eor r12, r12, r7", + "str r6, [r2, #120]", + "and r6, r4, r12", + "str r12, [r2, #124]", + "ldr r12, [r2, #80]", + "eor r6, r12, r6", + "ldr r7, [r2, #76]", + "and r6, r7, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #68]", + "and r5, r6, r5", + "ldr r6, [r2, #108]", + "eor r6, r6, r5", + "and r5, r4, r8", + "str r8, [r2, #108]", + "ldr r8, [r2, #72]", + "eor r5, r8, r5", + "ldr r8, [r2, #84]", + "str lr, [r2, #128]", + "eor lr, r8, r12", + "and r8, r4, lr", + "str r4, [r2, #132]", + "eor r4, r12, r8", + "and r4, r7, r4", + "eor r5, r5, r4", + "ldr r4, [r2, #64]", + "and r5, r4, r5", + "eor r6, r6, r5", + "ldr r5, [r2, #128]", + "eor lr, lr, r5", + "str r6, [r2, #136]", + "ldr r6, [r2, #60]", + "eor lr, lr, r6", + "ldr r6, [r2, #132]", + "ldr r5, [r2, #92]", + "and r5, r6, r5", + "eor r12, lr, r5", + "str r5, [r2, #92]", + "ldr r5, [r2, #112]", + "eor r5, r5, r8", + "and r5, r7, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #124]", + "ldr r8, [r2, #104]", + "eor r5, r5, r8", + "ldr r8, [r2, #68]", + "and r5, r8, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #120]", + "str lr, [r2, #104]", + "and lr, r6, r5", + "str r12, [r2, #124]", + "ldr r12, [r2, #84]", + "eor lr, r12, lr", + "and lr, r7, lr", + "ldr r4, [r2, #96]", + "eor lr, r4, lr", + "ldr r4, [r2, #88]", + "str lr, [r2, #112]", + "and lr, r6, r4", + "eor r5, r5, lr", + "and r12, r7, r12", + "eor r5, r5, r12", + "and r5, r8, r5", + "ldr r12, [r2, #112]", + "eor r12, r12, r5", + "ldr r5, [r2, #64]", + "and r12, r5, r12", + "str lr, [r2, #112]", + "ldr lr, [r2, #124]", + "eor lr, lr, r12", + "ldr r12, [r2, #104]", + "str lr, [r2, #124]", + "eor lr, r12, r6", + "eor lr, lr, r7", + "ldr r4, [r2, #96]", + "ldr r12, [r2, #92]", + "eor r5, r4, r12", + "and r5, r7, r5", + "eor r5, r6, r5", + "and r5, r8, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #80]", + "and r6, r6, r5", + "ldr r5, [r2, #72]", + "eor r5, r5, r6", + "ldr r12, [r2, #100]", + "eor r4, r4, r12", + "and r4, r7, r4", + "eor r5, r5, r4", + "and r6, r8, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #64]", + "and r5, r6, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #104]", + "eor r5, r5, r12", + "ldr r12, [r2, #116]", + "and r12, r7, r12", + "eor r5, r5, r12", + "ldr r12, [r2, #92]", + "ldr r4, [r2, #128]", + "str lr, [r2, #116]", + "eor lr, r12, r4", + "ldr r6, [r2, #60]", + "eor lr, lr, r6", + "ldr r6, [r2, #88]", + "ldr r4, [r2, #112]", + "eor r6, r6, r4", + "and r6, r7, r6", + "eor lr, lr, r6", + "and r8, r8, lr", + "eor r5, r5, r8", + "ldr r8, [r2, #108]", + "eor r8, r8, r12", + "ldr r12, [r2, #128]", + "eor r12, r8, r12", + "ldr lr, [r2, #60]", + "eor r12, r12, lr", + "and r7, r7, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #64]", + "and r7, r7, r8", + "eor r7, r5, r7", + "ldr r4, [r2, #136]", + "ldr r5, [r2, #124]", + "ldr r6, [r2, #116]", + "and r4, r4, #1", + "ror r4, r4, #18", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #2", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #28", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #13", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #19", + "eor r4, r4, lr, lsr #30", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #20", + "eor r5, r5, lr, lsr #31", + "and r5, r5, #1", + "ldr lr, [r0, #4]", + "mov r6, r11", + "lsr r6, r6, #21", + "eor r6, r6, lr", + "and r6, r6, #1", + "ldr lr, [r0, #4]", + "mov r7, r11", + "lsr r7, r7, #22", + "eor r7, r7, lr, lsr #1", + "and r7, r7, #1", + "ldr lr, [r0, #4]", + "mov r8, r11", + "lsr r8, r8, #23", + "eor r8, r8, lr, lsr #2", + "and r8, r8, #1", + "ldr lr, [r0, #4]", + "mov r12, r11", + "lsr r12, r12, #24", + "eor r12, r12, lr, lsr #3", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r7, [r2, #68]", + "ldr r7, [r2, #60]", + "eor r6, r6, r7", + "str r6, [r2, #72]", + "eor r6, r12, lr", + "eor r6, r6, r7", + "str r5, [r2, #76]", + "and r5, r8, r6", + "eor r7, r12, r5", + "str r5, [r2, #80]", + "and r5, r8, r12", + "str r8, [r2, #84]", + "eor r8, r6, r5", + "str r6, [r2, #88]", + "and r6, r4, r8", + "str r12, [r2, #92]", + "eor r12, r7, r6", + "str r7, [r2, #96]", + "eor r7, r8, lr", + "str lr, [r2, #100]", + "ldr lr, [r2, #60]", + "eor r7, r7, lr", + "and r5, r4, r5", + "eor lr, r7, r5", + "str r7, [r2, #104]", + "ldr r7, [r2, #76]", + "str r6, [r2, #108]", + "and r6, r7, lr", + "eor r6, r12, r6", + "str r12, [r2, #112]", + "and r12, r7, r8", + "eor lr, lr, r12", + "ldr r12, [r2, #68]", + "and lr, r12, lr", + "eor r6, r6, lr", + "ldr lr, [r2, #92]", + "and lr, r4, lr", + "str r8, [r2, #92]", + "ldr r8, [r2, #72]", + "eor r8, r8, lr", + "str lr, [r2, #72]", + "ldr lr, [r2, #88]", + "str r4, [r2, #116]", + "and r4, r7, lr", + "eor r8, r8, r4", + "and r5, r12, r5", + "eor r8, r8, r5", + "ldr r5, [r2, #64]", + "and r8, r5, r8", + "eor r4, r6, r8", + "ldr r8, [r2, #84]", + "eor r6, lr, r8", + "str r4, [r2, #120]", + "ldr r4, [r2, #108]", + "eor r4, r6, r4", + "str r6, [r2, #108]", + "ldr r6, [r2, #80]", + "ldr r5, [r2, #100]", + "eor r12, r6, r5", + "ldr lr, [r2, #60]", + "eor r12, r12, lr", + "ldr lr, [r2, #116]", + "and r5, lr, r6", + "eor r5, r12, r5", + "and r6, r7, r5", + "str r5, [r2, #124]", + "eor r5, r4, r6", + "str r6, [r2, #128]", + "ldr r6, [r2, #100]", + "str r12, [r2, #132]", + "eor r12, r8, r6", + "str r4, [r2, #136]", + "ldr r4, [r2, #60]", + "eor r12, r12, r4", + "and r4, lr, r12", + "eor r8, r8, r4", + "str r12, [r2, #84]", + "ldr r12, [r2, #88]", + "str r4, [r2, #140]", + "and r4, lr, r12", + "eor r12, r12, r4", + "and r12, r7, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #68]", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "eor r8, r8, r6", + "str r5, [r2, #112]", + "ldr r5, [r2, #60]", + "eor r8, r8, r5", + "ldr r12, [r2, #136]", + "eor r12, r12, r6", + "eor r12, r12, r5", + "and r12, r7, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #96]", + "str r8, [r2, #136]", + "eor r8, r12, r6", + "eor r8, r8, r5", + "and r12, lr, r8", + "str r8, [r2, #88]", + "ldr r8, [r2, #132]", + "eor lr, r8, r12", + "str r12, [r2, #144]", + "eor r12, r4, r6", + "eor r12, r12, r5", + "and r12, r7, r12", + "eor lr, lr, r12", + "str r4, [r2, #148]", + "ldr r4, [r2, #68]", + "and lr, r4, lr", + "str r12, [r2, #152]", + "ldr r12, [r2, #136]", + "eor r12, r12, lr", + "ldr lr, [r2, #64]", + "and r12, lr, r12", + "ldr lr, [r2, #112]", + "eor lr, lr, r12", + "ldr r12, [r2, #116]", + "str lr, [r2, #112]", + "and lr, r12, r8", + "ldr r12, [r2, #104]", + "eor r12, r12, lr", + "ldr lr, [r2, #124]", + "eor r8, lr, r6", + "eor r8, r8, r5", + "and r8, r7, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #128]", + "eor lr, lr, r8", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #80]", + "ldr r8, [r2, #140]", + "eor r8, lr, r8", + "ldr r5, [r2, #152]", + "eor r8, r8, r5", + "ldr r5, [r2, #72]", + "and r6, r7, r5", + "eor lr, lr, r6", + "and lr, r4, lr", + "eor r8, r8, lr", + "ldr lr, [r2, #64]", + "and r8, lr, r8", + "eor r6, r12, r8", + "ldr r8, [r2, #132]", + "eor r8, r8, r5", + "eor r8, r8, r7", + "ldr r5, [r2, #108]", + "ldr r12, [r2, #100]", + "eor r5, r5, r12", + "ldr r12, [r2, #60]", + "eor r5, r5, r12", + "ldr r12, [r2, #116]", + "and r12, r12, r5", + "ldr r5, [r2, #84]", + "eor r5, r5, r12", + "and r5, r7, r5", + "ldr r12, [r2, #92]", + "eor r12, r12, r5", + "and r12, r4, r12", + "eor r8, r8, r12", + "ldr r12, [r2, #96]", + "ldr r5, [r2, #148]", + "eor r12, r12, r5", + "str r6, [r2, #96]", + "ldr r6, [r2, #88]", + "str r8, [r2, #92]", + "ldr r8, [r2, #144]", + "eor r8, r6, r8", + "and r8, r7, r8", + "eor r12, r12, r8", + "and r7, r7, r5", + "eor r6, r6, r7", + "and r4, r4, r6", + "eor r12, r12, r4", + "and lr, lr, r12", + "ldr r12, [r2, #92]", + "eor r7, r12, lr", + "ldr r4, [r2, #120]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #96]", + "and r4, r4, #1", + "ror r4, r4, #6", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #30", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #16", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #24", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #15", + "eor r4, r4, lr, lsr #24", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #16", + "eor r5, r5, lr, lsr #25", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #17", + "eor r6, r6, lr, lsr #26", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #18", + "eor r7, r7, lr, lsr #27", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #19", + "eor r8, r8, lr, lsr #28", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #20", + "eor r12, r12, lr, lsr #29", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r4, [r2, #68]", + "ldr r4, [r2, #60]", + "eor r6, r6, r4", + "str r6, [r2, #72]", + "eor r6, r7, lr", + "eor r6, r6, r4", + "str r8, [r2, #76]", + "and r8, r5, r7", + "eor r4, r6, r8", + "str r8, [r2, #80]", + "and r8, r12, r4", + "str r4, [r2, #84]", + "eor r4, r6, r8", + "str r8, [r2, #88]", + "eor r8, r7, r5", + "str r7, [r2, #92]", + "eor r7, r8, lr", + "str r6, [r2, #96]", + "ldr r6, [r2, #60]", + "eor r7, r7, r6", + "and r6, r12, r7", + "str r7, [r2, #100]", + "eor r7, r8, r6", + "str r8, [r2, #104]", + "ldr r8, [r2, #76]", + "and r7, r8, r7", + "eor r4, r4, r7", + "eor r7, r5, lr", + "str r12, [r2, #108]", + "ldr r12, [r2, #60]", + "eor r7, r7, r12", + "eor r12, r5, r6", + "str r6, [r2, #112]", + "and r6, r8, r12", + "str r5, [r2, #116]", + "eor r5, r7, r6", + "str r6, [r2, #120]", + "ldr r6, [r2, #64]", + "and r5, r6, r5", + "eor r4, r4, r5", + "ldr r5, [r2, #84]", + "str r7, [r2, #124]", + "eor r7, r5, lr", + "ldr r5, [r2, #60]", + "eor r7, r7, r5", + "str r4, [r2, #128]", + "ldr r4, [r2, #108]", + "and r7, r4, r7", + "ldr r6, [r2, #100]", + "eor r7, r6, r7", + "and r7, r8, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #80]", + "eor r7, r7, lr", + "eor r7, r7, r5", + "ldr r5, [r2, #116]", + "str lr, [r2, #80]", + "ldr lr, [r2, #96]", + "and r6, r5, lr", + "ldr r5, [r2, #72]", + "eor r5, r5, r6", + "and lr, r4, r5", + "eor r7, r7, lr", + "str r5, [r2, #72]", + "ldr r5, [r2, #104]", + "and r5, r8, r5", + "eor r7, r7, r5", + "str r5, [r2, #104]", + "ldr r5, [r2, #64]", + "and r7, r5, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #68]", + "and r5, r7, r12", + "ldr r7, [r2, #128]", + "eor r7, r7, r5", + "and r5, r4, r6", + "str r7, [r2, #128]", + "ldr r7, [r2, #100]", + "eor r7, r7, r5", + "ldr r4, [r2, #80]", + "str r5, [r2, #100]", + "eor r5, lr, r4", + "ldr r4, [r2, #60]", + "eor r5, r5, r4", + "and r5, r8, r5", + "eor r5, r7, r5", + "str r7, [r2, #132]", + "eor r7, r6, lr", + "str r6, [r2, #136]", + "ldr r6, [r2, #92]", + "str lr, [r2, #140]", + "ldr lr, [r2, #112]", + "eor lr, r6, lr", + "and lr, r8, lr", + "eor r7, r7, lr", + "ldr r6, [r2, #64]", + "and r7, r6, r7", + "eor r5, r5, r7", + "ldr r7, [r2, #80]", + "eor r12, r12, r7", + "eor r12, r12, r4", + "ldr r4, [r2, #68]", + "and r12, r4, r12", + "eor r5, r5, r12", + "ldr r12, [r2, #84]", + "str r5, [r2, #112]", + "ldr r5, [r2, #140]", + "eor r12, r12, r5", + "ldr r5, [r2, #96]", + "and r5, r8, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #116]", + "eor r5, r5, lr", + "and r5, r6, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #132]", + "eor r5, r5, r7", + "ldr lr, [r2, #60]", + "eor r5, r5, lr", + "ldr lr, [r2, #72]", + "ldr r7, [r2, #100]", + "eor lr, lr, r7", + "and lr, r8, lr", + "eor r5, r5, lr", + "ldr lr, [r2, #124]", + "ldr r8, [r2, #88]", + "eor lr, lr, r8", + "ldr r8, [r2, #104]", + "eor lr, lr, r8", + "and lr, r6, lr", + "eor r5, r5, lr", + "and lr, r4, r5", + "eor r12, r12, lr", + "ldr lr, [r2, #136]", + "ldr r8, [r2, #108]", + "eor r8, lr, r8", + "str r12, [r2, #108]", + "ldr r12, [r2, #92]", + "eor r12, r12, lr", + "eor r12, r12, r7", + "ldr r7, [r2, #76]", + "and r7, r7, r12", + "eor r8, r8, r7", + "ldr r7, [r2, #88]", + "ldr r12, [r2, #80]", + "eor r7, r7, r12", + "ldr lr, [r2, #60]", + "eor r7, r7, lr", + "ldr r4, [r2, #120]", + "eor r7, r7, r4", + "and r6, r6, r7", + "eor r8, r8, r6", + "eor r5, r5, r12", + "eor r5, r5, lr", + "ldr lr, [r2, #68]", + "and lr, lr, r5", + "eor r7, r8, lr", + "ldr r4, [r2, #128]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #108]", + "and r4, r4, #1", + "ror r4, r4, #1", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #10", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #20", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #26", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #11", + "eor r4, r4, lr, lsr #18", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #12", + "eor r5, r5, lr, lsr #19", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #13", + "eor r6, r6, lr, lsr #20", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #14", + "eor r7, r7, lr, lsr #21", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #15", + "eor r8, r8, lr, lsr #22", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #16", + "eor r12, r12, lr, lsr #23", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r5, [r2, #64]", + "eor r5, r4, r4", + "str r6, [r2, #68]", + "ldr r6, [r2, #60]", + "eor r5, r5, r6", + "str r8, [r2, #72]", + "eor r8, r7, lr", + "eor r8, r8, r6", + "str r7, [r2, #76]", + "and r7, r8, r12", + "str r8, [r2, #80]", + "eor r8, r5, r7", + "eor r4, r4, lr", + "eor r4, r4, r6", + "str r5, [r2, #84]", + "and r5, r4, r8", + "str r8, [r2, #88]", + "eor r8, r12, r5", + "str r5, [r2, #92]", + "eor r5, r12, lr", + "eor r5, r5, r6", + "str r12, [r2, #96]", + "ldr r12, [r2, #80]", + "str r4, [r2, #100]", + "and r4, r12, r5", + "eor r12, r5, r4", + "str r4, [r2, #104]", + "ldr r4, [r2, #72]", + "eor r4, r4, lr", + "eor r4, r4, r6", + "and r6, r4, r12", + "eor r6, r8, r6", + "str r8, [r2, #72]", + "eor r8, r5, r7", + "str r12, [r2, #108]", + "and r12, r4, r8", + "str r8, [r2, #112]", + "ldr r8, [r2, #76]", + "eor r12, r8, r12", + "ldr r8, [r2, #68]", + "eor r8, r8, lr", + "str lr, [r2, #68]", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "and r12, r8, r12", + "eor r6, r6, r12", + "ldr r12, [r2, #100]", + "str r6, [r2, #116]", + "and r6, r12, r5", + "str r8, [r2, #120]", + "ldr r8, [r2, #80]", + "eor r6, r8, r6", + "str r5, [r2, #124]", + "ldr r5, [r2, #96]", + "eor lr, r5, r8", + "and r7, r12, r7", + "eor r7, lr, r7", + "and r7, r4, r7", + "eor r6, r6, r7", + "ldr r7, [r2, #108]", + "ldr r8, [r2, #68]", + "str lr, [r2, #128]", + "eor lr, r7, r8", + "ldr r5, [r2, #60]", + "eor lr, lr, r5", + "and lr, r12, lr", + "ldr r7, [r2, #124]", + "eor r5, r7, r12", + "and r5, r4, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #120]", + "and lr, r5, lr", + "eor r6, r6, lr", + "ldr lr, [r2, #64]", + "eor lr, lr, r8", + "ldr r7, [r2, #60]", + "eor lr, lr, r7", + "and r6, lr, r6", + "str lr, [r2, #64]", + "ldr lr, [r2, #116]", + "eor lr, lr, r6", + "ldr r6, [r2, #108]", + "str lr, [r2, #116]", + "and lr, r12, r6", + "ldr r6, [r2, #88]", + "eor r5, r6, lr", + "eor r5, r5, r4", + "ldr r6, [r2, #104]", + "str lr, [r2, #132]", + "eor lr, r6, r8", + "eor lr, lr, r7", + "and r7, r12, lr", + "ldr r8, [r2, #84]", + "eor r8, r8, r7", + "and r6, r12, r6", + "str lr, [r2, #104]", + "and lr, r4, r6", + "eor r8, r8, lr", + "ldr lr, [r2, #120]", + "and r8, lr, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "eor r6, r8, r6", + "and r6, r4, r6", + "ldr r8, [r2, #76]", + "eor r6, r8, r6", + "ldr r8, [r2, #96]", + "and r8, r12, r8", + "ldr r12, [r2, #124]", + "eor r12, r12, r8", + "str r8, [r2, #124]", + "and r8, r4, r12", + "eor r8, r7, r8", + "and r8, lr, r8", + "eor r6, r6, r8", + "ldr r8, [r2, #64]", + "and r6, r8, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #108]", + "str r5, [r2, #96]", + "ldr r5, [r2, #100]", + "str r12, [r2, #84]", + "eor r12, r6, r5", + "eor r12, r12, r4", + "ldr r8, [r2, #104]", + "ldr r6, [r2, #132]", + "eor r8, r8, r6", + "ldr r6, [r2, #128]", + "eor r5, r6, r7", + "and r5, r4, r5", + "eor r8, r8, r5", + "and r8, lr, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #68]", + "eor r5, r6, r8", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "ldr r8, [r2, #100]", + "and r6, r8, r5", + "str r5, [r2, #132]", + "ldr r5, [r2, #108]", + "eor r5, r5, r6", + "and r5, lr, r5", + "str r6, [r2, #108]", + "ldr r6, [r2, #88]", + "eor r6, r6, r5", + "ldr r5, [r2, #64]", + "and r6, r5, r6", + "eor r6, r12, r6", + "ldr r12, [r2, #80]", + "eor r12, r12, r7", + "ldr r7, [r2, #72]", + "and r7, r4, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #112]", + "str r6, [r2, #72]", + "eor r6, r7, r8", + "and r6, r4, r6", + "ldr r5, [r2, #84]", + "eor r5, r5, r6", + "and r5, lr, r5", + "eor r12, r12, r5", + "ldr r5, [r2, #132]", + "ldr r6, [r2, #92]", + "eor r5, r5, r6", + "ldr r6, [r2, #76]", + "and r8, r8, r6", + "ldr r6, [r2, #128]", + "eor r6, r6, r8", + "and r6, r4, r6", + "eor r5, r5, r6", + "ldr r6, [r2, #68]", + "eor r7, r7, r6", + "ldr r8, [r2, #60]", + "eor r7, r7, r8", + "str r12, [r2, #112]", + "ldr r12, [r2, #108]", + "eor r7, r7, r12", + "ldr r12, [r2, #124]", + "eor r12, r12, r6", + "eor r12, r12, r8", + "and r4, r4, r12", + "eor r7, r7, r4", + "and lr, lr, r7", + "eor r5, r5, lr", + "ldr lr, [r2, #64]", + "and lr, lr, r5", + "ldr r5, [r2, #112]", + "eor r7, r5, lr", + "ldr r4, [r2, #116]", + "ldr r5, [r2, #96]", + "ldr r6, [r2, #72]", + "and r4, r4, #1", + "ror r4, r4, #3", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #25", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #14", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #8", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #7", + "eor r4, r4, lr, lsr #12", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #8", + "eor r5, r5, lr, lsr #13", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #9", + "eor r6, r6, lr, lsr #14", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #10", + "eor r7, r7, lr, lsr #15", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #11", + "eor r8, r8, lr, lsr #16", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #12", + "eor r12, r12, lr, lsr #17", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r12, [r2, #64]", + "eor r12, r4, r4", + "str r4, [r2, #68]", + "ldr r4, [r2, #60]", + "eor r12, r12, r4", + "str r12, [r2, #72]", + "eor r12, r8, lr", + "eor r12, r12, r4", + "and r4, r7, r12", + "str r12, [r2, #76]", + "eor r12, r4, r5", + "str lr, [r2, #80]", + "eor lr, r8, r4", + "str r8, [r2, #84]", + "and r8, r5, r7", + "str r4, [r2, #88]", + "eor r4, lr, r8", + "and r4, r6, r4", + "eor r12, r12, r4", + "ldr r4, [r2, #80]", + "str lr, [r2, #92]", + "eor lr, r8, r4", + "str r8, [r2, #96]", + "ldr r8, [r2, #60]", + "eor lr, lr, r8", + "str r12, [r2, #100]", + "eor r12, r7, r4", + "eor r12, r12, r8", + "and r8, r5, r12", + "str r12, [r2, #104]", + "eor r12, r7, r8", + "str r8, [r2, #108]", + "and r8, r6, r12", + "eor lr, lr, r8", + "str r12, [r2, #112]", + "ldr r12, [r2, #64]", + "and lr, r12, lr", + "str r8, [r2, #116]", + "ldr r8, [r2, #100]", + "eor r8, r8, lr", + "ldr lr, [r2, #76]", + "str r8, [r2, #100]", + "eor r8, lr, r7", + "and r12, r5, r8", + "str r5, [r2, #120]", + "ldr r5, [r2, #88]", + "str r8, [r2, #124]", + "eor r8, r5, r12", + "and r8, r6, r8", + "ldr r5, [r2, #84]", + "and r7, r7, r5", + "eor r5, lr, r7", + "ldr lr, [r2, #124]", + "str r7, [r2, #128]", + "eor r7, lr, r4", + "ldr r4, [r2, #60]", + "eor r7, r7, r4", + "eor r7, r7, r12", + "and r7, r6, r7", + "eor r7, r5, r7", + "str r5, [r2, #132]", + "ldr r5, [r2, #64]", + "and r7, r5, r7", + "eor r8, r8, r7", + "ldr r7, [r2, #68]", + "and r8, r7, r8", + "str r12, [r2, #136]", + "ldr r12, [r2, #100]", + "eor r12, r12, r8", + "ldr r8, [r2, #120]", + "str r12, [r2, #100]", + "ldr r12, [r2, #88]", + "and r4, r8, r12", + "ldr r12, [r2, #128]", + "eor lr, r12, r4", + "ldr r12, [r2, #84]", + "and r12, r8, r12", + "ldr r7, [r2, #72]", + "eor r7, r7, r12", + "str r4, [r2, #72]", + "and r4, r6, r7", + "eor lr, lr, r4", + "ldr r4, [r2, #92]", + "str r7, [r2, #84]", + "ldr r7, [r2, #108]", + "eor r4, r4, r7", + "and r12, r6, r12", + "eor r4, r4, r12", + "and r4, r5, r4", + "eor lr, lr, r4", + "and r4, r6, r8", + "str r12, [r2, #92]", + "ldr r12, [r2, #84]", + "eor r12, r12, r4", + "ldr r4, [r2, #104]", + "ldr r7, [r2, #72]", + "eor r4, r4, r7", + "ldr r7, [r2, #76]", + "str lr, [r2, #104]", + "and lr, r8, r7", + "and r8, r6, lr", + "eor r4, r4, r8", + "and r4, r5, r4", + "eor r12, r12, r4", + "ldr r4, [r2, #68]", + "and r12, r4, r12", + "ldr r8, [r2, #104]", + "eor r8, r8, r12", + "ldr r12, [r2, #124]", + "str r8, [r2, #104]", + "ldr r8, [r2, #108]", + "eor r12, r12, r8", + "str lr, [r2, #124]", + "ldr lr, [r2, #96]", + "eor r7, r7, lr", + "and r7, r6, r7", + "eor r12, r12, r7", + "ldr r7, [r2, #88]", + "ldr lr, [r2, #80]", + "eor r8, r7, lr", + "ldr r4, [r2, #60]", + "eor r8, r8, r4", + "ldr r7, [r2, #120]", + "ldr r4, [r2, #128]", + "and lr, r7, r4", + "eor lr, r8, lr", + "str r8, [r2, #96]", + "ldr r8, [r2, #136]", + "and r8, r6, r8", + "eor lr, lr, r8", + "and lr, r5, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #92]", + "ldr r8, [r2, #80]", + "eor lr, lr, r8", + "ldr r8, [r2, #60]", + "eor lr, lr, r8", + "ldr r8, [r2, #88]", + "str r12, [r2, #60]", + "ldr r12, [r2, #72]", + "eor r8, r8, r12", + "eor r4, r4, r7", + "and r4, r6, r4", + "eor r8, r8, r4", + "and r8, r5, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #68]", + "and lr, r8, lr", + "ldr r4, [r2, #60]", + "eor r4, r4, lr", + "ldr lr, [r2, #132]", + "eor r12, lr, r7", + "str r4, [r2, #60]", + "ldr r4, [r2, #116]", + "eor r12, r12, r4", + "ldr r4, [r2, #112]", + "and r8, r5, r4", + "eor r12, r12, r8", + "ldr r8, [r2, #96]", + "str r12, [r2, #116]", + "ldr r12, [r2, #108]", + "eor r12, r8, r12", + "and r12, r6, r12", + "eor r4, r4, r12", + "and r7, r7, r8", + "eor r8, r8, r7", + "ldr r7, [r2, #124]", + "eor lr, lr, r7", + "and r6, r6, lr", + "eor r8, r8, r6", + "and r5, r5, r8", + "eor r4, r4, r5", + "ldr r5, [r2, #68]", + "and r5, r5, r4", + "ldr r4, [r2, #116]", + "eor r7, r4, r5", + "ldr r4, [r2, #100]", + "ldr r5, [r2, #104]", + "ldr r6, [r2, #60]", + "and r4, r4, #1", + "ror r4, r4, #19", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #11", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #29", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #4", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #3", + "eor r4, r4, lr, lsr #6", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "lsr r5, r5, #4", + "eor r5, r5, lr, lsr #7", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #5", + "eor r6, r6, lr, lsr #8", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #6", + "eor r7, r7, lr, lsr #9", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #7", + "eor r8, r8, lr, lsr #10", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #8", + "eor r12, r12, lr, lsr #11", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r5, [r2, #64]", + "eor r5, r4, r4", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "str r7, [r2, #72]", + "eor r7, r12, r4", + "str r5, [r2, #76]", + "and r5, r4, r12", + "str r4, [r2, #80]", + "and r4, r6, r5", + "str r12, [r2, #84]", + "eor r12, r7, r4", + "str r4, [r2, #88]", + "eor r4, r5, lr", + "eor r4, r4, r8", + "str r7, [r2, #92]", + "and r7, r6, r4", + "str r5, [r2, #96]", + "ldr r5, [r2, #76]", + "str r4, [r2, #100]", + "eor r4, r5, r7", + "str r7, [r2, #104]", + "ldr r7, [r2, #72]", + "and r5, r7, r4", + "eor r12, r12, r5", + "ldr r5, [r2, #84]", + "str r4, [r2, #108]", + "eor r4, r5, lr", + "eor r4, r4, r8", + "ldr r5, [r2, #80]", + "and r8, r5, r4", + "str r4, [r2, #112]", + "and r4, r6, r8", + "str r8, [r2, #116]", + "ldr r8, [r2, #76]", + "str lr, [r2, #120]", + "eor lr, r8, r4", + "ldr r8, [r2, #100]", + "str r4, [r2, #124]", + "and r4, r7, r8", + "eor lr, lr, r4", + "str r4, [r2, #128]", + "ldr r4, [r2, #68]", + "and lr, r4, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #104]", + "and r8, r7, lr", + "ldr lr, [r2, #108]", + "eor lr, lr, r8", + "and r8, r6, r5", + "ldr r5, [r2, #96]", + "eor r8, r5, r8", + "and r8, r4, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #64]", + "and lr, r8, lr", + "eor r12, r12, lr", + "eor lr, r5, r6", + "str r12, [r2, #108]", + "ldr r12, [r2, #92]", + "ldr r8, [r2, #120]", + "eor r4, r12, r8", + "ldr r12, [r2, #60]", + "eor r4, r4, r12", + "ldr r12, [r2, #124]", + "eor r8, r4, r12", + "and r8, r7, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #84]", + "str r4, [r2, #132]", + "and r4, r6, r8", + "str r6, [r2, #136]", + "ldr r6, [r2, #76]", + "str lr, [r2, #140]", + "eor lr, r6, r4", + "eor r5, r8, r5", + "eor r6, r5, r12", + "and r6, r7, r6", + "eor lr, lr, r6", + "ldr r12, [r2, #68]", + "and lr, r12, lr", + "str r4, [r2, #96]", + "ldr r4, [r2, #140]", + "eor r4, r4, lr", + "ldr lr, [r2, #112]", + "ldr r8, [r2, #116]", + "str r4, [r2, #140]", + "eor r4, lr, r8", + "ldr r8, [r2, #80]", + "ldr lr, [r2, #120]", + "eor r8, r8, lr", + "ldr lr, [r2, #60]", + "eor r8, r8, lr", + "ldr lr, [r2, #136]", + "and r8, lr, r8", + "eor r8, r4, r8", + "eor r8, r8, r6", + "ldr r6, [r2, #132]", + "str r4, [r2, #80]", + "and r4, lr, r6", + "and r6, r7, r5", + "eor r4, r4, r6", + "and r4, r12, r4", + "eor r8, r8, r4", + "ldr r4, [r2, #64]", + "and r8, r4, r8", + "ldr r6, [r2, #140]", + "eor r6, r6, r8", + "ldr r8, [r2, #120]", + "eor r5, r5, r8", + "ldr r8, [r2, #60]", + "eor r5, r5, r8", + "ldr r8, [r2, #112]", + "and r8, lr, r8", + "str r6, [r2, #112]", + "eor r6, r5, r8", + "str r5, [r2, #60]", + "ldr r5, [r2, #84]", + "str r8, [r2, #120]", + "and r8, r7, r5", + "eor r6, r6, r8", + "str r8, [r2, #140]", + "ldr r8, [r2, #132]", + "ldr r5, [r2, #104]", + "eor r8, r8, r5", + "ldr r5, [r2, #100]", + "ldr r4, [r2, #96]", + "eor r5, r5, r4", + "and r5, r7, r5", + "eor r8, r8, r5", + "and r8, r12, r8", + "eor r6, r6, r8", + "ldr r8, [r2, #92]", + "and r8, lr, r8", + "and r8, r7, r8", + "ldr r5, [r2, #76]", + "eor r5, r5, r8", + "ldr r8, [r2, #124]", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #64]", + "and r5, r8, r5", + "eor r6, r6, r5", + "ldr r5, [r2, #116]", + "eor r5, r5, r4", + "str r6, [r2, #116]", + "ldr r6, [r2, #128]", + "eor r5, r5, r6", + "ldr r6, [r2, #84]", + "ldr r8, [r2, #120]", + "eor r8, r6, r8", + "ldr r4, [r2, #80]", + "and lr, lr, r4", + "eor r4, r4, lr", + "and r4, r7, r4", + "eor r8, r8, r4", + "and r8, r12, r8", + "eor r5, r5, r8", + "ldr r8, [r2, #60]", + "ldr r4, [r2, #88]", + "eor r8, r8, r4", + "eor r6, r6, lr", + "and r7, r7, r6", + "eor r8, r8, r7", + "ldr r7, [r2, #96]", + "ldr r6, [r2, #140]", + "eor r7, r7, r6", + "and r12, r12, r7", + "eor r8, r8, r12", + "ldr r12, [r2, #64]", + "and r12, r12, r8", + "eor r7, r5, r12", + "ldr r4, [r2, #108]", + "ldr r5, [r2, #112]", + "ldr r6, [r2, #116]", + "and r4, r4, #1", + "ror r4, r4, #7", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #22", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #12", + "eor r10, r10, r6", + "and r7, r7, #1", + "eor r10, r10, r7", + "ldr lr, [r0, #0]", + "mov r4, r11", + "lsr r4, r4, #31", + "eor r4, r4, lr", + "and r4, r4, #1", + "ldr lr, [r0, #0]", + "mov r5, r11", + "eor r5, r5, lr, lsr #1", + "and r5, r5, #1", + "ldr lr, [r0, #0]", + "mov r6, r11", + "lsr r6, r6, #1", + "eor r6, r6, lr, lsr #2", + "and r6, r6, #1", + "ldr lr, [r0, #0]", + "mov r7, r11", + "lsr r7, r7, #2", + "eor r7, r7, lr, lsr #3", + "and r7, r7, #1", + "ldr lr, [r0, #0]", + "mov r8, r11", + "lsr r8, r8, #3", + "eor r8, r8, lr, lsr #4", + "and r8, r8, #1", + "ldr lr, [r0, #0]", + "mov r12, r11", + "lsr r12, r12, #4", + "eor r12, r12, lr, lsr #5", + "and r12, r12, #1", + "mov lr, #0", + "sub lr, lr, #1", + "str lr, [r2, #60]", + "eor lr, r4, r4", + "str r6, [r2, #64]", + "eor r6, r4, r4", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r6, r6, r8", + "str r6, [r2, #72]", + "eor r6, r4, lr", + "eor r6, r6, r8", + "str r4, [r2, #76]", + "eor r4, r12, r6", + "eor r7, r7, lr", + "eor r7, r7, r8", + "str r6, [r2, #80]", + "eor r6, r4, r7", + "eor r5, r5, lr", + "eor r5, r5, r8", + "eor r6, r6, r5", + "str r4, [r2, #84]", + "ldr r4, [r2, #76]", + "str r6, [r2, #88]", + "and r6, r7, r4", + "ldr r4, [r2, #80]", + "and r8, r4, r12", + "str r12, [r2, #92]", + "and r12, r7, r8", + "str r7, [r2, #96]", + "eor r7, r4, r12", + "and r7, r5, r7", + "eor r7, r6, r7", + "str r12, [r2, #100]", + "ldr r12, [r2, #68]", + "eor r12, r12, lr", + "str r8, [r2, #68]", + "ldr r8, [r2, #60]", + "eor r12, r12, r8", + "and r7, r12, r7", + "str r12, [r2, #104]", + "ldr r12, [r2, #88]", + "eor r12, r12, r7", + "ldr r7, [r2, #92]", + "str r12, [r2, #88]", + "eor r12, r7, lr", + "eor r12, r12, r8", + "and r8, r4, r12", + "str lr, [r2, #108]", + "ldr lr, [r2, #72]", + "str r12, [r2, #112]", + "eor r12, lr, r8", + "str r8, [r2, #116]", + "eor r8, r12, r6", + "and r8, r5, r8", + "eor r4, r4, r8", + "ldr r8, [r2, #68]", + "str r12, [r2, #80]", + "eor r12, r7, r8", + "str r6, [r2, #120]", + "ldr r6, [r2, #96]", + "and r7, r6, r12", + "eor lr, lr, r7", + "ldr r6, [r2, #112]", + "str r12, [r2, #72]", + "and r12, r5, r6", + "eor lr, lr, r12", + "str r12, [r2, #124]", + "ldr r12, [r2, #104]", + "and lr, r12, lr", + "eor r4, r4, lr", + "ldr lr, [r2, #64]", + "ldr r12, [r2, #108]", + "eor lr, lr, r12", + "str r5, [r2, #64]", + "ldr r5, [r2, #60]", + "eor lr, lr, r5", + "and r4, lr, r4", + "str lr, [r2, #128]", + "ldr lr, [r2, #88]", + "eor r4, lr, r4", + "eor lr, r8, r12", + "eor lr, lr, r5", + "str r4, [r2, #88]", + "eor r4, lr, r7", + "str r7, [r2, #132]", + "ldr r7, [r2, #72]", + "eor r7, r7, r12", + "eor r7, r7, r5", + "ldr r8, [r2, #96]", + "str lr, [r2, #72]", + "and lr, r8, r7", + "eor r6, r6, lr", + "str r7, [r2, #112]", + "ldr r7, [r2, #64]", + "and r6, r7, r6", + "eor r4, r4, r6", + "ldr r6, [r2, #100]", + "str lr, [r2, #136]", + "eor lr, r6, r12", + "eor lr, lr, r5", + "and r8, r7, r6", + "eor r8, lr, r8", + "str lr, [r2, #140]", + "ldr lr, [r2, #104]", + "and r8, lr, r8", + "eor r4, r4, r8", + "ldr r8, [r2, #92]", + "ldr r6, [r2, #116]", + "str r4, [r2, #144]", + "eor r4, r8, r6", + "ldr r8, [r2, #120]", + "eor r8, r4, r8", + "ldr r6, [r2, #84]", + "and r6, r7, r6", + "eor lr, r8, r6", + "eor r8, r8, r12", + "eor r8, r8, r5", + "eor r4, r4, r12", + "eor r4, r4, r5", + "and r4, r7, r4", + "eor r8, r8, r4", + "ldr r4, [r2, #104]", + "and r8, r4, r8", + "eor lr, lr, r8", + "ldr r8, [r2, #128]", + "and lr, r8, lr", + "ldr r5, [r2, #144]", + "eor r5, r5, lr", + "ldr lr, [r2, #116]", + "str r5, [r2, #144]", + "ldr r5, [r2, #100]", + "eor r12, lr, r5", + "str r6, [r2, #84]", + "ldr r6, [r2, #96]", + "ldr lr, [r2, #72]", + "and r8, r6, lr", + "ldr r6, [r2, #92]", + "eor r6, r6, r8", + "and r8, r7, r6", + "eor r12, r12, r8", + "ldr r8, [r2, #136]", + "eor r8, lr, r8", + "and r8, r4, r8", + "eor r12, r12, r8", + "ldr r8, [r2, #124]", + "eor lr, lr, r8", + "str r6, [r2, #72]", + "ldr r6, [r2, #68]", + "eor r5, r6, r5", + "eor r5, r5, r8", + "and r5, r4, r5", + "eor lr, lr, r5", + "ldr r5, [r2, #128]", + "and lr, r5, lr", + "eor r12, r12, lr", + "ldr lr, [r2, #140]", + "and lr, r7, lr", + "ldr r8, [r2, #72]", + "eor r8, r8, lr", + "ldr lr, [r2, #96]", + "str r12, [r2, #72]", + "ldr r12, [r2, #116]", + "and lr, lr, r12", + "eor r6, r6, lr", + "ldr lr, [r2, #76]", + "ldr r12, [r2, #132]", + "eor lr, lr, r12", + "and lr, r7, lr", + "eor lr, r6, lr", + "and lr, r4, lr", + "eor r8, r8, lr", + "ldr lr, [r2, #80]", + "ldr r12, [r2, #84]", + "eor lr, lr, r12", + "ldr r12, [r2, #108]", + "eor r6, r6, r12", + "ldr r12, [r2, #60]", + "eor r6, r6, r12", + "ldr r12, [r2, #112]", + "and r7, r7, r12", + "eor r6, r6, r7", + "and r4, r4, r6", + "eor lr, lr, r4", + "and r5, r5, lr", + "eor r7, r8, r5", + "ldr r4, [r2, #88]", + "ldr r5, [r2, #144]", + "ldr r6, [r2, #72]", + "and r4, r4, #1", + "ror r4, r4, #21", + "eor r10, r10, r4", + "and r5, r5, #1", + "ror r5, r5, #15", + "eor r10, r10, r5", + "and r6, r6, #1", + "ror r6, r6, #27", + "eor r10, r10, r6", + "and r7, r7, #1", + "ror r7, r7, #5", + "eor r10, r10, r7", + "mov lr, r10", + "mov r10, r11", + "mov r11, lr", + "sub r0, r0, #8", + "subs r9, r9, #1", + "bne 22b", + "mov lr, r10", + "mov r10, r11", + "mov r11, lr", + "mov r5, #0", + "mov r4, #0", + "mov r9, #1", + "mov r12, r11", + "lsr r12, r12, #24", + "and r12, r12, r9", + "ror r12, r12, #1", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #24", + "and r12, r12, r9", + "ror r12, r12, #2", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #16", + "and r12, r12, r9", + "ror r12, r12, #3", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #16", + "and r12, r12, r9", + "ror r12, r12, #4", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #8", + "and r12, r12, r9", + "ror r12, r12, #5", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #8", + "and r12, r12, r9", + "ror r12, r12, #6", + "eor r4, r4, r12", + "mov r12, r11", + "and r12, r12, r9", + "ror r12, r12, #7", + "eor r4, r4, r12", + "mov r12, r10", + "and r12, r12, r9", + "ror r12, r12, #8", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #25", + "and r12, r12, r9", + "ror r12, r12, #9", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #25", + "and r12, r12, r9", + "ror r12, r12, #10", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #17", + "and r12, r12, r9", + "ror r12, r12, #11", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #17", + "and r12, r12, r9", + "ror r12, r12, #12", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #9", + "and r12, r12, r9", + "ror r12, r12, #13", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #9", + "and r12, r12, r9", + "ror r12, r12, #14", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #1", + "and r12, r12, r9", + "ror r12, r12, #15", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #1", + "and r12, r12, r9", + "ror r12, r12, #16", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #26", + "and r12, r12, r9", + "ror r12, r12, #17", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #26", + "and r12, r12, r9", + "ror r12, r12, #18", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #18", + "and r12, r12, r9", + "ror r12, r12, #19", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #18", + "and r12, r12, r9", + "ror r12, r12, #20", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #10", + "and r12, r12, r9", + "ror r12, r12, #21", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #10", + "and r12, r12, r9", + "ror r12, r12, #22", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #2", + "and r12, r12, r9", + "ror r12, r12, #23", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #2", + "and r12, r12, r9", + "ror r12, r12, #24", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #27", + "and r12, r12, r9", + "ror r12, r12, #25", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #27", + "and r12, r12, r9", + "ror r12, r12, #26", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #19", + "and r12, r12, r9", + "ror r12, r12, #27", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #19", + "and r12, r12, r9", + "ror r12, r12, #28", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #11", + "and r12, r12, r9", + "ror r12, r12, #29", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #11", + "and r12, r12, r9", + "ror r12, r12, #30", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #3", + "and r12, r12, r9", + "ror r12, r12, #31", + "eor r4, r4, r12", + "mov r12, r10", + "lsr r12, r12, #3", + "and r12, r12, r9", + "eor r4, r4, r12", + "mov r12, r11", + "lsr r12, r12, #28", + "and r12, r12, r9", + "ror r12, r12, #1", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #28", + "and r12, r12, r9", + "ror r12, r12, #2", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #20", + "and r12, r12, r9", + "ror r12, r12, #3", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #20", + "and r12, r12, r9", + "ror r12, r12, #4", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #12", + "and r12, r12, r9", + "ror r12, r12, #5", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #12", + "and r12, r12, r9", + "ror r12, r12, #6", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #4", + "and r12, r12, r9", + "ror r12, r12, #7", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #4", + "and r12, r12, r9", + "ror r12, r12, #8", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #29", + "and r12, r12, r9", + "ror r12, r12, #9", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #29", + "and r12, r12, r9", + "ror r12, r12, #10", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #21", + "and r12, r12, r9", + "ror r12, r12, #11", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #21", + "and r12, r12, r9", + "ror r12, r12, #12", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #13", + "and r12, r12, r9", + "ror r12, r12, #13", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #13", + "and r12, r12, r9", + "ror r12, r12, #14", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #5", + "and r12, r12, r9", + "ror r12, r12, #15", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #5", + "and r12, r12, r9", + "ror r12, r12, #16", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #30", + "and r12, r12, r9", + "ror r12, r12, #17", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #30", + "and r12, r12, r9", + "ror r12, r12, #18", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #22", + "and r12, r12, r9", + "ror r12, r12, #19", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #22", + "and r12, r12, r9", + "ror r12, r12, #20", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #14", + "and r12, r12, r9", + "ror r12, r12, #21", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #14", + "and r12, r12, r9", + "ror r12, r12, #22", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #6", + "and r12, r12, r9", + "ror r12, r12, #23", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #6", + "and r12, r12, r9", + "ror r12, r12, #24", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #31", + "and r12, r12, r9", + "ror r12, r12, #25", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #31", + "and r12, r12, r9", + "ror r12, r12, #26", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #23", + "and r12, r12, r9", + "ror r12, r12, #27", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #23", + "and r12, r12, r9", + "ror r12, r12, #28", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #15", + "and r12, r12, r9", + "ror r12, r12, #29", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #15", + "and r12, r12, r9", + "ror r12, r12, #30", + "eor r5, r5, r12", + "mov r12, r11", + "lsr r12, r12, #7", + "and r12, r12, r9", + "ror r12, r12, #31", + "eor r5, r5, r12", + "mov r12, r10", + "lsr r12, r12, #7", + "and r12, r12, r9", + "eor r5, r5, r12", + "rev r4, r4", + "rev r5, r5", + "str r4, [r1, #0]", + "str r5, [r1, #4]", + "add r0, r0, #8", + "ldr r4, [r2, #0]", + "ldr r5, [r2, #4]", + "ldr r6, [r2, #8]", + "ldr r7, [r2, #12]", + "ldr r8, [r2, #16]", + "ldr r9, [r2, #20]", + "ldr r10, [r2, #24]", + "ldr r11, [r2, #28]", + "ldr lr, [r2, #32]", + "bx lr", + ) +} + +/// Triple DES ECB encryption (SP 800-38A §6.1) of `n` complete 8-byte blocks at `data`, in place, under the schedule written by `vg_triple_des_expand_key`. No padding is added or removed. For `n = 0`, no data is transformed. +/// +/// Contract: `VG.Spec.TripleDes.ecbEncryptContract`. Constant time: only pointers and `n` may affect timing, not the schedule or data. +/// +/// Baseline ARMv7, calling the verified Triple DES block primitive for each complete block. +/// +/// # Safety +/// +/// * `schedule` must be valid for reads of 384 bytes. +/// * `data` must be valid for reads and writes of `8 * n` bytes. +/// * `scratch` must be valid for reads and writes of 1024 bytes. +/// * The contents of `scratch` on return are unspecified. +/// * `data` and `scratch` must not overlap each other or `schedule` (distinct Rust objects never do). +/// * None of `schedule`, `data` and `scratch` may wrap around the end of the address space (no Rust object does). +#[unsafe(naked)] +pub(crate) unsafe extern "C" fn vg_triple_des_ecb_encrypt(schedule: *const [u8; 384], data: *mut [u8; 8], n: usize, scratch: *mut [u64; 128]) { + core::arch::naked_asm!( + "str lr, [r3, #512]", + "mov r12, r3", + "mov r3, r2", + "mov r2, r12", + "cmp r3, #0", + "beq 20f", + "22:", + "bl {vg_triple_des_encrypt_block}", + "add r1, r1, #8", + "subs r3, r3, #1", + "bne 22b", + "b 21f", + "20:", + "21:", + "ldr lr, [r2, #512]", + "bx lr", + vg_triple_des_encrypt_block = sym super::triple_des::vg_triple_des_encrypt_block, + ) +} + +/// Triple DES ECB decryption (SP 800-38A §6.1) of `n` complete 8-byte blocks at `data`, in place, under the schedule written by `vg_triple_des_expand_key`. No padding is added or removed. For `n = 0`, no data is transformed. +/// +/// Contract: `VG.Spec.TripleDes.ecbDecryptContract`. Constant time: only pointers and `n` may affect timing, not the schedule or data. +/// +/// Baseline ARMv7, calling the verified Triple DES block primitive for each complete block. +/// +/// # Safety +/// +/// * `schedule` must be valid for reads of 384 bytes. +/// * `data` must be valid for reads and writes of `8 * n` bytes. +/// * `scratch` must be valid for reads and writes of 1024 bytes. +/// * The contents of `scratch` on return are unspecified. +/// * `data` and `scratch` must not overlap each other or `schedule` (distinct Rust objects never do). +/// * None of `schedule`, `data` and `scratch` may wrap around the end of the address space (no Rust object does). +#[unsafe(naked)] +pub(crate) unsafe extern "C" fn vg_triple_des_ecb_decrypt(schedule: *const [u8; 384], data: *mut [u8; 8], n: usize, scratch: *mut [u64; 128]) { + core::arch::naked_asm!( + "str lr, [r3, #512]", + "mov r12, r3", + "mov r3, r2", + "mov r2, r12", + "cmp r3, #0", + "beq 20f", + "22:", + "bl {vg_triple_des_decrypt_block}", + "add r1, r1, #8", + "subs r3, r3, #1", + "bne 22b", + "b 21f", + "20:", + "21:", + "ldr lr, [r2, #512]", + "bx lr", + vg_triple_des_decrypt_block = sym super::triple_des::vg_triple_des_decrypt_block, + ) +} diff --git a/src/triple_des_ecb.rs b/src/triple_des_ecb.rs index b49448a43..3f85c81ec 100644 --- a/src/triple_des_ecb.rs +++ b/src/triple_des_ecb.rs @@ -3,7 +3,7 @@ //! Key expansion and ECB encryption/decryption use verified primitives. //! Each operation accepts complete eight-byte blocks, including empty input. -#![cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] +#![cfg(any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "arm"))] use crate::arch::triple_des::{ vg_triple_des_ecb_decrypt, vg_triple_des_ecb_encrypt, vg_triple_des_expand_key, diff --git a/tests/cavp/triple_des_ecb.rs b/tests/cavp/triple_des_ecb.rs index 1f6186de8..288b1c2fa 100644 --- a/tests/cavp/triple_des_ecb.rs +++ b/tests/cavp/triple_des_ecb.rs @@ -1,6 +1,6 @@ //! NIST CAVP ECB vectors, with unmodified sources under vectors/. -#![cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] +#![cfg(any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "arm"))] use std::collections::BTreeMap;