Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to using "RandomShake" as CSPRNG #53

Merged
merged 14 commits into from
Nov 21, 2024
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
74 changes: 48 additions & 26 deletions .github/workflows/test_ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Test ML-KEM Key Encapsulation Mechanism (NIST FIPS 203)
name: Test ML-KEM i.e. NIST FIPS 203

on:
push:
Expand All @@ -11,31 +11,53 @@ jobs:
runs-on: ${{matrix.os}}
strategy:
matrix:
os: [ubuntu-24.04, macos-latest]
os: [ubuntu-latest, macos-latest]
compiler: [g++, clang++]
build_type: [debug, release]
test_type: [standard, asan, ubsan]
max-parallel: 4

steps:
- uses: actions/checkout@v4
- name: Setup Google-Test
run: |
pushd ~
git clone https://github.com/google/googletest.git -b v1.15.0
pushd googletest
mkdir build
pushd build
cmake .. -DBUILD_GMOCK=OFF
make
sudo make install
popd
popd
popd
- name: Execute Tests on ${{matrix.os}}, compiled with ${{matrix.compiler}}
run: CXX=${{matrix.compiler}} make -j
- name: Execute Tests with AddressSanitizer, in DEBUG mode, on ${{matrix.os}}, compiled with ${{matrix.compiler}}
run: CXX=${{matrix.compiler}} make debug_asan_test -j
- name: Execute Tests with AddressSanitizer, in RELEASE mode, on ${{matrix.os}}, compiled with ${{matrix.compiler}}
run: CXX=${{matrix.compiler}} make release_asan_test -j
- name: Execute Tests with UndefinedBehaviourSanitizer, in DEBUG mode, on ${{matrix.os}}, compiled with ${{matrix.compiler}}
run: CXX=${{matrix.compiler}} make debug_ubsan_test -j
- name: Execute Tests with UndefinedBehaviourSanitizer, in RELEASE mode, on ${{matrix.os}}, compiled with ${{matrix.compiler}}
run: CXX=${{matrix.compiler}} make release_ubsan_test -j
- uses: actions/checkout@v4

- name: Setup Google Test
uses: Bacondish2023/setup-googletest@v1
with:
tag: v1.15.2


- name: Build and Test (${{ matrix.compiler }}, ${{ matrix.build_type }}, ${{ matrix.test_type }})
run: |
CXX=${{ matrix.compiler }}
if [[ ${{ matrix.test_type }} == "standard" ]]; then
make test -j 2>&1 | tee build.log
else
make ${{ matrix.build_type }}_${{ matrix.test_type }}_test -j 2>&1 | tee build.log
fi
if [ $? -ne 0 ]; then
echo "Build or Test Failed! See build.log for details."
exit 1
fi

- name: Upload Build Log
uses: actions/upload-artifact@v3
with:
name: build-log-${{ matrix.compiler }}-${{ matrix.build_type }}-${{ matrix.test_type }}
path: build.log


- name: Run Examples
if: ${{ matrix.test_type == 'standard' && matrix.build_type == 'release' }}
run: |
CXX=${{ matrix.compiler }} make example -j 2>&1 | tee example.log
if [ $? -ne 0 ]; then
echo "Example execution Failed! See example.log for details."
exit 1
fi

- name: Upload Example Log (if failed)
if: ${{ steps.Run_Examples.outcome != 'success' && matrix.test_type == 'standard' && matrix.build_type == 'release' }}
uses: actions/upload-artifact@v3
with:
name: example-log-${{ matrix.compiler }}
path: example.log
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
[submodule "gtest-parallel"]
path = gtest-parallel
url = https://github.com/google/gtest-parallel.git
[submodule "RandomShake"]
path = RandomShake
url = https://github.com/itzmeanjan/RandomShake.git
153 changes: 24 additions & 129 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,154 +1,49 @@
DEFAULT_GOAL := help

# Collects inspiration from https://github.com/itzmeanjan/RandomShake/blob/a9cd4085a4d38d7b99ee42caadc56fc2d64ec1dc/Makefile#L1-L9
.PHONY: help
help:
@for file in $(MAKEFILE_LIST); do \
grep -E '^[a-zA-Z_-]+:.*?## .*$$' $${file} | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}';\
done

