Skip to content

Commit cb6bb10

Browse files
committed
Initial risc-v vector extension support (using standard vector intrinsics.)
Signed-off-by: Markku-Juhani O. Saarinen <[email protected]>
1 parent 97bfbfa commit cb6bb10

File tree

9 files changed

+1122
-1
lines changed

9 files changed

+1122
-1
lines changed

examples/monolithic_build/mlkem_native_monobuild.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,37 @@
455455
#undef MLK_NTT_BOUND
456456
/* mlkem/native/meta.h */
457457
#undef MLK_NATIVE_META_H
458+
/* mlkem/native/riscv64/meta.h */
459+
#undef MLK_ARITH_BACKEND_RISCV64
460+
#undef MLK_NATIVE_RISCV64_META_H
461+
#undef MLK_USE_NATIVE_INTT
462+
#undef MLK_USE_NATIVE_NTT
463+
#undef MLK_USE_NATIVE_POLYVEC_BASEMUL_ACC_MONTGOMERY_CACHED
464+
#undef MLK_USE_NATIVE_POLY_MULCACHE_COMPUTE
465+
#undef MLK_USE_NATIVE_POLY_REDUCE
466+
#undef MLK_USE_NATIVE_POLY_TOMONT
467+
#undef MLK_USE_NATIVE_REJ_UNIFORM
468+
/* mlkem/native/riscv64/src/arith_native_riscv64.h */
469+
#undef MLK_NATIVE_RISCV64_SRC_ARITH_NATIVE_RISCV64_H
470+
#undef mlk_rv64v_poly_add
471+
#undef mlk_rv64v_poly_basemul_mont_add_k2
472+
#undef mlk_rv64v_poly_basemul_mont_add_k3
473+
#undef mlk_rv64v_poly_basemul_mont_add_k4
474+
#undef mlk_rv64v_poly_invntt_tomont
475+
#undef mlk_rv64v_poly_ntt
476+
#undef mlk_rv64v_poly_reduce
477+
#undef mlk_rv64v_poly_sub
478+
#undef mlk_rv64v_poly_tomont
479+
#undef mlk_rv64v_rej_uniform
480+
/* mlkem/native/riscv64/src/rv64v_settings.h */
481+
#undef MLKEM_QI
482+
#undef MLK_MONT_NR
483+
#undef MLK_MONT_R1
484+
#undef MLK_MONT_R2
485+
#undef MLK_NATIVE_RISCV64_SRC_RV64V_SETTINGS_H
486+
#undef MLK_RVV_E16M1_VL
487+
#undef MLK_RVV_VLEN
488+
#undef MLK_RVV_WIDENING_MUL
458489
/* mlkem/native/x86_64/meta.h */
459490
#undef MLK_ARITH_BACKEND_X86_64_DEFAULT
460491
#undef MLK_NATIVE_X86_64_META_H

mlkem/native/meta.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,8 @@
1818
#include "x86_64/meta.h"
1919
#endif
2020

21+
#ifdef MLK_SYS_RISCV64
22+
#include "riscv64/meta.h"
23+
#endif
24+
2125
#endif /* !MLK_NATIVE_META_H */

