summaryrefslogtreecommitdiffstats
path: root/tcl8.6/libtommath
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2018-12-25 17:48:54 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2018-12-25 17:48:54 (GMT)
commit8eb0f61e2e27ef6594eee8bcf68d574fb087fe66 (patch)
treefc0f3692516c8c3e8090df20223d342a1b64df93 /tcl8.6/libtommath
parent5f5fd2864a3193a8d5da12fcb92ba7379084c286 (diff)
downloadblt-8eb0f61e2e27ef6594eee8bcf68d574fb087fe66.zip
blt-8eb0f61e2e27ef6594eee8bcf68d574fb087fe66.tar.gz
blt-8eb0f61e2e27ef6594eee8bcf68d574fb087fe66.tar.bz2
update tcl/tk
Diffstat (limited to 'tcl8.6/libtommath')
-rw-r--r--tcl8.6/libtommath/bn_fast_s_mp_mul_digs.c103
-rw-r--r--tcl8.6/libtommath/bn_fast_s_mp_sqr.c110
-rw-r--r--tcl8.6/libtommath/bn_mp_add.c49
-rw-r--r--tcl8.6/libtommath/bn_mp_add_d.c112
-rw-r--r--tcl8.6/libtommath/bn_mp_and.c53
-rw-r--r--tcl8.6/libtommath/bn_mp_clamp.c40
-rw-r--r--tcl8.6/libtommath/bn_mp_clear.c40
-rw-r--r--tcl8.6/libtommath/bn_mp_clear_multi.c30
-rw-r--r--tcl8.6/libtommath/bn_mp_cmp.c39
-rw-r--r--tcl8.6/libtommath/bn_mp_cmp_d.c40
-rw-r--r--tcl8.6/libtommath/bn_mp_cmp_mag.c51
-rw-r--r--tcl8.6/libtommath/bn_mp_cnt_lsb.c49
-rw-r--r--tcl8.6/libtommath/bn_mp_copy.c64
-rw-r--r--tcl8.6/libtommath/bn_mp_count_bits.c41
-rw-r--r--tcl8.6/libtommath/bn_mp_div.c288
-rw-r--r--tcl8.6/libtommath/bn_mp_div_2.c64
-rw-r--r--tcl8.6/libtommath/bn_mp_div_2d.c93
-rw-r--r--tcl8.6/libtommath/bn_mp_div_3.c75
-rw-r--r--tcl8.6/libtommath/bn_mp_div_d.c110
-rw-r--r--tcl8.6/libtommath/bn_mp_exch.c30
-rw-r--r--tcl8.6/libtommath/bn_mp_expt_d.c53
-rw-r--r--tcl8.6/libtommath/bn_mp_grow.c53
-rw-r--r--tcl8.6/libtommath/bn_mp_init.c42
-rw-r--r--tcl8.6/libtommath/bn_mp_init_copy.c28
-rw-r--r--tcl8.6/libtommath/bn_mp_init_multi.c55
-rw-r--r--tcl8.6/libtommath/bn_mp_init_set.c28
-rw-r--r--tcl8.6/libtommath/bn_mp_init_set_int.c27
-rw-r--r--tcl8.6/libtommath/bn_mp_init_size.c44
-rw-r--r--tcl8.6/libtommath/bn_mp_karatsuba_mul.c163
-rw-r--r--tcl8.6/libtommath/bn_mp_karatsuba_sqr.c117
-rw-r--r--tcl8.6/libtommath/bn_mp_lshd.c63
-rw-r--r--tcl8.6/libtommath/bn_mp_mod.c44
-rw-r--r--tcl8.6/libtommath/bn_mp_mod_2d.c51
-rw-r--r--tcl8.6/libtommath/bn_mp_mul.c62
-rw-r--r--tcl8.6/libtommath/bn_mp_mul_2.c78
-rw-r--r--tcl8.6/libtommath/bn_mp_mul_2d.c81
-rw-r--r--tcl8.6/libtommath/bn_mp_mul_d.c75
-rw-r--r--tcl8.6/libtommath/bn_mp_neg.c36
-rw-r--r--tcl8.6/libtommath/bn_mp_or.c46
-rw-r--r--tcl8.6/libtommath/bn_mp_radix_size.c78
-rw-r--r--tcl8.6/libtommath/bn_mp_radix_smap.c20
-rw-r--r--tcl8.6/libtommath/bn_mp_read_radix.c88
-rw-r--r--tcl8.6/libtommath/bn_mp_rshd.c68
-rw-r--r--tcl8.6/libtommath/bn_mp_set.c25
-rw-r--r--tcl8.6/libtommath/bn_mp_set_int.c44
-rw-r--r--tcl8.6/libtommath/bn_mp_shrink.c36
-rw-r--r--tcl8.6/libtommath/bn_mp_sqr.c54
-rw-r--r--tcl8.6/libtommath/bn_mp_sqrt.c142
-rw-r--r--tcl8.6/libtommath/bn_mp_sub.c55
-rw-r--r--tcl8.6/libtommath/bn_mp_sub_d.c89
-rw-r--r--tcl8.6/libtommath/bn_mp_to_unsigned_bin.c44
-rw-r--r--tcl8.6/libtommath/bn_mp_to_unsigned_bin_n.c27
-rw-r--r--tcl8.6/libtommath/bn_mp_toom_mul.c280
-rw-r--r--tcl8.6/libtommath/bn_mp_toom_sqr.c222
-rw-r--r--tcl8.6/libtommath/bn_mp_toradix_n.c84
-rw-r--r--tcl8.6/libtommath/bn_mp_unsigned_bin_size.c24
-rw-r--r--tcl8.6/libtommath/bn_mp_xor.c47
-rw-r--r--tcl8.6/libtommath/bn_mp_zero.c32
-rw-r--r--tcl8.6/libtommath/bn_reverse.c35
-rw-r--r--tcl8.6/libtommath/bn_s_mp_add.c105
-rw-r--r--tcl8.6/libtommath/bn_s_mp_mul_digs.c86
-rw-r--r--tcl8.6/libtommath/bn_s_mp_sqr.c80
-rw-r--r--tcl8.6/libtommath/bn_s_mp_sub.c85
-rw-r--r--tcl8.6/libtommath/bncore.c32
-rw-r--r--tcl8.6/libtommath/tommath.h579
-rw-r--r--tcl8.6/libtommath/tommath_class.h995
-rw-r--r--tcl8.6/libtommath/tommath_superclass.h72
67 files changed, 6155 insertions, 0 deletions
diff --git a/tcl8.6/libtommath/bn_fast_s_mp_mul_digs.c b/tcl8.6/libtommath/bn_fast_s_mp_mul_digs.c
new file mode 100644
index 0000000..ab157b9
--- /dev/null
+++ b/tcl8.6/libtommath/bn_fast_s_mp_mul_digs.c
@@ -0,0 +1,103 @@
+#include <tommath.h>
+#ifdef BN_FAST_S_MP_MUL_DIGS_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://math.libtomcrypt.com
+ */
+
+/* Fast (comba) multiplier
+ *
+ * This is the fast column-array [comba] multiplier. It is
+ * designed to compute the columns of the product first
+ * then handle the carries afterwards. This has the effect
+ * of making the nested loops that compute the columns very
+ * simple and schedulable on super-scalar processors.
+ *
+ * This has been modified to produce a variable number of
+ * digits of output so if say only a half-product is required
+ * you don't have to compute the upper half (a feature
+ * required for fast Barrett reduction).
+ *
+ * Based on Algorithm 14.12 on pp.595 of HAC.
+ *
+ */
+int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+ int olduse, res, pa, ix, iz;
+ mp_digit W[MP_WARRAY];
+ register mp_word _W;
+
+ /* grow the destination as required */
+ if (c->alloc < digs) {
+ if ((res = mp_grow (c, digs)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* number of output digits to produce */
+ pa = MIN(digs, a->used + b->used);
+
+ /* clear the carry */
+ _W = 0;
+ for (ix = 0; ix < pa; ix++) {
+ int tx, ty;
+ int iy;
+ mp_digit *tmpx, *tmpy;
+
+ /* get offsets into the two bignums */
+ ty = MIN(b->used-1, ix);
+ tx = ix - ty;
+
+ /* setup temp aliases */
+ tmpx = a->dp + tx;
+ tmpy = b->dp + ty;
+
+ /* this is the number of times the loop will iterrate, essentially
+ while (tx++ < a->used && ty-- >= 0) { ... }
+ */
+ iy = MIN(a->used-tx, ty+1);
+
+ /* execute loop */
+ for (iz = 0; iz < iy; ++iz) {
+ _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+
+ }
+
+ /* store term */
+ W[ix] = ((mp_digit)_W) & MP_MASK;
+
+ /* make next carry */
+ _W = _W >> ((mp_word)DIGIT_BIT);
+ }
+
+ /* setup dest */
+ olduse = c->used;
+ c->used = pa;
+
+ {
+ register mp_digit *tmpc;
+ tmpc = c->dp;
+ for (ix = 0; ix < pa+1; ix++) {
+ /* now extract the previous digit [below the carry] */
+ *tmpc++ = W[ix];
+ }
+
+ /* clear unused digits [that existed in the old copy of c] */
+ for (; ix < olduse; ix++) {
+ *tmpc++ = 0;
+ }
+ }
+ mp_clamp (c);
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_fast_s_mp_sqr.c b/tcl8.6/libtommath/bn_fast_s_mp_sqr.c
new file mode 100644
index 0000000..1abf24b
--- /dev/null
+++ b/tcl8.6/libtommath/bn_fast_s_mp_sqr.c
@@ -0,0 +1,110 @@
+#include <tommath.h>
+#ifdef BN_FAST_S_MP_SQR_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://math.libtomcrypt.com
+ */
+
+/* the jist of squaring...
+ * you do like mult except the offset of the tmpx [one that
+ * starts closer to zero] can't equal the offset of tmpy.
+ * So basically you set up iy like before then you min it with
+ * (ty-tx) so that it never happens. You double all those
+ * you add in the inner loop
+
+After that loop you do the squares and add them in.
+*/
+
+int fast_s_mp_sqr (mp_int * a, mp_int * b)
+{
+ int olduse, res, pa, ix, iz;
+ mp_digit W[MP_WARRAY], *tmpx;
+ mp_word W1;
+
+ /* grow the destination as required */
+ pa = a->used + a->used;
+ if (b->alloc < pa) {
+ if ((res = mp_grow (b, pa)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* number of output digits to produce */
+ W1 = 0;
+ for (ix = 0; ix < pa; ix++) {
+ int tx, ty, iy;
+ mp_word _W;
+ mp_digit *tmpy;
+
+ /* clear counter */
+ _W = 0;
+
+ /* get offsets into the two bignums */
+ ty = MIN(a->used-1, ix);
+ tx = ix - ty;
+
+ /* setup temp aliases */
+ tmpx = a->dp + tx;
+ tmpy = a->dp + ty;
+
+ /* this is the number of times the loop will iterrate, essentially
+ while (tx++ < a->used && ty-- >= 0) { ... }
+ */
+ iy = MIN(a->used-tx, ty+1);
+
+ /* now for squaring tx can never equal ty
+ * we halve the distance since they approach at a rate of 2x
+ * and we have to round because odd cases need to be executed
+ */
+ iy = MIN(iy, (ty-tx+1)>>1);
+
+ /* execute loop */
+ for (iz = 0; iz < iy; iz++) {
+ _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+ }
+
+ /* double the inner product and add carry */
+ _W = _W + _W + W1;
+
+ /* even columns have the square term in them */
+ if ((ix&1) == 0) {
+ _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
+ }
+
+ /* store it */
+ W[ix] = (mp_digit)(_W & MP_MASK);
+
+ /* make next carry */
+ W1 = _W >> ((mp_word)DIGIT_BIT);
+ }
+
+ /* setup dest */
+ olduse = b->used;
+ b->used = a->used+a->used;
+
+ {
+ mp_digit *tmpb;
+ tmpb = b->dp;
+ for (ix = 0; ix < pa; ix++) {
+ *tmpb++ = W[ix] & MP_MASK;
+ }
+
+ /* clear unused digits [that existed in the old copy of c] */
+ for (; ix < olduse; ix++) {
+ *tmpb++ = 0;
+ }
+ }
+ mp_clamp (b);
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_add.c b/tcl8.6/libtommath/bn_mp_add.c
new file mode 100644
index 0000000..d9b8fa5
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_add.c
@@ -0,0 +1,49 @@
+#include <tommath.h>
+#ifdef BN_MP_ADD_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://math.libtomcrypt.com
+ */
+
+/* high level addition (handles signs) */
+int mp_add (mp_int * a, mp_int * b, mp_int * c)
+{
+ int sa, sb, res;
+
+ /* get sign of both inputs */
+ sa = a->sign;
+ sb = b->sign;
+
+ /* handle two cases, not four */
+ if (sa == sb) {
+ /* both positive or both negative */
+ /* add their magnitudes, copy the sign */
+ c->sign = sa;
+ res = s_mp_add (a, b, c);
+ } else {
+ /* one positive, the other negative */
+ /* subtract the one with the greater magnitude from */
+ /* the one of the lesser magnitude. The result gets */
+ /* the sign of the one with the greater magnitude. */
+ if (mp_cmp_mag (a, b) == MP_LT) {
+ c->sign = sb;
+ res = s_mp_sub (b, a, c);
+ } else {
+ c->sign = sa;
+ res = s_mp_sub (a, b, c);
+ }
+ }
+ return res;
+}
+
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_add_d.c b/tcl8.6/libtommath/bn_mp_add_d.c
new file mode 100644
index 0000000..aec8fc8
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_add_d.c
@@ -0,0 +1,112 @@
+#include <tommath.h>
+#ifdef BN_MP_ADD_D_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
+ */
+
+/* single digit addition */
+int
+mp_add_d (mp_int * a, mp_digit b, mp_int * c)
+{
+ int res, ix, oldused;
+ mp_digit *tmpa, *tmpc, mu;
+
+ /* grow c as required */
+ if (c->alloc < a->used + 1) {
+ if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* if a is negative and |a| >= b, call c = |a| - b */
+ if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
+ /* temporarily fix sign of a */
+ a->sign = MP_ZPOS;
+
+ /* c = |a| - b */
+ res = mp_sub_d(a, b, c);
+
+ /* fix sign */
+ a->sign = c->sign = MP_NEG;
+
+ /* clamp */
+ mp_clamp(c);
+
+ return res;
+ }
+
+ /* old number of used digits in c */
+ oldused = c->used;
+
+ /* sign always positive */
+ c->sign = MP_ZPOS;
+
+ /* source alias */
+ tmpa = a->dp;
+
+ /* destination alias */
+ tmpc = c->dp;
+
+ /* if a is positive */
+ if (a->sign == MP_ZPOS) {
+ /* add digit, after this we're propagating
+ * the carry.
+ */
+ *tmpc = *tmpa++ + b;
+ mu = *tmpc >> DIGIT_BIT;
+ *tmpc++ &= MP_MASK;
+
+ /* now handle rest of the digits */
+ for (ix = 1; ix < a->used; ix++) {
+ *tmpc = *tmpa++ + mu;
+ mu = *tmpc >> DIGIT_BIT;
+ *tmpc++ &= MP_MASK;
+ }
+ /* set final carry */
+ ix++;
+ *tmpc++ = mu;
+
+ /* setup size */
+ c->used = a->used + 1;
+ } else {
+ /* a was negative and |a| < b */
+ c->used = 1;
+
+ /* the result is a single digit */
+ if (a->used == 1) {
+ *tmpc++ = b - a->dp[0];
+ } else {
+ *tmpc++ = b;
+ }
+
+ /* setup count so the clearing of oldused
+ * can fall through correctly
+ */
+ ix = 1;
+ }
+
+ /* now zero to oldused */
+ while (ix++ < oldused) {
+ *tmpc++ = 0;
+ }
+ mp_clamp(c);
+
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source$ */
+/* $Revision: 0.41 $ */
+/* $Date: 2007-04-18 09:58:18 +0000 $ */
diff --git a/tcl8.6/libtommath/bn_mp_and.c b/tcl8.6/libtommath/bn_mp_and.c
new file mode 100644
index 0000000..02bef18
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_and.c
@@ -0,0 +1,53 @@
+#include <tommath.h>
+#ifdef BN_MP_AND_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://math.libtomcrypt.com
+ */
+
+/* AND two ints together */
+int
+mp_and (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res, ix, px;
+ mp_int t, *x;
+
+ if (a->used > b->used) {
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+ px = b->used;
+ x = b;
+ } else {
+ if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
+ return res;
+ }
+ px = a->used;
+ x = a;
+ }
+
+ for (ix = 0; ix < px; ix++) {
+ t.dp[ix] &= x->dp[ix];
+ }
+
+ /* zero digits above the last from the smallest mp_int */
+ for (; ix < t.used; ix++) {
+ t.dp[ix] = 0;
+ }
+
+ mp_clamp (&t);
+ mp_exch (c, &t);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_clamp.c b/tcl8.6/libtommath/bn_mp_clamp.c
new file mode 100644
index 0000000..74887bb
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_clamp.c
@@ -0,0 +1,40 @@
+#include <tommath.h>
+#ifdef BN_MP_CLAMP_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://math.libtomcrypt.com
+ */
+
+/* trim unused digits
+ *
+ * This is used to ensure that leading zero digits are
+ * trimed and the leading "used" digit will be non-zero
+ * Typically very fast. Also fixes the sign if there
+ * are no more leading digits
+ */
+void
+mp_clamp (mp_int * a)
+{
+ /* decrease used while the most significant digit is
+ * zero.
+ */
+ while (a->used > 0 && a->dp[a->used - 1] == 0) {
+ --(a->used);
+ }
+
+ /* reset the sign flag if used == 0 */
+ if (a->used == 0) {
+ a->sign = MP_ZPOS;
+ }
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_clear.c b/tcl8.6/libtommath/bn_mp_clear.c
new file mode 100644
index 0000000..bd07e76
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_clear.c
@@ -0,0 +1,40 @@
+#include <tommath.h>
+#ifdef BN_MP_CLEAR_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://math.libtomcrypt.com
+ */
+
+/* clear one (frees) */
+void
+mp_clear (mp_int * a)
+{
+ int i;
+
+ /* only do anything if a hasn't been freed previously */
+ if (a->dp != NULL) {
+ /* first zero the digits */
+ for (i = 0; i < a->used; i++) {
+ a->dp[i] = 0;
+ }
+
+ /* free ram */
+ XFREE(a->dp);
+
+ /* reset members to make debugging easier */
+ a->dp = NULL;
+ a->alloc = a->used = 0;
+ a->sign = MP_ZPOS;
+ }
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_clear_multi.c b/tcl8.6/libtommath/bn_mp_clear_multi.c
new file mode 100644
index 0000000..c3ad7a8
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_clear_multi.c
@@ -0,0 +1,30 @@
+#include <tommath.h>
+#ifdef BN_MP_CLEAR_MULTI_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://math.libtomcrypt.com
+ */
+#include <stdarg.h>
+
+void mp_clear_multi(mp_int *mp, ...)
+{
+ mp_int* next_mp = mp;
+ va_list args;
+ va_start(args, mp);
+ while (next_mp != NULL) {
+ mp_clear(next_mp);
+ next_mp = va_arg(args, mp_int*);
+ }
+ va_end(args);
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_cmp.c b/tcl8.6/libtommath/bn_mp_cmp.c
new file mode 100644
index 0000000..943249d
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_cmp.c
@@ -0,0 +1,39 @@
+#include <tommath.h>
+#ifdef BN_MP_CMP_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://math.libtomcrypt.com
+ */
+
+/* compare two ints (signed)*/
+int
+mp_cmp (const mp_int * a, const mp_int * b)
+{
+ /* compare based on sign */
+ if (a->sign != b->sign) {
+ if (a->sign == MP_NEG) {
+ return MP_LT;
+ } else {
+ return MP_GT;
+ }
+ }
+
+ /* compare digits */
+ if (a->sign == MP_NEG) {
+ /* if negative compare opposite direction */
+ return mp_cmp_mag(b, a);
+ } else {
+ return mp_cmp_mag(a, b);
+ }
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_cmp_d.c b/tcl8.6/libtommath/bn_mp_cmp_d.c
new file mode 100644
index 0000000..ecec091
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_cmp_d.c
@@ -0,0 +1,40 @@
+#include <tommath.h>
+#ifdef BN_MP_CMP_D_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://math.libtomcrypt.com
+ */
+
+/* compare a digit */
+int mp_cmp_d(const mp_int * a, mp_digit b)
+{
+ /* compare based on sign */
+ if (a->sign == MP_NEG) {
+ return MP_LT;
+ }
+
+ /* compare based on magnitude */
+ if (a->used > 1) {
+ return MP_GT;
+ }
+
+ /* compare the only digit of a to b */
+ if (a->dp[0] > b) {
+ return MP_GT;
+ } else if (a->dp[0] < b) {
+ return MP_LT;
+ } else {
+ return MP_EQ;
+ }
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_cmp_mag.c b/tcl8.6/libtommath/bn_mp_cmp_mag.c
new file mode 100644
index 0000000..b23a191
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_cmp_mag.c
@@ -0,0 +1,51 @@
+#include <tommath.h>
+#ifdef BN_MP_CMP_MAG_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://math.libtomcrypt.com
+ */
+
+/* compare maginitude of two ints (unsigned) */
+int mp_cmp_mag (const mp_int * a, const mp_int * b)
+{
+ int n;
+ mp_digit *tmpa, *tmpb;
+
+ /* compare based on # of non-zero digits */
+ if (a->used > b->used) {
+ return MP_GT;
+ }
+
+ if (a->used < b->used) {
+ return MP_LT;
+ }
+
+ /* alias for a */
+ tmpa = a->dp + (a->used - 1);
+
+ /* alias for b */
+ tmpb = b->dp + (a->used - 1);
+
+ /* compare based on digits */
+ for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
+ if (*tmpa > *tmpb) {
+ return MP_GT;
+ }
+
+ if (*tmpa < *tmpb) {
+ return MP_LT;
+ }
+ }
+ return MP_EQ;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_cnt_lsb.c b/tcl8.6/libtommath/bn_mp_cnt_lsb.c
new file mode 100644
index 0000000..f205e8c
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_cnt_lsb.c
@@ -0,0 +1,49 @@
+#include <tommath.h>
+#ifdef BN_MP_CNT_LSB_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://math.libtomcrypt.com
+ */
+
+static const int lnz[16] = {
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+};
+
+/* Counts the number of lsbs which are zero before the first zero bit */
+int mp_cnt_lsb(const mp_int *a)
+{
+ int x;
+ mp_digit q, qq;
+
+ /* easy out */
+ if (mp_iszero(a) == 1) {
+ return 0;
+ }
+
+ /* scan lower digits until non-zero */
+ for (x = 0; x < a->used && a->dp[x] == 0; x++);
+ q = a->dp[x];
+ x *= DIGIT_BIT;
+
+ /* now scan this digit until a 1 is found */
+ if ((q & 1) == 0) {
+ do {
+ qq = q & 15;
+ x += lnz[qq];
+ q >>= 4;
+ } while (qq == 0);
+ }
+ return x;
+}
+
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_copy.c b/tcl8.6/libtommath/bn_mp_copy.c
new file mode 100644
index 0000000..ffbc0d4
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_copy.c
@@ -0,0 +1,64 @@
+#include <tommath.h>
+#ifdef BN_MP_COPY_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://math.libtomcrypt.com
+ */
+
+/* copy, b = a */
+int
+mp_copy (const mp_int * a, mp_int * b)
+{
+ int res, n;
+
+ /* if dst == src do nothing */
+ if (a == b) {
+ return MP_OKAY;
+ }
+
+ /* grow dest */
+ if (b->alloc < a->used) {
+ if ((res = mp_grow (b, a->used)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* zero b and copy the parameters over */
+ {
+ register mp_digit *tmpa, *tmpb;
+
+ /* pointer aliases */
+
+ /* source */
+ tmpa = a->dp;
+
+ /* destination */
+ tmpb = b->dp;
+
+ /* copy all the digits */
+ for (n = 0; n < a->used; n++) {
+ *tmpb++ = *tmpa++;
+ }
+
+ /* clear high digits */
+ for (; n < b->used; n++) {
+ *tmpb++ = 0;
+ }
+ }
+
+ /* copy used count and sign */
+ b->used = a->used;
+ b->sign = a->sign;
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_count_bits.c b/tcl8.6/libtommath/bn_mp_count_bits.c
new file mode 100644
index 0000000..00d364e
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_count_bits.c
@@ -0,0 +1,41 @@
+#include <tommath.h>
+#ifdef BN_MP_COUNT_BITS_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://math.libtomcrypt.com
+ */
+
+/* returns the number of bits in an int */
+int
+mp_count_bits (const mp_int * a)
+{
+ int r;
+ mp_digit q;
+
+ /* shortcut */
+ if (a->used == 0) {
+ return 0;
+ }
+
+ /* get number of digits and add that */
+ r = (a->used - 1) * DIGIT_BIT;
+
+ /* take the last digit and count the bits in it */
+ q = a->dp[a->used - 1];
+ while (q > ((mp_digit) 0)) {
+ ++r;
+ q >>= ((mp_digit) 1);
+ }
+ return r;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_div.c b/tcl8.6/libtommath/bn_mp_div.c
new file mode 100644
index 0000000..de4ca04
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_div.c
@@ -0,0 +1,288 @@
+#include <tommath.h>
+#ifdef BN_MP_DIV_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://math.libtomcrypt.com
+ */
+
+#ifdef BN_MP_DIV_SMALL
+
+/* slower bit-bang division... also smaller */
+int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+ mp_int ta, tb, tq, q;
+ int res, n, n2;
+
+ /* is divisor zero ? */
+ if (mp_iszero (b) == 1) {
+ return MP_VAL;
+ }
+
+ /* if a < b then q=0, r = a */
+ if (mp_cmp_mag (a, b) == MP_LT) {
+ if (d != NULL) {
+ res = mp_copy (a, d);
+ } else {
+ res = MP_OKAY;
+ }
+ if (c != NULL) {
+ mp_zero (c);
+ }
+ return res;
+ }
+
+ /* init our temps */
+ if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) {
+ return res;
+ }
+
+
+ mp_set(&tq, 1);
+ n = mp_count_bits(a) - mp_count_bits(b);
+ if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
+ ((res = mp_abs(b, &tb)) != MP_OKAY) ||
+ ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
+ ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
+ goto LBL_ERR;
+ }
+
+ while (n-- >= 0) {
+ if (mp_cmp(&tb, &ta) != MP_GT) {
+ if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
+ ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
+ goto LBL_ERR;
+ }
+ }
+ if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
+ ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
+ goto LBL_ERR;
+ }
+ }
+
+ /* now q == quotient and ta == remainder */
+ n = a->sign;
+ n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG);
+ if (c != NULL) {
+ mp_exch(c, &q);
+ c->sign = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
+ }
+ if (d != NULL) {
+ mp_exch(d, &ta);
+ d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
+ }
+LBL_ERR:
+ mp_clear_multi(&ta, &tb, &tq, &q, NULL);
+ return res;
+}
+
+#else
+
+/* integer signed division.
+ * c*b + d == a [e.g. a/b, c=quotient, d=remainder]
+ * HAC pp.598 Algorithm 14.20
+ *
+ * Note that the description in HAC is horribly
+ * incomplete. For example, it doesn't consider
+ * the case where digits are removed from 'x' in
+ * the inner loop. It also doesn't consider the
+ * case that y has fewer than three digits, etc..
+ *
+ * The overall algorithm is as described as
+ * 14.20 from HAC but fixed to treat these cases.
+*/
+int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+ mp_int q, x, y, t1, t2;
+ int res, n, t, i, norm, neg;
+
+ /* is divisor zero ? */
+ if (mp_iszero (b) == 1) {
+ return MP_VAL;
+ }
+
+ /* if a < b then q=0, r = a */
+ if (mp_cmp_mag (a, b) == MP_LT) {
+ if (d != NULL) {
+ res = mp_copy (a, d);
+ } else {
+ res = MP_OKAY;
+ }
+ if (c != NULL) {
+ mp_zero (c);
+ }
+ return res;
+ }
+
+ if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) {
+ return res;
+ }
+ q.used = a->used + 2;
+
+ if ((res = mp_init (&t1)) != MP_OKAY) {
+ goto LBL_Q;
+ }
+
+ if ((res = mp_init (&t2)) != MP_OKAY) {
+ goto LBL_T1;
+ }
+
+ if ((res = mp_init_copy (&x, a)) != MP_OKAY) {
+ goto LBL_T2;
+ }
+
+ if ((res = mp_init_copy (&y, b)) != MP_OKAY) {
+ goto LBL_X;
+ }
+
+ /* fix the sign */
+ neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
+ x.sign = y.sign = MP_ZPOS;
+
+ /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
+ norm = mp_count_bits(&y) % DIGIT_BIT;
+ if (norm < (int)(DIGIT_BIT-1)) {
+ norm = (DIGIT_BIT-1) - norm;
+ if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+ if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+ } else {
+ norm = 0;
+ }
+
+ /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
+ n = x.used - 1;
+ t = y.used - 1;
+
+ /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
+ if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
+ goto LBL_Y;
+ }
+
+ while (mp_cmp (&x, &y) != MP_LT) {
+ ++(q.dp[n - t]);
+ if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+ }
+
+ /* reset y by shifting it back down */
+ mp_rshd (&y, n - t);
+
+ /* step 3. for i from n down to (t + 1) */
+ for (i = n; i >= (t + 1); i--) {
+ if (i > x.used) {
+ continue;
+ }
+
+ /* step 3.1 if xi == yt then set q{i-t-1} to b-1,
+ * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
+ if (x.dp[i] == y.dp[t]) {
+ q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1);
+ } else {
+ mp_word tmp;
+ tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT);
+ tmp |= ((mp_word) x.dp[i - 1]);
+ tmp /= ((mp_word) y.dp[t]);
+ if (tmp > (mp_word) MP_MASK)
+ tmp = MP_MASK;
+ q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK));
+ }
+
+ /* while (q{i-t-1} * (yt * b + y{t-1})) >
+ xi * b**2 + xi-1 * b + xi-2
+
+ do q{i-t-1} -= 1;
+ */
+ q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK;
+ do {
+ q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK;
+
+ /* find left hand */
+ mp_zero (&t1);
+ t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
+ t1.dp[1] = y.dp[t];
+ t1.used = 2;
+ if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ /* find right hand */
+ t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
+ t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
+ t2.dp[2] = x.dp[i];
+ t2.used = 3;
+ } while (mp_cmp_mag(&t1, &t2) == MP_GT);
+
+ /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
+ if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
+ if (x.sign == MP_NEG) {
+ if ((res = mp_copy (&y, &t1)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+ if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+ if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) {
+ goto LBL_Y;
+ }
+
+ q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK;
+ }
+ }
+
+ /* now q is the quotient and x is the remainder
+ * [which we have to normalize]
+ */
+
+ /* get sign before writing to c */
+ x.sign = x.used == 0 ? MP_ZPOS : a->sign;
+
+ if (c != NULL) {
+ mp_clamp (&q);
+ mp_exch (&q, c);
+ c->sign = neg;
+ }
+
+ if (d != NULL) {
+ mp_div_2d (&x, norm, &x, NULL);
+ mp_exch (&x, d);
+ }
+
+ res = MP_OKAY;
+
+LBL_Y:mp_clear (&y);
+LBL_X:mp_clear (&x);
+LBL_T2:mp_clear (&t2);
+LBL_T1:mp_clear (&t1);
+LBL_Q:mp_clear (&q);
+ return res;
+}
+
+#endif
+
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_div_2.c b/tcl8.6/libtommath/bn_mp_div_2.c
new file mode 100644
index 0000000..186a959
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_div_2.c
@@ -0,0 +1,64 @@
+#include <tommath.h>
+#ifdef BN_MP_DIV_2_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://math.libtomcrypt.com
+ */
+
+/* b = a/2 */
+int mp_div_2(mp_int * a, mp_int * b)
+{
+ int x, res, oldused;
+
+ /* copy */
+ if (b->alloc < a->used) {
+ if ((res = mp_grow (b, a->used)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ oldused = b->used;
+ b->used = a->used;
+ {
+ register mp_digit r, rr, *tmpa, *tmpb;
+
+ /* source alias */
+ tmpa = a->dp + b->used - 1;
+
+ /* dest alias */
+ tmpb = b->dp + b->used - 1;
+
+ /* carry */
+ r = 0;
+ for (x = b->used - 1; x >= 0; x--) {
+ /* get the carry for the next iteration */
+ rr = *tmpa & 1;
+
+ /* shift the current digit, add in carry and store */
+ *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
+
+ /* forward carry to next iteration */
+ r = rr;
+ }
+
+ /* zero excess digits */
+ tmpb = b->dp + b->used;
+ for (x = b->used; x < oldused; x++) {
+ *tmpb++ = 0;
+ }
+ }
+ b->sign = a->sign;
+ mp_clamp (b);
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_div_2d.c b/tcl8.6/libtommath/bn_mp_div_2d.c
new file mode 100644
index 0000000..d7b7e05
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_div_2d.c
@@ -0,0 +1,93 @@
+#include <tommath.h>
+#ifdef BN_MP_DIV_2D_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://math.libtomcrypt.com
+ */
+
+/* shift right by a certain bit count (store quotient in c, optional remainder in d) */
+int mp_div_2d (const mp_int * a, int b, mp_int * c, mp_int * d)
+{
+ mp_digit D, r, rr;
+ int x, res;
+ mp_int t;
+
+
+ /* if the shift count is <= 0 then we do no work */
+ if (b <= 0) {
+ res = mp_copy (a, c);
+ if (d != NULL) {
+ mp_zero (d);
+ }
+ return res;
+ }
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
+ return res;
+ }
+
+ /* get the remainder */
+ if (d != NULL) {
+ if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ }
+
+ /* copy */
+ if ((res = mp_copy (a, c)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+
+ /* shift by as many digits in the bit count */
+ if (b >= (int)DIGIT_BIT) {
+ mp_rshd (c, b / DIGIT_BIT);
+ }
+
+ /* shift any bit count < DIGIT_BIT */
+ D = (mp_digit) (b % DIGIT_BIT);
+ if (D != 0) {
+ register mp_digit *tmpc, mask, shift;
+
+ /* mask */
+ mask = (((mp_digit)1) << D) - 1;
+
+ /* shift for lsb */
+ shift = DIGIT_BIT - D;
+
+ /* alias */
+ tmpc = c->dp + (c->used - 1);
+
+ /* carry */
+ r = 0;
+ for (x = c->used - 1; x >= 0; x--) {
+ /* get the lower bits of this word in a temp */
+ rr = *tmpc & mask;
+
+ /* shift the current word and mix in the carry bits from the previous word */
+ *tmpc = (*tmpc >> D) | (r << shift);
+ --tmpc;
+
+ /* set the carry to the carry bits of the current word found above */
+ r = rr;
+ }
+ }
+ mp_clamp (c);
+ if (d != NULL) {
+ mp_exch (&t, d);
+ }
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_div_3.c b/tcl8.6/libtommath/bn_mp_div_3.c
new file mode 100644
index 0000000..79a9816
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_div_3.c
@@ -0,0 +1,75 @@
+#include <tommath.h>
+#ifdef BN_MP_DIV_3_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://math.libtomcrypt.com
+ */
+
+/* divide by three (based on routine from MPI and the GMP manual) */
+int
+mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
+{
+ mp_int q;
+ mp_word w, t;
+ mp_digit b;
+ int res, ix;
+
+ /* b = 2**DIGIT_BIT / 3 */
+ b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3);
+
+ if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
+ return res;
+ }
+
+ q.used = a->used;
+ q.sign = a->sign;
+ w = 0;
+ for (ix = a->used - 1; ix >= 0; ix--) {
+ w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
+
+ if (w >= 3) {
+ /* multiply w by [1/3] */
+ t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
+
+ /* now subtract 3 * [w/3] from w, to get the remainder */
+ w -= t+t+t;
+
+ /* fixup the remainder as required since
+ * the optimization is not exact.
+ */
+ while (w >= 3) {
+ t += 1;
+ w -= 3;
+ }
+ } else {
+ t = 0;
+ }
+ q.dp[ix] = (mp_digit)t;
+ }
+
+ /* [optional] store the remainder */
+ if (d != NULL) {
+ *d = (mp_digit)w;
+ }
+
+ /* [optional] store the quotient */
+ if (c != NULL) {
+ mp_clamp(&q);
+ mp_exch(&q, c);
+ }
+ mp_clear(&q);
+
+ return res;
+}
+
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_div_d.c b/tcl8.6/libtommath/bn_mp_div_d.c
new file mode 100644
index 0000000..af18d0a
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_div_d.c
@@ -0,0 +1,110 @@
+#include <tommath.h>
+#ifdef BN_MP_DIV_D_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://math.libtomcrypt.com
+ */
+
+static int s_is_power_of_two(mp_digit b, int *p)
+{
+ int x;
+
+ /* quick out - if (b & (b-1)) isn't zero, b isn't a power of two */
+ if ((b==0) || (b & (b-1))) {
+ return 0;
+ }
+ for (x = 1; x < DIGIT_BIT; x++) {
+ if (b == (((mp_digit)1)<<x)) {
+ *p = x;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* single digit division (based on routine from MPI) */
+int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
+{
+ mp_int q;
+ mp_word w;
+ mp_digit t;
+ int res, ix;
+
+ /* cannot divide by zero */
+ if (b == 0) {
+ return MP_VAL;
+ }
+
+ /* quick outs */
+ if (b == 1 || mp_iszero(a) == 1) {
+ if (d != NULL) {
+ *d = 0;
+ }
+ if (c != NULL) {
+ return mp_copy(a, c);
+ }
+ return MP_OKAY;
+ }
+
+ /* power of two ? */
+ if (s_is_power_of_two(b, &ix) == 1) {
+ if (d != NULL) {
+ *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);
+ }
+ if (c != NULL) {
+ return mp_div_2d(a, ix, c, NULL);
+ }
+ return MP_OKAY;
+ }
+
+#ifdef BN_MP_DIV_3_C
+ /* three? */
+ if (b == 3) {
+ return mp_div_3(a, c, d);
+ }
+#endif
+
+ /* no easy answer [c'est la vie]. Just division */
+ if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
+ return res;
+ }
+
+ q.used = a->used;
+ q.sign = a->sign;
+ w = 0;
+ for (ix = a->used - 1; ix >= 0; ix--) {
+ w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
+
+ if (w >= b) {
+ t = (mp_digit)(w / b);
+ w -= ((mp_word)t) * ((mp_word)b);
+ } else {
+ t = 0;
+ }
+ q.dp[ix] = (mp_digit)t;
+ }
+
+ if (d != NULL) {
+ *d = (mp_digit)w;
+ }
+
+ if (c != NULL) {
+ mp_clamp(&q);
+ mp_exch(&q, c);
+ }
+ mp_clear(&q);
+
+ return res;
+}
+
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_exch.c b/tcl8.6/libtommath/bn_mp_exch.c
new file mode 100644
index 0000000..b7bd186
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_exch.c
@@ -0,0 +1,30 @@
+#include <tommath.h>
+#ifdef BN_MP_EXCH_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://math.libtomcrypt.com
+ */
+
+/* swap the elements of two integers, for cases where you can't simply swap the
+ * mp_int pointers around
+ */
+void
+mp_exch (mp_int * a, mp_int * b)
+{
+ mp_int t;
+
+ t = *a;
+ *a = *b;
+ *b = t;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_expt_d.c b/tcl8.6/libtommath/bn_mp_expt_d.c
new file mode 100644
index 0000000..132f480
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_expt_d.c
@@ -0,0 +1,53 @@
+#include <tommath.h>
+#ifdef BN_MP_EXPT_D_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://math.libtomcrypt.com
+ */
+
+/* calculate c = a**b using a square-multiply algorithm */
+int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
+{
+ int res, x;
+ mp_int g;
+
+ if ((res = mp_init_copy (&g, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* set initial result */
+ mp_set (c, 1);
+
+ for (x = 0; x < (int) DIGIT_BIT; x++) {
+ /* square */
+ if ((res = mp_sqr (c, c)) != MP_OKAY) {
+ mp_clear (&g);
+ return res;
+ }
+
+ /* if the bit is set multiply */
+ if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) {
+ if ((res = mp_mul (c, &g, c)) != MP_OKAY) {
+ mp_clear (&g);
+ return res;
+ }
+ }
+
+ /* shift to next bit */
+ b <<= 1;
+ }
+
+ mp_clear (&g);
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_grow.c b/tcl8.6/libtommath/bn_mp_grow.c
new file mode 100644
index 0000000..b5b2407
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_grow.c
@@ -0,0 +1,53 @@
+#include <tommath.h>
+#ifdef BN_MP_GROW_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://math.libtomcrypt.com
+ */
+
+/* grow as required */
+int mp_grow (mp_int * a, int size)
+{
+ int i;
+ mp_digit *tmp;
+
+ /* if the alloc size is smaller alloc more ram */
+ if (a->alloc < size) {
+ /* ensure there are always at least MP_PREC digits extra on top */
+ size += (MP_PREC * 2) - (size % MP_PREC);
+
+ /* reallocate the array a->dp
+ *
+ * We store the return in a temporary variable
+ * in case the operation failed we don't want
+ * to overwrite the dp member of a.
+ */
+ tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size);
+ if (tmp == NULL) {
+ /* reallocation failed but "a" is still valid [can be freed] */
+ return MP_MEM;
+ }
+
+ /* reallocation succeeded so set a->dp */
+ a->dp = tmp;
+
+ /* zero excess digits */
+ i = a->alloc;
+ a->alloc = size;
+ for (; i < a->alloc; i++) {
+ a->dp[i] = 0;
+ }
+ }
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_init.c b/tcl8.6/libtommath/bn_mp_init.c
new file mode 100644
index 0000000..ddb2d07
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_init.c
@@ -0,0 +1,42 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_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://math.libtomcrypt.com
+ */
+
+/* init a new mp_int */
+int mp_init (mp_int * a)
+{
+ int i;
+
+ /* allocate memory required and clear it */
+ a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC);
+ if (a->dp == NULL) {
+ return MP_MEM;
+ }
+
+ /* set the digits to zero */
+ for (i = 0; i < MP_PREC; i++) {
+ a->dp[i] = 0;
+ }
+
+ /* set the used to zero, allocated digits to the default precision
+ * and sign to positive */
+ a->used = 0;
+ a->alloc = MP_PREC;
+ a->sign = MP_ZPOS;
+
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_init_copy.c b/tcl8.6/libtommath/bn_mp_init_copy.c
new file mode 100644
index 0000000..2410a9f
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_init_copy.c
@@ -0,0 +1,28 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_COPY_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://math.libtomcrypt.com
+ */
+
+/* creates "a" then copies b into it */
+int mp_init_copy (mp_int * a, mp_int * b)
+{
+ int res;
+
+ if ((res = mp_init (a)) != MP_OKAY) {
+ return res;
+ }
+ return mp_copy (b, a);
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_init_multi.c b/tcl8.6/libtommath/bn_mp_init_multi.c
new file mode 100644
index 0000000..44e3fe6
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_init_multi.c
@@ -0,0 +1,55 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_MULTI_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://math.libtomcrypt.com
+ */
+#include <stdarg.h>
+
+int mp_init_multi(mp_int *mp, ...)
+{
+ mp_err res = MP_OKAY; /* Assume ok until proven otherwise */
+ int n = 0; /* Number of ok inits */
+ mp_int* cur_arg = mp;
+ va_list args;
+
+ va_start(args, mp); /* init args to next argument from caller */
+ while (cur_arg != NULL) {
+ if (mp_init(cur_arg) != MP_OKAY) {
+ /* Oops - error! Back-track and mp_clear what we already
+ succeeded in init-ing, then return error.
+ */
+ va_list clean_args;
+
+ /* end the current list */
+ va_end(args);
+
+ /* now start cleaning up */
+ cur_arg = mp;
+ va_start(clean_args, mp);
+ while (n--) {
+ mp_clear(cur_arg);
+ cur_arg = va_arg(clean_args, mp_int*);
+ }
+ va_end(clean_args);
+ res = MP_MEM;
+ break;
+ }
+ n++;
+ cur_arg = va_arg(args, mp_int*);
+ }
+ va_end(args);
+ return res; /* Assumed ok, if error flagged above. */
+}
+
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_init_set.c b/tcl8.6/libtommath/bn_mp_init_set.c
new file mode 100644
index 0000000..dc08867
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_init_set.c
@@ -0,0 +1,28 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_SET_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://math.libtomcrypt.com
+ */
+
+/* initialize and set a digit */
+int mp_init_set (mp_int * a, mp_digit b)
+{
+ int err;
+ if ((err = mp_init(a)) != MP_OKAY) {
+ return err;
+ }
+ mp_set(a, b);
+ return err;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_init_set_int.c b/tcl8.6/libtommath/bn_mp_init_set_int.c
new file mode 100644
index 0000000..56b27e0
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_init_set_int.c
@@ -0,0 +1,27 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_SET_INT_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://math.libtomcrypt.com
+ */
+
+/* initialize and set a digit */
+int mp_init_set_int (mp_int * a, unsigned long b)
+{
+ int err;
+ if ((err = mp_init(a)) != MP_OKAY) {
+ return err;
+ }
+ return mp_set_int(a, b);
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_init_size.c b/tcl8.6/libtommath/bn_mp_init_size.c
new file mode 100644
index 0000000..8ed2c2a
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_init_size.c
@@ -0,0 +1,44 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_SIZE_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://math.libtomcrypt.com
+ */
+
+/* init an mp_init for a given size */
+int mp_init_size (mp_int * a, int size)
+{
+ int x;
+
+ /* pad size so there are always extra digits */
+ size += (MP_PREC * 2) - (size % MP_PREC);
+
+ /* alloc mem */
+ a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size);
+ if (a->dp == NULL) {
+ return MP_MEM;
+ }
+
+ /* set the members */
+ a->used = 0;
+ a->alloc = size;
+ a->sign = MP_ZPOS;
+
+ /* zero the digits */
+ for (x = 0; x < size; x++) {
+ a->dp[x] = 0;
+ }
+
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_karatsuba_mul.c b/tcl8.6/libtommath/bn_mp_karatsuba_mul.c
new file mode 100644
index 0000000..0d62b9b
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_karatsuba_mul.c
@@ -0,0 +1,163 @@
+#include <tommath.h>
+#ifdef BN_MP_KARATSUBA_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.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* c = |a| * |b| using Karatsuba Multiplication using
+ * three half size multiplications
+ *
+ * Let B represent the radix [e.g. 2**DIGIT_BIT] and
+ * let n represent half of the number of digits in
+ * the min(a,b)
+ *
+ * a = a1 * B**n + a0
+ * b = b1 * B**n + b0
+ *
+ * Then, a * b =>
+ a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0
+ *
+ * Note that a1b1 and a0b0 are used twice and only need to be
+ * computed once. So in total three half size (half # of
+ * digit) multiplications are performed, a0b0, a1b1 and
+ * (a1+b1)(a0+b0)
+ *
+ * Note that a multiplication of half the digits requires
+ * 1/4th the number of single precision multiplications so in
+ * total after one call 25% of the single precision multiplications
+ * are saved. Note also that the call to mp_mul can end up back
+ * in this function if the a0, a1, b0, or b1 are above the threshold.
+ * This is known as divide-and-conquer and leads to the famous
+ * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than
+ * the standard O(N**2) that the baseline/comba methods use.
+ * Generally though the overhead of this method doesn't pay off
+ * until a certain size (N ~ 80) is reached.
+ */
+int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c)
+{
+ mp_int x0, x1, y0, y1, t1, x0y0, x1y1;
+ int B, err;
+
+ /* default the return code to an error */
+ err = MP_MEM;
+
+ /* min # of digits */
+ B = MIN (a->used, b->used);
+
+ /* now divide in two */
+ B = B >> 1;
+
+ /* init copy all the temps */
+ if (mp_init_size (&x0, B) != MP_OKAY)
+ goto ERR;
+ if (mp_init_size (&x1, a->used - B) != MP_OKAY)
+ goto X0;
+ if (mp_init_size (&y0, B) != MP_OKAY)
+ goto X1;
+ if (mp_init_size (&y1, b->used - B) != MP_OKAY)
+ goto Y0;
+
+ /* init temps */
+ if (mp_init_size (&t1, B * 2) != MP_OKAY)
+ goto Y1;
+ if (mp_init_size (&x0y0, B * 2) != MP_OKAY)
+ goto T1;
+ if (mp_init_size (&x1y1, B * 2) != MP_OKAY)
+ goto X0Y0;
+
+ /* now shift the digits */
+ x0.used = y0.used = B;
+ x1.used = a->used - B;
+ y1.used = b->used - B;
+
+ {
+ register int x;
+ register mp_digit *tmpa, *tmpb, *tmpx, *tmpy;
+
+ /* we copy the digits directly instead of using higher level functions
+ * since we also need to shift the digits
+ */
+ tmpa = a->dp;
+ tmpb = b->dp;
+
+ tmpx = x0.dp;
+ tmpy = y0.dp;
+ for (x = 0; x < B; x++) {
+ *tmpx++ = *tmpa++;
+ *tmpy++ = *tmpb++;
+ }
+
+ tmpx = x1.dp;
+ for (x = B; x < a->used; x++) {
+ *tmpx++ = *tmpa++;
+ }
+
+ tmpy = y1.dp;
+ for (x = B; x < b->used; x++) {
+ *tmpy++ = *tmpb++;
+ }
+ }
+
+ /* only need to clamp the lower words since by definition the
+ * upper words x1/y1 must have a known number of digits
+ */
+ mp_clamp (&x0);
+ mp_clamp (&y0);
+
+ /* now calc the products x0y0 and x1y1 */
+ /* after this x0 is no longer required, free temp [x0==t2]! */
+ if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY)
+ goto X1Y1; /* x0y0 = x0*y0 */
+ if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY)
+ goto X1Y1; /* x1y1 = x1*y1 */
+
+ /* now calc x1+x0 and y1+y0 */
+ if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
+ goto X1Y1; /* t1 = x1 - x0 */
+ if (s_mp_add (&y1, &y0, &x0) != MP_OKAY)
+ goto X1Y1; /* t2 = y1 - y0 */
+ if (mp_mul (&t1, &x0, &t1) != MP_OKAY)
+ goto X1Y1; /* t1 = (x1 + x0) * (y1 + y0) */
+
+ /* add x0y0 */
+ if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY)
+ goto X1Y1; /* t2 = x0y0 + x1y1 */
+ if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY)
+ goto X1Y1; /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */
+
+ /* shift by B */
+ if (mp_lshd (&t1, B) != MP_OKAY)
+ goto X1Y1; /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */
+ if (mp_lshd (&x1y1, B * 2) != MP_OKAY)
+ goto X1Y1; /* x1y1 = x1y1 << 2*B */
+
+ if (mp_add (&x0y0, &t1, &t1) != MP_OKAY)
+ goto X1Y1; /* t1 = x0y0 + t1 */
+ if (mp_add (&t1, &x1y1, c) != MP_OKAY)
+ goto X1Y1; /* t1 = x0y0 + t1 + x1y1 */
+
+ /* Algorithm succeeded set the return code to MP_OKAY */
+ err = MP_OKAY;
+
+X1Y1:mp_clear (&x1y1);
+X0Y0:mp_clear (&x0y0);
+T1:mp_clear (&t1);
+Y1:mp_clear (&y1);
+Y0:mp_clear (&y0);
+X1:mp_clear (&x1);
+X0:mp_clear (&x0);
+ERR:
+ return err;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_karatsuba_sqr.c b/tcl8.6/libtommath/bn_mp_karatsuba_sqr.c
new file mode 100644
index 0000000..829405a
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_karatsuba_sqr.c
@@ -0,0 +1,117 @@
+#include <tommath.h>
+#ifdef BN_MP_KARATSUBA_SQR_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://math.libtomcrypt.com
+ */
+
+/* Karatsuba squaring, computes b = a*a using three
+ * half size squarings
+ *
+ * See comments of karatsuba_mul for details. It
+ * is essentially the same algorithm but merely
+ * tuned to perform recursive squarings.
+ */
+int mp_karatsuba_sqr (mp_int * a, mp_int * b)
+{
+ mp_int x0, x1, t1, t2, x0x0, x1x1;
+ int B, err;
+
+ err = MP_MEM;
+
+ /* min # of digits */
+ B = a->used;
+
+ /* now divide in two */
+ B = B >> 1;
+
+ /* init copy all the temps */
+ if (mp_init_size (&x0, B) != MP_OKAY)
+ goto ERR;
+ if (mp_init_size (&x1, a->used - B) != MP_OKAY)
+ goto X0;
+
+ /* init temps */
+ if (mp_init_size (&t1, a->used * 2) != MP_OKAY)
+ goto X1;
+ if (mp_init_size (&t2, a->used * 2) != MP_OKAY)
+ goto T1;
+ if (mp_init_size (&x0x0, B * 2) != MP_OKAY)
+ goto T2;
+ if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY)
+ goto X0X0;
+
+ {
+ register int x;
+ register mp_digit *dst, *src;
+
+ src = a->dp;
+
+ /* now shift the digits */
+ dst = x0.dp;
+ for (x = 0; x < B; x++) {
+ *dst++ = *src++;
+ }
+
+ dst = x1.dp;
+ for (x = B; x < a->used; x++) {
+ *dst++ = *src++;
+ }
+ }
+
+ x0.used = B;
+ x1.used = a->used - B;
+
+ mp_clamp (&x0);
+
+ /* now calc the products x0*x0 and x1*x1 */
+ if (mp_sqr (&x0, &x0x0) != MP_OKAY)
+ goto X1X1; /* x0x0 = x0*x0 */
+ if (mp_sqr (&x1, &x1x1) != MP_OKAY)
+ goto X1X1; /* x1x1 = x1*x1 */
+
+ /* now calc (x1+x0)**2 */
+ if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
+ goto X1X1; /* t1 = x1 - x0 */
+ if (mp_sqr (&t1, &t1) != MP_OKAY)
+ goto X1X1; /* t1 = (x1 - x0) * (x1 - x0) */
+
+ /* add x0y0 */
+ if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY)
+ goto X1X1; /* t2 = x0x0 + x1x1 */
+ if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY)
+ goto X1X1; /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */
+
+ /* shift by B */
+ if (mp_lshd (&t1, B) != MP_OKAY)
+ goto X1X1; /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */
+ if (mp_lshd (&x1x1, B * 2) != MP_OKAY)
+ goto X1X1; /* x1x1 = x1x1 << 2*B */
+
+ if (mp_add (&x0x0, &t1, &t1) != MP_OKAY)
+ goto X1X1; /* t1 = x0x0 + t1 */
+ if (mp_add (&t1, &x1x1, b) != MP_OKAY)
+ goto X1X1; /* t1 = x0x0 + t1 + x1x1 */
+
+ err = MP_OKAY;
+
+X1X1:mp_clear (&x1x1);
+X0X0:mp_clear (&x0x0);
+T2:mp_clear (&t2);
+T1:mp_clear (&t1);
+X1:mp_clear (&x1);
+X0:mp_clear (&x0);
+ERR:
+ return err;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_lshd.c b/tcl8.6/libtommath/bn_mp_lshd.c
new file mode 100644
index 0000000..ce1e63b
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_lshd.c
@@ -0,0 +1,63 @@
+#include <tommath.h>
+#ifdef BN_MP_LSHD_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://math.libtomcrypt.com
+ */
+
+/* shift left a certain amount of digits */
+int mp_lshd (mp_int * a, int b)
+{
+ int x, res;
+
+ /* if its less than zero return */
+ if (b <= 0) {
+ return MP_OKAY;
+ }
+
+ /* grow to fit the new digits */
+ if (a->alloc < a->used + b) {
+ if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ {
+ register mp_digit *top, *bottom;
+
+ /* increment the used by the shift amount then copy upwards */
+ a->used += b;
+
+ /* top */
+ top = a->dp + a->used - 1;
+
+ /* base */
+ bottom = a->dp + a->used - 1 - b;
+
+ /* much like mp_rshd this is implemented using a sliding window
+ * except the window goes the otherway around. Copying from
+ * the bottom to the top. see bn_mp_rshd.c for more info.
+ */
+ for (x = a->used - 1; x >= b; x--) {
+ *top-- = *bottom--;
+ }
+
+ /* zero the lower digits */
+ top = a->dp;
+ for (x = 0; x < b; x++) {
+ *top++ = 0;
+ }
+ }
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_mod.c b/tcl8.6/libtommath/bn_mp_mod.c
new file mode 100644
index 0000000..98e155e
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_mod.c
@@ -0,0 +1,44 @@
+#include <tommath.h>
+#ifdef BN_MP_MOD_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://math.libtomcrypt.com
+ */
+
+/* c = a mod b, 0 <= c < b */
+int
+mp_mod (mp_int * a, mp_int * b, mp_int * c)
+{
+ mp_int t;
+ int res;
+
+ if ((res = mp_init (&t)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+
+ if (t.sign != b->sign) {
+ res = mp_add (b, &t, c);
+ } else {
+ res = MP_OKAY;
+ mp_exch (&t, c);
+ }
+
+ mp_clear (&t);
+ return res;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_mod_2d.c b/tcl8.6/libtommath/bn_mp_mod_2d.c
new file mode 100644
index 0000000..0170f65
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_mod_2d.c
@@ -0,0 +1,51 @@
+#include <tommath.h>
+#ifdef BN_MP_MOD_2D_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://math.libtomcrypt.com
+ */
+
+/* calc a value mod 2**b */
+int
+mp_mod_2d (const mp_int * a, int b, mp_int * c)
+{
+ int x, res;
+
+ /* if b is <= 0 then zero the int */
+ if (b <= 0) {
+ mp_zero (c);
+ return MP_OKAY;
+ }
+
+ /* if the modulus is larger than the value than return */
+ if (b >= (int) (a->used * DIGIT_BIT)) {
+ res = mp_copy (a, c);
+ return res;
+ }
+
+ /* copy */
+ if ((res = mp_copy (a, c)) != MP_OKAY) {
+ return res;
+ }
+
+ /* zero digits above the last digit of the modulus */
+ for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
+ c->dp[x] = 0;
+ }
+ /* clear the digit that is not completely outside/inside the modulus */
+ c->dp[b / DIGIT_BIT] &=
+ (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
+ mp_clamp (c);
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_mul.c b/tcl8.6/libtommath/bn_mp_mul.c
new file mode 100644
index 0000000..fc024be
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_mul.c
@@ -0,0 +1,62 @@
+#include <tommath.h>
+#ifdef BN_MP_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.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* high level multiplication (handles sign) */
+int mp_mul (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res, neg;
+ neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
+
+ /* use Toom-Cook? */
+#ifdef BN_MP_TOOM_MUL_C
+ if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) {
+ res = mp_toom_mul(a, b, c);
+ } else
+#endif
+#ifdef BN_MP_KARATSUBA_MUL_C
+ /* use Karatsuba? */
+ if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) {
+ res = mp_karatsuba_mul (a, b, c);
+ } else
+#endif
+ {
+ /* can we use the fast multiplier?
+ *
+ * The fast multiplier can be used if the output will
+ * have less than MP_WARRAY digits and the number of
+ * digits won't affect carry propagation
+ */
+ int digs = a->used + b->used + 1;
+
+#ifdef BN_FAST_S_MP_MUL_DIGS_C
+ if ((digs < MP_WARRAY) &&
+ MIN(a->used, b->used) <=
+ (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+ res = fast_s_mp_mul_digs (a, b, c, digs);
+ } else
+#endif
+#ifdef BN_S_MP_MUL_DIGS_C
+ res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */
+#else
+ res = MP_VAL;
+#endif
+
+ }
+ c->sign = (c->used > 0) ? neg : MP_ZPOS;
+ return res;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_mul_2.c b/tcl8.6/libtommath/bn_mp_mul_2.c
new file mode 100644
index 0000000..2ca6022
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_mul_2.c
@@ -0,0 +1,78 @@
+#include <tommath.h>
+#ifdef BN_MP_MUL_2_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://math.libtomcrypt.com
+ */
+
+/* b = a*2 */
+int mp_mul_2(mp_int * a, mp_int * b)
+{
+ int x, res, oldused;
+
+ /* grow to accomodate result */
+ if (b->alloc < a->used + 1) {
+ if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ oldused = b->used;
+ b->used = a->used;
+
+ {
+ register mp_digit r, rr, *tmpa, *tmpb;
+
+ /* alias for source */
+ tmpa = a->dp;
+
+ /* alias for dest */
+ tmpb = b->dp;
+
+ /* carry */
+ r = 0;
+ for (x = 0; x < a->used; x++) {
+
+ /* get what will be the *next* carry bit from the
+ * MSB of the current digit
+ */
+ rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
+
+ /* now shift up this digit, add in the carry [from the previous] */
+ *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
+
+ /* copy the carry that would be from the source
+ * digit into the next iteration
+ */
+ r = rr;
+ }
+
+ /* new leading digit? */
+ if (r != 0) {
+ /* add a MSB which is always 1 at this point */
+ *tmpb = 1;
+ ++(b->used);
+ }
+
+ /* now zero any excess digits on the destination
+ * that we didn't write to
+ */
+ tmpb = b->dp + b->used;
+ for (x = b->used; x < oldused; x++) {
+ *tmpb++ = 0;
+ }
+ }
+ b->sign = a->sign;
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_mul_2d.c b/tcl8.6/libtommath/bn_mp_mul_2d.c
new file mode 100644
index 0000000..4ac2e4e
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_mul_2d.c
@@ -0,0 +1,81 @@
+#include <tommath.h>
+#ifdef BN_MP_MUL_2D_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://math.libtomcrypt.com
+ */
+
+/* shift left by a certain bit count */
+int mp_mul_2d (const mp_int * a, int b, mp_int * c)
+{
+ mp_digit d;
+ int res;
+
+ /* copy */
+ if (a != c) {
+ if ((res = mp_copy (a, c)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
+ if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* shift by as many digits in the bit count */
+ if (b >= (int)DIGIT_BIT) {
+ if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* shift any bit count < DIGIT_BIT */
+ d = (mp_digit) (b % DIGIT_BIT);
+ if (d != 0) {
+ register mp_digit *tmpc, shift, mask, r, rr;
+ register int x;
+
+ /* bitmask for carries */
+ mask = (((mp_digit)1) << d) - 1;
+
+ /* shift for msbs */
+ shift = DIGIT_BIT - d;
+
+ /* alias */
+ tmpc = c->dp;
+
+ /* carry */
+ r = 0;
+ for (x = 0; x < c->used; x++) {
+ /* get the higher bits of the current word */
+ rr = (*tmpc >> shift) & mask;
+
+ /* shift the current word and OR in the carry */
+ *tmpc = ((*tmpc << d) | r) & MP_MASK;
+ ++tmpc;
+
+ /* set the carry to the carry bits of the current word */
+ r = rr;
+ }
+
+ /* set final carry */
+ if (r != 0) {
+ c->dp[(c->used)++] = r;
+ }
+ }
+ mp_clamp (c);
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_mul_d.c b/tcl8.6/libtommath/bn_mp_mul_d.c
new file mode 100644
index 0000000..ba45a0c
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_mul_d.c
@@ -0,0 +1,75 @@
+#include <tommath.h>
+#ifdef BN_MP_MUL_D_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://math.libtomcrypt.com
+ */
+
+/* multiply by a digit */
+int
+mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
+{
+ mp_digit u, *tmpa, *tmpc;
+ mp_word r;
+ int ix, res, olduse;
+
+ /* make sure c is big enough to hold a*b */
+ if (c->alloc < a->used + 1) {
+ if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* get the original destinations used count */
+ olduse = c->used;
+
+ /* set the sign */
+ c->sign = a->sign;
+
+ /* alias for a->dp [source] */
+ tmpa = a->dp;
+
+ /* alias for c->dp [dest] */
+ tmpc = c->dp;
+
+ /* zero carry */
+ u = 0;
+
+ /* compute columns */
+ for (ix = 0; ix < a->used; ix++) {
+ /* compute product and carry sum for this term */
+ r = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b);
+
+ /* mask off higher bits to get a single digit */
+ *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+ /* send carry into next iteration */
+ u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+ }
+
+ /* store final carry [if any] and increment ix offset */
+ *tmpc++ = u;
+ ++ix;
+
+ /* now zero digits above the top */
+ while (ix++ < olduse) {
+ *tmpc++ = 0;
+ }
+
+ /* set used count */
+ c->used = a->used + 1;
+ mp_clamp(c);
+
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_neg.c b/tcl8.6/libtommath/bn_mp_neg.c
new file mode 100644
index 0000000..07fb148
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_neg.c
@@ -0,0 +1,36 @@
+#include <tommath.h>
+#ifdef BN_MP_NEG_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://math.libtomcrypt.com
+ */
+
+/* b = -a */
+int mp_neg (const mp_int * a, mp_int * b)
+{
+ int res;
+ if (a != b) {
+ if ((res = mp_copy (a, b)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ if (mp_iszero(b) != MP_YES) {
+ b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
+ } else {
+ b->sign = MP_ZPOS;
+ }
+
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_or.c b/tcl8.6/libtommath/bn_mp_or.c
new file mode 100644
index 0000000..aa5b1bd
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_or.c
@@ -0,0 +1,46 @@
+#include <tommath.h>
+#ifdef BN_MP_OR_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://math.libtomcrypt.com
+ */
+
+/* OR two ints together */
+int mp_or (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res, ix, px;
+ mp_int t, *x;
+
+ if (a->used > b->used) {
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+ px = b->used;
+ x = b;
+ } else {
+ if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
+ return res;
+ }
+ px = a->used;
+ x = a;
+ }
+
+ for (ix = 0; ix < px; ix++) {
+ t.dp[ix] |= x->dp[ix];
+ }
+ mp_clamp (&t);
+ mp_exch (c, &t);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_radix_size.c b/tcl8.6/libtommath/bn_mp_radix_size.c
new file mode 100644
index 0000000..9d95c48
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_radix_size.c
@@ -0,0 +1,78 @@
+#include <tommath.h>
+#ifdef BN_MP_RADIX_SIZE_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
+ */
+
+/* returns size of ASCII reprensentation */
+int mp_radix_size (mp_int * a, int radix, int *size)
+{
+ int res, digs;
+ mp_int t;
+ mp_digit d;
+
+ *size = 0;
+
+ /* special case for binary */
+ if (radix == 2) {
+ *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
+ return MP_OKAY;
+ }
+
+ /* make sure the radix is in range */
+ if (radix < 2 || radix > 64) {
+ return MP_VAL;
+ }
+
+ if (mp_iszero(a) == MP_YES) {
+ *size = 2;
+ return MP_OKAY;
+ }
+
+ /* digs is the digit count */
+ digs = 0;
+
+ /* if it's negative add one for the sign */
+ if (a->sign == MP_NEG) {
+ ++digs;
+ }
+
+ /* init a copy of the input */
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* force temp to positive */
+ t.sign = MP_ZPOS;
+
+ /* fetch out all of the digits */
+ while (mp_iszero (&t) == MP_NO) {
+ if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ ++digs;
+ }
+ mp_clear (&t);
+
+ /* return digs + 1, the 1 is for the NULL byte that would be required. */
+ *size = digs + 1;
+ return MP_OKAY;
+}
+
+#endif
+
+/* $Source$ */
+/* $Revision: 0.41 $ */
+/* $Date: 2007-04-18 09:58:18 +0000 $ */
diff --git a/tcl8.6/libtommath/bn_mp_radix_smap.c b/tcl8.6/libtommath/bn_mp_radix_smap.c
new file mode 100644
index 0000000..7aeb375
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_radix_smap.c
@@ -0,0 +1,20 @@
+#include <tommath.h>
+#ifdef BN_MP_RADIX_SMAP_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://math.libtomcrypt.com
+ */
+
+/* chars used in radix conversions */
+const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_read_radix.c b/tcl8.6/libtommath/bn_mp_read_radix.c
new file mode 100644
index 0000000..4b92589
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_read_radix.c
@@ -0,0 +1,88 @@
+#include <tommath.h>
+#ifdef BN_MP_READ_RADIX_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://math.libtomcrypt.com
+ */
+
+/* read a string [ASCII] in a given radix */
+int mp_read_radix (mp_int * a, const char *str, int radix)
+{
+ int y, res, neg;
+ char ch;
+
+ /* zero the digit bignum */
+ mp_zero(a);
+
+ /* make sure the radix is ok */
+ if (radix < 2 || radix > 64) {
+ return MP_VAL;
+ }
+
+ /* if the leading digit is a
+ * minus set the sign to negative.
+ */
+ if (*str == '-') {
+ ++str;
+ neg = MP_NEG;
+ } else {
+ neg = MP_ZPOS;
+ }
+
+ /* set the integer to the default of zero */
+ mp_zero (a);
+
+ /* process each digit of the string */
+ while (*str) {
+ /* if the radix < 36 the conversion is case insensitive
+ * this allows numbers like 1AB and 1ab to represent the same value
+ * [e.g. in hex]
+ */
+ ch = (char) ((radix < 36) ? toupper ((unsigned char) *str) : *str);
+ for (y = 0; y < 64; y++) {
+ if (ch == mp_s_rmap[y]) {
+ break;
+ }
+ }
+
+ /* if the char was found in the map
+ * and is less than the given radix add it
+ * to the number, otherwise exit the loop.
+ */
+ if (y < radix) {
+ if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) {
+ return res;
+ }
+ if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) {
+ return res;
+ }
+ } else {
+ break;
+ }
+ ++str;
+ }
+
+ /* if an illegal character was found, fail. */
+
+ if ( *str != '\0' ) {
+ mp_zero( a );
+ return MP_VAL;
+ }
+
+ /* set the sign only if a != 0 */
+ if (mp_iszero(a) != 1) {
+ a->sign = neg;
+ }
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_rshd.c b/tcl8.6/libtommath/bn_mp_rshd.c
new file mode 100644
index 0000000..e6095b3
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_rshd.c
@@ -0,0 +1,68 @@
+#include <tommath.h>
+#ifdef BN_MP_RSHD_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://math.libtomcrypt.com
+ */
+
+/* shift right a certain amount of digits */
+void mp_rshd (mp_int * a, int b)
+{
+ int x;
+
+ /* if b <= 0 then ignore it */
+ if (b <= 0) {
+ return;
+ }
+
+ /* if b > used then simply zero it and return */
+ if (a->used <= b) {
+ mp_zero (a);
+ return;
+ }
+
+ {
+ register mp_digit *bottom, *top;
+
+ /* shift the digits down */
+
+ /* bottom */
+ bottom = a->dp;
+
+ /* top [offset into digits] */
+ top = a->dp + b;
+
+ /* this is implemented as a sliding window where
+ * the window is b-digits long and digits from
+ * the top of the window are copied to the bottom
+ *
+ * e.g.
+
+ b-2 | b-1 | b0 | b1 | b2 | ... | bb | ---->
+ /\ | ---->
+ \-------------------/ ---->
+ */
+ for (x = 0; x < (a->used - b); x++) {
+ *bottom++ = *top++;
+ }
+
+ /* zero the top digits */
+ for (; x < a->used; x++) {
+ *bottom++ = 0;
+ }
+ }
+
+ /* remove excess digits */
+ a->used -= b;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_set.c b/tcl8.6/libtommath/bn_mp_set.c
new file mode 100644
index 0000000..c32fc42
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_set.c
@@ -0,0 +1,25 @@
+#include <tommath.h>
+#ifdef BN_MP_SET_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://math.libtomcrypt.com
+ */
+
+/* set to a digit */
+void mp_set (mp_int * a, mp_digit b)
+{
+ mp_zero (a);
+ a->dp[0] = b & MP_MASK;
+ a->used = (a->dp[0] != 0) ? 1 : 0;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_set_int.c b/tcl8.6/libtommath/bn_mp_set_int.c
new file mode 100644
index 0000000..b0fc344
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_set_int.c
@@ -0,0 +1,44 @@
+#include <tommath.h>
+#ifdef BN_MP_SET_INT_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://math.libtomcrypt.com
+ */
+
+/* set a 32-bit const */
+int mp_set_int (mp_int * a, unsigned long b)
+{
+ int x, res;
+
+ mp_zero (a);
+
+ /* set four bits at a time */
+ for (x = 0; x < 8; x++) {
+ /* shift the number up four bits */
+ if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* OR in the top four bits of the source */
+ a->dp[0] |= (b >> 28) & 15;
+
+ /* shift the source up to the next four bits */
+ b <<= 4;
+
+ /* ensure that digits are not clamped off */
+ a->used += 1;
+ }
+ mp_clamp (a);
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_shrink.c b/tcl8.6/libtommath/bn_mp_shrink.c
new file mode 100644
index 0000000..bfdf93a
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_shrink.c
@@ -0,0 +1,36 @@
+#include <tommath.h>
+#ifdef BN_MP_SHRINK_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://math.libtomcrypt.com
+ */
+
+/* shrink a bignum */
+int mp_shrink (mp_int * a)
+{
+ mp_digit *tmp;
+ int used = 1;
+
+ if(a->used > 0)
+ used = a->used;
+
+ if (a->alloc != used) {
+ if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * used)) == NULL) {
+ return MP_MEM;
+ }
+ a->dp = tmp;
+ a->alloc = used;
+ }
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_sqr.c b/tcl8.6/libtommath/bn_mp_sqr.c
new file mode 100644
index 0000000..3938537
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_sqr.c
@@ -0,0 +1,54 @@
+#include <tommath.h>
+#ifdef BN_MP_SQR_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://math.libtomcrypt.com
+ */
+
+/* computes b = a*a */
+int
+mp_sqr (mp_int * a, mp_int * b)
+{
+ int res;
+
+#ifdef BN_MP_TOOM_SQR_C
+ /* use Toom-Cook? */
+ if (a->used >= TOOM_SQR_CUTOFF) {
+ res = mp_toom_sqr(a, b);
+ /* Karatsuba? */
+ } else
+#endif
+#ifdef BN_MP_KARATSUBA_SQR_C
+if (a->used >= KARATSUBA_SQR_CUTOFF) {
+ res = mp_karatsuba_sqr (a, b);
+ } else
+#endif
+ {
+#ifdef BN_FAST_S_MP_SQR_C
+ /* can we use the fast comba multiplier? */
+ if ((a->used * 2 + 1) < MP_WARRAY &&
+ a->used <
+ (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) {
+ res = fast_s_mp_sqr (a, b);
+ } else
+#endif
+#ifdef BN_S_MP_SQR_C
+ res = s_mp_sqr (a, b);
+#else
+ res = MP_VAL;
+#endif
+ }
+ b->sign = MP_ZPOS;
+ return res;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_sqrt.c b/tcl8.6/libtommath/bn_mp_sqrt.c
new file mode 100644
index 0000000..016b8ba
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_sqrt.c
@@ -0,0 +1,142 @@
+#include <tommath.h>
+
+#ifdef BN_MP_SQRT_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://math.libtomcrypt.com
+ */
+
+#ifndef NO_FLOATING_POINT
+#include <math.h>
+#endif
+
+/* this function is less generic than mp_n_root, simpler and faster */
+int mp_sqrt(mp_int *arg, mp_int *ret)
+{
+ int res;
+ mp_int t1,t2;
+ int i, j, k;
+#ifndef NO_FLOATING_POINT
+ volatile double d;
+ mp_digit dig;
+#endif
+
+ /* must be positive */
+ if (arg->sign == MP_NEG) {
+ return MP_VAL;
+ }
+
+ /* easy out */
+ if (mp_iszero(arg) == MP_YES) {
+ mp_zero(ret);
+ return MP_OKAY;
+ }
+
+ i = (arg->used / 2) - 1;
+ j = 2 * i;
+ if ((res = mp_init_size(&t1, i+2)) != MP_OKAY) {
+ return res;
+ }
+
+ if ((res = mp_init(&t2)) != MP_OKAY) {
+ goto E2;
+ }
+
+ for (k = 0; k < i; ++k) {
+ t1.dp[k] = (mp_digit) 0;
+ }
+
+#ifndef NO_FLOATING_POINT
+
+ /* Estimate the square root using the hardware floating point unit. */
+
+ d = 0.0;
+ for (k = arg->used-1; k >= j; --k) {
+ d = ldexp(d, DIGIT_BIT) + (double) (arg->dp[k]);
+ }
+
+ /*
+ * At this point, d is the nearest floating point number to the most
+ * significant 1 or 2 mp_digits of arg. Extract its square root.
+ */
+
+ d = sqrt(d);
+
+ /* dig is the most significant mp_digit of the square root */
+
+ dig = (mp_digit) ldexp(d, -DIGIT_BIT);
+
+ /*
+ * If the most significant digit is nonzero, find the next digit down
+ * by subtracting DIGIT_BIT times thie most significant digit.
+ * Subtract one from the result so that our initial estimate is always
+ * low.
+ */
+
+ if (dig) {
+ t1.used = i+2;
+ d -= ldexp((double) dig, DIGIT_BIT);
+ if (d >= 1.0) {
+ t1.dp[i+1] = dig;
+ t1.dp[i] = ((mp_digit) d) - 1;
+ } else {
+ t1.dp[i+1] = dig-1;
+ t1.dp[i] = MP_DIGIT_MAX;
+ }
+ } else {
+ t1.used = i+1;
+ t1.dp[i] = ((mp_digit) d) - 1;
+ }
+
+#else
+
+ /* Estimate the square root as having 1 in the most significant place. */
+
+ t1.used = i + 2;
+ t1.dp[i+1] = (mp_digit) 1;
+ t1.dp[i] = (mp_digit) 0;
+
+#endif
+
+ /* t1 > 0 */
+ if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
+ goto E1;
+ }
+ if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
+ goto E1;
+ }
+ if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
+ goto E1;
+ }
+ /* And now t1 > sqrt(arg) */
+ do {
+ if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
+ goto E1;
+ }
+ if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
+ goto E1;
+ }
+ if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
+ goto E1;
+ }
+ /* t1 >= sqrt(arg) >= t2 at this point */
+ } while (mp_cmp_mag(&t1,&t2) == MP_GT);
+
+ mp_exch(&t1,ret);
+
+E1: mp_clear(&t2);
+E2: mp_clear(&t1);
+ return res;
+}
+
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_sub.c b/tcl8.6/libtommath/bn_mp_sub.c
new file mode 100644
index 0000000..13cb43e
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_sub.c
@@ -0,0 +1,55 @@
+#include <tommath.h>
+#ifdef BN_MP_SUB_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://math.libtomcrypt.com
+ */
+
+/* high level subtraction (handles signs) */
+int
+mp_sub (mp_int * a, mp_int * b, mp_int * c)
+{
+ int sa, sb, res;
+
+ sa = a->sign;
+ sb = b->sign;
+
+ if (sa != sb) {
+ /* subtract a negative from a positive, OR */
+ /* subtract a positive from a negative. */
+ /* In either case, ADD their magnitudes, */
+ /* and use the sign of the first number. */
+ c->sign = sa;
+ res = s_mp_add (a, b, c);
+ } else {
+ /* subtract a positive from a positive, OR */
+ /* subtract a negative from a negative. */
+ /* First, take the difference between their */
+ /* magnitudes, then... */
+ if (mp_cmp_mag (a, b) != MP_LT) {
+ /* Copy the sign from the first */
+ c->sign = sa;
+ /* The first has a larger or equal magnitude */
+ res = s_mp_sub (a, b, c);
+ } else {
+ /* The result has the *opposite* sign from */
+ /* the first number. */
+ c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
+ /* The second has a larger magnitude */
+ res = s_mp_sub (b, a, c);
+ }
+ }
+ return res;
+}
+
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_sub_d.c b/tcl8.6/libtommath/bn_mp_sub_d.c
new file mode 100644
index 0000000..b1e4e3f
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_sub_d.c
@@ -0,0 +1,89 @@
+#include <tommath.h>
+#ifdef BN_MP_SUB_D_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://math.libtomcrypt.com
+ */
+
+/* single digit subtraction */
+int
+mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
+{
+ mp_digit *tmpa, *tmpc, mu;
+ int res, ix, oldused;
+
+ /* grow c as required */
+ if (c->alloc < a->used + 1) {
+ if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* if a is negative just do an unsigned
+ * addition [with fudged signs]
+ */
+ if (a->sign == MP_NEG) {
+ a->sign = MP_ZPOS;
+ res = mp_add_d(a, b, c);
+ a->sign = c->sign = MP_NEG;
+
+ /* clamp */
+ mp_clamp(c);
+
+ return res;
+ }
+
+ /* setup regs */
+ oldused = c->used;
+ tmpa = a->dp;
+ tmpc = c->dp;
+
+ /* if a <= b simply fix the single digit */
+ if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
+ if (a->used == 1) {
+ *tmpc++ = b - *tmpa;
+ } else {
+ *tmpc++ = b;
+ }
+ ix = 1;
+
+ /* negative/1digit */
+ c->sign = MP_NEG;
+ c->used = 1;
+ } else {
+ /* positive/size */
+ c->sign = MP_ZPOS;
+ c->used = a->used;
+
+ /* subtract first digit */
+ *tmpc = *tmpa++ - b;
+ mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
+ *tmpc++ &= MP_MASK;
+
+ /* handle rest of the digits */
+ for (ix = 1; ix < a->used; ix++) {
+ *tmpc = *tmpa++ - mu;
+ mu = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
+ *tmpc++ &= MP_MASK;
+ }
+ }
+
+ /* zero excess digits */
+ while (ix++ < oldused) {
+ *tmpc++ = 0;
+ }
+ mp_clamp(c);
+ return MP_OKAY;
+}
+
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_to_unsigned_bin.c b/tcl8.6/libtommath/bn_mp_to_unsigned_bin.c
new file mode 100644
index 0000000..9496398
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_to_unsigned_bin.c
@@ -0,0 +1,44 @@
+#include <tommath.h>
+#ifdef BN_MP_TO_UNSIGNED_BIN_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://math.libtomcrypt.com
+ */
+
+/* store in unsigned [big endian] format */
+int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
+{
+ int x, res;
+ mp_int t;
+
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+
+ x = 0;
+ while (mp_iszero (&t) == 0) {
+#ifndef MP_8BIT
+ b[x++] = (unsigned char) (t.dp[0] & 255);
+#else
+ b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7));
+#endif
+ if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ }
+ bn_reverse (b, x);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_to_unsigned_bin_n.c b/tcl8.6/libtommath/bn_mp_to_unsigned_bin_n.c
new file mode 100644
index 0000000..4f2a31d
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_to_unsigned_bin_n.c
@@ -0,0 +1,27 @@
+#include <tommath.h>
+#ifdef BN_MP_TO_UNSIGNED_BIN_N_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://math.libtomcrypt.com
+ */
+
+/* store in unsigned [big endian] format */
+int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
+{
+ if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) {
+ return MP_VAL;
+ }
+ *outlen = mp_unsigned_bin_size(a);
+ return mp_to_unsigned_bin(a, b);
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_toom_mul.c b/tcl8.6/libtommath/bn_mp_toom_mul.c
new file mode 100644
index 0000000..9daefbd
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_toom_mul.c
@@ -0,0 +1,280 @@
+#include <tommath.h>
+#ifdef BN_MP_TOOM_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.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* multiplication using the Toom-Cook 3-way algorithm
+ *
+ * Much more complicated than Karatsuba but has a lower
+ * asymptotic running time of O(N**1.464). This algorithm is
+ * only particularly useful on VERY large inputs
+ * (we're talking 1000s of digits here...).
+*/
+int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
+{
+ mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2;
+ int res, B;
+
+ /* init temps */
+ if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4,
+ &a0, &a1, &a2, &b0, &b1,
+ &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
+ return res;
+ }
+
+ /* B */
+ B = MIN(a->used, b->used) / 3;
+
+ /* a = a2 * B**2 + a1 * B + a0 */
+ if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_copy(a, &a1)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&a1, B);
+ mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
+
+ if ((res = mp_copy(a, &a2)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&a2, B*2);
+
+ /* b = b2 * B**2 + b1 * B + b0 */
+ if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_copy(b, &b1)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&b1, B);
+ mp_mod_2d(&b1, DIGIT_BIT * B, &b1);
+
+ if ((res = mp_copy(b, &b2)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&b2, B*2);
+
+ /* w0 = a0*b0 */
+ if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w4 = a2 * b2 */
+ if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */
+ if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */
+ if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+
+
+ /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */
+ if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* now solve the matrix
+
+ 0 0 0 0 1
+ 1 2 4 8 16
+ 1 1 1 1 1
+ 16 8 4 2 1
+ 1 0 0 0 0
+
+ using 12 subtractions, 4 shifts,
+ 2 small divisions and 1 small multiplication
+ */
+
+ /* r1 - r4 */
+ if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r0 */
+ if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1/2 */
+ if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3/2 */
+ if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r2 - r0 - r4 */
+ if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - r2 */
+ if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r2 */
+ if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - 8r0 */
+ if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - 8r4 */
+ if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* 3r2 - r1 - r3 */
+ if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - r2 */
+ if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r2 */
+ if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1/3 */
+ if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3/3 */
+ if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* at this point shift W[n] by B*n */
+ if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ERR:
+ mp_clear_multi(&w0, &w1, &w2, &w3, &w4,
+ &a0, &a1, &a2, &b0, &b1,
+ &b2, &tmp1, &tmp2, NULL);
+ return res;
+}
+
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_toom_sqr.c b/tcl8.6/libtommath/bn_mp_toom_sqr.c
new file mode 100644
index 0000000..9e3f79c
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_toom_sqr.c
@@ -0,0 +1,222 @@
+#include <tommath.h>
+#ifdef BN_MP_TOOM_SQR_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://math.libtomcrypt.com
+ */
+
+/* squaring using Toom-Cook 3-way algorithm */
+int
+mp_toom_sqr(mp_int *a, mp_int *b)
+{
+ mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
+ int res, B;
+
+ /* init temps */
+ if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) {
+ return res;
+ }
+
+ /* B */
+ B = a->used / 3;
+
+ /* a = a2 * B**2 + a1 * B + a0 */
+ if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_copy(a, &a1)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&a1, B);
+ mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
+
+ if ((res = mp_copy(a, &a2)) != MP_OKAY) {
+ goto ERR;
+ }
+ mp_rshd(&a2, B*2);
+
+ /* w0 = a0*a0 */
+ if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w4 = a2 * a2 */
+ if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w1 = (a2 + 2(a1 + 2a0))**2 */
+ if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* w3 = (a0 + 2(a1 + 2a2))**2 */
+ if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+
+
+ /* w2 = (a2 + a1 + a0)**2 */
+ if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* now solve the matrix
+
+ 0 0 0 0 1
+ 1 2 4 8 16
+ 1 1 1 1 1
+ 16 8 4 2 1
+ 1 0 0 0 0
+
+ using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
+ */
+
+ /* r1 - r4 */
+ if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r0 */
+ if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1/2 */
+ if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3/2 */
+ if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r2 - r0 - r4 */
+ if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - r2 */
+ if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r2 */
+ if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - 8r0 */
+ if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - 8r4 */
+ if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* 3r2 - r1 - r3 */
+ if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1 - r2 */
+ if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3 - r2 */
+ if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r1/3 */
+ if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
+ goto ERR;
+ }
+ /* r3/3 */
+ if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ /* at this point shift W[n] by B*n */
+ if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
+ goto ERR;
+ }
+ if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) {
+ goto ERR;
+ }
+
+ERR:
+ mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL);
+ return res;
+}
+
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_toradix_n.c b/tcl8.6/libtommath/bn_mp_toradix_n.c
new file mode 100644
index 0000000..dedce71
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_toradix_n.c
@@ -0,0 +1,84 @@
+#include <tommath.h>
+#ifdef BN_MP_TORADIX_N_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://math.libtomcrypt.com
+ */
+
+/* stores a bignum as a ASCII string in a given radix (2..64)
+ *
+ * Stores upto maxlen-1 chars and always a NULL byte
+ */
+int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen)
+{
+ int res, digs;
+ mp_int t;
+ mp_digit d;
+ char *_s = str;
+
+ /* check range of the maxlen, radix */
+ if (maxlen < 2 || radix < 2 || radix > 64) {
+ return MP_VAL;
+ }
+
+ /* quick out if its zero */
+ if (mp_iszero(a) == MP_YES) {
+ *str++ = '0';
+ *str = '\0';
+ return MP_OKAY;
+ }
+
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+
+ /* if it is negative output a - */
+ if (t.sign == MP_NEG) {
+ /* we have to reverse our digits later... but not the - sign!! */
+ ++_s;
+
+ /* store the flag and mark the number as positive */
+ *str++ = '-';
+ t.sign = MP_ZPOS;
+
+ /* subtract a char */
+ --maxlen;
+ }
+
+ digs = 0;
+ while (mp_iszero (&t) == 0) {
+ if (--maxlen < 1) {
+ /* no more room */
+ break;
+ }
+ if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+ mp_clear (&t);
+ return res;
+ }
+ *str++ = mp_s_rmap[d];
+ ++digs;
+ }
+
+ /* reverse the digits of the string. In this case _s points
+ * to the first digit [exluding the sign] of the number
+ */
+ bn_reverse ((unsigned char *)_s, digs);
+
+ /* append a NULL so the string is properly terminated */
+ *str = '\0';
+
+ mp_clear (&t);
+ return MP_OKAY;
+}
+
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_unsigned_bin_size.c b/tcl8.6/libtommath/bn_mp_unsigned_bin_size.c
new file mode 100644
index 0000000..58c18fb
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_unsigned_bin_size.c
@@ -0,0 +1,24 @@
+#include <tommath.h>
+#ifdef BN_MP_UNSIGNED_BIN_SIZE_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://math.libtomcrypt.com
+ */
+
+/* get the size for an unsigned equivalent */
+int mp_unsigned_bin_size (mp_int * a)
+{
+ int size = mp_count_bits (a);
+ return (size / 8 + ((size & 7) != 0 ? 1 : 0));
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_xor.c b/tcl8.6/libtommath/bn_mp_xor.c
new file mode 100644
index 0000000..432f42e
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_xor.c
@@ -0,0 +1,47 @@
+#include <tommath.h>
+#ifdef BN_MP_XOR_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://math.libtomcrypt.com
+ */
+
+/* XOR two ints together */
+int
+mp_xor (mp_int * a, mp_int * b, mp_int * c)
+{
+ int res, ix, px;
+ mp_int t, *x;
+
+ if (a->used > b->used) {
+ if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+ return res;
+ }
+ px = b->used;
+ x = b;
+ } else {
+ if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
+ return res;
+ }
+ px = a->used;
+ x = a;
+ }
+
+ for (ix = 0; ix < px; ix++) {
+ t.dp[ix] ^= x->dp[ix];
+ }
+ mp_clamp (&t);
+ mp_exch (c, &t);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_mp_zero.c b/tcl8.6/libtommath/bn_mp_zero.c
new file mode 100644
index 0000000..d697a60
--- /dev/null
+++ b/tcl8.6/libtommath/bn_mp_zero.c
@@ -0,0 +1,32 @@
+#include <tommath.h>
+#ifdef BN_MP_ZERO_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://math.libtomcrypt.com
+ */
+
+/* set to zero */
+void mp_zero (mp_int * a)
+{
+ int n;
+ mp_digit *tmp;
+
+ a->sign = MP_ZPOS;
+ a->used = 0;
+
+ tmp = a->dp;
+ for (n = 0; n < a->alloc; n++) {
+ *tmp++ = 0;
+ }
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_reverse.c b/tcl8.6/libtommath/bn_reverse.c
new file mode 100644
index 0000000..9d7fd29
--- /dev/null
+++ b/tcl8.6/libtommath/bn_reverse.c
@@ -0,0 +1,35 @@
+#include <tommath.h>
+#ifdef BN_REVERSE_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://math.libtomcrypt.com
+ */
+
+/* reverse an array, used for radix code */
+void
+bn_reverse (unsigned char *s, int len)
+{
+ int ix, iy;
+ unsigned char t;
+
+ ix = 0;
+ iy = len - 1;
+ while (ix < iy) {
+ t = s[ix];
+ s[ix] = s[iy];
+ s[iy] = t;
+ ++ix;
+ --iy;
+ }
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_s_mp_add.c b/tcl8.6/libtommath/bn_s_mp_add.c
new file mode 100644
index 0000000..7527bf8
--- /dev/null
+++ b/tcl8.6/libtommath/bn_s_mp_add.c
@@ -0,0 +1,105 @@
+#include <tommath.h>
+#ifdef BN_S_MP_ADD_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://math.libtomcrypt.com
+ */
+
+/* low level addition, based on HAC pp.594, Algorithm 14.7 */
+int
+s_mp_add (mp_int * a, mp_int * b, mp_int * c)
+{
+ mp_int *x;
+ int olduse, res, min, max;
+
+ /* find sizes, we let |a| <= |b| which means we have to sort
+ * them. "x" will point to the input with the most digits
+ */
+ if (a->used > b->used) {
+ min = b->used;
+ max = a->used;
+ x = a;
+ } else {
+ min = a->used;
+ max = b->used;
+ x = b;
+ }
+
+ /* init result */
+ if (c->alloc < max + 1) {
+ if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
+ return res;
+ }
+ }
+
+ /* get old used digit count and set new one */
+ olduse = c->used;
+ c->used = max + 1;
+
+ {
+ register mp_digit u, *tmpa, *tmpb, *tmpc;
+ register int i;
+
+ /* alias for digit pointers */
+
+ /* first input */
+ tmpa = a->dp;
+
+ /* second input */
+ tmpb = b->dp;
+
+ /* destination */
+ tmpc = c->dp;
+
+ /* zero the carry */
+ u = 0;
+ for (i = 0; i < min; i++) {
+ /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
+ *tmpc = *tmpa++ + *tmpb++ + u;
+
+ /* U = carry bit of T[i] */
+ u = *tmpc >> ((mp_digit)DIGIT_BIT);
+
+ /* take away carry bit from T[i] */
+ *tmpc++ &= MP_MASK;
+ }
+
+ /* now copy higher words if any, that is in A+B
+ * if A or B has more digits add those in
+ */
+ if (min != max) {
+ for (; i < max; i++) {
+ /* T[i] = X[i] + U */
+ *tmpc = x->dp[i] + u;
+
+ /* U = carry bit of T[i] */
+ u = *tmpc >> ((mp_digit)DIGIT_BIT);
+
+ /* take away carry bit from T[i] */
+ *tmpc++ &= MP_MASK;
+ }
+ }
+
+ /* add carry */
+ *tmpc++ = u;
+
+ /* clear digits above oldused */
+ for (i = c->used; i < olduse; i++) {
+ *tmpc++ = 0;
+ }
+ }
+
+ mp_clamp (c);
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_s_mp_mul_digs.c b/tcl8.6/libtommath/bn_s_mp_mul_digs.c
new file mode 100644
index 0000000..401f32e
--- /dev/null
+++ b/tcl8.6/libtommath/bn_s_mp_mul_digs.c
@@ -0,0 +1,86 @@
+#include <tommath.h>
+#ifdef BN_S_MP_MUL_DIGS_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://math.libtomcrypt.com
+ */
+
+/* multiplies |a| * |b| and only computes upto digs digits of result
+ * HAC pp. 595, Algorithm 14.12 Modified so you can control how
+ * many digits of output are created.
+ */
+int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+ mp_int t;
+ int res, pa, pb, ix, iy;
+ mp_digit u;
+ mp_word r;
+ mp_digit tmpx, *tmpt, *tmpy;
+
+ /* can we use the fast multiplier? */
+ if (((digs) < MP_WARRAY) &&
+ MIN (a->used, b->used) <
+ (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+ return fast_s_mp_mul_digs (a, b, c, digs);
+ }
+
+ if ((res = mp_init_size (&t, digs)) != MP_OKAY) {
+ return res;
+ }
+ t.used = digs;
+
+ /* compute the digits of the product directly */
+ pa = a->used;
+ for (ix = 0; ix < pa; ix++) {
+ /* set the carry to zero */
+ u = 0;
+
+ /* limit ourselves to making digs digits of output */
+ pb = MIN (b->used, digs - ix);
+
+ /* setup some aliases */
+ /* copy of the digit from a used within the nested loop */
+ tmpx = a->dp[ix];
+
+ /* an alias for the destination shifted ix places */
+ tmpt = t.dp + ix;
+
+ /* an alias for the digits of b */
+ tmpy = b->dp;
+
+ /* compute the columns of the output and propagate the carry */
+ for (iy = 0; iy < pb; iy++) {
+ /* compute the column as a mp_word */
+ r = ((mp_word)*tmpt) +
+ ((mp_word)tmpx) * ((mp_word)*tmpy++) +
+ ((mp_word) u);
+
+ /* the new column is the lower part of the result */
+ *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+ /* get the carry word from the result */
+ u = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+ }
+ /* set carry if it is placed below digs */
+ if (ix + iy < digs) {
+ *tmpt = u;
+ }
+ }
+
+ mp_clamp (&t);
+ mp_exch (&t, c);
+
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_s_mp_sqr.c b/tcl8.6/libtommath/bn_s_mp_sqr.c
new file mode 100644
index 0000000..464663f
--- /dev/null
+++ b/tcl8.6/libtommath/bn_s_mp_sqr.c
@@ -0,0 +1,80 @@
+#include <tommath.h>
+#ifdef BN_S_MP_SQR_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://math.libtomcrypt.com
+ */
+
+/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
+int s_mp_sqr (mp_int * a, mp_int * b)
+{
+ mp_int t;
+ int res, ix, iy, pa;
+ mp_word r;
+ mp_digit u, tmpx, *tmpt;
+
+ pa = a->used;
+ if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
+ return res;
+ }
+
+ /* default used is maximum possible size */
+ t.used = 2*pa + 1;
+
+ for (ix = 0; ix < pa; ix++) {
+ /* first calculate the digit at 2*ix */
+ /* calculate double precision result */
+ r = ((mp_word) t.dp[2*ix]) +
+ ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
+
+ /* store lower part in result */
+ t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
+
+ /* get the carry */
+ u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+
+ /* left hand side of A[ix] * A[iy] */
+ tmpx = a->dp[ix];
+
+ /* alias for where to store the results */
+ tmpt = t.dp + (2*ix + 1);
+
+ for (iy = ix + 1; iy < pa; iy++) {
+ /* first calculate the product */
+ r = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
+
+ /* now calculate the double precision result, note we use
+ * addition instead of *2 since it's easier to optimize
+ */
+ r = ((mp_word) *tmpt) + r + r + ((mp_word) u);
+
+ /* store lower part */
+ *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+ /* get carry */
+ u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+ }
+ /* propagate upwards */
+ while (u != ((mp_digit) 0)) {
+ r = ((mp_word) *tmpt) + ((mp_word) u);
+ *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+ u = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+ }
+ }
+
+ mp_clamp (&t);
+ mp_exch (&t, b);
+ mp_clear (&t);
+ return MP_OKAY;
+}
+#endif
diff --git a/tcl8.6/libtommath/bn_s_mp_sub.c b/tcl8.6/libtommath/bn_s_mp_sub.c
new file mode 100644
index 0000000..328c9e5
--- /dev/null
+++ b/tcl8.6/libtommath/bn_s_mp_sub.c
@@ -0,0 +1,85 @@
+#include <tommath.h>
+#ifdef BN_S_MP_SUB_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://math.libtomcrypt.com
+ */
+
+/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
+int
+s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
+{
+ int olduse, res, min, max;
+
+ /* find sizes */
+ min = b->used;
+ max = a->used;
+
+ /* init result */
+ if (c->alloc < max) {
+ if ((res = mp_grow (c, max)) != MP_OKAY) {
+ return res;
+ }
+ }
+ olduse = c->used;
+ c->used = max;
+
+ {
+ register mp_digit u, *tmpa, *tmpb, *tmpc;
+ register int i;
+
+ /* alias for digit pointers */
+ tmpa = a->dp;
+ tmpb = b->dp;
+ tmpc = c->dp;
+
+ /* set carry to zero */
+ u = 0;
+ for (i = 0; i < min; i++) {
+ /* T[i] = A[i] - B[i] - U */
+ *tmpc = *tmpa++ - *tmpb++ - u;
+
+ /* U = carry bit of T[i]
+ * Note this saves performing an AND operation since
+ * if a carry does occur it will propagate all the way to the
+ * MSB. As a result a single shift is enough to get the carry
+ */
+ u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
+
+ /* Clear carry from T[i] */
+ *tmpc++ &= MP_MASK;
+ }
+
+ /* now copy higher words if any, e.g. if A has more digits than B */
+ for (; i < max; i++) {
+ /* T[i] = A[i] - U */
+ *tmpc = *tmpa++ - u;
+
+ /* U = carry bit of T[i] */
+ u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
+
+ /* Clear carry from T[i] */
+ *tmpc++ &= MP_MASK;
+ }
+
+ /* clear digits above used (since we may not have grown result above) */
+ for (i = c->used; i < olduse; i++) {
+ *tmpc++ = 0;
+ }
+ }
+
+ mp_clamp (c);
+ return MP_OKAY;
+}
+
+#endif
diff --git a/tcl8.6/libtommath/bncore.c b/tcl8.6/libtommath/bncore.c
new file mode 100644
index 0000000..eb95a2e
--- /dev/null
+++ b/tcl8.6/libtommath/bncore.c
@@ -0,0 +1,32 @@
+#include <tommath.h>
+#ifdef BNCORE_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://math.libtomcrypt.com
+ */
+
+/* Known optimal configurations
+
+ CPU /Compiler /MUL CUTOFF/SQR CUTOFF
+-------------------------------------------------------------
+ Intel P4 Northwood /GCC v3.4.1 / 88/ 128/LTM 0.32 ;-)
+ AMD Athlon64 /GCC v3.4.4 / 80/ 120/LTM 0.35
+
+*/
+
+int KARATSUBA_MUL_CUTOFF = 80, /* Min. number of digits before Karatsuba multiplication is used. */
+ KARATSUBA_SQR_CUTOFF = 120, /* Min. number of digits before Karatsuba squaring is used. */
+
+ TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */
+ TOOM_SQR_CUTOFF = 400;
+#endif
diff --git a/tcl8.6/libtommath/tommath.h b/tcl8.6/libtommath/tommath.h
new file mode 100644
index 0000000..cb3435f
--- /dev/null
+++ b/tcl8.6/libtommath/tommath.h
@@ -0,0 +1,579 @@
+/* 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://math.libtomcrypt.com
+ */
+#ifndef BN_H_
+#define BN_H_
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <limits.h>
+
+#include <tommath_class.h>
+
+#ifndef MIN
+# define MIN(x,y) ((x)<(y)?(x):(y))
+#endif
+
+#ifndef MAX
+# define MAX(x,y) ((x)>(y)?(x):(y))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+
+/* C++ compilers don't like assigning void * to mp_digit * */
+#define OPT_CAST(x) (x *)
+
+#else
+
+/* C on the other hand doesn't care */
+#define OPT_CAST(x)
+
+#endif
+
+
+/* detect 64-bit mode if possible */
+#if defined(__x86_64__)
+# if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT))
+# define MP_64BIT
+# endif
+#endif
+
+/* some default configurations.
+ *
+ * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
+ * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
+ *
+ * At the very least a mp_digit must be able to hold 7 bits
+ * [any size beyond that is ok provided it doesn't overflow the data type]
+ */
+#ifdef MP_8BIT
+ typedef unsigned char mp_digit;
+ typedef unsigned short mp_word;
+#elif defined(MP_16BIT)
+ typedef unsigned short mp_digit;
+ typedef unsigned long mp_word;
+#elif defined(MP_64BIT)
+ /* for GCC only on supported platforms */
+#ifndef CRYPT
+ typedef unsigned long long ulong64;
+ typedef signed long long long64;
+#endif
+
+ typedef unsigned long mp_digit;
+ typedef unsigned long mp_word __attribute__ ((mode(TI)));
+
+# define DIGIT_BIT 60
+#else
+ /* this is the default case, 28-bit digits */
+
+ /* this is to make porting into LibTomCrypt easier :-) */
+#ifndef CRYPT
+# if defined(_MSC_VER) || defined(__BORLANDC__)
+ typedef unsigned __int64 ulong64;
+ typedef signed __int64 long64;
+# else
+ typedef unsigned long long ulong64;
+ typedef signed long long long64;
+# endif
+#endif
+
+ typedef unsigned long mp_digit;
+ typedef ulong64 mp_word;
+
+#ifdef MP_31BIT
+ /* this is an extension that uses 31-bit digits */
+# define DIGIT_BIT 31
+#else
+ /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
+# define DIGIT_BIT 28
+# define MP_28BIT
+#endif
+#endif
+
+/* define heap macros */
+#ifndef CRYPT
+ /* default to libc stuff */
+# ifndef XMALLOC
+# define XMALLOC malloc
+# define XFREE free
+# define XREALLOC realloc
+# define XCALLOC calloc
+# else
+ /* prototypes for our heap functions */
+ extern void *XMALLOC(size_t n);
+ extern void *XREALLOC(void *p, size_t n);
+ extern void *XCALLOC(size_t n, size_t s);
+ extern void XFREE(void *p);
+# endif
+#endif
+
+
+/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
+#ifndef DIGIT_BIT
+# define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) /* bits per digit */
+#endif
+
+#define MP_DIGIT_BIT DIGIT_BIT
+#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
+#define MP_DIGIT_MAX MP_MASK
+
+/* equalities */
+#define MP_LT -1 /* less than */
+#define MP_EQ 0 /* equal to */
+#define MP_GT 1 /* greater than */
+
+#define MP_ZPOS 0 /* positive integer */
+#define MP_NEG 1 /* negative */
+
+#define MP_OKAY 0 /* ok result */
+#define MP_MEM -2 /* out of mem */
+#define MP_VAL -3 /* invalid input */
+#define MP_RANGE MP_VAL
+
+#define MP_YES 1 /* yes response */
+#define MP_NO 0 /* no response */
+
+/* Primality generation flags */
+#define LTM_PRIME_BBS 0x0001 /* BBS style prime */
+#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */
+#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */
+
+typedef int mp_err;
+
+/* you'll have to tune these... */
+extern int KARATSUBA_MUL_CUTOFF,
+ KARATSUBA_SQR_CUTOFF,
+ TOOM_MUL_CUTOFF,
+ TOOM_SQR_CUTOFF;
+
+/* define this to use lower memory usage routines (exptmods mostly) */
+/* #define MP_LOW_MEM */
+
+/* default precision */
+#ifndef MP_PREC
+# ifndef MP_LOW_MEM
+# define MP_PREC 32 /* default digits of precision */
+# else
+# define MP_PREC 8 /* default digits of precision */
+# endif
+#endif
+
+/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
+#define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
+
+/* the infamous mp_int structure */
+typedef struct {
+ int used, alloc, sign;
+ mp_digit *dp;
+} mp_int;
+
+/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
+typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
+
+
+#define USED(m) ((m)->used)
+#define DIGIT(m,k) ((m)->dp[(k)])
+#define SIGN(m) ((m)->sign)
+
+/* error code to char* string */
+char *mp_error_to_string(int code);
+
+/* ---> init and deinit bignum functions <--- */
+/* init a bignum */
+int mp_init(mp_int *a);
+
+/* free a bignum */
+void mp_clear(mp_int *a);
+
+/* init a null terminated series of arguments */
+int mp_init_multi(mp_int *mp, ...);
+
+/* clear a null terminated series of arguments */
+void mp_clear_multi(mp_int *mp, ...);
+
+/* exchange two ints */
+void mp_exch(mp_int *a, mp_int *b);
+
+/* shrink ram required for a bignum */
+int mp_shrink(mp_int *a);
+
+/* grow an int to a given size */
+int mp_grow(mp_int *a, int size);
+
+/* init to a given number of digits */
+int mp_init_size(mp_int *a, int size);
+
+/* ---> Basic Manipulations <--- */
+#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
+#define mp_iseven(a) (((a)->used == 0 || (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
+#define mp_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
+
+/* set to zero */
+void mp_zero(mp_int *a);
+
+/* set to a digit */
+void mp_set(mp_int *a, mp_digit b);
+
+/* set a 32-bit const */
+int mp_set_int(mp_int *a, unsigned long b);
+
+/* get a 32-bit value */
+unsigned long mp_get_int(mp_int * a);
+
+/* initialize and set a digit */
+int mp_init_set (mp_int * a, mp_digit b);
+
+/* initialize and set 32-bit value */
+int mp_init_set_int (mp_int * a, unsigned long b);
+
+/* copy, b = a */
+int mp_copy(const mp_int *a, mp_int *b);
+
+/* inits and copies, a = b */
+int mp_init_copy(mp_int *a, mp_int *b);
+
+/* trim unused digits */
+void mp_clamp(mp_int *a);
+
+/* ---> digit manipulation <--- */
+
+/* right shift by "b" digits */
+void mp_rshd(mp_int *a, int b);
+
+/* left shift by "b" digits */
+int mp_lshd(mp_int *a, int b);
+
+/* c = a / 2**b */
+int mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d);
+
+/* b = a/2 */
+int mp_div_2(mp_int *a, mp_int *b);
+
+/* c = a * 2**b */
+int mp_mul_2d(const mp_int *a, int b, mp_int *c);
+
+/* b = a*2 */
+int mp_mul_2(mp_int *a, mp_int *b);
+
+/* c = a mod 2**d */
+int mp_mod_2d(const mp_int *a, int b, mp_int *c);
+
+/* computes a = 2**b */
+int mp_2expt(mp_int *a, int b);
+
+/* Counts the number of lsbs which are zero before the first zero bit */
+int mp_cnt_lsb(const mp_int *a);
+
+/* I Love Earth! */
+
+/* makes a pseudo-random int of a given size */
+int mp_rand(mp_int *a, int digits);
+
+/* ---> binary operations <--- */
+/* c = a XOR b */
+int mp_xor(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a OR b */
+int mp_or(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a AND b */
+int mp_and(mp_int *a, mp_int *b, mp_int *c);
+
+/* ---> Basic arithmetic <--- */
+
+/* b = -a */
+int mp_neg(const mp_int *a, mp_int *b);
+
+/* b = |a| */
+int mp_abs(mp_int *a, mp_int *b);
+
+/* compare a to b */
+int mp_cmp(const mp_int *a, const mp_int *b);
+
+/* compare |a| to |b| */
+int mp_cmp_mag(const mp_int *a, const mp_int *b);
+
+/* c = a + b */
+int mp_add(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a - b */
+int mp_sub(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a * b */
+int mp_mul(mp_int *a, mp_int *b, mp_int *c);
+
+/* b = a*a */
+int mp_sqr(mp_int *a, mp_int *b);
+
+/* a/b => cb + d == a */
+int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* c = a mod b, 0 <= c < b */
+int mp_mod(mp_int *a, mp_int *b, mp_int *c);
+
+/* ---> single digit functions <--- */
+
+/* compare against a single digit */
+int mp_cmp_d(const mp_int *a, mp_digit b);
+
+/* c = a + b */
+int mp_add_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* c = a - b */
+int mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* c = a * b */
+int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* a/b => cb + d == a */
+int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
+
+/* a/3 => 3c + d == a */
+int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
+
+/* c = a**b */
+int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* c = a mod b, 0 <= c < b */
+int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c);
+
+/* ---> number theory <--- */
+
+/* d = a + b (mod c) */
+int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* d = a - b (mod c) */
+int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* d = a * b (mod c) */
+int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* c = a * a (mod b) */
+int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = 1/a (mod b) */
+int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = (a, b) */
+int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
+
+/* produces value such that U1*a + U2*b = U3 */
+int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
+
+/* c = [a, b] or (a*b)/(a, b) */
+int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
+
+/* finds one of the b'th root of a, such that |c|**b <= |a|
+ *
+ * returns error if a < 0 and b is even
+ */
+int mp_n_root(mp_int *a, mp_digit b, mp_int *c);
+
+/* special sqrt algo */
+int mp_sqrt(mp_int *arg, mp_int *ret);
+
+/* is number a square? */
+int mp_is_square(mp_int *arg, int *ret);
+
+/* computes the jacobi c = (a | n) (or Legendre if b is prime) */
+int mp_jacobi(mp_int *a, mp_int *n, int *c);
+
+/* used to setup the Barrett reduction for a given modulus b */
+int mp_reduce_setup(mp_int *a, mp_int *b);
+
+/* Barrett Reduction, computes a (mod b) with a precomputed value c
+ *
+ * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely
+ * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code].
+ */
+int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
+
+/* setups the montgomery reduction */
+int mp_montgomery_setup(mp_int *a, mp_digit *mp);
+
+/* computes a = B**n mod b without division or multiplication useful for
+ * normalizing numbers in a Montgomery system.
+ */
+int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
+
+/* computes x/R == x (mod N) via Montgomery Reduction */
+int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
+
+/* returns 1 if a is a valid DR modulus */
+int mp_dr_is_modulus(mp_int *a);
+
+/* sets the value of "d" required for mp_dr_reduce */
+void mp_dr_setup(mp_int *a, mp_digit *d);
+
+/* reduces a modulo b using the Diminished Radix method */
+int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
+
+/* returns true if a can be reduced with mp_reduce_2k */
+int mp_reduce_is_2k(mp_int *a);
+
+/* determines k value for 2k reduction */
+int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
+
+/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
+int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
+
+/* returns true if a can be reduced with mp_reduce_2k_l */
+int mp_reduce_is_2k_l(mp_int *a);
+
+/* determines k value for 2k reduction */
+int mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
+
+/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
+int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);
+
+/* d = a**b (mod c) */
+int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* ---> Primes <--- */
+
+/* number of primes */
+#ifdef MP_8BIT
+# define PRIME_SIZE 31
+#else
+# define PRIME_SIZE 256
+#endif
+
+/* table of first PRIME_SIZE primes */
+extern const mp_digit ltm_prime_tab[];
+
+/* result=1 if a is divisible by one of the first PRIME_SIZE primes */
+int mp_prime_is_divisible(mp_int *a, int *result);
+
+/* performs one Fermat test of "a" using base "b".
+ * Sets result to 0 if composite or 1 if probable prime
+ */
+int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
+
+/* performs one Miller-Rabin test of "a" using base "b".
+ * Sets result to 0 if composite or 1 if probable prime
+ */
+int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result);
+
+/* This gives [for a given bit size] the number of trials required
+ * such that Miller-Rabin gives a prob of failure lower than 2^-96
+ */
+int mp_prime_rabin_miller_trials(int size);
+
+/* performs t rounds of Miller-Rabin on "a" using the first
+ * t prime bases. Also performs an initial sieve of trial
+ * division. Determines if "a" is prime with probability
+ * of error no more than (1/4)**t.
+ *
+ * Sets result to 1 if probably prime, 0 otherwise
+ */
+int mp_prime_is_prime(mp_int *a, int t, int *result);
+
+/* finds the next prime after the number "a" using "t" trials
+ * of Miller-Rabin.
+ *
+ * bbs_style = 1 means the prime must be congruent to 3 mod 4
+ */
+int mp_prime_next_prime(mp_int *a, int t, int bbs_style);
+
+/* makes a truly random prime of a given size (bytes),
+ * call with bbs = 1 if you want it to be congruent to 3 mod 4
+ *
+ * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ * The prime generated will be larger than 2^(8*size).
+ */
+#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat)
+
+/* makes a truly random prime of a given size (bits),
+ *
+ * Flags are as follows:
+ *
+ * LTM_PRIME_BBS - make prime congruent to 3 mod 4
+ * LTM_PRIME_SAFE - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
+ * LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero
+ * LTM_PRIME_2MSB_ON - make the 2nd highest bit one
+ *
+ * You have to supply a callback which fills in a buffer with random bytes. "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something). This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ */
+int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat);
+
+/* ---> radix conversion <--- */
+int mp_count_bits(const mp_int *a);
+
+int mp_unsigned_bin_size(mp_int *a);
+int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c);
+int mp_to_unsigned_bin(mp_int *a, unsigned char *b);
+int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
+
+int mp_signed_bin_size(mp_int *a);
+int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c);
+int mp_to_signed_bin(mp_int *a, unsigned char *b);
+int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
+
+int mp_read_radix(mp_int *a, const char *str, int radix);
+int mp_toradix(mp_int *a, char *str, int radix);
+int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen);
+int mp_radix_size(mp_int *a, int radix, int *size);
+
+int mp_fread(mp_int *a, int radix, FILE *stream);
+int mp_fwrite(mp_int *a, int radix, FILE *stream);
+
+#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
+#define mp_raw_size(mp) mp_signed_bin_size(mp)
+#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str))
+#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
+#define mp_mag_size(mp) mp_unsigned_bin_size(mp)
+#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str))
+
+#define mp_tobinary(M, S) mp_toradix((M), (S), 2)
+#define mp_tooctal(M, S) mp_toradix((M), (S), 8)
+#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
+#define mp_tohex(M, S) mp_toradix((M), (S), 16)
+
+/* lowlevel functions, do not call! */
+int s_mp_add(mp_int *a, mp_int *b, mp_int *c);
+int s_mp_sub(mp_int *a, mp_int *b, mp_int *c);
+#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
+int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int fast_s_mp_sqr(mp_int *a, mp_int *b);
+int s_mp_sqr(mp_int *a, mp_int *b);
+int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c);
+int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
+int mp_karatsuba_sqr(mp_int *a, mp_int *b);
+int mp_toom_sqr(mp_int *a, mp_int *b);
+int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c);
+int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c);
+int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
+int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode);
+int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int mode);
+void bn_reverse(unsigned char *s, int len);
+
+extern const char *mp_s_rmap;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tcl8.6/libtommath/tommath_class.h b/tcl8.6/libtommath/tommath_class.h
new file mode 100644
index 0000000..b9cc902
--- /dev/null
+++ b/tcl8.6/libtommath/tommath_class.h
@@ -0,0 +1,995 @@
+#if !(defined(LTM1) && defined(LTM2) && defined(LTM3))
+#if defined(LTM2)
+#define LTM3
+#endif
+#if defined(LTM1)
+#define LTM2
+#endif
+#define LTM1
+
+#if defined(LTM_ALL)
+#define BN_ERROR_C
+#define BN_FAST_MP_INVMOD_C
+#define BN_FAST_MP_MONTGOMERY_REDUCE_C
+#define BN_FAST_S_MP_MUL_DIGS_C
+#define BN_FAST_S_MP_MUL_HIGH_DIGS_C
+#define BN_FAST_S_MP_SQR_C
+#define BN_MP_2EXPT_C
+#define BN_MP_ABS_C
+#define BN_MP_ADD_C
+#define BN_MP_ADD_D_C
+#define BN_MP_ADDMOD_C
+#define BN_MP_AND_C
+#define BN_MP_CLAMP_C
+#define BN_MP_CLEAR_C
+#define BN_MP_CLEAR_MULTI_C
+#define BN_MP_CMP_C
+#define BN_MP_CMP_D_C
+#define BN_MP_CMP_MAG_C
+#define BN_MP_CNT_LSB_C
+#define BN_MP_COPY_C
+#define BN_MP_COUNT_BITS_C
+#define BN_MP_DIV_C
+#define BN_MP_DIV_2_C
+#define BN_MP_DIV_2D_C
+#define BN_MP_DIV_3_C
+#define BN_MP_DIV_D_C
+#define BN_MP_DR_IS_MODULUS_C
+#define BN_MP_DR_REDUCE_C
+#define BN_MP_DR_SETUP_C
+#define BN_MP_EXCH_C
+#define BN_MP_EXPT_D_C
+#define BN_MP_EXPTMOD_C
+#define BN_MP_EXPTMOD_FAST_C
+#define BN_MP_EXTEUCLID_C
+#define BN_MP_FREAD_C
+#define BN_MP_FWRITE_C
+#define BN_MP_GCD_C
+#define BN_MP_GET_INT_C
+#define BN_MP_GROW_C
+#define BN_MP_INIT_C
+#define BN_MP_INIT_COPY_C
+#define BN_MP_INIT_MULTI_C
+#define BN_MP_INIT_SET_C
+#define BN_MP_INIT_SET_INT_C
+#define BN_MP_INIT_SIZE_C
+#define BN_MP_INVMOD_C
+#define BN_MP_INVMOD_SLOW_C
+#define BN_MP_IS_SQUARE_C
+#define BN_MP_JACOBI_C
+#define BN_MP_KARATSUBA_MUL_C
+#define BN_MP_KARATSUBA_SQR_C
+#define BN_MP_LCM_C
+#define BN_MP_LSHD_C
+#define BN_MP_MOD_C
+#define BN_MP_MOD_2D_C
+#define BN_MP_MOD_D_C
+#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+#define BN_MP_MONTGOMERY_REDUCE_C
+#define BN_MP_MONTGOMERY_SETUP_C
+#define BN_MP_MUL_C
+#define BN_MP_MUL_2_C
+#define BN_MP_MUL_2D_C
+#define BN_MP_MUL_D_C
+#define BN_MP_MULMOD_C
+#define BN_MP_N_ROOT_C
+#define BN_MP_NEG_C
+#define BN_MP_OR_C
+#define BN_MP_PRIME_FERMAT_C
+#define BN_MP_PRIME_IS_DIVISIBLE_C
+#define BN_MP_PRIME_IS_PRIME_C
+#define BN_MP_PRIME_MILLER_RABIN_C
+#define BN_MP_PRIME_NEXT_PRIME_C
+#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+#define BN_MP_PRIME_RANDOM_EX_C
+#define BN_MP_RADIX_SIZE_C
+#define BN_MP_RADIX_SMAP_C
+#define BN_MP_RAND_C
+#define BN_MP_READ_RADIX_C
+#define BN_MP_READ_SIGNED_BIN_C
+#define BN_MP_READ_UNSIGNED_BIN_C
+#define BN_MP_REDUCE_C
+#define BN_MP_REDUCE_2K_C
+#define BN_MP_REDUCE_2K_L_C
+#define BN_MP_REDUCE_2K_SETUP_C
+#define BN_MP_REDUCE_2K_SETUP_L_C
+#define BN_MP_REDUCE_IS_2K_C
+#define BN_MP_REDUCE_IS_2K_L_C
+#define BN_MP_REDUCE_SETUP_C
+#define BN_MP_RSHD_C
+#define BN_MP_SET_C
+#define BN_MP_SET_INT_C
+#define BN_MP_SHRINK_C
+#define BN_MP_SIGNED_BIN_SIZE_C
+#define BN_MP_SQR_C
+#define BN_MP_SQRMOD_C
+#define BN_MP_SQRT_C
+#define BN_MP_SUB_C
+#define BN_MP_SUB_D_C
+#define BN_MP_SUBMOD_C
+#define BN_MP_TO_SIGNED_BIN_C
+#define BN_MP_TO_SIGNED_BIN_N_C
+#define BN_MP_TO_UNSIGNED_BIN_C
+#define BN_MP_TO_UNSIGNED_BIN_N_C
+#define BN_MP_TOOM_MUL_C
+#define BN_MP_TOOM_SQR_C
+#define BN_MP_TORADIX_C
+#define BN_MP_TORADIX_N_C
+#define BN_MP_UNSIGNED_BIN_SIZE_C
+#define BN_MP_XOR_C
+#define BN_MP_ZERO_C
+#define BN_PRIME_TAB_C
+#define BN_REVERSE_C
+#define BN_S_MP_ADD_C
+#define BN_S_MP_EXPTMOD_C
+#define BN_S_MP_MUL_DIGS_C
+#define BN_S_MP_MUL_HIGH_DIGS_C
+#define BN_S_MP_SQR_C
+#define BN_S_MP_SUB_C
+#define BNCORE_C
+#endif
+
+#if defined(BN_ERROR_C)
+ #define BN_MP_ERROR_TO_STRING_C
+#endif
+
+#if defined(BN_FAST_MP_INVMOD_C)
+ #define BN_MP_ISEVEN_C
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_COPY_C
+ #define BN_MP_MOD_C
+ #define BN_MP_SET_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_ISODD_C
+ #define BN_MP_SUB_C
+ #define BN_MP_CMP_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_CMP_D_C
+ #define BN_MP_ADD_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_FAST_S_MP_MUL_DIGS_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_FAST_S_MP_SQR_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_2EXPT_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_GROW_C
+#endif
+
+#if defined(BN_MP_ABS_C)
+ #define BN_MP_COPY_C
+#endif
+
+#if defined(BN_MP_ADD_C)
+ #define BN_S_MP_ADD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_ADD_D_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_SUB_D_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_ADDMOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_ADD_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_AND_C)
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_CLAMP_C)
+#endif
+
+#if defined(BN_MP_CLEAR_C)
+#endif
+
+#if defined(BN_MP_CLEAR_MULTI_C)
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_CMP_C)
+ #define BN_MP_CMP_MAG_C
+#endif
+
+#if defined(BN_MP_CMP_D_C)
+#endif
+
+#if defined(BN_MP_CMP_MAG_C)
+#endif
+
+#if defined(BN_MP_CNT_LSB_C)
+ #define BN_MP_ISZERO_C
+#endif
+
+#if defined(BN_MP_COPY_C)
+ #define BN_MP_GROW_C
+#endif
+
+#if defined(BN_MP_COUNT_BITS_C)
+#endif
+
+#if defined(BN_MP_DIV_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_COPY_C
+ #define BN_MP_ZERO_C
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_SET_C
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_ABS_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_CMP_C
+ #define BN_MP_SUB_C
+ #define BN_MP_ADD_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_MULTI_C
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_INIT_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_DIV_2_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_DIV_2D_C)
+ #define BN_MP_COPY_C
+ #define BN_MP_ZERO_C
+ #define BN_MP_INIT_C
+ #define BN_MP_MOD_2D_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_MP_DIV_3_C)
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_DIV_D_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_COPY_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_DIV_3_C
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_DR_IS_MODULUS_C)
+#endif
+
+#if defined(BN_MP_DR_REDUCE_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_DR_SETUP_C)
+#endif
+
+#if defined(BN_MP_EXCH_C)
+#endif
+
+#if defined(BN_MP_EXPT_D_C)
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_SET_C
+ #define BN_MP_SQR_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MUL_C
+#endif
+
+#if defined(BN_MP_EXPTMOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_INVMOD_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_ABS_C
+ #define BN_MP_CLEAR_MULTI_C
+ #define BN_MP_REDUCE_IS_2K_L_C
+ #define BN_S_MP_EXPTMOD_C
+ #define BN_MP_DR_IS_MODULUS_C
+ #define BN_MP_REDUCE_IS_2K_C
+ #define BN_MP_ISODD_C
+ #define BN_MP_EXPTMOD_FAST_C
+#endif
+
+#if defined(BN_MP_EXPTMOD_FAST_C)
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_INIT_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MONTGOMERY_SETUP_C
+ #define BN_FAST_MP_MONTGOMERY_REDUCE_C
+ #define BN_MP_MONTGOMERY_REDUCE_C
+ #define BN_MP_DR_SETUP_C
+ #define BN_MP_DR_REDUCE_C
+ #define BN_MP_REDUCE_2K_SETUP_C
+ #define BN_MP_REDUCE_2K_C
+ #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+ #define BN_MP_MULMOD_C
+ #define BN_MP_SET_C
+ #define BN_MP_MOD_C
+ #define BN_MP_COPY_C
+ #define BN_MP_SQR_C
+ #define BN_MP_MUL_C
+ #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_MP_EXTEUCLID_C)
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_SET_C
+ #define BN_MP_COPY_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_DIV_C
+ #define BN_MP_MUL_C
+ #define BN_MP_SUB_C
+ #define BN_MP_NEG_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_FREAD_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_S_RMAP_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_ADD_D_C
+ #define BN_MP_CMP_D_C
+#endif
+
+#if defined(BN_MP_FWRITE_C)
+ #define BN_MP_RADIX_SIZE_C
+ #define BN_MP_TORADIX_C
+#endif
+
+#if defined(BN_MP_GCD_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_ABS_C
+ #define BN_MP_ZERO_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_CNT_LSB_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_EXCH_C
+ #define BN_S_MP_SUB_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_GET_INT_C)
+#endif
+
+#if defined(BN_MP_GROW_C)
+#endif
+
+#if defined(BN_MP_INIT_C)
+#endif
+
+#if defined(BN_MP_INIT_COPY_C)
+ #define BN_MP_COPY_C
+#endif
+
+#if defined(BN_MP_INIT_MULTI_C)
+ #define BN_MP_ERR_C
+ #define BN_MP_INIT_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_INIT_SET_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_SET_C
+#endif
+
+#if defined(BN_MP_INIT_SET_INT_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_SET_INT_C
+#endif
+
+#if defined(BN_MP_INIT_SIZE_C)
+ #define BN_MP_INIT_C
+#endif
+
+#if defined(BN_MP_INVMOD_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_ISODD_C
+ #define BN_FAST_MP_INVMOD_C
+ #define BN_MP_INVMOD_SLOW_C
+#endif
+
+#if defined(BN_MP_INVMOD_SLOW_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_MOD_C
+ #define BN_MP_COPY_C
+ #define BN_MP_ISEVEN_C
+ #define BN_MP_SET_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_ISODD_C
+ #define BN_MP_ADD_C
+ #define BN_MP_SUB_C
+ #define BN_MP_CMP_C
+ #define BN_MP_CMP_D_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_IS_SQUARE_C)
+ #define BN_MP_MOD_D_C
+ #define BN_MP_INIT_SET_INT_C
+ #define BN_MP_MOD_C
+ #define BN_MP_GET_INT_C
+ #define BN_MP_SQRT_C
+ #define BN_MP_SQR_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_JACOBI_C)
+ #define BN_MP_CMP_D_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_CNT_LSB_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_MOD_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_KARATSUBA_MUL_C)
+ #define BN_MP_MUL_C
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_SUB_C
+ #define BN_MP_ADD_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_KARATSUBA_SQR_C)
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_SQR_C
+ #define BN_MP_SUB_C
+ #define BN_S_MP_ADD_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_ADD_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_LCM_C)
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_GCD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_DIV_C
+ #define BN_MP_MUL_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_LSHD_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_RSHD_C
+#endif
+
+#if defined(BN_MP_MOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_DIV_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_ADD_C
+ #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_MP_MOD_2D_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_COPY_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_MOD_D_C)
+ #define BN_MP_DIV_D_C
+#endif
+
+#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C)
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_2EXPT_C
+ #define BN_MP_SET_C
+ #define BN_MP_MUL_2_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_MONTGOMERY_REDUCE_C)
+ #define BN_FAST_MP_MONTGOMERY_REDUCE_C
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_MONTGOMERY_SETUP_C)
+#endif
+
+#if defined(BN_MP_MUL_C)
+ #define BN_MP_TOOM_MUL_C
+ #define BN_MP_KARATSUBA_MUL_C
+ #define BN_FAST_S_MP_MUL_DIGS_C
+ #define BN_S_MP_MUL_C
+ #define BN_S_MP_MUL_DIGS_C
+#endif
+
+#if defined(BN_MP_MUL_2_C)
+ #define BN_MP_GROW_C
+#endif
+
+#if defined(BN_MP_MUL_2D_C)
+ #define BN_MP_COPY_C
+ #define BN_MP_GROW_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_MUL_D_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_MULMOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_MUL_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_N_ROOT_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_SET_C
+ #define BN_MP_COPY_C
+ #define BN_MP_EXPT_D_C
+ #define BN_MP_MUL_C
+ #define BN_MP_SUB_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_DIV_C
+ #define BN_MP_CMP_C
+ #define BN_MP_SUB_D_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_NEG_C)
+ #define BN_MP_COPY_C
+ #define BN_MP_ISZERO_C
+#endif
+
+#if defined(BN_MP_OR_C)
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_FERMAT_C)
+ #define BN_MP_CMP_D_C
+ #define BN_MP_INIT_C
+ #define BN_MP_EXPTMOD_C
+ #define BN_MP_CMP_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_IS_DIVISIBLE_C)
+ #define BN_MP_MOD_D_C
+#endif
+
+#if defined(BN_MP_PRIME_IS_PRIME_C)
+ #define BN_MP_CMP_D_C
+ #define BN_MP_PRIME_IS_DIVISIBLE_C
+ #define BN_MP_INIT_C
+ #define BN_MP_SET_C
+ #define BN_MP_PRIME_MILLER_RABIN_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_MILLER_RABIN_C)
+ #define BN_MP_CMP_D_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_SUB_D_C
+ #define BN_MP_CNT_LSB_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_EXPTMOD_C
+ #define BN_MP_CMP_C
+ #define BN_MP_SQRMOD_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_NEXT_PRIME_C)
+ #define BN_MP_CMP_D_C
+ #define BN_MP_SET_C
+ #define BN_MP_SUB_D_C
+ #define BN_MP_ISEVEN_C
+ #define BN_MP_MOD_D_C
+ #define BN_MP_INIT_C
+ #define BN_MP_ADD_D_C
+ #define BN_MP_PRIME_MILLER_RABIN_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C)
+#endif
+
+#if defined(BN_MP_PRIME_RANDOM_EX_C)
+ #define BN_MP_READ_UNSIGNED_BIN_C
+ #define BN_MP_PRIME_IS_PRIME_C
+ #define BN_MP_SUB_D_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_MUL_2_C
+ #define BN_MP_ADD_D_C
+#endif
+
+#if defined(BN_MP_RADIX_SIZE_C)
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_DIV_D_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_RADIX_SMAP_C)
+ #define BN_MP_S_RMAP_C
+#endif
+
+#if defined(BN_MP_RAND_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_ADD_D_C
+ #define BN_MP_LSHD_C
+#endif
+
+#if defined(BN_MP_READ_RADIX_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_S_RMAP_C
+ #define BN_MP_RADIX_SMAP_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_ADD_D_C
+ #define BN_MP_ISZERO_C
+#endif
+
+#if defined(BN_MP_READ_SIGNED_BIN_C)
+ #define BN_MP_READ_UNSIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_READ_UNSIGNED_BIN_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_ZERO_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_REDUCE_C)
+ #define BN_MP_REDUCE_SETUP_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_MUL_C
+ #define BN_S_MP_MUL_HIGH_DIGS_C
+ #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
+ #define BN_MP_MOD_2D_C
+ #define BN_S_MP_MUL_DIGS_C
+ #define BN_MP_SUB_C
+ #define BN_MP_CMP_D_C
+ #define BN_MP_SET_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_ADD_C
+ #define BN_MP_CMP_C
+ #define BN_S_MP_SUB_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_MUL_D_C
+ #define BN_S_MP_ADD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_L_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_MUL_C
+ #define BN_S_MP_ADD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_SETUP_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_2EXPT_C
+ #define BN_MP_CLEAR_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_SETUP_L_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_2EXPT_C
+ #define BN_MP_COUNT_BITS_C
+ #define BN_S_MP_SUB_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_IS_2K_C)
+ #define BN_MP_REDUCE_2K_C
+ #define BN_MP_COUNT_BITS_C
+#endif
+
+#if defined(BN_MP_REDUCE_IS_2K_L_C)
+#endif
+
+#if defined(BN_MP_REDUCE_SETUP_C)
+ #define BN_MP_2EXPT_C
+ #define BN_MP_DIV_C
+#endif
+
+#if defined(BN_MP_RSHD_C)
+ #define BN_MP_ZERO_C
+#endif
+
+#if defined(BN_MP_SET_C)
+ #define BN_MP_ZERO_C
+#endif
+
+#if defined(BN_MP_SET_INT_C)
+ #define BN_MP_ZERO_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_SHRINK_C)
+#endif
+
+#if defined(BN_MP_SIGNED_BIN_SIZE_C)
+ #define BN_MP_UNSIGNED_BIN_SIZE_C
+#endif
+
+#if defined(BN_MP_SQR_C)
+ #define BN_MP_TOOM_SQR_C
+ #define BN_MP_KARATSUBA_SQR_C
+ #define BN_FAST_S_MP_SQR_C
+ #define BN_S_MP_SQR_C
+#endif
+
+#if defined(BN_MP_SQRMOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_SQR_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_SQRT_C)
+ #define BN_MP_N_ROOT_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_ZERO_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_DIV_C
+ #define BN_MP_ADD_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_SUB_C)
+ #define BN_S_MP_ADD_C
+ #define BN_MP_CMP_MAG_C
+ #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_SUB_D_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_ADD_D_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_SUBMOD_C)
+ #define BN_MP_INIT_C
+ #define BN_MP_SUB_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_TO_SIGNED_BIN_C)
+ #define BN_MP_TO_UNSIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_TO_SIGNED_BIN_N_C)
+ #define BN_MP_SIGNED_BIN_SIZE_C
+ #define BN_MP_TO_SIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_TO_UNSIGNED_BIN_C)
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_ISZERO_C
+ #define BN_MP_DIV_2D_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_TO_UNSIGNED_BIN_N_C)
+ #define BN_MP_UNSIGNED_BIN_SIZE_C
+ #define BN_MP_TO_UNSIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_TOOM_MUL_C)
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_MOD_2D_C
+ #define BN_MP_COPY_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_MUL_C
+ #define BN_MP_MUL_2_C
+ #define BN_MP_ADD_C
+ #define BN_MP_SUB_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_DIV_3_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_TOOM_SQR_C)
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_MOD_2D_C
+ #define BN_MP_COPY_C
+ #define BN_MP_RSHD_C
+ #define BN_MP_SQR_C
+ #define BN_MP_MUL_2_C
+ #define BN_MP_ADD_C
+ #define BN_MP_SUB_C
+ #define BN_MP_DIV_2_C
+ #define BN_MP_MUL_2D_C
+ #define BN_MP_MUL_D_C
+ #define BN_MP_DIV_3_C
+ #define BN_MP_LSHD_C
+ #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_TORADIX_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_DIV_D_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_S_RMAP_C
+#endif
+
+#if defined(BN_MP_TORADIX_N_C)
+ #define BN_MP_ISZERO_C
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_DIV_D_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_S_RMAP_C
+#endif
+
+#if defined(BN_MP_UNSIGNED_BIN_SIZE_C)
+ #define BN_MP_COUNT_BITS_C
+#endif
+
+#if defined(BN_MP_XOR_C)
+ #define BN_MP_INIT_COPY_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_ZERO_C)
+#endif
+
+#if defined(BN_PRIME_TAB_C)
+#endif
+
+#if defined(BN_REVERSE_C)
+#endif
+
+#if defined(BN_S_MP_ADD_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_S_MP_EXPTMOD_C)
+ #define BN_MP_COUNT_BITS_C
+ #define BN_MP_INIT_C
+ #define BN_MP_CLEAR_C
+ #define BN_MP_REDUCE_SETUP_C
+ #define BN_MP_REDUCE_C
+ #define BN_MP_REDUCE_2K_SETUP_L_C
+ #define BN_MP_REDUCE_2K_L_C
+ #define BN_MP_MOD_C
+ #define BN_MP_COPY_C
+ #define BN_MP_SQR_C
+ #define BN_MP_MUL_C
+ #define BN_MP_SET_C
+ #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_S_MP_MUL_DIGS_C)
+ #define BN_FAST_S_MP_MUL_DIGS_C
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_S_MP_MUL_HIGH_DIGS_C)
+ #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_S_MP_SQR_C)
+ #define BN_MP_INIT_SIZE_C
+ #define BN_MP_CLAMP_C
+ #define BN_MP_EXCH_C
+ #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_S_MP_SUB_C)
+ #define BN_MP_GROW_C
+ #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BNCORE_C)
+#endif
+
+#ifdef LTM3
+#define LTM_LAST
+#endif
+#include <tommath_superclass.h>
+#include <tommath_class.h>
+#else
+#define LTM_LAST
+#endif
diff --git a/tcl8.6/libtommath/tommath_superclass.h b/tcl8.6/libtommath/tommath_superclass.h
new file mode 100644
index 0000000..e3926df
--- /dev/null
+++ b/tcl8.6/libtommath/tommath_superclass.h
@@ -0,0 +1,72 @@
+/* super class file for PK algos */
+
+/* default ... include all MPI */
+#define LTM_ALL
+
+/* RSA only (does not support DH/DSA/ECC) */
+/* #define SC_RSA_1 */
+
+/* For reference.... On an Athlon64 optimizing for speed...
+
+ LTM's mpi.o with all functions [striped] is 142KiB in size.
+
+*/
+
+/* Works for RSA only, mpi.o is 68KiB */
+#ifdef SC_RSA_1
+ #define BN_MP_SHRINK_C
+ #define BN_MP_LCM_C
+ #define BN_MP_PRIME_RANDOM_EX_C
+ #define BN_MP_INVMOD_C
+ #define BN_MP_GCD_C
+ #define BN_MP_MOD_C
+ #define BN_MP_MULMOD_C
+ #define BN_MP_ADDMOD_C
+ #define BN_MP_EXPTMOD_C
+ #define BN_MP_SET_INT_C
+ #define BN_MP_INIT_MULTI_C
+ #define BN_MP_CLEAR_MULTI_C
+ #define BN_MP_UNSIGNED_BIN_SIZE_C
+ #define BN_MP_TO_UNSIGNED_BIN_C
+ #define BN_MP_MOD_D_C
+ #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+ #define BN_REVERSE_C
+ #define BN_PRIME_TAB_C
+
+ /* other modifiers */
+ #define BN_MP_DIV_SMALL /* Slower division, not critical */
+
+ /* here we are on the last pass so we turn things off. The functions classes are still there
+ * but we remove them specifically from the build. This also invokes tweaks in functions
+ * like removing support for even moduli, etc...
+ */
+#ifdef LTM_LAST
+ #undef BN_MP_TOOM_MUL_C
+ #undef BN_MP_TOOM_SQR_C
+ #undef BN_MP_KARATSUBA_MUL_C
+ #undef BN_MP_KARATSUBA_SQR_C
+ #undef BN_MP_REDUCE_C
+ #undef BN_MP_REDUCE_SETUP_C
+ #undef BN_MP_DR_IS_MODULUS_C
+ #undef BN_MP_DR_SETUP_C
+ #undef BN_MP_DR_REDUCE_C
+ #undef BN_MP_REDUCE_IS_2K_C
+ #undef BN_MP_REDUCE_2K_SETUP_C
+ #undef BN_MP_REDUCE_2K_C
+ #undef BN_S_MP_EXPTMOD_C
+ #undef BN_MP_DIV_3_C
+ #undef BN_S_MP_MUL_HIGH_DIGS_C
+ #undef BN_FAST_S_MP_MUL_HIGH_DIGS_C
+ #undef BN_FAST_MP_INVMOD_C
+
+ /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold
+ * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines]
+ * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without
+ * trouble.
+ */
+ #undef BN_S_MP_MUL_DIGS_C
+ #undef BN_S_MP_SQR_C
+ #undef BN_MP_MONTGOMERY_REDUCE_C
+#endif
+
+#endif