CXX ?= clang++
CXX_FLAGS := -std=c++20
WARN_FLAGS := -Wall -Wextra -Wpedantic
DEBUG_FLAGS := -O1 -g
RELEASE_FLAGS := -O3 -march=native
LINK_OPT_FLAGS := -flto
ASAN_FLAGS := -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address # From https://clang.llvm.org/docs/AddressSanitizer.html
DEBUG_ASAN_FLAGS := $(DEBUG_FLAGS) $(ASAN_FLAGS)
RELEASE_ASAN_FLAGS := -g $(RELEASE_FLAGS) $(ASAN_FLAGS)
UBSAN_FLAGS := -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=undefined # From https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
DEBUG_UBSAN_FLAGS := $(DEBUG_FLAGS) $(UBSAN_FLAGS)
RELEASE_UBSAN_FLAGS := -g $(RELEASE_FLAGS) $(UBSAN_FLAGS)

I_FLAGS := -I ./include
SHA3_INC_DIR = ./sha3/include
SUBTLE_INC_DIR = ./subtle/include
DEP_IFLAGS = -I $(SHA3_INC_DIR) -I $(SUBTLE_INC_DIR)
SHA3_INC_DIR := ./sha3/include
SUBTLE_INC_DIR := ./subtle/include
RANDOMSHAKE_INC_DIR := ./RandomShake/include
DEP_IFLAGS := -I $(SHA3_INC_DIR) -I $(SUBTLE_INC_DIR) -I $(RANDOMSHAKE_INC_DIR)

SRC_DIR := include
ML_KEM_SOURCES := $(shell find $(SRC_DIR) -name '*.hpp')
BUILD_DIR := build
TEST_BUILD_DIR := $(BUILD_DIR)/test
BENCHMARK_BUILD_DIR := $(BUILD_DIR)/benchmark
ASAN_BUILD_DIR := $(BUILD_DIR)/asan
DEBUG_ASAN_BUILD_DIR := $(ASAN_BUILD_DIR)/debug
RELEASE_ASAN_BUILD_DIR := $(ASAN_BUILD_DIR)/release
UBSAN_BUILD_DIR := $(BUILD_DIR)/ubsan
DEBUG_UBSAN_BUILD_DIR := $(UBSAN_BUILD_DIR)/debug
RELEASE_UBSAN_BUILD_DIR := $(UBSAN_BUILD_DIR)/release

