Beispiel #1
0
/* Construct ECGroup from named parameters. */
ECGroup *
ECGroup_fromName(const ECCurveName name)
{
    ECGroup *group = NULL;
    ECCurveParams *params = NULL;
    mp_err res = MP_OKAY;

    params = EC_GetNamedCurveParams(name);
    if (params == NULL) {
        res = MP_UNDEF;
        goto CLEANUP;
    }

    /* construct actual group */
    group = ecgroup_fromNameAndHex(name, params);
    if (group == NULL) {
        res = MP_UNDEF;
        goto CLEANUP;
    }

CLEANUP:
    EC_FreeCurveParams(params);
    if (res != MP_OKAY) {
        ECGroup_free(group);
        return NULL;
    }
    return group;
}
Beispiel #2
0
/* Allocate memory for a new ECGroup object. */
ECGroup *
ECGroup_new()
{
    mp_err res = MP_OKAY;
    ECGroup *group;
    group = (ECGroup *) malloc(sizeof(ECGroup));
    if (group == NULL)
        return NULL;
    group->constructed = MP_YES;
    group->meth = NULL;
    group->text = NULL;
    MP_DIGITS(&group->curvea) = 0;
    MP_DIGITS(&group->curveb) = 0;
    MP_DIGITS(&group->genx) = 0;
    MP_DIGITS(&group->geny) = 0;
    MP_DIGITS(&group->order) = 0;
    group->base_point_mul = NULL;
    group->points_mul = NULL;
    group->validate_point = NULL;
    group->extra1 = NULL;
    group->extra2 = NULL;
    group->extra_free = NULL;
    MP_CHECKOK(mp_init(&group->curvea));
    MP_CHECKOK(mp_init(&group->curveb));
    MP_CHECKOK(mp_init(&group->genx));
    MP_CHECKOK(mp_init(&group->geny));
    MP_CHECKOK(mp_init(&group->order));

CLEANUP:
    if (res != MP_OKAY) {
        ECGroup_free(group);
        return NULL;
    }
    return group;
}
Beispiel #3
0
/* Tests a number of curves optimized using floating point arithmetic */
int
main(void)
{
	mp_err res = MP_OKAY;
	ECGroup *ecgroup = NULL;

	/* specific arithmetic tests */
	M_TestCurve("SECG-160R1", ECCurve_SECG_PRIME_160R1);
	M_TestCurve("SECG-192R1", ECCurve_SECG_PRIME_192R1);
	M_TestCurve("SEGC-224R1", ECCurve_SECG_PRIME_224R1);

  CLEANUP:
	ECGroup_free(ecgroup);
	if (res != MP_OKAY) {
		printf("Error: exiting with error value %i\n", res);
	}
	return res;
}
Beispiel #4
0
/* Construct a generic ECGroup for elliptic curves over prime fields with
 * field arithmetic implemented in Montgomery coordinates. */
ECGroup *
ECGroup_consGFp_mont(const mp_int *irr, const mp_int *curvea,
                     const mp_int *curveb, const mp_int *genx,
                     const mp_int *geny, const mp_int *order, int cofactor)
{
    mp_err res = MP_OKAY;
    ECGroup *group = NULL;

    group = ECGroup_new();
    if (group == NULL)
        return NULL;

    group->meth = GFMethod_consGFp_mont(irr);
    if (group->meth == NULL) {
        res = MP_MEM;
        goto CLEANUP;
    }
    MP_CHECKOK(group->meth->
               field_enc(curvea, &group->curvea, group->meth));
    MP_CHECKOK(group->meth->
               field_enc(curveb, &group->curveb, group->meth));
    MP_CHECKOK(group->meth->field_enc(genx, &group->genx, group->meth));
    MP_CHECKOK(group->meth->field_enc(geny, &group->geny, group->meth));
    MP_CHECKOK(mp_copy(order, &group->order));
    group->cofactor = cofactor;
    group->point_add = &ec_GFp_pt_add_aff;
    group->point_sub = &ec_GFp_pt_sub_aff;
    group->point_dbl = &ec_GFp_pt_dbl_aff;
    group->point_mul = &ec_GFp_pt_mul_jm_wNAF;
    group->base_point_mul = NULL;
    group->points_mul = &ec_GFp_pts_mul_jac;
    group->validate_point = &ec_GFp_validate_point;

CLEANUP:
    if (res != MP_OKAY) {
        ECGroup_free(group);
        return NULL;
    }
    return group;
}
Beispiel #5
0
/* Construct a generic ECGroup for elliptic curves over binary polynomial
 * fields. */
