b355146
/*
9189f03
 * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
9189f03
 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
b355146
 *
510bcc2
 * Licensed under the OpenSSL license (the "License").  You may not use
510bcc2
 * this file except in compliance with the License.  You can obtain a copy
510bcc2
 * in the file LICENSE in the source distribution or at
510bcc2
 * https://www.openssl.org/source/license.html
b355146
 */
510bcc2
9189f03
#include "internal/nelem.h"
9189f03
#include "testutil.h"
b355146
9189f03
#ifndef OPENSSL_NO_EC
a1fb602
# include <openssl/ec.h>
a1fb602
# ifndef OPENSSL_NO_ENGINE
a1fb602
#  include <openssl/engine.h>
a1fb602
# endif
a1fb602
# include <openssl/err.h>
a1fb602
# include <openssl/obj_mac.h>
a1fb602
# include <openssl/objects.h>
a1fb602
# include <openssl/rand.h>
a1fb602
# include <openssl/bn.h>
a1fb602
# include <openssl/opensslconf.h>
a1fb602
9189f03
static size_t crv_len = 0;
9189f03
static EC_builtin_curve *curves = NULL;
b355146
b355146
/* test multiplication with group order, long and negative scalars */
9189f03
static int group_order_tests(EC_GROUP *group)
a1fb602
{
9189f03
    BIGNUM *n1 = NULL, *n2 = NULL, *order = NULL;
9189f03
    EC_POINT *P = NULL, *Q = NULL, *R = NULL, *S = NULL;
62ec0f1
    const EC_POINT *G = NULL;
9189f03
    BN_CTX *ctx = NULL;
9189f03
    int i = 0, r = 0;
9189f03
9189f03
    if (!TEST_ptr(n1 = BN_new())
9189f03
        || !TEST_ptr(n2 = BN_new())
9189f03
        || !TEST_ptr(order = BN_new())
9189f03
        || !TEST_ptr(ctx = BN_CTX_new())
62ec0f1
        || !TEST_ptr(G = EC_GROUP_get0_generator(group))
9189f03
        || !TEST_ptr(P = EC_POINT_new(group))
9189f03
        || !TEST_ptr(Q = EC_POINT_new(group))
9189f03
        || !TEST_ptr(R = EC_POINT_new(group))
9189f03
        || !TEST_ptr(S = EC_POINT_new(group)))
9189f03
        goto err;
9189f03
9189f03
    if (!TEST_true(EC_GROUP_get_order(group, order, ctx))
9189f03
        || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
9189f03
        || !TEST_true(EC_POINT_is_at_infinity(group, Q))
9189f03
        || !TEST_true(EC_GROUP_precompute_mult(group, ctx))
9189f03
        || !TEST_true(EC_POINT_mul(group, Q, order, NULL, NULL, ctx))
62ec0f1
        || !TEST_true(EC_POINT_is_at_infinity(group, Q))
62ec0f1
        || !TEST_true(EC_POINT_copy(P, G))
62ec0f1
        || !TEST_true(BN_one(n1))
62ec0f1
        || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
62ec0f1
        || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
62ec0f1
        || !TEST_true(BN_sub(n1, order, n1))
62ec0f1
        || !TEST_true(EC_POINT_mul(group, Q, n1, NULL, NULL, ctx))
62ec0f1
        || !TEST_true(EC_POINT_invert(group, Q, ctx))
62ec0f1
        || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
9189f03
        goto err;
9189f03
a1fb602
    for (i = 1; i <= 2; i++) {
a1fb602
        const BIGNUM *scalars[6];
a1fb602
        const EC_POINT *points[6];
a1fb602
9189f03
        if (!TEST_true(BN_set_word(n1, i))
9189f03
            /*
9189f03
             * If i == 1, P will be the predefined generator for which
9189f03
             * EC_GROUP_precompute_mult has set up precomputation.
9189f03
             */
9189f03
            || !TEST_true(EC_POINT_mul(group, P, n1, NULL, NULL, ctx))
62ec0f1
            || (i == 1 && !TEST_int_eq(0, EC_POINT_cmp(group, P, G, ctx)))
9189f03
            || !TEST_true(BN_one(n1))
9189f03
            /* n1 = 1 - order */
9189f03
            || !TEST_true(BN_sub(n1, n1, order))
9189f03
            || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n1, ctx))
9189f03
            || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
9189f03
9189f03
            /* n2 = 1 + order */
9189f03
            || !TEST_true(BN_add(n2, order, BN_value_one()))
9189f03
            || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
9189f03
            || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx))
9189f03
9189f03
            /* n2 = (1 - order) * (1 + order) = 1 - order^2 */
9189f03
            || !TEST_true(BN_mul(n2, n1, n2, ctx))
9189f03
            || !TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
9189f03
            || !TEST_int_eq(0, EC_POINT_cmp(group, Q, P, ctx)))
9189f03
            goto err;
a1fb602
a1fb602
        /* n2 = order^2 - 1 */
a1fb602
        BN_set_negative(n2, 0);
