summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/ec/ecp_methods.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/ec/ecp_methods.c')
-rw-r--r--src/lib/libcrypto/ec/ecp_methods.c206
1 files changed, 205 insertions, 1 deletions
diff --git a/src/lib/libcrypto/ec/ecp_methods.c b/src/lib/libcrypto/ec/ecp_methods.c
index 9cce6880df..f3c9f05850 100644
--- a/src/lib/libcrypto/ec/ecp_methods.c
+++ b/src/lib/libcrypto/ec/ecp_methods.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ecp_methods.c,v 1.2 2024/11/12 10:26:06 tb Exp $ */ 1/* $OpenBSD: ecp_methods.c,v 1.3 2024/11/12 10:44:25 tb Exp $ */
2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de> 2/* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
3 * for the OpenSSL project. 3 * for the OpenSSL project.
4 * Includes code written by Bodo Moeller for the OpenSSL project. 4 * Includes code written by Bodo Moeller for the OpenSSL project.
@@ -1608,6 +1608,160 @@ ec_GFp_simple_mul_double_nonct(const EC_GROUP *group, EC_POINT *r,
1608 return ec_wNAF_mul(group, r, g_scalar, 1, &point, &p_scalar, ctx); 1608 return ec_wNAF_mul(group, r, g_scalar, 1, &point, &p_scalar, ctx);
1609} 1609}
1610 1610
1611static void
1612ec_GFp_mont_group_clear(EC_GROUP *group)
1613{
1614 BN_MONT_CTX_free(group->mont_ctx);
1615 group->mont_ctx = NULL;
1616
1617 BN_free(group->mont_one);
1618 group->mont_one = NULL;
1619}
1620
1621static int
1622ec_GFp_mont_group_init(EC_GROUP *group)
1623{
1624 int ok;
1625
1626 ok = ec_GFp_simple_group_init(group);
1627 group->mont_ctx = NULL;
1628 group->mont_one = NULL;
1629 return ok;
1630}
1631
1632static void
1633ec_GFp_mont_group_finish(EC_GROUP *group)
1634{
1635 ec_GFp_mont_group_clear(group);
1636 ec_GFp_simple_group_finish(group);
1637}
1638
1639static int
1640ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src)
1641{
1642 ec_GFp_mont_group_clear(dest);
1643
1644 if (!ec_GFp_simple_group_copy(dest, src))
1645 return 0;
1646
1647 if (src->mont_ctx != NULL) {
1648 dest->mont_ctx = BN_MONT_CTX_new();
1649 if (dest->mont_ctx == NULL)
1650 return 0;
1651 if (!BN_MONT_CTX_copy(dest->mont_ctx, src->mont_ctx))
1652 goto err;
1653 }
1654 if (src->mont_one != NULL) {
1655 dest->mont_one = BN_dup(src->mont_one);
1656 if (dest->mont_one == NULL)
1657 goto err;
1658 }
1659 return 1;
1660
1661 err:
1662 if (dest->mont_ctx != NULL) {
1663 BN_MONT_CTX_free(dest->mont_ctx);
1664 dest->mont_ctx = NULL;
1665 }
1666 return 0;
1667}
1668
1669static int
1670ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a,
1671 const BIGNUM *b, BN_CTX *ctx)
1672{
1673 BN_MONT_CTX *mont = NULL;
1674 BIGNUM *one = NULL;
1675 int ret = 0;
1676
1677 ec_GFp_mont_group_clear(group);
1678
1679 mont = BN_MONT_CTX_new();
1680 if (mont == NULL)
1681 goto err;
1682 if (!BN_MONT_CTX_set(mont, p, ctx)) {
1683 ECerror(ERR_R_BN_LIB);
1684 goto err;
1685 }
1686 one = BN_new();
1687 if (one == NULL)
1688 goto err;
1689 if (!BN_to_montgomery(one, BN_value_one(), mont, ctx))
1690 goto err;
1691
1692 group->mont_ctx = mont;
1693 mont = NULL;
1694 group->mont_one = one;
1695 one = NULL;
1696
1697 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
1698 if (!ret)
1699 ec_GFp_mont_group_clear(group);
1700
1701 err:
1702 BN_MONT_CTX_free(mont);
1703 BN_free(one);
1704
1705 return ret;
1706}
1707
1708static int
1709ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1710 const BIGNUM *b, BN_CTX *ctx)
1711{
1712 if (group->mont_ctx == NULL) {
1713 ECerror(EC_R_NOT_INITIALIZED);
1714 return 0;
1715 }
1716 return BN_mod_mul_montgomery(r, a, b, group->mont_ctx, ctx);
1717}
1718
1719static int
1720ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1721 BN_CTX *ctx)
1722{
1723 if (group->mont_ctx == NULL) {
1724 ECerror(EC_R_NOT_INITIALIZED);
1725 return 0;
1726 }
1727 return BN_mod_mul_montgomery(r, a, a, group->mont_ctx, ctx);
1728}
1729
1730static int
1731ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1732 BN_CTX *ctx)
1733{
1734 if (group->mont_ctx == NULL) {
1735 ECerror(EC_R_NOT_INITIALIZED);
1736 return 0;
1737 }
1738 return BN_to_montgomery(r, a, group->mont_ctx, ctx);
1739}
1740
1741static int
1742ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1743 BN_CTX *ctx)
1744{
1745 if (group->mont_ctx == NULL) {
1746 ECerror(EC_R_NOT_INITIALIZED);
1747 return 0;
1748 }
1749 return BN_from_montgomery(r, a, group->mont_ctx, ctx);
1750}
1751
1752static int
1753ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, BN_CTX *ctx)
1754{
1755 if (group->mont_one == NULL) {
1756 ECerror(EC_R_NOT_INITIALIZED);
1757 return 0;
1758 }
1759 if (!bn_copy(r, group->mont_one))
1760 return 0;
1761
1762 return 1;
1763}
1764
1611static const EC_METHOD ec_GFp_simple_method = { 1765static const EC_METHOD ec_GFp_simple_method = {
1612 .field_type = NID_X9_62_prime_field, 1766 .field_type = NID_X9_62_prime_field,
1613 .group_init = ec_GFp_simple_group_init, 1767 .group_init = ec_GFp_simple_group_init,
@@ -1654,3 +1808,53 @@ EC_GFp_simple_method(void)
1654 return &ec_GFp_simple_method; 1808 return &ec_GFp_simple_method;
1655} 1809}
1656LCRYPTO_ALIAS(EC_GFp_simple_method); 1810LCRYPTO_ALIAS(EC_GFp_simple_method);
1811
1812static const EC_METHOD ec_GFp_mont_method = {
1813 .field_type = NID_X9_62_prime_field,
1814 .group_init = ec_GFp_mont_group_init,
1815 .group_finish = ec_GFp_mont_group_finish,
1816 .group_copy = ec_GFp_mont_group_copy,
1817 .group_set_curve = ec_GFp_mont_group_set_curve,
1818 .group_get_curve = ec_GFp_simple_group_get_curve,
1819 .group_get_degree = ec_GFp_simple_group_get_degree,
1820 .group_order_bits = ec_group_simple_order_bits,
1821 .group_check_discriminant = ec_GFp_simple_group_check_discriminant,
1822 .point_init = ec_GFp_simple_point_init,
1823 .point_finish = ec_GFp_simple_point_finish,
1824 .point_copy = ec_GFp_simple_point_copy,
1825 .point_set_to_infinity = ec_GFp_simple_point_set_to_infinity,
1826 .point_set_Jprojective_coordinates =
1827 ec_GFp_simple_set_Jprojective_coordinates,
1828 .point_get_Jprojective_coordinates =
1829 ec_GFp_simple_get_Jprojective_coordinates,
1830 .point_set_affine_coordinates =
1831 ec_GFp_simple_point_set_affine_coordinates,
1832 .point_get_affine_coordinates =
1833 ec_GFp_simple_point_get_affine_coordinates,
1834 .point_set_compressed_coordinates =
1835 ec_GFp_simple_set_compressed_coordinates,
1836 .add = ec_GFp_simple_add,
1837 .dbl = ec_GFp_simple_dbl,
1838 .invert = ec_GFp_simple_invert,
1839 .is_at_infinity = ec_GFp_simple_is_at_infinity,
1840 .is_on_curve = ec_GFp_simple_is_on_curve,
1841 .point_cmp = ec_GFp_simple_cmp,
1842 .make_affine = ec_GFp_simple_make_affine,
1843 .points_make_affine = ec_GFp_simple_points_make_affine,
1844 .mul_generator_ct = ec_GFp_simple_mul_generator_ct,
1845 .mul_single_ct = ec_GFp_simple_mul_single_ct,
1846 .mul_double_nonct = ec_GFp_simple_mul_double_nonct,
1847 .field_mul = ec_GFp_mont_field_mul,
1848 .field_sqr = ec_GFp_mont_field_sqr,
1849 .field_encode = ec_GFp_mont_field_encode,
1850 .field_decode = ec_GFp_mont_field_decode,
1851 .field_set_to_one = ec_GFp_mont_field_set_to_one,
1852 .blind_coordinates = ec_GFp_simple_blind_coordinates,
1853};
1854
1855const EC_METHOD *
1856EC_GFp_mont_method(void)
1857{
1858 return &ec_GFp_mont_method;
1859}
1860LCRYPTO_ALIAS(EC_GFp_mont_method);