Skip to content

Commit 1769c26

Browse files
committed
Merge branch 'main' of github.com:riscv/riscv-crypto
2 parents 56ed795 + 00e517f commit 1769c26

File tree

8 files changed

+287
-21
lines changed

8 files changed

+287
-21
lines changed

doc/vector/code-samples/Makefile

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@ LDFLAGS+=-static
3232
# with different values of VLEN.
3333
COMMON_SPIKE_FLAGS?=--isa=rv64gcv$(MARCH_EXT_FLAGS)
3434

35+
# List of VLEN values being tested.
36+
# All code samples support values >=128, some support VLEN=64.
37+
#
38+
# Each value requires a separate Spike invocation. Overriding
39+
# the list is an easy way to reduce run time if only specific
40+
# values are of interest.
41+
#
42+
# TODO: ideally we'd have logic supporting VLEN=32, which also
43+
# implies ELEN=32 (i.e., rv32). The code was developed for rv64,
44+
# hence VLEN=32 runs are not valid.
45+
TESTED_VLENS?=64 128 256 512
46+
3547
TEST_VECTORS_DIR=test-vectors
3648

3749
CBC_VECTORS=\
@@ -80,6 +92,7 @@ C_OBJECTS=\
8092
zkb-test.o \
8193
zvbb-test.o \
8294
zvbc-test.o \
95+
zvkg-test.o \
8396

8497
ASM_OBJECTS=\
8598
vlen-bits.o \
@@ -92,7 +105,7 @@ ASM_OBJECTS=\
92105
zvksed.o \
93106
zvksh.o \
94107

95-
default: aes-cbc-test aes-gcm-test sha-test sm3-test sm4-test zvbb-test zvbc-test
108+
default: aes-cbc-test aes-gcm-test sha-test sm3-test sm4-test zvbb-test zvbc-test zvkg-test
96109

97110
.PHONY: test-vectors
98111
test-vectors: $(SUBDIR_CBC_VECTORS) $(SUBDIR_GCM_VECTORS) $(SUBDIR_SHA_VECTORS)
@@ -133,52 +146,69 @@ zvbb-test: zvbb-test.o zvbb.o log.o vlen-bits.o
133146
zvbc-test: zvbc-test.o zvbc.o log.o vlen-bits.o
134147
$(LD) $(LDFLAGS) -o $@ $^
135148

136-
# TODO: add VLEN=32, VLEN=64 runs.
149+
zvkg-test: zvkg-test.o zvkg.o log.o vlen-bits.o
150+
$(LD) $(LDFLAGS) -o $@ $^
151+
137152
.PHONY: run-aes-cbc
138153
run-aes-cbc: aes-cbc-test
139-
for VLEN in 128 256 512; do \
154+
for VLEN in $(TESTED_VLENS); do \
140155
$(SPIKE) --varch=vlen:$${VLEN},elen:64 $(COMMON_SPIKE_FLAGS) $(PK) $< || exit 1; \
141156
done
142157

143-
# TODO: add VLEN=64 runs.
158+
# TODO: add logic supporting VLEN=64 runs.
144159
.PHONY: run-aes-gcm
145160
run-aes-gcm: aes-gcm-test
146-
for VLEN in 128 256 512; do \
147-
$(SPIKE) --varch=vlen:$${VLEN},elen:64 $(COMMON_SPIKE_FLAGS) $(PK) $< || exit 1; \
161+
for VLEN in $(TESTED_VLENS); do \
162+
if [[ $${VLEN} == 64 ]]; then \
163+
echo "*** Skipping $< test with VLEN=$${VLEN}"; \
164+
else \
165+
$(SPIKE) --varch=vlen:$${VLEN},elen:64 $(COMMON_SPIKE_FLAGS) $(PK) $< || exit 1; \
166+
fi \
148167
done
149168

150169
.PHONY: run-sha
151170
run-sha: sha-test
152-
for VLEN in 64 128 256 512; do \
171+
for VLEN in $(TESTED_VLENS); do \
153172
$(SPIKE) --varch=vlen:$${VLEN},elen:64 $(COMMON_SPIKE_FLAGS) $(PK) $< || exit 1; \
154173
done
155174

156175
.PHONY: run-sm3
157176
run-sm3: sm3-test
158-
for VLEN in 64 128 256 512; do \
177+
for VLEN in $(TESTED_VLENS); do \
159178
$(SPIKE) --varch=vlen:$${VLEN},elen:64 $(COMMON_SPIKE_FLAGS) $(PK) $< || exit 1; \
160179
done
161180