9189f03
        if (!TEST_true(EC_POINT_mul(group, Q, NULL, P, n2, ctx))
9189f03
            /* Add P to verify the result. */
9189f03
            || !TEST_true(EC_POINT_add(group, Q, Q, P, ctx))
9189f03
            || !TEST_true(EC_POINT_is_at_infinity(group, Q))
9189f03
9189f03
            /* Exercise EC_POINTs_mul, including corner cases. */
9189f03
            || !TEST_false(EC_POINT_is_at_infinity(group, P)))
9189f03
            goto err;
510bcc2
510bcc2
        scalars[0] = scalars[1] = BN_value_one();
510bcc2
        points[0]  = points[1]  = P;
510bcc2
9189f03
        if (!TEST_true(EC_POINTs_mul(group, R, NULL, 2, points, scalars, ctx))
9189f03
            || !TEST_true(EC_POINT_dbl(group, S, points[0], ctx))
9189f03
            || !TEST_int_eq(0, EC_POINT_cmp(group, R, S, ctx)))
9189f03
            goto err;
510bcc2
a1fb602
        scalars[0] = n1;
a1fb602
        points[0] = Q;          /* => infinity */
a1fb602
        scalars[1] = n2;
a1fb602
        points[1] = P;          /* => -P */
a1fb602
        scalars[2] = n1;
a1fb602
        points[2] = Q;          /* => infinity */
a1fb602
        scalars[3] = n2;
a1fb602
        points[3] = Q;          /* => infinity */
a1fb602
        scalars[4] = n1;
a1fb602
        points[4] = P;          /* => P */
a1fb602
        scalars[5] = n2;
a1fb602
        points[5] = Q;          /* => infinity */
9189f03
        if (!TEST_true(EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx))
9189f03
            || !TEST_true(EC_POINT_is_at_infinity(group, P)))
9189f03
            goto err;
a1fb602
    }
a1fb602
9189f03
    r = 1;
9189f03
err:
9189f03
    if (r == 0 && i != 0)
9189f03
        TEST_info(i == 1 ? "allowing precomputation" :
9189f03
                           "without precomputation");
a1fb602
    EC_POINT_free(P);
a1fb602
    EC_POINT_free(Q);
510bcc2
    EC_POINT_free(R);
510bcc2
    EC_POINT_free(S);
a1fb602
    BN_free(n1);
a1fb602
    BN_free(n2);
a1fb602
    BN_free(order);
a1fb602
    BN_CTX_free(ctx);
9189f03
    return r;
a1fb602
}
b355146
9189f03
static int prime_field_tests(void)
a1fb602
{
a1fb602
    BN_CTX *ctx = NULL;
9189f03
    BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL;
9189f03
    EC_GROUP *group = NULL, *tmp = NULL;
9189f03
    EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL,
9189f03
             *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;
9189f03
    EC_POINT *P = NULL, *Q = NULL, *R = NULL;
9189f03
    BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;
9189f03
    const EC_POINT *points[4];
9189f03
    const BIGNUM *scalars[4];
a1fb602
    unsigned char buf[100];
9189f03
    size_t len, r = 0;
a1fb602
    int k;
a1fb602
9189f03
    if (!TEST_ptr(ctx = BN_CTX_new())
9189f03
        || !TEST_ptr(p = BN_new())
9189f03
        || !TEST_ptr(a = BN_new())
9189f03
        || !TEST_ptr(b = BN_new())
9189f03
        /*
9189f03
         * applications should use EC_GROUP_new_curve_GFp so
9189f03
         * that the library gets to choose the EC_METHOD
9189f03
         */
9189f03
        || !TEST_ptr(group = EC_GROUP_new(EC_GFp_mont_method()))
9189f03
        || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))
9189f03
        || !TEST_true(EC_GROUP_copy(tmp, group)))
9189f03
        goto err;
9189f03
    EC_GROUP_free(group);
9189f03
    group = tmp;
9189f03
    tmp = NULL;
9189f03
9189f03
    buf[0] = 0;
9189f03
    if (!TEST_ptr(P = EC_POINT_new(group))
9189f03
        || !TEST_ptr(Q = EC_POINT_new(group))
9189f03
        || !TEST_ptr(R = EC_POINT_new(group))
9189f03
        || !TEST_ptr(x = BN_new())
9189f03
        || !TEST_ptr(y = BN_new())
9189f03
        || !TEST_ptr(z = BN_new())
9189f03
        || !TEST_ptr(yplusone = BN_new()))
9189f03
        goto err;
a1fb602
e443a79
    /* Curve P-224 (FIPS PUB 186-2, App. 6) */