ECGroup *
ECGroup_consGF2m(const mp_int *irr, const unsigned int irr_arr[5],
                 const mp_int *curvea, const mp_int *curveb,
                 const mp_int *genx, const mp_int *geny,
                 const mp_int *order, int cofactor)
{
    mp_err res = MP_OKAY;
    ECGroup *group = NULL;

    group = ECGroup_new();
    if (group == NULL)
        return NULL;

    group->meth = GFMethod_consGF2m(irr, irr_arr);
    if (group->meth == NULL) {
        res = MP_MEM;
        goto CLEANUP;
    }
    MP_CHECKOK(mp_copy(curvea, &group->curvea));
    MP_CHECKOK(mp_copy(curveb, &group->curveb));
    MP_CHECKOK(mp_copy(genx, &group->genx));
    MP_CHECKOK(mp_copy(geny, &group->geny));
    MP_CHECKOK(mp_copy(order, &group->order));
    group->cofactor = cofactor;
    group->point_add = &ec_GF2m_pt_add_aff;
    group->point_sub = &ec_GF2m_pt_sub_aff;
    group->point_dbl = &ec_GF2m_pt_dbl_aff;
    group->point_mul = &ec_GF2m_pt_mul_mont;
    group->base_point_mul = NULL;
    group->points_mul = &ec_pts_mul_basic;
    group->validate_point = &ec_GF2m_validate_point;

CLEANUP:
    if (res != MP_OKAY) {
        ECGroup_free(group);
        return NULL;
    }
    return group;
}
Beispiel #6
0
/* Allocate memory for a new ECGroup object. */
ECGroup *
ECGroup_new(int kmflag)
{
	mp_err res = MP_OKAY;
	ECGroup *group;
#ifdef _KERNEL
	group = (ECGroup *) kmem_alloc(sizeof(ECGroup), kmflag);
#else
	group = (ECGroup *) malloc(sizeof(ECGroup));
#endif
	if (group == NULL)
		return NULL;
	group->constructed = MP_YES;
        group->meth = NULL;
	group->text = NULL;
	MP_DIGITS(&group->curvea) = 0;
	MP_DIGITS(&group->curveb) = 0;
	MP_DIGITS(&group->genx) = 0;
	MP_DIGITS(&group->geny) = 0;
	MP_DIGITS(&group->order) = 0;
	group->base_point_mul = NULL;
	group->points_mul = NULL;
	group->validate_point = NULL;
	group->extra1 = NULL;
	group->extra2 = NULL;
	group->extra_free = NULL;
	MP_CHECKOK(mp_init(&group->curvea, kmflag));
	MP_CHECKOK(mp_init(&group->curveb, kmflag));
	MP_CHECKOK(mp_init(&group->genx, kmflag));
	MP_CHECKOK(mp_init(&group->geny, kmflag));
	MP_CHECKOK(mp_init(&group->order, kmflag));

  CLEANUP:
	if (res != MP_OKAY) {
		ECGroup_free(group);
		return NULL;
	}
	return group;
}
Beispiel #7
0
/* Validates an EC public key as described in Section 5.2.2 of
 * X9.62. The ECDH primitive when used without the cofactor does
 * not address small subgroup attacks, which may occur when the
 * public key is not valid. These attacks can be prevented by 
 * validating the public key before using ECDH.
 */
SECStatus 
EC_ValidatePublicKey(ECParams *ecParams, SECItem *publicValue)
{
#ifndef NSS_DISABLE_ECC
    mp_int Px, Py;
    ECGroup *group = NULL;
    SECStatus rv = SECFailure;
    mp_err err = MP_OKAY;
    int len;

    if (!ecParams || !publicValue) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }
	
    /* NOTE: We only support uncompressed points for now */
    len = (ecParams->fieldID.size + 7) >> 3;
    if (publicValue->data[0] != EC_POINT_FORM_UNCOMPRESSED) {
	PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
	return SECFailure;
    } else if (publicValue->len != (2 * len + 1)) {
	PORT_SetError(SEC_ERROR_BAD_KEY);
	return SECFailure;
    }

    MP_DIGITS(&Px) = 0;
    MP_DIGITS(&Py) = 0;
    CHECK_MPI_OK( mp_init(&Px) );
    CHECK_MPI_OK( mp_init(&Py) );

    /* Initialize Px and Py */
    CHECK_MPI_OK( mp_read_unsigned_octets(&Px, publicValue->data + 1, (mp_size) len) );
    CHECK_MPI_OK( mp_read_unsigned_octets(&Py, publicValue->data + 1 + len, (mp_size) len) );

    /* construct from named params */
    group = ECGroup_fromName(ecParams->name);
    if (group == NULL) {
	/*
	 * ECGroup_fromName fails if ecParams->name is not a valid
	 * ECCurveName value, or if we run out of memory, or perhaps
	 * for other reasons.  Unfortunately if ecParams->name is a
	 * valid ECCurveName value, we don't know what the right error
	 * code should be because ECGroup_fromName doesn't return an
	 * error code to the caller.  Set err to MP_UNDEF because
	 * that's what ECGroup_fromName uses internally.
	 */
	if ((ecParams->name <= ECCurve_noName) ||
	    (ecParams->name >= ECCurve_pastLastCurve)) {
	    err = MP_BADARG;
	} else {
	    err = MP_UNDEF;
	}
	goto cleanup;
    }

    /* validate public point */
    if ((err = ECPoint_validate(group, &Px, &Py)) < MP_YES) {
	if (err == MP_NO) {
	    PORT_SetError(SEC_ERROR_BAD_KEY);
	    rv = SECFailure;
	    err = MP_OKAY;  /* don't change the error code */
	}
	goto cleanup;
    }

    rv = SECSuccess;

