Skip to content

Commit f2aab8a

Browse files
ilway25bhess
andauthored
Neon implementation (#5)
* Add NEON boilerplate * Add mul_add_mat_x_m_mat for neon * Add mul_add_mat_trans_x_m_mat for neon * Add mul_add_m_upper_triangular_mat_x_mat for neon * Add mul_add_m_upper_triangular_mat_x_mat_trans for neon * -O^t * (P1*O + P2) with AVX2 technique * Improve V*P1*V^t & V*L * Add mayo_12_P1P1t_times_O_neon * Add S*P*S^t * Remove old neon implementation * Adapt AVX's EF ot Neon * Adapt Christer Knorborg's Neon AES * Finish Mayo3 for Neon * Finish Mayo5 for Neon * Remove accidentally added neon header dependency * Add Neon to README * Add m1cycles * Uses vsliq_n_u8 when accumulating odd/even results * Remove useless old matrix code * Make it work with RPi4 * Fix license issues * add action for macos-latest --------- Co-authored-by: Basil Hess <[email protected]>
1 parent 3dace0e commit f2aab8a

23 files changed

+2731
-39
lines changed

.cmake/target.cmake

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# SPDX-License-Identifier: Apache-2.0
22

3-
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64")
3+
if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm64" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64")
44
add_definitions(-DTARGET_ARM64)
55
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm")
66
add_definitions(-DTARGET_ARM)
@@ -15,7 +15,9 @@ else()
1515
add_definitions(-DTARGET_OTHER)
1616
endif()
1717

18-
if (UNIX)
18+
if (APPLE)
19+
add_definitions(-DTARGET_OS_MAC)
20+
elseif (UNIX)
1921
add_definitions(-DTARGET_OS_UNIX)
2022
else()
2123
add_definitions(-DTARGET_OS_OTHER)
@@ -47,6 +49,7 @@ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
4749
-mcpu=apple-m1)
4850
endif()
4951
option(ENABLE_AESNI "Use AESni" OFF)
52+
option(ENABLE_AESNEON "Use AES-NEON" ON)
5053
endif()
5154

5255

@@ -60,6 +63,9 @@ elseif(${MAYO_BUILD_TYPE} MATCHES "opt")
6063
elseif(${MAYO_BUILD_TYPE} MATCHES "avx2")
6164
add_definitions(-DMAYO_BUILD_TYPE_AVX2)
6265
option(ENABLE_PARAMS_DYNAMIC "Use dynamic parameters" OFF)
66+
elseif(${MAYO_BUILD_TYPE} MATCHES "neon")
67+
add_definitions(-DMAYO_BUILD_TYPE_NEON)
68+
option(ENABLE_PARAMS_DYNAMIC "Use dynamic parameters" OFF)
6369
endif()
6470

6571
separate_arguments(C_OPT_FLAGS UNIX_COMMAND "${G_C_OPT_FLAGS}")

.github/workflows/macos_m1.yml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: CMake (macos-neon)
2+
3+
on:
4+
push:
5+
branches: [ '*' ]
6+
pull_request:
7+
branches: [ "main" ]
8+
9+
env:
10+
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
11+
BUILD_TYPE: Debug
12+
13+
jobs:
14+
build_test:
15+
runs-on: macos-latest
16+
strategy:
17+
matrix:
18+
mayo_build_type: [neon]
19+
20+
steps:
21+
- uses: actions/checkout@v3
22+
- name: Set up Python 3.10
23+
uses: actions/setup-python@v5
24+
with:
25+
python-version: "3.10"
26+
27+
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
28+
# You can convert this to a matrix build if you need cross-platform coverage.
29+
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
30+
31+
- name: Configure CMake
32+
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
33+
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
34+
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DMAYO_BUILD_TYPE=${{ matrix.mayo_build_type }}
35+
36+
- name: Build
37+
# Build your program with the given configuration
38+
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
39+
40+
- name: Test
41+
working-directory: ${{github.workspace}}/build
42+
# Execute tests defined by the CMake configuration.
43+
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
44+
run: ctest -C ${{env.BUILD_TYPE}}
45+
46+
- name: Examples (neon)
47+
working-directory: ${{github.workspace}}/build/apps
48+
run: |
49+
./PQCgenKAT_sign_mayo_1
50+
./PQCgenKAT_sign_mayo_2
51+
./PQCgenKAT_sign_mayo_3
52+
./PQCgenKAT_sign_mayo_5
53+
./example_mayo_1
54+
./example_mayo_2
55+
./example_mayo_3
56+
./example_mayo_5
57+
./example_nistapi_mayo_1
58+
./example_nistapi_mayo_2
59+
./example_nistapi_mayo_3
60+
./example_nistapi_mayo_5
61+
if: matrix.mayo_build_type == 'neon'
62+
63+
- name: Address Sanitizer ASAN
64+
run: |
65+
rm -rf build
66+
cmake -Bbuild -DCMAKE_BUILD_TYPE=ASAN -DMAYO_BUILD_TYPE=${{ matrix.mayo_build_type }} -DCMAKE_C_COMPILER=clang
67+
cmake --build build
68+
ctest -V --test-dir build

