Skip to content

Commit

Permalink
Merge branch 'bigint'
Browse files Browse the repository at this point in the history
  • Loading branch information
jnthn committed Nov 15, 2011
2 parents 397dab4 + 6dc4277 commit 0e7280c
Show file tree
Hide file tree
Showing 154 changed files with 38,811 additions and 26,105 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -10,6 +10,7 @@ Makefile
*.obj
*.rc
*.dll
*.dll.a
*.manifest
*.exp
*.lib
Expand All @@ -27,6 +28,7 @@ PASTRegex.pbc
NQPHLL.pbc
NQPP6Regex.pbc
QRegex.pbc
CallBuilder.pbc
nqp
nqp.c
nqp_group.c
Expand Down
29 changes: 29 additions & 0 deletions 3rdparty/libtommath/LICENSE
@@ -0,0 +1,29 @@
LibTomMath is licensed under DUAL licensing terms.

Choose and use the license of your needs.

[LICENSE #1]

LibTomMath is public domain. As should all quality software be.

Tom St Denis

[/LICENSE #1]

[LICENSE #2]

DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004

Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>

Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.

DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. You just DO WHAT THE FUCK YOU WANT TO.

[/LICENSE #2]
47 changes: 47 additions & 0 deletions 3rdparty/libtommath/bn_error.c
@@ -0,0 +1,47 @@
#include <tommath.h>
#ifdef BN_ERROR_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.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/

static const struct {
int code;
const char *msg;
} msgs[] = {
{ MP_OKAY, "Successful" },
{ MP_MEM, "Out of heap" },
{ MP_VAL, "Value out of range" }
};

/* return a char * string for a given code */
char *mp_error_to_string(int code)
{
int x;

/* scan the lookup table for the given message */
for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) {
if (msgs[x].code == code) {
return msgs[x].msg;
}
}

/* generic reply for invalid code */
return "Invalid error code";
}

#endif

/* $Source$ */
/* $Revision$ */
/* $Date$ */
148 changes: 148 additions & 0 deletions 3rdparty/libtommath/bn_fast_mp_invmod.c
@@ -0,0 +1,148 @@
#include <tommath.h>
#ifdef BN_FAST_MP_INVMOD_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.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/

/* computes the modular inverse via binary extended euclidean algorithm,
* that is c = 1/a mod b
*
* Based on slow invmod except this is optimized for the case where b is
* odd as per HAC Note 14.64 on pp. 610
*/
int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
{
mp_int x, y, u, v, B, D;
int res, neg;

/* 2. [modified] b must be odd */
if (mp_iseven (b) == 1) {
return MP_VAL;
}

/* init all our temps */
if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
return res;
}

/* x == modulus, y == value to invert */
if ((res = mp_copy (b, &x)) != MP_OKAY) {
goto LBL_ERR;
}

/* we need y = |a| */
if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
goto LBL_ERR;
}

/* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
if ((res = mp_copy (&x, &u)) != MP_OKAY) {
goto LBL_ERR;
}
if ((res = mp_copy (&y, &v)) != MP_OKAY) {
goto LBL_ERR;
}
mp_set (&D, 1);

top:
/* 4. while u is even do */
while (mp_iseven (&u) == 1) {
/* 4.1 u = u/2 */
if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
goto LBL_ERR;
}
/* 4.2 if B is odd then */
if (mp_isodd (&B) == 1) {
if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* B = B/2 */
if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
goto LBL_ERR;
}
}

/* 5. while v is even do */
while (mp_iseven (&v) == 1) {
/* 5.1 v = v/2 */
if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
goto LBL_ERR;
}
/* 5.2 if D is odd then */
if (mp_isodd (&D) == 1) {
/* D = (D-x)/2 */
if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
/* D = D/2 */
if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}

/* 6. if u >= v then */
if (mp_cmp (&u, &v) != MP_LT) {
/* u = u - v, B = B - D */
if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
goto LBL_ERR;
}

if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
goto LBL_ERR;
}
} else {
/* v - v - u, D = D - B */
if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
goto LBL_ERR;
}

if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}

/* if not zero goto step 4 */
if (mp_iszero (&u) == 0) {
goto top;
}

/* now a = C, b = D, gcd == g*v */

/* if v != 1 then there is no inverse */
if (mp_cmp_d (&v, 1) != MP_EQ) {
res = MP_VAL;
goto LBL_ERR;
}

/* b is now the inverse */
neg = a->sign;
while (D.sign == MP_NEG) {
if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
goto LBL_ERR;
}
}
mp_exch (&D, c);
c->sign = neg;
res = MP_OKAY;

LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
return res;
}
#endif

/* $Source$ */
/* $Revision$ */
/* $Date$ */

0 comments on commit 0e7280c

Please sign in to comment.