cleanup:
    ECGroup_free(group);
    mp_clear(&Px);
    mp_clear(&Py);
    if (err) {
	MP_TO_SEC_ERROR(err);
	rv = SECFailure;
    }
    return rv;
#else
    PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG);
    return SECFailure;
#endif /* NSS_DISABLE_ECC */
}
Beispiel #8
0
/* 
 * Computes scalar point multiplication pointQ = k1 * G + k2 * pointP for
 * the curve whose parameters are encoded in params with base point G.
 */
SECStatus 
ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
             const SECItem *pointP, SECItem *pointQ)
{
    mp_int Px, Py, Qx, Qy;
    mp_int Gx, Gy, order, irreducible, a, b;
#if 0 /* currently don't support non-named curves */
    unsigned int irr_arr[5];
#endif
    ECGroup *group = NULL;
    SECStatus rv = SECFailure;
    mp_err err = MP_OKAY;
    int len;

#if EC_DEBUG
    int i;
    char mpstr[256];

    printf("ec_points_mul: params [len=%d]:", params->DEREncoding.len);
    for (i = 0; i < params->DEREncoding.len; i++) 
	    printf("%02x:", params->DEREncoding.data[i]);
    printf("\n");

	if (k1 != NULL) {
		mp_tohex(k1, mpstr);
		printf("ec_points_mul: scalar k1: %s\n", mpstr);
		mp_todecimal(k1, mpstr);
		printf("ec_points_mul: scalar k1: %s (dec)\n", mpstr);
	}

	if (k2 != NULL) {
		mp_tohex(k2, mpstr);
		printf("ec_points_mul: scalar k2: %s\n", mpstr);
		mp_todecimal(k2, mpstr);
		printf("ec_points_mul: scalar k2: %s (dec)\n", mpstr);
	}

	if (pointP != NULL) {
		printf("ec_points_mul: pointP [len=%d]:", pointP->len);
		for (i = 0; i < pointP->len; i++) 
			printf("%02x:", pointP->data[i]);
		printf("\n");
	}
#endif

	/* NOTE: We only support uncompressed points for now */
	len = (params->fieldID.size + 7) >> 3;
	if (pointP != NULL) {
		if ((pointP->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
			(pointP->len != (2 * len + 1))) {
			PORT_SetError(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM);
			return SECFailure;
		};
	}

	MP_DIGITS(&Px) = 0;
	MP_DIGITS(&Py) = 0;
	MP_DIGITS(&Qx) = 0;
	MP_DIGITS(&Qy) = 0;
	MP_DIGITS(&Gx) = 0;
	MP_DIGITS(&Gy) = 0;
	MP_DIGITS(&order) = 0;
	MP_DIGITS(&irreducible) = 0;
	MP_DIGITS(&a) = 0;
	MP_DIGITS(&b) = 0;
	CHECK_MPI_OK( mp_init(&Px) );
	CHECK_MPI_OK( mp_init(&Py) );
	CHECK_MPI_OK( mp_init(&Qx) );
	CHECK_MPI_OK( mp_init(&Qy) );
	CHECK_MPI_OK( mp_init(&Gx) );
	CHECK_MPI_OK( mp_init(&Gy) );
	CHECK_MPI_OK( mp_init(&order) );
	CHECK_MPI_OK( mp_init(&irreducible) );
	CHECK_MPI_OK( mp_init(&a) );
	CHECK_MPI_OK( mp_init(&b) );

	if ((k2 != NULL) && (pointP != NULL)) {
		/* Initialize Px and Py */
		CHECK_MPI_OK( mp_read_unsigned_octets(&Px, pointP->data + 1, (mp_size) len) );
		CHECK_MPI_OK( mp_read_unsigned_octets(&Py, pointP->data + 1 + len, (mp_size) len) );
	}

	/* construct from named params, if possible */
	if (params->name != ECCurve_noName) {
		group = ECGroup_fromName(params->name);
	}

#if 0 /* currently don't support non-named curves */
	if (group == NULL) {
		/* Set up mp_ints containing the curve coefficients */
		CHECK_MPI_OK( mp_read_unsigned_octets(&Gx, params->base.data + 1, 
										  (mp_size) len) );
		CHECK_MPI_OK( mp_read_unsigned_octets(&Gy, params->base.data + 1 + len, 
										  (mp_size) len) );
		SECITEM_TO_MPINT( params->order, &order );
		SECITEM_TO_MPINT( params->curve.a, &a );
		SECITEM_TO_MPINT( params->curve.b, &b );
		if (params->fieldID.type == ec_field_GFp) {
			SECITEM_TO_MPINT( params->fieldID.u.prime, &irreducible );
			group = ECGroup_consGFp(&irreducible, &a, &b, &Gx, &Gy, &order, params->cofactor);
		} else {
			SECITEM_TO_MPINT( params->fieldID.u.poly, &irreducible );
			irr_arr[0] = params->fieldID.size;
			irr_arr[1] = params->fieldID.k1;
			irr_arr[2] = params->fieldID.k2;
			irr_arr[3] = params->fieldID.k3;
			irr_arr[4] = 0;
			group = ECGroup_consGF2m(&irreducible, irr_arr, &a, &b, &Gx, &Gy, &order, params->cofactor);
		}
	}
#endif
	if (group == NULL)
		goto cleanup;

	if ((k2 != NULL) && (pointP != NULL)) {
		CHECK_MPI_OK( ECPoints_mul(group, k1, k2, &Px, &Py, &Qx, &Qy) );
	} else {
		CHECK_MPI_OK( ECPoints_mul(group, k1, NULL, NULL, NULL, &Qx, &Qy) );
    }

    /* Construct the SECItem representation of point Q */
    pointQ->data[0] = EC_POINT_FORM_UNCOMPRESSED;
    CHECK_MPI_OK( mp_to_fixlen_octets(&Qx, pointQ->data + 1,
	                              (mp_size) len) );
    CHECK_MPI_OK( mp_to_fixlen_octets(&Qy, pointQ->data + 1 + len,
	                              (mp_size) len) );

    rv = SECSuccess;

#if EC_DEBUG
    printf("ec_points_mul: pointQ [len=%d]:", pointQ->len);
    for (i = 0; i < pointQ->len; i++) 
	    printf("%02x:", pointQ->data[i]);
    printf("\n");
#endif

cleanup:
    ECGroup_free(group);
    mp_clear(&Px);
    mp_clear(&Py);
    mp_clear(&Qx);
    mp_clear(&Qy);
    mp_clear(&Gx);
    mp_clear(&Gy);
    mp_clear(&order);
    mp_clear(&irreducible);
    mp_clear(&a);
    mp_clear(&b);
    if (err) {
	MP_TO_SEC_ERROR(err);
	rv = SECFailure;
    }

    return rv;
}
Beispiel #9
0
/* Construct ECGroup from hex parameters and name, if any. Called by
 * ECGroup_fromHex and ECGroup_fromName. */
ECGroup *
ecgroup_fromNameAndHex(const ECCurveName name,
                       const ECCurveParams * params)
{
    mp_int irr, curvea, curveb, genx, geny, order;
    int bits;
    ECGroup *group = NULL;
    mp_err res = MP_OKAY;

    /* initialize values */
    MP_DIGITS(&irr) = 0;
    MP_DIGITS(&curvea) = 0;
    MP_DIGITS(&curveb) = 0;
    MP_DIGITS(&genx) = 0;
    MP_DIGITS(&geny) = 0;
    MP_DIGITS(&order) = 0;
    MP_CHECKOK(mp_init(&irr));
    MP_CHECKOK(mp_init(&curvea));
    MP_CHECKOK(mp_init(&curveb));
    MP_CHECKOK(mp_init(&genx));
    MP_CHECKOK(mp_init(&geny));
    MP_CHECKOK(mp_init(&order));
    MP_CHECKOK(mp_read_radix(&irr, params->irr, 16));
    MP_CHECKOK(mp_read_radix(&curvea, params->curvea, 16));
    MP_CHECKOK(mp_read_radix(&curveb, params->curveb, 16));
    MP_CHECKOK(mp_read_radix(&genx, params->genx, 16));
    MP_CHECKOK(mp_read_radix(&geny, params->geny, 16));
    MP_CHECKOK(mp_read_radix(&order, params->order, 16));

    /* determine number of bits */
    bits = mpl_significant_bits(&irr) - 1;
    if (bits < MP_OKAY) {
        res = bits;
        goto CLEANUP;
    }

    /* determine which optimizations (if any) to use */
    if (params->field == ECField_GFp) {
        switch (name) {
#ifdef NSS_ECC_MORE_THAN_SUITE_B
#ifdef ECL_USE_FP
        case ECCurve_SECG_PRIME_160R1:
            group =
                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
                                &order, params->cofactor);
            if (group == NULL) {
                res = MP_UNDEF;
                goto CLEANUP;
            }
            MP_CHECKOK(ec_group_set_secp160r1_fp(group));
            break;
#endif
        case ECCurve_SECG_PRIME_192R1:
#ifdef ECL_USE_FP
            group =
                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
                                &order, params->cofactor);
            if (group == NULL) {
                res = MP_UNDEF;
                goto CLEANUP;
            }
            MP_CHECKOK(ec_group_set_nistp192_fp(group));
#else
            group =
                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
                                &order, params->cofactor);
            if (group == NULL) {
                res = MP_UNDEF;
                goto CLEANUP;
            }
            MP_CHECKOK(ec_group_set_gfp192(group, name));
#endif
            break;
        case ECCurve_SECG_PRIME_224R1:
#ifdef ECL_USE_FP
            group =
                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
                                &order, params->cofactor);
            if (group == NULL) {
                res = MP_UNDEF;
                goto CLEANUP;
            }
            MP_CHECKOK(ec_group_set_nistp224_fp(group));
