Skip to content

Commit

Permalink
Added unit tests for shamir functions
Browse files Browse the repository at this point in the history
  • Loading branch information
aido committed Nov 4, 2023
1 parent 977fb76 commit f26e617
Show file tree
Hide file tree
Showing 11 changed files with 387 additions and 12 deletions.
35 changes: 34 additions & 1 deletion .github/workflows/ci-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,44 @@ jobs:
upload_app_binaries_artifact: compiled_app_binaries
run_for_devices: '["nanos", "nanox", "nanosp", "stax"]'

ledger_app_test:
ledger_app_test_function:
name: Run ragger tests using the reusable workflow
needs: ledger_app_build
uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_ragger_tests.yml@v1
with:
download_app_binaries_artifact: compiled_app_binaries
test_dir: tests/functional
run_for_devices: '["nanos"]'

ledger_app_test_unit:
name: Unit tests
needs: ledger_app_build
runs-on: ubuntu-latest

container:
image: ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder:latest

steps:
- name: Clone
uses: actions/checkout@v2
- name: Build unit tests
run: |
cd tests/unit/
make
- name: Generate code coverage
run: |
cd tests/unit/
make coverage
- uses: actions/upload-artifact@v2
with:
name: code-coverage
path: tests/unit/coverage
- name: Upload to codecov.io
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: ./tests/unit/coverage.info
flags: unittests
name: codecov-app-seed-tool
fail_ci_if_error: true
verbose: true
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Change log

## [1.5.1] - 2023-11-02
## [1.5.1] - 2023-11-04
### Added
-
- Added unit tests for shamir

### Changed
- Reduce size of Nano binaries slightly by removing duplicate flows
Expand Down
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@

# Seed Tool: A Ledger application that provides some useful seed management utilities

