mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 13:53:31 +01:00
Extract simple integer math into its own module
This commit is contained in:
parent
3883338c81
commit
2cf033f238
2
.gitignore
vendored
2
.gitignore
vendored
@ -173,6 +173,8 @@ uptime-*.json
|
|||||||
/src/lib/libtor-ctime-testing.a
|
/src/lib/libtor-ctime-testing.a
|
||||||
/src/lib/libtor-err.a
|
/src/lib/libtor-err.a
|
||||||
/src/lib/libtor-err-testing.a
|
/src/lib/libtor-err-testing.a
|
||||||
|
/src/lib/libtor-intmath.a
|
||||||
|
/src/lib/libtor-intmath-testing.a
|
||||||
/src/lib/libtor-malloc.a
|
/src/lib/libtor-malloc.a
|
||||||
/src/lib/libtor-malloc-testing.a
|
/src/lib/libtor-malloc-testing.a
|
||||||
/src/lib/libtor-string.a
|
/src/lib/libtor-string.a
|
||||||
|
@ -45,6 +45,7 @@ TOR_UTIL_LIBS = \
|
|||||||
src/lib/libtor-malloc.a \
|
src/lib/libtor-malloc.a \
|
||||||
src/lib/libtor-wallclock.a \
|
src/lib/libtor-wallclock.a \
|
||||||
src/lib/libtor-err.a \
|
src/lib/libtor-err.a \
|
||||||
|
src/lib/libtor-intmath.a \
|
||||||
src/lib/libtor-ctime.a
|
src/lib/libtor-ctime.a
|
||||||
|
|
||||||
# Variants of the above for linking the testing variant of tor (for coverage
|
# Variants of the above for linking the testing variant of tor (for coverage
|
||||||
@ -56,6 +57,7 @@ TOR_UTIL_TESTING_LIBS = \
|
|||||||
src/lib/libtor-malloc-testing.a \
|
src/lib/libtor-malloc-testing.a \
|
||||||
src/lib/libtor-wallclock-testing.a \
|
src/lib/libtor-wallclock-testing.a \
|
||||||
src/lib/libtor-err-testing.a \
|
src/lib/libtor-err-testing.a \
|
||||||
|
src/lib/libtor-intmath.a \
|
||||||
src/lib/libtor-ctime-testing.a
|
src/lib/libtor-ctime-testing.a
|
||||||
|
|
||||||
# Internal crypto libraries used in Tor
|
# Internal crypto libraries used in Tor
|
||||||
|
@ -166,105 +166,6 @@ tor_llround(double d)
|
|||||||
#endif /* defined(HAVE_LLROUND) || ... */
|
#endif /* defined(HAVE_LLROUND) || ... */
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns floor(log2(u64)). If u64 is 0, (incorrectly) returns 0. */
|
|
||||||
int
|
|
||||||
tor_log2(uint64_t u64)
|
|
||||||
{
|
|
||||||
int r = 0;
|
|
||||||
if (u64 >= (U64_LITERAL(1)<<32)) {
|
|
||||||
u64 >>= 32;
|
|
||||||
r = 32;
|
|
||||||
}
|
|
||||||
if (u64 >= (U64_LITERAL(1)<<16)) {
|
|
||||||
u64 >>= 16;
|
|
||||||
r += 16;
|
|
||||||
}
|
|
||||||
if (u64 >= (U64_LITERAL(1)<<8)) {
|
|
||||||
u64 >>= 8;
|
|
||||||
r += 8;
|
|
||||||
}
|
|
||||||
if (u64 >= (U64_LITERAL(1)<<4)) {
|
|
||||||
u64 >>= 4;
|
|
||||||
r += 4;
|
|
||||||
}
|
|
||||||
if (u64 >= (U64_LITERAL(1)<<2)) {
|
|
||||||
u64 >>= 2;
|
|
||||||
r += 2;
|
|
||||||
}
|
|
||||||
if (u64 >= (U64_LITERAL(1)<<1)) {
|
|
||||||
// u64 >>= 1; // not using this any more.
|
|
||||||
r += 1;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return the power of 2 in range [1,UINT64_MAX] closest to <b>u64</b>. If
|
|
||||||
* there are two powers of 2 equally close, round down. */
|
|
||||||
uint64_t
|
|
||||||
round_to_power_of_2(uint64_t u64)
|
|
||||||
{
|
|
||||||
int lg2;
|
|
||||||
uint64_t low;
|
|
||||||
uint64_t high;
|
|
||||||
if (u64 == 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
lg2 = tor_log2(u64);
|
|
||||||
low = U64_LITERAL(1) << lg2;
|
|
||||||
|
|
||||||
if (lg2 == 63)
|
|
||||||
return low;
|
|
||||||
|
|
||||||
high = U64_LITERAL(1) << (lg2+1);
|
|
||||||
if (high - u64 < u64 - low)
|
|
||||||
return high;
|
|
||||||
else
|
|
||||||
return low;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return the lowest x such that x is at least <b>number</b>, and x modulo
|
|
||||||
* <b>divisor</b> == 0. If no such x can be expressed as an unsigned, return
|
|
||||||
* UINT_MAX. Asserts if divisor is zero. */
|
|
||||||
unsigned
|
|
||||||
round_to_next_multiple_of(unsigned number, unsigned divisor)
|
|
||||||
{
|
|
||||||
tor_assert(divisor > 0);
|
|
||||||
if (UINT_MAX - divisor + 1 < number)
|
|
||||||
return UINT_MAX;
|
|
||||||
number += divisor - 1;
|
|
||||||
number -= number % divisor;
|
|
||||||
return number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return the lowest x such that x is at least <b>number</b>, and x modulo
|
|
||||||
* <b>divisor</b> == 0. If no such x can be expressed as a uint32_t, return
|
|
||||||
* UINT32_MAX. Asserts if divisor is zero. */
|
|
||||||
uint32_t
|
|
||||||
round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor)
|
|
||||||
{
|
|
||||||
tor_assert(divisor > 0);
|
|
||||||
if (UINT32_MAX - divisor + 1 < number)
|
|
||||||
return UINT32_MAX;
|
|
||||||
|
|
||||||
number += divisor - 1;
|
|
||||||
number -= number % divisor;
|
|
||||||
return number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return the lowest x such that x is at least <b>number</b>, and x modulo
|
|
||||||
* <b>divisor</b> == 0. If no such x can be expressed as a uint64_t, return
|
|
||||||
* UINT64_MAX. Asserts if divisor is zero. */
|
|
||||||
uint64_t
|
|
||||||
round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor)
|
|
||||||
{
|
|
||||||
tor_assert(divisor > 0);
|
|
||||||
if (UINT64_MAX - divisor + 1 < number)
|
|
||||||
return UINT64_MAX;
|
|
||||||
number += divisor - 1;
|
|
||||||
number -= number % divisor;
|
|
||||||
return number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Transform a random value <b>p</b> from the uniform distribution in
|
/** Transform a random value <b>p</b> from the uniform distribution in
|
||||||
* [0.0, 1.0[ into a Laplace distributed value with location parameter
|
* [0.0, 1.0[ into a Laplace distributed value with location parameter
|
||||||
* <b>mu</b> and scale parameter <b>b</b>. Truncate the final result
|
* <b>mu</b> and scale parameter <b>b</b>. Truncate the final result
|
||||||
@ -319,68 +220,6 @@ add_laplace_noise(int64_t signal_, double random_, double delta_f,
|
|||||||
return signal_ + noise;
|
return signal_ + noise;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper: safely add two uint32_t's, capping at UINT32_MAX rather
|
|
||||||
* than overflow */
|
|
||||||
uint32_t
|
|
||||||
tor_add_u32_nowrap(uint32_t a, uint32_t b)
|
|
||||||
{
|
|
||||||
/* a+b > UINT32_MAX check, without overflow */
|
|
||||||
if (PREDICT_UNLIKELY(a > UINT32_MAX - b)) {
|
|
||||||
return UINT32_MAX;
|
|
||||||
} else {
|
|
||||||
return a+b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Helper: return greatest common divisor of a,b */
|
|
||||||
static uint64_t
|
|
||||||
gcd64(uint64_t a, uint64_t b)
|
|
||||||
{
|
|
||||||
while (b) {
|
|
||||||
uint64_t t = b;
|
|
||||||
b = a % b;
|
|
||||||
a = t;
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given a fraction *<b>numer</b> / *<b>denom</b>, simplify it.
|
|
||||||
* Requires that the denominator is greater than 0. */
|
|
||||||
void
|
|
||||||
simplify_fraction64(uint64_t *numer, uint64_t *denom)
|
|
||||||
{
|
|
||||||
tor_assert(denom);
|
|
||||||
uint64_t gcd = gcd64(*numer, *denom);
|
|
||||||
*numer /= gcd;
|
|
||||||
*denom /= gcd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Return the number of bits set in <b>v</b>. */
|
|
||||||
int
|
|
||||||
n_bits_set_u8(uint8_t v)
|
|
||||||
{
|
|
||||||
static const int nybble_table[] = {
|
|
||||||
0, /* 0000 */
|
|
||||||
1, /* 0001 */
|
|
||||||
1, /* 0010 */
|
|
||||||
2, /* 0011 */
|
|
||||||
1, /* 0100 */
|
|
||||||
2, /* 0101 */
|
|
||||||
2, /* 0110 */
|
|
||||||
3, /* 0111 */
|
|
||||||
1, /* 1000 */
|
|
||||||
2, /* 1001 */
|
|
||||||
2, /* 1010 */
|
|
||||||
3, /* 1011 */
|
|
||||||
2, /* 1100 */
|
|
||||||
3, /* 1101 */
|
|
||||||
3, /* 1110 */
|
|
||||||
4, /* 1111 */
|
|
||||||
};
|
|
||||||
|
|
||||||
return nybble_table[v & 15] + nybble_table[v>>4];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =====
|
/* =====
|
||||||
* String manipulation
|
* String manipulation
|
||||||
* ===== */
|
* ===== */
|
||||||
|
@ -27,6 +27,10 @@
|
|||||||
#include "lib/wallclock/approx_time.h"
|
#include "lib/wallclock/approx_time.h"
|
||||||
#include "lib/string/util_string.h"
|
#include "lib/string/util_string.h"
|
||||||
#include "lib/string/scanf.h"
|
#include "lib/string/scanf.h"
|
||||||
|
#include "lib/intmath/bits.h"
|
||||||
|
#include "lib/intmath/addsub.h"
|
||||||
|
#include "lib/intmath/muldiv.h"
|
||||||
|
#include "lib/intmath/cmp.h"
|
||||||
#include "common/util_bug.h"
|
#include "common/util_bug.h"
|
||||||
|
|
||||||
#ifndef O_BINARY
|
#ifndef O_BINARY
|
||||||
@ -66,35 +70,10 @@ void tor_log_mallinfo(int severity);
|
|||||||
double tor_mathlog(double d) ATTR_CONST;
|
double tor_mathlog(double d) ATTR_CONST;
|
||||||
long tor_lround(double d) ATTR_CONST;
|
long tor_lround(double d) ATTR_CONST;
|
||||||
int64_t tor_llround(double d) ATTR_CONST;
|
int64_t tor_llround(double d) ATTR_CONST;
|
||||||
int tor_log2(uint64_t u64) ATTR_CONST;
|
|
||||||
uint64_t round_to_power_of_2(uint64_t u64);
|
|
||||||
unsigned round_to_next_multiple_of(unsigned number, unsigned divisor);
|
|
||||||
uint32_t round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor);
|
|
||||||
uint64_t round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor);
|
|
||||||
int64_t sample_laplace_distribution(double mu, double b, double p);
|
int64_t sample_laplace_distribution(double mu, double b, double p);
|
||||||
int64_t add_laplace_noise(int64_t signal, double random, double delta_f,
|
int64_t add_laplace_noise(int64_t signal, double random, double delta_f,
|
||||||
double epsilon);
|
double epsilon);
|
||||||
int n_bits_set_u8(uint8_t v);
|
|
||||||
int64_t clamp_double_to_int64(double number);
|
int64_t clamp_double_to_int64(double number);
|
||||||
void simplify_fraction64(uint64_t *numer, uint64_t *denom);
|
|
||||||
|
|
||||||
uint32_t tor_add_u32_nowrap(uint32_t a, uint32_t b);
|
|
||||||
|
|
||||||
/* Compute the CEIL of <b>a</b> divided by <b>b</b>, for nonnegative <b>a</b>
|
|
||||||
* and positive <b>b</b>. Works on integer types only. Not defined if a+(b-1)
|
|
||||||
* can overflow. */
|
|
||||||
#define CEIL_DIV(a,b) (((a)+((b)-1))/(b))
|
|
||||||
|
|
||||||
/* Return <b>v</b> if it's between <b>min</b> and <b>max</b>. Otherwise
|
|
||||||
* return <b>min</b> if <b>v</b> is smaller than <b>min</b>, or <b>max</b> if
|
|
||||||
* <b>b</b> is larger than <b>max</b>.
|
|
||||||
*
|
|
||||||
* Requires that <b>min</b> is no more than <b>max</b>. May evaluate any of
|
|
||||||
* its arguments more than once! */
|
|
||||||
#define CLAMP(min,v,max) \
|
|
||||||
( ((v) < (min)) ? (min) : \
|
|
||||||
((v) > (max)) ? (max) : \
|
|
||||||
(v) )
|
|
||||||
|
|
||||||
/* String manipulation */
|
/* String manipulation */
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ include src/lib/container/include.am
|
|||||||
include src/lib/crypt_ops/include.am
|
include src/lib/crypt_ops/include.am
|
||||||
include src/lib/defs/include.am
|
include src/lib/defs/include.am
|
||||||
include src/lib/include.libdonna.am
|
include src/lib/include.libdonna.am
|
||||||
|
include src/lib/intmath/include.am
|
||||||
include src/lib/malloc/include.am
|
include src/lib/malloc/include.am
|
||||||
include src/lib/string/include.am
|
include src/lib/string/include.am
|
||||||
include src/lib/testsupport/include.am
|
include src/lib/testsupport/include.am
|
||||||
|
@ -7,10 +7,10 @@ lib/malloc/*.h
|
|||||||
lib/err/*.h
|
lib/err/*.h
|
||||||
lib/string/*.h
|
lib/string/*.h
|
||||||
lib/testsupport/testsupport.h
|
lib/testsupport/testsupport.h
|
||||||
|
lib/intmath/*.h
|
||||||
|
|
||||||
ht.h
|
ht.h
|
||||||
siphash.h
|
siphash.h
|
||||||
|
|
||||||
# XXX I'd like to remove this.
|
# XXX I'd like to remove this.
|
||||||
common/util.h
|
|
||||||
common/util_bug.h
|
common/util_bug.h
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "lib/malloc/util_malloc.h"
|
#include "lib/malloc/util_malloc.h"
|
||||||
#include "lib/container/bloomfilt.h"
|
#include "lib/container/bloomfilt.h"
|
||||||
#include "common/util.h" // For tor_log2
|
#include "lib/intmath/bits.h"
|
||||||
|
|
||||||
/** Return a newly allocated digestset_t, optimized to hold a total of
|
/** Return a newly allocated digestset_t, optimized to hold a total of
|
||||||
* <b>max_elements</b> digests with a reasonably low false positive weight. */
|
* <b>max_elements</b> digests with a reasonably low false positive weight. */
|
||||||
|
@ -6,6 +6,7 @@ lib/ctime/*.h
|
|||||||
lib/defs/*.h
|
lib/defs/*.h
|
||||||
lib/malloc/*.h
|
lib/malloc/*.h
|
||||||
lib/err/*.h
|
lib/err/*.h
|
||||||
|
lib/intmath/*.h
|
||||||
lib/string/*.h
|
lib/string/*.h
|
||||||
lib/testsupport/testsupport.h
|
lib/testsupport/testsupport.h
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "lib/crypt_ops/crypto_s2k.h"
|
#include "lib/crypt_ops/crypto_s2k.h"
|
||||||
#include "lib/crypt_ops/crypto_util.h"
|
#include "lib/crypt_ops/crypto_util.h"
|
||||||
#include "lib/ctime/di_ops.h"
|
#include "lib/ctime/di_ops.h"
|
||||||
|
#include "lib/intmath/muldiv.h"
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
#include "trunnel/pwbox.h"
|
#include "trunnel/pwbox.h"
|
||||||
|
|
||||||
@ -212,4 +213,3 @@ crypto_unpwbox(uint8_t **out, size_t *outlen_out,
|
|||||||
memwipe(keys, 0, sizeof(keys));
|
memwipe(keys, 0, sizeof(keys));
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
src/lib/intmath/.may_include
Normal file
4
src/lib/intmath/.may_include
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
orconfig.h
|
||||||
|
lib/cc/*.h
|
||||||
|
lib/err/*.h
|
||||||
|
lib/intmath/*.h
|
20
src/lib/intmath/addsub.c
Normal file
20
src/lib/intmath/addsub.c
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/* Copyright (c) 2003-2004, Roger Dingledine
|
||||||
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||||
|
* Copyright (c) 2007-2018, The Tor Project, Inc. */
|
||||||
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
#include "lib/intmath/addsub.h"
|
||||||
|
#include "lib/cc/compat_compiler.h"
|
||||||
|
|
||||||
|
/* Helper: safely add two uint32_t's, capping at UINT32_MAX rather
|
||||||
|
* than overflow */
|
||||||
|
uint32_t
|
||||||
|
tor_add_u32_nowrap(uint32_t a, uint32_t b)
|
||||||
|
{
|
||||||
|
/* a+b > UINT32_MAX check, without overflow */
|
||||||
|
if (PREDICT_UNLIKELY(a > UINT32_MAX - b)) {
|
||||||
|
return UINT32_MAX;
|
||||||
|
} else {
|
||||||
|
return a+b;
|
||||||
|
}
|
||||||
|
}
|
13
src/lib/intmath/addsub.h
Normal file
13
src/lib/intmath/addsub.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/* Copyright (c) 2003-2004, Roger Dingledine
|
||||||
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||||
|
* Copyright (c) 2007-2018, The Tor Project, Inc. */
|
||||||
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
#ifndef TOR_INTMATH_ADDSUB_H
|
||||||
|
#define TOR_INTMATH_ADDSUB_H
|
||||||
|
|
||||||
|
#include "lib/cc/torint.h"
|
||||||
|
|
||||||
|
uint32_t tor_add_u32_nowrap(uint32_t a, uint32_t b);
|
||||||
|
|
||||||
|
#endif /* !defined(TOR_INTMATH_MULDIV_H) */
|
88
src/lib/intmath/bits.c
Normal file
88
src/lib/intmath/bits.c
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/* Copyright (c) 2003-2004, Roger Dingledine
|
||||||
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||||
|
* Copyright (c) 2007-2018, The Tor Project, Inc. */
|
||||||
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
#include "lib/intmath/bits.h"
|
||||||
|
|
||||||
|
/** Returns floor(log2(u64)). If u64 is 0, (incorrectly) returns 0. */
|
||||||
|
int
|
||||||
|
tor_log2(uint64_t u64)
|
||||||
|
{
|
||||||
|
int r = 0;
|
||||||
|
if (u64 >= (U64_LITERAL(1)<<32)) {
|
||||||
|
u64 >>= 32;
|
||||||
|
r = 32;
|
||||||
|
}
|
||||||
|
if (u64 >= (U64_LITERAL(1)<<16)) {
|
||||||
|
u64 >>= 16;
|
||||||
|
r += 16;
|
||||||
|
}
|
||||||
|
if (u64 >= (U64_LITERAL(1)<<8)) {
|
||||||
|
u64 >>= 8;
|
||||||
|
r += 8;
|
||||||
|
}
|
||||||
|
if (u64 >= (U64_LITERAL(1)<<4)) {
|
||||||
|
u64 >>= 4;
|
||||||
|
r += 4;
|
||||||
|
}
|
||||||
|
if (u64 >= (U64_LITERAL(1)<<2)) {
|
||||||
|
u64 >>= 2;
|
||||||
|
r += 2;
|
||||||
|
}
|
||||||
|
if (u64 >= (U64_LITERAL(1)<<1)) {
|
||||||
|
// u64 >>= 1; // not using this any more.
|
||||||
|
r += 1;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the power of 2 in range [1,UINT64_MAX] closest to <b>u64</b>. If
|
||||||
|
* there are two powers of 2 equally close, round down. */
|
||||||
|
uint64_t
|
||||||
|
round_to_power_of_2(uint64_t u64)
|
||||||
|
{
|
||||||
|
int lg2;
|
||||||
|
uint64_t low;
|
||||||
|
uint64_t high;
|
||||||
|
if (u64 == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
lg2 = tor_log2(u64);
|
||||||
|
low = U64_LITERAL(1) << lg2;
|
||||||
|
|
||||||
|
if (lg2 == 63)
|
||||||
|
return low;
|
||||||
|
|
||||||
|
high = U64_LITERAL(1) << (lg2+1);
|
||||||
|
if (high - u64 < u64 - low)
|
||||||
|
return high;
|
||||||
|
else
|
||||||
|
return low;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the number of bits set in <b>v</b>. */
|
||||||
|
int
|
||||||
|
n_bits_set_u8(uint8_t v)
|
||||||
|
{
|
||||||
|
static const int nybble_table[] = {
|
||||||
|
0, /* 0000 */
|
||||||
|
1, /* 0001 */
|
||||||
|
1, /* 0010 */
|
||||||
|
2, /* 0011 */
|
||||||
|
1, /* 0100 */
|
||||||
|
2, /* 0101 */
|
||||||
|
2, /* 0110 */
|
||||||
|
3, /* 0111 */
|
||||||
|
1, /* 1000 */
|
||||||
|
2, /* 1001 */
|
||||||
|
2, /* 1010 */
|
||||||
|
3, /* 1011 */
|
||||||
|
2, /* 1100 */
|
||||||
|
3, /* 1101 */
|
||||||
|
3, /* 1110 */
|
||||||
|
4, /* 1111 */
|
||||||
|
};
|
||||||
|
|
||||||
|
return nybble_table[v & 15] + nybble_table[v>>4];
|
||||||
|
}
|
16
src/lib/intmath/bits.h
Normal file
16
src/lib/intmath/bits.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/* Copyright (c) 2003-2004, Roger Dingledine
|
||||||
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||||
|
* Copyright (c) 2007-2018, The Tor Project, Inc. */
|
||||||
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
#ifndef TOR_INTMATH_BITS_H
|
||||||
|
#define TOR_INTMATH_BITS_H
|
||||||
|
|
||||||
|
#include "lib/cc/torint.h"
|
||||||
|
#include "lib/cc/compat_compiler.h"
|
||||||
|
|
||||||
|
int tor_log2(uint64_t u64) ATTR_CONST;
|
||||||
|
uint64_t round_to_power_of_2(uint64_t u64);
|
||||||
|
int n_bits_set_u8(uint8_t v);
|
||||||
|
|
||||||
|
#endif /* !defined(TOR_INTMATH_BITS_H) */
|
20
src/lib/intmath/cmp.h
Normal file
20
src/lib/intmath/cmp.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/* Copyright (c) 2003-2004, Roger Dingledine
|
||||||
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||||
|
* Copyright (c) 2007-2018, The Tor Project, Inc. */
|
||||||
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
#ifndef TOR_INTMATH_CMP_H
|
||||||
|
#define TOR_INTMATH_CMP_H
|
||||||
|
|
||||||
|
/* Return <b>v</b> if it's between <b>min</b> and <b>max</b>. Otherwise
|
||||||
|
* return <b>min</b> if <b>v</b> is smaller than <b>min</b>, or <b>max</b> if
|
||||||
|
* <b>b</b> is larger than <b>max</b>.
|
||||||
|
*
|
||||||
|
* Requires that <b>min</b> is no more than <b>max</b>. May evaluate any of
|
||||||
|
* its arguments more than once! */
|
||||||
|
#define CLAMP(min,v,max) \
|
||||||
|
( ((v) < (min)) ? (min) : \
|
||||||
|
((v) > (max)) ? (max) : \
|
||||||
|
(v) )
|
||||||
|
|
||||||
|
#endif /* !defined(TOR_INTMATH_CMP_H) */
|
22
src/lib/intmath/include.am
Normal file
22
src/lib/intmath/include.am
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
noinst_LIBRARIES += src/lib/libtor-intmath.a
|
||||||
|
|
||||||
|
if UNITTESTS_ENABLED
|
||||||
|
noinst_LIBRARIES += src/lib/libtor-intmath-testing.a
|
||||||
|
endif
|
||||||
|
|
||||||
|
src_lib_libtor_intmath_a_SOURCES = \
|
||||||
|
src/lib/intmath/addsub.c \
|
||||||
|
src/lib/intmath/bits.c \
|
||||||
|
src/lib/intmath/muldiv.c
|
||||||
|
|
||||||
|
src_lib_libtor_intmath_testing_a_SOURCES = \
|
||||||
|
$(src_lib_libtor_intmath_a_SOURCES)
|
||||||
|
src_lib_libtor_intmath_testing_a_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS)
|
||||||
|
src_lib_libtor_intmath_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
|
||||||
|
|
||||||
|
noinst_HEADERS += \
|
||||||
|
src/lib/intmath/addsub.h \
|
||||||
|
src/lib/intmath/cmp.h \
|
||||||
|
src/lib/intmath/bits.h \
|
||||||
|
src/lib/intmath/muldiv.h
|
75
src/lib/intmath/muldiv.c
Normal file
75
src/lib/intmath/muldiv.c
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/* Copyright (c) 2003-2004, Roger Dingledine
|
||||||
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||||
|
* Copyright (c) 2007-2018, The Tor Project, Inc. */
|
||||||
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
#include "lib/intmath/muldiv.h"
|
||||||
|
#include "lib/err/torerr.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/** Return the lowest x such that x is at least <b>number</b>, and x modulo
|
||||||
|
* <b>divisor</b> == 0. If no such x can be expressed as an unsigned, return
|
||||||
|
* UINT_MAX. Asserts if divisor is zero. */
|
||||||
|
unsigned
|
||||||
|
round_to_next_multiple_of(unsigned number, unsigned divisor)
|
||||||
|
{
|
||||||
|
raw_assert(divisor > 0);
|
||||||
|
if (UINT_MAX - divisor + 1 < number)
|
||||||
|
return UINT_MAX;
|
||||||
|
number += divisor - 1;
|
||||||
|
number -= number % divisor;
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the lowest x such that x is at least <b>number</b>, and x modulo
|
||||||
|
* <b>divisor</b> == 0. If no such x can be expressed as a uint32_t, return
|
||||||
|
* UINT32_MAX. Asserts if divisor is zero. */
|
||||||
|
uint32_t
|
||||||
|
round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor)
|
||||||
|
{
|
||||||
|
raw_assert(divisor > 0);
|
||||||
|
if (UINT32_MAX - divisor + 1 < number)
|
||||||
|
return UINT32_MAX;
|
||||||
|
|
||||||
|
number += divisor - 1;
|
||||||
|
number -= number % divisor;
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return the lowest x such that x is at least <b>number</b>, and x modulo
|
||||||
|
* <b>divisor</b> == 0. If no such x can be expressed as a uint64_t, return
|
||||||
|
* UINT64_MAX. Asserts if divisor is zero. */
|
||||||
|
uint64_t
|
||||||
|
round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor)
|
||||||
|
{
|
||||||
|
raw_assert(divisor > 0);
|
||||||
|
if (UINT64_MAX - divisor + 1 < number)
|
||||||
|
return UINT64_MAX;
|
||||||
|
number += divisor - 1;
|
||||||
|
number -= number % divisor;
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Helper: return greatest common divisor of a,b */
|
||||||
|
static uint64_t
|
||||||
|
gcd64(uint64_t a, uint64_t b)
|
||||||
|
{
|
||||||
|
while (b) {
|
||||||
|
uint64_t t = b;
|
||||||
|
b = a % b;
|
||||||
|
a = t;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given a fraction *<b>numer</b> / *<b>denom</b>, simplify it.
|
||||||
|
* Requires that the denominator is greater than 0. */
|
||||||
|
void
|
||||||
|
simplify_fraction64(uint64_t *numer, uint64_t *denom)
|
||||||
|
{
|
||||||
|
raw_assert(denom);
|
||||||
|
uint64_t gcd = gcd64(*numer, *denom);
|
||||||
|
*numer /= gcd;
|
||||||
|
*denom /= gcd;
|
||||||
|
}
|
22
src/lib/intmath/muldiv.h
Normal file
22
src/lib/intmath/muldiv.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/* Copyright (c) 2003-2004, Roger Dingledine
|
||||||
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||||
|
* Copyright (c) 2007-2018, The Tor Project, Inc. */
|
||||||
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
#ifndef TOR_INTMATH_MULDIV_H
|
||||||
|
#define TOR_INTMATH_MULDIV_H
|
||||||
|
|
||||||
|
#include "lib/cc/torint.h"
|
||||||
|
|
||||||
|
unsigned round_to_next_multiple_of(unsigned number, unsigned divisor);
|
||||||
|
uint32_t round_uint32_to_next_multiple_of(uint32_t number, uint32_t divisor);
|
||||||
|
uint64_t round_uint64_to_next_multiple_of(uint64_t number, uint64_t divisor);
|
||||||
|
|
||||||
|
void simplify_fraction64(uint64_t *numer, uint64_t *denom);
|
||||||
|
|
||||||
|
/* Compute the CEIL of <b>a</b> divided by <b>b</b>, for nonnegative <b>a</b>
|
||||||
|
* and positive <b>b</b>. Works on integer types only. Not defined if a+(b-1)
|
||||||
|
* can overflow. */
|
||||||
|
#define CEIL_DIV(a,b) (((a)+((b)-1))/(b))
|
||||||
|
|
||||||
|
#endif /* !defined(TOR_INTMATH_MULDIV_H) */
|
@ -156,6 +156,7 @@ pub fn main() {
|
|||||||
cfg.component("tor-malloc");
|
cfg.component("tor-malloc");
|
||||||
cfg.component("tor-err-testing");
|
cfg.component("tor-err-testing");
|
||||||
cfg.component("or-event-testing");
|
cfg.component("or-event-testing");
|
||||||
|
cfg.component("tor-intmath-testing");
|
||||||
cfg.component("tor-ctime-testing");
|
cfg.component("tor-ctime-testing");
|
||||||
cfg.component("curve25519_donna");
|
cfg.component("curve25519_donna");
|
||||||
cfg.component("keccak-tiny");
|
cfg.component("keccak-tiny");
|
||||||
|
Loading…
Reference in New Issue
Block a user