#else
            group =
                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
                                &order, params->cofactor);
            if (group == NULL) {
                res = MP_UNDEF;
                goto CLEANUP;
            }
            MP_CHECKOK(ec_group_set_gfp224(group, name));
#endif
            break;
#endif /* NSS_ECC_MORE_THAN_SUITE_B */
        case ECCurve_SECG_PRIME_256R1:
            group =
                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
                                &order, params->cofactor);
            if (group == NULL) {
                res = MP_UNDEF;
                goto CLEANUP;
            }
            MP_CHECKOK(ec_group_set_gfp256(group, name));
            MP_CHECKOK(ec_group_set_gfp256_32(group, name));
            break;
        case ECCurve_SECG_PRIME_521R1:
            group =
                ECGroup_consGFp(&irr, &curvea, &curveb, &genx, &geny,
                                &order, params->cofactor);
            if (group == NULL) {
                res = MP_UNDEF;
                goto CLEANUP;
            }
            MP_CHECKOK(ec_group_set_gfp521(group, name));
            break;
        default:
            /* use generic arithmetic */
            group =
                ECGroup_consGFp_mont(&irr, &curvea, &curveb, &genx, &geny,
                                     &order, params->cofactor);
            if (group == NULL) {
                res = MP_UNDEF;
                goto CLEANUP;
            }
        }