e443a79
9189f03
    if (!TEST_true(BN_hex2bn(&p,         "FFFFFFFFFFFFFFFFFFFFFFFF"
9189f03
                                    "FFFFFFFF000000000000000000000001"))
9189f03
        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
9189f03
        || !TEST_true(BN_hex2bn(&a,         "FFFFFFFFFFFFFFFFFFFFFFFF"
9189f03
                                    "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))
9189f03
        || !TEST_true(BN_hex2bn(&b,         "B4050A850C04B3ABF5413256"
9189f03
                                    "5044B0B7D7BFD8BA270B39432355FFB4"))
62ec0f1
        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
9189f03
        || !TEST_true(BN_hex2bn(&x,         "B70E0CBD6BB4BF7F321390B9"
9189f03
                                    "4A03C1D356C21122343280D6115C1D21"))
62ec0f1
        || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
9189f03
        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
9189f03
        || !TEST_true(BN_hex2bn(&z,         "FFFFFFFFFFFFFFFFFFFFFFFF"
9189f03
                                    "FFFF16A2E0B8F03E13DD29455C5C2A3D"))
9189f03
        || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
62ec0f1
        || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
9189f03
        goto err;
9189f03
9189f03
    TEST_info("NIST curve P-224 -- Generator");
9189f03
    test_output_bignum("x", x);
9189f03
    test_output_bignum("y", y);
e443a79
    /* G_y value taken from the standard: */
9189f03
    if (!TEST_true(BN_hex2bn(&z,         "BD376388B5F723FB4C22DFE6"
9189f03
                                 "CD4375A05A07476444D5819985007E34"))
9189f03
        || !TEST_BN_eq(y, z)
9189f03
        || !TEST_true(BN_add(yplusone, y, BN_value_one()))
e443a79
    /*
e443a79
     * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
e443a79
     * and therefore setting the coordinates should fail.
e443a79
     */
62ec0f1
        || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
62ec0f1
                                                       ctx))
9189f03
        || !TEST_int_eq(EC_GROUP_get_degree(group), 224)
9189f03
        || !group_order_tests(group)
9189f03
        || !TEST_ptr(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))
9189f03
        || !TEST_true(EC_GROUP_copy(P_224, group))
e443a79
a1fb602
    /* Curve P-256 (FIPS PUB 186-2, App. 6) */
a1fb602
9189f03
        || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"
9189f03
                                    "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))
9189f03
        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
9189f03
        || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"
9189f03
                                    "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))
9189f03
        || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"
9189f03
                                    "651D06B0CC53B0F63BCE3C3E27D2604B"))
62ec0f1
        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
9189f03
9189f03
        || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"
9189f03
                                    "77037D812DEB33A0F4A13945D898C296"))
62ec0f1
        || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
9189f03
        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
9189f03
        || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"
9189f03
                                    "BCE6FAADA7179E84F3B9CAC2FC632551"))
9189f03
        || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
62ec0f1
        || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
9189f03
        goto err;
9189f03
9189f03
    TEST_info("NIST curve P-256 -- Generator");
9189f03
    test_output_bignum("x", x);
9189f03
    test_output_bignum("y", y);
a1fb602
    /* G_y value taken from the standard: */
9189f03
    if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"
9189f03
                                 "2BCE33576B315ECECBB6406837BF51F5"))
9189f03
        || !TEST_BN_eq(y, z)
9189f03
        || !TEST_true(BN_add(yplusone, y, BN_value_one()))
510bcc2
    /*
510bcc2
     * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
510bcc2
     * and therefore setting the coordinates should fail.
510bcc2
     */
62ec0f1
        || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
62ec0f1
                                                       ctx))
9189f03
        || !TEST_int_eq(EC_GROUP_get_degree(group), 256)
9189f03
        || !group_order_tests(group)
9189f03
        || !TEST_ptr(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))
9189f03
        || !TEST_true(EC_GROUP_copy(P_256, group))
a1fb602
a1fb602
    /* Curve P-384 (FIPS PUB 186-2, App. 6) */
a1fb602
9189f03
        || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9189f03
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
9189f03
                                    "FFFFFFFF0000000000000000FFFFFFFF"))
9189f03
        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
9189f03
        || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9189f03
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"
9189f03
                                    "FFFFFFFF0000000000000000FFFFFFFC"))
9189f03
        || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"
9189f03
                                    "181D9C6EFE8141120314088F5013875A"
9189f03
                                    "C656398D8A2ED19D2A85C8EDD3EC2AEF"))
62ec0f1
        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
9189f03
9189f03
        || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"
9189f03
                                    "6E1D3B628BA79B9859F741E082542A38"
9189f03
                                    "5502F25DBF55296C3A545E3872760AB7"))
62ec0f1
        || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))
9189f03
        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
9189f03
        || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9189f03
                                    "FFFFFFFFFFFFFFFFC7634D81F4372DDF"
9189f03
                                    "581A0DB248B0A77AECEC196ACCC52973"))
9189f03
        || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
62ec0f1
        || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
9189f03
        goto err;
9189f03
9189f03
    TEST_info("NIST curve P-384 -- Generator");
9189f03
    test_output_bignum("x", x);
9189f03
    test_output_bignum("y", y);
a1fb602
    /* G_y value taken from the standard: */
9189f03
    if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"
9189f03
                                 "F8F41DBD289A147CE9DA3113B5F0B8C0"
9189f03
                                 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))
9189f03
        || !TEST_BN_eq(y, z)