mlkem/native/riscv64/meta.h

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (c) The mlkem-native project authors
3+
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
4+
*/
5+
6+
#ifndef MLK_NATIVE_RISCV64_META_H
7+
#define MLK_NATIVE_RISCV64_META_H
8+
9+
/* Identifier for this backend so that source and assembly files
10+
* in the build can be appropriately guarded. */
11+
#define MLK_ARITH_BACKEND_RISCV64
12+
13+
/* Set of primitives that this backend replaces */
14+
#define MLK_USE_NATIVE_NTT
15+
#define MLK_USE_NATIVE_INTT
16+
#define MLK_USE_NATIVE_POLY_TOMONT
17+
#define MLK_USE_NATIVE_REJ_UNIFORM
18+
#define MLK_USE_NATIVE_POLY_REDUCE
19+
#define MLK_USE_NATIVE_POLY_MULCACHE_COMPUTE
20+
#define MLK_USE_NATIVE_POLYVEC_BASEMUL_ACC_MONTGOMERY_CACHED
21+
22+
#include "../../common.h"
23+
24+
#if !defined(__ASSEMBLER__)
25+
26+
#include "src/arith_native_riscv64.h"
27+
28+
static MLK_INLINE void mlk_ntt_native(int16_t data[MLKEM_N])
29+
{
30+
mlk_rv64v_poly_ntt(data);
31+
}
32+
33+
static MLK_INLINE void mlk_intt_native(int16_t data[MLKEM_N])
34+
{
35+
mlk_rv64v_poly_invntt_tomont(data);
36+
}
37+
38+
static MLK_INLINE void mlk_poly_tomont_native(int16_t data[MLKEM_N])
39+
{
40+
mlk_rv64v_poly_tomont(data);
41+
}
42+
43+
static MLK_INLINE int mlk_rej_uniform_native(int16_t *r, unsigned len,
44+
const uint8_t *buf,
45+
unsigned buflen)
46+
{
47+
return mlk_rv64v_rej_uniform(r, len, buf, buflen);
48+
}
49+
50+
static MLK_INLINE void mlk_poly_reduce_native(int16_t data[MLKEM_N])
51+
{
52+
mlk_rv64v_poly_reduce(data);
53+
}
54+
55+
static MLK_INLINE void mlk_poly_mulcache_compute_native(
56+
int16_t x[MLKEM_N / 2], const int16_t y[MLKEM_N])
57+
{
58+
(void)x; /* not using the cache atm */
59+
(void)y;
60+
}
61+
62+
static MLK_INLINE void mlk_polyvec_basemul_acc_montgomery_cached_k2_native(
63+
int16_t r[MLKEM_N], const int16_t a[2 * MLKEM_N],
64+
const int16_t b[2 * MLKEM_N], const int16_t b_cache[2 * (MLKEM_N / 2)])
65+
{
66+
(void)b_cache;
67+
mlk_rv64v_poly_basemul_mont_add_k2(r, a, b);
68+
}
69+
70+
static MLK_INLINE void mlk_polyvec_basemul_acc_montgomery_cached_k3_native(
71+
int16_t r[MLKEM_N], const int16_t a[3 * MLKEM_N],
72+
const int16_t b[3 * MLKEM_N], const int16_t b_cache[3 * (MLKEM_N / 2)])
73+
{
74+
(void)b_cache;
75+
mlk_rv64v_poly_basemul_mont_add_k3(r, a, b);
76+
}
77+
78+
static MLK_INLINE void mlk_polyvec_basemul_acc_montgomery_cached_k4_native(
79+
int16_t r[MLKEM_N], const int16_t a[4 * MLKEM_N],
80+
const int16_t b[4 * MLKEM_N], const int16_t b_cache[4 * (MLKEM_N / 2)])
81+
{
82+
(void)b_cache;
83+
mlk_rv64v_poly_basemul_mont_add_k4(r, a, b);
84+
}
85+
86+
#endif /* !__ASSEMBLER__ */
87+
88+
#endif /* !MLK_NATIVE_RISCV64_META_H */

