On Fri, 21 Feb 2025, Damien Miller wrote: > > sparc64$ grep -n '__builtin_popcount' openssh-9.8p1/libcrux_mlkem768_sha3.h > > grep: openssh-9.8p1/libcrux_mlkem768_sha3.h: No such file or directory > > sparc64$ > > Ah sorry, I was driving "git diff" badly. The code is indeed new. > > Can you provide some more details about your compiler? We already have > logic to disable ML-KEM if the compiler is too old (search defines.h for > USE_MLKEM768X25519), and it would be trivial to extend that. > > It's probably fairly easy to put a simple popcount in for compatibility > too, but I don't think we need to be very fancy there. > > To do either of these in OpenSSH though, we need to be able to identify > compilers that lack __builtin_popcount... Try the attached patch. You'll need to rebuild configure after applying it.
diff --git a/configure.ac b/configure.ac index b802d0e60..254b2d9cb 100644 --- a/configure.ac +++ b/configure.ac @@ -2072,6 +2072,19 @@ AC_CHECK_FUNCS([ \ warn \ ]) +AC_MSG_CHECKING([whether compiler supports __builtin_popcount]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include <stdlib.h> + ]], + [[ int x = 123, y; + y = __builtin_popcount(123); + exit(y == 6 ? 0 : -1); ]])], + [ AC_MSG_RESULT([yes]) ], [ + AC_MSG_RESULT([no]) + AC_DEFINE([MISSING_BUILTIN_POPCOUNT], [1], [Define if your compiler lacks __builtin_popcount]) + ] +) + AC_CHECK_DECLS([bzero, memmem]) dnl Wide character support. diff --git a/libcrux_mlkem768_sha3.h b/libcrux_mlkem768_sha3.h index b8ac1436f..885e82baf 100644 --- a/libcrux_mlkem768_sha3.h +++ b/libcrux_mlkem768_sha3.h @@ -177,10 +177,14 @@ static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t buf[4]) { } static inline uint32_t core_num__u8_6__count_ones(uint8_t x0) { -#ifdef _MSC_VER +#if defined(_MSC_VER) return __popcnt(x0); -#else +#elif !defined(MISSING_BUILTIN_POPCOUNT) return __builtin_popcount(x0); +#else + const uint8_t v[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + return v[x0 & 0xf] + v[(x0 >> 4) & 0xf]; + #endif } diff --git a/mlkem768.sh b/mlkem768.sh index 3d12b2ed8..cbc3d14da 100644 --- a/mlkem768.sh +++ b/mlkem768.sh @@ -49,6 +49,11 @@ echo '#define KRML_HOST_EPRINTF(...)' echo '#define KRML_HOST_EXIT(x) fatal_f("internal error")' echo +__builtin_popcount_replacement=' + const uint8_t v[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + return v[x0 & 0xf] + v[(x0 >> 4) & 0xf]; +' + for i in $FILES; do echo "/* from $i */" # Changes to all files: @@ -62,7 +67,10 @@ for i in $FILES; do # Replace endian functions with versions that work. perl -0777 -pe 's/(static inline void core_num__u64_9__to_le_bytes.*\n)([^}]*\n)/\1 v = htole64(v);\n\2/' | perl -0777 -pe 's/(static inline uint64_t core_num__u64_9__from_le_bytes.*?)return v;/\1return le64toh(v);/s' | - perl -0777 -pe 's/(static inline uint32_t core_num__u32_8__from_le_bytes.*?)return v;/\1return le32toh(v);/s' + perl -0777 -pe 's/(static inline uint32_t core_num__u32_8__from_le_bytes.*?)return v;/\1return le32toh(v);/s' | + # Compat for popcount. + perl -0777 -pe 's/\#ifdef (_MSC_VER)(.*?return __popcnt\(x0\);)/\#if defined(\1)\2/s' | + perl -0777 -pe "s/\\#else(\\n\\s+return __builtin_popcount\\(x0\\);)/\\#elif !defined(MISSING_BUILTIN_POPCOUNT)\\1\\n#else$__builtin_popcount_replacement/s" ;; # Default: pass through. *)
_______________________________________________ openssh-unix-dev mailing list openssh-unix-dev@xxxxxxxxxxx https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev