Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 91 additions & 1 deletion .github/actions/config-variations/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ inputs:
description: 'GitHub token'
required: true
tests:
description: 'List of tests to run (space-separated IDs) or "all" for all tests. Available IDs: pct-enabled, pct-enabled-broken, reduce-ram, reduce-ram-pct, custom-alloc-heap, custom-zeroize, native-cap-ON, native-cap-OFF, native-cap-ID_AA64PFR1_EL1, native-cap-CPUID_AVX2, no-asm, serial-fips202, custom-randombytes, custom-memcpy, custom-memset, custom-stdlib, nblocks-1, nblocks-4, nblocks-6'
description: 'List of tests to run (space-separated IDs) or "all" for all tests. Available IDs: pct-enabled, pct-enabled-broken, reduce-ram, reduce-ram-pct, custom-alloc-heap, custom-zeroize, native-cap-ON, native-cap-OFF, native-cap-ID_AA64PFR1_EL1, native-cap-CPUID_AVX2, no-asm, serial-fips202, custom-randombytes, custom-memcpy, custom-memset, custom-stdlib, nblocks-1, nblocks-4, nblocks-6, keygen-only, sign-only, verify-only, keygen-sign, keygen-verify, sign-verify'
required: false
default: 'all'
opt:
Expand Down Expand Up @@ -302,3 +302,93 @@ runs:
examples: false # Some examples use a custom config themselves
alloc: false # Requires custom config
rng_fail: true
- name: "Keygen-only API"
if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'keygen-only') }}
uses: ./.github/actions/multi-functest
with:
gh_token: ${{ inputs.gh_token }}
compile_mode: native
cflags: "-DMLD_CONFIG_NO_SIGN_API -DMLD_CONFIG_NO_VERIFY_API -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
func: true
kat: true
acvp: true
stack: true
rng_fail: true
opt: ${{ inputs.opt }}
examples: true
- name: "Sign-only API"
if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'sign-only') }}
uses: ./.github/actions/multi-functest
with:
gh_token: ${{ inputs.gh_token }}
compile_mode: native
cflags: "-DMLD_CONFIG_NO_KEYPAIR_API -DMLD_CONFIG_NO_VERIFY_API -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
func: true
kat: true
acvp: true
stack: true
rng_fail: true
opt: ${{ inputs.opt }}
examples: true
- name: "Verify-only API"
if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'verify-only') }}
uses: ./.github/actions/multi-functest
with:
gh_token: ${{ inputs.gh_token }}
compile_mode: native
cflags: "-DMLD_CONFIG_NO_KEYPAIR_API -DMLD_CONFIG_NO_SIGN_API -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
func: true
kat: true
acvp: true
stack: true
rng_fail: true
opt: ${{ inputs.opt }}
examples: true
- name: "Keygen+Sign API (no verify)"
if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'keygen-sign') }}
uses: ./.github/actions/multi-functest
with:
gh_token: ${{ inputs.gh_token }}
compile_mode: native
cflags: "-DMLD_CONFIG_NO_VERIFY_API -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
func: true
kat: true
acvp: true
stack: true
rng_fail: true
opt: ${{ inputs.opt }}
examples: true
- name: "Keygen+Verify API (no sign)"
if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'keygen-verify') }}
uses: ./.github/actions/multi-functest
with:
gh_token: ${{ inputs.gh_token }}
compile_mode: native
cflags: "-DMLD_CONFIG_NO_SIGN_API -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
func: true
kat: true
acvp: true
stack: true
rng_fail: true
opt: ${{ inputs.opt }}
examples: true
- name: "Sign+Verify API (no keygen)"
if: ${{ inputs.tests == 'all' || contains(inputs.tests, 'sign-verify') }}
uses: ./.github/actions/multi-functest
with:
gh_token: ${{ inputs.gh_token }}
compile_mode: native
cflags: "-DMLD_CONFIG_NO_KEYPAIR_API -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all"
func: true
kat: true
acvp: true
stack: true
rng_fail: true
opt: ${{ inputs.opt }}
examples: true
50 changes: 33 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -450,35 +450,38 @@ jobs:
stack: true
check_namespace: false
config_variations:
name: Non-standard configurations
name: "Config: ${{ matrix.test.name }} (${{ matrix.target.name }})"
strategy:
fail-fast: false
matrix:
external:
- ${{ github.repository_owner != 'pq-code-package' }}
target:
- runner: ubuntu-24.04-arm
name: 'ubuntu-latest (aarch64)'
name: 'aarch64'
- runner: ubuntu-latest
name: 'ubuntu-latest (x86_64)'
exclude:
- {external: true,
target: {
runner: ubuntu-24.04-arm,
name: 'ubuntu-latest (aarch64)',
}}
- {external: true,
target: {
runner: ubuntu-latest,
name: 'ubuntu-latest (x86_64)',
}}
name: 'x86_64'
test:
- name: pct
ids: pct-enabled pct-enabled-broken
- name: reduce-ram
ids: reduce-ram reduce-ram-pct
- name: custom-hooks
ids: custom-alloc-heap custom-zeroize custom-randombytes custom-memcpy custom-memset custom-stdlib
- name: native-cap
ids: native-cap-ON native-cap-OFF native-cap-ID_AA64PFR1_EL1 native-cap-CPUID_AVX2
- name: asm-fips202
ids: no-asm serial-fips202
- name: nblocks
ids: nblocks-1 nblocks-4 nblocks-6
- name: reduced-api
ids: keygen-only sign-only verify-only keygen-sign keygen-verify sign-verify
runs-on: ${{ matrix.target.runner }}
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: "Config Variations"
- name: "Config: ${{ matrix.test.name }} (${{ matrix.target.name }})"
uses: ./.github/actions/config-variations
with:
gh_token: ${{ secrets.GITHUB_TOKEN }}
tests: ${{ matrix.test.ids }}
check-cf-protections:
name: Test control-flow protections (${{ matrix.compiler.name }}, x86_64)
strategy:
Expand Down Expand Up @@ -766,6 +769,19 @@ jobs:
gh_token: ${{ secrets.GITHUB_TOKEN }}
script: |
python3 ./scripts/autogen --dry-run ${{ matrix.target.extra_args }}
check_test_vectors:
runs-on: ubuntu-latest
name: Check test vectors
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: ./.github/actions/setup-shell
with:
nix-shell: ci
nix-cache: 'true'
gh_token: ${{ secrets.GITHUB_TOKEN }}
script: |
make acvp OPT=0
python3 ./scripts/autogen --test-vectors --dry-run
check_hol_light_object_code:
strategy:
fail-fast: false
Expand Down
35 changes: 26 additions & 9 deletions META.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
# - Field to query, e.g. "kat-sha256"
#
# Optional:
# - Value to compare against
# - Value to compare against. If omitted, stdin is read instead:
# if stdin is "SKIPPED", the test is reported as skipped;
# otherwise stdin is hashed with sha256 and compared.