README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ The following build options have been used to report performance numbers in the
3636
2. Optimized (AES-NI enabled): `cmake -DMAYO_BUILD_TYPE=opt -DENABLE_AESNI=ON ..`
3737
3. Optimized (AES-NI disabled): `cmake -DMAYO_BUILD_TYPE=opt -DENABLE_AESNI=OFF ..`
3838
4. AVX2: `cmake -DMAYO_BUILD_TYPE=avx2 -DENABLE_AESNI=ON ..`
39+
5. A64 M1 NEON: `cmake -DMAYO_BUILD_TYPE=neon -DENABLE_AESNI=ON ..`
40+
6. A64 RPi4 Cortex-A72 NEON: `cmake -DMAYO_BUILD_TYPE=neon -DENABLE_AESNI=OFF ..`
3941

4042
## Build options
4143

@@ -64,6 +66,7 @@ Specifies the build type for which Mayo is built. The options are `ref`, `opt` a
6466
- `ref` builds MAYO implemented with portable C code for native target architecture, using run-time parameters.
6567
- `opt` builds MAYO implemented with optimized portable C code, compiled with `-march=native` (if available) and AES acceleration (if available)
6668
- `avx2` builds MAYO implemented with optimized AVX2 code, compiled with `-march=native` (if available) and AES acceleration (if available)
69+
- `neon` builds MAYO implemented with optimized NEON code, compiled with `-march=native` (if available) and AES acceleration (if available)
6770

6871
The default build type if none is specified is `opt`.
6972

@@ -89,10 +92,10 @@ The following artifacts are built:
8992
- `libmayo_<level>_nistapi.a`: library for `MAYO_<level>` against the NIST API.
9093
- `libmayo_<level>_nistapi_test.a`: library for `MAYO_<level>` against the NIST API. Only for test, using the deterministic CTR-DRBG as backend.
9194
- `mayo_bench_<param>`: Benchmarking suites.
92-
- `mayo_test_kat_<param>` (`opt` and `avx2`), `mayo_test_kat` (`ref`): KAT test suites.
93-
- `mayo_test_scheme_<param>` (`opt` and `avx2`), `mayo_test_scheme` (`ref`): Self-test suites.
95+
- `mayo_test_kat_<param>` (`opt`, `avx2` and `neon`), `mayo_test_kat` (`ref`): KAT test suites.
96+
- `mayo_test_scheme_<param>` (`opt`, `avx2` and `neon`), `mayo_test_scheme` (`ref`): Self-test suites.
9497
- `PQCgenKAT_sign_<param>`: App for generating NIST KAT.
95-
- `example_<param>` (`opt` and `avx2`), `example_mayo` (`ref`): Example app using the MAYO API.
98+
- `example_<param>` (`opt`, `avx2` and `neon`), `example_mayo` (`ref`): Example app using the MAYO API.
9699
- `example_nistapi_<param>`: Example app using the NIST API.
97100

98101
## Test
@@ -121,8 +124,9 @@ KAT verification is done as part of the test harness (see previous section).
121124

122125
A benchmarking suite is built and runs with the following command, where `params` specifies the MAYO parameter set and `runs` the number of benchmark runs:
123126

124-
If `MAYO_BUILD_TYPE` is `opt` or `avx2`:
127+
If `MAYO_BUILD_TYPE` is `opt`, `avx2` or `neon`:
125128
- `test/mayo_bench_<param> <runs>`,
129+
- On Apple M1 chips, this must be run with root permission.
126130

127131
If `MAYO_BUILD_TYPE` is `ref`:
128132
- `test/mayo_bench <param> <runs>`,
@@ -156,9 +160,11 @@ Third party code is used in some test and common code files:
156160

