Skip to content

Commit

Permalink
Merge pull request #53 from itzmeanjan/use-randomshake-as-csprng
Browse files Browse the repository at this point in the history
Switch to using "RandomShake" as CSPRNG
  • Loading branch information
itzmeanjan authored Nov 21, 2024
2 parents b43b819 + 08d2b7b commit 61cf680
Show file tree
Hide file tree
Showing 28 changed files with 3,222 additions and 533 deletions.
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

0 comments on commit 61cf680

Please sign in to comment.