diff options
author | Johan Pascal <johan.pascal@linphone.org> | 2020-11-23 21:19:41 +0100 |
---|---|---|
committer | Johan Pascal <johan.pascal@linphone.org> | 2020-11-23 21:19:41 +0100 |
commit | fc42c673ab72de074d54c8ab76dfda8af3d99682 (patch) | |
tree | 6361b1bfc877f3363b422fbcb260df57174dc066 | |
parent | Avoid branching on mask bit extension. (diff) | |
download | goldilocks-fc42c673ab72de074d54c8ab76dfda8af3d99682.tar.xz goldilocks-fc42c673ab72de074d54c8ab76dfda8af3d99682.zip |
Expand bit to mask as inline function
use the -1 to unsigned integer trick, disable windows C4146
-rw-r--r-- | src/include/word.h | 16 | ||||
-rw-r--r-- | src/per_curve/decaf.tmpl.c | 2 | ||||
-rw-r--r-- | src/per_curve/elligator.tmpl.c | 8 | ||||
-rw-r--r-- | src/per_curve/scalar.tmpl.c | 2 | ||||
-rw-r--r-- | src/per_field/f_generic.tmpl.c | 2 |
5 files changed, 23 insertions, 7 deletions
diff --git a/src/include/word.h b/src/include/word.h index d10a804..7eb4f2a 100644 --- a/src/include/word.h +++ b/src/include/word.h @@ -67,6 +67,22 @@ extern int posix_memalign(void **, size_t, size_t); #else #error "For now, libdecaf only supports 32- and 64-bit architectures." #endif + +/** + * Expand bit 0 of the given uint8_t to a mask_t all 1 or all 0 + * The input must be either 0 or 1 + */ +DECAF_INLINE mask_t bit_to_mask(uint8_t bit) { +#ifdef _MSC_VER +#pragma warning ( push) +#pragma warning ( disable : 4146) +#endif + return -bit; +#ifdef _MSC_VER +#pragma warning ( pop) +#endif + +} /* Scalar limbs are keyed off of the API word size instead of the arch word size. */ #if DECAF_WORD_BITS == 64 diff --git a/src/per_curve/decaf.tmpl.c b/src/per_curve/decaf.tmpl.c index 89c1685..abdee61 100644 --- a/src/per_curve/decaf.tmpl.c +++ b/src/per_curve/decaf.tmpl.c @@ -1272,7 +1272,7 @@ decaf_error_t decaf_x$(gf_shortname) ( if (t/8==0) sb &= -(uint8_t)COFACTOR; else if (t == X_PRIVATE_BITS-1) sb = -1; - mask_t k_t = ~((1 - ((sb>>(t%8)) & 1))*DECAF_MASK_ALL_SET); /* expand mask bit 0 to the whole mask without branching */ + mask_t k_t = bit_to_mask((sb>>(t%8)) & 1); swap ^= k_t; gf_cond_swap(x2,x3,swap); diff --git a/src/per_curve/elligator.tmpl.c b/src/per_curve/elligator.tmpl.c index 98672de..0210d0a 100644 --- a/src/per_curve/elligator.tmpl.c +++ b/src/per_curve/elligator.tmpl.c @@ -109,13 +109,13 @@ API_NS(invert_elligator_nonuniform) ( uint32_t hint_ ) { mask_t hint = hint_; - mask_t sgn_s = ~((1 - (hint & 1))*DECAF_MASK_ALL_SET), /* expand hint bit 0 to the whole mask without branching */ - sgn_altx = ~((1 - (hint>>1 & 1))*DECAF_MASK_ALL_SET), - sgn_r0 = ~((1 - (hint>>2 & 1))*DECAF_MASK_ALL_SET), + mask_t sgn_s = bit_to_mask(hint & 1), + sgn_altx = bit_to_mask((hint>>1) & 1), + sgn_r0 = bit_to_mask((hint>>2) & 1), /* FUTURE MAGIC: eventually if there's a curve which needs sgn_ed_T but not sgn_r0, * change this mask extraction. */ - sgn_ed_T = ~((1 - (hint>>3 & 1))*DECAF_MASK_ALL_SET); + sgn_ed_T = bit_to_mask((hint>>3) & 1); gf a,b,c; API_NS(deisogenize)(a,b,c,p,sgn_s,sgn_altx,sgn_ed_T); diff --git a/src/per_curve/scalar.tmpl.c b/src/per_curve/scalar.tmpl.c index d95eb07..24d32cf 100644 --- a/src/per_curve/scalar.tmpl.c +++ b/src/per_curve/scalar.tmpl.c @@ -314,7 +314,7 @@ void API_NS(scalar_halve) ( scalar_t out, const scalar_t a ) { - decaf_word_t mask = ~((1-(a->limb[0] & 1))*DECAF_WORD_ALL_SET); /* expand a->limb[0] bit 0 to the whole mask without branching */ + decaf_word_t mask = bit_to_mask((a->limb[0]) & 1); decaf_dword_t chain = 0; unsigned int i; for (i=0; i<SCALAR_LIMBS; i++) { diff --git a/src/per_field/f_generic.tmpl.c b/src/per_field/f_generic.tmpl.c index 489f91a..33110f1 100644 --- a/src/per_field/f_generic.tmpl.c +++ b/src/per_field/f_generic.tmpl.c @@ -37,7 +37,7 @@ mask_t gf_lobit(const gf x) { gf y; gf_copy(y,x); gf_strong_reduce(y); - return ~((1-(y->limb[0]&1))*DECAF_MASK_ALL_SET); /* expand y->limb[0] bit 0 to the whole mask without branching */ + return bit_to_mask((y->limb[0]) & 1); } /** Deserialize from wire format; return -1 on success and 0 on failure. */ |