summaryrefslogtreecommitdiff
path: root/security/nss/lib/freebl/mpi/mdxptest.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/freebl/mpi/mdxptest.c')
-rw-r--r--security/nss/lib/freebl/mpi/mdxptest.c342
1 files changed, 342 insertions, 0 deletions
diff --git a/security/nss/lib/freebl/mpi/mdxptest.c b/security/nss/lib/freebl/mpi/mdxptest.c
new file mode 100644
index 000000000..0377c5949
--- /dev/null
+++ b/security/nss/lib/freebl/mpi/mdxptest.c
@@ -0,0 +1,342 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include <time.h>
+#include "mpi.h"
+#include "mpi-priv.h"
+
+/* #define OLD_WAY 1 */
+
+/* This key is the 1024-bit test key used for speed testing of RSA private
+** key ops.
+*/
+
+#define CONST const
+
+static CONST unsigned char default_n[128] = {
+0xc2,0xae,0x96,0x89,0xaf,0xce,0xd0,0x7b,0x3b,0x35,0xfd,0x0f,0xb1,0xf4,0x7a,0xd1,
+0x3c,0x7d,0xb5,0x86,0xf2,0x68,0x36,0xc9,0x97,0xe6,0x82,0x94,0x86,0xaa,0x05,0x39,
+0xec,0x11,0x51,0xcc,0x5c,0xa1,0x59,0xba,0x29,0x18,0xf3,0x28,0xf1,0x9d,0xe3,0xae,
+0x96,0x5d,0x6d,0x87,0x73,0xf6,0xf6,0x1f,0xd0,0x2d,0xfb,0x2f,0x7a,0x13,0x7f,0xc8,
+0x0c,0x7a,0xe9,0x85,0xfb,0xce,0x74,0x86,0xf8,0xef,0x2f,0x85,0x37,0x73,0x0f,0x62,
+0x4e,0x93,0x17,0xb7,0x7e,0x84,0x9a,0x94,0x11,0x05,0xca,0x0d,0x31,0x4b,0x2a,0xc8,
+0xdf,0xfe,0xe9,0x0c,0x13,0xc7,0xf2,0xad,0x19,0x64,0x28,0x3c,0xb5,0x6a,0xc8,0x4b,
+0x79,0xea,0x7c,0xce,0x75,0x92,0x45,0x3e,0xa3,0x9d,0x64,0x6f,0x04,0x69,0x19,0x17
+};
+
+static CONST unsigned char default_d[128] = {
+0x13,0xcb,0xbc,0xf2,0xf3,0x35,0x8c,0x6d,0x7b,0x6f,0xd9,0xf3,0xa6,0x9c,0xbd,0x80,
+0x59,0x2e,0x4f,0x2f,0x11,0xa7,0x17,0x2b,0x18,0x8f,0x0f,0xe8,0x1a,0x69,0x5f,0x6e,
+0xac,0x5a,0x76,0x7e,0xd9,0x4c,0x6e,0xdb,0x47,0x22,0x8a,0x57,0x37,0x7a,0x5e,0x94,
+0x7a,0x25,0xb5,0xe5,0x78,0x1d,0x3c,0x99,0xaf,0x89,0x7d,0x69,0x2e,0x78,0x9d,0x1d,
+0x84,0xc8,0xc1,0xd7,0x1a,0xb2,0x6d,0x2d,0x8a,0xd9,0xab,0x6b,0xce,0xae,0xb0,0xa0,
+0x58,0x55,0xad,0x5c,0x40,0x8a,0xd6,0x96,0x08,0x8a,0xe8,0x63,0xe6,0x3d,0x6c,0x20,
+0x49,0xc7,0xaf,0x0f,0x25,0x73,0xd3,0x69,0x43,0x3b,0xf2,0x32,0xf8,0x3d,0x5e,0xee,
+0x7a,0xca,0xd6,0x94,0x55,0xe5,0xbd,0x25,0x34,0x8d,0x63,0x40,0xb5,0x8a,0xc3,0x01
+};
+
+
+#define DEFAULT_ITERS 50
+
+typedef clock_t timetype;
+#define gettime(x) *(x) = clock()
+#define subtime(a, b) a -= b
+#define msec(x) ((clock_t)((double)x * 1000.0 / CLOCKS_PER_SEC))
+#define sec(x) (x / CLOCKS_PER_SEC)
+
+struct TimingContextStr {
+ timetype start;
+ timetype end;
+ timetype interval;
+
+ int minutes;
+ int seconds;
+ int millisecs;
+};
+
+typedef struct TimingContextStr TimingContext;
+
+TimingContext *CreateTimingContext(void)
+{
+ return (TimingContext *)malloc(sizeof(TimingContext));
+}
+
+void DestroyTimingContext(TimingContext *ctx)
+{
+ free(ctx);
+}
+
+void TimingBegin(TimingContext *ctx)
+{
+ gettime(&ctx->start);
+}
+
+static void timingUpdate(TimingContext *ctx)
+{
+
+ ctx->millisecs = msec(ctx->interval) % 1000;
+ ctx->seconds = sec(ctx->interval);
+ ctx->minutes = ctx->seconds / 60;
+ ctx->seconds %= 60;
+
+}
+
+void TimingEnd(TimingContext *ctx)
+{
+ gettime(&ctx->end);
+ ctx->interval = ctx->end;
+ subtime(ctx->interval, ctx->start);
+ timingUpdate(ctx);
+}
+
+char *TimingGenerateString(TimingContext *ctx)
+{
+ static char sBuf[4096];
+
+ sprintf(sBuf, "%d minutes, %d.%03d seconds", ctx->minutes,
+ ctx->seconds, ctx->millisecs);
+ return sBuf;
+}
+
+static void
+dumpBytes( unsigned char * b, int l)
+{
+ int i;
+ if (l <= 0)
+ return;
+ for (i = 0; i < l; ++i) {
+ if (i % 16 == 0)
+ printf("\t");
+ printf(" %02x", b[i]);
+ if (i % 16 == 15)
+ printf("\n");
+ }
+ if ((i % 16) != 0)
+ printf("\n");
+ printf("\n");
+}
+
+static mp_err
+testNewFuncs(const unsigned char * modulusBytes, int modulus_len)
+{
+ mp_err mperr = MP_OKAY;
+ mp_int modulus;
+ unsigned char buf[512];
+
+ mperr = mp_init(&modulus);
+ mperr = mp_read_unsigned_octets(&modulus, modulusBytes, modulus_len );
+ mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len);
+ mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len+1);
+ mperr = mp_to_fixlen_octets(&modulus, buf, modulus_len+4);
+ mperr = mp_to_unsigned_octets(&modulus, buf, modulus_len);
+ mperr = mp_to_signed_octets(&modulus, buf, modulus_len + 1);
+ mp_clear(&modulus);
+ return mperr;
+}
+
+int
+testModExp( const unsigned char * modulusBytes,
+ const unsigned int expo,
+ const unsigned char * input,
+ unsigned char * output,
+ int modulus_len)
+{
+ mp_err mperr = MP_OKAY;
+ mp_int modulus;
+ mp_int base;
+ mp_int exponent;
+ mp_int result;
+
+ mperr = mp_init(&modulus);
+ mperr += mp_init(&base);
+ mperr += mp_init(&exponent);
+ mperr += mp_init(&result);
+ /* we initialize all mp_ints unconditionally, even if some fail.
+ ** This guarantees that the DIGITS pointer is valid (even if null).
+ ** So, mp_clear will do the right thing below.
+ */
+ if (mperr == MP_OKAY) {
+ mperr = mp_read_unsigned_octets(&modulus,
+ modulusBytes + (sizeof default_n - modulus_len), modulus_len );
+ mperr += mp_read_unsigned_octets(&base, input, modulus_len );
+ mp_set(&exponent, expo);
+ if (mperr == MP_OKAY) {
+#if OLD_WAY
+ mperr = s_mp_exptmod(&base, &exponent, &modulus, &result);
+#else
+ mperr = mp_exptmod(&base, &exponent, &modulus, &result);
+#endif
+ if (mperr == MP_OKAY) {
+ mperr = mp_to_fixlen_octets(&result, output, modulus_len);
+ }
+ }
+ }
+ mp_clear(&base);
+ mp_clear(&result);
+
+ mp_clear(&modulus);
+ mp_clear(&exponent);
+
+ return (int)mperr;
+}
+
+int
+doModExp( const unsigned char * modulusBytes,
+ const unsigned char * exponentBytes,
+ const unsigned char * input,
+ unsigned char * output,
+ int modulus_len)
+{
+ mp_err mperr = MP_OKAY;
+ mp_int modulus;
+ mp_int base;
+ mp_int exponent;
+ mp_int result;
+
+ mperr = mp_init(&modulus);
+ mperr += mp_init(&base);
+ mperr += mp_init(&exponent);
+ mperr += mp_init(&result);
+ /* we initialize all mp_ints unconditionally, even if some fail.
+ ** This guarantees that the DIGITS pointer is valid (even if null).
+ ** So, mp_clear will do the right thing below.
+ */
+ if (mperr == MP_OKAY) {
+ mperr = mp_read_unsigned_octets(&modulus,
+ modulusBytes + (sizeof default_n - modulus_len), modulus_len );
+ mperr += mp_read_unsigned_octets(&exponent, exponentBytes, modulus_len );
+ mperr += mp_read_unsigned_octets(&base, input, modulus_len );
+ if (mperr == MP_OKAY) {
+#if OLD_WAY
+ mperr = s_mp_exptmod(&base, &exponent, &modulus, &result);
+#else
+ mperr = mp_exptmod(&base, &exponent, &modulus, &result);
+#endif
+ if (mperr == MP_OKAY) {
+ mperr = mp_to_fixlen_octets(&result, output, modulus_len);
+ }
+ }
+ }
+ mp_clear(&base);
+ mp_clear(&result);
+
+ mp_clear(&modulus);
+ mp_clear(&exponent);
+
+ return (int)mperr;
+}
+
+int
+main(int argc, char **argv)
+{
+ TimingContext * timeCtx;
+ char * progName;
+ long iters = DEFAULT_ITERS;
+ unsigned int modulus_len;
+ int i;
+ int rv;
+ unsigned char buf [1024];
+ unsigned char buf2[1024];
+
+ progName = strrchr(argv[0], '/');
+ if (!progName)
+ progName = strrchr(argv[0], '\\');
+ progName = progName ? progName+1 : argv[0];
+
+ if (argc >= 2) {
+ iters = atol(argv[1]);
+ }
+
+ if (argc >= 3) {
+ modulus_len = atol(argv[2]);
+ } else
+ modulus_len = sizeof default_n;
+
+ /* no library init function !? */
+
+ memset(buf, 0x41, sizeof buf);
+
+ if (iters < 2) {
+ testNewFuncs( default_n, modulus_len);
+ testNewFuncs( default_n+1, modulus_len - 1);
+ testNewFuncs( default_n+2, modulus_len - 2);
+ testNewFuncs( default_n+3, modulus_len - 3);
+
+ printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
+ rv = testModExp(default_n, 0, buf, buf2, modulus_len);
+ dumpBytes((unsigned char *)buf2, modulus_len);
+
+ printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
+ rv = testModExp(default_n, 1, buf, buf2, modulus_len);
+ dumpBytes((unsigned char *)buf2, modulus_len);
+
+ printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
+ rv = testModExp(default_n, 2, buf, buf2, modulus_len);
+ dumpBytes((unsigned char *)buf2, modulus_len);
+
+ printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
+ rv = testModExp(default_n, 3, buf, buf2, modulus_len);
+ dumpBytes((unsigned char *)buf2, modulus_len);
+ }
+ printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
+ rv = doModExp(default_n, default_d, buf, buf2, modulus_len);
+ if (rv != 0) {
+ fprintf(stderr, "Error in modexp operation:\n");
+ exit(1);
+ }
+ dumpBytes((unsigned char *)buf2, modulus_len);
+ printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
+
+ timeCtx = CreateTimingContext();
+ TimingBegin(timeCtx);
+ i = iters;
+ while (i--) {
+ rv = doModExp(default_n, default_d, buf, buf2, modulus_len);
+ if (rv != 0) {
+ fprintf(stderr, "Error in modexp operation\n");
+ exit(1);
+ }
+ }
+ TimingEnd(timeCtx);
+ printf("%ld iterations in %s\n", iters, TimingGenerateString(timeCtx));
+ printf("%lu allocations, %lu frees, %lu copies\n", mp_allocs, mp_frees, mp_copies);
+
+ return 0;
+}