Add 64-bit integer utilities
This commit is contained in:
		
							parent
							
								
									e541a90ef6
								
							
						
					
					
						commit
						e1fb4af90b
					
				@ -230,6 +230,12 @@ else
 | 
				
			|||||||
  set_precomp=no
 | 
					  set_precomp=no
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AC_MSG_CHECKING([for  __builtin_clzll])
 | 
				
			||||||
 | 
					AC_COMPILE_IFELSE([AC_LANG_SOURCE([[void myfunc() { __builtin_clzll(1);}]])],
 | 
				
			||||||
 | 
					    [ AC_MSG_RESULT([yes]);AC_DEFINE(HAVE_BUILTIN_CLZLL,1,[Define this symbol if  __builtin_clzll is available]) ],
 | 
				
			||||||
 | 
					    [ AC_MSG_RESULT([no])
 | 
				
			||||||
 | 
					    ])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if test x"$req_asm" = x"auto"; then
 | 
					if test x"$req_asm" = x"auto"; then
 | 
				
			||||||
  SECP_64BIT_ASM_CHECK
 | 
					  SECP_64BIT_ASM_CHECK
 | 
				
			||||||
  if test x"$has_64bit_asm" = x"yes"; then
 | 
					  if test x"$has_64bit_asm" = x"yes"; then
 | 
				
			||||||
 | 
				
			|||||||
@ -35,4 +35,7 @@ static void secp256k1_rand256_test(unsigned char *b32);
 | 
				
			|||||||
/** Generate pseudorandom bytes with long sequences of zero and one bits. */
 | 
					/** Generate pseudorandom bytes with long sequences of zero and one bits. */
 | 
				
			||||||
static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len);
 | 
					static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Generate a pseudorandom 64-bit integer in the range min..max, inclusive. */
 | 
				
			||||||
 | 
					static int64_t secp256k1_rands64(uint64_t min, uint64_t max);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* SECP256K1_TESTRAND_H */
 | 
					#endif /* SECP256K1_TESTRAND_H */
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
/**********************************************************************
 | 
					/**********************************************************************
 | 
				
			||||||
 * Copyright (c) 2013-2015 Pieter Wuille                              *
 | 
					 * Copyright (c) 2013-2015 Pieter Wuille, Gregory Maxwell             *
 | 
				
			||||||
 * Distributed under the MIT software license, see the accompanying   *
 | 
					 * Distributed under the MIT software license, see the accompanying   *
 | 
				
			||||||
 * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
 | 
					 * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
 | 
				
			||||||
 **********************************************************************/
 | 
					 **********************************************************************/
 | 
				
			||||||
