Skip to content

Commit

Permalink
More CT coverage for CI
Browse files Browse the repository at this point in the history
Optimize matrix multiplication in sign
Blocker values in critical sections for newer clang versions and untested configurations

Co-authored-by: Ward Beullens <[email protected]>
Co-authored-by: Basil Hess <[email protected]>
  • Loading branch information
bhess and WardBeullens committed Jul 24, 2024
1 parent cde2675 commit 3dace0e
Show file tree
Hide file tree
Showing 16 changed files with 310 additions and 88 deletions.
51 changes: 51 additions & 0 deletions .cmake/sanitizers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,54 @@ set(CMAKE_C_FLAGS_COVERAGE
"-fprofile-arcs -ftest-coverage"
CACHE STRING "Flags used by the C compiler during Coverage builds."
FORCE)

# CT-testing configs
set(CMAKE_C_FLAGS_CTOS
"-Os -gdwarf-4"
CACHE STRING "Flags used by the C compiler during CT builds."
FORCE)

set(CMAKE_C_FLAGS_CTO0
"-O0 -gdwarf-4"
CACHE STRING "Flags used by the C compiler during CT builds."
FORCE)

set(CMAKE_C_FLAGS_CTO1
"-O1 -gdwarf-4"
CACHE STRING "Flags used by the C compiler during CT builds."
FORCE)

set(CMAKE_C_FLAGS_CTO2
"-O2 -gdwarf-4"
CACHE STRING "Flags used by the C compiler during CT builds."
FORCE)

set(CMAKE_C_FLAGS_CTO3
"-O3 -gdwarf-4"
CACHE STRING "Flags used by the C compiler during CT builds."
FORCE)

set(CMAKE_C_FLAGS_CTOSNOVEC
"-Os -fno-vectorize -gdwarf-4"
CACHE STRING "Flags used by the C compiler during CT builds."
FORCE)

set(CMAKE_C_FLAGS_CTO0NOVEC
"-O0 -fno-vectorize -gdwarf-4"
CACHE STRING "Flags used by the C compiler during CT builds."
FORCE)

set(CMAKE_C_FLAGS_CTO1NOVEC
"-O1 -fno-vectorize -gdwarf-4"
CACHE STRING "Flags used by the C compiler during CT builds."
FORCE)

set(CMAKE_C_FLAGS_CTO2NOVEC
"-O2 -fno-vectorize -gdwarf-4"
CACHE STRING "Flags used by the C compiler during CT builds."
FORCE)

set(CMAKE_C_FLAGS_CTO3NOVEC
"-O3 -fno-vectorize -gdwarf-4"
CACHE STRING "Flags used by the C compiler during CT builds."
FORCE)
61 changes: 61 additions & 0 deletions .github/workflows/ci_clang.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# This is a basic workflow to help you get started with Actions

name: CT-tests (clang, clang-14 and clang-18)

# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "github" branch
push:
branches: [ '*' ]
pull_request:
branches: [ "main" ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
ct:
# The type of runner that the job will run on
runs-on: ubuntu-latest
strategy:
matrix:
clang_config: [CTOS, CTO0, CTO2, CTO3, CTOSNOVEC, CTO0NOVEC, CTO2NOVEC, CTO3NOVEC]
# TODO: valgrind seems buggy with CT01 and CT01NOVEC
clang_version: [clang, clang-15, clang-18]
mayo_build_type: [ref, opt, avx2]


# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.10
uses: actions/setup-python@v5
with:
python-version: "3.10"

- name: Install dependencies
run: wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - && wget https://apt.llvm.org/llvm.sh && sudo bash ./llvm.sh 18 && sudo apt update && sudo apt -y install build-essential valgrind cmake libboost-tools-dev libpthread-stubs0-dev libssl-dev clang-15 clang-18 clang gcc gcc-12

- name: CT-Test (clang)
run: |
ldd --version
rm -rf build && mkdir build && cd build && cmake -DENABLE_CT_TESTING=ON -DMAYO_BUILD_TYPE=${{ matrix.mayo_build_type }} -DCMAKE_C_COMPILER=${{ matrix.clang_version }} -DCMAKE_BUILD_TYPE=${{ matrix.clang_config }} -DMAYO_MARCH="-march=haswell -maes" .. && make -j
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme_MAYO_1
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme_MAYO_2
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme_MAYO_3
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme_MAYO_5
cd ..
if: (matrix.mayo_build_type == 'opt' || matrix.mayo_build_type == 'avx2') && !(matrix.clang_config == 'CTO3' && matrix.mayo_build_type == 'opt')

- name: CT-Test (clang)
run: |
ldd --version
rm -rf build && mkdir build && cd build && cmake -DENABLE_CT_TESTING=ON -DMAYO_BUILD_TYPE=${{ matrix.mayo_build_type }} -DCMAKE_C_COMPILER=${{ matrix.clang_version }} -DCMAKE_BUILD_TYPE=${{ matrix.clang_config }} -DMAYO_MARCH="-march=haswell -maes" .. && make -j
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme MAYO-1
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme MAYO-2
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme MAYO-3
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme MAYO-5
cd ..
if: matrix.mayo_build_type == 'ref'
60 changes: 60 additions & 0 deletions .github/workflows/ci_gcc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# This is a basic workflow to help you get started with Actions

name: CT-tests (gcc and gcc-12)

# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the "github" branch
push:
branches: [ '*' ]
pull_request:
branches: [ "main" ]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
ct:
# The type of runner that the job will run on
runs-on: ubuntu-latest
strategy:
matrix:
gcc_config: [CTOS, CTO0, CTO1, CTO2, CTO3]
gcc_version: [gcc, gcc-12]
mayo_build_type: [ref, opt, avx2]


# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.10
uses: actions/setup-python@v5
with:
python-version: "3.10"

- name: Install dependencies
run: sudo apt update && sudo apt -y install build-essential valgrind cmake libboost-tools-dev libpthread-stubs0-dev libssl-dev clang-15 clang gcc gcc-12

- name: CT-Test (gcc)
run: |
ldd --version
rm -rf build && mkdir build && cd build && cmake -DENABLE_CT_TESTING=ON -DMAYO_BUILD_TYPE=${{ matrix.mayo_build_type }} -DCMAKE_C_COMPILER=${{ matrix.gcc_version }} -DCMAKE_BUILD_TYPE=${{ matrix.gcc_config }} -DMAYO_MARCH="-march=haswell -maes" .. && make -j
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme_MAYO_1
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme_MAYO_2
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme_MAYO_3
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme_MAYO_5
cd ..
if: matrix.mayo_build_type == 'opt' || matrix.mayo_build_type == 'avx2'

- name: CT-Test (clang)
run: |
ldd --version
rm -rf build && mkdir build && cd build && cmake -DENABLE_CT_TESTING=ON -DMAYO_BUILD_TYPE=${{ matrix.mayo_build_type }} -DCMAKE_C_COMPILER=${{ matrix.gcc_version }} -DCMAKE_BUILD_TYPE=${{ matrix.gcc_config }} -DMAYO_MARCH="-march=haswell -maes" .. && make -j
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme MAYO-1
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme MAYO-2
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme MAYO-3
valgrind --tool=memcheck --error-exitcode=1 --track-origins=yes test/mayo_test_scheme MAYO-5
cd ..
if: matrix.mayo_build_type == 'ref'
2 changes: 1 addition & 1 deletion .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.10
uses: actions/setup-python@v3
uses: actions/setup-python@v5
with:
python-version: "3.10"

Expand Down
45 changes: 40 additions & 5 deletions include/mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,69 @@
#define BSWAP64(i) ((BSWAP32((i) >> 32) & 0xffffffff) | (BSWAP32(i) << 32))
#endif

extern volatile uint32_t uint32_t_blocker;
extern volatile uint64_t uint64_t_blocker;
extern volatile unsigned char unsigned_char_blocker;

#if !(((!defined(__clang__) && defined(__GNUC__) && __GNUC__ <= 12)) && (defined(__x86_64__) || defined(_M_X64)))
// a > b -> b - a is negative
// returns 0xFFFFFFFF if true, 0x00000000 if false
static inline uint32_t ct_is_greater_than(int a, int b) {
int32_t diff = b - a;
return ((uint32_t) (diff >> (8*sizeof(uint32_t)-1)) ^ uint32_t_blocker);
}

// a > b -> b - a is negative
// returns 0xFFFFFFFF if true, 0x00000000 if false
static inline uint64_t ct_64_is_greater_than(int a, int b) {
int64_t diff = ((int64_t) b) - ((int64_t) a);
return ((uint64_t) (diff >> (8*sizeof(uint64_t)-1)) ^ uint64_t_blocker);
}

// if a == b -> 0x00000000, else 0xFFFFFFFF
static inline uint32_t ct_compare_32(int a, int b) {
return ((uint32_t)((-(int32_t)(a ^ b)) >> (8*sizeof(uint32_t)-1)) ^ uint32_t_blocker);
}

// if a == b -> 0x0000000000000000, else 0xFFFFFFFFFFFFFFFF
static inline uint64_t ct_compare_64(int a, int b) {
return ((uint64_t)((-(int64_t)(a ^ b)) >> (8*sizeof(uint64_t)-1)) ^ uint64_t_blocker);
}

// if a == b -> 0x00, else 0xFF
static inline unsigned char ct_compare_8(unsigned char a, unsigned char b) {
return ((int8_t)((-(int32_t)(a ^ b)) >> (8*sizeof(uint32_t)-1)) ^ unsigned_char_blocker);
}
#else
// a > b -> b - a is negative
// returns 0xFFFFFFFF if true, 0x00000000 if false
static inline uint32_t ct_is_greater_than(int a, int b) {
int32_t diff = b - a;
return (uint32_t) (diff >> (8*sizeof(uint32_t)-1));
return ((uint32_t) (diff >> (8*sizeof(uint32_t)-1)));
}

// a > b -> b - a is negative
// returns 0xFFFFFFFF if true, 0x00000000 if false
static inline uint64_t ct_64_is_greater_than(int a, int b) {
int64_t diff = ((int64_t) b) - ((int64_t) a);
return (uint64_t) (diff >> (8*sizeof(uint64_t)-1));
return ((uint64_t) (diff >> (8*sizeof(uint64_t)-1)));
}

// if a == b -> 0x00000000, else 0xFFFFFFFF
static inline uint32_t ct_compare_32(int a, int b) {
return (uint32_t)((-(int32_t)(a ^ b)) >> (8*sizeof(uint32_t)-1));
return ((uint32_t)((-(int32_t)(a ^ b)) >> (8*sizeof(uint32_t)-1)));
}

// if a == b -> 0x0000000000000000, else 0xFFFFFFFFFFFFFFFF
static inline uint64_t ct_compare_64(int a, int b) {
return (uint64_t)((-(int64_t)(a ^ b)) >> (8*sizeof(uint64_t)-1));
return ((uint64_t)((-(int64_t)(a ^ b)) >> (8*sizeof(uint64_t)-1)));
}

// if a == b -> 0x00, else 0xFF
static inline unsigned char ct_compare_8(unsigned char a, unsigned char b) {
return (int8_t)((-(int32_t)(a ^ b)) >> (8*sizeof(uint32_t)-1));
return ((int8_t)((-(int32_t)(a ^ b)) >> (8*sizeof(uint32_t)-1)));
}
#endif

/**
* Clears and frees allocated memory.
Expand Down
1 change: 1 addition & 0 deletions src/AVX2/arithmetic_128.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <stdint.h>
#include <mayo.h>
#include <arithmetic_common.h>
#include <simple_arithmetic.h>

// This implements arithmetic for vectors of 128 field elements in Z_2[x]/(x^4+x+1)

Expand Down
1 change: 1 addition & 0 deletions src/AVX2/arithmetic_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <stdint.h>
#include <mayo.h>
#include <arithmetic_common.h>
#include <simple_arithmetic.h>

// This implements arithmetic for vectors of 64 field elements in Z_2[x]/(x^4+x+1)

Expand Down
1 change: 1 addition & 0 deletions src/AVX2/arithmetic_96.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <stdint.h>
#include <mayo.h>
#include <arithmetic_common.h>
#include <simple_arithmetic.h>

// This implements arithmetic for vectors of 96 field elements in Z_2[x]/(x^4+x+1)

Expand Down
26 changes: 1 addition & 25 deletions src/AVX2/arithmetic_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <stdint.h>
#include <immintrin.h>
#include <mem.h>

#define K_OVER_2 ((K_MAX+1)/2)

Expand Down Expand Up @@ -146,30 +147,5 @@ inline void mayo_S2_multabs_avx2(const unsigned char *S2, __m256i *S2_multabs) {
}
}

static inline uint64_t gf16v_mul_u64( uint64_t a, uint8_t b ) {
uint64_t mask_msb = 0x8888888888888888ULL;
uint64_t a_msb;
uint64_t a64 = a;
uint64_t b32 = b;
uint64_t r64 = a64 * (b32 & 1);

a_msb = a64 & mask_msb; // MSB, 3rd bits
a64 ^= a_msb; // clear MSB
a64 = (a64 << 1) ^ ((a_msb >> 3) * 3);
r64 ^= (a64) * ((b32 >> 1) & 1);

a_msb = a64 & mask_msb; // MSB, 3rd bits
a64 ^= a_msb; // clear MSB
a64 = (a64 << 1) ^ ((a_msb >> 3) * 3);
r64 ^= (a64) * ((b32 >> 2) & 1);

a_msb = a64 & mask_msb; // MSB, 3rd bits
a64 ^= a_msb; // clear MSB
a64 = (a64 << 1) ^ ((a_msb >> 3) * 3);
r64 ^= (a64) * ((b32 >> 3) & 1);

return r64;
}

#endif

1 change: 1 addition & 0 deletions src/AVX2/shuffle_arithmetic_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ inline void mayo_12_Ot_times_P1O_P2_avx2(const uint64_t *_P1O_P2, __m256i *O_mul
}
}


static
inline void mayo_12_P1P1t_times_O(const uint64_t *_P1, const unsigned char *O, uint64_t *_acc){

Expand Down
50 changes: 50 additions & 0 deletions src/arithmetic.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <mem.h>
#include <echelon_form.h>
#include <stdalign.h>
#include <string.h>
#ifdef ENABLE_CT_TESTING
#include <valgrind/memcheck.h>
#endif
Expand Down Expand Up @@ -325,3 +326,52 @@ int sample_solution(const mayo_params_t *p, unsigned char *A,
return 1;
}

void finish_signature(const mayo_params_t* p, const unsigned char* O, const unsigned char* x, const unsigned char* Vdec, unsigned char* s){

const int param_n = PARAM_n(p);
const int param_o = PARAM_o(p);
const int param_k = PARAM_k(p);
const int legs = (param_n-param_o+31)/32;
uint64_t product[N_MAX/32*2*K_MAX] = {0};
uint64_t O_col[N_MAX/32*2];

// matrix mul
for (int i = 0; i < param_o; i++)
{
// read column of O
memset((void *) O_col, 0, 2*legs*8);
for (int j = 0; j < param_n-param_o; j++)
{
O_col[(j/16)] ^= ( ((uint64_t) O[j*param_o + i ]) << (4*(j%16)));
}

// process column of O
for (int j = 0; j < param_k; j++)
{
#ifdef MAYO_VARIANT
#if N_MAX-O_MAX <= 64
vec_mul_add_64(O_col, x[j*param_o+i], product + j*2*legs);
#elif N_MAX-O_MAX <= 96
vec_mul_add_96(O_col, x[j*param_o+i], product + j*2*legs);
#elif N_MAX-O_MAX <= 128
vec_mul_add_128(O_col, x[j*param_o+i], product + j*2*legs);
#else
not implemented
#endif
#else
m_vec_mul_add(legs, O_col, x[j*param_o+i], product + j*2*legs);
#endif
}
}

// write product to s
for (int i = 0; i < param_k; i++)
{
for (int j = 0; j < param_n-param_o; j++)
{
s[param_n*i + j] = Vdec[i*(param_n-param_o) + j] ^ ((product[i*2*legs + (j/16)] >> (4*(j%16))) & 0xf);
}
memcpy(s + i*param_n + (param_n-param_o), x + i*param_o, param_o);
}

}
Loading

0 comments on commit 3dace0e

Please sign in to comment.