Skip to content

Armv8.1-M: add pqmx MVE inverse NTT - #1367

Open
bremoran wants to merge 12 commits into
mainfrom
armv81m-pqmx-intt
Open

Armv8.1-M: add pqmx MVE inverse NTT#1367
bremoran wants to merge 12 commits into
mainfrom
armv81m-pqmx-intt

Conversation

@bremoran

@bremoran bremoran commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Adds the pqmx Cortex-M55 MVE iNTT and keeps pqmx’s 4×4-transposed NTT order across native NTT, matrix expansion, pointwise operations, and iNTT. The native iNTT consumes that custom order and returns normal coefficient order.

The ML-DSA 41978 ToMont scale remains a separate scalar C step; folding it into the assembly is intentionally left for follow-up work.

This includes the clean input, selected SLOTHY schedule, autogen integration, ABI checker coverage, and direct iNTT/custom-order round-trip tests.

N657x0 component measurements, compared in the same session with #1327’s native forward NTT plus C iNTT baseline:

Component Before After Change
poly_ntt 3,402 2,716 −20.2%
poly_invntt_tomont 34,049 7,583 −77.7%

The matrix-pointwise component rises by approximately 1.0–1.1% due to the required conversion to pqmx custom order. End-to-end average cycle counts improve across all parameter sets, with signing improving by roughly 10–13%.

Fixes: #1328

bremoran added 12 commits August 3, 2026 17:16
Build the ABI checker and assembly sources directly with Zephyr's target toolchain. Select the Armv8.1-M checker for M55 and preserve OPT/AUTO through the run stage so the checker is actually executed.

Signed-off-by: Brendan Moran <brendan.moran@arm.com>
Include OPT, the selected FIPS202 backend, and configurable test counts in the active build marker so changes to those inputs rebuild stale Zephyr binaries. Track the native assembly amalgamation and its direct development-source include as explicit dependencies, and allow QEMU execution timeouts to be overridden.

Signed-off-by: Brendan Moran <brendan.moran@arm.com>
Signed-off-by: Brendan Moran <brendan.moran@arm.com>
The lazy/eager polyvector unit test allocates both ML-DSA-87
representations and their scratch space through MLD_ALLOC. The default
MLD_ALLOC implementation expands to aligned automatic arrays, so this
single test exceeds the Zephyr test thread stack on the Cortex-M55 test
configuration.

Use test-local, aligned static buffers for this workspace. The
TEST_STATIC_ALLOC and TEST_STATIC_FREE helpers are deliberately scoped
to test_unit.c: they preserve cleanup by zeroizing every buffer and
clearing its pointer, without changing the allocator used by production
code or other tests.

Only test/src/test_unit.c changes. The test inputs, comparisons, and
coverage remain the same; this commit changes where its temporary
workspace is stored.

Signed-off-by: Brendan Moran <brendan.moran@arm.com>
Generated ABI checks normally fill every assembly argument buffer with
random bytes. That is unsuitable for interfaces containing control data.
The Armv8.1-M Keccak x1 permutation consumes 49 round-constant words and
requires the final word to be 0x000000ff as a loop terminator. Leaving
that word random can make the checker read beyond the supplied buffer.

Add an optional test_bytes mapping to buffer entries in the assembly ABI
YAML. scripts/autogen validates that offsets are integers within the
buffer and that values are bytes, sorts the overrides, and emits them
after randombytes initializes the rest of the buffer. Existing ABI
metadata without test_bytes retains its current behaviour.

Document the new metadata in test/abicheck/README.md. The generic
facility is introduced here before its Keccak x1 consumer so the
following backend commit contains only feature-specific metadata and
generated checks.

Signed-off-by: Brendan Moran <brendan.moran@arm.com>
Add the first of three deliberately separated Cortex-M55 Keccak changes: a known-good scalar baseline derived from the Adomnicai/XKCP Armv7-M implementation. Measurements made while preparing the series showed that the existing Cortex-M7 schedule runs faster on Cortex-M55 than the Cortex-M4 schedule, so this commit establishes the M7-scheduled implementation before later commits introduce an M55 scheduling model and a 64-bit load/store-aware scalar input. The code in this commit is scalar and does not require or use MVE.

Keep the Keccak state in the even/odd bit-interleaved representation across permutations. Native xor and extract hooks convert only the lanes crossing the byte interface, and a private round-constant table supplies the 24 interleaved constants and loop terminator expected by the permutation.