9189f03
        || !TEST_true(BN_add(yplusone, y, BN_value_one()))
510bcc2
    /*
510bcc2
     * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
510bcc2
     * and therefore setting the coordinates should fail.
510bcc2
     */
62ec0f1
        || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
62ec0f1
                                                       ctx))
9189f03
        || !TEST_int_eq(EC_GROUP_get_degree(group), 384)
9189f03
        || !group_order_tests(group)
9189f03
        || !TEST_ptr(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))
9189f03
        || !TEST_true(EC_GROUP_copy(P_384, group))
a1fb602
a1fb602
    /* Curve P-521 (FIPS PUB 186-2, App. 6) */
9189f03
        || !TEST_true(BN_hex2bn(&p,                              "1FF"
9189f03
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9189f03
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9189f03
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9189f03
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))
9189f03
        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
9189f03
        || !TEST_true(BN_hex2bn(&a,                              "1FF"
9189f03
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9189f03
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9189f03
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9189f03
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))
9189f03
        || !TEST_true(BN_hex2bn(&b,                              "051"
9189f03
                                    "953EB9618E1C9A1F929A21A0B68540EE"
9189f03
                                    "A2DA725B99B315F3B8B489918EF109E1"
9189f03
                                    "56193951EC7E937B1652C0BD3BB1BF07"
9189f03
                                    "3573DF883D2C34F1EF451FD46B503F00"))
62ec0f1
        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))
9189f03
        || !TEST_true(BN_hex2bn(&x,                               "C6"
9189f03
                                    "858E06B70404E9CD9E3ECB662395B442"
9189f03
                                    "9C648139053FB521F828AF606B4D3DBA"
9189f03
                                    "A14B5E77EFE75928FE1DC127A2FFA8DE"
9189f03
                                    "3348B3C1856A429BF97E7E31C2E5BD66"))
62ec0f1
        || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))
9189f03
        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
9189f03
        || !TEST_true(BN_hex2bn(&z,                              "1FF"
9189f03
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
9189f03
                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"
9189f03
                                    "51868783BF2F966B7FCC0148F709A5D0"
9189f03
                                    "3BB5C9B8899C47AEBB6FB71E91386409"))
9189f03
        || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))
62ec0f1
        || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))
9189f03
        goto err;
9189f03
9189f03
    TEST_info("NIST curve P-521 -- Generator");
9189f03
    test_output_bignum("x", x);
9189f03
    test_output_bignum("y", y);
a1fb602
    /* G_y value taken from the standard: */
9189f03
    if (!TEST_true(BN_hex2bn(&z,                              "118"
9189f03
                                 "39296A789A3BC0045C8A5FB42C7D1BD9"
9189f03
                                 "98F54449579B446817AFBD17273E662C"
9189f03
                                 "97EE72995EF42640C550B9013FAD0761"
9189f03
                                 "353C7086A272C24088BE94769FD16650"))
9189f03
        || !TEST_BN_eq(y, z)
9189f03
        || !TEST_true(BN_add(yplusone, y, BN_value_one()))
510bcc2
    /*
510bcc2
     * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
510bcc2
     * and therefore setting the coordinates should fail.
510bcc2
     */
62ec0f1
        || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,
62ec0f1
                                                       ctx))
9189f03
        || !TEST_int_eq(EC_GROUP_get_degree(group), 521)
9189f03
        || !group_order_tests(group)
9189f03
        || !TEST_ptr(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))
9189f03
        || !TEST_true(EC_GROUP_copy(P_521, group))
a1fb602
a1fb602
    /* more tests using the last curve */
a1fb602
510bcc2
    /* Restore the point that got mangled in the (x, y + 1) test. */
62ec0f1
        || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))
9189f03
        || !TEST_true(EC_POINT_copy(Q, P))
9189f03
        || !TEST_false(EC_POINT_is_at_infinity(group, Q))
9189f03
        || !TEST_true(EC_POINT_dbl(group, P, P, ctx))
9189f03
        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)
9189f03
        || !TEST_true(EC_POINT_invert(group, Q, ctx))       /* P = -2Q */
9189f03
        || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))
9189f03
        || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))
9189f03
        || !TEST_true(EC_POINT_is_at_infinity(group, R))    /* R = P + 2Q */
9189f03
        || !TEST_false(EC_POINT_is_at_infinity(group, Q)))
9189f03
        goto err;
9189f03
    points[0] = Q;
9189f03
    points[1] = Q;
9189f03
    points[2] = Q;
9189f03
    points[3] = Q;
9189f03
9189f03
    if (!TEST_true(EC_GROUP_get_order(group, z, ctx))
9189f03
        || !TEST_true(BN_add(y, z, BN_value_one()))
9189f03
        || !TEST_BN_even(y)
9189f03
        || !TEST_true(BN_rshift1(y, y)))
9189f03
        goto err;
9189f03
    scalars[0] = y;         /* (group order + 1)/2, so y*Q + y*Q = Q */
9189f03
    scalars[1] = y;
9189f03
9189f03
    TEST_note("combined multiplication ...");