mlkem/native/riscv64/riscv64-notes.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
[//]: # (SPDX-License-Identifier: CC-BY-4.0)
2+
3+
# rv64v-notes.md
4+
5+
Notes on RISC-V Vector support.
6+
7+
**WARNING** This is highly experimental. Currently vlen=256 only.
8+
9+
### Some preprequisites for cross compiling
10+
11+
Here's a collection of prerequisites (may contain extras/duplicates:
12+
```
13+
sudo apt install \
14+
asciidoctor autoconf automake autotools-dev bc bison build-essential ccache \
15+
clang clang-format cmake curl device-tree-compiler flex g++ gawk gdb git \
16+
gperf graphviz help2man libeigen3-dev libexpat1-dev libffi-dev libfl2 \
17+
libfl-dev libglib2.0-dev libgmp-dev libgoogle-perftools-dev libmpc-dev \
18+
libmpfr-dev libreadline-dev libtool ninja-build patchutils perl pkg-config \
19+
python3 python3-dev python3-pip slirp tcl-dev texinfo tio xdot zlib1g \
20+
zlib1g-dev libboost-all-dev libboost-system-dev libboost-python-dev \
21+
libboost-filesystem-dev libboost-thread-dev libboost-program-options-dev \
22+
libftdi-dev libusb-1.0-0-dev libftdi1-dev
23+
```
24+
25+
### Set up local tool directories
26+
27+
I have the following lines at the end of In `~/.bashrc` so that toolchains
28+
can be installed without sude:
29+
```
30+
export RVSRC="$HOME/rv/src"
31+
export RISCV="$HOME/rv/riscv"
32+
export PATH="$RISCV/bin:$PATH"
33+
```
34+
35+
Just create the directories (as a regular user):
36+
```
37+
mkdir -p $RVSRC $RISCV
38+
```
39+
40+
### Build regular cross-compiler toolchains
41+
42+
Builds `riscv64-unknown-linux-gnu-*` toolchains, both gcc and clang:
43+
```
44+
cd $RVSRC
45+
git clone https://github.com/riscv/riscv-gnu-toolchain
46+
cd riscv-gnu-toolchain
47+
./configure --prefix=$RISCV --enable-llvm --enable-linux --with-arch=rv64gcv
48+
time make
49+
```
50+
This installs the tools locally locally (no `make install`.)
51+
52+
53+
### An experimental spike emulator with a RISC-V Keccak instruction:
54+
55+
The patch provides a single vector instruction for "full Keccak" used by
56+
`mlkem/fips202/native/riscv64/keccak_inst.h` when
57+
`MLK_SYS_RISCV64_KECCAK_INST` is set.
58+
The corresponding ISA extension flag (that needs to be passed to spike)
59+
is `_zvkk`.
60+
61+
```
62+
cd $RVSRC
63+
git clone https://github.com/mjosaarinen/riscv-isa-sim.git
64+
cd riscv-isa-sim
65+
git checkout dev-keccak
66+
mkdir build
67+
cd build
68+
../configure --prefix=$RISCV --with-target=riscv64-unknown-linux-gnu
69+
time make
70+
make install
71+
```
72+
73+
### You'll also need pk
74+
```
75+
cd $RVSRC
76+
git clone https://github.com/riscv-software-src/riscv-pk.git
77+
cd riscv-pk
78+
mkdir build
79+
cd build
80+
../configure --prefix=$RISCV --host=riscv64-unknown-linux-gnu CC=clang-19
81+
make
82+
make install
83+
```
84+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) The mlkem-native project authors
3+
* SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
4+
*/
5+
#ifndef MLK_NATIVE_RISCV64_SRC_ARITH_NATIVE_RISCV64_H
6+
#define MLK_NATIVE_RISCV64_SRC_ARITH_NATIVE_RISCV64_H
7+
8+
#include <stdint.h>
9+
#include "../../../common.h"
10+
11+
#define mlk_rv64v_poly_ntt MLK_NAMESPACE(ntt_riscv64)
12+
void mlk_rv64v_poly_ntt(int16_t *);
13+
14+
#define mlk_rv64v_poly_invntt_tomont MLK_NAMESPACE(intt_riscv64)
15+
void mlk_rv64v_poly_invntt_tomont(int16_t *r);
16+
17+
#define mlk_rv64v_poly_basemul_mont_add_k2 MLK_NAMESPACE(basemul_add_k2_riscv64)
18+
void mlk_rv64v_poly_basemul_mont_add_k2(int16_t *r, const int16_t *a,
19+
const int16_t *b);
20+
21+
#define mlk_rv64v_poly_basemul_mont_add_k3 MLK_NAMESPACE(basemul_add_k3_riscv64)
22+
void mlk_rv64v_poly_basemul_mont_add_k3(int16_t *r, const int16_t *a,
23+
const int16_t *b);
24+
25+
#define mlk_rv64v_poly_basemul_mont_add_k4 MLK_NAMESPACE(basemul_add_k4_riscv64)
26+
void mlk_rv64v_poly_basemul_mont_add_k4(int16_t *r, const int16_t *a,
27+
const int16_t *b);
28+
29+
#define mlk_rv64v_poly_tomont MLK_NAMESPACE(tomont_riscv64)
30+
void mlk_rv64v_poly_tomont(int16_t *r);
31+
32+
#define mlk_rv64v_poly_reduce MLK_NAMESPACE(reduce_riscv64)
33+
void mlk_rv64v_poly_reduce(int16_t *r);
34+
35+
#define mlk_rv64v_poly_add MLK_NAMESPACE(poly_add_riscv64)
36+
void mlk_rv64v_poly_add(int16_t *r, const int16_t *a, const int16_t *b);
37+
38+
#define mlk_rv64v_poly_sub MLK_NAMESPACE(poly_sub_riscv64)
39+
void mlk_rv64v_poly_sub(int16_t *r, const int16_t *a, const int16_t *b);
40+
41+
#define mlk_rv64v_rej_uniform MLK_NAMESPACE(rj_uniform_riscv64)
42+
unsigned int mlk_rv64v_rej_uniform(int16_t *r, unsigned int len,
43+
const uint8_t *buf, unsigned int buflen);
44+
45+
#endif /* !MLK_NATIVE_RISCV64_SRC_ARITH_NATIVE_RISCV64_H */

0 commit comments

Comments
 (0)