BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
{
    bn_check_top(b);
    if (a == b)
        return a;
    if (bn_wexpand(a, b->top) == NULL)
        return NULL;
    if (b->top > 0)
        memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
    a->neg = b->neg;
    a->top = b->top;
    a->flags |= b->flags & BN_FLG_FIXED_TOP;
    bn_check_top(a);
    return a;
}
['static int prime_field_tests(void)\n{\n    BN_CTX *ctx = NULL;\n    BIGNUM *p = NULL, *a = NULL, *b = NULL, *scalar3 = NULL;\n    EC_GROUP *group = NULL, *tmp = NULL;\n    EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL,\n             *P_256 = NULL, *P_384 = NULL, *P_521 = NULL;\n    EC_POINT *P = NULL, *Q = NULL, *R = NULL;\n    BIGNUM *x = NULL, *y = NULL, *z = NULL, *yplusone = NULL;\n    const EC_POINT *points[4];\n    const BIGNUM *scalars[4];\n    unsigned char buf[100];\n    size_t len, r = 0;\n    int k;\n    if (!TEST_ptr(ctx = BN_CTX_new())\n        || !TEST_ptr(p = BN_new())\n        || !TEST_ptr(a = BN_new())\n        || !TEST_ptr(b = BN_new())\n        || !TEST_true(BN_hex2bn(&p, "17"))\n        || !TEST_true(BN_hex2bn(&a, "1"))\n        || !TEST_true(BN_hex2bn(&b, "1"))\n        || !TEST_ptr(group = EC_GROUP_new(EC_GFp_mont_method()))\n        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))\n        || !TEST_ptr(tmp = EC_GROUP_new(EC_GROUP_method_of(group)))\n        || !TEST_true(EC_GROUP_copy(tmp, group)))\n        goto err;\n    EC_GROUP_free(group);\n    group = tmp;\n    tmp = NULL;\n    if (!TEST_true(EC_GROUP_get_curve(group, p, a, b, ctx)))\n        goto err;\n    TEST_info("Curve defined by Weierstrass equation");\n    TEST_note("     y^2 = x^3 + a*x + b (mod p)");\n    test_output_bignum("a", a);\n    test_output_bignum("b", b);\n    test_output_bignum("p", p);\n    buf[0] = 0;\n    if (!TEST_ptr(P = EC_POINT_new(group))\n        || !TEST_ptr(Q = EC_POINT_new(group))\n        || !TEST_ptr(R = EC_POINT_new(group))\n        || !TEST_true(EC_POINT_set_to_infinity(group, P))\n        || !TEST_true(EC_POINT_is_at_infinity(group, P))\n        || !TEST_true(EC_POINT_oct2point(group, Q, buf, 1, ctx))\n        || !TEST_true(EC_POINT_add(group, P, P, Q, ctx))\n        || !TEST_true(EC_POINT_is_at_infinity(group, P))\n        || !TEST_ptr(x = BN_new())\n        || !TEST_ptr(y = BN_new())\n        || !TEST_ptr(z = BN_new())\n        || !TEST_ptr(yplusone = BN_new())\n        || !TEST_true(BN_hex2bn(&x, "D"))\n        || !TEST_true(EC_POINT_set_compressed_coordinates(group, Q, x, 1, ctx)))\n        goto err;\n    if (!TEST_int_gt(EC_POINT_is_on_curve(group, Q, ctx), 0)) {\n        if (!TEST_true(EC_POINT_get_affine_coordinates(group, Q, x, y, ctx)))\n            goto err;\n        TEST_info("Point is not on curve");\n        test_output_bignum("x", x);\n        test_output_bignum("y", y);\n        goto err;\n    }\n    TEST_note("A cyclic subgroup:");\n    k = 100;\n    do {\n        if (!TEST_int_ne(k--, 0))\n            goto err;\n        if (EC_POINT_is_at_infinity(group, P)) {\n            TEST_note("     point at infinity");\n        } else {\n            if (!TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y,\n                                                           ctx)))\n                goto err;\n            test_output_bignum("x", x);\n            test_output_bignum("y", y);\n        }\n        if (!TEST_true(EC_POINT_copy(R, P))\n            || !TEST_true(EC_POINT_add(group, P, P, Q, ctx)))\n            goto err;\n    } while (!EC_POINT_is_at_infinity(group, P));\n    if (!TEST_true(EC_POINT_add(group, P, Q, R, ctx))\n        || !TEST_true(EC_POINT_is_at_infinity(group, P)))\n        goto err;\n    len =\n        EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf,\n                           sizeof(buf), ctx);\n    if (!TEST_size_t_ne(len, 0)\n        || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))\n        || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))\n        goto err;\n    test_output_memory("Generator as octet string, compressed form:",\n                       buf, len);\n    len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED,\n                             buf, sizeof(buf), ctx);\n    if (!TEST_size_t_ne(len, 0)\n        || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))\n        || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))\n        goto err;\n    test_output_memory("Generator as octet string, uncompressed form:",\n                       buf, len);\n    len = EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID,\n                             buf, sizeof(buf), ctx);\n    if (!TEST_size_t_ne(len, 0)\n        || !TEST_true(EC_POINT_oct2point(group, P, buf, len, ctx))\n        || !TEST_int_eq(0, EC_POINT_cmp(group, P, Q, ctx)))\n        goto err;\n    test_output_memory("Generator as octet string, hybrid form:",\n                       buf, len);\n    if (!TEST_true(EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z,\n                                                            ctx)))\n        goto err;\n    TEST_info("A representation of the inverse of that generator in");\n    TEST_note("Jacobian projective coordinates");\n    test_output_bignum("x", x);\n    test_output_bignum("y", y);\n    test_output_bignum("z", z);\n    if (!TEST_true(EC_POINT_invert(group, P, ctx))\n        || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))\n        || !TEST_true(BN_hex2bn(&p,                         "FFFFFFFF"\n                                    "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF"))\n        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))\n        || !TEST_true(BN_hex2bn(&a,                         "FFFFFFFF"\n                                    "FFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC"))\n        || !TEST_true(BN_hex2bn(&b,                         "1C97BEFC"\n                                    "54BD7A8B65ACF89F81D4D4ADC565FA45"))\n        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))\n        || !TEST_true(BN_hex2bn(&x,                         "4A96B568"\n                                    "8EF573284664698968C38BB913CBFC82"))\n        || !TEST_true(BN_hex2bn(&y,                         "23a62855"\n                                    "3168947d59dcc912042351377ac5fb32"))\n        || !TEST_true(BN_add(yplusone, y, BN_value_one()))\n        || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,\n                                                       ctx))\n        || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))\n        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)\n        || !TEST_true(BN_hex2bn(&z,                       "0100000000"\n                                    "000000000001F4C8F927AED3CA752257"))\n        || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))\n        || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))\n        goto err;\n    TEST_info("SEC2 curve secp160r1 -- Generator");\n    test_output_bignum("x", x);\n    test_output_bignum("y", y);\n    if (!TEST_true(BN_hex2bn(&z,                         "23a62855"\n                                 "3168947d59dcc912042351377ac5fb32"))\n        || !TEST_BN_eq(y, z)\n        || !TEST_int_eq(EC_GROUP_get_degree(group), 160)\n        || !group_order_tests(group)\n        || !TEST_ptr(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))\n        || !TEST_true(EC_GROUP_copy(P_160, group))\n        || !TEST_true(BN_hex2bn(&p,                 "FFFFFFFFFFFFFFFF"\n                                    "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF"))\n        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))\n        || !TEST_true(BN_hex2bn(&a,                 "FFFFFFFFFFFFFFFF"\n                                    "FFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC"))\n        || !TEST_true(BN_hex2bn(&b,                 "64210519E59C80E7"\n                                    "0FA7E9AB72243049FEB8DEECC146B9B1"))\n        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))\n        || !TEST_true(BN_hex2bn(&x,                 "188DA80EB03090F6"\n                                    "7CBF20EB43A18800F4FF0AFD82FF1012"))\n        || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))\n        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)\n        || !TEST_true(BN_hex2bn(&z,                 "FFFFFFFFFFFFFFFF"\n                                    "FFFFFFFF99DEF836146BC9B1B4D22831"))\n        || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))\n        || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))\n        goto err;\n    TEST_info("NIST curve P-192 -- Generator");\n    test_output_bignum("x", x);\n    test_output_bignum("y", y);\n    if (!TEST_true(BN_hex2bn(&z,                 "07192B95FFC8DA78"\n                                 "631011ED6B24CDD573F977A11E794811"))\n        || !TEST_BN_eq(y, z)\n        || !TEST_true(BN_add(yplusone, y, BN_value_one()))\n        || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,\n                                                       ctx))\n        || !TEST_int_eq(EC_GROUP_get_degree(group), 192)\n        || !group_order_tests(group)\n        || !TEST_ptr(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))\n        || !TEST_true(EC_GROUP_copy(P_192, group))\n        || !TEST_true(BN_hex2bn(&p,         "FFFFFFFFFFFFFFFFFFFFFFFF"\n                                    "FFFFFFFF000000000000000000000001"))\n        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))\n        || !TEST_true(BN_hex2bn(&a,         "FFFFFFFFFFFFFFFFFFFFFFFF"\n                                    "FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE"))\n        || !TEST_true(BN_hex2bn(&b,         "B4050A850C04B3ABF5413256"\n                                    "5044B0B7D7BFD8BA270B39432355FFB4"))\n        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))\n        || !TEST_true(BN_hex2bn(&x,         "B70E0CBD6BB4BF7F321390B9"\n                                    "4A03C1D356C21122343280D6115C1D21"))\n        || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))\n        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)\n        || !TEST_true(BN_hex2bn(&z,         "FFFFFFFFFFFFFFFFFFFFFFFF"\n                                    "FFFF16A2E0B8F03E13DD29455C5C2A3D"))\n        || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))\n        || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))\n        goto err;\n    TEST_info("NIST curve P-224 -- Generator");\n    test_output_bignum("x", x);\n    test_output_bignum("y", y);\n    if (!TEST_true(BN_hex2bn(&z,         "BD376388B5F723FB4C22DFE6"\n                                 "CD4375A05A07476444D5819985007E34"))\n        || !TEST_BN_eq(y, z)\n        || !TEST_true(BN_add(yplusone, y, BN_value_one()))\n        || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,\n                                                       ctx))\n        || !TEST_int_eq(EC_GROUP_get_degree(group), 224)\n        || !group_order_tests(group)\n        || !TEST_ptr(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))\n        || !TEST_true(EC_GROUP_copy(P_224, group))\n        || !TEST_true(BN_hex2bn(&p, "FFFFFFFF000000010000000000000000"\n                                    "00000000FFFFFFFFFFFFFFFFFFFFFFFF"))\n        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))\n        || !TEST_true(BN_hex2bn(&a, "FFFFFFFF000000010000000000000000"\n                                    "00000000FFFFFFFFFFFFFFFFFFFFFFFC"))\n        || !TEST_true(BN_hex2bn(&b, "5AC635D8AA3A93E7B3EBBD55769886BC"\n                                    "651D06B0CC53B0F63BCE3C3E27D2604B"))\n        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))\n        || !TEST_true(BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F2"\n                                    "77037D812DEB33A0F4A13945D898C296"))\n        || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))\n        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)\n        || !TEST_true(BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFF"\n                                    "BCE6FAADA7179E84F3B9CAC2FC632551"))\n        || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))\n        || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))\n        goto err;\n    TEST_info("NIST curve P-256 -- Generator");\n    test_output_bignum("x", x);\n    test_output_bignum("y", y);\n    if (!TEST_true(BN_hex2bn(&z, "4FE342E2FE1A7F9B8EE7EB4A7C0F9E16"\n                                 "2BCE33576B315ECECBB6406837BF51F5"))\n        || !TEST_BN_eq(y, z)\n        || !TEST_true(BN_add(yplusone, y, BN_value_one()))\n        || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,\n                                                       ctx))\n        || !TEST_int_eq(EC_GROUP_get_degree(group), 256)\n        || !group_order_tests(group)\n        || !TEST_ptr(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))\n        || !TEST_true(EC_GROUP_copy(P_256, group))\n        || !TEST_true(BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"\n                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"\n                                    "FFFFFFFF0000000000000000FFFFFFFF"))\n        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))\n        || !TEST_true(BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"\n                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE"\n                                    "FFFFFFFF0000000000000000FFFFFFFC"))\n        || !TEST_true(BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19"\n                                    "181D9C6EFE8141120314088F5013875A"\n                                    "C656398D8A2ED19D2A85C8EDD3EC2AEF"))\n        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))\n        || !TEST_true(BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD74"\n                                    "6E1D3B628BA79B9859F741E082542A38"\n                                    "5502F25DBF55296C3A545E3872760AB7"))\n        || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 1, ctx))\n        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)\n        || !TEST_true(BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"\n                                    "FFFFFFFFFFFFFFFFC7634D81F4372DDF"\n                                    "581A0DB248B0A77AECEC196ACCC52973"))\n        || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))\n        || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))\n        goto err;\n    TEST_info("NIST curve P-384 -- Generator");\n    test_output_bignum("x", x);\n    test_output_bignum("y", y);\n    if (!TEST_true(BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29"\n                                 "F8F41DBD289A147CE9DA3113B5F0B8C0"\n                                 "0A60B1CE1D7E819D7A431D7C90EA0E5F"))\n        || !TEST_BN_eq(y, z)\n        || !TEST_true(BN_add(yplusone, y, BN_value_one()))\n        || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,\n                                                       ctx))\n        || !TEST_int_eq(EC_GROUP_get_degree(group), 384)\n        || !group_order_tests(group)\n        || !TEST_ptr(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))\n        || !TEST_true(EC_GROUP_copy(P_384, group))\n        || !TEST_true(BN_hex2bn(&p,                              "1FF"\n                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"\n                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"\n                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"\n                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"))\n        || !TEST_int_eq(1, BN_is_prime_ex(p, BN_prime_checks, ctx, NULL))\n        || !TEST_true(BN_hex2bn(&a,                              "1FF"\n                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"\n                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"\n                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"\n                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC"))\n        || !TEST_true(BN_hex2bn(&b,                              "051"\n                                    "953EB9618E1C9A1F929A21A0B68540EE"\n                                    "A2DA725B99B315F3B8B489918EF109E1"\n                                    "56193951EC7E937B1652C0BD3BB1BF07"\n                                    "3573DF883D2C34F1EF451FD46B503F00"))\n        || !TEST_true(EC_GROUP_set_curve(group, p, a, b, ctx))\n        || !TEST_true(BN_hex2bn(&x,                               "C6"\n                                    "858E06B70404E9CD9E3ECB662395B442"\n                                    "9C648139053FB521F828AF606B4D3DBA"\n                                    "A14B5E77EFE75928FE1DC127A2FFA8DE"\n                                    "3348B3C1856A429BF97E7E31C2E5BD66"))\n        || !TEST_true(EC_POINT_set_compressed_coordinates(group, P, x, 0, ctx))\n        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)\n        || !TEST_true(BN_hex2bn(&z,                              "1FF"\n                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"\n                                    "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA"\n                                    "51868783BF2F966B7FCC0148F709A5D0"\n                                    "3BB5C9B8899C47AEBB6FB71E91386409"))\n        || !TEST_true(EC_GROUP_set_generator(group, P, z, BN_value_one()))\n        || !TEST_true(EC_POINT_get_affine_coordinates(group, P, x, y, ctx)))\n        goto err;\n    TEST_info("NIST curve P-521 -- Generator");\n    test_output_bignum("x", x);\n    test_output_bignum("y", y);\n    if (!TEST_true(BN_hex2bn(&z,                              "118"\n                                 "39296A789A3BC0045C8A5FB42C7D1BD9"\n                                 "98F54449579B446817AFBD17273E662C"\n                                 "97EE72995EF42640C550B9013FAD0761"\n                                 "353C7086A272C24088BE94769FD16650"))\n        || !TEST_BN_eq(y, z)\n        || !TEST_true(BN_add(yplusone, y, BN_value_one()))\n        || !TEST_false(EC_POINT_set_affine_coordinates(group, P, x, yplusone,\n                                                       ctx))\n        || !TEST_int_eq(EC_GROUP_get_degree(group), 521)\n        || !group_order_tests(group)\n        || !TEST_ptr(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))\n        || !TEST_true(EC_GROUP_copy(P_521, group))\n        || !TEST_true(EC_POINT_set_affine_coordinates(group, P, x, y, ctx))\n        || !TEST_true(EC_POINT_copy(Q, P))\n        || !TEST_false(EC_POINT_is_at_infinity(group, Q))\n        || !TEST_true(EC_POINT_dbl(group, P, P, ctx))\n        || !TEST_int_gt(EC_POINT_is_on_curve(group, P, ctx), 0)\n        || !TEST_true(EC_POINT_invert(group, Q, ctx))\n        || !TEST_true(EC_POINT_add(group, R, P, Q, ctx))\n        || !TEST_true(EC_POINT_add(group, R, R, Q, ctx))\n        || !TEST_true(EC_POINT_is_at_infinity(group, R))\n        || !TEST_false(EC_POINT_is_at_infinity(group, Q)))\n        goto err;\n    points[0] = Q;\n    points[1] = Q;\n    points[2] = Q;\n    points[3] = Q;\n    if (!TEST_true(EC_GROUP_get_order(group, z, ctx))\n        || !TEST_true(BN_add(y, z, BN_value_one()))\n        || !TEST_BN_even(y)\n        || !TEST_true(BN_rshift1(y, y)))\n        goto err;\n    scalars[0] = y;\n    scalars[1] = y;\n    TEST_note("combined multiplication ...");\n    if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))\n        || !TEST_true(EC_POINTs_mul(group, R, z, 2, points, scalars, ctx))\n        || !TEST_int_eq(0, EC_POINT_cmp(group, P, R, ctx))\n        || !TEST_int_eq(0, EC_POINT_cmp(group, R, Q, ctx))\n        || !TEST_true(BN_rand(y, BN_num_bits(y), 0, 0))\n        || !TEST_true(BN_add(z, z, y)))\n        goto err;\n    BN_set_negative(z, 1);\n    scalars[0] = y;\n    scalars[1] = z;\n    if (!TEST_true(EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx))\n        || !TEST_true(EC_POINT_is_at_infinity(group, P))\n        || !TEST_true(BN_rand(x, BN_num_bits(y) - 1, 0, 0))\n        || !TEST_true(BN_add(z, x, y)))\n        goto err;\n    BN_set_negative(z, 1);\n    scalars[0] = x;\n    scalars[1] = y;\n    scalars[2] = z;\n    if (!TEST_ptr(scalar3 = BN_new()))\n        goto err;\n    BN_zero(scalar3);\n    scalars[3] = scalar3;\n    if (!TEST_true(EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx))\n        || !TEST_true(EC_POINT_is_at_infinity(group, P)))\n        goto err;\n    TEST_note(" ok\\n");\n    r = 1;\nerr:\n    BN_CTX_free(ctx);\n    BN_free(p);\n    BN_free(a);\n    BN_free(b);\n    EC_GROUP_free(group);\n    EC_GROUP_free(tmp);\n    EC_POINT_free(P);\n    EC_POINT_free(Q);\n    EC_POINT_free(R);\n    BN_free(x);\n    BN_free(y);\n    BN_free(z);\n    BN_free(yplusone);\n    BN_free(scalar3);\n    EC_GROUP_free(P_160);\n    EC_GROUP_free(P_192);\n    EC_GROUP_free(P_224);\n    EC_GROUP_free(P_256);\n    EC_GROUP_free(P_384);\n    EC_GROUP_free(P_521);\n    return r;\n}', "int BN_hex2bn(BIGNUM **bn, const char *a)\n{\n    BIGNUM *ret = NULL;\n    BN_ULONG l = 0;\n    int neg = 0, h, m, i, j, k, c;\n    int num;\n    if (a == NULL || *a == '\\0')\n        return 0;\n    if (*a == '-') {\n        neg = 1;\n        a++;\n    }\n    for (i = 0; i <= INT_MAX / 4 && ossl_isxdigit(a[i]); i++)\n        continue;\n    if (i == 0 || i > INT_MAX / 4)\n        goto err;\n    num = i + neg;\n    if (bn == NULL)\n        return num;\n    if (*bn == NULL) {\n        if ((ret = BN_new()) == NULL)\n            return 0;\n    } else {\n        ret = *bn;\n        BN_zero(ret);\n    }\n    if (bn_expand(ret, i * 4) == NULL)\n        goto err;\n    j = i;\n    m = 0;\n    h = 0;\n    while (j > 0) {\n        m = (BN_BYTES * 2 <= j) ? BN_BYTES * 2 : j;\n        l = 0;\n        for (;;) {\n            c = a[j - m];\n            k = OPENSSL_hexchar2int(c);\n            if (k < 0)\n                k = 0;\n            l = (l << 4) | k;\n            if (--m <= 0) {\n                ret->d[h++] = l;\n                break;\n            }\n        }\n        j -= BN_BYTES * 2;\n    }\n    ret->top = h;\n    bn_correct_top(ret);\n    *bn = ret;\n    bn_check_top(ret);\n    if (ret->top != 0)\n        ret->neg = neg;\n    return num;\n err:\n    if (*bn == NULL)\n        BN_free(ret);\n    return 0;\n}", 'int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,\n                  size_t num, const EC_POINT *points[],\n                  const BIGNUM *scalars[], BN_CTX *ctx)\n{\n    int ret = 0;\n    size_t i = 0;\n    BN_CTX *new_ctx = NULL;\n    if ((scalar == NULL) && (num == 0)) {\n        return EC_POINT_set_to_infinity(group, r);\n    }\n    if (!ec_point_is_compat(r, group)) {\n        ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);\n        return 0;\n    }\n    for (i = 0; i < num; i++) {\n        if (!ec_point_is_compat(points[i], group)) {\n            ECerr(EC_F_EC_POINTS_MUL, EC_R_INCOMPATIBLE_OBJECTS);\n            return 0;\n        }\n    }\n    if (ctx == NULL && (ctx = new_ctx = BN_CTX_secure_new()) == NULL) {\n        ECerr(EC_F_EC_POINTS_MUL, ERR_R_INTERNAL_ERROR);\n        return 0;\n    }\n    if (group->meth->mul != NULL)\n        ret = group->meth->mul(group, r, scalar, num, points, scalars, ctx);\n    else\n        ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx);\n    BN_CTX_free(new_ctx);\n    return ret;\n}', 'int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,\n                size_t num, const EC_POINT *points[], const BIGNUM *scalars[],\n                BN_CTX *ctx)\n{\n    const EC_POINT *generator = NULL;\n    EC_POINT *tmp = NULL;\n    size_t totalnum;\n    size_t blocksize = 0, numblocks = 0;\n    size_t pre_points_per_block = 0;\n    size_t i, j;\n    int k;\n    int r_is_inverted = 0;\n    int r_is_at_infinity = 1;\n    size_t *wsize = NULL;\n    signed char **wNAF = NULL;\n    size_t *wNAF_len = NULL;\n    size_t max_len = 0;\n    size_t num_val;\n    EC_POINT **val = NULL;\n    EC_POINT **v;\n    EC_POINT ***val_sub = NULL;\n    const EC_PRE_COMP *pre_comp = NULL;\n    int num_scalar = 0;\n    int ret = 0;\n    if (!BN_is_zero(group->order) && !BN_is_zero(group->cofactor)) {\n        if ((scalar != group->order) && (scalar != NULL) && (num == 0)) {\n            return ec_scalar_mul_ladder(group, r, scalar, NULL, ctx);\n        }\n        if ((scalar == NULL) && (num == 1) && (scalars[0] != group->order)) {\n            return ec_scalar_mul_ladder(group, r, scalars[0], points[0], ctx);\n        }\n    }\n    if (scalar != NULL) {\n        generator = EC_GROUP_get0_generator(group);\n        if (generator == NULL) {\n            ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR);\n            goto err;\n        }\n        pre_comp = group->pre_comp.ec;\n        if (pre_comp && pre_comp->numblocks\n            && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) ==\n                0)) {\n            blocksize = pre_comp->blocksize;\n            numblocks = (BN_num_bits(scalar) / blocksize) + 1;\n            if (numblocks > pre_comp->numblocks)\n                numblocks = pre_comp->numblocks;\n            pre_points_per_block = (size_t)1 << (pre_comp->w - 1);\n            if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {\n                ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);\n                goto err;\n            }\n        } else {\n            pre_comp = NULL;\n            numblocks = 1;\n            num_scalar = 1;\n        }\n    }\n    totalnum = num + numblocks;\n    wsize = OPENSSL_malloc(totalnum * sizeof(wsize[0]));\n    wNAF_len = OPENSSL_malloc(totalnum * sizeof(wNAF_len[0]));\n    wNAF = OPENSSL_malloc((totalnum + 1) * sizeof(wNAF[0]));\n    val_sub = OPENSSL_malloc(totalnum * sizeof(val_sub[0]));\n    if (wNAF != NULL)\n        wNAF[0] = NULL;\n    if (wsize == NULL || wNAF_len == NULL || wNAF == NULL || val_sub == NULL) {\n        ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    num_val = 0;\n    for (i = 0; i < num + num_scalar; i++) {\n        size_t bits;\n        bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar);\n        wsize[i] = EC_window_bits_for_scalar_size(bits);\n        num_val += (size_t)1 << (wsize[i] - 1);\n        wNAF[i + 1] = NULL;\n        wNAF[i] =\n            bn_compute_wNAF((i < num ? scalars[i] : scalar), wsize[i],\n                            &wNAF_len[i]);\n        if (wNAF[i] == NULL)\n            goto err;\n        if (wNAF_len[i] > max_len)\n            max_len = wNAF_len[i];\n    }\n    if (numblocks) {\n        if (pre_comp == NULL) {\n            if (num_scalar != 1) {\n                ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);\n                goto err;\n            }\n        } else {\n            signed char *tmp_wNAF = NULL;\n            size_t tmp_len = 0;\n            if (num_scalar != 0) {\n                ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);\n                goto err;\n            }\n            wsize[num] = pre_comp->w;\n            tmp_wNAF = bn_compute_wNAF(scalar, wsize[num], &tmp_len);\n            if (!tmp_wNAF)\n                goto err;\n            if (tmp_len <= max_len) {\n                numblocks = 1;\n                totalnum = num + 1;\n                wNAF[num] = tmp_wNAF;\n                wNAF[num + 1] = NULL;\n                wNAF_len[num] = tmp_len;\n                val_sub[num] = pre_comp->points;\n            } else {\n                signed char *pp;\n                EC_POINT **tmp_points;\n                if (tmp_len < numblocks * blocksize) {\n                    numblocks = (tmp_len + blocksize - 1) / blocksize;\n                    if (numblocks > pre_comp->numblocks) {\n                        ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);\n                        OPENSSL_free(tmp_wNAF);\n                        goto err;\n                    }\n                    totalnum = num + numblocks;\n                }\n                pp = tmp_wNAF;\n                tmp_points = pre_comp->points;\n                for (i = num; i < totalnum; i++) {\n                    if (i < totalnum - 1) {\n                        wNAF_len[i] = blocksize;\n                        if (tmp_len < blocksize) {\n                            ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);\n                            OPENSSL_free(tmp_wNAF);\n                            goto err;\n                        }\n                        tmp_len -= blocksize;\n                    } else\n                        wNAF_len[i] = tmp_len;\n                    wNAF[i + 1] = NULL;\n                    wNAF[i] = OPENSSL_malloc(wNAF_len[i]);\n                    if (wNAF[i] == NULL) {\n                        ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);\n                        OPENSSL_free(tmp_wNAF);\n                        goto err;\n                    }\n                    memcpy(wNAF[i], pp, wNAF_len[i]);\n                    if (wNAF_len[i] > max_len)\n                        max_len = wNAF_len[i];\n                    if (*tmp_points == NULL) {\n                        ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);\n                        OPENSSL_free(tmp_wNAF);\n                        goto err;\n                    }\n                    val_sub[i] = tmp_points;\n                    tmp_points += pre_points_per_block;\n                    pp += blocksize;\n                }\n                OPENSSL_free(tmp_wNAF);\n            }\n        }\n    }\n    val = OPENSSL_malloc((num_val + 1) * sizeof(val[0]));\n    if (val == NULL) {\n        ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    val[num_val] = NULL;\n    v = val;\n    for (i = 0; i < num + num_scalar; i++) {\n        val_sub[i] = v;\n        for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) {\n            *v = EC_POINT_new(group);\n            if (*v == NULL)\n                goto err;\n            v++;\n        }\n    }\n    if (!(v == val + num_val)) {\n        ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR);\n        goto err;\n    }\n    if ((tmp = EC_POINT_new(group)) == NULL)\n        goto err;\n    for (i = 0; i < num + num_scalar; i++) {\n        if (i < num) {\n            if (!EC_POINT_copy(val_sub[i][0], points[i]))\n                goto err;\n        } else {\n            if (!EC_POINT_copy(val_sub[i][0], generator))\n                goto err;\n        }\n        if (wsize[i] > 1) {\n            if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx))\n                goto err;\n            for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) {\n                if (!EC_POINT_add\n                    (group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx))\n                    goto err;\n            }\n        }\n    }\n    if (!EC_POINTs_make_affine(group, num_val, val, ctx))\n        goto err;\n    r_is_at_infinity = 1;\n    for (k = max_len - 1; k >= 0; k--) {\n        if (!r_is_at_infinity) {\n            if (!EC_POINT_dbl(group, r, r, ctx))\n                goto err;\n        }\n        for (i = 0; i < totalnum; i++) {\n            if (wNAF_len[i] > (size_t)k) {\n                int digit = wNAF[i][k];\n                int is_neg;\n                if (digit) {\n                    is_neg = digit < 0;\n                    if (is_neg)\n                        digit = -digit;\n                    if (is_neg != r_is_inverted) {\n                        if (!r_is_at_infinity) {\n                            if (!EC_POINT_invert(group, r, ctx))\n                                goto err;\n                        }\n                        r_is_inverted = !r_is_inverted;\n                    }\n                    if (r_is_at_infinity) {\n                        if (!EC_POINT_copy(r, val_sub[i][digit >> 1]))\n                            goto err;\n                        r_is_at_infinity = 0;\n                    } else {\n                        if (!EC_POINT_add\n                            (group, r, r, val_sub[i][digit >> 1], ctx))\n                            goto err;\n                    }\n                }\n            }\n        }\n    }\n    if (r_is_at_infinity) {\n        if (!EC_POINT_set_to_infinity(group, r))\n            goto err;\n    } else {\n        if (r_is_inverted)\n            if (!EC_POINT_invert(group, r, ctx))\n                goto err;\n    }\n    ret = 1;\n err:\n    EC_POINT_free(tmp);\n    OPENSSL_free(wsize);\n    OPENSSL_free(wNAF_len);\n    if (wNAF != NULL) {\n        signed char **w;\n        for (w = wNAF; *w != NULL; w++)\n            OPENSSL_free(*w);\n        OPENSSL_free(wNAF);\n    }\n    if (val != NULL) {\n        for (v = val; *v != NULL; v++)\n            EC_POINT_clear_free(*v);\n        OPENSSL_free(val);\n    }\n    OPENSSL_free(val_sub);\n    return ret;\n}', 'int ec_scalar_mul_ladder(const EC_GROUP *group, EC_POINT *r,\n                         const BIGNUM *scalar, const EC_POINT *point,\n                         BN_CTX *ctx)\n{\n    int i, cardinality_bits, group_top, kbit, pbit, Z_is_one;\n    EC_POINT *p = NULL;\n    EC_POINT *s = NULL;\n    BIGNUM *k = NULL;\n    BIGNUM *lambda = NULL;\n    BIGNUM *cardinality = NULL;\n    int ret = 0;\n    if (point != NULL && EC_POINT_is_at_infinity(group, point))\n        return EC_POINT_set_to_infinity(group, r);\n    if (BN_is_zero(group->order)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_ORDER);\n        return 0;\n    }\n    if (BN_is_zero(group->cofactor)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_UNKNOWN_COFACTOR);\n        return 0;\n    }\n    BN_CTX_start(ctx);\n    if (((p = EC_POINT_new(group)) == NULL)\n        || ((s = EC_POINT_new(group)) == NULL)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    if (point == NULL) {\n        if (!EC_POINT_copy(p, group->generator)) {\n            ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);\n            goto err;\n        }\n    } else {\n        if (!EC_POINT_copy(p, point)) {\n            ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_EC_LIB);\n            goto err;\n        }\n    }\n    EC_POINT_BN_set_flags(p, BN_FLG_CONSTTIME);\n    EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME);\n    EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME);\n    cardinality = BN_CTX_get(ctx);\n    lambda = BN_CTX_get(ctx);\n    k = BN_CTX_get(ctx);\n    if (k == NULL) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_MALLOC_FAILURE);\n        goto err;\n    }\n    if (!BN_mul(cardinality, group->order, group->cofactor, ctx)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);\n        goto err;\n    }\n    cardinality_bits = BN_num_bits(cardinality);\n    group_top = bn_get_top(cardinality);\n    if ((bn_wexpand(k, group_top + 2) == NULL)\n        || (bn_wexpand(lambda, group_top + 2) == NULL)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);\n        goto err;\n    }\n    if (!BN_copy(k, scalar)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);\n        goto err;\n    }\n    BN_set_flags(k, BN_FLG_CONSTTIME);\n    if ((BN_num_bits(k) > cardinality_bits) || (BN_is_negative(k))) {\n        if (!BN_nnmod(k, k, cardinality, ctx)) {\n            ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);\n            goto err;\n        }\n    }\n    if (!BN_add(lambda, k, cardinality)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);\n        goto err;\n    }\n    BN_set_flags(lambda, BN_FLG_CONSTTIME);\n    if (!BN_add(k, lambda, cardinality)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);\n        goto err;\n    }\n    kbit = BN_is_bit_set(lambda, cardinality_bits);\n    BN_consttime_swap(kbit, k, lambda, group_top + 2);\n    group_top = bn_get_top(group->field);\n    if ((bn_wexpand(s->X, group_top) == NULL)\n        || (bn_wexpand(s->Y, group_top) == NULL)\n        || (bn_wexpand(s->Z, group_top) == NULL)\n        || (bn_wexpand(r->X, group_top) == NULL)\n        || (bn_wexpand(r->Y, group_top) == NULL)\n        || (bn_wexpand(r->Z, group_top) == NULL)\n        || (bn_wexpand(p->X, group_top) == NULL)\n        || (bn_wexpand(p->Y, group_top) == NULL)\n        || (bn_wexpand(p->Z, group_top) == NULL)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, ERR_R_BN_LIB);\n        goto err;\n    }\n    if (!ec_point_blind_coordinates(group, p, ctx)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_POINT_COORDINATES_BLIND_FAILURE);\n        goto err;\n    }\n    if (!ec_point_ladder_pre(group, r, s, p, ctx)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_PRE_FAILURE);\n        goto err;\n    }\n    pbit = 1;\n#define EC_POINT_CSWAP(c, a, b, w, t) do {         \\\n        BN_consttime_swap(c, (a)->X, (b)->X, w);   \\\n        BN_consttime_swap(c, (a)->Y, (b)->Y, w);   \\\n        BN_consttime_swap(c, (a)->Z, (b)->Z, w);   \\\n        t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \\\n        (a)->Z_is_one ^= (t);                      \\\n        (b)->Z_is_one ^= (t);                      \\\n} while(0)\n    for (i = cardinality_bits - 1; i >= 0; i--) {\n        kbit = BN_is_bit_set(k, i) ^ pbit;\n        EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one);\n        if (!ec_point_ladder_step(group, r, s, p, ctx)) {\n            ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_STEP_FAILURE);\n            goto err;\n        }\n        pbit ^= kbit;\n    }\n    EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one);\n#undef EC_POINT_CSWAP\n    if (!ec_point_ladder_post(group, r, s, p, ctx)) {\n        ECerr(EC_F_EC_SCALAR_MUL_LADDER, EC_R_LADDER_POST_FAILURE);\n        goto err;\n    }\n    ret = 1;\n err:\n    EC_POINT_free(p);\n    EC_POINT_clear_free(s);\n    BN_CTX_end(ctx);\n    return ret;\n}', 'BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)\n{\n    bn_check_top(b);\n    if (a == b)\n        return a;\n    if (bn_wexpand(a, b->top) == NULL)\n        return NULL;\n    if (b->top > 0)\n        memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);\n    a->neg = b->neg;\n    a->top = b->top;\n    a->flags |= b->flags & BN_FLG_FIXED_TOP;\n    bn_check_top(a);\n    return a;\n}', 'BIGNUM *bn_wexpand(BIGNUM *a, int words)\n{\n    return (words <= a->dmax) ? a : bn_expand2(a, words);\n}']