9189f03
9189f03
    /* z is still the group order */
9189f03
    if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
9189f03
        || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))
9189f03
        || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))
9189f03
        || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))
9189f03
        || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))
9189f03
        || !TEST_true(BN_add(z, z, y)))
9189f03
        goto err;
9189f03
    BN_set_negative(z, 1);
9189f03
    scalars[0] = y;
9189f03
    scalars[1] = z;         /* z = -(order + y) */
9189f03
9189f03
    if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))
9189f03
        || !TEST_true(EC_POINT_is_at_infinity(group, P))
9189f03
        || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))
9189f03
        || !TEST_true(BN_add(z, x, y)))
9189f03
        goto err;
9189f03
    BN_set_negative(z, 1);
9189f03
    scalars[0] = x;
9189f03
    scalars[1] = y;
9189f03
    scalars[2] = z;         /* z = -(x+y) */
9189f03
9189f03
    if (!TEST_ptr(scalar3 = BN_new()))
9189f03
        goto err;
9189f03
    BN_zero(scalar3);
9189f03
    scalars[3] = scalar3;
9189f03
9189f03
    if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))
9189f03
        || !TEST_true(EC_POINT_is_at_infinity(group, P)))
9189f03
        goto err;
9189f03
9189f03
    TEST_note(" ok\n");
9189f03
9189f03
9189f03
    r = 1;
9189f03
err:
510bcc2
    BN_CTX_free(ctx);
a1fb602
    BN_free(p);
a1fb602
    BN_free(a);
a1fb602
    BN_free(b);
a1fb602
    EC_GROUP_free(group);
9189f03
    EC_GROUP_free(tmp);
a1fb602
    EC_POINT_free(P);
a1fb602
    EC_POINT_free(Q);
a1fb602
    EC_POINT_free(R);
a1fb602
    BN_free(x);
a1fb602
    BN_free(y);
a1fb602
    BN_free(z);
510bcc2
    BN_free(yplusone);
9189f03
    BN_free(scalar3);
a1fb602
e443a79
    EC_GROUP_free(P_224);
510bcc2
    EC_GROUP_free(P_256);
510bcc2
    EC_GROUP_free(P_384);
510bcc2
    EC_GROUP_free(P_521);
9189f03
    return r;
a1fb602
}
b355146
9189f03
static int internal_curve_test(int n)
a1fb602
{
9189f03
    EC_GROUP *group = NULL;
9189f03
    int nid = curves[n].nid;
a1fb602
9189f03
    if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
9189f03
        TEST_info("EC_GROUP_new_curve_name() failed with curve %s\n",
9189f03
                  OBJ_nid2sn(nid));
9189f03
        return 0;
a1fb602
    }
9189f03
    if (!TEST_true(EC_GROUP_check(group, NULL))) {
9189f03
        TEST_info("EC_GROUP_check() failed with curve %s\n", OBJ_nid2sn(nid));
a1fb602
        EC_GROUP_free(group);
9189f03
        return 0;
a1fb602
    }
9189f03
    EC_GROUP_free(group);
9189f03
    return 1;
9189f03
}
510bcc2
9189f03
static int internal_curve_test_method(int n)
9189f03
{
9189f03
    int r, nid = curves[n].nid;
9189f03
    EC_GROUP *group;
510bcc2
9189f03
    if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))) {
9189f03
        TEST_info("Curve %s failed\n", OBJ_nid2sn(nid));
9189f03
        return 0;
9189f03
    }
9189f03
    r = group_order_tests(group);
9189f03
    EC_GROUP_free(group);
9189f03
    return r;
a1fb602
}
a1fb602
a1fb602
# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
a1fb602
/*
a1fb602
 * nistp_test_params contains magic numbers for testing our optimized
a1fb602
 * implementations of several NIST curves with characteristic > 3.
a1fb602
 */