#ifdef NSS_ECC_MORE_THAN_SUITE_B
    } else if (params->field == ECField_GF2m) {
        group = ECGroup_consGF2m(&irr, NULL, &curvea, &curveb, &genx, &geny, &order, params->cofactor);
        if (group == NULL) {
            res = MP_UNDEF;
            goto CLEANUP;
        }
        if ((name == ECCurve_NIST_K163) ||
                (name == ECCurve_NIST_B163) ||
                (name == ECCurve_SECG_CHAR2_163R1)) {
            MP_CHECKOK(ec_group_set_gf2m163(group, name));
        } else if ((name == ECCurve_SECG_CHAR2_193R1) ||
                   (name == ECCurve_SECG_CHAR2_193R2)) {
            MP_CHECKOK(ec_group_set_gf2m193(group, name));
        } else if ((name == ECCurve_NIST_K233) ||
                   (name == ECCurve_NIST_B233)) {
            MP_CHECKOK(ec_group_set_gf2m233(group, name));
        }
#endif
    } else {
        res = MP_UNDEF;
        goto CLEANUP;
    }

    /* set name, if any */
    if ((group != NULL) && (params->text != NULL)) {
        group->text = strdup(params->text);
        if (group->text == NULL) {
            res = MP_MEM;
        }
    }

CLEANUP:
    mp_clear(&irr);
    mp_clear(&curvea);
    mp_clear(&curveb);
    mp_clear(&genx);
    mp_clear(&geny);
    mp_clear(&order);
    if (res != MP_OKAY) {
        ECGroup_free(group);
        return NULL;
    }
    return group;
}
Beispiel #10
0
/* Performs tests of elliptic curve cryptography over prime fields If
 * tests fail, then it prints an error message, aborts, and returns an
 * error code. Otherwise, returns 0. */
