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 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT

// ----------------------------------------------------------------------------
// Scalar product of 3-element polynomial vectors in NTT domain, with mulcache
// Inputs a[768], b[768], bt[384] (signed 16-bit words); output r[256] (signed 16-bit words)
//
// The inputs a and b are considered as 3-element vectors of linear
// polynomials in the NTT domain (in Montgomery form), and the bt
// argument an analogous 3-element vector of mulcaches for the bi:
//
//   a0 = a[0..255], a1 = a[256..511], a2 = a[512..767]
//   b0 = b[0..255], b1 = b[256..511], b2 = b[512..767],
//   bt0 = bt[0..127], bt1 = bt[128..255], bt2 = bt[256..383]
//
// Scalar multiplication of those 3-element vectors is performed,
// with base multiplication in Fq[X]/(X^2-zeta^i'), with zeta^i'
// being a power of zeta = 17, with i bit-reversed as used for NTTs,
// making use of the mulcache for optimization.
//
// All input elements are assumed <= 2^12 and the bts are
// assumed to be as computed by mlkem_mulcache_compute.
//
// extern void mlkem_basemul_k3
//      (int16_t r[static 256],const int16_t a[static 768],
//       const int16_t b[static 768], const int16_t bt[static 384]);
//
// Standard ARM ABI: X0 = r, X1 = a, X2 = b, X3 = bt
// ----------------------------------------------------------------------------