@ -107,4 +107,21 @@ static void secp256k1_rand256_test(unsigned char *b32) {
 | 
				
			|||||||
    secp256k1_rand_bytes_test(b32, 32);
 | 
					    secp256k1_rand_bytes_test(b32, 32);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SECP256K1_INLINE static int64_t secp256k1_rands64(uint64_t min, uint64_t max) {
 | 
				
			||||||
 | 
					    uint64_t range;
 | 
				
			||||||
 | 
					    uint64_t r;
 | 
				
			||||||
 | 
					    uint64_t clz;
 | 
				
			||||||
 | 
					    VERIFY_CHECK(max >= min);
 | 
				
			||||||
 | 
					    if (max == min) {
 | 
				
			||||||
 | 
					        return min;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    range = max - min;
 | 
				
			||||||
 | 
					    clz = secp256k1_clz64_var(range);
 | 
				
			||||||
 | 
					    do {
 | 
				
			||||||
 | 
					        r = ((uint64_t)secp256k1_rand32() << 32) | secp256k1_rand32();
 | 
				
			||||||
 | 
					        r >>= clz;
 | 
				
			||||||
 | 
					    } while (r > range);
 | 
				
			||||||
 | 
					    return min + (int64_t)r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* SECP256K1_TESTRAND_IMPL_H */
 | 
					#endif /* SECP256K1_TESTRAND_IMPL_H */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										49
									
								
								src/tests.c
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								src/tests.c
									
									
									
									
									
								
							@ -1,5 +1,5 @@
 | 
				
			|||||||
/**********************************************************************
 | 
					/**********************************************************************
 | 
				
			||||||
 * Copyright (c) 2013, 2014, 2015 Pieter Wuille, Gregory Maxwell      *
 | 
					 * Copyright (c) 2013-2015 Pieter Wuille, Gregory Maxwell             *
 | 
				
			||||||
 * Distributed under the MIT software license, see the accompanying   *
 | 
					 * Distributed under the MIT software license, see the accompanying   *
 | 
				
			||||||
 * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
 | 
					 * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
 | 
				
			||||||
 **********************************************************************/
 | 
					 **********************************************************************/
 | 
				
			||||||
@ -140,6 +140,52 @@ void random_scalar_order(secp256k1_scalar *num) {
 | 
				
			|||||||
    } while(1);
 | 
					    } while(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void run_util_tests(void) {
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					    uint64_t r;
 | 
				
			||||||
 | 
					    uint64_t r2;
 | 
				
			||||||
 | 
					    uint64_t r3;
 | 
				
			||||||
 | 
					    int64_t s;
 | 
				
			||||||
 | 
					    CHECK(secp256k1_clz64_var(0) == 64);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_clz64_var(1) == 63);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_clz64_var(2) == 62);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_clz64_var(3) == 62);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_clz64_var(~0ULL) == 0);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_clz64_var((~0ULL) - 1) == 0);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_clz64_var((~0ULL) >> 1) == 1);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_clz64_var((~0ULL) >> 2) == 2);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_sign_and_abs64(&r, INT64_MAX) == 0);
 | 
				
			||||||
 | 
					    CHECK(r == INT64_MAX);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_sign_and_abs64(&r, INT64_MAX - 1) == 0);
 | 
				
			||||||
 | 
					    CHECK(r == INT64_MAX - 1);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_sign_and_abs64(&r, INT64_MIN) == 1);
 | 
				
			||||||
 | 
					    CHECK(r == (uint64_t)INT64_MAX + 1);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_sign_and_abs64(&r, INT64_MIN + 1) == 1);
 | 
				
			||||||
 | 
					    CHECK(r == (uint64_t)INT64_MAX);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_sign_and_abs64(&r, 0) == 0);
 | 
				
			||||||
 | 
					    CHECK(r == 0);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_sign_and_abs64(&r, 1) == 0);
 | 
				
			||||||
 | 
					    CHECK(r == 1);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_sign_and_abs64(&r, -1) == 1);
 | 
				
			||||||
 | 
					    CHECK(r == 1);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_sign_and_abs64(&r, 2) == 0);
 | 
				
			||||||
 | 
					    CHECK(r == 2);
 | 
				
			||||||
 | 
					    CHECK(secp256k1_sign_and_abs64(&r, -2) == 1);
 | 
				
			||||||
 | 
					    CHECK(r == 2);
 | 
				
			||||||
 | 
					    for (i = 0; i < 10; i++) {
 | 
				
			||||||
 | 
					        CHECK(secp256k1_clz64_var((~0ULL) - secp256k1_rand32()) == 0);
 | 
				
			||||||
 | 
					        r = ((uint64_t)secp256k1_rand32() << 32) | secp256k1_rand32();
 | 
				
			||||||
 | 
					        r2 = secp256k1_rands64(0, r);
 | 
				
			||||||
 | 
					        CHECK(r2 <= r);
 | 
				
			||||||
 | 
					        r3 = secp256k1_rands64(r2, r);
 | 
				
			||||||
 | 
					        CHECK((r3 >= r2) && (r3 <= r));
 | 
				
			||||||
 | 
					        r = secp256k1_rands64(0, INT64_MAX);
 | 
				
			||||||
 | 
					        s = (int64_t)r * (secp256k1_rand32()&1?-1:1);
 | 
				
			||||||
 | 
					        CHECK(secp256k1_sign_and_abs64(&r2, s) == (s < 0));
 | 
				
			||||||
 | 
					        CHECK(r2 == r);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void run_context_tests(int use_prealloc) {
 | 
					void run_context_tests(int use_prealloc) {
 | 
				
			||||||
    secp256k1_pubkey pubkey;
 | 
					    secp256k1_pubkey pubkey;
 | 
				
			||||||
    secp256k1_pubkey zero_pubkey;
 | 
					    secp256k1_pubkey zero_pubkey;
 | 
				
			||||||
@ -5223,6 +5269,7 @@ int main(int argc, char **argv) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    run_rand_bits();
 | 
					    run_rand_bits();
 | 
				
			||||||
    run_rand_int();
 | 
					    run_rand_int();
 | 
				
			||||||
 | 
					    run_util_tests();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    run_sha256_tests();
 | 
					    run_sha256_tests();
 | 
				
			||||||
    run_hmac_sha256_tests();
 | 
					    run_hmac_sha256_tests();
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										28
									
								
								src/util.h
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								src/util.h
									
									
									
									
									
								
							@ -1,5 +1,5 @@
 | 
				
			|||||||
/**********************************************************************
 | 
					/**********************************************************************
 | 
				
			||||||
 * Copyright (c) 2013, 2014 Pieter Wuille                             *
 | 
					 * Copyright (c) 2013-2015 Pieter Wuille, Gregory Maxwell             *
 | 
				
			||||||
 * Distributed under the MIT software license, see the accompanying   *
 | 
					 * Distributed under the MIT software license, see the accompanying   *
 | 
				
			||||||
 * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
 | 
					 * file COPYING or http://www.opensource.org/licenses/mit-license.php.*
 | 
				
			||||||
 **********************************************************************/
 | 
					 **********************************************************************/
 | 
				
			||||||
@ -125,6 +125,32 @@ static SECP256K1_INLINE void *manual_alloc(void** prealloc_ptr, size_t alloc_siz
 | 
				
			|||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Extract the sign of an int64, take the abs and return a uint64, constant time. */
 | 
				
			||||||
 | 
					SECP256K1_INLINE static int secp256k1_sign_and_abs64(uint64_t *out, int64_t in) {
 | 
				
			||||||
 | 
					    uint64_t mask0, mask1;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    ret = in < 0;
 | 
				
			||||||
 | 
					    mask0 = ret + ~((uint64_t)0);
 | 
				
			||||||
 | 
					    mask1 = ~mask0;
 | 
				
			||||||
 | 
					    *out = (uint64_t)in;
 | 
				
			||||||
 | 
					    *out = (*out & mask0) | ((~*out + 1) & mask1);
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SECP256K1_INLINE static int secp256k1_clz64_var(uint64_t x) {
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					    if (!x) {
 | 
				
			||||||
 | 
					        return 64;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					# if defined(HAVE_BUILTIN_CLZLL)
 | 
				
			||||||
 | 
					    ret = __builtin_clzll(x);
 | 
				
			||||||
 | 
					# else
 | 
				
			||||||
 | 
					    /*FIXME: debruijn fallback. */
 | 
				
			||||||
 | 
					    for (ret = 0; ((x & (1ULL << 63)) == 0); x <<= 1, ret++);
 | 
				
			||||||
 | 
					# endif
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Macro for restrict, when available and not in a VERIFY build. */
 | 
					/* Macro for restrict, when available and not in a VERIFY build. */
 | 
				
			||||||
#if defined(SECP256K1_BUILD) && defined(VERIFY)
 | 
					#if defined(SECP256K1_BUILD) && defined(VERIFY)
 | 
				
			||||||
# define SECP256K1_RESTRICT
 | 
					# define SECP256K1_RESTRICT
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user