int
main(int argv, char **argc)
{

    int ectestTime = 0;
    int ectestPrint = 0;
    int i;
    ECGroup *group = NULL;
    ECCurveParams *params = NULL;
    mp_err res;

    /* read command-line arguments */
    for (i = 1; i < argv; i++) {
        if ((strcasecmp(argc[i], "time") == 0) || (strcasecmp(argc[i], "-time") == 0) || (strcasecmp(argc[i], "--time") == 0)) {
            ectestTime = 1;
        } else if ((strcasecmp(argc[i], "print") == 0) || (strcasecmp(argc[i], "-print") == 0) || (strcasecmp(argc[i], "--print") == 0)) {
            ectestPrint = 1;
        } else {
            printUsage();
            return 0;
        }
    }

    /* generic arithmetic tests */
    ECTEST_GENERIC_GFP("SECP-160R1", ECCurve_SECG_PRIME_160R1);

    /* specific arithmetic tests */
    ECTEST_NAMED_GFP("NIST-P192", ECCurve_NIST_P192);
    ECTEST_NAMED_GFP("NIST-P224", ECCurve_NIST_P224);
    ECTEST_NAMED_GFP("NIST-P256", ECCurve_NIST_P256);
    ECTEST_NAMED_GFP("NIST-P384", ECCurve_NIST_P384);
    ECTEST_NAMED_GFP("NIST-P521", ECCurve_NIST_P521);
    ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v1", ECCurve_X9_62_PRIME_192V1);
    ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v2", ECCurve_X9_62_PRIME_192V2);
    ECTEST_NAMED_GFP("ANSI X9.62 PRIME192v3", ECCurve_X9_62_PRIME_192V3);
    ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v1", ECCurve_X9_62_PRIME_239V1);
    ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v2", ECCurve_X9_62_PRIME_239V2);
    ECTEST_NAMED_GFP("ANSI X9.62 PRIME239v3", ECCurve_X9_62_PRIME_239V3);
    ECTEST_NAMED_GFP("ANSI X9.62 PRIME256v1", ECCurve_X9_62_PRIME_256V1);
    ECTEST_NAMED_GFP("SECP-112R1", ECCurve_SECG_PRIME_112R1);
    ECTEST_NAMED_GFP("SECP-112R2", ECCurve_SECG_PRIME_112R2);
    ECTEST_NAMED_GFP("SECP-128R1", ECCurve_SECG_PRIME_128R1);
    ECTEST_NAMED_GFP("SECP-128R2", ECCurve_SECG_PRIME_128R2);
    ECTEST_NAMED_GFP("SECP-160K1", ECCurve_SECG_PRIME_160K1);
    ECTEST_NAMED_GFP("SECP-160R1", ECCurve_SECG_PRIME_160R1);
    ECTEST_NAMED_GFP("SECP-160R2", ECCurve_SECG_PRIME_160R2);
    ECTEST_NAMED_GFP("SECP-192K1", ECCurve_SECG_PRIME_192K1);
    ECTEST_NAMED_GFP("SECP-192R1", ECCurve_SECG_PRIME_192R1);
    ECTEST_NAMED_GFP("SECP-224K1", ECCurve_SECG_PRIME_224K1);
    ECTEST_NAMED_GFP("SECP-224R1", ECCurve_SECG_PRIME_224R1);
    ECTEST_NAMED_GFP("SECP-256K1", ECCurve_SECG_PRIME_256K1);
    ECTEST_NAMED_GFP("SECP-256R1", ECCurve_SECG_PRIME_256R1);
    ECTEST_NAMED_GFP("SECP-384R1", ECCurve_SECG_PRIME_384R1);
    ECTEST_NAMED_GFP("SECP-521R1", ECCurve_SECG_PRIME_521R1);
    ECTEST_NAMED_GFP("WTLS-6 (112)", ECCurve_WTLS_6);
    ECTEST_NAMED_GFP("WTLS-7 (160)", ECCurve_WTLS_7);
    ECTEST_NAMED_GFP("WTLS-8 (112)", ECCurve_WTLS_8);
    ECTEST_NAMED_GFP("WTLS-9 (160)", ECCurve_WTLS_9);
    ECTEST_NAMED_GFP("WTLS-12 (224)", ECCurve_WTLS_12);
    ECTEST_NAMED_GFP("Curve25519", ECCurve25519);

CLEANUP:
    EC_FreeCurveParams(params);
    ECGroup_free(group);
    if (res != MP_OKAY) {
        printf("Error: exiting with error value %i\n", res);
    }
    return res;
}
Beispiel #11
0
/* 
 * Computes scalar point multiplication pointQ = k1 * G + k2 * pointP for
 * the curve whose parameters are encoded in params with base point G.
 */
