Blame SOURCES/ectest.c

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