1*9469f4f1Schristos /* $NetBSD: sntrup761.c,v 1.4 2024/09/24 21:32:18 christos Exp $ */ 2*9469f4f1Schristos /* $OpenBSD: sntrup761.c,v 1.8 2024/09/16 05:37:05 djm Exp $ */ 3cffc2a7aSchristos 4cffc2a7aSchristos /* 5cffc2a7aSchristos * Public Domain, Authors: 6cffc2a7aSchristos * - Daniel J. Bernstein 7cffc2a7aSchristos * - Chitchanok Chuengsatiansup 8cffc2a7aSchristos * - Tanja Lange 9cffc2a7aSchristos * - Christine van Vredendaal 10cffc2a7aSchristos */ 11d95a8471Schristos #include "includes.h" 12*9469f4f1Schristos __RCSID("$NetBSD: sntrup761.c,v 1.4 2024/09/24 21:32:18 christos Exp $"); 13cffc2a7aSchristos 14cffc2a7aSchristos #include <string.h> 15cffc2a7aSchristos #include "crypto_api.h" 16cffc2a7aSchristos 17*9469f4f1Schristos #define crypto_declassify(x, y) do {} while (0) 18*9469f4f1Schristos 19cffc2a7aSchristos #define int8 crypto_int8 20cffc2a7aSchristos #define uint8 crypto_uint8 21cffc2a7aSchristos #define int16 crypto_int16 22cffc2a7aSchristos #define uint16 crypto_uint16 23cffc2a7aSchristos #define int32 crypto_int32 24cffc2a7aSchristos #define uint32 crypto_uint32 25cffc2a7aSchristos #define int64 crypto_int64 26cffc2a7aSchristos #define uint64 crypto_uint64 27*9469f4f1Schristos extern volatile crypto_int16 crypto_int16_optblocker; 28*9469f4f1Schristos extern volatile crypto_int32 crypto_int32_optblocker; 29*9469f4f1Schristos extern volatile crypto_int64 crypto_int64_optblocker; 30cffc2a7aSchristos 31*9469f4f1Schristos /* from supercop-20240808/cryptoint/crypto_int16.h */ 32*9469f4f1Schristos /* auto-generated: cd cryptoint; ./autogen */ 33*9469f4f1Schristos /* cryptoint 20240806 */ 34cffc2a7aSchristos 35*9469f4f1Schristos #ifndef crypto_int16_h 36*9469f4f1Schristos #define crypto_int16_h 37cffc2a7aSchristos 38*9469f4f1Schristos #define crypto_int16 int16_t 39*9469f4f1Schristos #define crypto_int16_unsigned uint16_t 40*9469f4f1Schristos 41*9469f4f1Schristos 42*9469f4f1Schristos 43*9469f4f1Schristos __attribute__((unused)) 44*9469f4f1Schristos static inline 45*9469f4f1Schristos crypto_int16 crypto_int16_load(const unsigned char *crypto_int16_s) { 46*9469f4f1Schristos crypto_int16 crypto_int16_z = 0; 47*9469f4f1Schristos crypto_int16_z |= ((crypto_int16) (*crypto_int16_s++)) << 0; 48*9469f4f1Schristos crypto_int16_z |= ((crypto_int16) (*crypto_int16_s++)) << 8; 49*9469f4f1Schristos return crypto_int16_z; 50*9469f4f1Schristos } 51*9469f4f1Schristos 52*9469f4f1Schristos __attribute__((unused)) 53*9469f4f1Schristos static inline 54*9469f4f1Schristos void crypto_int16_store(unsigned char *crypto_int16_s,crypto_int16 crypto_int16_x) { 55*9469f4f1Schristos *crypto_int16_s++ = crypto_int16_x >> 0; 56*9469f4f1Schristos *crypto_int16_s++ = crypto_int16_x >> 8; 57*9469f4f1Schristos } 58*9469f4f1Schristos 59*9469f4f1Schristos __attribute__((unused)) 60*9469f4f1Schristos static inline 61*9469f4f1Schristos crypto_int16 crypto_int16_negative_mask(crypto_int16 crypto_int16_x) { 62*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 63*9469f4f1Schristos __asm__ ("sarw $15,%0" : "+r"(crypto_int16_x) : : "cc"); 64*9469f4f1Schristos return crypto_int16_x; 65*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 66*9469f4f1Schristos crypto_int16 crypto_int16_y; 67*9469f4f1Schristos __asm__ ("sbfx %w0,%w1,15,1" : "=r"(crypto_int16_y) : "r"(crypto_int16_x) : ); 68*9469f4f1Schristos return crypto_int16_y; 69*9469f4f1Schristos #else 70*9469f4f1Schristos crypto_int16_x >>= 16-6; 71*9469f4f1Schristos crypto_int16_x ^= crypto_int16_optblocker; 72*9469f4f1Schristos crypto_int16_x >>= 5; 73*9469f4f1Schristos return crypto_int16_x; 74*9469f4f1Schristos #endif 75*9469f4f1Schristos } 76*9469f4f1Schristos 77*9469f4f1Schristos __attribute__((unused)) 78*9469f4f1Schristos static inline 79*9469f4f1Schristos crypto_int16_unsigned crypto_int16_unsigned_topbit_01(crypto_int16_unsigned crypto_int16_x) { 80*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 81*9469f4f1Schristos __asm__ ("shrw $15,%0" : "+r"(crypto_int16_x) : : "cc"); 82*9469f4f1Schristos return crypto_int16_x; 83*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 84*9469f4f1Schristos crypto_int16 crypto_int16_y; 85*9469f4f1Schristos __asm__ ("ubfx %w0,%w1,15,1" : "=r"(crypto_int16_y) : "r"(crypto_int16_x) : ); 86*9469f4f1Schristos return crypto_int16_y; 87*9469f4f1Schristos #else 88*9469f4f1Schristos crypto_int16_x >>= 16-6; 89*9469f4f1Schristos crypto_int16_x ^= crypto_int16_optblocker; 90*9469f4f1Schristos crypto_int16_x >>= 5; 91*9469f4f1Schristos return crypto_int16_x; 92*9469f4f1Schristos #endif 93*9469f4f1Schristos } 94*9469f4f1Schristos 95*9469f4f1Schristos __attribute__((unused)) 96*9469f4f1Schristos static inline 97*9469f4f1Schristos crypto_int16 crypto_int16_negative_01(crypto_int16 crypto_int16_x) { 98*9469f4f1Schristos return crypto_int16_unsigned_topbit_01(crypto_int16_x); 99*9469f4f1Schristos } 100*9469f4f1Schristos 101*9469f4f1Schristos __attribute__((unused)) 102*9469f4f1Schristos static inline 103*9469f4f1Schristos crypto_int16 crypto_int16_topbit_mask(crypto_int16 crypto_int16_x) { 104*9469f4f1Schristos return crypto_int16_negative_mask(crypto_int16_x); 105*9469f4f1Schristos } 106*9469f4f1Schristos 107*9469f4f1Schristos __attribute__((unused)) 108*9469f4f1Schristos static inline 109*9469f4f1Schristos crypto_int16 crypto_int16_topbit_01(crypto_int16 crypto_int16_x) { 110*9469f4f1Schristos return crypto_int16_unsigned_topbit_01(crypto_int16_x); 111*9469f4f1Schristos } 112*9469f4f1Schristos 113*9469f4f1Schristos __attribute__((unused)) 114*9469f4f1Schristos static inline 115*9469f4f1Schristos crypto_int16 crypto_int16_bottombit_mask(crypto_int16 crypto_int16_x) { 116*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 117*9469f4f1Schristos __asm__ ("andw $1,%0" : "+r"(crypto_int16_x) : : "cc"); 118*9469f4f1Schristos return -crypto_int16_x; 119*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 120*9469f4f1Schristos crypto_int16 crypto_int16_y; 121*9469f4f1Schristos __asm__ ("sbfx %w0,%w1,0,1" : "=r"(crypto_int16_y) : "r"(crypto_int16_x) : ); 122*9469f4f1Schristos return crypto_int16_y; 123*9469f4f1Schristos #else 124*9469f4f1Schristos crypto_int16_x &= 1 ^ crypto_int16_optblocker; 125*9469f4f1Schristos return -crypto_int16_x; 126*9469f4f1Schristos #endif 127*9469f4f1Schristos } 128*9469f4f1Schristos 129*9469f4f1Schristos __attribute__((unused)) 130*9469f4f1Schristos static inline 131*9469f4f1Schristos crypto_int16 crypto_int16_bottombit_01(crypto_int16 crypto_int16_x) { 132*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 133*9469f4f1Schristos __asm__ ("andw $1,%0" : "+r"(crypto_int16_x) : : "cc"); 134*9469f4f1Schristos return crypto_int16_x; 135*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 136*9469f4f1Schristos crypto_int16 crypto_int16_y; 137*9469f4f1Schristos __asm__ ("ubfx %w0,%w1,0,1" : "=r"(crypto_int16_y) : "r"(crypto_int16_x) : ); 138*9469f4f1Schristos return crypto_int16_y; 139*9469f4f1Schristos #else 140*9469f4f1Schristos crypto_int16_x &= 1 ^ crypto_int16_optblocker; 141*9469f4f1Schristos return crypto_int16_x; 142*9469f4f1Schristos #endif 143*9469f4f1Schristos } 144*9469f4f1Schristos 145*9469f4f1Schristos __attribute__((unused)) 146*9469f4f1Schristos static inline 147*9469f4f1Schristos crypto_int16 crypto_int16_bitinrangepublicpos_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_s) { 148*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 149*9469f4f1Schristos __asm__ ("sarw %%cl,%0" : "+r"(crypto_int16_x) : "c"(crypto_int16_s) : "cc"); 150*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 151*9469f4f1Schristos __asm__ ("sxth %w0,%w0\n asr %w0,%w0,%w1" : "+&r"(crypto_int16_x) : "r"(crypto_int16_s) : ); 152*9469f4f1Schristos #else 153*9469f4f1Schristos crypto_int16_x >>= crypto_int16_s ^ crypto_int16_optblocker; 154*9469f4f1Schristos #endif 155*9469f4f1Schristos return crypto_int16_bottombit_mask(crypto_int16_x); 156*9469f4f1Schristos } 157*9469f4f1Schristos 158*9469f4f1Schristos __attribute__((unused)) 159*9469f4f1Schristos static inline 160*9469f4f1Schristos crypto_int16 crypto_int16_bitinrangepublicpos_01(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_s) { 161*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 162*9469f4f1Schristos __asm__ ("sarw %%cl,%0" : "+r"(crypto_int16_x) : "c"(crypto_int16_s) : "cc"); 163*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 164*9469f4f1Schristos __asm__ ("sxth %w0,%w0\n asr %w0,%w0,%w1" : "+&r"(crypto_int16_x) : "r"(crypto_int16_s) : ); 165*9469f4f1Schristos #else 166*9469f4f1Schristos crypto_int16_x >>= crypto_int16_s ^ crypto_int16_optblocker; 167*9469f4f1Schristos #endif 168*9469f4f1Schristos return crypto_int16_bottombit_01(crypto_int16_x); 169*9469f4f1Schristos } 170*9469f4f1Schristos 171*9469f4f1Schristos __attribute__((unused)) 172*9469f4f1Schristos static inline 173*9469f4f1Schristos crypto_int16 crypto_int16_shlmod(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_s) { 174*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 175*9469f4f1Schristos crypto_int16_s &= 15; 176*9469f4f1Schristos __asm__ ("shlw %%cl,%0" : "+r"(crypto_int16_x) : "c"(crypto_int16_s) : "cc"); 177*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 178*9469f4f1Schristos __asm__ ("and %w0,%w0,15\n and %w1,%w1,65535\n lsl %w1,%w1,%w0" : "+&r"(crypto_int16_s), "+r"(crypto_int16_x) : : ); 179*9469f4f1Schristos #else 180*9469f4f1Schristos int crypto_int16_k, crypto_int16_l; 181*9469f4f1Schristos for (crypto_int16_l = 0,crypto_int16_k = 1;crypto_int16_k < 16;++crypto_int16_l,crypto_int16_k *= 2) 182*9469f4f1Schristos crypto_int16_x ^= (crypto_int16_x ^ (crypto_int16_x << crypto_int16_k)) & crypto_int16_bitinrangepublicpos_mask(crypto_int16_s,crypto_int16_l); 183*9469f4f1Schristos #endif 184*9469f4f1Schristos return crypto_int16_x; 185*9469f4f1Schristos } 186*9469f4f1Schristos 187*9469f4f1Schristos __attribute__((unused)) 188*9469f4f1Schristos static inline 189*9469f4f1Schristos crypto_int16 crypto_int16_shrmod(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_s) { 190*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 191*9469f4f1Schristos crypto_int16_s &= 15; 192*9469f4f1Schristos __asm__ ("sarw %%cl,%0" : "+r"(crypto_int16_x) : "c"(crypto_int16_s) : "cc"); 193*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 194*9469f4f1Schristos __asm__ ("and %w0,%w0,15\n sxth %w1,%w1\n asr %w1,%w1,%w0" : "+&r"(crypto_int16_s), "+r"(crypto_int16_x) : : ); 195*9469f4f1Schristos #else 196*9469f4f1Schristos int crypto_int16_k, crypto_int16_l; 197*9469f4f1Schristos for (crypto_int16_l = 0,crypto_int16_k = 1;crypto_int16_k < 16;++crypto_int16_l,crypto_int16_k *= 2) 198*9469f4f1Schristos crypto_int16_x ^= (crypto_int16_x ^ (crypto_int16_x >> crypto_int16_k)) & crypto_int16_bitinrangepublicpos_mask(crypto_int16_s,crypto_int16_l); 199*9469f4f1Schristos #endif 200*9469f4f1Schristos return crypto_int16_x; 201*9469f4f1Schristos } 202*9469f4f1Schristos 203*9469f4f1Schristos __attribute__((unused)) 204*9469f4f1Schristos static inline 205*9469f4f1Schristos crypto_int16 crypto_int16_bitmod_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_s) { 206*9469f4f1Schristos crypto_int16_x = crypto_int16_shrmod(crypto_int16_x,crypto_int16_s); 207*9469f4f1Schristos return crypto_int16_bottombit_mask(crypto_int16_x); 208*9469f4f1Schristos } 209*9469f4f1Schristos 210*9469f4f1Schristos __attribute__((unused)) 211*9469f4f1Schristos static inline 212*9469f4f1Schristos crypto_int16 crypto_int16_bitmod_01(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_s) { 213*9469f4f1Schristos crypto_int16_x = crypto_int16_shrmod(crypto_int16_x,crypto_int16_s); 214*9469f4f1Schristos return crypto_int16_bottombit_01(crypto_int16_x); 215*9469f4f1Schristos } 216*9469f4f1Schristos 217*9469f4f1Schristos __attribute__((unused)) 218*9469f4f1Schristos static inline 219*9469f4f1Schristos crypto_int16 crypto_int16_nonzero_mask(crypto_int16 crypto_int16_x) { 220*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 221*9469f4f1Schristos crypto_int16 crypto_int16_q,crypto_int16_z; 222*9469f4f1Schristos __asm__ ("xorw %0,%0\n movw $-1,%1\n testw %2,%2\n cmovnew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x) : "cc"); 223*9469f4f1Schristos return crypto_int16_z; 224*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 225*9469f4f1Schristos crypto_int16 crypto_int16_z; 226*9469f4f1Schristos __asm__ ("tst %w1,65535\n csetm %w0,ne" : "=r"(crypto_int16_z) : "r"(crypto_int16_x) : "cc"); 227*9469f4f1Schristos return crypto_int16_z; 228*9469f4f1Schristos #else 229*9469f4f1Schristos crypto_int16_x |= -crypto_int16_x; 230*9469f4f1Schristos return crypto_int16_negative_mask(crypto_int16_x); 231*9469f4f1Schristos #endif 232*9469f4f1Schristos } 233*9469f4f1Schristos 234*9469f4f1Schristos __attribute__((unused)) 235*9469f4f1Schristos static inline 236*9469f4f1Schristos crypto_int16 crypto_int16_nonzero_01(crypto_int16 crypto_int16_x) { 237*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 238*9469f4f1Schristos crypto_int16 crypto_int16_q,crypto_int16_z; 239*9469f4f1Schristos __asm__ ("xorw %0,%0\n movw $1,%1\n testw %2,%2\n cmovnew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x) : "cc"); 240*9469f4f1Schristos return crypto_int16_z; 241*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 242*9469f4f1Schristos crypto_int16 crypto_int16_z; 243*9469f4f1Schristos __asm__ ("tst %w1,65535\n cset %w0,ne" : "=r"(crypto_int16_z) : "r"(crypto_int16_x) : "cc"); 244*9469f4f1Schristos return crypto_int16_z; 245*9469f4f1Schristos #else 246*9469f4f1Schristos crypto_int16_x |= -crypto_int16_x; 247*9469f4f1Schristos return crypto_int16_unsigned_topbit_01(crypto_int16_x); 248*9469f4f1Schristos #endif 249*9469f4f1Schristos } 250*9469f4f1Schristos 251*9469f4f1Schristos __attribute__((unused)) 252*9469f4f1Schristos static inline 253*9469f4f1Schristos crypto_int16 crypto_int16_positive_mask(crypto_int16 crypto_int16_x) { 254*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 255*9469f4f1Schristos crypto_int16 crypto_int16_q,crypto_int16_z; 256*9469f4f1Schristos __asm__ ("xorw %0,%0\n movw $-1,%1\n testw %2,%2\n cmovgw %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x) : "cc"); 257*9469f4f1Schristos return crypto_int16_z; 258*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 259*9469f4f1Schristos crypto_int16 crypto_int16_z; 260*9469f4f1Schristos __asm__ ("sxth %w0,%w1\n cmp %w0,0\n csetm %w0,gt" : "=r"(crypto_int16_z) : "r"(crypto_int16_x) : "cc"); 261*9469f4f1Schristos return crypto_int16_z; 262*9469f4f1Schristos #else 263*9469f4f1Schristos crypto_int16 crypto_int16_z = -crypto_int16_x; 264*9469f4f1Schristos crypto_int16_z ^= crypto_int16_x & crypto_int16_z; 265*9469f4f1Schristos return crypto_int16_negative_mask(crypto_int16_z); 266*9469f4f1Schristos #endif 267*9469f4f1Schristos } 268*9469f4f1Schristos 269*9469f4f1Schristos __attribute__((unused)) 270*9469f4f1Schristos static inline 271*9469f4f1Schristos crypto_int16 crypto_int16_positive_01(crypto_int16 crypto_int16_x) { 272*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 273*9469f4f1Schristos crypto_int16 crypto_int16_q,crypto_int16_z; 274*9469f4f1Schristos __asm__ ("xorw %0,%0\n movw $1,%1\n testw %2,%2\n cmovgw %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x) : "cc"); 275*9469f4f1Schristos return crypto_int16_z; 276*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 277*9469f4f1Schristos crypto_int16 crypto_int16_z; 278*9469f4f1Schristos __asm__ ("sxth %w0,%w1\n cmp %w0,0\n cset %w0,gt" : "=r"(crypto_int16_z) : "r"(crypto_int16_x) : "cc"); 279*9469f4f1Schristos return crypto_int16_z; 280*9469f4f1Schristos #else 281*9469f4f1Schristos crypto_int16 crypto_int16_z = -crypto_int16_x; 282*9469f4f1Schristos crypto_int16_z ^= crypto_int16_x & crypto_int16_z; 283*9469f4f1Schristos return crypto_int16_unsigned_topbit_01(crypto_int16_z); 284*9469f4f1Schristos #endif 285*9469f4f1Schristos } 286*9469f4f1Schristos 287*9469f4f1Schristos __attribute__((unused)) 288*9469f4f1Schristos static inline 289*9469f4f1Schristos crypto_int16 crypto_int16_zero_mask(crypto_int16 crypto_int16_x) { 290*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 291*9469f4f1Schristos crypto_int16 crypto_int16_q,crypto_int16_z; 292*9469f4f1Schristos __asm__ ("xorw %0,%0\n movw $-1,%1\n testw %2,%2\n cmovew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x) : "cc"); 293*9469f4f1Schristos return crypto_int16_z; 294*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 295*9469f4f1Schristos crypto_int16 crypto_int16_z; 296*9469f4f1Schristos __asm__ ("tst %w1,65535\n csetm %w0,eq" : "=r"(crypto_int16_z) : "r"(crypto_int16_x) : "cc"); 297*9469f4f1Schristos return crypto_int16_z; 298*9469f4f1Schristos #else 299*9469f4f1Schristos return ~crypto_int16_nonzero_mask(crypto_int16_x); 300*9469f4f1Schristos #endif 301*9469f4f1Schristos } 302*9469f4f1Schristos 303*9469f4f1Schristos __attribute__((unused)) 304*9469f4f1Schristos static inline 305*9469f4f1Schristos crypto_int16 crypto_int16_zero_01(crypto_int16 crypto_int16_x) { 306*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 307*9469f4f1Schristos crypto_int16 crypto_int16_q,crypto_int16_z; 308*9469f4f1Schristos __asm__ ("xorw %0,%0\n movw $1,%1\n testw %2,%2\n cmovew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x) : "cc"); 309*9469f4f1Schristos return crypto_int16_z; 310*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 311*9469f4f1Schristos crypto_int16 crypto_int16_z; 312*9469f4f1Schristos __asm__ ("tst %w1,65535\n cset %w0,eq" : "=r"(crypto_int16_z) : "r"(crypto_int16_x) : "cc"); 313*9469f4f1Schristos return crypto_int16_z; 314*9469f4f1Schristos #else 315*9469f4f1Schristos return 1-crypto_int16_nonzero_01(crypto_int16_x); 316*9469f4f1Schristos #endif 317*9469f4f1Schristos } 318*9469f4f1Schristos 319*9469f4f1Schristos __attribute__((unused)) 320*9469f4f1Schristos static inline 321*9469f4f1Schristos crypto_int16 crypto_int16_unequal_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { 322*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 323*9469f4f1Schristos crypto_int16 crypto_int16_q,crypto_int16_z; 324*9469f4f1Schristos __asm__ ("xorw %0,%0\n movw $-1,%1\n cmpw %3,%2\n cmovnew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 325*9469f4f1Schristos return crypto_int16_z; 326*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 327*9469f4f1Schristos crypto_int16 crypto_int16_z; 328*9469f4f1Schristos __asm__ ("and %w0,%w1,65535\n cmp %w0,%w2,uxth\n csetm %w0,ne" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 329*9469f4f1Schristos return crypto_int16_z; 330*9469f4f1Schristos #else 331*9469f4f1Schristos return crypto_int16_nonzero_mask(crypto_int16_x ^ crypto_int16_y); 332*9469f4f1Schristos #endif 333*9469f4f1Schristos } 334*9469f4f1Schristos 335*9469f4f1Schristos __attribute__((unused)) 336*9469f4f1Schristos static inline 337*9469f4f1Schristos crypto_int16 crypto_int16_unequal_01(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { 338*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 339*9469f4f1Schristos crypto_int16 crypto_int16_q,crypto_int16_z; 340*9469f4f1Schristos __asm__ ("xorw %0,%0\n movw $1,%1\n cmpw %3,%2\n cmovnew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 341*9469f4f1Schristos return crypto_int16_z; 342*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 343*9469f4f1Schristos crypto_int16 crypto_int16_z; 344*9469f4f1Schristos __asm__ ("and %w0,%w1,65535\n cmp %w0,%w2,uxth\n cset %w0,ne" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 345*9469f4f1Schristos return crypto_int16_z; 346*9469f4f1Schristos #else 347*9469f4f1Schristos return crypto_int16_nonzero_01(crypto_int16_x ^ crypto_int16_y); 348*9469f4f1Schristos #endif 349*9469f4f1Schristos } 350*9469f4f1Schristos 351*9469f4f1Schristos __attribute__((unused)) 352*9469f4f1Schristos static inline 353*9469f4f1Schristos crypto_int16 crypto_int16_equal_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { 354*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 355*9469f4f1Schristos crypto_int16 crypto_int16_q,crypto_int16_z; 356*9469f4f1Schristos __asm__ ("xorw %0,%0\n movw $-1,%1\n cmpw %3,%2\n cmovew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 357*9469f4f1Schristos return crypto_int16_z; 358*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 359*9469f4f1Schristos crypto_int16 crypto_int16_z; 360*9469f4f1Schristos __asm__ ("and %w0,%w1,65535\n cmp %w0,%w2,uxth\n csetm %w0,eq" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 361*9469f4f1Schristos return crypto_int16_z; 362*9469f4f1Schristos #else 363*9469f4f1Schristos return ~crypto_int16_unequal_mask(crypto_int16_x,crypto_int16_y); 364*9469f4f1Schristos #endif 365*9469f4f1Schristos } 366*9469f4f1Schristos 367*9469f4f1Schristos __attribute__((unused)) 368*9469f4f1Schristos static inline 369*9469f4f1Schristos crypto_int16 crypto_int16_equal_01(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { 370*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 371*9469f4f1Schristos crypto_int16 crypto_int16_q,crypto_int16_z; 372*9469f4f1Schristos __asm__ ("xorw %0,%0\n movw $1,%1\n cmpw %3,%2\n cmovew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 373*9469f4f1Schristos return crypto_int16_z; 374*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 375*9469f4f1Schristos crypto_int16 crypto_int16_z; 376*9469f4f1Schristos __asm__ ("and %w0,%w1,65535\n cmp %w0,%w2,uxth\n cset %w0,eq" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 377*9469f4f1Schristos return crypto_int16_z; 378*9469f4f1Schristos #else 379*9469f4f1Schristos return 1-crypto_int16_unequal_01(crypto_int16_x,crypto_int16_y); 380*9469f4f1Schristos #endif 381*9469f4f1Schristos } 382*9469f4f1Schristos 383*9469f4f1Schristos __attribute__((unused)) 384*9469f4f1Schristos static inline 385*9469f4f1Schristos crypto_int16 crypto_int16_min(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { 386*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 387*9469f4f1Schristos __asm__ ("cmpw %1,%0\n cmovgw %1,%0" : "+r"(crypto_int16_x) : "r"(crypto_int16_y) : "cc"); 388*9469f4f1Schristos return crypto_int16_x; 389*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 390*9469f4f1Schristos __asm__ ("sxth %w0,%w0\n cmp %w0,%w1,sxth\n csel %w0,%w0,%w1,lt" : "+&r"(crypto_int16_x) : "r"(crypto_int16_y) : "cc"); 391*9469f4f1Schristos return crypto_int16_x; 392*9469f4f1Schristos #else 393*9469f4f1Schristos crypto_int16 crypto_int16_r = crypto_int16_y ^ crypto_int16_x; 394*9469f4f1Schristos crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x; 395*9469f4f1Schristos crypto_int16_z ^= crypto_int16_r & (crypto_int16_z ^ crypto_int16_y); 396*9469f4f1Schristos crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z); 397*9469f4f1Schristos crypto_int16_z &= crypto_int16_r; 398*9469f4f1Schristos return crypto_int16_x ^ crypto_int16_z; 399*9469f4f1Schristos #endif 400*9469f4f1Schristos } 401*9469f4f1Schristos 402*9469f4f1Schristos __attribute__((unused)) 403*9469f4f1Schristos static inline 404*9469f4f1Schristos crypto_int16 crypto_int16_max(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { 405*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 406*9469f4f1Schristos __asm__ ("cmpw %1,%0\n cmovlw %1,%0" : "+r"(crypto_int16_x) : "r"(crypto_int16_y) : "cc"); 407*9469f4f1Schristos return crypto_int16_x; 408*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 409*9469f4f1Schristos __asm__ ("sxth %w0,%w0\n cmp %w0,%w1,sxth\n csel %w0,%w1,%w0,lt" : "+&r"(crypto_int16_x) : "r"(crypto_int16_y) : "cc"); 410*9469f4f1Schristos return crypto_int16_x; 411*9469f4f1Schristos #else 412*9469f4f1Schristos crypto_int16 crypto_int16_r = crypto_int16_y ^ crypto_int16_x; 413*9469f4f1Schristos crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x; 414*9469f4f1Schristos crypto_int16_z ^= crypto_int16_r & (crypto_int16_z ^ crypto_int16_y); 415*9469f4f1Schristos crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z); 416*9469f4f1Schristos crypto_int16_z &= crypto_int16_r; 417*9469f4f1Schristos return crypto_int16_y ^ crypto_int16_z; 418*9469f4f1Schristos #endif 419*9469f4f1Schristos } 420*9469f4f1Schristos 421*9469f4f1Schristos __attribute__((unused)) 422*9469f4f1Schristos static inline 423*9469f4f1Schristos void crypto_int16_minmax(crypto_int16 *crypto_int16_p,crypto_int16 *crypto_int16_q) { 424*9469f4f1Schristos crypto_int16 crypto_int16_x = *crypto_int16_p; 425*9469f4f1Schristos crypto_int16 crypto_int16_y = *crypto_int16_q; 426*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 427*9469f4f1Schristos crypto_int16 crypto_int16_z; 428*9469f4f1Schristos __asm__ ("cmpw %2,%1\n movw %1,%0\n cmovgw %2,%1\n cmovgw %0,%2" : "=&r"(crypto_int16_z), "+&r"(crypto_int16_x), "+r"(crypto_int16_y) : : "cc"); 429*9469f4f1Schristos *crypto_int16_p = crypto_int16_x; 430*9469f4f1Schristos *crypto_int16_q = crypto_int16_y; 431*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 432*9469f4f1Schristos crypto_int16 crypto_int16_r, crypto_int16_s; 433*9469f4f1Schristos __asm__ ("sxth %w0,%w0\n cmp %w0,%w3,sxth\n csel %w1,%w0,%w3,lt\n csel %w2,%w3,%w0,lt" : "+&r"(crypto_int16_x), "=&r"(crypto_int16_r), "=r"(crypto_int16_s) : "r"(crypto_int16_y) : "cc"); 434*9469f4f1Schristos *crypto_int16_p = crypto_int16_r; 435*9469f4f1Schristos *crypto_int16_q = crypto_int16_s; 436*9469f4f1Schristos #else 437*9469f4f1Schristos crypto_int16 crypto_int16_r = crypto_int16_y ^ crypto_int16_x; 438*9469f4f1Schristos crypto_int16 crypto_int16_z = crypto_int16_y - crypto_int16_x; 439*9469f4f1Schristos crypto_int16_z ^= crypto_int16_r & (crypto_int16_z ^ crypto_int16_y); 440*9469f4f1Schristos crypto_int16_z = crypto_int16_negative_mask(crypto_int16_z); 441*9469f4f1Schristos crypto_int16_z &= crypto_int16_r; 442*9469f4f1Schristos crypto_int16_x ^= crypto_int16_z; 443*9469f4f1Schristos crypto_int16_y ^= crypto_int16_z; 444*9469f4f1Schristos *crypto_int16_p = crypto_int16_x; 445*9469f4f1Schristos *crypto_int16_q = crypto_int16_y; 446*9469f4f1Schristos #endif 447*9469f4f1Schristos } 448*9469f4f1Schristos 449*9469f4f1Schristos __attribute__((unused)) 450*9469f4f1Schristos static inline 451*9469f4f1Schristos crypto_int16 crypto_int16_smaller_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { 452*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 453*9469f4f1Schristos crypto_int16 crypto_int16_q,crypto_int16_z; 454*9469f4f1Schristos __asm__ ("xorw %0,%0\n movw $-1,%1\n cmpw %3,%2\n cmovlw %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 455*9469f4f1Schristos return crypto_int16_z; 456*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 457*9469f4f1Schristos crypto_int16 crypto_int16_z; 458*9469f4f1Schristos __asm__ ("sxth %w0,%w1\n cmp %w0,%w2,sxth\n csetm %w0,lt" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 459*9469f4f1Schristos return crypto_int16_z; 460*9469f4f1Schristos #else 461*9469f4f1Schristos crypto_int16 crypto_int16_r = crypto_int16_x ^ crypto_int16_y; 462*9469f4f1Schristos crypto_int16 crypto_int16_z = crypto_int16_x - crypto_int16_y; 463*9469f4f1Schristos crypto_int16_z ^= crypto_int16_r & (crypto_int16_z ^ crypto_int16_x); 464*9469f4f1Schristos return crypto_int16_negative_mask(crypto_int16_z); 465*9469f4f1Schristos #endif 466*9469f4f1Schristos } 467*9469f4f1Schristos 468*9469f4f1Schristos __attribute__((unused)) 469*9469f4f1Schristos static inline 470*9469f4f1Schristos crypto_int16 crypto_int16_smaller_01(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { 471*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 472*9469f4f1Schristos crypto_int16 crypto_int16_q,crypto_int16_z; 473*9469f4f1Schristos __asm__ ("xorw %0,%0\n movw $1,%1\n cmpw %3,%2\n cmovlw %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 474*9469f4f1Schristos return crypto_int16_z; 475*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 476*9469f4f1Schristos crypto_int16 crypto_int16_z; 477*9469f4f1Schristos __asm__ ("sxth %w0,%w1\n cmp %w0,%w2,sxth\n cset %w0,lt" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 478*9469f4f1Schristos return crypto_int16_z; 479*9469f4f1Schristos #else 480*9469f4f1Schristos crypto_int16 crypto_int16_r = crypto_int16_x ^ crypto_int16_y; 481*9469f4f1Schristos crypto_int16 crypto_int16_z = crypto_int16_x - crypto_int16_y; 482*9469f4f1Schristos crypto_int16_z ^= crypto_int16_r & (crypto_int16_z ^ crypto_int16_x); 483*9469f4f1Schristos return crypto_int16_unsigned_topbit_01(crypto_int16_z); 484*9469f4f1Schristos #endif 485*9469f4f1Schristos } 486*9469f4f1Schristos 487*9469f4f1Schristos __attribute__((unused)) 488*9469f4f1Schristos static inline 489*9469f4f1Schristos crypto_int16 crypto_int16_leq_mask(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { 490*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 491*9469f4f1Schristos crypto_int16 crypto_int16_q,crypto_int16_z; 492*9469f4f1Schristos __asm__ ("xorw %0,%0\n movw $-1,%1\n cmpw %3,%2\n cmovlew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 493*9469f4f1Schristos return crypto_int16_z; 494*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 495*9469f4f1Schristos crypto_int16 crypto_int16_z; 496*9469f4f1Schristos __asm__ ("sxth %w0,%w1\n cmp %w0,%w2,sxth\n csetm %w0,le" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 497*9469f4f1Schristos return crypto_int16_z; 498*9469f4f1Schristos #else 499*9469f4f1Schristos return ~crypto_int16_smaller_mask(crypto_int16_y,crypto_int16_x); 500*9469f4f1Schristos #endif 501*9469f4f1Schristos } 502*9469f4f1Schristos 503*9469f4f1Schristos __attribute__((unused)) 504*9469f4f1Schristos static inline 505*9469f4f1Schristos crypto_int16 crypto_int16_leq_01(crypto_int16 crypto_int16_x,crypto_int16 crypto_int16_y) { 506*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 507*9469f4f1Schristos crypto_int16 crypto_int16_q,crypto_int16_z; 508*9469f4f1Schristos __asm__ ("xorw %0,%0\n movw $1,%1\n cmpw %3,%2\n cmovlew %1,%0" : "=&r"(crypto_int16_z), "=&r"(crypto_int16_q) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 509*9469f4f1Schristos return crypto_int16_z; 510*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 511*9469f4f1Schristos crypto_int16 crypto_int16_z; 512*9469f4f1Schristos __asm__ ("sxth %w0,%w1\n cmp %w0,%w2,sxth\n cset %w0,le" : "=&r"(crypto_int16_z) : "r"(crypto_int16_x), "r"(crypto_int16_y) : "cc"); 513*9469f4f1Schristos return crypto_int16_z; 514*9469f4f1Schristos #else 515*9469f4f1Schristos return 1-crypto_int16_smaller_01(crypto_int16_y,crypto_int16_x); 516*9469f4f1Schristos #endif 517*9469f4f1Schristos } 518*9469f4f1Schristos 519*9469f4f1Schristos __attribute__((unused)) 520*9469f4f1Schristos static inline 521*9469f4f1Schristos int crypto_int16_ones_num(crypto_int16 crypto_int16_x) { 522*9469f4f1Schristos crypto_int16_unsigned crypto_int16_y = crypto_int16_x; 523*9469f4f1Schristos const crypto_int16 C0 = 0x5555; 524*9469f4f1Schristos const crypto_int16 C1 = 0x3333; 525*9469f4f1Schristos const crypto_int16 C2 = 0x0f0f; 526*9469f4f1Schristos crypto_int16_y -= ((crypto_int16_y >> 1) & C0); 527*9469f4f1Schristos crypto_int16_y = (crypto_int16_y & C1) + ((crypto_int16_y >> 2) & C1); 528*9469f4f1Schristos crypto_int16_y = (crypto_int16_y + (crypto_int16_y >> 4)) & C2; 529*9469f4f1Schristos crypto_int16_y = (crypto_int16_y + (crypto_int16_y >> 8)) & 0xff; 530*9469f4f1Schristos return crypto_int16_y; 531*9469f4f1Schristos } 532*9469f4f1Schristos 533*9469f4f1Schristos __attribute__((unused)) 534*9469f4f1Schristos static inline 535*9469f4f1Schristos int crypto_int16_bottomzeros_num(crypto_int16 crypto_int16_x) { 536*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 537*9469f4f1Schristos crypto_int16 fallback = 16; 538*9469f4f1Schristos __asm__ ("bsfw %0,%0\n cmovew %1,%0" : "+&r"(crypto_int16_x) : "r"(fallback) : "cc"); 539*9469f4f1Schristos return crypto_int16_x; 540*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 541*9469f4f1Schristos int64_t crypto_int16_y; 542*9469f4f1Schristos __asm__ ("orr %w0,%w1,-65536\n rbit %w0,%w0\n clz %w0,%w0" : "=r"(crypto_int16_y) : "r"(crypto_int16_x) : ); 543*9469f4f1Schristos return crypto_int16_y; 544*9469f4f1Schristos #else 545*9469f4f1Schristos crypto_int16 crypto_int16_y = crypto_int16_x ^ (crypto_int16_x-1); 546*9469f4f1Schristos crypto_int16_y = ((crypto_int16) crypto_int16_y) >> 1; 547*9469f4f1Schristos crypto_int16_y &= ~(crypto_int16_x & (((crypto_int16) 1) << (16-1))); 548*9469f4f1Schristos return crypto_int16_ones_num(crypto_int16_y); 549*9469f4f1Schristos #endif 550*9469f4f1Schristos } 551*9469f4f1Schristos 552*9469f4f1Schristos #endif 553*9469f4f1Schristos 554*9469f4f1Schristos /* from supercop-20240808/cryptoint/crypto_int32.h */ 555*9469f4f1Schristos /* auto-generated: cd cryptoint; ./autogen */ 556*9469f4f1Schristos /* cryptoint 20240806 */ 557*9469f4f1Schristos 558*9469f4f1Schristos #ifndef crypto_int32_h 559*9469f4f1Schristos #define crypto_int32_h 560*9469f4f1Schristos 561*9469f4f1Schristos #define crypto_int32 int32_t 562*9469f4f1Schristos #define crypto_int32_unsigned uint32_t 563*9469f4f1Schristos 564*9469f4f1Schristos 565*9469f4f1Schristos 566*9469f4f1Schristos __attribute__((unused)) 567*9469f4f1Schristos static inline 568*9469f4f1Schristos crypto_int32 crypto_int32_load(const unsigned char *crypto_int32_s) { 569*9469f4f1Schristos crypto_int32 crypto_int32_z = 0; 570*9469f4f1Schristos crypto_int32_z |= ((crypto_int32) (*crypto_int32_s++)) << 0; 571*9469f4f1Schristos crypto_int32_z |= ((crypto_int32) (*crypto_int32_s++)) << 8; 572*9469f4f1Schristos crypto_int32_z |= ((crypto_int32) (*crypto_int32_s++)) << 16; 573*9469f4f1Schristos crypto_int32_z |= ((crypto_int32) (*crypto_int32_s++)) << 24; 574*9469f4f1Schristos return crypto_int32_z; 575*9469f4f1Schristos } 576*9469f4f1Schristos 577*9469f4f1Schristos __attribute__((unused)) 578*9469f4f1Schristos static inline 579*9469f4f1Schristos void crypto_int32_store(unsigned char *crypto_int32_s,crypto_int32 crypto_int32_x) { 580*9469f4f1Schristos *crypto_int32_s++ = crypto_int32_x >> 0; 581*9469f4f1Schristos *crypto_int32_s++ = crypto_int32_x >> 8; 582*9469f4f1Schristos *crypto_int32_s++ = crypto_int32_x >> 16; 583*9469f4f1Schristos *crypto_int32_s++ = crypto_int32_x >> 24; 584*9469f4f1Schristos } 585*9469f4f1Schristos 586*9469f4f1Schristos __attribute__((unused)) 587*9469f4f1Schristos static inline 588*9469f4f1Schristos crypto_int32 crypto_int32_negative_mask(crypto_int32 crypto_int32_x) { 589*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 590*9469f4f1Schristos __asm__ ("sarl $31,%0" : "+r"(crypto_int32_x) : : "cc"); 591*9469f4f1Schristos return crypto_int32_x; 592*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 593*9469f4f1Schristos crypto_int32 crypto_int32_y; 594*9469f4f1Schristos __asm__ ("asr %w0,%w1,31" : "=r"(crypto_int32_y) : "r"(crypto_int32_x) : ); 595*9469f4f1Schristos return crypto_int32_y; 596*9469f4f1Schristos #else 597*9469f4f1Schristos crypto_int32_x >>= 32-6; 598*9469f4f1Schristos crypto_int32_x ^= crypto_int32_optblocker; 599*9469f4f1Schristos crypto_int32_x >>= 5; 600*9469f4f1Schristos return crypto_int32_x; 601*9469f4f1Schristos #endif 602*9469f4f1Schristos } 603*9469f4f1Schristos 604*9469f4f1Schristos __attribute__((unused)) 605*9469f4f1Schristos static inline 606*9469f4f1Schristos crypto_int32_unsigned crypto_int32_unsigned_topbit_01(crypto_int32_unsigned crypto_int32_x) { 607*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 608*9469f4f1Schristos __asm__ ("shrl $31,%0" : "+r"(crypto_int32_x) : : "cc"); 609*9469f4f1Schristos return crypto_int32_x; 610*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 611*9469f4f1Schristos crypto_int32 crypto_int32_y; 612*9469f4f1Schristos __asm__ ("lsr %w0,%w1,31" : "=r"(crypto_int32_y) : "r"(crypto_int32_x) : ); 613*9469f4f1Schristos return crypto_int32_y; 614*9469f4f1Schristos #else 615*9469f4f1Schristos crypto_int32_x >>= 32-6; 616*9469f4f1Schristos crypto_int32_x ^= crypto_int32_optblocker; 617*9469f4f1Schristos crypto_int32_x >>= 5; 618*9469f4f1Schristos return crypto_int32_x; 619*9469f4f1Schristos #endif 620*9469f4f1Schristos } 621*9469f4f1Schristos 622*9469f4f1Schristos __attribute__((unused)) 623*9469f4f1Schristos static inline 624*9469f4f1Schristos crypto_int32 crypto_int32_negative_01(crypto_int32 crypto_int32_x) { 625*9469f4f1Schristos return crypto_int32_unsigned_topbit_01(crypto_int32_x); 626*9469f4f1Schristos } 627*9469f4f1Schristos 628*9469f4f1Schristos __attribute__((unused)) 629*9469f4f1Schristos static inline 630*9469f4f1Schristos crypto_int32 crypto_int32_topbit_mask(crypto_int32 crypto_int32_x) { 631*9469f4f1Schristos return crypto_int32_negative_mask(crypto_int32_x); 632*9469f4f1Schristos } 633*9469f4f1Schristos 634*9469f4f1Schristos __attribute__((unused)) 635*9469f4f1Schristos static inline 636*9469f4f1Schristos crypto_int32 crypto_int32_topbit_01(crypto_int32 crypto_int32_x) { 637*9469f4f1Schristos return crypto_int32_unsigned_topbit_01(crypto_int32_x); 638*9469f4f1Schristos } 639*9469f4f1Schristos 640*9469f4f1Schristos __attribute__((unused)) 641*9469f4f1Schristos static inline 642*9469f4f1Schristos crypto_int32 crypto_int32_bottombit_mask(crypto_int32 crypto_int32_x) { 643*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 644*9469f4f1Schristos __asm__ ("andl $1,%0" : "+r"(crypto_int32_x) : : "cc"); 645*9469f4f1Schristos return -crypto_int32_x; 646*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 647*9469f4f1Schristos crypto_int32 crypto_int32_y; 648*9469f4f1Schristos __asm__ ("sbfx %w0,%w1,0,1" : "=r"(crypto_int32_y) : "r"(crypto_int32_x) : ); 649*9469f4f1Schristos return crypto_int32_y; 650*9469f4f1Schristos #else 651*9469f4f1Schristos crypto_int32_x &= 1 ^ crypto_int32_optblocker; 652*9469f4f1Schristos return -crypto_int32_x; 653*9469f4f1Schristos #endif 654*9469f4f1Schristos } 655*9469f4f1Schristos 656*9469f4f1Schristos __attribute__((unused)) 657*9469f4f1Schristos static inline 658*9469f4f1Schristos crypto_int32 crypto_int32_bottombit_01(crypto_int32 crypto_int32_x) { 659*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 660*9469f4f1Schristos __asm__ ("andl $1,%0" : "+r"(crypto_int32_x) : : "cc"); 661*9469f4f1Schristos return crypto_int32_x; 662*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 663*9469f4f1Schristos crypto_int32 crypto_int32_y; 664*9469f4f1Schristos __asm__ ("ubfx %w0,%w1,0,1" : "=r"(crypto_int32_y) : "r"(crypto_int32_x) : ); 665*9469f4f1Schristos return crypto_int32_y; 666*9469f4f1Schristos #else 667*9469f4f1Schristos crypto_int32_x &= 1 ^ crypto_int32_optblocker; 668*9469f4f1Schristos return crypto_int32_x; 669*9469f4f1Schristos #endif 670*9469f4f1Schristos } 671*9469f4f1Schristos 672*9469f4f1Schristos __attribute__((unused)) 673*9469f4f1Schristos static inline 674*9469f4f1Schristos crypto_int32 crypto_int32_bitinrangepublicpos_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_s) { 675*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 676*9469f4f1Schristos __asm__ ("sarl %%cl,%0" : "+r"(crypto_int32_x) : "c"(crypto_int32_s) : "cc"); 677*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 678*9469f4f1Schristos __asm__ ("asr %w0,%w0,%w1" : "+r"(crypto_int32_x) : "r"(crypto_int32_s) : ); 679*9469f4f1Schristos #else 680*9469f4f1Schristos crypto_int32_x >>= crypto_int32_s ^ crypto_int32_optblocker; 681*9469f4f1Schristos #endif 682*9469f4f1Schristos return crypto_int32_bottombit_mask(crypto_int32_x); 683*9469f4f1Schristos } 684*9469f4f1Schristos 685*9469f4f1Schristos __attribute__((unused)) 686*9469f4f1Schristos static inline 687*9469f4f1Schristos crypto_int32 crypto_int32_bitinrangepublicpos_01(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_s) { 688*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 689*9469f4f1Schristos __asm__ ("sarl %%cl,%0" : "+r"(crypto_int32_x) : "c"(crypto_int32_s) : "cc"); 690*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 691*9469f4f1Schristos __asm__ ("asr %w0,%w0,%w1" : "+r"(crypto_int32_x) : "r"(crypto_int32_s) : ); 692*9469f4f1Schristos #else 693*9469f4f1Schristos crypto_int32_x >>= crypto_int32_s ^ crypto_int32_optblocker; 694*9469f4f1Schristos #endif 695*9469f4f1Schristos return crypto_int32_bottombit_01(crypto_int32_x); 696*9469f4f1Schristos } 697*9469f4f1Schristos 698*9469f4f1Schristos __attribute__((unused)) 699*9469f4f1Schristos static inline 700*9469f4f1Schristos crypto_int32 crypto_int32_shlmod(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_s) { 701*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 702*9469f4f1Schristos __asm__ ("shll %%cl,%0" : "+r"(crypto_int32_x) : "c"(crypto_int32_s) : "cc"); 703*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 704*9469f4f1Schristos __asm__ ("lsl %w0,%w0,%w1" : "+r"(crypto_int32_x) : "r"(crypto_int32_s) : ); 705*9469f4f1Schristos #else 706*9469f4f1Schristos int crypto_int32_k, crypto_int32_l; 707*9469f4f1Schristos for (crypto_int32_l = 0,crypto_int32_k = 1;crypto_int32_k < 32;++crypto_int32_l,crypto_int32_k *= 2) 708*9469f4f1Schristos crypto_int32_x ^= (crypto_int32_x ^ (crypto_int32_x << crypto_int32_k)) & crypto_int32_bitinrangepublicpos_mask(crypto_int32_s,crypto_int32_l); 709*9469f4f1Schristos #endif 710*9469f4f1Schristos return crypto_int32_x; 711*9469f4f1Schristos } 712*9469f4f1Schristos 713*9469f4f1Schristos __attribute__((unused)) 714*9469f4f1Schristos static inline 715*9469f4f1Schristos crypto_int32 crypto_int32_shrmod(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_s) { 716*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 717*9469f4f1Schristos __asm__ ("sarl %%cl,%0" : "+r"(crypto_int32_x) : "c"(crypto_int32_s) : "cc"); 718*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 719*9469f4f1Schristos __asm__ ("asr %w0,%w0,%w1" : "+r"(crypto_int32_x) : "r"(crypto_int32_s) : ); 720*9469f4f1Schristos #else 721*9469f4f1Schristos int crypto_int32_k, crypto_int32_l; 722*9469f4f1Schristos for (crypto_int32_l = 0,crypto_int32_k = 1;crypto_int32_k < 32;++crypto_int32_l,crypto_int32_k *= 2) 723*9469f4f1Schristos crypto_int32_x ^= (crypto_int32_x ^ (crypto_int32_x >> crypto_int32_k)) & crypto_int32_bitinrangepublicpos_mask(crypto_int32_s,crypto_int32_l); 724*9469f4f1Schristos #endif 725*9469f4f1Schristos return crypto_int32_x; 726*9469f4f1Schristos } 727*9469f4f1Schristos 728*9469f4f1Schristos __attribute__((unused)) 729*9469f4f1Schristos static inline 730*9469f4f1Schristos crypto_int32 crypto_int32_bitmod_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_s) { 731*9469f4f1Schristos crypto_int32_x = crypto_int32_shrmod(crypto_int32_x,crypto_int32_s); 732*9469f4f1Schristos return crypto_int32_bottombit_mask(crypto_int32_x); 733*9469f4f1Schristos } 734*9469f4f1Schristos 735*9469f4f1Schristos __attribute__((unused)) 736*9469f4f1Schristos static inline 737*9469f4f1Schristos crypto_int32 crypto_int32_bitmod_01(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_s) { 738*9469f4f1Schristos crypto_int32_x = crypto_int32_shrmod(crypto_int32_x,crypto_int32_s); 739*9469f4f1Schristos return crypto_int32_bottombit_01(crypto_int32_x); 740*9469f4f1Schristos } 741*9469f4f1Schristos 742*9469f4f1Schristos __attribute__((unused)) 743*9469f4f1Schristos static inline 744*9469f4f1Schristos crypto_int32 crypto_int32_nonzero_mask(crypto_int32 crypto_int32_x) { 745*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 746*9469f4f1Schristos crypto_int32 crypto_int32_q,crypto_int32_z; 747*9469f4f1Schristos __asm__ ("xorl %0,%0\n movl $-1,%1\n testl %2,%2\n cmovnel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x) : "cc"); 748*9469f4f1Schristos return crypto_int32_z; 749*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 750*9469f4f1Schristos crypto_int32 crypto_int32_z; 751*9469f4f1Schristos __asm__ ("cmp %w1,0\n csetm %w0,ne" : "=r"(crypto_int32_z) : "r"(crypto_int32_x) : "cc"); 752*9469f4f1Schristos return crypto_int32_z; 753*9469f4f1Schristos #else 754*9469f4f1Schristos crypto_int32_x |= -crypto_int32_x; 755*9469f4f1Schristos return crypto_int32_negative_mask(crypto_int32_x); 756*9469f4f1Schristos #endif 757*9469f4f1Schristos } 758*9469f4f1Schristos 759*9469f4f1Schristos __attribute__((unused)) 760*9469f4f1Schristos static inline 761*9469f4f1Schristos crypto_int32 crypto_int32_nonzero_01(crypto_int32 crypto_int32_x) { 762*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 763*9469f4f1Schristos crypto_int32 crypto_int32_q,crypto_int32_z; 764*9469f4f1Schristos __asm__ ("xorl %0,%0\n movl $1,%1\n testl %2,%2\n cmovnel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x) : "cc"); 765*9469f4f1Schristos return crypto_int32_z; 766*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 767*9469f4f1Schristos crypto_int32 crypto_int32_z; 768*9469f4f1Schristos __asm__ ("cmp %w1,0\n cset %w0,ne" : "=r"(crypto_int32_z) : "r"(crypto_int32_x) : "cc"); 769*9469f4f1Schristos return crypto_int32_z; 770*9469f4f1Schristos #else 771*9469f4f1Schristos crypto_int32_x |= -crypto_int32_x; 772*9469f4f1Schristos return crypto_int32_unsigned_topbit_01(crypto_int32_x); 773*9469f4f1Schristos #endif 774*9469f4f1Schristos } 775*9469f4f1Schristos 776*9469f4f1Schristos __attribute__((unused)) 777*9469f4f1Schristos static inline 778*9469f4f1Schristos crypto_int32 crypto_int32_positive_mask(crypto_int32 crypto_int32_x) { 779*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 780*9469f4f1Schristos crypto_int32 crypto_int32_q,crypto_int32_z; 781*9469f4f1Schristos __asm__ ("xorl %0,%0\n movl $-1,%1\n testl %2,%2\n cmovgl %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x) : "cc"); 782*9469f4f1Schristos return crypto_int32_z; 783*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 784*9469f4f1Schristos crypto_int32 crypto_int32_z; 785*9469f4f1Schristos __asm__ ("cmp %w1,0\n csetm %w0,gt" : "=r"(crypto_int32_z) : "r"(crypto_int32_x) : "cc"); 786*9469f4f1Schristos return crypto_int32_z; 787*9469f4f1Schristos #else 788*9469f4f1Schristos crypto_int32 crypto_int32_z = -crypto_int32_x; 789*9469f4f1Schristos crypto_int32_z ^= crypto_int32_x & crypto_int32_z; 790*9469f4f1Schristos return crypto_int32_negative_mask(crypto_int32_z); 791*9469f4f1Schristos #endif 792*9469f4f1Schristos } 793*9469f4f1Schristos 794*9469f4f1Schristos __attribute__((unused)) 795*9469f4f1Schristos static inline 796*9469f4f1Schristos crypto_int32 crypto_int32_positive_01(crypto_int32 crypto_int32_x) { 797*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 798*9469f4f1Schristos crypto_int32 crypto_int32_q,crypto_int32_z; 799*9469f4f1Schristos __asm__ ("xorl %0,%0\n movl $1,%1\n testl %2,%2\n cmovgl %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x) : "cc"); 800*9469f4f1Schristos return crypto_int32_z; 801*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 802*9469f4f1Schristos crypto_int32 crypto_int32_z; 803*9469f4f1Schristos __asm__ ("cmp %w1,0\n cset %w0,gt" : "=r"(crypto_int32_z) : "r"(crypto_int32_x) : "cc"); 804*9469f4f1Schristos return crypto_int32_z; 805*9469f4f1Schristos #else 806*9469f4f1Schristos crypto_int32 crypto_int32_z = -crypto_int32_x; 807*9469f4f1Schristos crypto_int32_z ^= crypto_int32_x & crypto_int32_z; 808*9469f4f1Schristos return crypto_int32_unsigned_topbit_01(crypto_int32_z); 809*9469f4f1Schristos #endif 810*9469f4f1Schristos } 811*9469f4f1Schristos 812*9469f4f1Schristos __attribute__((unused)) 813*9469f4f1Schristos static inline 814*9469f4f1Schristos crypto_int32 crypto_int32_zero_mask(crypto_int32 crypto_int32_x) { 815*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 816*9469f4f1Schristos crypto_int32 crypto_int32_q,crypto_int32_z; 817*9469f4f1Schristos __asm__ ("xorl %0,%0\n movl $-1,%1\n testl %2,%2\n cmovel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x) : "cc"); 818*9469f4f1Schristos return crypto_int32_z; 819*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 820*9469f4f1Schristos crypto_int32 crypto_int32_z; 821*9469f4f1Schristos __asm__ ("cmp %w1,0\n csetm %w0,eq" : "=r"(crypto_int32_z) : "r"(crypto_int32_x) : "cc"); 822*9469f4f1Schristos return crypto_int32_z; 823*9469f4f1Schristos #else 824*9469f4f1Schristos return ~crypto_int32_nonzero_mask(crypto_int32_x); 825*9469f4f1Schristos #endif 826*9469f4f1Schristos } 827*9469f4f1Schristos 828*9469f4f1Schristos __attribute__((unused)) 829*9469f4f1Schristos static inline 830*9469f4f1Schristos crypto_int32 crypto_int32_zero_01(crypto_int32 crypto_int32_x) { 831*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 832*9469f4f1Schristos crypto_int32 crypto_int32_q,crypto_int32_z; 833*9469f4f1Schristos __asm__ ("xorl %0,%0\n movl $1,%1\n testl %2,%2\n cmovel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x) : "cc"); 834*9469f4f1Schristos return crypto_int32_z; 835*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 836*9469f4f1Schristos crypto_int32 crypto_int32_z; 837*9469f4f1Schristos __asm__ ("cmp %w1,0\n cset %w0,eq" : "=r"(crypto_int32_z) : "r"(crypto_int32_x) : "cc"); 838*9469f4f1Schristos return crypto_int32_z; 839*9469f4f1Schristos #else 840*9469f4f1Schristos return 1-crypto_int32_nonzero_01(crypto_int32_x); 841*9469f4f1Schristos #endif 842*9469f4f1Schristos } 843*9469f4f1Schristos 844*9469f4f1Schristos __attribute__((unused)) 845*9469f4f1Schristos static inline 846*9469f4f1Schristos crypto_int32 crypto_int32_unequal_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { 847*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 848*9469f4f1Schristos crypto_int32 crypto_int32_q,crypto_int32_z; 849*9469f4f1Schristos __asm__ ("xorl %0,%0\n movl $-1,%1\n cmpl %3,%2\n cmovnel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 850*9469f4f1Schristos return crypto_int32_z; 851*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 852*9469f4f1Schristos crypto_int32 crypto_int32_z; 853*9469f4f1Schristos __asm__ ("cmp %w1,%w2\n csetm %w0,ne" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 854*9469f4f1Schristos return crypto_int32_z; 855*9469f4f1Schristos #else 856*9469f4f1Schristos return crypto_int32_nonzero_mask(crypto_int32_x ^ crypto_int32_y); 857*9469f4f1Schristos #endif 858*9469f4f1Schristos } 859*9469f4f1Schristos 860*9469f4f1Schristos __attribute__((unused)) 861*9469f4f1Schristos static inline 862*9469f4f1Schristos crypto_int32 crypto_int32_unequal_01(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { 863*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 864*9469f4f1Schristos crypto_int32 crypto_int32_q,crypto_int32_z; 865*9469f4f1Schristos __asm__ ("xorl %0,%0\n movl $1,%1\n cmpl %3,%2\n cmovnel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 866*9469f4f1Schristos return crypto_int32_z; 867*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 868*9469f4f1Schristos crypto_int32 crypto_int32_z; 869*9469f4f1Schristos __asm__ ("cmp %w1,%w2\n cset %w0,ne" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 870*9469f4f1Schristos return crypto_int32_z; 871*9469f4f1Schristos #else 872*9469f4f1Schristos return crypto_int32_nonzero_01(crypto_int32_x ^ crypto_int32_y); 873*9469f4f1Schristos #endif 874*9469f4f1Schristos } 875*9469f4f1Schristos 876*9469f4f1Schristos __attribute__((unused)) 877*9469f4f1Schristos static inline 878*9469f4f1Schristos crypto_int32 crypto_int32_equal_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { 879*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 880*9469f4f1Schristos crypto_int32 crypto_int32_q,crypto_int32_z; 881*9469f4f1Schristos __asm__ ("xorl %0,%0\n movl $-1,%1\n cmpl %3,%2\n cmovel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 882*9469f4f1Schristos return crypto_int32_z; 883*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 884*9469f4f1Schristos crypto_int32 crypto_int32_z; 885*9469f4f1Schristos __asm__ ("cmp %w1,%w2\n csetm %w0,eq" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 886*9469f4f1Schristos return crypto_int32_z; 887*9469f4f1Schristos #else 888*9469f4f1Schristos return ~crypto_int32_unequal_mask(crypto_int32_x,crypto_int32_y); 889*9469f4f1Schristos #endif 890*9469f4f1Schristos } 891*9469f4f1Schristos 892*9469f4f1Schristos __attribute__((unused)) 893*9469f4f1Schristos static inline 894*9469f4f1Schristos crypto_int32 crypto_int32_equal_01(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { 895*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 896*9469f4f1Schristos crypto_int32 crypto_int32_q,crypto_int32_z; 897*9469f4f1Schristos __asm__ ("xorl %0,%0\n movl $1,%1\n cmpl %3,%2\n cmovel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 898*9469f4f1Schristos return crypto_int32_z; 899*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 900*9469f4f1Schristos crypto_int32 crypto_int32_z; 901*9469f4f1Schristos __asm__ ("cmp %w1,%w2\n cset %w0,eq" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 902*9469f4f1Schristos return crypto_int32_z; 903*9469f4f1Schristos #else 904*9469f4f1Schristos return 1-crypto_int32_unequal_01(crypto_int32_x,crypto_int32_y); 905*9469f4f1Schristos #endif 906*9469f4f1Schristos } 907*9469f4f1Schristos 908*9469f4f1Schristos __attribute__((unused)) 909*9469f4f1Schristos static inline 910*9469f4f1Schristos crypto_int32 crypto_int32_min(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { 911*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 912*9469f4f1Schristos __asm__ ("cmpl %1,%0\n cmovgl %1,%0" : "+r"(crypto_int32_x) : "r"(crypto_int32_y) : "cc"); 913*9469f4f1Schristos return crypto_int32_x; 914*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 915*9469f4f1Schristos __asm__ ("cmp %w0,%w1\n csel %w0,%w0,%w1,lt" : "+r"(crypto_int32_x) : "r"(crypto_int32_y) : "cc"); 916*9469f4f1Schristos return crypto_int32_x; 917*9469f4f1Schristos #else 918*9469f4f1Schristos crypto_int64 crypto_int32_r = (crypto_int64)crypto_int32_y ^ (crypto_int64)crypto_int32_x; 919*9469f4f1Schristos crypto_int64 crypto_int32_z = (crypto_int64)crypto_int32_y - (crypto_int64)crypto_int32_x; 920*9469f4f1Schristos crypto_int32_z ^= crypto_int32_r & (crypto_int32_z ^ crypto_int32_y); 921*9469f4f1Schristos crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z); 922*9469f4f1Schristos crypto_int32_z &= crypto_int32_r; 923*9469f4f1Schristos return crypto_int32_x ^ crypto_int32_z; 924*9469f4f1Schristos #endif 925*9469f4f1Schristos } 926*9469f4f1Schristos 927*9469f4f1Schristos __attribute__((unused)) 928*9469f4f1Schristos static inline 929*9469f4f1Schristos crypto_int32 crypto_int32_max(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { 930*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 931*9469f4f1Schristos __asm__ ("cmpl %1,%0\n cmovll %1,%0" : "+r"(crypto_int32_x) : "r"(crypto_int32_y) : "cc"); 932*9469f4f1Schristos return crypto_int32_x; 933*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 934*9469f4f1Schristos __asm__ ("cmp %w0,%w1\n csel %w0,%w1,%w0,lt" : "+r"(crypto_int32_x) : "r"(crypto_int32_y) : "cc"); 935*9469f4f1Schristos return crypto_int32_x; 936*9469f4f1Schristos #else 937*9469f4f1Schristos crypto_int64 crypto_int32_r = (crypto_int64)crypto_int32_y ^ (crypto_int64)crypto_int32_x; 938*9469f4f1Schristos crypto_int64 crypto_int32_z = (crypto_int64)crypto_int32_y - (crypto_int64)crypto_int32_x; 939*9469f4f1Schristos crypto_int32_z ^= crypto_int32_r & (crypto_int32_z ^ crypto_int32_y); 940*9469f4f1Schristos crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z); 941*9469f4f1Schristos crypto_int32_z &= crypto_int32_r; 942*9469f4f1Schristos return crypto_int32_y ^ crypto_int32_z; 943*9469f4f1Schristos #endif 944*9469f4f1Schristos } 945*9469f4f1Schristos 946*9469f4f1Schristos __attribute__((unused)) 947*9469f4f1Schristos static inline 948*9469f4f1Schristos void crypto_int32_minmax(crypto_int32 *crypto_int32_p,crypto_int32 *crypto_int32_q) { 949*9469f4f1Schristos crypto_int32 crypto_int32_x = *crypto_int32_p; 950*9469f4f1Schristos crypto_int32 crypto_int32_y = *crypto_int32_q; 951*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 952*9469f4f1Schristos crypto_int32 crypto_int32_z; 953*9469f4f1Schristos __asm__ ("cmpl %2,%1\n movl %1,%0\n cmovgl %2,%1\n cmovgl %0,%2" : "=&r"(crypto_int32_z), "+&r"(crypto_int32_x), "+r"(crypto_int32_y) : : "cc"); 954*9469f4f1Schristos *crypto_int32_p = crypto_int32_x; 955*9469f4f1Schristos *crypto_int32_q = crypto_int32_y; 956*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 957*9469f4f1Schristos crypto_int32 crypto_int32_r, crypto_int32_s; 958*9469f4f1Schristos __asm__ ("cmp %w2,%w3\n csel %w0,%w2,%w3,lt\n csel %w1,%w3,%w2,lt" : "=&r"(crypto_int32_r), "=r"(crypto_int32_s) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 959*9469f4f1Schristos *crypto_int32_p = crypto_int32_r; 960*9469f4f1Schristos *crypto_int32_q = crypto_int32_s; 961*9469f4f1Schristos #else 962*9469f4f1Schristos crypto_int64 crypto_int32_r = (crypto_int64)crypto_int32_y ^ (crypto_int64)crypto_int32_x; 963*9469f4f1Schristos crypto_int64 crypto_int32_z = (crypto_int64)crypto_int32_y - (crypto_int64)crypto_int32_x; 964*9469f4f1Schristos crypto_int32_z ^= crypto_int32_r & (crypto_int32_z ^ crypto_int32_y); 965*9469f4f1Schristos crypto_int32_z = crypto_int32_negative_mask(crypto_int32_z); 966*9469f4f1Schristos crypto_int32_z &= crypto_int32_r; 967*9469f4f1Schristos crypto_int32_x ^= crypto_int32_z; 968*9469f4f1Schristos crypto_int32_y ^= crypto_int32_z; 969*9469f4f1Schristos *crypto_int32_p = crypto_int32_x; 970*9469f4f1Schristos *crypto_int32_q = crypto_int32_y; 971*9469f4f1Schristos #endif 972*9469f4f1Schristos } 973*9469f4f1Schristos 974*9469f4f1Schristos __attribute__((unused)) 975*9469f4f1Schristos static inline 976*9469f4f1Schristos crypto_int32 crypto_int32_smaller_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { 977*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 978*9469f4f1Schristos crypto_int32 crypto_int32_q,crypto_int32_z; 979*9469f4f1Schristos __asm__ ("xorl %0,%0\n movl $-1,%1\n cmpl %3,%2\n cmovll %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 980*9469f4f1Schristos return crypto_int32_z; 981*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 982*9469f4f1Schristos crypto_int32 crypto_int32_z; 983*9469f4f1Schristos __asm__ ("cmp %w1,%w2\n csetm %w0,lt" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 984*9469f4f1Schristos return crypto_int32_z; 985*9469f4f1Schristos #else 986*9469f4f1Schristos crypto_int32 crypto_int32_r = crypto_int32_x ^ crypto_int32_y; 987*9469f4f1Schristos crypto_int32 crypto_int32_z = crypto_int32_x - crypto_int32_y; 988*9469f4f1Schristos crypto_int32_z ^= crypto_int32_r & (crypto_int32_z ^ crypto_int32_x); 989*9469f4f1Schristos return crypto_int32_negative_mask(crypto_int32_z); 990*9469f4f1Schristos #endif 991*9469f4f1Schristos } 992*9469f4f1Schristos 993*9469f4f1Schristos __attribute__((unused)) 994*9469f4f1Schristos static inline 995*9469f4f1Schristos crypto_int32 crypto_int32_smaller_01(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { 996*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 997*9469f4f1Schristos crypto_int32 crypto_int32_q,crypto_int32_z; 998*9469f4f1Schristos __asm__ ("xorl %0,%0\n movl $1,%1\n cmpl %3,%2\n cmovll %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 999*9469f4f1Schristos return crypto_int32_z; 1000*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1001*9469f4f1Schristos crypto_int32 crypto_int32_z; 1002*9469f4f1Schristos __asm__ ("cmp %w1,%w2\n cset %w0,lt" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 1003*9469f4f1Schristos return crypto_int32_z; 1004*9469f4f1Schristos #else 1005*9469f4f1Schristos crypto_int32 crypto_int32_r = crypto_int32_x ^ crypto_int32_y; 1006*9469f4f1Schristos crypto_int32 crypto_int32_z = crypto_int32_x - crypto_int32_y; 1007*9469f4f1Schristos crypto_int32_z ^= crypto_int32_r & (crypto_int32_z ^ crypto_int32_x); 1008*9469f4f1Schristos return crypto_int32_unsigned_topbit_01(crypto_int32_z); 1009*9469f4f1Schristos #endif 1010*9469f4f1Schristos } 1011*9469f4f1Schristos 1012*9469f4f1Schristos __attribute__((unused)) 1013*9469f4f1Schristos static inline 1014*9469f4f1Schristos crypto_int32 crypto_int32_leq_mask(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { 1015*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1016*9469f4f1Schristos crypto_int32 crypto_int32_q,crypto_int32_z; 1017*9469f4f1Schristos __asm__ ("xorl %0,%0\n movl $-1,%1\n cmpl %3,%2\n cmovlel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 1018*9469f4f1Schristos return crypto_int32_z; 1019*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1020*9469f4f1Schristos crypto_int32 crypto_int32_z; 1021*9469f4f1Schristos __asm__ ("cmp %w1,%w2\n csetm %w0,le" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 1022*9469f4f1Schristos return crypto_int32_z; 1023*9469f4f1Schristos #else 1024*9469f4f1Schristos return ~crypto_int32_smaller_mask(crypto_int32_y,crypto_int32_x); 1025*9469f4f1Schristos #endif 1026*9469f4f1Schristos } 1027*9469f4f1Schristos 1028*9469f4f1Schristos __attribute__((unused)) 1029*9469f4f1Schristos static inline 1030*9469f4f1Schristos crypto_int32 crypto_int32_leq_01(crypto_int32 crypto_int32_x,crypto_int32 crypto_int32_y) { 1031*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1032*9469f4f1Schristos crypto_int32 crypto_int32_q,crypto_int32_z; 1033*9469f4f1Schristos __asm__ ("xorl %0,%0\n movl $1,%1\n cmpl %3,%2\n cmovlel %1,%0" : "=&r"(crypto_int32_z), "=&r"(crypto_int32_q) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 1034*9469f4f1Schristos return crypto_int32_z; 1035*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1036*9469f4f1Schristos crypto_int32 crypto_int32_z; 1037*9469f4f1Schristos __asm__ ("cmp %w1,%w2\n cset %w0,le" : "=r"(crypto_int32_z) : "r"(crypto_int32_x), "r"(crypto_int32_y) : "cc"); 1038*9469f4f1Schristos return crypto_int32_z; 1039*9469f4f1Schristos #else 1040*9469f4f1Schristos return 1-crypto_int32_smaller_01(crypto_int32_y,crypto_int32_x); 1041*9469f4f1Schristos #endif 1042*9469f4f1Schristos } 1043*9469f4f1Schristos 1044*9469f4f1Schristos __attribute__((unused)) 1045*9469f4f1Schristos static inline 1046*9469f4f1Schristos int crypto_int32_ones_num(crypto_int32 crypto_int32_x) { 1047*9469f4f1Schristos crypto_int32_unsigned crypto_int32_y = crypto_int32_x; 1048*9469f4f1Schristos const crypto_int32 C0 = 0x55555555; 1049*9469f4f1Schristos const crypto_int32 C1 = 0x33333333; 1050*9469f4f1Schristos const crypto_int32 C2 = 0x0f0f0f0f; 1051*9469f4f1Schristos crypto_int32_y -= ((crypto_int32_y >> 1) & C0); 1052*9469f4f1Schristos crypto_int32_y = (crypto_int32_y & C1) + ((crypto_int32_y >> 2) & C1); 1053*9469f4f1Schristos crypto_int32_y = (crypto_int32_y + (crypto_int32_y >> 4)) & C2; 1054*9469f4f1Schristos crypto_int32_y += crypto_int32_y >> 8; 1055*9469f4f1Schristos crypto_int32_y = (crypto_int32_y + (crypto_int32_y >> 16)) & 0xff; 1056*9469f4f1Schristos return crypto_int32_y; 1057*9469f4f1Schristos } 1058*9469f4f1Schristos 1059*9469f4f1Schristos __attribute__((unused)) 1060*9469f4f1Schristos static inline 1061*9469f4f1Schristos int crypto_int32_bottomzeros_num(crypto_int32 crypto_int32_x) { 1062*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1063*9469f4f1Schristos crypto_int32 fallback = 32; 1064*9469f4f1Schristos __asm__ ("bsfl %0,%0\n cmovel %1,%0" : "+&r"(crypto_int32_x) : "r"(fallback) : "cc"); 1065*9469f4f1Schristos return crypto_int32_x; 1066*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1067*9469f4f1Schristos int64_t crypto_int32_y; 1068*9469f4f1Schristos __asm__ ("rbit %w0,%w1\n clz %w0,%w0" : "=r"(crypto_int32_y) : "r"(crypto_int32_x) : ); 1069*9469f4f1Schristos return crypto_int32_y; 1070*9469f4f1Schristos #else 1071*9469f4f1Schristos crypto_int32 crypto_int32_y = crypto_int32_x ^ (crypto_int32_x-1); 1072*9469f4f1Schristos crypto_int32_y = ((crypto_int32) crypto_int32_y) >> 1; 1073*9469f4f1Schristos crypto_int32_y &= ~(crypto_int32_x & (((crypto_int32) 1) << (32-1))); 1074*9469f4f1Schristos return crypto_int32_ones_num(crypto_int32_y); 1075*9469f4f1Schristos #endif 1076*9469f4f1Schristos } 1077*9469f4f1Schristos 1078*9469f4f1Schristos #endif 1079*9469f4f1Schristos 1080*9469f4f1Schristos /* from supercop-20240808/cryptoint/crypto_int64.h */ 1081*9469f4f1Schristos /* auto-generated: cd cryptoint; ./autogen */ 1082*9469f4f1Schristos /* cryptoint 20240806 */ 1083*9469f4f1Schristos 1084*9469f4f1Schristos #ifndef crypto_int64_h 1085*9469f4f1Schristos #define crypto_int64_h 1086*9469f4f1Schristos 1087*9469f4f1Schristos #define crypto_int64 int64_t 1088*9469f4f1Schristos #define crypto_int64_unsigned uint64_t 1089*9469f4f1Schristos 1090*9469f4f1Schristos 1091*9469f4f1Schristos 1092*9469f4f1Schristos __attribute__((unused)) 1093*9469f4f1Schristos static inline 1094*9469f4f1Schristos crypto_int64 crypto_int64_load(const unsigned char *crypto_int64_s) { 1095*9469f4f1Schristos crypto_int64 crypto_int64_z = 0; 1096*9469f4f1Schristos crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 0; 1097*9469f4f1Schristos crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 8; 1098*9469f4f1Schristos crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 16; 1099*9469f4f1Schristos crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 24; 1100*9469f4f1Schristos crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 32; 1101*9469f4f1Schristos crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 40; 1102*9469f4f1Schristos crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 48; 1103*9469f4f1Schristos crypto_int64_z |= ((crypto_int64) (*crypto_int64_s++)) << 56; 1104*9469f4f1Schristos return crypto_int64_z; 1105*9469f4f1Schristos } 1106*9469f4f1Schristos 1107*9469f4f1Schristos __attribute__((unused)) 1108*9469f4f1Schristos static inline 1109*9469f4f1Schristos void crypto_int64_store(unsigned char *crypto_int64_s,crypto_int64 crypto_int64_x) { 1110*9469f4f1Schristos *crypto_int64_s++ = crypto_int64_x >> 0; 1111*9469f4f1Schristos *crypto_int64_s++ = crypto_int64_x >> 8; 1112*9469f4f1Schristos *crypto_int64_s++ = crypto_int64_x >> 16; 1113*9469f4f1Schristos *crypto_int64_s++ = crypto_int64_x >> 24; 1114*9469f4f1Schristos *crypto_int64_s++ = crypto_int64_x >> 32; 1115*9469f4f1Schristos *crypto_int64_s++ = crypto_int64_x >> 40; 1116*9469f4f1Schristos *crypto_int64_s++ = crypto_int64_x >> 48; 1117*9469f4f1Schristos *crypto_int64_s++ = crypto_int64_x >> 56; 1118*9469f4f1Schristos } 1119*9469f4f1Schristos 1120*9469f4f1Schristos __attribute__((unused)) 1121*9469f4f1Schristos static inline 1122*9469f4f1Schristos crypto_int64 crypto_int64_negative_mask(crypto_int64 crypto_int64_x) { 1123*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1124*9469f4f1Schristos __asm__ ("sarq $63,%0" : "+r"(crypto_int64_x) : : "cc"); 1125*9469f4f1Schristos return crypto_int64_x; 1126*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1127*9469f4f1Schristos crypto_int64 crypto_int64_y; 1128*9469f4f1Schristos __asm__ ("asr %0,%1,63" : "=r"(crypto_int64_y) : "r"(crypto_int64_x) : ); 1129*9469f4f1Schristos return crypto_int64_y; 1130*9469f4f1Schristos #else 1131*9469f4f1Schristos crypto_int64_x >>= 64-6; 1132*9469f4f1Schristos crypto_int64_x ^= crypto_int64_optblocker; 1133*9469f4f1Schristos crypto_int64_x >>= 5; 1134*9469f4f1Schristos return crypto_int64_x; 1135*9469f4f1Schristos #endif 1136*9469f4f1Schristos } 1137*9469f4f1Schristos 1138*9469f4f1Schristos __attribute__((unused)) 1139*9469f4f1Schristos static inline 1140*9469f4f1Schristos crypto_int64_unsigned crypto_int64_unsigned_topbit_01(crypto_int64_unsigned crypto_int64_x) { 1141*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1142*9469f4f1Schristos __asm__ ("shrq $63,%0" : "+r"(crypto_int64_x) : : "cc"); 1143*9469f4f1Schristos return crypto_int64_x; 1144*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1145*9469f4f1Schristos crypto_int64 crypto_int64_y; 1146*9469f4f1Schristos __asm__ ("lsr %0,%1,63" : "=r"(crypto_int64_y) : "r"(crypto_int64_x) : ); 1147*9469f4f1Schristos return crypto_int64_y; 1148*9469f4f1Schristos #else 1149*9469f4f1Schristos crypto_int64_x >>= 64-6; 1150*9469f4f1Schristos crypto_int64_x ^= crypto_int64_optblocker; 1151*9469f4f1Schristos crypto_int64_x >>= 5; 1152*9469f4f1Schristos return crypto_int64_x; 1153*9469f4f1Schristos #endif 1154*9469f4f1Schristos } 1155*9469f4f1Schristos 1156*9469f4f1Schristos __attribute__((unused)) 1157*9469f4f1Schristos static inline 1158*9469f4f1Schristos crypto_int64 crypto_int64_negative_01(crypto_int64 crypto_int64_x) { 1159*9469f4f1Schristos return crypto_int64_unsigned_topbit_01(crypto_int64_x); 1160*9469f4f1Schristos } 1161*9469f4f1Schristos 1162*9469f4f1Schristos __attribute__((unused)) 1163*9469f4f1Schristos static inline 1164*9469f4f1Schristos crypto_int64 crypto_int64_topbit_mask(crypto_int64 crypto_int64_x) { 1165*9469f4f1Schristos return crypto_int64_negative_mask(crypto_int64_x); 1166*9469f4f1Schristos } 1167*9469f4f1Schristos 1168*9469f4f1Schristos __attribute__((unused)) 1169*9469f4f1Schristos static inline 1170*9469f4f1Schristos crypto_int64 crypto_int64_topbit_01(crypto_int64 crypto_int64_x) { 1171*9469f4f1Schristos return crypto_int64_unsigned_topbit_01(crypto_int64_x); 1172*9469f4f1Schristos } 1173*9469f4f1Schristos 1174*9469f4f1Schristos __attribute__((unused)) 1175*9469f4f1Schristos static inline 1176*9469f4f1Schristos crypto_int64 crypto_int64_bottombit_mask(crypto_int64 crypto_int64_x) { 1177*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1178*9469f4f1Schristos __asm__ ("andq $1,%0" : "+r"(crypto_int64_x) : : "cc"); 1179*9469f4f1Schristos return -crypto_int64_x; 1180*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1181*9469f4f1Schristos crypto_int64 crypto_int64_y; 1182*9469f4f1Schristos __asm__ ("sbfx %0,%1,0,1" : "=r"(crypto_int64_y) : "r"(crypto_int64_x) : ); 1183*9469f4f1Schristos return crypto_int64_y; 1184*9469f4f1Schristos #else 1185*9469f4f1Schristos crypto_int64_x &= 1 ^ crypto_int64_optblocker; 1186*9469f4f1Schristos return -crypto_int64_x; 1187*9469f4f1Schristos #endif 1188*9469f4f1Schristos } 1189*9469f4f1Schristos 1190*9469f4f1Schristos __attribute__((unused)) 1191*9469f4f1Schristos static inline 1192*9469f4f1Schristos crypto_int64 crypto_int64_bottombit_01(crypto_int64 crypto_int64_x) { 1193*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1194*9469f4f1Schristos __asm__ ("andq $1,%0" : "+r"(crypto_int64_x) : : "cc"); 1195*9469f4f1Schristos return crypto_int64_x; 1196*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1197*9469f4f1Schristos crypto_int64 crypto_int64_y; 1198*9469f4f1Schristos __asm__ ("ubfx %0,%1,0,1" : "=r"(crypto_int64_y) : "r"(crypto_int64_x) : ); 1199*9469f4f1Schristos return crypto_int64_y; 1200*9469f4f1Schristos #else 1201*9469f4f1Schristos crypto_int64_x &= 1 ^ crypto_int64_optblocker; 1202*9469f4f1Schristos return crypto_int64_x; 1203*9469f4f1Schristos #endif 1204*9469f4f1Schristos } 1205*9469f4f1Schristos 1206*9469f4f1Schristos __attribute__((unused)) 1207*9469f4f1Schristos static inline 1208*9469f4f1Schristos crypto_int64 crypto_int64_bitinrangepublicpos_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_s) { 1209*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1210*9469f4f1Schristos __asm__ ("sarq %%cl,%0" : "+r"(crypto_int64_x) : "c"(crypto_int64_s) : "cc"); 1211*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1212*9469f4f1Schristos __asm__ ("asr %0,%0,%1" : "+r"(crypto_int64_x) : "r"(crypto_int64_s) : ); 1213*9469f4f1Schristos #else 1214*9469f4f1Schristos crypto_int64_x >>= crypto_int64_s ^ crypto_int64_optblocker; 1215*9469f4f1Schristos #endif 1216*9469f4f1Schristos return crypto_int64_bottombit_mask(crypto_int64_x); 1217*9469f4f1Schristos } 1218*9469f4f1Schristos 1219*9469f4f1Schristos __attribute__((unused)) 1220*9469f4f1Schristos static inline 1221*9469f4f1Schristos crypto_int64 crypto_int64_bitinrangepublicpos_01(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_s) { 1222*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1223*9469f4f1Schristos __asm__ ("sarq %%cl,%0" : "+r"(crypto_int64_x) : "c"(crypto_int64_s) : "cc"); 1224*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1225*9469f4f1Schristos __asm__ ("asr %0,%0,%1" : "+r"(crypto_int64_x) : "r"(crypto_int64_s) : ); 1226*9469f4f1Schristos #else 1227*9469f4f1Schristos crypto_int64_x >>= crypto_int64_s ^ crypto_int64_optblocker; 1228*9469f4f1Schristos #endif 1229*9469f4f1Schristos return crypto_int64_bottombit_01(crypto_int64_x); 1230*9469f4f1Schristos } 1231*9469f4f1Schristos 1232*9469f4f1Schristos __attribute__((unused)) 1233*9469f4f1Schristos static inline 1234*9469f4f1Schristos crypto_int64 crypto_int64_shlmod(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_s) { 1235*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1236*9469f4f1Schristos __asm__ ("shlq %%cl,%0" : "+r"(crypto_int64_x) : "c"(crypto_int64_s) : "cc"); 1237*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1238*9469f4f1Schristos __asm__ ("lsl %0,%0,%1" : "+r"(crypto_int64_x) : "r"(crypto_int64_s) : ); 1239*9469f4f1Schristos #else 1240*9469f4f1Schristos int crypto_int64_k, crypto_int64_l; 1241*9469f4f1Schristos for (crypto_int64_l = 0,crypto_int64_k = 1;crypto_int64_k < 64;++crypto_int64_l,crypto_int64_k *= 2) 1242*9469f4f1Schristos crypto_int64_x ^= (crypto_int64_x ^ (crypto_int64_x << crypto_int64_k)) & crypto_int64_bitinrangepublicpos_mask(crypto_int64_s,crypto_int64_l); 1243*9469f4f1Schristos #endif 1244*9469f4f1Schristos return crypto_int64_x; 1245*9469f4f1Schristos } 1246*9469f4f1Schristos 1247*9469f4f1Schristos __attribute__((unused)) 1248*9469f4f1Schristos static inline 1249*9469f4f1Schristos crypto_int64 crypto_int64_shrmod(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_s) { 1250*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1251*9469f4f1Schristos __asm__ ("sarq %%cl,%0" : "+r"(crypto_int64_x) : "c"(crypto_int64_s) : "cc"); 1252*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1253*9469f4f1Schristos __asm__ ("asr %0,%0,%1" : "+r"(crypto_int64_x) : "r"(crypto_int64_s) : ); 1254*9469f4f1Schristos #else 1255*9469f4f1Schristos int crypto_int64_k, crypto_int64_l; 1256*9469f4f1Schristos for (crypto_int64_l = 0,crypto_int64_k = 1;crypto_int64_k < 64;++crypto_int64_l,crypto_int64_k *= 2) 1257*9469f4f1Schristos crypto_int64_x ^= (crypto_int64_x ^ (crypto_int64_x >> crypto_int64_k)) & crypto_int64_bitinrangepublicpos_mask(crypto_int64_s,crypto_int64_l); 1258*9469f4f1Schristos #endif 1259*9469f4f1Schristos return crypto_int64_x; 1260*9469f4f1Schristos } 1261*9469f4f1Schristos 1262*9469f4f1Schristos __attribute__((unused)) 1263*9469f4f1Schristos static inline 1264*9469f4f1Schristos crypto_int64 crypto_int64_bitmod_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_s) { 1265*9469f4f1Schristos crypto_int64_x = crypto_int64_shrmod(crypto_int64_x,crypto_int64_s); 1266*9469f4f1Schristos return crypto_int64_bottombit_mask(crypto_int64_x); 1267*9469f4f1Schristos } 1268*9469f4f1Schristos 1269*9469f4f1Schristos __attribute__((unused)) 1270*9469f4f1Schristos static inline 1271*9469f4f1Schristos crypto_int64 crypto_int64_bitmod_01(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_s) { 1272*9469f4f1Schristos crypto_int64_x = crypto_int64_shrmod(crypto_int64_x,crypto_int64_s); 1273*9469f4f1Schristos return crypto_int64_bottombit_01(crypto_int64_x); 1274*9469f4f1Schristos } 1275*9469f4f1Schristos 1276*9469f4f1Schristos __attribute__((unused)) 1277*9469f4f1Schristos static inline 1278*9469f4f1Schristos crypto_int64 crypto_int64_nonzero_mask(crypto_int64 crypto_int64_x) { 1279*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1280*9469f4f1Schristos crypto_int64 crypto_int64_q,crypto_int64_z; 1281*9469f4f1Schristos __asm__ ("xorq %0,%0\n movq $-1,%1\n testq %2,%2\n cmovneq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x) : "cc"); 1282*9469f4f1Schristos return crypto_int64_z; 1283*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1284*9469f4f1Schristos crypto_int64 crypto_int64_z; 1285*9469f4f1Schristos __asm__ ("cmp %1,0\n csetm %0,ne" : "=r"(crypto_int64_z) : "r"(crypto_int64_x) : "cc"); 1286*9469f4f1Schristos return crypto_int64_z; 1287*9469f4f1Schristos #else 1288*9469f4f1Schristos crypto_int64_x |= -crypto_int64_x; 1289*9469f4f1Schristos return crypto_int64_negative_mask(crypto_int64_x); 1290*9469f4f1Schristos #endif 1291*9469f4f1Schristos } 1292*9469f4f1Schristos 1293*9469f4f1Schristos __attribute__((unused)) 1294*9469f4f1Schristos static inline 1295*9469f4f1Schristos crypto_int64 crypto_int64_nonzero_01(crypto_int64 crypto_int64_x) { 1296*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1297*9469f4f1Schristos crypto_int64 crypto_int64_q,crypto_int64_z; 1298*9469f4f1Schristos __asm__ ("xorq %0,%0\n movq $1,%1\n testq %2,%2\n cmovneq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x) : "cc"); 1299*9469f4f1Schristos return crypto_int64_z; 1300*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1301*9469f4f1Schristos crypto_int64 crypto_int64_z; 1302*9469f4f1Schristos __asm__ ("cmp %1,0\n cset %0,ne" : "=r"(crypto_int64_z) : "r"(crypto_int64_x) : "cc"); 1303*9469f4f1Schristos return crypto_int64_z; 1304*9469f4f1Schristos #else 1305*9469f4f1Schristos crypto_int64_x |= -crypto_int64_x; 1306*9469f4f1Schristos return crypto_int64_unsigned_topbit_01(crypto_int64_x); 1307*9469f4f1Schristos #endif 1308*9469f4f1Schristos } 1309*9469f4f1Schristos 1310*9469f4f1Schristos __attribute__((unused)) 1311*9469f4f1Schristos static inline 1312*9469f4f1Schristos crypto_int64 crypto_int64_positive_mask(crypto_int64 crypto_int64_x) { 1313*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1314*9469f4f1Schristos crypto_int64 crypto_int64_q,crypto_int64_z; 1315*9469f4f1Schristos __asm__ ("xorq %0,%0\n movq $-1,%1\n testq %2,%2\n cmovgq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x) : "cc"); 1316*9469f4f1Schristos return crypto_int64_z; 1317*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1318*9469f4f1Schristos crypto_int64 crypto_int64_z; 1319*9469f4f1Schristos __asm__ ("cmp %1,0\n csetm %0,gt" : "=r"(crypto_int64_z) : "r"(crypto_int64_x) : "cc"); 1320*9469f4f1Schristos return crypto_int64_z; 1321*9469f4f1Schristos #else 1322*9469f4f1Schristos crypto_int64 crypto_int64_z = -crypto_int64_x; 1323*9469f4f1Schristos crypto_int64_z ^= crypto_int64_x & crypto_int64_z; 1324*9469f4f1Schristos return crypto_int64_negative_mask(crypto_int64_z); 1325*9469f4f1Schristos #endif 1326*9469f4f1Schristos } 1327*9469f4f1Schristos 1328*9469f4f1Schristos __attribute__((unused)) 1329*9469f4f1Schristos static inline 1330*9469f4f1Schristos crypto_int64 crypto_int64_positive_01(crypto_int64 crypto_int64_x) { 1331*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1332*9469f4f1Schristos crypto_int64 crypto_int64_q,crypto_int64_z; 1333*9469f4f1Schristos __asm__ ("xorq %0,%0\n movq $1,%1\n testq %2,%2\n cmovgq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x) : "cc"); 1334*9469f4f1Schristos return crypto_int64_z; 1335*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1336*9469f4f1Schristos crypto_int64 crypto_int64_z; 1337*9469f4f1Schristos __asm__ ("cmp %1,0\n cset %0,gt" : "=r"(crypto_int64_z) : "r"(crypto_int64_x) : "cc"); 1338*9469f4f1Schristos return crypto_int64_z; 1339*9469f4f1Schristos #else 1340*9469f4f1Schristos crypto_int64 crypto_int64_z = -crypto_int64_x; 1341*9469f4f1Schristos crypto_int64_z ^= crypto_int64_x & crypto_int64_z; 1342*9469f4f1Schristos return crypto_int64_unsigned_topbit_01(crypto_int64_z); 1343*9469f4f1Schristos #endif 1344*9469f4f1Schristos } 1345*9469f4f1Schristos 1346*9469f4f1Schristos __attribute__((unused)) 1347*9469f4f1Schristos static inline 1348*9469f4f1Schristos crypto_int64 crypto_int64_zero_mask(crypto_int64 crypto_int64_x) { 1349*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1350*9469f4f1Schristos crypto_int64 crypto_int64_q,crypto_int64_z; 1351*9469f4f1Schristos __asm__ ("xorq %0,%0\n movq $-1,%1\n testq %2,%2\n cmoveq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x) : "cc"); 1352*9469f4f1Schristos return crypto_int64_z; 1353*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1354*9469f4f1Schristos crypto_int64 crypto_int64_z; 1355*9469f4f1Schristos __asm__ ("cmp %1,0\n csetm %0,eq" : "=r"(crypto_int64_z) : "r"(crypto_int64_x) : "cc"); 1356*9469f4f1Schristos return crypto_int64_z; 1357*9469f4f1Schristos #else 1358*9469f4f1Schristos return ~crypto_int64_nonzero_mask(crypto_int64_x); 1359*9469f4f1Schristos #endif 1360*9469f4f1Schristos } 1361*9469f4f1Schristos 1362*9469f4f1Schristos __attribute__((unused)) 1363*9469f4f1Schristos static inline 1364*9469f4f1Schristos crypto_int64 crypto_int64_zero_01(crypto_int64 crypto_int64_x) { 1365*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1366*9469f4f1Schristos crypto_int64 crypto_int64_q,crypto_int64_z; 1367*9469f4f1Schristos __asm__ ("xorq %0,%0\n movq $1,%1\n testq %2,%2\n cmoveq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x) : "cc"); 1368*9469f4f1Schristos return crypto_int64_z; 1369*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1370*9469f4f1Schristos crypto_int64 crypto_int64_z; 1371*9469f4f1Schristos __asm__ ("cmp %1,0\n cset %0,eq" : "=r"(crypto_int64_z) : "r"(crypto_int64_x) : "cc"); 1372*9469f4f1Schristos return crypto_int64_z; 1373*9469f4f1Schristos #else 1374*9469f4f1Schristos return 1-crypto_int64_nonzero_01(crypto_int64_x); 1375*9469f4f1Schristos #endif 1376*9469f4f1Schristos } 1377*9469f4f1Schristos 1378*9469f4f1Schristos __attribute__((unused)) 1379*9469f4f1Schristos static inline 1380*9469f4f1Schristos crypto_int64 crypto_int64_unequal_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { 1381*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1382*9469f4f1Schristos crypto_int64 crypto_int64_q,crypto_int64_z; 1383*9469f4f1Schristos __asm__ ("xorq %0,%0\n movq $-1,%1\n cmpq %3,%2\n cmovneq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1384*9469f4f1Schristos return crypto_int64_z; 1385*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1386*9469f4f1Schristos crypto_int64 crypto_int64_z; 1387*9469f4f1Schristos __asm__ ("cmp %1,%2\n csetm %0,ne" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1388*9469f4f1Schristos return crypto_int64_z; 1389*9469f4f1Schristos #else 1390*9469f4f1Schristos return crypto_int64_nonzero_mask(crypto_int64_x ^ crypto_int64_y); 1391*9469f4f1Schristos #endif 1392*9469f4f1Schristos } 1393*9469f4f1Schristos 1394*9469f4f1Schristos __attribute__((unused)) 1395*9469f4f1Schristos static inline 1396*9469f4f1Schristos crypto_int64 crypto_int64_unequal_01(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { 1397*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1398*9469f4f1Schristos crypto_int64 crypto_int64_q,crypto_int64_z; 1399*9469f4f1Schristos __asm__ ("xorq %0,%0\n movq $1,%1\n cmpq %3,%2\n cmovneq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1400*9469f4f1Schristos return crypto_int64_z; 1401*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1402*9469f4f1Schristos crypto_int64 crypto_int64_z; 1403*9469f4f1Schristos __asm__ ("cmp %1,%2\n cset %0,ne" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1404*9469f4f1Schristos return crypto_int64_z; 1405*9469f4f1Schristos #else 1406*9469f4f1Schristos return crypto_int64_nonzero_01(crypto_int64_x ^ crypto_int64_y); 1407*9469f4f1Schristos #endif 1408*9469f4f1Schristos } 1409*9469f4f1Schristos 1410*9469f4f1Schristos __attribute__((unused)) 1411*9469f4f1Schristos static inline 1412*9469f4f1Schristos crypto_int64 crypto_int64_equal_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { 1413*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1414*9469f4f1Schristos crypto_int64 crypto_int64_q,crypto_int64_z; 1415*9469f4f1Schristos __asm__ ("xorq %0,%0\n movq $-1,%1\n cmpq %3,%2\n cmoveq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1416*9469f4f1Schristos return crypto_int64_z; 1417*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1418*9469f4f1Schristos crypto_int64 crypto_int64_z; 1419*9469f4f1Schristos __asm__ ("cmp %1,%2\n csetm %0,eq" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1420*9469f4f1Schristos return crypto_int64_z; 1421*9469f4f1Schristos #else 1422*9469f4f1Schristos return ~crypto_int64_unequal_mask(crypto_int64_x,crypto_int64_y); 1423*9469f4f1Schristos #endif 1424*9469f4f1Schristos } 1425*9469f4f1Schristos 1426*9469f4f1Schristos __attribute__((unused)) 1427*9469f4f1Schristos static inline 1428*9469f4f1Schristos crypto_int64 crypto_int64_equal_01(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { 1429*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1430*9469f4f1Schristos crypto_int64 crypto_int64_q,crypto_int64_z; 1431*9469f4f1Schristos __asm__ ("xorq %0,%0\n movq $1,%1\n cmpq %3,%2\n cmoveq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1432*9469f4f1Schristos return crypto_int64_z; 1433*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1434*9469f4f1Schristos crypto_int64 crypto_int64_z; 1435*9469f4f1Schristos __asm__ ("cmp %1,%2\n cset %0,eq" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1436*9469f4f1Schristos return crypto_int64_z; 1437*9469f4f1Schristos #else 1438*9469f4f1Schristos return 1-crypto_int64_unequal_01(crypto_int64_x,crypto_int64_y); 1439*9469f4f1Schristos #endif 1440*9469f4f1Schristos } 1441*9469f4f1Schristos 1442*9469f4f1Schristos __attribute__((unused)) 1443*9469f4f1Schristos static inline 1444*9469f4f1Schristos crypto_int64 crypto_int64_min(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { 1445*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1446*9469f4f1Schristos __asm__ ("cmpq %1,%0\n cmovgq %1,%0" : "+r"(crypto_int64_x) : "r"(crypto_int64_y) : "cc"); 1447*9469f4f1Schristos return crypto_int64_x; 1448*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1449*9469f4f1Schristos __asm__ ("cmp %0,%1\n csel %0,%0,%1,lt" : "+r"(crypto_int64_x) : "r"(crypto_int64_y) : "cc"); 1450*9469f4f1Schristos return crypto_int64_x; 1451*9469f4f1Schristos #else 1452*9469f4f1Schristos crypto_int64 crypto_int64_r = crypto_int64_y ^ crypto_int64_x; 1453*9469f4f1Schristos crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x; 1454*9469f4f1Schristos crypto_int64_z ^= crypto_int64_r & (crypto_int64_z ^ crypto_int64_y); 1455*9469f4f1Schristos crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z); 1456*9469f4f1Schristos crypto_int64_z &= crypto_int64_r; 1457*9469f4f1Schristos return crypto_int64_x ^ crypto_int64_z; 1458*9469f4f1Schristos #endif 1459*9469f4f1Schristos } 1460*9469f4f1Schristos 1461*9469f4f1Schristos __attribute__((unused)) 1462*9469f4f1Schristos static inline 1463*9469f4f1Schristos crypto_int64 crypto_int64_max(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { 1464*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1465*9469f4f1Schristos __asm__ ("cmpq %1,%0\n cmovlq %1,%0" : "+r"(crypto_int64_x) : "r"(crypto_int64_y) : "cc"); 1466*9469f4f1Schristos return crypto_int64_x; 1467*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1468*9469f4f1Schristos __asm__ ("cmp %0,%1\n csel %0,%1,%0,lt" : "+r"(crypto_int64_x) : "r"(crypto_int64_y) : "cc"); 1469*9469f4f1Schristos return crypto_int64_x; 1470*9469f4f1Schristos #else 1471*9469f4f1Schristos crypto_int64 crypto_int64_r = crypto_int64_y ^ crypto_int64_x; 1472*9469f4f1Schristos crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x; 1473*9469f4f1Schristos crypto_int64_z ^= crypto_int64_r & (crypto_int64_z ^ crypto_int64_y); 1474*9469f4f1Schristos crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z); 1475*9469f4f1Schristos crypto_int64_z &= crypto_int64_r; 1476*9469f4f1Schristos return crypto_int64_y ^ crypto_int64_z; 1477*9469f4f1Schristos #endif 1478*9469f4f1Schristos } 1479*9469f4f1Schristos 1480*9469f4f1Schristos __attribute__((unused)) 1481*9469f4f1Schristos static inline 1482*9469f4f1Schristos void crypto_int64_minmax(crypto_int64 *crypto_int64_p,crypto_int64 *crypto_int64_q) { 1483*9469f4f1Schristos crypto_int64 crypto_int64_x = *crypto_int64_p; 1484*9469f4f1Schristos crypto_int64 crypto_int64_y = *crypto_int64_q; 1485*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1486*9469f4f1Schristos crypto_int64 crypto_int64_z; 1487*9469f4f1Schristos __asm__ ("cmpq %2,%1\n movq %1,%0\n cmovgq %2,%1\n cmovgq %0,%2" : "=&r"(crypto_int64_z), "+&r"(crypto_int64_x), "+r"(crypto_int64_y) : : "cc"); 1488*9469f4f1Schristos *crypto_int64_p = crypto_int64_x; 1489*9469f4f1Schristos *crypto_int64_q = crypto_int64_y; 1490*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1491*9469f4f1Schristos crypto_int64 crypto_int64_r, crypto_int64_s; 1492*9469f4f1Schristos __asm__ ("cmp %2,%3\n csel %0,%2,%3,lt\n csel %1,%3,%2,lt" : "=&r"(crypto_int64_r), "=r"(crypto_int64_s) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1493*9469f4f1Schristos *crypto_int64_p = crypto_int64_r; 1494*9469f4f1Schristos *crypto_int64_q = crypto_int64_s; 1495*9469f4f1Schristos #else 1496*9469f4f1Schristos crypto_int64 crypto_int64_r = crypto_int64_y ^ crypto_int64_x; 1497*9469f4f1Schristos crypto_int64 crypto_int64_z = crypto_int64_y - crypto_int64_x; 1498*9469f4f1Schristos crypto_int64_z ^= crypto_int64_r & (crypto_int64_z ^ crypto_int64_y); 1499*9469f4f1Schristos crypto_int64_z = crypto_int64_negative_mask(crypto_int64_z); 1500*9469f4f1Schristos crypto_int64_z &= crypto_int64_r; 1501*9469f4f1Schristos crypto_int64_x ^= crypto_int64_z; 1502*9469f4f1Schristos crypto_int64_y ^= crypto_int64_z; 1503*9469f4f1Schristos *crypto_int64_p = crypto_int64_x; 1504*9469f4f1Schristos *crypto_int64_q = crypto_int64_y; 1505*9469f4f1Schristos #endif 1506*9469f4f1Schristos } 1507*9469f4f1Schristos 1508*9469f4f1Schristos __attribute__((unused)) 1509*9469f4f1Schristos static inline 1510*9469f4f1Schristos crypto_int64 crypto_int64_smaller_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { 1511*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1512*9469f4f1Schristos crypto_int64 crypto_int64_q,crypto_int64_z; 1513*9469f4f1Schristos __asm__ ("xorq %0,%0\n movq $-1,%1\n cmpq %3,%2\n cmovlq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1514*9469f4f1Schristos return crypto_int64_z; 1515*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1516*9469f4f1Schristos crypto_int64 crypto_int64_z; 1517*9469f4f1Schristos __asm__ ("cmp %1,%2\n csetm %0,lt" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1518*9469f4f1Schristos return crypto_int64_z; 1519*9469f4f1Schristos #else 1520*9469f4f1Schristos crypto_int64 crypto_int64_r = crypto_int64_x ^ crypto_int64_y; 1521*9469f4f1Schristos crypto_int64 crypto_int64_z = crypto_int64_x - crypto_int64_y; 1522*9469f4f1Schristos crypto_int64_z ^= crypto_int64_r & (crypto_int64_z ^ crypto_int64_x); 1523*9469f4f1Schristos return crypto_int64_negative_mask(crypto_int64_z); 1524*9469f4f1Schristos #endif 1525*9469f4f1Schristos } 1526*9469f4f1Schristos 1527*9469f4f1Schristos __attribute__((unused)) 1528*9469f4f1Schristos static inline 1529*9469f4f1Schristos crypto_int64 crypto_int64_smaller_01(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { 1530*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1531*9469f4f1Schristos crypto_int64 crypto_int64_q,crypto_int64_z; 1532*9469f4f1Schristos __asm__ ("xorq %0,%0\n movq $1,%1\n cmpq %3,%2\n cmovlq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1533*9469f4f1Schristos return crypto_int64_z; 1534*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1535*9469f4f1Schristos crypto_int64 crypto_int64_z; 1536*9469f4f1Schristos __asm__ ("cmp %1,%2\n cset %0,lt" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1537*9469f4f1Schristos return crypto_int64_z; 1538*9469f4f1Schristos #else 1539*9469f4f1Schristos crypto_int64 crypto_int64_r = crypto_int64_x ^ crypto_int64_y; 1540*9469f4f1Schristos crypto_int64 crypto_int64_z = crypto_int64_x - crypto_int64_y; 1541*9469f4f1Schristos crypto_int64_z ^= crypto_int64_r & (crypto_int64_z ^ crypto_int64_x); 1542*9469f4f1Schristos return crypto_int64_unsigned_topbit_01(crypto_int64_z); 1543*9469f4f1Schristos #endif 1544*9469f4f1Schristos } 1545*9469f4f1Schristos 1546*9469f4f1Schristos __attribute__((unused)) 1547*9469f4f1Schristos static inline 1548*9469f4f1Schristos crypto_int64 crypto_int64_leq_mask(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { 1549*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1550*9469f4f1Schristos crypto_int64 crypto_int64_q,crypto_int64_z; 1551*9469f4f1Schristos __asm__ ("xorq %0,%0\n movq $-1,%1\n cmpq %3,%2\n cmovleq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1552*9469f4f1Schristos return crypto_int64_z; 1553*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1554*9469f4f1Schristos crypto_int64 crypto_int64_z; 1555*9469f4f1Schristos __asm__ ("cmp %1,%2\n csetm %0,le" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1556*9469f4f1Schristos return crypto_int64_z; 1557*9469f4f1Schristos #else 1558*9469f4f1Schristos return ~crypto_int64_smaller_mask(crypto_int64_y,crypto_int64_x); 1559*9469f4f1Schristos #endif 1560*9469f4f1Schristos } 1561*9469f4f1Schristos 1562*9469f4f1Schristos __attribute__((unused)) 1563*9469f4f1Schristos static inline 1564*9469f4f1Schristos crypto_int64 crypto_int64_leq_01(crypto_int64 crypto_int64_x,crypto_int64 crypto_int64_y) { 1565*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1566*9469f4f1Schristos crypto_int64 crypto_int64_q,crypto_int64_z; 1567*9469f4f1Schristos __asm__ ("xorq %0,%0\n movq $1,%1\n cmpq %3,%2\n cmovleq %1,%0" : "=&r"(crypto_int64_z), "=&r"(crypto_int64_q) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1568*9469f4f1Schristos return crypto_int64_z; 1569*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1570*9469f4f1Schristos crypto_int64 crypto_int64_z; 1571*9469f4f1Schristos __asm__ ("cmp %1,%2\n cset %0,le" : "=r"(crypto_int64_z) : "r"(crypto_int64_x), "r"(crypto_int64_y) : "cc"); 1572*9469f4f1Schristos return crypto_int64_z; 1573*9469f4f1Schristos #else 1574*9469f4f1Schristos return 1-crypto_int64_smaller_01(crypto_int64_y,crypto_int64_x); 1575*9469f4f1Schristos #endif 1576*9469f4f1Schristos } 1577*9469f4f1Schristos 1578*9469f4f1Schristos __attribute__((unused)) 1579*9469f4f1Schristos static inline 1580*9469f4f1Schristos int crypto_int64_ones_num(crypto_int64 crypto_int64_x) { 1581*9469f4f1Schristos crypto_int64_unsigned crypto_int64_y = crypto_int64_x; 1582*9469f4f1Schristos const crypto_int64 C0 = 0x5555555555555555; 1583*9469f4f1Schristos const crypto_int64 C1 = 0x3333333333333333; 1584*9469f4f1Schristos const crypto_int64 C2 = 0x0f0f0f0f0f0f0f0f; 1585*9469f4f1Schristos crypto_int64_y -= ((crypto_int64_y >> 1) & C0); 1586*9469f4f1Schristos crypto_int64_y = (crypto_int64_y & C1) + ((crypto_int64_y >> 2) & C1); 1587*9469f4f1Schristos crypto_int64_y = (crypto_int64_y + (crypto_int64_y >> 4)) & C2; 1588*9469f4f1Schristos crypto_int64_y += crypto_int64_y >> 8; 1589*9469f4f1Schristos crypto_int64_y += crypto_int64_y >> 16; 1590*9469f4f1Schristos crypto_int64_y = (crypto_int64_y + (crypto_int64_y >> 32)) & 0xff; 1591*9469f4f1Schristos return crypto_int64_y; 1592*9469f4f1Schristos } 1593*9469f4f1Schristos 1594*9469f4f1Schristos __attribute__((unused)) 1595*9469f4f1Schristos static inline 1596*9469f4f1Schristos int crypto_int64_bottomzeros_num(crypto_int64 crypto_int64_x) { 1597*9469f4f1Schristos #if defined(__GNUC__) && defined(__x86_64__) 1598*9469f4f1Schristos crypto_int64 fallback = 64; 1599*9469f4f1Schristos __asm__ ("bsfq %0,%0\n cmoveq %1,%0" : "+&r"(crypto_int64_x) : "r"(fallback) : "cc"); 1600*9469f4f1Schristos return crypto_int64_x; 1601*9469f4f1Schristos #elif defined(__GNUC__) && defined(__aarch64__) 1602*9469f4f1Schristos int64_t crypto_int64_y; 1603*9469f4f1Schristos __asm__ ("rbit %0,%1\n clz %0,%0" : "=r"(crypto_int64_y) : "r"(crypto_int64_x) : ); 1604*9469f4f1Schristos return crypto_int64_y; 1605*9469f4f1Schristos #else 1606*9469f4f1Schristos crypto_int64 crypto_int64_y = crypto_int64_x ^ (crypto_int64_x-1); 1607*9469f4f1Schristos crypto_int64_y = ((crypto_int64) crypto_int64_y) >> 1; 1608*9469f4f1Schristos crypto_int64_y &= ~(crypto_int64_x & (((crypto_int64) 1) << (64-1))); 1609*9469f4f1Schristos return crypto_int64_ones_num(crypto_int64_y); 1610*9469f4f1Schristos #endif 1611*9469f4f1Schristos } 1612*9469f4f1Schristos 1613*9469f4f1Schristos #endif 1614*9469f4f1Schristos 1615*9469f4f1Schristos /* from supercop-20240808/crypto_sort/int32/portable4/sort.c */ 1616*9469f4f1Schristos #define int32_MINMAX(a,b) crypto_int32_minmax(&a,&b) 1617cffc2a7aSchristos 1618cffc2a7aSchristos static void crypto_sort_int32(void *array,long long n) 1619cffc2a7aSchristos { 1620cffc2a7aSchristos long long top,p,q,r,i,j; 1621cffc2a7aSchristos int32 *x = array; 1622cffc2a7aSchristos 1623cffc2a7aSchristos if (n < 2) return; 1624cffc2a7aSchristos top = 1; 1625cffc2a7aSchristos while (top < n - top) top += top; 1626cffc2a7aSchristos 1627cffc2a7aSchristos for (p = top;p >= 1;p >>= 1) { 1628cffc2a7aSchristos i = 0; 1629cffc2a7aSchristos while (i + 2 * p <= n) { 1630cffc2a7aSchristos for (j = i;j < i + p;++j) 1631cffc2a7aSchristos int32_MINMAX(x[j],x[j+p]); 1632cffc2a7aSchristos i += 2 * p; 1633cffc2a7aSchristos } 1634cffc2a7aSchristos for (j = i;j < n - p;++j) 1635cffc2a7aSchristos int32_MINMAX(x[j],x[j+p]); 1636cffc2a7aSchristos 1637cffc2a7aSchristos i = 0; 1638cffc2a7aSchristos j = 0; 1639cffc2a7aSchristos for (q = top;q > p;q >>= 1) { 1640cffc2a7aSchristos if (j != i) for (;;) { 1641cffc2a7aSchristos if (j == n - q) goto done; 1642cffc2a7aSchristos int32 a = x[j + p]; 1643cffc2a7aSchristos for (r = q;r > p;r >>= 1) 1644cffc2a7aSchristos int32_MINMAX(a,x[j + r]); 1645cffc2a7aSchristos x[j + p] = a; 1646cffc2a7aSchristos ++j; 1647cffc2a7aSchristos if (j == i + p) { 1648cffc2a7aSchristos i += 2 * p; 1649cffc2a7aSchristos break; 1650cffc2a7aSchristos } 1651cffc2a7aSchristos } 1652cffc2a7aSchristos while (i + p <= n - q) { 1653cffc2a7aSchristos for (j = i;j < i + p;++j) { 1654cffc2a7aSchristos int32 a = x[j + p]; 1655cffc2a7aSchristos for (r = q;r > p;r >>= 1) 1656cffc2a7aSchristos int32_MINMAX(a,x[j+r]); 1657cffc2a7aSchristos x[j + p] = a; 1658cffc2a7aSchristos } 1659cffc2a7aSchristos i += 2 * p; 1660cffc2a7aSchristos } 1661cffc2a7aSchristos /* now i + p > n - q */ 1662cffc2a7aSchristos j = i; 1663cffc2a7aSchristos while (j < n - q) { 1664cffc2a7aSchristos int32 a = x[j + p]; 1665cffc2a7aSchristos for (r = q;r > p;r >>= 1) 1666cffc2a7aSchristos int32_MINMAX(a,x[j+r]); 1667cffc2a7aSchristos x[j + p] = a; 1668cffc2a7aSchristos ++j; 1669cffc2a7aSchristos } 1670cffc2a7aSchristos 1671cffc2a7aSchristos done: ; 1672cffc2a7aSchristos } 1673cffc2a7aSchristos } 1674cffc2a7aSchristos } 1675cffc2a7aSchristos 1676*9469f4f1Schristos /* from supercop-20240808/crypto_sort/uint32/useint32/sort.c */ 1677cffc2a7aSchristos 1678cffc2a7aSchristos /* can save time by vectorizing xor loops */ 1679cffc2a7aSchristos /* can save time by integrating xor loops with int32_sort */ 1680cffc2a7aSchristos 1681cffc2a7aSchristos static void crypto_sort_uint32(void *array,long long n) 1682cffc2a7aSchristos { 1683cffc2a7aSchristos crypto_uint32 *x = array; 1684cffc2a7aSchristos long long j; 1685cffc2a7aSchristos for (j = 0;j < n;++j) x[j] ^= 0x80000000; 1686cffc2a7aSchristos crypto_sort_int32(array,n); 1687cffc2a7aSchristos for (j = 0;j < n;++j) x[j] ^= 0x80000000; 1688cffc2a7aSchristos } 1689cffc2a7aSchristos 1690*9469f4f1Schristos /* from supercop-20240808/crypto_kem/sntrup761/compact/kem.c */ 1691*9469f4f1Schristos // 20240806 djb: some automated conversion to cryptoint 1692cffc2a7aSchristos 1693*9469f4f1Schristos #define p 761 1694*9469f4f1Schristos #define q 4591 1695*9469f4f1Schristos #define w 286 1696*9469f4f1Schristos #define q12 ((q - 1) / 2) 1697*9469f4f1Schristos typedef int8_t small; 1698*9469f4f1Schristos typedef int16_t Fq; 1699*9469f4f1Schristos #define Hash_bytes 32 1700*9469f4f1Schristos #define Small_bytes ((p + 3) / 4) 1701*9469f4f1Schristos typedef small Inputs[p]; 1702*9469f4f1Schristos #define SecretKeys_bytes (2 * Small_bytes) 1703*9469f4f1Schristos #define Confirm_bytes 32 1704cffc2a7aSchristos 1705*9469f4f1Schristos static small F3_freeze(int16_t x) { return x - 3 * ((10923 * x + 16384) >> 15); } 1706cffc2a7aSchristos 1707*9469f4f1Schristos static Fq Fq_freeze(int32_t x) { 1708*9469f4f1Schristos const int32_t q16 = (0x10000 + q / 2) / q; 1709*9469f4f1Schristos const int32_t q20 = (0x100000 + q / 2) / q; 1710*9469f4f1Schristos const int32_t q28 = (0x10000000 + q / 2) / q; 1711*9469f4f1Schristos x -= q * ((q16 * x) >> 16); 1712*9469f4f1Schristos x -= q * ((q20 * x) >> 20); 1713*9469f4f1Schristos return x - q * ((q28 * x + 0x8000000) >> 28); 1714*9469f4f1Schristos } 1715cffc2a7aSchristos 1716*9469f4f1Schristos static int Weightw_mask(small *r) { 1717*9469f4f1Schristos int i, weight = 0; 1718*9469f4f1Schristos for (i = 0; i < p; ++i) weight += crypto_int64_bottombit_01(r[i]); 1719*9469f4f1Schristos return crypto_int16_nonzero_mask(weight - w); 1720*9469f4f1Schristos } 1721cffc2a7aSchristos 1722*9469f4f1Schristos static void uint32_divmod_uint14(uint32_t *Q, uint16_t *r, uint32_t x, uint16_t m) { 1723*9469f4f1Schristos uint32_t qpart, mask, v = 0x80000000 / m; 1724*9469f4f1Schristos qpart = (x * (uint64_t)v) >> 31; 1725*9469f4f1Schristos x -= qpart * m; 1726*9469f4f1Schristos *Q = qpart; 1727*9469f4f1Schristos qpart = (x * (uint64_t)v) >> 31; 1728*9469f4f1Schristos x -= qpart * m; 1729*9469f4f1Schristos *Q += qpart; 1730*9469f4f1Schristos x -= m; 1731*9469f4f1Schristos *Q += 1; 1732*9469f4f1Schristos mask = crypto_int32_negative_mask(x); 1733*9469f4f1Schristos x += mask & (uint32_t)m; 1734*9469f4f1Schristos *Q += mask; 1735cffc2a7aSchristos *r = x; 1736cffc2a7aSchristos } 1737cffc2a7aSchristos 1738*9469f4f1Schristos static uint16_t uint32_mod_uint14(uint32_t x, uint16_t m) { 1739*9469f4f1Schristos uint32_t Q; 1740*9469f4f1Schristos uint16_t r; 1741*9469f4f1Schristos uint32_divmod_uint14(&Q, &r, x, m); 1742cffc2a7aSchristos return r; 1743cffc2a7aSchristos } 1744cffc2a7aSchristos 1745*9469f4f1Schristos static void Encode(unsigned char *out, const uint16_t *R, const uint16_t *M, long long len) { 1746cffc2a7aSchristos if (len == 1) { 1747*9469f4f1Schristos uint16_t r = R[0], m = M[0]; 1748cffc2a7aSchristos while (m > 1) { 1749cffc2a7aSchristos *out++ = r; 1750cffc2a7aSchristos r >>= 8; 1751cffc2a7aSchristos m = (m + 255) >> 8; 1752cffc2a7aSchristos } 1753cffc2a7aSchristos } 1754cffc2a7aSchristos if (len > 1) { 1755*9469f4f1Schristos uint16_t R2[(len + 1) / 2], M2[(len + 1) / 2]; 1756cffc2a7aSchristos long long i; 1757cffc2a7aSchristos for (i = 0; i < len - 1; i += 2) { 1758*9469f4f1Schristos uint32_t m0 = M[i]; 1759*9469f4f1Schristos uint32_t r = R[i] + R[i + 1] * m0; 1760*9469f4f1Schristos uint32_t m = M[i + 1] * m0; 1761cffc2a7aSchristos while (m >= 16384) { 1762cffc2a7aSchristos *out++ = r; 1763cffc2a7aSchristos r >>= 8; 1764cffc2a7aSchristos m = (m + 255) >> 8; 1765cffc2a7aSchristos } 1766cffc2a7aSchristos R2[i / 2] = r; 1767cffc2a7aSchristos M2[i / 2] = m; 1768cffc2a7aSchristos } 1769cffc2a7aSchristos if (i < len) { 1770cffc2a7aSchristos R2[i / 2] = R[i]; 1771cffc2a7aSchristos M2[i / 2] = M[i]; 1772cffc2a7aSchristos } 1773cffc2a7aSchristos Encode(out, R2, M2, (len + 1) / 2); 1774cffc2a7aSchristos } 1775cffc2a7aSchristos } 1776cffc2a7aSchristos 1777*9469f4f1Schristos static void Decode(uint16_t *out, const unsigned char *S, const uint16_t *M, long long len) { 1778*9469f4f1Schristos if (len == 1) { 1779*9469f4f1Schristos if (M[0] == 1) 1780*9469f4f1Schristos *out = 0; 1781*9469f4f1Schristos else if (M[0] <= 256) 1782*9469f4f1Schristos *out = uint32_mod_uint14(S[0], M[0]); 1783*9469f4f1Schristos else 1784*9469f4f1Schristos *out = uint32_mod_uint14(S[0] + (((uint16_t)S[1]) << 8), M[0]); 1785*9469f4f1Schristos } 1786*9469f4f1Schristos if (len > 1) { 1787*9469f4f1Schristos uint16_t R2[(len + 1) / 2], M2[(len + 1) / 2], bottomr[len / 2]; 1788*9469f4f1Schristos uint32_t bottomt[len / 2]; 1789*9469f4f1Schristos long long i; 1790*9469f4f1Schristos for (i = 0; i < len - 1; i += 2) { 1791*9469f4f1Schristos uint32_t m = M[i] * (uint32_t)M[i + 1]; 1792*9469f4f1Schristos if (m > 256 * 16383) { 1793*9469f4f1Schristos bottomt[i / 2] = 256 * 256; 1794*9469f4f1Schristos bottomr[i / 2] = S[0] + 256 * S[1]; 1795*9469f4f1Schristos S += 2; 1796*9469f4f1Schristos M2[i / 2] = (((m + 255) >> 8) + 255) >> 8; 1797*9469f4f1Schristos } else if (m >= 16384) { 1798*9469f4f1Schristos bottomt[i / 2] = 256; 1799*9469f4f1Schristos bottomr[i / 2] = S[0]; 1800*9469f4f1Schristos S += 1; 1801*9469f4f1Schristos M2[i / 2] = (m + 255) >> 8; 1802*9469f4f1Schristos } else { 1803*9469f4f1Schristos bottomt[i / 2] = 1; 1804*9469f4f1Schristos bottomr[i / 2] = 0; 1805*9469f4f1Schristos M2[i / 2] = m; 1806*9469f4f1Schristos } 1807*9469f4f1Schristos } 1808*9469f4f1Schristos if (i < len) M2[i / 2] = M[i]; 1809*9469f4f1Schristos Decode(R2, S, M2, (len + 1) / 2); 1810*9469f4f1Schristos for (i = 0; i < len - 1; i += 2) { 1811*9469f4f1Schristos uint32_t r1, r = bottomr[i / 2]; 1812*9469f4f1Schristos uint16_t r0; 1813*9469f4f1Schristos r += bottomt[i / 2] * R2[i / 2]; 1814*9469f4f1Schristos uint32_divmod_uint14(&r1, &r0, r, M[i]); 1815*9469f4f1Schristos r1 = uint32_mod_uint14(r1, M[i + 1]); 1816*9469f4f1Schristos *out++ = r0; 1817*9469f4f1Schristos *out++ = r1; 1818*9469f4f1Schristos } 1819*9469f4f1Schristos if (i < len) *out++ = R2[i / 2]; 1820*9469f4f1Schristos } 1821cffc2a7aSchristos } 1822cffc2a7aSchristos 1823*9469f4f1Schristos static void R3_fromRq(small *out, const Fq *r) { 1824*9469f4f1Schristos int i; 1825*9469f4f1Schristos for (i = 0; i < p; ++i) out[i] = F3_freeze(r[i]); 1826cffc2a7aSchristos } 1827cffc2a7aSchristos 1828*9469f4f1Schristos static void R3_mult(small *h, const small *f, const small *g) { 1829*9469f4f1Schristos int16_t fg[p + p - 1]; 1830*9469f4f1Schristos int i, j; 1831*9469f4f1Schristos for (i = 0; i < p + p - 1; ++i) fg[i] = 0; 1832*9469f4f1Schristos for (i = 0; i < p; ++i) 1833*9469f4f1Schristos for (j = 0; j < p; ++j) fg[i + j] += f[i] * (int16_t)g[j]; 1834*9469f4f1Schristos for (i = p; i < p + p - 1; ++i) fg[i - p] += fg[i]; 1835*9469f4f1Schristos for (i = p; i < p + p - 1; ++i) fg[i - p + 1] += fg[i]; 1836*9469f4f1Schristos for (i = 0; i < p; ++i) h[i] = F3_freeze(fg[i]); 1837cffc2a7aSchristos } 1838cffc2a7aSchristos 1839*9469f4f1Schristos static int R3_recip(small *out, const small *in) { 1840*9469f4f1Schristos small f[p + 1], g[p + 1], v[p + 1], r[p + 1]; 1841*9469f4f1Schristos int sign, swap, t, i, loop, delta = 1; 1842*9469f4f1Schristos for (i = 0; i < p + 1; ++i) v[i] = 0; 1843*9469f4f1Schristos for (i = 0; i < p + 1; ++i) r[i] = 0; 1844*9469f4f1Schristos r[0] = 1; 1845*9469f4f1Schristos for (i = 0; i < p; ++i) f[i] = 0; 1846*9469f4f1Schristos f[0] = 1; 1847*9469f4f1Schristos f[p - 1] = f[p] = -1; 1848*9469f4f1Schristos for (i = 0; i < p; ++i) g[p - 1 - i] = in[i]; 1849*9469f4f1Schristos g[p] = 0; 1850*9469f4f1Schristos for (loop = 0; loop < 2 * p - 1; ++loop) { 1851*9469f4f1Schristos for (i = p; i > 0; --i) v[i] = v[i - 1]; 1852*9469f4f1Schristos v[0] = 0; 1853*9469f4f1Schristos sign = -g[0] * f[0]; 1854*9469f4f1Schristos swap = crypto_int16_negative_mask(-delta) & crypto_int16_nonzero_mask(g[0]); 1855*9469f4f1Schristos delta ^= swap & (delta ^ -delta); 1856*9469f4f1Schristos delta += 1; 1857*9469f4f1Schristos for (i = 0; i < p + 1; ++i) { 1858*9469f4f1Schristos t = swap & (f[i] ^ g[i]); 1859*9469f4f1Schristos f[i] ^= t; 1860*9469f4f1Schristos g[i] ^= t; 1861*9469f4f1Schristos t = swap & (v[i] ^ r[i]); 1862*9469f4f1Schristos v[i] ^= t; 1863*9469f4f1Schristos r[i] ^= t; 1864*9469f4f1Schristos } 1865*9469f4f1Schristos for (i = 0; i < p + 1; ++i) g[i] = F3_freeze(g[i] + sign * f[i]); 1866*9469f4f1Schristos for (i = 0; i < p + 1; ++i) r[i] = F3_freeze(r[i] + sign * v[i]); 1867*9469f4f1Schristos for (i = 0; i < p; ++i) g[i] = g[i + 1]; 1868*9469f4f1Schristos g[p] = 0; 1869*9469f4f1Schristos } 1870*9469f4f1Schristos sign = f[0]; 1871*9469f4f1Schristos for (i = 0; i < p; ++i) out[i] = sign * v[p - 1 - i]; 1872*9469f4f1Schristos return crypto_int16_nonzero_mask(delta); 1873cffc2a7aSchristos } 1874cffc2a7aSchristos 1875*9469f4f1Schristos static void Rq_mult_small(Fq *h, const Fq *f, const small *g) { 1876*9469f4f1Schristos int32_t fg[p + p - 1]; 1877*9469f4f1Schristos int i, j; 1878*9469f4f1Schristos for (i = 0; i < p + p - 1; ++i) fg[i] = 0; 1879*9469f4f1Schristos for (i = 0; i < p; ++i) 1880*9469f4f1Schristos for (j = 0; j < p; ++j) fg[i + j] += f[i] * (int32_t)g[j]; 1881*9469f4f1Schristos for (i = p; i < p + p - 1; ++i) fg[i - p] += fg[i]; 1882*9469f4f1Schristos for (i = p; i < p + p - 1; ++i) fg[i - p + 1] += fg[i]; 1883*9469f4f1Schristos for (i = 0; i < p; ++i) h[i] = Fq_freeze(fg[i]); 1884*9469f4f1Schristos } 1885cffc2a7aSchristos 1886*9469f4f1Schristos static void Rq_mult3(Fq *h, const Fq *f) { 1887*9469f4f1Schristos int i; 1888*9469f4f1Schristos for (i = 0; i < p; ++i) h[i] = Fq_freeze(3 * f[i]); 1889*9469f4f1Schristos } 1890*9469f4f1Schristos 1891*9469f4f1Schristos static Fq Fq_recip(Fq a1) { 1892cffc2a7aSchristos int i = 1; 1893cffc2a7aSchristos Fq ai = a1; 1894cffc2a7aSchristos while (i < q - 2) { 1895*9469f4f1Schristos ai = Fq_freeze(a1 * (int32_t)ai); 1896cffc2a7aSchristos i += 1; 1897cffc2a7aSchristos } 1898cffc2a7aSchristos return ai; 1899cffc2a7aSchristos } 1900cffc2a7aSchristos 1901*9469f4f1Schristos static int Rq_recip3(Fq *out, const small *in) { 1902*9469f4f1Schristos Fq f[p + 1], g[p + 1], v[p + 1], r[p + 1], scale; 1903*9469f4f1Schristos int swap, t, i, loop, delta = 1; 1904*9469f4f1Schristos int32_t f0, g0; 1905cffc2a7aSchristos for (i = 0; i < p + 1; ++i) v[i] = 0; 1906cffc2a7aSchristos for (i = 0; i < p + 1; ++i) r[i] = 0; 1907cffc2a7aSchristos r[0] = Fq_recip(3); 1908cffc2a7aSchristos for (i = 0; i < p; ++i) f[i] = 0; 1909*9469f4f1Schristos f[0] = 1; 1910*9469f4f1Schristos f[p - 1] = f[p] = -1; 1911cffc2a7aSchristos for (i = 0; i < p; ++i) g[p - 1 - i] = in[i]; 1912cffc2a7aSchristos g[p] = 0; 1913cffc2a7aSchristos for (loop = 0; loop < 2 * p - 1; ++loop) { 1914cffc2a7aSchristos for (i = p; i > 0; --i) v[i] = v[i - 1]; 1915cffc2a7aSchristos v[0] = 0; 1916*9469f4f1Schristos swap = crypto_int16_negative_mask(-delta) & crypto_int16_nonzero_mask(g[0]); 1917cffc2a7aSchristos delta ^= swap & (delta ^ -delta); 1918cffc2a7aSchristos delta += 1; 1919cffc2a7aSchristos for (i = 0; i < p + 1; ++i) { 1920*9469f4f1Schristos t = swap & (f[i] ^ g[i]); 1921*9469f4f1Schristos f[i] ^= t; 1922*9469f4f1Schristos g[i] ^= t; 1923*9469f4f1Schristos t = swap & (v[i] ^ r[i]); 1924*9469f4f1Schristos v[i] ^= t; 1925*9469f4f1Schristos r[i] ^= t; 1926cffc2a7aSchristos } 1927cffc2a7aSchristos f0 = f[0]; 1928cffc2a7aSchristos g0 = g[0]; 1929cffc2a7aSchristos for (i = 0; i < p + 1; ++i) g[i] = Fq_freeze(f0 * g[i] - g0 * f[i]); 1930cffc2a7aSchristos for (i = 0; i < p + 1; ++i) r[i] = Fq_freeze(f0 * r[i] - g0 * v[i]); 1931cffc2a7aSchristos for (i = 0; i < p; ++i) g[i] = g[i + 1]; 1932cffc2a7aSchristos g[p] = 0; 1933cffc2a7aSchristos } 1934cffc2a7aSchristos scale = Fq_recip(f[0]); 1935*9469f4f1Schristos for (i = 0; i < p; ++i) out[i] = Fq_freeze(scale * (int32_t)v[p - 1 - i]); 1936*9469f4f1Schristos return crypto_int16_nonzero_mask(delta); 1937cffc2a7aSchristos } 1938cffc2a7aSchristos 1939*9469f4f1Schristos static void Round(Fq *out, const Fq *a) { 1940cffc2a7aSchristos int i; 1941cffc2a7aSchristos for (i = 0; i < p; ++i) out[i] = a[i] - F3_freeze(a[i]); 1942cffc2a7aSchristos } 1943cffc2a7aSchristos 1944*9469f4f1Schristos static void Short_fromlist(small *out, const uint32_t *in) { 1945*9469f4f1Schristos uint32_t L[p]; 1946cffc2a7aSchristos int i; 1947*9469f4f1Schristos for (i = 0; i < w; ++i) L[i] = in[i] & (uint32_t)-2; 1948*9469f4f1Schristos for (i = w; i < p; ++i) L[i] = (in[i] & (uint32_t)-3) | 1; 1949cffc2a7aSchristos crypto_sort_uint32(L, p); 1950cffc2a7aSchristos for (i = 0; i < p; ++i) out[i] = (L[i] & 3) - 1; 1951cffc2a7aSchristos } 1952cffc2a7aSchristos 1953*9469f4f1Schristos static void Hash_prefix(unsigned char *out, int b, const unsigned char *in, int inlen) { 1954*9469f4f1Schristos unsigned char x[inlen + 1], h[64]; 1955cffc2a7aSchristos int i; 1956cffc2a7aSchristos x[0] = b; 1957cffc2a7aSchristos for (i = 0; i < inlen; ++i) x[i + 1] = in[i]; 1958cffc2a7aSchristos crypto_hash_sha512(h, x, inlen + 1); 1959cffc2a7aSchristos for (i = 0; i < 32; ++i) out[i] = h[i]; 1960cffc2a7aSchristos } 1961cffc2a7aSchristos 1962*9469f4f1Schristos static uint32_t urandom32(void) { 1963cffc2a7aSchristos unsigned char c[4]; 1964*9469f4f1Schristos uint32_t result = 0; 1965*9469f4f1Schristos int i; 1966cffc2a7aSchristos randombytes(c, 4); 1967*9469f4f1Schristos for (i = 0; i < 4; ++i) result += ((uint32_t)c[i]) << (8 * i); 1968*9469f4f1Schristos return result; 1969cffc2a7aSchristos } 1970cffc2a7aSchristos 1971*9469f4f1Schristos static void Short_random(small *out) { 1972*9469f4f1Schristos uint32_t L[p]; 1973cffc2a7aSchristos int i; 1974cffc2a7aSchristos for (i = 0; i < p; ++i) L[i] = urandom32(); 1975cffc2a7aSchristos Short_fromlist(out, L); 1976cffc2a7aSchristos } 1977cffc2a7aSchristos 1978*9469f4f1Schristos static void Small_random(small *out) { 1979cffc2a7aSchristos int i; 1980cffc2a7aSchristos for (i = 0; i < p; ++i) out[i] = (((urandom32() & 0x3fffffff) * 3) >> 30) - 1; 1981cffc2a7aSchristos } 1982cffc2a7aSchristos 1983*9469f4f1Schristos static void KeyGen(Fq *h, small *f, small *ginv) { 1984cffc2a7aSchristos small g[p]; 1985cffc2a7aSchristos Fq finv[p]; 1986cffc2a7aSchristos for (;;) { 1987*9469f4f1Schristos int result; 1988cffc2a7aSchristos Small_random(g); 1989*9469f4f1Schristos result = R3_recip(ginv, g); 1990*9469f4f1Schristos crypto_declassify(&result, sizeof result); 1991*9469f4f1Schristos if (result == 0) break; 1992cffc2a7aSchristos } 1993cffc2a7aSchristos Short_random(f); 1994*9469f4f1Schristos Rq_recip3(finv, f); 1995cffc2a7aSchristos Rq_mult_small(h, finv, g); 1996cffc2a7aSchristos } 1997cffc2a7aSchristos 1998*9469f4f1Schristos static void Encrypt(Fq *c, const small *r, const Fq *h) { 1999cffc2a7aSchristos Fq hr[p]; 2000cffc2a7aSchristos Rq_mult_small(hr, h, r); 2001cffc2a7aSchristos Round(c, hr); 2002cffc2a7aSchristos } 2003cffc2a7aSchristos 2004*9469f4f1Schristos static void Decrypt(small *r, const Fq *c, const small *f, const small *ginv) { 2005*9469f4f1Schristos Fq cf[p], cf3[p]; 2006*9469f4f1Schristos small e[p], ev[p]; 2007*9469f4f1Schristos int mask, i; 2008cffc2a7aSchristos Rq_mult_small(cf, c, f); 2009cffc2a7aSchristos Rq_mult3(cf3, cf); 2010cffc2a7aSchristos R3_fromRq(e, cf3); 2011cffc2a7aSchristos R3_mult(ev, e, ginv); 2012*9469f4f1Schristos mask = Weightw_mask(ev); 2013cffc2a7aSchristos for (i = 0; i < w; ++i) r[i] = ((ev[i] ^ 1) & ~mask) ^ 1; 2014cffc2a7aSchristos for (i = w; i < p; ++i) r[i] = ev[i] & ~mask; 2015cffc2a7aSchristos } 2016cffc2a7aSchristos 2017*9469f4f1Schristos static void Small_encode(unsigned char *s, const small *f) { 2018*9469f4f1Schristos int i, j; 2019cffc2a7aSchristos for (i = 0; i < p / 4; ++i) { 2020*9469f4f1Schristos small x = 0; 2021*9469f4f1Schristos for (j = 0;j < 4;++j) x += (*f++ + 1) << (2 * j); 2022cffc2a7aSchristos *s++ = x; 2023cffc2a7aSchristos } 2024*9469f4f1Schristos *s = *f++ + 1; 2025cffc2a7aSchristos } 2026cffc2a7aSchristos 2027*9469f4f1Schristos static void Small_decode(small *f, const unsigned char *s) { 2028*9469f4f1Schristos int i, j; 2029cffc2a7aSchristos for (i = 0; i < p / 4; ++i) { 2030*9469f4f1Schristos unsigned char x = *s++; 2031*9469f4f1Schristos for (j = 0;j < 4;++j) *f++ = ((small)((x >> (2 * j)) & 3)) - 1; 2032cffc2a7aSchristos } 2033*9469f4f1Schristos *f++ = ((small)(*s & 3)) - 1; 2034cffc2a7aSchristos } 2035cffc2a7aSchristos 2036*9469f4f1Schristos static void Rq_encode(unsigned char *s, const Fq *r) { 2037*9469f4f1Schristos uint16_t R[p], M[p]; 2038cffc2a7aSchristos int i; 2039cffc2a7aSchristos for (i = 0; i < p; ++i) R[i] = r[i] + q12; 2040cffc2a7aSchristos for (i = 0; i < p; ++i) M[i] = q; 2041cffc2a7aSchristos Encode(s, R, M, p); 2042cffc2a7aSchristos } 2043cffc2a7aSchristos 2044*9469f4f1Schristos static void Rq_decode(Fq *r, const unsigned char *s) { 2045*9469f4f1Schristos uint16_t R[p], M[p]; 2046cffc2a7aSchristos int i; 2047cffc2a7aSchristos for (i = 0; i < p; ++i) M[i] = q; 2048cffc2a7aSchristos Decode(R, s, M, p); 2049cffc2a7aSchristos for (i = 0; i < p; ++i) r[i] = ((Fq)R[i]) - q12; 2050cffc2a7aSchristos } 2051cffc2a7aSchristos 2052*9469f4f1Schristos static void Rounded_encode(unsigned char *s, const Fq *r) { 2053*9469f4f1Schristos uint16_t R[p], M[p]; 2054cffc2a7aSchristos int i; 2055cffc2a7aSchristos for (i = 0; i < p; ++i) R[i] = ((r[i] + q12) * 10923) >> 15; 2056cffc2a7aSchristos for (i = 0; i < p; ++i) M[i] = (q + 2) / 3; 2057cffc2a7aSchristos Encode(s, R, M, p); 2058cffc2a7aSchristos } 2059cffc2a7aSchristos 2060*9469f4f1Schristos static void Rounded_decode(Fq *r, const unsigned char *s) { 2061*9469f4f1Schristos uint16_t R[p], M[p]; 2062cffc2a7aSchristos int i; 2063cffc2a7aSchristos for (i = 0; i < p; ++i) M[i] = (q + 2) / 3; 2064cffc2a7aSchristos Decode(R, s, M, p); 2065cffc2a7aSchristos for (i = 0; i < p; ++i) r[i] = R[i] * 3 - q12; 2066cffc2a7aSchristos } 2067cffc2a7aSchristos 2068*9469f4f1Schristos static void ZKeyGen(unsigned char *pk, unsigned char *sk) { 2069cffc2a7aSchristos Fq h[p]; 2070cffc2a7aSchristos small f[p], v[p]; 2071cffc2a7aSchristos KeyGen(h, f, v); 2072cffc2a7aSchristos Rq_encode(pk, h); 2073*9469f4f1Schristos Small_encode(sk, f); 2074*9469f4f1Schristos Small_encode(sk + Small_bytes, v); 2075cffc2a7aSchristos } 2076cffc2a7aSchristos 2077*9469f4f1Schristos static void ZEncrypt(unsigned char *C, const Inputs r, const unsigned char *pk) { 2078*9469f4f1Schristos Fq h[p], c[p]; 2079cffc2a7aSchristos Rq_decode(h, pk); 2080cffc2a7aSchristos Encrypt(c, r, h); 2081cffc2a7aSchristos Rounded_encode(C, c); 2082cffc2a7aSchristos } 2083cffc2a7aSchristos 2084*9469f4f1Schristos static void ZDecrypt(Inputs r, const unsigned char *C, const unsigned char *sk) { 2085cffc2a7aSchristos small f[p], v[p]; 2086cffc2a7aSchristos Fq c[p]; 2087*9469f4f1Schristos Small_decode(f, sk); 2088*9469f4f1Schristos Small_decode(v, sk + Small_bytes); 2089cffc2a7aSchristos Rounded_decode(c, C); 2090cffc2a7aSchristos Decrypt(r, c, f, v); 2091cffc2a7aSchristos } 2092cffc2a7aSchristos 2093*9469f4f1Schristos static void HashConfirm(unsigned char *h, const unsigned char *r, const unsigned char *cache) { 2094cffc2a7aSchristos unsigned char x[Hash_bytes * 2]; 2095cffc2a7aSchristos int i; 2096*9469f4f1Schristos Hash_prefix(x, 3, r, Small_bytes); 2097cffc2a7aSchristos for (i = 0; i < Hash_bytes; ++i) x[Hash_bytes + i] = cache[i]; 2098cffc2a7aSchristos Hash_prefix(h, 2, x, sizeof x); 2099cffc2a7aSchristos } 2100cffc2a7aSchristos 2101*9469f4f1Schristos static void HashSession(unsigned char *k, int b, const unsigned char *y, const unsigned char *z) { 2102*9469f4f1Schristos unsigned char x[Hash_bytes + crypto_kem_sntrup761_CIPHERTEXTBYTES]; 2103cffc2a7aSchristos int i; 2104*9469f4f1Schristos Hash_prefix(x, 3, y, Small_bytes); 2105*9469f4f1Schristos for (i = 0; i < crypto_kem_sntrup761_CIPHERTEXTBYTES; ++i) x[Hash_bytes + i] = z[i]; 2106cffc2a7aSchristos Hash_prefix(k, b, x, sizeof x); 2107cffc2a7aSchristos } 2108cffc2a7aSchristos 2109*9469f4f1Schristos int crypto_kem_sntrup761_keypair(unsigned char *pk, unsigned char *sk) { 2110cffc2a7aSchristos int i; 2111*9469f4f1Schristos ZKeyGen(pk, sk); 2112*9469f4f1Schristos sk += SecretKeys_bytes; 2113*9469f4f1Schristos for (i = 0; i < crypto_kem_sntrup761_PUBLICKEYBYTES; ++i) *sk++ = pk[i]; 2114*9469f4f1Schristos randombytes(sk, Small_bytes); 2115*9469f4f1Schristos Hash_prefix(sk + Small_bytes, 4, pk, crypto_kem_sntrup761_PUBLICKEYBYTES); 2116*9469f4f1Schristos return 0; 2117cffc2a7aSchristos } 2118cffc2a7aSchristos 2119*9469f4f1Schristos static void Hide(unsigned char *c, unsigned char *r_enc, const Inputs r, const unsigned char *pk, const unsigned char *cache) { 2120*9469f4f1Schristos Small_encode(r_enc, r); 2121*9469f4f1Schristos ZEncrypt(c, r, pk); 2122*9469f4f1Schristos HashConfirm(c + crypto_kem_sntrup761_CIPHERTEXTBYTES - Confirm_bytes, r_enc, cache); 2123cffc2a7aSchristos } 2124cffc2a7aSchristos 2125*9469f4f1Schristos int crypto_kem_sntrup761_enc(unsigned char *c, unsigned char *k, const unsigned char *pk) { 2126cffc2a7aSchristos Inputs r; 2127*9469f4f1Schristos unsigned char r_enc[Small_bytes], cache[Hash_bytes]; 2128*9469f4f1Schristos Hash_prefix(cache, 4, pk, crypto_kem_sntrup761_PUBLICKEYBYTES); 2129*9469f4f1Schristos Short_random(r); 2130cffc2a7aSchristos Hide(c, r_enc, r, pk, cache); 2131cffc2a7aSchristos HashSession(k, 1, r_enc, c); 2132*9469f4f1Schristos return 0; 2133cffc2a7aSchristos } 2134cffc2a7aSchristos 2135*9469f4f1Schristos static int Ciphertexts_diff_mask(const unsigned char *c, const unsigned char *c2) { 2136*9469f4f1Schristos uint16_t differentbits = 0; 2137*9469f4f1Schristos int len = crypto_kem_sntrup761_CIPHERTEXTBYTES; 2138cffc2a7aSchristos while (len-- > 0) differentbits |= (*c++) ^ (*c2++); 2139*9469f4f1Schristos return (crypto_int64_bitmod_01((differentbits - 1),8)) - 1; 2140cffc2a7aSchristos } 2141cffc2a7aSchristos 2142*9469f4f1Schristos int crypto_kem_sntrup761_dec(unsigned char *k, const unsigned char *c, const unsigned char *sk) { 2143cffc2a7aSchristos const unsigned char *pk = sk + SecretKeys_bytes; 2144*9469f4f1Schristos const unsigned char *rho = pk + crypto_kem_sntrup761_PUBLICKEYBYTES; 2145*9469f4f1Schristos const unsigned char *cache = rho + Small_bytes; 2146cffc2a7aSchristos Inputs r; 2147*9469f4f1Schristos unsigned char r_enc[Small_bytes], cnew[crypto_kem_sntrup761_CIPHERTEXTBYTES]; 2148*9469f4f1Schristos int mask, i; 2149cffc2a7aSchristos ZDecrypt(r, c, sk); 2150cffc2a7aSchristos Hide(cnew, r_enc, r, pk, cache); 2151cffc2a7aSchristos mask = Ciphertexts_diff_mask(c, cnew); 2152*9469f4f1Schristos for (i = 0; i < Small_bytes; ++i) r_enc[i] ^= mask & (r_enc[i] ^ rho[i]); 2153cffc2a7aSchristos HashSession(k, 1 + mask, r_enc, c); 2154cffc2a7aSchristos return 0; 2155cffc2a7aSchristos } 2156cffc2a7aSchristos 2157