META=META.yml

Expand All @@ -33,15 +35,30 @@ if (which yq >/dev/null 2>&1); then
fi
fi

INPUT=$3
if [[ $INPUT != "" ]]; then
if [[ $INPUT != "$VAL" ]]; then
echo "$META $1 $2: FAIL ($VAL != $INPUT)"
exit 1
else
echo "$META $1 $2: OK"
# Determine the input to compare against
if [[ $3 != "" ]]; then
INPUT=$3
else
STDIN=$(cat)
if [[ $STDIN == SKIPPED* ]]; then
Comment thread
mkannwischer marked this conversation as resolved.
echo "$META $1 $2: SKIPPED"
exit 0
fi
if command -v shasum >/dev/null 2>&1; then
SHA256SUM="shasum -a 256"
elif command -v sha256sum >/dev/null 2>&1; then
SHA256SUM="sha256sum"
else
echo "ERROR: Neither 'shasum' nor 'sha256sum' found."
exit 1
fi
INPUT=$(echo "$STDIN" | $SHA256SUM | cut -d " " -f 1)
fi

if [[ $INPUT != "$VAL" ]]; then
echo "$META $1 $2: FAIL ($VAL != $INPUT)"
exit 1
else
echo "$VAL"
echo "$META $1 $2: OK"
exit 0
fi
12 changes: 3 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,12 @@ build: func kat acvp
test: run_kat run_func run_acvp run_unit run_alloc run_rng_fail
$(Q)echo " Everything checks fine!"

# Detect available SHA256 command
SHA256SUM := $(shell command -v shasum >/dev/null 2>&1 && echo "shasum -a 256" || (command -v sha256sum >/dev/null 2>&1 && echo "sha256sum" || echo ""))
ifeq ($(SHA256SUM),)
$(error Neither 'shasum' nor 'sha256sum' found. Please install one of these tools.)
endif

run_kat_44: kat_44
set -o pipefail; $(W) $(MLDSA44_DIR)/bin/gen_KAT44 | $(SHA256SUM) | cut -d " " -f 1 | xargs ./META.sh ML-DSA-44 kat-sha256
$(W) $(MLDSA44_DIR)/bin/gen_KAT44 | ./META.sh ML-DSA-44 kat-sha256
run_kat_65: kat_65
set -o pipefail; $(W) $(MLDSA65_DIR)/bin/gen_KAT65 | $(SHA256SUM) | cut -d " " -f 1 | xargs ./META.sh ML-DSA-65 kat-sha256
$(W) $(MLDSA65_DIR)/bin/gen_KAT65 | ./META.sh ML-DSA-65 kat-sha256
run_kat_87: kat_87
set -o pipefail; $(W) $(MLDSA87_DIR)/bin/gen_KAT87 | $(SHA256SUM) | cut -d " " -f 1 | xargs ./META.sh ML-DSA-87 kat-sha256
$(W) $(MLDSA87_DIR)/bin/gen_KAT87 | ./META.sh ML-DSA-87 kat-sha256
run_kat: run_kat_44 run_kat_65 run_kat_87

run_func_44: func_44
Expand Down
8 changes: 8 additions & 0 deletions dev/aarch64_clean/meta.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ static MLD_INLINE int mld_rej_uniform_native(int32_t *r, unsigned len,
return (int)mld_rej_uniform_asm(r, buf, buflen, mld_rej_uniform_table);
}

#if !defined(MLD_CONFIG_NO_KEYPAIR_API)
#if defined(MLD_CONFIG_MULTILEVEL_WITH_SHARED) || MLDSA_ETA == 2
MLD_MUST_CHECK_RETURN_VALUE
static MLD_INLINE int mld_rej_uniform_eta2_native(int32_t *r, unsigned len,
Expand Down Expand Up @@ -119,7 +120,9 @@ static MLD_INLINE int mld_rej_uniform_eta4_native(int32_t *r, unsigned len,
return (int)outlen;
}
#endif /* MLD_CONFIG_MULTILEVEL_WITH_SHARED || MLDSA_ETA == 4 */
#endif /* !MLD_CONFIG_NO_KEYPAIR_API */

#if !defined(MLD_CONFIG_NO_SIGN_API)
#if defined(MLD_CONFIG_MULTILEVEL_WITH_SHARED) || \
(MLD_CONFIG_PARAMETER_SET == 65 || MLD_CONFIG_PARAMETER_SET == 87)
MLD_MUST_CHECK_RETURN_VALUE
Expand All @@ -140,6 +143,7 @@ static MLD_INLINE int mld_poly_decompose_88_native(int32_t *a1, int32_t *a0)
}
#endif /* MLD_CONFIG_MULTILEVEL_WITH_SHARED || MLD_CONFIG_PARAMETER_SET == 44 \
*/
#endif /* !MLD_CONFIG_NO_SIGN_API */

MLD_MUST_CHECK_RETURN_VALUE
static MLD_INLINE int mld_poly_caddq_native(int32_t a[MLDSA_N])
Expand All @@ -148,6 +152,7 @@ static MLD_INLINE int mld_poly_caddq_native(int32_t a[MLDSA_N])
return MLD_NATIVE_FUNC_SUCCESS;
}

#if !defined(MLD_CONFIG_NO_VERIFY_API)
#if defined(MLD_CONFIG_MULTILEVEL_WITH_SHARED) || \
(MLD_CONFIG_PARAMETER_SET == 65 || MLD_CONFIG_PARAMETER_SET == 87)
MLD_MUST_CHECK_RETURN_VALUE
Expand All @@ -170,13 +175,15 @@ static MLD_INLINE int mld_poly_use_hint_88_native(int32_t *b, const int32_t *a,
}
#endif /* MLD_CONFIG_MULTILEVEL_WITH_SHARED || MLD_CONFIG_PARAMETER_SET == 44 \
*/
#endif /* !MLD_CONFIG_NO_VERIFY_API */

MLD_MUST_CHECK_RETURN_VALUE
static MLD_INLINE int mld_poly_chknorm_native(const int32_t *a, int32_t B)
{
return mld_poly_chknorm_asm(a, B);
}

#if !defined(MLD_CONFIG_NO_SIGN_API) || !defined(MLD_CONFIG_NO_VERIFY_API)
#if defined(MLD_CONFIG_MULTILEVEL_WITH_SHARED) || MLD_CONFIG_PARAMETER_SET == 44
MLD_MUST_CHECK_RETURN_VALUE
static MLD_INLINE int mld_polyz_unpack_17_native(int32_t *r, const uint8_t *buf)
Expand Down Expand Up @@ -206,6 +213,7 @@ static MLD_INLINE int mld_poly_pointwise_montgomery_native(
mld_poly_pointwise_montgomery_asm(out, in0, in1);
return MLD_NATIVE_FUNC_SUCCESS;
}
#endif /* !MLD_CONFIG_NO_SIGN_API || !MLD_CONFIG_NO_VERIFY_API */

#if defined(MLD_CONFIG_MULTILEVEL_WITH_SHARED) || MLDSA_L == 4
MLD_MUST_CHECK_RETURN_VALUE
Expand Down
12 changes: 12 additions & 0 deletions dev/aarch64_clean/src/arith_native_aarch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ extern const int32_t mld_aarch64_intt_zetas_layer123456[];