SECStatus 
ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
             const SECItem *pointP, SECItem *pointQ, int kmflag)
{
    mp_int Px, Py, Qx, Qy;
    mp_int Gx, Gy, order, irreducible, a, b;
    ECGroup *group = NULL;
    SECStatus rv = SECFailure;
    mp_err err = MP_OKAY;
    int len;

#if EC_DEBUG
    int i;
    char mpstr[256];
	if (k1 != NULL) {
		mp_tohex(k1, mpstr);
		printf("ec_points_mul: scalar k1: %s\n", mpstr);
		mp_todecimal(k1, mpstr);
		printf("ec_points_mul: scalar k1: %s (dec)\n", mpstr);
	}

	if (k2 != NULL) {
		mp_tohex(k2, mpstr);
		printf("ec_points_mul: scalar k2: %s\n", mpstr);
		mp_todecimal(k2, mpstr);
		printf("ec_points_mul: scalar k2: %s (dec)\n", mpstr);
	}

	if (pointP != NULL) {
		printf("ec_points_mul: pointP [len=%d]:", pointP->len);
		for (i = 0; i < pointP->len; i++) 
			printf("%02x:", pointP->data[i]);
		printf("\n");
	}
#endif

	/* NOTE: We only support uncompressed points for now */
	len = (params->fieldID.size + 7) >> 3;
	if (pointP != NULL) {
		if ((pointP->data[0] != EC_POINT_FORM_UNCOMPRESSED) ||
			(pointP->len != (unsigned int)(2 * len + 1))) {
			return SECFailure;
		};
	}

	MP_DIGITS(&Px) = 0;
	MP_DIGITS(&Py) = 0;
	MP_DIGITS(&Qx) = 0;
	MP_DIGITS(&Qy) = 0;
	MP_DIGITS(&Gx) = 0;
	MP_DIGITS(&Gy) = 0;
	MP_DIGITS(&order) = 0;
	MP_DIGITS(&irreducible) = 0;
	MP_DIGITS(&a) = 0;
	MP_DIGITS(&b) = 0;
	CHECK_MPI_OK( mp_init(&Px) );
	CHECK_MPI_OK( mp_init(&Py) );
	CHECK_MPI_OK( mp_init(&Qx) );
	CHECK_MPI_OK( mp_init(&Qy) );
	CHECK_MPI_OK( mp_init(&Gx) );
	CHECK_MPI_OK( mp_init(&Gy) );
	CHECK_MPI_OK( mp_init(&order) );
	CHECK_MPI_OK( mp_init(&irreducible) );
	CHECK_MPI_OK( mp_init(&a) );
	CHECK_MPI_OK( mp_init(&b) );

	if ((k2 != NULL) && (pointP != NULL)) {
		/* Initialize Px and Py */
		CHECK_MPI_OK( mp_read_unsigned_octets(&Px, pointP->data + 1, (mp_size) len) );
		CHECK_MPI_OK( mp_read_unsigned_octets(&Py, pointP->data + 1 + len, (mp_size) len) );
	}

	/* construct from named params, if possible */
	if (params->name != ECCurve_noName) {
		group = ECGroup_fromName(params->name);
	}

	if (group == NULL)
		goto cleanup;

	if ((k2 != NULL) && (pointP != NULL)) {
		CHECK_MPI_OK( ECPoints_mul(group, k1, k2, &Px, &Py, &Qx, &Qy) );
	} else {
		CHECK_MPI_OK( ECPoints_mul(group, k1, NULL, NULL, NULL, &Qx, &Qy) );
    }

    /* Construct the SECItem representation of point Q */
    pointQ->data[0] = EC_POINT_FORM_UNCOMPRESSED;
    CHECK_MPI_OK( mp_to_fixlen_octets(&Qx, pointQ->data + 1,
	                              (mp_size) len) );
    CHECK_MPI_OK( mp_to_fixlen_octets(&Qy, pointQ->data + 1 + len,
	                              (mp_size) len) );

    rv = SECSuccess;

#if EC_DEBUG
    printf("ec_points_mul: pointQ [len=%d]:", pointQ->len);
    for (i = 0; i < pointQ->len; i++) 
	    printf("%02x:", pointQ->data[i]);
    printf("\n");
#endif

cleanup:
    ECGroup_free(group);
    mp_clear(&Px);
    mp_clear(&Py);
    mp_clear(&Qx);
    mp_clear(&Qy);
    mp_clear(&Gx);
    mp_clear(&Gy);
    mp_clear(&order);
    mp_clear(&irreducible);
    mp_clear(&a);
    mp_clear(&b);
    if (err) {
	MP_TO_SEC_ERROR(err);
	rv = SECFailure;
    }

    return rv;
}
Beispiel #12
0
/* Performs tests of elliptic curve cryptography over binary polynomial
 * fields. If tests fail, then it prints an error message, aborts, and
 * returns an error code. Otherwise, returns 0. */
