From eb29149c7b476f3e923d69ecc81f9c4b151d81d1 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 1 Oct 2026 19:29:29 +0000 Subject: [PATCH 1/5] Implement AArch64 Triple DES scalar programs and verify Boolean rounds --- .../Impl/TripleDes/AArch64/Block.lean | 67 ++++ .../Impl/TripleDes/AArch64/Common.lean | 26 ++ .../Impl/TripleDes/AArch64/Ecb.lean | 27 ++ .../Impl/TripleDes/AArch64/ExpandKey.lean | 50 +++ .../Impl/TripleDes/AArch64/Permutation.lean | 12 + .../Impl/TripleDes/AArch64/Sbox.lean | 30 ++ .../Proof/TripleDes/AArch64/ConstantTime.lean | 45 +++ .../Proof/TripleDes/AArch64/FunctionsLit.lean | 13 + .../Proof/TripleDes/AArch64/Lit.lean | 21 ++ .../Proof/TripleDes/AArch64/Permutation.lean | 90 ++++++ .../Proof/TripleDes/AArch64/Round.lean | 285 ++++++++++++++++++ .../Proof/TripleDes/AArch64/RoundLit.lean | 25 ++ .../Proof/TripleDes/AArch64/Sbox.lean | 114 +++++++ 13 files changed, 805 insertions(+) create mode 100644 lean/VerifiedGarbage/Impl/TripleDes/AArch64/Block.lean create mode 100644 lean/VerifiedGarbage/Impl/TripleDes/AArch64/Common.lean create mode 100644 lean/VerifiedGarbage/Impl/TripleDes/AArch64/Ecb.lean create mode 100644 lean/VerifiedGarbage/Impl/TripleDes/AArch64/ExpandKey.lean create mode 100644 lean/VerifiedGarbage/Impl/TripleDes/AArch64/Permutation.lean create mode 100644 lean/VerifiedGarbage/Impl/TripleDes/AArch64/Sbox.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/ConstantTime.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/FunctionsLit.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Lit.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Permutation.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Round.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundLit.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Sbox.lean 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/ConstantTime.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/ConstantTime.lean new file mode 100644 index 000000000..29ba53955 --- /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 RC2 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/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/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/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/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/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/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 From b9bcc3ccc7b198860f0158a0bb0783f1a817d6ff Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 1 Oct 2026 19:40:11 +0000 Subject: [PATCH 2/5] Verify complete AArch64 DES loops and three-pass EDE composition --- .../Proof/TripleDes/AArch64/Body.lean | 40 +++++ .../Proof/TripleDes/AArch64/Box.lean | 55 +++++++ .../Proof/TripleDes/AArch64/Bytes.lean | 36 +++++ .../Proof/TripleDes/AArch64/Initial.lean | 58 ++++++++ .../Proof/TripleDes/AArch64/Loop.lean | 139 ++++++++++++++++++ .../Proof/TripleDes/AArch64/Pass.lean | 85 +++++++++++ .../Proof/TripleDes/AArch64/PassStart.lean | 40 +++++ .../Proof/TripleDes/AArch64/Ready.lean | 83 +++++++++++ .../Proof/TripleDes/AArch64/RoundBody.lean | 126 ++++++++++++++++ .../TripleDes/AArch64/RoundFunction.lean | 82 +++++++++++ .../Proof/TripleDes/AArch64/RoundStep.lean | 69 +++++++++ .../Proof/TripleDes/AArch64/Spills.lean | 89 +++++++++++ .../Proof/TripleDes/AArch64/WordState.lean | 28 ++++ 13 files changed, 930 insertions(+) create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Body.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Box.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Bytes.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Initial.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Loop.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Pass.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/PassStart.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ready.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundBody.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundFunction.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/RoundStep.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Spills.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/WordState.lean 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/Initial.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Initial.lean new file mode 100644 index 000000000..b9411348d --- /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 = + 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 = + 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/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/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/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/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/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/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 From c39fd7ed08b75d7d74b319ade9c085e7abbbcc77 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 1 Oct 2026 19:52:27 +0000 Subject: [PATCH 3/5] Verify AArch64 Triple DES block APIs against shared contracts --- .../Proof/TripleDes/AArch64/Block.lean | 85 +++++++++++++ .../Proof/TripleDes/AArch64/BlockIO.lean | 116 ++++++++++++++++++ .../Proof/TripleDes/AArch64/Head.lean | 86 +++++++++++++ .../Proof/TripleDes/AArch64/Initial.lean | 4 +- .../Proof/TripleDes/AArch64/Pre.lean | 79 ++++++++++++ .../Proof/TripleDes/AArch64/Save.lean | 75 +++++++++++ .../Proof/TripleDes/AArch64/Store.lean | 80 ++++++++++++ .../Proof/TripleDes/AArch64/Tail.lean | 69 +++++++++++ .../TripleDes/AArch64/VerifiedBlock.lean | 63 ++++++++++ .../Proof/TripleDes/AArch64/Word.lean | 30 +++++ 10 files changed, 685 insertions(+), 2 deletions(-) create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Block.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/BlockIO.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Head.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Pre.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Save.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Store.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Tail.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/VerifiedBlock.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Word.lean 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/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 index b9411348d..cfaf817d7 100644 --- a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Initial.lean +++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Initial.lean @@ -23,7 +23,7 @@ theorem initial_raw_ok (s : State) : (∀ 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 = + 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 @@ -49,7 +49,7 @@ theorem final_raw_ok (s : State) : (∀ 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 = + 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 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/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/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..675bb4762 --- /dev/null +++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Word.lean @@ -0,0 +1,30 @@ +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)] + +end VG.Proof.TripleDes.AArch64 From 6e7c93a25b9c9c7f37d277a157096ec9cd1f0120 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 1 Oct 2026 20:15:07 +0000 Subject: [PATCH 4/5] Verify complete AArch64 Triple DES key expansion --- .../Proof/TripleDes/AArch64/Key/Body.lean | 71 +++++++++ .../TripleDes/AArch64/Key/Component.lean | 42 +++++ .../TripleDes/AArch64/Key/Composition.lean | 150 ++++++++++++++++++ .../Proof/TripleDes/AArch64/Key/Contract.lean | 22 +++ .../Proof/TripleDes/AArch64/Key/Copy.lean | 90 +++++++++++ .../Proof/TripleDes/AArch64/Key/Correct.lean | 80 ++++++++++ .../Proof/TripleDes/AArch64/Key/Load.lean | 103 ++++++++++++ .../Proof/TripleDes/AArch64/Key/Loop.lean | 117 ++++++++++++++ .../TripleDes/AArch64/Key/Permutation.lean | 35 ++++ .../Proof/TripleDes/AArch64/Key/Rotation.lean | 126 +++++++++++++++ .../Proof/TripleDes/AArch64/Key/Save.lean | 55 +++++++ .../Proof/TripleDes/AArch64/Key/Store.lean | 104 ++++++++++++ .../Proof/TripleDes/AArch64/Key/Verified.lean | 32 ++++ .../Proof/TripleDes/AArch64/KeySteps.lean | 34 ++++ .../Proof/TripleDes/AArch64/Word.lean | 12 ++ 15 files changed, 1073 insertions(+) create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Body.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Component.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Composition.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Contract.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Copy.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Correct.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Load.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Loop.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Permutation.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Rotation.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Save.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Store.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Key/Verified.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/KeySteps.lean 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/Word.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Word.lean index 675bb4762..43d8b2727 100644 --- a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Word.lean +++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/Word.lean @@ -27,4 +27,16 @@ theorem packHalves_shift (l r : BitVec 32) : 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 From 1fcef8321c136d5969fdbcd23093c72d464760f8 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Thu, 1 Oct 2026 20:15:07 +0000 Subject: [PATCH 5/5] Verify AArch64 Triple DES ECB and enable the public API --- README.md | 2 +- bench/benches/primitives/triple_des_ecb.rs | 4 +- .../Artifacts/TripleDes/AArch64.lean | 56 + .../Proof/TripleDes/AArch64/ConstantTime.lean | 2 +- .../Proof/TripleDes/AArch64/Ecb/Body.lean | 56 + .../Proof/TripleDes/AArch64/Ecb/Call.lean | 74 + .../Proof/TripleDes/AArch64/Ecb/Contract.lean | 23 + .../Proof/TripleDes/AArch64/Ecb/Correct.lean | 80 + .../Proof/TripleDes/AArch64/Ecb/IO.lean | 92 + .../Proof/TripleDes/AArch64/Ecb/Loop.lean | 89 + .../TripleDes/AArch64/Ecb/LoopFrame.lean | 67 + .../Proof/TripleDes/AArch64/Ecb/Pre.lean | 56 + .../Proof/TripleDes/AArch64/Ecb/Slice.lean | 45 + .../Proof/TripleDes/AArch64/Ecb/Steps.lean | 52 + .../Proof/TripleDes/AArch64/Ecb/Verified.lean | 48 + src/asm/aarch64/mod.rs | 3 + src/asm/aarch64/triple_des.rs | 11936 ++++++++++++++++ src/triple_des_ecb.rs | 2 +- tests/cavp/triple_des_ecb.rs | 2 +- 19 files changed, 12683 insertions(+), 6 deletions(-) create mode 100644 lean/VerifiedGarbage/Artifacts/TripleDes/AArch64.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Body.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Call.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Contract.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Correct.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/IO.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Loop.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/LoopFrame.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Pre.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Slice.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Steps.lean create mode 100644 lean/VerifiedGarbage/Proof/TripleDes/AArch64/Ecb/Verified.lean create mode 100644 src/asm/aarch64/triple_des.rs 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/Proof/TripleDes/AArch64/ConstantTime.lean b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/ConstantTime.lean index 29ba53955..590811dc0 100644 --- a/lean/VerifiedGarbage/Proof/TripleDes/AArch64/ConstantTime.lean +++ b/lean/VerifiedGarbage/Proof/TripleDes/AArch64/ConstantTime.lean @@ -1,7 +1,7 @@ import VerifiedGarbage.Proof.TripleDes.AArch64.FunctionsLit import VerifiedGarbage.Proof.Framework.AArch64.Taint -/-! # Constant-time RC2 block and key-expansion programs -/ +/-! # Constant-time Triple DES block and key-expansion programs -/ namespace 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/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;