security/nss/lib/freebl/ecl/tests/ec_naft.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/lib/freebl/ecl/tests/ec_naft.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,117 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +#include "mpi.h"
     1.9 +#include "mplogic.h"
    1.10 +#include "ecl.h"
    1.11 +#include "ecp.h"
    1.12 +#include "ecl-priv.h"
    1.13 +
    1.14 +#include <sys/types.h>
    1.15 +#include <stdio.h>
    1.16 +#include <time.h>
    1.17 +#include <sys/time.h>
    1.18 +#include <sys/resource.h>
    1.19 +
    1.20 +/* Returns 2^e as an integer. This is meant to be used for small powers of 
    1.21 + * two. */
    1.22 +int ec_twoTo(int e);
    1.23 +
    1.24 +/* Number of bits of scalar to test */
    1.25 +#define BITSIZE 160
    1.26 +
    1.27 +/* Time k repetitions of operation op. */
    1.28 +#define M_TimeOperation(op, k) { \
    1.29 +	double dStart, dNow, dUserTime; \
    1.30 +	struct rusage ru; \
    1.31 +	int i; \
    1.32 +	getrusage(RUSAGE_SELF, &ru); \
    1.33 +	dStart = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \
    1.34 +	for (i = 0; i < k; i++) { \
    1.35 +		{ op; } \
    1.36 +	}; \
    1.37 +	getrusage(RUSAGE_SELF, &ru); \
    1.38 +	dNow = (double)ru.ru_utime.tv_sec+(double)ru.ru_utime.tv_usec*0.000001; \
    1.39 +	dUserTime = dNow-dStart; \
    1.40 +	if (dUserTime) printf("    %-45s\n      k: %6i, t: %6.2f sec\n", #op, k, dUserTime); \
    1.41 +}
    1.42 +
    1.43 +/* Tests wNAF computation. Non-adjacent-form is discussed in the paper: D. 
    1.44 + * Hankerson, J. Hernandez and A. Menezes, "Software implementation of
    1.45 + * elliptic curve cryptography over binary fields", Proc. CHES 2000. */
    1.46 +
    1.47 +mp_err
    1.48 +main(void)
    1.49 +{
    1.50 +	signed char naf[BITSIZE + 1];
    1.51 +	ECGroup *group = NULL;
    1.52 +	mp_int k;
    1.53 +	mp_int *scalar;
    1.54 +	int i, count;
    1.55 +	int res;
    1.56 +	int w = 5;
    1.57 +	char s[1000];
    1.58 +
    1.59 +	/* Get a 160 bit scalar to compute wNAF from */
    1.60 +	group = ECGroup_fromName(ECCurve_SECG_PRIME_160R1);
    1.61 +	scalar = &group->genx;
    1.62 +
    1.63 +	/* Compute wNAF representation of scalar */
    1.64 +	ec_compute_wNAF(naf, BITSIZE, scalar, w);
    1.65 +
    1.66 +	/* Verify correctness of representation */
    1.67 +	mp_init(&k);				/* init k to 0 */
    1.68 +
    1.69 +	for (i = BITSIZE; i >= 0; i--) {
    1.70 +		mp_add(&k, &k, &k);
    1.71 +		/* digits in mp_???_d are unsigned */
    1.72 +		if (naf[i] >= 0) {
    1.73 +			mp_add_d(&k, naf[i], &k);
    1.74 +		} else {
    1.75 +			mp_sub_d(&k, -naf[i], &k);
    1.76 +		}
    1.77 +	}
    1.78 +
    1.79 +	if (mp_cmp(&k, scalar) != 0) {
    1.80 +		printf("Error:  incorrect NAF value.\n");
    1.81 +		MP_CHECKOK(mp_toradix(&k, s, 16));
    1.82 +		printf("NAF value   %s\n", s);
    1.83 +		MP_CHECKOK(mp_toradix(scalar, s, 16));
    1.84 +		printf("original value   %s\n", s);
    1.85 +		goto CLEANUP;
    1.86 +	}
    1.87 +
    1.88 +	/* Verify digits of representation are valid */
    1.89 +	for (i = 0; i <= BITSIZE; i++) {
    1.90 +		if (naf[i] % 2 == 0 && naf[i] != 0) {
    1.91 +			printf("Error:  Even non-zero digit found.\n");
    1.92 +			goto CLEANUP;
    1.93 +		}
    1.94 +		if (naf[i] < -(ec_twoTo(w - 1)) || naf[i] >= ec_twoTo(w - 1)) {
    1.95 +			printf("Error:  Magnitude of naf digit too large.\n");
    1.96 +			goto CLEANUP;
    1.97 +		}
    1.98 +	}
    1.99 +
   1.100 +	/* Verify sparsity of representation */
   1.101 +	count = w - 1;
   1.102 +	for (i = 0; i <= BITSIZE; i++) {
   1.103 +		if (naf[i] != 0) {
   1.104 +			if (count < w - 1) {
   1.105 +				printf("Error:  Sparsity failed.\n");
   1.106 +				goto CLEANUP;
   1.107 +			}
   1.108 +			count = 0;
   1.109 +		} else
   1.110 +			count++;
   1.111 +	}
   1.112 +
   1.113 +	/* Check timing */
   1.114 +	M_TimeOperation(ec_compute_wNAF(naf, BITSIZE, scalar, w), 10000);
   1.115 +
   1.116 +	printf("Test passed.\n");
   1.117 +  CLEANUP:
   1.118 +	ECGroup_free(group);
   1.119 +	return MP_OKAY;
   1.120 +}

mercurial