From 20fb301d9e31d42e3e49f9e938d5ce38effaaa72 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Fri, 15 Nov 2024 11:54:49 +0000 Subject: [PATCH] update boring flow --- libcrux-ml-kem/boring.sh | 8 +- libcrux-ml-kem/cg/boring/eurydice_glue.h | 182 ++++++++++++++++++ libcrux-ml-kem/cg/boring/karamel/target.h | 55 ++++++ libcrux-ml-kem/cg/code_gen.txt | 2 +- libcrux-ml-kem/cg/libcrux_core.h | 2 +- libcrux-ml-kem/cg/libcrux_ct_ops.h | 2 +- libcrux-ml-kem/cg/libcrux_mlkem768_avx2.h | 2 +- libcrux-ml-kem/cg/libcrux_mlkem768_portable.h | 2 +- libcrux-ml-kem/cg/libcrux_sha3_avx2.h | 2 +- libcrux-ml-kem/cg/libcrux_sha3_portable.h | 2 +- 10 files changed, 250 insertions(+), 9 deletions(-) create mode 100644 libcrux-ml-kem/cg/boring/eurydice_glue.h create mode 100644 libcrux-ml-kem/cg/boring/karamel/target.h diff --git a/libcrux-ml-kem/boring.sh b/libcrux-ml-kem/boring.sh index 43a9d499a..3ba5c2e1c 100755 --- a/libcrux-ml-kem/boring.sh +++ b/libcrux-ml-kem/boring.sh @@ -27,10 +27,14 @@ clang-format-18 --style=Google -i cg/*.h if [[ -n "$BORINGSSL_HOME" ]]; then echo "Copying the files into $BORINGSSL_HOME/third_party/libcrux/" - cp cg/*.h $BORINGSSL_HOME/third_party/libcrux/ + cp cg/libcrux_*.h $BORINGSSL_HOME/third_party/libcrux/ cp cg/code_gen.txt $BORINGSSL_HOME/third_party/libcrux/ - cp -r cg/karamel $BORINGSSL_HOME/third_party/libcrux/ cp -r cg/intrinsics $BORINGSSL_HOME/third_party/libcrux/ + + # We use special files here. + cp cg/boring/eurydice_glue.h $BORINGSSL_HOME/third_party/libcrux/ + cp -r cg/boring/karamel $BORINGSSL_HOME/third_party/libcrux/ + libcrux_rev=$(git rev-parse HEAD) echo "libcrux: $libcrux_rev" >> $BORINGSSL_HOME/third_party/libcrux/code_gen.txt fi diff --git a/libcrux-ml-kem/cg/boring/eurydice_glue.h b/libcrux-ml-kem/cg/boring/eurydice_glue.h new file mode 100644 index 000000000..79cf1285b --- /dev/null +++ b/libcrux-ml-kem/cg/boring/eurydice_glue.h @@ -0,0 +1,182 @@ +/* + * SPDX-FileCopyrightText: 2024 Eurydice Contributors + * SPDX-FileCopyrightText: 2024 Cryspen Sarl + * + * SPDX-License-Identifier: MIT or Apache-2.0 + */ + +#pragma once + +#if defined(__cplusplus) +extern "C" { +#endif + +#include +#include +#include +#include +#include + +#include "karamel/target.h" + +// SLICES, ARRAYS, ETC. + +// The MSVC C++ compiler does not support compound literals. +// This CLITERAL is used to turn `(type){...}` into `type{...}` when using a C++ +// compiler. +#if defined(__cplusplus) +#define CLITERAL(type) type +#else +#define CLITERAL(type) (type) +#endif + +// We represent a slice as a pair of an (untyped) pointer, along with the length +// of the slice, i.e. the number of elements in the slice (this is NOT the +// number of bytes). This design choice has two important consequences. +// - if you need to use `ptr`, you MUST cast it to a proper type *before* +// performing pointer +// arithmetic on it (remember that C desugars pointer arithmetic based on the +// type of the address) +// - if you need to use `len` for a C style function (e.g. memcpy, memcmp), you +// need to multiply it +// by sizeof t, where t is the type of the elements. +// +// Empty slices have `len == 0` and `ptr` always needs to be valid pointer that +// is not NULL (otherwise the construction in EURYDICE_SLICE computes `NULL + +// start`). +typedef struct { + void *ptr; + size_t len; +} Eurydice_slice; + +// Helper macro to create a slice out of a pointer x, a start index in x +// (included), and an end index in x (excluded). The argument x must be suitably +// cast to something that can decay (see remark above about how pointer +// arithmetic works in C), meaning either pointer or array type. +#define EURYDICE_SLICE(x, start, end) \ + (CLITERAL(Eurydice_slice){.ptr = (void *)(x + start), .len = end - start}) +#define EURYDICE_SLICE_LEN(s, _) s.len +// This macro is a pain because in case the dereferenced element type is an +// array, you cannot simply write `t x` as it would yield `int[4] x` instead, +// which is NOT correct C syntax, so we add a dedicated phase in Eurydice that +// adds an extra argument to this macro at the last minute so that we have the +// correct type of *pointers* to elements. +#define Eurydice_slice_index(s, i, t, t_ptr_t) (((t_ptr_t)s.ptr)[i]) +#define Eurydice_slice_subslice(s, r, t, _) \ + EURYDICE_SLICE((t *)s.ptr, r.start, r.end) +// Variant for when the start and end indices are statically known (i.e., the +// range argument `r` is a literal). +#define Eurydice_slice_subslice2(s, start, end, t) \ + EURYDICE_SLICE((t *)s.ptr, start, end) +#define Eurydice_slice_subslice_to(s, subslice_end_pos, t, _) \ + EURYDICE_SLICE((t *)s.ptr, 0, subslice_end_pos) +#define Eurydice_slice_subslice_from(s, subslice_start_pos, t, _) \ + EURYDICE_SLICE((t *)s.ptr, subslice_start_pos, s.len) +#define Eurydice_array_to_slice(end, x, t) \ + EURYDICE_SLICE(x, 0, \ + end) /* x is already at an array type, no need for cast */ +#define Eurydice_array_to_subslice(_arraylen, x, r, t, _) \ + EURYDICE_SLICE((t *)x, r.start, r.end) +// Same as above, variant for when start and end are statically known +#define Eurydice_array_to_subslice2(x, start, end, t) \ + EURYDICE_SLICE((t *)x, start, end) +#define Eurydice_array_to_subslice_to(_size, x, r, t, _range_t) \ + EURYDICE_SLICE((t *)x, 0, r) +#define Eurydice_array_to_subslice_from(size, x, r, t, _range_t) \ + EURYDICE_SLICE((t *)x, r, size) +#define Eurydice_slice_len(s, t) EURYDICE_SLICE_LEN(s, t) +#define Eurydice_slice_copy(dst, src, t) \ + memcpy(dst.ptr, src.ptr, dst.len * sizeof(t)) +#define core_array___Array_T__N__23__as_slice(len_, ptr_, t, _ret_t) \ + ((Eurydice_slice){.ptr = ptr_, .len = len_}) + +#define core_array___core__clone__Clone_for__Array_T__N___20__clone( \ + len, src, dst, elem_type, _ret_t) \ + (memcpy(dst, src, len * sizeof(elem_type))) +#define TryFromSliceError uint8_t + +#define Eurydice_array_eq(sz, a1, a2, t, _) \ + (memcmp(a1, a2, sz * sizeof(t)) == 0) +#define core_array_equality___core__cmp__PartialEq__Array_U__N___for__Array_T__N____eq( \ + sz, a1, a2, t, _, _ret_t) \ + Eurydice_array_eq(sz, a1, a2, t, _) +#define core_array_equality___core__cmp__PartialEq__0___Slice_U____for__Array_T__N___3__eq( \ + sz, a1, a2, t, _, _ret_t) \ + Eurydice_array_eq(sz, a1, ((a2)->ptr), t, _) + +#define Eurydice_slice_split_at(slice, mid, element_type, ret_t) \ + (CLITERAL(ret_t){ \ + .fst = EURYDICE_SLICE((element_type *)slice.ptr, 0, mid), \ + .snd = EURYDICE_SLICE((element_type *)slice.ptr, mid, slice.len)}) +#define Eurydice_slice_split_at_mut(slice, mid, element_type, ret_t) \ + (CLITERAL(ret_t){ \ + .fst = {.ptr = slice.ptr, .len = mid}, \ + .snd = {.ptr = (char *)slice.ptr + mid * sizeof(element_type), \ + .len = slice.len - mid}}) + +// Conversion of slice to an array, rewritten (by Eurydice) to name the +// destination array, since arrays are not values in C. +// N.B.: see note in karamel/lib/Inlining.ml if you change this. +#define Eurydice_slice_to_array2(dst, src, _, t_arr) \ + Eurydice_slice_to_array3(&(dst)->tag, (char *)&(dst)->val.case_Ok, src, \ + sizeof(t_arr)) + +static inline void Eurydice_slice_to_array3(uint8_t *dst_tag, char *dst_ok, + Eurydice_slice src, size_t sz) { + *dst_tag = 0; + memcpy(dst_ok, src.ptr, sz); +} + +// CORE STUFF (conversions, endianness, ...) + +static inline void core_num__u64_9__to_le_bytes(uint64_t v, uint8_t buf[8]) { + CRYPTO_store_u64_le(buf, v); +} +static inline uint64_t core_num__u64_9__from_le_bytes(uint8_t buf[8]) { + return CRYPTO_load_u64_le(buf); +} + +static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t buf[4]) { + return CRYPTO_load_u32_le(buf); +} + +static inline uint32_t core_num__u8_6__count_ones(uint8_t x0) { +#if defined(__GNUC__) || defined(__clang__) + return __builtin_popcount(x0); +#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) + // || defined(_M_ARM64)) // since MSVC 2022 17.11 Preview 3 + return __popcnt(x0); +#else + x0 = (x0 & 0b01010101) + (x0 >> 1 & 0b01010101); + x0 = (x0 & 0b00110011) + (x0 >> 2 & 0b00110011); + x0 = (x0 & 0b00001111) + (x0 >> 4 & 0b00001111); + return x0; +#endif +} + +// unsigned overflow wraparound semantics in C +static inline uint16_t core_num__u16_7__wrapping_add(uint16_t x, uint16_t y) { + return x + y; +} +static inline uint8_t core_num__u8_6__wrapping_sub(uint8_t x, uint8_t y) { + return x - y; +} + +// ITERATORS + +#define Eurydice_range_iter_next(iter_ptr, t, ret_t) \ + (((iter_ptr)->start == (iter_ptr)->end) \ + ? (CLITERAL(ret_t){.tag = None}) \ + : (CLITERAL(ret_t){.tag = Some, .f0 = (iter_ptr)->start++})) + +#define core_iter_range___core__iter__traits__iterator__Iterator_for_core__ops__range__Range_A__TraitClause_0___6__next \ + Eurydice_range_iter_next + +// See note in karamel/lib/Inlining.ml if you change this +#define Eurydice_into_iter(x, t, _ret_t) (x) +#define core_iter_traits_collect___core__iter__traits__collect__IntoIterator_for_I__1__into_iter \ + Eurydice_into_iter + +#if defined(__cplusplus) +} +#endif diff --git a/libcrux-ml-kem/cg/boring/karamel/target.h b/libcrux-ml-kem/cg/boring/karamel/target.h new file mode 100644 index 000000000..f05271541 --- /dev/null +++ b/libcrux-ml-kem/cg/boring/karamel/target.h @@ -0,0 +1,55 @@ +/* Copyright (c) INRIA and Microsoft Corporation. All rights reserved. + * Licensed under the Apache 2.0 and MIT Licenses. + * + * SPDX-FileCopyrightText: 2024 INRIA and Microsoft Corporation + * SPDX-FileCopyrightText: 2024 Cryspen Sarl + * + * SPDX-License-Identifier: MIT or Apache-2.0 + */ + +#ifndef __KRML_TARGET_H +#define __KRML_TARGET_H + +#ifndef KRML_HOST_PRINTF +#define KRML_HOST_PRINTF printf +#endif + +#if ((defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \ + (defined(__cplusplus) && __cplusplus > 199711L)) && \ + (!defined(KRML_HOST_EPRINTF)) +#define KRML_HOST_EPRINTF(...) fprintf(stderr, __VA_ARGS__) +#elif !(defined KRML_HOST_EPRINTF) && defined(_MSC_VER) +#define KRML_HOST_EPRINTF(...) fprintf(stderr, __VA_ARGS__) +#endif + +#ifndef KRML_HOST_EXIT +#define KRML_HOST_EXIT exit +#endif + +// This does not actually force inline. +// Forcing inline increases stack usage beyond acceptable limits +#define KRML_MUSTINLINE inline + +#ifndef KRML_NOINLINE +#if defined(_MSC_VER) +#define KRML_NOINLINE __declspec(noinline) +#elif defined(__GNUC__) || defined(__clang__) +#define KRML_NOINLINE __attribute__((noinline, unused)) +#else +#define KRML_NOINLINE +#warning "The KRML_NOINLINE macro is not defined for this toolchain!" +#warning "The compiler may defeat side-channel resistance with optimizations." +#warning \ + "Please locate target.h and try to fill it out with a suitable definition for this compiler." +#endif +#endif + +#ifndef KRML_ATTRIBUTE_TARGET +#if defined(__GNUC__) || defined(__clang__) +#define KRML_ATTRIBUTE_TARGET(x) __attribute__((target(x))) +#else +#define KRML_ATTRIBUTE_TARGET(x) +#endif +#endif + +#endif diff --git a/libcrux-ml-kem/cg/code_gen.txt b/libcrux-ml-kem/cg/code_gen.txt index 96556d5be..3bbff9516 100644 --- a/libcrux-ml-kem/cg/code_gen.txt +++ b/libcrux-ml-kem/cg/code_gen.txt @@ -3,4 +3,4 @@ Charon: 45f5a34f336e35c6cc2253bc90cbdb8d812cefa9 Eurydice: 7d686376ec943225ff89942978c6c3028bac689c Karamel: 8c3612018c25889288da6857771be3ad03b75bcd F*: 5643e656b989aca7629723653a2570c7df6252b9-dirty -Libcrux: 122ee3d193e33f55c2324ee84f974e647255f545 +Libcrux: dc479b888127f61fdc6af2d8524c06a6a6fb1e9c diff --git a/libcrux-ml-kem/cg/libcrux_core.h b/libcrux-ml-kem/cg/libcrux_core.h index 05b642dd2..797299a5e 100644 --- a/libcrux-ml-kem/cg/libcrux_core.h +++ b/libcrux-ml-kem/cg/libcrux_core.h @@ -8,7 +8,7 @@ * Eurydice: 7d686376ec943225ff89942978c6c3028bac689c * Karamel: 8c3612018c25889288da6857771be3ad03b75bcd * F*: 5643e656b989aca7629723653a2570c7df6252b9-dirty - * Libcrux: 122ee3d193e33f55c2324ee84f974e647255f545 + * Libcrux: dc479b888127f61fdc6af2d8524c06a6a6fb1e9c */ #ifndef __libcrux_core_H diff --git a/libcrux-ml-kem/cg/libcrux_ct_ops.h b/libcrux-ml-kem/cg/libcrux_ct_ops.h index 58a2d4582..d29deded9 100644 --- a/libcrux-ml-kem/cg/libcrux_ct_ops.h +++ b/libcrux-ml-kem/cg/libcrux_ct_ops.h @@ -8,7 +8,7 @@ * Eurydice: 7d686376ec943225ff89942978c6c3028bac689c * Karamel: 8c3612018c25889288da6857771be3ad03b75bcd * F*: 5643e656b989aca7629723653a2570c7df6252b9-dirty - * Libcrux: 122ee3d193e33f55c2324ee84f974e647255f545 + * Libcrux: dc479b888127f61fdc6af2d8524c06a6a6fb1e9c */ #ifndef __libcrux_ct_ops_H diff --git a/libcrux-ml-kem/cg/libcrux_mlkem768_avx2.h b/libcrux-ml-kem/cg/libcrux_mlkem768_avx2.h index 6680aaac8..09c5ec2f6 100644 --- a/libcrux-ml-kem/cg/libcrux_mlkem768_avx2.h +++ b/libcrux-ml-kem/cg/libcrux_mlkem768_avx2.h @@ -8,7 +8,7 @@ * Eurydice: 7d686376ec943225ff89942978c6c3028bac689c * Karamel: 8c3612018c25889288da6857771be3ad03b75bcd * F*: 5643e656b989aca7629723653a2570c7df6252b9-dirty - * Libcrux: 122ee3d193e33f55c2324ee84f974e647255f545 + * Libcrux: dc479b888127f61fdc6af2d8524c06a6a6fb1e9c */ #ifndef __libcrux_mlkem768_avx2_H diff --git a/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h b/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h index a2e8ef0a4..0ef93f4c2 100644 --- a/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h +++ b/libcrux-ml-kem/cg/libcrux_mlkem768_portable.h @@ -8,7 +8,7 @@ * Eurydice: 7d686376ec943225ff89942978c6c3028bac689c * Karamel: 8c3612018c25889288da6857771be3ad03b75bcd * F*: 5643e656b989aca7629723653a2570c7df6252b9-dirty - * Libcrux: 122ee3d193e33f55c2324ee84f974e647255f545 + * Libcrux: dc479b888127f61fdc6af2d8524c06a6a6fb1e9c */ #ifndef __libcrux_mlkem768_portable_H diff --git a/libcrux-ml-kem/cg/libcrux_sha3_avx2.h b/libcrux-ml-kem/cg/libcrux_sha3_avx2.h index 22d1ca76b..412ce26b2 100644 --- a/libcrux-ml-kem/cg/libcrux_sha3_avx2.h +++ b/libcrux-ml-kem/cg/libcrux_sha3_avx2.h @@ -8,7 +8,7 @@ * Eurydice: 7d686376ec943225ff89942978c6c3028bac689c * Karamel: 8c3612018c25889288da6857771be3ad03b75bcd * F*: 5643e656b989aca7629723653a2570c7df6252b9-dirty - * Libcrux: 122ee3d193e33f55c2324ee84f974e647255f545 + * Libcrux: dc479b888127f61fdc6af2d8524c06a6a6fb1e9c */ #ifndef __libcrux_sha3_avx2_H diff --git a/libcrux-ml-kem/cg/libcrux_sha3_portable.h b/libcrux-ml-kem/cg/libcrux_sha3_portable.h index 68757a15e..6bed02ce3 100644 --- a/libcrux-ml-kem/cg/libcrux_sha3_portable.h +++ b/libcrux-ml-kem/cg/libcrux_sha3_portable.h @@ -8,7 +8,7 @@ * Eurydice: 7d686376ec943225ff89942978c6c3028bac689c * Karamel: 8c3612018c25889288da6857771be3ad03b75bcd * F*: 5643e656b989aca7629723653a2570c7df6252b9-dirty - * Libcrux: 122ee3d193e33f55c2324ee84f974e647255f545 + * Libcrux: dc479b888127f61fdc6af2d8524c06a6a6fb1e9c */ #ifndef __libcrux_sha3_portable_H