a1fb602
struct nistp_test_params {
62ec0f1
    const EC_METHOD *(*meth) (void);
a1fb602
    int degree;
a1fb602
    /*
a1fb602
     * Qx, Qy and D are taken from
e7a0ff5
     * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf
a1fb602
     * Otherwise, values are standard curve parameters from FIPS 180-3
a1fb602
     */
a1fb602
    const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d;
a1fb602
};
a1fb602
a1fb602
static const struct nistp_test_params nistp_tests_params[] = {
a1fb602
    {
9189f03
     /* P-224 */
9189f03
     EC_GFp_nistp224_method,
9189f03
     224,
9189f03
     /* p */
9189f03
     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
9189f03
     /* a */
9189f03
     "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
9189f03
     /* b */
9189f03
     "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
9189f03
     /* Qx */
9189f03
     "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E",
9189f03
     /* Qy */
9189f03
     "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555",
9189f03
     /* Gx */
9189f03
     "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
9189f03
     /* Gy */
9189f03
     "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
9189f03
     /* order */
9189f03
     "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
9189f03
     /* d */
9189f03
     "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8",
9189f03
     },
9189f03
    {
a1fb602
     /* P-256 */
a1fb602
     EC_GFp_nistp256_method,
a1fb602
     256,
a1fb602
     /* p */
a1fb602
     "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
a1fb602
     /* a */
a1fb602
     "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
a1fb602
     /* b */
a1fb602
     "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
a1fb602
     /* Qx */
a1fb602
     "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19",
a1fb602
     /* Qy */
a1fb602
     "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09",
a1fb602
     /* Gx */
a1fb602
     "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
a1fb602
     /* Gy */
a1fb602
     "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
a1fb602
     /* order */
a1fb602
     "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
a1fb602
     /* d */
a1fb602
     "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96",
a1fb602
     },
a1fb602
    {
a1fb602
     /* P-521 */
a1fb602
     EC_GFp_nistp521_method,
a1fb602
     521,
a1fb602
     /* p */
9189f03
                                                                  "1ff"
9189f03
     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
9189f03
     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
a1fb602
     /* a */
9189f03
                                                                  "1ff"
9189f03
     "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
9189f03
     "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
a1fb602
     /* b */
9189f03
                                                                  "051"
9189f03
     "953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e1"
9189f03
     "56193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
a1fb602
     /* Qx */
9189f03
                                                                 "0098"
9189f03
     "e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e"
9189f03
     "59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4",
a1fb602
     /* Qy */
9189f03
                                                                 "0164"
9189f03
     "350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8"
9189f03
     "554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e",
a1fb602
     /* Gx */
9189f03
                                                                   "c6"
9189f03
     "858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dba"
9189f03
     "a14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
a1fb602
     /* Gy */
9189f03
                                                                  "118"
9189f03
     "39296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c"
9189f03
     "97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
a1fb602
     /* order */
9189f03
                                                                  "1ff"
9189f03
     "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"
9189f03
     "51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
a1fb602
     /* d */
9189f03
                                                                 "0100"
9189f03
     "085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eee"
9189f03
     "df09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722",
a1fb602
     },
a1fb602
};
a1fb602
9189f03
static int nistp_single_test(int idx)
a1fb602
{
9189f03
    const struct nistp_test_params *test = nistp_tests_params + idx;
9189f03
    BN_CTX *ctx = NULL;
9189f03
    BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
9189f03
    BIGNUM *n = NULL, *m = NULL, *order = NULL, *yplusone = NULL;
9189f03
    EC_GROUP *NISTP = NULL;
9189f03
    EC_POINT *G = NULL, *P = NULL, *Q = NULL, *Q_CHECK = NULL;
9189f03
    int r = 0;
9189f03
9189f03
    TEST_note("NIST curve P-%d (optimised implementation):",
9189f03
              test->degree);
9189f03
    if (!TEST_ptr(ctx = BN_CTX_new())
9189f03
        || !TEST_ptr(p = BN_new())
9189f03
        || !TEST_ptr(a = BN_new())
9189f03
        || !TEST_ptr(b = BN_new())
9189f03
        || !TEST_ptr(x = BN_new())
9189f03
        || !TEST_ptr(y = BN_new())
9189f03
        || !TEST_ptr(m = BN_new())
9189f03
        || !TEST_ptr(n = BN_new())
9189f03
        || !TEST_ptr(order = BN_new())
9189f03
        || !TEST_ptr(yplusone = BN_new())
9189f03
9189f03
        || !TEST_ptr(NISTP = EC_GROUP_new(test->meth()))
9189f03
        || !TEST_true(BN_hex2bn(&p, test->p))
9189f03
        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))
9189f03
        || !TEST_true(BN_hex2bn(&a, test->a))
9189f03
        || !TEST_true(BN_hex2bn(&b, test->b))
62ec0f1
        || !TEST_true(EC_GROUP_set_curve(NISTP, p, a, b, ctx))
9189f03
        || !TEST_ptr(G = EC_POINT_new(NISTP))
9189f03
        || !TEST_ptr(P = EC_POINT_new(NISTP))
9189f03
        || !TEST_ptr(Q = EC_POINT_new(NISTP))
9189f03
        || !TEST_ptr(Q_CHECK = EC_POINT_new(NISTP))
9189f03
        || !TEST_true(BN_hex2bn(&x, test->Qx))
9189f03
        || !TEST_true(BN_hex2bn(&y, test->Qy))
9189f03
        || !TEST_true(BN_add(yplusone, y, BN_value_one()))
510bcc2
    /*
510bcc2
     * When (x, y) is on the curve, (x, y + 1) is, as it happens, not,
510bcc2
     * and therefore setting the coordinates should fail.
510bcc2
     */
62ec0f1
        || !TEST_false(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x,
62ec0f1
                                                       yplusone, ctx))
62ec0f1
        || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, Q_CHECK, x, y,
62ec0f1
                                                      ctx))
9189f03
        || !TEST_true(BN_hex2bn(&x, test->Gx))
9189f03
        || !TEST_true(BN_hex2bn(&y, test->Gy))
62ec0f1
        || !TEST_true(EC_POINT_set_affine_coordinates(NISTP, G, x, y, ctx))
