+#ifdef EC_NISTP224_64_GCC_128
+void nistp224_test()
+ {
+ fprintf(stdout, "\nNIST curve P-224 (optimised implementation):\n");
+ BIGNUM *p, *a, *b, *x, *y, *n, *m, *order;
+ p = BN_new();
+ a = BN_new();
+ b = BN_new();
+ x = BN_new(); y = BN_new();
+ m = BN_new(); n = BN_new(); order = BN_new();
+ BN_CTX *ctx = BN_CTX_new();
+ EC_GROUP *NISTP224;
+ EC_POINT *G, *P, *Q, *Q_CHECK;
+
+ NISTP224 = EC_GROUP_new(EC_GFp_nistp224_method());
+ if(!NISTP224) ABORT;
+ if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) ABORT;
+ if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) ABORT;
+ if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) ABORT;
+ if (!BN_hex2bn(&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) ABORT;
+ if (!EC_GROUP_set_curve_GFp(NISTP224, p, a, b, ctx)) ABORT;
+ G = EC_POINT_new(NISTP224);
+ P = EC_POINT_new(NISTP224);
+ Q = EC_POINT_new(NISTP224);
+ Q_CHECK = EC_POINT_new(NISTP224);
+ if(!BN_hex2bn(&x, "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E")) ABORT;
+ if(!BN_hex2bn(&y, "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555")) ABORT;
+ if(!EC_POINT_set_affine_coordinates_GFp(NISTP224, Q_CHECK, x, y, ctx)) ABORT;
+ if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT;
+ if (!BN_hex2bn(&y, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) ABORT;
+ if (!EC_POINT_set_affine_coordinates_GFp(NISTP224, G, x, y, ctx)) ABORT;
+ if (!BN_hex2bn(&order, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT;
+ if (!EC_GROUP_set_generator(NISTP224, G, order, BN_value_one())) ABORT;
+
+ fprintf(stdout, "verify degree ... ");
+ if (EC_GROUP_get_degree(NISTP224) != 224) ABORT;
+ fprintf(stdout, "ok\n");
+
+ fprintf(stdout, "NIST test vectors ... ");
+ if (!BN_hex2bn(&n, "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8")) ABORT;
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP224, Q, n, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP224, Q, NULL, G, n, ctx);
+ if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT;
+
+ /* set generator to P = 2*G, where G is the standard generator */
+ if (!EC_POINT_dbl(NISTP224, P, G, ctx)) ABORT;
+ if (!EC_GROUP_set_generator(NISTP224, P, order, BN_value_one())) ABORT;
+ /* set the scalar to m=n/2, where n is the NIST test scalar */
+ if (!BN_rshift(m, n, 1)) ABORT;
+
+ /* test the non-standard generator */
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP224, Q, m, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP224, Q, NULL, P, m, ctx);
+ if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT;
+
+ /* now repeat all tests with precomputation */
+ if (!EC_GROUP_precompute_mult(NISTP224, ctx)) ABORT;
+
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP224, Q, m, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP224, Q, NULL, P, m, ctx);
+ if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT;
+
+ /* reset generator */
+ if (!EC_GROUP_set_generator(NISTP224, G, order, BN_value_one())) ABORT;
+ /* fixed point multiplication */
+ EC_POINT_mul(NISTP224, Q, n, NULL, NULL, ctx);
+ if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT;
+ /* random point multiplication */
+ EC_POINT_mul(NISTP224, Q, NULL, G, n, ctx);
+ if (0 != EC_POINT_cmp(NISTP224, Q, Q_CHECK, ctx)) ABORT;
+
+ fprintf(stdout, "ok\n");
+ group_order_tests(NISTP224);
+#if 0
+ timings(NISTP224, TIMING_BASE_PT, ctx);
+ timings(NISTP224, TIMING_RAND_PT, ctx);
+#endif
+ EC_GROUP_free(NISTP224);
+ EC_POINT_free(G);
+ EC_POINT_free(P);
+ EC_POINT_free(Q);
+ EC_POINT_free(Q_CHECK);
+ BN_free(n);
+ BN_free(m);
+ BN_free(p);
+ BN_free(a);
+ BN_free(b);
+ BN_free(x);
+ BN_free(y);
+ BN_free(order);
+ BN_CTX_free(ctx);
+ }
+#endif
+