M sha_consts/sha_consts.c => sha_consts/sha_consts.c +20 -27
@@ 124,8 124,8 @@ void frac64(const unsigned long int *primes, int n)
mpfr_t prime, cbrt_prime;
- /* We assume 113 bits of precision according to IEEE-754 Quadruple precision
- * binary 128 bit floating point numbers */
+ /* We assume 113 bits of precision according to IEEE-754 Quadruple
+ * precision binary 128 bit floating point numbers */
mpfr_prec_t prec = 113;
mpfr_inits2(prec, prime, cbrt_prime, (mpfr_ptr) 0);
@@ 137,34 137,27 @@ void frac64(const unsigned long int *primes, int n)
/* MPFR's cube root function */
mpfr_cbrt(cbrt_prime, prime, MPFR_RNDN);
- /* This is an attempt to get raw significand bytes out of MPFR */
+ /*
+ * This is an attempt to get raw significand bytes out of MPFR
+ */
- /* The `mpfr_custom_get_significand()` function returns a pointer to
- * the significand in memory. We shall cast this into a custom type
- * which is able to handle 128 bits of data and we can then access its
- * higher order bits and lower order bits and extract the fractional
- * part accordingly. */
- sig128_t significand = *(sig128_t *)
- mpfr_custom_get_significand(cbrt_prime);
+ /* The `mpfr_custom_get_significand()` function returns a
+ * pointer to the significand in memory which in this case is
+ * 128 bits wide. I don't know how good the support for
+ * `__int128` is, but at least GCC and clang are happy to
+ * compile this for x86_64 with GCC slightly bitching because
+ * of `-Wpedantic` which is fixed by prefixing the type with
+ * `__extension__`. Hence I'm ditching the idea of using a
+ * special struct and figuring out the endianness BS and using
+ * `__int128`. Let's see what breaks!
+ */
+ __extension__ unsigned __int128 significand = *(unsigned __int128 *)
+ mpfr_custom_get_significand(cbrt_prime);
int exponent = mpfr_custom_get_exp(cbrt_prime);
- /* Due to MPFR preserving endianess throughout the length of the
- * significand, the upper and lower 64-bit words need to be swapped in
- * case the machine is little endian.
- *
- * Here we deternine the endianess in a quick and dirty way: */
- int end_check = 1;
- if ( *(uint8_t *) &end_check ) {
- /* We detect little endian system */
- uint64_t temp = significand.upper;
- significand.upper = significand.lower;
- significand.lower = temp;
- }
-
- /* Then shift the entire 128 bit word left by the exponent */
- uint64_t fractional_part = significand.upper << exponent
- |
- significand.lower >> (64 - exponent);
+ /* Shift the entire 128 bit word left by the exponent and then
+ * take the most significand 64 bits. */
+ uint64_t fractional_part = significand >> (64 - exponent);
printf("0x%016"PRIx64"\n", fractional_part);
}
M sha_consts/sha_consts.h => sha_consts/sha_consts.h +0 -7
@@ 1,13 1,6 @@
#ifndef _SHA_CONSTS_H
# define _SHA_CONSTS_H
-# include <stdint.h>
-
-typedef struct {
- uint64_t upper;
- uint64_t lower;
-} sig128_t;
-
void frac32(const unsigned long int *, int);
void frac64(const unsigned long int *, int);