graviola 0.4.0

graviola is a modern, fast cryptography library
Documentation
// generated source. do not edit.
#![allow(non_upper_case_globals, unused_macros, unused_imports)]
use crate::low::macros::*;

// Copyright (c) 2024 The mlkem-native project authors
// Copyright (c) 2021-2022 Arm Limited
// Copyright (c) 2022 Matthias Kannwischer
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT

// ----------------------------------------------------------------------------
// Keccak-f1600 permutation for SHA3
// Input a[25], rc[24]; output a[25]
//
// Thinking of the input/output array a as a row-major flattening of a
// 5x5 matrix of 64-bit words, this performs the Keccak-f1600 permutation,
// all 24 rounds with the distinct round constants rc[i] for each one. For
// correct operation, the input pointer rc should point at the standard
// round constants as in the specification:
//
//   https://keccak.team/keccak_specs_summary.html#roundConstants
//
// This operation is at the core of SHA3 and is fully specified here:
//
//   https://keccak.team/files/Keccak-reference-3.0.pdf
//
// extern void sha3_keccak_f1600(uint64_t a[static 25],
//                               const uint64_t rc[static 24]);
//
// Standard ARM ABI: X0 = a, X1 = rc
// ----------------------------------------------------------------------------

/// Keccak-f1600 permutation for SHA3
///
/// Input a[25], rc[24]; output a[25]
///
/// Thinking of the input/output array a as a row-major flattening of a
/// 5x5 matrix of 64-bit words, this performs the Keccak-f1600 permutation,
/// all 24 rounds with the distinct round constants rc[i] for each one. For
/// correct operation, the input pointer rc should point at the standard
/// round constants as in the specification:
///
///   https://keccak.team/keccak_specs_summary.html#roundConstants
///
/// This operation is at the core of SHA3 and is fully specified here:
///
///   https://keccak.team/files/Keccak-reference-3.0.pdf
pub(crate) fn sha3_keccak_f1600(a: &mut [u64; 25], rc: &[u64; 24]) {
    // SAFETY: inline assembly. see [crate::low::inline_assembly_safety] for safety info.
    unsafe {
        core::arch::asm!(

        // This is almost exactly the same as the scalar code in the mlkem-native
        // repository here:
        //
        // https://github.com/pq-code-package/mlkem-native/blob/main/mlkem/fips202/native/aarch64/src/keccak_f1600_x1_scalar_asm.S
        //
        // The only change is the use of simple 64-bit addressing in place of
        // the unnecessary down-and-upcasting arising from [x9, w25, uxtw #3]

        Q!("    sub             " "sp, sp, # (128 + 0)"),
        Q!("    stp             " "x19, x20, [sp, # (32 + 0)]"),
        Q!("    stp             " "x21, x22, [sp, # (48 + 0)]"),
        Q!("    stp             " "x23, x24, [sp, # (64 + 0)]"),
        Q!("    stp             " "x25, x26, [sp, # (80 + 0)]"),
        Q!("    stp             " "x27, x28, [sp, # (96 + 0)]"),
        Q!("    stp             " "x29, x30, [sp, # (112 + 0)]"),

        Q!(Label!("Lsha3_keccak_f1600_initial", 2) ":"),
        Q!("    mov             " "x26, x1"),
        Q!("    str             " "x26, [sp, #8]"),
        Q!("    ldp             " "x1, x6, [x0]"),
        Q!("    ldp             " "x11, x16, [x0, #16]"),
        Q!("    ldp             " "x21, x2, [x0, #32]"),
        Q!("    ldp             " "x7, x12, [x0, #48]"),
        Q!("    ldp             " "x17, x22, [x0, #64]"),
        Q!("    ldp             " "x3, x8, [x0, #80]"),
        Q!("    ldp             " "x13, x28, [x0, #96]"),
        Q!("    ldp             " "x23, x4, [x0, #112]"),
        Q!("    ldp             " "x9, x14, [x0, #128]"),
        Q!("    ldp             " "x19, x24, [x0, #144]"),
        Q!("    ldp             " "x5, x10, [x0, #160]"),
        Q!("    ldp             " "x15, x20, [x0, #176]"),
        Q!("    ldr             " "x25, [x0, #192]"),
        Q!("    str             " "x0, [sp]"),
        Q!("    eor             " "x30, x24, x25"),
        Q!("    eor             " "x27, x9, x10"),
        Q!("    eor             " "x0, x30, x21"),
        Q!("    eor             " "x26, x27, x6"),
        Q!("    eor             " "x27, x26, x7"),
        Q!("    eor             " "x29, x0, x22"),
        Q!("    eor             " "x26, x29, x23"),
        Q!("    eor             " "x29, x4, x5"),
        Q!("    eor             " "x30, x29, x1"),
        Q!("    eor             " "x0, x27, x8"),
        Q!("    eor             " "x29, x30, x2"),
        Q!("    eor             " "x30, x19, x20"),
        Q!("    eor             " "x30, x30, x16"),
        Q!("    eor             " "x27, x26, x0, ror #63"),
        Q!("    eor             " "x4, x4, x27"),
        Q!("    eor             " "x30, x30, x17"),
        Q!("    eor             " "x30, x30, x28"),
        Q!("    eor             " "x29, x29, x3"),
        Q!("    eor             " "x0, x0, x30, ror #63"),
        Q!("    eor             " "x30, x30, x29, ror #63"),
        Q!("    eor             " "x22, x22, x30"),
        Q!("    eor             " "x23, x23, x30"),
        Q!("    str             " "x23, [sp, #24]"),
        Q!("    eor             " "x23, x14, x15"),
        Q!("    eor             " "x14, x14, x0"),
        Q!("    eor             " "x23, x23, x11"),
        Q!("    eor             " "x15, x15, x0"),
        Q!("    eor             " "x1, x1, x27"),
        Q!("    eor             " "x23, x23, x12"),
        Q!("    eor             " "x23, x23, x13"),
        Q!("    eor             " "x11, x11, x0"),
        Q!("    eor             " "x29, x29, x23, ror #63"),
        Q!("    eor             " "x23, x23, x26, ror #63"),
        Q!("    eor             " "x26, x13, x0"),
        Q!("    eor             " "x13, x28, x23"),
        Q!("    eor             " "x28, x24, x30"),
        Q!("    eor             " "x24, x16, x23"),
        Q!("    eor             " "x16, x21, x30"),
        Q!("    eor             " "x21, x25, x30"),
        Q!("    eor             " "x30, x19, x23"),
        Q!("    eor             " "x19, x20, x23"),
        Q!("    eor             " "x20, x17, x23"),
        Q!("    eor             " "x17, x12, x0"),
        Q!("    eor             " "x0, x2, x27"),
        Q!("    eor             " "x2, x6, x29"),
        Q!("    eor             " "x6, x8, x29"),
        Q!("    bic             " "x8, x28, x13, ror #47"),
        Q!("    eor             " "x12, x3, x27"),
        Q!("    bic             " "x3, x13, x17, ror #19"),
        Q!("    eor             " "x5, x5, x27"),
        Q!("    ldr             " "x27, [sp, #24]"),
        Q!("    bic             " "x25, x17, x2, ror #5"),
        Q!("    eor             " "x9, x9, x29"),
        Q!("    eor             " "x23, x25, x5, ror #52"),
        Q!("    eor             " "x3, x3, x2, ror #24"),
        Q!("    eor             " "x8, x8, x17, ror #2"),
        Q!("    eor             " "x17, x10, x29"),
        Q!("    bic             " "x25, x12, x22, ror #47"),
        Q!("    eor             " "x29, x7, x29"),
        Q!("    bic             " "x10, x4, x27, ror #2"),
        Q!("    bic             " "x7, x5, x28, ror #10"),
        Q!("    eor             " "x10, x10, x20, ror #50"),
        Q!("    eor             " "x13, x7, x13, ror #57"),
        Q!("    bic             " "x7, x2, x5, ror #47"),
        Q!("    eor             " "x2, x25, x24, ror #39"),
        Q!("    bic             " "x25, x20, x11, ror #57"),
        Q!("    bic             " "x5, x17, x4, ror #25"),
        Q!("    eor             " "x25, x25, x17, ror #53"),
        Q!("    bic             " "x17, x11, x17, ror #60"),
        Q!("    eor             " "x28, x7, x28, ror #57"),
        Q!("    bic             " "x7, x9, x12, ror #42"),
        Q!("    eor             " "x7, x7, x22, ror #25"),
        Q!("    bic             " "x22, x22, x24, ror #56"),
        Q!("    bic             " "x24, x24, x15, ror #31"),
        Q!("    eor             " "x22, x22, x15, ror #23"),
        Q!("    bic             " "x20, x27, x20, ror #48"),
        Q!("    bic             " "x15, x15, x9, ror #16"),
        Q!("    eor             " "x12, x15, x12, ror #58"),
        Q!("    eor             " "x15, x5, x27, ror #27"),
        Q!("    eor             " "x5, x20, x11, ror #41"),
        Q!("    ldr             " "x11, [sp, #8]"),
        Q!("    eor             " "x20, x17, x4, ror #21"),
        Q!("    eor             " "x17, x24, x9, ror #47"),
        Q!("    mov             " "x24, #0x1"),
        Q!("    bic             " "x9, x0, x16, ror #9"),
        Q!("    str             " "x24, [sp, #16]"),
        Q!("    bic             " "x24, x29, x1, ror #44"),
        Q!("    bic             " "x27, x1, x21, ror #50"),
        Q!("    bic             " "x4, x26, x29, ror #63"),
        Q!("    eor             " "x1, x1, x4, ror #21"),
        Q!("    ldr             " "x11, [x11]"),
        Q!("    bic             " "x4, x21, x30, ror #57"),
        Q!("    eor             " "x21, x24, x21, ror #30"),
        Q!("    eor             " "x24, x9, x19, ror #44"),
        Q!("    bic             " "x9, x14, x6, ror #5"),
        Q!("    eor             " "x9, x9, x0, ror #43"),
        Q!("    bic             " "x0, x6, x0, ror #38"),
        Q!("    eor             " "x1, x1, x11"),
        Q!("    eor             " "x11, x4, x26, ror #35"),
        Q!("    eor             " "x4, x0, x16, ror #47"),
        Q!("    bic             " "x0, x16, x19, ror #35"),
        Q!("    eor             " "x16, x27, x30, ror #43"),
        Q!("    bic             " "x27, x30, x26, ror #42"),
        Q!("    bic             " "x26, x19, x14, ror #41"),
        Q!("    eor             " "x19, x0, x14, ror #12"),
        Q!("    eor             " "x14, x26, x6, ror #46"),
        Q!("    eor             " "x6, x27, x29, ror #41"),

        // Main loop maintains the invariant that there are deferred rotations to
        // reach the full effect of i Keccak rounds. By absorbing rotations into
        // shifted operands, the total number of rotation instructions is reduced
        // relative to a naive implementation.

        Q!(Label!("Lsha3_keccak_f1600_loop", 3) ":"),
        Q!("    eor             " "x0, x15, x11, ror #52"),
        Q!("    eor             " "x0, x0, x13, ror #48"),
        Q!("    eor             " "x26, x8, x9, ror #57"),
        Q!("    eor             " "x27, x0, x14, ror #10"),
        Q!("    eor             " "x29, x16, x28, ror #63"),
        Q!("    eor             " "x26, x26, x6, ror #51"),
        Q!("    eor             " "x30, x23, x22, ror #50"),
        Q!("    eor             " "x0, x26, x10, ror #31"),
        Q!("    eor             " "x29, x29, x19, ror #37"),
        Q!("    eor             " "x27, x27, x12, ror #5"),
        Q!("    eor             " "x30, x30, x24, ror #34"),
        Q!("    eor             " "x0, x0, x7, ror #27"),
        Q!("    eor             " "x26, x30, x21, ror #26"),
        Q!("    eor             " "x26, x26, x25, ror #15"),
        Q!("    ror             " "x30, x27, #62"),
        Q!("    eor             " "x30, x30, x26, ror #57"),
        Q!("    ror             " "x26, x26, #58"),
        Q!("    eor             " "x16, x30, x16"),
        Q!("    eor             " "x28, x30, x28, ror #63"),
        Q!("    str             " "x28, [sp, #24]"),
        Q!("    eor             " "x29, x29, x17, ror #36"),
        Q!("    eor             " "x28, x1, x2, ror #61"),
        Q!("    eor             " "x19, x30, x19, ror #37"),
        Q!("    eor             " "x29, x29, x20, ror #2"),
        Q!("    eor             " "x28, x28, x4, ror #54"),
        Q!("    eor             " "x26, x26, x0, ror #55"),
        Q!("    eor             " "x28, x28, x3, ror #39"),
        Q!("    eor             " "x28, x28, x5, ror #25"),
        Q!("    ror             " "x0, x0, #56"),
        Q!("    eor             " "x0, x0, x29, ror #63"),
        Q!("    eor             " "x27, x28, x27, ror #61"),
        Q!("    eor             " "x13, x0, x13, ror #46"),
        Q!("    eor             " "x28, x29, x28, ror #63"),
        Q!("    eor             " "x29, x30, x20, ror #2"),
        Q!("    eor             " "x20, x26, x3, ror #39"),
        Q!("    eor             " "x11, x0, x11, ror #50"),
        Q!("    eor             " "x25, x28, x25, ror #9"),
        Q!("    eor             " "x3, x28, x21, ror #20"),
        Q!("    eor             " "x21, x26, x1"),
        Q!("    eor             " "x9, x27, x9, ror #49"),
        Q!("    eor             " "x24, x28, x24, ror #28"),
        Q!("    eor             " "x1, x30, x17, ror #36"),
        Q!("    eor             " "x14, x0, x14, ror #8"),
        Q!("    eor             " "x22, x28, x22, ror #44"),
        Q!("    eor             " "x8, x27, x8, ror #56"),
        Q!("    eor             " "x17, x27, x7, ror #19"),
        Q!("    eor             " "x15, x0, x15, ror #62"),
        Q!("    bic             " "x7, x20, x22, ror #47"),
        Q!("    eor             " "x4, x26, x4, ror #54"),
        Q!("    eor             " "x0, x0, x12, ror #3"),
        Q!("    eor             " "x28, x28, x23, ror #58"),
        Q!("    eor             " "x23, x26, x2, ror #61"),
        Q!("    eor             " "x26, x26, x5, ror #25"),
        Q!("    eor             " "x2, x7, x16, ror #39"),
        Q!("    bic             " "x7, x9, x20, ror #42"),
        Q!("    bic             " "x30, x15, x9, ror #16"),
        Q!("    eor             " "x7, x7, x22, ror #25"),
        Q!("    eor             " "x12, x30, x20, ror #58"),
        Q!("    bic             " "x20, x22, x16, ror #56"),
        Q!("    eor             " "x30, x27, x6, ror #43"),
        Q!("    eor             " "x22, x20, x15, ror #23"),
        Q!("    bic             " "x6, x19, x13, ror #42"),
        Q!("    eor             " "x6, x6, x17, ror #41"),
        Q!("    bic             " "x5, x13, x17, ror #63"),
        Q!("    eor             " "x5, x21, x5, ror #21"),
        Q!("    bic             " "x17, x17, x21, ror #44"),
        Q!("    eor             " "x27, x27, x10, ror #23"),
        Q!("    bic             " "x21, x21, x25, ror #50"),
        Q!("    bic             " "x20, x27, x4, ror #25"),
        Q!("    bic             " "x10, x16, x15, ror #31"),
        Q!("    eor             " "x16, x21, x19, ror #43"),
        Q!("    eor             " "x21, x17, x25, ror #30"),
        Q!("    bic             " "x19, x25, x19, ror #57"),
        Q!("    ldr             " "x25, [sp, #16]"),
        Q!("    eor             " "x17, x10, x9, ror #47"),
        Q!("    ldr             " "x9, [sp, #8]"),
        Q!("    eor             " "x15, x20, x28, ror #27"),
        Q!("    bic             " "x20, x4, x28, ror #2"),
        Q!("    eor             " "x10, x20, x1, ror #50"),
        Q!("    bic             " "x20, x11, x27, ror #60"),
        Q!("    eor             " "x20, x20, x4, ror #21"),
        Q!("    bic             " "x4, x28, x1, ror #48"),
        Q!("    bic             " "x1, x1, x11, ror #57"),
        Q!("    ldr             " "x28, [x9, x25, lsl #3]"),
        Q!("    ldr             " "x9, [sp, #24]"),
        Q!("    add             " "x25, x25, #0x1"),
        Q!("    str             " "x25, [sp, #16]"),
        Q!("    cmp             " "x25, #0x17"),
        Q!("    eor             " "x25, x1, x27, ror #53"),
        Q!("    bic             " "x27, x30, x26, ror #47"),
        Q!("    eor             " "x1, x5, x28"),
        Q!("    eor             " "x5, x4, x11, ror #41"),
        Q!("    eor             " "x11, x19, x13, ror #35"),
        Q!("    bic             " "x13, x26, x24, ror #10"),
        Q!("    eor             " "x28, x27, x24, ror #57"),
        Q!("    bic             " "x27, x24, x9, ror #47"),
        Q!("    bic             " "x19, x23, x3, ror #9"),
        Q!("    bic             " "x4, x29, x14, ror #41"),
        Q!("    eor             " "x24, x19, x29, ror #44"),
        Q!("    bic             " "x29, x3, x29, ror #35"),
        Q!("    eor             " "x13, x13, x9, ror #57"),
        Q!("    eor             " "x19, x29, x14, ror #12"),
        Q!("    bic             " "x29, x9, x0, ror #19"),
        Q!("    bic             " "x14, x14, x8, ror #5"),
        Q!("    eor             " "x9, x14, x23, ror #43"),
        Q!("    eor             " "x14, x4, x8, ror #46"),
        Q!("    bic             " "x23, x8, x23, ror #38"),
        Q!("    eor             " "x8, x27, x0, ror #2"),
        Q!("    eor             " "x4, x23, x3, ror #47"),
        Q!("    bic             " "x3, x0, x30, ror #5"),
        Q!("    eor             " "x23, x3, x26, ror #52"),
        Q!("    eor             " "x3, x29, x30, ror #24"),
        Q!("    ble             " Label!("Lsha3_keccak_f1600_loop", 3, Before)),

        // Final rotations

        Q!("    ror             " "x6, x6, #43"),
        Q!("    ror             " "x11, x11, #50"),
        Q!("    ror             " "x21, x21, #20"),
        Q!("    ror             " "x2, x2, #61"),
        Q!("    ror             " "x7, x7, #19"),
        Q!("    ror             " "x12, x12, #3"),
        Q!("    ror             " "x17, x17, #36"),
        Q!("    ror             " "x22, x22, #44"),
        Q!("    ror             " "x3, x3, #39"),
        Q!("    ror             " "x8, x8, #56"),
        Q!("    ror             " "x13, x13, #46"),
        Q!("    ror             " "x28, x28, #63"),
        Q!("    ror             " "x23, x23, #58"),
        Q!("    ror             " "x4, x4, #54"),
        Q!("    ror             " "x9, x9, #49"),
        Q!("    ror             " "x14, x14, #8"),
        Q!("    ror             " "x19, x19, #37"),
        Q!("    ror             " "x24, x24, #28"),
        Q!("    ror             " "x5, x5, #25"),
        Q!("    ror             " "x10, x10, #23"),
        Q!("    ror             " "x15, x15, #62"),
        Q!("    ror             " "x20, x20, #2"),
        Q!("    ror             " "x25, x25, #9"),
        Q!("    ldr             " "x0, [sp]"),
        Q!("    stp             " "x1, x6, [x0]"),
        Q!("    stp             " "x11, x16, [x0, #16]"),
        Q!("    stp             " "x21, x2, [x0, #32]"),
        Q!("    stp             " "x7, x12, [x0, #48]"),
        Q!("    stp             " "x17, x22, [x0, #64]"),
        Q!("    stp             " "x3, x8, [x0, #80]"),
        Q!("    stp             " "x13, x28, [x0, #96]"),
        Q!("    stp             " "x23, x4, [x0, #112]"),
        Q!("    stp             " "x9, x14, [x0, #128]"),
        Q!("    stp             " "x19, x24, [x0, #144]"),
        Q!("    stp             " "x5, x10, [x0, #160]"),
        Q!("    stp             " "x15, x20, [x0, #176]"),
        Q!("    str             " "x25, [x0, #192]"),
        Q!("    ldp             " "x19, x20, [sp, # (32 + 0)]"),
        Q!("    ldp             " "x21, x22, [sp, # (48 + 0)]"),
        Q!("    ldp             " "x23, x24, [sp, # (64 + 0)]"),
        Q!("    ldp             " "x25, x26, [sp, # (80 + 0)]"),
        Q!("    ldp             " "x27, x28, [sp, # (96 + 0)]"),
        Q!("    ldp             " "x29, x30, [sp, # (112 + 0)]"),
        Q!("    add             " "sp, sp, # (128 + 0)"),
        inout("x0") a.as_mut_ptr() => _,
        inout("x1") rc.as_ptr() => _,
        // clobbers
        out("x10") _,
        out("x11") _,
        out("x12") _,
        out("x13") _,
        out("x14") _,
        out("x15") _,
        out("x16") _,
        out("x17") _,
        out("x2") _,
        out("x20") _,
        out("x21") _,
        out("x22") _,
        out("x23") _,
        out("x24") _,
        out("x25") _,
        out("x26") _,
        out("x27") _,
        out("x28") _,
        out("x3") _,
        out("x30") _,
        out("x4") _,
        out("x5") _,
        out("x6") _,
        out("x7") _,
        out("x8") _,
        out("x9") _,
            )
    };
}