diff --git a/README.md b/README.md
index 08a9a3cfa..3b7117e76 100644
--- a/README.md
+++ b/README.md
@@ -399,7 +399,7 @@ yours to keep:
✅ |
-❌ |
+✅ |
❌ |
diff --git a/bench/benches/primitives/triple_des_ecb.rs b/bench/benches/primitives/triple_des_ecb.rs
index a7d2a4f25..ced6a1ed7 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(target_arch = "x86_64")]
+#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
pub fn bench(c: &mut Criterion) {
use std::hint::black_box;
@@ -59,5 +59,5 @@ pub fn bench(c: &mut Criterion) {
}
}
-#[cfg(not(target_arch = "x86_64"))]
+#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
pub fn bench(_: &mut Criterion) {}
diff --git a/lean/VerifiedGarbage/Artifacts/TripleDes/AArch64.lean b/lean/VerifiedGarbage/Artifacts/TripleDes/AArch64.lean
new file mode 100644
index 000000000..a8d979a02
--- /dev/null
+++ b/lean/VerifiedGarbage/Artifacts/TripleDes/AArch64.lean
@@ -0,0 +1,56 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.VerifiedBlock
+import VerifiedGarbage.Proof.TripleDes.AArch64.Key.Verified
+import VerifiedGarbage.Proof.TripleDes.AArch64.Ecb.Verified
+
+namespace VG.Artifacts.TripleDes.AArch64
+
+def artifacts : List Artifact := [
+ { Spec.TripleDes.expandKeyApi with
+ target := AArch64.target
+ doc := Spec.TripleDes.expandKeyApi.doc
+ (notes := ["Baseline AArch64 scalar key expansion with fixed permutations and public round-count branches."])
+ code := Impl.TripleDes.AArch64.Key.expandKey
+ contract := Spec.TripleDes.expandKeyContract AArch64.abi
+ stack := 0
+ verified := Proof.TripleDes.AArch64.Key.verified
+ spSafe := Code.all_of_forall (fun _ => rfl) _ },
+ { Spec.TripleDes.encryptBlockApi with
+ target := AArch64.target
+ doc := Spec.TripleDes.encryptBlockApi.doc
+ (notes := ["Baseline AArch64 scalar Boolean S-box circuits; IP and FP shared across all three DES passes."])
+ code := Impl.TripleDes.AArch64.encryptBlock
+ contract := Spec.TripleDes.encryptBlockContract AArch64.abi
+ stack := 0
+ verified := Proof.TripleDes.AArch64.encrypt_verified
+ spSafe := Code.all_of_forall (fun _ => rfl) _ },
+ { Spec.TripleDes.decryptBlockApi with
+ target := AArch64.target
+ doc := Spec.TripleDes.decryptBlockApi.doc
+ (notes := ["Baseline AArch64 scalar Boolean S-box circuits with reverse EDE key order."])
+ code := Impl.TripleDes.AArch64.decryptBlock
+ contract := Spec.TripleDes.decryptBlockContract AArch64.abi
+ stack := 0
+ verified := Proof.TripleDes.AArch64.decrypt_verified
+ spSafe := Code.all_of_forall (fun _ => rfl) _ },
+ { Spec.TripleDes.ecbEncryptApi with
+ target := AArch64.target
+ doc := Spec.TripleDes.ecbEncryptApi.doc
+ (notes := ["Baseline AArch64, calling the verified Triple DES block primitive for each complete block."])
+ code := Impl.TripleDes.AArch64.Ecb.encrypt
+ contract := Spec.TripleDes.ecbEncryptContract AArch64.abi 0
+ stack := 0
+ ofSig := ⟨_, _, _, by unfold Spec.TripleDes.ecbEncryptContract Spec.TripleDes.ecbContract; rfl⟩
+ verified := Proof.TripleDes.AArch64.Ecb.encrypt_verified
+ spSafe := Code.all_of_forall (fun _ => rfl) _ },
+ { Spec.TripleDes.ecbDecryptApi with
+ target := AArch64.target
+ doc := Spec.TripleDes.ecbDecryptApi.doc
+ (notes := ["Baseline AArch64, calling the verified Triple DES block primitive for each complete block."])
+ code := Impl.TripleDes.AArch64.Ecb.decrypt
+ contract := Spec.TripleDes.ecbDecryptContract AArch64.abi 0
+ stack := 0
+ ofSig := ⟨_, _, _, by unfold Spec.TripleDes.ecbDecryptContract Spec.TripleDes.ecbContract; rfl⟩
+ verified := Proof.TripleDes.AArch64.Ecb.decrypt_verified
+ spSafe := Code.all_of_forall (fun _ => rfl) _ }]
+
+end VG.Artifacts.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Impl/TripleDes/AArch64/Block.lean b/lean/VerifiedGarbage/Impl/TripleDes/AArch64/Block.lean
new file mode 100644
index 000000000..d369c0dab
--- /dev/null
+++ b/lean/VerifiedGarbage/Impl/TripleDes/AArch64/Block.lean
@@ -0,0 +1,67 @@
+import VerifiedGarbage.Impl.TripleDes.AArch64.Common
+import VerifiedGarbage.Impl.TripleDes.AArch64.Sbox
+
+namespace VG.Impl.TripleDes.AArch64
+
+open VG.AArch64
+open VG.Spec.TripleDes (Direction)
+
+def savedRegs : List Reg := [.x19, .x20, .x21, .x22]
+
+def blockSave : List Instr := savedRegs.zipIdx.map fun (r, i) => .str .x r .x2 (8 * i)
+def blockRestore : List Instr := savedRegs.zipIdx.map fun (r, i) => .ldr .x r .x2 (8 * i)
+
+def blockLoad : List Instr :=
+ [.ldr .x .x3 .x1 0, .rev .x3 .x3] ++
+ permuteCode Spec.TripleDes.ip 64 .x10 .x3 .x11 .x12 ++
+ [.lsr .x .x19 .x10 32, rr .x20 .x10] ++ mask .x20 32
+
+def sboxInputs (i : Nat) : List Instr :=
+ [.ldr .x .x10 .x22 0, imm .x12 1] ++ (List.range 6).flatMap fun j =>
+ let k := 6 * i + 5 - j
+ [rr (q j) .x20] ++ shr (q j) (32 - Spec.TripleDes.expansion.getD k 1) ++
+ [rr .x11 .x10] ++ shr .x11 (47 - k) ++
+ [.logic .eor .x (q j) (q j) .x11, .logic .and .x (q j) (q j) .x12]
+
+def sboxOutputs (i : Nat) : List Instr :=
+ [imm .x10 1] ++ (List.range 4).flatMap fun j =>
+ let position := 4 * i + 4 - j
+ let dst := (Spec.TripleDes.p.toList.findIdx? (· == position)).getD 0
+ [.logic .and .x (q j) (q j) .x10] ++ placeBit (q j) (31 - dst) ++
+ [.logic .eor .x .x19 .x19 (q j)]
+
+def box (i : Nat) : List Instr := sboxInputs i ++ sboxCode i ++ sboxOutputs i
+
+def swapHalves : List Instr := [rr .x3 .x19, rr .x19 .x20, rr .x20 .x3]
+
+def roundBody : List Instr := (List.range 8).flatMap box ++ swapHalves
+
+def roundAdvance (d : Direction) : List Instr :=
+ [if d = .encrypt then .addImm .x .x22 .x22 8 else .subImm .x .x22 .x22 8,
+ .subImm .x .x21 .x21 1]
+
+def passStart (component : Nat) (d : Direction) : List Instr :=
+ [.addImm .x .x22 .x0 (128 * component + if d = .encrypt then 0 else 120),
+ imm .x21 16]
+
+def pass (component : Nat) (d : Direction) : Prog isa :=
+ .seq (.block (passStart component d))
+ (.seq (.loop (.block (roundBody ++ roundAdvance d)) (.nonzero .x .x21)) (.block swapHalves))
+
+def blockBody (d : Direction) : Prog isa :=
+ match d with
+ | .encrypt => .seq (pass 0 .encrypt) (.seq (pass 1 .decrypt) (pass 2 .encrypt))
+ | .decrypt => .seq (pass 2 .decrypt) (.seq (pass 1 .encrypt) (pass 0 .decrypt))
+
+def blockStore : List Instr :=
+ [.lsl .x .x3 .x19 32, .logic .eor .x .x3 .x3 .x20] ++
+ permuteCode Spec.TripleDes.fp 64 .x10 .x3 .x11 .x12 ++ [.rev .x3 .x10]
+
+def block (d : Direction) : Prog isa :=
+ .seq (.block (blockSave ++ blockLoad))
+ (.seq (blockBody d) (.block (blockStore ++ blockRestore ++ [.str .x .x3 .x1 0])))
+
+def encryptBlock : Prog isa := block .encrypt
+def decryptBlock : Prog isa := block .decrypt
+
+end VG.Impl.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Impl/TripleDes/AArch64/Common.lean b/lean/VerifiedGarbage/Impl/TripleDes/AArch64/Common.lean
new file mode 100644
index 000000000..f4ee175c5
--- /dev/null
+++ b/lean/VerifiedGarbage/Impl/TripleDes/AArch64/Common.lean
@@ -0,0 +1,26 @@
+import VerifiedGarbage.Spec.TripleDes
+import VerifiedGarbage.TCB.AArch64.Isa
+
+namespace VG.Impl.TripleDes.AArch64
+
+open VG.AArch64
+
+def rr (d n : Reg) : Instr := .addImm .x d n 0
+
+def imm (r : Reg) (n : Nat) : Instr := .movz .x r (BitVec.ofNat 16 n) 0
+
+def shr (r : Reg) (n : Nat) : List Instr := if n = 0 then [] else [.lsr .x r r n]
+
+def placeBit (r : Reg) (n : Nat) : List Instr := if n = 0 then [] else [.ror .x r r (64 - n)]
+
+/-- Keep exactly the low `n` bits with two fixed shifts. -/
+def mask (r : Reg) (n : Nat) : List Instr :=
+ [.lsl .x r r (64 - n), .lsr .x r r (64 - n)]
+
+def permuteCode {m : Nat} (positions : Vector Nat m) (n : Nat) (dst src tmp bit : Reg) : List Instr :=
+ [imm dst 0, imm bit 1] ++ (List.range m).flatMap fun j =>
+ [rr tmp src] ++ shr tmp (n - positions.getD j 1) ++
+ [.logic .and .x tmp tmp bit] ++ placeBit tmp (m - 1 - j) ++
+ [.logic .eor .x dst dst tmp]
+
+end VG.Impl.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Impl/TripleDes/AArch64/Ecb.lean b/lean/VerifiedGarbage/Impl/TripleDes/AArch64/Ecb.lean
new file mode 100644
index 000000000..d45ccaae8
--- /dev/null
+++ b/lean/VerifiedGarbage/Impl/TripleDes/AArch64/Ecb.lean
@@ -0,0 +1,27 @@
+import VerifiedGarbage.Impl.TripleDes.AArch64.Block
+
+namespace VG.Impl.TripleDes.AArch64.Ecb
+
+open VG.AArch64 VG.Impl.TripleDes.AArch64
+open VG.Spec.TripleDes (Direction)
+
+def save : List Instr := [.str .x .x23 .x3 512, .str .x .x30 .x3 520]
+def setup : List Instr := [rr .x23 .x2, rr .x2 .x3]
+def restore : List Instr := [.ldr .x .x23 .x2 512, .ldr .x .x30 .x2 520]
+
+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 := [.addImm .x .x1 .x1 8, .subImm .x .x23 .x23 1]
+
+def ecb (d : Direction) : Prog isa :=
+ .seq (.block (save ++ setup))
+ (.seq (.ite (.zero .x .x23) (.block [])
+ (.loop (.seq (blockCall d) (.block advance)) (.nonzero .x .x23))) (.block restore))
+
+def encrypt : Prog isa := ecb .encrypt
+def decrypt : Prog isa := ecb .decrypt
+
+end VG.Impl.TripleDes.AArch64.Ecb
diff --git a/lean/VerifiedGarbage/Impl/TripleDes/AArch64/ExpandKey.lean b/lean/VerifiedGarbage/Impl/TripleDes/AArch64/ExpandKey.lean
new file mode 100644
index 000000000..74011e187
--- /dev/null
+++ b/lean/VerifiedGarbage/Impl/TripleDes/AArch64/ExpandKey.lean
@@ -0,0 +1,50 @@
+import VerifiedGarbage.Impl.TripleDes.AArch64.Common
+
+namespace VG.Impl.TripleDes.AArch64.Key
+
+open VG.AArch64 VG.Impl.TripleDes.AArch64
+
+def savedRegs : List Reg := [.x19, .x20, .x21, .x22]
+
+def save : List Instr := savedRegs.zipIdx.map fun (r, i) => .str .x r .x3 (8 * i)
+def restore : List Instr := savedRegs.zipIdx.map fun (r, i) => .ldr .x r .x3 (8 * i)
+
+def load (offset component : Nat) : List Instr :=
+ [.ldr .x .x4 .x0 offset, .rev .x4 .x4] ++
+ permuteCode Spec.TripleDes.pc1 64 .x5 .x4 .x6 .x7 ++
+ [.lsr .x .x19 .x5 28, rr .x20 .x5] ++ mask .x20 28 ++
+ [imm .x21 0, .addImm .x .x22 .x2 (128 * component)]
+
+def rotate28 (r : Reg) (n : Nat) : List Instr :=
+ [.lsr .x .x4 r (28 - n), .ror .x r r (64 - n), .logic .eor .x r r .x4] ++ mask r 28
+
+def rotate (n : Nat) : Prog isa := .block (rotate28 .x19 n ++ rotate28 .x20 n)
+
+def rotation : Prog isa :=
+ .seq (.block [.lsr .x .x4 .x21 1])
+ (.ite (.zero .x .x4) (rotate 1)
+ (.seq (.block [.subImm .x .x4 .x21 8])
+ (.ite (.zero .x .x4) (rotate 1)
+ (.seq (.block [.subImm .x .x4 .x21 15])
+ (.ite (.zero .x .x4) (rotate 1) (rotate 2))))))
+
+def storeRound : List Instr :=
+ [.lsl .x .x4 .x19 28, .logic .eor .x .x4 .x4 .x20] ++
+ permuteCode Spec.TripleDes.pc2 56 .x5 .x4 .x6 .x7 ++
+ [.str .x .x5 .x22 0, .addImm .x .x22 .x22 8, .addImm .x .x21 .x21 1,
+ .subImm .x .x4 .x21 16]
+
+def component (offset index : Nat) : Prog isa :=
+ .seq (.block (load offset index)) (.loop (.seq rotation (.block storeRound)) (.nonzero .x .x4))
+
+def copyThird : List Instr :=
+ (List.range 16).flatMap fun j => [.ldr .x .x4 .x2 (8 * j), .str .x .x4 .x2 (256 + 8 * j)]
+
+def expandKey : Prog isa :=
+ .seq (.block save)
+ (.seq (component 0 0)
+ (.seq (component 8 1)
+ (.seq (.block [.subImm .x .x4 .x1 16])
+ (.seq (.ite (.zero .x .x4) (.block copyThird) (component 16 2)) (.block restore)))))
+
+end VG.Impl.TripleDes.AArch64.Key
diff --git a/lean/VerifiedGarbage/Impl/TripleDes/AArch64/Permutation.lean b/lean/VerifiedGarbage/Impl/TripleDes/AArch64/Permutation.lean
new file mode 100644
index 000000000..0d34855c8
--- /dev/null
+++ b/lean/VerifiedGarbage/Impl/TripleDes/AArch64/Permutation.lean
@@ -0,0 +1,12 @@
+import VerifiedGarbage.Impl.TripleDes.AArch64.Common
+
+namespace VG.Impl.TripleDes.AArch64
+
+open VG.AArch64
+
+def initialPermutation : Prog isa := .block (permuteCode Spec.TripleDes.ip 64 .x10 .x3 .x11 .x12)
+def finalPermutation : Prog isa := .block (permuteCode Spec.TripleDes.fp 64 .x10 .x3 .x11 .x12)
+def keyPermutation1 : Prog isa := .block (permuteCode Spec.TripleDes.pc1 64 .x5 .x4 .x6 .x7)
+def keyPermutation2 : Prog isa := .block (permuteCode Spec.TripleDes.pc2 56 .x5 .x4 .x6 .x7)
+
+end VG.Impl.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Impl/TripleDes/AArch64/Sbox.lean b/lean/VerifiedGarbage/Impl/TripleDes/AArch64/Sbox.lean
new file mode 100644
index 000000000..3625c677f
--- /dev/null
+++ b/lean/VerifiedGarbage/Impl/TripleDes/AArch64/Sbox.lean
@@ -0,0 +1,30 @@
+import VerifiedGarbage.Impl.TripleDes.Circuit
+import VerifiedGarbage.Impl.Aes.AArch64.Alloc
+
+namespace VG.Impl.TripleDes.AArch64
+
+open VG.AArch64
+
+def q : Nat → Reg
+ | 0 => .x3 | 1 => .x4 | 2 => .x5 | 3 => .x6 | 4 => .x7 | _ => .x8
+
+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 eight temporary registers; scratch slots 0–3 are reserved. -/
+def sboxCode (i : Nat) : List Instr :=
+ VG.Impl.Aes.AArch64.compile .x2 (Circuit.gates i) sboxIns (sboxOuts i)
+ [.x10, .x11, .x12, .x13, .x14, .x15, .x16, .x17] .x9 (List.range' 4 48)
+
+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.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Block.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Block.lean
new file mode 100644
index 000000000..cfc014b4d
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Block.lean
@@ -0,0 +1,85 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Head
+import VerifiedGarbage.Proof.TripleDes.AArch64.Tail
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.Impl.TripleDes.AArch64
+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 := [⟨s.gpr .x1, 8⟩, ⟨s.gpr .x2, 512⟩]
+
+structure BlockPost (keys : Schedule) (direction : Direction) (original s : State) : Prop where
+ result : Spec.TripleDes.blockAt s.mem (original.gpr .x1) =
+ blockResult keys direction (Spec.TripleDes.blockAt original.mem (original.gpr .x1))
+ 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 : Addr) (direction : Direction) (s : State)
+ (hp : HeadPre (Spec.TripleDes.componentSchedule keys) base s)
+ (hwrite : InRegions s.wr (s.gpr .x1) 8) :
+ 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₁.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.regs q hq).trans (hs₁.regs q (hkeep q hq))
+ have saved₂ := hs₁.saved.congr (hs₂.2.2.regs .x2 (by decide)) hs₂.2.2.frame
+ have savedRead₂ : ∀ i < 4, InRegions (s₂.rd ++ s₂.wr) (s₂.gpr .x2 + BitVec.ofNat 64 (8 * i)) 8 := by
+ rw [hs₂.2.2.rd, hs₂.2.2.wr, hs₁.rd, hs₁.wr, hregs₂ .x2 (by decide)]
+ exact hp.saveRead
+ have hwrite₂ : InRegions s₂.wr (s₂.gpr .x1) 8 := by
+ rw [hs₂.2.2.wr, hs₁.wr, hregs₂ .x1 (by decide)]
+ exact hwrite
+ apply WP.mono (blockTail_ok s s₂ _ hs₂.1 saved₂ savedRead₂ hwrite₂)
+ intro s₃ hs₃
+ refine ⟨?_, hs₃.saved, hs₃.rd.trans (hs₂.2.2.rd.trans hs₁.rd),
+ hs₃.wr.trans (hs₂.2.2.wr.trans hs₁.wr),
+ hs₃.sp.trans (hs₂.2.2.sp.trans hs₁.sp),
+ fun q hq => (hs₃.regs q hq).trans (hregs₂ q hq), ?_⟩
+ · have hresult := hs₃.result
+ rw [hregs₂ .x1 (by decide)] at hresult
+ exact hresult.trans (blockResult_core keys direction _)
+ · have hf₁ : Frame (blockRegions s) s.mem s₁.mem := hs₁.frame.sub (by
+ intro r hr
+ obtain rfl := List.mem_singleton.mp hr
+ exact ⟨⟨s.gpr .x2, 512⟩, by simp [blockRegions], Region.sub_prefix (by decide)⟩)
+ have hf₂ : Frame (blockRegions s) s₁.mem s₂.mem := hs₂.2.2.frame.sub (by
+ intro r hr
+ obtain rfl := List.mem_singleton.mp hr
+ refine ⟨⟨s.gpr .x2, 512⟩, by simp [blockRegions], ?_⟩
+ have hbase := hs₁.regs .x2 (by decide)
+ change Region.Sub ⟨s₁.gpr .x2 + BitVec.ofNat 64 32, 384⟩ ⟨s.gpr .x2, 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₂ .x1 (by decide)]
+ exact ⟨⟨s.gpr .x1, 8⟩, by simp [blockRegions], fun _ h => h⟩)
+ exact hf₁.trans (hf₂.trans hf₃)
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/BlockIO.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/BlockIO.lean
new file mode 100644
index 000000000..3757eb002
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/BlockIO.lean
@@ -0,0 +1,116 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Bytes
+import VerifiedGarbage.Proof.TripleDes.AArch64.Initial
+import VerifiedGarbage.Proof.TripleDes.AArch64.Word
+import VerifiedGarbage.Proof.TripleDes.AArch64.Box
+import VerifiedGarbage.Proof.Framework.AArch64.RegUpd
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.RegUpd VG.Impl.TripleDes.AArch64
+
+def loadKept : List Reg := [.x0, .x1, .x2, .x21, .x22, .x23, .x24, .x25, .x26, .x27, .x28, .x30]
+
+theorem readData_ok (s : State)
+ (hread : InRegions (s.rd ++ s.wr) (s.gpr .x1) 8) :
+ ∃ s', runBlock isa [.ldr .x .x3 .x1 0, .rev .x3 .x3] s = some s' ∧
+ s'.gpr .x3 = Spec.TripleDes.decodeBlock (Spec.TripleDes.blockAt s.mem (s.gpr .x1)) ∧
+ s'.mem = s.mem ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧
+ (∀ r, r ≠ .x3 → s'.gpr r = s.gpr r) := by
+ have hload := exec_ldr_x (t := .x3) (n := .x1) (off := 0) (by decide)
+ (by simpa only [BitVec.ofNat_eq_ofNat, BitVec.add_zero] using hread)
+ refine ⟨_, by
+ simp only [runBlock_cons, hload, runStep_some, runBlock_nil, exec_rev, State.read,
+ BitVec.setWidth_eq, gpr_write_self]
+ rfl, ?_, ?_, ?_, ?_, ?_, ?_⟩
+ · simp only [gpr_write_self, BitVec.setWidth_eq, BitVec.add_zero]
+ exact (decodeBlock_readW s.mem (s.gpr .x1)).symm
+ · simp only [mem_write]
+ · simp only [rd_write]
+ · simp only [wr_write]
+ · simp only [sp_write]
+ · intro r hr; simp only [gpr_write, hr, ite_false]
+
+def splitHalves : List Instr :=
+ [.lsr .x .x19 .x10 32, rr .x20 .x10] ++ mask .x20 32
+
+theorem splitHalves_ok (s : State) :
+ ∃ s', runBlock isa splitHalves s = some s' ∧
+ s'.gpr .x19 = s.gpr .x10 >>> 32 ∧
+ s'.gpr .x20 = ((s.gpr .x10).setWidth 32).setWidth 64 ∧
+ s'.mem = s.mem ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧
+ (∀ r, r ≠ .x19 → r ≠ .x20 → s'.gpr r = s.gpr r) := by
+ refine ⟨_, by
+ simp only [splitHalves, mask, rr, List.cons_append, List.nil_append, runBlock_cons,
+ runStep_some, runBlock_nil, exec, Size.bits,
+ show (32 : Nat) < 64 from by decide, show (0 : Nat) < 4096 from by decide,
+ ite_true, State.read, gpr_write, BitVec.setWidth_eq, BitVec.add_zero,
+ reduceCtorEq, ite_false]
+ rfl, ?_, ?_, ?_, ?_, ?_, ?_, ?_⟩
+ · simp only [gpr_write, reduceCtorEq, ite_false, ite_true, BitVec.setWidth_eq]
+ · simp only [gpr_write, reduceCtorEq, ite_false, ite_true, BitVec.setWidth_eq]
+ exact mask_word _ 32 (by decide) (by decide)
+ · simp only [mem_write]
+ · simp only [rd_write]
+ · simp only [wr_write]
+ · simp only [sp_write]
+ · intro r h19 h20; simp only [gpr_write, h19, h20, ite_false]
+
+theorem upperHalf_extend (x : BitVec 64) :
+ x >>> 32 = ((x >>> 32).setWidth 32).setWidth 64 := by
+ apply BitVec.eq_of_getLsbD_eq
+ intro j hj
+ simp only [BitVec.getLsbD_setWidth, BitVec.getLsbD_ushiftRight]
+ by_cases h : j < 32
+ · simp only [h, hj, decide_true, Bool.true_and]
+ · have hz : x.getLsbD (32 + j) = false := BitVec.getLsbD_of_ge _ _ (by omega)
+ simp only [h, hj, decide_false, decide_true, Bool.false_and, Bool.true_and, hz]
+
+theorem runAppend_some (xs ys : List Instr) (s t u : State)
+ (hx : runBlock isa xs s = some t) (hy : runBlock isa ys t = some u) :
+ runBlock isa (xs ++ ys) s = some u := by
+ calc
+ runBlock isa (xs ++ ys) s = (runBlock isa xs s).bind (runBlock isa ys) :=
+ runBoxes_append xs ys s
+ _ = (some t).bind (runBlock isa ys) := congrArg (fun v => v.bind (runBlock isa ys)) hx
+ _ = runBlock isa ys t := Option.bind_some t (runBlock isa ys)
+ _ = some u := hy
+
+
+theorem initial_preserves : loadKept.all (fun r =>
+ (instrs initialPermutation.lit).all (fun op => dstOf op != some r)) = true := by
+ decide +kernel
+
+theorem blockLoad_ok (s : State)
+ (hread : InRegions (s.rd ++ s.wr) (s.gpr .x1) 8) :
+ ∃ s', runBlock isa blockLoad s = some s' ∧
+ s'.gpr .x19 =
+ (((Spec.TripleDes.permute Spec.TripleDes.ip
+ (Spec.TripleDes.decodeBlock (Spec.TripleDes.blockAt s.mem (s.gpr .x1)))) >>> 32).setWidth 32).setWidth 64 ∧
+ s'.gpr .x20 =
+ ((Spec.TripleDes.permute Spec.TripleDes.ip
+ (Spec.TripleDes.decodeBlock (Spec.TripleDes.blockAt s.mem (s.gpr .x1)))).setWidth 32).setWidth 64 ∧
+ 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₁, word₁, mem₁, rd₁, wr₁, sp₁, regs₁⟩ := readData_ok s hread
+ obtain ⟨s₂, run₂, word₂, rd₂, wr₂, sp₂, mem₂, regs₂⟩ := initial_raw_ok s₁
+ obtain ⟨s₃, run₃, left₃, right₃, mem₃, rd₃, wr₃, sp₃, regs₃⟩ := splitHalves_ok s₂
+ have hword : s₂.gpr .x10 = Spec.TripleDes.permute Spec.TripleDes.ip
+ (Spec.TripleDes.decodeBlock (Spec.TripleDes.blockAt s.mem (s.gpr .x1))) :=
+ word₂.trans (congrArg (Spec.TripleDes.permute Spec.TripleDes.ip) word₁)
+ have hhead := runAppend_some _ _ _ _ _ run₁ run₂
+ have htail := runAppend_some _ _ _ _ _ hhead run₃
+ have hcode : blockLoad =
+ (([.ldr .x .x3 .x1 0, .rev .x3 .x3] : List Instr) ++
+ permuteCode Spec.TripleDes.ip 64 .x10 .x3 .x11 .x12) ++ splitHalves := by
+ simp only [blockLoad, splitHalves, List.append_assoc]
+ refine ⟨s₃, (congrArg (fun is => runBlock isa is s) hcode).trans htail, ?_, ?_,
+ mem₃.trans (mem₂.trans mem₁), rd₃.trans (rd₂.trans rd₁),
+ wr₃.trans (wr₂.trans wr₁), sp₃.trans (sp₂.trans sp₁), ?_⟩
+ · exact left₃.trans ((congrArg (fun x : BitVec 64 => x >>> 32) hword).trans (upperHalf_extend _))
+ · exact right₃.trans (congrArg (fun x : BitVec 64 => (x.setWidth 32).setWidth 64) hword)
+ · intro r hr
+ have hno := List.all_eq_true.mp initial_preserves r hr
+ have hne : r ≠ .x3 ∧ r ≠ .x19 ∧ r ≠ .x20 := by revert hr; cases r <;> decide
+ exact (regs₃ r hne.2.1 hne.2.2).trans ((regs₂ r hno).trans (regs₁ r hne.1))
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Body.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Body.lean
new file mode 100644
index 000000000..4cf0254a9
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Body.lean
@@ -0,0 +1,40 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Ready
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.Impl.TripleDes.AArch64
+open VG.Spec.TripleDes (Direction DesSchedule)
+open VG.Proof.TripleDes (desCore)
+
+theorem threePasses_ok (keys : Nat → DesSchedule) (base : Addr) (s : State) (x : BitVec 64)
+ (c₀ c₁ c₂ : Nat) (h₀ : c₀ < 3) (h₁ : c₁ < 3) (h₂ : c₂ < 3)
+ (d₀ d₁ d₂ : Direction) (hready : Ready keys base s) (hword : WordState x s) :
+ WP isa (.seq (pass c₀ d₀) (.seq (pass c₁ d₁) (pass c₂ 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) := by
+ apply WP.seq
+ apply WP.mono (pass_word_ok keys base s x c₀ h₀ d₀ hready hword)
+ intro s₁ hs₁
+ apply WP.seq
+ apply WP.mono (pass_word_ok keys base s₁ _ c₁ h₁ d₁ hs₁.2.1 hs₁.1)
+ intro s₂ hs₂
+ apply WP.mono (pass_word_ok keys base s₂ _ c₂ h₂ d₂ hs₂.2.1 hs₂.1)
+ intro s₃ hs₃
+ exact ⟨hs₃.1, hs₃.2.1, hs₁.2.2.trans (hs₂.2.2.trans hs₃.2.2)⟩
+
+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 : Addr) (s : State) (x : BitVec 64)
+ (direction : Direction) (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) := by
+ cases direction
+ · exact threePasses_ok keys base s x 0 1 2 (by decide) (by decide) (by decide)
+ .encrypt .decrypt .encrypt hready hword
+ · exact threePasses_ok keys base s x 2 1 0 (by decide) (by decide) (by decide)
+ .decrypt .encrypt .decrypt hready hword
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Box.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Box.lean
new file mode 100644
index 000000000..22f2f98e8
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Box.lean
@@ -0,0 +1,55 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Round
+import VerifiedGarbage.Proof.TripleDes.AArch64.Spills
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.Straight VG.Impl.TripleDes.AArch64
+
+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 : InRegions (s.rd ++ s.wr) (s.gpr .x22) 8) :
+ ∃ s', runBlock isa (box i) s = some s' ∧
+ s'.gpr .x19 = s.gpr .x19 ^^^
+ (boxPiece i (Spec.TripleDes.sBox i
+ (roundChunk i ((s.gpr .x20).setWidth 32)
+ ((s.mem.readW (s.gpr .x22) 64).setWidth 48)))).zeroExtend 64 ∧
+ 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 ∈ .x19 :: 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₁ .x2 (by decide)) (kept₁ .x2 (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 .x20).setWidth 32)
+ ((s.mem.readW (s.gpr .x22) 64).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₂ .x19 (by decide), kept₁ .x19 (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₂ run₂
+ have hregion : spillRegion s₁ = spillRegion s := by
+ simp only [spillRegion, kept₁ .x2 (by decide)]
+ rw [hregion, mem₁] at hf
+ rw [mem₃]
+ exact hf
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Bytes.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Bytes.lean
new file mode 100644
index 000000000..35ec8af6f
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Bytes.lean
@@ -0,0 +1,36 @@
+import VerifiedGarbage.Proof.TripleDes.Bytes
+import VerifiedGarbage.Proof.Framework.AArch64.Exec
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.Spec.TripleDes
+
+theorem decodeBlock_readW (m : Mem) (p : Addr) :
+ decodeBlock (blockAt m p) = rev64 (m.readW p 64) := by
+ rw [VG.Proof.TripleDes.decodeBlock_cat, rev64_readW]
+ simp only [VG.Proof.TripleDes.catBlock, blockAt, Vector.getElem_ofFn,
+ BitVec.add_assoc, BitVec.add_zero]
+ rfl
+
+
+theorem rev64_byte (x : BitVec 64) (i : Nat) (hi : i < 8) :
+ (rev64 x).extractLsb' (8 * i) 8 = (x >>> (8 * (7 - i))).setWidth 8 := by
+ have hcases : ∀ k < 8, k = 0 ∨ k = 1 ∨ k = 2 ∨ k = 3 ∨
+ k = 4 ∨ k = 5 ∨ k = 6 ∨ k = 7 := by decide
+ rcases hcases i hi with rfl | rfl | rfl | rfl | rfl | rfl | rfl | rfl
+ all_goals
+ simp (disch := decide) only [rev64, 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 (rev64 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 rev64_byte x i hi
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/ConstantTime.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/ConstantTime.lean
new file mode 100644
index 000000000..590811dc0
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/ConstantTime.lean
@@ -0,0 +1,45 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.FunctionsLit
+import VerifiedGarbage.Proof.Framework.AArch64.Taint
+
+/-! # Constant-time Triple DES block and key-expansion programs -/
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.Impl.TripleDes.AArch64
+
+/-- 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 [.x0, .x1, .x2]) encryptBlock := by
+ refine VG.Taint.constantTime (A := taint) (Taint.ofRegs [.x0, .x1, .x2]) ?_ (by taint_decide)
+ intro s₁ s₂ _ _ hp
+ exact ⟨hp.1, fun r hr => hp.2 r (Taint.mem_ofRegs.mp hr)⟩
+
+theorem decryptBlock_constantTime (pre : State → Prop) :
+ ConstantTime isa pre (PublicRegs [.x0, .x1, .x2]) decryptBlock := by
+ refine VG.Taint.constantTime (A := taint) (Taint.ofRegs [.x0, .x1, .x2]) ?_ (by taint_decide)
+ intro s₁ s₂ _ _ hp
+ exact ⟨hp.1, fun r hr => hp.2 r (Taint.mem_ofRegs.mp hr)⟩
+
+theorem expandKey_constantTime (pre : State → Prop) :
+ ConstantTime isa pre (PublicRegs [.x0, .x1, .x2, .x3]) Key.expandKey := by
+ refine VG.Taint.constantTime (A := taint) (Taint.ofRegs [.x0, .x1, .x2, .x3]) ?_ (by taint_decide)
+ intro s₁ s₂ _ _ hp
+ exact ⟨hp.1, fun r hr => hp.2 r (Taint.mem_ofRegs.mp hr)⟩
+
+theorem ecbEncrypt_constantTime (pre : State → Prop) :
+ ConstantTime isa pre (PublicRegs [.x0, .x1, .x2, .x3]) Ecb.encrypt := by
+ refine VG.Taint.constantTime (A := taint) (Taint.ofRegs [.x0, .x1, .x2, .x3]) ?_ (by taint_decide)
+ intro s₁ s₂ _ _ hp
+ exact ⟨hp.1, fun r hr => hp.2 r (Taint.mem_ofRegs.mp hr)⟩
+
+theorem ecbDecrypt_constantTime (pre : State → Prop) :
+ ConstantTime isa pre (PublicRegs [.x0, .x1, .x2, .x3]) Ecb.decrypt := by
+ refine VG.Taint.constantTime (A := taint) (Taint.ofRegs [.x0, .x1, .x2, .x3]) ?_ (by taint_decide)
+ intro s₁ s₂ _ _ hp
+ exact ⟨hp.1, fun r hr => hp.2 r (Taint.mem_ofRegs.mp hr)⟩
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Body.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Body.lean
new file mode 100644
index 000000000..3d982d245
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Body.lean
@@ -0,0 +1,56 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Ecb.Slice
+import VerifiedGarbage.Proof.TripleDes.AArch64.Ecb.Steps
+import VerifiedGarbage.Proof.TripleDes.EcbMemory
+
+namespace VG.Proof.TripleDes.AArch64.Ecb
+
+open VG VG.AArch64 VG.Spec.TripleDes
+
+structure BodyPost (d : Direction) (s : State) (n : Nat) (s' : State) : Prop where
+ ptr : s'.gpr .x1 = s.gpr .x1 + 8
+ count : s'.gpr .x23 = BitVec.ofNat 64 (n - 1)
+ flag : zeroCount s' = some (decide (n = 1))
+ reg : ∀ r ∈ kept, r ≠ .x1 → r ≠ .x23 → s'.gpr r = s.gpr r
+ callee : ∀ r ∈ savedAcrossCall, r ≠ .x23 → s'.gpr r = s.gpr r
+ rd : s'.rd = s.rd
+ wr : s'.wr = s.wr
+ mem : Frame ([dataR s, ⟨s.gpr .x2, 512⟩]) s.mem s'.mem
+ data : Spec.TripleDes.blockAt s'.mem (s.gpr .x1) =
+ blockResult (Spec.TripleDes.scheduleAt s.mem (s.gpr .x0)) d
+ (Spec.TripleDes.blockAt s.mem (s.gpr .x1))
+
+theorem body_ok (d : Direction) (s : State) (n : Nat) (hn : 1 ≤ n) (bound : n < 2 ^ 64)
+ (count : s.gpr .x23 = BitVec.ofNat 64 n) (hp : StepPre s) :
+ WP isa (.seq (Impl.TripleDes.AArch64.Ecb.blockCall d) (.block Impl.TripleDes.AArch64.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 .x23 - 1 = BitVec.ofNat 64 (n - 1) := by
+ rw [h₁.reg .x23 (by decide), count]
+ exact Offset.ofNat_sub_ofNat hn
+ refine ⟨by rw [ptr₂, h₁.reg .x1 (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 ≠ .x1 := by
+ have fact : ∀ r ∈ savedAcrossCall, r ≠ .x1 := 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)) : StepPre s' n :=
+ hp.slice (i := 1) (by omega) h.rd h.wr
+ (h.reg .x0 (by decide) (by decide) (by decide))
+ (h.reg .x2 (by decide) (by decide) (by decide))
+ h.ptr
+
+end VG.Proof.TripleDes.AArch64.Ecb
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Call.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Call.lean
new file mode 100644
index 000000000..baab618a1
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Call.lean
@@ -0,0 +1,74 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.VerifiedBlock
+import VerifiedGarbage.Impl.TripleDes.AArch64.Ecb
+import VerifiedGarbage.Proof.Framework.AArch64.Call
+
+/-! # Calling the verified block primitive from ECB -/
+
+namespace VG.Proof.TripleDes.AArch64.Ecb
+
+open VG VG.AArch64 VG.Impl.TripleDes.AArch64
+
+def savedAcrossCall : List Reg := [.x19, .x20, .x21, .x22, .x23, .x24, .x25, .x26, .x27, .x28]
+
+def kept : List Reg := [.x0, .x1, .x2, .x23, .x24]
+
+theorem block_keeps (d : Spec.TripleDes.Direction) :
+ ((instrs (block d)).all fun i => kept.all fun r => decide (dstOf i ≠ some r)) = true := by
+ cases d
+ · change ((instrs encryptBlock).all _) = true
+ rw [← Code.allInstrs_eq]; lit_decide
+ · change ((instrs decryptBlock).all _) = true
+ rw [← Code.allInstrs_eq]; lit_decide
+
+theorem block_keeps_reg (d : Spec.TripleDes.Direction) {r : Reg} (hr : r ∈ kept) :
+ ∀ i ∈ instrs (block d), dstOf i ≠ some r := by
+ intro i hi
+ have h := List.all_eq_true.mp (List.all_eq_true.mp (block_keeps d) i hi) r hr
+ simpa using h
+
+theorem block_correct' (d : Spec.TripleDes.Direction) (s : State) (hs : (blockContract d).pre s) :
+ ∃ t s', Exec isa (block d) s t s' ∧ abiPreserved s s' ∧ (blockContract d).post s s' := by
+ cases d
+ · exact encrypt_correct s hs
+ · exact decrypt_correct s hs
+
+theorem blockCall_eq (d : Spec.TripleDes.Direction) : Impl.TripleDes.AArch64.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 [⟨s.gpr .x0, 384⟩, ⟨s.gpr .x1, 8⟩, ⟨s.gpr .x2, 512⟩] (s.rd ++ s.wr)
+ writes : Covers [⟨s.gpr .x1, 8⟩, ⟨s.gpr .x2, 512⟩] s.wr
+ keyScratch : (Region.mk (s.gpr .x0) 384).Disjoint ⟨s.gpr .x2, 512⟩
+ dataScratch : (Region.mk (s.gpr .x1) 8).Disjoint ⟨s.gpr .x2, 512⟩
+
+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 [⟨s.gpr .x1, 8⟩, ⟨s.gpr .x2, 512⟩] s.mem s'.mem
+ output : Spec.TripleDes.blockAt s'.mem (s.gpr .x1) =
+ blockResult (Spec.TripleDes.scheduleAt s.mem (s.gpr .x0)) d (Spec.TripleDes.blockAt s.mem (s.gpr .x1))
+
+theorem call_ok (d : Spec.TripleDes.Direction) (s : State) (hp : CallPre s) :
+ WP isa (Impl.TripleDes.AArch64.Ecb.blockCall d) s (CallPost d s) := by
+ rw [blockCall_eq]
+ refine WP.call (k := blockContract d) (block_correct' d)
+ (rd := [⟨s.gpr .x0, 384⟩]) (wr := [⟨s.gpr .x1, 8⟩, ⟨s.gpr .x2, 512⟩]) ?_ hp.reads hp.writes ?_ (by cases d <;> rfl)
+ · simp only [blockContract, State.withRegions_gpr, State.withRegions_rd, State.withRegions_wr,
+ State.callEntry_gpr _ (by decide : Reg.x0 ∉ linkRegs),
+ State.callEntry_gpr _ (by decide : Reg.x1 ∉ linkRegs), State.callEntry_gpr _ (by decide : Reg.x2 ∉ linkRegs)]
+ exact ⟨trivial, trivial, hp.keyScratch, hp.dataScratch⟩
+ · intro s' rd wr sp frame callee regs out
+ have sep : ∀ r ∈ kept, r ∉ linkRegs := by decide
+ have saved : ∀ r ∈ savedAcrossCall, r ∈ preserved ∧ r ≠ .x30 := by decide
+ refine ⟨fun r hr => regs r (sep r hr) (block_keeps_reg d hr),
+ fun r hr => callee r (saved r hr).1 (saved r hr).2, rd, wr, frame, ?_⟩
+ change Spec.TripleDes.blockAt s'.mem _ = blockResult _ d _ at out
+ simp only [State.withRegions_gpr, State.withRegions_mem, State.callEntry_mem,
+ State.callEntry_gpr _ (by decide : Reg.x0 ∉ linkRegs),
+ State.callEntry_gpr _ (by decide : Reg.x1 ∉ linkRegs)] at out
+ exact out
+
+end VG.Proof.TripleDes.AArch64.Ecb
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Contract.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Contract.lean
new file mode 100644
index 000000000..4a0fe01ec
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Contract.lean
@@ -0,0 +1,23 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Ecb.IO
+import VerifiedGarbage.Proof.Framework.Contract
+import VerifiedGarbage.Spec.TripleDes.Contract
+
+namespace VG.Proof.TripleDes.AArch64.Ecb
+
+open VG VG.AArch64
+
+def contract (d : Spec.TripleDes.Direction) : Contract isa where
+ pre s :=
+ let key : Region := ⟨s.gpr .x0, 384⟩
+ let data : Region := ⟨s.gpr .x1, 8 * (s.gpr .x2).toNat⟩
+ let buf : Region := ⟨s.gpr .x3, 1024⟩
+ s.rd = [key] ∧ s.wr = [data, buf] ∧ key.Disjoint data ∧ key.Disjoint buf ∧
+ data.Disjoint buf ∧
+ (s.gpr .x1).toNat + 8 * (s.gpr .x2).toNat ≤ 2 ^ 64
+ post s s' :=
+ Spec.TripleDes.blocksAt s'.mem (s.gpr .x1) (s.gpr .x2).toNat =
+ Spec.TripleDes.ecb (Spec.TripleDes.scheduleAt s.mem (s.gpr .x0)) d
+ (Spec.TripleDes.blocksAt s.mem (s.gpr .x1) (s.gpr .x2).toNat)
+ pub := PublicRegs [.x0, .x1, .x2, .x3]
+
+end VG.Proof.TripleDes.AArch64.Ecb
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Correct.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Correct.lean
new file mode 100644
index 000000000..703dd3da6
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Correct.lean
@@ -0,0 +1,80 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Ecb.Contract
+
+namespace VG.Proof.TripleDes.AArch64.Ecb
+
+open VG VG.AArch64
+
+theorem ecb_correct (d : Spec.TripleDes.Direction) (s : State) (hs : (contract d).pre s) :
+ WP isa (Impl.TripleDes.AArch64.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⟩ := hs
+ have writes (i : Nat) (hi : i + 8 ≤ 1024) : InRegions s.wr (s.gpr .x3 + BitVec.ofNat 64 i) 8 := by
+ rw [hwr]
+ exact ⟨⟨s.gpr .x3, 1024⟩, by simp, Offset.contains_base _ hi (by omega)⟩
+ rw [Impl.TripleDes.AArch64.Ecb.ecb]
+ apply WP.seq
+ rw [WP.block_append_iff]
+ obtain ⟨s₁, run₁, keep₁⟩ := save_ok s (writes 512 (by decide)) (writes 520 (by decide))
+ refine WP.of_runBlock ⟨s₁, run₁, ?_⟩
+ obtain ⟨s₂, run₂, count₂, buf₂, 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₂
+ have key₂ := (keep₂.reg .x0 (by decide)).trans (g₁ .x0)
+ have data₂ := (keep₂.reg .x1 (by decide)).trans (g₁ .x1)
+ 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 [⟨s.gpr .x3, 1024⟩] s.mem s₂.mem := by
+ rw [mem₂]; exact savedMem_frame s
+ have initialKey := VG.Proof.TripleDes.scheduleAt_eq_of_frame (s.gpr .x0) scratchFrame
+ (by simpa using keyBuf)
+ have initialData := VG.Proof.TripleDes.blocksAt_frame scratchFrame (s.gpr .x1) (s.gpr .x2).toNat
+ (by simpa using dataBuf)
+ have hp₂ : StepPre s₂ (s.gpr .x2).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
+ apply WP.seq
+ apply WP.mono (maybeLoop_ok d s₂ (s.gpr .x2).toNat (by omega) hp₂
+ (by simpa using count₂))
+ intro s₃ h₃
+ have rd₃ := h₃.rd.trans rd₂
+ have wr₃ := h₃.wr.trans wr₂
+ have buf₃ := (h₃.reg .x2 (by decide) (by decide) (by decide)).trans buf₂
+ have readable (i : Nat) (hi : i + 8 ≤ 1024) :
+ InRegions (s₃.rd ++ s₃.wr) (s₃.gpr .x2 + BitVec.ofNat 64 i) 8 := by
+ rw [rd₃, wr₃, buf₃]
+ obtain ⟨r, hr, hc⟩ := writes i hi
+ exact ⟨r, List.mem_append_right _ hr, hc⟩
+ have counter : s₃.mem.readW (s₃.gpr .x2 + BitVec.ofNat 64 512) 64 = s.gpr .x23 := by
+ have h := h₃.scratchRead hp₂ 512 (by decide)
+ rw [buf₂, mem₂, savedMem_counter] at h
+ rw [buf₃]; exact h
+ have link : s₃.mem.readW (s₃.gpr .x2 + BitVec.ofNat 64 520) 64 = s.gpr .x30 := by
+ have h := h₃.scratchRead hp₂ 520 (by decide)
+ rw [buf₂, mem₂, savedMem_link] at h
+ rw [buf₃]; exact h
+ obtain ⟨s₄, run₄, counter₄, link₄, keep₄⟩ := restore_ok s₃ (s.gpr .x23) (s.gpr .x30)
+ (readable 512 (by decide)) (readable 520 (by decide)) counter link
+ refine WP.of_runBlock ⟨s₄, run₄, ?_⟩
+ constructor
+ · intro r hr
+ by_cases hc : r = .x23
+ · subst r; exact counter₄
+ by_cases hl : r = .x30
+ · subst r; exact link₄
+ have hsaved : ∀ r ∈ preserved, r ≠ .x30 → r ∈ savedAcrossCall := by decide
+ rw [keep₄.reg r (by simp [hc, hl]), h₃.callee r (hsaved r hr hl) hc]
+ have sep : ∀ r ∈ preserved, r ≠ .x23 → r ∉ [.x23, .x2] := by decide
+ exact (keep₂.reg r (sep r hr hc)).trans (g₁ r)
+ · have out := h₃.data
+ rw [key₂, data₂, initialKey, initialData] at out
+ change Spec.TripleDes.blocksAt s₄.mem (s.gpr .x1) (s.gpr .x2).toNat = _
+ rw [keep₄.mem]; exact out
+
+end VG.Proof.TripleDes.AArch64.Ecb
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/IO.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/IO.lean
new file mode 100644
index 000000000..f2eea01b3
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/IO.lean
@@ -0,0 +1,92 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Ecb.Loop
+
+/-! # ECB register saves, setup, and restoration -/
+
+namespace VG.Proof.TripleDes.AArch64.Ecb
+
+open VG VG.AArch64 VG.AArch64.RegUpd VG.Impl.TripleDes.AArch64
+open VG.Proof.Rc2.AArch64 (Keep)
+
+def savedMem (s : State) : Mem :=
+ (s.mem.writeW (s.gpr .x3 + BitVec.ofNat 64 512) (s.gpr .x23)).writeW
+ (s.gpr .x3 + BitVec.ofNat 64 520) (s.gpr .x30)
+
+theorem save_ok (s : State)
+ (w₁ : InRegions s.wr (s.gpr .x3 + BitVec.ofNat 64 512) 8)
+ (w₃ : InRegions s.wr (s.gpr .x3 + BitVec.ofNat 64 520) 8) :
+ ∃ s', runBlock isa Impl.TripleDes.AArch64.Ecb.save s = some s' ∧ Keep [] {s with mem := savedMem s} s' := by
+ refine ⟨_, by
+ simp only [Impl.TripleDes.AArch64.Ecb.save, runBlock_cons, runStep_some, runBlock_nil,
+ exec, addr, Size.bytes, Nat.reduceMod, Nat.reduceMul, Nat.reduceLT, and_self, ite_true, Option.bind_some,
+ State.store, State.read, BitVec.setWidth_eq, w₁, w₃]
+ rfl, ?_⟩
+ exact ⟨fun _ _ => rfl, rfl, rfl, rfl⟩
+
+theorem savedMem_frame (s : State) : Frame [⟨s.gpr .x3, 1024⟩] s.mem (savedMem s) :=
+ ((Frame.refl _ _).writeW List.mem_cons_self _
+ (Offset.contains_base _ (by decide : 512 + 8 ≤ 1024) (by decide))).writeW List.mem_cons_self _
+ (Offset.contains_base _ (by decide : 520 + 8 ≤ 1024) (by decide))
+
+theorem savedMem_counter (s : State) : (savedMem s).readW (s.gpr .x3 + BitVec.ofNat 64 512) 64 = s.gpr .x23 := by
+ rw [savedMem, Mem.readW_writeW_sep (Offset.sep _ (by decide : 512 + 8 ≤ 520 ∨ 520 + 8 ≤ 512)
+ (by decide) (by decide)) (by decide), Mem.readW_writeW_self64]
+
+theorem savedMem_link (s : State) : (savedMem s).readW (s.gpr .x3 + BitVec.ofNat 64 520) 64 = s.gpr .x30 := by
+ rw [savedMem, Mem.readW_writeW_self64]
+
+theorem setup_ok (s : State) :
+ ∃ s', runBlock isa Impl.TripleDes.AArch64.Ecb.setup s = some s' ∧
+ s'.gpr .x23 = s.gpr .x2 ∧ s'.gpr .x2 = s.gpr .x3 ∧ Keep [.x23, .x2] s s' := by
+ refine ⟨_, by
+ simp only [Impl.TripleDes.AArch64.Ecb.setup, rr, runBlock_cons, exec]
+ rfl, ?_⟩
+ refine ⟨?_, ?_, ?_⟩
+ · simp [gpr_write, State.read, BitVec.add_zero, BitVec.setWidth_eq]
+ · simp [gpr_write, State.read, BitVec.add_zero, BitVec.setWidth_eq]
+ · constructor
+ · intro r hr
+ simp only [List.mem_cons, List.not_mem_nil, or_false, not_or] at hr
+ simp only [gpr_write, BitVec.setWidth_eq, hr.1, hr.2, ite_false]
+ · simp only [mem_write]
+ · simp only [rd_write]
+ · simp only [wr_write]
+
+theorem restore_ok (s : State) (b lr : BitVec 64)
+ (r₁ : InRegions (s.rd ++ s.wr) (s.gpr .x2 + BitVec.ofNat 64 512) 8)
+ (r₃ : InRegions (s.rd ++ s.wr) (s.gpr .x2 + BitVec.ofNat 64 520) 8)
+ (v₁ : s.mem.readW (s.gpr .x2 + BitVec.ofNat 64 512) 64 = b)
+ (v₃ : s.mem.readW (s.gpr .x2 + BitVec.ofNat 64 520) 64 = lr) :
+ ∃ s', runBlock isa Impl.TripleDes.AArch64.Ecb.restore s = some s' ∧
+ s'.gpr .x23 = b ∧ s'.gpr .x30 = lr ∧ Keep [.x23, .x30] s s' := by
+ change s.mem.read _ 8 = b at v₁
+ change s.mem.read _ 8 = lr at v₃
+ refine ⟨_, by
+ simp only [Impl.TripleDes.AArch64.Ecb.restore, runBlock_cons, runStep_some, runBlock_nil,
+ exec, addr, Size.bytes, Nat.reduceMod, Nat.reduceMul, Nat.reduceLT, and_self, ite_true, Option.bind_some,
+ State.load, BitVec.setWidth_eq, gpr_write, mem_write, rd_write, wr_write,
+ r₁, r₃, reduceCtorEq, ite_false, Option.map_some, v₁, v₃]
+ rfl, ?_⟩
+ refine ⟨?_, gpr_write_self _ _ _ _, ?_⟩
+ · simp [gpr_write, BitVec.setWidth_eq]
+ · constructor
+ · intro r hr
+ simp only [List.mem_cons, List.not_mem_nil, or_false, not_or] at hr
+ simp only [gpr_write, BitVec.setWidth_eq, hr.1, hr.2, ite_false]
+ · simp only [mem_write]
+ · simp only [rd_write]
+ · simp only [wr_write]
+
+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 + 8 ≤ 1024) :
+ s'.mem.readW (s.gpr .x2 + BitVec.ofNat 64 i) 64 =
+ s.mem.readW (s.gpr .x2 + BitVec.ofNat 64 i) 64 := by
+ have sub : Region.Sub ⟨s.gpr .x2 + BitVec.ofNat 64 i, 8⟩ (bufR s) :=
+ Offset.sub_base _ hi.2
+ have sep : (Region.mk (s.gpr .x2 + BitVec.ofNat 64 i) 8).Disjoint ⟨s.gpr .x2, 512⟩ :=
+ Offset.disjoint_base _ (by omega) (by omega)
+ apply h.mem.readW (r := ⟨s.gpr .x2 + BitVec.ofNat 64 i, 8⟩) (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.AArch64.Ecb
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Loop.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Loop.lean
new file mode 100644
index 000000000..bd5e3a091
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Loop.lean
@@ -0,0 +1,89 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Ecb.LoopFrame
+
+/-! # Correctness of the ECB loop on complete blocks -/
+
+namespace VG.Proof.TripleDes.AArch64.Ecb
+
+open VG VG.AArch64
+open VG.Proof.TripleDes (blocksAt_cons)
+
+structure LoopPost (d : Spec.TripleDes.Direction) (s : State) (n : Nat) (s' : State) : Prop where
+ ptr : s'.gpr .x1 = s.gpr .x1 + BitVec.ofNat 64 (8 * n)
+ count : s'.gpr .x23 = 0
+ reg : ∀ r ∈ kept, r ≠ .x1 → r ≠ .x23 → s'.gpr r = s.gpr r
+ callee : ∀ r ∈ savedAcrossCall, r ≠ .x23 → 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 (s.gpr .x1) n =
+ Spec.TripleDes.ecb (Spec.TripleDes.scheduleAt s.mem (s.gpr .x0)) d
+ (Spec.TripleDes.blocksAt s.mem (s.gpr .x1) 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 ^ 64 → StepPre s n → s.gpr .x23 = BitVec.ofNat 64 n →
+ WP isa (.loop (.seq (Impl.TripleDes.AArch64.Ecb.blockCall d) (.block Impl.TripleDes.AArch64.Ecb.advance)) (.nonzero .x .x23)) 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
+ 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 bound
+ have data := h₂.data
+ have ki := h₁.reg .x0 (by decide) (by decide) (by decide)
+ have bi := h₁.reg .x2 (by decide) (by decide) (by decide)
+ rw [ki, h₁.ptr, 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 .x1 + ·) (by
+ change BitVec.ofNat 64 8 + BitVec.ofNat 64 (8 * n) = _
+ rw [← BitVec.ofNat_add]
+ exact congrArg (BitVec.ofNat 64) (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) bi h₁.ptr)
+ · have first := firstBlock_frame h₁ hp bound h₂.mem
+ 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 ^ 64)
+ (hp : StepPre s n) (count : s.gpr .x23 = BitVec.ofNat 64 n)
+ :
+ WP isa (.ite (.zero .x .x23) (.block []) (.loop (.seq (Impl.TripleDes.AArch64.Ecb.blockCall d) (.block Impl.TripleDes.AArch64.Ecb.advance)) (.nonzero .x .x23))) s (LoopPost d s n) := by
+ have flag' : zeroCount s = some (decide (n = 0)) := by
+ rw [zeroCount, count, counter_zero n (by omega)]
+ 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.AArch64.Ecb
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/LoopFrame.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/LoopFrame.lean
new file mode 100644
index 000000000..50b02f0e5
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/LoopFrame.lean
@@ -0,0 +1,67 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Ecb.Body
+
+/-! # Frames for successive ECB blocks -/
+
+namespace VG.Proof.TripleDes.AArch64.Ecb
+
+open VG VG.AArch64
+
+def stepWrites (s : State) : List Region := [dataR s, ⟨s.gpr .x2, 512⟩]
+
+def loopWrites (s : State) (n : Nat) : List Region := [dataR s n, ⟨s.gpr .x2, 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)
+ (buf : s'.gpr .x2 = s.gpr .x2)
+ (ptr : s'.gpr .x1 = s.gpr .x1 + BitVec.ofNat 64 (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 ⟨s'.gpr .x1, 8 * m⟩ ⟨s.gpr .x1, 8 * n⟩
+ rw [ptr]
+ exact Offset.sub_base _ (by omega)
+ · refine ⟨⟨s.gpr .x2, 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 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 (s.gpr .x0) = Spec.TripleDes.scheduleAt s.mem (s.gpr .x0) := 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 (s.gpr .x1 + 8) n = Spec.TripleDes.blocksAt s.mem (s.gpr .x1 + 8) n := by
+ have sub : Region.Sub ⟨s.gpr .x1 + 8, 8 * n⟩ (dataR s (n + 1)) :=
+ Offset.sub_base _ (by change 8 + 8 * n ≤ 8 * (n + 1); omega)
+ have sep : (Region.mk (s.gpr .x1 + 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) :
+ Spec.TripleDes.blockAt m (s.gpr .x1) = Spec.TripleDes.blockAt s'.mem (s.gpr .x1) := 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 ⟨s.gpr .x1 + 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 .x2 (by decide) (by decide) (by decide)
+ simpa only [loopWrites, dataR, buf, h.ptr,
+ 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.AArch64.Ecb
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Pre.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Pre.lean
new file mode 100644
index 000000000..6c5e3e477
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Pre.lean
@@ -0,0 +1,56 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Ecb.Call
+
+/-! # Permissions and separation for one ECB step -/
+
+namespace VG.Proof.TripleDes.AArch64.Ecb
+
+open VG VG.AArch64
+
+abbrev keyR (s : State) : Region := ⟨s.gpr .x0, 384⟩
+abbrev dataR (s : State) (n : Nat := 1) : Region := ⟨s.gpr .x1, 8 * n⟩
+abbrev bufR (s : State) : Region := ⟨s.gpr .x2, 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)
+
+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 .x0 (by decide)
+ have c := regs .x1 (by decide)
+ have d := regs .x2 (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
+
+theorem StepPre.call {s : State} (hp : StepPre s) : CallPre s := by
+ constructor
+ · have hc : Covers [⟨s.gpr .x0, 384⟩, ⟨s.gpr .x1, 8⟩, ⟨s.gpr .x2, 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 [⟨s.gpr .x1, 8⟩, ⟨s.gpr .x2, 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))
+
+
+end VG.Proof.TripleDes.AArch64.Ecb
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Slice.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Slice.lean
new file mode 100644
index 000000000..78a35e825
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Slice.lean
@@ -0,0 +1,45 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Ecb.Pre
+
+/-! # Restricting ECB permissions to a consecutive subrange -/
+
+namespace VG.Proof.TripleDes.AArch64.Ecb
+
+open VG VG.AArch64
+
+theorem StepPre.slice {s s' : State} {n m i : Nat} (hp : StepPre s n) (bound : i + m ≤ n)
+ (rd : s'.rd = s.rd) (wr : s'.wr = s.wr)
+ (key : s'.gpr .x0 = s.gpr .x0)
+ (buf : s'.gpr .x2 = s.gpr .x2)
+ (ptr : s'.gpr .x1 = s.gpr .x1 + BitVec.ofNat 64 (8 * i)) : StepPre s' m := by
+ have sub : Region.Sub (dataR s' m) (dataR s n) := by
+ change Region.Sub ⟨s'.gpr .x1, 8 * m⟩ ⟨s.gpr .x1, 8 * n⟩
+ rw [ptr]
+ 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, ptr, 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, ptr, 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
+
+theorem StepPre.head {s : State} {n : Nat} (hp : StepPre s n) (hn : 1 ≤ n) : StepPre s :=
+ hp.slice (i := 0) hn rfl rfl rfl rfl (by simp)
+
+end VG.Proof.TripleDes.AArch64.Ecb
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Steps.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Steps.lean
new file mode 100644
index 000000000..89bd0997a
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Steps.lean
@@ -0,0 +1,52 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Ecb.Call
+import VerifiedGarbage.Proof.TripleDes.EcbMemory
+
+/-! # ECB pointer advancement and public loop counters -/
+
+namespace VG.Proof.TripleDes.AArch64.Ecb
+
+open VG VG.AArch64 VG.AArch64.RegUpd VG.Impl.TripleDes.AArch64
+open VG.Proof.Rc2.AArch64 (Keep)
+
+def zeroCount (s : State) : Option Bool := some (s.gpr .x23 == 0)
+
+theorem eval_zeroCount (s : State) : eval (.zero .x .x23) s = zeroCount s := rfl
+
+theorem eval_nonzeroCount (s : State) : eval (.nonzero .x .x23) s = (zeroCount s).map (! ·) := rfl
+
+theorem advance_ok (s : State) :
+ ∃ s', runBlock isa Impl.TripleDes.AArch64.Ecb.advance s = some s' ∧
+ s'.gpr .x1 = s.gpr .x1 + 8 ∧ s'.gpr .x23 = s.gpr .x23 - 1 ∧
+ zeroCount s' = some ((s.gpr .x23 - 1) == 0) ∧ Keep [.x1, .x23] s s' := by
+ refine ⟨_, by
+ simp only [Impl.TripleDes.AArch64.Ecb.advance, runBlock_cons, runStep_some, runBlock_nil,
+ exec, State.read, BitVec.setWidth_eq, Nat.reduceLT, ite_true,
+ gpr_write, reduceCtorEq, ite_false]
+ rfl, ?_⟩
+ refine ⟨?_, ?_, ?_, ?_⟩
+ · simp only [gpr_write, reduceCtorEq, ite_false, ite_true, BitVec.setWidth_eq]
+ rfl
+ · exact gpr_write_self _ _ _ _
+ · rfl
+ · constructor
+ · intro r hr
+ simp only [List.mem_cons, List.not_mem_nil, or_false, not_or] at hr
+ simp only [gpr_write, hr.1, hr.2, ite_false]
+ · simp only [mem_write]
+ · simp only [rd_write]
+ · simp only [wr_write]
+
+theorem counter_zero (n : Nat) (hn : n < 2 ^ 64) :
+ ((BitVec.ofNat 64 n) == (0 : BitVec 64)) = 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.AArch64.Ecb
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Verified.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Verified.lean
new file mode 100644
index 000000000..c2ca01e24
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Verified.lean
@@ -0,0 +1,48 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Ecb.Correct
+
+namespace VG.Proof.TripleDes.AArch64.Ecb
+
+open VG VG.AArch64
+
+def satState : State where
+ gpr r := match r with
+ | .x0 => 0x1000 | .x1 => 0x2000 | .x3 => 0x3000 | _ => 0
+ sp := 0x4000
+ 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.AArch64.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.AArch64.Ecb.encrypt s t s' at he
+ exact ⟨t, s', he, ⟨ha, VG.AArch64.Exec.sp he, VG.AArch64.Exec.preservedV he (by lit_decide)⟩, hp⟩
+
+theorem decrypt_correct (s : State) (hs : (contract .decrypt).pre s) :
+ ∃ t s', Exec isa Impl.TripleDes.AArch64.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.AArch64.Ecb.decrypt s t s' at he
+ exact ⟨t, s', he, ⟨ha, VG.AArch64.Exec.sp he, VG.AArch64.Exec.preservedV he (by lit_decide)⟩, hp⟩
+
+theorem publicRegs_four (s₁ s₂ : State) : PublicRegs [.x0, .x1, .x2, .x3] s₁ s₂ ↔
+ s₁.sp = s₂.sp ∧ s₁.gpr .x0 = s₂.gpr .x0 ∧ s₁.gpr .x1 = s₂.gpr .x1 ∧
+ s₁.gpr .x2 = s₂.gpr .x2 ∧ s₁.gpr .x3 = s₂.gpr .x3 := by
+ simp [PublicRegs]
+
+theorem encrypt_verified : Verified target Impl.TripleDes.AArch64.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, contract, publicRegs_four] [satState] using satState
+
+theorem decrypt_verified : Verified target Impl.TripleDes.AArch64.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, contract, publicRegs_four] [satState] using satState
+
+end VG.Proof.TripleDes.AArch64.Ecb
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/FunctionsLit.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/FunctionsLit.lean
new file mode 100644
index 000000000..1a1e553be
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/FunctionsLit.lean
@@ -0,0 +1,13 @@
+import VerifiedGarbage.Proof.Framework.AArch64.Lit
+import VerifiedGarbage.Impl.TripleDes.AArch64.ExpandKey
+import VerifiedGarbage.Impl.TripleDes.AArch64.Ecb
+
+namespace VG
+
+materialize_code Impl.TripleDes.AArch64.encryptBlock
+materialize_code Impl.TripleDes.AArch64.decryptBlock
+materialize_code Impl.TripleDes.AArch64.Key.expandKey
+materialize_code Impl.TripleDes.AArch64.Ecb.encrypt
+materialize_code Impl.TripleDes.AArch64.Ecb.decrypt
+
+end VG
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Head.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Head.lean
new file mode 100644
index 000000000..e5c4ddd09
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Head.lean
@@ -0,0 +1,86 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Body
+import VerifiedGarbage.Proof.TripleDes.AArch64.BlockIO
+import VerifiedGarbage.Proof.TripleDes.AArch64.Save
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.Straight VG.Impl.TripleDes.AArch64
+open VG.Spec.TripleDes (Direction DesSchedule)
+open VG.Proof.TripleDes (roundKey)
+
+def saveRegion (s : State) : Region := ⟨s.gpr .x2, 32⟩
+
+structure HeadPre (keys : Nat → DesSchedule) (base : Addr) (s : State) : Prop where
+ spills : Ok sboxCfg s
+ pointer : s.gpr .x0 = base
+ saveRead : ∀ i < 4, InRegions (s.rd ++ s.wr) (s.gpr .x2 + BitVec.ofNat 64 (8 * i)) 8
+ saveWrite : ∀ i < 4, InRegions s.wr (s.gpr .x2 + BitVec.ofNat 64 (8 * i)) 8
+ dataRead : InRegions (s.rd ++ s.wr) (s.gpr .x1) 8
+ dataSeparate : (⟨s.gpr .x1, 8⟩ : Region).Disjoint (saveRegion s)
+ read : ∀ c < 3, ∀ d : Direction, ∀ j < 16,
+ InRegions (s.rd ++ s.wr) (keyAddr (componentBase base c) d j) 8
+ separateWork : ∀ c < 3, ∀ d : Direction, ∀ j < 16,
+ (⟨keyAddr (componentBase base c) d j, 8⟩ : Region).Disjoint (spillRegion s)
+ separateSave : ∀ c < 3, ∀ d : Direction, ∀ j < 16,
+ (⟨keyAddr (componentBase base c) d j, 8⟩ : Region).Disjoint (saveRegion s)
+ values : ∀ c < 3, ∀ d : Direction, ∀ j < 16,
+ (s.mem.readW (keyAddr (componentBase base c) d j) 64).setWidth 48 = roundKey (keys c) d j
+
+structure HeadPost (keys : Nat → DesSchedule) (base : Addr) (original s : State) : Prop where
+ word : WordState (Spec.TripleDes.permute Spec.TripleDes.ip
+ (Spec.TripleDes.decodeBlock (Spec.TripleDes.blockAt original.mem (original.gpr .x1)))) 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 : Addr} {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 .x2 = s.gpr .x2 := congrFun hg .x2
+ refine ⟨hp.spills.congr hbase hbase hrd hwr, (congrFun hg .x0).trans hp.pointer, ?_, ?_, ?_⟩
+ · rw [hrd, hwr]; exact hp.read
+ · rw [show spillRegion t = spillRegion s from
+ congrArg (fun p => (⟨p + BitVec.ofNat 64 32, 384⟩ : Region)) hbase]
+ exact hp.separateWork
+ · intro c hc d j hj
+ have hmem := hf.readW (a := keyAddr (componentBase base c) d j) (w := 64)
+ (r := ⟨keyAddr (componentBase base c) d j, 8⟩) (Region.contains_self _ _)
+ (fun q hq => by obtain rfl := List.mem_singleton.mp hq; exact hp.separateSave c hc d j hj)
+ (by decide)
+ exact (congrArg (BitVec.setWidth 48) hmem).trans (hp.values c hc d j hj)
+
+theorem blockHead_ok (keys : Nat → DesSchedule) (base : Addr) (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.saveWrite)
+ intro s₁ hs₁
+ have hready := ready_afterSave hp hs₁.gpr hs₁.rd hs₁.wr hs₁.frame
+ have hread₁ : InRegions (s₁.rd ++ s₁.wr) (s₁.gpr .x1) 8 := by
+ rw [hs₁.rd, hs₁.wr, hs₁.gpr]; exact hp.dataRead
+ have hdata : Spec.TripleDes.blockAt s₁.mem (s₁.gpr .x1) =
+ Spec.TripleDes.blockAt s.mem (s.gpr .x1) := 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₁ 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₂ .x2 (by decide)) (regs₂ .x0 (by decide)) rd₂ wr₂ hframe,
+ hs₁.saved.congr (regs₂ .x2 (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).setWidth 64) hinput),
+ right₂.trans (congrArg (fun x : BitVec 64 => (x.setWidth 32).setWidth 64) hinput)⟩
+ · intro q hq
+ exact (regs₂ q hq).trans (congrFun hs₁.gpr q)
+ · rw [mem₂]; exact hs₁.frame
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Initial.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Initial.lean
new file mode 100644
index 000000000..cfaf817d7
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Initial.lean
@@ -0,0 +1,58 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Permutation
+import VerifiedGarbage.Proof.TripleDes.Core
+namespace VG.Proof.TripleDes.AArch64
+open VG VG.AArch64 VG.Impl.TripleDes.AArch64
+
+theorem initial_ok (s : State) :
+ ∃ s', runBlock isa (instrs initialPermutation.lit) s = some s' ∧
+ s'.gpr .x10 = (Spec.TripleDes.permute Spec.TripleDes.ip
+ ((s.gpr .x3).setWidth 64)).zeroExtend 64 ∧
+ 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) :=
+ fixedPermutation_ok Spec.TripleDes.ip (by decide) (by decide)
+ VG.Proof.TripleDes.ip_bounds .x3 .x10 (instrs initialPermutation.lit) initialPermutation_check s
+end VG.Proof.TripleDes.AArch64
+namespace VG.Proof.TripleDes.AArch64
+open VG VG.AArch64 VG.Impl.TripleDes.AArch64
+
+theorem initial_raw_ok (s : State) :
+ ∃ s', runBlock isa (permuteCode Spec.TripleDes.ip 64 .x10 .x3 .x11 .x12) s = some s' ∧
+ s'.gpr .x10 = Spec.TripleDes.permute Spec.TripleDes.ip (s.gpr .x3) ∧
+ 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, word, rd, wr, sp, mem, regs⟩ := initial_ok s
+ have hcode : permuteCode Spec.TripleDes.ip 64 .x10 .x3 .x11 .x12 =
+ 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⟩
+ exact word.trans ((BitVec.setWidth_eq _).trans
+ (congrArg (Spec.TripleDes.permute Spec.TripleDes.ip) (BitVec.setWidth_eq _)))
+end VG.Proof.TripleDes.AArch64
+
+namespace VG.Proof.TripleDes.AArch64
+open VG VG.AArch64 VG.Impl.TripleDes.AArch64
+theorem final_ok (s : State) :
+ ∃ s', runBlock isa (instrs finalPermutation.lit) s = some s' ∧
+ s'.gpr .x10 = (Spec.TripleDes.permute Spec.TripleDes.fp
+ ((s.gpr .x3).setWidth 64)).zeroExtend 64 ∧
+ 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) :=
+ fixedPermutation_ok Spec.TripleDes.fp (by decide) (by decide)
+ VG.Proof.TripleDes.fp_bounds .x3 .x10 (instrs finalPermutation.lit) finalPermutation_check s
+
+theorem final_raw_ok (s : State) :
+ ∃ s', runBlock isa (permuteCode Spec.TripleDes.fp 64 .x10 .x3 .x11 .x12) s = some s' ∧
+ s'.gpr .x10 = Spec.TripleDes.permute Spec.TripleDes.fp (s.gpr .x3) ∧
+ 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, word, rd, wr, sp, mem, regs⟩ := final_ok s
+ have hcode : permuteCode Spec.TripleDes.fp 64 .x10 .x3 .x11 .x12 =
+ 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⟩
+ exact word.trans ((BitVec.setWidth_eq _).trans
+ (congrArg (Spec.TripleDes.permute Spec.TripleDes.fp) (BitVec.setWidth_eq _)))
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Body.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Body.lean
new file mode 100644
index 000000000..dfc2b3163
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Body.lean
@@ -0,0 +1,71 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Key.Composition
+
+namespace VG.Proof.TripleDes.AArch64.Key
+
+open VG VG.AArch64 VG.AArch64.RegUpd
+open VG.Proof.Rc2.AArch64 (Keep)
+
+theorem cmpLength_ok (s : State) :
+ ∃ s', runBlock isa [.subImm .x .x4 .x1 16] s = some s' ∧
+ isa.eval (.zero .x .x4) s' = some (s.gpr .x1 == 16) ∧ Keep [.x4] s s' := by
+ refine ⟨s.write .x .x4 (s.gpr .x1 - 16), ?_, ?_, write_keep _ _⟩
+ · simp only [runBlock_cons, runStep_some, runBlock_nil, exec,
+ show (16 : Nat) < 4096 from by decide, ite_true, State.read, BitVec.setWidth_eq]
+ rfl
+ · change VG.AArch64.eval (.zero .x .x4) _ = _
+ simp only [VG.AArch64.eval, State.read, gpr_write_self, BitVec.setWidth_eq]
+ 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 [.x4] 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 64) : (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.AArch64.Key.restore) t Q) :
+ WP isa (.seq (Impl.TripleDes.AArch64.Key.component 0 0)
+ (.seq (Impl.TripleDes.AArch64.Key.component 8 1)
+ (.seq (.block [.subImm .x .x4 .x1 16])
+ (.seq (.ite (.zero .x .x4) (.block Impl.TripleDes.AArch64.Key.copyThird)
+ (Impl.TripleDes.AArch64.Key.component 16 2)) (.block Impl.TripleDes.AArch64.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 (.zero .x .x4) s₃ = some (decide ((origin.gpr .x1).toNat = 16)) := by
+ rw [flag₃, hs₂.reg .x1 (by decide), beq16_toNat]
+ by_cases h16 : (origin.gpr .x1).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.AArch64.Key
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Component.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Component.lean
new file mode 100644
index 000000000..9c576b220
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Component.lean
@@ -0,0 +1,42 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Key.Loop
+import VerifiedGarbage.Proof.TripleDes.Schedule
+
+namespace VG.Proof.TripleDes.AArch64.Key
+
+open VG VG.AArch64
+open VG.Proof.TripleDes.AArch64.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 % 8 = 0 ∧ offset < 32768)
+ (hr : InRegions (s.rd ++ s.wr) (s.gpr .x0 + BitVec.ofNat 64 offset) 8)
+ (hw : ∀ j < 16, InRegions s.wr
+ (s.gpr .x2 + BitVec.ofNat 64 (128 * component) + BitVec.ofNat 64 (8 * j)) 8) :
+ WP isa (Impl.TripleDes.AArch64.Key.component offset component) s
+ (ComponentPost (Spec.TripleDes.expandDesKey (Spec.TripleDes.decodeBlock
+ (Spec.TripleDes.blockAt s.mem (s.gpr .x0 + BitVec.ofNat 64 offset))))
+ (s.gpr .x2 + BitVec.ofNat 64 (128 * component)) s) := by
+ rw [Impl.TripleDes.AArch64.Key.component]
+ apply WP.seq
+ apply WP.mono (load_ok s offset component hc ho hr)
+ intro s₁ h₁
+ have writes : ∀ j < 16, InRegions s₁.wr
+ (s.gpr .x2 + BitVec.ofNat 64 (128 * component) + BitVec.ofNat 64 (8 * j)) 8 := by
+ rw [h₁.wr]; exact hw
+ apply WP.mono (loop_ok _ _ s₁ 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.AArch64.Key
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Composition.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Composition.lean
new file mode 100644
index 000000000..d3a527aec
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Composition.lean
@@ -0,0 +1,150 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Key.Copy
+import VerifiedGarbage.Proof.TripleDes.KeyMemory
+
+namespace VG.Proof.TripleDes.AArch64.Key
+
+open VG VG.AArch64
+open VG.Proof.TripleDes (componentKeys componentOffset)
+
+abbrev keyR (s : State) : Region := ⟨s.gpr .x0, (s.gpr .x1).toNat⟩
+abbrev outputR (s : State) : Region := ⟨s.gpr .x2, 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 (origin.gpr .x2) c j) 64 =
+ ((componentKeys origin.mem (origin.gpr .x0) (origin.gpr .x1).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 + 8 ≤ (s.gpr .x1).toNat →
+ InRegions (s.rd ++ s.wr) (s.gpr .x0 + BitVec.ofNat 64 offset) 8
+ writes : ∀ offset, offset + 8 ≤ 384 → InRegions s.wr (s.gpr .x2 + BitVec.ofNat 64 offset) 8
+ keyOutput : (keyR s).Disjoint (outputR s)
+ valid : Spec.TripleDes.validKey (s.gpr .x1).toNat
+
+theorem componentStep_ok (origin s : State) (c : Nat) (hc : c < 3)
+ (hp : Permissions origin) (hs : Components origin s c)
+ (hoff : componentOffset (origin.gpr .x1).toNat c = 8 * c) :
+ WP isa (Impl.TripleDes.AArch64.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 read : InRegions (s.rd ++ s.wr) (s.gpr .x0 + BitVec.ofNat 64 (8 * c)) 8 := by
+ rw [hs.rd, hs.wr, hs.reg .x0 (by decide)]
+ exact hp.reads _ offsetBound
+ have write : ∀ j < 16, InRegions s.wr
+ (s.gpr .x2 + BitVec.ofNat 64 (128 * c) + BitVec.ofNat 64 (8 * j)) 8 := by
+ intro j hj
+ rw [hs.wr, hs.reg .x2 (by decide), Offset.add_ofNat_add_ofNat]
+ exact hp.writes _ (by omega_using [hc, hj])
+ apply WP.mono (component_ok s (8 * c) c hc (by omega) read write)
+ intro t ht
+ have frame : Frame [⟨origin.gpr .x2 + BitVec.ofNat 64 (128 * c), 128⟩] s.mem t.mem := by
+ have hf := ht.frame
+ rw [hs.reg .x2 (by decide)] at hf
+ exact hf
+ have key : Spec.TripleDes.blockAt s.mem (s.gpr .x0 + BitVec.ofNat 64 (8 * c)) =
+ Spec.TripleDes.blockAt origin.mem (origin.gpr .x0 + BitVec.ofNat 64 (8 * c)) := by
+ rw [hs.reg .x0 (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 [key, hs.reg .x2 (by decide), 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 (origin.gpr .x2) k j) 8).Disjoint
+ ⟨origin.gpr .x2 + 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 (origin.gpr .x2) k j) (w := 64) (r := ⟨slot (origin.gpr .x2) 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 .x1).toNat = 16) :
+ WP isa (.block Impl.TripleDes.AArch64.Key.copyThird) s (Components origin · 3) := by
+ have reads : ∀ i < 16, InRegions (s.rd ++ s.wr) (s.gpr .x2 + BitVec.ofNat 64 (8 * i)) 8 := by
+ intro i hi
+ rw [hs.rd, hs.wr, hs.reg .x2 (by decide)]
+ obtain ⟨r, hr, hc⟩ := hp.writes (8 * i) (by omega_using [hi])
+ exact ⟨r, List.mem_append_right _ hr, hc⟩
+ have writes : ∀ i < 16, InRegions s.wr (s.gpr .x2 + BitVec.ofNat 64 (256 + 8 * i)) 8 := by
+ intro i hi
+ rw [hs.wr, hs.reg .x2 (by decide)]
+ exact hp.writes _ (by omega_using [hi])
+ apply WP.mono (copy_ok s 16 (by decide) reads writes)
+ intro t ht
+ have frame : Frame [⟨origin.gpr .x2 + BitVec.ofNat 64 256, 128⟩] s.mem t.mem := by
+ have h := ht.frame
+ rw [hs.reg .x2 (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 (origin.gpr .x0) (origin.gpr .x1).toNat 2 =
+ componentKeys origin.mem (origin.gpr .x0) (origin.gpr .x1).toNat 0 := by
+ rw [hn]; rfl
+ have h := ht.keys j hj
+ rw [hs.reg .x2 (by decide)] at h
+ change t.mem.readW (origin.gpr .x2 + 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 (origin.gpr .x2) c j) 8).Disjoint
+ ⟨origin.gpr .x2 + 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 (origin.gpr .x2) c j) (w := 64) (r := ⟨slot (origin.gpr .x2) 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 ≠ .x4 := by decide
+ exact (ht.reg r (unused r hr)).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 (origin.gpr .x2) =
+ VG.Proof.TripleDes.expandedMemory origin.mem (origin.gpr .x0) (origin.gpr .x1).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 (origin.gpr .x2) 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.AArch64.Key
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Contract.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Contract.lean
new file mode 100644
index 000000000..06d371df7
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Contract.lean
@@ -0,0 +1,22 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Key.Body
+import VerifiedGarbage.Proof.TripleDes.AArch64.Key.Save
+import VerifiedGarbage.Proof.TripleDes.AArch64.ConstantTime
+import VerifiedGarbage.Spec.TripleDes.Contract
+
+namespace VG.Proof.TripleDes.AArch64.Key
+
+open VG VG.AArch64
+
+def contract : Contract isa where
+ pre s :=
+ let key : Region := ⟨s.gpr .x0, (s.gpr .x1).toNat⟩
+ let output : Region := ⟨s.gpr .x2, 384⟩
+ let scratch : Region := ⟨s.gpr .x3, 512⟩
+ s.rd = [key] ∧ s.wr = [output, scratch] ∧ key.Disjoint output ∧ key.Disjoint scratch ∧
+ output.Disjoint scratch ∧
+ Spec.TripleDes.validKey (s.gpr .x1).toNat
+ post s s' := Spec.TripleDes.scheduleAt s'.mem (s.gpr .x2) =
+ Spec.TripleDes.expandKey (Spec.TripleDes.bytesAt s.mem (s.gpr .x0) (s.gpr .x1).toNat)
+ pub := PublicRegs [.x0, .x1, .x2, .x3]
+
+end VG.Proof.TripleDes.AArch64.Key
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Copy.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Copy.lean
new file mode 100644
index 000000000..2c0562ca8
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Copy.lean
@@ -0,0 +1,90 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Key.Component
+import VerifiedGarbage.Proof.Rc2.AArch64.Lookup
+
+namespace VG.Proof.TripleDes.AArch64.Key
+
+open VG VG.AArch64 VG.AArch64.RegUpd VG.Impl.TripleDes.AArch64
+open VG.Proof.Rc2.AArch64 (Keep)
+
+theorem copy64_ok (s : State) (src dst : Reg) (a b : Nat) (hne : dst ≠ .x4)
+ (readable : InRegions (s.rd ++ s.wr) (s.gpr src + BitVec.ofNat 64 a) 8)
+ (writable : InRegions s.wr (s.gpr dst + BitVec.ofNat 64 b) 8)
+ (ha : a % 8 = 0 ∧ a < 32768 := by decide)
+ (hb : b % 8 = 0 ∧ b < 32768 := by decide) :
+ ∃ s', runBlock isa [.ldr .x .x4 src a, .str .x .x4 dst b] s = some s' ∧
+ Keep [.x4] {s with
+ mem := s.mem.writeW (s.gpr dst + BitVec.ofNat 64 b) (s.mem.readW (s.gpr src + BitVec.ofNat 64 a) 64)} s' := by
+ have hw : InRegions (s.write .x .x4 (s.mem.readW (s.gpr src + BitVec.ofNat 64 a) 64)).wr
+ ((s.write .x .x4 (s.mem.readW (s.gpr src + BitVec.ofNat 64 a) 64)).gpr dst + BitVec.ofNat 64 b) 8 := by
+ simpa only [wr_write, gpr_write, hne, ite_false] using writable
+ refine ⟨_, by
+ rw [runBlock_cons, exec_ldr_x ha readable, runStep_some,
+ runBlock_cons, exec_str_x hb hw, runStep_some, runBlock_nil], ?_⟩
+ constructor
+ · intro r hr
+ have hn : r ≠ .x4 := by intro h; subst r; exact hr (by simp)
+ exact gpr_write_of_ne _ _ _ hn
+ · simp only [gpr_write, hne, ite_false, ite_true, BitVec.setWidth_eq, mem_write]
+ · rfl
+ · rfl
+
+ def copyCode (n : Nat) : List Instr :=
+ (List.range n).flatMap fun j =>
+ [.ldr .x .x4 .x2 (8 * j), .str .x .x4 .x2 (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 ≠ .x4 → 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)
+ (hr : ∀ i < 16, InRegions (s.rd ++ s.wr) (s.gpr .x2 + BitVec.ofNat 64 (8 * i)) 8)
+ (hw : ∀ i < 16, InRegions s.wr (s.gpr .x2 + BitVec.ofNat 64 (256 + 8 * i)) 8) :
+ WP isa (.block (copyCode n)) s (CopyPost (s.gpr .x2) 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 .x2 = s.gpr .x2 := h₁.reg .x2 (by decide)
+ have readable : InRegions (s₁.rd ++ s₁.wr) (s₁.gpr .x2 + BitVec.ofNat 64 (8 * n)) 8 := by
+ rw [h₁.rd, h₁.wr, hbase]; exact hr n (by omega)
+ have writable : InRegions s₁.wr (s₁.gpr .x2 + BitVec.ofNat 64 (256 + 8 * n)) 8 := by
+ rw [h₁.wr, hbase]; exact hw n (by omega)
+ obtain ⟨s₂, run₂, keep₂⟩ := copy64_ok s₁ .x2 .x2
+ (8 * n) (256 + 8 * n) (by decide) readable writable (by omega) (by omega)
+ have source : s₁.mem.readW (s.gpr .x2 + BitVec.ofNat 64 (8 * n)) 64 =
+ s.mem.readW (s.gpr .x2 + BitVec.ofNat 64 (8 * n)) 64 := by
+ apply h₁.frame.readW (r := ⟨s.gpr .x2 + BitVec.ofNat 64 (8 * n), 8⟩)
+ (Region.contains_self _ _) _ (by decide)
+ intro r h
+ obtain rfl := List.mem_singleton.mp h
+ exact Offset.disjoint (s.gpr .x2) (by omega) (by omega) (by decide)
+ have mem₂ : s₂.mem = s₁.mem.writeW (s.gpr .x2 + BitVec.ofNat 64 (256 + 8 * n))
+ (s.mem.readW (s.gpr .x2 + BitVec.ofNat 64 (8 * n)) 64) := by
+ have hm := keep₂.mem
+ rw [hbase, source] at hm
+ exact hm
+ refine WP.of_runBlock ⟨s₂, run₂, ⟨?_, keep₂.rd.trans h₁.rd, keep₂.wr.trans h₁.wr,
+ fun r hr => (keep₂.reg r (by simpa only [List.mem_singleton] using hr)).trans (h₁.reg r hr), ?_⟩⟩
+ · intro i hi
+ rw [mem₂]
+ by_cases he : i = n
+ · subst i; exact Mem.readW_writeW_self64 _ _ _
+ · rw [Mem.readW_writeW_sep (Offset.sep (s.gpr .x2) (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 (s.gpr .x2 + 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.AArch64.Key
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Correct.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Correct.lean
new file mode 100644
index 000000000..39edf60f0
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Correct.lean
@@ -0,0 +1,80 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Key.Contract
+
+namespace VG.Proof.TripleDes.AArch64.Key
+
+open VG VG.AArch64
+
+ theorem expand_correct (s : State) (hs : contract.pre s) :
+ WP isa Impl.TripleDes.AArch64.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⟩ := hs
+ have scratchWrites : ∀ i < 4, InRegions s.wr (s.gpr .x3 + BitVec.ofNat 64 (8 * i)) 8 := by
+ intro i hi
+ rw [hwr]
+ exact ⟨⟨s.gpr .x3, 512⟩, by simp, Offset.contains_base _ (by omega_using [hi]) (by omega_using [hi])⟩
+ rw [Impl.TripleDes.AArch64.Key.expandKey]
+ apply WP.seq
+ apply WP.mono (save_ok s 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 ⟨⟨s.gpr .x0, (s.gpr .x1).toNat⟩, by simp,
+ Offset.contains_base _ (by simpa only [g₁] using hoff) (by
+ have bound := BitVec.isLt (s.gpr .x1)
+ rw [g₁] at hoff
+ omega_using [hoff, bound])⟩
+ · intro offset hoff
+ rw [h₁.2.2.1, g₁, hwr]
+ exact ⟨⟨s.gpr .x2, 384⟩, by simp, Offset.contains_base _ hoff (by omega_using [hoff])⟩
+ · simpa only [keyR, outputR, g₁] using keyOutput
+ · simpa only [g₁] using valid
+ 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 [⟨s.gpr .x2, 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 ⟨s.gpr .x3 + BitVec.ofNat 64 (8 * i), 8⟩ ⟨s.gpr .x3, 512⟩ :=
+ Offset.sub_base _ (by omega_using [hi])
+ have mem := frame₂.readW (a := s.gpr .x3 + BitVec.ofNat 64 (8 * i)) (w := 64)
+ (r := ⟨s.gpr .x3 + BitVec.ofNat 64 (8 * i), 8⟩) (Region.contains_self _ _)
+ (fun r hr => by obtain rfl := List.mem_singleton.mp hr; exact (outputScratch.sub_right sub).symm)
+ (by decide)
+ rw [g₂ .x3 (by decide)]
+ have saved₁ := h₁.2.2.2.1 i hi
+ rw [g₁] at saved₁
+ exact mem.trans saved₁
+ have scratchReads : ∀ i < 4, InRegions (s₂.rd ++ s₂.wr) (s₂.gpr .x3 + BitVec.ofNat 64 (8 * i)) 8 := by
+ intro i hi
+ rw [h₂.rd, h₂.wr, h₁.2.1, h₁.2.2.1, g₂ .x3 (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₂ scratchReads)
+ intro s₃ h₃
+ have scratchFrame : Frame [⟨s.gpr .x3, 512⟩] s.mem s₁.mem := h₁.2.2.2.2.sub (by
+ intro r hr
+ obtain rfl := List.mem_singleton.mp hr
+ exact ⟨⟨s.gpr .x3, 512⟩, by simp, Region.sub_prefix (by decide)⟩)
+ have initialBytes := VG.Proof.TripleDes.bytesAt_eq_of_frame (s.gpr .x0) (s.gpr .x1).toNat
+ scratchFrame (Nat.le_of_lt (BitVec.isLt _)) (by simpa using keyScratch)
+ constructor
+ · intro r hr
+ have kept : ∀ r ∈ preserved, r ∈ Impl.TripleDes.AArch64.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 (s.gpr .x0) (s.gpr .x1).toNat valid,
+ initialBytes] at result
+ change Spec.TripleDes.scheduleAt s₃.mem (s.gpr .x2) = _
+ rw [h₃.2.mem]
+ exact result
+
+end VG.Proof.TripleDes.AArch64.Key
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Load.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Load.lean
new file mode 100644
index 000000000..c62d98f07
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Load.lean
@@ -0,0 +1,103 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Key.Permutation
+import VerifiedGarbage.Proof.TripleDes.AArch64.BlockIO
+import VerifiedGarbage.Impl.TripleDes.AArch64.ExpandKey
+
+namespace VG.Proof.TripleDes.AArch64.Key
+
+open VG VG.AArch64 VG.AArch64.RegUpd VG.Impl.TripleDes.AArch64
+
+def keyKept : List Reg := [.x0, .x1, .x2, .x3, .x23, .x24, .x25, .x26, .x27, .x28, .x30]
+
+theorem readKey_ok (s : State) (offset : Nat) (ho : offset % 8 = 0 ∧ offset < 32768)
+ (hr : InRegions (s.rd ++ s.wr) (s.gpr .x0 + BitVec.ofNat 64 offset) 8) :
+ ∃ s', runBlock isa [.ldr .x .x4 .x0 offset, .rev .x4 .x4] s = some s' ∧
+ s'.gpr .x4 = Spec.TripleDes.decodeBlock
+ (Spec.TripleDes.blockAt s.mem (s.gpr .x0 + BitVec.ofNat 64 offset)) ∧
+ s'.mem = s.mem ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧
+ (∀ r, r ≠ .x4 → s'.gpr r = s.gpr r) := by
+ refine ⟨_, by
+ simp only [runBlock_cons, exec_ldr_x ho hr, runStep_some, runBlock_nil,
+ exec_rev, State.read, BitVec.setWidth_eq, gpr_write_self]
+ rfl, ?_, ?_, ?_, ?_, ?_⟩
+ · simp only [gpr_write_self, BitVec.setWidth_eq]
+ exact (decodeBlock_readW s.mem _).symm
+ · simp only [mem_write]
+ · simp only [rd_write]
+ · simp only [wr_write]
+ · intro r hr; simp only [gpr_write, hr, ite_false]
+
+def loadTail (component : Nat) : List Instr :=
+ [.lsr .x .x19 .x5 28, rr .x20 .x5] ++ mask .x20 28 ++
+ [imm .x21 0, .addImm .x .x22 .x2 (128 * component)]
+
+theorem loadTail_ok (s : State) (component : Nat) (hc : component < 3) (x : BitVec 56)
+ (hx : s.gpr .x5 = x.setWidth 64) :
+ ∃ s', runBlock isa (loadTail component) s = some s' ∧
+ s'.gpr .x19 = ((x >>> 28).setWidth 28).setWidth 64 ∧
+ s'.gpr .x20 = (x.setWidth 28).setWidth 64 ∧ s'.gpr .x21 = 0 ∧
+ s'.gpr .x22 = s.gpr .x2 + BitVec.ofNat 64 (128 * component) ∧
+ s'.mem = s.mem ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧
+ (∀ r, r ∉ [Reg.x19, .x20, .x21, .x22] → s'.gpr r = s.gpr r) := by
+ have hb : 128 * component < 4096 := by omega
+ refine ⟨_, by
+ simp only [loadTail, rr, imm, mask, List.cons_append, List.nil_append,
+ runBlock_cons, runStep_some, runBlock_nil, exec, Size.bits, hb,
+ show (28 : Nat) < 64 from by decide, show (36 : Nat) < 64 from by decide,
+ show (0 : Nat) < 64 from by decide, show (0 : Nat) < 4096 from by decide,
+ Nat.mul_zero, ite_true, State.read, BitVec.setWidth_eq, gpr_write,
+ BitVec.add_zero, reduceCtorEq, ite_false]
+ rfl, ?_, ?_, ?_, ?_, ?_, ?_, ?_, ?_⟩
+ · simp only [gpr_write, BitVec.setWidth_eq, reduceCtorEq, ite_true, ite_false]
+ rw [hx]; exact VG.Proof.TripleDes.split28_upper x
+ · simp only [gpr_write, BitVec.setWidth_eq, reduceCtorEq, ite_true, ite_false]
+ rw [hx, mask_word _ 28 (by decide) (by decide), BitVec.setWidth_setWidth_of_le x (by decide : 28 ≤ 64)]
+ · simp only [gpr_write, BitVec.setWidth_eq, reduceCtorEq, ite_true, ite_false]; rfl
+ · simp only [gpr_write, BitVec.setWidth_eq, reduceCtorEq, ite_true, ite_false]
+ · simp only [mem_write]
+ · simp only [rd_write]
+ · simp only [wr_write]
+ · intro r hr
+ simp only [List.mem_cons, List.not_mem_nil, or_false, not_or] at hr
+ simp only [gpr_write, hr.1, hr.2.1, hr.2.2.1, hr.2.2.2, ite_false]
+
+structure LoadPost (x : BitVec 56) (component : Nat) (s s' : State) : Prop where
+ c : s'.gpr .x19 = ((x >>> 28).setWidth 28).setWidth 64
+ d : s'.gpr .x20 = (x.setWidth 28).setWidth 64
+ counter : s'.gpr .x21 = 0
+ ptr : s'.gpr .x22 = s.gpr .x2 + BitVec.ofNat 64 (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 % 8 = 0 ∧ offset < 32768)
+ (hr : InRegions (s.rd ++ s.wr) (s.gpr .x0 + BitVec.ofNat 64 offset) 8) :
+ WP isa (.block (Impl.TripleDes.AArch64.Key.load offset component)) s
+ (LoadPost (Spec.TripleDes.permute Spec.TripleDes.pc1 (Spec.TripleDes.decodeBlock
+ (Spec.TripleDes.blockAt s.mem (s.gpr .x0 + BitVec.ofNat 64 offset)))) component s) := by
+ have code : Impl.TripleDes.AArch64.Key.load offset component =
+ (([.ldr .x .x4 .x0 offset, .rev .x4 .x4] : List Instr) ++
+ permuteCode Spec.TripleDes.pc1 64 .x5 .x4 .x6 .x7) ++ loadTail component := by
+ simp only [Impl.TripleDes.AArch64.Key.load, loadTail, List.append_assoc]
+ rw [code, WP.block_append_iff, WP.block_append_iff]
+ obtain ⟨s₁, run₁, key₁, mem₁, rd₁, wr₁, reg₁⟩ := readKey_ok s offset ho hr
+ refine WP.of_runBlock ⟨s₁, run₁, ?_⟩
+ obtain ⟨s₂, run₂, word₂, rd₂, wr₂, _, mem₂, reg₂⟩ := pc1_ok s₁
+ refine WP.of_runBlock ⟨s₂, run₂, ?_⟩
+ rw [key₁] at word₂
+ obtain ⟨s₃, run₃, c₃, d₃, counter₃, ptr₃, mem₃, rd₃, wr₃, reg₃⟩ := loadTail_ok s₂ component hc _ word₂
+ refine WP.of_runBlock ⟨s₃, run₃, ⟨c₃, d₃, counter₃, ?_, mem₃.trans (mem₂.trans mem₁),
+ rd₃.trans (rd₂.trans rd₁), wr₃.trans (wr₂.trans wr₁), ?_⟩⟩
+ · have rdx₂ : s₂.gpr .x2 = s.gpr .x2 :=
+ (reg₂ .x2 (by decide +kernel)).trans (reg₁ .x2 (by decide))
+ rw [rdx₂] at ptr₃
+ exact ptr₃
+ · intro r hr
+ have unused : ∀ r ∈ keyKept,
+ r ∉ [Reg.x19, .x20, .x21, .x22] ∧ r ≠ .x4 := 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).trans ((reg₂ r (hcheck r hr)).trans (reg₁ r (unused r hr).2))
+
+end VG.Proof.TripleDes.AArch64.Key
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Loop.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Loop.lean
new file mode 100644
index 000000000..2a9724abc
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Loop.lean
@@ -0,0 +1,117 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Key.Rotation
+import VerifiedGarbage.Proof.TripleDes.AArch64.Key.Store
+import VerifiedGarbage.Proof.Framework.Offset
+import VerifiedGarbage.Proof.Framework.Omega
+
+namespace VG.Proof.TripleDes.AArch64.Key
+
+open VG VG.AArch64
+open VG.Proof.TripleDes.AArch64.Key (keyKept)
+open VG.Proof.TripleDes (keyPrefix keyInitial keyStep keyPrefix_succ)
+
+structure LoopState (key : BitVec 64) (base : Addr) (origin : State) (j : Nat) (s : State) : Prop where
+ c : s.gpr .x19 = (keyPrefix key j).1.setWidth 64
+ d : s.gpr .x20 = (keyPrefix key j).2.1.setWidth 64
+ counter : s.gpr .x21 = BitVec.ofNat 64 j
+ pointer : s.gpr .x22 = base + BitVec.ofNat 64 (8 * j)
+ keys : ∀ i < j, ∀ hi : i < 16, s.mem.readW (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 [⟨base, 128⟩] origin.mem s.mem
+
+def LoopInv (key : BitVec 64) (base : Addr) (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 : Addr) (origin : State)
+ (hw : ∀ j < 16, InRegions origin.wr (base + BitVec.ofNat 64 (8 * j)) 8)
+ (j : Nat) (hj : j < 16) (s : State) (hs : LoopState key base origin j s) :
+ WP isa (.seq Impl.TripleDes.AArch64.Key.rotation (.block Impl.TripleDes.AArch64.Key.storeRound)) s
+ (fun s' => isa.eval (.nonzero .x .x4) 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 ++ [.x21, .x22]),
+ r ≠ .x4 ∧ r ≠ .x19 ∧ r ≠ .x20 := by decide
+ have reg₁ : ∀ r ∈ (keyKept ++ [.x21, .x22]), 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 write₁ : InRegions s₁.wr (s₁.gpr .x22) 8 := by
+ rw [h₁.wr, hs.wr, reg₁ .x22 (by decide), hs.pointer]
+ exact hw j hj
+ apply WP.mono (storeRound_ok s₁ _ _ j hj h₁.c h₁.d
+ ((reg₁ .x21 (by decide)).trans hs.counter) write₁)
+ intro s₂ h₂
+ have hmem : s₂.mem = s.mem.writeW (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₁ .x22 (by decide), hs.pointer]
+ 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 .x19 (by decide)).trans h₁.c
+ · rw [keyPrefix_succ]
+ exact (h₂.reg .x20 (by decide)).trans h₁.d
+ · rw [h₂.ptr, reg₁ .x22 (by decide), hs.pointer]
+ change base + BitVec.ofNat 64 (8 * j) + BitVec.ofNat 64 8 = _
+ rw [Offset.add_ofNat_add_ofNat]
+ exact congrArg (fun n => base + BitVec.ofNat 64 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 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 ++ [.x19, .x20]) ∧
+ r ∈ (keyKept ++ [.x21, .x22]) := 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 base (by omega_using [hj]) (by omega_using [hj]))
+
+theorem loopStep (key : BitVec 64) (base : Addr) (origin : State)
+ (hw : ∀ j < 16, InRegions origin.wr (base + BitVec.ofNat 64 (8 * j)) 8)
+ (n : Nat) (s : State) (hs : LoopInv key base origin n s) :
+ WP isa (.seq Impl.TripleDes.AArch64.Key.rotation (.block Impl.TripleDes.AArch64.Key.storeRound)) s
+ (fun s' => (isa.eval (.nonzero .x .x4) s' = some false ∧ LoopState key base origin 16 s') ∨
+ (isa.eval (.nonzero .x .x4) s' = some true ∧ ∃ m < n, LoopInv key base origin m s')) := by
+ apply WP.mono (loopBody_ok key base origin 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 : Addr) (s : State)
+ (hw : ∀ j < 16, InRegions s.wr (base + BitVec.ofNat 64 (8 * j)) 8)
+ (hc : s.gpr .x19 = (keyInitial key).1.setWidth 64)
+ (hd : s.gpr .x20 = (keyInitial key).2.1.setWidth 64)
+ (hcount : s.gpr .x21 = 0) (hptr : s.gpr .x22 = base) :
+ WP isa (.loop (.seq Impl.TripleDes.AArch64.Key.rotation
+ (.block Impl.TripleDes.AArch64.Key.storeRound)) (.nonzero .x .x4)) s (LoopState key base s 16) := by
+ apply WP.loop (M := isa) (body := .seq Impl.TripleDes.AArch64.Key.rotation
+ (.block Impl.TripleDes.AArch64.Key.storeRound)) (c := .nonzero .x .x4)
+ (Q := LoopState key base s 16) (LoopInv key base s) (loopStep key base s 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.AArch64.Key
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Permutation.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Permutation.lean
new file mode 100644
index 000000000..5ac07e15d
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Permutation.lean
@@ -0,0 +1,35 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Permutation
+
+namespace VG.Proof.TripleDes.AArch64.Key
+
+open VG VG.AArch64 VG.Impl.TripleDes.AArch64
+
+ theorem pc1_ok (s : State) :
+ ∃ s', runBlock isa (permuteCode Spec.TripleDes.pc1 64 .x5 .x4 .x6 .x7) s = some s' ∧
+ s'.gpr .x5 = (Spec.TripleDes.permute Spec.TripleDes.pc1 (s.gpr .x4)).setWidth 64 ∧
+ 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, word, rd, wr, sp, mem, regs⟩ :=
+ fixedPermutation_ok Spec.TripleDes.pc1 (by decide) (by decide) (by decide)
+ .x4 .x5 (instrs keyPermutation1.lit) keyPermutation1_check s
+ have hcode : permuteCode Spec.TripleDes.pc1 64 .x5 .x4 .x6 .x7 = instrs keyPermutation1.lit :=
+ congrArg instrs keyPermutation1.lit_eq
+ refine ⟨s', (congrArg (fun is => runBlock isa is s) hcode).trans run, ?_, rd, wr, sp, mem, regs⟩
+ exact word.trans (congrArg (fun x => (Spec.TripleDes.permute Spec.TripleDes.pc1 x).setWidth 64)
+ (BitVec.setWidth_eq _))
+
+theorem pc2_ok (s : State) :
+ ∃ s', runBlock isa (permuteCode Spec.TripleDes.pc2 56 .x5 .x4 .x6 .x7) s = some s' ∧
+ s'.gpr .x5 = (Spec.TripleDes.permute Spec.TripleDes.pc2 ((s.gpr .x4).setWidth 56)).setWidth 64 ∧
+ 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, word, rd, wr, sp, mem, regs⟩ :=
+ fixedPermutation_ok Spec.TripleDes.pc2 (by decide) (by decide) (by decide)
+ .x4 .x5 (instrs keyPermutation2.lit) keyPermutation2_check s
+ have hcode : permuteCode Spec.TripleDes.pc2 56 .x5 .x4 .x6 .x7 = instrs keyPermutation2.lit :=
+ congrArg instrs keyPermutation2.lit_eq
+ exact ⟨s', (congrArg (fun is => runBlock isa is s) hcode).trans run, word, rd, wr, sp, mem, regs⟩
+
+end VG.Proof.TripleDes.AArch64.Key
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Rotation.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Rotation.lean
new file mode 100644
index 000000000..03e6a3d06
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Rotation.lean
@@ -0,0 +1,126 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.KeySteps
+import VerifiedGarbage.Proof.TripleDes.KeySchedule
+import VerifiedGarbage.Proof.Rc2.AArch64.Lookup
+
+namespace VG.Proof.TripleDes.AArch64.Key
+
+open VG VG.AArch64 VG.AArch64.RegUpd VG.Impl.TripleDes.AArch64
+open VG.Proof.Rc2.AArch64 (Keep)
+
+structure RotatePost (c d : BitVec 28) (n : Nat) (s s' : State) : Prop where
+ c : s'.gpr .x19 = (c.rotateLeft n).setWidth 64
+ d : s'.gpr .x20 = (d.rotateLeft n).setWidth 64
+ mem : s'.mem = s.mem
+ rd : s'.rd = s.rd
+ wr : s'.wr = s.wr
+ reg : ∀ r, r ≠ .x4 → r ≠ .x19 → r ≠ .x20 → s'.gpr r = s.gpr r
+
+theorem rotate_ok (s : State) (c d : BitVec 28)
+ (hc : s.gpr .x19 = c.setWidth 64) (hd : s.gpr .x20 = d.setWidth 64)
+ (n : Nat) (hn : 1 ≤ n) (hn' : n < 28) :
+ WP isa (Impl.TripleDes.AArch64.Key.rotate n) s (RotatePost c d n s) := by
+ rw [Impl.TripleDes.AArch64.Key.rotate, WP.block_append_iff]
+ obtain ⟨s₁, run₁, c₁, mem₁, rd₁, wr₁, _, reg₁⟩ := rotate28_ok s .x19 (by decide) c hc n hn hn'
+ refine WP.of_runBlock ⟨s₁, run₁, ?_⟩
+ have d₁ : s₁.gpr .x20 = d.setWidth 64 := (reg₁ .x20 (by decide) (by decide)).trans hd
+ obtain ⟨s₂, run₂, d₂, mem₂, rd₂, wr₂, _, reg₂⟩ := rotate28_ok s₁ .x20 (by decide) d d₁ n hn hn'
+ refine WP.of_runBlock ⟨s₂, run₂, ⟨(reg₂ .x19 (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 64 j >>> 1) == (0 : BitVec 64)) = decide (j < 2) ∧
+ ((BitVec.ofNat 64 j - BitVec.ofNat 64 k) == (0 : BitVec 64)) = decide (j = k) := by
+ decide
+
+theorem write_keep (s : State) (v : BitVec 64) : Keep [.x4] s (s.write .x .x4 v) := by
+ refine ⟨?_, mem_write _ _ _ _, rd_write _ _ _ _, wr_write _ _ _ _⟩
+ intro r hr
+ simp only [List.mem_singleton] at hr
+ exact gpr_write_of_ne _ _ _ hr
+
+theorem lowTest_ok (s : State) (j : Nat) (hj : j < 16)
+ (hv : s.gpr .x21 = BitVec.ofNat 64 j) :
+ ∃ s', runBlock isa [.lsr .x .x4 .x21 1] s = some s' ∧
+ isa.eval (.zero .x .x4) s' = some (decide (j < 2)) ∧ Keep [.x4] s s' := by
+ refine ⟨s.write .x .x4 (s.gpr .x21 >>> 1), ?_, ?_, write_keep _ _⟩
+ · simp only [runBlock_cons, runStep_some, runBlock_nil, exec, Size.bits,
+ show (1 : Nat) < 64 from by decide, ite_true, State.read, BitVec.setWidth_eq]
+ · change VG.AArch64.eval (.zero .x .x4) _ = _
+ simp only [VG.AArch64.eval, State.read, gpr_write_self, BitVec.setWidth_eq, hv]
+ exact congrArg some (comparison_values j hj 0 (by decide)).1
+
+theorem eqTest_ok (s : State) (j k : Nat) (hj : j < 16) (hk : k < 16)
+ (hv : s.gpr .x21 = BitVec.ofNat 64 j) :
+ ∃ s', runBlock isa [.subImm .x .x4 .x21 k] s = some s' ∧
+ isa.eval (.zero .x .x4) s' = some (decide (j = k)) ∧ Keep [.x4] s s' := by
+ refine ⟨s.write .x .x4 (s.gpr .x21 - BitVec.ofNat 64 k), ?_, ?_, write_keep _ _⟩
+ · simp only [runBlock_cons, runStep_some, runBlock_nil, exec,
+ show k < 4096 from by omega, ite_true, State.read, BitVec.setWidth_eq]
+ · change VG.AArch64.eval (.zero .x .x4) _ = _
+ simp only [VG.AArch64.eval, State.read, gpr_write_self, BitVec.setWidth_eq, hv]
+ exact congrArg some (comparison_values j hj k hk).2
+
+theorem rotation_ok (s : State) (c d : BitVec 28) (j : Nat) (hj : j < 16)
+ (hc : s.gpr .x19 = c.setWidth 64) (hd : s.gpr .x20 = d.setWidth 64)
+ (hjreg : s.gpr .x21 = BitVec.ofNat 64 j) :
+ WP isa Impl.TripleDes.AArch64.Key.rotation s
+ (RotatePost c d (Spec.TripleDes.rotations.getD j 0) s) := by
+ rw [Impl.TripleDes.AArch64.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 [.x4] s s') (n : Nat) (hn : 1 ≤ n) (hn' : n < 28)
+ (hv : Spec.TripleDes.rotations.getD j 0 = n) :
+ WP isa (Impl.TripleDes.AArch64.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 .x19 (by simp)).trans hc)
+ ((h.reg .x20 (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 [.x4] s a) (hb : Keep [.x4] a b) : Keep [.x4] 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 .x21 (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 .x21 (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.AArch64.Key
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Save.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Save.lean
new file mode 100644
index 000000000..b6f09a033
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Save.lean
@@ -0,0 +1,55 @@
+import VerifiedGarbage.Proof.Rc2.AArch64.Save
+import VerifiedGarbage.Impl.TripleDes.AArch64.ExpandKey
+
+namespace VG.Proof.TripleDes.AArch64.Key
+
+open VG VG.AArch64 VG.Impl.TripleDes.AArch64
+
+/-- The four callee-saved registers, in slot order. -/
+def savedReg (i : Nat) : Reg := (Impl.TripleDes.AArch64.Key.savedRegs).getD i .x19
+
+theorem save_eq : Impl.TripleDes.AArch64.Key.save = VG.Proof.Rc2.AArch64.saveCode .x3 savedReg 4 := by
+ decide +kernel
+
+theorem restore_eq : Impl.TripleDes.AArch64.Key.restore = VG.Proof.Rc2.AArch64.restoreCode .x3 savedReg (List.range 4) := by
+ decide +kernel
+
+def Saved (original current : State) : Prop :=
+ ∀ i < 4, current.mem.readW (current.gpr .x3 + BitVec.ofNat 64 (8 * i)) 64 =
+ original.gpr (savedReg i)
+
+theorem save_ok (s : State)
+ (hw : ∀ i < 4, InRegions s.wr (s.gpr .x3 + BitVec.ofNat 64 (8 * i)) 8) :
+ WP isa (.block Impl.TripleDes.AArch64.Key.save) s (fun s' =>
+ s'.gpr = s.gpr ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧ Saved s s' ∧
+ Frame [⟨s.gpr .x3, 32⟩] s.mem s'.mem) := by
+ rw [save_eq]
+ apply WP.mono (VG.Proof.Rc2.AArch64.saveCode_ok s .x3 savedReg 4 (by decide) 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.AArch64.saveMem_read _ _ _ 4 (by decide) i hi
+ · rw [hs.2.2.2]
+ exact VG.Proof.Rc2.AArch64.saveMem_frame _ _ _ 4 (by decide)
+
+theorem savedReg_separate : ∀ i < 4, savedReg i ≠ .x3 := by decide +kernel
+
+theorem restore_ok (original s : State) (hsaved : Saved original s)
+ (hread : ∀ i < 4, InRegions (s.rd ++ s.wr) (s.gpr .x3 + BitVec.ofNat 64 (8 * i)) 8) :
+ WP isa (.block Impl.TripleDes.AArch64.Key.restore) s (fun s' =>
+ (∀ r ∈ Impl.TripleDes.AArch64.Key.savedRegs, s'.gpr r = original.gpr r) ∧
+ VG.Proof.Rc2.AArch64.Keep (Impl.TripleDes.AArch64.Key.savedRegs) s s') := by
+ rw [restore_eq]
+ have hregs : (List.range 4).map savedReg = Impl.TripleDes.AArch64.Key.savedRegs := by decide +kernel
+ have h := VG.Proof.Rc2.AArch64.restoreCode_ok s .x3 savedReg (List.range 4) original.gpr
+ (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.AArch64.Key
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Store.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Store.lean
new file mode 100644
index 000000000..b5b91fd88
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Store.lean
@@ -0,0 +1,104 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Key.Load
+
+namespace VG.Proof.TripleDes.AArch64.Key
+
+open VG VG.AArch64 VG.AArch64.RegUpd VG.Impl.TripleDes.AArch64
+
+def pack : List Instr := [.lsl .x .x4 .x19 28, .logic .eor .x .x4 .x4 .x20]
+
+def tail : List Instr := [.str .x .x5 .x22 0, .addImm .x .x22 .x22 8,
+ .addImm .x .x21 .x21 1, .subImm .x .x4 .x21 16]
+
+theorem pack_ok (s : State) (c d : BitVec 28)
+ (hc : s.gpr .x19 = c.setWidth 64) (hd : s.gpr .x20 = d.setWidth 64) :
+ ∃ s', runBlock isa pack s = some s' ∧
+ (s'.gpr .x4).setWidth 56 = c ++ d ∧
+ s'.mem = s.mem ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧
+ (∀ r, r ≠ .x4 → s'.gpr r = s.gpr r) := by
+ refine ⟨_, by
+ simp only [pack, runBlock_cons, runStep_some, runBlock_nil, exec, Size.bits,
+ show (28 : Nat) < 64 from by decide, ite_true, State.read,
+ BitVec.setWidth_eq, gpr_write_self]
+ rfl, ?_, ?_, ?_, ?_, ?_⟩
+ · simp only [gpr_write, BitVec.setWidth_eq, reduceCtorEq, ite_true, ite_false]
+ rw [hc, hd]; exact pack28_shift c d
+ · simp only [mem_write]
+ · simp only [rd_write]
+ · simp only [wr_write]
+ · intro r hr; simp only [gpr_write, hr, ite_false]
+
+theorem nextRound_values : ∀ j < 16,
+ BitVec.ofNat 64 j + 1 = BitVec.ofNat 64 (j + 1) ∧
+ ((BitVec.ofNat 64 j + 1 - (16 : BitVec 64)) != 0) = decide (j ≠ 15) := by decide
+
+theorem tail_ok (s : State) (j : Nat) (hj : j < 16)
+ (hc : s.gpr .x21 = BitVec.ofNat 64 j)
+ (hw : InRegions s.wr (s.gpr .x22) 8) :
+ ∃ s', runBlock isa tail s = some s' ∧
+ s'.mem = s.mem.writeW (s.gpr .x22) (s.gpr .x5) ∧
+ s'.gpr .x22 = s.gpr .x22 + 8 ∧ s'.gpr .x21 = BitVec.ofNat 64 (j + 1) ∧
+ isa.eval (.nonzero .x .x4) s' = some (decide (j ≠ 15)) ∧
+ s'.rd = s.rd ∧ s'.wr = s.wr ∧
+ (∀ r, r ≠ .x4 → r ≠ .x21 → r ≠ .x22 → s'.gpr r = s.gpr r) := by
+ have hstore := exec_str_x (t := .x5) (n := .x22) (off := 0) (by decide)
+ (by simpa only [BitVec.ofNat_eq_ofNat, BitVec.add_zero] using hw)
+ refine ⟨_, by
+ rw [tail, runBlock_cons, hstore, runStep_some]
+ simp only [runBlock_cons, runStep_some, runBlock_nil, exec,
+ show (8 : Nat) < 4096 from by decide, show (1 : Nat) < 4096 from by decide,
+ show (16 : Nat) < 4096 from by decide, ite_true, State.read, BitVec.setWidth_eq,
+ gpr_write, reduceCtorEq, ite_false, ite_true]
+ rfl, ?_, ?_, ?_, ?_, ?_, ?_, ?_⟩
+ · simp only [mem_write, BitVec.add_zero]
+ · simp only [gpr_write, BitVec.setWidth_eq, reduceCtorEq, ite_true, ite_false]; rfl
+ · simp only [gpr_write, BitVec.setWidth_eq, reduceCtorEq, ite_true, ite_false]
+ rw [hc]; exact (nextRound_values j hj).1
+ · change VG.AArch64.eval (.nonzero .x .x4) _ = _
+ simp only [VG.AArch64.eval, State.read, gpr_write, BitVec.setWidth_eq,
+ reduceCtorEq, ite_true, ite_false, hc]
+ exact congrArg some (nextRound_values j hj).2
+ · simp only [rd_write]
+ · simp only [wr_write]
+ · intro r h4 h21 h22; simp only [gpr_write, h4, h21, h22, ite_false]
+
+structure StorePost (c d : BitVec 28) (j : Nat) (s s' : State) : Prop where
+ mem : s'.mem = s.mem.writeW (s.gpr .x22) ((Spec.TripleDes.permute Spec.TripleDes.pc2 (c ++ d)).setWidth 64)
+ ptr : s'.gpr .x22 = s.gpr .x22 + 8
+ counter : s'.gpr .x21 = BitVec.ofNat 64 (j + 1)
+ flag : isa.eval (.nonzero .x .x4) s' = some (decide (j ≠ 15))
+ rd : s'.rd = s.rd
+ wr : s'.wr = s.wr
+ reg : ∀ r ∈ (keyKept ++ [.x19, .x20]), s'.gpr r = s.gpr r
+
+theorem storeRound_ok (s : State) (c d : BitVec 28) (j : Nat) (hj : j < 16)
+ (hc : s.gpr .x19 = c.setWidth 64) (hd : s.gpr .x20 = d.setWidth 64)
+ (hjreg : s.gpr .x21 = BitVec.ofNat 64 j) (hw : InRegions s.wr (s.gpr .x22) 8) :
+ WP isa (.block Impl.TripleDes.AArch64.Key.storeRound) s (StorePost c d j s) := by
+ have code : Impl.TripleDes.AArch64.Key.storeRound =
+ (pack ++ permuteCode Spec.TripleDes.pc2 56 .x5 .x4 .x6 .x7) ++ tail := rfl
+ rw [code, WP.block_append_iff, WP.block_append_iff]
+ obtain ⟨s₁, run₁, word₁, mem₁, rd₁, wr₁, reg₁⟩ := pack_ok s c d hc hd
+ refine WP.of_runBlock ⟨s₁, run₁, ?_⟩
+ obtain ⟨s₂, run₂, word₂, rd₂, wr₂, _, mem₂, reg₂⟩ := pc2_ok s₁
+ refine WP.of_runBlock ⟨s₂, run₂, ?_⟩
+ rw [word₁] at word₂
+ have checks : ∀ r ∈ (keyKept ++ [.x19, .x20, .x21, .x22]),
+ ((instrs keyPermutation2.lit).all fun op => dstOf op != some r) = true := by decide +kernel
+ have keep₂ : ∀ r ∈ (keyKept ++ [.x19, .x20, .x21, .x22]), s₂.gpr r = s.gpr r := by
+ intro r hr
+ have unused : ∀ r ∈ (keyKept ++ [.x19, .x20, .x21, .x22]), r ≠ .x4 := by decide
+ exact (reg₂ r (checks r hr)).trans (reg₁ r (unused r hr))
+ have counter₂ := (keep₂ .x21 (by decide)).trans hjreg
+ have write₂ : InRegions s₂.wr (s₂.gpr .x22) 8 := by
+ rw [wr₂, wr₁, keep₂ .x22 (by decide)]; exact hw
+ obtain ⟨s₃, run₃, mem₃, ptr₃, counter₃, flag₃, rd₃, wr₃, reg₃⟩ := tail_ok s₂ j hj counter₂ write₂
+ refine WP.of_runBlock ⟨s₃, run₃, ⟨?_, ?_, counter₃, flag₃, rd₃.trans (rd₂.trans rd₁),
+ wr₃.trans (wr₂.trans wr₁), ?_⟩⟩
+ · rw [mem₃, mem₂, mem₁, keep₂ .x22 (by decide), word₂]
+ · rw [ptr₃, keep₂ .x22 (by decide)]
+ · intro r hr
+ have incl : ∀ r ∈ (keyKept ++ [.x19, .x20]),
+ r ≠ .x4 ∧ r ≠ .x21 ∧ r ≠ .x22 ∧ r ∈ (keyKept ++ [.x19, .x20, .x21, .x22]) := by decide
+ exact (reg₃ r (incl r hr).1 (incl r hr).2.1 (incl r hr).2.2.1).trans (keep₂ r (incl r hr).2.2.2)
+
+end VG.Proof.TripleDes.AArch64.Key
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Verified.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Verified.lean
new file mode 100644
index 000000000..a5af3eeb2
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Verified.lean
@@ -0,0 +1,32 @@
+import VerifiedGarbage.Proof.Framework.AArch64.VecPreserved
+import VerifiedGarbage.Proof.TripleDes.AArch64.Key.Correct
+import VerifiedGarbage.Proof.Framework.Contract
+
+namespace VG.Proof.TripleDes.AArch64.Key
+
+open VG VG.AArch64
+
+def satState : State where
+ gpr r := match r with
+ | .x0 => 0x1000 | .x1 => 16 | .x2 => 0x2000 | .x3 => 0x3000 | _ => 0
+ sp := 0x4000
+ mem _ := 0
+ rd := [⟨0x1000, 16⟩]
+ wr := [⟨0x2000, 384⟩, ⟨0x3000, 512⟩]
+
+theorem correct (s : State) (hs : contract.pre s) :
+ ∃ t s', Exec isa Impl.TripleDes.AArch64.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.AArch64.Exec.sp he, VG.AArch64.Exec.preservedV he (by lit_decide)⟩, hp⟩
+
+theorem publicRegs_four (s₁ s₂ : State) : PublicRegs [.x0, .x1, .x2, .x3] s₁ s₂ ↔
+ s₁.sp = s₂.sp ∧ s₁.gpr .x0 = s₂.gpr .x0 ∧ s₁.gpr .x1 = s₂.gpr .x1 ∧ s₁.gpr .x2 = s₂.gpr .x2 ∧
+ s₁.gpr .x3 = s₂.gpr .x3 := by simp [PublicRegs]
+
+theorem verified : Verified target Impl.TripleDes.AArch64.Key.expandKey
+ (Spec.TripleDes.expandKeyContract abi) := by
+ refine Verified.of_correct correct (expandKey_constantTime _) ?_
+ sig_implies [Spec.TripleDes.expandKeyContract, Spec.TripleDes.expandKeySig, abi, argRegs,
+ contract, publicRegs_four] [satState] using satState
+
+end VG.Proof.TripleDes.AArch64.Key
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/KeySteps.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/KeySteps.lean
new file mode 100644
index 000000000..f5b30c456
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/KeySteps.lean
@@ -0,0 +1,34 @@
+import VerifiedGarbage.Impl.TripleDes.AArch64.ExpandKey
+import VerifiedGarbage.Proof.TripleDes.AArch64.Word
+import VerifiedGarbage.Proof.Framework.AArch64.Exec
+import VerifiedGarbage.Proof.Framework.AArch64.RegUpd
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.RegUpd VG.Impl.TripleDes.AArch64
+
+theorem rotate28_ok (s : State) (r : Reg) (hr : r ≠ .x4)
+ (x : BitVec 28) (hx : s.gpr r = x.setWidth 64)
+ (n : Nat) (hn : 1 ≤ n) (hn' : n < 28) :
+ ∃ s', runBlock isa (Key.rotate28 r n) s = some s' ∧
+ s'.gpr r = (x.rotateLeft n).setWidth 64 ∧
+ s'.mem = s.mem ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧
+ (∀ r', r' ≠ r → r' ≠ .x4 → s'.gpr r' = s.gpr r') := by
+ have hleft : 64 - n < 64 := by omega
+ have hright : 28 - n < 64 := by omega
+ refine ⟨_, by
+ simp only [Key.rotate28, mask, List.cons_append, List.nil_append,
+ runBlock_cons, runStep_some, runBlock_nil, exec, Size.bits, hleft, hright,
+ show (36 : Nat) < 64 from by decide, ite_true, State.read,
+ BitVec.setWidth_eq, hr, Ne.symm hr, gpr_write, ite_false]
+ rfl, ?_, ?_, ?_, ?_, ?_, ?_⟩
+ · simp only [gpr_write, ite_true, BitVec.setWidth_eq, hr, ite_false]
+ rw [hx, mask_word _ 28 (by decide) (by decide)]
+ exact (VG.Proof.TripleDes.mask28 _).symm.trans (VG.Proof.TripleDes.rotate28_word x n hn hn')
+ · simp only [mem_write]
+ · simp only [rd_write]
+ · simp only [wr_write]
+ · simp only [sp_write]
+ · intro r' h1 h2; simp only [gpr_write, h1, h2, ite_false]
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Lit.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Lit.lean
new file mode 100644
index 000000000..2db744d49
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Lit.lean
@@ -0,0 +1,21 @@
+import VerifiedGarbage.Impl.TripleDes.AArch64.Sbox
+import VerifiedGarbage.Impl.TripleDes.AArch64.Permutation
+import VerifiedGarbage.Proof.Framework.AArch64.Lit
+
+namespace VG.Impl.TripleDes.AArch64
+
+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.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Loop.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Loop.lean
new file mode 100644
index 000000000..507e9212f
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Loop.lean
@@ -0,0 +1,139 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.RoundStep
+import VerifiedGarbage.Proof.TripleDes.Core
+import VerifiedGarbage.Proof.Framework.Omega
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.Straight VG.Impl.TripleDes.AArch64
+open VG.Spec.TripleDes (Direction DesSchedule)
+open VG.Proof.TripleDes (roundKey roundPrefix feistelStep)
+
+def keyAddr (base : Addr) (direction : Direction) (j : Nat) : Addr :=
+ base + BitVec.ofNat 64 (8 * (if direction = .encrypt then j else 15 - j))
+
+theorem keyAddr_step (base : Addr) (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 64 (8 * j) + BitVec.ofNat 64 8 =
+ base + BitVec.ofNat 64 (8 * (j + 1))
+ rw [Offset.add_ofNat_add_ofNat]
+ exact congrArg (fun i => base + BitVec.ofNat 64 i) (by omega)
+ · change base + BitVec.ofNat 64 (8 * (15 - j)) - BitVec.ofNat 64 8 =
+ base + BitVec.ofNat 64 (8 * (15 - (j + 1)))
+ rw [Offset.add_ofNat_sub _ (by omega)]
+ exact congrArg (fun i => base + BitVec.ofNat 64 i) (by omega)
+
+structure LoopInv (keys : DesSchedule) (direction : Direction) (base : Addr)
+ (origin : State) (v : BitVec 32 × BitVec 32) (n : Nat) (s : State) : Prop where
+ positive : 1 ≤ n
+ bounded : n ≤ 16
+ left : s.gpr .x19 = (roundPrefix keys direction (16 - n) v).1.setWidth 64
+ right : s.gpr .x20 = (roundPrefix keys direction (16 - n) v).2.setWidth 64
+ counter : s.gpr .x21 = BitVec.ofNat 64 n
+ pointer : s.gpr .x22 = 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)
+ (origin : State) (v : BitVec 32 × BitVec 32) (s : State) : Prop where
+ left : s.gpr .x19 = (roundPrefix keys direction 16 v).1.setWidth 64
+ right : s.gpr .x20 = (roundPrefix keys direction 16 v).2.setWidth 64
+ counter : s.gpr .x21 = 0
+ 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 : Addr)
+ (origin : State) (v : BitVec 32 × BitVec 32)
+ (hok : Ok sboxCfg origin)
+ (hread : ∀ j < 16, InRegions (origin.rd ++ origin.wr) (keyAddr base direction j) 8)
+ (hsep : ∀ j < 16, (⟨keyAddr base direction j, 8⟩ : Region).Disjoint (spillRegion origin))
+ (hkeys : ∀ j < 16, (origin.mem.readW (keyAddr base direction j) 64).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 (.nonzero .x .x21) s' = some false ∧ LoopPost keys direction origin v s') ∨
+ (isa.eval (.nonzero .x .x21) 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 .x2 (by decide)]
+ have hokS : Ok sboxCfg s := hok.congr
+ (hs.regs .x2 (by decide)) (hs.regs .x2 (by decide)) hs.rd hs.wr
+ have hreadS : InRegions (s.rd ++ s.wr) (s.gpr .x22) 8 := by
+ rw [hs.rd, hs.wr, hs.pointer]; exact hread _ hj
+ have hsepS : (⟨s.gpr .x22, 8⟩ : Region).Disjoint (spillRegion s) := by
+ rw [hs.pointer]
+ rw [hwork]
+ exact hsep _ hj
+ have hk : (s.mem.readW (s.gpr .x22) 64).setWidth 48 = roundKey keys direction (16 - n) := by
+ rw [hs.pointer]
+ have hmem := hs.frame.readW (a := keyAddr base direction (16 - n)) (w := 64)
+ (r := ⟨keyAddr base direction (16 - n), 8⟩)
+ (Region.contains_self _ _) (fun q hq => by
+ obtain rfl := List.mem_singleton.mp hq
+ exact hsep _ hj) (by decide)
+ 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 _ _ (s.mem.readW (s.gpr .x22) 64) 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 .x19 = (roundPrefix keys direction (16 - (n - 1)) v).1.setWidth 64 := by
+ rw [hidx]
+ exact left.trans (congrArg (fun pair => pair.1.setWidth 64)
+ (VG.Proof.TripleDes.roundPrefix_succ keys direction (16 - n) v).symm)
+ have hright : s'.gpr .x20 = (roundPrefix keys direction (16 - (n - 1)) v).2.setWidth 64 := 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).setWidth 64) hk
+ exact (right.trans hval).trans (congrArg (fun pair => pair.2.setWidth 64)
+ (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, 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 : Addr)
+ (origin : State) (v : BitVec 32 × BitVec 32)
+ (hok : Ok sboxCfg origin)
+ (hl : origin.gpr .x19 = v.1.setWidth 64) (hr : origin.gpr .x20 = v.2.setWidth 64)
+ (hptr : origin.gpr .x22 = keyAddr base direction 0)
+ (hcount : origin.gpr .x21 = BitVec.ofNat 64 16)
+ (hread : ∀ j < 16, InRegions (origin.rd ++ origin.wr) (keyAddr base direction j) 8)
+ (hsep : ∀ j < 16, (⟨keyAddr base direction j, 8⟩ : Region).Disjoint (spillRegion origin))
+ (hkeys : ∀ j < 16, (origin.mem.readW (keyAddr base direction j) 64).setWidth 48 =
+ roundKey keys direction j) :
+ WP isa (.loop (.block (roundBody ++ roundAdvance direction)) (.nonzero .x .x21))
+ origin (LoopPost keys direction origin v) := by
+ apply WP.loop (M := isa) (body := .block (roundBody ++ roundAdvance direction))
+ (c := .nonzero .x .x21) (Q := LoopPost keys direction 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.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Pass.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Pass.lean
new file mode 100644
index 000000000..5b5287097
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Pass.lean
@@ -0,0 +1,85 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.PassStart
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.Straight VG.Impl.TripleDes.AArch64
+open VG.Spec.TripleDes (Direction DesSchedule)
+open VG.Proof.TripleDes (roundKey roundPrefix)
+
+structure PassPost (keys : DesSchedule) (direction : Direction)
+ (origin : State) (v : BitVec 32 × BitVec 32) (s : State) : Prop where
+ left : s.gpr .x19 = (roundPrefix keys direction 16 v).2.setWidth 64
+ right : s.gpr .x20 = (roundPrefix keys direction 16 v).1.setWidth 64
+ 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 : Addr)
+ (origin : State) (v : BitVec 32 × BitVec 32)
+ (hok : Ok sboxCfg origin)
+ (hl : origin.gpr .x19 = v.1.setWidth 64) (hr : origin.gpr .x20 = v.2.setWidth 64)
+ (hptr : origin.gpr .x22 = keyAddr base direction 0)
+ (hcount : origin.gpr .x21 = BitVec.ofNat 64 16)
+ (hread : ∀ j < 16, InRegions (origin.rd ++ origin.wr) (keyAddr base direction j) 8)
+ (hsep : ∀ j < 16, (⟨keyAddr base direction j, 8⟩ : Region).Disjoint (spillRegion origin))
+ (hkeys : ∀ j < 16, (origin.mem.readW (keyAddr base direction j) 64).setWidth 48 =
+ roundKey keys direction j) :
+ WP isa (.seq (.loop (.block (roundBody ++ roundAdvance direction)) (.nonzero .x .x21))
+ (.block swapHalves)) origin (PassPost keys direction 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,
+ 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 (component : Nat) (hc : component < 3)
+ (keys : DesSchedule) (direction : Direction) (base : Addr)
+ (origin : State) (v : BitVec 32 × BitVec 32)
+ (hok : Ok sboxCfg origin)
+ (hl : origin.gpr .x19 = v.1.setWidth 64) (hr : origin.gpr .x20 = v.2.setWidth 64)
+ (hptr : origin.gpr .x0 + BitVec.ofNat 64 (passOffset component direction) =
+ keyAddr base direction 0)
+ (hread : ∀ j < 16, InRegions (origin.rd ++ origin.wr) (keyAddr base direction j) 8)
+ (hsep : ∀ j < 16, (⟨keyAddr base direction j, 8⟩ : Region).Disjoint (spillRegion origin))
+ (hkeys : ∀ j < 16, (origin.mem.readW (keyAddr base direction j) 64).setWidth 48 =
+ roundKey keys direction j) :
+ WP isa (pass component direction) origin (PassPost keys direction origin v) := by
+ obtain ⟨s, run, ptr, count, mem, rd, wr, sp, regs⟩ := passStart_ok component hc direction origin
+ have hbase : s.gpr .x2 = origin.gpr .x2 := regs .x2 (by decide) (by decide)
+ have hwork : spillRegion s = spillRegion origin := by simp only [spillRegion, hbase]
+ have hkeysS : ∀ j < 16, (s.mem.readW (keyAddr base direction j) 64).setWidth 48 =
+ roundKey keys direction j := by rw [mem]; exact hkeys
+ have hreadS : ∀ j < 16, InRegions (s.rd ++ s.wr) (keyAddr base direction j) 8 := by
+ rw [rd, wr]; exact hread
+ have hsepS : ∀ j < 16, (⟨keyAddr base direction j, 8⟩ : 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 .x19 (by decide) (by decide)).trans hl)
+ ((regs .x20 (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.rd.trans rd, hs.wr.trans wr, hs.sp.trans sp, ?_, ?_⟩
+ · intro q hq
+ have hneq : ∀ r ∈ roundStepKept, r ≠ .x21 ∧ r ≠ .x22 := by decide
+ exact (hs.regs q hq).trans (regs q (hneq q hq).1 (hneq q hq).2)
+ · have hf := hs.frame
+ rw [hwork, mem] at hf
+ exact hf
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/PassStart.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/PassStart.lean
new file mode 100644
index 000000000..2d805e933
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/PassStart.lean
@@ -0,0 +1,40 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Loop
+import VerifiedGarbage.Proof.Framework.AArch64.RegUpd
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.RegUpd VG.Impl.TripleDes.AArch64
+open VG.Spec.TripleDes (Direction)
+
+def passOffset (component : Nat) (direction : Direction) : Nat :=
+ 128 * component + if direction = .encrypt then 0 else 120
+
+theorem passOffset_bound : ∀ c < 3, ∀ d : Direction, passOffset c d < 4096 := by
+ intro c hc d
+ cases d <;> simp only [passOffset, reduceCtorEq, ite_true, ite_false] <;> omega
+
+theorem passStart_ok (component : Nat) (hc : component < 3) (direction : Direction)
+ (s : State) :
+ ∃ s', runBlock isa (passStart component direction) s = some s' ∧
+ s'.gpr .x22 = s.gpr .x0 + BitVec.ofNat 64 (passOffset component direction) ∧
+ s'.gpr .x21 = BitVec.ofNat 64 16 ∧ s'.mem = s.mem ∧
+ s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧
+ (∀ r, r ≠ .x21 → r ≠ .x22 → s'.gpr r = s.gpr r) := by
+ have hb := passOffset_bound component hc direction
+ change 128 * component + (if direction = .encrypt then 0 else 120) < 4096 at hb
+ refine ⟨_, by
+ simp only [passStart, imm, runBlock_cons, runStep_some, runBlock_nil, exec,
+ hb, ite_true, Size.bits, Nat.mul_zero,
+ show (0 : Nat) < 64 from by decide, State.read, BitVec.setWidth_eq]
+ rfl, ?_, ?_, ?_, ?_, ?_, ?_, ?_⟩
+ · simp only [gpr_write, reduceCtorEq, ite_false, ite_true, BitVec.setWidth_eq]
+ rfl
+ · simp only [gpr_write, ite_true, BitVec.setWidth_eq]; rfl
+ · simp only [mem_write]
+ · simp only [rd_write]
+ · simp only [wr_write]
+ · simp only [sp_write]
+ · intro r hr₁ hr₂
+ simp only [gpr_write, hr₁, hr₂, ite_false]
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Permutation.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Permutation.lean
new file mode 100644
index 000000000..1e9744e19
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Permutation.lean
@@ -0,0 +1,90 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Lit
+import VerifiedGarbage.Proof.TripleDes.Permutation
+import VerifiedGarbage.Proof.Framework.AArch64.Linear
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.Straight VG.Bitslice VG.Impl.TripleDes.AArch64
+
+def permutationCfg : Cfg := { base := .x2, slots := 0, ext := .x2, exts := 0 }
+def permutationInputs (src : Reg) : List (Reg × Nat) := [(src, 0)]
+
+def permutationBits {m : Nat} (positions : Vector Nat m) (n p : Nat) : List Nat :=
+ if p < m then [n - positions.getD (m - 1 - p) 1] else []
+
+def permutationOutputs {m : Nat} (positions : Vector Nat m) (n : Nat) (dst : Reg) :
+ List (Reg × (Nat → List Nat)) := [(dst, permutationBits positions n)]
+
+theorem initialPermutation_check :
+ check (lanes 64 6) permutationCfg (linExt 1) (instrs initialPermutation.lit)
+ (linEnv (permutationInputs .x3)) (linPost 6 (permutationOutputs Spec.TripleDes.ip 64 .x10)) = true := by
+ decide +kernel
+
+theorem finalPermutation_check :
+ check (lanes 64 6) permutationCfg (linExt 1) (instrs finalPermutation.lit)
+ (linEnv (permutationInputs .x3)) (linPost 6 (permutationOutputs Spec.TripleDes.fp 64 .x10)) = true := by
+ decide +kernel
+
+theorem keyPermutation1_check :
+ check (lanes 64 6) permutationCfg (linExt 1) (instrs keyPermutation1.lit)
+ (linEnv (permutationInputs .x4)) (linPost 6 (permutationOutputs Spec.TripleDes.pc1 64 .x5)) = true := by
+ decide +kernel
+
+theorem keyPermutation2_check :
+ check (lanes 64 6) permutationCfg (linExt 1) (instrs keyPermutation2.lit)
+ (linEnv (permutationInputs .x4)) (linPost 6 (permutationOutputs Spec.TripleDes.pc2 56 .x5)) = true := by
+ decide +kernel
+
+theorem permutationCfg_ok (s : State) : Ok permutationCfg s := by
+ refine ⟨?_, ?_, by decide, ?_⟩
+ · intro k hk; simp [permutationCfg] at hk
+ · intro k hk; simp [permutationCfg] at hk
+ · intro k hk; simp [permutationCfg] at hk
+
+theorem fixedPermutation_ok {m n : Nat} (positions : Vector Nat m)
+ (hn : 0 < n) (hn64 : n ≤ 64)
+ (bounds : ∀ k < m, 1 ≤ positions.getD k 1 ∧ positions.getD k 1 ≤ n)
+ (src dst : Reg) (is : List Instr)
+ (hchk : check (lanes 64 6) permutationCfg (linExt 1) is
+ (linEnv (permutationInputs src)) (linPost 6 (permutationOutputs positions n dst)) = true)
+ (s : State) :
+ ∃ s', runBlock isa is s = some s' ∧
+ s'.gpr dst = (Spec.TripleDes.permute positions ((s.gpr src).setWidth n)).zeroExtend 64 ∧
+ 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 64 := fun _ => s.gpr src
+ 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_singleton, Prod.mk.injEq] at h
+ obtain ⟨rfl, rfl⟩ := 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 j hj
+ have hout := out dst (permutationBits positions n) (by simp [permutationOutputs]) j hj
+ change (s'.gpr dst).getLsbD j =
+ ((Spec.TripleDes.permute positions ((s.gpr src).setWidth n)).setWidth 64).getLsbD j
+ rw [BitVec.getLsbD_setWidth]
+ simp only [hj, decide_true, Bool.true_and]
+ rw [hout]
+ by_cases hjm : j < m
+ · have hk : m - 1 - j < m := by omega
+ obtain ⟨hlo, hhi⟩ := bounds _ hk
+ have hsource : n - positions.getD (m - 1 - j) 1 < n := by omega
+ have h64 : n - positions.getD (m - 1 - j) 1 < 64 := by omega
+ rw [VG.Proof.TripleDes.permute_bit positions _ hn j hjm,
+ BitVec.getLsbD_setWidth]
+ simp only [hsource, decide_true, Bool.true_and, permutationBits, hjm, ite_true,
+ xorBits, List.foldr_cons, List.foldr_nil, Bool.xor_false, bitOf,
+ Nat.mod_eq_of_lt h64, W]
+ · rw [BitVec.getLsbD_of_ge _ _ (by omega)]
+ simp only [permutationBits, hjm, ite_false, xorBits, List.foldr_nil]
+ · 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.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Pre.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Pre.lean
new file mode 100644
index 000000000..6d09e6582
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Pre.lean
@@ -0,0 +1,79 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Block
+import VerifiedGarbage.Proof.TripleDes.Schedule
+import VerifiedGarbage.Proof.TripleDes.AArch64.ConstantTime
+import VerifiedGarbage.Proof.Framework.AArch64.VecPreserved
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.Straight VG.Impl.TripleDes.AArch64
+open VG.Spec.TripleDes (Direction)
+
+def blockContract (d : Direction) : Contract isa where
+ pre s :=
+ let key : Region := ⟨s.gpr .x0, 384⟩
+ let data : Region := ⟨s.gpr .x1, 8⟩
+ let scratch : Region := ⟨s.gpr .x2, 512⟩
+ s.rd = [key] ∧ s.wr = [data, scratch] ∧ key.Disjoint scratch ∧ data.Disjoint scratch
+ post s s' := Spec.TripleDes.blockAt s'.mem (s.gpr .x1) =
+ blockResult (Spec.TripleDes.scheduleAt s.mem (s.gpr .x0)) d (Spec.TripleDes.blockAt s.mem (s.gpr .x1))
+ pub := PublicRegs [.x0, .x1, .x2]
+
+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 : Addr) (c : Nat) (d : Direction) (j : Nat) :
+ keyAddr (componentBase base c) d j = base + BitVec.ofNat 64 (8 * (16 * c + selectedRound d j)) := by
+ unfold keyAddr componentBase selectedRound
+ rw [Offset.add_ofNat_add_ofNat]
+ exact congrArg (fun n => base + BitVec.ofNat 64 n) (by omega)
+
+theorem headPre_of_contract (d : Direction) (s : State) (hs : (blockContract d).pre s) :
+ HeadPre (Spec.TripleDes.componentSchedule (Spec.TripleDes.scheduleAt s.mem (s.gpr .x0)))
+ (s.gpr .x0) s := by
+ obtain ⟨hrd, hwr, keySep, dataSep⟩ := hs
+ have scratchWrites : ∀ i < 64, InRegions s.wr (s.gpr .x2 + BitVec.ofNat 64 (8 * i)) 8 := by
+ intro i hi
+ rw [hwr]
+ exact ⟨⟨s.gpr .x2, 512⟩, by simp, Offset.contains_base _ (by omega) (by omega)⟩
+ have scratchReads : ∀ i < 64, InRegions (s.rd ++ s.wr) (s.gpr .x2 + BitVec.ofNat 64 (8 * i)) 8 := by
+ intro i hi
+ rw [hrd, hwr]
+ exact ⟨⟨s.gpr .x2, 512⟩, by simp, Offset.contains_base _ (by omega) (by omega)⟩
+ have spills : Ok sboxCfg s := by
+ refine ⟨scratchWrites, ?_, by decide, ?_⟩
+ · intro k hk; change k < 0 at hk; omega
+ · intro k hk j hj; change j < 0 at hj; omega
+ have keyContains : ∀ c < 3, ∀ direction : Direction, ∀ j < 16,
+ (⟨s.gpr .x0, 384⟩ : Region).Contains (keyAddr (componentBase (s.gpr .x0) c) direction j) 8 := by
+ intro c hc direction j hj
+ rw [keyAddr_component]
+ have hindex := selectedRound_bound direction j hj
+ exact Offset.contains_base _ (by omega) (by omega)
+ have keySub : ∀ c < 3, ∀ direction : Direction, ∀ j < 16,
+ Region.Sub ⟨keyAddr (componentBase (s.gpr .x0) c) direction j, 8⟩ ⟨s.gpr .x0, 384⟩ := by
+ intro c hc direction j hj
+ rw [keyAddr_component]
+ have hindex := selectedRound_bound direction j hj
+ exact Offset.sub_base _ (by omega)
+ have workSub : Region.Sub (spillRegion s) ⟨s.gpr .x2, 512⟩ := Offset.sub_base _ (by decide)
+ have saveSub : Region.Sub (saveRegion s) ⟨s.gpr .x2, 512⟩ := Region.sub_prefix (by decide)
+ refine ⟨spills, rfl, (fun i hi => scratchReads i (by omega)),
+ (fun i hi => scratchWrites i (by omega)), ?_, dataSep.sub_right saveSub, ?_, ?_, ?_, ?_⟩
+ · rw [hrd, hwr]
+ exact ⟨⟨s.gpr .x1, 8⟩, by simp, Region.contains_self _ _⟩
+ · intro c hc direction j hj
+ rw [hrd, hwr]
+ exact ⟨⟨s.gpr .x0, 384⟩, by simp, keyContains c hc direction j hj⟩
+ · intro c hc direction j hj
+ exact (keySep.sub_left (keySub c hc direction j hj)).sub_right workSub
+ · intro c hc direction j hj
+ exact (keySep.sub_left (keySub c hc direction j hj)).sub_right saveSub
+ · intro c hc direction j hj
+ rw [keyAddr_component]
+ exact (VG.Proof.TripleDes.componentSchedule_readW s.mem (s.gpr .x0) c
+ (selectedRound direction j) hc (selectedRound_bound direction j hj)).symm
+
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ready.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ready.lean
new file mode 100644
index 000000000..932cefcde
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ready.lean
@@ -0,0 +1,83 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.WordState
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.Straight VG.Impl.TripleDes.AArch64
+open VG.Spec.TripleDes (Direction DesSchedule)
+open VG.Proof.TripleDes (roundKey)
+
+def componentBase (base : Addr) (component : Nat) : Addr :=
+ base + BitVec.ofNat 64 (128 * component)
+
+structure Ready (keys : Nat → DesSchedule) (base : Addr) (s : State) : Prop where
+ spills : Ok sboxCfg s
+ baseReg : s.gpr .x0 = base
+ read : ∀ c < 3, ∀ d : Direction, ∀ j < 16,
+ InRegions (s.rd ++ s.wr) (keyAddr (componentBase base c) d j) 8
+ separate : ∀ c < 3, ∀ d : Direction, ∀ j < 16,
+ (⟨keyAddr (componentBase base c) d j, 8⟩ : Region).Disjoint (spillRegion s)
+ values : ∀ c < 3, ∀ d : Direction, ∀ j < 16,
+ (s.mem.readW (keyAddr (componentBase base c) d j) 64).setWidth 48 = roundKey (keys c) d j
+
+theorem Ready.congr {keys : Nat → DesSchedule} {base : Addr} {s t : State}
+ (hs : Ready keys base s) (hbase : t.gpr .x2 = s.gpr .x2)
+ (hkey : t.gpr .x0 = s.gpr .x0) (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 => (⟨p + BitVec.ofNat 64 32, 384⟩ : Region)) hbase
+ refine ⟨hs.spills.congr hbase hbase hrd hwr, hkey.trans hs.baseReg, ?_, ?_, ?_⟩
+ · rw [hrd, hwr]; exact hs.read
+ · rw [hwork]; exact hs.separate
+ · intro c hc d j hj
+ have hmem := hf.readW (a := keyAddr (componentBase base c) d j) (w := 64)
+ (r := ⟨keyAddr (componentBase base c) d j, 8⟩) (Region.contains_self _ _)
+ (fun q hq => by obtain rfl := List.mem_singleton.mp hq; exact hs.separate c hc d j hj) (by decide)
+ exact (congrArg (BitVec.setWidth 48) hmem).trans (hs.values c hc d j hj)
+
+theorem passPointer (base : Addr) (c : Nat) (d : Direction) :
+ base + BitVec.ofNat 64 (passOffset c d) = keyAddr (componentBase base c) d 0 := by
+ cases d
+ · change base + BitVec.ofNat 64 (128 * c + 0) = base + BitVec.ofNat 64 (128 * c) + (0 : BitVec 64)
+ exact (congrArg (fun n => base + BitVec.ofNat 64 n) (Nat.add_zero (128 * c))).trans
+ (BitVec.add_zero (base + BitVec.ofNat 64 (128 * c))).symm
+ · simp only [passOffset, keyAddr, componentBase, reduceCtorEq, ite_false]
+ rw [Offset.add_ofNat_add_ofNat]
+
+
+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 => (⟨p + BitVec.ofNat 64 32, 384⟩ : Region)) (hs.regs .x2 (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 : Addr) (s : State) (x : BitVec 64)
+ (c : Nat) (hc : c < 3) (d : Direction)
+ (hready : Ready keys base s) (hword : WordState x s) :
+ WP isa (pass c d) s (fun t => WordState (VG.Proof.TripleDes.desCore (keys c) d x) t ∧
+ Ready keys base t ∧ Stable s t) := by
+ have hptr : s.gpr .x0 + BitVec.ofNat 64 (passOffset c d) =
+ keyAddr (componentBase base c) d 0 := by
+ rw [hready.baseReg]
+ exact passPointer base c d
+ apply WP.mono (pass_ok c hc (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 .x2 (by decide)) (ht.regs .x0 (by decide)) ht.rd ht.wr ht.frame,
+ ht.rd, ht.wr, ht.sp, ht.regs, ht.frame⟩
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Round.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Round.lean
new file mode 100644
index 000000000..8ccc5ce8d
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Round.lean
@@ -0,0 +1,285 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.RoundLit
+import VerifiedGarbage.Proof.TripleDes.AArch64.Sbox
+import VerifiedGarbage.Proof.TripleDes.Permutation
+import VerifiedGarbage.Proof.Framework.AArch64.Linear
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.Straight VG.Bitslice VG.Impl.TripleDes.AArch64
+
+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 := .x2, slots := 0, ext := .x22, exts := 1 }
+def roundInputRegs : List (Reg × Nat) := [(.x20, 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, 64 + (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 64 7) roundInputCfg (linExt 1) (instrs (sboxInputsLiteral i))
+ (linEnv roundInputRegs) (linPost 7 (roundInputPost i)) = true := by
+ decide +kernel
+
+def roundOutputCfg : Cfg := { base := .x2, slots := 0, ext := .x2, exts := 0 }
+def roundOutputRegs : List (Reg × Nat) :=
+ [(.x19, 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 (64 * (j + 1)) else none)
+
+theorem roundOutput_check : ∀ i < 8,
+ check (lanes 64 9) roundOutputCfg (linExt 5) (instrs (sboxOutputsLiteral i))
+ (linEnv roundOutputRegs) (linPost 9 [(.x19, 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 : InRegions (s.rd ++ s.wr) (s.gpr .x22) 8) : Ok roundInputCfg s := by
+ refine ⟨?_, ?_, by decide, ?_⟩
+ · intro k hk; simp [roundInputCfg] at hk
+ · intro k hk
+ have hk0 : k = 0 := by simp only [roundInputCfg] at hk; omega
+ subst k
+ simpa only [roundInputCfg, wordAddr, Nat.mul_zero,
+ BitVec.add_zero] using hread
+ · 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 : InRegions (s.rd ++ s.wr) (s.gpr .x22) 8) :
+ ∃ s', runBlock isa (sboxInputs i) s = some s' ∧
+ (∀ j < 6, ∀ p < 64, (s'.gpr (q j)).getLsbD p =
+ xorBits (fun k => if k = 0 then s.gpr .x20
+ else s.mem.readW (s.gpr .x22) 64) (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 64 := fun k =>
+ if k = 0 then s.gpr .x20 else s.mem.readW (s.gpr .x22) 64
+ 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 hj0 : j = 0 := by simp only [roundInputCfg] at hj; omega
+ subst j
+ exact ⟨by decide, by simp [W, wordAddr, 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 < 64 ∧
+ 47 - (6 * i + 5 - j) < 64 := by
+ decide +kernel
+
+theorem bitOf_low (W : Nat → BitVec 64) (a : Nat) (ha : a < 64) :
+ bitOf W a = (W 0).getLsbD a := by
+ simp only [bitOf, Nat.div_eq_of_lt ha, Nat.mod_eq_of_lt ha]
+
+theorem bitOf_next (W : Nat → BitVec 64) (a : Nat) (ha : a < 64) :
+ bitOf W (64 + a) = (W 1).getLsbD a := by
+ have hd : (64 + a) / 64 = 1 := by omega
+ simp only [bitOf, hd, Nat.add_mod_left, Nat.mod_eq_of_lt ha]
+
+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 64) (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 : InRegions (s.rd ++ s.wr) (s.gpr .x22) 8) :
+ ∃ s', runBlock isa (sboxInputs i) s = some s' ∧
+ inputAt s' 0 = roundChunk i ((s.gpr .x20).setWidth 32)
+ ((s.mem.readW (s.gpr .x22) 64).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_next _ _ hk, ite_true]
+ rfl
+
+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 < 64,
+ roundOutputBits i p = [p] ++
+ (if p < 32 ∧ boxSource p / 4 = i then
+ [64 * (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 ⟨?_, ?_, by decide, ?_⟩
+ · intro k hk; simp [roundOutputCfg] at hk
+ · intro k hk; simp [roundOutputCfg] at hk
+ · 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 < 64, (s'.gpr .x19).getLsbD p =
+ xorBits (fun k => if k = 0 then s.gpr .x19 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 64 := fun k =>
+ if k = 0 then s.gpr .x19 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 .x19 (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 64) (j : Nat) :
+ bitOf W (64 * 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 .x19 = s.gpr .x19 ^^^ (boxPiece i b).zeroExtend 64 ∧
+ 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]
+ · simp only [h, ite_false, xorBits_nil]
+ simp only [boxPiece, getLsbD_ofBits]
+ by_cases hp32 : p < 32
+ · have hs : boxSource p / 4 ≠ i := by omega
+ simp only [hp32, decide_true, Bool.true_and, hs, ite_false]
+ · simp only [hp32, decide_false, Bool.false_and]
+
+def roundKept : List Reg := [.x0, .x1, .x2, .x20, .x21, .x22, .x23, .x24, .x25, .x26, .x27, .x28, .x30]
+
+theorem roundInput_keeps : ∀ i < 8, (.x19 :: 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 ∈ .x19 :: 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.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundBody.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundBody.lean
new file mode 100644
index 000000000..f8f31458e
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundBody.lean
@@ -0,0 +1,126 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Box
+import VerifiedGarbage.Proof.TripleDes.AArch64.RoundFunction
+import VerifiedGarbage.Proof.Framework.AArch64.RegUpd
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.Straight VG.Impl.TripleDes.AArch64
+
+def contribution (r k : BitVec 64) (i : Nat) : BitVec 64 :=
+ (boxPiece i (Spec.TripleDes.sBox i
+ (roundChunk i (r.setWidth 32) (k.setWidth 48)))).zeroExtend 64
+
+/-- 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 k : BitVec 64) (s : State) (hok : Ok sboxCfg s)
+ (hr : s.gpr .x20 = r) (hk : s.mem.readW (s.gpr .x22) 64 = k)
+ (hread : InRegions (s.rd ++ s.wr) (s.gpr .x22) 8)
+ (hsep : (⟨s.gpr .x22, 8⟩ : Region).Disjoint (spillRegion s)) :
+ ∃ s', runBlock isa (indices.flatMap box) s = some s' ∧
+ s'.gpr .x19 = indices.foldl (fun out i => out ^^^ contribution r k i) (s.gpr .x19) ∧
+ 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₁ .x2 (by decide)]
+ have hr₁ : s₁.gpr .x20 = r := (keep₁ .x20 (by decide)).trans hr
+ have hk₁ : s₁.mem.readW (s₁.gpr .x22) 64 = k := by
+ rw [keep₁ .x22 (by decide)]
+ refine Eq.trans (frame₁.readW (r := ⟨s.gpr .x22, 8⟩) ?_ ?_ (by decide)) hk
+ · simp [Region.Contains]
+ · intro q hq
+ obtain rfl := List.mem_singleton.mp hq
+ exact hsep
+ have hread₁ : InRegions (s₁.rd ++ s₁.wr) (s₁.gpr .x22) 8 := by
+ rw [rd₁, wr₁, keep₁ .x22 (by decide)]
+ exact hread
+ have hsep₁ : (⟨s₁.gpr .x22, 8⟩ : Region).Disjoint (spillRegion s₁) := by
+ rw [keep₁ .x22 (by decide), hregion]
+ exact hsep
+ have hok₁ : Ok sboxCfg s₁ := hok.congr
+ (keep₁ .x2 (by decide)) (keep₁ .x2 (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 .x19 = s.gpr .x19 ^^^ 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 k : BitVec 64) (l : BitVec 64) :
+ (List.range 8).foldl (fun out i => out ^^^ contribution r k i) l =
+ l ^^^ (Spec.TripleDes.roundFunction (r.setWidth 32) (k.setWidth 48)).zeroExtend 64 := by
+ rw [foldl_xor_start]
+ have hf := foldl_xor_extend (List.range 8)
+ (fun i => boxPiece i (Spec.TripleDes.sBox i
+ (roundChunk i (r.setWidth 32) (k.setWidth 48)))) 0
+ have hz : (0 : BitVec 32).setWidth 64 = 0 := BitVec.setWidth_zero 64 32
+ have hinit := congrArg (fun b : BitVec 64 =>
+ (List.range 8).foldl (fun out i => out ^^^ contribution r k i) b) hz
+ have hg := congrArg (BitVec.setWidth 64)
+ (boxPieces_eq_roundFunction (r.setWidth 32) (k.setWidth 48))
+ exact congrArg (fun x => l ^^^ x) ((hinit.symm.trans hf).trans hg)
+
+def roundOuterKept : List Reg := [.x0, .x1, .x2, .x21, .x22, .x23, .x24, .x25, .x26, .x27, .x28, .x30]
+
+theorem swapHalves_ok (s : State) :
+ ∃ s', runBlock isa swapHalves s = some s' ∧
+ s'.gpr .x19 = s.gpr .x20 ∧ s'.gpr .x20 = s.gpr .x19 ∧
+ 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.AArch64.RegUpd in
+ refine ⟨_, by
+ simp only [swapHalves, rr, runBlock_cons, runStep_some, runBlock_nil, exec,
+ show (0 : Nat) < 4096 from by decide, ite_true, State.read,
+ BitVec.setWidth_eq, BitVec.add_zero, gpr_write]
+ rfl, ?_, ?_, ?_, ?_, ?_, ?_, ?_⟩
+ · simp only [gpr_write, BitVec.setWidth_eq]; rfl
+ · simp only [gpr_write, BitVec.setWidth_eq]; rfl
+ · simp only [rd_write]
+ · simp only [wr_write]
+ · simp only [sp_write]
+ · simp only [mem_write]
+ · intro q hq
+ have hneq : q ≠ .x3 ∧ q ≠ .x19 ∧ q ≠ .x20 := by
+ revert hq; cases q <;> decide
+ simp only [gpr_write, 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 .x19 = l.setWidth 64) (hr : s.gpr .x20 = r.setWidth 64)
+ (hk : s.mem.readW (s.gpr .x22) 64 = k) (hok : Ok sboxCfg s)
+ (hread : InRegions (s.rd ++ s.wr) (s.gpr .x22) 8)
+ (hsep : (⟨s.gpr .x22, 8⟩ : Region).Disjoint (spillRegion s)) :
+ ∃ s', runBlock isa roundBody s = some s' ∧
+ s'.gpr .x19 = r.setWidth 64 ∧
+ s'.gpr .x20 = (l ^^^ Spec.TripleDes.roundFunction r (k.setWidth 48)).setWidth 64 ∧
+ 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.setWidth 64) 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₁ .x20 (by decide)).trans hr)
+ · rw [right, value, contributions_roundFunction, hl]
+ have hwidth : (r.setWidth 64).setWidth 32 = r := by simp
+ rw [hwidth]
+ exact BitVec.setWidth_xor.symm
+ · 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.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundFunction.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundFunction.lean
new file mode 100644
index 000000000..a7f5674e1
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundFunction.lean
@@ -0,0 +1,82 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Round
+import VerifiedGarbage.Proof.TripleDes.Round
+
+namespace VG.Proof.TripleDes.AArch64
+
+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 64) (a : BitVec 64) :
+ 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 64) ^^^ f i = f i := BitVec.zero_xor
+ rw [hz, ih (a ^^^ f i), ih (f i)]
+ exact BitVec.xor_assoc _ _ _
+
+theorem foldl_xor_extend (xs : List Nat) (f : Nat → BitVec 32) (a : BitVec 32) :
+ xs.foldl (fun out i => out ^^^ (f i).setWidth 64) (a.setWidth 64) =
+ (xs.foldl (fun out i => out ^^^ f i) a).setWidth 64 := by
+ induction xs generalizing a with
+ | nil => rfl
+ | cons i xs ih =>
+ simp only [List.foldl_cons]
+ rw [← BitVec.setWidth_xor]
+ exact ih _
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundLit.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundLit.lean
new file mode 100644
index 000000000..1282e2a0e
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundLit.lean
@@ -0,0 +1,25 @@
+import VerifiedGarbage.Impl.TripleDes.AArch64.Block
+import VerifiedGarbage.Proof.Framework.AArch64.Lit
+
+namespace VG.Impl.TripleDes.AArch64
+
+open VG.AArch64
+
+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.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundStep.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundStep.lean
new file mode 100644
index 000000000..0e1b02ea9
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundStep.lean
@@ -0,0 +1,69 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.RoundBody
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.Straight VG.AArch64.RegUpd VG.Impl.TripleDes.AArch64
+
+def roundStepKept : List Reg := [.x0, .x1, .x2, .x23, .x24, .x25, .x26, .x27, .x28, .x30]
+
+theorem countDown_rules : ∀ n < 17, 1 ≤ n →
+ (BitVec.ofNat 64 n - 1 = BitVec.ofNat 64 (n - 1)) ∧
+ ((BitVec.ofNat 64 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 .x22 = (if d = .encrypt then s.gpr .x22 + 8 else s.gpr .x22 - 8) ∧
+ s'.gpr .x21 = s.gpr .x21 - 1 ∧
+ s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧ s'.mem = s.mem ∧
+ (∀ r, r ≠ .x21 → r ≠ .x22 → s'.gpr r = s.gpr r) := by
+ cases d <;> refine ⟨_, by
+ simp only [roundAdvance, ite_true, reduceCtorEq, ite_false, runBlock_cons,
+ runStep_some, runBlock_nil, exec, show (8 : Nat) < 4096 from by decide,
+ show (1 : Nat) < 4096 from by decide, ite_true, State.read,
+ BitVec.setWidth_eq, gpr_write]
+ rfl, ?_, ?_, ?_, ?_, ?_, ?_, ?_⟩
+ all_goals
+ try simp only [gpr_write, BitVec.setWidth_eq, rd_write, wr_write, sp_write, mem_write,
+ reduceCtorEq, ite_true, ite_false]
+ 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 .x19 = l.setWidth 64) (hr : s.gpr .x20 = r.setWidth 64)
+ (hk : s.mem.readW (s.gpr .x22) 64 = k) (hok : Ok sboxCfg s)
+ (hread : InRegions (s.rd ++ s.wr) (s.gpr .x22) 8)
+ (hsep : (⟨s.gpr .x22, 8⟩ : Region).Disjoint (spillRegion s))
+ (hcount : s.gpr .x21 = BitVec.ofNat 64 n) :
+ ∃ s', runBlock isa (roundBody ++ roundAdvance d) s = some s' ∧
+ s'.gpr .x19 = r.setWidth 64 ∧
+ s'.gpr .x20 = (l ^^^ Spec.TripleDes.roundFunction r (k.setWidth 48)).setWidth 64 ∧
+ s'.gpr .x22 = (if d = .encrypt then s.gpr .x22 + 8 else s.gpr .x22 - 8) ∧
+ s'.gpr .x21 = BitVec.ofNat 64 (n - 1) ∧
+ isa.eval (.nonzero .x .x21) 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₂, rd₂, wr₂, sp₂, mem₂, keep₂⟩ := roundAdvance_ok d s₁
+ obtain ⟨hsub, hzero⟩ := countDown_rules n hn' hn
+ have hcount₁ : s₁.gpr .x21 = BitVec.ofNat 64 n := (keep₁ .x21 (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₂ .x19 (by decide) (by decide)).trans left₁
+ · exact (keep₂ .x20 (by decide) (by decide)).trans right₁
+ · rw [ptr₂, keep₁ .x22 (by decide)]
+ · rw [count₂, hcount₁, hsub]
+ · change VG.AArch64.eval (.nonzero .x .x21) s₂ = _
+ simp only [VG.AArch64.eval, State.read, BitVec.setWidth_eq, count₂, hcount₁, hzero]
+ · intro q hq
+ have hq' : q ∈ roundOuterKept := by revert hq; cases q <;> decide
+ have hneq : q ≠ .x21 ∧ q ≠ .x22 := 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.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Save.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Save.lean
new file mode 100644
index 000000000..78a8a1fbd
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Save.lean
@@ -0,0 +1,75 @@
+import VerifiedGarbage.Proof.Rc2.AArch64.Save
+import VerifiedGarbage.Proof.TripleDes.AArch64.RoundStep
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.Impl.TripleDes.AArch64
+
+def savedReg (i : Nat) : Reg := savedRegs.getD i .x19
+
+theorem blockSave_eq : blockSave = VG.Proof.Rc2.AArch64.saveCode .x2 savedReg 4 := by
+ decide +kernel
+
+theorem blockRestore_eq : blockRestore = VG.Proof.Rc2.AArch64.restoreCode .x2 savedReg (List.range 4) := by
+ decide +kernel
+
+def Saved (original current : State) : Prop :=
+ ∀ i < 4, current.mem.readW (current.gpr .x2 + BitVec.ofNat 64 (8 * i)) 64 =
+ 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 [⟨original.gpr .x2, 32⟩] original.mem current.mem
+
+theorem blockSave_ok (s : State)
+ (hw : ∀ i < 4, InRegions s.wr (s.gpr .x2 + BitVec.ofNat 64 (8 * i)) 8) :
+ WP isa (.block blockSave) s (SavePost s) := by
+ rw [blockSave_eq]
+ obtain ⟨t, s', he, hs⟩ := VG.Proof.Rc2.AArch64.saveCode_ok s .x2 savedReg 4 (by decide) hw
+ refine ⟨t, s', he, hs.1, hs.2.1, hs.2.2.1, VG.AArch64.Exec.sp he, ?_, ?_⟩
+ · intro i hi
+ rw [hs.1, hs.2.2.2]
+ exact VG.Proof.Rc2.AArch64.saveMem_read _ _ _ 4 (by decide) i hi
+ · rw [hs.2.2.2]
+ exact VG.Proof.Rc2.AArch64.saveMem_frame _ _ _ 4 (by decide)
+
+theorem savedReg_separate : ∀ i < 4, savedReg i ≠ .x2 := by decide +kernel
+
+structure RestorePost (original origin current : State) : Prop where
+ saved : ∀ r ∈ savedRegs, current.gpr r = original.gpr r
+ keep : VG.Proof.Rc2.AArch64.Keep savedRegs origin current
+ sp : current.sp = origin.sp
+
+theorem blockRestore_ok (original s : State) (hsaved : Saved original s)
+ (hread : ∀ i < 4, InRegions (s.rd ++ s.wr) (s.gpr .x2 + BitVec.ofNat 64 (8 * i)) 8) :
+ WP isa (.block blockRestore) s (RestorePost original s) := by
+ rw [blockRestore_eq]
+ have hregs : (List.range 4).map savedReg = savedRegs := by decide +kernel
+ obtain ⟨t, s', he, hs⟩ := VG.Proof.Rc2.AArch64.restoreCode_ok s .x2 savedReg (List.range 4) original.gpr
+ (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.AArch64.Exec.sp he⟩
+
+theorem savedSlot_spill_disjoint (s : State) (i : Nat) (hi : i < 4) :
+ (⟨s.gpr .x2 + BitVec.ofNat 64 (8 * i), 8⟩ : Region).Disjoint (spillRegion s) :=
+ Offset.disjoint (s.gpr .x2) (by omega) (by omega) (by decide)
+
+theorem Saved.congr {original s t : State} (hs : Saved original s)
+ (hbase : t.gpr .x2 = s.gpr .x2) (hf : Frame [spillRegion s] s.mem t.mem) :
+ Saved original t := by
+ intro i hi
+ have hmem := hf.readW (a := s.gpr .x2 + BitVec.ofNat 64 (8 * i)) (w := 64)
+ (r := ⟨s.gpr .x2 + BitVec.ofNat 64 (8 * i), 8⟩) (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.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Sbox.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Sbox.lean
new file mode 100644
index 000000000..e9923deff
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Sbox.lean
@@ -0,0 +1,114 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Lit
+import VerifiedGarbage.Spec.TripleDes
+import VerifiedGarbage.Proof.Framework.AArch64.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 64-bit words. This verifies both the circuits
+and the allocator's output, including spills.
+-/
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.Straight VG.Bitslice VG.Impl.TripleDes.AArch64
+
+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 := .x2, slots := 64, ext := .x2, 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 64 64) sboxCfg (fun _ => none) (instrs (sboxLiteral i))
+ sboxEnv (sboxPost i) = true := by
+ decide +kernel
+
+def sboxWrites : List Reg := [.x3, .x4, .x5, .x6, .x7, .x8, .x9, .x10, .x11, .x12, .x13, .x14, .x15, .x16, .x17]
+
+theorem sbox_preserves : ∀ i < 8,
+ [Reg.x0, .x1, .x2, .x19, .x20, .x21, .x22, .x23, .x24, .x25, .x26, .x27, .x28, .x30].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 < 64, (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 < 64, ∃ 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.x0, .x1, .x2, .x19, .x20, .x21, .x22, .x23, .x24, .x25, .x26, .x27, .x28, .x30] := 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.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Spills.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Spills.lean
new file mode 100644
index 000000000..4e3d747a1
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Spills.lean
@@ -0,0 +1,89 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Sbox
+import VerifiedGarbage.Proof.Framework.AArch64.RegUpd
+import VerifiedGarbage.Proof.Framework.Offset
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.RegUpd VG.Impl.TripleDes.AArch64
+
+def spillRegion (s : State) : Region := ⟨s.gpr .x2 + BitVec.ofNat 64 32, 384⟩
+
+def spillSafe : Instr → Bool
+ | .addImm .x d _ _ | .subImm .x d _ _ | .movz .x d _ _
+ | .logic _ .x d _ _ | .ldr .x d _ _ => d != .x2
+ | .str .x _ n off => decide (n = .x2 ∧ 32 ≤ off ∧ off + 8 ≤ 416)
+ | _ => false
+
+theorem spillSafe_check : ∀ i < 8,
+ (instrs (sboxLiteral i)).all spillSafe = true := by decide +kernel
+
+theorem write_frame (s : State) (d : Reg) (v : BitVec 64) (hd : d ≠ .x2) :
+ (s.write .x d v).gpr .x2 = s.gpr .x2 ∧
+ Frame [spillRegion s] s.mem (s.write .x d v).mem := by
+ exact ⟨gpr_write_of_ne _ _ _ (Ne.symm hd), by
+ rw [mem_write]; exact Frame.refl _ _⟩
+
+theorem spillStep_frame (i : Instr) (s s' : State)
+ (h : spillSafe i = true) (he : exec i s = some s') :
+ s'.gpr .x2 = s.gpr .x2 ∧ Frame [spillRegion s] s.mem s'.mem := by
+ cases i <;> simp only [spillSafe, Bool.false_eq_true] at h
+ case addImm sz d n imm | subImm sz d n imm | movz sz d imm hw =>
+ cases sz <;> simp only [Bool.false_eq_true] at h
+ have hd : d ≠ .x2 := by simpa using h
+ simp only [exec] at he
+ split at he <;> [skip; cases he]
+ obtain rfl := Option.some.inj he
+ exact write_frame _ _ _ hd
+ case logic op sz d n m =>
+ cases sz <;> simp only [Bool.false_eq_true] at h
+ have hd : d ≠ .x2 := by simpa using h
+ simp only [exec, Option.some.injEq] at he
+ subst s'
+ exact write_frame _ _ _ hd
+ case ldr sz d n off =>
+ cases sz <;> simp only [Bool.false_eq_true] at h
+ have hd : d ≠ .x2 := by simpa using h
+ simp only [exec, Option.bind_eq_some_iff, Option.map_eq_some_iff] at he
+ obtain ⟨a, _, v, _, rfl⟩ := he
+ exact write_frame _ _ _ hd
+ case str sz t n off =>
+ cases sz <;> simp only [Bool.false_eq_true] at h
+ obtain ⟨rfl, hlo, hhi⟩ := of_decide_eq_true h
+ simp only [exec, addr, Size.bytes] at he
+ split at he <;> [skip; cases he]
+ simp only [Option.bind_some, State.store] at he
+ split at he <;> [skip; cases he]
+ obtain rfl := Option.some.inj he
+ refine ⟨rfl, ?_⟩
+ change Frame [spillRegion s] s.mem (s.mem.writeW (s.gpr .x2 + BitVec.ofNat 64 off) (s.gpr t))
+ refine (Frame.refl _ _).writeW (List.mem_singleton_self _) _ ?_
+ exact Offset.contains (s.gpr .x2) (by omega) (by omega) (by decide)
+
+theorem spillBlock_frame (is : List Instr) (s s' : State)
+ (hsafe : is.all spillSafe = true) (he : runBlock isa is s = some s') :
+ s'.gpr .x2 = s.gpr .x2 ∧ 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₁ hsafe.1 hi
+ obtain ⟨hg', hf'⟩ := ih s₁ 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)
+ (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 _ _ _ h he).2
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Store.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Store.lean
new file mode 100644
index 000000000..3bb4e84d3
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Store.lean
@@ -0,0 +1,80 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.BlockIO
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.AArch64.RegUpd VG.Impl.TripleDes.AArch64
+
+def packHalves : List Instr := [.lsl .x .x3 .x19 32, .logic .eor .x .x3 .x3 .x20]
+
+theorem packHalves_ok (s : State) :
+ ∃ s', runBlock isa packHalves s = some s' ∧
+ s'.gpr .x3 = s.gpr .x19 <<< 32 ^^^ s.gpr .x20 ∧
+ s'.mem = s.mem ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧
+ (∀ r, r ≠ .x3 → s'.gpr r = s.gpr r) := by
+ refine ⟨_, by
+ simp only [packHalves, runBlock_cons, runStep_some, runBlock_nil, exec, Size.bits,
+ show (32 : Nat) < 64 from by decide, ite_true, State.read,
+ BitVec.setWidth_eq, gpr_write_self]
+ rfl, ?_, ?_, ?_, ?_, ?_, ?_⟩
+ · simp only [gpr_write, reduceCtorEq, ite_true, ite_false, BitVec.setWidth_eq]
+ · simp only [mem_write]
+ · simp only [rd_write]
+ · simp only [wr_write]
+ · simp only [sp_write]
+ · intro r hr; simp only [gpr_write, hr, ite_false]
+
+theorem storeTail_ok (s : State) :
+ ∃ s', runBlock isa [.rev .x3 .x10] s = some s' ∧
+ s'.gpr .x3 = rev64 (s.gpr .x10) ∧
+ s'.mem = s.mem ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧
+ (∀ r, r ≠ .x3 → s'.gpr r = s.gpr r) := by
+ refine ⟨_, by simp only [runBlock_cons, runStep_some, runBlock_nil, exec_rev]; rfl,
+ ?_, ?_, ?_, ?_, ?_, ?_⟩
+ · simp only [gpr_write_self, State.read, BitVec.setWidth_eq]
+ · simp only [mem_write]
+ · simp only [rd_write]
+ · simp only [wr_write]
+ · simp only [sp_write]
+ · intro r hr; simp only [gpr_write, hr, ite_false]
+
+theorem final_preserves : loadKept.all (fun r =>
+ (instrs finalPermutation.lit).all (fun op => dstOf op != some r)) = true := by
+ decide +kernel
+
+theorem blockStore_ok (s : State) (l r : BitVec 32)
+ (hl : s.gpr .x19 = l.setWidth 64) (hr : s.gpr .x20 = r.setWidth 64) :
+ ∃ s', runBlock isa blockStore s = some s' ∧
+ s'.gpr .x3 = rev64 (Spec.TripleDes.permute Spec.TripleDes.fp (l ++ r)) ∧
+ s'.mem = s.mem ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp ∧
+ (∀ q ∈ loadKept, s'.gpr q = s.gpr q) := by
+ obtain ⟨s₁, run₁, word₁, mem₁, rd₁, wr₁, sp₁, regs₁⟩ := packHalves_ok s
+ obtain ⟨s₂, run₂, word₂, rd₂, wr₂, sp₂, mem₂, regs₂⟩ := final_raw_ok s₁
+ obtain ⟨s₃, run₃, word₃, mem₃, rd₃, wr₃, sp₃, regs₃⟩ := storeTail_ok s₂
+ have hword : s₁.gpr .x3 = l ++ r := by
+ rw [hl, hr] at word₁
+ exact word₁.trans (packHalves_shift l r)
+ have hhead := runAppend_some _ _ _ _ _ run₁ run₂
+ have htail := runAppend_some _ _ _ _ _ hhead run₃
+ have hcode : blockStore =
+ (packHalves ++ permuteCode Spec.TripleDes.fp 64 .x10 .x3 .x11 .x12) ++
+ [.rev .x3 .x10] := rfl
+ refine ⟨s₃, (congrArg (fun is => runBlock isa is s) hcode).trans htail, ?_,
+ mem₃.trans (mem₂.trans mem₁), rd₃.trans (rd₂.trans rd₁),
+ wr₃.trans (wr₂.trans wr₁), sp₃.trans (sp₂.trans sp₁), ?_⟩
+ · exact word₃.trans (congrArg rev64 (word₂.trans
+ (congrArg (Spec.TripleDes.permute Spec.TripleDes.fp) hword)))
+ · intro q hq
+ have hno := List.all_eq_true.mp final_preserves q hq
+ have hneq : q ≠ .x3 := by revert hq; cases q <;> decide
+ exact (regs₃ q hneq).trans ((regs₂ q hno).trans (regs₁ q hneq))
+
+theorem writeData_ok (s : State) (hwrite : InRegions s.wr (s.gpr .x1) 8) :
+ ∃ s', runBlock isa [.str .x .x3 .x1 0] s = some s' ∧
+ s'.mem = s.mem.writeW (s.gpr .x1) (s.gpr .x3) ∧
+ s'.gpr = s.gpr ∧ s'.rd = s.rd ∧ s'.wr = s.wr ∧ s'.sp = s.sp := by
+ have hstore := exec_str_x (t := .x3) (n := .x1) (off := 0) (by decide)
+ (by simpa only [BitVec.ofNat_eq_ofNat, BitVec.add_zero] using hwrite)
+ refine ⟨{s with mem := s.mem.writeW (s.gpr .x1) (s.gpr .x3)}, ?_, rfl, rfl, rfl, rfl, rfl⟩
+ simp only [runBlock_cons, hstore, runStep_some, runBlock_nil, BitVec.add_zero]
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Tail.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Tail.lean
new file mode 100644
index 000000000..b820bf1c1
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Tail.lean
@@ -0,0 +1,69 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Store
+import VerifiedGarbage.Proof.TripleDes.AArch64.Save
+import VerifiedGarbage.Proof.TripleDes.AArch64.WordState
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.Impl.TripleDes.AArch64
+
+structure TailPost (original origin : State) (x : BitVec 64) (s : State) : Prop where
+ result : Spec.TripleDes.blockAt s.mem (origin.gpr .x1) =
+ Spec.TripleDes.encodeBlock (Spec.TripleDes.permute Spec.TripleDes.fp x)
+ saved : ∀ r ∈ savedRegs, s.gpr r = original.gpr r
+ 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 [⟨origin.gpr .x1, 8⟩] origin.mem s.mem
+
+theorem blockTail_ok (original s : State) (x : BitVec 64)
+ (hword : WordState x s) (hsaved : Saved original s)
+ (hsavedRead : ∀ i < 4, InRegions (s.rd ++ s.wr) (s.gpr .x2 + BitVec.ofNat 64 (8 * i)) 8)
+ (hwrite : InRegions s.wr (s.gpr .x1) 8) :
+ WP isa (.block (blockStore ++ blockRestore ++ ([.str .x .x3 .x1 0] : List Instr)))
+ s (TailPost original s x) := by
+ obtain ⟨s₁, run₁, word₁, mem₁, rd₁, wr₁, sp₁, regs₁⟩ :=
+ blockStore_ok s ((x >>> 32).setWidth 32) (x.setWidth 32) hword.left hword.right
+ have word : s₁.gpr .x3 = rev64 (Spec.TripleDes.permute Spec.TripleDes.fp x) :=
+ word₁.trans (congrArg (fun v => rev64 (Spec.TripleDes.permute Spec.TripleDes.fp v))
+ (VG.Proof.TripleDes.halves_append x))
+ have saved₁ : Saved original s₁ := by
+ intro i hi
+ rw [regs₁ .x2 (by decide), mem₁]
+ exact hsaved i hi
+ have savedRead₁ : ∀ i < 4, InRegions (s₁.rd ++ s₁.wr) (s₁.gpr .x2 + BitVec.ofNat 64 (8 * i)) 8 := by
+ rw [rd₁, wr₁, regs₁ .x2 (by decide)]
+ exact hsavedRead
+ apply WP.block_append
+ apply WP.block_append
+ apply WP.of_runBlock
+ refine ⟨s₁, run₁, ?_⟩
+ apply WP.mono (blockRestore_ok original s₁ saved₁ savedRead₁)
+ intro s₂ hs₂
+ have hnonsaved : ∀ q ∈ (.x3 :: roundStepKept), q ∉ savedRegs := by decide
+ have hrax₂ : s₂.gpr .x3 = rev64 (Spec.TripleDes.permute Spec.TripleDes.fp x) :=
+ (hs₂.keep.reg .x3 (hnonsaved .x3 (by decide))).trans word
+ have hregs₂ : ∀ q ∈ roundStepKept, s₂.gpr q = s.gpr q := by
+ intro q hq
+ have hkeep : ∀ r ∈ roundStepKept, r ∈ (.x3 :: roundStepKept) ∧
+ r ∈ loadKept := by decide
+ exact (hs₂.keep.reg q (hnonsaved q (hkeep q hq).1)).trans (regs₁ q (hkeep q hq).2)
+ have hwrite₂ : InRegions s₂.wr (s₂.gpr .x1) 8 := by
+ rw [hs₂.keep.wr, wr₁, hregs₂ .x1 (by decide)]
+ exact hwrite
+ obtain ⟨s₃, run₃, mem₃, gpr₃, rd₃, wr₃, sp₃⟩ := writeData_ok s₂ hwrite₂
+ apply WP.of_runBlock
+ refine ⟨s₃, run₃, ?_, ?_, rd₃.trans (hs₂.keep.rd.trans rd₁),
+ wr₃.trans (hs₂.keep.wr.trans wr₁), sp₃.trans (hs₂.sp.trans sp₁), ?_, ?_⟩
+ · rw [mem₃, hs₂.keep.mem, mem₁, hregs₂ .x1 (by decide), hrax₂]
+ exact blockAt_writeW s.mem (s.gpr .x1) (Spec.TripleDes.permute Spec.TripleDes.fp x)
+ · intro r hr
+ rw [gpr₃]
+ exact hs₂.saved r hr
+ · intro q hq
+ rw [gpr₃]
+ exact hregs₂ q hq
+ · rw [mem₃, hs₂.keep.mem, mem₁, hregs₂ .x1 (by decide)]
+ exact (Frame.refl _ _).writeW (List.mem_singleton_self _) _ (Region.contains_self _ _)
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/VerifiedBlock.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/VerifiedBlock.lean
new file mode 100644
index 000000000..fd9cb8eb8
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/VerifiedBlock.lean
@@ -0,0 +1,63 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Pre
+import VerifiedGarbage.Proof.Framework.Contract
+import VerifiedGarbage.Spec.TripleDes.Contract
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.Impl.TripleDes.AArch64
+open VG.Spec.TripleDes (Direction)
+
+theorem block_gprCorrect (d : Direction) (s : State) (hs : (blockContract d).pre s) :
+ WP isa (block d) s (fun s' => GprAbi s s' ∧ (blockContract d).post s s') := by
+ have hp := headPre_of_contract d s hs
+ have hwrite : InRegions s.wr (s.gpr .x1) 8 := by
+ rw [hs.2.1]
+ exact ⟨⟨s.gpr .x1, 8⟩, by simp, Region.contains_self _ _⟩
+ apply WP.mono (block_ok (Spec.TripleDes.scheduleAt s.mem (s.gpr .x0)) (s.gpr .x0) 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, VG.AArch64.Exec.preservedV he (by lit_decide)⟩, 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, VG.AArch64.Exec.preservedV he (by lit_decide)⟩, hp⟩
+
+def satState : State where
+ gpr r := match r with
+ | .x0 => 0x1000 | .x1 => 0x2000 | .x2 => 0x3000 | _ => 0
+ sp := 0x4000
+ mem _ := 0
+ rd := [⟨0x1000, 384⟩]
+ wr := [⟨0x2000, 8⟩, ⟨0x3000, 512⟩]
+
+theorem publicRegs_three (s t : State) : PublicRegs [.x0, .x1, .x2] s t ↔
+ s.sp = t.sp ∧ s.gpr .x0 = t.gpr .x0 ∧ s.gpr .x1 = t.gpr .x1 ∧ s.gpr .x2 = t.gpr .x2 := 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,
+ 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,
+ blockContract, publicRegs_three, blockResult] [satState] using satState
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Word.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Word.lean
new file mode 100644
index 000000000..43d8b2727
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Word.lean
@@ -0,0 +1,42 @@
+import VerifiedGarbage.Proof.TripleDes.Word
+
+namespace VG.Proof.TripleDes.AArch64
+
+theorem mask_word (x : BitVec 64) (n : Nat) (hn : 0 < n) (hn64 : n ≤ 64) :
+ (x <<< (64 - n)) >>> (64 - n) = (x.setWidth n).setWidth 64 := 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 : 64 - n + j < 64 := by omega
+ have hlo : ¬64 - n + j < 64 - n := by omega
+ simp only [hi, hlo, h, hj, decide_true, decide_false, Bool.not_false,
+ Bool.true_and, show 64 - n + j - (64 - n) = j by omega]
+ · have ho : ¬64 - n + j < 64 := by omega
+ simp only [ho, h, hj, decide_true, decide_false, Bool.false_and, Bool.true_and]
+
+theorem packHalves_shift (l r : BitVec 32) :
+ l.setWidth 64 <<< 32 ^^^ r.setWidth 64 = l ++ r := by
+ apply BitVec.eq_of_getLsbD_eq
+ intro j hj
+ simp only [BitVec.getLsbD_xor, BitVec.getLsbD_shiftLeft, BitVec.getLsbD_setWidth,
+ BitVec.getLsbD_append]
+ by_cases h : j < 32
+ · simp [h, hj]
+ · have hb : j - 32 < 32 := by omega
+ simp [h, hj, hb, show j - 32 < 64 by omega,
+ BitVec.getLsbD_of_ge r j (by omega)]
+
+theorem pack28_shift (c d : BitVec 28) :
+ ((c.setWidth 64 <<< 28) ^^^ d.setWidth 64).setWidth 56 = c ++ d := by
+ apply BitVec.eq_of_getLsbD_eq
+ intro j hj
+ simp only [BitVec.getLsbD_setWidth, BitVec.getLsbD_xor,
+ BitVec.getLsbD_shiftLeft, BitVec.getLsbD_append, hj, decide_true, Bool.true_and]
+ by_cases h : j < 28
+ · simp [h, show j < 64 by omega]
+ · simp [h, show j < 64 by omega, show j - 28 < 28 by omega,
+ show j - 28 < 64 by omega, BitVec.getLsbD_of_ge d j (by omega)]
+
+
+end VG.Proof.TripleDes.AArch64
diff --git a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/WordState.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/WordState.lean
new file mode 100644
index 000000000..3a6a135ce
--- /dev/null
+++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/WordState.lean
@@ -0,0 +1,28 @@
+import VerifiedGarbage.Proof.TripleDes.AArch64.Pass
+import VerifiedGarbage.Proof.TripleDes.Word
+
+namespace VG.Proof.TripleDes.AArch64
+
+open VG VG.AArch64 VG.Impl.TripleDes.AArch64
+open VG.Proof.TripleDes (desCore roundPrefix)
+
+/-- A DES word held as two zero-extended 32-bit Feistel registers. -/
+structure WordState (x : BitVec 64) (s : State) : Prop where
+ left : s.gpr .x19 = ((x >>> 32).setWidth 32).setWidth 64
+ right : s.gpr .x20 = (x.setWidth 32).setWidth 64
+
+theorem PassPost.wordState {keys : Spec.TripleDes.DesSchedule}
+ {direction : Spec.TripleDes.Direction} {origin s : State} {x : BitVec 64}
+ (hs : PassPost keys direction 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).setWidth 64 = halves.2.setWidth 64 :=
+ (congrArg (fun v : BitVec 64 => ((v >>> 32).setWidth 32).setWidth 64) hcore).trans
+ (congrArg (BitVec.setWidth 64) (VG.Proof.TripleDes.appended_left halves.2 halves.1))
+ have hright : ((desCore keys direction x).setWidth 32).setWidth 64 = halves.1.setWidth 64 :=
+ (congrArg (fun v : BitVec 64 => (v.setWidth 32).setWidth 64) hcore).trans
+ (congrArg (BitVec.setWidth 64) (VG.Proof.TripleDes.appended_right halves.2 halves.1))
+ exact ⟨hs.left.trans hleft.symm, hs.right.trans hright.symm⟩
+
+end VG.Proof.TripleDes.AArch64
diff --git a/src/asm/aarch64/mod.rs b/src/asm/aarch64/mod.rs
index e8f82190d..8a875fde2 100644
--- a/src/asm/aarch64/mod.rs
+++ b/src/asm/aarch64/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/aarch64/triple_des.rs b/src/asm/aarch64/triple_des.rs
new file mode 100644
index 000000000..f56735fc3
--- /dev/null
+++ b/src/asm/aarch64/triple_des.rs
@@ -0,0 +1,11936 @@
+// @generated from lean/VerifiedGarbage/Artifacts.lean by lean/Emit.lean. DO NOT EDIT.
+//! Verified `triple_des` functions for `aarch64`.
+#![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 AArch64 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 x19, [x3, #0]",
+ "str x20, [x3, #8]",
+ "str x21, [x3, #16]",
+ "str x22, [x3, #24]",
+ "ldr x4, [x0, #0]",
+ "rev x4, x4",
+ "movz x5, #0, lsl #0",
+ "movz x7, #1, lsl #0",
+ "add x6, x4, #0",
+ "lsr x6, x6, #7",
+ "and x6, x6, x7",
+ "ror x6, x6, #9",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #15",
+ "and x6, x6, x7",
+ "ror x6, x6, #10",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #23",
+ "and x6, x6, x7",
+ "ror x6, x6, #11",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #31",
+ "and x6, x6, x7",
+ "ror x6, x6, #12",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #39",
+ "and x6, x6, x7",
+ "ror x6, x6, #13",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #47",
+ "and x6, x6, x7",
+ "ror x6, x6, #14",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #55",
+ "and x6, x6, x7",
+ "ror x6, x6, #15",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #63",
+ "and x6, x6, x7",
+ "ror x6, x6, #16",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #6",
+ "and x6, x6, x7",
+ "ror x6, x6, #17",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #14",
+ "and x6, x6, x7",
+ "ror x6, x6, #18",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #22",
+ "and x6, x6, x7",
+ "ror x6, x6, #19",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #30",
+ "and x6, x6, x7",
+ "ror x6, x6, #20",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #38",
+ "and x6, x6, x7",
+ "ror x6, x6, #21",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #46",
+ "and x6, x6, x7",
+ "ror x6, x6, #22",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #54",
+ "and x6, x6, x7",
+ "ror x6, x6, #23",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #62",
+ "and x6, x6, x7",
+ "ror x6, x6, #24",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #5",
+ "and x6, x6, x7",
+ "ror x6, x6, #25",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #13",
+ "and x6, x6, x7",
+ "ror x6, x6, #26",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #21",
+ "and x6, x6, x7",
+ "ror x6, x6, #27",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #29",
+ "and x6, x6, x7",
+ "ror x6, x6, #28",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #37",
+ "and x6, x6, x7",
+ "ror x6, x6, #29",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #45",
+ "and x6, x6, x7",
+ "ror x6, x6, #30",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #53",
+ "and x6, x6, x7",
+ "ror x6, x6, #31",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #61",
+ "and x6, x6, x7",
+ "ror x6, x6, #32",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #4",
+ "and x6, x6, x7",
+ "ror x6, x6, #33",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #12",
+ "and x6, x6, x7",
+ "ror x6, x6, #34",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #20",
+ "and x6, x6, x7",
+ "ror x6, x6, #35",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #28",
+ "and x6, x6, x7",
+ "ror x6, x6, #36",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #1",
+ "and x6, x6, x7",
+ "ror x6, x6, #37",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #9",
+ "and x6, x6, x7",
+ "ror x6, x6, #38",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #17",
+ "and x6, x6, x7",
+ "ror x6, x6, #39",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #25",
+ "and x6, x6, x7",
+ "ror x6, x6, #40",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #33",
+ "and x6, x6, x7",
+ "ror x6, x6, #41",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #41",
+ "and x6, x6, x7",
+ "ror x6, x6, #42",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #49",
+ "and x6, x6, x7",
+ "ror x6, x6, #43",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #57",
+ "and x6, x6, x7",
+ "ror x6, x6, #44",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #2",
+ "and x6, x6, x7",
+ "ror x6, x6, #45",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #10",
+ "and x6, x6, x7",
+ "ror x6, x6, #46",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #18",
+ "and x6, x6, x7",
+ "ror x6, x6, #47",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #26",
+ "and x6, x6, x7",
+ "ror x6, x6, #48",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #34",
+ "and x6, x6, x7",
+ "ror x6, x6, #49",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #42",
+ "and x6, x6, x7",
+ "ror x6, x6, #50",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #50",
+ "and x6, x6, x7",
+ "ror x6, x6, #51",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #58",
+ "and x6, x6, x7",
+ "ror x6, x6, #52",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #3",
+ "and x6, x6, x7",
+ "ror x6, x6, #53",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #11",
+ "and x6, x6, x7",
+ "ror x6, x6, #54",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #19",
+ "and x6, x6, x7",
+ "ror x6, x6, #55",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #27",
+ "and x6, x6, x7",
+ "ror x6, x6, #56",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #35",
+ "and x6, x6, x7",
+ "ror x6, x6, #57",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #43",
+ "and x6, x6, x7",
+ "ror x6, x6, #58",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #51",
+ "and x6, x6, x7",
+ "ror x6, x6, #59",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #59",
+ "and x6, x6, x7",
+ "ror x6, x6, #60",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #36",
+ "and x6, x6, x7",
+ "ror x6, x6, #61",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #44",
+ "and x6, x6, x7",
+ "ror x6, x6, #62",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #52",
+ "and x6, x6, x7",
+ "ror x6, x6, #63",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #60",
+ "and x6, x6, x7",
+ "eor x5, x5, x6",
+ "lsr x19, x5, #28",
+ "add x20, x5, #0",
+ "lsl x20, x20, #36",
+ "lsr x20, x20, #36",
+ "movz x21, #0, lsl #0",
+ "add x22, x2, #0",
+ "20:",
+ "lsr x4, x21, #1",
+ "cbz x4, 21f",
+ "sub x4, x21, #8",
+ "cbz x4, 23f",
+ "sub x4, x21, #15",
+ "cbz x4, 25f",
+ "lsr x4, x19, #26",
+ "ror x19, x19, #62",
+ "eor x19, x19, x4",
+ "lsl x19, x19, #36",
+ "lsr x19, x19, #36",
+ "lsr x4, x20, #26",
+ "ror x20, x20, #62",
+ "eor x20, x20, x4",
+ "lsl x20, x20, #36",
+ "lsr x20, x20, #36",
+ "b 26f",
+ "25:",
+ "lsr x4, x19, #27",
+ "ror x19, x19, #63",
+ "eor x19, x19, x4",
+ "lsl x19, x19, #36",
+ "lsr x19, x19, #36",
+ "lsr x4, x20, #27",
+ "ror x20, x20, #63",
+ "eor x20, x20, x4",
+ "lsl x20, x20, #36",
+ "lsr x20, x20, #36",
+ "26:",
+ "b 24f",
+ "23:",
+ "lsr x4, x19, #27",
+ "ror x19, x19, #63",
+ "eor x19, x19, x4",
+ "lsl x19, x19, #36",
+ "lsr x19, x19, #36",
+ "lsr x4, x20, #27",
+ "ror x20, x20, #63",
+ "eor x20, x20, x4",
+ "lsl x20, x20, #36",
+ "lsr x20, x20, #36",
+ "24:",
+ "b 22f",
+ "21:",
+ "lsr x4, x19, #27",
+ "ror x19, x19, #63",
+ "eor x19, x19, x4",
+ "lsl x19, x19, #36",
+ "lsr x19, x19, #36",
+ "lsr x4, x20, #27",
+ "ror x20, x20, #63",
+ "eor x20, x20, x4",
+ "lsl x20, x20, #36",
+ "lsr x20, x20, #36",
+ "22:",
+ "lsl x4, x19, #28",
+ "eor x4, x4, x20",
+ "movz x5, #0, lsl #0",
+ "movz x7, #1, lsl #0",
+ "add x6, x4, #0",
+ "lsr x6, x6, #42",
+ "and x6, x6, x7",
+ "ror x6, x6, #17",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #39",
+ "and x6, x6, x7",
+ "ror x6, x6, #18",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #45",
+ "and x6, x6, x7",
+ "ror x6, x6, #19",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #32",
+ "and x6, x6, x7",
+ "ror x6, x6, #20",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #55",
+ "and x6, x6, x7",
+ "ror x6, x6, #21",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #51",
+ "and x6, x6, x7",
+ "ror x6, x6, #22",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #53",
+ "and x6, x6, x7",
+ "ror x6, x6, #23",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #28",
+ "and x6, x6, x7",
+ "ror x6, x6, #24",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #41",
+ "and x6, x6, x7",
+ "ror x6, x6, #25",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #50",
+ "and x6, x6, x7",
+ "ror x6, x6, #26",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #35",
+ "and x6, x6, x7",
+ "ror x6, x6, #27",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #46",
+ "and x6, x6, x7",
+ "ror x6, x6, #28",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #33",
+ "and x6, x6, x7",
+ "ror x6, x6, #29",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #37",
+ "and x6, x6, x7",
+ "ror x6, x6, #30",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #44",
+ "and x6, x6, x7",
+ "ror x6, x6, #31",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #52",
+ "and x6, x6, x7",
+ "ror x6, x6, #32",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #30",
+ "and x6, x6, x7",
+ "ror x6, x6, #33",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #48",
+ "and x6, x6, x7",
+ "ror x6, x6, #34",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #40",
+ "and x6, x6, x7",
+ "ror x6, x6, #35",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #49",
+ "and x6, x6, x7",
+ "ror x6, x6, #36",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #29",
+ "and x6, x6, x7",
+ "ror x6, x6, #37",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #36",
+ "and x6, x6, x7",
+ "ror x6, x6, #38",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #43",
+ "and x6, x6, x7",
+ "ror x6, x6, #39",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #54",
+ "and x6, x6, x7",
+ "ror x6, x6, #40",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #15",
+ "and x6, x6, x7",
+ "ror x6, x6, #41",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #4",
+ "and x6, x6, x7",
+ "ror x6, x6, #42",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #25",
+ "and x6, x6, x7",
+ "ror x6, x6, #43",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #19",
+ "and x6, x6, x7",
+ "ror x6, x6, #44",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #9",
+ "and x6, x6, x7",
+ "ror x6, x6, #45",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #1",
+ "and x6, x6, x7",
+ "ror x6, x6, #46",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #26",
+ "and x6, x6, x7",
+ "ror x6, x6, #47",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #16",
+ "and x6, x6, x7",
+ "ror x6, x6, #48",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #5",
+ "and x6, x6, x7",
+ "ror x6, x6, #49",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #11",
+ "and x6, x6, x7",
+ "ror x6, x6, #50",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #23",
+ "and x6, x6, x7",
+ "ror x6, x6, #51",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #8",
+ "and x6, x6, x7",
+ "ror x6, x6, #52",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #12",
+ "and x6, x6, x7",
+ "ror x6, x6, #53",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #7",
+ "and x6, x6, x7",
+ "ror x6, x6, #54",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #17",
+ "and x6, x6, x7",
+ "ror x6, x6, #55",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "and x6, x6, x7",
+ "ror x6, x6, #56",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #22",
+ "and x6, x6, x7",
+ "ror x6, x6, #57",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #3",
+ "and x6, x6, x7",
+ "ror x6, x6, #58",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #10",
+ "and x6, x6, x7",
+ "ror x6, x6, #59",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #14",
+ "and x6, x6, x7",
+ "ror x6, x6, #60",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #6",
+ "and x6, x6, x7",
+ "ror x6, x6, #61",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #20",
+ "and x6, x6, x7",
+ "ror x6, x6, #62",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #27",
+ "and x6, x6, x7",
+ "ror x6, x6, #63",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #24",
+ "and x6, x6, x7",
+ "eor x5, x5, x6",
+ "str x5, [x22, #0]",
+ "add x22, x22, #8",
+ "add x21, x21, #1",
+ "sub x4, x21, #16",
+ "cbnz x4, 20b",
+ "ldr x4, [x0, #8]",
+ "rev x4, x4",
+ "movz x5, #0, lsl #0",
+ "movz x7, #1, lsl #0",
+ "add x6, x4, #0",
+ "lsr x6, x6, #7",
+ "and x6, x6, x7",
+ "ror x6, x6, #9",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #15",
+ "and x6, x6, x7",
+ "ror x6, x6, #10",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #23",
+ "and x6, x6, x7",
+ "ror x6, x6, #11",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #31",
+ "and x6, x6, x7",
+ "ror x6, x6, #12",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #39",
+ "and x6, x6, x7",
+ "ror x6, x6, #13",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #47",
+ "and x6, x6, x7",
+ "ror x6, x6, #14",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #55",
+ "and x6, x6, x7",
+ "ror x6, x6, #15",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #63",
+ "and x6, x6, x7",
+ "ror x6, x6, #16",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #6",
+ "and x6, x6, x7",
+ "ror x6, x6, #17",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #14",
+ "and x6, x6, x7",
+ "ror x6, x6, #18",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #22",
+ "and x6, x6, x7",
+ "ror x6, x6, #19",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #30",
+ "and x6, x6, x7",
+ "ror x6, x6, #20",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #38",
+ "and x6, x6, x7",
+ "ror x6, x6, #21",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #46",
+ "and x6, x6, x7",
+ "ror x6, x6, #22",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #54",
+ "and x6, x6, x7",
+ "ror x6, x6, #23",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #62",
+ "and x6, x6, x7",
+ "ror x6, x6, #24",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #5",
+ "and x6, x6, x7",
+ "ror x6, x6, #25",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #13",
+ "and x6, x6, x7",
+ "ror x6, x6, #26",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #21",
+ "and x6, x6, x7",
+ "ror x6, x6, #27",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #29",
+ "and x6, x6, x7",
+ "ror x6, x6, #28",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #37",
+ "and x6, x6, x7",
+ "ror x6, x6, #29",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #45",
+ "and x6, x6, x7",
+ "ror x6, x6, #30",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #53",
+ "and x6, x6, x7",
+ "ror x6, x6, #31",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #61",
+ "and x6, x6, x7",
+ "ror x6, x6, #32",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #4",
+ "and x6, x6, x7",
+ "ror x6, x6, #33",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #12",
+ "and x6, x6, x7",
+ "ror x6, x6, #34",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #20",
+ "and x6, x6, x7",
+ "ror x6, x6, #35",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #28",
+ "and x6, x6, x7",
+ "ror x6, x6, #36",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #1",
+ "and x6, x6, x7",
+ "ror x6, x6, #37",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #9",
+ "and x6, x6, x7",
+ "ror x6, x6, #38",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #17",
+ "and x6, x6, x7",
+ "ror x6, x6, #39",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #25",
+ "and x6, x6, x7",
+ "ror x6, x6, #40",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #33",
+ "and x6, x6, x7",
+ "ror x6, x6, #41",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #41",
+ "and x6, x6, x7",
+ "ror x6, x6, #42",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #49",
+ "and x6, x6, x7",
+ "ror x6, x6, #43",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #57",
+ "and x6, x6, x7",
+ "ror x6, x6, #44",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #2",
+ "and x6, x6, x7",
+ "ror x6, x6, #45",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #10",
+ "and x6, x6, x7",
+ "ror x6, x6, #46",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #18",
+ "and x6, x6, x7",
+ "ror x6, x6, #47",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #26",
+ "and x6, x6, x7",
+ "ror x6, x6, #48",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #34",
+ "and x6, x6, x7",
+ "ror x6, x6, #49",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #42",
+ "and x6, x6, x7",
+ "ror x6, x6, #50",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #50",
+ "and x6, x6, x7",
+ "ror x6, x6, #51",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #58",
+ "and x6, x6, x7",
+ "ror x6, x6, #52",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #3",
+ "and x6, x6, x7",
+ "ror x6, x6, #53",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #11",
+ "and x6, x6, x7",
+ "ror x6, x6, #54",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #19",
+ "and x6, x6, x7",
+ "ror x6, x6, #55",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #27",
+ "and x6, x6, x7",
+ "ror x6, x6, #56",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #35",
+ "and x6, x6, x7",
+ "ror x6, x6, #57",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #43",
+ "and x6, x6, x7",
+ "ror x6, x6, #58",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #51",
+ "and x6, x6, x7",
+ "ror x6, x6, #59",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #59",
+ "and x6, x6, x7",
+ "ror x6, x6, #60",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #36",
+ "and x6, x6, x7",
+ "ror x6, x6, #61",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #44",
+ "and x6, x6, x7",
+ "ror x6, x6, #62",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #52",
+ "and x6, x6, x7",
+ "ror x6, x6, #63",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #60",
+ "and x6, x6, x7",
+ "eor x5, x5, x6",
+ "lsr x19, x5, #28",
+ "add x20, x5, #0",
+ "lsl x20, x20, #36",
+ "lsr x20, x20, #36",
+ "movz x21, #0, lsl #0",
+ "add x22, x2, #128",
+ "27:",
+ "lsr x4, x21, #1",
+ "cbz x4, 28f",
+ "sub x4, x21, #8",
+ "cbz x4, 210f",
+ "sub x4, x21, #15",
+ "cbz x4, 212f",
+ "lsr x4, x19, #26",
+ "ror x19, x19, #62",
+ "eor x19, x19, x4",
+ "lsl x19, x19, #36",
+ "lsr x19, x19, #36",
+ "lsr x4, x20, #26",
+ "ror x20, x20, #62",
+ "eor x20, x20, x4",
+ "lsl x20, x20, #36",
+ "lsr x20, x20, #36",
+ "b 213f",
+ "212:",
+ "lsr x4, x19, #27",
+ "ror x19, x19, #63",
+ "eor x19, x19, x4",
+ "lsl x19, x19, #36",
+ "lsr x19, x19, #36",
+ "lsr x4, x20, #27",
+ "ror x20, x20, #63",
+ "eor x20, x20, x4",
+ "lsl x20, x20, #36",
+ "lsr x20, x20, #36",
+ "213:",
+ "b 211f",
+ "210:",
+ "lsr x4, x19, #27",
+ "ror x19, x19, #63",
+ "eor x19, x19, x4",
+ "lsl x19, x19, #36",
+ "lsr x19, x19, #36",
+ "lsr x4, x20, #27",
+ "ror x20, x20, #63",
+ "eor x20, x20, x4",
+ "lsl x20, x20, #36",
+ "lsr x20, x20, #36",
+ "211:",
+ "b 29f",
+ "28:",
+ "lsr x4, x19, #27",
+ "ror x19, x19, #63",
+ "eor x19, x19, x4",
+ "lsl x19, x19, #36",
+ "lsr x19, x19, #36",
+ "lsr x4, x20, #27",
+ "ror x20, x20, #63",
+ "eor x20, x20, x4",
+ "lsl x20, x20, #36",
+ "lsr x20, x20, #36",
+ "29:",
+ "lsl x4, x19, #28",
+ "eor x4, x4, x20",
+ "movz x5, #0, lsl #0",
+ "movz x7, #1, lsl #0",
+ "add x6, x4, #0",
+ "lsr x6, x6, #42",
+ "and x6, x6, x7",
+ "ror x6, x6, #17",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #39",
+ "and x6, x6, x7",
+ "ror x6, x6, #18",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #45",
+ "and x6, x6, x7",
+ "ror x6, x6, #19",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #32",
+ "and x6, x6, x7",
+ "ror x6, x6, #20",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #55",
+ "and x6, x6, x7",
+ "ror x6, x6, #21",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #51",
+ "and x6, x6, x7",
+ "ror x6, x6, #22",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #53",
+ "and x6, x6, x7",
+ "ror x6, x6, #23",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #28",
+ "and x6, x6, x7",
+ "ror x6, x6, #24",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #41",
+ "and x6, x6, x7",
+ "ror x6, x6, #25",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #50",
+ "and x6, x6, x7",
+ "ror x6, x6, #26",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #35",
+ "and x6, x6, x7",
+ "ror x6, x6, #27",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #46",
+ "and x6, x6, x7",
+ "ror x6, x6, #28",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #33",
+ "and x6, x6, x7",
+ "ror x6, x6, #29",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #37",
+ "and x6, x6, x7",
+ "ror x6, x6, #30",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #44",
+ "and x6, x6, x7",
+ "ror x6, x6, #31",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #52",
+ "and x6, x6, x7",
+ "ror x6, x6, #32",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #30",
+ "and x6, x6, x7",
+ "ror x6, x6, #33",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #48",
+ "and x6, x6, x7",
+ "ror x6, x6, #34",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #40",
+ "and x6, x6, x7",
+ "ror x6, x6, #35",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #49",
+ "and x6, x6, x7",
+ "ror x6, x6, #36",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #29",
+ "and x6, x6, x7",
+ "ror x6, x6, #37",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #36",
+ "and x6, x6, x7",
+ "ror x6, x6, #38",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #43",
+ "and x6, x6, x7",
+ "ror x6, x6, #39",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #54",
+ "and x6, x6, x7",
+ "ror x6, x6, #40",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #15",
+ "and x6, x6, x7",
+ "ror x6, x6, #41",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #4",
+ "and x6, x6, x7",
+ "ror x6, x6, #42",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #25",
+ "and x6, x6, x7",
+ "ror x6, x6, #43",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #19",
+ "and x6, x6, x7",
+ "ror x6, x6, #44",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #9",
+ "and x6, x6, x7",
+ "ror x6, x6, #45",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #1",
+ "and x6, x6, x7",
+ "ror x6, x6, #46",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #26",
+ "and x6, x6, x7",
+ "ror x6, x6, #47",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #16",
+ "and x6, x6, x7",
+ "ror x6, x6, #48",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #5",
+ "and x6, x6, x7",
+ "ror x6, x6, #49",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #11",
+ "and x6, x6, x7",
+ "ror x6, x6, #50",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #23",
+ "and x6, x6, x7",
+ "ror x6, x6, #51",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #8",
+ "and x6, x6, x7",
+ "ror x6, x6, #52",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #12",
+ "and x6, x6, x7",
+ "ror x6, x6, #53",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #7",
+ "and x6, x6, x7",
+ "ror x6, x6, #54",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #17",
+ "and x6, x6, x7",
+ "ror x6, x6, #55",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "and x6, x6, x7",
+ "ror x6, x6, #56",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #22",
+ "and x6, x6, x7",
+ "ror x6, x6, #57",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #3",
+ "and x6, x6, x7",
+ "ror x6, x6, #58",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #10",
+ "and x6, x6, x7",
+ "ror x6, x6, #59",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #14",
+ "and x6, x6, x7",
+ "ror x6, x6, #60",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #6",
+ "and x6, x6, x7",
+ "ror x6, x6, #61",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #20",
+ "and x6, x6, x7",
+ "ror x6, x6, #62",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #27",
+ "and x6, x6, x7",
+ "ror x6, x6, #63",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #24",
+ "and x6, x6, x7",
+ "eor x5, x5, x6",
+ "str x5, [x22, #0]",
+ "add x22, x22, #8",
+ "add x21, x21, #1",
+ "sub x4, x21, #16",
+ "cbnz x4, 27b",
+ "sub x4, x1, #16",
+ "cbz x4, 214f",
+ "ldr x4, [x0, #16]",
+ "rev x4, x4",
+ "movz x5, #0, lsl #0",
+ "movz x7, #1, lsl #0",
+ "add x6, x4, #0",
+ "lsr x6, x6, #7",
+ "and x6, x6, x7",
+ "ror x6, x6, #9",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #15",
+ "and x6, x6, x7",
+ "ror x6, x6, #10",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #23",
+ "and x6, x6, x7",
+ "ror x6, x6, #11",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #31",
+ "and x6, x6, x7",
+ "ror x6, x6, #12",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #39",
+ "and x6, x6, x7",
+ "ror x6, x6, #13",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #47",
+ "and x6, x6, x7",
+ "ror x6, x6, #14",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #55",
+ "and x6, x6, x7",
+ "ror x6, x6, #15",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #63",
+ "and x6, x6, x7",
+ "ror x6, x6, #16",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #6",
+ "and x6, x6, x7",
+ "ror x6, x6, #17",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #14",
+ "and x6, x6, x7",
+ "ror x6, x6, #18",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #22",
+ "and x6, x6, x7",
+ "ror x6, x6, #19",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #30",
+ "and x6, x6, x7",
+ "ror x6, x6, #20",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #38",
+ "and x6, x6, x7",
+ "ror x6, x6, #21",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #46",
+ "and x6, x6, x7",
+ "ror x6, x6, #22",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #54",
+ "and x6, x6, x7",
+ "ror x6, x6, #23",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #62",
+ "and x6, x6, x7",
+ "ror x6, x6, #24",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #5",
+ "and x6, x6, x7",
+ "ror x6, x6, #25",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #13",
+ "and x6, x6, x7",
+ "ror x6, x6, #26",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #21",
+ "and x6, x6, x7",
+ "ror x6, x6, #27",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #29",
+ "and x6, x6, x7",
+ "ror x6, x6, #28",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #37",
+ "and x6, x6, x7",
+ "ror x6, x6, #29",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #45",
+ "and x6, x6, x7",
+ "ror x6, x6, #30",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #53",
+ "and x6, x6, x7",
+ "ror x6, x6, #31",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #61",
+ "and x6, x6, x7",
+ "ror x6, x6, #32",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #4",
+ "and x6, x6, x7",
+ "ror x6, x6, #33",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #12",
+ "and x6, x6, x7",
+ "ror x6, x6, #34",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #20",
+ "and x6, x6, x7",
+ "ror x6, x6, #35",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #28",
+ "and x6, x6, x7",
+ "ror x6, x6, #36",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #1",
+ "and x6, x6, x7",
+ "ror x6, x6, #37",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #9",
+ "and x6, x6, x7",
+ "ror x6, x6, #38",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #17",
+ "and x6, x6, x7",
+ "ror x6, x6, #39",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #25",
+ "and x6, x6, x7",
+ "ror x6, x6, #40",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #33",
+ "and x6, x6, x7",
+ "ror x6, x6, #41",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #41",
+ "and x6, x6, x7",
+ "ror x6, x6, #42",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #49",
+ "and x6, x6, x7",
+ "ror x6, x6, #43",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #57",
+ "and x6, x6, x7",
+ "ror x6, x6, #44",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #2",
+ "and x6, x6, x7",
+ "ror x6, x6, #45",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #10",
+ "and x6, x6, x7",
+ "ror x6, x6, #46",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #18",
+ "and x6, x6, x7",
+ "ror x6, x6, #47",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #26",
+ "and x6, x6, x7",
+ "ror x6, x6, #48",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #34",
+ "and x6, x6, x7",
+ "ror x6, x6, #49",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #42",
+ "and x6, x6, x7",
+ "ror x6, x6, #50",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #50",
+ "and x6, x6, x7",
+ "ror x6, x6, #51",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #58",
+ "and x6, x6, x7",
+ "ror x6, x6, #52",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #3",
+ "and x6, x6, x7",
+ "ror x6, x6, #53",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #11",
+ "and x6, x6, x7",
+ "ror x6, x6, #54",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #19",
+ "and x6, x6, x7",
+ "ror x6, x6, #55",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #27",
+ "and x6, x6, x7",
+ "ror x6, x6, #56",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #35",
+ "and x6, x6, x7",
+ "ror x6, x6, #57",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #43",
+ "and x6, x6, x7",
+ "ror x6, x6, #58",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #51",
+ "and x6, x6, x7",
+ "ror x6, x6, #59",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #59",
+ "and x6, x6, x7",
+ "ror x6, x6, #60",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #36",
+ "and x6, x6, x7",
+ "ror x6, x6, #61",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #44",
+ "and x6, x6, x7",
+ "ror x6, x6, #62",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #52",
+ "and x6, x6, x7",
+ "ror x6, x6, #63",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #60",
+ "and x6, x6, x7",
+ "eor x5, x5, x6",
+ "lsr x19, x5, #28",
+ "add x20, x5, #0",
+ "lsl x20, x20, #36",
+ "lsr x20, x20, #36",
+ "movz x21, #0, lsl #0",
+ "add x22, x2, #256",
+ "216:",
+ "lsr x4, x21, #1",
+ "cbz x4, 217f",
+ "sub x4, x21, #8",
+ "cbz x4, 219f",
+ "sub x4, x21, #15",
+ "cbz x4, 221f",
+ "lsr x4, x19, #26",
+ "ror x19, x19, #62",
+ "eor x19, x19, x4",
+ "lsl x19, x19, #36",
+ "lsr x19, x19, #36",
+ "lsr x4, x20, #26",
+ "ror x20, x20, #62",
+ "eor x20, x20, x4",
+ "lsl x20, x20, #36",
+ "lsr x20, x20, #36",
+ "b 222f",
+ "221:",
+ "lsr x4, x19, #27",
+ "ror x19, x19, #63",
+ "eor x19, x19, x4",
+ "lsl x19, x19, #36",
+ "lsr x19, x19, #36",
+ "lsr x4, x20, #27",
+ "ror x20, x20, #63",
+ "eor x20, x20, x4",
+ "lsl x20, x20, #36",
+ "lsr x20, x20, #36",
+ "222:",
+ "b 220f",
+ "219:",
+ "lsr x4, x19, #27",
+ "ror x19, x19, #63",
+ "eor x19, x19, x4",
+ "lsl x19, x19, #36",
+ "lsr x19, x19, #36",
+ "lsr x4, x20, #27",
+ "ror x20, x20, #63",
+ "eor x20, x20, x4",
+ "lsl x20, x20, #36",
+ "lsr x20, x20, #36",
+ "220:",
+ "b 218f",
+ "217:",
+ "lsr x4, x19, #27",
+ "ror x19, x19, #63",
+ "eor x19, x19, x4",
+ "lsl x19, x19, #36",
+ "lsr x19, x19, #36",
+ "lsr x4, x20, #27",
+ "ror x20, x20, #63",
+ "eor x20, x20, x4",
+ "lsl x20, x20, #36",
+ "lsr x20, x20, #36",
+ "218:",
+ "lsl x4, x19, #28",
+ "eor x4, x4, x20",
+ "movz x5, #0, lsl #0",
+ "movz x7, #1, lsl #0",
+ "add x6, x4, #0",
+ "lsr x6, x6, #42",
+ "and x6, x6, x7",
+ "ror x6, x6, #17",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #39",
+ "and x6, x6, x7",
+ "ror x6, x6, #18",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #45",
+ "and x6, x6, x7",
+ "ror x6, x6, #19",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #32",
+ "and x6, x6, x7",
+ "ror x6, x6, #20",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #55",
+ "and x6, x6, x7",
+ "ror x6, x6, #21",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #51",
+ "and x6, x6, x7",
+ "ror x6, x6, #22",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #53",
+ "and x6, x6, x7",
+ "ror x6, x6, #23",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #28",
+ "and x6, x6, x7",
+ "ror x6, x6, #24",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #41",
+ "and x6, x6, x7",
+ "ror x6, x6, #25",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #50",
+ "and x6, x6, x7",
+ "ror x6, x6, #26",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #35",
+ "and x6, x6, x7",
+ "ror x6, x6, #27",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #46",
+ "and x6, x6, x7",
+ "ror x6, x6, #28",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #33",
+ "and x6, x6, x7",
+ "ror x6, x6, #29",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #37",
+ "and x6, x6, x7",
+ "ror x6, x6, #30",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #44",
+ "and x6, x6, x7",
+ "ror x6, x6, #31",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #52",
+ "and x6, x6, x7",
+ "ror x6, x6, #32",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #30",
+ "and x6, x6, x7",
+ "ror x6, x6, #33",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #48",
+ "and x6, x6, x7",
+ "ror x6, x6, #34",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #40",
+ "and x6, x6, x7",
+ "ror x6, x6, #35",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #49",
+ "and x6, x6, x7",
+ "ror x6, x6, #36",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #29",
+ "and x6, x6, x7",
+ "ror x6, x6, #37",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #36",
+ "and x6, x6, x7",
+ "ror x6, x6, #38",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #43",
+ "and x6, x6, x7",
+ "ror x6, x6, #39",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #54",
+ "and x6, x6, x7",
+ "ror x6, x6, #40",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #15",
+ "and x6, x6, x7",
+ "ror x6, x6, #41",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #4",
+ "and x6, x6, x7",
+ "ror x6, x6, #42",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #25",
+ "and x6, x6, x7",
+ "ror x6, x6, #43",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #19",
+ "and x6, x6, x7",
+ "ror x6, x6, #44",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #9",
+ "and x6, x6, x7",
+ "ror x6, x6, #45",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #1",
+ "and x6, x6, x7",
+ "ror x6, x6, #46",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #26",
+ "and x6, x6, x7",
+ "ror x6, x6, #47",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #16",
+ "and x6, x6, x7",
+ "ror x6, x6, #48",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #5",
+ "and x6, x6, x7",
+ "ror x6, x6, #49",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #11",
+ "and x6, x6, x7",
+ "ror x6, x6, #50",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #23",
+ "and x6, x6, x7",
+ "ror x6, x6, #51",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #8",
+ "and x6, x6, x7",
+ "ror x6, x6, #52",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #12",
+ "and x6, x6, x7",
+ "ror x6, x6, #53",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #7",
+ "and x6, x6, x7",
+ "ror x6, x6, #54",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #17",
+ "and x6, x6, x7",
+ "ror x6, x6, #55",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "and x6, x6, x7",
+ "ror x6, x6, #56",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #22",
+ "and x6, x6, x7",
+ "ror x6, x6, #57",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #3",
+ "and x6, x6, x7",
+ "ror x6, x6, #58",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #10",
+ "and x6, x6, x7",
+ "ror x6, x6, #59",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #14",
+ "and x6, x6, x7",
+ "ror x6, x6, #60",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #6",
+ "and x6, x6, x7",
+ "ror x6, x6, #61",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #20",
+ "and x6, x6, x7",
+ "ror x6, x6, #62",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #27",
+ "and x6, x6, x7",
+ "ror x6, x6, #63",
+ "eor x5, x5, x6",
+ "add x6, x4, #0",
+ "lsr x6, x6, #24",
+ "and x6, x6, x7",
+ "eor x5, x5, x6",
+ "str x5, [x22, #0]",
+ "add x22, x22, #8",
+ "add x21, x21, #1",
+ "sub x4, x21, #16",
+ "cbnz x4, 216b",
+ "b 215f",
+ "214:",
+ "ldr x4, [x2, #0]",
+ "str x4, [x2, #256]",
+ "ldr x4, [x2, #8]",
+ "str x4, [x2, #264]",
+ "ldr x4, [x2, #16]",
+ "str x4, [x2, #272]",
+ "ldr x4, [x2, #24]",
+ "str x4, [x2, #280]",
+ "ldr x4, [x2, #32]",
+ "str x4, [x2, #288]",
+ "ldr x4, [x2, #40]",
+ "str x4, [x2, #296]",
+ "ldr x4, [x2, #48]",
+ "str x4, [x2, #304]",
+ "ldr x4, [x2, #56]",
+ "str x4, [x2, #312]",
+ "ldr x4, [x2, #64]",
+ "str x4, [x2, #320]",
+ "ldr x4, [x2, #72]",
+ "str x4, [x2, #328]",
+ "ldr x4, [x2, #80]",
+ "str x4, [x2, #336]",
+ "ldr x4, [x2, #88]",
+ "str x4, [x2, #344]",
+ "ldr x4, [x2, #96]",
+ "str x4, [x2, #352]",
+ "ldr x4, [x2, #104]",
+ "str x4, [x2, #360]",
+ "ldr x4, [x2, #112]",
+ "str x4, [x2, #368]",
+ "ldr x4, [x2, #120]",
+ "str x4, [x2, #376]",
+ "215:",
+ "ldr x19, [x3, #0]",
+ "ldr x20, [x3, #8]",
+ "ldr x21, [x3, #16]",
+ "ldr x22, [x3, #24]",
+ "ret",
+ )
+}
+
+/// 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 AArch64 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 x19, [x2, #0]",
+ "str x20, [x2, #8]",
+ "str x21, [x2, #16]",
+ "str x22, [x2, #24]",
+ "ldr x3, [x1, #0]",
+ "rev x3, x3",
+ "movz x10, #0, lsl #0",
+ "movz x12, #1, lsl #0",
+ "add x11, x3, #0",
+ "lsr x11, x11, #6",
+ "and x11, x11, x12",
+ "ror x11, x11, #1",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #14",
+ "and x11, x11, x12",
+ "ror x11, x11, #2",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #22",
+ "and x11, x11, x12",
+ "ror x11, x11, #3",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #30",
+ "and x11, x11, x12",
+ "ror x11, x11, #4",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #38",
+ "and x11, x11, x12",
+ "ror x11, x11, #5",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #46",
+ "and x11, x11, x12",
+ "ror x11, x11, #6",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #54",
+ "and x11, x11, x12",
+ "ror x11, x11, #7",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #62",
+ "and x11, x11, x12",
+ "ror x11, x11, #8",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #4",
+ "and x11, x11, x12",
+ "ror x11, x11, #9",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #12",
+ "and x11, x11, x12",
+ "ror x11, x11, #10",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #20",
+ "and x11, x11, x12",
+ "ror x11, x11, #11",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #28",
+ "and x11, x11, x12",
+ "ror x11, x11, #12",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #36",
+ "and x11, x11, x12",
+ "ror x11, x11, #13",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #44",
+ "and x11, x11, x12",
+ "ror x11, x11, #14",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #52",
+ "and x11, x11, x12",
+ "ror x11, x11, #15",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #60",
+ "and x11, x11, x12",
+ "ror x11, x11, #16",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #2",
+ "and x11, x11, x12",
+ "ror x11, x11, #17",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #10",
+ "and x11, x11, x12",
+ "ror x11, x11, #18",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #18",
+ "and x11, x11, x12",
+ "ror x11, x11, #19",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #26",
+ "and x11, x11, x12",
+ "ror x11, x11, #20",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #34",
+ "and x11, x11, x12",
+ "ror x11, x11, #21",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #42",
+ "and x11, x11, x12",
+ "ror x11, x11, #22",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #50",
+ "and x11, x11, x12",
+ "ror x11, x11, #23",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #58",
+ "and x11, x11, x12",
+ "ror x11, x11, #24",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "and x11, x11, x12",
+ "ror x11, x11, #25",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #8",
+ "and x11, x11, x12",
+ "ror x11, x11, #26",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #16",
+ "and x11, x11, x12",
+ "ror x11, x11, #27",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #24",
+ "and x11, x11, x12",
+ "ror x11, x11, #28",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #32",
+ "and x11, x11, x12",
+ "ror x11, x11, #29",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #40",
+ "and x11, x11, x12",
+ "ror x11, x11, #30",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #48",
+ "and x11, x11, x12",
+ "ror x11, x11, #31",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #56",
+ "and x11, x11, x12",
+ "ror x11, x11, #32",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #7",
+ "and x11, x11, x12",
+ "ror x11, x11, #33",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #15",
+ "and x11, x11, x12",
+ "ror x11, x11, #34",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #23",
+ "and x11, x11, x12",
+ "ror x11, x11, #35",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #31",
+ "and x11, x11, x12",
+ "ror x11, x11, #36",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #39",
+ "and x11, x11, x12",
+ "ror x11, x11, #37",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #47",
+ "and x11, x11, x12",
+ "ror x11, x11, #38",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #55",
+ "and x11, x11, x12",
+ "ror x11, x11, #39",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #63",
+ "and x11, x11, x12",
+ "ror x11, x11, #40",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #5",
+ "and x11, x11, x12",
+ "ror x11, x11, #41",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #13",
+ "and x11, x11, x12",
+ "ror x11, x11, #42",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #21",
+ "and x11, x11, x12",
+ "ror x11, x11, #43",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #29",
+ "and x11, x11, x12",
+ "ror x11, x11, #44",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #37",
+ "and x11, x11, x12",
+ "ror x11, x11, #45",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #45",
+ "and x11, x11, x12",
+ "ror x11, x11, #46",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #53",
+ "and x11, x11, x12",
+ "ror x11, x11, #47",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #61",
+ "and x11, x11, x12",
+ "ror x11, x11, #48",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #3",
+ "and x11, x11, x12",
+ "ror x11, x11, #49",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #11",
+ "and x11, x11, x12",
+ "ror x11, x11, #50",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #19",
+ "and x11, x11, x12",
+ "ror x11, x11, #51",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #27",
+ "and x11, x11, x12",
+ "ror x11, x11, #52",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #35",
+ "and x11, x11, x12",
+ "ror x11, x11, #53",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #43",
+ "and x11, x11, x12",
+ "ror x11, x11, #54",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #51",
+ "and x11, x11, x12",
+ "ror x11, x11, #55",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #59",
+ "and x11, x11, x12",
+ "ror x11, x11, #56",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #1",
+ "and x11, x11, x12",
+ "ror x11, x11, #57",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #9",
+ "and x11, x11, x12",
+ "ror x11, x11, #58",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #17",
+ "and x11, x11, x12",
+ "ror x11, x11, #59",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #25",
+ "and x11, x11, x12",
+ "ror x11, x11, #60",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #33",
+ "and x11, x11, x12",
+ "ror x11, x11, #61",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #41",
+ "and x11, x11, x12",
+ "ror x11, x11, #62",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #49",
+ "and x11, x11, x12",
+ "ror x11, x11, #63",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #57",
+ "and x11, x11, x12",
+ "eor x10, x10, x11",
+ "lsr x19, x10, #32",
+ "add x20, x10, #0",
+ "lsl x20, x20, #32",
+ "lsr x20, x20, #32",
+ "add x22, x0, #0",
+ "movz x21, #16, lsl #0",
+ "20:",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #27",
+ "add x11, x10, #0",
+ "lsr x11, x11, #42",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #28",
+ "add x11, x10, #0",
+ "lsr x11, x11, #43",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #29",
+ "add x11, x10, #0",
+ "lsr x11, x11, #44",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #30",
+ "add x11, x10, #0",
+ "lsr x11, x11, #45",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #31",
+ "add x11, x10, #0",
+ "lsr x11, x11, #46",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "add x11, x10, #0",
+ "lsr x11, x11, #47",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x10",
+ "eor x11, x11, x9",
+ "and x12, x7, x11",
+ "eor x13, x3, x7",
+ "and x14, x4, x13",
+ "eor x14, x12, x14",
+ "eor x15, x11, x12",
+ "and x16, x4, x15",
+ "eor x16, x3, x16",
+ "and x16, x8, x16",
+ "eor x14, x14, x16",
+ "and x16, x7, x3",
+ "eor x17, x16, x10",
+ "eor x17, x17, x9",
+ "str x13, [x2, #32]",
+ "and x13, x4, x17",
+ "str x3, [x2, #40]",
+ "eor x3, x16, x13",
+ "str x12, [x2, #48]",
+ "eor x12, x7, x10",
+ "eor x12, x12, x9",
+ "str x10, [x2, #56]",
+ "eor x10, x12, x13",
+ "str x13, [x2, #64]",
+ "and x13, x8, x10",
+ "eor x3, x3, x13",
+ "and x3, x6, x3",
+ "eor x14, x14, x3",
+ "and x7, x4, x7",
+ "eor x3, x17, x7",
+ "and x13, x4, x12",
+ "str x7, [x2, #72]",
+ "eor x7, x11, x13",
+ "and x7, x8, x7",
+ "eor x3, x3, x7",
+ "and x7, x4, x11",
+ "str x12, [x2, #80]",
+ "eor x12, x15, x7",
+ "and x12, x8, x12",
+ "and x12, x6, x12",
+ "eor x3, x3, x12",
+ "and x3, x5, x3",
+ "eor x3, x14, x3",
+ "eor x11, x11, x16",
+ "eor x16, x11, x13",
+ "ldr x14, [x2, #48]",
+ "ldr x12, [x2, #56]",
+ "str x3, [x2, #88]",
+ "eor x3, x14, x12",
+ "eor x3, x3, x9",
+ "and x11, x4, x11",
+ "eor x11, x3, x11",
+ "str x10, [x2, #96]",
+ "and x10, x8, x11",
+ "eor x16, x16, x10",
+ "eor x10, x15, x12",
+ "eor x10, x10, x9",
+ "eor x13, x10, x13",
+ "and x12, x4, x14",
+ "eor x14, x14, x12",
+ "and x14, x8, x14",
+ "eor x12, x13, x14",
+ "and x12, x6, x12",
+ "eor x16, x16, x12",
+ "eor x11, x11, x14",
+ "ldr x14, [x2, #40]",
+ "and x12, x4, x14",
+ "eor x14, x3, x12",
+ "and x14, x8, x14",
+ "str x3, [x2, #48]",
+ "eor x3, x15, x14",
+ "and x3, x6, x3",
+ "eor x11, x11, x3",
+ "and x11, x5, x11",
+ "eor x16, x16, x11",
+ "eor x11, x15, x12",
+ "and x3, x8, x13",
+ "eor x11, x11, x3",
+ "eor x17, x17, x7",
+ "and x10, x4, x10",
+ "ldr x7, [x2, #48]",
+ "eor x7, x7, x10",
+ "and x7, x8, x7",
+ "eor x17, x17, x7",
+ "and x17, x6, x17",
+ "eor x11, x11, x17",
+ "ldr x17, [x2, #64]",
+ "and x7, x8, x17",
+ "eor x13, x13, x7",
+ "ldr x7, [x2, #40]",
+ "eor x7, x7, x12",
+ "eor x7, x7, x14",
+ "and x7, x6, x7",
+ "eor x13, x13, x7",
+ "and x13, x5, x13",
+ "eor x11, x11, x13",
+ "ldr x13, [x2, #32]",
+ "ldr x7, [x2, #56]",
+ "eor x13, x13, x7",
+ "eor x13, x13, x9",
+ "eor x13, x13, x4",
+ "eor x17, x17, x7",
+ "eor x17, x17, x9",
+ "and x17, x8, x17",
+ "eor x17, x13, x17",
+ "ldr x14, [x2, #96]",
+ "eor x14, x14, x7",
+ "eor x14, x14, x9",
+ "and x14, x8, x14",
+ "ldr x7, [x2, #80]",
+ "eor x7, x7, x14",
+ "and x7, x6, x7",
+ "eor x17, x17, x7",
+ "ldr x7, [x2, #72]",
+ "eor x7, x15, x7",
+ "and x7, x8, x7",
+ "eor x12, x12, x7",
+ "eor x15, x15, x4",
+ "and x8, x8, x15",
+ "eor x13, x13, x8",
+ "and x6, x6, x13",
+ "eor x12, x12, x6",
+ "and x5, x5, x12",
+ "eor x6, x17, x5",
+ "ldr x3, [x2, #88]",
+ "add x4, x16, #0",
+ "add x5, x11, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #63",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #55",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #49",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #41",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #23",
+ "add x11, x10, #0",
+ "lsr x11, x11, #36",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #24",
+ "add x11, x10, #0",
+ "lsr x11, x11, #37",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #25",
+ "add x11, x10, #0",
+ "lsr x11, x11, #38",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #26",
+ "add x11, x10, #0",
+ "lsr x11, x11, #39",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #27",
+ "add x11, x10, #0",
+ "lsr x11, x11, #40",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #28",
+ "add x11, x10, #0",
+ "lsr x11, x11, #41",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "and x13, x4, x8",
+ "eor x14, x8, x13",
+ "and x15, x3, x14",
+ "eor x15, x12, x15",
+ "eor x16, x13, x10",
+ "eor x16, x16, x9",
+ "and x17, x3, x16",
+ "str x16, [x2, #32]",
+ "eor x16, x14, x17",
+ "and x16, x7, x16",
+ "eor x15, x15, x16",
+ "str x17, [x2, #40]",
+ "and x17, x4, x12",
+ "str x16, [x2, #48]",
+ "eor x16, x12, x17",
+ "eor x14, x14, x10",
+ "eor x14, x14, x9",
+ "str x12, [x2, #56]",
+ "and x12, x3, x14",
+ "str x14, [x2, #64]",
+ "eor x14, x16, x12",
+ "str x12, [x2, #72]",
+ "eor x12, x16, x10",
+ "eor x12, x12, x9",
+ "str x16, [x2, #80]",
+ "and x16, x3, x12",
+ "eor x16, x4, x16",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x17",
+ "eor x14, x11, x14",
+ "eor x16, x8, x4",
+ "str x17, [x2, #88]",
+ "and x17, x3, x16",
+ "str x11, [x2, #96]",
+ "eor x11, x4, x17",
+ "and x11, x7, x11",
+ "eor x14, x14, x11",
+ "and x14, x5, x14",
+ "eor x15, x15, x14",
+ "eor x16, x16, x10",
+ "eor x16, x16, x9",
+ "and x13, x3, x13",
+ "eor x14, x16, x13",
+ "ldr x11, [x2, #64]",
+ "eor x11, x11, x17",
+ "and x11, x7, x11",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "eor x12, x12, x11",
+ "and x12, x6, x12",
+ "eor x14, x14, x12",
+ "ldr x12, [x2, #80]",
+ "and x11, x3, x12",
+ "eor x11, x8, x11",
+ "and x11, x7, x11",
+ "ldr x17, [x2, #32]",
+ "eor x11, x17, x11",
+ "str x15, [x2, #48]",
+ "ldr x15, [x2, #56]",
+ "str x10, [x2, #64]",
+ "and x10, x3, x15",
+ "eor x12, x12, x10",
+ "and x8, x7, x8",
+ "eor x12, x12, x8",
+ "and x12, x6, x12",
+ "eor x11, x11, x12",
+ "and x11, x5, x11",
+ "eor x14, x14, x11",
+ "eor x11, x16, x3",
+ "eor x11, x11, x7",
+ "eor x12, x17, x13",
+ "and x12, x7, x12",
+ "eor x12, x3, x12",
+ "and x12, x6, x12",
+ "eor x11, x11, x12",
+ "and x3, x3, x4",
+ "ldr x4, [x2, #96]",
+ "eor x4, x4, x3",
+ "ldr x12, [x2, #40]",
+ "eor x17, x17, x12",
+ "and x17, x7, x17",
+ "eor x4, x4, x17",
+ "and x3, x6, x3",
+ "eor x4, x4, x3",
+ "and x4, x5, x4",
+ "eor x11, x11, x4",
+ "eor x16, x16, x12",
+ "ldr x12, [x2, #72]",
+ "and x12, x7, x12",
+ "eor x16, x16, x12",
+ "ldr x12, [x2, #64]",
+ "eor x4, x13, x12",
+ "eor x4, x4, x9",
+ "eor x15, x15, x10",
+ "and x15, x7, x15",
+ "eor x4, x4, x15",
+ "and x6, x6, x4",
+ "eor x16, x16, x6",
+ "ldr x6, [x2, #88]",
+ "eor x6, x6, x13",
+ "eor x12, x6, x12",
+ "eor x12, x12, x9",
+ "and x7, x7, x12",
+ "eor x6, x6, x7",
+ "and x5, x5, x6",
+ "eor x6, x16, x5",
+ "ldr x3, [x2, #48]",
+ "add x4, x14, #0",
+ "add x5, x11, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #50",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #34",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #60",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #45",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #19",
+ "add x11, x10, #0",
+ "lsr x11, x11, #30",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #20",
+ "add x11, x10, #0",
+ "lsr x11, x11, #31",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #21",
+ "add x11, x10, #0",
+ "lsr x11, x11, #32",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #22",
+ "add x11, x10, #0",
+ "lsr x11, x11, #33",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #23",
+ "add x11, x10, #0",
+ "lsr x11, x11, #34",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #24",
+ "add x11, x10, #0",
+ "lsr x11, x11, #35",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "and x13, x7, x12",
+ "eor x14, x8, x13",
+ "and x15, x7, x8",
+ "eor x16, x12, x15",
+ "and x17, x3, x16",
+ "str x13, [x2, #32]",
+ "eor x13, x14, x17",
+ "str x14, [x2, #40]",
+ "eor x14, x16, x10",
+ "eor x14, x14, x9",
+ "and x15, x3, x15",
+ "str x10, [x2, #48]",
+ "eor x10, x14, x15",
+ "str x14, [x2, #56]",
+ "and x14, x4, x10",
+ "eor x14, x13, x14",
+ "str x13, [x2, #64]",
+ "and x13, x4, x16",
+ "eor x10, x10, x13",
+ "and x10, x6, x10",
+ "eor x14, x14, x10",
+ "and x8, x3, x8",
+ "eor x11, x11, x8",
+ "and x10, x4, x12",
+ "eor x11, x11, x10",
+ "and x15, x6, x15",
+ "eor x11, x11, x15",
+ "and x11, x5, x11",
+ "eor x14, x14, x11",
+ "eor x11, x12, x7",
+ "eor x17, x11, x17",
+ "ldr x15, [x2, #32]",
+ "ldr x10, [x2, #48]",
+ "eor x13, x15, x10",
+ "eor x13, x13, x9",
+ "str x14, [x2, #72]",
+ "and x14, x3, x15",
+ "eor x14, x13, x14",
+ "str x16, [x2, #80]",
+ "and x16, x4, x14",
+ "str x11, [x2, #88]",
+ "eor x11, x17, x16",
+ "str x8, [x2, #96]",
+ "eor x8, x7, x10",
+ "eor x8, x8, x9",
+ "and x15, x3, x8",
+ "eor x7, x7, x15",
+ "str x8, [x2, #104]",
+ "and x8, x3, x12",
+ "eor x12, x12, x8",
+ "and x12, x4, x12",
+ "eor x7, x7, x12",
+ "and x7, x6, x7",
+ "eor x11, x11, x7",
+ "ldr x7, [x2, #64]",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x17, x4, x17",
+ "eor x7, x7, x17",
+ "ldr x17, [x2, #40]",
+ "eor x12, x17, x10",
+ "eor x12, x12, x9",
+ "and x17, x3, x12",
+ "str x12, [x2, #64]",
+ "eor x12, x13, x17",
+ "str x17, [x2, #112]",
+ "eor x17, x8, x10",
+ "eor x17, x17, x9",
+ "and x17, x4, x17",
+ "eor x12, x12, x17",
+ "and x12, x6, x12",
+ "eor x7, x7, x12",
+ "and x7, x5, x7",
+ "eor x11, x11, x7",
+ "and x7, x3, x13",
+ "ldr x12, [x2, #56]",
+ "eor x12, x12, x7",
+ "eor x7, x14, x10",
+ "eor x7, x7, x9",
+ "and x7, x4, x7",
+ "eor x12, x12, x7",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x12, x12, x14",
+ "ldr x14, [x2, #32]",
+ "eor x15, x14, x15",
+ "eor x15, x15, x17",
+ "ldr x17, [x2, #96]",
+ "and x16, x4, x17",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x15, x15, x14",
+ "and x15, x5, x15",
+ "eor x12, x12, x15",
+ "eor x13, x13, x17",
+ "eor x13, x13, x4",
+ "ldr x17, [x2, #88]",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x3, x3, x17",
+ "ldr x17, [x2, #104]",
+ "eor x17, x17, x3",
+ "and x17, x4, x17",
+ "ldr x3, [x2, #80]",
+ "eor x3, x3, x17",
+ "and x3, x6, x3",
+ "eor x13, x13, x3",
+ "ldr x3, [x2, #40]",
+ "eor x3, x3, x8",
+ "ldr x17, [x2, #64]",
+ "ldr x10, [x2, #112]",
+ "eor x10, x17, x10",
+ "and x10, x4, x10",
+ "eor x3, x3, x10",
+ "and x4, x4, x8",
+ "eor x17, x17, x4",
+ "and x6, x6, x17",
+ "eor x3, x3, x6",
+ "and x5, x5, x3",
+ "eor x6, x13, x5",
+ "ldr x3, [x2, #72]",
+ "add x4, x11, #0",
+ "add x5, x12, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #38",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #62",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #48",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #56",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #15",
+ "add x11, x10, #0",
+ "lsr x11, x11, #24",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #16",
+ "add x11, x10, #0",
+ "lsr x11, x11, #25",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #17",
+ "add x11, x10, #0",
+ "lsr x11, x11, #26",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #18",
+ "add x11, x10, #0",
+ "lsr x11, x11, #27",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #19",
+ "add x11, x10, #0",
+ "lsr x11, x11, #28",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #20",
+ "add x11, x10, #0",
+ "lsr x11, x11, #29",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x6, x10",
+ "eor x12, x12, x9",
+ "and x13, x4, x6",
+ "eor x14, x12, x13",
+ "and x15, x8, x14",
+ "eor x16, x12, x15",
+ "eor x17, x6, x4",
+ "str x15, [x2, #32]",
+ "eor x15, x17, x10",
+ "eor x15, x15, x9",
+ "str x6, [x2, #40]",
+ "and x6, x8, x15",
+ "str x3, [x2, #48]",
+ "eor x3, x17, x6",
+ "and x3, x7, x3",
+ "eor x16, x16, x3",
+ "eor x3, x4, x10",
+ "eor x3, x3, x9",
+ "str x17, [x2, #56]",
+ "eor x17, x4, x6",
+ "str x6, [x2, #64]",
+ "and x6, x7, x17",
+ "str x11, [x2, #72]",
+ "eor x11, x3, x6",
+ "and x11, x5, x11",
+ "eor x16, x16, x11",
+ "eor x11, x14, x10",
+ "eor x11, x11, x9",
+ "and x11, x8, x11",
+ "eor x11, x15, x11",
+ "and x11, x7, x11",
+ "eor x17, x17, x11",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x11, x4, x12",
+ "str x6, [x2, #80]",
+ "ldr x6, [x2, #72]",
+ "eor x6, x6, x11",
+ "str x3, [x2, #72]",
+ "and x3, x8, x6",
+ "eor x13, x13, x3",
+ "str x6, [x2, #88]",
+ "ldr x6, [x2, #56]",
+ "and x6, x7, x6",
+ "eor x13, x13, x6",
+ "and x13, x5, x13",
+ "eor x17, x17, x13",
+ "ldr x13, [x2, #48]",
+ "str x6, [x2, #56]",
+ "and x6, x13, x17",
+ "eor x16, x16, x6",
+ "and x6, x8, x11",
+ "eor x15, x15, x6",
+ "str x16, [x2, #96]",
+ "eor x16, x3, x10",
+ "eor x16, x16, x9",
+ "and x16, x7, x16",
+ "eor x16, x15, x16",
+ "str x8, [x2, #104]",
+ "eor x8, x11, x3",
+ "str x11, [x2, #112]",
+ "ldr x11, [x2, #40]",
+ "str x6, [x2, #120]",
+ "ldr x6, [x2, #64]",
+ "eor x6, x11, x6",
+ "and x6, x7, x6",
+ "eor x8, x8, x6",
+ "and x8, x5, x8",
+ "eor x16, x16, x8",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x17, x13, x17",
+ "eor x16, x16, x17",
+ "eor x14, x14, x3",
+ "and x12, x7, x12",
+ "eor x14, x14, x12",
+ "eor x4, x4, x6",
+ "and x4, x5, x4",
+ "eor x14, x14, x4",
+ "eor x15, x15, x10",
+ "eor x15, x15, x9",
+ "ldr x4, [x2, #88]",
+ "ldr x6, [x2, #120]",
+ "eor x4, x4, x6",
+ "and x4, x7, x4",
+ "eor x15, x15, x4",
+ "ldr x4, [x2, #72]",
+ "ldr x12, [x2, #32]",
+ "eor x4, x4, x12",
+ "ldr x3, [x2, #56]",
+ "eor x4, x4, x3",
+ "and x4, x5, x4",
+ "eor x15, x15, x4",
+ "and x4, x13, x15",
+ "eor x14, x14, x4",
+ "ldr x4, [x2, #112]",
+ "ldr x3, [x2, #104]",
+ "eor x3, x4, x3",
+ "eor x11, x11, x4",
+ "eor x11, x11, x6",
+ "and x7, x7, x11",
+ "eor x3, x3, x7",
+ "eor x12, x12, x10",
+ "eor x12, x12, x9",
+ "ldr x7, [x2, #80]",
+ "eor x12, x12, x7",
+ "and x5, x5, x12",
+ "eor x3, x3, x5",
+ "eor x15, x15, x10",
+ "eor x15, x15, x9",
+ "and x13, x13, x15",
+ "eor x6, x3, x13",
+ "ldr x3, [x2, #96]",
+ "add x4, x16, #0",
+ "add x5, x14, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #33",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #42",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #52",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #58",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #11",
+ "add x11, x10, #0",
+ "lsr x11, x11, #18",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #12",
+ "add x11, x10, #0",
+ "lsr x11, x11, #19",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #13",
+ "add x11, x10, #0",
+ "lsr x11, x11, #20",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #14",
+ "add x11, x10, #0",
+ "lsr x11, x11, #21",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #15",
+ "add x11, x10, #0",
+ "lsr x11, x11, #22",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #16",
+ "add x11, x10, #0",
+ "lsr x11, x11, #23",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x6, x10",
+ "eor x12, x12, x9",
+ "and x13, x12, x8",
+ "eor x14, x11, x13",
+ "eor x3, x3, x10",
+ "eor x3, x3, x9",
+ "and x15, x3, x14",
+ "eor x16, x8, x15",
+ "eor x17, x8, x10",
+ "eor x17, x17, x9",
+ "str x15, [x2, #32]",
+ "and x15, x12, x17",
+ "str x11, [x2, #40]",
+ "eor x11, x17, x15",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "str x15, [x2, #48]",
+ "and x15, x7, x11",
+ "eor x15, x16, x15",
+ "str x16, [x2, #56]",
+ "eor x16, x17, x13",
+ "str x14, [x2, #64]",
+ "and x14, x7, x16",
+ "eor x14, x6, x14",
+ "eor x5, x5, x10",
+ "eor x5, x5, x9",
+ "and x14, x5, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x17",
+ "eor x14, x12, x14",
+ "str x6, [x2, #72]",
+ "eor x6, x8, x12",
+ "and x13, x3, x13",
+ "eor x13, x6, x13",
+ "and x13, x7, x13",
+ "eor x14, x14, x13",
+ "eor x13, x11, x10",
+ "eor x13, x13, x9",
+ "and x13, x3, x13",
+ "str x12, [x2, #80]",
+ "eor x12, x17, x3",
+ "and x12, x7, x12",
+ "eor x13, x13, x12",
+ "and x13, x5, x13",
+ "eor x14, x14, x13",
+ "eor x4, x4, x10",
+ "eor x4, x4, x9",
+ "and x14, x4, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x11",
+ "ldr x13, [x2, #64]",
+ "eor x12, x13, x14",
+ "eor x12, x12, x7",
+ "str x15, [x2, #88]",
+ "ldr x15, [x2, #48]",
+ "eor x13, x15, x10",
+ "eor x13, x13, x9",
+ "str x10, [x2, #96]",
+ "and x10, x3, x13",
+ "str x6, [x2, #104]",
+ "ldr x6, [x2, #40]",
+ "eor x6, x6, x10",
+ "and x15, x3, x15",
+ "str x13, [x2, #48]",
+ "and x13, x7, x15",
+ "eor x6, x6, x13",
+ "and x6, x5, x6",
+ "eor x12, x12, x6",
+ "eor x15, x16, x15",
+ "and x15, x7, x15",
+ "ldr x6, [x2, #72]",
+ "eor x15, x6, x15",
+ "and x8, x3, x8",
+ "eor x17, x17, x8",
+ "and x13, x7, x17",
+ "eor x13, x10, x13",
+ "and x13, x5, x13",
+ "eor x15, x15, x13",
+ "and x15, x4, x15",
+ "eor x12, x12, x15",
+ "eor x15, x11, x3",
+ "eor x15, x15, x7",
+ "ldr x13, [x2, #48]",
+ "eor x13, x13, x14",
+ "ldr x14, [x2, #104]",
+ "str x12, [x2, #48]",
+ "eor x12, x14, x10",
+ "and x12, x7, x12",
+ "eor x13, x13, x12",
+ "and x13, x5, x13",
+ "eor x15, x15, x13",
+ "ldr x13, [x2, #96]",
+ "eor x12, x14, x13",
+ "eor x12, x12, x9",
+ "str x8, [x2, #40]",
+ "and x8, x3, x12",
+ "eor x11, x11, x8",
+ "and x11, x5, x11",
+ "str x8, [x2, #112]",
+ "ldr x8, [x2, #64]",
+ "eor x8, x8, x11",
+ "and x8, x4, x8",
+ "eor x15, x15, x8",
+ "ldr x8, [x2, #80]",
+ "eor x8, x8, x10",
+ "ldr x10, [x2, #56]",
+ "and x10, x7, x10",
+ "eor x8, x8, x10",
+ "eor x10, x16, x3",
+ "and x10, x7, x10",
+ "eor x17, x17, x10",
+ "and x17, x5, x17",
+ "eor x8, x8, x17",
+ "ldr x17, [x2, #32]",
+ "eor x12, x12, x17",
+ "and x3, x3, x6",
+ "eor x14, x14, x3",
+ "and x14, x7, x14",
+ "eor x12, x12, x14",
+ "eor x16, x16, x13",
+ "eor x16, x16, x9",
+ "ldr x14, [x2, #112]",
+ "eor x16, x16, x14",
+ "ldr x14, [x2, #40]",
+ "eor x14, x14, x13",
+ "eor x14, x14, x9",
+ "and x7, x7, x14",
+ "eor x16, x16, x7",
+ "and x5, x5, x16",
+ "eor x12, x12, x5",
+ "and x4, x4, x12",
+ "eor x6, x8, x4",
+ "ldr x3, [x2, #88]",
+ "ldr x4, [x2, #48]",
+ "add x5, x15, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #35",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #57",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #46",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #40",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #7",
+ "add x11, x10, #0",
+ "lsr x11, x11, #12",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #8",
+ "add x11, x10, #0",
+ "lsr x11, x11, #13",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #9",
+ "add x11, x10, #0",
+ "lsr x11, x11, #14",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #10",
+ "add x11, x10, #0",
+ "lsr x11, x11, #15",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #11",
+ "add x11, x10, #0",
+ "lsr x11, x11, #16",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #12",
+ "add x11, x10, #0",
+ "lsr x11, x11, #17",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x7, x10",
+ "eor x12, x12, x9",
+ "and x13, x6, x12",
+ "eor x14, x13, x4",
+ "eor x15, x7, x13",
+ "and x16, x4, x6",
+ "eor x17, x15, x16",
+ "and x17, x5, x17",
+ "eor x14, x14, x17",
+ "eor x17, x16, x10",
+ "eor x17, x17, x9",
+ "str x16, [x2, #32]",
+ "eor x16, x6, x10",
+ "eor x16, x16, x9",
+ "str x15, [x2, #40]",
+ "and x15, x4, x16",
+ "str x16, [x2, #48]",
+ "eor x16, x6, x15",
+ "str x15, [x2, #56]",
+ "and x15, x5, x16",
+ "eor x17, x17, x15",
+ "and x17, x8, x17",
+ "eor x14, x14, x17",
+ "eor x17, x12, x6",
+ "str x16, [x2, #64]",
+ "and x16, x4, x17",
+ "str x15, [x2, #72]",
+ "eor x15, x13, x16",
+ "and x15, x5, x15",
+ "and x6, x6, x7",
+ "str x11, [x2, #80]",
+ "eor x11, x12, x6",
+ "str x12, [x2, #88]",
+ "eor x12, x17, x10",
+ "eor x12, x12, x9",
+ "eor x12, x12, x16",
+ "and x12, x5, x12",
+ "eor x12, x11, x12",
+ "and x12, x8, x12",
+ "eor x15, x15, x12",
+ "and x15, x3, x15",
+ "eor x14, x14, x15",
+ "and x15, x4, x13",
+ "eor x12, x6, x15",
+ "and x7, x4, x7",
+ "str x14, [x2, #96]",
+ "ldr x14, [x2, #80]",
+ "eor x14, x14, x7",
+ "str x11, [x2, #80]",
+ "and x11, x5, x14",
+ "eor x12, x12, x11",
+ "ldr x11, [x2, #40]",
+ "str x16, [x2, #104]",
+ "ldr x16, [x2, #56]",
+ "eor x11, x11, x16",
+ "and x7, x5, x7",
+ "eor x11, x11, x7",
+ "and x11, x8, x11",
+ "eor x12, x12, x11",
+ "and x11, x5, x4",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "eor x11, x11, x15",
+ "str x15, [x2, #48]",
+ "ldr x15, [x2, #88]",
+ "str x7, [x2, #40]",
+ "and x7, x4, x15",
+ "str x6, [x2, #112]",
+ "and x6, x5, x7",
+ "eor x11, x11, x6",
+ "and x11, x8, x11",
+ "eor x14, x14, x11",
+ "and x14, x3, x14",
+ "eor x12, x12, x14",
+ "eor x17, x17, x16",
+ "ldr x14, [x2, #32]",
+ "eor x15, x15, x14",
+ "and x15, x5, x15",
+ "eor x17, x17, x15",
+ "eor x15, x13, x10",
+ "eor x15, x15, x9",
+ "ldr x14, [x2, #112]",
+ "and x11, x4, x14",
+ "eor x11, x15, x11",
+ "ldr x6, [x2, #104]",
+ "and x6, x5, x6",
+ "eor x11, x11, x6",
+ "and x11, x8, x11",
+ "eor x17, x17, x11",
+ "ldr x11, [x2, #40]",
+ "eor x11, x11, x10",
+ "eor x11, x11, x9",
+ "ldr x10, [x2, #48]",
+ "eor x13, x13, x10",
+ "eor x14, x14, x4",
+ "and x14, x5, x14",
+ "eor x13, x13, x14",
+ "and x13, x8, x13",
+ "eor x11, x11, x13",
+ "and x11, x3, x11",
+ "eor x17, x17, x11",
+ "ldr x11, [x2, #80]",
+ "eor x13, x11, x4",
+ "ldr x14, [x2, #72]",
+ "eor x13, x13, x14",
+ "ldr x14, [x2, #64]",
+ "and x10, x8, x14",
+ "eor x13, x13, x10",
+ "eor x16, x15, x16",
+ "and x16, x5, x16",
+ "eor x14, x14, x16",
+ "and x4, x4, x15",
+ "eor x15, x15, x4",
+ "eor x11, x11, x7",
+ "and x5, x5, x11",
+ "eor x15, x15, x5",
+ "and x8, x8, x15",
+ "eor x14, x14, x8",
+ "and x3, x3, x14",
+ "eor x6, x13, x3",
+ "ldr x3, [x2, #96]",
+ "add x4, x12, #0",
+ "add x5, x17, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #51",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #43",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #61",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #36",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #3",
+ "add x11, x10, #0",
+ "lsr x11, x11, #6",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #4",
+ "add x11, x10, #0",
+ "lsr x11, x11, #7",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #5",
+ "add x11, x10, #0",
+ "lsr x11, x11, #8",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #6",
+ "add x11, x10, #0",
+ "lsr x11, x11, #9",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #7",
+ "add x11, x10, #0",
+ "lsr x11, x11, #10",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #8",
+ "add x11, x10, #0",
+ "lsr x11, x11, #11",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x3",
+ "and x13, x3, x8",
+ "and x14, x5, x13",
+ "eor x15, x12, x14",
+ "eor x16, x13, x10",
+ "eor x16, x16, x9",
+ "and x17, x5, x16",
+ "str x14, [x2, #32]",
+ "eor x14, x11, x17",
+ "str x12, [x2, #40]",
+ "and x12, x6, x14",
+ "eor x15, x15, x12",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "str x8, [x2, #48]",
+ "and x8, x3, x12",
+ "str x12, [x2, #56]",
+ "and x12, x5, x8",
+ "str x8, [x2, #64]",
+ "eor x8, x11, x12",
+ "str x11, [x2, #72]",
+ "and x11, x6, x16",
+ "eor x8, x8, x11",
+ "and x8, x7, x8",
+ "eor x15, x15, x8",
+ "and x8, x6, x17",
+ "eor x14, x14, x8",
+ "and x8, x5, x3",
+ "eor x8, x13, x8",
+ "and x8, x7, x8",
+ "eor x14, x14, x8",
+ "and x14, x4, x14",
+ "eor x15, x15, x14",
+ "eor x14, x13, x5",
+ "ldr x8, [x2, #40]",
+ "str x15, [x2, #80]",
+ "eor x15, x8, x10",
+ "eor x15, x15, x9",
+ "str x11, [x2, #88]",
+ "eor x11, x15, x12",
+ "and x11, x6, x11",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "and x8, x5, x11",
+ "str x16, [x2, #96]",
+ "ldr x16, [x2, #72]",
+ "str x17, [x2, #104]",
+ "eor x17, x16, x8",
+ "eor x13, x11, x13",
+ "eor x16, x13, x12",
+ "and x16, x6, x16",
+ "eor x17, x17, x16",
+ "and x17, x7, x17",
+ "eor x14, x14, x17",
+ "ldr x17, [x2, #56]",
+ "str x12, [x2, #112]",
+ "ldr x12, [x2, #64]",
+ "str x8, [x2, #120]",
+ "eor x8, x17, x12",
+ "eor x3, x3, x10",
+ "eor x3, x3, x9",
+ "and x3, x5, x3",
+ "eor x3, x8, x3",
+ "eor x3, x3, x16",
+ "and x16, x5, x15",
+ "str x8, [x2, #128]",
+ "and x8, x6, x13",
+ "eor x16, x16, x8",
+ "and x16, x7, x16",
+ "eor x3, x3, x16",
+ "and x3, x4, x3",
+ "eor x14, x14, x3",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x17, x5, x17",
+ "eor x10, x13, x17",
+ "and x3, x6, x11",
+ "eor x10, x10, x3",
+ "ldr x16, [x2, #104]",
+ "eor x15, x15, x16",
+ "ldr x16, [x2, #96]",
+ "ldr x8, [x2, #120]",
+ "eor x16, x16, x8",
+ "and x16, x6, x16",
+ "eor x15, x15, x16",
+ "and x15, x7, x15",
+ "eor x10, x10, x15",
+ "ldr x15, [x2, #40]",
+ "and x15, x5, x15",
+ "and x15, x6, x15",
+ "ldr x16, [x2, #72]",
+ "eor x16, x16, x15",
+ "ldr x15, [x2, #112]",
+ "and x15, x7, x15",
+ "eor x16, x16, x15",
+ "and x16, x4, x16",
+ "eor x10, x10, x16",
+ "eor x12, x12, x8",
+ "ldr x16, [x2, #88]",
+ "eor x12, x12, x16",
+ "eor x17, x11, x17",
+ "ldr x16, [x2, #128]",
+ "and x5, x5, x16",
+ "eor x16, x16, x5",
+ "and x16, x6, x16",
+ "eor x17, x17, x16",
+ "and x17, x7, x17",
+ "eor x12, x12, x17",
+ "ldr x17, [x2, #32]",
+ "eor x13, x13, x17",
+ "eor x11, x11, x5",
+ "and x6, x6, x11",
+ "eor x13, x13, x6",
+ "eor x8, x8, x3",
+ "and x7, x7, x8",
+ "eor x13, x13, x7",
+ "and x4, x4, x13",
+ "eor x6, x12, x4",
+ "ldr x3, [x2, #80]",
+ "add x4, x14, #0",
+ "add x5, x10, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #39",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #54",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #44",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #31",
+ "add x11, x10, #0",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "add x11, x10, #0",
+ "lsr x11, x11, #1",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #1",
+ "add x11, x10, #0",
+ "lsr x11, x11, #2",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #2",
+ "add x11, x10, #0",
+ "lsr x11, x11, #3",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #3",
+ "add x11, x10, #0",
+ "lsr x11, x11, #4",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #4",
+ "add x11, x10, #0",
+ "lsr x11, x11, #5",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x3, x10",
+ "eor x12, x12, x9",
+ "eor x13, x8, x12",
+ "eor x6, x6, x10",
+ "eor x6, x6, x9",
+ "eor x14, x13, x6",
+ "eor x4, x4, x10",
+ "eor x4, x4, x9",
+ "eor x14, x14, x4",
+ "and x15, x6, x3",
+ "and x16, x12, x8",
+ "and x17, x6, x16",
+ "str x3, [x2, #32]",
+ "eor x3, x12, x17",
+ "and x3, x4, x3",
+ "eor x3, x15, x3",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "and x3, x7, x3",
+ "eor x14, x14, x3",
+ "eor x3, x8, x10",
+ "eor x3, x3, x9",
+ "str x13, [x2, #40]",
+ "and x13, x12, x3",
+ "str x17, [x2, #48]",
+ "eor x17, x11, x13",
+ "str x13, [x2, #56]",
+ "eor x13, x17, x15",
+ "and x13, x4, x13",
+ "eor x12, x12, x13",
+ "eor x13, x8, x16",
+ "str x17, [x2, #64]",
+ "and x17, x6, x13",
+ "eor x11, x11, x17",
+ "str x15, [x2, #72]",
+ "and x15, x4, x3",
+ "eor x11, x11, x15",
+ "and x11, x7, x11",
+ "eor x12, x12, x11",
+ "eor x5, x5, x10",
+ "eor x5, x5, x9",
+ "and x12, x5, x12",
+ "eor x14, x14, x12",
+ "eor x12, x16, x10",
+ "eor x12, x12, x9",
+ "eor x11, x12, x17",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "str x14, [x2, #80]",
+ "and x14, x6, x13",
+ "eor x3, x3, x14",
+ "and x3, x4, x3",
+ "eor x11, x11, x3",
+ "ldr x3, [x2, #48]",
+ "str x13, [x2, #88]",
+ "eor x13, x3, x10",
+ "eor x13, x13, x9",
+ "str x17, [x2, #96]",
+ "and x17, x4, x3",
+ "eor x17, x13, x17",
+ "and x17, x7, x17",
+ "eor x11, x11, x17",
+ "ldr x17, [x2, #56]",
+ "str x13, [x2, #104]",
+ "eor x13, x8, x17",
+ "str x16, [x2, #112]",
+ "ldr x16, [x2, #72]",
+ "eor x16, x13, x16",
+ "str x15, [x2, #72]",
+ "ldr x15, [x2, #40]",
+ "and x15, x4, x15",
+ "str x14, [x2, #40]",
+ "eor x14, x16, x15",
+ "eor x16, x16, x10",
+ "eor x16, x16, x9",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x13, x4, x13",
+ "eor x16, x16, x13",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "and x14, x5, x14",
+ "eor x11, x11, x14",
+ "eor x14, x17, x3",
+ "and x16, x6, x12",
+ "eor x8, x8, x16",
+ "and x16, x4, x8",
+ "eor x14, x14, x16",
+ "ldr x16, [x2, #40]",
+ "eor x16, x12, x16",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "ldr x16, [x2, #72]",
+ "eor x12, x12, x16",
+ "ldr x13, [x2, #112]",
+ "eor x3, x13, x3",
+ "eor x3, x3, x16",
+ "and x3, x7, x3",
+ "eor x12, x12, x3",
+ "and x12, x5, x12",
+ "eor x14, x14, x12",
+ "ldr x12, [x2, #104]",
+ "and x12, x4, x12",
+ "eor x8, x8, x12",
+ "and x6, x6, x17",
+ "eor x13, x13, x6",
+ "ldr x6, [x2, #32]",
+ "ldr x17, [x2, #96]",
+ "eor x6, x6, x17",
+ "and x6, x4, x6",
+ "eor x6, x13, x6",
+ "and x6, x7, x6",
+ "eor x8, x8, x6",
+ "ldr x6, [x2, #64]",
+ "eor x6, x6, x15",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "ldr x10, [x2, #88]",
+ "and x4, x4, x10",
+ "eor x13, x13, x4",
+ "and x7, x7, x13",
+ "eor x6, x6, x7",
+ "and x5, x5, x6",
+ "eor x6, x8, x5",
+ "ldr x3, [x2, #80]",
+ "add x4, x11, #0",
+ "add x5, x14, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #53",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #47",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #59",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #37",
+ "eor x19, x19, x6",
+ "add x3, x19, #0",
+ "add x19, x20, #0",
+ "add x20, x3, #0",
+ "add x22, x22, #8",
+ "sub x21, x21, #1",
+ "cbnz x21, 20b",
+ "add x3, x19, #0",
+ "add x19, x20, #0",
+ "add x20, x3, #0",
+ "add x22, x0, #248",
+ "movz x21, #16, lsl #0",
+ "21:",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #27",
+ "add x11, x10, #0",
+ "lsr x11, x11, #42",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #28",
+ "add x11, x10, #0",
+ "lsr x11, x11, #43",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #29",
+ "add x11, x10, #0",
+ "lsr x11, x11, #44",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #30",
+ "add x11, x10, #0",
+ "lsr x11, x11, #45",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #31",
+ "add x11, x10, #0",
+ "lsr x11, x11, #46",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "add x11, x10, #0",
+ "lsr x11, x11, #47",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x10",
+ "eor x11, x11, x9",
+ "and x12, x7, x11",
+ "eor x13, x3, x7",
+ "and x14, x4, x13",
+ "eor x14, x12, x14",
+ "eor x15, x11, x12",
+ "and x16, x4, x15",
+ "eor x16, x3, x16",
+ "and x16, x8, x16",
+ "eor x14, x14, x16",
+ "and x16, x7, x3",
+ "eor x17, x16, x10",
+ "eor x17, x17, x9",
+ "str x13, [x2, #32]",
+ "and x13, x4, x17",
+ "str x3, [x2, #40]",
+ "eor x3, x16, x13",
+ "str x12, [x2, #48]",
+ "eor x12, x7, x10",
+ "eor x12, x12, x9",
+ "str x10, [x2, #56]",
+ "eor x10, x12, x13",
+ "str x13, [x2, #64]",
+ "and x13, x8, x10",
+ "eor x3, x3, x13",
+ "and x3, x6, x3",
+ "eor x14, x14, x3",
+ "and x7, x4, x7",
+ "eor x3, x17, x7",
+ "and x13, x4, x12",
+ "str x7, [x2, #72]",
+ "eor x7, x11, x13",
+ "and x7, x8, x7",
+ "eor x3, x3, x7",
+ "and x7, x4, x11",
+ "str x12, [x2, #80]",
+ "eor x12, x15, x7",
+ "and x12, x8, x12",
+ "and x12, x6, x12",
+ "eor x3, x3, x12",
+ "and x3, x5, x3",
+ "eor x3, x14, x3",
+ "eor x11, x11, x16",
+ "eor x16, x11, x13",
+ "ldr x14, [x2, #48]",
+ "ldr x12, [x2, #56]",
+ "str x3, [x2, #88]",
+ "eor x3, x14, x12",
+ "eor x3, x3, x9",
+ "and x11, x4, x11",
+ "eor x11, x3, x11",
+ "str x10, [x2, #96]",
+ "and x10, x8, x11",
+ "eor x16, x16, x10",
+ "eor x10, x15, x12",
+ "eor x10, x10, x9",
+ "eor x13, x10, x13",
+ "and x12, x4, x14",
+ "eor x14, x14, x12",
+ "and x14, x8, x14",
+ "eor x12, x13, x14",
+ "and x12, x6, x12",
+ "eor x16, x16, x12",
+ "eor x11, x11, x14",
+ "ldr x14, [x2, #40]",
+ "and x12, x4, x14",
+ "eor x14, x3, x12",
+ "and x14, x8, x14",
+ "str x3, [x2, #48]",
+ "eor x3, x15, x14",
+ "and x3, x6, x3",
+ "eor x11, x11, x3",
+ "and x11, x5, x11",
+ "eor x16, x16, x11",
+ "eor x11, x15, x12",
+ "and x3, x8, x13",
+ "eor x11, x11, x3",
+ "eor x17, x17, x7",
+ "and x10, x4, x10",
+ "ldr x7, [x2, #48]",
+ "eor x7, x7, x10",
+ "and x7, x8, x7",
+ "eor x17, x17, x7",
+ "and x17, x6, x17",
+ "eor x11, x11, x17",
+ "ldr x17, [x2, #64]",
+ "and x7, x8, x17",
+ "eor x13, x13, x7",
+ "ldr x7, [x2, #40]",
+ "eor x7, x7, x12",
+ "eor x7, x7, x14",
+ "and x7, x6, x7",
+ "eor x13, x13, x7",
+ "and x13, x5, x13",
+ "eor x11, x11, x13",
+ "ldr x13, [x2, #32]",
+ "ldr x7, [x2, #56]",
+ "eor x13, x13, x7",
+ "eor x13, x13, x9",
+ "eor x13, x13, x4",
+ "eor x17, x17, x7",
+ "eor x17, x17, x9",
+ "and x17, x8, x17",
+ "eor x17, x13, x17",
+ "ldr x14, [x2, #96]",
+ "eor x14, x14, x7",
+ "eor x14, x14, x9",
+ "and x14, x8, x14",
+ "ldr x7, [x2, #80]",
+ "eor x7, x7, x14",
+ "and x7, x6, x7",
+ "eor x17, x17, x7",
+ "ldr x7, [x2, #72]",
+ "eor x7, x15, x7",
+ "and x7, x8, x7",
+ "eor x12, x12, x7",
+ "eor x15, x15, x4",
+ "and x8, x8, x15",
+ "eor x13, x13, x8",
+ "and x6, x6, x13",
+ "eor x12, x12, x6",
+ "and x5, x5, x12",
+ "eor x6, x17, x5",
+ "ldr x3, [x2, #88]",
+ "add x4, x16, #0",
+ "add x5, x11, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #63",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #55",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #49",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #41",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #23",
+ "add x11, x10, #0",
+ "lsr x11, x11, #36",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #24",
+ "add x11, x10, #0",
+ "lsr x11, x11, #37",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #25",
+ "add x11, x10, #0",
+ "lsr x11, x11, #38",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #26",
+ "add x11, x10, #0",
+ "lsr x11, x11, #39",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #27",
+ "add x11, x10, #0",
+ "lsr x11, x11, #40",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #28",
+ "add x11, x10, #0",
+ "lsr x11, x11, #41",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "and x13, x4, x8",
+ "eor x14, x8, x13",
+ "and x15, x3, x14",
+ "eor x15, x12, x15",
+ "eor x16, x13, x10",
+ "eor x16, x16, x9",
+ "and x17, x3, x16",
+ "str x16, [x2, #32]",
+ "eor x16, x14, x17",
+ "and x16, x7, x16",
+ "eor x15, x15, x16",
+ "str x17, [x2, #40]",
+ "and x17, x4, x12",
+ "str x16, [x2, #48]",
+ "eor x16, x12, x17",
+ "eor x14, x14, x10",
+ "eor x14, x14, x9",
+ "str x12, [x2, #56]",
+ "and x12, x3, x14",
+ "str x14, [x2, #64]",
+ "eor x14, x16, x12",
+ "str x12, [x2, #72]",
+ "eor x12, x16, x10",
+ "eor x12, x12, x9",
+ "str x16, [x2, #80]",
+ "and x16, x3, x12",
+ "eor x16, x4, x16",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x17",
+ "eor x14, x11, x14",
+ "eor x16, x8, x4",
+ "str x17, [x2, #88]",
+ "and x17, x3, x16",
+ "str x11, [x2, #96]",
+ "eor x11, x4, x17",
+ "and x11, x7, x11",
+ "eor x14, x14, x11",
+ "and x14, x5, x14",
+ "eor x15, x15, x14",
+ "eor x16, x16, x10",
+ "eor x16, x16, x9",
+ "and x13, x3, x13",
+ "eor x14, x16, x13",
+ "ldr x11, [x2, #64]",
+ "eor x11, x11, x17",
+ "and x11, x7, x11",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "eor x12, x12, x11",
+ "and x12, x6, x12",
+ "eor x14, x14, x12",
+ "ldr x12, [x2, #80]",
+ "and x11, x3, x12",
+ "eor x11, x8, x11",
+ "and x11, x7, x11",
+ "ldr x17, [x2, #32]",
+ "eor x11, x17, x11",
+ "str x15, [x2, #48]",
+ "ldr x15, [x2, #56]",
+ "str x10, [x2, #64]",
+ "and x10, x3, x15",
+ "eor x12, x12, x10",
+ "and x8, x7, x8",
+ "eor x12, x12, x8",
+ "and x12, x6, x12",
+ "eor x11, x11, x12",
+ "and x11, x5, x11",
+ "eor x14, x14, x11",
+ "eor x11, x16, x3",
+ "eor x11, x11, x7",
+ "eor x12, x17, x13",
+ "and x12, x7, x12",
+ "eor x12, x3, x12",
+ "and x12, x6, x12",
+ "eor x11, x11, x12",
+ "and x3, x3, x4",
+ "ldr x4, [x2, #96]",
+ "eor x4, x4, x3",
+ "ldr x12, [x2, #40]",
+ "eor x17, x17, x12",
+ "and x17, x7, x17",
+ "eor x4, x4, x17",
+ "and x3, x6, x3",
+ "eor x4, x4, x3",
+ "and x4, x5, x4",
+ "eor x11, x11, x4",
+ "eor x16, x16, x12",
+ "ldr x12, [x2, #72]",
+ "and x12, x7, x12",
+ "eor x16, x16, x12",
+ "ldr x12, [x2, #64]",
+ "eor x4, x13, x12",
+ "eor x4, x4, x9",
+ "eor x15, x15, x10",
+ "and x15, x7, x15",
+ "eor x4, x4, x15",
+ "and x6, x6, x4",
+ "eor x16, x16, x6",
+ "ldr x6, [x2, #88]",
+ "eor x6, x6, x13",
+ "eor x12, x6, x12",
+ "eor x12, x12, x9",
+ "and x7, x7, x12",
+ "eor x6, x6, x7",
+ "and x5, x5, x6",
+ "eor x6, x16, x5",
+ "ldr x3, [x2, #48]",
+ "add x4, x14, #0",
+ "add x5, x11, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #50",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #34",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #60",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #45",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #19",
+ "add x11, x10, #0",
+ "lsr x11, x11, #30",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #20",
+ "add x11, x10, #0",
+ "lsr x11, x11, #31",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #21",
+ "add x11, x10, #0",
+ "lsr x11, x11, #32",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #22",
+ "add x11, x10, #0",
+ "lsr x11, x11, #33",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #23",
+ "add x11, x10, #0",
+ "lsr x11, x11, #34",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #24",
+ "add x11, x10, #0",
+ "lsr x11, x11, #35",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "and x13, x7, x12",
+ "eor x14, x8, x13",
+ "and x15, x7, x8",
+ "eor x16, x12, x15",
+ "and x17, x3, x16",
+ "str x13, [x2, #32]",
+ "eor x13, x14, x17",
+ "str x14, [x2, #40]",
+ "eor x14, x16, x10",
+ "eor x14, x14, x9",
+ "and x15, x3, x15",
+ "str x10, [x2, #48]",
+ "eor x10, x14, x15",
+ "str x14, [x2, #56]",
+ "and x14, x4, x10",
+ "eor x14, x13, x14",
+ "str x13, [x2, #64]",
+ "and x13, x4, x16",
+ "eor x10, x10, x13",
+ "and x10, x6, x10",
+ "eor x14, x14, x10",
+ "and x8, x3, x8",
+ "eor x11, x11, x8",
+ "and x10, x4, x12",
+ "eor x11, x11, x10",
+ "and x15, x6, x15",
+ "eor x11, x11, x15",
+ "and x11, x5, x11",
+ "eor x14, x14, x11",
+ "eor x11, x12, x7",
+ "eor x17, x11, x17",
+ "ldr x15, [x2, #32]",
+ "ldr x10, [x2, #48]",
+ "eor x13, x15, x10",
+ "eor x13, x13, x9",
+ "str x14, [x2, #72]",
+ "and x14, x3, x15",
+ "eor x14, x13, x14",
+ "str x16, [x2, #80]",
+ "and x16, x4, x14",
+ "str x11, [x2, #88]",
+ "eor x11, x17, x16",
+ "str x8, [x2, #96]",
+ "eor x8, x7, x10",
+ "eor x8, x8, x9",
+ "and x15, x3, x8",
+ "eor x7, x7, x15",
+ "str x8, [x2, #104]",
+ "and x8, x3, x12",
+ "eor x12, x12, x8",
+ "and x12, x4, x12",
+ "eor x7, x7, x12",
+ "and x7, x6, x7",
+ "eor x11, x11, x7",
+ "ldr x7, [x2, #64]",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x17, x4, x17",
+ "eor x7, x7, x17",
+ "ldr x17, [x2, #40]",
+ "eor x12, x17, x10",
+ "eor x12, x12, x9",
+ "and x17, x3, x12",
+ "str x12, [x2, #64]",
+ "eor x12, x13, x17",
+ "str x17, [x2, #112]",
+ "eor x17, x8, x10",
+ "eor x17, x17, x9",
+ "and x17, x4, x17",
+ "eor x12, x12, x17",
+ "and x12, x6, x12",
+ "eor x7, x7, x12",
+ "and x7, x5, x7",
+ "eor x11, x11, x7",
+ "and x7, x3, x13",
+ "ldr x12, [x2, #56]",
+ "eor x12, x12, x7",
+ "eor x7, x14, x10",
+ "eor x7, x7, x9",
+ "and x7, x4, x7",
+ "eor x12, x12, x7",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x12, x12, x14",
+ "ldr x14, [x2, #32]",
+ "eor x15, x14, x15",
+ "eor x15, x15, x17",
+ "ldr x17, [x2, #96]",
+ "and x16, x4, x17",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x15, x15, x14",
+ "and x15, x5, x15",
+ "eor x12, x12, x15",
+ "eor x13, x13, x17",
+ "eor x13, x13, x4",
+ "ldr x17, [x2, #88]",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x3, x3, x17",
+ "ldr x17, [x2, #104]",
+ "eor x17, x17, x3",
+ "and x17, x4, x17",
+ "ldr x3, [x2, #80]",
+ "eor x3, x3, x17",
+ "and x3, x6, x3",
+ "eor x13, x13, x3",
+ "ldr x3, [x2, #40]",
+ "eor x3, x3, x8",
+ "ldr x17, [x2, #64]",
+ "ldr x10, [x2, #112]",
+ "eor x10, x17, x10",
+ "and x10, x4, x10",
+ "eor x3, x3, x10",
+ "and x4, x4, x8",
+ "eor x17, x17, x4",
+ "and x6, x6, x17",
+ "eor x3, x3, x6",
+ "and x5, x5, x3",
+ "eor x6, x13, x5",
+ "ldr x3, [x2, #72]",
+ "add x4, x11, #0",
+ "add x5, x12, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #38",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #62",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #48",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #56",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #15",
+ "add x11, x10, #0",
+ "lsr x11, x11, #24",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #16",
+ "add x11, x10, #0",
+ "lsr x11, x11, #25",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #17",
+ "add x11, x10, #0",
+ "lsr x11, x11, #26",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #18",
+ "add x11, x10, #0",
+ "lsr x11, x11, #27",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #19",
+ "add x11, x10, #0",
+ "lsr x11, x11, #28",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #20",
+ "add x11, x10, #0",
+ "lsr x11, x11, #29",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x6, x10",
+ "eor x12, x12, x9",
+ "and x13, x4, x6",
+ "eor x14, x12, x13",
+ "and x15, x8, x14",
+ "eor x16, x12, x15",
+ "eor x17, x6, x4",
+ "str x15, [x2, #32]",
+ "eor x15, x17, x10",
+ "eor x15, x15, x9",
+ "str x6, [x2, #40]",
+ "and x6, x8, x15",
+ "str x3, [x2, #48]",
+ "eor x3, x17, x6",
+ "and x3, x7, x3",
+ "eor x16, x16, x3",
+ "eor x3, x4, x10",
+ "eor x3, x3, x9",
+ "str x17, [x2, #56]",
+ "eor x17, x4, x6",
+ "str x6, [x2, #64]",
+ "and x6, x7, x17",
+ "str x11, [x2, #72]",
+ "eor x11, x3, x6",
+ "and x11, x5, x11",
+ "eor x16, x16, x11",
+ "eor x11, x14, x10",
+ "eor x11, x11, x9",
+ "and x11, x8, x11",
+ "eor x11, x15, x11",
+ "and x11, x7, x11",
+ "eor x17, x17, x11",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x11, x4, x12",
+ "str x6, [x2, #80]",
+ "ldr x6, [x2, #72]",
+ "eor x6, x6, x11",
+ "str x3, [x2, #72]",
+ "and x3, x8, x6",
+ "eor x13, x13, x3",
+ "str x6, [x2, #88]",
+ "ldr x6, [x2, #56]",
+ "and x6, x7, x6",
+ "eor x13, x13, x6",
+ "and x13, x5, x13",
+ "eor x17, x17, x13",
+ "ldr x13, [x2, #48]",
+ "str x6, [x2, #56]",
+ "and x6, x13, x17",
+ "eor x16, x16, x6",
+ "and x6, x8, x11",
+ "eor x15, x15, x6",
+ "str x16, [x2, #96]",
+ "eor x16, x3, x10",
+ "eor x16, x16, x9",
+ "and x16, x7, x16",
+ "eor x16, x15, x16",
+ "str x8, [x2, #104]",
+ "eor x8, x11, x3",
+ "str x11, [x2, #112]",
+ "ldr x11, [x2, #40]",
+ "str x6, [x2, #120]",
+ "ldr x6, [x2, #64]",
+ "eor x6, x11, x6",
+ "and x6, x7, x6",
+ "eor x8, x8, x6",
+ "and x8, x5, x8",
+ "eor x16, x16, x8",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x17, x13, x17",
+ "eor x16, x16, x17",
+ "eor x14, x14, x3",
+ "and x12, x7, x12",
+ "eor x14, x14, x12",
+ "eor x4, x4, x6",
+ "and x4, x5, x4",
+ "eor x14, x14, x4",
+ "eor x15, x15, x10",
+ "eor x15, x15, x9",
+ "ldr x4, [x2, #88]",
+ "ldr x6, [x2, #120]",
+ "eor x4, x4, x6",
+ "and x4, x7, x4",
+ "eor x15, x15, x4",
+ "ldr x4, [x2, #72]",
+ "ldr x12, [x2, #32]",
+ "eor x4, x4, x12",
+ "ldr x3, [x2, #56]",
+ "eor x4, x4, x3",
+ "and x4, x5, x4",
+ "eor x15, x15, x4",
+ "and x4, x13, x15",
+ "eor x14, x14, x4",
+ "ldr x4, [x2, #112]",
+ "ldr x3, [x2, #104]",
+ "eor x3, x4, x3",
+ "eor x11, x11, x4",
+ "eor x11, x11, x6",
+ "and x7, x7, x11",
+ "eor x3, x3, x7",
+ "eor x12, x12, x10",
+ "eor x12, x12, x9",
+ "ldr x7, [x2, #80]",
+ "eor x12, x12, x7",
+ "and x5, x5, x12",
+ "eor x3, x3, x5",
+ "eor x15, x15, x10",
+ "eor x15, x15, x9",
+ "and x13, x13, x15",
+ "eor x6, x3, x13",
+ "ldr x3, [x2, #96]",
+ "add x4, x16, #0",
+ "add x5, x14, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #33",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #42",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #52",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #58",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #11",
+ "add x11, x10, #0",
+ "lsr x11, x11, #18",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #12",
+ "add x11, x10, #0",
+ "lsr x11, x11, #19",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #13",
+ "add x11, x10, #0",
+ "lsr x11, x11, #20",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #14",
+ "add x11, x10, #0",
+ "lsr x11, x11, #21",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #15",
+ "add x11, x10, #0",
+ "lsr x11, x11, #22",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #16",
+ "add x11, x10, #0",
+ "lsr x11, x11, #23",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x6, x10",
+ "eor x12, x12, x9",
+ "and x13, x12, x8",
+ "eor x14, x11, x13",
+ "eor x3, x3, x10",
+ "eor x3, x3, x9",
+ "and x15, x3, x14",
+ "eor x16, x8, x15",
+ "eor x17, x8, x10",
+ "eor x17, x17, x9",
+ "str x15, [x2, #32]",
+ "and x15, x12, x17",
+ "str x11, [x2, #40]",
+ "eor x11, x17, x15",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "str x15, [x2, #48]",
+ "and x15, x7, x11",
+ "eor x15, x16, x15",
+ "str x16, [x2, #56]",
+ "eor x16, x17, x13",
+ "str x14, [x2, #64]",
+ "and x14, x7, x16",
+ "eor x14, x6, x14",
+ "eor x5, x5, x10",
+ "eor x5, x5, x9",
+ "and x14, x5, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x17",
+ "eor x14, x12, x14",
+ "str x6, [x2, #72]",
+ "eor x6, x8, x12",
+ "and x13, x3, x13",
+ "eor x13, x6, x13",
+ "and x13, x7, x13",
+ "eor x14, x14, x13",
+ "eor x13, x11, x10",
+ "eor x13, x13, x9",
+ "and x13, x3, x13",
+ "str x12, [x2, #80]",
+ "eor x12, x17, x3",
+ "and x12, x7, x12",
+ "eor x13, x13, x12",
+ "and x13, x5, x13",
+ "eor x14, x14, x13",
+ "eor x4, x4, x10",
+ "eor x4, x4, x9",
+ "and x14, x4, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x11",
+ "ldr x13, [x2, #64]",
+ "eor x12, x13, x14",
+ "eor x12, x12, x7",
+ "str x15, [x2, #88]",
+ "ldr x15, [x2, #48]",
+ "eor x13, x15, x10",
+ "eor x13, x13, x9",
+ "str x10, [x2, #96]",
+ "and x10, x3, x13",
+ "str x6, [x2, #104]",
+ "ldr x6, [x2, #40]",
+ "eor x6, x6, x10",
+ "and x15, x3, x15",
+ "str x13, [x2, #48]",
+ "and x13, x7, x15",
+ "eor x6, x6, x13",
+ "and x6, x5, x6",
+ "eor x12, x12, x6",
+ "eor x15, x16, x15",
+ "and x15, x7, x15",
+ "ldr x6, [x2, #72]",
+ "eor x15, x6, x15",
+ "and x8, x3, x8",
+ "eor x17, x17, x8",
+ "and x13, x7, x17",
+ "eor x13, x10, x13",
+ "and x13, x5, x13",
+ "eor x15, x15, x13",
+ "and x15, x4, x15",
+ "eor x12, x12, x15",
+ "eor x15, x11, x3",
+ "eor x15, x15, x7",
+ "ldr x13, [x2, #48]",
+ "eor x13, x13, x14",
+ "ldr x14, [x2, #104]",
+ "str x12, [x2, #48]",
+ "eor x12, x14, x10",
+ "and x12, x7, x12",
+ "eor x13, x13, x12",
+ "and x13, x5, x13",
+ "eor x15, x15, x13",
+ "ldr x13, [x2, #96]",
+ "eor x12, x14, x13",
+ "eor x12, x12, x9",
+ "str x8, [x2, #40]",
+ "and x8, x3, x12",
+ "eor x11, x11, x8",
+ "and x11, x5, x11",
+ "str x8, [x2, #112]",
+ "ldr x8, [x2, #64]",
+ "eor x8, x8, x11",
+ "and x8, x4, x8",
+ "eor x15, x15, x8",
+ "ldr x8, [x2, #80]",
+ "eor x8, x8, x10",
+ "ldr x10, [x2, #56]",
+ "and x10, x7, x10",
+ "eor x8, x8, x10",
+ "eor x10, x16, x3",
+ "and x10, x7, x10",
+ "eor x17, x17, x10",
+ "and x17, x5, x17",
+ "eor x8, x8, x17",
+ "ldr x17, [x2, #32]",
+ "eor x12, x12, x17",
+ "and x3, x3, x6",
+ "eor x14, x14, x3",
+ "and x14, x7, x14",
+ "eor x12, x12, x14",
+ "eor x16, x16, x13",
+ "eor x16, x16, x9",
+ "ldr x14, [x2, #112]",
+ "eor x16, x16, x14",
+ "ldr x14, [x2, #40]",
+ "eor x14, x14, x13",
+ "eor x14, x14, x9",
+ "and x7, x7, x14",
+ "eor x16, x16, x7",
+ "and x5, x5, x16",
+ "eor x12, x12, x5",
+ "and x4, x4, x12",
+ "eor x6, x8, x4",
+ "ldr x3, [x2, #88]",
+ "ldr x4, [x2, #48]",
+ "add x5, x15, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #35",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #57",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #46",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #40",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #7",
+ "add x11, x10, #0",
+ "lsr x11, x11, #12",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #8",
+ "add x11, x10, #0",
+ "lsr x11, x11, #13",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #9",
+ "add x11, x10, #0",
+ "lsr x11, x11, #14",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #10",
+ "add x11, x10, #0",
+ "lsr x11, x11, #15",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #11",
+ "add x11, x10, #0",
+ "lsr x11, x11, #16",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #12",
+ "add x11, x10, #0",
+ "lsr x11, x11, #17",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x7, x10",
+ "eor x12, x12, x9",
+ "and x13, x6, x12",
+ "eor x14, x13, x4",
+ "eor x15, x7, x13",
+ "and x16, x4, x6",
+ "eor x17, x15, x16",
+ "and x17, x5, x17",
+ "eor x14, x14, x17",
+ "eor x17, x16, x10",
+ "eor x17, x17, x9",
+ "str x16, [x2, #32]",
+ "eor x16, x6, x10",
+ "eor x16, x16, x9",
+ "str x15, [x2, #40]",
+ "and x15, x4, x16",
+ "str x16, [x2, #48]",
+ "eor x16, x6, x15",
+ "str x15, [x2, #56]",
+ "and x15, x5, x16",
+ "eor x17, x17, x15",
+ "and x17, x8, x17",
+ "eor x14, x14, x17",
+ "eor x17, x12, x6",
+ "str x16, [x2, #64]",
+ "and x16, x4, x17",
+ "str x15, [x2, #72]",
+ "eor x15, x13, x16",
+ "and x15, x5, x15",
+ "and x6, x6, x7",
+ "str x11, [x2, #80]",
+ "eor x11, x12, x6",
+ "str x12, [x2, #88]",
+ "eor x12, x17, x10",
+ "eor x12, x12, x9",
+ "eor x12, x12, x16",
+ "and x12, x5, x12",
+ "eor x12, x11, x12",
+ "and x12, x8, x12",
+ "eor x15, x15, x12",
+ "and x15, x3, x15",
+ "eor x14, x14, x15",
+ "and x15, x4, x13",
+ "eor x12, x6, x15",
+ "and x7, x4, x7",
+ "str x14, [x2, #96]",
+ "ldr x14, [x2, #80]",
+ "eor x14, x14, x7",
+ "str x11, [x2, #80]",
+ "and x11, x5, x14",
+ "eor x12, x12, x11",
+ "ldr x11, [x2, #40]",
+ "str x16, [x2, #104]",
+ "ldr x16, [x2, #56]",
+ "eor x11, x11, x16",
+ "and x7, x5, x7",
+ "eor x11, x11, x7",
+ "and x11, x8, x11",
+ "eor x12, x12, x11",
+ "and x11, x5, x4",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "eor x11, x11, x15",
+ "str x15, [x2, #48]",
+ "ldr x15, [x2, #88]",
+ "str x7, [x2, #40]",
+ "and x7, x4, x15",
+ "str x6, [x2, #112]",
+ "and x6, x5, x7",
+ "eor x11, x11, x6",
+ "and x11, x8, x11",
+ "eor x14, x14, x11",
+ "and x14, x3, x14",
+ "eor x12, x12, x14",
+ "eor x17, x17, x16",
+ "ldr x14, [x2, #32]",
+ "eor x15, x15, x14",
+ "and x15, x5, x15",
+ "eor x17, x17, x15",
+ "eor x15, x13, x10",
+ "eor x15, x15, x9",
+ "ldr x14, [x2, #112]",
+ "and x11, x4, x14",
+ "eor x11, x15, x11",
+ "ldr x6, [x2, #104]",
+ "and x6, x5, x6",
+ "eor x11, x11, x6",
+ "and x11, x8, x11",
+ "eor x17, x17, x11",
+ "ldr x11, [x2, #40]",
+ "eor x11, x11, x10",
+ "eor x11, x11, x9",
+ "ldr x10, [x2, #48]",
+ "eor x13, x13, x10",
+ "eor x14, x14, x4",
+ "and x14, x5, x14",
+ "eor x13, x13, x14",
+ "and x13, x8, x13",
+ "eor x11, x11, x13",
+ "and x11, x3, x11",
+ "eor x17, x17, x11",
+ "ldr x11, [x2, #80]",
+ "eor x13, x11, x4",
+ "ldr x14, [x2, #72]",
+ "eor x13, x13, x14",
+ "ldr x14, [x2, #64]",
+ "and x10, x8, x14",
+ "eor x13, x13, x10",
+ "eor x16, x15, x16",
+ "and x16, x5, x16",
+ "eor x14, x14, x16",
+ "and x4, x4, x15",
+ "eor x15, x15, x4",
+ "eor x11, x11, x7",
+ "and x5, x5, x11",
+ "eor x15, x15, x5",
+ "and x8, x8, x15",
+ "eor x14, x14, x8",
+ "and x3, x3, x14",
+ "eor x6, x13, x3",
+ "ldr x3, [x2, #96]",
+ "add x4, x12, #0",
+ "add x5, x17, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #51",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #43",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #61",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #36",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #3",
+ "add x11, x10, #0",
+ "lsr x11, x11, #6",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #4",
+ "add x11, x10, #0",
+ "lsr x11, x11, #7",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #5",
+ "add x11, x10, #0",
+ "lsr x11, x11, #8",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #6",
+ "add x11, x10, #0",
+ "lsr x11, x11, #9",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #7",
+ "add x11, x10, #0",
+ "lsr x11, x11, #10",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #8",
+ "add x11, x10, #0",
+ "lsr x11, x11, #11",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x3",
+ "and x13, x3, x8",
+ "and x14, x5, x13",
+ "eor x15, x12, x14",
+ "eor x16, x13, x10",
+ "eor x16, x16, x9",
+ "and x17, x5, x16",
+ "str x14, [x2, #32]",
+ "eor x14, x11, x17",
+ "str x12, [x2, #40]",
+ "and x12, x6, x14",
+ "eor x15, x15, x12",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "str x8, [x2, #48]",
+ "and x8, x3, x12",
+ "str x12, [x2, #56]",
+ "and x12, x5, x8",
+ "str x8, [x2, #64]",
+ "eor x8, x11, x12",
+ "str x11, [x2, #72]",
+ "and x11, x6, x16",
+ "eor x8, x8, x11",
+ "and x8, x7, x8",
+ "eor x15, x15, x8",
+ "and x8, x6, x17",
+ "eor x14, x14, x8",
+ "and x8, x5, x3",
+ "eor x8, x13, x8",
+ "and x8, x7, x8",
+ "eor x14, x14, x8",
+ "and x14, x4, x14",
+ "eor x15, x15, x14",
+ "eor x14, x13, x5",
+ "ldr x8, [x2, #40]",
+ "str x15, [x2, #80]",
+ "eor x15, x8, x10",
+ "eor x15, x15, x9",
+ "str x11, [x2, #88]",
+ "eor x11, x15, x12",
+ "and x11, x6, x11",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "and x8, x5, x11",
+ "str x16, [x2, #96]",
+ "ldr x16, [x2, #72]",
+ "str x17, [x2, #104]",
+ "eor x17, x16, x8",
+ "eor x13, x11, x13",
+ "eor x16, x13, x12",
+ "and x16, x6, x16",
+ "eor x17, x17, x16",
+ "and x17, x7, x17",
+ "eor x14, x14, x17",
+ "ldr x17, [x2, #56]",
+ "str x12, [x2, #112]",
+ "ldr x12, [x2, #64]",
+ "str x8, [x2, #120]",
+ "eor x8, x17, x12",
+ "eor x3, x3, x10",
+ "eor x3, x3, x9",
+ "and x3, x5, x3",
+ "eor x3, x8, x3",
+ "eor x3, x3, x16",
+ "and x16, x5, x15",
+ "str x8, [x2, #128]",
+ "and x8, x6, x13",
+ "eor x16, x16, x8",
+ "and x16, x7, x16",
+ "eor x3, x3, x16",
+ "and x3, x4, x3",
+ "eor x14, x14, x3",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x17, x5, x17",
+ "eor x10, x13, x17",
+ "and x3, x6, x11",
+ "eor x10, x10, x3",
+ "ldr x16, [x2, #104]",
+ "eor x15, x15, x16",
+ "ldr x16, [x2, #96]",
+ "ldr x8, [x2, #120]",
+ "eor x16, x16, x8",
+ "and x16, x6, x16",
+ "eor x15, x15, x16",
+ "and x15, x7, x15",
+ "eor x10, x10, x15",
+ "ldr x15, [x2, #40]",
+ "and x15, x5, x15",
+ "and x15, x6, x15",
+ "ldr x16, [x2, #72]",
+ "eor x16, x16, x15",
+ "ldr x15, [x2, #112]",
+ "and x15, x7, x15",
+ "eor x16, x16, x15",
+ "and x16, x4, x16",
+ "eor x10, x10, x16",
+ "eor x12, x12, x8",
+ "ldr x16, [x2, #88]",
+ "eor x12, x12, x16",
+ "eor x17, x11, x17",
+ "ldr x16, [x2, #128]",
+ "and x5, x5, x16",
+ "eor x16, x16, x5",
+ "and x16, x6, x16",
+ "eor x17, x17, x16",
+ "and x17, x7, x17",
+ "eor x12, x12, x17",
+ "ldr x17, [x2, #32]",
+ "eor x13, x13, x17",
+ "eor x11, x11, x5",
+ "and x6, x6, x11",
+ "eor x13, x13, x6",
+ "eor x8, x8, x3",
+ "and x7, x7, x8",
+ "eor x13, x13, x7",
+ "and x4, x4, x13",
+ "eor x6, x12, x4",
+ "ldr x3, [x2, #80]",
+ "add x4, x14, #0",
+ "add x5, x10, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #39",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #54",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #44",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #31",
+ "add x11, x10, #0",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "add x11, x10, #0",
+ "lsr x11, x11, #1",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #1",
+ "add x11, x10, #0",
+ "lsr x11, x11, #2",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #2",
+ "add x11, x10, #0",
+ "lsr x11, x11, #3",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #3",
+ "add x11, x10, #0",
+ "lsr x11, x11, #4",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #4",
+ "add x11, x10, #0",
+ "lsr x11, x11, #5",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x3, x10",
+ "eor x12, x12, x9",
+ "eor x13, x8, x12",
+ "eor x6, x6, x10",
+ "eor x6, x6, x9",
+ "eor x14, x13, x6",
+ "eor x4, x4, x10",
+ "eor x4, x4, x9",
+ "eor x14, x14, x4",
+ "and x15, x6, x3",
+ "and x16, x12, x8",
+ "and x17, x6, x16",
+ "str x3, [x2, #32]",
+ "eor x3, x12, x17",
+ "and x3, x4, x3",
+ "eor x3, x15, x3",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "and x3, x7, x3",
+ "eor x14, x14, x3",
+ "eor x3, x8, x10",
+ "eor x3, x3, x9",
+ "str x13, [x2, #40]",
+ "and x13, x12, x3",
+ "str x17, [x2, #48]",
+ "eor x17, x11, x13",
+ "str x13, [x2, #56]",
+ "eor x13, x17, x15",
+ "and x13, x4, x13",
+ "eor x12, x12, x13",
+ "eor x13, x8, x16",
+ "str x17, [x2, #64]",
+ "and x17, x6, x13",
+ "eor x11, x11, x17",
+ "str x15, [x2, #72]",
+ "and x15, x4, x3",
+ "eor x11, x11, x15",
+ "and x11, x7, x11",
+ "eor x12, x12, x11",
+ "eor x5, x5, x10",
+ "eor x5, x5, x9",
+ "and x12, x5, x12",
+ "eor x14, x14, x12",
+ "eor x12, x16, x10",
+ "eor x12, x12, x9",
+ "eor x11, x12, x17",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "str x14, [x2, #80]",
+ "and x14, x6, x13",
+ "eor x3, x3, x14",
+ "and x3, x4, x3",
+ "eor x11, x11, x3",
+ "ldr x3, [x2, #48]",
+ "str x13, [x2, #88]",
+ "eor x13, x3, x10",
+ "eor x13, x13, x9",
+ "str x17, [x2, #96]",
+ "and x17, x4, x3",
+ "eor x17, x13, x17",
+ "and x17, x7, x17",
+ "eor x11, x11, x17",
+ "ldr x17, [x2, #56]",
+ "str x13, [x2, #104]",
+ "eor x13, x8, x17",
+ "str x16, [x2, #112]",
+ "ldr x16, [x2, #72]",
+ "eor x16, x13, x16",
+ "str x15, [x2, #72]",
+ "ldr x15, [x2, #40]",
+ "and x15, x4, x15",
+ "str x14, [x2, #40]",
+ "eor x14, x16, x15",
+ "eor x16, x16, x10",
+ "eor x16, x16, x9",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x13, x4, x13",
+ "eor x16, x16, x13",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "and x14, x5, x14",
+ "eor x11, x11, x14",
+ "eor x14, x17, x3",
+ "and x16, x6, x12",
+ "eor x8, x8, x16",
+ "and x16, x4, x8",
+ "eor x14, x14, x16",
+ "ldr x16, [x2, #40]",
+ "eor x16, x12, x16",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "ldr x16, [x2, #72]",
+ "eor x12, x12, x16",
+ "ldr x13, [x2, #112]",
+ "eor x3, x13, x3",
+ "eor x3, x3, x16",
+ "and x3, x7, x3",
+ "eor x12, x12, x3",
+ "and x12, x5, x12",
+ "eor x14, x14, x12",
+ "ldr x12, [x2, #104]",
+ "and x12, x4, x12",
+ "eor x8, x8, x12",
+ "and x6, x6, x17",
+ "eor x13, x13, x6",
+ "ldr x6, [x2, #32]",
+ "ldr x17, [x2, #96]",
+ "eor x6, x6, x17",
+ "and x6, x4, x6",
+ "eor x6, x13, x6",
+ "and x6, x7, x6",
+ "eor x8, x8, x6",
+ "ldr x6, [x2, #64]",
+ "eor x6, x6, x15",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "ldr x10, [x2, #88]",
+ "and x4, x4, x10",
+ "eor x13, x13, x4",
+ "and x7, x7, x13",
+ "eor x6, x6, x7",
+ "and x5, x5, x6",
+ "eor x6, x8, x5",
+ "ldr x3, [x2, #80]",
+ "add x4, x11, #0",
+ "add x5, x14, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #53",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #47",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #59",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #37",
+ "eor x19, x19, x6",
+ "add x3, x19, #0",
+ "add x19, x20, #0",
+ "add x20, x3, #0",
+ "sub x22, x22, #8",
+ "sub x21, x21, #1",
+ "cbnz x21, 21b",
+ "add x3, x19, #0",
+ "add x19, x20, #0",
+ "add x20, x3, #0",
+ "add x22, x0, #256",
+ "movz x21, #16, lsl #0",
+ "22:",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #27",
+ "add x11, x10, #0",
+ "lsr x11, x11, #42",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #28",
+ "add x11, x10, #0",
+ "lsr x11, x11, #43",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #29",
+ "add x11, x10, #0",
+ "lsr x11, x11, #44",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #30",
+ "add x11, x10, #0",
+ "lsr x11, x11, #45",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #31",
+ "add x11, x10, #0",
+ "lsr x11, x11, #46",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "add x11, x10, #0",
+ "lsr x11, x11, #47",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x10",
+ "eor x11, x11, x9",
+ "and x12, x7, x11",
+ "eor x13, x3, x7",
+ "and x14, x4, x13",
+ "eor x14, x12, x14",
+ "eor x15, x11, x12",
+ "and x16, x4, x15",
+ "eor x16, x3, x16",
+ "and x16, x8, x16",
+ "eor x14, x14, x16",
+ "and x16, x7, x3",
+ "eor x17, x16, x10",
+ "eor x17, x17, x9",
+ "str x13, [x2, #32]",
+ "and x13, x4, x17",
+ "str x3, [x2, #40]",
+ "eor x3, x16, x13",
+ "str x12, [x2, #48]",
+ "eor x12, x7, x10",
+ "eor x12, x12, x9",
+ "str x10, [x2, #56]",
+ "eor x10, x12, x13",
+ "str x13, [x2, #64]",
+ "and x13, x8, x10",
+ "eor x3, x3, x13",
+ "and x3, x6, x3",
+ "eor x14, x14, x3",
+ "and x7, x4, x7",
+ "eor x3, x17, x7",
+ "and x13, x4, x12",
+ "str x7, [x2, #72]",
+ "eor x7, x11, x13",
+ "and x7, x8, x7",
+ "eor x3, x3, x7",
+ "and x7, x4, x11",
+ "str x12, [x2, #80]",
+ "eor x12, x15, x7",
+ "and x12, x8, x12",
+ "and x12, x6, x12",
+ "eor x3, x3, x12",
+ "and x3, x5, x3",
+ "eor x3, x14, x3",
+ "eor x11, x11, x16",
+ "eor x16, x11, x13",
+ "ldr x14, [x2, #48]",
+ "ldr x12, [x2, #56]",
+ "str x3, [x2, #88]",
+ "eor x3, x14, x12",
+ "eor x3, x3, x9",
+ "and x11, x4, x11",
+ "eor x11, x3, x11",
+ "str x10, [x2, #96]",
+ "and x10, x8, x11",
+ "eor x16, x16, x10",
+ "eor x10, x15, x12",
+ "eor x10, x10, x9",
+ "eor x13, x10, x13",
+ "and x12, x4, x14",
+ "eor x14, x14, x12",
+ "and x14, x8, x14",
+ "eor x12, x13, x14",
+ "and x12, x6, x12",
+ "eor x16, x16, x12",
+ "eor x11, x11, x14",
+ "ldr x14, [x2, #40]",
+ "and x12, x4, x14",
+ "eor x14, x3, x12",
+ "and x14, x8, x14",
+ "str x3, [x2, #48]",
+ "eor x3, x15, x14",
+ "and x3, x6, x3",
+ "eor x11, x11, x3",
+ "and x11, x5, x11",
+ "eor x16, x16, x11",
+ "eor x11, x15, x12",
+ "and x3, x8, x13",
+ "eor x11, x11, x3",
+ "eor x17, x17, x7",
+ "and x10, x4, x10",
+ "ldr x7, [x2, #48]",
+ "eor x7, x7, x10",
+ "and x7, x8, x7",
+ "eor x17, x17, x7",
+ "and x17, x6, x17",
+ "eor x11, x11, x17",
+ "ldr x17, [x2, #64]",
+ "and x7, x8, x17",
+ "eor x13, x13, x7",
+ "ldr x7, [x2, #40]",
+ "eor x7, x7, x12",
+ "eor x7, x7, x14",
+ "and x7, x6, x7",
+ "eor x13, x13, x7",
+ "and x13, x5, x13",
+ "eor x11, x11, x13",
+ "ldr x13, [x2, #32]",
+ "ldr x7, [x2, #56]",
+ "eor x13, x13, x7",
+ "eor x13, x13, x9",
+ "eor x13, x13, x4",
+ "eor x17, x17, x7",
+ "eor x17, x17, x9",
+ "and x17, x8, x17",
+ "eor x17, x13, x17",
+ "ldr x14, [x2, #96]",
+ "eor x14, x14, x7",
+ "eor x14, x14, x9",
+ "and x14, x8, x14",
+ "ldr x7, [x2, #80]",
+ "eor x7, x7, x14",
+ "and x7, x6, x7",
+ "eor x17, x17, x7",
+ "ldr x7, [x2, #72]",
+ "eor x7, x15, x7",
+ "and x7, x8, x7",
+ "eor x12, x12, x7",
+ "eor x15, x15, x4",
+ "and x8, x8, x15",
+ "eor x13, x13, x8",
+ "and x6, x6, x13",
+ "eor x12, x12, x6",
+ "and x5, x5, x12",
+ "eor x6, x17, x5",
+ "ldr x3, [x2, #88]",
+ "add x4, x16, #0",
+ "add x5, x11, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #63",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #55",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #49",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #41",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #23",
+ "add x11, x10, #0",
+ "lsr x11, x11, #36",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #24",
+ "add x11, x10, #0",
+ "lsr x11, x11, #37",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #25",
+ "add x11, x10, #0",
+ "lsr x11, x11, #38",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #26",
+ "add x11, x10, #0",
+ "lsr x11, x11, #39",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #27",
+ "add x11, x10, #0",
+ "lsr x11, x11, #40",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #28",
+ "add x11, x10, #0",
+ "lsr x11, x11, #41",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "and x13, x4, x8",
+ "eor x14, x8, x13",
+ "and x15, x3, x14",
+ "eor x15, x12, x15",
+ "eor x16, x13, x10",
+ "eor x16, x16, x9",
+ "and x17, x3, x16",
+ "str x16, [x2, #32]",
+ "eor x16, x14, x17",
+ "and x16, x7, x16",
+ "eor x15, x15, x16",
+ "str x17, [x2, #40]",
+ "and x17, x4, x12",
+ "str x16, [x2, #48]",
+ "eor x16, x12, x17",
+ "eor x14, x14, x10",
+ "eor x14, x14, x9",
+ "str x12, [x2, #56]",
+ "and x12, x3, x14",
+ "str x14, [x2, #64]",
+ "eor x14, x16, x12",
+ "str x12, [x2, #72]",
+ "eor x12, x16, x10",
+ "eor x12, x12, x9",
+ "str x16, [x2, #80]",
+ "and x16, x3, x12",
+ "eor x16, x4, x16",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x17",
+ "eor x14, x11, x14",
+ "eor x16, x8, x4",
+ "str x17, [x2, #88]",
+ "and x17, x3, x16",
+ "str x11, [x2, #96]",
+ "eor x11, x4, x17",
+ "and x11, x7, x11",
+ "eor x14, x14, x11",
+ "and x14, x5, x14",
+ "eor x15, x15, x14",
+ "eor x16, x16, x10",
+ "eor x16, x16, x9",
+ "and x13, x3, x13",
+ "eor x14, x16, x13",
+ "ldr x11, [x2, #64]",
+ "eor x11, x11, x17",
+ "and x11, x7, x11",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "eor x12, x12, x11",
+ "and x12, x6, x12",
+ "eor x14, x14, x12",
+ "ldr x12, [x2, #80]",
+ "and x11, x3, x12",
+ "eor x11, x8, x11",
+ "and x11, x7, x11",
+ "ldr x17, [x2, #32]",
+ "eor x11, x17, x11",
+ "str x15, [x2, #48]",
+ "ldr x15, [x2, #56]",
+ "str x10, [x2, #64]",
+ "and x10, x3, x15",
+ "eor x12, x12, x10",
+ "and x8, x7, x8",
+ "eor x12, x12, x8",
+ "and x12, x6, x12",
+ "eor x11, x11, x12",
+ "and x11, x5, x11",
+ "eor x14, x14, x11",
+ "eor x11, x16, x3",
+ "eor x11, x11, x7",
+ "eor x12, x17, x13",
+ "and x12, x7, x12",
+ "eor x12, x3, x12",
+ "and x12, x6, x12",
+ "eor x11, x11, x12",
+ "and x3, x3, x4",
+ "ldr x4, [x2, #96]",
+ "eor x4, x4, x3",
+ "ldr x12, [x2, #40]",
+ "eor x17, x17, x12",
+ "and x17, x7, x17",
+ "eor x4, x4, x17",
+ "and x3, x6, x3",
+ "eor x4, x4, x3",
+ "and x4, x5, x4",
+ "eor x11, x11, x4",
+ "eor x16, x16, x12",
+ "ldr x12, [x2, #72]",
+ "and x12, x7, x12",
+ "eor x16, x16, x12",
+ "ldr x12, [x2, #64]",
+ "eor x4, x13, x12",
+ "eor x4, x4, x9",
+ "eor x15, x15, x10",
+ "and x15, x7, x15",
+ "eor x4, x4, x15",
+ "and x6, x6, x4",
+ "eor x16, x16, x6",
+ "ldr x6, [x2, #88]",
+ "eor x6, x6, x13",
+ "eor x12, x6, x12",
+ "eor x12, x12, x9",
+ "and x7, x7, x12",
+ "eor x6, x6, x7",
+ "and x5, x5, x6",
+ "eor x6, x16, x5",
+ "ldr x3, [x2, #48]",
+ "add x4, x14, #0",
+ "add x5, x11, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #50",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #34",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #60",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #45",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #19",
+ "add x11, x10, #0",
+ "lsr x11, x11, #30",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #20",
+ "add x11, x10, #0",
+ "lsr x11, x11, #31",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #21",
+ "add x11, x10, #0",
+ "lsr x11, x11, #32",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #22",
+ "add x11, x10, #0",
+ "lsr x11, x11, #33",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #23",
+ "add x11, x10, #0",
+ "lsr x11, x11, #34",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #24",
+ "add x11, x10, #0",
+ "lsr x11, x11, #35",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "and x13, x7, x12",
+ "eor x14, x8, x13",
+ "and x15, x7, x8",
+ "eor x16, x12, x15",
+ "and x17, x3, x16",
+ "str x13, [x2, #32]",
+ "eor x13, x14, x17",
+ "str x14, [x2, #40]",
+ "eor x14, x16, x10",
+ "eor x14, x14, x9",
+ "and x15, x3, x15",
+ "str x10, [x2, #48]",
+ "eor x10, x14, x15",
+ "str x14, [x2, #56]",
+ "and x14, x4, x10",
+ "eor x14, x13, x14",
+ "str x13, [x2, #64]",
+ "and x13, x4, x16",
+ "eor x10, x10, x13",
+ "and x10, x6, x10",
+ "eor x14, x14, x10",
+ "and x8, x3, x8",
+ "eor x11, x11, x8",
+ "and x10, x4, x12",
+ "eor x11, x11, x10",
+ "and x15, x6, x15",
+ "eor x11, x11, x15",
+ "and x11, x5, x11",
+ "eor x14, x14, x11",
+ "eor x11, x12, x7",
+ "eor x17, x11, x17",
+ "ldr x15, [x2, #32]",
+ "ldr x10, [x2, #48]",
+ "eor x13, x15, x10",
+ "eor x13, x13, x9",
+ "str x14, [x2, #72]",
+ "and x14, x3, x15",
+ "eor x14, x13, x14",
+ "str x16, [x2, #80]",
+ "and x16, x4, x14",
+ "str x11, [x2, #88]",
+ "eor x11, x17, x16",
+ "str x8, [x2, #96]",
+ "eor x8, x7, x10",
+ "eor x8, x8, x9",
+ "and x15, x3, x8",
+ "eor x7, x7, x15",
+ "str x8, [x2, #104]",
+ "and x8, x3, x12",
+ "eor x12, x12, x8",
+ "and x12, x4, x12",
+ "eor x7, x7, x12",
+ "and x7, x6, x7",
+ "eor x11, x11, x7",
+ "ldr x7, [x2, #64]",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x17, x4, x17",
+ "eor x7, x7, x17",
+ "ldr x17, [x2, #40]",
+ "eor x12, x17, x10",
+ "eor x12, x12, x9",
+ "and x17, x3, x12",
+ "str x12, [x2, #64]",
+ "eor x12, x13, x17",
+ "str x17, [x2, #112]",
+ "eor x17, x8, x10",
+ "eor x17, x17, x9",
+ "and x17, x4, x17",
+ "eor x12, x12, x17",
+ "and x12, x6, x12",
+ "eor x7, x7, x12",
+ "and x7, x5, x7",
+ "eor x11, x11, x7",
+ "and x7, x3, x13",
+ "ldr x12, [x2, #56]",
+ "eor x12, x12, x7",
+ "eor x7, x14, x10",
+ "eor x7, x7, x9",
+ "and x7, x4, x7",
+ "eor x12, x12, x7",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x12, x12, x14",
+ "ldr x14, [x2, #32]",
+ "eor x15, x14, x15",
+ "eor x15, x15, x17",
+ "ldr x17, [x2, #96]",
+ "and x16, x4, x17",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x15, x15, x14",
+ "and x15, x5, x15",
+ "eor x12, x12, x15",
+ "eor x13, x13, x17",
+ "eor x13, x13, x4",
+ "ldr x17, [x2, #88]",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x3, x3, x17",
+ "ldr x17, [x2, #104]",
+ "eor x17, x17, x3",
+ "and x17, x4, x17",
+ "ldr x3, [x2, #80]",
+ "eor x3, x3, x17",
+ "and x3, x6, x3",
+ "eor x13, x13, x3",
+ "ldr x3, [x2, #40]",
+ "eor x3, x3, x8",
+ "ldr x17, [x2, #64]",
+ "ldr x10, [x2, #112]",
+ "eor x10, x17, x10",
+ "and x10, x4, x10",
+ "eor x3, x3, x10",
+ "and x4, x4, x8",
+ "eor x17, x17, x4",
+ "and x6, x6, x17",
+ "eor x3, x3, x6",
+ "and x5, x5, x3",
+ "eor x6, x13, x5",
+ "ldr x3, [x2, #72]",
+ "add x4, x11, #0",
+ "add x5, x12, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #38",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #62",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #48",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #56",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #15",
+ "add x11, x10, #0",
+ "lsr x11, x11, #24",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #16",
+ "add x11, x10, #0",
+ "lsr x11, x11, #25",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #17",
+ "add x11, x10, #0",
+ "lsr x11, x11, #26",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #18",
+ "add x11, x10, #0",
+ "lsr x11, x11, #27",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #19",
+ "add x11, x10, #0",
+ "lsr x11, x11, #28",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #20",
+ "add x11, x10, #0",
+ "lsr x11, x11, #29",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x6, x10",
+ "eor x12, x12, x9",
+ "and x13, x4, x6",
+ "eor x14, x12, x13",
+ "and x15, x8, x14",
+ "eor x16, x12, x15",
+ "eor x17, x6, x4",
+ "str x15, [x2, #32]",
+ "eor x15, x17, x10",
+ "eor x15, x15, x9",
+ "str x6, [x2, #40]",
+ "and x6, x8, x15",
+ "str x3, [x2, #48]",
+ "eor x3, x17, x6",
+ "and x3, x7, x3",
+ "eor x16, x16, x3",
+ "eor x3, x4, x10",
+ "eor x3, x3, x9",
+ "str x17, [x2, #56]",
+ "eor x17, x4, x6",
+ "str x6, [x2, #64]",
+ "and x6, x7, x17",
+ "str x11, [x2, #72]",
+ "eor x11, x3, x6",
+ "and x11, x5, x11",
+ "eor x16, x16, x11",
+ "eor x11, x14, x10",
+ "eor x11, x11, x9",
+ "and x11, x8, x11",
+ "eor x11, x15, x11",
+ "and x11, x7, x11",
+ "eor x17, x17, x11",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x11, x4, x12",
+ "str x6, [x2, #80]",
+ "ldr x6, [x2, #72]",
+ "eor x6, x6, x11",
+ "str x3, [x2, #72]",
+ "and x3, x8, x6",
+ "eor x13, x13, x3",
+ "str x6, [x2, #88]",
+ "ldr x6, [x2, #56]",
+ "and x6, x7, x6",
+ "eor x13, x13, x6",
+ "and x13, x5, x13",
+ "eor x17, x17, x13",
+ "ldr x13, [x2, #48]",
+ "str x6, [x2, #56]",
+ "and x6, x13, x17",
+ "eor x16, x16, x6",
+ "and x6, x8, x11",
+ "eor x15, x15, x6",
+ "str x16, [x2, #96]",
+ "eor x16, x3, x10",
+ "eor x16, x16, x9",
+ "and x16, x7, x16",
+ "eor x16, x15, x16",
+ "str x8, [x2, #104]",
+ "eor x8, x11, x3",
+ "str x11, [x2, #112]",
+ "ldr x11, [x2, #40]",
+ "str x6, [x2, #120]",
+ "ldr x6, [x2, #64]",
+ "eor x6, x11, x6",
+ "and x6, x7, x6",
+ "eor x8, x8, x6",
+ "and x8, x5, x8",
+ "eor x16, x16, x8",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x17, x13, x17",
+ "eor x16, x16, x17",
+ "eor x14, x14, x3",
+ "and x12, x7, x12",
+ "eor x14, x14, x12",
+ "eor x4, x4, x6",
+ "and x4, x5, x4",
+ "eor x14, x14, x4",
+ "eor x15, x15, x10",
+ "eor x15, x15, x9",
+ "ldr x4, [x2, #88]",
+ "ldr x6, [x2, #120]",
+ "eor x4, x4, x6",
+ "and x4, x7, x4",
+ "eor x15, x15, x4",
+ "ldr x4, [x2, #72]",
+ "ldr x12, [x2, #32]",
+ "eor x4, x4, x12",
+ "ldr x3, [x2, #56]",
+ "eor x4, x4, x3",
+ "and x4, x5, x4",
+ "eor x15, x15, x4",
+ "and x4, x13, x15",
+ "eor x14, x14, x4",
+ "ldr x4, [x2, #112]",
+ "ldr x3, [x2, #104]",
+ "eor x3, x4, x3",
+ "eor x11, x11, x4",
+ "eor x11, x11, x6",
+ "and x7, x7, x11",
+ "eor x3, x3, x7",
+ "eor x12, x12, x10",
+ "eor x12, x12, x9",
+ "ldr x7, [x2, #80]",
+ "eor x12, x12, x7",
+ "and x5, x5, x12",
+ "eor x3, x3, x5",
+ "eor x15, x15, x10",
+ "eor x15, x15, x9",
+ "and x13, x13, x15",
+ "eor x6, x3, x13",
+ "ldr x3, [x2, #96]",
+ "add x4, x16, #0",
+ "add x5, x14, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #33",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #42",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #52",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #58",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #11",
+ "add x11, x10, #0",
+ "lsr x11, x11, #18",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #12",
+ "add x11, x10, #0",
+ "lsr x11, x11, #19",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #13",
+ "add x11, x10, #0",
+ "lsr x11, x11, #20",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #14",
+ "add x11, x10, #0",
+ "lsr x11, x11, #21",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #15",
+ "add x11, x10, #0",
+ "lsr x11, x11, #22",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #16",
+ "add x11, x10, #0",
+ "lsr x11, x11, #23",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x6, x10",
+ "eor x12, x12, x9",
+ "and x13, x12, x8",
+ "eor x14, x11, x13",
+ "eor x3, x3, x10",
+ "eor x3, x3, x9",
+ "and x15, x3, x14",
+ "eor x16, x8, x15",
+ "eor x17, x8, x10",
+ "eor x17, x17, x9",
+ "str x15, [x2, #32]",
+ "and x15, x12, x17",
+ "str x11, [x2, #40]",
+ "eor x11, x17, x15",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "str x15, [x2, #48]",
+ "and x15, x7, x11",
+ "eor x15, x16, x15",
+ "str x16, [x2, #56]",
+ "eor x16, x17, x13",
+ "str x14, [x2, #64]",
+ "and x14, x7, x16",
+ "eor x14, x6, x14",
+ "eor x5, x5, x10",
+ "eor x5, x5, x9",
+ "and x14, x5, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x17",
+ "eor x14, x12, x14",
+ "str x6, [x2, #72]",
+ "eor x6, x8, x12",
+ "and x13, x3, x13",
+ "eor x13, x6, x13",
+ "and x13, x7, x13",
+ "eor x14, x14, x13",
+ "eor x13, x11, x10",
+ "eor x13, x13, x9",
+ "and x13, x3, x13",
+ "str x12, [x2, #80]",
+ "eor x12, x17, x3",
+ "and x12, x7, x12",
+ "eor x13, x13, x12",
+ "and x13, x5, x13",
+ "eor x14, x14, x13",
+ "eor x4, x4, x10",
+ "eor x4, x4, x9",
+ "and x14, x4, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x11",
+ "ldr x13, [x2, #64]",
+ "eor x12, x13, x14",
+ "eor x12, x12, x7",
+ "str x15, [x2, #88]",
+ "ldr x15, [x2, #48]",
+ "eor x13, x15, x10",
+ "eor x13, x13, x9",
+ "str x10, [x2, #96]",
+ "and x10, x3, x13",
+ "str x6, [x2, #104]",
+ "ldr x6, [x2, #40]",
+ "eor x6, x6, x10",
+ "and x15, x3, x15",
+ "str x13, [x2, #48]",
+ "and x13, x7, x15",
+ "eor x6, x6, x13",
+ "and x6, x5, x6",
+ "eor x12, x12, x6",
+ "eor x15, x16, x15",
+ "and x15, x7, x15",
+ "ldr x6, [x2, #72]",
+ "eor x15, x6, x15",
+ "and x8, x3, x8",
+ "eor x17, x17, x8",
+ "and x13, x7, x17",
+ "eor x13, x10, x13",
+ "and x13, x5, x13",
+ "eor x15, x15, x13",
+ "and x15, x4, x15",
+ "eor x12, x12, x15",
+ "eor x15, x11, x3",
+ "eor x15, x15, x7",
+ "ldr x13, [x2, #48]",
+ "eor x13, x13, x14",
+ "ldr x14, [x2, #104]",
+ "str x12, [x2, #48]",
+ "eor x12, x14, x10",
+ "and x12, x7, x12",
+ "eor x13, x13, x12",
+ "and x13, x5, x13",
+ "eor x15, x15, x13",
+ "ldr x13, [x2, #96]",
+ "eor x12, x14, x13",
+ "eor x12, x12, x9",
+ "str x8, [x2, #40]",
+ "and x8, x3, x12",
+ "eor x11, x11, x8",
+ "and x11, x5, x11",
+ "str x8, [x2, #112]",
+ "ldr x8, [x2, #64]",
+ "eor x8, x8, x11",
+ "and x8, x4, x8",
+ "eor x15, x15, x8",
+ "ldr x8, [x2, #80]",
+ "eor x8, x8, x10",
+ "ldr x10, [x2, #56]",
+ "and x10, x7, x10",
+ "eor x8, x8, x10",
+ "eor x10, x16, x3",
+ "and x10, x7, x10",
+ "eor x17, x17, x10",
+ "and x17, x5, x17",
+ "eor x8, x8, x17",
+ "ldr x17, [x2, #32]",
+ "eor x12, x12, x17",
+ "and x3, x3, x6",
+ "eor x14, x14, x3",
+ "and x14, x7, x14",
+ "eor x12, x12, x14",
+ "eor x16, x16, x13",
+ "eor x16, x16, x9",
+ "ldr x14, [x2, #112]",
+ "eor x16, x16, x14",
+ "ldr x14, [x2, #40]",
+ "eor x14, x14, x13",
+ "eor x14, x14, x9",
+ "and x7, x7, x14",
+ "eor x16, x16, x7",
+ "and x5, x5, x16",
+ "eor x12, x12, x5",
+ "and x4, x4, x12",
+ "eor x6, x8, x4",
+ "ldr x3, [x2, #88]",
+ "ldr x4, [x2, #48]",
+ "add x5, x15, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #35",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #57",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #46",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #40",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #7",
+ "add x11, x10, #0",
+ "lsr x11, x11, #12",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #8",
+ "add x11, x10, #0",
+ "lsr x11, x11, #13",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #9",
+ "add x11, x10, #0",
+ "lsr x11, x11, #14",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #10",
+ "add x11, x10, #0",
+ "lsr x11, x11, #15",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #11",
+ "add x11, x10, #0",
+ "lsr x11, x11, #16",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #12",
+ "add x11, x10, #0",
+ "lsr x11, x11, #17",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x7, x10",
+ "eor x12, x12, x9",
+ "and x13, x6, x12",
+ "eor x14, x13, x4",
+ "eor x15, x7, x13",
+ "and x16, x4, x6",
+ "eor x17, x15, x16",
+ "and x17, x5, x17",
+ "eor x14, x14, x17",
+ "eor x17, x16, x10",
+ "eor x17, x17, x9",
+ "str x16, [x2, #32]",
+ "eor x16, x6, x10",
+ "eor x16, x16, x9",
+ "str x15, [x2, #40]",
+ "and x15, x4, x16",
+ "str x16, [x2, #48]",
+ "eor x16, x6, x15",
+ "str x15, [x2, #56]",
+ "and x15, x5, x16",
+ "eor x17, x17, x15",
+ "and x17, x8, x17",
+ "eor x14, x14, x17",
+ "eor x17, x12, x6",
+ "str x16, [x2, #64]",
+ "and x16, x4, x17",
+ "str x15, [x2, #72]",
+ "eor x15, x13, x16",
+ "and x15, x5, x15",
+ "and x6, x6, x7",
+ "str x11, [x2, #80]",
+ "eor x11, x12, x6",
+ "str x12, [x2, #88]",
+ "eor x12, x17, x10",
+ "eor x12, x12, x9",
+ "eor x12, x12, x16",
+ "and x12, x5, x12",
+ "eor x12, x11, x12",
+ "and x12, x8, x12",
+ "eor x15, x15, x12",
+ "and x15, x3, x15",
+ "eor x14, x14, x15",
+ "and x15, x4, x13",
+ "eor x12, x6, x15",
+ "and x7, x4, x7",
+ "str x14, [x2, #96]",
+ "ldr x14, [x2, #80]",
+ "eor x14, x14, x7",
+ "str x11, [x2, #80]",
+ "and x11, x5, x14",
+ "eor x12, x12, x11",
+ "ldr x11, [x2, #40]",
+ "str x16, [x2, #104]",
+ "ldr x16, [x2, #56]",
+ "eor x11, x11, x16",
+ "and x7, x5, x7",
+ "eor x11, x11, x7",
+ "and x11, x8, x11",
+ "eor x12, x12, x11",
+ "and x11, x5, x4",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "eor x11, x11, x15",
+ "str x15, [x2, #48]",
+ "ldr x15, [x2, #88]",
+ "str x7, [x2, #40]",
+ "and x7, x4, x15",
+ "str x6, [x2, #112]",
+ "and x6, x5, x7",
+ "eor x11, x11, x6",
+ "and x11, x8, x11",
+ "eor x14, x14, x11",
+ "and x14, x3, x14",
+ "eor x12, x12, x14",
+ "eor x17, x17, x16",
+ "ldr x14, [x2, #32]",
+ "eor x15, x15, x14",
+ "and x15, x5, x15",
+ "eor x17, x17, x15",
+ "eor x15, x13, x10",
+ "eor x15, x15, x9",
+ "ldr x14, [x2, #112]",
+ "and x11, x4, x14",
+ "eor x11, x15, x11",
+ "ldr x6, [x2, #104]",
+ "and x6, x5, x6",
+ "eor x11, x11, x6",
+ "and x11, x8, x11",
+ "eor x17, x17, x11",
+ "ldr x11, [x2, #40]",
+ "eor x11, x11, x10",
+ "eor x11, x11, x9",
+ "ldr x10, [x2, #48]",
+ "eor x13, x13, x10",
+ "eor x14, x14, x4",
+ "and x14, x5, x14",
+ "eor x13, x13, x14",
+ "and x13, x8, x13",
+ "eor x11, x11, x13",
+ "and x11, x3, x11",
+ "eor x17, x17, x11",
+ "ldr x11, [x2, #80]",
+ "eor x13, x11, x4",
+ "ldr x14, [x2, #72]",
+ "eor x13, x13, x14",
+ "ldr x14, [x2, #64]",
+ "and x10, x8, x14",
+ "eor x13, x13, x10",
+ "eor x16, x15, x16",
+ "and x16, x5, x16",
+ "eor x14, x14, x16",
+ "and x4, x4, x15",
+ "eor x15, x15, x4",
+ "eor x11, x11, x7",
+ "and x5, x5, x11",
+ "eor x15, x15, x5",
+ "and x8, x8, x15",
+ "eor x14, x14, x8",
+ "and x3, x3, x14",
+ "eor x6, x13, x3",
+ "ldr x3, [x2, #96]",
+ "add x4, x12, #0",
+ "add x5, x17, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #51",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #43",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #61",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #36",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #3",
+ "add x11, x10, #0",
+ "lsr x11, x11, #6",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #4",
+ "add x11, x10, #0",
+ "lsr x11, x11, #7",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #5",
+ "add x11, x10, #0",
+ "lsr x11, x11, #8",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #6",
+ "add x11, x10, #0",
+ "lsr x11, x11, #9",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #7",
+ "add x11, x10, #0",
+ "lsr x11, x11, #10",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #8",
+ "add x11, x10, #0",
+ "lsr x11, x11, #11",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x3",
+ "and x13, x3, x8",
+ "and x14, x5, x13",
+ "eor x15, x12, x14",
+ "eor x16, x13, x10",
+ "eor x16, x16, x9",
+ "and x17, x5, x16",
+ "str x14, [x2, #32]",
+ "eor x14, x11, x17",
+ "str x12, [x2, #40]",
+ "and x12, x6, x14",
+ "eor x15, x15, x12",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "str x8, [x2, #48]",
+ "and x8, x3, x12",
+ "str x12, [x2, #56]",
+ "and x12, x5, x8",
+ "str x8, [x2, #64]",
+ "eor x8, x11, x12",
+ "str x11, [x2, #72]",
+ "and x11, x6, x16",
+ "eor x8, x8, x11",
+ "and x8, x7, x8",
+ "eor x15, x15, x8",
+ "and x8, x6, x17",
+ "eor x14, x14, x8",
+ "and x8, x5, x3",
+ "eor x8, x13, x8",
+ "and x8, x7, x8",
+ "eor x14, x14, x8",
+ "and x14, x4, x14",
+ "eor x15, x15, x14",
+ "eor x14, x13, x5",
+ "ldr x8, [x2, #40]",
+ "str x15, [x2, #80]",
+ "eor x15, x8, x10",
+ "eor x15, x15, x9",
+ "str x11, [x2, #88]",
+ "eor x11, x15, x12",
+ "and x11, x6, x11",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "and x8, x5, x11",
+ "str x16, [x2, #96]",
+ "ldr x16, [x2, #72]",
+ "str x17, [x2, #104]",
+ "eor x17, x16, x8",
+ "eor x13, x11, x13",
+ "eor x16, x13, x12",
+ "and x16, x6, x16",
+ "eor x17, x17, x16",
+ "and x17, x7, x17",
+ "eor x14, x14, x17",
+ "ldr x17, [x2, #56]",
+ "str x12, [x2, #112]",
+ "ldr x12, [x2, #64]",
+ "str x8, [x2, #120]",
+ "eor x8, x17, x12",
+ "eor x3, x3, x10",
+ "eor x3, x3, x9",
+ "and x3, x5, x3",
+ "eor x3, x8, x3",
+ "eor x3, x3, x16",
+ "and x16, x5, x15",
+ "str x8, [x2, #128]",
+ "and x8, x6, x13",
+ "eor x16, x16, x8",
+ "and x16, x7, x16",
+ "eor x3, x3, x16",
+ "and x3, x4, x3",
+ "eor x14, x14, x3",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x17, x5, x17",
+ "eor x10, x13, x17",
+ "and x3, x6, x11",
+ "eor x10, x10, x3",
+ "ldr x16, [x2, #104]",
+ "eor x15, x15, x16",
+ "ldr x16, [x2, #96]",
+ "ldr x8, [x2, #120]",
+ "eor x16, x16, x8",
+ "and x16, x6, x16",
+ "eor x15, x15, x16",
+ "and x15, x7, x15",
+ "eor x10, x10, x15",
+ "ldr x15, [x2, #40]",
+ "and x15, x5, x15",
+ "and x15, x6, x15",
+ "ldr x16, [x2, #72]",
+ "eor x16, x16, x15",
+ "ldr x15, [x2, #112]",
+ "and x15, x7, x15",
+ "eor x16, x16, x15",
+ "and x16, x4, x16",
+ "eor x10, x10, x16",
+ "eor x12, x12, x8",
+ "ldr x16, [x2, #88]",
+ "eor x12, x12, x16",
+ "eor x17, x11, x17",
+ "ldr x16, [x2, #128]",
+ "and x5, x5, x16",
+ "eor x16, x16, x5",
+ "and x16, x6, x16",
+ "eor x17, x17, x16",
+ "and x17, x7, x17",
+ "eor x12, x12, x17",
+ "ldr x17, [x2, #32]",
+ "eor x13, x13, x17",
+ "eor x11, x11, x5",
+ "and x6, x6, x11",
+ "eor x13, x13, x6",
+ "eor x8, x8, x3",
+ "and x7, x7, x8",
+ "eor x13, x13, x7",
+ "and x4, x4, x13",
+ "eor x6, x12, x4",
+ "ldr x3, [x2, #80]",
+ "add x4, x14, #0",
+ "add x5, x10, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #39",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #54",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #44",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #31",
+ "add x11, x10, #0",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "add x11, x10, #0",
+ "lsr x11, x11, #1",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #1",
+ "add x11, x10, #0",
+ "lsr x11, x11, #2",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #2",
+ "add x11, x10, #0",
+ "lsr x11, x11, #3",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #3",
+ "add x11, x10, #0",
+ "lsr x11, x11, #4",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #4",
+ "add x11, x10, #0",
+ "lsr x11, x11, #5",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x3, x10",
+ "eor x12, x12, x9",
+ "eor x13, x8, x12",
+ "eor x6, x6, x10",
+ "eor x6, x6, x9",
+ "eor x14, x13, x6",
+ "eor x4, x4, x10",
+ "eor x4, x4, x9",
+ "eor x14, x14, x4",
+ "and x15, x6, x3",
+ "and x16, x12, x8",
+ "and x17, x6, x16",
+ "str x3, [x2, #32]",
+ "eor x3, x12, x17",
+ "and x3, x4, x3",
+ "eor x3, x15, x3",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "and x3, x7, x3",
+ "eor x14, x14, x3",
+ "eor x3, x8, x10",
+ "eor x3, x3, x9",
+ "str x13, [x2, #40]",
+ "and x13, x12, x3",
+ "str x17, [x2, #48]",
+ "eor x17, x11, x13",
+ "str x13, [x2, #56]",
+ "eor x13, x17, x15",
+ "and x13, x4, x13",
+ "eor x12, x12, x13",
+ "eor x13, x8, x16",
+ "str x17, [x2, #64]",
+ "and x17, x6, x13",
+ "eor x11, x11, x17",
+ "str x15, [x2, #72]",
+ "and x15, x4, x3",
+ "eor x11, x11, x15",
+ "and x11, x7, x11",
+ "eor x12, x12, x11",
+ "eor x5, x5, x10",
+ "eor x5, x5, x9",
+ "and x12, x5, x12",
+ "eor x14, x14, x12",
+ "eor x12, x16, x10",
+ "eor x12, x12, x9",
+ "eor x11, x12, x17",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "str x14, [x2, #80]",
+ "and x14, x6, x13",
+ "eor x3, x3, x14",
+ "and x3, x4, x3",
+ "eor x11, x11, x3",
+ "ldr x3, [x2, #48]",
+ "str x13, [x2, #88]",
+ "eor x13, x3, x10",
+ "eor x13, x13, x9",
+ "str x17, [x2, #96]",
+ "and x17, x4, x3",
+ "eor x17, x13, x17",
+ "and x17, x7, x17",
+ "eor x11, x11, x17",
+ "ldr x17, [x2, #56]",
+ "str x13, [x2, #104]",
+ "eor x13, x8, x17",
+ "str x16, [x2, #112]",
+ "ldr x16, [x2, #72]",
+ "eor x16, x13, x16",
+ "str x15, [x2, #72]",
+ "ldr x15, [x2, #40]",
+ "and x15, x4, x15",
+ "str x14, [x2, #40]",
+ "eor x14, x16, x15",
+ "eor x16, x16, x10",
+ "eor x16, x16, x9",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x13, x4, x13",
+ "eor x16, x16, x13",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "and x14, x5, x14",
+ "eor x11, x11, x14",
+ "eor x14, x17, x3",
+ "and x16, x6, x12",
+ "eor x8, x8, x16",
+ "and x16, x4, x8",
+ "eor x14, x14, x16",
+ "ldr x16, [x2, #40]",
+ "eor x16, x12, x16",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "ldr x16, [x2, #72]",
+ "eor x12, x12, x16",
+ "ldr x13, [x2, #112]",
+ "eor x3, x13, x3",
+ "eor x3, x3, x16",
+ "and x3, x7, x3",
+ "eor x12, x12, x3",
+ "and x12, x5, x12",
+ "eor x14, x14, x12",
+ "ldr x12, [x2, #104]",
+ "and x12, x4, x12",
+ "eor x8, x8, x12",
+ "and x6, x6, x17",
+ "eor x13, x13, x6",
+ "ldr x6, [x2, #32]",
+ "ldr x17, [x2, #96]",
+ "eor x6, x6, x17",
+ "and x6, x4, x6",
+ "eor x6, x13, x6",
+ "and x6, x7, x6",
+ "eor x8, x8, x6",
+ "ldr x6, [x2, #64]",
+ "eor x6, x6, x15",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "ldr x10, [x2, #88]",
+ "and x4, x4, x10",
+ "eor x13, x13, x4",
+ "and x7, x7, x13",
+ "eor x6, x6, x7",
+ "and x5, x5, x6",
+ "eor x6, x8, x5",
+ "ldr x3, [x2, #80]",
+ "add x4, x11, #0",
+ "add x5, x14, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #53",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #47",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #59",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #37",
+ "eor x19, x19, x6",
+ "add x3, x19, #0",
+ "add x19, x20, #0",
+ "add x20, x3, #0",
+ "add x22, x22, #8",
+ "sub x21, x21, #1",
+ "cbnz x21, 22b",
+ "add x3, x19, #0",
+ "add x19, x20, #0",
+ "add x20, x3, #0",
+ "lsl x3, x19, #32",
+ "eor x3, x3, x20",
+ "movz x10, #0, lsl #0",
+ "movz x12, #1, lsl #0",
+ "add x11, x3, #0",
+ "lsr x11, x11, #24",
+ "and x11, x11, x12",
+ "ror x11, x11, #1",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #56",
+ "and x11, x11, x12",
+ "ror x11, x11, #2",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #16",
+ "and x11, x11, x12",
+ "ror x11, x11, #3",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #48",
+ "and x11, x11, x12",
+ "ror x11, x11, #4",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #8",
+ "and x11, x11, x12",
+ "ror x11, x11, #5",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #40",
+ "and x11, x11, x12",
+ "ror x11, x11, #6",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "and x11, x11, x12",
+ "ror x11, x11, #7",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #32",
+ "and x11, x11, x12",
+ "ror x11, x11, #8",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #25",
+ "and x11, x11, x12",
+ "ror x11, x11, #9",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #57",
+ "and x11, x11, x12",
+ "ror x11, x11, #10",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #17",
+ "and x11, x11, x12",
+ "ror x11, x11, #11",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #49",
+ "and x11, x11, x12",
+ "ror x11, x11, #12",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #9",
+ "and x11, x11, x12",
+ "ror x11, x11, #13",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #41",
+ "and x11, x11, x12",
+ "ror x11, x11, #14",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #1",
+ "and x11, x11, x12",
+ "ror x11, x11, #15",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #33",
+ "and x11, x11, x12",
+ "ror x11, x11, #16",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #26",
+ "and x11, x11, x12",
+ "ror x11, x11, #17",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #58",
+ "and x11, x11, x12",
+ "ror x11, x11, #18",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #18",
+ "and x11, x11, x12",
+ "ror x11, x11, #19",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #50",
+ "and x11, x11, x12",
+ "ror x11, x11, #20",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #10",
+ "and x11, x11, x12",
+ "ror x11, x11, #21",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #42",
+ "and x11, x11, x12",
+ "ror x11, x11, #22",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #2",
+ "and x11, x11, x12",
+ "ror x11, x11, #23",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #34",
+ "and x11, x11, x12",
+ "ror x11, x11, #24",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #27",
+ "and x11, x11, x12",
+ "ror x11, x11, #25",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #59",
+ "and x11, x11, x12",
+ "ror x11, x11, #26",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #19",
+ "and x11, x11, x12",
+ "ror x11, x11, #27",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #51",
+ "and x11, x11, x12",
+ "ror x11, x11, #28",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #11",
+ "and x11, x11, x12",
+ "ror x11, x11, #29",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #43",
+ "and x11, x11, x12",
+ "ror x11, x11, #30",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #3",
+ "and x11, x11, x12",
+ "ror x11, x11, #31",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #35",
+ "and x11, x11, x12",
+ "ror x11, x11, #32",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #28",
+ "and x11, x11, x12",
+ "ror x11, x11, #33",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #60",
+ "and x11, x11, x12",
+ "ror x11, x11, #34",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #20",
+ "and x11, x11, x12",
+ "ror x11, x11, #35",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #52",
+ "and x11, x11, x12",
+ "ror x11, x11, #36",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #12",
+ "and x11, x11, x12",
+ "ror x11, x11, #37",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #44",
+ "and x11, x11, x12",
+ "ror x11, x11, #38",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #4",
+ "and x11, x11, x12",
+ "ror x11, x11, #39",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #36",
+ "and x11, x11, x12",
+ "ror x11, x11, #40",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #29",
+ "and x11, x11, x12",
+ "ror x11, x11, #41",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #61",
+ "and x11, x11, x12",
+ "ror x11, x11, #42",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #21",
+ "and x11, x11, x12",
+ "ror x11, x11, #43",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #53",
+ "and x11, x11, x12",
+ "ror x11, x11, #44",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #13",
+ "and x11, x11, x12",
+ "ror x11, x11, #45",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #45",
+ "and x11, x11, x12",
+ "ror x11, x11, #46",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #5",
+ "and x11, x11, x12",
+ "ror x11, x11, #47",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #37",
+ "and x11, x11, x12",
+ "ror x11, x11, #48",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #30",
+ "and x11, x11, x12",
+ "ror x11, x11, #49",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #62",
+ "and x11, x11, x12",
+ "ror x11, x11, #50",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #22",
+ "and x11, x11, x12",
+ "ror x11, x11, #51",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #54",
+ "and x11, x11, x12",
+ "ror x11, x11, #52",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #14",
+ "and x11, x11, x12",
+ "ror x11, x11, #53",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #46",
+ "and x11, x11, x12",
+ "ror x11, x11, #54",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #6",
+ "and x11, x11, x12",
+ "ror x11, x11, #55",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #38",
+ "and x11, x11, x12",
+ "ror x11, x11, #56",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #31",
+ "and x11, x11, x12",
+ "ror x11, x11, #57",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #63",
+ "and x11, x11, x12",
+ "ror x11, x11, #58",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #23",
+ "and x11, x11, x12",
+ "ror x11, x11, #59",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #55",
+ "and x11, x11, x12",
+ "ror x11, x11, #60",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #15",
+ "and x11, x11, x12",
+ "ror x11, x11, #61",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #47",
+ "and x11, x11, x12",
+ "ror x11, x11, #62",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #7",
+ "and x11, x11, x12",
+ "ror x11, x11, #63",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #39",
+ "and x11, x11, x12",
+ "eor x10, x10, x11",
+ "rev x3, x10",
+ "ldr x19, [x2, #0]",
+ "ldr x20, [x2, #8]",
+ "ldr x21, [x2, #16]",
+ "ldr x22, [x2, #24]",
+ "str x3, [x1, #0]",
+ "ret",
+ )
+}
+
+/// 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 AArch64 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 x19, [x2, #0]",
+ "str x20, [x2, #8]",
+ "str x21, [x2, #16]",
+ "str x22, [x2, #24]",
+ "ldr x3, [x1, #0]",
+ "rev x3, x3",
+ "movz x10, #0, lsl #0",
+ "movz x12, #1, lsl #0",
+ "add x11, x3, #0",
+ "lsr x11, x11, #6",
+ "and x11, x11, x12",
+ "ror x11, x11, #1",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #14",
+ "and x11, x11, x12",
+ "ror x11, x11, #2",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #22",
+ "and x11, x11, x12",
+ "ror x11, x11, #3",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #30",
+ "and x11, x11, x12",
+ "ror x11, x11, #4",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #38",
+ "and x11, x11, x12",
+ "ror x11, x11, #5",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #46",
+ "and x11, x11, x12",
+ "ror x11, x11, #6",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #54",
+ "and x11, x11, x12",
+ "ror x11, x11, #7",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #62",
+ "and x11, x11, x12",
+ "ror x11, x11, #8",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #4",
+ "and x11, x11, x12",
+ "ror x11, x11, #9",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #12",
+ "and x11, x11, x12",
+ "ror x11, x11, #10",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #20",
+ "and x11, x11, x12",
+ "ror x11, x11, #11",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #28",
+ "and x11, x11, x12",
+ "ror x11, x11, #12",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #36",
+ "and x11, x11, x12",
+ "ror x11, x11, #13",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #44",
+ "and x11, x11, x12",
+ "ror x11, x11, #14",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #52",
+ "and x11, x11, x12",
+ "ror x11, x11, #15",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #60",
+ "and x11, x11, x12",
+ "ror x11, x11, #16",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #2",
+ "and x11, x11, x12",
+ "ror x11, x11, #17",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #10",
+ "and x11, x11, x12",
+ "ror x11, x11, #18",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #18",
+ "and x11, x11, x12",
+ "ror x11, x11, #19",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #26",
+ "and x11, x11, x12",
+ "ror x11, x11, #20",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #34",
+ "and x11, x11, x12",
+ "ror x11, x11, #21",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #42",
+ "and x11, x11, x12",
+ "ror x11, x11, #22",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #50",
+ "and x11, x11, x12",
+ "ror x11, x11, #23",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #58",
+ "and x11, x11, x12",
+ "ror x11, x11, #24",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "and x11, x11, x12",
+ "ror x11, x11, #25",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #8",
+ "and x11, x11, x12",
+ "ror x11, x11, #26",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #16",
+ "and x11, x11, x12",
+ "ror x11, x11, #27",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #24",
+ "and x11, x11, x12",
+ "ror x11, x11, #28",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #32",
+ "and x11, x11, x12",
+ "ror x11, x11, #29",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #40",
+ "and x11, x11, x12",
+ "ror x11, x11, #30",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #48",
+ "and x11, x11, x12",
+ "ror x11, x11, #31",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #56",
+ "and x11, x11, x12",
+ "ror x11, x11, #32",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #7",
+ "and x11, x11, x12",
+ "ror x11, x11, #33",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #15",
+ "and x11, x11, x12",
+ "ror x11, x11, #34",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #23",
+ "and x11, x11, x12",
+ "ror x11, x11, #35",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #31",
+ "and x11, x11, x12",
+ "ror x11, x11, #36",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #39",
+ "and x11, x11, x12",
+ "ror x11, x11, #37",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #47",
+ "and x11, x11, x12",
+ "ror x11, x11, #38",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #55",
+ "and x11, x11, x12",
+ "ror x11, x11, #39",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #63",
+ "and x11, x11, x12",
+ "ror x11, x11, #40",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #5",
+ "and x11, x11, x12",
+ "ror x11, x11, #41",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #13",
+ "and x11, x11, x12",
+ "ror x11, x11, #42",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #21",
+ "and x11, x11, x12",
+ "ror x11, x11, #43",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #29",
+ "and x11, x11, x12",
+ "ror x11, x11, #44",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #37",
+ "and x11, x11, x12",
+ "ror x11, x11, #45",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #45",
+ "and x11, x11, x12",
+ "ror x11, x11, #46",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #53",
+ "and x11, x11, x12",
+ "ror x11, x11, #47",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #61",
+ "and x11, x11, x12",
+ "ror x11, x11, #48",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #3",
+ "and x11, x11, x12",
+ "ror x11, x11, #49",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #11",
+ "and x11, x11, x12",
+ "ror x11, x11, #50",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #19",
+ "and x11, x11, x12",
+ "ror x11, x11, #51",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #27",
+ "and x11, x11, x12",
+ "ror x11, x11, #52",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #35",
+ "and x11, x11, x12",
+ "ror x11, x11, #53",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #43",
+ "and x11, x11, x12",
+ "ror x11, x11, #54",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #51",
+ "and x11, x11, x12",
+ "ror x11, x11, #55",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #59",
+ "and x11, x11, x12",
+ "ror x11, x11, #56",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #1",
+ "and x11, x11, x12",
+ "ror x11, x11, #57",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #9",
+ "and x11, x11, x12",
+ "ror x11, x11, #58",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #17",
+ "and x11, x11, x12",
+ "ror x11, x11, #59",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #25",
+ "and x11, x11, x12",
+ "ror x11, x11, #60",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #33",
+ "and x11, x11, x12",
+ "ror x11, x11, #61",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #41",
+ "and x11, x11, x12",
+ "ror x11, x11, #62",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #49",
+ "and x11, x11, x12",
+ "ror x11, x11, #63",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #57",
+ "and x11, x11, x12",
+ "eor x10, x10, x11",
+ "lsr x19, x10, #32",
+ "add x20, x10, #0",
+ "lsl x20, x20, #32",
+ "lsr x20, x20, #32",
+ "add x22, x0, #376",
+ "movz x21, #16, lsl #0",
+ "20:",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #27",
+ "add x11, x10, #0",
+ "lsr x11, x11, #42",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #28",
+ "add x11, x10, #0",
+ "lsr x11, x11, #43",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #29",
+ "add x11, x10, #0",
+ "lsr x11, x11, #44",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #30",
+ "add x11, x10, #0",
+ "lsr x11, x11, #45",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #31",
+ "add x11, x10, #0",
+ "lsr x11, x11, #46",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "add x11, x10, #0",
+ "lsr x11, x11, #47",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x10",
+ "eor x11, x11, x9",
+ "and x12, x7, x11",
+ "eor x13, x3, x7",
+ "and x14, x4, x13",
+ "eor x14, x12, x14",
+ "eor x15, x11, x12",
+ "and x16, x4, x15",
+ "eor x16, x3, x16",
+ "and x16, x8, x16",
+ "eor x14, x14, x16",
+ "and x16, x7, x3",
+ "eor x17, x16, x10",
+ "eor x17, x17, x9",
+ "str x13, [x2, #32]",
+ "and x13, x4, x17",
+ "str x3, [x2, #40]",
+ "eor x3, x16, x13",
+ "str x12, [x2, #48]",
+ "eor x12, x7, x10",
+ "eor x12, x12, x9",
+ "str x10, [x2, #56]",
+ "eor x10, x12, x13",
+ "str x13, [x2, #64]",
+ "and x13, x8, x10",
+ "eor x3, x3, x13",
+ "and x3, x6, x3",
+ "eor x14, x14, x3",
+ "and x7, x4, x7",
+ "eor x3, x17, x7",
+ "and x13, x4, x12",
+ "str x7, [x2, #72]",
+ "eor x7, x11, x13",
+ "and x7, x8, x7",
+ "eor x3, x3, x7",
+ "and x7, x4, x11",
+ "str x12, [x2, #80]",
+ "eor x12, x15, x7",
+ "and x12, x8, x12",
+ "and x12, x6, x12",
+ "eor x3, x3, x12",
+ "and x3, x5, x3",
+ "eor x3, x14, x3",
+ "eor x11, x11, x16",
+ "eor x16, x11, x13",
+ "ldr x14, [x2, #48]",
+ "ldr x12, [x2, #56]",
+ "str x3, [x2, #88]",
+ "eor x3, x14, x12",
+ "eor x3, x3, x9",
+ "and x11, x4, x11",
+ "eor x11, x3, x11",
+ "str x10, [x2, #96]",
+ "and x10, x8, x11",
+ "eor x16, x16, x10",
+ "eor x10, x15, x12",
+ "eor x10, x10, x9",
+ "eor x13, x10, x13",
+ "and x12, x4, x14",
+ "eor x14, x14, x12",
+ "and x14, x8, x14",
+ "eor x12, x13, x14",
+ "and x12, x6, x12",
+ "eor x16, x16, x12",
+ "eor x11, x11, x14",
+ "ldr x14, [x2, #40]",
+ "and x12, x4, x14",
+ "eor x14, x3, x12",
+ "and x14, x8, x14",
+ "str x3, [x2, #48]",
+ "eor x3, x15, x14",
+ "and x3, x6, x3",
+ "eor x11, x11, x3",
+ "and x11, x5, x11",
+ "eor x16, x16, x11",
+ "eor x11, x15, x12",
+ "and x3, x8, x13",
+ "eor x11, x11, x3",
+ "eor x17, x17, x7",
+ "and x10, x4, x10",
+ "ldr x7, [x2, #48]",
+ "eor x7, x7, x10",
+ "and x7, x8, x7",
+ "eor x17, x17, x7",
+ "and x17, x6, x17",
+ "eor x11, x11, x17",
+ "ldr x17, [x2, #64]",
+ "and x7, x8, x17",
+ "eor x13, x13, x7",
+ "ldr x7, [x2, #40]",
+ "eor x7, x7, x12",
+ "eor x7, x7, x14",
+ "and x7, x6, x7",
+ "eor x13, x13, x7",
+ "and x13, x5, x13",
+ "eor x11, x11, x13",
+ "ldr x13, [x2, #32]",
+ "ldr x7, [x2, #56]",
+ "eor x13, x13, x7",
+ "eor x13, x13, x9",
+ "eor x13, x13, x4",
+ "eor x17, x17, x7",
+ "eor x17, x17, x9",
+ "and x17, x8, x17",
+ "eor x17, x13, x17",
+ "ldr x14, [x2, #96]",
+ "eor x14, x14, x7",
+ "eor x14, x14, x9",
+ "and x14, x8, x14",
+ "ldr x7, [x2, #80]",
+ "eor x7, x7, x14",
+ "and x7, x6, x7",
+ "eor x17, x17, x7",
+ "ldr x7, [x2, #72]",
+ "eor x7, x15, x7",
+ "and x7, x8, x7",
+ "eor x12, x12, x7",
+ "eor x15, x15, x4",
+ "and x8, x8, x15",
+ "eor x13, x13, x8",
+ "and x6, x6, x13",
+ "eor x12, x12, x6",
+ "and x5, x5, x12",
+ "eor x6, x17, x5",
+ "ldr x3, [x2, #88]",
+ "add x4, x16, #0",
+ "add x5, x11, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #63",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #55",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #49",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #41",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #23",
+ "add x11, x10, #0",
+ "lsr x11, x11, #36",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #24",
+ "add x11, x10, #0",
+ "lsr x11, x11, #37",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #25",
+ "add x11, x10, #0",
+ "lsr x11, x11, #38",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #26",
+ "add x11, x10, #0",
+ "lsr x11, x11, #39",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #27",
+ "add x11, x10, #0",
+ "lsr x11, x11, #40",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #28",
+ "add x11, x10, #0",
+ "lsr x11, x11, #41",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "and x13, x4, x8",
+ "eor x14, x8, x13",
+ "and x15, x3, x14",
+ "eor x15, x12, x15",
+ "eor x16, x13, x10",
+ "eor x16, x16, x9",
+ "and x17, x3, x16",
+ "str x16, [x2, #32]",
+ "eor x16, x14, x17",
+ "and x16, x7, x16",
+ "eor x15, x15, x16",
+ "str x17, [x2, #40]",
+ "and x17, x4, x12",
+ "str x16, [x2, #48]",
+ "eor x16, x12, x17",
+ "eor x14, x14, x10",
+ "eor x14, x14, x9",
+ "str x12, [x2, #56]",
+ "and x12, x3, x14",
+ "str x14, [x2, #64]",
+ "eor x14, x16, x12",
+ "str x12, [x2, #72]",
+ "eor x12, x16, x10",
+ "eor x12, x12, x9",
+ "str x16, [x2, #80]",
+ "and x16, x3, x12",
+ "eor x16, x4, x16",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x17",
+ "eor x14, x11, x14",
+ "eor x16, x8, x4",
+ "str x17, [x2, #88]",
+ "and x17, x3, x16",
+ "str x11, [x2, #96]",
+ "eor x11, x4, x17",
+ "and x11, x7, x11",
+ "eor x14, x14, x11",
+ "and x14, x5, x14",
+ "eor x15, x15, x14",
+ "eor x16, x16, x10",
+ "eor x16, x16, x9",
+ "and x13, x3, x13",
+ "eor x14, x16, x13",
+ "ldr x11, [x2, #64]",
+ "eor x11, x11, x17",
+ "and x11, x7, x11",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "eor x12, x12, x11",
+ "and x12, x6, x12",
+ "eor x14, x14, x12",
+ "ldr x12, [x2, #80]",
+ "and x11, x3, x12",
+ "eor x11, x8, x11",
+ "and x11, x7, x11",
+ "ldr x17, [x2, #32]",
+ "eor x11, x17, x11",
+ "str x15, [x2, #48]",
+ "ldr x15, [x2, #56]",
+ "str x10, [x2, #64]",
+ "and x10, x3, x15",
+ "eor x12, x12, x10",
+ "and x8, x7, x8",
+ "eor x12, x12, x8",
+ "and x12, x6, x12",
+ "eor x11, x11, x12",
+ "and x11, x5, x11",
+ "eor x14, x14, x11",
+ "eor x11, x16, x3",
+ "eor x11, x11, x7",
+ "eor x12, x17, x13",
+ "and x12, x7, x12",
+ "eor x12, x3, x12",
+ "and x12, x6, x12",
+ "eor x11, x11, x12",
+ "and x3, x3, x4",
+ "ldr x4, [x2, #96]",
+ "eor x4, x4, x3",
+ "ldr x12, [x2, #40]",
+ "eor x17, x17, x12",
+ "and x17, x7, x17",
+ "eor x4, x4, x17",
+ "and x3, x6, x3",
+ "eor x4, x4, x3",
+ "and x4, x5, x4",
+ "eor x11, x11, x4",
+ "eor x16, x16, x12",
+ "ldr x12, [x2, #72]",
+ "and x12, x7, x12",
+ "eor x16, x16, x12",
+ "ldr x12, [x2, #64]",
+ "eor x4, x13, x12",
+ "eor x4, x4, x9",
+ "eor x15, x15, x10",
+ "and x15, x7, x15",
+ "eor x4, x4, x15",
+ "and x6, x6, x4",
+ "eor x16, x16, x6",
+ "ldr x6, [x2, #88]",
+ "eor x6, x6, x13",
+ "eor x12, x6, x12",
+ "eor x12, x12, x9",
+ "and x7, x7, x12",
+ "eor x6, x6, x7",
+ "and x5, x5, x6",
+ "eor x6, x16, x5",
+ "ldr x3, [x2, #48]",
+ "add x4, x14, #0",
+ "add x5, x11, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #50",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #34",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #60",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #45",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #19",
+ "add x11, x10, #0",
+ "lsr x11, x11, #30",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #20",
+ "add x11, x10, #0",
+ "lsr x11, x11, #31",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #21",
+ "add x11, x10, #0",
+ "lsr x11, x11, #32",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #22",
+ "add x11, x10, #0",
+ "lsr x11, x11, #33",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #23",
+ "add x11, x10, #0",
+ "lsr x11, x11, #34",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #24",
+ "add x11, x10, #0",
+ "lsr x11, x11, #35",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "and x13, x7, x12",
+ "eor x14, x8, x13",
+ "and x15, x7, x8",
+ "eor x16, x12, x15",
+ "and x17, x3, x16",
+ "str x13, [x2, #32]",
+ "eor x13, x14, x17",
+ "str x14, [x2, #40]",
+ "eor x14, x16, x10",
+ "eor x14, x14, x9",
+ "and x15, x3, x15",
+ "str x10, [x2, #48]",
+ "eor x10, x14, x15",
+ "str x14, [x2, #56]",
+ "and x14, x4, x10",
+ "eor x14, x13, x14",
+ "str x13, [x2, #64]",
+ "and x13, x4, x16",
+ "eor x10, x10, x13",
+ "and x10, x6, x10",
+ "eor x14, x14, x10",
+ "and x8, x3, x8",
+ "eor x11, x11, x8",
+ "and x10, x4, x12",
+ "eor x11, x11, x10",
+ "and x15, x6, x15",
+ "eor x11, x11, x15",
+ "and x11, x5, x11",
+ "eor x14, x14, x11",
+ "eor x11, x12, x7",
+ "eor x17, x11, x17",
+ "ldr x15, [x2, #32]",
+ "ldr x10, [x2, #48]",
+ "eor x13, x15, x10",
+ "eor x13, x13, x9",
+ "str x14, [x2, #72]",
+ "and x14, x3, x15",
+ "eor x14, x13, x14",
+ "str x16, [x2, #80]",
+ "and x16, x4, x14",
+ "str x11, [x2, #88]",
+ "eor x11, x17, x16",
+ "str x8, [x2, #96]",
+ "eor x8, x7, x10",
+ "eor x8, x8, x9",
+ "and x15, x3, x8",
+ "eor x7, x7, x15",
+ "str x8, [x2, #104]",
+ "and x8, x3, x12",
+ "eor x12, x12, x8",
+ "and x12, x4, x12",
+ "eor x7, x7, x12",
+ "and x7, x6, x7",
+ "eor x11, x11, x7",
+ "ldr x7, [x2, #64]",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x17, x4, x17",
+ "eor x7, x7, x17",
+ "ldr x17, [x2, #40]",
+ "eor x12, x17, x10",
+ "eor x12, x12, x9",
+ "and x17, x3, x12",
+ "str x12, [x2, #64]",
+ "eor x12, x13, x17",
+ "str x17, [x2, #112]",
+ "eor x17, x8, x10",
+ "eor x17, x17, x9",
+ "and x17, x4, x17",
+ "eor x12, x12, x17",
+ "and x12, x6, x12",
+ "eor x7, x7, x12",
+ "and x7, x5, x7",
+ "eor x11, x11, x7",
+ "and x7, x3, x13",
+ "ldr x12, [x2, #56]",
+ "eor x12, x12, x7",
+ "eor x7, x14, x10",
+ "eor x7, x7, x9",
+ "and x7, x4, x7",
+ "eor x12, x12, x7",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x12, x12, x14",
+ "ldr x14, [x2, #32]",
+ "eor x15, x14, x15",
+ "eor x15, x15, x17",
+ "ldr x17, [x2, #96]",
+ "and x16, x4, x17",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x15, x15, x14",
+ "and x15, x5, x15",
+ "eor x12, x12, x15",
+ "eor x13, x13, x17",
+ "eor x13, x13, x4",
+ "ldr x17, [x2, #88]",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x3, x3, x17",
+ "ldr x17, [x2, #104]",
+ "eor x17, x17, x3",
+ "and x17, x4, x17",
+ "ldr x3, [x2, #80]",
+ "eor x3, x3, x17",
+ "and x3, x6, x3",
+ "eor x13, x13, x3",
+ "ldr x3, [x2, #40]",
+ "eor x3, x3, x8",
+ "ldr x17, [x2, #64]",
+ "ldr x10, [x2, #112]",
+ "eor x10, x17, x10",
+ "and x10, x4, x10",
+ "eor x3, x3, x10",
+ "and x4, x4, x8",
+ "eor x17, x17, x4",
+ "and x6, x6, x17",
+ "eor x3, x3, x6",
+ "and x5, x5, x3",
+ "eor x6, x13, x5",
+ "ldr x3, [x2, #72]",
+ "add x4, x11, #0",
+ "add x5, x12, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #38",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #62",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #48",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #56",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #15",
+ "add x11, x10, #0",
+ "lsr x11, x11, #24",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #16",
+ "add x11, x10, #0",
+ "lsr x11, x11, #25",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #17",
+ "add x11, x10, #0",
+ "lsr x11, x11, #26",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #18",
+ "add x11, x10, #0",
+ "lsr x11, x11, #27",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #19",
+ "add x11, x10, #0",
+ "lsr x11, x11, #28",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #20",
+ "add x11, x10, #0",
+ "lsr x11, x11, #29",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x6, x10",
+ "eor x12, x12, x9",
+ "and x13, x4, x6",
+ "eor x14, x12, x13",
+ "and x15, x8, x14",
+ "eor x16, x12, x15",
+ "eor x17, x6, x4",
+ "str x15, [x2, #32]",
+ "eor x15, x17, x10",
+ "eor x15, x15, x9",
+ "str x6, [x2, #40]",
+ "and x6, x8, x15",
+ "str x3, [x2, #48]",
+ "eor x3, x17, x6",
+ "and x3, x7, x3",
+ "eor x16, x16, x3",
+ "eor x3, x4, x10",
+ "eor x3, x3, x9",
+ "str x17, [x2, #56]",
+ "eor x17, x4, x6",
+ "str x6, [x2, #64]",
+ "and x6, x7, x17",
+ "str x11, [x2, #72]",
+ "eor x11, x3, x6",
+ "and x11, x5, x11",
+ "eor x16, x16, x11",
+ "eor x11, x14, x10",
+ "eor x11, x11, x9",
+ "and x11, x8, x11",
+ "eor x11, x15, x11",
+ "and x11, x7, x11",
+ "eor x17, x17, x11",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x11, x4, x12",
+ "str x6, [x2, #80]",
+ "ldr x6, [x2, #72]",
+ "eor x6, x6, x11",
+ "str x3, [x2, #72]",
+ "and x3, x8, x6",
+ "eor x13, x13, x3",
+ "str x6, [x2, #88]",
+ "ldr x6, [x2, #56]",
+ "and x6, x7, x6",
+ "eor x13, x13, x6",
+ "and x13, x5, x13",
+ "eor x17, x17, x13",
+ "ldr x13, [x2, #48]",
+ "str x6, [x2, #56]",
+ "and x6, x13, x17",
+ "eor x16, x16, x6",
+ "and x6, x8, x11",
+ "eor x15, x15, x6",
+ "str x16, [x2, #96]",
+ "eor x16, x3, x10",
+ "eor x16, x16, x9",
+ "and x16, x7, x16",
+ "eor x16, x15, x16",
+ "str x8, [x2, #104]",
+ "eor x8, x11, x3",
+ "str x11, [x2, #112]",
+ "ldr x11, [x2, #40]",
+ "str x6, [x2, #120]",
+ "ldr x6, [x2, #64]",
+ "eor x6, x11, x6",
+ "and x6, x7, x6",
+ "eor x8, x8, x6",
+ "and x8, x5, x8",
+ "eor x16, x16, x8",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x17, x13, x17",
+ "eor x16, x16, x17",
+ "eor x14, x14, x3",
+ "and x12, x7, x12",
+ "eor x14, x14, x12",
+ "eor x4, x4, x6",
+ "and x4, x5, x4",
+ "eor x14, x14, x4",
+ "eor x15, x15, x10",
+ "eor x15, x15, x9",
+ "ldr x4, [x2, #88]",
+ "ldr x6, [x2, #120]",
+ "eor x4, x4, x6",
+ "and x4, x7, x4",
+ "eor x15, x15, x4",
+ "ldr x4, [x2, #72]",
+ "ldr x12, [x2, #32]",
+ "eor x4, x4, x12",
+ "ldr x3, [x2, #56]",
+ "eor x4, x4, x3",
+ "and x4, x5, x4",
+ "eor x15, x15, x4",
+ "and x4, x13, x15",
+ "eor x14, x14, x4",
+ "ldr x4, [x2, #112]",
+ "ldr x3, [x2, #104]",
+ "eor x3, x4, x3",
+ "eor x11, x11, x4",
+ "eor x11, x11, x6",
+ "and x7, x7, x11",
+ "eor x3, x3, x7",
+ "eor x12, x12, x10",
+ "eor x12, x12, x9",
+ "ldr x7, [x2, #80]",
+ "eor x12, x12, x7",
+ "and x5, x5, x12",
+ "eor x3, x3, x5",
+ "eor x15, x15, x10",
+ "eor x15, x15, x9",
+ "and x13, x13, x15",
+ "eor x6, x3, x13",
+ "ldr x3, [x2, #96]",
+ "add x4, x16, #0",
+ "add x5, x14, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #33",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #42",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #52",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #58",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #11",
+ "add x11, x10, #0",
+ "lsr x11, x11, #18",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #12",
+ "add x11, x10, #0",
+ "lsr x11, x11, #19",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #13",
+ "add x11, x10, #0",
+ "lsr x11, x11, #20",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #14",
+ "add x11, x10, #0",
+ "lsr x11, x11, #21",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #15",
+ "add x11, x10, #0",
+ "lsr x11, x11, #22",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #16",
+ "add x11, x10, #0",
+ "lsr x11, x11, #23",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x6, x10",
+ "eor x12, x12, x9",
+ "and x13, x12, x8",
+ "eor x14, x11, x13",
+ "eor x3, x3, x10",
+ "eor x3, x3, x9",
+ "and x15, x3, x14",
+ "eor x16, x8, x15",
+ "eor x17, x8, x10",
+ "eor x17, x17, x9",
+ "str x15, [x2, #32]",
+ "and x15, x12, x17",
+ "str x11, [x2, #40]",
+ "eor x11, x17, x15",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "str x15, [x2, #48]",
+ "and x15, x7, x11",
+ "eor x15, x16, x15",
+ "str x16, [x2, #56]",
+ "eor x16, x17, x13",
+ "str x14, [x2, #64]",
+ "and x14, x7, x16",
+ "eor x14, x6, x14",
+ "eor x5, x5, x10",
+ "eor x5, x5, x9",
+ "and x14, x5, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x17",
+ "eor x14, x12, x14",
+ "str x6, [x2, #72]",
+ "eor x6, x8, x12",
+ "and x13, x3, x13",
+ "eor x13, x6, x13",
+ "and x13, x7, x13",
+ "eor x14, x14, x13",
+ "eor x13, x11, x10",
+ "eor x13, x13, x9",
+ "and x13, x3, x13",
+ "str x12, [x2, #80]",
+ "eor x12, x17, x3",
+ "and x12, x7, x12",
+ "eor x13, x13, x12",
+ "and x13, x5, x13",
+ "eor x14, x14, x13",
+ "eor x4, x4, x10",
+ "eor x4, x4, x9",
+ "and x14, x4, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x11",
+ "ldr x13, [x2, #64]",
+ "eor x12, x13, x14",
+ "eor x12, x12, x7",
+ "str x15, [x2, #88]",
+ "ldr x15, [x2, #48]",
+ "eor x13, x15, x10",
+ "eor x13, x13, x9",
+ "str x10, [x2, #96]",
+ "and x10, x3, x13",
+ "str x6, [x2, #104]",
+ "ldr x6, [x2, #40]",
+ "eor x6, x6, x10",
+ "and x15, x3, x15",
+ "str x13, [x2, #48]",
+ "and x13, x7, x15",
+ "eor x6, x6, x13",
+ "and x6, x5, x6",
+ "eor x12, x12, x6",
+ "eor x15, x16, x15",
+ "and x15, x7, x15",
+ "ldr x6, [x2, #72]",
+ "eor x15, x6, x15",
+ "and x8, x3, x8",
+ "eor x17, x17, x8",
+ "and x13, x7, x17",
+ "eor x13, x10, x13",
+ "and x13, x5, x13",
+ "eor x15, x15, x13",
+ "and x15, x4, x15",
+ "eor x12, x12, x15",
+ "eor x15, x11, x3",
+ "eor x15, x15, x7",
+ "ldr x13, [x2, #48]",
+ "eor x13, x13, x14",
+ "ldr x14, [x2, #104]",
+ "str x12, [x2, #48]",
+ "eor x12, x14, x10",
+ "and x12, x7, x12",
+ "eor x13, x13, x12",
+ "and x13, x5, x13",
+ "eor x15, x15, x13",
+ "ldr x13, [x2, #96]",
+ "eor x12, x14, x13",
+ "eor x12, x12, x9",
+ "str x8, [x2, #40]",
+ "and x8, x3, x12",
+ "eor x11, x11, x8",
+ "and x11, x5, x11",
+ "str x8, [x2, #112]",
+ "ldr x8, [x2, #64]",
+ "eor x8, x8, x11",
+ "and x8, x4, x8",
+ "eor x15, x15, x8",
+ "ldr x8, [x2, #80]",
+ "eor x8, x8, x10",
+ "ldr x10, [x2, #56]",
+ "and x10, x7, x10",
+ "eor x8, x8, x10",
+ "eor x10, x16, x3",
+ "and x10, x7, x10",
+ "eor x17, x17, x10",
+ "and x17, x5, x17",
+ "eor x8, x8, x17",
+ "ldr x17, [x2, #32]",
+ "eor x12, x12, x17",
+ "and x3, x3, x6",
+ "eor x14, x14, x3",
+ "and x14, x7, x14",
+ "eor x12, x12, x14",
+ "eor x16, x16, x13",
+ "eor x16, x16, x9",
+ "ldr x14, [x2, #112]",
+ "eor x16, x16, x14",
+ "ldr x14, [x2, #40]",
+ "eor x14, x14, x13",
+ "eor x14, x14, x9",
+ "and x7, x7, x14",
+ "eor x16, x16, x7",
+ "and x5, x5, x16",
+ "eor x12, x12, x5",
+ "and x4, x4, x12",
+ "eor x6, x8, x4",
+ "ldr x3, [x2, #88]",
+ "ldr x4, [x2, #48]",
+ "add x5, x15, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #35",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #57",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #46",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #40",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #7",
+ "add x11, x10, #0",
+ "lsr x11, x11, #12",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #8",
+ "add x11, x10, #0",
+ "lsr x11, x11, #13",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #9",
+ "add x11, x10, #0",
+ "lsr x11, x11, #14",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #10",
+ "add x11, x10, #0",
+ "lsr x11, x11, #15",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #11",
+ "add x11, x10, #0",
+ "lsr x11, x11, #16",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #12",
+ "add x11, x10, #0",
+ "lsr x11, x11, #17",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x7, x10",
+ "eor x12, x12, x9",
+ "and x13, x6, x12",
+ "eor x14, x13, x4",
+ "eor x15, x7, x13",
+ "and x16, x4, x6",
+ "eor x17, x15, x16",
+ "and x17, x5, x17",
+ "eor x14, x14, x17",
+ "eor x17, x16, x10",
+ "eor x17, x17, x9",
+ "str x16, [x2, #32]",
+ "eor x16, x6, x10",
+ "eor x16, x16, x9",
+ "str x15, [x2, #40]",
+ "and x15, x4, x16",
+ "str x16, [x2, #48]",
+ "eor x16, x6, x15",
+ "str x15, [x2, #56]",
+ "and x15, x5, x16",
+ "eor x17, x17, x15",
+ "and x17, x8, x17",
+ "eor x14, x14, x17",
+ "eor x17, x12, x6",
+ "str x16, [x2, #64]",
+ "and x16, x4, x17",
+ "str x15, [x2, #72]",
+ "eor x15, x13, x16",
+ "and x15, x5, x15",
+ "and x6, x6, x7",
+ "str x11, [x2, #80]",
+ "eor x11, x12, x6",
+ "str x12, [x2, #88]",
+ "eor x12, x17, x10",
+ "eor x12, x12, x9",
+ "eor x12, x12, x16",
+ "and x12, x5, x12",
+ "eor x12, x11, x12",
+ "and x12, x8, x12",
+ "eor x15, x15, x12",
+ "and x15, x3, x15",
+ "eor x14, x14, x15",
+ "and x15, x4, x13",
+ "eor x12, x6, x15",
+ "and x7, x4, x7",
+ "str x14, [x2, #96]",
+ "ldr x14, [x2, #80]",
+ "eor x14, x14, x7",
+ "str x11, [x2, #80]",
+ "and x11, x5, x14",
+ "eor x12, x12, x11",
+ "ldr x11, [x2, #40]",
+ "str x16, [x2, #104]",
+ "ldr x16, [x2, #56]",
+ "eor x11, x11, x16",
+ "and x7, x5, x7",
+ "eor x11, x11, x7",
+ "and x11, x8, x11",
+ "eor x12, x12, x11",
+ "and x11, x5, x4",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "eor x11, x11, x15",
+ "str x15, [x2, #48]",
+ "ldr x15, [x2, #88]",
+ "str x7, [x2, #40]",
+ "and x7, x4, x15",
+ "str x6, [x2, #112]",
+ "and x6, x5, x7",
+ "eor x11, x11, x6",
+ "and x11, x8, x11",
+ "eor x14, x14, x11",
+ "and x14, x3, x14",
+ "eor x12, x12, x14",
+ "eor x17, x17, x16",
+ "ldr x14, [x2, #32]",
+ "eor x15, x15, x14",
+ "and x15, x5, x15",
+ "eor x17, x17, x15",
+ "eor x15, x13, x10",
+ "eor x15, x15, x9",
+ "ldr x14, [x2, #112]",
+ "and x11, x4, x14",
+ "eor x11, x15, x11",
+ "ldr x6, [x2, #104]",
+ "and x6, x5, x6",
+ "eor x11, x11, x6",
+ "and x11, x8, x11",
+ "eor x17, x17, x11",
+ "ldr x11, [x2, #40]",
+ "eor x11, x11, x10",
+ "eor x11, x11, x9",
+ "ldr x10, [x2, #48]",
+ "eor x13, x13, x10",
+ "eor x14, x14, x4",
+ "and x14, x5, x14",
+ "eor x13, x13, x14",
+ "and x13, x8, x13",
+ "eor x11, x11, x13",
+ "and x11, x3, x11",
+ "eor x17, x17, x11",
+ "ldr x11, [x2, #80]",
+ "eor x13, x11, x4",
+ "ldr x14, [x2, #72]",
+ "eor x13, x13, x14",
+ "ldr x14, [x2, #64]",
+ "and x10, x8, x14",
+ "eor x13, x13, x10",
+ "eor x16, x15, x16",
+ "and x16, x5, x16",
+ "eor x14, x14, x16",
+ "and x4, x4, x15",
+ "eor x15, x15, x4",
+ "eor x11, x11, x7",
+ "and x5, x5, x11",
+ "eor x15, x15, x5",
+ "and x8, x8, x15",
+ "eor x14, x14, x8",
+ "and x3, x3, x14",
+ "eor x6, x13, x3",
+ "ldr x3, [x2, #96]",
+ "add x4, x12, #0",
+ "add x5, x17, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #51",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #43",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #61",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #36",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #3",
+ "add x11, x10, #0",
+ "lsr x11, x11, #6",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #4",
+ "add x11, x10, #0",
+ "lsr x11, x11, #7",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #5",
+ "add x11, x10, #0",
+ "lsr x11, x11, #8",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #6",
+ "add x11, x10, #0",
+ "lsr x11, x11, #9",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #7",
+ "add x11, x10, #0",
+ "lsr x11, x11, #10",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #8",
+ "add x11, x10, #0",
+ "lsr x11, x11, #11",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x3",
+ "and x13, x3, x8",
+ "and x14, x5, x13",
+ "eor x15, x12, x14",
+ "eor x16, x13, x10",
+ "eor x16, x16, x9",
+ "and x17, x5, x16",
+ "str x14, [x2, #32]",
+ "eor x14, x11, x17",
+ "str x12, [x2, #40]",
+ "and x12, x6, x14",
+ "eor x15, x15, x12",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "str x8, [x2, #48]",
+ "and x8, x3, x12",
+ "str x12, [x2, #56]",
+ "and x12, x5, x8",
+ "str x8, [x2, #64]",
+ "eor x8, x11, x12",
+ "str x11, [x2, #72]",
+ "and x11, x6, x16",
+ "eor x8, x8, x11",
+ "and x8, x7, x8",
+ "eor x15, x15, x8",
+ "and x8, x6, x17",
+ "eor x14, x14, x8",
+ "and x8, x5, x3",
+ "eor x8, x13, x8",
+ "and x8, x7, x8",
+ "eor x14, x14, x8",
+ "and x14, x4, x14",
+ "eor x15, x15, x14",
+ "eor x14, x13, x5",
+ "ldr x8, [x2, #40]",
+ "str x15, [x2, #80]",
+ "eor x15, x8, x10",
+ "eor x15, x15, x9",
+ "str x11, [x2, #88]",
+ "eor x11, x15, x12",
+ "and x11, x6, x11",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "and x8, x5, x11",
+ "str x16, [x2, #96]",
+ "ldr x16, [x2, #72]",
+ "str x17, [x2, #104]",
+ "eor x17, x16, x8",
+ "eor x13, x11, x13",
+ "eor x16, x13, x12",
+ "and x16, x6, x16",
+ "eor x17, x17, x16",
+ "and x17, x7, x17",
+ "eor x14, x14, x17",
+ "ldr x17, [x2, #56]",
+ "str x12, [x2, #112]",
+ "ldr x12, [x2, #64]",
+ "str x8, [x2, #120]",
+ "eor x8, x17, x12",
+ "eor x3, x3, x10",
+ "eor x3, x3, x9",
+ "and x3, x5, x3",
+ "eor x3, x8, x3",
+ "eor x3, x3, x16",
+ "and x16, x5, x15",
+ "str x8, [x2, #128]",
+ "and x8, x6, x13",
+ "eor x16, x16, x8",
+ "and x16, x7, x16",
+ "eor x3, x3, x16",
+ "and x3, x4, x3",
+ "eor x14, x14, x3",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x17, x5, x17",
+ "eor x10, x13, x17",
+ "and x3, x6, x11",
+ "eor x10, x10, x3",
+ "ldr x16, [x2, #104]",
+ "eor x15, x15, x16",
+ "ldr x16, [x2, #96]",
+ "ldr x8, [x2, #120]",
+ "eor x16, x16, x8",
+ "and x16, x6, x16",
+ "eor x15, x15, x16",
+ "and x15, x7, x15",
+ "eor x10, x10, x15",
+ "ldr x15, [x2, #40]",
+ "and x15, x5, x15",
+ "and x15, x6, x15",
+ "ldr x16, [x2, #72]",
+ "eor x16, x16, x15",
+ "ldr x15, [x2, #112]",
+ "and x15, x7, x15",
+ "eor x16, x16, x15",
+ "and x16, x4, x16",
+ "eor x10, x10, x16",
+ "eor x12, x12, x8",
+ "ldr x16, [x2, #88]",
+ "eor x12, x12, x16",
+ "eor x17, x11, x17",
+ "ldr x16, [x2, #128]",
+ "and x5, x5, x16",
+ "eor x16, x16, x5",
+ "and x16, x6, x16",
+ "eor x17, x17, x16",
+ "and x17, x7, x17",
+ "eor x12, x12, x17",
+ "ldr x17, [x2, #32]",
+ "eor x13, x13, x17",
+ "eor x11, x11, x5",
+ "and x6, x6, x11",
+ "eor x13, x13, x6",
+ "eor x8, x8, x3",
+ "and x7, x7, x8",
+ "eor x13, x13, x7",
+ "and x4, x4, x13",
+ "eor x6, x12, x4",
+ "ldr x3, [x2, #80]",
+ "add x4, x14, #0",
+ "add x5, x10, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #39",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #54",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #44",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #31",
+ "add x11, x10, #0",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "add x11, x10, #0",
+ "lsr x11, x11, #1",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #1",
+ "add x11, x10, #0",
+ "lsr x11, x11, #2",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #2",
+ "add x11, x10, #0",
+ "lsr x11, x11, #3",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #3",
+ "add x11, x10, #0",
+ "lsr x11, x11, #4",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #4",
+ "add x11, x10, #0",
+ "lsr x11, x11, #5",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x3, x10",
+ "eor x12, x12, x9",
+ "eor x13, x8, x12",
+ "eor x6, x6, x10",
+ "eor x6, x6, x9",
+ "eor x14, x13, x6",
+ "eor x4, x4, x10",
+ "eor x4, x4, x9",
+ "eor x14, x14, x4",
+ "and x15, x6, x3",
+ "and x16, x12, x8",
+ "and x17, x6, x16",
+ "str x3, [x2, #32]",
+ "eor x3, x12, x17",
+ "and x3, x4, x3",
+ "eor x3, x15, x3",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "and x3, x7, x3",
+ "eor x14, x14, x3",
+ "eor x3, x8, x10",
+ "eor x3, x3, x9",
+ "str x13, [x2, #40]",
+ "and x13, x12, x3",
+ "str x17, [x2, #48]",
+ "eor x17, x11, x13",
+ "str x13, [x2, #56]",
+ "eor x13, x17, x15",
+ "and x13, x4, x13",
+ "eor x12, x12, x13",
+ "eor x13, x8, x16",
+ "str x17, [x2, #64]",
+ "and x17, x6, x13",
+ "eor x11, x11, x17",
+ "str x15, [x2, #72]",
+ "and x15, x4, x3",
+ "eor x11, x11, x15",
+ "and x11, x7, x11",
+ "eor x12, x12, x11",
+ "eor x5, x5, x10",
+ "eor x5, x5, x9",
+ "and x12, x5, x12",
+ "eor x14, x14, x12",
+ "eor x12, x16, x10",
+ "eor x12, x12, x9",
+ "eor x11, x12, x17",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "str x14, [x2, #80]",
+ "and x14, x6, x13",
+ "eor x3, x3, x14",
+ "and x3, x4, x3",
+ "eor x11, x11, x3",
+ "ldr x3, [x2, #48]",
+ "str x13, [x2, #88]",
+ "eor x13, x3, x10",
+ "eor x13, x13, x9",
+ "str x17, [x2, #96]",
+ "and x17, x4, x3",
+ "eor x17, x13, x17",
+ "and x17, x7, x17",
+ "eor x11, x11, x17",
+ "ldr x17, [x2, #56]",
+ "str x13, [x2, #104]",
+ "eor x13, x8, x17",
+ "str x16, [x2, #112]",
+ "ldr x16, [x2, #72]",
+ "eor x16, x13, x16",
+ "str x15, [x2, #72]",
+ "ldr x15, [x2, #40]",
+ "and x15, x4, x15",
+ "str x14, [x2, #40]",
+ "eor x14, x16, x15",
+ "eor x16, x16, x10",
+ "eor x16, x16, x9",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x13, x4, x13",
+ "eor x16, x16, x13",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "and x14, x5, x14",
+ "eor x11, x11, x14",
+ "eor x14, x17, x3",
+ "and x16, x6, x12",
+ "eor x8, x8, x16",
+ "and x16, x4, x8",
+ "eor x14, x14, x16",
+ "ldr x16, [x2, #40]",
+ "eor x16, x12, x16",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "ldr x16, [x2, #72]",
+ "eor x12, x12, x16",
+ "ldr x13, [x2, #112]",
+ "eor x3, x13, x3",
+ "eor x3, x3, x16",
+ "and x3, x7, x3",
+ "eor x12, x12, x3",
+ "and x12, x5, x12",
+ "eor x14, x14, x12",
+ "ldr x12, [x2, #104]",
+ "and x12, x4, x12",
+ "eor x8, x8, x12",
+ "and x6, x6, x17",
+ "eor x13, x13, x6",
+ "ldr x6, [x2, #32]",
+ "ldr x17, [x2, #96]",
+ "eor x6, x6, x17",
+ "and x6, x4, x6",
+ "eor x6, x13, x6",
+ "and x6, x7, x6",
+ "eor x8, x8, x6",
+ "ldr x6, [x2, #64]",
+ "eor x6, x6, x15",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "ldr x10, [x2, #88]",
+ "and x4, x4, x10",
+ "eor x13, x13, x4",
+ "and x7, x7, x13",
+ "eor x6, x6, x7",
+ "and x5, x5, x6",
+ "eor x6, x8, x5",
+ "ldr x3, [x2, #80]",
+ "add x4, x11, #0",
+ "add x5, x14, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #53",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #47",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #59",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #37",
+ "eor x19, x19, x6",
+ "add x3, x19, #0",
+ "add x19, x20, #0",
+ "add x20, x3, #0",
+ "sub x22, x22, #8",
+ "sub x21, x21, #1",
+ "cbnz x21, 20b",
+ "add x3, x19, #0",
+ "add x19, x20, #0",
+ "add x20, x3, #0",
+ "add x22, x0, #128",
+ "movz x21, #16, lsl #0",
+ "21:",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #27",
+ "add x11, x10, #0",
+ "lsr x11, x11, #42",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #28",
+ "add x11, x10, #0",
+ "lsr x11, x11, #43",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #29",
+ "add x11, x10, #0",
+ "lsr x11, x11, #44",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #30",
+ "add x11, x10, #0",
+ "lsr x11, x11, #45",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #31",
+ "add x11, x10, #0",
+ "lsr x11, x11, #46",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "add x11, x10, #0",
+ "lsr x11, x11, #47",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x10",
+ "eor x11, x11, x9",
+ "and x12, x7, x11",
+ "eor x13, x3, x7",
+ "and x14, x4, x13",
+ "eor x14, x12, x14",
+ "eor x15, x11, x12",
+ "and x16, x4, x15",
+ "eor x16, x3, x16",
+ "and x16, x8, x16",
+ "eor x14, x14, x16",
+ "and x16, x7, x3",
+ "eor x17, x16, x10",
+ "eor x17, x17, x9",
+ "str x13, [x2, #32]",
+ "and x13, x4, x17",
+ "str x3, [x2, #40]",
+ "eor x3, x16, x13",
+ "str x12, [x2, #48]",
+ "eor x12, x7, x10",
+ "eor x12, x12, x9",
+ "str x10, [x2, #56]",
+ "eor x10, x12, x13",
+ "str x13, [x2, #64]",
+ "and x13, x8, x10",
+ "eor x3, x3, x13",
+ "and x3, x6, x3",
+ "eor x14, x14, x3",
+ "and x7, x4, x7",
+ "eor x3, x17, x7",
+ "and x13, x4, x12",
+ "str x7, [x2, #72]",
+ "eor x7, x11, x13",
+ "and x7, x8, x7",
+ "eor x3, x3, x7",
+ "and x7, x4, x11",
+ "str x12, [x2, #80]",
+ "eor x12, x15, x7",
+ "and x12, x8, x12",
+ "and x12, x6, x12",
+ "eor x3, x3, x12",
+ "and x3, x5, x3",
+ "eor x3, x14, x3",
+ "eor x11, x11, x16",
+ "eor x16, x11, x13",
+ "ldr x14, [x2, #48]",
+ "ldr x12, [x2, #56]",
+ "str x3, [x2, #88]",
+ "eor x3, x14, x12",
+ "eor x3, x3, x9",
+ "and x11, x4, x11",
+ "eor x11, x3, x11",
+ "str x10, [x2, #96]",
+ "and x10, x8, x11",
+ "eor x16, x16, x10",
+ "eor x10, x15, x12",
+ "eor x10, x10, x9",
+ "eor x13, x10, x13",
+ "and x12, x4, x14",
+ "eor x14, x14, x12",
+ "and x14, x8, x14",
+ "eor x12, x13, x14",
+ "and x12, x6, x12",
+ "eor x16, x16, x12",
+ "eor x11, x11, x14",
+ "ldr x14, [x2, #40]",
+ "and x12, x4, x14",
+ "eor x14, x3, x12",
+ "and x14, x8, x14",
+ "str x3, [x2, #48]",
+ "eor x3, x15, x14",
+ "and x3, x6, x3",
+ "eor x11, x11, x3",
+ "and x11, x5, x11",
+ "eor x16, x16, x11",
+ "eor x11, x15, x12",
+ "and x3, x8, x13",
+ "eor x11, x11, x3",
+ "eor x17, x17, x7",
+ "and x10, x4, x10",
+ "ldr x7, [x2, #48]",
+ "eor x7, x7, x10",
+ "and x7, x8, x7",
+ "eor x17, x17, x7",
+ "and x17, x6, x17",
+ "eor x11, x11, x17",
+ "ldr x17, [x2, #64]",
+ "and x7, x8, x17",
+ "eor x13, x13, x7",
+ "ldr x7, [x2, #40]",
+ "eor x7, x7, x12",
+ "eor x7, x7, x14",
+ "and x7, x6, x7",
+ "eor x13, x13, x7",
+ "and x13, x5, x13",
+ "eor x11, x11, x13",
+ "ldr x13, [x2, #32]",
+ "ldr x7, [x2, #56]",
+ "eor x13, x13, x7",
+ "eor x13, x13, x9",
+ "eor x13, x13, x4",
+ "eor x17, x17, x7",
+ "eor x17, x17, x9",
+ "and x17, x8, x17",
+ "eor x17, x13, x17",
+ "ldr x14, [x2, #96]",
+ "eor x14, x14, x7",
+ "eor x14, x14, x9",
+ "and x14, x8, x14",
+ "ldr x7, [x2, #80]",
+ "eor x7, x7, x14",
+ "and x7, x6, x7",
+ "eor x17, x17, x7",
+ "ldr x7, [x2, #72]",
+ "eor x7, x15, x7",
+ "and x7, x8, x7",
+ "eor x12, x12, x7",
+ "eor x15, x15, x4",
+ "and x8, x8, x15",
+ "eor x13, x13, x8",
+ "and x6, x6, x13",
+ "eor x12, x12, x6",
+ "and x5, x5, x12",
+ "eor x6, x17, x5",
+ "ldr x3, [x2, #88]",
+ "add x4, x16, #0",
+ "add x5, x11, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #63",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #55",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #49",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #41",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #23",
+ "add x11, x10, #0",
+ "lsr x11, x11, #36",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #24",
+ "add x11, x10, #0",
+ "lsr x11, x11, #37",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #25",
+ "add x11, x10, #0",
+ "lsr x11, x11, #38",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #26",
+ "add x11, x10, #0",
+ "lsr x11, x11, #39",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #27",
+ "add x11, x10, #0",
+ "lsr x11, x11, #40",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #28",
+ "add x11, x10, #0",
+ "lsr x11, x11, #41",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "and x13, x4, x8",
+ "eor x14, x8, x13",
+ "and x15, x3, x14",
+ "eor x15, x12, x15",
+ "eor x16, x13, x10",
+ "eor x16, x16, x9",
+ "and x17, x3, x16",
+ "str x16, [x2, #32]",
+ "eor x16, x14, x17",
+ "and x16, x7, x16",
+ "eor x15, x15, x16",
+ "str x17, [x2, #40]",
+ "and x17, x4, x12",
+ "str x16, [x2, #48]",
+ "eor x16, x12, x17",
+ "eor x14, x14, x10",
+ "eor x14, x14, x9",
+ "str x12, [x2, #56]",
+ "and x12, x3, x14",
+ "str x14, [x2, #64]",
+ "eor x14, x16, x12",
+ "str x12, [x2, #72]",
+ "eor x12, x16, x10",
+ "eor x12, x12, x9",
+ "str x16, [x2, #80]",
+ "and x16, x3, x12",
+ "eor x16, x4, x16",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x17",
+ "eor x14, x11, x14",
+ "eor x16, x8, x4",
+ "str x17, [x2, #88]",
+ "and x17, x3, x16",
+ "str x11, [x2, #96]",
+ "eor x11, x4, x17",
+ "and x11, x7, x11",
+ "eor x14, x14, x11",
+ "and x14, x5, x14",
+ "eor x15, x15, x14",
+ "eor x16, x16, x10",
+ "eor x16, x16, x9",
+ "and x13, x3, x13",
+ "eor x14, x16, x13",
+ "ldr x11, [x2, #64]",
+ "eor x11, x11, x17",
+ "and x11, x7, x11",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "eor x12, x12, x11",
+ "and x12, x6, x12",
+ "eor x14, x14, x12",
+ "ldr x12, [x2, #80]",
+ "and x11, x3, x12",
+ "eor x11, x8, x11",
+ "and x11, x7, x11",
+ "ldr x17, [x2, #32]",
+ "eor x11, x17, x11",
+ "str x15, [x2, #48]",
+ "ldr x15, [x2, #56]",
+ "str x10, [x2, #64]",
+ "and x10, x3, x15",
+ "eor x12, x12, x10",
+ "and x8, x7, x8",
+ "eor x12, x12, x8",
+ "and x12, x6, x12",
+ "eor x11, x11, x12",
+ "and x11, x5, x11",
+ "eor x14, x14, x11",
+ "eor x11, x16, x3",
+ "eor x11, x11, x7",
+ "eor x12, x17, x13",
+ "and x12, x7, x12",
+ "eor x12, x3, x12",
+ "and x12, x6, x12",
+ "eor x11, x11, x12",
+ "and x3, x3, x4",
+ "ldr x4, [x2, #96]",
+ "eor x4, x4, x3",
+ "ldr x12, [x2, #40]",
+ "eor x17, x17, x12",
+ "and x17, x7, x17",
+ "eor x4, x4, x17",
+ "and x3, x6, x3",
+ "eor x4, x4, x3",
+ "and x4, x5, x4",
+ "eor x11, x11, x4",
+ "eor x16, x16, x12",
+ "ldr x12, [x2, #72]",
+ "and x12, x7, x12",
+ "eor x16, x16, x12",
+ "ldr x12, [x2, #64]",
+ "eor x4, x13, x12",
+ "eor x4, x4, x9",
+ "eor x15, x15, x10",
+ "and x15, x7, x15",
+ "eor x4, x4, x15",
+ "and x6, x6, x4",
+ "eor x16, x16, x6",
+ "ldr x6, [x2, #88]",
+ "eor x6, x6, x13",
+ "eor x12, x6, x12",
+ "eor x12, x12, x9",
+ "and x7, x7, x12",
+ "eor x6, x6, x7",
+ "and x5, x5, x6",
+ "eor x6, x16, x5",
+ "ldr x3, [x2, #48]",
+ "add x4, x14, #0",
+ "add x5, x11, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #50",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #34",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #60",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #45",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #19",
+ "add x11, x10, #0",
+ "lsr x11, x11, #30",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #20",
+ "add x11, x10, #0",
+ "lsr x11, x11, #31",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #21",
+ "add x11, x10, #0",
+ "lsr x11, x11, #32",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #22",
+ "add x11, x10, #0",
+ "lsr x11, x11, #33",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #23",
+ "add x11, x10, #0",
+ "lsr x11, x11, #34",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #24",
+ "add x11, x10, #0",
+ "lsr x11, x11, #35",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "and x13, x7, x12",
+ "eor x14, x8, x13",
+ "and x15, x7, x8",
+ "eor x16, x12, x15",
+ "and x17, x3, x16",
+ "str x13, [x2, #32]",
+ "eor x13, x14, x17",
+ "str x14, [x2, #40]",
+ "eor x14, x16, x10",
+ "eor x14, x14, x9",
+ "and x15, x3, x15",
+ "str x10, [x2, #48]",
+ "eor x10, x14, x15",
+ "str x14, [x2, #56]",
+ "and x14, x4, x10",
+ "eor x14, x13, x14",
+ "str x13, [x2, #64]",
+ "and x13, x4, x16",
+ "eor x10, x10, x13",
+ "and x10, x6, x10",
+ "eor x14, x14, x10",
+ "and x8, x3, x8",
+ "eor x11, x11, x8",
+ "and x10, x4, x12",
+ "eor x11, x11, x10",
+ "and x15, x6, x15",
+ "eor x11, x11, x15",
+ "and x11, x5, x11",
+ "eor x14, x14, x11",
+ "eor x11, x12, x7",
+ "eor x17, x11, x17",
+ "ldr x15, [x2, #32]",
+ "ldr x10, [x2, #48]",
+ "eor x13, x15, x10",
+ "eor x13, x13, x9",
+ "str x14, [x2, #72]",
+ "and x14, x3, x15",
+ "eor x14, x13, x14",
+ "str x16, [x2, #80]",
+ "and x16, x4, x14",
+ "str x11, [x2, #88]",
+ "eor x11, x17, x16",
+ "str x8, [x2, #96]",
+ "eor x8, x7, x10",
+ "eor x8, x8, x9",
+ "and x15, x3, x8",
+ "eor x7, x7, x15",
+ "str x8, [x2, #104]",
+ "and x8, x3, x12",
+ "eor x12, x12, x8",
+ "and x12, x4, x12",
+ "eor x7, x7, x12",
+ "and x7, x6, x7",
+ "eor x11, x11, x7",
+ "ldr x7, [x2, #64]",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x17, x4, x17",
+ "eor x7, x7, x17",
+ "ldr x17, [x2, #40]",
+ "eor x12, x17, x10",
+ "eor x12, x12, x9",
+ "and x17, x3, x12",
+ "str x12, [x2, #64]",
+ "eor x12, x13, x17",
+ "str x17, [x2, #112]",
+ "eor x17, x8, x10",
+ "eor x17, x17, x9",
+ "and x17, x4, x17",
+ "eor x12, x12, x17",
+ "and x12, x6, x12",
+ "eor x7, x7, x12",
+ "and x7, x5, x7",
+ "eor x11, x11, x7",
+ "and x7, x3, x13",
+ "ldr x12, [x2, #56]",
+ "eor x12, x12, x7",
+ "eor x7, x14, x10",
+ "eor x7, x7, x9",
+ "and x7, x4, x7",
+ "eor x12, x12, x7",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x12, x12, x14",
+ "ldr x14, [x2, #32]",
+ "eor x15, x14, x15",
+ "eor x15, x15, x17",
+ "ldr x17, [x2, #96]",
+ "and x16, x4, x17",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x15, x15, x14",
+ "and x15, x5, x15",
+ "eor x12, x12, x15",
+ "eor x13, x13, x17",
+ "eor x13, x13, x4",
+ "ldr x17, [x2, #88]",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x3, x3, x17",
+ "ldr x17, [x2, #104]",
+ "eor x17, x17, x3",
+ "and x17, x4, x17",
+ "ldr x3, [x2, #80]",
+ "eor x3, x3, x17",
+ "and x3, x6, x3",
+ "eor x13, x13, x3",
+ "ldr x3, [x2, #40]",
+ "eor x3, x3, x8",
+ "ldr x17, [x2, #64]",
+ "ldr x10, [x2, #112]",
+ "eor x10, x17, x10",
+ "and x10, x4, x10",
+ "eor x3, x3, x10",
+ "and x4, x4, x8",
+ "eor x17, x17, x4",
+ "and x6, x6, x17",
+ "eor x3, x3, x6",
+ "and x5, x5, x3",
+ "eor x6, x13, x5",
+ "ldr x3, [x2, #72]",
+ "add x4, x11, #0",
+ "add x5, x12, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #38",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #62",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #48",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #56",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #15",
+ "add x11, x10, #0",
+ "lsr x11, x11, #24",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #16",
+ "add x11, x10, #0",
+ "lsr x11, x11, #25",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #17",
+ "add x11, x10, #0",
+ "lsr x11, x11, #26",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #18",
+ "add x11, x10, #0",
+ "lsr x11, x11, #27",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #19",
+ "add x11, x10, #0",
+ "lsr x11, x11, #28",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #20",
+ "add x11, x10, #0",
+ "lsr x11, x11, #29",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x6, x10",
+ "eor x12, x12, x9",
+ "and x13, x4, x6",
+ "eor x14, x12, x13",
+ "and x15, x8, x14",
+ "eor x16, x12, x15",
+ "eor x17, x6, x4",
+ "str x15, [x2, #32]",
+ "eor x15, x17, x10",
+ "eor x15, x15, x9",
+ "str x6, [x2, #40]",
+ "and x6, x8, x15",
+ "str x3, [x2, #48]",
+ "eor x3, x17, x6",
+ "and x3, x7, x3",
+ "eor x16, x16, x3",
+ "eor x3, x4, x10",
+ "eor x3, x3, x9",
+ "str x17, [x2, #56]",
+ "eor x17, x4, x6",
+ "str x6, [x2, #64]",
+ "and x6, x7, x17",
+ "str x11, [x2, #72]",
+ "eor x11, x3, x6",
+ "and x11, x5, x11",
+ "eor x16, x16, x11",
+ "eor x11, x14, x10",
+ "eor x11, x11, x9",
+ "and x11, x8, x11",
+ "eor x11, x15, x11",
+ "and x11, x7, x11",
+ "eor x17, x17, x11",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x11, x4, x12",
+ "str x6, [x2, #80]",
+ "ldr x6, [x2, #72]",
+ "eor x6, x6, x11",
+ "str x3, [x2, #72]",
+ "and x3, x8, x6",
+ "eor x13, x13, x3",
+ "str x6, [x2, #88]",
+ "ldr x6, [x2, #56]",
+ "and x6, x7, x6",
+ "eor x13, x13, x6",
+ "and x13, x5, x13",
+ "eor x17, x17, x13",
+ "ldr x13, [x2, #48]",
+ "str x6, [x2, #56]",
+ "and x6, x13, x17",
+ "eor x16, x16, x6",
+ "and x6, x8, x11",
+ "eor x15, x15, x6",
+ "str x16, [x2, #96]",
+ "eor x16, x3, x10",
+ "eor x16, x16, x9",
+ "and x16, x7, x16",
+ "eor x16, x15, x16",
+ "str x8, [x2, #104]",
+ "eor x8, x11, x3",
+ "str x11, [x2, #112]",
+ "ldr x11, [x2, #40]",
+ "str x6, [x2, #120]",
+ "ldr x6, [x2, #64]",
+ "eor x6, x11, x6",
+ "and x6, x7, x6",
+ "eor x8, x8, x6",
+ "and x8, x5, x8",
+ "eor x16, x16, x8",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x17, x13, x17",
+ "eor x16, x16, x17",
+ "eor x14, x14, x3",
+ "and x12, x7, x12",
+ "eor x14, x14, x12",
+ "eor x4, x4, x6",
+ "and x4, x5, x4",
+ "eor x14, x14, x4",
+ "eor x15, x15, x10",
+ "eor x15, x15, x9",
+ "ldr x4, [x2, #88]",
+ "ldr x6, [x2, #120]",
+ "eor x4, x4, x6",
+ "and x4, x7, x4",
+ "eor x15, x15, x4",
+ "ldr x4, [x2, #72]",
+ "ldr x12, [x2, #32]",
+ "eor x4, x4, x12",
+ "ldr x3, [x2, #56]",
+ "eor x4, x4, x3",
+ "and x4, x5, x4",
+ "eor x15, x15, x4",
+ "and x4, x13, x15",
+ "eor x14, x14, x4",
+ "ldr x4, [x2, #112]",
+ "ldr x3, [x2, #104]",
+ "eor x3, x4, x3",
+ "eor x11, x11, x4",
+ "eor x11, x11, x6",
+ "and x7, x7, x11",
+ "eor x3, x3, x7",
+ "eor x12, x12, x10",
+ "eor x12, x12, x9",
+ "ldr x7, [x2, #80]",
+ "eor x12, x12, x7",
+ "and x5, x5, x12",
+ "eor x3, x3, x5",
+ "eor x15, x15, x10",
+ "eor x15, x15, x9",
+ "and x13, x13, x15",
+ "eor x6, x3, x13",
+ "ldr x3, [x2, #96]",
+ "add x4, x16, #0",
+ "add x5, x14, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #33",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #42",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #52",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #58",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #11",
+ "add x11, x10, #0",
+ "lsr x11, x11, #18",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #12",
+ "add x11, x10, #0",
+ "lsr x11, x11, #19",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #13",
+ "add x11, x10, #0",
+ "lsr x11, x11, #20",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #14",
+ "add x11, x10, #0",
+ "lsr x11, x11, #21",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #15",
+ "add x11, x10, #0",
+ "lsr x11, x11, #22",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #16",
+ "add x11, x10, #0",
+ "lsr x11, x11, #23",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x6, x10",
+ "eor x12, x12, x9",
+ "and x13, x12, x8",
+ "eor x14, x11, x13",
+ "eor x3, x3, x10",
+ "eor x3, x3, x9",
+ "and x15, x3, x14",
+ "eor x16, x8, x15",
+ "eor x17, x8, x10",
+ "eor x17, x17, x9",
+ "str x15, [x2, #32]",
+ "and x15, x12, x17",
+ "str x11, [x2, #40]",
+ "eor x11, x17, x15",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "str x15, [x2, #48]",
+ "and x15, x7, x11",
+ "eor x15, x16, x15",
+ "str x16, [x2, #56]",
+ "eor x16, x17, x13",
+ "str x14, [x2, #64]",
+ "and x14, x7, x16",
+ "eor x14, x6, x14",
+ "eor x5, x5, x10",
+ "eor x5, x5, x9",
+ "and x14, x5, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x17",
+ "eor x14, x12, x14",
+ "str x6, [x2, #72]",
+ "eor x6, x8, x12",
+ "and x13, x3, x13",
+ "eor x13, x6, x13",
+ "and x13, x7, x13",
+ "eor x14, x14, x13",
+ "eor x13, x11, x10",
+ "eor x13, x13, x9",
+ "and x13, x3, x13",
+ "str x12, [x2, #80]",
+ "eor x12, x17, x3",
+ "and x12, x7, x12",
+ "eor x13, x13, x12",
+ "and x13, x5, x13",
+ "eor x14, x14, x13",
+ "eor x4, x4, x10",
+ "eor x4, x4, x9",
+ "and x14, x4, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x11",
+ "ldr x13, [x2, #64]",
+ "eor x12, x13, x14",
+ "eor x12, x12, x7",
+ "str x15, [x2, #88]",
+ "ldr x15, [x2, #48]",
+ "eor x13, x15, x10",
+ "eor x13, x13, x9",
+ "str x10, [x2, #96]",
+ "and x10, x3, x13",
+ "str x6, [x2, #104]",
+ "ldr x6, [x2, #40]",
+ "eor x6, x6, x10",
+ "and x15, x3, x15",
+ "str x13, [x2, #48]",
+ "and x13, x7, x15",
+ "eor x6, x6, x13",
+ "and x6, x5, x6",
+ "eor x12, x12, x6",
+ "eor x15, x16, x15",
+ "and x15, x7, x15",
+ "ldr x6, [x2, #72]",
+ "eor x15, x6, x15",
+ "and x8, x3, x8",
+ "eor x17, x17, x8",
+ "and x13, x7, x17",
+ "eor x13, x10, x13",
+ "and x13, x5, x13",
+ "eor x15, x15, x13",
+ "and x15, x4, x15",
+ "eor x12, x12, x15",
+ "eor x15, x11, x3",
+ "eor x15, x15, x7",
+ "ldr x13, [x2, #48]",
+ "eor x13, x13, x14",
+ "ldr x14, [x2, #104]",
+ "str x12, [x2, #48]",
+ "eor x12, x14, x10",
+ "and x12, x7, x12",
+ "eor x13, x13, x12",
+ "and x13, x5, x13",
+ "eor x15, x15, x13",
+ "ldr x13, [x2, #96]",
+ "eor x12, x14, x13",
+ "eor x12, x12, x9",
+ "str x8, [x2, #40]",
+ "and x8, x3, x12",
+ "eor x11, x11, x8",
+ "and x11, x5, x11",
+ "str x8, [x2, #112]",
+ "ldr x8, [x2, #64]",
+ "eor x8, x8, x11",
+ "and x8, x4, x8",
+ "eor x15, x15, x8",
+ "ldr x8, [x2, #80]",
+ "eor x8, x8, x10",
+ "ldr x10, [x2, #56]",
+ "and x10, x7, x10",
+ "eor x8, x8, x10",
+ "eor x10, x16, x3",
+ "and x10, x7, x10",
+ "eor x17, x17, x10",
+ "and x17, x5, x17",
+ "eor x8, x8, x17",
+ "ldr x17, [x2, #32]",
+ "eor x12, x12, x17",
+ "and x3, x3, x6",
+ "eor x14, x14, x3",
+ "and x14, x7, x14",
+ "eor x12, x12, x14",
+ "eor x16, x16, x13",
+ "eor x16, x16, x9",
+ "ldr x14, [x2, #112]",
+ "eor x16, x16, x14",
+ "ldr x14, [x2, #40]",
+ "eor x14, x14, x13",
+ "eor x14, x14, x9",
+ "and x7, x7, x14",
+ "eor x16, x16, x7",
+ "and x5, x5, x16",
+ "eor x12, x12, x5",
+ "and x4, x4, x12",
+ "eor x6, x8, x4",
+ "ldr x3, [x2, #88]",
+ "ldr x4, [x2, #48]",
+ "add x5, x15, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #35",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #57",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #46",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #40",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #7",
+ "add x11, x10, #0",
+ "lsr x11, x11, #12",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #8",
+ "add x11, x10, #0",
+ "lsr x11, x11, #13",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #9",
+ "add x11, x10, #0",
+ "lsr x11, x11, #14",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #10",
+ "add x11, x10, #0",
+ "lsr x11, x11, #15",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #11",
+ "add x11, x10, #0",
+ "lsr x11, x11, #16",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #12",
+ "add x11, x10, #0",
+ "lsr x11, x11, #17",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x7, x10",
+ "eor x12, x12, x9",
+ "and x13, x6, x12",
+ "eor x14, x13, x4",
+ "eor x15, x7, x13",
+ "and x16, x4, x6",
+ "eor x17, x15, x16",
+ "and x17, x5, x17",
+ "eor x14, x14, x17",
+ "eor x17, x16, x10",
+ "eor x17, x17, x9",
+ "str x16, [x2, #32]",
+ "eor x16, x6, x10",
+ "eor x16, x16, x9",
+ "str x15, [x2, #40]",
+ "and x15, x4, x16",
+ "str x16, [x2, #48]",
+ "eor x16, x6, x15",
+ "str x15, [x2, #56]",
+ "and x15, x5, x16",
+ "eor x17, x17, x15",
+ "and x17, x8, x17",
+ "eor x14, x14, x17",
+ "eor x17, x12, x6",
+ "str x16, [x2, #64]",
+ "and x16, x4, x17",
+ "str x15, [x2, #72]",
+ "eor x15, x13, x16",
+ "and x15, x5, x15",
+ "and x6, x6, x7",
+ "str x11, [x2, #80]",
+ "eor x11, x12, x6",
+ "str x12, [x2, #88]",
+ "eor x12, x17, x10",
+ "eor x12, x12, x9",
+ "eor x12, x12, x16",
+ "and x12, x5, x12",
+ "eor x12, x11, x12",
+ "and x12, x8, x12",
+ "eor x15, x15, x12",
+ "and x15, x3, x15",
+ "eor x14, x14, x15",
+ "and x15, x4, x13",
+ "eor x12, x6, x15",
+ "and x7, x4, x7",
+ "str x14, [x2, #96]",
+ "ldr x14, [x2, #80]",
+ "eor x14, x14, x7",
+ "str x11, [x2, #80]",
+ "and x11, x5, x14",
+ "eor x12, x12, x11",
+ "ldr x11, [x2, #40]",
+ "str x16, [x2, #104]",
+ "ldr x16, [x2, #56]",
+ "eor x11, x11, x16",
+ "and x7, x5, x7",
+ "eor x11, x11, x7",
+ "and x11, x8, x11",
+ "eor x12, x12, x11",
+ "and x11, x5, x4",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "eor x11, x11, x15",
+ "str x15, [x2, #48]",
+ "ldr x15, [x2, #88]",
+ "str x7, [x2, #40]",
+ "and x7, x4, x15",
+ "str x6, [x2, #112]",
+ "and x6, x5, x7",
+ "eor x11, x11, x6",
+ "and x11, x8, x11",
+ "eor x14, x14, x11",
+ "and x14, x3, x14",
+ "eor x12, x12, x14",
+ "eor x17, x17, x16",
+ "ldr x14, [x2, #32]",
+ "eor x15, x15, x14",
+ "and x15, x5, x15",
+ "eor x17, x17, x15",
+ "eor x15, x13, x10",
+ "eor x15, x15, x9",
+ "ldr x14, [x2, #112]",
+ "and x11, x4, x14",
+ "eor x11, x15, x11",
+ "ldr x6, [x2, #104]",
+ "and x6, x5, x6",
+ "eor x11, x11, x6",
+ "and x11, x8, x11",
+ "eor x17, x17, x11",
+ "ldr x11, [x2, #40]",
+ "eor x11, x11, x10",
+ "eor x11, x11, x9",
+ "ldr x10, [x2, #48]",
+ "eor x13, x13, x10",
+ "eor x14, x14, x4",
+ "and x14, x5, x14",
+ "eor x13, x13, x14",
+ "and x13, x8, x13",
+ "eor x11, x11, x13",
+ "and x11, x3, x11",
+ "eor x17, x17, x11",
+ "ldr x11, [x2, #80]",
+ "eor x13, x11, x4",
+ "ldr x14, [x2, #72]",
+ "eor x13, x13, x14",
+ "ldr x14, [x2, #64]",
+ "and x10, x8, x14",
+ "eor x13, x13, x10",
+ "eor x16, x15, x16",
+ "and x16, x5, x16",
+ "eor x14, x14, x16",
+ "and x4, x4, x15",
+ "eor x15, x15, x4",
+ "eor x11, x11, x7",
+ "and x5, x5, x11",
+ "eor x15, x15, x5",
+ "and x8, x8, x15",
+ "eor x14, x14, x8",
+ "and x3, x3, x14",
+ "eor x6, x13, x3",
+ "ldr x3, [x2, #96]",
+ "add x4, x12, #0",
+ "add x5, x17, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #51",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #43",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #61",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #36",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #3",
+ "add x11, x10, #0",
+ "lsr x11, x11, #6",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #4",
+ "add x11, x10, #0",
+ "lsr x11, x11, #7",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #5",
+ "add x11, x10, #0",
+ "lsr x11, x11, #8",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #6",
+ "add x11, x10, #0",
+ "lsr x11, x11, #9",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #7",
+ "add x11, x10, #0",
+ "lsr x11, x11, #10",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #8",
+ "add x11, x10, #0",
+ "lsr x11, x11, #11",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x3",
+ "and x13, x3, x8",
+ "and x14, x5, x13",
+ "eor x15, x12, x14",
+ "eor x16, x13, x10",
+ "eor x16, x16, x9",
+ "and x17, x5, x16",
+ "str x14, [x2, #32]",
+ "eor x14, x11, x17",
+ "str x12, [x2, #40]",
+ "and x12, x6, x14",
+ "eor x15, x15, x12",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "str x8, [x2, #48]",
+ "and x8, x3, x12",
+ "str x12, [x2, #56]",
+ "and x12, x5, x8",
+ "str x8, [x2, #64]",
+ "eor x8, x11, x12",
+ "str x11, [x2, #72]",
+ "and x11, x6, x16",
+ "eor x8, x8, x11",
+ "and x8, x7, x8",
+ "eor x15, x15, x8",
+ "and x8, x6, x17",
+ "eor x14, x14, x8",
+ "and x8, x5, x3",
+ "eor x8, x13, x8",
+ "and x8, x7, x8",
+ "eor x14, x14, x8",
+ "and x14, x4, x14",
+ "eor x15, x15, x14",
+ "eor x14, x13, x5",
+ "ldr x8, [x2, #40]",
+ "str x15, [x2, #80]",
+ "eor x15, x8, x10",
+ "eor x15, x15, x9",
+ "str x11, [x2, #88]",
+ "eor x11, x15, x12",
+ "and x11, x6, x11",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "and x8, x5, x11",
+ "str x16, [x2, #96]",
+ "ldr x16, [x2, #72]",
+ "str x17, [x2, #104]",
+ "eor x17, x16, x8",
+ "eor x13, x11, x13",
+ "eor x16, x13, x12",
+ "and x16, x6, x16",
+ "eor x17, x17, x16",
+ "and x17, x7, x17",
+ "eor x14, x14, x17",
+ "ldr x17, [x2, #56]",
+ "str x12, [x2, #112]",
+ "ldr x12, [x2, #64]",
+ "str x8, [x2, #120]",
+ "eor x8, x17, x12",
+ "eor x3, x3, x10",
+ "eor x3, x3, x9",
+ "and x3, x5, x3",
+ "eor x3, x8, x3",
+ "eor x3, x3, x16",
+ "and x16, x5, x15",
+ "str x8, [x2, #128]",
+ "and x8, x6, x13",
+ "eor x16, x16, x8",
+ "and x16, x7, x16",
+ "eor x3, x3, x16",
+ "and x3, x4, x3",
+ "eor x14, x14, x3",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x17, x5, x17",
+ "eor x10, x13, x17",
+ "and x3, x6, x11",
+ "eor x10, x10, x3",
+ "ldr x16, [x2, #104]",
+ "eor x15, x15, x16",
+ "ldr x16, [x2, #96]",
+ "ldr x8, [x2, #120]",
+ "eor x16, x16, x8",
+ "and x16, x6, x16",
+ "eor x15, x15, x16",
+ "and x15, x7, x15",
+ "eor x10, x10, x15",
+ "ldr x15, [x2, #40]",
+ "and x15, x5, x15",
+ "and x15, x6, x15",
+ "ldr x16, [x2, #72]",
+ "eor x16, x16, x15",
+ "ldr x15, [x2, #112]",
+ "and x15, x7, x15",
+ "eor x16, x16, x15",
+ "and x16, x4, x16",
+ "eor x10, x10, x16",
+ "eor x12, x12, x8",
+ "ldr x16, [x2, #88]",
+ "eor x12, x12, x16",
+ "eor x17, x11, x17",
+ "ldr x16, [x2, #128]",
+ "and x5, x5, x16",
+ "eor x16, x16, x5",
+ "and x16, x6, x16",
+ "eor x17, x17, x16",
+ "and x17, x7, x17",
+ "eor x12, x12, x17",
+ "ldr x17, [x2, #32]",
+ "eor x13, x13, x17",
+ "eor x11, x11, x5",
+ "and x6, x6, x11",
+ "eor x13, x13, x6",
+ "eor x8, x8, x3",
+ "and x7, x7, x8",
+ "eor x13, x13, x7",
+ "and x4, x4, x13",
+ "eor x6, x12, x4",
+ "ldr x3, [x2, #80]",
+ "add x4, x14, #0",
+ "add x5, x10, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #39",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #54",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #44",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #31",
+ "add x11, x10, #0",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "add x11, x10, #0",
+ "lsr x11, x11, #1",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #1",
+ "add x11, x10, #0",
+ "lsr x11, x11, #2",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #2",
+ "add x11, x10, #0",
+ "lsr x11, x11, #3",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #3",
+ "add x11, x10, #0",
+ "lsr x11, x11, #4",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #4",
+ "add x11, x10, #0",
+ "lsr x11, x11, #5",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x3, x10",
+ "eor x12, x12, x9",
+ "eor x13, x8, x12",
+ "eor x6, x6, x10",
+ "eor x6, x6, x9",
+ "eor x14, x13, x6",
+ "eor x4, x4, x10",
+ "eor x4, x4, x9",
+ "eor x14, x14, x4",
+ "and x15, x6, x3",
+ "and x16, x12, x8",
+ "and x17, x6, x16",
+ "str x3, [x2, #32]",
+ "eor x3, x12, x17",
+ "and x3, x4, x3",
+ "eor x3, x15, x3",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "and x3, x7, x3",
+ "eor x14, x14, x3",
+ "eor x3, x8, x10",
+ "eor x3, x3, x9",
+ "str x13, [x2, #40]",
+ "and x13, x12, x3",
+ "str x17, [x2, #48]",
+ "eor x17, x11, x13",
+ "str x13, [x2, #56]",
+ "eor x13, x17, x15",
+ "and x13, x4, x13",
+ "eor x12, x12, x13",
+ "eor x13, x8, x16",
+ "str x17, [x2, #64]",
+ "and x17, x6, x13",
+ "eor x11, x11, x17",
+ "str x15, [x2, #72]",
+ "and x15, x4, x3",
+ "eor x11, x11, x15",
+ "and x11, x7, x11",
+ "eor x12, x12, x11",
+ "eor x5, x5, x10",
+ "eor x5, x5, x9",
+ "and x12, x5, x12",
+ "eor x14, x14, x12",
+ "eor x12, x16, x10",
+ "eor x12, x12, x9",
+ "eor x11, x12, x17",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "str x14, [x2, #80]",
+ "and x14, x6, x13",
+ "eor x3, x3, x14",
+ "and x3, x4, x3",
+ "eor x11, x11, x3",
+ "ldr x3, [x2, #48]",
+ "str x13, [x2, #88]",
+ "eor x13, x3, x10",
+ "eor x13, x13, x9",
+ "str x17, [x2, #96]",
+ "and x17, x4, x3",
+ "eor x17, x13, x17",
+ "and x17, x7, x17",
+ "eor x11, x11, x17",
+ "ldr x17, [x2, #56]",
+ "str x13, [x2, #104]",
+ "eor x13, x8, x17",
+ "str x16, [x2, #112]",
+ "ldr x16, [x2, #72]",
+ "eor x16, x13, x16",
+ "str x15, [x2, #72]",
+ "ldr x15, [x2, #40]",
+ "and x15, x4, x15",
+ "str x14, [x2, #40]",
+ "eor x14, x16, x15",
+ "eor x16, x16, x10",
+ "eor x16, x16, x9",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x13, x4, x13",
+ "eor x16, x16, x13",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "and x14, x5, x14",
+ "eor x11, x11, x14",
+ "eor x14, x17, x3",
+ "and x16, x6, x12",
+ "eor x8, x8, x16",
+ "and x16, x4, x8",
+ "eor x14, x14, x16",
+ "ldr x16, [x2, #40]",
+ "eor x16, x12, x16",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "ldr x16, [x2, #72]",
+ "eor x12, x12, x16",
+ "ldr x13, [x2, #112]",
+ "eor x3, x13, x3",
+ "eor x3, x3, x16",
+ "and x3, x7, x3",
+ "eor x12, x12, x3",
+ "and x12, x5, x12",
+ "eor x14, x14, x12",
+ "ldr x12, [x2, #104]",
+ "and x12, x4, x12",
+ "eor x8, x8, x12",
+ "and x6, x6, x17",
+ "eor x13, x13, x6",
+ "ldr x6, [x2, #32]",
+ "ldr x17, [x2, #96]",
+ "eor x6, x6, x17",
+ "and x6, x4, x6",
+ "eor x6, x13, x6",
+ "and x6, x7, x6",
+ "eor x8, x8, x6",
+ "ldr x6, [x2, #64]",
+ "eor x6, x6, x15",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "ldr x10, [x2, #88]",
+ "and x4, x4, x10",
+ "eor x13, x13, x4",
+ "and x7, x7, x13",
+ "eor x6, x6, x7",
+ "and x5, x5, x6",
+ "eor x6, x8, x5",
+ "ldr x3, [x2, #80]",
+ "add x4, x11, #0",
+ "add x5, x14, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #53",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #47",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #59",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #37",
+ "eor x19, x19, x6",
+ "add x3, x19, #0",
+ "add x19, x20, #0",
+ "add x20, x3, #0",
+ "add x22, x22, #8",
+ "sub x21, x21, #1",
+ "cbnz x21, 21b",
+ "add x3, x19, #0",
+ "add x19, x20, #0",
+ "add x20, x3, #0",
+ "add x22, x0, #120",
+ "movz x21, #16, lsl #0",
+ "22:",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #27",
+ "add x11, x10, #0",
+ "lsr x11, x11, #42",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #28",
+ "add x11, x10, #0",
+ "lsr x11, x11, #43",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #29",
+ "add x11, x10, #0",
+ "lsr x11, x11, #44",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #30",
+ "add x11, x10, #0",
+ "lsr x11, x11, #45",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #31",
+ "add x11, x10, #0",
+ "lsr x11, x11, #46",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "add x11, x10, #0",
+ "lsr x11, x11, #47",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x10",
+ "eor x11, x11, x9",
+ "and x12, x7, x11",
+ "eor x13, x3, x7",
+ "and x14, x4, x13",
+ "eor x14, x12, x14",
+ "eor x15, x11, x12",
+ "and x16, x4, x15",
+ "eor x16, x3, x16",
+ "and x16, x8, x16",
+ "eor x14, x14, x16",
+ "and x16, x7, x3",
+ "eor x17, x16, x10",
+ "eor x17, x17, x9",
+ "str x13, [x2, #32]",
+ "and x13, x4, x17",
+ "str x3, [x2, #40]",
+ "eor x3, x16, x13",
+ "str x12, [x2, #48]",
+ "eor x12, x7, x10",
+ "eor x12, x12, x9",
+ "str x10, [x2, #56]",
+ "eor x10, x12, x13",
+ "str x13, [x2, #64]",
+ "and x13, x8, x10",
+ "eor x3, x3, x13",
+ "and x3, x6, x3",
+ "eor x14, x14, x3",
+ "and x7, x4, x7",
+ "eor x3, x17, x7",
+ "and x13, x4, x12",
+ "str x7, [x2, #72]",
+ "eor x7, x11, x13",
+ "and x7, x8, x7",
+ "eor x3, x3, x7",
+ "and x7, x4, x11",
+ "str x12, [x2, #80]",
+ "eor x12, x15, x7",
+ "and x12, x8, x12",
+ "and x12, x6, x12",
+ "eor x3, x3, x12",
+ "and x3, x5, x3",
+ "eor x3, x14, x3",
+ "eor x11, x11, x16",
+ "eor x16, x11, x13",
+ "ldr x14, [x2, #48]",
+ "ldr x12, [x2, #56]",
+ "str x3, [x2, #88]",
+ "eor x3, x14, x12",
+ "eor x3, x3, x9",
+ "and x11, x4, x11",
+ "eor x11, x3, x11",
+ "str x10, [x2, #96]",
+ "and x10, x8, x11",
+ "eor x16, x16, x10",
+ "eor x10, x15, x12",
+ "eor x10, x10, x9",
+ "eor x13, x10, x13",
+ "and x12, x4, x14",
+ "eor x14, x14, x12",
+ "and x14, x8, x14",
+ "eor x12, x13, x14",
+ "and x12, x6, x12",
+ "eor x16, x16, x12",
+ "eor x11, x11, x14",
+ "ldr x14, [x2, #40]",
+ "and x12, x4, x14",
+ "eor x14, x3, x12",
+ "and x14, x8, x14",
+ "str x3, [x2, #48]",
+ "eor x3, x15, x14",
+ "and x3, x6, x3",
+ "eor x11, x11, x3",
+ "and x11, x5, x11",
+ "eor x16, x16, x11",
+ "eor x11, x15, x12",
+ "and x3, x8, x13",
+ "eor x11, x11, x3",
+ "eor x17, x17, x7",
+ "and x10, x4, x10",
+ "ldr x7, [x2, #48]",
+ "eor x7, x7, x10",
+ "and x7, x8, x7",
+ "eor x17, x17, x7",
+ "and x17, x6, x17",
+ "eor x11, x11, x17",
+ "ldr x17, [x2, #64]",
+ "and x7, x8, x17",
+ "eor x13, x13, x7",
+ "ldr x7, [x2, #40]",
+ "eor x7, x7, x12",
+ "eor x7, x7, x14",
+ "and x7, x6, x7",
+ "eor x13, x13, x7",
+ "and x13, x5, x13",
+ "eor x11, x11, x13",
+ "ldr x13, [x2, #32]",
+ "ldr x7, [x2, #56]",
+ "eor x13, x13, x7",
+ "eor x13, x13, x9",
+ "eor x13, x13, x4",
+ "eor x17, x17, x7",
+ "eor x17, x17, x9",
+ "and x17, x8, x17",
+ "eor x17, x13, x17",
+ "ldr x14, [x2, #96]",
+ "eor x14, x14, x7",
+ "eor x14, x14, x9",
+ "and x14, x8, x14",
+ "ldr x7, [x2, #80]",
+ "eor x7, x7, x14",
+ "and x7, x6, x7",
+ "eor x17, x17, x7",
+ "ldr x7, [x2, #72]",
+ "eor x7, x15, x7",
+ "and x7, x8, x7",
+ "eor x12, x12, x7",
+ "eor x15, x15, x4",
+ "and x8, x8, x15",
+ "eor x13, x13, x8",
+ "and x6, x6, x13",
+ "eor x12, x12, x6",
+ "and x5, x5, x12",
+ "eor x6, x17, x5",
+ "ldr x3, [x2, #88]",
+ "add x4, x16, #0",
+ "add x5, x11, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #63",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #55",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #49",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #41",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #23",
+ "add x11, x10, #0",
+ "lsr x11, x11, #36",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #24",
+ "add x11, x10, #0",
+ "lsr x11, x11, #37",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #25",
+ "add x11, x10, #0",
+ "lsr x11, x11, #38",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #26",
+ "add x11, x10, #0",
+ "lsr x11, x11, #39",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #27",
+ "add x11, x10, #0",
+ "lsr x11, x11, #40",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #28",
+ "add x11, x10, #0",
+ "lsr x11, x11, #41",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "and x13, x4, x8",
+ "eor x14, x8, x13",
+ "and x15, x3, x14",
+ "eor x15, x12, x15",
+ "eor x16, x13, x10",
+ "eor x16, x16, x9",
+ "and x17, x3, x16",
+ "str x16, [x2, #32]",
+ "eor x16, x14, x17",
+ "and x16, x7, x16",
+ "eor x15, x15, x16",
+ "str x17, [x2, #40]",
+ "and x17, x4, x12",
+ "str x16, [x2, #48]",
+ "eor x16, x12, x17",
+ "eor x14, x14, x10",
+ "eor x14, x14, x9",
+ "str x12, [x2, #56]",
+ "and x12, x3, x14",
+ "str x14, [x2, #64]",
+ "eor x14, x16, x12",
+ "str x12, [x2, #72]",
+ "eor x12, x16, x10",
+ "eor x12, x12, x9",
+ "str x16, [x2, #80]",
+ "and x16, x3, x12",
+ "eor x16, x4, x16",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x17",
+ "eor x14, x11, x14",
+ "eor x16, x8, x4",
+ "str x17, [x2, #88]",
+ "and x17, x3, x16",
+ "str x11, [x2, #96]",
+ "eor x11, x4, x17",
+ "and x11, x7, x11",
+ "eor x14, x14, x11",
+ "and x14, x5, x14",
+ "eor x15, x15, x14",
+ "eor x16, x16, x10",
+ "eor x16, x16, x9",
+ "and x13, x3, x13",
+ "eor x14, x16, x13",
+ "ldr x11, [x2, #64]",
+ "eor x11, x11, x17",
+ "and x11, x7, x11",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "eor x12, x12, x11",
+ "and x12, x6, x12",
+ "eor x14, x14, x12",
+ "ldr x12, [x2, #80]",
+ "and x11, x3, x12",
+ "eor x11, x8, x11",
+ "and x11, x7, x11",
+ "ldr x17, [x2, #32]",
+ "eor x11, x17, x11",
+ "str x15, [x2, #48]",
+ "ldr x15, [x2, #56]",
+ "str x10, [x2, #64]",
+ "and x10, x3, x15",
+ "eor x12, x12, x10",
+ "and x8, x7, x8",
+ "eor x12, x12, x8",
+ "and x12, x6, x12",
+ "eor x11, x11, x12",
+ "and x11, x5, x11",
+ "eor x14, x14, x11",
+ "eor x11, x16, x3",
+ "eor x11, x11, x7",
+ "eor x12, x17, x13",
+ "and x12, x7, x12",
+ "eor x12, x3, x12",
+ "and x12, x6, x12",
+ "eor x11, x11, x12",
+ "and x3, x3, x4",
+ "ldr x4, [x2, #96]",
+ "eor x4, x4, x3",
+ "ldr x12, [x2, #40]",
+ "eor x17, x17, x12",
+ "and x17, x7, x17",
+ "eor x4, x4, x17",
+ "and x3, x6, x3",
+ "eor x4, x4, x3",
+ "and x4, x5, x4",
+ "eor x11, x11, x4",
+ "eor x16, x16, x12",
+ "ldr x12, [x2, #72]",
+ "and x12, x7, x12",
+ "eor x16, x16, x12",
+ "ldr x12, [x2, #64]",
+ "eor x4, x13, x12",
+ "eor x4, x4, x9",
+ "eor x15, x15, x10",
+ "and x15, x7, x15",
+ "eor x4, x4, x15",
+ "and x6, x6, x4",
+ "eor x16, x16, x6",
+ "ldr x6, [x2, #88]",
+ "eor x6, x6, x13",
+ "eor x12, x6, x12",
+ "eor x12, x12, x9",
+ "and x7, x7, x12",
+ "eor x6, x6, x7",
+ "and x5, x5, x6",
+ "eor x6, x16, x5",
+ "ldr x3, [x2, #48]",
+ "add x4, x14, #0",
+ "add x5, x11, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #50",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #34",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #60",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #45",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #19",
+ "add x11, x10, #0",
+ "lsr x11, x11, #30",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #20",
+ "add x11, x10, #0",
+ "lsr x11, x11, #31",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #21",
+ "add x11, x10, #0",
+ "lsr x11, x11, #32",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #22",
+ "add x11, x10, #0",
+ "lsr x11, x11, #33",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #23",
+ "add x11, x10, #0",
+ "lsr x11, x11, #34",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #24",
+ "add x11, x10, #0",
+ "lsr x11, x11, #35",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "and x13, x7, x12",
+ "eor x14, x8, x13",
+ "and x15, x7, x8",
+ "eor x16, x12, x15",
+ "and x17, x3, x16",
+ "str x13, [x2, #32]",
+ "eor x13, x14, x17",
+ "str x14, [x2, #40]",
+ "eor x14, x16, x10",
+ "eor x14, x14, x9",
+ "and x15, x3, x15",
+ "str x10, [x2, #48]",
+ "eor x10, x14, x15",
+ "str x14, [x2, #56]",
+ "and x14, x4, x10",
+ "eor x14, x13, x14",
+ "str x13, [x2, #64]",
+ "and x13, x4, x16",
+ "eor x10, x10, x13",
+ "and x10, x6, x10",
+ "eor x14, x14, x10",
+ "and x8, x3, x8",
+ "eor x11, x11, x8",
+ "and x10, x4, x12",
+ "eor x11, x11, x10",
+ "and x15, x6, x15",
+ "eor x11, x11, x15",
+ "and x11, x5, x11",
+ "eor x14, x14, x11",
+ "eor x11, x12, x7",
+ "eor x17, x11, x17",
+ "ldr x15, [x2, #32]",
+ "ldr x10, [x2, #48]",
+ "eor x13, x15, x10",
+ "eor x13, x13, x9",
+ "str x14, [x2, #72]",
+ "and x14, x3, x15",
+ "eor x14, x13, x14",
+ "str x16, [x2, #80]",
+ "and x16, x4, x14",
+ "str x11, [x2, #88]",
+ "eor x11, x17, x16",
+ "str x8, [x2, #96]",
+ "eor x8, x7, x10",
+ "eor x8, x8, x9",
+ "and x15, x3, x8",
+ "eor x7, x7, x15",
+ "str x8, [x2, #104]",
+ "and x8, x3, x12",
+ "eor x12, x12, x8",
+ "and x12, x4, x12",
+ "eor x7, x7, x12",
+ "and x7, x6, x7",
+ "eor x11, x11, x7",
+ "ldr x7, [x2, #64]",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x17, x4, x17",
+ "eor x7, x7, x17",
+ "ldr x17, [x2, #40]",
+ "eor x12, x17, x10",
+ "eor x12, x12, x9",
+ "and x17, x3, x12",
+ "str x12, [x2, #64]",
+ "eor x12, x13, x17",
+ "str x17, [x2, #112]",
+ "eor x17, x8, x10",
+ "eor x17, x17, x9",
+ "and x17, x4, x17",
+ "eor x12, x12, x17",
+ "and x12, x6, x12",
+ "eor x7, x7, x12",
+ "and x7, x5, x7",
+ "eor x11, x11, x7",
+ "and x7, x3, x13",
+ "ldr x12, [x2, #56]",
+ "eor x12, x12, x7",
+ "eor x7, x14, x10",
+ "eor x7, x7, x9",
+ "and x7, x4, x7",
+ "eor x12, x12, x7",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x12, x12, x14",
+ "ldr x14, [x2, #32]",
+ "eor x15, x14, x15",
+ "eor x15, x15, x17",
+ "ldr x17, [x2, #96]",
+ "and x16, x4, x17",
+ "eor x14, x14, x16",
+ "and x14, x6, x14",
+ "eor x15, x15, x14",
+ "and x15, x5, x15",
+ "eor x12, x12, x15",
+ "eor x13, x13, x17",
+ "eor x13, x13, x4",
+ "ldr x17, [x2, #88]",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x3, x3, x17",
+ "ldr x17, [x2, #104]",
+ "eor x17, x17, x3",
+ "and x17, x4, x17",
+ "ldr x3, [x2, #80]",
+ "eor x3, x3, x17",
+ "and x3, x6, x3",
+ "eor x13, x13, x3",
+ "ldr x3, [x2, #40]",
+ "eor x3, x3, x8",
+ "ldr x17, [x2, #64]",
+ "ldr x10, [x2, #112]",
+ "eor x10, x17, x10",
+ "and x10, x4, x10",
+ "eor x3, x3, x10",
+ "and x4, x4, x8",
+ "eor x17, x17, x4",
+ "and x6, x6, x17",
+ "eor x3, x3, x6",
+ "and x5, x5, x3",
+ "eor x6, x13, x5",
+ "ldr x3, [x2, #72]",
+ "add x4, x11, #0",
+ "add x5, x12, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #38",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #62",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #48",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #56",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #15",
+ "add x11, x10, #0",
+ "lsr x11, x11, #24",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #16",
+ "add x11, x10, #0",
+ "lsr x11, x11, #25",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #17",
+ "add x11, x10, #0",
+ "lsr x11, x11, #26",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #18",
+ "add x11, x10, #0",
+ "lsr x11, x11, #27",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #19",
+ "add x11, x10, #0",
+ "lsr x11, x11, #28",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #20",
+ "add x11, x10, #0",
+ "lsr x11, x11, #29",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x6, x10",
+ "eor x12, x12, x9",
+ "and x13, x4, x6",
+ "eor x14, x12, x13",
+ "and x15, x8, x14",
+ "eor x16, x12, x15",
+ "eor x17, x6, x4",
+ "str x15, [x2, #32]",
+ "eor x15, x17, x10",
+ "eor x15, x15, x9",
+ "str x6, [x2, #40]",
+ "and x6, x8, x15",
+ "str x3, [x2, #48]",
+ "eor x3, x17, x6",
+ "and x3, x7, x3",
+ "eor x16, x16, x3",
+ "eor x3, x4, x10",
+ "eor x3, x3, x9",
+ "str x17, [x2, #56]",
+ "eor x17, x4, x6",
+ "str x6, [x2, #64]",
+ "and x6, x7, x17",
+ "str x11, [x2, #72]",
+ "eor x11, x3, x6",
+ "and x11, x5, x11",
+ "eor x16, x16, x11",
+ "eor x11, x14, x10",
+ "eor x11, x11, x9",
+ "and x11, x8, x11",
+ "eor x11, x15, x11",
+ "and x11, x7, x11",
+ "eor x17, x17, x11",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x11, x4, x12",
+ "str x6, [x2, #80]",
+ "ldr x6, [x2, #72]",
+ "eor x6, x6, x11",
+ "str x3, [x2, #72]",
+ "and x3, x8, x6",
+ "eor x13, x13, x3",
+ "str x6, [x2, #88]",
+ "ldr x6, [x2, #56]",
+ "and x6, x7, x6",
+ "eor x13, x13, x6",
+ "and x13, x5, x13",
+ "eor x17, x17, x13",
+ "ldr x13, [x2, #48]",
+ "str x6, [x2, #56]",
+ "and x6, x13, x17",
+ "eor x16, x16, x6",
+ "and x6, x8, x11",
+ "eor x15, x15, x6",
+ "str x16, [x2, #96]",
+ "eor x16, x3, x10",
+ "eor x16, x16, x9",
+ "and x16, x7, x16",
+ "eor x16, x15, x16",
+ "str x8, [x2, #104]",
+ "eor x8, x11, x3",
+ "str x11, [x2, #112]",
+ "ldr x11, [x2, #40]",
+ "str x6, [x2, #120]",
+ "ldr x6, [x2, #64]",
+ "eor x6, x11, x6",
+ "and x6, x7, x6",
+ "eor x8, x8, x6",
+ "and x8, x5, x8",
+ "eor x16, x16, x8",
+ "eor x17, x17, x10",
+ "eor x17, x17, x9",
+ "and x17, x13, x17",
+ "eor x16, x16, x17",
+ "eor x14, x14, x3",
+ "and x12, x7, x12",
+ "eor x14, x14, x12",
+ "eor x4, x4, x6",
+ "and x4, x5, x4",
+ "eor x14, x14, x4",
+ "eor x15, x15, x10",
+ "eor x15, x15, x9",
+ "ldr x4, [x2, #88]",
+ "ldr x6, [x2, #120]",
+ "eor x4, x4, x6",
+ "and x4, x7, x4",
+ "eor x15, x15, x4",
+ "ldr x4, [x2, #72]",
+ "ldr x12, [x2, #32]",
+ "eor x4, x4, x12",
+ "ldr x3, [x2, #56]",
+ "eor x4, x4, x3",
+ "and x4, x5, x4",
+ "eor x15, x15, x4",
+ "and x4, x13, x15",
+ "eor x14, x14, x4",
+ "ldr x4, [x2, #112]",
+ "ldr x3, [x2, #104]",
+ "eor x3, x4, x3",
+ "eor x11, x11, x4",
+ "eor x11, x11, x6",
+ "and x7, x7, x11",
+ "eor x3, x3, x7",
+ "eor x12, x12, x10",
+ "eor x12, x12, x9",
+ "ldr x7, [x2, #80]",
+ "eor x12, x12, x7",
+ "and x5, x5, x12",
+ "eor x3, x3, x5",
+ "eor x15, x15, x10",
+ "eor x15, x15, x9",
+ "and x13, x13, x15",
+ "eor x6, x3, x13",
+ "ldr x3, [x2, #96]",
+ "add x4, x16, #0",
+ "add x5, x14, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #33",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #42",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #52",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #58",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #11",
+ "add x11, x10, #0",
+ "lsr x11, x11, #18",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #12",
+ "add x11, x10, #0",
+ "lsr x11, x11, #19",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #13",
+ "add x11, x10, #0",
+ "lsr x11, x11, #20",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #14",
+ "add x11, x10, #0",
+ "lsr x11, x11, #21",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #15",
+ "add x11, x10, #0",
+ "lsr x11, x11, #22",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #16",
+ "add x11, x10, #0",
+ "lsr x11, x11, #23",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x6, x10",
+ "eor x12, x12, x9",
+ "and x13, x12, x8",
+ "eor x14, x11, x13",
+ "eor x3, x3, x10",
+ "eor x3, x3, x9",
+ "and x15, x3, x14",
+ "eor x16, x8, x15",
+ "eor x17, x8, x10",
+ "eor x17, x17, x9",
+ "str x15, [x2, #32]",
+ "and x15, x12, x17",
+ "str x11, [x2, #40]",
+ "eor x11, x17, x15",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "str x15, [x2, #48]",
+ "and x15, x7, x11",
+ "eor x15, x16, x15",
+ "str x16, [x2, #56]",
+ "eor x16, x17, x13",
+ "str x14, [x2, #64]",
+ "and x14, x7, x16",
+ "eor x14, x6, x14",
+ "eor x5, x5, x10",
+ "eor x5, x5, x9",
+ "and x14, x5, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x17",
+ "eor x14, x12, x14",
+ "str x6, [x2, #72]",
+ "eor x6, x8, x12",
+ "and x13, x3, x13",
+ "eor x13, x6, x13",
+ "and x13, x7, x13",
+ "eor x14, x14, x13",
+ "eor x13, x11, x10",
+ "eor x13, x13, x9",
+ "and x13, x3, x13",
+ "str x12, [x2, #80]",
+ "eor x12, x17, x3",
+ "and x12, x7, x12",
+ "eor x13, x13, x12",
+ "and x13, x5, x13",
+ "eor x14, x14, x13",
+ "eor x4, x4, x10",
+ "eor x4, x4, x9",
+ "and x14, x4, x14",
+ "eor x15, x15, x14",
+ "and x14, x3, x11",
+ "ldr x13, [x2, #64]",
+ "eor x12, x13, x14",
+ "eor x12, x12, x7",
+ "str x15, [x2, #88]",
+ "ldr x15, [x2, #48]",
+ "eor x13, x15, x10",
+ "eor x13, x13, x9",
+ "str x10, [x2, #96]",
+ "and x10, x3, x13",
+ "str x6, [x2, #104]",
+ "ldr x6, [x2, #40]",
+ "eor x6, x6, x10",
+ "and x15, x3, x15",
+ "str x13, [x2, #48]",
+ "and x13, x7, x15",
+ "eor x6, x6, x13",
+ "and x6, x5, x6",
+ "eor x12, x12, x6",
+ "eor x15, x16, x15",
+ "and x15, x7, x15",
+ "ldr x6, [x2, #72]",
+ "eor x15, x6, x15",
+ "and x8, x3, x8",
+ "eor x17, x17, x8",
+ "and x13, x7, x17",
+ "eor x13, x10, x13",
+ "and x13, x5, x13",
+ "eor x15, x15, x13",
+ "and x15, x4, x15",
+ "eor x12, x12, x15",
+ "eor x15, x11, x3",
+ "eor x15, x15, x7",
+ "ldr x13, [x2, #48]",
+ "eor x13, x13, x14",
+ "ldr x14, [x2, #104]",
+ "str x12, [x2, #48]",
+ "eor x12, x14, x10",
+ "and x12, x7, x12",
+ "eor x13, x13, x12",
+ "and x13, x5, x13",
+ "eor x15, x15, x13",
+ "ldr x13, [x2, #96]",
+ "eor x12, x14, x13",
+ "eor x12, x12, x9",
+ "str x8, [x2, #40]",
+ "and x8, x3, x12",
+ "eor x11, x11, x8",
+ "and x11, x5, x11",
+ "str x8, [x2, #112]",
+ "ldr x8, [x2, #64]",
+ "eor x8, x8, x11",
+ "and x8, x4, x8",
+ "eor x15, x15, x8",
+ "ldr x8, [x2, #80]",
+ "eor x8, x8, x10",
+ "ldr x10, [x2, #56]",
+ "and x10, x7, x10",
+ "eor x8, x8, x10",
+ "eor x10, x16, x3",
+ "and x10, x7, x10",
+ "eor x17, x17, x10",
+ "and x17, x5, x17",
+ "eor x8, x8, x17",
+ "ldr x17, [x2, #32]",
+ "eor x12, x12, x17",
+ "and x3, x3, x6",
+ "eor x14, x14, x3",
+ "and x14, x7, x14",
+ "eor x12, x12, x14",
+ "eor x16, x16, x13",
+ "eor x16, x16, x9",
+ "ldr x14, [x2, #112]",
+ "eor x16, x16, x14",
+ "ldr x14, [x2, #40]",
+ "eor x14, x14, x13",
+ "eor x14, x14, x9",
+ "and x7, x7, x14",
+ "eor x16, x16, x7",
+ "and x5, x5, x16",
+ "eor x12, x12, x5",
+ "and x4, x4, x12",
+ "eor x6, x8, x4",
+ "ldr x3, [x2, #88]",
+ "ldr x4, [x2, #48]",
+ "add x5, x15, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #35",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #57",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #46",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #40",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #7",
+ "add x11, x10, #0",
+ "lsr x11, x11, #12",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #8",
+ "add x11, x10, #0",
+ "lsr x11, x11, #13",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #9",
+ "add x11, x10, #0",
+ "lsr x11, x11, #14",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #10",
+ "add x11, x10, #0",
+ "lsr x11, x11, #15",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #11",
+ "add x11, x10, #0",
+ "lsr x11, x11, #16",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #12",
+ "add x11, x10, #0",
+ "lsr x11, x11, #17",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x7, x10",
+ "eor x12, x12, x9",
+ "and x13, x6, x12",
+ "eor x14, x13, x4",
+ "eor x15, x7, x13",
+ "and x16, x4, x6",
+ "eor x17, x15, x16",
+ "and x17, x5, x17",
+ "eor x14, x14, x17",
+ "eor x17, x16, x10",
+ "eor x17, x17, x9",
+ "str x16, [x2, #32]",
+ "eor x16, x6, x10",
+ "eor x16, x16, x9",
+ "str x15, [x2, #40]",
+ "and x15, x4, x16",
+ "str x16, [x2, #48]",
+ "eor x16, x6, x15",
+ "str x15, [x2, #56]",
+ "and x15, x5, x16",
+ "eor x17, x17, x15",
+ "and x17, x8, x17",
+ "eor x14, x14, x17",
+ "eor x17, x12, x6",
+ "str x16, [x2, #64]",
+ "and x16, x4, x17",
+ "str x15, [x2, #72]",
+ "eor x15, x13, x16",
+ "and x15, x5, x15",
+ "and x6, x6, x7",
+ "str x11, [x2, #80]",
+ "eor x11, x12, x6",
+ "str x12, [x2, #88]",
+ "eor x12, x17, x10",
+ "eor x12, x12, x9",
+ "eor x12, x12, x16",
+ "and x12, x5, x12",
+ "eor x12, x11, x12",
+ "and x12, x8, x12",
+ "eor x15, x15, x12",
+ "and x15, x3, x15",
+ "eor x14, x14, x15",
+ "and x15, x4, x13",
+ "eor x12, x6, x15",
+ "and x7, x4, x7",
+ "str x14, [x2, #96]",
+ "ldr x14, [x2, #80]",
+ "eor x14, x14, x7",
+ "str x11, [x2, #80]",
+ "and x11, x5, x14",
+ "eor x12, x12, x11",
+ "ldr x11, [x2, #40]",
+ "str x16, [x2, #104]",
+ "ldr x16, [x2, #56]",
+ "eor x11, x11, x16",
+ "and x7, x5, x7",
+ "eor x11, x11, x7",
+ "and x11, x8, x11",
+ "eor x12, x12, x11",
+ "and x11, x5, x4",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "eor x11, x11, x15",
+ "str x15, [x2, #48]",
+ "ldr x15, [x2, #88]",
+ "str x7, [x2, #40]",
+ "and x7, x4, x15",
+ "str x6, [x2, #112]",
+ "and x6, x5, x7",
+ "eor x11, x11, x6",
+ "and x11, x8, x11",
+ "eor x14, x14, x11",
+ "and x14, x3, x14",
+ "eor x12, x12, x14",
+ "eor x17, x17, x16",
+ "ldr x14, [x2, #32]",
+ "eor x15, x15, x14",
+ "and x15, x5, x15",
+ "eor x17, x17, x15",
+ "eor x15, x13, x10",
+ "eor x15, x15, x9",
+ "ldr x14, [x2, #112]",
+ "and x11, x4, x14",
+ "eor x11, x15, x11",
+ "ldr x6, [x2, #104]",
+ "and x6, x5, x6",
+ "eor x11, x11, x6",
+ "and x11, x8, x11",
+ "eor x17, x17, x11",
+ "ldr x11, [x2, #40]",
+ "eor x11, x11, x10",
+ "eor x11, x11, x9",
+ "ldr x10, [x2, #48]",
+ "eor x13, x13, x10",
+ "eor x14, x14, x4",
+ "and x14, x5, x14",
+ "eor x13, x13, x14",
+ "and x13, x8, x13",
+ "eor x11, x11, x13",
+ "and x11, x3, x11",
+ "eor x17, x17, x11",
+ "ldr x11, [x2, #80]",
+ "eor x13, x11, x4",
+ "ldr x14, [x2, #72]",
+ "eor x13, x13, x14",
+ "ldr x14, [x2, #64]",
+ "and x10, x8, x14",
+ "eor x13, x13, x10",
+ "eor x16, x15, x16",
+ "and x16, x5, x16",
+ "eor x14, x14, x16",
+ "and x4, x4, x15",
+ "eor x15, x15, x4",
+ "eor x11, x11, x7",
+ "and x5, x5, x11",
+ "eor x15, x15, x5",
+ "and x8, x8, x15",
+ "eor x14, x14, x8",
+ "and x3, x3, x14",
+ "eor x6, x13, x3",
+ "ldr x3, [x2, #96]",
+ "add x4, x12, #0",
+ "add x5, x17, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #51",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #43",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #61",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #36",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #3",
+ "add x11, x10, #0",
+ "lsr x11, x11, #6",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "lsr x4, x4, #4",
+ "add x11, x10, #0",
+ "lsr x11, x11, #7",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #5",
+ "add x11, x10, #0",
+ "lsr x11, x11, #8",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #6",
+ "add x11, x10, #0",
+ "lsr x11, x11, #9",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #7",
+ "add x11, x10, #0",
+ "lsr x11, x11, #10",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #8",
+ "add x11, x10, #0",
+ "lsr x11, x11, #11",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x8, x3",
+ "and x13, x3, x8",
+ "and x14, x5, x13",
+ "eor x15, x12, x14",
+ "eor x16, x13, x10",
+ "eor x16, x16, x9",
+ "and x17, x5, x16",
+ "str x14, [x2, #32]",
+ "eor x14, x11, x17",
+ "str x12, [x2, #40]",
+ "and x12, x6, x14",
+ "eor x15, x15, x12",
+ "eor x12, x8, x10",
+ "eor x12, x12, x9",
+ "str x8, [x2, #48]",
+ "and x8, x3, x12",
+ "str x12, [x2, #56]",
+ "and x12, x5, x8",
+ "str x8, [x2, #64]",
+ "eor x8, x11, x12",
+ "str x11, [x2, #72]",
+ "and x11, x6, x16",
+ "eor x8, x8, x11",
+ "and x8, x7, x8",
+ "eor x15, x15, x8",
+ "and x8, x6, x17",
+ "eor x14, x14, x8",
+ "and x8, x5, x3",
+ "eor x8, x13, x8",
+ "and x8, x7, x8",
+ "eor x14, x14, x8",
+ "and x14, x4, x14",
+ "eor x15, x15, x14",
+ "eor x14, x13, x5",
+ "ldr x8, [x2, #40]",
+ "str x15, [x2, #80]",
+ "eor x15, x8, x10",
+ "eor x15, x15, x9",
+ "str x11, [x2, #88]",
+ "eor x11, x15, x12",
+ "and x11, x6, x11",
+ "eor x14, x14, x11",
+ "ldr x11, [x2, #48]",
+ "and x8, x5, x11",
+ "str x16, [x2, #96]",
+ "ldr x16, [x2, #72]",
+ "str x17, [x2, #104]",
+ "eor x17, x16, x8",
+ "eor x13, x11, x13",
+ "eor x16, x13, x12",
+ "and x16, x6, x16",
+ "eor x17, x17, x16",
+ "and x17, x7, x17",
+ "eor x14, x14, x17",
+ "ldr x17, [x2, #56]",
+ "str x12, [x2, #112]",
+ "ldr x12, [x2, #64]",
+ "str x8, [x2, #120]",
+ "eor x8, x17, x12",
+ "eor x3, x3, x10",
+ "eor x3, x3, x9",
+ "and x3, x5, x3",
+ "eor x3, x8, x3",
+ "eor x3, x3, x16",
+ "and x16, x5, x15",
+ "str x8, [x2, #128]",
+ "and x8, x6, x13",
+ "eor x16, x16, x8",
+ "and x16, x7, x16",
+ "eor x3, x3, x16",
+ "and x3, x4, x3",
+ "eor x14, x14, x3",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x17, x5, x17",
+ "eor x10, x13, x17",
+ "and x3, x6, x11",
+ "eor x10, x10, x3",
+ "ldr x16, [x2, #104]",
+ "eor x15, x15, x16",
+ "ldr x16, [x2, #96]",
+ "ldr x8, [x2, #120]",
+ "eor x16, x16, x8",
+ "and x16, x6, x16",
+ "eor x15, x15, x16",
+ "and x15, x7, x15",
+ "eor x10, x10, x15",
+ "ldr x15, [x2, #40]",
+ "and x15, x5, x15",
+ "and x15, x6, x15",
+ "ldr x16, [x2, #72]",
+ "eor x16, x16, x15",
+ "ldr x15, [x2, #112]",
+ "and x15, x7, x15",
+ "eor x16, x16, x15",
+ "and x16, x4, x16",
+ "eor x10, x10, x16",
+ "eor x12, x12, x8",
+ "ldr x16, [x2, #88]",
+ "eor x12, x12, x16",
+ "eor x17, x11, x17",
+ "ldr x16, [x2, #128]",
+ "and x5, x5, x16",
+ "eor x16, x16, x5",
+ "and x16, x6, x16",
+ "eor x17, x17, x16",
+ "and x17, x7, x17",
+ "eor x12, x12, x17",
+ "ldr x17, [x2, #32]",
+ "eor x13, x13, x17",
+ "eor x11, x11, x5",
+ "and x6, x6, x11",
+ "eor x13, x13, x6",
+ "eor x8, x8, x3",
+ "and x7, x7, x8",
+ "eor x13, x13, x7",
+ "and x4, x4, x13",
+ "eor x6, x12, x4",
+ "ldr x3, [x2, #80]",
+ "add x4, x14, #0",
+ "add x5, x10, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #39",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #54",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #44",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "eor x19, x19, x6",
+ "ldr x10, [x22, #0]",
+ "movz x12, #1, lsl #0",
+ "add x3, x20, #0",
+ "lsr x3, x3, #31",
+ "add x11, x10, #0",
+ "eor x3, x3, x11",
+ "and x3, x3, x12",
+ "add x4, x20, #0",
+ "add x11, x10, #0",
+ "lsr x11, x11, #1",
+ "eor x4, x4, x11",
+ "and x4, x4, x12",
+ "add x5, x20, #0",
+ "lsr x5, x5, #1",
+ "add x11, x10, #0",
+ "lsr x11, x11, #2",
+ "eor x5, x5, x11",
+ "and x5, x5, x12",
+ "add x6, x20, #0",
+ "lsr x6, x6, #2",
+ "add x11, x10, #0",
+ "lsr x11, x11, #3",
+ "eor x6, x6, x11",
+ "and x6, x6, x12",
+ "add x7, x20, #0",
+ "lsr x7, x7, #3",
+ "add x11, x10, #0",
+ "lsr x11, x11, #4",
+ "eor x7, x7, x11",
+ "and x7, x7, x12",
+ "add x8, x20, #0",
+ "lsr x8, x8, #4",
+ "add x11, x10, #0",
+ "lsr x11, x11, #5",
+ "eor x8, x8, x11",
+ "and x8, x8, x12",
+ "movz x9, #0, lsl #0",
+ "sub x9, x9, #1",
+ "eor x10, x3, x3",
+ "eor x11, x3, x3",
+ "eor x11, x11, x9",
+ "eor x12, x3, x10",
+ "eor x12, x12, x9",
+ "eor x13, x8, x12",
+ "eor x6, x6, x10",
+ "eor x6, x6, x9",
+ "eor x14, x13, x6",
+ "eor x4, x4, x10",
+ "eor x4, x4, x9",
+ "eor x14, x14, x4",
+ "and x15, x6, x3",
+ "and x16, x12, x8",
+ "and x17, x6, x16",
+ "str x3, [x2, #32]",
+ "eor x3, x12, x17",
+ "and x3, x4, x3",
+ "eor x3, x15, x3",
+ "eor x7, x7, x10",
+ "eor x7, x7, x9",
+ "and x3, x7, x3",
+ "eor x14, x14, x3",
+ "eor x3, x8, x10",
+ "eor x3, x3, x9",
+ "str x13, [x2, #40]",
+ "and x13, x12, x3",
+ "str x17, [x2, #48]",
+ "eor x17, x11, x13",
+ "str x13, [x2, #56]",
+ "eor x13, x17, x15",
+ "and x13, x4, x13",
+ "eor x12, x12, x13",
+ "eor x13, x8, x16",
+ "str x17, [x2, #64]",
+ "and x17, x6, x13",
+ "eor x11, x11, x17",
+ "str x15, [x2, #72]",
+ "and x15, x4, x3",
+ "eor x11, x11, x15",
+ "and x11, x7, x11",
+ "eor x12, x12, x11",
+ "eor x5, x5, x10",
+ "eor x5, x5, x9",
+ "and x12, x5, x12",
+ "eor x14, x14, x12",
+ "eor x12, x16, x10",
+ "eor x12, x12, x9",
+ "eor x11, x12, x17",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "str x14, [x2, #80]",
+ "and x14, x6, x13",
+ "eor x3, x3, x14",
+ "and x3, x4, x3",
+ "eor x11, x11, x3",
+ "ldr x3, [x2, #48]",
+ "str x13, [x2, #88]",
+ "eor x13, x3, x10",
+ "eor x13, x13, x9",
+ "str x17, [x2, #96]",
+ "and x17, x4, x3",
+ "eor x17, x13, x17",
+ "and x17, x7, x17",
+ "eor x11, x11, x17",
+ "ldr x17, [x2, #56]",
+ "str x13, [x2, #104]",
+ "eor x13, x8, x17",
+ "str x16, [x2, #112]",
+ "ldr x16, [x2, #72]",
+ "eor x16, x13, x16",
+ "str x15, [x2, #72]",
+ "ldr x15, [x2, #40]",
+ "and x15, x4, x15",
+ "str x14, [x2, #40]",
+ "eor x14, x16, x15",
+ "eor x16, x16, x10",
+ "eor x16, x16, x9",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "and x13, x4, x13",
+ "eor x16, x16, x13",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "and x14, x5, x14",
+ "eor x11, x11, x14",
+ "eor x14, x17, x3",
+ "and x16, x6, x12",
+ "eor x8, x8, x16",
+ "and x16, x4, x8",
+ "eor x14, x14, x16",
+ "ldr x16, [x2, #40]",
+ "eor x16, x12, x16",
+ "and x16, x7, x16",
+ "eor x14, x14, x16",
+ "ldr x16, [x2, #72]",
+ "eor x12, x12, x16",
+ "ldr x13, [x2, #112]",
+ "eor x3, x13, x3",
+ "eor x3, x3, x16",
+ "and x3, x7, x3",
+ "eor x12, x12, x3",
+ "and x12, x5, x12",
+ "eor x14, x14, x12",
+ "ldr x12, [x2, #104]",
+ "and x12, x4, x12",
+ "eor x8, x8, x12",
+ "and x6, x6, x17",
+ "eor x13, x13, x6",
+ "ldr x6, [x2, #32]",
+ "ldr x17, [x2, #96]",
+ "eor x6, x6, x17",
+ "and x6, x4, x6",
+ "eor x6, x13, x6",
+ "and x6, x7, x6",
+ "eor x8, x8, x6",
+ "ldr x6, [x2, #64]",
+ "eor x6, x6, x15",
+ "eor x13, x13, x10",
+ "eor x13, x13, x9",
+ "ldr x10, [x2, #88]",
+ "and x4, x4, x10",
+ "eor x13, x13, x4",
+ "and x7, x7, x13",
+ "eor x6, x6, x7",
+ "and x5, x5, x6",
+ "eor x6, x8, x5",
+ "ldr x3, [x2, #80]",
+ "add x4, x11, #0",
+ "add x5, x14, #0",
+ "movz x10, #1, lsl #0",
+ "and x3, x3, x10",
+ "ror x3, x3, #53",
+ "eor x19, x19, x3",
+ "and x4, x4, x10",
+ "ror x4, x4, #47",
+ "eor x19, x19, x4",
+ "and x5, x5, x10",
+ "ror x5, x5, #59",
+ "eor x19, x19, x5",
+ "and x6, x6, x10",
+ "ror x6, x6, #37",
+ "eor x19, x19, x6",
+ "add x3, x19, #0",
+ "add x19, x20, #0",
+ "add x20, x3, #0",
+ "sub x22, x22, #8",
+ "sub x21, x21, #1",
+ "cbnz x21, 22b",
+ "add x3, x19, #0",
+ "add x19, x20, #0",
+ "add x20, x3, #0",
+ "lsl x3, x19, #32",
+ "eor x3, x3, x20",
+ "movz x10, #0, lsl #0",
+ "movz x12, #1, lsl #0",
+ "add x11, x3, #0",
+ "lsr x11, x11, #24",
+ "and x11, x11, x12",
+ "ror x11, x11, #1",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #56",
+ "and x11, x11, x12",
+ "ror x11, x11, #2",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #16",
+ "and x11, x11, x12",
+ "ror x11, x11, #3",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #48",
+ "and x11, x11, x12",
+ "ror x11, x11, #4",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #8",
+ "and x11, x11, x12",
+ "ror x11, x11, #5",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #40",
+ "and x11, x11, x12",
+ "ror x11, x11, #6",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "and x11, x11, x12",
+ "ror x11, x11, #7",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #32",
+ "and x11, x11, x12",
+ "ror x11, x11, #8",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #25",
+ "and x11, x11, x12",
+ "ror x11, x11, #9",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #57",
+ "and x11, x11, x12",
+ "ror x11, x11, #10",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #17",
+ "and x11, x11, x12",
+ "ror x11, x11, #11",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #49",
+ "and x11, x11, x12",
+ "ror x11, x11, #12",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #9",
+ "and x11, x11, x12",
+ "ror x11, x11, #13",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #41",
+ "and x11, x11, x12",
+ "ror x11, x11, #14",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #1",
+ "and x11, x11, x12",
+ "ror x11, x11, #15",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #33",
+ "and x11, x11, x12",
+ "ror x11, x11, #16",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #26",
+ "and x11, x11, x12",
+ "ror x11, x11, #17",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #58",
+ "and x11, x11, x12",
+ "ror x11, x11, #18",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #18",
+ "and x11, x11, x12",
+ "ror x11, x11, #19",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #50",
+ "and x11, x11, x12",
+ "ror x11, x11, #20",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #10",
+ "and x11, x11, x12",
+ "ror x11, x11, #21",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #42",
+ "and x11, x11, x12",
+ "ror x11, x11, #22",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #2",
+ "and x11, x11, x12",
+ "ror x11, x11, #23",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #34",
+ "and x11, x11, x12",
+ "ror x11, x11, #24",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #27",
+ "and x11, x11, x12",
+ "ror x11, x11, #25",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #59",
+ "and x11, x11, x12",
+ "ror x11, x11, #26",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #19",
+ "and x11, x11, x12",
+ "ror x11, x11, #27",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #51",
+ "and x11, x11, x12",
+ "ror x11, x11, #28",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #11",
+ "and x11, x11, x12",
+ "ror x11, x11, #29",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #43",
+ "and x11, x11, x12",
+ "ror x11, x11, #30",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #3",
+ "and x11, x11, x12",
+ "ror x11, x11, #31",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #35",
+ "and x11, x11, x12",
+ "ror x11, x11, #32",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #28",
+ "and x11, x11, x12",
+ "ror x11, x11, #33",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #60",
+ "and x11, x11, x12",
+ "ror x11, x11, #34",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #20",
+ "and x11, x11, x12",
+ "ror x11, x11, #35",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #52",
+ "and x11, x11, x12",
+ "ror x11, x11, #36",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #12",
+ "and x11, x11, x12",
+ "ror x11, x11, #37",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #44",
+ "and x11, x11, x12",
+ "ror x11, x11, #38",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #4",
+ "and x11, x11, x12",
+ "ror x11, x11, #39",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #36",
+ "and x11, x11, x12",
+ "ror x11, x11, #40",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #29",
+ "and x11, x11, x12",
+ "ror x11, x11, #41",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #61",
+ "and x11, x11, x12",
+ "ror x11, x11, #42",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #21",
+ "and x11, x11, x12",
+ "ror x11, x11, #43",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #53",
+ "and x11, x11, x12",
+ "ror x11, x11, #44",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #13",
+ "and x11, x11, x12",
+ "ror x11, x11, #45",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #45",
+ "and x11, x11, x12",
+ "ror x11, x11, #46",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #5",
+ "and x11, x11, x12",
+ "ror x11, x11, #47",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #37",
+ "and x11, x11, x12",
+ "ror x11, x11, #48",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #30",
+ "and x11, x11, x12",
+ "ror x11, x11, #49",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #62",
+ "and x11, x11, x12",
+ "ror x11, x11, #50",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #22",
+ "and x11, x11, x12",
+ "ror x11, x11, #51",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #54",
+ "and x11, x11, x12",
+ "ror x11, x11, #52",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #14",
+ "and x11, x11, x12",
+ "ror x11, x11, #53",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #46",
+ "and x11, x11, x12",
+ "ror x11, x11, #54",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #6",
+ "and x11, x11, x12",
+ "ror x11, x11, #55",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #38",
+ "and x11, x11, x12",
+ "ror x11, x11, #56",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #31",
+ "and x11, x11, x12",
+ "ror x11, x11, #57",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #63",
+ "and x11, x11, x12",
+ "ror x11, x11, #58",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #23",
+ "and x11, x11, x12",
+ "ror x11, x11, #59",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #55",
+ "and x11, x11, x12",
+ "ror x11, x11, #60",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #15",
+ "and x11, x11, x12",
+ "ror x11, x11, #61",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #47",
+ "and x11, x11, x12",
+ "ror x11, x11, #62",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #7",
+ "and x11, x11, x12",
+ "ror x11, x11, #63",
+ "eor x10, x10, x11",
+ "add x11, x3, #0",
+ "lsr x11, x11, #39",
+ "and x11, x11, x12",
+ "eor x10, x10, x11",
+ "rev x3, x10",
+ "ldr x19, [x2, #0]",
+ "ldr x20, [x2, #8]",
+ "ldr x21, [x2, #16]",
+ "ldr x22, [x2, #24]",
+ "str x3, [x1, #0]",
+ "ret",
+ )
+}
+
+/// 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 AArch64, 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 x23, [x3, #512]",
+ "str x30, [x3, #520]",
+ "add x23, x2, #0",
+ "add x2, x3, #0",
+ "cbz x23, 20f",
+ "22:",
+ "bl {vg_triple_des_encrypt_block}",
+ "add x1, x1, #8",
+ "sub x23, x23, #1",
+ "cbnz x23, 22b",
+ "b 21f",
+ "20:",
+ "21:",
+ "ldr x23, [x2, #512]",
+ "ldr x30, [x2, #520]",
+ "ret",
+ 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 AArch64, 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 x23, [x3, #512]",
+ "str x30, [x3, #520]",
+ "add x23, x2, #0",
+ "add x2, x3, #0",
+ "cbz x23, 20f",
+ "22:",
+ "bl {vg_triple_des_decrypt_block}",
+ "add x1, x1, #8",
+ "sub x23, x23, #1",
+ "cbnz x23, 22b",
+ "b 21f",
+ "20:",
+ "21:",
+ "ldr x23, [x2, #512]",
+ "ldr x30, [x2, #520]",
+ "ret",
+ 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 ce230249f..b49448a43 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(target_arch = "x86_64")]
+#![cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
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 631471115..1f6186de8 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(target_arch = "x86_64")]
+#![cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
use std::collections::BTreeMap;