#define mld_rej_uniform_table MLD_NAMESPACE(rej_uniform_table)
extern const uint8_t mld_rej_uniform_table[];
#if !defined(MLD_CONFIG_NO_KEYPAIR_API)
#define mld_rej_uniform_eta_table MLD_NAMESPACE(rej_uniform_eta_table)
extern const uint8_t mld_rej_uniform_eta_table[];
#endif

#if !defined(MLD_CONFIG_NO_SIGN_API) || !defined(MLD_CONFIG_NO_VERIFY_API)
#if defined(MLD_CONFIG_MULTILEVEL_WITH_SHARED) || MLD_CONFIG_PARAMETER_SET == 44
#define mld_polyz_unpack_17_indices MLD_NAMESPACE(polyz_unpack_17_indices)
extern const uint8_t mld_polyz_unpack_17_indices[];
Expand All @@ -38,6 +41,7 @@ extern const uint8_t mld_polyz_unpack_17_indices[];
#define mld_polyz_unpack_19_indices MLD_NAMESPACE(polyz_unpack_19_indices)
extern const uint8_t mld_polyz_unpack_19_indices[];
#endif
#endif /* !MLD_CONFIG_NO_SIGN_API || !MLD_CONFIG_NO_VERIFY_API */


/*
Expand Down Expand Up @@ -78,6 +82,7 @@ MLD_MUST_CHECK_RETURN_VALUE
uint64_t mld_rej_uniform_asm(int32_t *r, const uint8_t *buf, unsigned buflen,
const uint8_t *table);

#if !defined(MLD_CONFIG_NO_KEYPAIR_API)
#define mld_rej_uniform_eta2_asm MLD_NAMESPACE(rej_uniform_eta2_asm)
MLD_MUST_CHECK_RETURN_VALUE
uint64_t mld_rej_uniform_eta2_asm(int32_t *r, const uint8_t *buf,
Expand All @@ -87,12 +92,15 @@ uint64_t mld_rej_uniform_eta2_asm(int32_t *r, const uint8_t *buf,
MLD_MUST_CHECK_RETURN_VALUE
uint64_t mld_rej_uniform_eta4_asm(int32_t *r, const uint8_t *buf,
unsigned buflen, const uint8_t *table);
#endif /* !MLD_CONFIG_NO_KEYPAIR_API */

#if !defined(MLD_CONFIG_NO_SIGN_API)
#define mld_poly_decompose_32_asm MLD_NAMESPACE(poly_decompose_32_asm)
void mld_poly_decompose_32_asm(int32_t *a1, int32_t *a0);

#define mld_poly_decompose_88_asm MLD_NAMESPACE(poly_decompose_88_asm)
void mld_poly_decompose_88_asm(int32_t *a1, int32_t *a0);
#endif /* !MLD_CONFIG_NO_SIGN_API */

#define mld_poly_caddq_asm MLD_NAMESPACE(poly_caddq_asm)
void mld_poly_caddq_asm(int32_t *a)
Expand All @@ -105,11 +113,13 @@ __contract__(
ensures(array_bound(a, 0, MLDSA_N, 0, MLDSA_Q))
);

#if !defined(MLD_CONFIG_NO_VERIFY_API)
#define mld_poly_use_hint_32_asm MLD_NAMESPACE(poly_use_hint_32_asm)
void mld_poly_use_hint_32_asm(int32_t *b, const int32_t *a, const int32_t *h);

#define mld_poly_use_hint_88_asm MLD_NAMESPACE(poly_use_hint_88_asm)
void mld_poly_use_hint_88_asm(int32_t *b, const int32_t *a, const int32_t *h);
#endif /* !MLD_CONFIG_NO_VERIFY_API */

#define mld_poly_chknorm_asm MLD_NAMESPACE(poly_chknorm_asm)
MLD_MUST_CHECK_RETURN_VALUE
Expand All @@ -124,6 +134,7 @@ __contract__(
ensures((return_value == 0) == array_abs_bound(a, 0, MLDSA_N, B))
);

#if !defined(MLD_CONFIG_NO_SIGN_API) || !defined(MLD_CONFIG_NO_VERIFY_API)
#define mld_polyz_unpack_17_asm MLD_NAMESPACE(polyz_unpack_17_asm)
void mld_polyz_unpack_17_asm(int32_t *r, const uint8_t *buf,
const uint8_t *indices);
Expand All @@ -149,6 +160,7 @@ __contract__(
ensures(array_abs_bound(r, 0, MLDSA_N, 8380417))
/* check-magic: on */
);
#endif /* !MLD_CONFIG_NO_SIGN_API || !MLD_CONFIG_NO_VERIFY_API */

#define mld_polyvecl_pointwise_acc_montgomery_l4_asm \
MLD_NAMESPACE(polyvecl_pointwise_acc_montgomery_l4_asm)
Expand Down
Loading
Loading