commit 2cf033f238c111bef62552da16117568435d3a18 Author: Nick Mathewson nickm@torproject.org Date: Fri Jun 22 09:48:24 2018 -0400
Extract simple integer math into its own module --- .gitignore | 2 + Makefile.am | 2 + src/common/util.c | 161 --------------------------------------- src/common/util.h | 29 +------ src/include.am | 1 + src/lib/container/.may_include | 2 +- src/lib/container/bloomfilt.c | 2 +- src/lib/crypt_ops/.may_include | 1 + src/lib/crypt_ops/crypto_pwbox.c | 2 +- src/lib/intmath/.may_include | 4 + src/lib/intmath/addsub.c | 20 +++++ src/lib/intmath/addsub.h | 13 ++++ src/lib/intmath/bits.c | 88 +++++++++++++++++++++ src/lib/intmath/bits.h | 16 ++++ src/lib/intmath/cmp.h | 20 +++++ src/lib/intmath/include.am | 22 ++++++ src/lib/intmath/muldiv.c | 75 ++++++++++++++++++ src/lib/intmath/muldiv.h | 22 ++++++ src/rust/build.rs | 1 + 19 files changed, 294 insertions(+), 189 deletions(-)
diff --git a/.gitignore b/.gitignore index d03e1136d..6a48ba275 100644 --- a/.gitignore +++ b/.gitignore @@ -173,6 +173,8 @@ uptime-*.json /src/lib/libtor-ctime-testing.a /src/lib/libtor-err.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-testing.a /src/lib/libtor-string.a diff --git a/Makefile.am b/Makefile.am index 50d1408fe..172ab36f6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -45,6 +45,7 @@ TOR_UTIL_LIBS = \ src/lib/libtor-malloc.a \ src/lib/libtor-wallclock.a \ src/lib/libtor-err.a \ + src/lib/libtor-intmath.a \ src/lib/libtor-ctime.a
# 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-wallclock-testing.a \ src/lib/libtor-err-testing.a \ + src/lib/libtor-intmath.a \ src/lib/libtor-ctime-testing.a
# Internal crypto libraries used in Tor diff --git a/src/common/util.c b/src/common/util.c index fc996f16c..5efbb2bbf 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -166,105 +166,6 @@ tor_llround(double d) #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 * [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 @@ -319,68 +220,6 @@ add_laplace_noise(int64_t signal_, double random_, double delta_f, 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 * ===== */ diff --git a/src/common/util.h b/src/common/util.h index de6ba8ece..8f6ec34dc 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -27,6 +27,10 @@ #include "lib/wallclock/approx_time.h" #include "lib/string/util_string.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"
#ifndef O_BINARY @@ -66,35 +70,10 @@ void tor_log_mallinfo(int severity); double tor_mathlog(double d) ATTR_CONST; long tor_lround(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 add_laplace_noise(int64_t signal, double random, double delta_f, double epsilon); -int n_bits_set_u8(uint8_t v); 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 */
diff --git a/src/include.am b/src/include.am index 5676a2359..d69a2fd01 100644 --- a/src/include.am +++ b/src/include.am @@ -7,6 +7,7 @@ include src/lib/container/include.am include src/lib/crypt_ops/include.am include src/lib/defs/include.am include src/lib/include.libdonna.am +include src/lib/intmath/include.am include src/lib/malloc/include.am include src/lib/string/include.am include src/lib/testsupport/include.am diff --git a/src/lib/container/.may_include b/src/lib/container/.may_include index eaa020bf5..42458b295 100644 --- a/src/lib/container/.may_include +++ b/src/lib/container/.may_include @@ -7,10 +7,10 @@ lib/malloc/*.h lib/err/*.h lib/string/*.h lib/testsupport/testsupport.h +lib/intmath/*.h
ht.h siphash.h
# XXX I'd like to remove this. -common/util.h common/util_bug.h diff --git a/src/lib/container/bloomfilt.c b/src/lib/container/bloomfilt.c index 4847408ee..cbb4d13e5 100644 --- a/src/lib/container/bloomfilt.c +++ b/src/lib/container/bloomfilt.c @@ -14,7 +14,7 @@ #include <stdlib.h> #include "lib/malloc/util_malloc.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 * <b>max_elements</b> digests with a reasonably low false positive weight. */ diff --git a/src/lib/crypt_ops/.may_include b/src/lib/crypt_ops/.may_include index 0a9a0dda2..1b9289b2f 100644 --- a/src/lib/crypt_ops/.may_include +++ b/src/lib/crypt_ops/.may_include @@ -6,6 +6,7 @@ lib/ctime/*.h lib/defs/*.h lib/malloc/*.h lib/err/*.h +lib/intmath/*.h lib/string/*.h lib/testsupport/testsupport.h
diff --git a/src/lib/crypt_ops/crypto_pwbox.c b/src/lib/crypt_ops/crypto_pwbox.c index 9a315d42d..6944f8ab5 100644 --- a/src/lib/crypt_ops/crypto_pwbox.c +++ b/src/lib/crypt_ops/crypto_pwbox.c @@ -15,6 +15,7 @@ #include "lib/crypt_ops/crypto_s2k.h" #include "lib/crypt_ops/crypto_util.h" #include "lib/ctime/di_ops.h" +#include "lib/intmath/muldiv.h" #include "common/util.h" #include "trunnel/pwbox.h"
@@ -212,4 +213,3 @@ crypto_unpwbox(uint8_t **out, size_t *outlen_out, memwipe(keys, 0, sizeof(keys)); return rv; } - diff --git a/src/lib/intmath/.may_include b/src/lib/intmath/.may_include new file mode 100644 index 000000000..d96c11222 --- /dev/null +++ b/src/lib/intmath/.may_include @@ -0,0 +1,4 @@ +orconfig.h +lib/cc/*.h +lib/err/*.h +lib/intmath/*.h diff --git a/src/lib/intmath/addsub.c b/src/lib/intmath/addsub.c new file mode 100644 index 000000000..816c5a2bd --- /dev/null +++ b/src/lib/intmath/addsub.c @@ -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; + } +} diff --git a/src/lib/intmath/addsub.h b/src/lib/intmath/addsub.h new file mode 100644 index 000000000..5277adfa4 --- /dev/null +++ b/src/lib/intmath/addsub.h @@ -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) */ diff --git a/src/lib/intmath/bits.c b/src/lib/intmath/bits.c new file mode 100644 index 000000000..85d901f71 --- /dev/null +++ b/src/lib/intmath/bits.c @@ -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]; +} diff --git a/src/lib/intmath/bits.h b/src/lib/intmath/bits.h new file mode 100644 index 000000000..70f855089 --- /dev/null +++ b/src/lib/intmath/bits.h @@ -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) */ diff --git a/src/lib/intmath/cmp.h b/src/lib/intmath/cmp.h new file mode 100644 index 000000000..90ea3ca07 --- /dev/null +++ b/src/lib/intmath/cmp.h @@ -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) */ diff --git a/src/lib/intmath/include.am b/src/lib/intmath/include.am new file mode 100644 index 000000000..40459d106 --- /dev/null +++ b/src/lib/intmath/include.am @@ -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 diff --git a/src/lib/intmath/muldiv.c b/src/lib/intmath/muldiv.c new file mode 100644 index 000000000..3e627b237 --- /dev/null +++ b/src/lib/intmath/muldiv.c @@ -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; +} diff --git a/src/lib/intmath/muldiv.h b/src/lib/intmath/muldiv.h new file mode 100644 index 000000000..de76d9eb6 --- /dev/null +++ b/src/lib/intmath/muldiv.h @@ -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) */ diff --git a/src/rust/build.rs b/src/rust/build.rs index 5c80265e5..03506fe84 100644 --- a/src/rust/build.rs +++ b/src/rust/build.rs @@ -156,6 +156,7 @@ pub fn main() { cfg.component("tor-malloc"); cfg.component("tor-err-testing"); cfg.component("or-event-testing"); + cfg.component("tor-intmath-testing"); cfg.component("tor-ctime-testing"); cfg.component("curve25519_donna"); cfg.component("keccak-tiny");
tor-commits@lists.torproject.org