TEST_DIR := tests
TEST_SOURCES := $(wildcard $(TEST_DIR)/*.cpp)
TEST_HEADERS := $(wildcard $(TEST_DIR)/*.hpp)
TEST_OBJECTS := $(addprefix $(TEST_BUILD_DIR)/, $(notdir $(patsubst %.cpp,%.o,$(TEST_SOURCES))))
TEST_BINARY := $(TEST_BUILD_DIR)/test.out
TEST_LINK_FLAGS := -lgtest -lgtest_main
GTEST_PARALLEL := ./gtest-parallel/gtest-parallel
DEBUG_ASAN_TEST_OBJECTS := $(addprefix $(DEBUG_ASAN_BUILD_DIR)/, $(notdir $(patsubst %.cpp,%.o,$(TEST_SOURCES))))
RELEASE_ASAN_TEST_OBJECTS := $(addprefix $(RELEASE_ASAN_BUILD_DIR)/, $(notdir $(patsubst %.cpp,%.o,$(TEST_SOURCES))))
DEBUG_ASAN_TEST_BINARY := $(DEBUG_ASAN_BUILD_DIR)/test.out
RELEASE_ASAN_TEST_BINARY := $(RELEASE_ASAN_BUILD_DIR)/test.out
DEBUG_UBSAN_TEST_OBJECTS := $(addprefix $(DEBUG_UBSAN_BUILD_DIR)/, $(notdir $(patsubst %.cpp,%.o,$(TEST_SOURCES))))
RELEASE_UBSAN_TEST_OBJECTS := $(addprefix $(RELEASE_UBSAN_BUILD_DIR)/, $(notdir $(patsubst %.cpp,%.o,$(TEST_SOURCES))))
DEBUG_UBSAN_TEST_BINARY := $(DEBUG_UBSAN_BUILD_DIR)/test.out
RELEASE_UBSAN_TEST_BINARY := $(RELEASE_UBSAN_BUILD_DIR)/test.out

BENCHMARK_DIR := benchmarks
BENCHMARK_SOURCES := $(wildcard $(BENCHMARK_DIR)/*.cpp)
BENCHMARK_HEADERS := $(wildcard $(BENCHMARK_DIR)/*.hpp)
BENCHMARK_OBJECTS := $(addprefix $(BENCHMARK_BUILD_DIR)/, $(notdir $(patsubst %.cpp,%.o,$(BENCHMARK_SOURCES))))
BENCHMARK_LINK_FLAGS := -lbenchmark -lbenchmark_main -lpthread
BENCHMARK_BINARY := $(BENCHMARK_BUILD_DIR)/bench.out
PERF_LINK_FLAGS := -lbenchmark -lbenchmark_main -lpfm -lpthread
PERF_BINARY := $(BENCHMARK_BUILD_DIR)/perf.out
BENCHMARK_OUT_FILE := bench_result_on_$(shell uname -s)_$(shell uname -r)_$(shell uname -m)_with_$(CXX)_$(shell $(CXX) -dumpversion).json

all: test

$(DEBUG_ASAN_BUILD_DIR):
mkdir -p $@

$(RELEASE_ASAN_BUILD_DIR):
mkdir -p $@

$(DEBUG_UBSAN_BUILD_DIR):
mkdir -p $@

$(RELEASE_UBSAN_BUILD_DIR):
mkdir -p $@

$(TEST_BUILD_DIR):
mkdir -p $@

$(BENCHMARK_BUILD_DIR):
mkdir -p $@
include tests/test.mk
include benchmarks/bench.mk
include examples/example.mk

$(SUBTLE_INC_DIR):
git submodule update --init subtle

$(SHA3_INC_DIR): $(SUBTLE_INC_DIR)
$(RANDOMSHAKE_INC_DIR): $(SUBTLE_INC_DIR)
git submodule update --init --recursive RandomShake

$(SHA3_INC_DIR): $(RANDOMSHAKE_INC_DIR)
git submodule update --init sha3

$(GTEST_PARALLEL): $(SHA3_INC_DIR)
git submodule update --init gtest-parallel

$(TEST_BUILD_DIR)/%.o: $(TEST_DIR)/%.cpp $(TEST_BUILD_DIR) $(SHA3_INC_DIR) $(ASCON_INC_DIR) $(SUBTLE_INC_DIR)
$(CXX) $(CXX_FLAGS) $(WARN_FLAGS) $(RELEASE_FLAGS) $(I_FLAGS) $(DEP_IFLAGS) -c $< -o $@

$(DEBUG_ASAN_BUILD_DIR)/%.o: $(TEST_DIR)/%.cpp $(DEBUG_ASAN_BUILD_DIR) $(SHA3_INC_DIR) $(ASCON_INC_DIR) $(SUBTLE_INC_DIR)
$(CXX) $(CXX_FLAGS) $(WARN_FLAGS) $(DEBUG_ASAN_FLAGS) $(I_FLAGS) $(DEP_IFLAGS) -c $< -o $@

$(RELEASE_ASAN_BUILD_DIR)/%.o: $(TEST_DIR)/%.cpp $(RELEASE_ASAN_BUILD_DIR) $(SHA3_INC_DIR) $(ASCON_INC_DIR) $(SUBTLE_INC_DIR)
$(CXX) $(CXX_FLAGS) $(WARN_FLAGS) $(RELEASE_ASAN_FLAGS) $(I_FLAGS) $(DEP_IFLAGS) -c $< -o $@

$(DEBUG_UBSAN_BUILD_DIR)/%.o: $(TEST_DIR)/%.cpp $(DEBUG_UBSAN_BUILD_DIR) $(SHA3_INC_DIR) $(ASCON_INC_DIR) $(SUBTLE_INC_DIR)
$(CXX) $(CXX_FLAGS) $(WARN_FLAGS) $(DEBUG_UBSAN_FLAGS) $(I_FLAGS) $(DEP_IFLAGS) -c $< -o $@

$(RELEASE_UBSAN_BUILD_DIR)/%.o: $(TEST_DIR)/%.cpp $(RELEASE_UBSAN_BUILD_DIR) $(SHA3_INC_DIR) $(ASCON_INC_DIR) $(SUBTLE_INC_DIR)
$(CXX) $(CXX_FLAGS) $(WARN_FLAGS) $(RELEASE_UBSAN_FLAGS) $(I_FLAGS) $(DEP_IFLAGS) -c $< -o $@

$(TEST_BINARY): $(TEST_OBJECTS)
$(CXX) $(RELEASE_FLAGS) $(LINK_OPT_FLAGS) $^ $(TEST_LINK_FLAGS) -o $@

$(DEBUG_ASAN_TEST_BINARY): $(DEBUG_ASAN_TEST_OBJECTS)
$(CXX) $(DEBUG_ASAN_FLAGS) $^ $(TEST_LINK_FLAGS) -o $@

$(RELEASE_ASAN_TEST_BINARY): $(RELEASE_ASAN_TEST_OBJECTS)
$(CXX) $(RELEASE_ASAN_FLAGS) $^ $(TEST_LINK_FLAGS) -o $@

$(DEBUG_UBSAN_TEST_BINARY): $(DEBUG_UBSAN_TEST_OBJECTS)
$(CXX) $(DEBUG_UBSAN_FLAGS) $^ $(TEST_LINK_FLAGS) -o $@

$(RELEASE_UBSAN_TEST_BINARY): $(RELEASE_UBSAN_TEST_OBJECTS)
$(CXX) $(RELEASE_UBSAN_FLAGS) $^ $(TEST_LINK_FLAGS) -o $@

test: $(TEST_BINARY) $(GTEST_PARALLEL)
$(GTEST_PARALLEL) $< --print_test_times

debug_asan_test: $(DEBUG_ASAN_TEST_BINARY) $(GTEST_PARALLEL)
$(GTEST_PARALLEL) $< --print_test_times

release_asan_test: $(RELEASE_ASAN_TEST_BINARY) $(GTEST_PARALLEL)
$(GTEST_PARALLEL) $< --print_test_times

debug_ubsan_test: $(DEBUG_UBSAN_TEST_BINARY) $(GTEST_PARALLEL)
$(GTEST_PARALLEL) $< --print_test_times

release_ubsan_test: $(RELEASE_UBSAN_TEST_BINARY) $(GTEST_PARALLEL)
$(GTEST_PARALLEL) $< --print_test_times

$(BENCHMARK_BUILD_DIR)/%.o: $(BENCHMARK_DIR)/%.cpp $(BENCHMARK_BUILD_DIR) $(SHA3_INC_DIR) $(ASCON_INC_DIR) $(SUBTLE_INC_DIR)
$(CXX) $(CXX_FLAGS) $(WARN_FLAGS) $(RELEASE_FLAGS) $(I_FLAGS) $(DEP_IFLAGS) -c $< -o $@

$(BENCHMARK_BINARY): $(BENCHMARK_OBJECTS)
$(CXX) $(RELEASE_FLAGS) $(LINK_OPT_FLAGS) $^ $(BENCHMARK_LINK_FLAGS) -o $@

benchmark: $(BENCHMARK_BINARY)
# Must *not* build google-benchmark with libPFM
./$< --benchmark_time_unit=us --benchmark_min_warmup_time=.5 --benchmark_enable_random_interleaving=true --benchmark_repetitions=10 --benchmark_min_time=0.1s --benchmark_display_aggregates_only=true --benchmark_counters_tabular=true

$(PERF_BINARY): $(BENCHMARK_OBJECTS)
$(CXX) $(RELEASE_FLAGS) $(LINK_OPT_FLAGS) $^ $(PERF_LINK_FLAGS) -o $@

perf: $(PERF_BINARY)
# Must build google-benchmark with libPFM, follow https://gist.github.com/itzmeanjan/05dc3e946f635d00c5e0b21aae6203a7
./$< --benchmark_time_unit=us --benchmark_min_warmup_time=.5 --benchmark_enable_random_interleaving=true --benchmark_repetitions=10 --benchmark_min_time=0.1s --benchmark_display_aggregates_only=true --benchmark_counters_tabular=true --benchmark_perf_counters=CYCLES

.PHONY: format clean

clean:
.PHONY: clean
clean: ## Remove build directory
rm -rf $(BUILD_DIR)

format: $(ML_KEM_SOURCES) $(TEST_SOURCES) $(TEST_HEADERS) $(BENCHMARK_SOURCES) $(BENCHMARK_HEADERS)
.PHONY: format
format: $(ML_KEM_SOURCES) $(TEST_SOURCES) $(TEST_HEADERS) $(BENCHMARK_SOURCES) $(BENCHMARK_HEADERS) ## Format source code
clang-format -i $^
Loading
Loading