int
main(int argv, char **argc)
{

    int ectestTime = 0;
    int ectestPrint = 0;
    int i;
    ECGroup *group = NULL;
    ECCurveParams *params = NULL;
    mp_err res;

    /* read command-line arguments */
    for (i = 1; i < argv; i++) {
        if ((strcasecmp(argc[i], "time") == 0) || (strcasecmp(argc[i], "-time") == 0) || (strcasecmp(argc[i], "--time") == 0)) {
            ectestTime = 1;
        } else if ((strcasecmp(argc[i], "print") == 0) || (strcasecmp(argc[i], "-print") == 0) || (strcasecmp(argc[i], "--print") == 0)) {
            ectestPrint = 1;
        } else {
            printUsage();
            return 0;
        }
    }

    /* generic arithmetic tests */
    ECTEST_GENERIC_GF2M("SECT-131R1", ECCurve_SECG_CHAR2_131R1);

    /* specific arithmetic tests */
    ECTEST_NAMED_GF2M("NIST-K163", ECCurve_NIST_K163);
    ECTEST_NAMED_GF2M("NIST-B163", ECCurve_NIST_B163);
    ECTEST_NAMED_GF2M("NIST-K233", ECCurve_NIST_K233);
    ECTEST_NAMED_GF2M("NIST-B233", ECCurve_NIST_B233);
    ECTEST_NAMED_GF2M("NIST-K283", ECCurve_NIST_K283);
    ECTEST_NAMED_GF2M("NIST-B283", ECCurve_NIST_B283);
    ECTEST_NAMED_GF2M("NIST-K409", ECCurve_NIST_K409);
    ECTEST_NAMED_GF2M("NIST-B409", ECCurve_NIST_B409);
    ECTEST_NAMED_GF2M("NIST-K571", ECCurve_NIST_K571);
    ECTEST_NAMED_GF2M("NIST-B571", ECCurve_NIST_B571);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB163V1", ECCurve_X9_62_CHAR2_PNB163V1);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB163V2", ECCurve_X9_62_CHAR2_PNB163V2);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB163V3", ECCurve_X9_62_CHAR2_PNB163V3);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB176V1", ECCurve_X9_62_CHAR2_PNB176V1);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB191V1", ECCurve_X9_62_CHAR2_TNB191V1);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB191V2", ECCurve_X9_62_CHAR2_TNB191V2);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB191V3", ECCurve_X9_62_CHAR2_TNB191V3);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB208W1", ECCurve_X9_62_CHAR2_PNB208W1);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB239V1", ECCurve_X9_62_CHAR2_TNB239V1);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB239V2", ECCurve_X9_62_CHAR2_TNB239V2);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB239V3", ECCurve_X9_62_CHAR2_TNB239V3);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB272W1", ECCurve_X9_62_CHAR2_PNB272W1);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB304W1", ECCurve_X9_62_CHAR2_PNB304W1);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB359V1", ECCurve_X9_62_CHAR2_TNB359V1);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2PNB368W1", ECCurve_X9_62_CHAR2_PNB368W1);
    ECTEST_NAMED_GF2M("ANSI X9.62 C2TNB431R1", ECCurve_X9_62_CHAR2_TNB431R1);
    ECTEST_NAMED_GF2M("SECT-113R1", ECCurve_SECG_CHAR2_113R1);
    ECTEST_NAMED_GF2M("SECT-113R2", ECCurve_SECG_CHAR2_113R2);
    ECTEST_NAMED_GF2M("SECT-131R1", ECCurve_SECG_CHAR2_131R1);
    ECTEST_NAMED_GF2M("SECT-131R2", ECCurve_SECG_CHAR2_131R2);
    ECTEST_NAMED_GF2M("SECT-163K1", ECCurve_SECG_CHAR2_163K1);
    ECTEST_NAMED_GF2M("SECT-163R1", ECCurve_SECG_CHAR2_163R1);
    ECTEST_NAMED_GF2M("SECT-163R2", ECCurve_SECG_CHAR2_163R2);
    ECTEST_NAMED_GF2M("SECT-193R1", ECCurve_SECG_CHAR2_193R1);
    ECTEST_NAMED_GF2M("SECT-193R2", ECCurve_SECG_CHAR2_193R2);
    ECTEST_NAMED_GF2M("SECT-233K1", ECCurve_SECG_CHAR2_233K1);
    ECTEST_NAMED_GF2M("SECT-233R1", ECCurve_SECG_CHAR2_233R1);
    ECTEST_NAMED_GF2M("SECT-239K1", ECCurve_SECG_CHAR2_239K1);
    ECTEST_NAMED_GF2M("SECT-283K1", ECCurve_SECG_CHAR2_283K1);
    ECTEST_NAMED_GF2M("SECT-283R1", ECCurve_SECG_CHAR2_283R1);
    ECTEST_NAMED_GF2M("SECT-409K1", ECCurve_SECG_CHAR2_409K1);
    ECTEST_NAMED_GF2M("SECT-409R1", ECCurve_SECG_CHAR2_409R1);
    ECTEST_NAMED_GF2M("SECT-571K1", ECCurve_SECG_CHAR2_571K1);
    ECTEST_NAMED_GF2M("SECT-571R1", ECCurve_SECG_CHAR2_571R1);
    ECTEST_NAMED_GF2M("WTLS-1 (113)", ECCurve_WTLS_1);
    ECTEST_NAMED_GF2M("WTLS-3 (163)", ECCurve_WTLS_3);
    ECTEST_NAMED_GF2M("WTLS-4 (113)", ECCurve_WTLS_4);
    ECTEST_NAMED_GF2M("WTLS-5 (163)", ECCurve_WTLS_5);
    ECTEST_NAMED_GF2M("WTLS-10 (233)", ECCurve_WTLS_10);
    ECTEST_NAMED_GF2M("WTLS-11 (233)", ECCurve_WTLS_11);

CLEANUP:
    EC_FreeCurveParams(params);
    ECGroup_free(group);
    if (res != MP_OKAY) {
        printf("Error: exiting with error value %i\n", res);
    }
    return res;
}