9189f03
        || !TEST_true(BN_hex2bn(&order, test->order))
9189f03
        || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one()))
9189f03
        || !TEST_int_eq(EC_GROUP_get_degree(NISTP), test->degree))
9189f03
        goto err;
9189f03
9189f03
    TEST_note("NIST test vectors ... ");
9189f03
    if (!TEST_true(BN_hex2bn(&n, test->d)))
9189f03
        goto err;
a1fb602
    /* fixed point multiplication */
a1fb602
    EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
9189f03
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
9189f03
        goto err;
a1fb602
    /* random point multiplication */
a1fb602
    EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
9189f03
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
9189f03
9189f03
        /* set generator to P = 2*G, where G is the standard generator */
9189f03
        || !TEST_true(EC_POINT_dbl(NISTP, P, G, ctx))
9189f03
        || !TEST_true(EC_GROUP_set_generator(NISTP, P, order, BN_value_one()))
9189f03
        /* set the scalar to m=n/2, where n is the NIST test scalar */
9189f03
        || !TEST_true(BN_rshift(m, n, 1)))
9189f03
        goto err;
a1fb602
a1fb602
    /* test the non-standard generator */
a1fb602
    /* fixed point multiplication */
a1fb602
    EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
9189f03
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
9189f03
        goto err;
a1fb602
    /* random point multiplication */
a1fb602
    EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
9189f03
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
a1fb602
e7a0ff5
    /*
e7a0ff5
     * We have not performed precomputation so have_precompute mult should be
e7a0ff5
     * false
e7a0ff5
     */
9189f03
        || !TEST_false(EC_GROUP_have_precompute_mult(NISTP))
e7a0ff5
a1fb602
    /* now repeat all tests with precomputation */
9189f03
        || !TEST_true(EC_GROUP_precompute_mult(NISTP, ctx))
9189f03
        || !TEST_true(EC_GROUP_have_precompute_mult(NISTP)))
9189f03
        goto err;
a1fb602
a1fb602
    /* fixed point multiplication */
a1fb602
    EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx);
9189f03
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
9189f03
        goto err;
a1fb602
    /* random point multiplication */
a1fb602
    EC_POINT_mul(NISTP, Q, NULL, P, m, ctx);
9189f03
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx))
a1fb602
a1fb602
    /* reset generator */
9189f03
        || !TEST_true(EC_GROUP_set_generator(NISTP, G, order, BN_value_one())))
9189f03
        goto err;
a1fb602
    /* fixed point multiplication */
a1fb602
    EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx);
9189f03
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
9189f03
        goto err;
a1fb602
    /* random point multiplication */
a1fb602
    EC_POINT_mul(NISTP, Q, NULL, G, n, ctx);
9189f03
    if (!TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)))
9189f03
        goto err;
9189f03
9189f03
    /* regression test for felem_neg bug */
9189f03
    if (!TEST_true(BN_set_word(m, 32))
9189f03
        || !TEST_true(BN_set_word(n, 31))
9189f03
        || !TEST_true(EC_POINT_copy(P, G))
9189f03
        || !TEST_true(EC_POINT_invert(NISTP, P, ctx))
9189f03
        || !TEST_true(EC_POINT_mul(NISTP, Q, m, P, n, ctx))
9189f03
        || !TEST_int_eq(0, EC_POINT_cmp(NISTP, Q, G, ctx)))
9189f03
      goto err;
9189f03
9189f03
    r = group_order_tests(NISTP);
9189f03
err:
a1fb602
    EC_GROUP_free(NISTP);
a1fb602
    EC_POINT_free(G);
a1fb602
    EC_POINT_free(P);
a1fb602
    EC_POINT_free(Q);
a1fb602
    EC_POINT_free(Q_CHECK);
a1fb602
    BN_free(n);
a1fb602
    BN_free(m);
a1fb602
    BN_free(p);
a1fb602
    BN_free(a);
a1fb602
    BN_free(b);
a1fb602
    BN_free(x);
a1fb602
    BN_free(y);
a1fb602
    BN_free(order);
510bcc2
    BN_free(yplusone);
a1fb602
    BN_CTX_free(ctx);
9189f03
    return r;