181+
# TODO: add logic supporting VLEN=64 runs.
162182
.PHONY: run-sm4
163183
run-sm4: sm4-test
164-
for VLEN in 128 256 512; do \
165-
$(SPIKE) --varch=vlen:$${VLEN},elen:64 $(COMMON_SPIKE_FLAGS) $(PK) $< || exit 1; \
184+
for VLEN in $(TESTED_VLENS); do \
185+
if [[ $${VLEN} == 64 ]]; then \
186+
echo "*** Skipping $< test with VLEN=$${VLEN}"; \
187+
else \
188+
$(SPIKE) --varch=vlen:$${VLEN},elen:64 $(COMMON_SPIKE_FLAGS) $(PK) $< || exit 1; \
189+
fi \
166190
done
167191

168192
.PHONY: run-zvbb
169193
run-zvbb: zvbb-test
170-
for VLEN in 64 128 256 512; do \
194+
for VLEN in $(TESTED_VLENS); do \
171195
$(SPIKE) --varch=vlen:$${VLEN},elen:64 $(COMMON_SPIKE_FLAGS) $(PK) $< || exit 1; \
172196
done
173197

174198
.PHONY: run-zvbc
175199
run-zvbc: zvbc-test
176-
for VLEN in 64 128 256 512; do \
200+
for VLEN in $(TESTED_VLENS); do \
201+
$(SPIKE) --varch=vlen:$${VLEN},elen:64 $(COMMON_SPIKE_FLAGS) $(PK) $< || exit 1; \
202+
done
203+
204+
.PHONY: run-zvkg
205+
run-zvkg: zvkg-test
206+
for VLEN in $(TESTED_VLENS); do \
177207
$(SPIKE) --varch=vlen:$${VLEN},elen:64 $(COMMON_SPIKE_FLAGS) $(PK) $< || exit 1; \
178208
done
179209

180210
.PHONY: run-tests
181-
run-tests: run-aes-cbc run-aes-gcm run-sha run-sm3 run-sm4 run-zvbb run-zvbc
211+
run-tests: run-aes-cbc run-aes-gcm run-sha run-sm3 run-sm4 run-zvbb run-zvbc run-zvkg
182212

183213
.PHONY: clean
184214
clean:

doc/vector/code-samples/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,27 @@ make run-tests TARGET=riscv64-unknown-linux-gnu \
7373
- `sm3-test` - Build the SM3 example.
7474
- `sm4-test` - Build the SM4 example.
7575
- `zvbb-test` - Build the Zvbb example.
76+
- `zvbc-test` - Build the Zvbc example.
77+
- `zvkg-test` - Build the Zvkg example.
7678
- `run-tests` - Build and run all examples.
7779
- `run-aes-cbc` - Build and run the AES-CBC example in Spike.
7880
- `run-aes-gcm` - Build and run the AES-GCM example in Spike.
7981
- `run-sha` - Build and run the SHA example in Spike.
8082
- `run-sm3` - Build and run the SM3 example in Spike.
8183
- `run-sm4` - Build and run the SM4 example in Spike.
8284
- `run-zvbb` - Build and run the Zvbb example in Spike.
85+
- `run-zvbc` - Build and run the Zvbc example in Spike.
86+
- `run-zvkg` - Build and run the Zvkg example in Spike.
8387

8488
### Make variables
8589

8690
- `TARGET` - Target triplet to use. By default riscv64-linux-gnu.
8791
- `PK` - Location of the riscv-pk binary. By default it's
8892
`~/RISC-V/$(TARGET)/bin/pk`.
93+
- `TESTED_VLENS` - Space separated list of VLEN values being tested
94+
against. All algorithms support VLEN>=128, most support VLEN=64.
95+
Tests that do not support VLEN=64 will be skipped if that value
96+
is present in the list.
8997

9098
See Makefile for more details.
9199

doc/vector/code-samples/aes-gcm-test.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -426,15 +426,18 @@ run_test_zvb(const struct aes_gcm_test* test, int keylen)
426426
}
427427

428428
for (int i = 0; i < test->ctlen / 16; i++) {
429-
if (!test->encrypt)
429+
if (!test->encrypt) {
430430
ghash(&Y, (uint128 *)(&xordata[16 * i]), &H);
431+
}
431432

432433
encrypt_block(&buf[16 * i], &counter_block, &key);
433-
for (int j = 0; j < 16; j++)
434+
for (int j = 0; j < 16; j++) {
434435
buf[16 * i + j] ^= xordata[16 * i + j];
436+
}
435437

436-
if (test->encrypt)
438+
if (test->encrypt) {
437439
ghash(&Y, (uint128 *)(&buf[16 * i]), &H);
440+
}
438441

439442
increment_counter_block(&counter_block);
440443
}
@@ -449,8 +452,9 @@ run_test_zvb(const struct aes_gcm_test* test, int keylen)
449452

450453
// buf shall have enough space to fit the extra bytes.
451454
encrypt_block(&buf[test->ctlen - rem], &counter_block, &key);
452-
for (int i = 0; i < rem; i++)
455+
for (int i = 0; i < rem; i++) {
453456
buf[test->ctlen - rem + i] ^= xordata[test->ctlen - rem + i];
457+
}
454458

