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;