[![Build app-seed-tool](https://github.com/aido/app-seed-tool/actions/workflows/ci-workflow.yml/badge.svg)](https://github.com/aido/app-seed-tool/actions/workflows/ci-workflow.yml)
[![CodeQL](https://github.com/aido/app-seed-tool/actions/workflows/codeql-workflow.yml/badge.svg)](https://github.com/aido/app-seed-tool/actions/workflows/codeql-workflow.yml)
[![Code style check](https://github.com/aido/app-seed-tool/actions/workflows/lint-workflow.yml/badge.svg)](https://github.com/aido/app-seed-tool/actions/workflows/lint-workflow.yml)
[![License](https://img.shields.io/github/license/aido/app-seed-tool)](https://github.com/aido/app-seed-tool/blob/develop/LICENSE)

[![Release](https://img.shields.io/github/release/aido/app-seed-tool)](https://github.com/aido/app-seed-tool/releases)
![nanos](https://img.shields.io/badge/nanos-working-green)
![nanox](https://img.shields.io/badge/nanox-working-green])
![nanosp](https://img.shields.io/badge/nanosp-working-green)
![stax](https://img.shields.io/badge/stax-in_progress-orange)

[![Build app-seed-tool](https://github.com/aido/app-seed-tool/actions/workflows/ci-workflow.yml/badge.svg)](https://github.com/aido/app-seed-tool/actions/workflows/ci-workflow.yml)
[![CodeQL](https://github.com/aido/app-seed-tool/actions/workflows/codeql-workflow.yml/badge.svg)](https://github.com/aido/app-seed-tool/actions/workflows/codeql-workflow.yml)
[![Code style check](https://github.com/aido/app-seed-tool/actions/workflows/lint-workflow.yml/badge.svg)](https://github.com/aido/app-seed-tool/actions/workflows/lint-workflow.yml)
[![codecov](https://codecov.io/gh/aido/app-seed-tool/branch/develop/graph/badge.svg?token=uCkGEbhGl3)](https://codecov.io/gh/aido/app-seed-tool/tree/develop)

Use the utilities provided by this Ledger application to check a backed up seed or generate [Shamir's Secret Sharing (SSS)](https://en.wikipedia.org/wiki/Shamir%27s_secret_sharing) for a seed.

## Check BIP39
Expand Down
9 changes: 4 additions & 5 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@

### Todo

- [ ] Add unit tests
- [ ] Update automated tests to test on nanox and nanosp
- [ ] Add code coverage to GitHub actions
- [ ] Save memory by setting the SSKR word buffer (G_bolos_ux_context.sskr_words_buffer) to a sensible size. Maybe just store SSKR Bytewords as shorter two letter minimal Bytewords rather than a 4 letter Byteword plus spaace for each share. Convert minimal ByteWords back to four letter Bytewords just prior to display.

### In Progress

- [ ] Add Ledger Stax to list of devices app works on
- [x] Add SSKR Generate option to Stax
- [ ] Write BIP39 to SSKR functionality
- [ ] Add SSKR Check option to Stax
- [ ] Write SSKR to BIP39 functionality
- [ ] Test with 29-word SSKR shares
- [ ] Test with 46-word SSKR shares
- [ ] Functional Test with 29-word SSKR shares
- [ ] Functional Test with 46-word SSKR shares

### Done ✓

- [x] Add unit tests
- [x] Add code coverage to GitHub actions
- [x] Add option to generate BIP39 mnemonics from SSKR shares even if shares do not validate against seed on device
- A user may have lost or damaged original device and now needs to generate the recovery phrase from another secure device
- [x] Fix warnings about deprecated functions during build
Expand Down
22 changes: 22 additions & 0 deletions tests/unit/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Editor Files and Folders

.idea/
.vscode/
.DS_Store
*~
\#*#

# Build Files and Binaries

*.log
*.o
*.so
*.dll
*.dylib
cmake-build-*/
*build/
build/

# Coverage file
coverage.info
coverage
69 changes: 69 additions & 0 deletions tests/unit/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
cmake_minimum_required(VERSION 3.10)

if(${CMAKE_VERSION} VERSION_LESS 3.10)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()

# project information
project(unit_tests
VERSION 0.1
DESCRIPTION "Unit tests for app-seed-tool Ledger Application"
LANGUAGES C)


# guard against bad build-type strings
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug")
endif()

include(CTest)
ENABLE_TESTING()

# specify C standard
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED True)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -pedantic -g -O0 --coverage")

set(GCC_COVERAGE_LINK_FLAGS "--coverage -lgcov")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}")

# guard against in-source builds
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt. ")
endif()

# Fetch cmocka
find_package(cmocka QUIET)
include(FetchContent)
FetchContent_Declare(
cmocka
GIT_REPOSITORY https://git.cryptomilk.org/projects/cmocka.git
GIT_TAG cmocka-1.1.5
GIT_SHALLOW 1
)
set(WITH_STATIC_LIB ON CACHE BOOL "CMocka: Build with a static library" FORCE)
set(WITH_CMOCKERY_SUPPORT OFF CACHE BOOL "CMocka: Install a cmockery header" FORCE)
set(WITH_EXAMPLES OFF CACHE BOOL "CMocka: Build examples" FORCE)
set(UNIT_TESTING OFF CACHE BOOL "CMocka: Build with unit testing" FORCE)
set(PICKY_DEVELOPER OFF CACHE BOOL "CMocka: Build with picky developer flags" FORCE)
FetchContent_MakeAvailable(cmocka)

add_compile_definitions(TEST DEBUG=0 SKIP_FOR_CMOCKA)
add_compile_definitions(HAVE_HASH HAVE_HMAC HAVE_SHA256)

include_directories(./lib ../../src/bc-sskr/bc-shamir $ENV{LEDGER_SECURE_SDK}/include $ENV{LEDGER_SECURE_SDK}/lib_cxng/include $ENV{LEDGER_SECURE_SDK}/lib_cxng/src)

# add src
set(LIB_SOURCES ./lib/random.c $ENV{LEDGER_SECURE_SDK}/lib_cxng/src/cx_ram.c $ENV{LEDGER_SECURE_SDK}/lib_cxng/src/cx_hash.c $ENV{LEDGER_SECURE_SDK}/lib_cxng/src/cx_sha256.c $ENV{LEDGER_SECURE_SDK}/lib_cxng/src/cx_hmac.c $ENV{LEDGER_SECURE_SDK}/lib_cxng/src/cx_utils.c)
add_library(unittest SHARED ${LIB_SOURCES} )

# add cmocka tests
set(LIB_SOURCES ../../src/bc-sskr/bc-shamir/shamir.c ../../src/bc-sskr/bc-shamir/interpolate.c ../../src/bc-sskr/bc-shamir/hazmat.c)
add_library(shamir SHARED ${LIB_SOURCES} )
add_executable(test_shamir tests/shamir.c)
target_link_libraries(test_shamir PUBLIC cmocka gcov shamir unittest)

foreach(target test_shamir)
add_test(NAME ${target} COMMAND ${target})
endforeach()
41 changes: 41 additions & 0 deletions tests/unit/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
MAKEFLAGS += --no-print-directory

RM ?= rm -f
ECHO = `which echo`

ifneq (,$(findstring xterm,${TERM}))
GREEN := \e[0;32m
RED := \e[0;31m
CYAN := \e[0;36m
RESET := \e[0m
else
GREEN := ""
RED := ""
RESET := ""
endif

BUILD_DIRECTORY = $(realpath build/)

DIRECTORY_BUILD = build

all:
@cmake -B ${DIRECTORY_BUILD} -H.
@make -C ${DIRECTORY_BUILD}
@CTEST_OUTPUT_ON_FAILURE=1 make -C ${DIRECTORY_BUILD} test

coverage: all
@lcov --directory . -b "${BUILD_DIRECTORY}" --capture --initial -o coverage.base
@lcov --rc lcov_branch_coverage=1 --directory . -b "${BUILD_DIRECTORY}" --capture -o coverage.capture
@lcov --directory . -b "${BUILD_DIRECTORY}" --add-tracefile coverage.base --add-tracefile coverage.capture -o coverage.info
@lcov --directory . -b "${BUILD_DIRECTORY}" --remove coverage.info '*/build/_deps/cmocka-src/src/*' '*/unit/lib/*' '*/unit/tests/*' '${LEDGER_SECURE_SDK}/lib_cxng/src/*' -o coverage.info
@$(ECHO) -e "${GREEN}[ OK ]${RESET} Generated 'coverage.info'."
@genhtml coverage.info -o coverage
@if [ -f coverage.base ]; then $(ECHO) -e "${RED}[ RM ]${RESET}" coverage.base && $(RM) -r coverage.base ; fi;
@if [ -f coverage.capture ]; then $(ECHO) -e "${RED}[ RM ]${RESET}" coverage.capture && $(RM) -r coverage.capture ; fi;

clean:
@if [ -d ${DIRECTORY_BUILD} ]; then $(ECHO) -e "${RED}[ RM ]${RESET}" ${DIRECTORY_BUILD} && $(RM) -r ${DIRECTORY_BUILD} ; fi;
@if [ -d coverage ]; then $(ECHO) -e "${RED}[ RM ]${RESET}" coverage && $(RM) -r coverage ; fi;
@if [ -f coverage.info ]; then $(ECHO) -e "${RED}[ RM ]${RESET}" coverage.info && $(RM) -r coverage.info ; fi;

.PHONY: all coverage clean
38 changes: 38 additions & 0 deletions tests/unit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Unit tests

It is important to unit test your functions.
This also allows you to document how your functions work.
We use the library [**cmocka**](https://cmocka.org/#features)

## Requirement

- [CMake >= 3.10](https://cmake.org/download/)
- [lcov >= 1.14](http://ltp.sourceforge.net/coverage/lcov.php)

Don't worry, you don't necessarily need to install the `cmocka library` because the **cmakelist automatically fetches** the library

## Add new test

Create new file into `tests` folder and follow [this initiation](https://cmocka.org/talks/cmocka_unit_testing_and_mocking.pdf)

Now go to the `CMakeLists.txt` file and add your test with the specific file you want to test.

## Usage

### Build

The `default rules` of makefile will compile the tests and run them.

```sh
make
```

The `coverage rule` will launch the default rules and generate the coverage and you will be **automatically redirected** to the generated .html
```sh
make coverage
```

The `clean rule` will delete the folders and files generated
```sh
make clean
```
Empty file added tests/unit/lib/bolos_target.h
Empty file.
10 changes: 10 additions & 0 deletions tests/unit/lib/random.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include <stdint.h>
#include <stddef.h>

unsigned char *fake_rng(uint8_t *buffer, size_t len)
{
for (size_t i = 0; i < len; i++) {
buffer[i] = i % 256;
}
return buffer;
}
Loading

0 comments on commit f26e617

Please sign in to comment.