add bn_divmod1000 including unit test

pull/25/head
Pavol Rusnak 8 years ago
parent 16f477787d
commit d61a151900
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D

@ -804,6 +804,30 @@ void bn_divmod58(bignum256 *a, uint32_t *r)
*r = rem;
}
// a / 1000 = a (+r)
void bn_divmod1000(bignum256 *a, uint32_t *r)
{
int i;
uint32_t rem, tmp;
rem = a->val[8] % 1000;
a->val[8] /= 1000;
for (i = 7; i >= 0; i--) {
// invariants:
// rem = old(a) >> 30(i+1) % 1000
// a[i+1..8] = old(a[i+1..8])/1000
// a[0..i] = old(a[0..i])
// 2^30 == 1073741*1000 + 824
tmp = rem * 824 + a->val[i];
// set a[i] = (rem * 2^30 + a[i])/1000
// = rem * 1073741 + (rem * 824 + a[i])/1000
a->val[i] = rem * 1073741 + (tmp / 1000);
// set rem = (rem * 2^30 + a[i]) mod 1000
// = (rem * 824 + a[i]) mod 1000
rem = tmp % 1000;
}
*r = rem;
}
#if USE_BN_PRINT
void bn_print(const bignum256 *a)
{

@ -87,6 +87,8 @@ void bn_subtract(const bignum256 *a, const bignum256 *b, bignum256 *res);
void bn_divmod58(bignum256 *a, uint32_t *r);
void bn_divmod1000(bignum256 *a, uint32_t *r);
#if USE_BN_PRINT
void bn_print(const bignum256 *a);
void bn_print_raw(const bignum256 *a);

@ -161,6 +161,35 @@ START_TEST(test_base58)
}
END_TEST
START_TEST(test_bignum_divmod)
{
uint32_t r;
int i;
bignum256 a = { { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0xffff} };
uint32_t ar[] = { 15, 14, 55, 29, 44, 24, 53, 49, 18, 55, 2, 28, 5, 4, 12, 43, 18, 37, 28, 14, 30, 46, 12, 11, 17, 10, 10, 13, 24, 45, 4, 33, 44, 42, 2, 46, 34, 43, 45, 28, 21, 18, 13, 17 };
i = 0;
while (!bn_is_zero(&a) && i < 44) {
bn_divmod58(&a, &r);
ck_assert_int_eq(r, ar[i]);
i++;
}
ck_assert_int_eq(i, 44);
bignum256 b = { { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0xffff} };
uint32_t br[] = { 935, 639, 129, 913, 7, 584, 457, 39, 564, 640, 665, 984, 269, 853, 907, 687, 8, 985, 570, 423, 195, 316, 237, 89, 792, 115 };
i = 0;
while (!bn_is_zero(&b) && i < 26) {
bn_divmod1000(&b, &r);
ck_assert_int_eq(r, br[i]);
i++;
}
ck_assert_int_eq(i, 26);
}
END_TEST
// test vector 1 from https://en.bitcoin.it/wiki/BIP_0032_TestVectors
START_TEST(test_bip32_vector_1)
@ -1981,6 +2010,10 @@ Suite *test_suite(void)
tcase_add_test(tc, test_base58);
suite_add_tcase(s, tc);
tc = tcase_create("bignum_divmod");
tcase_add_test(tc, test_bignum_divmod);
suite_add_tcase(s, tc);
tc = tcase_create("bip32");
tcase_add_test(tc, test_bip32_vector_1);
tcase_add_test(tc, test_bip32_vector_2);

Loading…
Cancel
Save