Organize the implementation so its origin and generated form remain reviewable. dev/fips202/armv81m_clean contains only the unscheduled permutation input. dev/fips202/armv81m_opt contains the SLOTHY driver, Makefile, concise development README, C wrapper, scheduled permutation, and separate scalar xor and extract assembly sources. Splitting the helpers gives every assembly file one external entry point and lets the normal loop-label check cover all x1 sources.

Teach scripts/autogen to merge the existing Armv8.1-M and new x1 development directories into the production directory. The retained filename set is derived from both inputs, replacing the hard-coded keep list and ensuring removed or renamed files cannot leave stale output. The helper assembly is simplified and synchronized like other production assembly, so mldsa_native_asm.S includes only files under mldsa/ and no longer reaches into dev/. Zephyr custom builds track all production assembly inputs for reliable rebuilds.

Describe and generate AAPCS32 checks for all three external assembly routines: permutation, xor, and extract. The scalar routines carry no MVE feature requirement. Add focused xor and extract tests for zero length, unaligned starts, 7/8/9-byte lane boundaries, cross-lane ranges, final-lane ranges, and the complete 200-byte state; canary-filled extraction buffers also detect writes beyond the requested length. Existing representation-aware permutation tests continue to compare against the portable reference.

Update the bibliography and license material for the imported XKCP, Adomnicai, and SLOTHY work. Keep the x1 header, constants, sources, generation path, tests, and ABI metadata separate from the established parallel implementation so no x4 source file is changed.

Signed-off-by: Brendan Moran <brendan.moran@arm.com>
Make the clean M7 Keccak source self-contained so SLOTHY retains its ABI metadata and integration guards during regeneration.

Signed-off-by: Brendan Moran <brendan.moran@arm.com>
Regenerate the scalar Keccak-f[1600] x1 schedule with the Armv8.1-M Cortex-M55 SLOTHY model, retain scalar ABI metadata, and wire the generated M55 artifact through autogen and production assembly.

Hypothesis: H_SLOTHY_001_LDRD_STRD_MODEL
Signed-off-by: Brendan Moran <brendan.moran@arm.com>
Regenerate the scalar Cortex-M55 Keccak-f[1600] schedule from the clean source using paired LDRD loads for the bit-interleaved theta parities. Keep the clean-to-opt-to-native pipeline explicit, document its scalar x1 and MVE x4 routing, and express the x1 state's 8-byte alignment in the assembly interface.

Signed-off-by: Brendan Moran <brendan.moran@arm.com>
Add MVE fast paths for x1 Keccak state XOR and extraction through byte 192, retaining the scalar helper for final-lane ranges and non-MVE Armv8.1-M builds. Generate the optimized and native sources, ABI checks, and boundary coverage.

Signed-off-by: Brendan Moran <brendan.moran@arm.com>
Import the pqmx Cortex-M55 forward NTT with its clean input and selected SLOTHY schedule. Restore the repository's standard bit-reversed output order in the Armv8.1-M wrapper, retain the C inverse NTT, and wire the backend through autogen, ABI checks, and Zephyr builds.

Refs: #1327
Signed-off-by: Brendan Moran <brendan.moran@arm.com>
Retain pqmx's custom NTT order through matrix operations and consume it with a native inverse NTT. Keep the ML-DSA 41978 ToMont scale separate in C.\n\nRef: #1328

Signed-off-by: Brendan Moran <brendan.moran@arm.com>
@bremoran
bremoran requested a review from a team as a code owner August 7, 2026 17:12
/// Copyright (c) 2022 Arm Limited
/// Copyright (c) 2022 Hanno Becker
/// Copyright (c) 2023 Amin Abdulrahman, Matthias Kannwischer
/// SPDX-License-Identifier: MIT

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bremoran Please can we keep the usual triple-licensing? I think there are two options:

  • Let an LLM rewrite the code based on https://eprint.iacr.org/2021/998 and/or the precedent of the other backends.
  • Check the re-licensing discussions with Hugo for whether the consent he provided on behalf of Arm would cover the relicensing hear. Or reach out internally directly.

@hanno-becker hanno-becker left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we sort out the licensing? I would like to stick with the established triple-licensing. We worked hard to achieve it and I don't want to deviate from it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Armv8.1-M: add regular and SLOTHY-optimized pqmx Cortex-M55 iNTT

2 participants