/// Scalar product of 3-element polynomial vectors in NTT domain, with mulcache
///
/// Inputs a[768], b[768], bt[384] (signed 16-bit words); output r[256] (signed 16-bit words)
///
/// The inputs a and b are considered as 3-element vectors of linear
/// polynomials in the NTT domain (in Montgomery form), and the bt
/// argument an analogous 3-element vector of mulcaches for the bi:
///
///   a0 = a[0..255], a1 = a[256..511], a2 = a[512..767]
///   b0 = b[0..255], b1 = b[256..511], b2 = b[512..767],
///   bt0 = bt[0..127], bt1 = bt[128..255], bt2 = bt[256..383]
///
/// Scalar multiplication of those 3-element vectors is performed,
/// with base multiplication in Fq[X]/(X^2-zeta^i'), with zeta^i'
/// being a power of zeta = 17, with i bit-reversed as used for NTTs,
/// making use of the mulcache for optimization.
///
/// All input elements are assumed <= 2^12 and the bts are
/// assumed to be as computed by mlkem_mulcache_compute.
pub(crate) fn mlkem_basemul_k3(
    r: &mut [i16; 256],
    a: &[i16; 768],
    b: &[i16; 768],
    bt: &[i16; 384],
) {
    // SAFETY: inline assembly. see [crate::low::inline_assembly_safety] for safety info.
    unsafe {
        core::arch::asm!(

        // This matches the code in the mlkem-native repository
        // https://github.com/pq-code-package/mlkem-native/blob/main/mlkem/native/aarch64/src/polyvec_basemul_acc_montgomery_cached_asm_k3.S

        Q!("    sub             " "sp, sp, # (64 + 0)"),
        Q!("    stp             " "d8, d9, [sp, # (0)]"),
        Q!("    stp             " "d10, d11, [sp, # (0x10)]"),
        Q!("    stp             " "d12, d13, [sp, # (0x20)]"),
        Q!("    stp             " "d14, d15, [sp, # (0x30)]"),
        Q!("    mov             " "w14, #0xd01"),
        Q!("    dup             " "v0.8h, w14"),
        Q!("    mov             " "w14, #0xcff"),
        Q!("    dup             " "v2.8h, w14"),
        Q!("    add             " "x4, x1, #0x200"),
        Q!("    add             " "x5, x2, #0x200"),
        Q!("    add             " "x6, x3, #0x100"),
        Q!("    add             " "x7, x1, #0x400"),
        Q!("    add             " "x8, x2, #0x400"),
        Q!("    add             " "x9, x3, #0x200"),
        Q!("    mov             " "x13, #0x10"),
        Q!("    ldr             " "q7, [x2, #0x10]"),
        Q!("    ldr             " "q20, [x2], #0x20"),
        Q!("    ldr             " "q15, [x1, #0x10]"),
        Q!("    uzp1            " "v8.8h, v20.8h, v7.8h"),
        Q!("    uzp2            " "v7.8h, v20.8h, v7.8h"),
        Q!("    ld1             " "{{ v20.8h }}, [x3], #16"),
        Q!("    ldr             " "q30, [x1], #0x20"),
        Q!("    ldr             " "q11, [x4], #0x20"),
        Q!("    uzp1            " "v16.8h, v30.8h, v15.8h"),
        Q!("    uzp2            " "v15.8h, v30.8h, v15.8h"),
        Q!("    smull           " "v30.4s, v16.4h, v7.4h"),
        Q!("    smull2          " "v7.4s, v16.8h, v7.8h"),
        Q!("    smull           " "v9.4s, v16.4h, v8.4h"),
        Q!("    smull2          " "v16.4s, v16.8h, v8.8h"),
        Q!("    smlal           " "v30.4s, v15.4h, v8.4h"),
        Q!("    smlal2          " "v7.4s, v15.8h, v8.8h"),
        Q!("    smlal           " "v9.4s, v15.4h, v20.4h"),
        Q!("    smlal2          " "v16.4s, v15.8h, v20.8h"),
        Q!("    ldur            " "q20, [x4, #-0x10]"),
        Q!("    ldr             " "q15, [x5], #0x20"),
        Q!("    uzp1            " "v8.8h, v11.8h, v20.8h"),
        Q!("    uzp2            " "v20.8h, v11.8h, v20.8h"),
        Q!("    ldur            " "q11, [x5, #-0x10]"),
        Q!("    ld1             " "{{ v27.8h }}, [x6], #16"),
        Q!("    uzp1            " "v10.8h, v15.8h, v11.8h"),
        Q!("    uzp2            " "v15.8h, v15.8h, v11.8h"),
        Q!("    smlal           " "v9.4s, v8.4h, v10.4h"),
        Q!("    smlal2          " "v16.4s, v8.8h, v10.8h"),
        Q!("    smlal           " "v30.4s, v8.4h, v15.4h"),
        Q!("    smlal2          " "v7.4s, v8.8h, v15.8h"),
        Q!("    smlal           " "v9.4s, v20.4h, v27.4h"),
        Q!("    smlal2          " "v16.4s, v20.8h, v27.8h"),
        Q!("    smlal           " "v30.4s, v20.4h, v10.4h"),
        Q!("    smlal2          " "v7.4s, v20.8h, v10.8h"),
        Q!("    ldr             " "q20, [x7], #0x20"),
        Q!("    ldur            " "q15, [x7, #-0x10]"),
        Q!("    ldr             " "q8, [x8], #0x20"),
        Q!("    uzp1            " "v11.8h, v20.8h, v15.8h"),
        Q!("    uzp2            " "v20.8h, v20.8h, v15.8h"),
        Q!("    ldur            " "q15, [x8, #-0x10]"),
        Q!("    ld1             " "{{ v27.8h }}, [x9], #16"),
        Q!("    uzp1            " "v10.8h, v8.8h, v15.8h"),
        Q!("    uzp2            " "v15.8h, v8.8h, v15.8h"),
        Q!("    smlal           " "v9.4s, v11.4h, v10.4h"),
        Q!("    smlal2          " "v16.4s, v11.8h, v10.8h"),
        Q!("    smlal           " "v30.4s, v11.4h, v15.4h"),
        Q!("    smlal2          " "v7.4s, v11.8h, v15.8h"),
        Q!("    smlal           " "v9.4s, v20.4h, v27.4h"),
        Q!("    smlal2          " "v16.4s, v20.8h, v27.8h"),
        Q!("    smlal           " "v30.4s, v20.4h, v10.4h"),
        Q!("    smlal2          " "v7.4s, v20.8h, v10.8h"),
        Q!("    ldr             " "q15, [x2], #0x20"),
        Q!("    uzp1            " "v20.8h, v9.8h, v16.8h"),
        Q!("    uzp1            " "v8.8h, v30.8h, v7.8h"),
        Q!("    mul             " "v20.8h, v20.8h, v2.8h"),
        Q!("    mul             " "v8.8h, v8.8h, v2.8h"),
        Q!("    ldr             " "q21, [x4], #0x20"),
        Q!("    smlal           " "v9.4s, v20.4h, v0.4h"),
        Q!("    smlal2          " "v16.4s, v20.8h, v0.8h"),
        Q!("    smlal           " "v30.4s, v8.4h, v0.4h"),
        Q!("    smlal2          " "v7.4s, v8.8h, v0.8h"),
        Q!("    ldur            " "q6, [x4, #-0x10]"),
        Q!("    uzp2            " "v27.8h, v9.8h, v16.8h"),
        Q!("    uzp2            " "v10.8h, v30.8h, v7.8h"),
        Q!("    ldur            " "q16, [x2, #-0x10]"),
        Q!("    ldr             " "q30, [x1, #0x10]"),
        Q!("    ld1             " "{{ v9.8h }}, [x3], #16"),
        Q!("    ldr             " "q1, [x5], #0x20"),
        Q!("    ldur            " "q12, [x5, #-0x10]"),
        Q!("    ld1             " "{{ v24.8h }}, [x6], #16"),
        Q!("    ldr             " "q19, [x7], #0x20"),
        Q!("    ldur            " "q31, [x7, #-0x10]"),
        Q!("    ldr             " "q17, [x8], #0x20"),
        Q!("    ldur            " "q18, [x8, #-0x10]"),
        Q!("    ld1             " "{{ v25.8h }}, [x9], #16"),
        Q!("    sub             " "x13, x13, #0x2"),

        Q!(Label!("Lmlkem_basemul_k3_loop", 2) ":"),
        Q!("    ldr             " "q20, [x1], #0x20"),
        Q!("    uzp1            " "v7.8h, v15.8h, v16.8h"),
        Q!("    uzp2            " "v15.8h, v15.8h, v16.8h"),
        Q!("    uzp1            " "v8.8h, v20.8h, v30.8h"),
        Q!("    uzp2            " "v20.8h, v20.8h, v30.8h"),
        Q!("    smull           " "v30.4s, v8.4h, v15.4h"),
        Q!("    smull2          " "v15.4s, v8.8h, v15.8h"),
        Q!("    smull           " "v11.4s, v8.4h, v7.4h"),
        Q!("    smull2          " "v8.4s, v8.8h, v7.8h"),
        Q!("    smlal           " "v30.4s, v20.4h, v7.4h"),
        Q!("    smlal2          " "v15.4s, v20.8h, v7.8h"),
        Q!("    smlal           " "v11.4s, v20.4h, v9.4h"),
        Q!("    smlal2          " "v8.4s, v20.8h, v9.8h"),
        Q!("    uzp1            " "v7.8h, v21.8h, v6.8h"),
        Q!("    uzp2            " "v20.8h, v21.8h, v6.8h"),
        Q!("    uzp1            " "v16.8h, v1.8h, v12.8h"),
        Q!("    uzp2            " "v9.8h, v1.8h, v12.8h"),
        Q!("    smlal           " "v11.4s, v7.4h, v16.4h"),
        Q!("    smlal2          " "v8.4s, v7.8h, v16.8h"),
        Q!("    smlal           " "v30.4s, v7.4h, v9.4h"),
        Q!("    smlal2          " "v15.4s, v7.8h, v9.8h"),
        Q!("    smlal           " "v11.4s, v20.4h, v24.4h"),
        Q!("    smlal2          " "v8.4s, v20.8h, v24.8h"),
        Q!("    smlal           " "v30.4s, v20.4h, v16.4h"),
        Q!("    smlal2          " "v15.4s, v20.8h, v16.8h"),
        Q!("    uzp1            " "v7.8h, v19.8h, v31.8h"),
        Q!("    uzp2            " "v20.8h, v19.8h, v31.8h"),
        Q!("    uzp1            " "v16.8h, v17.8h, v18.8h"),
        Q!("    uzp2            " "v9.8h, v17.8h, v18.8h"),
        Q!("    smlal           " "v11.4s, v7.4h, v16.4h"),
        Q!("    smlal2          " "v8.4s, v7.8h, v16.8h"),
        Q!("    smlal           " "v30.4s, v7.4h, v9.4h"),
        Q!("    smlal2          " "v15.4s, v7.8h, v9.8h"),
        Q!("    smlal           " "v11.4s, v20.4h, v25.4h"),
        Q!("    smlal2          " "v8.4s, v20.8h, v25.8h"),
        Q!("    smlal           " "v30.4s, v20.4h, v16.4h"),
        Q!("    smlal2          " "v15.4s, v20.8h, v16.8h"),
        Q!("    ldr             " "q16, [x2, #0x10]"),
        Q!("    uzp1            " "v7.8h, v11.8h, v8.8h"),
        Q!("    uzp1            " "v20.8h, v30.8h, v15.8h"),
        Q!("    mul             " "v7.8h, v7.8h, v2.8h"),
        Q!("    mul             " "v20.8h, v20.8h, v2.8h"),
        Q!("    zip2            " "v9.8h, v27.8h, v10.8h"),
        Q!("    zip1            " "v27.8h, v27.8h, v10.8h"),
        Q!("    smlal           " "v11.4s, v7.4h, v0.4h"),
        Q!("    smlal2          " "v8.4s, v7.8h, v0.8h"),
        Q!("    smlal           " "v30.4s, v20.4h, v0.4h"),
        Q!("    smlal2          " "v15.4s, v20.8h, v0.8h"),
        Q!("    str             " "q27, [x0], #0x20"),
        Q!("    uzp2            " "v27.8h, v11.8h, v8.8h"),
        Q!("    stur            " "q9, [x0, #-0x10]"),
        Q!("    uzp2            " "v10.8h, v30.8h, v15.8h"),
        Q!("    ldr             " "q30, [x1, #0x10]"),
        Q!("    ldr             " "q15, [x2], #0x20"),
        Q!("    ld1             " "{{ v9.8h }}, [x3], #16"),
        Q!("    ldr             " "q21, [x4], #0x20"),
        Q!("    ldur            " "q6, [x4, #-0x10]"),
        Q!("    ldr             " "q1, [x5], #0x20"),
        Q!("    ldur            " "q12, [x5, #-0x10]"),
        Q!("    ld1             " "{{ v24.8h }}, [x6], #16"),
        Q!("    ldr             " "q19, [x7], #0x20"),
        Q!("    ldur            " "q31, [x7, #-0x10]"),
        Q!("    ldr             " "q17, [x8], #0x20"),
        Q!("    ldur            " "q18, [x8, #-0x10]"),
        Q!("    ld1             " "{{ v25.8h }}, [x9], #16"),
        Q!("    sub             " "x13, x13, #0x1"),
        Q!("    cbnz            " "x13, " Label!("Lmlkem_basemul_k3_loop", 2, Before)),
        Q!("    ldr             " "q7, [x1], #0x20"),
        Q!("    uzp1            " "v20.8h, v15.8h, v16.8h"),
        Q!("    uzp2            " "v15.8h, v15.8h, v16.8h"),
        Q!("    uzp1            " "v23.8h, v7.8h, v30.8h"),
        Q!("    uzp2            " "v11.8h, v7.8h, v30.8h"),
        Q!("    smull2          " "v8.4s, v23.8h, v20.8h"),
        Q!("    smull           " "v5.4s, v23.4h, v20.4h"),
        Q!("    smull2          " "v30.4s, v23.8h, v15.8h"),
        Q!("    uzp1            " "v28.8h, v1.8h, v12.8h"),
        Q!("    smlal2          " "v8.4s, v11.8h, v9.8h"),
        Q!("    smlal           " "v5.4s, v11.4h, v9.4h"),
        Q!("    uzp1            " "v3.8h, v21.8h, v6.8h"),
        Q!("    smull           " "v16.4s, v23.4h, v15.4h"),
        Q!("    smlal2          " "v8.4s, v3.8h, v28.8h"),
        Q!("    smlal           " "v5.4s, v3.4h, v28.4h"),
        Q!("    uzp2            " "v29.8h, v21.8h, v6.8h"),
        Q!("    uzp1            " "v7.8h, v17.8h, v18.8h"),
        Q!("    smlal2          " "v8.4s, v29.8h, v24.8h"),
        Q!("    uzp1            " "v14.8h, v19.8h, v31.8h"),
        Q!("    smlal           " "v16.4s, v11.4h, v20.4h"),
        Q!("    smlal2          " "v30.4s, v11.8h, v20.8h"),
        Q!("    smlal2          " "v8.4s, v14.8h, v7.8h"),
        Q!("    uzp2            " "v20.8h, v1.8h, v12.8h"),
        Q!("    uzp2            " "v21.8h, v19.8h, v31.8h"),
        Q!("    smlal2          " "v30.4s, v3.8h, v20.8h"),
        Q!("    smlal           " "v16.4s, v3.4h, v20.4h"),
        Q!("    smlal           " "v5.4s, v29.4h, v24.4h"),
        Q!("    uzp2            " "v9.8h, v17.8h, v18.8h"),
        Q!("    smlal2          " "v30.4s, v29.8h, v28.8h"),
        Q!("    smlal           " "v16.4s, v29.4h, v28.4h"),
        Q!("    smlal           " "v5.4s, v14.4h, v7.4h"),
        Q!("    smlal2          " "v8.4s, v21.8h, v25.8h"),
        Q!("    smlal2          " "v30.4s, v14.8h, v9.8h"),
        Q!("    smlal           " "v16.4s, v14.4h, v9.4h"),
        Q!("    smlal           " "v5.4s, v21.4h, v25.4h"),
        Q!("    zip1            " "v20.8h, v27.8h, v10.8h"),
        Q!("    smlal2          " "v30.4s, v21.8h, v7.8h"),
        Q!("    smlal           " "v16.4s, v21.4h, v7.4h"),
        Q!("    uzp1            " "v7.8h, v5.8h, v8.8h"),
        Q!("    str             " "q20, [x0], #0x20"),
        Q!("    mul             " "v15.8h, v7.8h, v2.8h"),
        Q!("    uzp1            " "v7.8h, v16.8h, v30.8h"),
        Q!("    zip2            " "v31.8h, v27.8h, v10.8h"),
        Q!("    mul             " "v20.8h, v7.8h, v2.8h"),
        Q!("    smlal           " "v5.4s, v15.4h, v0.4h"),
        Q!("    smlal2          " "v8.4s, v15.8h, v0.8h"),
        Q!("    stur            " "q31, [x0, #-0x10]"),
        Q!("    smlal2          " "v30.4s, v20.8h, v0.8h"),
        Q!("    smlal           " "v16.4s, v20.4h, v0.4h"),
        Q!("    uzp2            " "v15.8h, v5.8h, v8.8h"),
        Q!("    uzp2            " "v20.8h, v16.8h, v30.8h"),
        Q!("    zip1            " "v7.8h, v15.8h, v20.8h"),
        Q!("    zip2            " "v20.8h, v15.8h, v20.8h"),
        Q!("    str             " "q7, [x0], #0x20"),
        Q!("    stur            " "q20, [x0, #-0x10]"),
        Q!("    ldp             " "d8, d9, [sp, # (0 + 0)]"),
        Q!("    ldp             " "d10, d11, [sp, # (0x10 + 0)]"),
        Q!("    ldp             " "d12, d13, [sp, # (0x20 + 0)]"),
        Q!("    ldp             " "d14, d15, [sp, # (0x30 + 0)]"),
        Q!("    add             " "sp, sp, # (64 + 0)"),
        inout("x0") r.as_mut_ptr() => _,
        inout("x1") a.as_ptr() => _,
        inout("x2") b.as_ptr() => _,
        inout("x3") bt.as_ptr() => _,
        // clobbers
        out("v0") _,
        out("v1") _,
        out("v10") _,
        out("v11") _,
        out("v12") _,
        out("v13") _,
        out("v14") _,
        out("v15") _,
        out("v16") _,
        out("v17") _,
        out("v18") _,
        out("v19") _,
        out("v2") _,
        out("v20") _,
        out("v21") _,
        out("v23") _,
        out("v24") _,
        out("v25") _,
        out("v27") _,
        out("v28") _,
        out("v29") _,
        out("v3") _,
        out("v30") _,
        out("v31") _,
        out("v5") _,
        out("v6") _,
        out("v7") _,
        out("v8") _,
        out("v9") _,
        out("x13") _,
        out("x14") _,
        out("x4") _,
        out("x5") _,
        out("x6") _,
        out("x7") _,
        out("x8") _,
        out("x9") _,
            )
    };
}