157161
- `common/aes_c.c`; MIT: "Copyright (c) 2016 Thomas Pornin <[email protected]>"
158162
- `common/aes128ctr.c`: MIT: "Copyright (c) 2016-2021 Open Quantum Safe project" and Public Domain
163+
- `common/aes_neon.c`: MIT: "Copyright (c) 2024 ChristerKnorborg" and Public Domain
159164
- `common/fips202.c`: Public Domain
160165
- `common/randombytes_system.c`: MIT: Copyright (c) 2017 Daan Sprenkels <[email protected]>
161166
- `apps/PQCgenKAT_sign.c`, `common/randombytes_ctrdrbg.c`, `test/test_kat.c`: by NIST (Public Domain)
167+
- `test/m1cycles.{c,h}`, Apache 2.0 or Public Domain
162168

163169
See also the SPDX License Identifiers in the respective files.
164170

include/mayo.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@
137137
#define MAYO_NAMESPACE(s) PARAM_NAME3(opt, s)
138138
#elif defined(MAYO_BUILD_TYPE_AVX2)
139139
#define MAYO_NAMESPACE(s) PARAM_NAME3(avx2, s)
140+
#elif defined(MAYO_BUILD_TYPE_NEON)
141+
#define MAYO_NAMESPACE(s) PARAM_NAME3(neon, s)
140142
#else
141143
#error "Build type not known"
142144
#endif
@@ -370,7 +372,7 @@ int mayo_open(const mayo_params_t *p, unsigned char *m,
370372
*
371373
* The implementation corresponds to Mayo.CompactKeyGen() in the Mayo spec.
372374
* The caller is responsible to allocate sufficient memory to hold pk and sk.
373-
*
375+
*
374376
* outputs a pair (csk, cpk) \in B^{csk_bytes} x B^{cpk_bytes}, where csk and
375377
* cpk are compact representations of a Mayo secret key and public key
376378
*

src/CMakeLists.txt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
set(SOURCE_FILES_COMMON_SYS common/randombytes_system.c common/aes_c.c common/aes128ctr.c common/fips202.c common/mem.c)
1+
set(SOURCE_FILES_COMMON_SYS common/randombytes_system.c common/aes_c.c common/aes128ctr.c common/aes_neon.c common/fips202.c common/mem.c)
22

33
add_library(mayo_common_sys ${SOURCE_FILES_COMMON_SYS})
44
target_include_directories(mayo_common_sys PRIVATE common ../include)
55
target_compile_options(mayo_common_sys PUBLIC ${C_OPT_FLAGS})
66

7-
set(SOURCE_FILES_COMMON_TEST common/randombytes_ctrdrbg.c common/aes_c.c common/aes128ctr.c common/fips202.c common/mem.c)
7+
set(SOURCE_FILES_COMMON_TEST common/randombytes_ctrdrbg.c common/aes_c.c common/aes128ctr.c common/aes_neon.c common/fips202.c common/mem.c)
88

99
add_library(mayo_common_test ${SOURCE_FILES_COMMON_TEST})
1010
target_include_directories(mayo_common_test PRIVATE common ../include)
@@ -21,12 +21,22 @@ if (ENABLE_AESNI)
2121
target_compile_definitions(mayo_common_test PUBLIC ENABLE_AESNI)
2222
endif()
2323

24+
if (ENABLE_AESNEON)
25+
message("AES-NEON enabled")
26+
target_compile_definitions(mayo_common_sys PUBLIC ENABLE_AESNEON)
27+
target_compile_definitions(mayo_common_test PUBLIC ENABLE_AESNEON)
28+
endif()
29+
2430
set(SOURCE_FILES_MAYO mayo.c params.c arithmetic.c)
2531

2632
if (${MAYO_BUILD_TYPE} MATCHES "avx2")
2733
message("Building for avx2")
2834
set(INC_PLATFORM ${PROJECT_SOURCE_DIR}/src/AVX2)
2935
add_definitions(-DMAYO_AVX)
36+
elseif (${MAYO_BUILD_TYPE} MATCHES "neon")
37+
message("Building for neon")
38+
set(INC_PLATFORM ${PROJECT_SOURCE_DIR}/src/neon)
39+
add_definitions(-DMAYO_NEON)
3040
else()
3141
set(INC_PLATFORM ${PROJECT_SOURCE_DIR}/src/generic)
3242
endif()

0 commit comments

Comments
 (0)