Skip to content

Space for speed #170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ env:
BUILDOPTIONS="--test-vs-mtest=333333 --mtest-real-rand"
- |
BUILDOPTIONS="--with-low-mp"
- |
BUILDOPTIONS="--with-low-mp --cflags=-DLTM_USE_FASTER_VERSIONS"
- |
BUILDOPTIONS="--with-m64 --with-m32 --with-mx32"
- |
BUILDOPTIONS="--with-m64 --with-m32 --with-mx32 --cflags=-DLTM_USE_FASTER_VERSIONS"

after_failure:
- cat test_*.log
Expand Down
94 changes: 94 additions & 0 deletions bn_mp_balance_mul.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include "tommath_private.h"
#ifdef BN_MP_BALANCE_MUL_C
/* LibTomMath, multiple-precision integer library -- Tom St Denis
*
* LibTomMath is a library that provides multiple-precision
* integer arithmetic as well as number theoretic functionality.
*
* The library was designed directly after the MPI library by
* Michael Fromberger but has been written from scratch with
* additional optimizations in place.
*
* SPDX-License-Identifier: Unlicense
*/


#if ( (defined LTM_USE_FASTER_VERSIONS) && (defined BN_MP_KARATSUBA_MUL_C) )
/* single-digit multiplication with the smaller number as the single-digit */
int mp_balance_mul(const mp_int *a, const mp_int *b, mp_int *c)
{
int e, count, len_a, len_b, nblocks, i, j, bsize;
mp_int a0, tmp, A, B, r;

len_a = a->used;
len_b = b->used;

nblocks = MAX(a->used, b->used) / MIN(a->used, b->used);
bsize = MIN(a->used, b->used) ;
e = MP_OKAY;

if ((e = mp_init_size(&a0, bsize + 2)) != MP_OKAY) {
return e;
}
if ((e = mp_init_multi(&tmp, &r, NULL)) != MP_OKAY) {
mp_clear(&a0);
return e;
}

/* Make sure that A is the larger one*/
if (len_a < len_b) {
B = *a;
A = *b;
} else {
A = *a;
B = *b;
}

for (i = 0, j=0; i < nblocks; i++) {
/* Cut a slice off of a */
a0.used = 0;
for (count = 0; count < bsize; count++) {
a0.dp[count] = A.dp[ j++ ];
a0.used++;
}
/* Multiply with b */
if ((e = mp_mul(&a0, &B, &tmp)) != MP_OKAY) {
goto LBL_ERR;
}
/* Shift tmp to the correct position */
if ((e = mp_lshd(&tmp, bsize * i)) != MP_OKAY) {
goto LBL_ERR;
}
/* Add to output. No carry needed */
if ((e = mp_add(&r, &tmp, &r)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* The left-overs; there are always left-overs */
if (j < A.used) {
a0.used = 0;
for (count = 0; j < A.used; count++) {
a0.dp[count] = A.dp[ j++ ];
a0.used++;
}
if ((e = mp_mul(&a0, &B, &tmp)) != MP_OKAY) {
goto LBL_ERR;
}
if ((e = mp_lshd(&tmp, bsize * i)) != MP_OKAY) {
goto LBL_ERR;
}
if ((e = mp_add(&r, &tmp, &r)) != MP_OKAY) {
goto LBL_ERR;
}
}

mp_exch(&r,c);
LBL_ERR:
mp_clear_multi(&a0, &tmp, &r,NULL);
return e;
}
#endif
#endif
/* ref: \$Format:\%D$ */
/* git commit: \$Format:\%H$ */
/* commit time: \$Format:\%ai$ */
38 changes: 38 additions & 0 deletions bn_mp_mul.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,42 @@
int mp_mul(const mp_int *a, const mp_int *b, mp_int *c)
{
int res, neg;
#if ( ((defined LTM_USE_FASTER_VERSIONS) && (defined BN_MP_BALANCE_MUL_C)) && (defined BN_MP_KARATSUBA_MUL_C) )
int len_b, len_a;
#endif
neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
/*
TODO: Assumes that nobody uses Toom-Cook-3 without Toom-Cook-2 (Karatsuba)
*/
#if ( ((defined LTM_USE_FASTER_VERSIONS) && (defined BN_MP_BALANCE_MUL_C)) && (defined BN_MP_KARATSUBA_MUL_C) )
len_a = a->used;
len_b = b->used;

if (len_a == len_b) {
goto LBL_GO_ON;
}

/*
* Check sizes. The smaller one needs to be larger than the Karatsuba cut-off.
* The bigger one needs to be at least about one KARATSUBA_MUL_CUTOFF bigger to make some
* sense, but it depends on architecture, OS and position of the planets, so YMMV.
*/
if (MIN(len_a, len_b) < KARATSUBA_MUL_CUTOFF
|| ((MAX(len_a, len_b)) / 2) < KARATSUBA_MUL_CUTOFF) {
goto LBL_GO_ON;
}
/*
* Not much effect was observed below a ratio of 1:2, but YMMV.
*/
if (MAX(len_a, len_b) / MIN(len_a, len_b) < 2) {
goto LBL_GO_ON;
}

res = mp_balance_mul(a,b,c);
goto LBL_END;

LBL_GO_ON:
#endif

/* use Toom-Cook? */
#ifdef BN_MP_TOOM_MUL_C
Expand Down Expand Up @@ -54,6 +89,9 @@ int mp_mul(const mp_int *a, const mp_int *b, mp_int *c)
#endif
}
}
#if ( ((defined LTM_USE_FASTER_VERSIONS) && (defined BN_MP_BALANCE_MUL_C)) && (defined BN_MP_KARATSUBA_MUL_C) )
LBL_END:
#endif
c->sign = (c->used > 0) ? neg : MP_ZPOS;
return res;
}
Expand Down
Loading