a1fb602
}
9189f03
# endif
a1fb602
9189f03
static const unsigned char p521_named[] = {
9189f03
    0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23,
9189f03
};
a1fb602
9189f03
static const unsigned char p521_explicit[] = {
9189f03
    0x30, 0x82, 0x01, 0xc3, 0x02, 0x01, 0x01, 0x30, 0x4d, 0x06, 0x07, 0x2a,
9189f03
    0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, 0x02, 0x42, 0x01, 0xff, 0xff, 0xff,
9189f03
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9189f03
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9189f03
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9189f03
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9189f03
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9189f03
    0xff, 0xff, 0x30, 0x81, 0x9f, 0x04, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff,
9189f03
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9189f03
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9189f03
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9189f03
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9189f03
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9189f03
    0xfc, 0x04, 0x42, 0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, 0x9a,
9189f03
    0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, 0x40, 0xee, 0xa2, 0xda, 0x72,
9189f03
    0x5b, 0x99, 0xb3, 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, 0x09,
9189f03
    0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, 0x93, 0x7b, 0x16, 0x52, 0xc0,
9189f03
    0xbd, 0x3b, 0xb1, 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, 0x34,
9189f03
    0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, 0x3f, 0x00, 0x03, 0x15, 0x00,
9189f03
    0xd0, 0x9e, 0x88, 0x00, 0x29, 0x1c, 0xb8, 0x53, 0x96, 0xcc, 0x67, 0x17,
9189f03
    0x39, 0x32, 0x84, 0xaa, 0xa0, 0xda, 0x64, 0xba, 0x04, 0x81, 0x85, 0x04,
9189f03
    0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, 0xe9, 0xcd, 0x9e, 0x3e,
9189f03
    0xcb, 0x66, 0x23, 0x95, 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f,
9189f03
    0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, 0x3d, 0xba, 0xa1, 0x4b,
9189f03
    0x5e, 0x77, 0xef, 0xe7, 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff,
9189f03
    0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, 0x42, 0x9b, 0xf9, 0x7e,
9189f03
    0x7e, 0x31, 0xc2, 0xe5, 0xbd, 0x66, 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78,
9189f03
    0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9,
9189f03
    0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17,
9189f03
    0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40,
9189f03
    0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86,
9189f03
    0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50,
9189f03
    0x02, 0x42, 0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9189f03
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
9189f03
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfa,
9189f03
    0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f, 0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48,
9189f03
    0xf7, 0x09, 0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c, 0x47, 0xae,
9189f03
    0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38, 0x64, 0x09, 0x02, 0x01, 0x01,
9189f03
};
a1fb602
9189f03
static int parameter_test(void)
510bcc2
{
9189f03
    EC_GROUP *group = NULL, *group2 = NULL;
9189f03
    ECPARAMETERS *ecparameters = NULL;
9189f03
    unsigned char *buf = NULL;
9189f03
    int r = 0, len;
9189f03
9189f03
    if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp384r1))
9189f03
        || !TEST_ptr(ecparameters = EC_GROUP_get_ecparameters(group, NULL))
9189f03
        || !TEST_ptr(group2 = EC_GROUP_new_from_ecparameters(ecparameters))
9189f03
        || !TEST_int_eq(EC_GROUP_cmp(group, group2, NULL), 0))
9189f03
        goto err;
510bcc2
9189f03
    EC_GROUP_free(group);
9189f03
    group = NULL;
510bcc2
9189f03
    /* Test the named curve encoding, which should be default. */
9189f03
    if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(NID_secp521r1))
9189f03
        || !TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
9189f03
        || !TEST_mem_eq(buf, len, p521_named, sizeof(p521_named)))
9189f03
        goto err;
510bcc2
9189f03
    OPENSSL_free(buf);
9189f03
    buf = NULL;
510bcc2
9189f03
    /*
9189f03
     * Test the explicit encoding. P-521 requires correctly zero-padding the
9189f03
     * curve coefficients.
9189f03
     */
9189f03
    EC_GROUP_set_asn1_flag(group, OPENSSL_EC_EXPLICIT_CURVE);
9189f03
    if (!TEST_true((len = i2d_ECPKParameters(group, &buf)) >= 0)
9189f03
        || !TEST_mem_eq(buf, len, p521_explicit, sizeof(p521_explicit)))
9189f03
        goto err;
510bcc2
9189f03
    r = 1;
9189f03
err:
510bcc2
    EC_GROUP_free(group);
510bcc2
    EC_GROUP_free(group2);
510bcc2
    ECPARAMETERS_free(ecparameters);
9189f03
    OPENSSL_free(buf);
9189f03
    return r;
510bcc2
}
9189f03
#endif
510bcc2
9189f03
int setup_tests(void)
a1fb602
{
9189f03
#ifndef OPENSSL_NO_EC
9189f03
    crv_len = EC_get_builtin_curves(NULL, 0);
9189f03
    if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
9189f03
        || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
9189f03
        return 0;
a1fb602
9189f03
    ADD_TEST(parameter_test);
9189f03
    ADD_TEST(prime_field_tests);
a1fb602
# ifndef OPENSSL_NO_EC2M
9189f03
    ADD_TEST(char2_field_tests);
9189f03
    ADD_ALL_TESTS(char2_curve_test, OSSL_NELEM(char2_curve_tests));
a1fb602
# endif
a1fb602
# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
9189f03
    ADD_ALL_TESTS(nistp_single_test, OSSL_NELEM(nistp_tests_params));
a1fb602
# endif
9189f03
    ADD_ALL_TESTS(internal_curve_test, crv_len);
9189f03
    ADD_ALL_TESTS(internal_curve_test_method, crv_len);
510bcc2
#endif
9189f03
    return 1;
a1fb602
}
9189f03
9189f03
void cleanup_tests(void)
9189f03
{
9189f03
#ifndef OPENSSL_NO_EC
9189f03
    OPENSSL_free(curves);
b355146
#endif
9189f03
}