@@ -1561,6 +1561,89 @@ static int parameter_test(void)
15611561 OPENSSL_free (buf );
15621562 return r ;
15631563}
1564+
1565+ /*-
1566+ * For named curves, test that:
1567+ * - the lib correctly computes the cofactor if passed a NULL or zero cofactor
1568+ * - a nonsensical cofactor throws an error (negative test)
1569+ * - nonsensical orders throw errors (negative tests)
1570+ */
1571+ static int cardinality_test (int n )
1572+ {
1573+ int ret = 0 ;
1574+ int nid = curves [n ].nid ;
1575+ BN_CTX * ctx = NULL ;
1576+ EC_GROUP * g1 = NULL , * g2 = NULL ;
1577+ EC_POINT * g2_gen = NULL ;
1578+ BIGNUM * g1_p = NULL , * g1_a = NULL , * g1_b = NULL , * g1_x = NULL , * g1_y = NULL ,
1579+ * g1_order = NULL , * g1_cf = NULL , * g2_cf = NULL ;
1580+
1581+ TEST_info ("Curve %s cardinality test" , OBJ_nid2sn (nid ));
1582+
1583+ if (!TEST_ptr (ctx = BN_CTX_new ())
1584+ || !TEST_ptr (g1 = EC_GROUP_new_by_curve_name (nid ))
1585+ || !TEST_ptr (g2 = EC_GROUP_new (EC_GROUP_method_of (g1 )))) {
1586+ EC_GROUP_free (g1 );
1587+ EC_GROUP_free (g2 );
1588+ BN_CTX_free (ctx );
1589+ return 0 ;
1590+ }
1591+
1592+ BN_CTX_start (ctx );
1593+ g1_p = BN_CTX_get (ctx );
1594+ g1_a = BN_CTX_get (ctx );
1595+ g1_b = BN_CTX_get (ctx );
1596+ g1_x = BN_CTX_get (ctx );
1597+ g1_y = BN_CTX_get (ctx );
1598+ g1_order = BN_CTX_get (ctx );
1599+ g1_cf = BN_CTX_get (ctx );
1600+
1601+ if (!TEST_ptr (g2_cf = BN_CTX_get (ctx ))
1602+ /* pull out the explicit curve parameters */
1603+ || !TEST_true (EC_GROUP_get_curve (g1 , g1_p , g1_a , g1_b , ctx ))
1604+ || !TEST_true (EC_POINT_get_affine_coordinates (g1 ,
1605+ EC_GROUP_get0_generator (g1 ), g1_x , g1_y , ctx ))
1606+ || !TEST_true (BN_copy (g1_order , EC_GROUP_get0_order (g1 )))
1607+ || !TEST_true (EC_GROUP_get_cofactor (g1 , g1_cf , ctx ))
1608+ /* construct g2 manually with g1 parameters */
1609+ || !TEST_true (EC_GROUP_set_curve (g2 , g1_p , g1_a , g1_b , ctx ))
1610+ || !TEST_ptr (g2_gen = EC_POINT_new (g2 ))
1611+ || !TEST_true (EC_POINT_set_affine_coordinates (g2 , g2_gen , g1_x , g1_y , ctx ))
1612+ /* pass NULL cofactor: lib should compute it */
1613+ || !TEST_true (EC_GROUP_set_generator (g2 , g2_gen , g1_order , NULL ))
1614+ || !TEST_true (EC_GROUP_get_cofactor (g2 , g2_cf , ctx ))
1615+ || !TEST_BN_eq (g1_cf , g2_cf )
1616+ /* pass zero cofactor: lib should compute it */
1617+ || !TEST_true (BN_set_word (g2_cf , 0 ))
1618+ || !TEST_true (EC_GROUP_set_generator (g2 , g2_gen , g1_order , g2_cf ))
1619+ || !TEST_true (EC_GROUP_get_cofactor (g2 , g2_cf , ctx ))
1620+ || !TEST_BN_eq (g1_cf , g2_cf )
1621+ /* negative test for invalid cofactor */
1622+ || !TEST_true (BN_set_word (g2_cf , 0 ))
1623+ || !TEST_true (BN_sub (g2_cf , g2_cf , BN_value_one ()))
1624+ || !TEST_false (EC_GROUP_set_generator (g2 , g2_gen , g1_order , g2_cf ))
1625+ /* negative test for NULL order */
1626+ || !TEST_false (EC_GROUP_set_generator (g2 , g2_gen , NULL , NULL ))
1627+ /* negative test for zero order */
1628+ || !TEST_true (BN_set_word (g1_order , 0 ))
1629+ || !TEST_false (EC_GROUP_set_generator (g2 , g2_gen , g1_order , NULL ))
1630+ /* negative test for negative order */
1631+ || !TEST_true (BN_set_word (g2_cf , 0 ))
1632+ || !TEST_true (BN_sub (g2_cf , g2_cf , BN_value_one ()))
1633+ || !TEST_false (EC_GROUP_set_generator (g2 , g2_gen , g1_order , NULL ))
1634+ /* negative test for too large order */
1635+ || !TEST_true (BN_lshift (g1_order , g1_p , 2 ))
1636+ || !TEST_false (EC_GROUP_set_generator (g2 , g2_gen , g1_order , NULL )))
1637+ goto err ;
1638+ ret = 1 ;
1639+ err :
1640+ EC_POINT_free (g2_gen );
1641+ EC_GROUP_free (g1 );
1642+ EC_GROUP_free (g2 );
1643+ BN_CTX_end (ctx );
1644+ BN_CTX_free (ctx );
1645+ return ret ;
1646+ }
15641647#endif
15651648
15661649int setup_tests (void )
@@ -1572,6 +1655,7 @@ int setup_tests(void)
15721655 return 0 ;
15731656
15741657 ADD_TEST (parameter_test );
1658+ ADD_ALL_TESTS (cardinality_test , crv_len );
15751659 ADD_TEST (prime_field_tests );
15761660# ifndef OPENSSL_NO_EC2M
15771661 ADD_TEST (char2_field_tests );
0 commit comments