-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit of the public Pinata source code
- Loading branch information
0 parents
commit 41b1d3b
Showing
215 changed files
with
78,039 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
* text=auto | ||
*.sh text eol=lf |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
on: | ||
push: | ||
branches: | ||
- main | ||
paths-ignore: | ||
- README.md | ||
pull_request: | ||
branches: | ||
- main | ||
paths-ignore: | ||
- README.md | ||
|
||
jobs: | ||
ubuntu: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
# Install system packages. | ||
- name: Install system packages | ||
run: sudo apt-get update && sudo apt-get install gcc-arm-none-eabi ninja-build libssl-dev libgtest-dev libboost-dev dfu-util | ||
|
||
# Checkout the repository. | ||
- uses: actions/checkout@v4 | ||
with: | ||
submodules: recursive | ||
|
||
# Compile firmware. | ||
- name: Configure firmware | ||
run: cmake -DCMAKE_TOOLCHAIN_FILE=gcc-arm-none-eabi.toolchain.cmake -DCMAKE_INSTALL_PREFIX=$(pwd)/build/firmware -GNinja -S. -Bbuild | ||
- name: Build firmware | ||
run: cmake --build ./build | ||
- name: Prepare firmware | ||
run: cmake --build ./build --target install | ||
|
||
# Compile test driver. | ||
- name: Configure test runner | ||
run: cmake -DCMAKE_BUILD_TYPE=Debug -SPinataTests -BPinataTests/build -GNinja | ||
- name: Build test runner | ||
run: cmake --build ./PinataTests/build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
build/ | ||
*.o | ||
*.bin | ||
*.dfu | ||
*.elf | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "PinataTests/PQClean"] | ||
path = PinataTests/PQClean | ||
url = https://github.com/PQClean/PQClean.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
cmake_minimum_required(VERSION 3.16) | ||
project(Pinata VERSION 3.2 LANGUAGES C ASM) | ||
|
||
if(NOT CMAKE_BUILD_TYPE OR CMAKE_BUILD_TYPE STREQUAL "") | ||
message(STATUS "Setting CMAKE_BUILD_TYPE to MinSizeRel") | ||
set(CMAKE_BUILD_TYPE MinSizeRel) | ||
endif() | ||
|
||
add_subdirectory(src) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
The Clear BSD License | ||
|
||
Copyright (c) 2024 Riscure B.V. | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted (subject to the limitations in the disclaimer | ||
below) provided that the following conditions are met: | ||
|
||
* Redistributions of source code must retain the above copyright notice, | ||
this list of conditions and the following disclaimer. | ||
|
||
* Redistributions in binary form must reproduce the above copyright | ||
notice, this list of conditions and the following disclaimer in the | ||
documentation and/or other materials provided with the distribution. | ||
|
||
* Neither the name of the copyright holder nor the names of its | ||
contributors may be used to endorse or promote products derived from this | ||
software without specific prior written permission. | ||
|
||
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY | ||
THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND | ||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER | ||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
POSSIBILITY OF SUCH DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--- | ||
ColumnLimit: 120 | ||
IndentWidth: 4 | ||
... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
dilithium3_round2/ | ||
dilithium3_round3/ | ||
kyber512_round3/ | ||
fuzz-dilithium | ||
fuzz-kyber | ||
crash-* | ||
*.json | ||
.cache | ||
build/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
cmake_minimum_required(VERSION 3.16) | ||
project(PinataTests C CXX) | ||
|
||
find_package(OpenSSL REQUIRED) | ||
find_package(GTest REQUIRED) | ||
find_package(Boost REQUIRED) | ||
|
||
set(DILITHIUM PQClean/crypto_sign/dilithium3/clean) | ||
set(KYBER PQClean/crypto_kem/kyber512/clean) | ||
|
||
add_executable(PinataTests | ||
main.cpp | ||
dilithium/test-dilithium.cpp | ||
kyber/test-kyber.cpp | ||
tests/Environment.cpp | ||
tests/PinataTests.cpp | ||
utilities/common.cpp | ||
#COMMON | ||
PQClean/common/fips202.c | ||
PQClean/common/randombytes.c | ||
PQClean/common/aes.c | ||
#DILITHIUM | ||
${DILITHIUM}/packing.c | ||
${DILITHIUM}/ntt.c | ||
${DILITHIUM}/poly.c | ||
${DILITHIUM}/polyvec.c | ||
${DILITHIUM}/reduce.c | ||
${DILITHIUM}/rounding.c | ||
${DILITHIUM}/sign.c | ||
${DILITHIUM}/symmetric-shake.c | ||
#KYBER | ||
${KYBER}/indcpa.c | ||
${KYBER}/polyvec.c | ||
${KYBER}/reduce.c | ||
${KYBER}/kem.c | ||
${KYBER}/ntt.c | ||
${KYBER}/cbd.c | ||
${KYBER}/poly.c | ||
${KYBER}/verify.c | ||
${KYBER}/symmetric-shake.c | ||
) | ||
|
||
target_compile_features(PinataTests PRIVATE cxx_std_20) | ||
target_include_directories(PinataTests PRIVATE PQClean/common) | ||
target_link_libraries(PinataTests PRIVATE Boost::boost OpenSSL::Crypto GTest::GTest) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# Testing the Pinata | ||
|
||
This project is for testing ciphers on Pinata. | ||
|
||
## Step 1 | ||
|
||
Run | ||
|
||
```sh | ||
git submodule update --init --recursive | ||
``` | ||
|
||
To initialize and fetch PQClean repo | ||
|
||
## Step 2 | ||
|
||
For Debian/Ubuntu, install the following system packages: | ||
|
||
```sh | ||
apt install libboost-dev libssl-dev libgtest-dev | ||
``` | ||
|
||
It's possible you may be able to use a different clang version. In that case, you will have to modify the `Makefile` to modify the clang version to your specific version. | ||
|
||
To be able to run and debug tests in VSCode (or any other text editor with LSP capabilities), install the following packages: | ||
|
||
|
||
```sh | ||
apt install clangd | ||
``` | ||
|
||
## Step 3 | ||
|
||
Compile the tests | ||
|
||
```sh | ||
cmake -S. -Bbuild -DCMAKE_EXPORT_COMPILE_COMMANDS=ON && cd build && make | ||
``` | ||
|
||
Enabling the option `CMAKE_EXPORT_COMPILE_COMMANDS` is optional. It creates the JSON compilation database (a file named `compile_commands.json`), which clangd will use for code autocompletion, navigation and suggestions. | ||
|
||
## Step 4 | ||
|
||
Let the Test Application know what serial port to use. Set and export an environment variable called `SERIAL_PORT` in your shell. For example, at the time of writing this was my serial port used for my physical Pinata: | ||
|
||
```sh | ||
export SERIAL_PORT=/dev/serial/by-id/usb-FTDI_TTL232R-3V3_FT9S6WRO-if00-port0 | ||
``` | ||
|
||
## Step 5 | ||
|
||
Run the tests | ||
|
||
```sh | ||
./build/PinataTests | ||
``` | ||
|
||
To see the list of all test cases: | ||
|
||
```sh | ||
./build/PinataTests --gtest_list_tests | ||
``` | ||
|
||
To run a specific test case of the test suite: | ||
|
||
```sh | ||
./build/PinataTests --gtest_filter=test128AESSWEncrypt | ||
``` | ||
|
||
Note that wildcards work for filtering test cases. For example, `/build/PinataTests --gtest_filter=test128AES* ` will run all 128AES tests. | ||
|
||
Run `./build/PinataTests --help` for help. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#include "test-dilithium.hpp" | ||
#include <optional> | ||
|
||
|
||
extern "C" { | ||
#include "../PQClean/crypto_sign/dilithium3/clean/api.h" | ||
} | ||
|
||
#if DILITHIUM_PUBLIC_KEY_SIZE != PQCLEAN_DILITHIUM3_CLEAN_CRYPTO_PUBLICKEYBYTES | ||
#error invalid public key size, update me! | ||
#endif | ||
#if DILITHIUM_PRIVATE_KEY_SIZE != PQCLEAN_DILITHIUM3_CLEAN_CRYPTO_SECRETKEYBYTES | ||
#error invalid private key size, update me! | ||
#endif | ||
#if DILITHIUM_SIGNATURE_SIZE != PQCLEAN_DILITHIUM3_CLEAN_CRYPTO_BYTES | ||
#error invalid signature size, update me! | ||
#endif | ||
|
||
#if defined(MODE) && !defined(DILITHIUM_MODE) | ||
#define DILITHIUM_MODE MODE | ||
#endif | ||
|
||
|
||
DilithiumGlobalState::DilithiumGlobalState() { | ||
// Ensure we're talking to a modern Pinata | ||
std::cout << "reading pinata device version...\n"; | ||
const auto [deviceMajorVersion, deviceMinorVersion] = pinata.getVersion(); | ||
if (deviceMajorVersion != PinataVersionMajor) { | ||
throw std::runtime_error("expected pinata major version 3"); | ||
} | ||
if (deviceMinorVersion != PinataVersionMinor) { | ||
throw std::runtime_error("expected pinata minor version 2"); | ||
} | ||
|
||
// Ensure the mode is the same | ||
std::cout << "ensuring dilithium modes agree\n"; | ||
if (pinata.dilithiumGetSecurityLevel() != 3) { | ||
throw std::runtime_error("pinata dilithium mode is not equal to " + std::to_string(3)); | ||
} | ||
|
||
// Ensure public and private key sizes match | ||
std::cout << "ensuring dilithium public and private key sizes agree\n"; | ||
const auto [pinataPublicKeySize, pinataPrivateKeySize] = pinata.dilithiumGetKeySizes(); | ||
if (pinataPublicKeySize != PQCLEAN_DILITHIUM3_CLEAN_CRYPTO_PUBLICKEYBYTES) { | ||
throw std::runtime_error("mismatching public key sizes (pinata: " + std::to_string(pinataPublicKeySize) + | ||
", reference impl: " + std::to_string(PQCLEAN_DILITHIUM3_CLEAN_CRYPTO_PUBLICKEYBYTES) + ")"); | ||
} | ||
if (pinataPrivateKeySize != PQCLEAN_DILITHIUM3_CLEAN_CRYPTO_SECRETKEYBYTES) { | ||
throw std::runtime_error("mismatching private key sizes (pinata: " + std::to_string(pinataPrivateKeySize) + | ||
", reference impl: " + std::to_string(PQCLEAN_DILITHIUM3_CLEAN_CRYPTO_SECRETKEYBYTES) + ")"); | ||
} | ||
|
||
// Generate a public/private key pair with the reference X86 implementation | ||
PQCLEAN_DILITHIUM3_CLEAN_crypto_sign_keypair(m_publicKey.data(), m_privateKey.data()); | ||
|
||
// Tell the pinata to use this public/private key pair for signing with Dilithium3 | ||
std::cout << "setting public and private key on Pinata (public key size: " << std::dec << PQCLEAN_DILITHIUM3_CLEAN_CRYPTO_PUBLICKEYBYTES | ||
<< ", private key size: " << PQCLEAN_DILITHIUM3_CLEAN_CRYPTO_SECRETKEYBYTES << ")\n"; | ||
pinata.dilithiumSetPublicPrivateKeyPair(m_publicKey.data(), m_publicKey.size(), m_privateKey.data(), m_privateKey.size()); | ||
} | ||
|
||
std::optional<DilithiumGlobalState> dg_state; | ||
|
||
std::array<unsigned char, DILITHIUM_MESSAGE_SIZE> message; | ||
std::array<unsigned char, PQCLEAN_DILITHIUM3_CLEAN_CRYPTO_BYTES + DILITHIUM_MESSAGE_SIZE> pinataSignedMessage; | ||
std::array<unsigned char, PQCLEAN_DILITHIUM3_CLEAN_CRYPTO_BYTES + DILITHIUM_MESSAGE_SIZE> referenceSignedMessage; | ||
|
||
|
||
extern "C" int TestDilithiumOneInput(const uint8_t *data, size_t size) { | ||
|
||
// ensure global state object is initialized | ||
if (!dg_state.has_value()) { | ||
std::cout << "setting up global state\n"; | ||
dg_state.emplace(); | ||
std::cout << "created state\n"; | ||
} | ||
|
||
// Prepare the fuzzed message | ||
std::fill(pinataSignedMessage.begin(), pinataSignedMessage.end(), (unsigned char)0); | ||
std::fill(message.begin(), message.end(), (unsigned char)0); | ||
std::copy(data, data + std::min(message.size(), size), message.begin()); | ||
std::cout << "message: " << message << '\n'; | ||
|
||
// Sign the fuzzed message on pinata | ||
dg_state->pinata.dilithiumSign(message.data(), message.size(), pinataSignedMessage.data(), PQCLEAN_DILITHIUM3_CLEAN_CRYPTO_BYTES); | ||
// Concatenate the signature and the fuzzed message together to obtain a "signed message" | ||
assert(pinataSignedMessage.size() == PQCLEAN_DILITHIUM3_CLEAN_CRYPTO_BYTES + message.size()); | ||
|
||
std::copy(message.begin(), message.end(), pinataSignedMessage.data() + PQCLEAN_DILITHIUM3_CLEAN_CRYPTO_BYTES); | ||
// The message should be at the end of the signed message buffer | ||
assert(std::memcmp(pinataSignedMessage.data() + PQCLEAN_DILITHIUM3_CLEAN_CRYPTO_BYTES, message.begin(), 16) == 0); | ||
|
||
// Sign the fuzzed message with the X86 reference implementation. | ||
// The reference implementation doesn't use randomized signatures. | ||
unsigned long messageLength = static_cast<unsigned long>(pinataSignedMessage.size()); | ||
PQCLEAN_DILITHIUM3_CLEAN_crypto_sign(referenceSignedMessage.data(), &messageLength, message.data(), message.size(), | ||
dg_state->getPrivateKey().data()); | ||
|
||
assert(messageLength == referenceSignedMessage.size()); | ||
|
||
// Pinata sign --> Reference verify | ||
assert(PQCLEAN_DILITHIUM3_CLEAN_crypto_sign_open(pinataSignedMessage.data(), &messageLength, pinataSignedMessage.data(), | ||
pinataSignedMessage.size(), dg_state->getPublicKey().data()) == 0); | ||
|
||
// Reference sign --> Pinata verify | ||
assert(dg_state->pinata.dilithiumVerify(referenceSignedMessage.data(), referenceSignedMessage.size())); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#pragma once | ||
|
||
|
||
#include <boost/algorithm/string/join.hpp> | ||
#include "../utilities/common.hpp" | ||
|
||
|
||
#define DILITHIUM_PUBLIC_KEY_SIZE 1952 | ||
#define DILITHIUM_PRIVATE_KEY_SIZE 4016 | ||
#define DILITHIUM_SIGNATURE_SIZE 3293 | ||
#define DILITHIUM_MESSAGE_SIZE 16 | ||
#define DILITHIUM_SIGNED_MESSAGE_SIZE (DILITHIUM_SIGNATURE_SIZE + DILITHIUM_MESSAGE_SIZE) | ||
|
||
|
||
class DilithiumGlobalState { | ||
public: | ||
DilithiumGlobalState(); | ||
const std::array<unsigned char, DILITHIUM_PUBLIC_KEY_SIZE>& getPublicKey() const noexcept { return m_publicKey; } | ||
const std::array<unsigned char, DILITHIUM_PRIVATE_KEY_SIZE>& getPrivateKey() const noexcept { return m_privateKey; } | ||
PinataClient pinata; | ||
|
||
private: | ||
std::array<unsigned char, DILITHIUM_PUBLIC_KEY_SIZE> m_publicKey; | ||
std::array<unsigned char, DILITHIUM_PRIVATE_KEY_SIZE> m_privateKey; | ||
}; | ||
|
||
extern "C" int TestDilithiumOneInput(const uint8_t* data, size_t size); |
Oops, something went wrong.