455459
if (test->encrypt) {
456460
bzero(&temp, sizeof(temp));

doc/vector/code-samples/zvkg-test.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// Copyright 2023 Rivos Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <assert.h>
16+
#include <byteswap.h>
17+
#include <inttypes.h>
18+
#include <stdarg.h>
19+
#include <stdbool.h>
20+
#include <stdint.h>
21+
#include <stdio.h>
22+
#include <stdlib.h>
23+
#include <string.h>
24+
25+
#include "log.h"
26+
#include "vlen-bits.h"
27+
#include "zvkg.h"
28+
29+
// @brief Return a 32-bit randomly generated number using rand()
30+
//
31+
// @return uint32_t
32+
//
33+
uint32_t
34+
rand32()
35+
{
36+
return rand();
37+
}
38+
39+
// @brief Tests vectorized multiply in Galois Field instruction vgmul
40+
// using randomly generated test vectors.
41+
//
42+
// 'vghsh.vv' is used to generate the "golden" outputs that we check vgmul
43+
// against. The correctness of vghsh is established in the test 'aes-gcm-test'.
44+
//
45+
int
46+
test_rand_vgmul()
47+
{
48+
#define kNumGroups 113
49+
#define kNumElements (4 * (kNumGroups))
50+
#define kRounds 100
51+
52+
uint32_t y[kNumElements];
53+
uint32_t z[kNumElements];
54+
uint32_t expected[kNumElements];
55+
uint32_t actual[kNumElements];
56+
57+
LOG("--- Testing vgmul against vghsh");
58+
59+
for (size_t round = 0; round < kRounds; ++round) {
60+
for (size_t i = 0; i < kNumElements; ++i) {
61+
actual[i] = expected[i] = rand32();
62+
y[i] = rand32();
63+
z[i] = 0;
64+
}
65+
66+
// The reference (expected) output is produced by vghsh
67+
zvkg_vghsh_vv(expected, z, y, kNumGroups);
68+
69+
// The tested (actual) output is produced by vgmul
70+
zvkg_vgmul_vv(actual, y, kNumGroups);
71+
72+
if (memcmp(actual, expected, sizeof(actual))) {
73+
LOG("FAILURE: 'actual' does NOT match 'expected'");
74+
for (size_t i = 0; i < kNumElements; ++i) {
75+
const uint32_t exp = expected[i];
76+
const uint32_t act = actual[i];
77+
LOG("expected[%3zd]: 0x%08" PRIx32
78+
", actual[%3zd]: 0x%08" PRIx32
79+
" %s", i, exp, i, act, (exp == act ? "==" : "!="));
80+
}
81+
return 1;
82+
}
83+
}
84+
85+
return 0;
86+
}
87+
88+
// @brief Calls test functions for our intrinsics
89+
//
90+
// @return int
91+
//
92+
int
93+
main()
94+
{
95+
const uint64_t vlen = vlen_bits();
96+
LOG("VLEN = %" PRIu64, vlen);
97+
98+
int res = 0;
99+
100+
// The correctness of 'vghsh.vv' is established in the test 'aes-gcm-test',
101+
// so this test is only there to validate 'vgmul.vv'.
102+
res = test_rand_vgmul();
103+
if (res != 0) {
104+
return res;
105+
}
106+
107+
return 0;
108+
}

doc/vector/code-samples/zvkg.h

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,39 @@
2121
// does not support unaligned access.
2222
//
2323
// Y <- (Y xor X) o H
24-
// Where 'o' is the Galois Field Multiplication.
24+
// where 'o' is the Galois Field Multiplication in GF(2^128).
2525
extern void
2626
zvkg_vghsh(
2727
void* Y,
2828
const void* X,
2929
const void* H
3030
);
3131

32+
// Y, X, and H point to arrays of 128 bits values, 32b aligned
33+
// if the processor does not support unaligned access.
34+
// 'n' is the number of 128b element groups.
35+
//
36+
// Y[i]_out = (Y[i]_in ^ X[i]) o H[i]
37+
// where 'o' is the Galois Field Multiplication in GF(2^128).
38+
extern void
39+
zvkg_vghsh_vv(
40+
void* Y,
41+
const void* X,
42+
const void* H,
43+
size_t n
44+
);
45+
46+
// X and Y point to arrays of 128 bits values, 32b aligned
47+
// if the processor does not support unaligned access.
48+
// 'n' is the number of 128b element groups.
49+
//
50+
// Y[i]_out = Y[i]_in o H[i]
51+
// where 'o' is the Galois Field Multiplication in GF(2^128).
52+
extern void
53+
zvkg_vgmul_vv(
54+
void* Y,
55+
const void* H,
56+
size_t n
57+
);
58+
3259
#endif // ZVKG_H_

0 commit comments

Comments
 (0)