Improve doc on special use of A in ecp group structure
Signed-off-by: Chien Wong <m@xv97.com>
diff --git a/include/mbedtls/ecp.h b/include/mbedtls/ecp.h
index 0e678a3..cd7fd26 100644
--- a/include/mbedtls/ecp.h
+++ b/include/mbedtls/ecp.h
@@ -196,6 +196,23 @@
* cardinality is denoted by \p N. Our code requires that \p N is an
* odd prime as mbedtls_ecp_mul() requires an odd number, and
* mbedtls_ecdsa_sign() requires that it is prime for blinding purposes.
+ * The default implementation only initializes \p A without setting it to the
+ * authentic value for curves with <code>A = -3</code>(SECP256R1, etc), in which
+ * case you need to load and free \p A by yourself when using domain parameters
+ * directly, for example:
+ * \code
+ * mbedtls_ecp_group_init(&grp);
+ * CHECK_RETURN(mbedtls_ecp_group_load(&grp, grp_id));
+ * if (mbedtls_ecp_group_a_is_minus_3(&grp)) {
+ * CHECK_RETURN(mbedtls_mpi_sub_int(&grp.A, &grp.P, 3);
+ * }
+ *
+ * access_grp_A_etc(&grp);
+ *
+ * cleanup:
+ * mbedtls_mpi_free(&grp.A);
+ * mbedtls_ecp_group_free(&grp);
+ * \endcode
*
* For Montgomery curves, we do not store \p A, but <code>(A + 2) / 4</code>,
* which is the quantity used in the formulas. Additionally, \p nbits is
@@ -223,8 +240,11 @@
typedef struct mbedtls_ecp_group {
mbedtls_ecp_group_id id; /*!< An internal group identifier. */
mbedtls_mpi P; /*!< The prime modulus of the base field. */
- mbedtls_mpi A; /*!< For Short Weierstrass: \p A in the equation. For
- Montgomery curves: <code>(A + 2) / 4</code>. */
+ mbedtls_mpi A; /*!< For Short Weierstrass: \p A in the equation. Note that
+ \p A is not set to the authentic value in some cases.
+ For Montgomery curves: <code>(A + 2) / 4</code>.
+ Refer to detailed description of mbedtls_ecp_group if
+ using domain parameters in the structure. */
mbedtls_mpi B; /*!< For Short Weierstrass: \p B in the equation.
For Montgomery curves: unused. */
mbedtls_ecp_point G; /*!< The generator of the subgroup used. */
@@ -992,6 +1012,26 @@
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED)
/**
+ * \brief This function checks if domain parameter A of the curve is
+ * \c -3.
+ *
+ * \note This function is only defined for short Weierstrass curves.
+ * It may not be included in builds without any short
+ * Weierstrass curve.
+ *
+ * \param grp The ECP group to use.
+ * This must be initialized and have group parameters
+ * set, for example through mbedtls_ecp_group_load().
+ *
+ * \return \c 1 if <code>A = -3</code>.
+ * \return \c 0 Otherwise.
+ */
+static inline int mbedtls_ecp_group_a_is_minus_3(const mbedtls_ecp_group *grp)
+{
+ return grp->A.MBEDTLS_PRIVATE(p) == NULL;
+}
+
+/**
* \brief This function performs multiplication and addition of two
* points by integers: \p R = \p m * \p P + \p n * \p Q
*
diff --git a/library/ecp.c b/library/ecp.c
index 870773c..f9b6672 100644
--- a/library/ecp.c
+++ b/library/ecp.c
@@ -1255,7 +1255,7 @@
MPI_ECP_SQR(rhs, X);
/* Special case for A = -3 */
- if (grp->A.p == NULL) {
+ if (mbedtls_ecp_group_a_is_minus_3(grp)) {
MPI_ECP_SUB_INT(rhs, rhs, 3);
} else {
MPI_ECP_ADD(rhs, rhs, &grp->A);
@@ -1526,7 +1526,7 @@
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
/* Special case for A = -3 */
- if (grp->A.p == NULL) {
+ if (mbedtls_ecp_group_a_is_minus_3(grp)) {
/* tmp[0] <- M = 3(X + Z^2)(X - Z^2) */
MPI_ECP_SQR(&tmp[1], &P->Z);
MPI_ECP_ADD(&tmp[2], &P->X, &tmp[1]);