Repository: randombit/botan
Pull request #3158 (2023-01-04 19:49:28)

starting to remove handmade thread facilities in favor of their C++20…
… counterparts.

codecov-commenter: # [Codecov](https://codecov.io/gh/randombit/botan/pull/3158?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd) Report
Base: **88.02**% // Head: **87.99**% // Decreases project coverage by **`-0.02%`** :warning:
> Coverage data is based on head [(`6c7a3e5`)](https://codecov.io/gh/randombit/botan/pull/3158?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd) compared to base [(`84e662b`)](https://codecov.io/gh/randombit/botan/commit/84e662b740650302a9bc194367220167155f38af?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd).
> Patch has no changes to coverable lines.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #3158      +/-   ##
==========================================
- Coverage   88.02%   87.99%   -0.03%     
==========================================
  Files         600      599       -1     
  Lines       67091    67076      -15     
  Branches     6703     6699       -4     
==========================================
- Hits        59057    59024      -33     
- Misses       5209     5234      +25     
+ Partials     2825     2818       -7     
```


| [Impacted Files](https://codecov.io/gh/randombit/botan/pull/3158?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd) | Coverage Δ | |
|---|---|---|
| [src/lib/filters/threaded\_fork.cpp](https://codecov.io/gh/randombit/botan/pull/3158?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd#diff-c3JjL2xpYi9maWx0ZXJzL3RocmVhZGVkX2ZvcmsuY3Bw) | `82.35% <ø> (ø)` | |
| [src/lib/entropy/rdseed/rdseed.cpp](https://codecov.io/gh/randombit/botan/pull/3158?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd#diff-c3JjL2xpYi9lbnRyb3B5L3Jkc2VlZC9yZHNlZWQuY3Bw) | `18.18% <0.00%> (-63.64%)` | :arrow_down: |
| [src/fuzzer/mode\_padding.cpp](https://codecov.io/gh/randombit/botan/pull/3158?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd#diff-c3JjL2Z1enplci9tb2RlX3BhZGRpbmcuY3Bw) | `82.69% <0.00%> (-8.05%)` | :arrow_down: |
| [src/fuzzer/barrett.cpp](https://codecov.io/gh/randombit/botan/pull/3158?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd#diff-c3JjL2Z1enplci9iYXJyZXR0LmNwcA==) | `72.22% <0.00%> (-5.56%)` | :arrow_down: |
| [src/fuzzer/uri.cpp](https://codecov.io/gh/randombit/botan/pull/3158?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd#diff-c3JjL2Z1enplci91cmkuY3Bw) | `75.00% <0.00%> (-5.00%)` | :arrow_down: |
| [src/cli/cli\_rng.cpp](https://codecov.io/gh/randombit/botan/pull/3158?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd#diff-c3JjL2NsaS9jbGlfcm5nLmNwcA==) | `60.00% <0.00%> (-4.00%)` | :arrow_down: |
| [src/lib/misc/cryptobox/cryptobox.cpp](https://codecov.io/gh/randombit/botan/pull/3158?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd#diff-c3JjL2xpYi9taXNjL2NyeXB0b2JveC9jcnlwdG9ib3guY3Bw) | `90.14% <0.00%> (-2.82%)` | :arrow_down: |
| [src/lib/utils/cpuid/cpuid\_x86.cpp](https://codecov.io/gh/randombit/botan/pull/3158?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd#diff-c3JjL2xpYi91dGlscy9jcHVpZC9jcHVpZF94ODYuY3Bw) | `45.94% <0.00%> (-2.71%)` | :arrow_down: |
| [src/fuzzer/oaep.cpp](https://codecov.io/gh/randombit/botan/pull/3158?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd#diff-c3JjL2Z1enplci9vYWVwLmNwcA==) | `44.44% <0.00%> (-1.99%)` | :arrow_down: |
| [src/lib/asn1/der\_enc.cpp](https://codecov.io/gh/randombit/botan/pull/3158?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd#diff-c3JjL2xpYi9hc24xL2Rlcl9lbmMuY3Bw) | `77.63% <0.00%> (-1.32%)` | :arrow_down: |
| ... and [7 more](https://codecov.io/gh/randombit/botan/pull/3158?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd) | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd)

</details>

[:umbrella: View full report at Codecov](https://codecov.io/gh/randombit/botan/pull/3158?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jack+Lloyd).


Patch:
diff --git a/.github/workflows/cifuzz.yml b/.github/workflows/cifuzz.yml
index c07b8676f..6331f3304 100644
--- a/.github/workflows/cifuzz.yml
+++ b/.github/workflows/cifuzz.yml
@@ -1,5 +1,10 @@
 name: CIFuzz
 on: [pull_request]
+
+# cancel running workflows when new commits are pushed
+concurrency:
+  cancel-in-progress: true
+
 jobs:
   Fuzzing:
     runs-on: ubuntu-22.04
diff --git a/configure.py b/configure.py
index 0c878336d..32739bf16 100755
--- a/configure.py
+++ b/configure.py
@@ -2243,7 +2243,6 @@ def create_template_vars(source_paths, build_paths, options, modules, cc, arch,
         'system_cert_bundle': options.system_cert_bundle,
 
         'fuzzer_mode': options.unsafe_fuzzer_mode,
-        'building_fuzzers': options.build_fuzzers,
         'fuzzer_type': options.build_fuzzers.upper() if options.build_fuzzers else '',
 
         'with_valgrind': options.with_valgrind,
diff --git a/doc/api_ref/ecc.rst b/doc/api_ref/ecc.rst
index 2af2ef2cd..f522bbe3d 100644
--- a/doc/api_ref/ecc.rst
+++ b/doc/api_ref/ecc.rst
@@ -88,7 +88,7 @@ during common operations.
 
          Return the ``b`` parameter of the elliptic curve equation.
 
-      .. cpp:function:: const EC_Point& get_base_point() const
+      .. cpp:function:: const PointGFp& get_base_point() const
 
          Return the groups base point element.
 
@@ -120,7 +120,7 @@ during common operations.
 
          Multiply ``x`` and ``y`` and reduce the result modulo the curve order.
 
-      .. cpp:function:: bool verify_public_element(const EC_Point& y) const
+      .. cpp:function:: bool verify_public_element(const PointGFp& y) const
 
          Return true if ``y`` seems to be a valid group element.
 
@@ -128,18 +128,18 @@ during common operations.
 
          Return the OID used to identify the curve. May be empty.
 
-      .. cpp:function:: EC_Point point(const BigInt& x, const BigInt& y) const
+      .. cpp:function:: PointGFp point(const BigInt& x, const BigInt& y) const
 
          Create and return a point with affine elements ``x`` and ``y``. Note
          this function *does not* verify that ``x`` and ``y`` satisfy the curve
          equation.
 
-      .. cpp:function:: EC_Point point_multiply(const BigInt& x, const EC_Point& pt, const BigInt& y) const
+      .. cpp:function:: PointGFp point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const
 
          Multi-exponentiation. Returns base_point*x + pt*y. Not constant time.
          (Ordinarily used for signature verification.)
 
-      .. cpp:function:: EC_Point blinded_base_point_multiply(const BigInt& k, \
+      .. cpp:function:: PointGFp blinded_base_point_multiply(const BigInt& k, \
                                             RandomNumberGenerator& rng, \
                                             std::vector<BigInt>& ws) const
 
@@ -151,7 +151,7 @@ during common operations.
 
          Like `blinded_base_point_multiply` but returns only the x coordinate.
 
-      .. cpp:function:: EC_Point blinded_var_point_multiply(const EC_Point& point, \
+      .. cpp:function:: PointGFp blinded_var_point_multiply(const PointGFp& point, \
                                           const BigInt& k, \
                                           RandomNumberGenerator& rng, \
                                           std::vector<BigInt>& ws) const
@@ -162,11 +162,11 @@ during common operations.
 
          Return a random scalar (ie an integer between 1 and the group order).
 
-      .. cpp:function:: EC_Point zero_point() const
+      .. cpp:function:: PointGFp zero_point() const
 
          Return the zero point (aka the point at infinity).
 
-      .. cpp:function:: EC_Point OS2ECP(const uint8_t bits[], size_t len) const
+      .. cpp:function:: PointGFp OS2ECP(const uint8_t bits[], size_t len) const
 
          Decode a point from the binary encoding. This function verifies that
          the decoded point is a valid element on the curve.
@@ -180,30 +180,30 @@ during common operations.
          Return a list of known groups, ie groups for which ``EC_Group(name)``
          will succeed.
 
-.. cpp:class:: EC_Point
+.. cpp:class:: PointGFp
 
    Stores elliptic curve points in Jacobian representation.
 
-   .. cpp:function:: std::vector<uint8_t> encode(EC_Point::Compression_Type format) const
+   .. cpp:function:: std::vector<uint8_t> encode(PointGFp::Compression_Type format) const
 
       Encode a point in a way that can later be decoded with `EC_Group::OS2ECP`.
 
-   .. cpp:function:: EC_Point& operator+=(const EC_Point& rhs)
+   .. cpp:function:: PointGFp& operator+=(const PointGFp& rhs)
 
       Point addition.
 
-   .. cpp:function:: EC_Point& operator-=(const EC_Point& rhs)
+   .. cpp:function:: PointGFp& operator-=(const PointGFp& rhs)
 
       Point subtraction.
 
-   .. cpp:function:: EC_Point& operator*=(const BigInt& scalar)
+   .. cpp:function:: PointGFp& operator*=(const BigInt& scalar)
 
       Point multiplication using Montgomery ladder.
 
       .. warning::
          Prefer the blinded functions in ``EC_Group``
 
-   .. cpp:function:: EC_Point& negate()
+   .. cpp:function:: PointGFp& negate()
 
       Negate this point.
 
@@ -220,7 +220,7 @@ during common operations.
       Convert the point to its equivalent affine coordinates. Throws
       if this is the point at infinity.
 
-   .. cpp:function:: static void force_all_affine(std::vector<EC_Point>& points, \
+   .. cpp:function:: static void force_all_affine(std::vector<PointGFp>& points, \
                                                   secure_vector<word>& ws)
 
       Force several points to be affine at once. Uses Montgomery's
@@ -243,15 +243,15 @@ during common operations.
 
       Randomize the point representation.
 
-   .. cpp:function:: bool operator==(const EC_Point& other) const
+   .. cpp:function:: bool operator==(const PointGFp& other) const
 
       Point equality. This compares the affine representations.
 
-   .. cpp:function:: void add(const EC_Point& other, std::vector<BigInt>& workspace)
+   .. cpp:function:: void add(const PointGFp& other, std::vector<BigInt>& workspace)
 
       Point addition, taking a workspace.
 
-   .. cpp:function:: void add_affine(const EC_Point& other, std::vector<BigInt>& workspace)
+   .. cpp:function:: void add_affine(const PointGFp& other, std::vector<BigInt>& workspace)
 
       Mixed (Jacobian+affine) addition, taking a workspace.
 
@@ -268,15 +268,15 @@ during common operations.
 
       Repeated point doubling.
 
-   .. cpp:function:: EC_Point plus(const EC_Point& other, std::vector<BigInt>& workspace) const
+   .. cpp:function:: PointGFp plus(const PointGFp& other, std::vector<BigInt>& workspace) const
 
       Point addition, returning the result.
 
-   .. cpp:function:: EC_Point double_of(std::vector<BigInt>& workspace) const
+   .. cpp:function:: PointGFp double_of(std::vector<BigInt>& workspace) const
 
       Point doubling, returning the result.
 
-   .. cpp:function:: EC_Point zero() const
+   .. cpp:function:: PointGFp zero() const
 
       Return the point at infinity
 
diff --git a/doc/dev_ref/fuzzing.rst b/doc/dev_ref/fuzzing.rst
index 888274a69..46e60fb53 100644
--- a/doc/dev_ref/fuzzing.rst
+++ b/doc/dev_ref/fuzzing.rst
@@ -19,7 +19,7 @@ need to compile libFuzzer::
 Then build the fuzzers::
 
   $ ./configure.py --cc=clang --build-fuzzer=libfuzzer --unsafe-fuzzer-mode \
-        --with-debug-info --enable-sanitizers=coverage,address,undefined
+        --enable-sanitizers=coverage,address,undefined
   $ make fuzzers
 
 Enabling 'coverage' sanitizer flags is required for libFuzzer to work.
diff --git a/doc/side_channels.rst b/doc/side_channels.rst
index 1ed5fe4d6..c394e5633 100644
--- a/doc/side_channels.rst
+++ b/doc/side_channels.rst
@@ -154,17 +154,17 @@ ECC point decoding
 The API function OS2ECP, which is used to convert byte strings to ECC points,
 verifies that all points satisfy the ECC curve equation. Points that do not
 satisfy the equation are invalid, and can sometimes be used to break
-protocols ([InvalidCurve] [InvalidCurveTLS]). See ec_point.cpp.
+protocols ([InvalidCurve] [InvalidCurveTLS]). See point_gfp.cpp.
 
 ECC scalar multiply
 ----------------------
 
 There are several different implementations of ECC scalar multiplications which
-depend on the API invoked. This include ``EC_Point::operator*``,
+depend on the API invoked. This include ``PointGFp::operator*``,
 ``EC_Group::blinded_base_point_multiply`` and
 ``EC_Group::blinded_var_point_multiply``.
 
-The ``EC_Point::operator*`` implementation uses the Montgomery ladder, which is
+The ``PointGFp::operator*`` implementation uses the Montgomery ladder, which is
 fairly resistant to side channels. However it leaks the size of the scalar,
 because the loop iterations are bounded by the scalar size. It should not be
 used in cases when the scalar is a secret.
@@ -200,7 +200,7 @@ points. The table of precomputed multiples is accessed using a masked lookup
 which should not leak information about the secret scalar to an attacker who can
 mount a cache-based side channel attack.
 
-See ec_point.cpp and point_mul.cpp in src/lib/pubkey/ec_group
+See point_gfp.cpp and point_mul.cpp
 
 ECDH
 ----------------------
diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in
index 9fa9a4bb3..67963b20e 100644
--- a/src/build-data/buildh.in
+++ b/src/build-data/buildh.in
@@ -54,14 +54,13 @@
 #define BOTAN_MP_WORD_BITS %{mp_bits}
 
 %{if fuzzer_mode}
-/** Disables certain validation checks to ease fuzzability of the library
+/** Disables certain validation checks to easy fuzzability of the library
  * @warning This causes the library build to be insecure, hence, it must not be
  *          used in a production environment!
  */
 #define BOTAN_UNSAFE_FUZZER_MODE
 %{endif}
 %{if fuzzer_type}
-#define BOTAN_FUZZERS_ARE_BEING_BUILT
 #define BOTAN_FUZZER_IS_%{fuzzer_type}
 %{endif}
 
diff --git a/src/cli/speed.cpp b/src/cli/speed.cpp
index 2fa7cf374..b2c22326e 100644
--- a/src/cli/speed.cpp
+++ b/src/cli/speed.cpp
@@ -1139,14 +1139,14 @@ class Speed final : public Command
             auto addf_timer = make_timer(group_name + " addf");
             auto dbl_timer = make_timer(group_name + " dbl");
 
-            const Botan::EC_Point& base_point = ec_group.get_base_point();
+            const Botan::PointGFp& base_point = ec_group.get_base_point();
 
             // create a non-affine point
             const auto random_k = Botan::BigInt::from_u64(0x4E6F537465707E);
-            Botan::EC_Point non_affine_pt = ec_group.get_base_point() * random_k;
-            Botan::EC_Point pt = ec_group.get_base_point();
+            Botan::PointGFp non_affine_pt = ec_group.get_base_point() * random_k;
+            Botan::PointGFp pt = ec_group.get_base_point();
 
-            std::vector<Botan::BigInt> ws(Botan::EC_Point::WORKSPACE_SIZE);
+            std::vector<Botan::BigInt> ws(Botan::PointGFp::WORKSPACE_SIZE);
 
             while(add_timer->under(runtime) && addf_timer->under(runtime) && dbl_timer->under(runtime))
                {
@@ -1187,7 +1187,7 @@ class Speed final : public Command
             auto blinded_mult_timer = make_timer(group_name + " blinded comb");
             auto blinded_var_mult_timer = make_timer(group_name + " blinded window");
 
-            const Botan::EC_Point& base_point = ec_group.get_base_point();
+            const Botan::PointGFp& base_point = ec_group.get_base_point();
 
             std::vector<Botan::BigInt> ws;
 
@@ -1197,12 +1197,12 @@ class Speed final : public Command
                {
                const Botan::BigInt scalar(rng(), ec_group.get_p_bits());
 
-               const Botan::EC_Point r1 = mult_timer->run([&]() { return base_point * scalar; });
+               const Botan::PointGFp r1 = mult_timer->run([&]() { return base_point * scalar; });
 
-               const Botan::EC_Point r2 = blinded_mult_timer->run(
+               const Botan::PointGFp r2 = blinded_mult_timer->run(
                   [&]() { return ec_group.blinded_base_point_multiply(scalar, rng(), ws); });
 
-               const Botan::EC_Point r3 = blinded_var_mult_timer->run(
+               const Botan::PointGFp r3 = blinded_var_mult_timer->run(
                   [&]() { return ec_group.blinded_var_point_multiply(base_point, scalar, rng(), ws); });
 
                BOTAN_ASSERT_EQUAL(r1, r2, "Same point computed by Montgomery and comb");
@@ -1227,9 +1227,9 @@ class Speed final : public Command
             while(uncmp_timer->under(runtime) && cmp_timer->under(runtime))
                {
                const Botan::BigInt k(rng(), 256);
-               const Botan::EC_Point p = ec_group.get_base_point() * k;
-               const std::vector<uint8_t> os_cmp = p.encode(Botan::EC_Point::COMPRESSED);
-               const std::vector<uint8_t> os_uncmp = p.encode(Botan::EC_Point::UNCOMPRESSED);
+               const Botan::PointGFp p = ec_group.get_base_point() * k;
+               const std::vector<uint8_t> os_cmp = p.encode(Botan::PointGFp::COMPRESSED);
+               const std::vector<uint8_t> os_uncmp = p.encode(Botan::PointGFp::UNCOMPRESSED);
 
                uncmp_timer->run([&]() { ec_group.OS2ECP(os_uncmp); });
                cmp_timer->run([&]() { ec_group.OS2ECP(os_cmp); });
@@ -1258,13 +1258,13 @@ class Speed final : public Command
 
                rng().randomize(input.data(), input.size());
 
-               const Botan::EC_Point p1 = h2c_ro_timer->run([&]() {
+               const Botan::PointGFp p1 = h2c_ro_timer->run([&]() {
                   return group.hash_to_curve("SHA-256", input.data(), input.size(), nullptr, 0, true);
                   });
 
                BOTAN_ASSERT_NOMSG(p1.on_the_curve());
 
-               const Botan::EC_Point p2 = h2c_nu_timer->run([&]() {
+               const Botan::PointGFp p2 = h2c_nu_timer->run([&]() {
                   return group.hash_to_curve("SHA-256", input.data(), input.size(), nullptr, 0, false);
                   });
 
diff --git a/src/examples/pkcs11_ecdh.cpp b/src/examples/pkcs11_ecdh.cpp
index b5cb84259..52c551ef5 100644
--- a/src/examples/pkcs11_ecdh.cpp
+++ b/src/examples/pkcs11_ecdh.cpp
@@ -55,7 +55,7 @@ int main() {
   // set import properties
   std::vector<uint8_t> ec_point;
   Botan::DER_Encoder(ec_point).encode(
-      priv_key_sw.public_point().encode(Botan::EC_Point::Compression_Type::UNCOMPRESSED),
+      priv_key_sw.public_point().encode(Botan::PointGFp::Compression_Type::UNCOMPRESSED),
       Botan::ASN1_Type::OctetString);
   Botan::PKCS11::EC_PublicKeyImportProperties pub_import_props(priv_key_sw.DER_domain(), ec_point);
 
@@ -107,10 +107,10 @@ int main() {
   Botan::PK_Key_Agreement kb(key_pair_other.second, rng, "Raw", "pkcs11");
 
   Botan::SymmetricKey alice_key =
-      ka.derive_key(32, key_pair_other.first.public_point().encode(Botan::EC_Point::UNCOMPRESSED));
+      ka.derive_key(32, key_pair_other.first.public_point().encode(Botan::PointGFp::UNCOMPRESSED));
 
   Botan::SymmetricKey bob_key =
-      kb.derive_key(32, key_pair.first.public_point().encode(Botan::EC_Point::UNCOMPRESSED));
+      kb.derive_key(32, key_pair.first.public_point().encode(Botan::PointGFp::UNCOMPRESSED));
 
   bool eq = alice_key == bob_key;
 
diff --git a/src/examples/pkcs11_ecdsa.cpp b/src/examples/pkcs11_ecdsa.cpp
index 45aa92d03..c93dd6f9d 100644
--- a/src/examples/pkcs11_ecdsa.cpp
+++ b/src/examples/pkcs11_ecdsa.cpp
@@ -54,7 +54,7 @@ int main() {
   // import to card
   std::vector<uint8_t> ec_point;
   Botan::DER_Encoder(ec_point).encode(
-      priv_key_sw.public_point().encode(Botan::EC_Point::Compression_Type::UNCOMPRESSED),
+      priv_key_sw.public_point().encode(Botan::PointGFp::Compression_Type::UNCOMPRESSED),
       Botan::ASN1_Type::OctetString);
   Botan::PKCS11::EC_PublicKeyImportProperties pub_import_props(priv_key_sw.DER_domain(), ec_point);
 
diff --git a/src/fuzzer/ecc_helper.h b/src/fuzzer/ecc_helper.h
index 9623ddf92..9d9f881b1 100644
--- a/src/fuzzer/ecc_helper.h
+++ b/src/fuzzer/ecc_helper.h
@@ -14,7 +14,7 @@
 
 namespace {
 
-inline std::ostream& operator<<(std::ostream& o, const Botan::EC_Point& point)
+inline std::ostream& operator<<(std::ostream& o, const Botan::PointGFp& point)
    {
    o << point.get_affine_x() << "," << point.get_affine_y();
    return o;
@@ -48,40 +48,40 @@ void check_ecc_math(const Botan::EC_Group& group,
                     const uint8_t in[], size_t len)
    {
    // These depend only on the group, which is also static
-   static const Botan::EC_Point base_point = group.get_base_point();
+   static const Botan::PointGFp base_point = group.get_base_point();
 
    // This is shared across runs to reduce overhead
-   static std::vector<Botan::BigInt> ws(Botan::EC_Point::WORKSPACE_SIZE);
+   static std::vector<Botan::BigInt> ws(Botan::PointGFp::WORKSPACE_SIZE);
 
    const size_t hlen = len / 2;
    const Botan::BigInt a = Botan::BigInt::decode(in, hlen);
    const Botan::BigInt b = Botan::BigInt::decode(in + hlen, len - hlen);
    const Botan::BigInt c = a + b;
 
-   const Botan::EC_Point P1 = base_point * a;
-   const Botan::EC_Point Q1 = base_point * b;
-   const Botan::EC_Point R1 = base_point * c;
+   const Botan::PointGFp P1 = base_point * a;
+   const Botan::PointGFp Q1 = base_point * b;
+   const Botan::PointGFp R1 = base_point * c;
 
-   const Botan::EC_Point S1 = P1 + Q1;
-   const Botan::EC_Point T1 = Q1 + P1;
+   const Botan::PointGFp S1 = P1 + Q1;
+   const Botan::PointGFp T1 = Q1 + P1;
 
    FUZZER_ASSERT_EQUAL(S1, R1);
    FUZZER_ASSERT_EQUAL(T1, R1);
 
-   const Botan::EC_Point P2 = group.blinded_base_point_multiply(a, fuzzer_rng(), ws);
-   const Botan::EC_Point Q2 = group.blinded_base_point_multiply(b, fuzzer_rng(), ws);
-   const Botan::EC_Point R2 = group.blinded_base_point_multiply(c, fuzzer_rng(), ws);
-   const Botan::EC_Point S2 = P2 + Q2;
-   const Botan::EC_Point T2 = Q2 + P2;
+   const Botan::PointGFp P2 = group.blinded_base_point_multiply(a, fuzzer_rng(), ws);
+   const Botan::PointGFp Q2 = group.blinded_base_point_multiply(b, fuzzer_rng(), ws);
+   const Botan::PointGFp R2 = group.blinded_base_point_multiply(c, fuzzer_rng(), ws);
+   const Botan::PointGFp S2 = P2 + Q2;
+   const Botan::PointGFp T2 = Q2 + P2;
 
    FUZZER_ASSERT_EQUAL(S2, R2);
    FUZZER_ASSERT_EQUAL(T2, R2);
 
-   const Botan::EC_Point P3 = group.blinded_var_point_multiply(base_point, a, fuzzer_rng(), ws);
-   const Botan::EC_Point Q3 = group.blinded_var_point_multiply(base_point, b, fuzzer_rng(), ws);
-   const Botan::EC_Point R3 = group.blinded_var_point_multiply(base_point, c, fuzzer_rng(), ws);
-   const Botan::EC_Point S3 = P3 + Q3;
-   const Botan::EC_Point T3 = Q3 + P3;
+   const Botan::PointGFp P3 = group.blinded_var_point_multiply(base_point, a, fuzzer_rng(), ws);
+   const Botan::PointGFp Q3 = group.blinded_var_point_multiply(base_point, b, fuzzer_rng(), ws);
+   const Botan::PointGFp R3 = group.blinded_var_point_multiply(base_point, c, fuzzer_rng(), ws);
+   const Botan::PointGFp S3 = P3 + Q3;
+   const Botan::PointGFp T3 = Q3 + P3;
 
    FUZZER_ASSERT_EQUAL(S3, R3);
    FUZZER_ASSERT_EQUAL(T3, R3);
diff --git a/src/fuzzer/fuzzers.h b/src/fuzzer/fuzzers.h
index 9bdf5b114..1df6e94c9 100644
--- a/src/fuzzer/fuzzers.h
+++ b/src/fuzzer/fuzzers.h
@@ -50,11 +50,11 @@ inline Botan::RandomNumberGenerator& fuzzer_rng()
    }
 
 #define FUZZER_WRITE_AND_CRASH(expr) \
-   do { std::cerr << expr << " @ Line " << __LINE__ << " in " << __FILE__ << "\n"; abort(); } while(0)
+   do { std::cerr << expr; abort(); } while(0)
 
 #define FUZZER_ASSERT_EQUAL(x, y) do {                                  \
    if(x != y) {                                                         \
-      FUZZER_WRITE_AND_CRASH(#x << " = " << x << " != "                \
+      FUZZER_WRITE_AND_CRASH(#x << " = " << x << " !=\n"                \
                              << #y << " = " << y << "\n");              \
    } } while(0)
 
diff --git a/src/fuzzer/mp_comba_mul.cpp b/src/fuzzer/mp_comba_mul.cpp
deleted file mode 100644
index 2da8a4162..000000000
--- a/src/fuzzer/mp_comba_mul.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-* (C) 2023 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include "mp_fuzzers.h"
-
-void fuzz(const uint8_t in[], size_t in_len)
-   {
-   const size_t words = (in_len + sizeof(word) - 1) / sizeof(word);
-
-   if(in_len == 0 || words > 2*16)
-      return;
-
-   word x[24] = { 0 };
-   word y[24] = { 0 };
-
-   std::memcpy(x, in, in_len / 2);
-   std::memcpy(y, in + in_len / 2, in_len - (in_len / 2));
-
-   const size_t x_words = ((in_len / 2) + sizeof(word) - 1) / sizeof(word);
-   const size_t y_words = ((in_len - (in_len / 2)) + sizeof(word) - 1) / sizeof(word);
-
-   word z4[2*4] = { 0 };
-   word z6[2*6] = { 0 };
-   word z8[2*8] = { 0 };
-   word z9[2*9] = { 0 };
-   word z16[2*16] = { 0 };
-   word z24[2*24] = { 0 };
-
-   word z_ref[2*24] = { 0 };
-
-   Botan::basecase_mul(z_ref, 2*24, x, x_words, y, y_words);
-
-   if(words <= 8)
-      Botan::bigint_comba_mul4(z4, x, y);
-   if(words <= 12)
-      Botan::bigint_comba_mul6(z6, x, y);
-   if(words <= 16)
-      Botan::bigint_comba_mul8(z8, x, y);
-   if(words <= 18)
-      Botan::bigint_comba_mul9(z9, x, y);
-   if(words <= 32)
-      Botan::bigint_comba_mul16(z16, x, y);
-   if(words <= 48)
-      Botan::bigint_comba_mul24(z24, x, y);
-
-   if(words <= 8)
-      compare_word_vec(z4, 2*4, z6, 2*6, "mul4 vs mul6");
-   if(words <= 12)
-      compare_word_vec(z6, 2*6, z8, 2*8, "mul6 vs mul8");
-   if(words <= 16)
-      compare_word_vec(z8, 2*8, z9, 2*9, "mul8 vs mul9");
-   if(words <= 18)
-      compare_word_vec(z9, 2*9, z16, 2*16, "mul9 vs mul16");
-   if(words <= 32)
-      compare_word_vec(z16, 2*16, z24, 2*24, "mul16 vs mul24");
-
-   compare_word_vec(z24, 2*24, z_ref, 2*24, "mul24 vs basecase mul");
-   }
diff --git a/src/fuzzer/mp_comba_sqr.cpp b/src/fuzzer/mp_comba_sqr.cpp
deleted file mode 100644
index 13b4a9a57..000000000
--- a/src/fuzzer/mp_comba_sqr.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-* (C) 2023 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include "mp_fuzzers.h"
-
-void fuzz(const uint8_t in[], size_t in_len)
-   {
-   const size_t words = (in_len + sizeof(word) - 1) / sizeof(word);
-
-   if(in_len == 0 || words > 24)
-      return;
-
-   word x[24] = { 0 };
-
-   std::memcpy(x, in, in_len);
-
-   word z4[2*4] = { 0 };
-   word z6[2*6] = { 0 };
-   word z8[2*8] = { 0 };
-   word z9[2*9] = { 0 };
-   word z16[2*16] = { 0 };
-   word z24[2*24] = { 0 };
-
-   word z_ref[2*24] = { 0 };
-
-   //dump_word_vec("x", x, words);
-
-   Botan::basecase_sqr(z_ref, 2*24, x, words);
-
-   if(words <= 4)
-      {
-      Botan::bigint_comba_sqr4(z4, x);
-      word z4m[2*4] = { 0 };
-      Botan::bigint_comba_mul4(z4m, x, x);
-      compare_word_vec(z4m, 2*4, z4, 2*4, "sqr4 vs mul4");
-      }
-   if(words <= 6)
-      {
-      Botan::bigint_comba_sqr6(z6, x);
-      word z6m[2*6] = { 0 };
-      Botan::bigint_comba_mul6(z6m, x, x);
-      compare_word_vec(z6m, 2*6, z6, 2*6, "sqr6 vs mul6");
-      }
-   if(words <= 8)
-      {
-      Botan::bigint_comba_sqr8(z8, x);
-      word z8m[2*8] = { 0 };
-      Botan::bigint_comba_mul8(z8m, x, x);
-      compare_word_vec(z8m, 2*8, z8, 2*8, "sqr8 vs mul8");
-      }
-   if(words <= 9)
-      {
-      Botan::bigint_comba_sqr9(z9, x);
-      word z9m[2*9] = { 0 };
-      Botan::bigint_comba_mul9(z9m, x, x);
-      compare_word_vec(z9m, 2*9, z9, 2*9, "sqr9 vs mul9");
-      }
-   if(words <= 16)
-      {
-      Botan::bigint_comba_sqr16(z16, x);
-      word z16m[2*16] = { 0 };
-      Botan::bigint_comba_mul16(z16m, x, x);
-      compare_word_vec(z16m, 2*16, z16, 2*16, "sqr16 vs mul16");
-      }
-   if(words <= 24)
-      {
-      Botan::bigint_comba_sqr24(z24, x);
-      word z24m[2*24] = { 0 };
-      Botan::bigint_comba_mul24(z24m, x, x);
-      compare_word_vec(z24m, 2*24, z24, 2*24, "sqr24 vs mul24");
-      }
-
-   if(words <= 4)
-      compare_word_vec(z4, 2*4, z6, 2*6, "sqr4 vs sqr6");
-   if(words <= 6)
-      compare_word_vec(z6, 2*6, z8, 2*8, "sqr6 vs sqr8");
-   if(words <= 8)
-      compare_word_vec(z8, 2*8, z9, 2*9, "sqr8 vs sqr9");
-   if(words <= 9)
-      compare_word_vec(z9, 2*9, z16, 2*16, "sqr9 vs sqr16");
-   if(words <= 16)
-      compare_word_vec(z16, 2*16, z24, 2*24, "sqr16 vs sqr24");
-
-   compare_word_vec(z24, 2*24, z_ref, 2*24, "sqr24 vs basecase sqr");
-   }
diff --git a/src/fuzzer/mp_fuzzers.h b/src/fuzzer/mp_fuzzers.h
deleted file mode 100644
index e1cd80b5d..000000000
--- a/src/fuzzer/mp_fuzzers.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-* (C) 2023 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_FUZZER_MP_HELPERS_H_
-#define BOTAN_FUZZER_MP_HELPERS_H_
-
-#include "fuzzers.h"
-#include <botan/internal/mp_core.h>
-
-#if BOTAN_MP_WORD_BITS == 64
-  #define WORD_FORMAT_STRING "%016lX"
-#else
-  #define WORD_FORMAT_STRING "%08X"
-#endif
-
-using Botan::word;
-
-namespace {
-
-void dump_word_vec(const char* name, const word x[], size_t x_len)
-   {
-   fprintf(stderr, "%s = ", name);
-   for(size_t i = 0; i != x_len; ++i)
-      {
-      fprintf(stderr, WORD_FORMAT_STRING, x[i]);
-      fprintf(stderr, " ");
-      }
-   fprintf(stderr, "\n");
-   }
-
-void compare_word_vec(const word x[], size_t x_len,
-                      const word y[], size_t y_len,
-                      const char* comparing)
-   {
-   const size_t common_words = std::min(x_len, y_len);
-
-   for(size_t i = 0; i != common_words; ++i)
-      {
-      if(x[i] != y[i])
-         {
-         dump_word_vec("x", x, x_len);
-         dump_word_vec("y", y, y_len);
-         FUZZER_WRITE_AND_CRASH("Comparison failed " << comparing);
-         }
-      }
-
-   // all other words must be zero
-   for(size_t i = common_words; i != x_len; ++i)
-      {
-      if(x[i] != 0)
-         {
-         dump_word_vec("x", x, x_len);
-         dump_word_vec("y", y, y_len);
-         FUZZER_WRITE_AND_CRASH("Unexpected non-zero in high words of x " << comparing);
-         }
-      }
-   for(size_t i = common_words; i != y_len; ++i)
-      {
-      if(y[i] != 0)
-         {
-         dump_word_vec("x", x, x_len);
-         dump_word_vec("y", y, y_len);
-         FUZZER_WRITE_AND_CRASH("Unexpected non-zero in high words of y " << comparing);
-         }
-      }
-   }
-
-}
-
-#endif
diff --git a/src/fuzzer/mp_redc.cpp b/src/fuzzer/mp_redc.cpp
deleted file mode 100644
index ae0c68bd7..000000000
--- a/src/fuzzer/mp_redc.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-* (C) 2023 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include "mp_fuzzers.h"
-
-namespace {
-
-template<size_t N>
-void fuzz_mp_redc(const uint8_t in[], size_t in_len)
-   {
-   FUZZER_ASSERT_EQUAL(in_len, (N*3 + 1)*sizeof(word));
-
-   word z[2*N] = { 0 };
-
-   word z_script[2*N] = { 0 };
-   word z_ref[2*N] = { 0 };
-   word p[N] = { 0 };
-   word p_dash = 0;
-
-   word ws[2*(N + 1)] = { 0 };
-
-   std::memcpy(z, in, sizeof(z));
-   std::memcpy(p, in + sizeof(z), sizeof(p));
-   std::memcpy(&p_dash, in + sizeof(z) + sizeof(p), sizeof(p_dash));
-
-   for(size_t i = 0; i != 2*N; ++i)
-      z_script[i] = z_ref[i] = z[i];
-
-   if(N == 4)
-      Botan::bigint_monty_redc_4(z_script, p, p_dash, ws);
-   else if(N == 6)
-      Botan::bigint_monty_redc_6(z_script, p, p_dash, ws);
-   else if(N == 8)
-      Botan::bigint_monty_redc_8(z_script, p, p_dash, ws);
-   else if(N == 16)
-      Botan::bigint_monty_redc_16(z_script, p, p_dash, ws);
-   else if(N == 24)
-      Botan::bigint_monty_redc_24(z_script, p, p_dash, ws);
-   else if(N == 32)
-      Botan::bigint_monty_redc_32(z_script, p, p_dash, ws);
-   else
-      std::abort();
-
-   Botan::bigint_monty_redc_generic(z_ref, 2*N, p, N, p_dash, ws);
-
-   for(size_t i = 0; i != 2*N; ++i)
-      {
-      if(z_script[i] != z_ref[i])
-         {
-         dump_word_vec("input", z, 2*N);
-         dump_word_vec("z_script", z_script, 2*N);
-         dump_word_vec("z_ref", z_ref, 2*N);
-         dump_word_vec("p", p, N);
-         dump_word_vec("p_dash", &p_dash, 1);
-         std::abort();
-         }
-      }
-   compare_word_vec(z_script, 2*N, z_ref, 2*N, "redc generic vs specialized");
-   }
-
-}
-
-void fuzz(const uint8_t in[], size_t len)
-   {
-   if(len == 0 || len % sizeof(word) != 0)
-      return;
-
-   const size_t words = len / sizeof(word);
-
-   switch(words)
-      {
-      case 4*3+1: return fuzz_mp_redc<4>(in, len);
-      case 6*3+1: return fuzz_mp_redc<6>(in, len);
-      case 8*3+1: return fuzz_mp_redc<8>(in, len);
-      case 16*3+1: return fuzz_mp_redc<16>(in, len);
-      case 24*3+1: return fuzz_mp_redc<24>(in, len);
-      case 32*3+1: return fuzz_mp_redc<32>(in, len);
-      }
-   }
diff --git a/src/fuzzer/os2ecp.cpp b/src/fuzzer/os2ecp.cpp
index 029ba4f6f..cb4a50b47 100644
--- a/src/fuzzer/os2ecp.cpp
+++ b/src/fuzzer/os2ecp.cpp
@@ -5,7 +5,7 @@
 */
 #include "fuzzers.h"
 #include <botan/ec_group.h>
-#include <botan/ec_point.h>
+#include <botan/point_gfp.h>
 
 namespace {
 
@@ -13,7 +13,7 @@ void check_os2ecp(const Botan::EC_Group& group, const uint8_t in[], size_t len)
    {
    try
       {
-      Botan::EC_Point point = group.OS2ECP(in, len);
+      Botan::PointGFp point = group.OS2ECP(in, len);
       }
    catch(Botan::Exception& e) {}
    }
diff --git a/src/lib/ffi/ffi_pkey_algs.cpp b/src/lib/ffi/ffi_pkey_algs.cpp
index b8e3662f2..3fd773168 100644
--- a/src/lib/ffi/ffi_pkey_algs.cpp
+++ b/src/lib/ffi/ffi_pkey_algs.cpp
@@ -93,7 +93,7 @@ int pubkey_load_ec(std::unique_ptr<ECPublicKey_t>& key,
       return BOTAN_FFI_ERROR_NULL_POINTER;
 
    Botan::EC_Group grp(curve_name);
-   Botan::EC_Point uncompressed_point = grp.point(public_x, public_y);
+   Botan::PointGFp uncompressed_point = grp.point(public_x, public_y);
    key.reset(new ECPublicKey_t(grp, uncompressed_point));
    return BOTAN_FFI_SUCCESS;
    }
diff --git a/src/lib/filters/threaded_fork.cpp b/src/lib/filters/threaded_fork.cpp
index 16206bfa2..07b2805ff 100644
--- a/src/lib/filters/threaded_fork.cpp
+++ b/src/lib/filters/threaded_fork.cpp
@@ -10,19 +10,20 @@
 
 #if defined(BOTAN_HAS_THREAD_UTILS)
 
-#include <botan/internal/semaphore.h>
 #include <botan/internal/barrier.h>
 #include <functional>
+#include <semaphore>
 
 namespace Botan {
 
 struct Threaded_Fork_Data
    {
+   static constexpr size_t max_filters = 1024;
    /*
    * Semaphore for indicating that there is work to be done (or to
    * quit)
    */
-   Semaphore m_input_ready_semaphore;
+   std::counting_semaphore<max_filters> m_input_ready_semaphore{0};
 
    /*
    * Synchronises all threads to complete processing data in lock-step.
@@ -60,6 +61,10 @@ Threaded_Fork::Threaded_Fork(Filter* filters[], size_t count) :
    Fork(nullptr, static_cast<size_t>(0)),
    m_thread_data(new Threaded_Fork_Data)
    {
+   if (count > Threaded_Fork_Data::max_filters)
+      {
+      throw Invalid_Argument("count exceeds the max filters supported");
+      }
    set_next(filters, count);
    }
 
diff --git a/src/lib/math/mp/mp_core.h b/src/lib/math/mp/mp_core.h
index de3f6d670..5c8ce1e95 100644
--- a/src/lib/math/mp/mp_core.h
+++ b/src/lib/math/mp/mp_core.h
@@ -275,7 +275,7 @@ inline word bigint_add3_nc(word z[],
 * @param x the first operand (and output)
 * @param x_size size of x
 * @param y the second operand
-* @param y_size size of y (must be <= x_size)
+* @param y_size size of y (must be >= x_size)
 */
 inline void bigint_add2(word x[], size_t x_size,
                         const word y[], size_t y_size)
@@ -338,10 +338,6 @@ inline void bigint_sub2_rev(word x[], const word y[], size_t y_size)
 
 /**
 * Three operand subtraction
-*
-* Expects that x_size >= y_size
-*
-* Writes to z[0:x_size] and returns borrow
 */
 inline word bigint_sub3(word z[],
                         const word x[], size_t x_size,
@@ -774,36 +770,35 @@ inline word bigint_modop(word n1, word n0, word d)
 /*
 * Comba Multiplication / Squaring
 */
-BOTAN_FUZZER_API void bigint_comba_mul4(word z[8], const word x[4], const word y[4]);
-BOTAN_FUZZER_API void bigint_comba_mul6(word z[12], const word x[6], const word y[6]);
-BOTAN_FUZZER_API void bigint_comba_mul8(word z[16], const word x[8], const word y[8]);
-BOTAN_FUZZER_API void bigint_comba_mul9(word z[18], const word x[9], const word y[9]);
-BOTAN_FUZZER_API void bigint_comba_mul16(word z[32], const word x[16], const word y[16]);
-BOTAN_FUZZER_API void bigint_comba_mul24(word z[48], const word x[24], const word y[24]);
-
-BOTAN_FUZZER_API void bigint_comba_sqr4(word out[8], const word in[4]);
-BOTAN_FUZZER_API void bigint_comba_sqr6(word out[12], const word in[6]);
-BOTAN_FUZZER_API void bigint_comba_sqr8(word out[16], const word in[8]);
-BOTAN_FUZZER_API void bigint_comba_sqr9(word out[18], const word in[9]);
-BOTAN_FUZZER_API void bigint_comba_sqr16(word out[32], const word in[16]);
-BOTAN_FUZZER_API void bigint_comba_sqr24(word out[48], const word in[24]);
+void bigint_comba_mul4(word z[8], const word x[4], const word y[4]);
+void bigint_comba_mul6(word z[12], const word x[6], const word y[6]);
+void bigint_comba_mul8(word z[16], const word x[8], const word y[8]);
+void bigint_comba_mul9(word z[18], const word x[9], const word y[9]);
+void bigint_comba_mul16(word z[32], const word x[16], const word y[16]);
+void bigint_comba_mul24(word z[48], const word x[24], const word y[24]);
+
+void bigint_comba_sqr4(word out[8], const word in[4]);
+void bigint_comba_sqr6(word out[12], const word in[6]);
+void bigint_comba_sqr8(word out[16], const word in[8]);
+void bigint_comba_sqr9(word out[18], const word in[9]);
+void bigint_comba_sqr16(word out[32], const word in[16]);
+void bigint_comba_sqr24(word out[48], const word in[24]);
 
 /*
 * Montgomery reduction
 *
 * Each of these functions makes the following assumptions:
 *
-* z_size == 2*p_size
-* ws_size >= p_size + 1
+* z_size >= 2*(p_size + 1)
+* ws_size >= z_size
 */
-BOTAN_FUZZER_API void bigint_monty_redc_4(word z[8], const word p[4], word p_dash, word ws[]);
-BOTAN_FUZZER_API void bigint_monty_redc_6(word z[12], const word p[6], word p_dash, word ws[]);
-BOTAN_FUZZER_API void bigint_monty_redc_8(word z[16], const word p[8], word p_dash, word ws[]);
-BOTAN_FUZZER_API void bigint_monty_redc_16(word z[32], const word p[16], word p_dash, word ws[]);
-BOTAN_FUZZER_API void bigint_monty_redc_24(word z[48], const word p[24], word p_dash, word ws[]);
-BOTAN_FUZZER_API void bigint_monty_redc_32(word z[64], const word p[32], word p_dash, word ws[]);
-
-BOTAN_FUZZER_API
+void bigint_monty_redc_4(word z[], const word p[4], word p_dash, word ws[]);
+void bigint_monty_redc_6(word z[], const word p[6], word p_dash, word ws[]);
+void bigint_monty_redc_8(word z[], const word p[8], word p_dash, word ws[]);
+void bigint_monty_redc_16(word z[], const word p[16], word p_dash, word ws[]);
+void bigint_monty_redc_24(word z[], const word p[24], word p_dash, word ws[]);
+void bigint_monty_redc_32(word z[], const word p[32], word p_dash, word ws[]);
+
 void bigint_monty_redc_generic(word z[], size_t z_size,
                                const word p[], size_t p_size, word p_dash,
                                word ws[]);
@@ -811,13 +806,13 @@ void bigint_monty_redc_generic(word z[], size_t z_size,
 
 /**
 * Montgomery Reduction
-* @param z integer to reduce, of size exactly 2*p_size.
+* @param z integer to reduce, of size exactly 2*(p_size+1).
            Output is in the first p_size+1 words, higher
            words are set to zero.
 * @param p modulus
 * @param p_size size of p
 * @param p_dash Montgomery value
-* @param ws array of at least p_size+1 words
+* @param ws array of at least 2*(p_size+1) words
 * @param ws_size size of ws in words
 */
 inline void bigint_monty_redc(word z[],
@@ -826,10 +821,9 @@ inline void bigint_monty_redc(word z[],
                               word ws[],
                               size_t ws_size)
    {
-   const size_t z_size = 2*p_size;
+   const size_t z_size = 2*(p_size+1);
 
-   BOTAN_ARG_CHECK(ws_size >= p_size + 1,
-                   "Montgomery workspace too small");
+   BOTAN_ARG_CHECK(ws_size >= z_size, "ws too small");
 
    if(p_size == 4)
       bigint_monty_redc_4(z, p, p_dash, ws);
@@ -847,25 +841,11 @@ inline void bigint_monty_redc(word z[],
       bigint_monty_redc_generic(z, z_size, p, p_size, p_dash, ws);
    }
 
-/**
-* Basecase O(N^2) multiplication
-*/
-BOTAN_FUZZER_API
-void basecase_mul(word z[], size_t z_size,
-                  const word x[], size_t x_size,
-                  const word y[], size_t y_size);
-
-/**
-* Basecase O(N^2) squaring
-*/
-BOTAN_FUZZER_API
-void basecase_sqr(word z[], size_t z_size,
-                  const word x[], size_t x_size);
-
 
 /*
 * High Level Multiplication/Squaring Interfaces
 */
+
 void bigint_mul(word z[], size_t z_size,
                 const word x[], size_t x_size, size_t x_sw,
                 const word y[], size_t y_size, size_t y_sw,
diff --git a/src/lib/math/mp/mp_karat.cpp b/src/lib/math/mp/mp_karat.cpp
index c269e352b..63885db17 100644
--- a/src/lib/math/mp/mp_karat.cpp
+++ b/src/lib/math/mp/mp_karat.cpp
@@ -13,6 +13,11 @@
 
 namespace Botan {
 
+namespace {
+
+const size_t KARATSUBA_MULTIPLY_THRESHOLD = 32;
+const size_t KARATSUBA_SQUARE_THRESHOLD = 32;
+
 /*
 * Simple O(N^2) Multiplication
 */
@@ -69,11 +74,6 @@ void basecase_sqr(word z[], size_t z_size,
       }
    }
 
-namespace {
-
-const size_t KARATSUBA_MULTIPLY_THRESHOLD = 32;
-const size_t KARATSUBA_SQUARE_THRESHOLD = 32;
-
 /*
 * Karatsuba Multiplication Operation
 */
diff --git a/src/lib/math/mp/mp_monty.cpp b/src/lib/math/mp/mp_monty.cpp
index 1aa4cd5fb..69edc1f22 100644
--- a/src/lib/math/mp/mp_monty.cpp
+++ b/src/lib/math/mp/mp_monty.cpp
@@ -11,19 +11,13 @@
 #include <botan/internal/ct_utils.h>
 #include <botan/mem_ops.h>
 #include <botan/exceptn.h>
-#include <botan/assert.h>
 
 namespace Botan {
 
 /*
 * Montgomery reduction - product scanning form
 *
-* Algorithm 5 from "Energy-Efficient Software Implementation of Long
-* Integer Modular Arithmetic"
-* (https://www.iacr.org/archive/ches2005/006.pdf)
-*
-* See also
-*
+* https://www.iacr.org/archive/ches2005/006.pdf
 * https://eprint.iacr.org/2013/882.pdf
 * https://www.microsoft.com/en-us/research/wp-content/uploads/1996/01/j37acmon.pdf
 */
@@ -31,9 +25,6 @@ void bigint_monty_redc_generic(word z[], size_t z_size,
                                const word p[], size_t p_size, word p_dash,
                                word ws[])
    {
-   BOTAN_ARG_CHECK(z_size >= 2*p_size && p_size > 0,
-                   "Invalid sizes for bigint_monty_redc_generic");
-
    word w2 = 0, w1 = 0, w0 = 0;
 
    w0 = z[0];
@@ -64,7 +55,7 @@ void bigint_monty_redc_generic(word z[], size_t z_size,
       w2 = 0;
       }
 
-   for(size_t i = 0; i != p_size - 1; ++i)
+   for(size_t i = 0; i != p_size; ++i)
       {
       for(size_t j = i + 1; j != p_size; ++j)
          {
@@ -74,16 +65,15 @@ void bigint_monty_redc_generic(word z[], size_t z_size,
       word3_add(&w2, &w1, &w0, z[p_size+i]);
 
       ws[i] = w0;
-
       w0 = w1;
       w1 = w2;
       w2 = 0;
       }
 
-   word3_add(&w2, &w1, &w0, z[2*p_size-1]);
+   word3_add(&w2, &w1, &w0, z[z_size-1]);
 
-   ws[p_size-1] = w0;
-   ws[p_size] = w1;
+   ws[p_size] = w0;
+   ws[p_size+1] = w1;
 
    /*
    * The result might need to be reduced mod p. To avoid a timing
@@ -91,22 +81,18 @@ void bigint_monty_redc_generic(word z[], size_t z_size,
    * of x - p a borrow is required then x was already < p.
    *
    * x starts at ws[0] and is p_size+1 bytes long.
-   * x - p starts at z[0] and is also p_size+1 bytes log
-   *
-   * If borrow was set then x was already < p and the subtraction
-   * was not needed. In that case overwrite z[0:p_size] with the
-   * original x in ws[0:p_size].
+   * x - p starts at ws[p_size+1] and is also p_size+1 bytes log
    *
-   * We only copy out p_size in the final step because we know
-   * the Montgomery result is < P
+   * Select which address to copy from indexing off of the final
+   * borrow.
    */
 
-   word borrow = bigint_sub3(z, ws, p_size + 1, p, p_size);
+   word borrow = bigint_sub3(ws + p_size + 1, ws, p_size + 1, p, p_size);
 
    BOTAN_DEBUG_ASSERT(borrow == 0 || borrow == 1);
 
-   CT::conditional_assign_mem(borrow, z, ws, p_size);
-   clear_mem(z + p_size, z_size - p_size);
+   CT::conditional_copy_mem(borrow, z, ws, ws + (p_size + 1), (p_size + 1));
+   clear_mem(z + p_size, z_size - p_size - 2);
    }
 
 }
diff --git a/src/lib/math/mp/mp_monty_n.cpp b/src/lib/math/mp/mp_monty_n.cpp
index 779a80500..d58889112 100644
--- a/src/lib/math/mp/mp_monty_n.cpp
+++ b/src/lib/math/mp/mp_monty_n.cpp
@@ -1,5 +1,5 @@
 /*
-* This file was automatically generated by ./src/scripts/monty.py on 2023-01-05
+* This file was automatically generated by ./src/scripts/monty.py on 2021-05-01
 * All manual changes will be lost. Edit the script instead.
 *
 * Botan is released under the Simplified BSD License (see license.txt)
@@ -10,7 +10,7 @@
 
 namespace Botan {
 
-void bigint_monty_redc_4(word z[8], const word p[4], word p_dash, word ws[])
+void bigint_monty_redc_4(word z[], const word p[4], word p_dash, word ws[])
    {
    word w2 = 0, w1 = 0, w0 = 0;
    w0 = z[0];
@@ -52,13 +52,16 @@ void bigint_monty_redc_4(word z[8], const word p[4], word p_dash, word ws[])
    w0 = w1; w1 = w2; w2 = 0;
    word3_add(&w2, &w1, &w0, z[7]);
    ws[3] = w0;
-   ws[4] = w1;
-   word borrow = bigint_sub3(z, ws, 4 + 1, p, 4);
-   CT::conditional_assign_mem(borrow, z, ws, 4);
-   clear_mem(z + 4, 4);
+   w0 = w1; w1 = w2; w2 = 0;
+   word3_add(&w2, &w1, &w0, z[9]);
+   ws[4] = w0;
+   ws[5] = w1;
+   word borrow = bigint_sub3(ws + 4 + 1, ws, 4 + 1, p, 4);
+   CT::conditional_copy_mem(borrow, z, ws, ws + 5, 5);
+   clear_mem(z + 4, 2*(4+1) - 4);
    }
 
-void bigint_monty_redc_6(word z[12], const word p[6], word p_dash, word ws[])
+void bigint_monty_redc_6(word z[], const word p[6], word p_dash, word ws[])
    {
    word w2 = 0, w1 = 0, w0 = 0;
    w0 = z[0];
@@ -132,13 +135,16 @@ void bigint_monty_redc_6(word z[12], const word p[6], word p_dash, word ws[])
    w0 = w1; w1 = w2; w2 = 0;
    word3_add(&w2, &w1, &w0, z[11]);
    ws[5] = w0;
-   ws[6] = w1;
-   word borrow = bigint_sub3(z, ws, 6 + 1, p, 6);
-   CT::conditional_assign_mem(borrow, z, ws, 6);
-   clear_mem(z + 6, 6);
+   w0 = w1; w1 = w2; w2 = 0;
+   word3_add(&w2, &w1, &w0, z[13]);
+   ws[6] = w0;
+   ws[7] = w1;
+   word borrow = bigint_sub3(ws + 6 + 1, ws, 6 + 1, p, 6);
+   CT::conditional_copy_mem(borrow, z, ws, ws + 7, 7);
+   clear_mem(z + 6, 2*(6+1) - 6);
    }
 
-void bigint_monty_redc_8(word z[16], const word p[8], word p_dash, word ws[])
+void bigint_monty_redc_8(word z[], const word p[8], word p_dash, word ws[])
    {
    word w2 = 0, w1 = 0, w0 = 0;
    w0 = z[0];
@@ -252,13 +258,16 @@ void bigint_monty_redc_8(word z[16], const word p[8], word p_dash, word ws[])
    w0 = w1; w1 = w2; w2 = 0;
    word3_add(&w2, &w1, &w0, z[15]);
    ws[7] = w0;
-   ws[8] = w1;
-   word borrow = bigint_sub3(z, ws, 8 + 1, p, 8);
-   CT::conditional_assign_mem(borrow, z, ws, 8);
-   clear_mem(z + 8, 8);
+   w0 = w1; w1 = w2; w2 = 0;
+   word3_add(&w2, &w1, &w0, z[17]);
+   ws[8] = w0;
+   ws[9] = w1;
+   word borrow = bigint_sub3(ws + 8 + 1, ws, 8 + 1, p, 8);
+   CT::conditional_copy_mem(borrow, z, ws, ws + 9, 9);
+   clear_mem(z + 8, 2*(8+1) - 8);
    }
 
-void bigint_monty_redc_16(word z[32], const word p[16], word p_dash, word ws[])
+void bigint_monty_redc_16(word z[], const word p[16], word p_dash, word ws[])
    {
    word w2 = 0, w1 = 0, w0 = 0;
    w0 = z[0];
@@ -612,13 +621,16 @@ void bigint_monty_redc_16(word z[32], const word p[16], word p_dash, word ws[])
    w0 = w1; w1 = w2; w2 = 0;
    word3_add(&w2, &w1, &w0, z[31]);
    ws[15] = w0;
-   ws[16] = w1;
-   word borrow = bigint_sub3(z, ws, 16 + 1, p, 16);
-   CT::conditional_assign_mem(borrow, z, ws, 16);
-   clear_mem(z + 16, 16);
+   w0 = w1; w1 = w2; w2 = 0;
+   word3_add(&w2, &w1, &w0, z[33]);
+   ws[16] = w0;
+   ws[17] = w1;
+   word borrow = bigint_sub3(ws + 16 + 1, ws, 16 + 1, p, 16);
+   CT::conditional_copy_mem(borrow, z, ws, ws + 17, 17);
+   clear_mem(z + 16, 2*(16+1) - 16);
    }
 
-void bigint_monty_redc_24(word z[48], const word p[24], word p_dash, word ws[])
+void bigint_monty_redc_24(word z[], const word p[24], word p_dash, word ws[])
    {
    word w2 = 0, w1 = 0, w0 = 0;
    w0 = z[0];
@@ -1340,13 +1352,16 @@ void bigint_monty_redc_24(word z[48], const word p[24], word p_dash, word ws[])
    w0 = w1; w1 = w2; w2 = 0;
    word3_add(&w2, &w1, &w0, z[47]);
    ws[23] = w0;
-   ws[24] = w1;
-   word borrow = bigint_sub3(z, ws, 24 + 1, p, 24);
-   CT::conditional_assign_mem(borrow, z, ws, 24);
-   clear_mem(z + 24, 24);
+   w0 = w1; w1 = w2; w2 = 0;
+   word3_add(&w2, &w1, &w0, z[49]);
+   ws[24] = w0;
+   ws[25] = w1;
+   word borrow = bigint_sub3(ws + 24 + 1, ws, 24 + 1, p, 24);
+   CT::conditional_copy_mem(borrow, z, ws, ws + 25, 25);
+   clear_mem(z + 24, 2*(24+1) - 24);
    }
 
-void bigint_monty_redc_32(word z[64], const word p[32], word p_dash, word ws[])
+void bigint_monty_redc_32(word z[], const word p[32], word p_dash, word ws[])
    {
    word w2 = 0, w1 = 0, w0 = 0;
    w0 = z[0];
@@ -2564,10 +2579,13 @@ void bigint_monty_redc_32(word z[64], const word p[32], word p_dash, word ws[])
    w0 = w1; w1 = w2; w2 = 0;
    word3_add(&w2, &w1, &w0, z[63]);
    ws[31] = w0;
-   ws[32] = w1;
-   word borrow = bigint_sub3(z, ws, 32 + 1, p, 32);
-   CT::conditional_assign_mem(borrow, z, ws, 32);
-   clear_mem(z + 32, 32);
+   w0 = w1; w1 = w2; w2 = 0;
+   word3_add(&w2, &w1, &w0, z[65]);
+   ws[32] = w0;
+   ws[33] = w1;
+   word borrow = bigint_sub3(ws + 32 + 1, ws, 32 + 1, p, 32);
+   CT::conditional_copy_mem(borrow, z, ws, ws + 33, 33);
+   clear_mem(z + 32, 2*(32+1) - 32);
    }
 
 }
diff --git a/src/lib/math/numbertheory/monty.cpp b/src/lib/math/numbertheory/monty.cpp
index 29a68d9fa..4d4dffa71 100644
--- a/src/lib/math/numbertheory/monty.cpp
+++ b/src/lib/math/numbertheory/monty.cpp
@@ -85,13 +85,13 @@ BigInt Montgomery_Params::inv_mod_p(const BigInt& x) const
 
 BigInt Montgomery_Params::redc(const BigInt& x, secure_vector<word>& ws) const
    {
-   const size_t output_size = m_p_words + 1;
+   const size_t output_size = 2*m_p_words + 2;
 
    if(ws.size() < output_size)
       ws.resize(output_size);
 
    BigInt z = x;
-   z.grow_to(2*m_p_words);
+   z.grow_to(output_size);
 
    bigint_monty_redc(z.mutable_data(),
                      m_p.data(), m_p_words, m_p_dash,
@@ -151,7 +151,7 @@ void Montgomery_Params::mul_by(BigInt& x,
                                const secure_vector<word>& y,
                                secure_vector<word>& ws) const
    {
-   const size_t output_size = 2*m_p_words;
+   const size_t output_size = 2*m_p_words + 2;
 
    if(ws.size() < 2*output_size)
       ws.resize(2*output_size);
@@ -179,7 +179,7 @@ void Montgomery_Params::mul_by(BigInt& x,
                                const BigInt& y,
                                secure_vector<word>& ws) const
    {
-   const size_t output_size = 2*m_p_words;
+   const size_t output_size = 2*m_p_words + 2;
 
    if(ws.size() < 2*output_size)
       ws.resize(2*output_size);
@@ -205,7 +205,7 @@ void Montgomery_Params::mul_by(BigInt& x,
 
 BigInt Montgomery_Params::sqr(const BigInt& x, secure_vector<word>& ws) const
    {
-   const size_t output_size = 2*m_p_words;
+   const size_t output_size = 2*m_p_words + 2;
 
    if(ws.size() < output_size)
       ws.resize(output_size);
@@ -228,7 +228,7 @@ BigInt Montgomery_Params::sqr(const BigInt& x, secure_vector<word>& ws) const
 void Montgomery_Params::square_this(BigInt& x,
                                     secure_vector<word>& ws) const
    {
-   const size_t output_size = 2*m_p_words;
+   const size_t output_size = 2*m_p_words + 2;
 
    if(ws.size() < 2*output_size)
       ws.resize(2*output_size);
diff --git a/src/lib/prov/pkcs11/p11_ecc_key.cpp b/src/lib/prov/pkcs11/p11_ecc_key.cpp
index f60e2f4d7..8561a1361 100644
--- a/src/lib/prov/pkcs11/p11_ecc_key.cpp
+++ b/src/lib/prov/pkcs11/p11_ecc_key.cpp
@@ -16,8 +16,8 @@
 
 namespace Botan::PKCS11 {
 namespace {
-/// Converts a DER-encoded ANSI X9.62 ECPoint to EC_Point
-EC_Point decode_public_point(const secure_vector<uint8_t>& ec_point_data, const EC_Group& group)
+/// Converts a DER-encoded ANSI X9.62 ECPoint to PointGFp
+PointGFp decode_public_point(const secure_vector<uint8_t>& ec_point_data, const EC_Group& group)
    {
    secure_vector<uint8_t> ec_point;
    BER_Decoder(ec_point_data).decode(ec_point, ASN1_Type::OctetString);
@@ -111,7 +111,7 @@ size_t PKCS11_EC_PrivateKey::key_length() const
 
 std::vector<uint8_t> PKCS11_EC_PrivateKey::public_key_bits() const
    {
-   return public_point().encode(EC_Point::COMPRESSED);
+   return public_point().encode(PointGFp::COMPRESSED);
    }
 
 size_t PKCS11_EC_PrivateKey::estimated_strength() const
diff --git a/src/lib/prov/pkcs11/p11_ecc_key.h b/src/lib/prov/pkcs11/p11_ecc_key.h
index da39a6c5a..46e24439d 100644
--- a/src/lib/prov/pkcs11/p11_ecc_key.h
+++ b/src/lib/prov/pkcs11/p11_ecc_key.h
@@ -169,7 +169,7 @@ class BOTAN_PUBLIC_API(2,0) PKCS11_EC_PrivateKey : public virtual Private_Key,
       * @param point the public point
       * @param point_encoding encoding of the point (default DER-encoded)
       */
-      void set_public_point(const EC_Point& point, PublicPointEncoding point_encoding = PublicPointEncoding::Der)
+      void set_public_point(const PointGFp& point, PublicPointEncoding point_encoding = PublicPointEncoding::Der)
          {
          m_public_key = point;
          m_point_encoding = point_encoding;
@@ -192,7 +192,7 @@ class BOTAN_PUBLIC_API(2,0) PKCS11_EC_PrivateKey : public virtual Private_Key,
       * @return the public point of the private key
       * @throws Exception if the public point was not set using set_public_point()
       */
-      const EC_Point& public_point() const
+      const PointGFp& public_point() const
          {
          if(m_public_key.is_zero())
             {
@@ -221,7 +221,7 @@ class BOTAN_PUBLIC_API(2,0) PKCS11_EC_PrivateKey : public virtual Private_Key,
 
    private:
       EC_Group m_domain_params;
-      EC_Point m_public_key;
+      PointGFp m_public_key;
       PublicPointEncoding m_point_encoding = PublicPointEncoding::Der;
    };
 }
diff --git a/src/lib/prov/pkcs11/p11_ecdh.h b/src/lib/prov/pkcs11/p11_ecdh.h
index 4ad08c773..aa2975a42 100644
--- a/src/lib/prov/pkcs11/p11_ecdh.h
+++ b/src/lib/prov/pkcs11/p11_ecdh.h
@@ -97,7 +97,7 @@ class BOTAN_PUBLIC_API(2,0) PKCS11_ECDH_PrivateKey final : public virtual PKCS11
 
       inline std::vector<uint8_t> public_value() const override
          {
-         return public_point().encode(EC_Point::UNCOMPRESSED);
+         return public_point().encode(PointGFp::UNCOMPRESSED);
          }
 
       /// @return the exported ECDH private key
diff --git a/src/lib/pubkey/ec_group/curve_gfp.cpp b/src/lib/pubkey/ec_group/curve_gfp.cpp
index 097ad6385..dca350126 100644
--- a/src/lib/pubkey/ec_group/curve_gfp.cpp
+++ b/src/lib/pubkey/ec_group/curve_gfp.cpp
@@ -58,7 +58,7 @@ class CurveGFp_Montgomery final : public CurveGFp_Repr
 
       size_t get_p_words() const override { return m_p_words; }
 
-      size_t get_ws_size() const override { return 2*m_p_words; }
+      size_t get_ws_size() const override { return 2*m_p_words + 4; }
 
       BigInt invert_element(const BigInt& x, secure_vector<word>& ws) const override;
 
@@ -111,7 +111,7 @@ void CurveGFp_Montgomery::from_curve_rep(BigInt& z, secure_vector<word>& ws) con
    if(ws.size() < get_ws_size())
       ws.resize(get_ws_size());
 
-   const size_t output_size = 2*m_p_words;
+   const size_t output_size = 2*m_p_words + 2;
    if(z.size() < output_size)
       z.grow_to(output_size);
 
@@ -131,7 +131,7 @@ void CurveGFp_Montgomery::curve_mul_words(BigInt& z,
    if(ws.size() < get_ws_size())
       ws.resize(get_ws_size());
 
-   const size_t output_size = 2*m_p_words;
+   const size_t output_size = 2*m_p_words + 2;
    if(z.size() < output_size)
       z.grow_to(output_size);
 
@@ -153,7 +153,7 @@ void CurveGFp_Montgomery::curve_sqr_words(BigInt& z,
    if(ws.size() < get_ws_size())
       ws.resize(get_ws_size());
 
-   const size_t output_size = 2*m_p_words;
+   const size_t output_size = 2*m_p_words + 2;
    if(z.size() < output_size)
       z.grow_to(output_size);
 
@@ -186,7 +186,7 @@ class CurveGFp_NIST : public CurveGFp_Repr
 
       size_t get_p_words() const override { return m_p_words; }
 
-      size_t get_ws_size() const override { return 2*m_p_words; }
+      size_t get_ws_size() const override { return 2*m_p_words + 4; }
 
       const BigInt& get_a_rep() const override { return m_a; }
 
@@ -250,7 +250,7 @@ void CurveGFp_NIST::curve_mul_words(BigInt& z,
    if(ws.size() < get_ws_size())
       ws.resize(get_ws_size());
 
-   const size_t output_size = 2*m_p_words;
+   const size_t output_size = 2*m_p_words + 2;
    if(z.size() < output_size)
       z.grow_to(output_size);
 
@@ -268,7 +268,7 @@ void CurveGFp_NIST::curve_sqr_words(BigInt& z, const word x[], size_t x_size,
    if(ws.size() < get_ws_size())
       ws.resize(get_ws_size());
 
-   const size_t output_size = 2*m_p_words;
+   const size_t output_size = 2*m_p_words + 2;
    if(z.size() < output_size)
       z.grow_to(output_size);
 
diff --git a/src/lib/pubkey/ec_group/curve_gfp.h b/src/lib/pubkey/ec_group/curve_gfp.h
index fdc483d7e..77c04ebf3 100644
--- a/src/lib/pubkey/ec_group/curve_gfp.h
+++ b/src/lib/pubkey/ec_group/curve_gfp.h
@@ -13,7 +13,7 @@
 #include <botan/bigint.h>
 #include <memory>
 
-// Currently exposed in EC_Point
+// Currently exposed in PointGFp
 //BOTAN_FUTURE_INTERNAL_HEADER(curve_gfp.h)
 
 namespace Botan {
@@ -88,7 +88,7 @@ class BOTAN_UNSTABLE_API CurveGFp_Repr
 * This class represents an elliptic curve over GF(p)
 *
 * There should not be any reason for applications to use this type.
-* If you need EC primitives use the interfaces EC_Group and EC_Point
+* If you need EC primitives use the interfaces EC_Group and PointGFp
 *
 * It is likely this class will be removed entirely in a future major
 * release.
diff --git a/src/lib/pubkey/ec_group/ec_group.cpp b/src/lib/pubkey/ec_group/ec_group.cpp
index 13ccbc51e..2e94ec5fc 100644
--- a/src/lib/pubkey/ec_group/ec_group.cpp
+++ b/src/lib/pubkey/ec_group/ec_group.cpp
@@ -97,7 +97,7 @@ class EC_Group_Data final
       size_t order_bytes() const { return (m_order_bits + 7) / 8; }
 
       const CurveGFp& curve() const { return m_curve; }
-      const EC_Point& base_point() const { return m_base_point; }
+      const PointGFp& base_point() const { return m_base_point; }
 
       bool a_is_minus_3() const { return m_a_is_minus_3; }
       bool a_is_zero() const { return m_a_is_zero; }
@@ -124,7 +124,7 @@ class EC_Group_Data final
          return inverse_mod(x, m_order);
          }
 
-      EC_Point blinded_base_point_multiply(const BigInt& k,
+      PointGFp blinded_base_point_multiply(const BigInt& k,
                                            RandomNumberGenerator& rng,
                                            std::vector<BigInt>& ws) const
          {
@@ -135,14 +135,14 @@ class EC_Group_Data final
 
    private:
       CurveGFp m_curve;
-      EC_Point m_base_point;
+      PointGFp m_base_point;
 
       BigInt m_g_x;
       BigInt m_g_y;
       BigInt m_order;
       BigInt m_cofactor;
       Modular_Reducer m_mod_order;
-      EC_Point_Base_Point_Precompute m_base_mult;
+      PointGFp_Base_Point_Precompute m_base_mult;
       OID m_oid;
       size_t m_p_bits;
       size_t m_order_bits;
@@ -541,7 +541,7 @@ const BigInt& EC_Group::get_b() const
    return data().b();
    }
 
-const EC_Point& EC_Group::get_base_point() const
+const PointGFp& EC_Group::get_base_point() const
    {
    return data().base_point();
    }
@@ -601,21 +601,21 @@ EC_Group_Source EC_Group::source() const
    return data().source();
    }
 
-size_t EC_Group::point_size(EC_Point::Compression_Type format) const
+size_t EC_Group::point_size(PointGFp::Compression_Type format) const
    {
    // Hybrid and standard format are (x,y), compressed is y, +1 format byte
-   if(format == EC_Point::COMPRESSED)
+   if(format == PointGFp::COMPRESSED)
       return (1 + get_p_bytes());
    else
       return (1 + 2*get_p_bytes());
    }
 
-EC_Point EC_Group::OS2ECP(const uint8_t bits[], size_t len) const
+PointGFp EC_Group::OS2ECP(const uint8_t bits[], size_t len) const
    {
    return Botan::OS2ECP(bits, len, data().curve());
    }
 
-EC_Point EC_Group::point(const BigInt& x, const BigInt& y) const
+PointGFp EC_Group::point(const BigInt& x, const BigInt& y) const
    {
    #if 0
    BigInt l = (x*x*x + x*get_a() + get_b()) % get_p();
@@ -627,16 +627,16 @@ EC_Point EC_Group::point(const BigInt& x, const BigInt& y) const
       }
 #endif
    // TODO: randomize the representation?
-   return EC_Point(data().curve(), x, y);
+   return PointGFp(data().curve(), x, y);
    }
 
-EC_Point EC_Group::point_multiply(const BigInt& x, const EC_Point& pt, const BigInt& y) const
+PointGFp EC_Group::point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const
    {
-   EC_Point_Multi_Point_Precompute xy_mul(get_base_point(), pt);
+   PointGFp_Multi_Point_Precompute xy_mul(get_base_point(), pt);
    return xy_mul.multi_exp(x, y);
    }
 
-EC_Point EC_Group::blinded_base_point_multiply(const BigInt& k,
+PointGFp EC_Group::blinded_base_point_multiply(const BigInt& k,
                                                RandomNumberGenerator& rng,
                                                std::vector<BigInt>& ws) const
    {
@@ -647,7 +647,7 @@ BigInt EC_Group::blinded_base_point_multiply_x(const BigInt& k,
                                                RandomNumberGenerator& rng,
                                                std::vector<BigInt>& ws) const
    {
-   const EC_Point pt = data().blinded_base_point_multiply(k, rng, ws);
+   const PointGFp pt = data().blinded_base_point_multiply(k, rng, ws);
 
    if(pt.is_zero())
       return BigInt::zero();
@@ -659,21 +659,21 @@ BigInt EC_Group::random_scalar(RandomNumberGenerator& rng) const
    return BigInt::random_integer(rng, BigInt::one(), get_order());
    }
 
-EC_Point EC_Group::blinded_var_point_multiply(const EC_Point& point,
+PointGFp EC_Group::blinded_var_point_multiply(const PointGFp& point,
                                               const BigInt& k,
                                               RandomNumberGenerator& rng,
                                               std::vector<BigInt>& ws) const
    {
-   EC_Point_Var_Point_Precompute mul(point, rng, ws);
+   PointGFp_Var_Point_Precompute mul(point, rng, ws);
    return mul.mul(k, rng, get_order(), ws);
    }
 
-EC_Point EC_Group::zero_point() const
+PointGFp EC_Group::zero_point() const
    {
-   return EC_Point(data().curve());
+   return PointGFp(data().curve());
    }
 
-EC_Point EC_Group::hash_to_curve(const std::string& hash_fn,
+PointGFp EC_Group::hash_to_curve(const std::string& hash_fn,
                                  const uint8_t input[],
                                  size_t input_len,
                                  const std::string& domain,
@@ -687,7 +687,7 @@ EC_Point EC_Group::hash_to_curve(const std::string& hash_fn,
                               random_oracle);
    }
 
-EC_Point EC_Group::hash_to_curve(const std::string& hash_fn,
+PointGFp EC_Group::hash_to_curve(const std::string& hash_fn,
                                  const uint8_t input[],
                                  size_t input_len,
                                  const uint8_t domain_sep[],
@@ -739,7 +739,7 @@ EC_Group::DER_encode(EC_Group_Encoding form) const
                .encode(BigInt::encode_1363(get_b(), p_bytes),
                        ASN1_Type::OctetString)
             .end_cons()
-              .encode(get_base_point().encode(EC_Point::UNCOMPRESSED), ASN1_Type::OctetString)
+              .encode(get_base_point().encode(PointGFp::UNCOMPRESSED), ASN1_Type::OctetString)
             .encode(get_order())
             .encode(get_cofactor())
          .end_cons();
@@ -785,7 +785,7 @@ bool EC_Group::operator==(const EC_Group& other) const
            get_cofactor() == other.get_cofactor());
    }
 
-bool EC_Group::verify_public_element(const EC_Point& point) const
+bool EC_Group::verify_public_element(const PointGFp& point) const
    {
    //check that public point is not at infinity
    if(point.is_zero())
@@ -820,7 +820,7 @@ bool EC_Group::verify_group(RandomNumberGenerator& rng,
    const BigInt& a = get_a();
    const BigInt& b = get_b();
    const BigInt& order = get_order();
-   const EC_Point& base_point = get_base_point();
+   const PointGFp& base_point = get_base_point();
 
    if(p <= 3 || order <= 0)
       return false;
diff --git a/src/lib/pubkey/ec_group/ec_group.h b/src/lib/pubkey/ec_group/ec_group.h
index d727b17e6..6ae180ee9 100644
--- a/src/lib/pubkey/ec_group/ec_group.h
+++ b/src/lib/pubkey/ec_group/ec_group.h
@@ -10,7 +10,7 @@
 #ifndef BOTAN_ECC_DOMAIN_PARAMETERS_H_
 #define BOTAN_ECC_DOMAIN_PARAMETERS_H_
 
-#include <botan/ec_point.h>
+#include <botan/point_gfp.h>
 #include <botan/asn1_obj.h>
 #include <memory>
 #include <set>
@@ -174,7 +174,7 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final
       * Return group base point
       * @result base point
       */
-      const EC_Point& get_base_point() const;
+      const PointGFp& get_base_point() const;
 
       /**
       * Return the x coordinate of the base point
@@ -237,7 +237,7 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final
       * In particular, checks that it is a point on the curve, not infinity,
       * and that it has order matching the group.
       */
-      bool verify_public_element(const EC_Point& y) const;
+      bool verify_public_element(const PointGFp& y) const;
 
       /**
       * Return the OID of these domain parameters
@@ -248,13 +248,13 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final
       /**
       * Return a point on this curve with the affine values x, y
       */
-      EC_Point point(const BigInt& x, const BigInt& y) const;
+      PointGFp point(const BigInt& x, const BigInt& y) const;
 
       /**
       * Multi exponentiate. Not constant time.
       * @return base_point*x + pt*y
       */
-      EC_Point point_multiply(const BigInt& x, const EC_Point& pt, const BigInt& y) const;
+      PointGFp point_multiply(const BigInt& x, const PointGFp& pt, const BigInt& y) const;
 
       /**
       * Blinded point multiplication, attempts resistance to side channels
@@ -263,7 +263,7 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final
       * @param ws a temp workspace
       * @return base_point*k
       */
-      EC_Point blinded_base_point_multiply(const BigInt& k,
+      PointGFp blinded_base_point_multiply(const BigInt& k,
                                            RandomNumberGenerator& rng,
                                            std::vector<BigInt>& ws) const;
 
@@ -288,7 +288,7 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final
       * @param ws a temp workspace
       * @return point*k
       */
-      EC_Point blinded_var_point_multiply(const EC_Point& point,
+      PointGFp blinded_var_point_multiply(const PointGFp& point,
                                           const BigInt& k,
                                           RandomNumberGenerator& rng,
                                           std::vector<BigInt>& ws) const;
@@ -311,7 +311,7 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final
       * @param random_oracle if the mapped point must be uniform (use
                "true" here unless you know what you are doing)
       */
-      EC_Point hash_to_curve(const std::string& hash_fn,
+      PointGFp hash_to_curve(const std::string& hash_fn,
                              const uint8_t input[],
                              size_t input_len,
                              const uint8_t domain_sep[],
@@ -330,7 +330,7 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final
       * @param random_oracle if the mapped point must be uniform (use
                "true" here unless you know what you are doing)
       */
-      EC_Point hash_to_curve(const std::string& hash_fn,
+      PointGFp hash_to_curve(const std::string& hash_fn,
                              const uint8_t input[],
                              size_t input_len,
                              const std::string& domain_sep,
@@ -339,14 +339,14 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final
       /**
       * Return the zero (or infinite) point on this curve
       */
-      EC_Point zero_point() const;
+      PointGFp zero_point() const;
 
-      size_t point_size(EC_Point::Compression_Type format) const;
+      size_t point_size(PointGFp::Compression_Type format) const;
 
-      EC_Point OS2ECP(const uint8_t bits[], size_t len) const;
+      PointGFp OS2ECP(const uint8_t bits[], size_t len) const;
 
       template<typename Alloc>
-      EC_Point OS2ECP(const std::vector<uint8_t, Alloc>& vec) const
+      PointGFp OS2ECP(const std::vector<uint8_t, Alloc>& vec) const
          {
          return this->OS2ECP(vec.data(), vec.size());
          }
diff --git a/src/lib/pubkey/ec_group/info.txt b/src/lib/pubkey/ec_group/info.txt
index 8e7175a5f..26bc5cafd 100644
--- a/src/lib/pubkey/ec_group/info.txt
+++ b/src/lib/pubkey/ec_group/info.txt
@@ -21,5 +21,5 @@ point_mul.h
 <header:public>
 curve_gfp.h
 ec_group.h
-ec_point.h
+point_gfp.h
 </header:public>
diff --git a/src/lib/pubkey/ec_group/ec_point.cpp b/src/lib/pubkey/ec_group/point_gfp.cpp
similarity index 89%
rename from src/lib/pubkey/ec_group/ec_point.cpp
rename to src/lib/pubkey/ec_group/point_gfp.cpp
index 7583b461f..168cede64 100644
--- a/src/lib/pubkey/ec_group/ec_point.cpp
+++ b/src/lib/pubkey/ec_group/point_gfp.cpp
@@ -7,14 +7,14 @@
 * Botan is released under the Simplified BSD License (see license.txt)
 */
 
-#include <botan/ec_point.h>
+#include <botan/point_gfp.h>
 #include <botan/numthry.h>
 #include <botan/rng.h>
 #include <botan/internal/ct_utils.h>
 
 namespace Botan {
 
-EC_Point::EC_Point(const CurveGFp& curve) :
+PointGFp::PointGFp(const CurveGFp& curve) :
    m_curve(curve),
    m_coord_x(0),
    m_coord_y(curve.get_1_rep()),
@@ -23,29 +23,29 @@ EC_Point::EC_Point(const CurveGFp& curve) :
    // Assumes Montgomery rep of zero is zero
    }
 
-EC_Point::EC_Point(const CurveGFp& curve, const BigInt& x, const BigInt& y) :
+PointGFp::PointGFp(const CurveGFp& curve, const BigInt& x, const BigInt& y) :
    m_curve(curve),
    m_coord_x(x),
    m_coord_y(y),
    m_coord_z(m_curve.get_1_rep())
    {
    if(x < 0 || x >= curve.get_p())
-      throw Invalid_Argument("Invalid EC_Point affine x");
+      throw Invalid_Argument("Invalid PointGFp affine x");
    if(y < 0 || y >= curve.get_p())
-      throw Invalid_Argument("Invalid EC_Point affine y");
+      throw Invalid_Argument("Invalid PointGFp affine y");
 
    secure_vector<word> monty_ws(m_curve.get_ws_size());
    m_curve.to_rep(m_coord_x, monty_ws);
    m_curve.to_rep(m_coord_y, monty_ws);
    }
 
-void EC_Point::randomize_repr(RandomNumberGenerator& rng)
+void PointGFp::randomize_repr(RandomNumberGenerator& rng)
    {
    secure_vector<word> ws(m_curve.get_ws_size());
    randomize_repr(rng, ws);
    }
 
-void EC_Point::randomize_repr(RandomNumberGenerator& rng, secure_vector<word>& ws)
+void PointGFp::randomize_repr(RandomNumberGenerator& rng, secure_vector<word>& ws)
    {
    const BigInt mask = BigInt::random_integer(rng, 2, m_curve.get_p());
 
@@ -68,8 +68,8 @@ namespace {
 
 inline void resize_ws(std::vector<BigInt>& ws_bn, size_t cap_size)
    {
-   BOTAN_ASSERT(ws_bn.size() >= EC_Point::WORKSPACE_SIZE,
-                "Expected size for EC_Point workspace");
+   BOTAN_ASSERT(ws_bn.size() >= PointGFp::WORKSPACE_SIZE,
+                "Expected size for PointGFp workspace");
 
    for(auto& ws : ws_bn)
       if(ws.size() < cap_size)
@@ -86,7 +86,7 @@ inline word all_zeros(const word x[], size_t len)
 
 }
 
-void EC_Point::add_affine(const word x_words[], size_t x_size,
+void PointGFp::add_affine(const word x_words[], size_t x_size,
                           const word y_words[], size_t y_size,
                           std::vector<BigInt>& ws_bn)
    {
@@ -169,7 +169,7 @@ void EC_Point::add_affine(const word x_words[], size_t x_size,
    m_coord_z.swap(T0);
    }
 
-void EC_Point::add(const word x_words[], size_t x_size,
+void PointGFp::add(const word x_words[], size_t x_size,
                    const word y_words[], size_t y_size,
                    const word z_words[], size_t z_size,
                    std::vector<BigInt>& ws_bn)
@@ -255,14 +255,14 @@ void EC_Point::add(const word x_words[], size_t x_size,
    m_curve.mul(m_coord_z, T3, T4, ws);
    }
 
-void EC_Point::mult2i(size_t iterations, std::vector<BigInt>& ws_bn)
+void PointGFp::mult2i(size_t iterations, std::vector<BigInt>& ws_bn)
    {
    if(iterations == 0)
       return;
 
    if(m_coord_y.is_zero())
       {
-      *this = EC_Point(m_curve); // setting myself to zero
+      *this = PointGFp(m_curve); // setting myself to zero
       return;
       }
 
@@ -275,14 +275,14 @@ void EC_Point::mult2i(size_t iterations, std::vector<BigInt>& ws_bn)
    }
 
 // *this *= 2
-void EC_Point::mult2(std::vector<BigInt>& ws_bn)
+void PointGFp::mult2(std::vector<BigInt>& ws_bn)
    {
    if(is_zero())
       return;
 
    if(m_coord_y.is_zero())
       {
-      *this = EC_Point(m_curve); // setting myself to zero
+      *this = PointGFp(m_curve); // setting myself to zero
       return;
       }
 
@@ -365,16 +365,16 @@ void EC_Point::mult2(std::vector<BigInt>& ws_bn)
    }
 
 // arithmetic operators
-EC_Point& EC_Point::operator+=(const EC_Point& rhs)
+PointGFp& PointGFp::operator+=(const PointGFp& rhs)
    {
-   std::vector<BigInt> ws(EC_Point::WORKSPACE_SIZE);
+   std::vector<BigInt> ws(PointGFp::WORKSPACE_SIZE);
    add(rhs, ws);
    return *this;
    }
 
-EC_Point& EC_Point::operator-=(const EC_Point& rhs)
+PointGFp& PointGFp::operator-=(const PointGFp& rhs)
    {
-   EC_Point minus_rhs = EC_Point(rhs).negate();
+   PointGFp minus_rhs = PointGFp(rhs).negate();
 
    if(is_zero())
       *this = minus_rhs;
@@ -384,21 +384,21 @@ EC_Point& EC_Point::operator-=(const EC_Point& rhs)
    return *this;
    }
 
-EC_Point& EC_Point::operator*=(const BigInt& scalar)
+PointGFp& PointGFp::operator*=(const BigInt& scalar)
    {
    *this = scalar * *this;
    return *this;
    }
 
-EC_Point operator*(const BigInt& scalar, const EC_Point& point)
+PointGFp operator*(const BigInt& scalar, const PointGFp& point)
    {
    BOTAN_DEBUG_ASSERT(point.on_the_curve());
 
    const size_t scalar_bits = scalar.bits();
 
-   std::vector<BigInt> ws(EC_Point::WORKSPACE_SIZE);
+   std::vector<BigInt> ws(PointGFp::WORKSPACE_SIZE);
 
-   EC_Point R[2] = { point.zero(), point };
+   PointGFp R[2] = { point.zero(), point };
 
    for(size_t i = scalar_bits; i > 0; i--)
       {
@@ -416,7 +416,7 @@ EC_Point operator*(const BigInt& scalar, const EC_Point& point)
    }
 
 //static
-void EC_Point::force_all_affine(std::vector<EC_Point>& points,
+void PointGFp::force_all_affine(std::vector<PointGFp>& points,
                                 secure_vector<word>& ws)
    {
    if(points.size() <= 1)
@@ -461,7 +461,7 @@ void EC_Point::force_all_affine(std::vector<EC_Point>& points,
 
    for(size_t i = points.size() - 1; i != 0; i--)
       {
-      EC_Point& point = points[i];
+      PointGFp& point = points[i];
 
       curve.mul(z_inv, s_inv, c[i-1], ws);
 
@@ -481,7 +481,7 @@ void EC_Point::force_all_affine(std::vector<EC_Point>& points,
    points[0].m_coord_z = rep_1;
    }
 
-void EC_Point::force_affine()
+void PointGFp::force_affine()
    {
    if(is_zero())
       throw Invalid_State("Cannot convert zero ECC point to affine");
@@ -496,12 +496,12 @@ void EC_Point::force_affine()
    m_coord_z = m_curve.get_1_rep();
    }
 
-bool EC_Point::is_affine() const
+bool PointGFp::is_affine() const
    {
    return m_curve.is_one(m_coord_z);
    }
 
-BigInt EC_Point::get_affine_x() const
+BigInt PointGFp::get_affine_x() const
    {
    if(is_zero())
       throw Invalid_State("Cannot convert zero point to affine");
@@ -520,7 +520,7 @@ BigInt EC_Point::get_affine_x() const
    return r;
    }
 
-BigInt EC_Point::get_affine_y() const
+BigInt PointGFp::get_affine_y() const
    {
    if(is_zero())
       throw Invalid_State("Cannot convert zero point to affine");
@@ -540,7 +540,7 @@ BigInt EC_Point::get_affine_y() const
    return r;
    }
 
-bool EC_Point::on_the_curve() const
+bool PointGFp::on_the_curve() const
    {
    /*
    Is the point still on the curve?? (If everything is correct, the
@@ -575,7 +575,7 @@ bool EC_Point::on_the_curve() const
    }
 
 // swaps the states of *this and other, does not throw!
-void EC_Point::swap(EC_Point& other)
+void PointGFp::swap(PointGFp& other)
    {
    m_curve.swap(other.m_curve);
    m_coord_x.swap(other.m_coord_x);
@@ -583,7 +583,7 @@ void EC_Point::swap(EC_Point& other)
    m_coord_z.swap(other.m_coord_z);
    }
 
-bool EC_Point::operator==(const EC_Point& other) const
+bool PointGFp::operator==(const PointGFp& other) const
    {
    if(m_curve != other.m_curve)
       return false;
@@ -597,7 +597,7 @@ bool EC_Point::operator==(const EC_Point& other) const
    }
 
 // encoding and decoding
-std::vector<uint8_t> EC_Point::encode(EC_Point::Compression_Type format) const
+std::vector<uint8_t> PointGFp::encode(PointGFp::Compression_Type format) const
    {
    if(is_zero())
       return std::vector<uint8_t>(1); // single 0 byte
@@ -609,20 +609,20 @@ std::vector<uint8_t> EC_Point::encode(EC_Point::Compression_Type format) const
 
    std::vector<uint8_t> result;
 
-   if(format == EC_Point::UNCOMPRESSED)
+   if(format == PointGFp::UNCOMPRESSED)
       {
       result.resize(1 + 2*p_bytes);
       result[0] = 0x04;
       BigInt::encode_1363(&result[1], p_bytes, x);
       BigInt::encode_1363(&result[1+p_bytes], p_bytes, y);
       }
-   else if(format == EC_Point::COMPRESSED)
+   else if(format == PointGFp::COMPRESSED)
       {
       result.resize(1 + p_bytes);
       result[0] = 0x02 | static_cast<uint8_t>(y.get_bit(0));
       BigInt::encode_1363(&result[1], p_bytes, x);
       }
-   else if(format == EC_Point::HYBRID)
+   else if(format == PointGFp::HYBRID)
       {
       result.resize(1 + 2*p_bytes);
       result[0] = 0x06 | static_cast<uint8_t>(y.get_bit(0));
@@ -663,16 +663,16 @@ BigInt decompress_point(bool yMod2,
 
 }
 
-EC_Point OS2ECP(const uint8_t data[], size_t data_len,
+PointGFp OS2ECP(const uint8_t data[], size_t data_len,
                 const CurveGFp& curve)
    {
    // Should we really be doing this?
    if(data_len <= 1)
-      return EC_Point(curve); // return zero
+      return PointGFp(curve); // return zero
 
    std::pair<BigInt, BigInt> xy = OS2ECP(data, data_len, curve.get_p(), curve.get_a(), curve.get_b());
 
-   EC_Point point(curve, xy.first, xy.second);
+   PointGFp point(curve, xy.first, xy.second);
 
    if(!point.on_the_curve())
       throw Decoding_Error("OS2ECP: Decoded point was not on the curve");
diff --git a/src/lib/pubkey/ec_group/ec_point.h b/src/lib/pubkey/ec_group/point_gfp.h
similarity index 78%
rename from src/lib/pubkey/ec_group/ec_point.h
rename to src/lib/pubkey/ec_group/point_gfp.h
index 8c9293227..631d0b612 100644
--- a/src/lib/pubkey/ec_group/ec_point.h
+++ b/src/lib/pubkey/ec_group/point_gfp.h
@@ -7,8 +7,8 @@
 * Botan is released under the Simplified BSD License (see license.txt)
 */
 
-#ifndef BOTAN_EC_POINT_H_
-#define BOTAN_EC_POINT_H_
+#ifndef BOTAN_POINT_GFP_H_
+#define BOTAN_POINT_GFP_H_
 
 #include <botan/curve_gfp.h>
 #include <botan/exceptn.h>
@@ -19,7 +19,7 @@ namespace Botan {
 /**
 * This class represents one point on a curve of GF(p)
 */
-class BOTAN_PUBLIC_API(2,0) EC_Point final
+class BOTAN_PUBLIC_API(2,0) PointGFp final
    {
    public:
       enum Compression_Type {
@@ -31,25 +31,25 @@ class BOTAN_PUBLIC_API(2,0) EC_Point final
       enum { WORKSPACE_SIZE = 8 };
 
       /**
-      * Construct an uninitialized EC_Point
+      * Construct an uninitialized PointGFp
       */
-      EC_Point() = default;
+      PointGFp() = default;
 
       /**
       * Construct the zero point
       * @param curve The base curve
       */
-      explicit EC_Point(const CurveGFp& curve);
+      explicit PointGFp(const CurveGFp& curve);
 
       /**
       * Copy constructor
       */
-      EC_Point(const EC_Point&) = default;
+      PointGFp(const PointGFp&) = default;
 
       /**
       * Move Constructor
       */
-      EC_Point(EC_Point&& other)
+      PointGFp(PointGFp&& other)
          {
          this->swap(other);
          }
@@ -57,12 +57,12 @@ class BOTAN_PUBLIC_API(2,0) EC_Point final
       /**
       * Standard Assignment
       */
-      EC_Point& operator=(const EC_Point&) = default;
+      PointGFp& operator=(const PointGFp&) = default;
 
       /**
       * Move Assignment
       */
-      EC_Point& operator=(EC_Point&& other)
+      PointGFp& operator=(PointGFp&& other)
          {
          if(this != &other)
             this->swap(other);
@@ -76,40 +76,40 @@ class BOTAN_PUBLIC_API(2,0) EC_Point final
       * @param x affine x coordinate
       * @param y affine y coordinate
       */
-      EC_Point(const CurveGFp& curve, const BigInt& x, const BigInt& y);
+      PointGFp(const CurveGFp& curve, const BigInt& x, const BigInt& y);
 
       /**
       * EC2OSP - elliptic curve to octet string primitive
       * @param format which format to encode using
       */
-      std::vector<uint8_t> encode(EC_Point::Compression_Type format) const;
+      std::vector<uint8_t> encode(PointGFp::Compression_Type format) const;
 
       /**
       * += Operator
-      * @param rhs the EC_Point to add to the local value
-      * @result resulting EC_Point
+      * @param rhs the PointGFp to add to the local value
+      * @result resulting PointGFp
       */
-      EC_Point& operator+=(const EC_Point& rhs);
+      PointGFp& operator+=(const PointGFp& rhs);
 
       /**
       * -= Operator
-      * @param rhs the EC_Point to subtract from the local value
-      * @result resulting EC_Point
+      * @param rhs the PointGFp to subtract from the local value
+      * @result resulting PointGFp
       */
-      EC_Point& operator-=(const EC_Point& rhs);
+      PointGFp& operator-=(const PointGFp& rhs);
 
       /**
       * *= Operator
-      * @param scalar the EC_Point to multiply with *this
-      * @result resulting EC_Point
+      * @param scalar the PointGFp to multiply with *this
+      * @result resulting PointGFp
       */
-      EC_Point& operator*=(const BigInt& scalar);
+      PointGFp& operator*=(const BigInt& scalar);
 
       /**
       * Negate this point
       * @return *this
       */
-      EC_Point& negate()
+      PointGFp& negate()
          {
          if(!is_zero())
             m_coord_y = m_curve.get_p() - m_coord_y;
@@ -147,7 +147,7 @@ class BOTAN_PUBLIC_API(2,0) EC_Point final
       /**
       * Force all points on the list to affine coordinates
       */
-      static void force_all_affine(std::vector<EC_Point>& points,
+      static void force_all_affine(std::vector<PointGFp>& points,
                                    secure_vector<word>& ws);
 
       bool is_affine() const;
@@ -169,7 +169,7 @@ class BOTAN_PUBLIC_API(2,0) EC_Point final
       * swaps the states of *this and other, does not throw!
       * @param other the object to swap values with
       */
-      void swap(EC_Point& other);
+      void swap(PointGFp& other);
 
       /**
       * Randomize the point representation
@@ -186,14 +186,14 @@ class BOTAN_PUBLIC_API(2,0) EC_Point final
       /**
       * Equality operator
       */
-      bool operator==(const EC_Point& other) const;
+      bool operator==(const PointGFp& other) const;
 
       /**
       * Point addition
       * @param other the point to add to *this
       * @param workspace temp space, at least WORKSPACE_SIZE elements
       */
-      void add(const EC_Point& other, std::vector<BigInt>& workspace)
+      void add(const PointGFp& other, std::vector<BigInt>& workspace)
          {
          BOTAN_ARG_CHECK(m_curve == other.m_curve, "cannot add points on different curves");
 
@@ -226,7 +226,7 @@ class BOTAN_PUBLIC_API(2,0) EC_Point final
       * @param other affine point to add - assumed to be affine!
       * @param workspace temp space, at least WORKSPACE_SIZE elements
       */
-      void add_affine(const EC_Point& other, std::vector<BigInt>& workspace)
+      void add_affine(const PointGFp& other, std::vector<BigInt>& workspace)
          {
          BOTAN_ASSERT_NOMSG(m_curve == other.m_curve);
          BOTAN_DEBUG_ASSERT(other.is_affine());
@@ -269,9 +269,9 @@ class BOTAN_PUBLIC_API(2,0) EC_Point final
       * @param workspace temp space, at least WORKSPACE_SIZE elements
       * @return other plus *this
       */
-      EC_Point plus(const EC_Point& other, std::vector<BigInt>& workspace) const
+      PointGFp plus(const PointGFp& other, std::vector<BigInt>& workspace) const
          {
-         EC_Point x = (*this);
+         PointGFp x = (*this);
          x.add(other, workspace);
          return x;
          }
@@ -281,9 +281,9 @@ class BOTAN_PUBLIC_API(2,0) EC_Point final
       * @param workspace temp space, at least WORKSPACE_SIZE elements
       * @return *this doubled
       */
-      EC_Point double_of(std::vector<BigInt>& workspace) const
+      PointGFp double_of(std::vector<BigInt>& workspace) const
          {
-         EC_Point x = (*this);
+         PointGFp x = (*this);
          x.mult2(workspace);
          return x;
          }
@@ -291,7 +291,7 @@ class BOTAN_PUBLIC_API(2,0) EC_Point final
       /**
       * Return the zero (aka infinite) point associated with this curve
       */
-      EC_Point zero() const { return EC_Point(m_curve); }
+      PointGFp zero() const { return PointGFp(m_curve); }
 
       /**
       * Return base curve of this point
@@ -312,7 +312,7 @@ class BOTAN_PUBLIC_API(2,0) EC_Point final
 * @param point the point value
 * @return scalar*point on the curve
 */
-BOTAN_PUBLIC_API(2,0) EC_Point operator*(const BigInt& scalar, const EC_Point& point);
+BOTAN_PUBLIC_API(2,0) PointGFp operator*(const BigInt& scalar, const PointGFp& point);
 
 /**
 * ECC point multiexponentiation - not constant time!
@@ -322,35 +322,35 @@ BOTAN_PUBLIC_API(2,0) EC_Point operator*(const BigInt& scalar, const EC_Point& p
 * @param z2 a scalar
 * @result (p1 * z1 + p2 * z2)
 */
-BOTAN_PUBLIC_API(2,0) EC_Point multi_exponentiate(
-   const EC_Point& p1, const BigInt& z1,
-   const EC_Point& p2, const BigInt& z2);
+BOTAN_PUBLIC_API(2,0) PointGFp multi_exponentiate(
+   const PointGFp& p1, const BigInt& z1,
+   const PointGFp& p2, const BigInt& z2);
 
 // relational operators
-inline bool operator!=(const EC_Point& lhs, const EC_Point& rhs)
+inline bool operator!=(const PointGFp& lhs, const PointGFp& rhs)
    {
    return !(rhs == lhs);
    }
 
 // arithmetic operators
-inline EC_Point operator-(const EC_Point& lhs)
+inline PointGFp operator-(const PointGFp& lhs)
    {
-   return EC_Point(lhs).negate();
+   return PointGFp(lhs).negate();
    }
 
-inline EC_Point operator+(const EC_Point& lhs, const EC_Point& rhs)
+inline PointGFp operator+(const PointGFp& lhs, const PointGFp& rhs)
    {
-   EC_Point tmp(lhs);
+   PointGFp tmp(lhs);
    return tmp += rhs;
    }
 
-inline EC_Point operator-(const EC_Point& lhs, const EC_Point& rhs)
+inline PointGFp operator-(const PointGFp& lhs, const PointGFp& rhs)
    {
-   EC_Point tmp(lhs);
+   PointGFp tmp(lhs);
    return tmp -= rhs;
    }
 
-inline EC_Point operator*(const EC_Point& point, const BigInt& scalar)
+inline PointGFp operator*(const PointGFp& point, const BigInt& scalar)
    {
    return scalar * point;
    }
@@ -359,7 +359,7 @@ inline EC_Point operator*(const EC_Point& point, const BigInt& scalar)
 * Perform point decoding
 * Use EC_Group::OS2ECP instead
 */
-EC_Point BOTAN_PUBLIC_API(2,0) OS2ECP(const uint8_t data[], size_t data_len,
+PointGFp BOTAN_PUBLIC_API(2,0) OS2ECP(const uint8_t data[], size_t data_len,
                                       const CurveGFp& curve);
 
 /**
@@ -378,20 +378,17 @@ std::pair<BigInt, BigInt> BOTAN_UNSTABLE_API OS2ECP(const uint8_t data[], size_t
                                                     const BigInt& curve_b);
 
 template<typename Alloc>
-EC_Point OS2ECP(const std::vector<uint8_t, Alloc>& data, const CurveGFp& curve)
+PointGFp OS2ECP(const std::vector<uint8_t, Alloc>& data, const CurveGFp& curve)
    { return OS2ECP(data.data(), data.size(), curve); }
 
-class EC_Point_Var_Point_Precompute;
-
-// The name used for this type in older versions
-typedef EC_Point PointGFp;
+class PointGFp_Var_Point_Precompute;
 
 }
 
 namespace std {
 
 template<>
-inline void swap<Botan::EC_Point>(Botan::EC_Point& x, Botan::EC_Point& y)
+inline void swap<Botan::PointGFp>(Botan::PointGFp& x, Botan::PointGFp& y)
    { x.swap(y); }
 
 }
diff --git a/src/lib/pubkey/ec_group/point_mul.cpp b/src/lib/pubkey/ec_group/point_mul.cpp
index 9848b6831..8d4441983 100644
--- a/src/lib/pubkey/ec_group/point_mul.cpp
+++ b/src/lib/pubkey/ec_group/point_mul.cpp
@@ -21,20 +21,20 @@ size_t blinding_size(const BigInt& group_order)
 
 }
 
-EC_Point multi_exponentiate(const EC_Point& x, const BigInt& z1,
-                            const EC_Point& y, const BigInt& z2)
+PointGFp multi_exponentiate(const PointGFp& x, const BigInt& z1,
+                            const PointGFp& y, const BigInt& z2)
    {
-   EC_Point_Multi_Point_Precompute xy_mul(x, y);
+   PointGFp_Multi_Point_Precompute xy_mul(x, y);
    return xy_mul.multi_exp(z1, z2);
    }
 
-EC_Point_Base_Point_Precompute::EC_Point_Base_Point_Precompute(const EC_Point& base,
+PointGFp_Base_Point_Precompute::PointGFp_Base_Point_Precompute(const PointGFp& base,
                                                                const Modular_Reducer& mod_order) :
    m_base_point(base),
    m_mod_order(mod_order),
    m_p_words(base.get_curve().get_p().sig_words())
    {
-   std::vector<BigInt> ws(EC_Point::WORKSPACE_SIZE);
+   std::vector<BigInt> ws(PointGFp::WORKSPACE_SIZE);
 
    const size_t p_bits = base.get_curve().get_p().bits();
 
@@ -45,10 +45,10 @@ EC_Point_Base_Point_Precompute::EC_Point_Base_Point_Precompute(const EC_Point& b
    */
    const size_t T_bits = round_up(p_bits + blinding_size(mod_order.get_modulus()) + 1, WINDOW_BITS) / WINDOW_BITS;
 
-   std::vector<EC_Point> T(WINDOW_SIZE*T_bits);
+   std::vector<PointGFp> T(WINDOW_SIZE*T_bits);
 
-   EC_Point g = base;
-   EC_Point g2, g4;
+   PointGFp g = base;
+   PointGFp g2, g4;
 
    for(size_t i = 0; i != T_bits; i++)
       {
@@ -69,7 +69,7 @@ EC_Point_Base_Point_Precompute::EC_Point_Base_Point_Precompute(const EC_Point& b
       g.mult2(ws);
       }
 
-   EC_Point::force_all_affine(T, ws[0].get_word_vector());
+   PointGFp::force_all_affine(T, ws[0].get_word_vector());
 
    m_W.resize(T.size() * 2 * m_p_words);
 
@@ -83,13 +83,13 @@ EC_Point_Base_Point_Precompute::EC_Point_Base_Point_Precompute(const EC_Point& b
       }
    }
 
-EC_Point EC_Point_Base_Point_Precompute::mul(const BigInt& k,
+PointGFp PointGFp_Base_Point_Precompute::mul(const BigInt& k,
                                              RandomNumberGenerator& rng,
                                              const BigInt& group_order,
                                              std::vector<BigInt>& ws) const
    {
    if(k.is_negative())
-      throw Invalid_Argument("EC_Point_Base_Point_Precompute scalar must be positive");
+      throw Invalid_Argument("PointGFp_Base_Point_Precompute scalar must be positive");
 
    // Instead of reducing k mod group order should we alter the mask size??
    BigInt scalar = m_mod_order.reduce(k);
@@ -121,10 +121,10 @@ EC_Point EC_Point_Base_Point_Precompute::mul(const BigInt& k,
    BOTAN_ASSERT(windows <= m_W.size() / (3*elem_size),
                 "Precomputed sufficient values for scalar mult");
 
-   EC_Point R = m_base_point.zero();
+   PointGFp R = m_base_point.zero();
 
-   if(ws.size() < EC_Point::WORKSPACE_SIZE)
-      ws.resize(EC_Point::WORKSPACE_SIZE);
+   if(ws.size() < PointGFp::WORKSPACE_SIZE)
+      ws.resize(PointGFp::WORKSPACE_SIZE);
 
    // the precomputed multiples are not secret so use std::vector
    std::vector<word> Wt(elem_size);
@@ -176,17 +176,17 @@ EC_Point EC_Point_Base_Point_Precompute::mul(const BigInt& k,
    return R;
    }
 
-EC_Point_Var_Point_Precompute::EC_Point_Var_Point_Precompute(const EC_Point& point,
+PointGFp_Var_Point_Precompute::PointGFp_Var_Point_Precompute(const PointGFp& point,
                                                              RandomNumberGenerator& rng,
                                                              std::vector<BigInt>& ws) :
    m_curve(point.get_curve()),
    m_p_words(m_curve.get_p().sig_words()),
    m_window_bits(4)
    {
-   if(ws.size() < EC_Point::WORKSPACE_SIZE)
-      ws.resize(EC_Point::WORKSPACE_SIZE);
+   if(ws.size() < PointGFp::WORKSPACE_SIZE)
+      ws.resize(PointGFp::WORKSPACE_SIZE);
 
-   std::vector<EC_Point> U(static_cast<size_t>(1) << m_window_bits);
+   std::vector<PointGFp> U(static_cast<size_t>(1) << m_window_bits);
    U[0] = point.zero();
    U[1] = point;
 
@@ -241,15 +241,15 @@ EC_Point_Var_Point_Precompute::EC_Point_Var_Point_Precompute(const EC_Point& poi
       }
    }
 
-EC_Point EC_Point_Var_Point_Precompute::mul(const BigInt& k,
+PointGFp PointGFp_Var_Point_Precompute::mul(const BigInt& k,
                                             RandomNumberGenerator& rng,
                                             const BigInt& group_order,
                                             std::vector<BigInt>& ws) const
    {
    if(k.is_negative())
-      throw Invalid_Argument("EC_Point_Var_Point_Precompute scalar must be positive");
-   if(ws.size() < EC_Point::WORKSPACE_SIZE)
-      ws.resize(EC_Point::WORKSPACE_SIZE);
+      throw Invalid_Argument("PointGFp_Var_Point_Precompute scalar must be positive");
+   if(ws.size() < PointGFp::WORKSPACE_SIZE)
+      ws.resize(PointGFp::WORKSPACE_SIZE);
 
    // Choose a small mask m and use k' = k + m*order (Coron's 1st countermeasure)
    const BigInt mask(rng, blinding_size(group_order), false);
@@ -259,7 +259,7 @@ EC_Point EC_Point_Var_Point_Precompute::mul(const BigInt& k,
    const size_t window_elems = static_cast<size_t>(1) << m_window_bits;
 
    size_t windows = round_up(scalar.bits(), m_window_bits) / m_window_bits;
-   EC_Point R(m_curve);
+   PointGFp R(m_curve);
    secure_vector<word> e(elem_size);
 
    if(windows > 0)
@@ -317,8 +317,8 @@ EC_Point EC_Point_Var_Point_Precompute::mul(const BigInt& k,
    }
 
 
-EC_Point_Multi_Point_Precompute::EC_Point_Multi_Point_Precompute(const EC_Point& x,
-                                                                 const EC_Point& y)
+PointGFp_Multi_Point_Precompute::PointGFp_Multi_Point_Precompute(const PointGFp& x,
+                                                                 const PointGFp& y)
    {
    if(x.on_the_curve() == false || y.on_the_curve() == false)
       {
@@ -326,17 +326,17 @@ EC_Point_Multi_Point_Precompute::EC_Point_Multi_Point_Precompute(const EC_Point&
       return;
       }
 
-   std::vector<BigInt> ws(EC_Point::WORKSPACE_SIZE);
+   std::vector<BigInt> ws(PointGFp::WORKSPACE_SIZE);
 
-   EC_Point x2 = x;
+   PointGFp x2 = x;
    x2.mult2(ws);
 
-   const EC_Point x3(x2.plus(x, ws));
+   const PointGFp x3(x2.plus(x, ws));
 
-   EC_Point y2 = y;
+   PointGFp y2 = y;
    y2.mult2(ws);
 
-   const EC_Point y3(y2.plus(y, ws));
+   const PointGFp y3(y2.plus(y, ws));
 
    m_M.reserve(15);
 
@@ -368,23 +368,23 @@ EC_Point_Multi_Point_Precompute::EC_Point_Multi_Point_Precompute(const EC_Point&
 
    if(no_infinity)
       {
-      EC_Point::force_all_affine(m_M, ws[0].get_word_vector());
+      PointGFp::force_all_affine(m_M, ws[0].get_word_vector());
       }
 
    m_no_infinity = no_infinity;
    }
 
-EC_Point EC_Point_Multi_Point_Precompute::multi_exp(const BigInt& z1,
+PointGFp PointGFp_Multi_Point_Precompute::multi_exp(const BigInt& z1,
                                                     const BigInt& z2) const
    {
    if(m_M.size() == 1)
       return m_M[0];
 
-   std::vector<BigInt> ws(EC_Point::WORKSPACE_SIZE);
+   std::vector<BigInt> ws(PointGFp::WORKSPACE_SIZE);
 
    const size_t z_bits = round_up(std::max(z1.bits(), z2.bits()), 2);
 
-   EC_Point H = m_M[0].zero();
+   PointGFp H = m_M[0].zero();
 
    for(size_t i = 0; i != z_bits; i += 2)
       {
diff --git a/src/lib/pubkey/ec_group/point_mul.h b/src/lib/pubkey/ec_group/point_mul.h
index ffae2c5ab..095620428 100644
--- a/src/lib/pubkey/ec_group/point_mul.h
+++ b/src/lib/pubkey/ec_group/point_mul.h
@@ -7,24 +7,24 @@
 #ifndef BOTAN_POINT_MUL_H_
 #define BOTAN_POINT_MUL_H_
 
-#include <botan/ec_point.h>
+#include <botan/point_gfp.h>
 
 namespace Botan {
 
 class Modular_Reducer;
 
-class EC_Point_Base_Point_Precompute final
+class PointGFp_Base_Point_Precompute final
    {
    public:
-      EC_Point_Base_Point_Precompute(const EC_Point& base_point,
+      PointGFp_Base_Point_Precompute(const PointGFp& base_point,
                                      const Modular_Reducer& mod_order);
 
-      EC_Point mul(const BigInt& k,
+      PointGFp mul(const BigInt& k,
                    RandomNumberGenerator& rng,
                    const BigInt& group_order,
                    std::vector<BigInt>& ws) const;
    private:
-      const EC_Point& m_base_point;
+      const PointGFp& m_base_point;
       const Modular_Reducer& m_mod_order;
 
       enum { WINDOW_BITS = 3 };
@@ -38,14 +38,14 @@ class EC_Point_Base_Point_Precompute final
       std::vector<word> m_W;
    };
 
-class EC_Point_Var_Point_Precompute final
+class PointGFp_Var_Point_Precompute final
    {
    public:
-      EC_Point_Var_Point_Precompute(const EC_Point& point,
+      PointGFp_Var_Point_Precompute(const PointGFp& point,
                                     RandomNumberGenerator& rng,
                                     std::vector<BigInt>& ws);
 
-      EC_Point mul(const BigInt& k,
+      PointGFp mul(const BigInt& k,
                    RandomNumberGenerator& rng,
                    const BigInt& group_order,
                    std::vector<BigInt>& ws) const;
@@ -63,20 +63,20 @@ class EC_Point_Var_Point_Precompute final
       secure_vector<word> m_T;
    };
 
-class EC_Point_Multi_Point_Precompute final
+class PointGFp_Multi_Point_Precompute final
    {
    public:
-      EC_Point_Multi_Point_Precompute(const EC_Point& g1,
-                                      const EC_Point& g2);
+      PointGFp_Multi_Point_Precompute(const PointGFp& g1,
+                                      const PointGFp& g2);
 
       /*
       * Return (g1*k1 + g2*k2)
       * Not constant time, intended to use with public inputs
       */
-      EC_Point multi_exp(const BigInt& k1,
+      PointGFp multi_exp(const BigInt& k1,
                          const BigInt& k2) const;
    private:
-      std::vector<EC_Point> m_M;
+      std::vector<PointGFp> m_M;
       bool m_no_infinity;
    };
 
diff --git a/src/lib/pubkey/ec_h2c/ec_h2c.cpp b/src/lib/pubkey/ec_h2c/ec_h2c.cpp
index 968b8c247..d2e79a316 100644
--- a/src/lib/pubkey/ec_h2c/ec_h2c.cpp
+++ b/src/lib/pubkey/ec_h2c/ec_h2c.cpp
@@ -126,7 +126,7 @@ BigInt ct_choose(bool first, const BigInt& x, const BigInt& y)
    return z;
    }
 
-EC_Point map_to_curve_sswu(const EC_Group& group, const Modular_Reducer& mod_p, const BigInt& u)
+PointGFp map_to_curve_sswu(const EC_Group& group, const Modular_Reducer& mod_p, const BigInt& u)
    {
    const BigInt& p = group.get_p();
    const BigInt& A = group.get_a();
@@ -181,7 +181,7 @@ EC_Point map_to_curve_sswu(const EC_Group& group, const Modular_Reducer& mod_p,
 
 }
 
-EC_Point hash_to_curve_sswu(const EC_Group& group,
+PointGFp hash_to_curve_sswu(const EC_Group& group,
                             const std::string& hash_fn,
                             const uint8_t input[],
                             size_t input_len,
@@ -197,7 +197,7 @@ EC_Point hash_to_curve_sswu(const EC_Group& group,
                                 input, input_len,
                                 domain_sep, domain_sep_len);
 
-   EC_Point pt = map_to_curve_sswu(group, mod_p, u[0]);
+   PointGFp pt = map_to_curve_sswu(group, mod_p, u[0]);
 
    for(size_t i = 1; i != u.size(); ++i)
       pt += map_to_curve_sswu(group, mod_p, u[i]);
diff --git a/src/lib/pubkey/ec_h2c/ec_h2c.h b/src/lib/pubkey/ec_h2c/ec_h2c.h
index 8dba5dbc8..f932e76a5 100644
--- a/src/lib/pubkey/ec_h2c/ec_h2c.h
+++ b/src/lib/pubkey/ec_h2c/ec_h2c.h
@@ -8,7 +8,7 @@
 #define BOTAN_ECC_HASH_TO_CURVE_H_
 
 #include <botan/types.h>
-#include <botan/ec_point.h>
+#include <botan/point_gfp.h>
 #include <string>
 
 namespace Botan {
@@ -34,7 +34,7 @@ void BOTAN_TEST_API expand_message_xmd(const std::string& hash_fn,
 * This method requires that the ECC group have (a*b) != 0
 * which excludes certain groups including secp256k1
 */
-EC_Point hash_to_curve_sswu(const EC_Group& group,
+PointGFp hash_to_curve_sswu(const EC_Group& group,
                             const std::string& hash_fn,
                             const uint8_t input[],
                             size_t input_len,
diff --git a/src/lib/pubkey/ecc_key/ecc_key.cpp b/src/lib/pubkey/ecc_key/ecc_key.cpp
index 67d526c25..d5afbbf07 100644
--- a/src/lib/pubkey/ecc_key/ecc_key.cpp
+++ b/src/lib/pubkey/ecc_key/ecc_key.cpp
@@ -12,7 +12,7 @@
 #include <botan/der_enc.h>
 #include <botan/ber_dec.h>
 #include <botan/secmem.h>
-#include <botan/ec_point.h>
+#include <botan/point_gfp.h>
 #include <botan/internal/workfactor.h>
 
 namespace Botan {
@@ -40,7 +40,7 @@ EC_Group_Encoding default_encoding_for(EC_Group& group)
 }
 
 EC_PublicKey::EC_PublicKey(const EC_Group& dom_par,
-                           const EC_Point& pub_point) :
+                           const PointGFp& pub_point) :
    m_domain_params(dom_par),
    m_public_key(pub_point),
    m_domain_encoding(default_encoding_for(m_domain_params))
@@ -77,11 +77,11 @@ std::vector<uint8_t> EC_PublicKey::public_key_bits() const
    return public_point().encode(point_encoding());
    }
 
-void EC_PublicKey::set_point_encoding(EC_Point::Compression_Type enc)
+void EC_PublicKey::set_point_encoding(PointGFp::Compression_Type enc)
    {
-   if(enc != EC_Point::COMPRESSED &&
-      enc != EC_Point::UNCOMPRESSED &&
-      enc != EC_Point::HYBRID)
+   if(enc != PointGFp::COMPRESSED &&
+      enc != PointGFp::UNCOMPRESSED &&
+      enc != PointGFp::HYBRID)
       throw Invalid_Argument("Invalid point encoding for EC_PublicKey");
 
    m_point_encoding = enc;
@@ -147,7 +147,7 @@ secure_vector<uint8_t> EC_PrivateKey::private_key_bits() const
          .encode(static_cast<size_t>(1))
          .encode(BigInt::encode_1363(m_private_key, m_private_key.bytes()), ASN1_Type::OctetString)
          .start_explicit_context_specific(1)
-            .encode(m_public_key.encode(EC_Point::Compression_Type::UNCOMPRESSED), ASN1_Type::BitString)
+            .encode(m_public_key.encode(PointGFp::Compression_Type::UNCOMPRESSED), ASN1_Type::BitString)
          .end_cons()
       .end_cons()
       .get_contents();
diff --git a/src/lib/pubkey/ecc_key/ecc_key.h b/src/lib/pubkey/ecc_key/ecc_key.h
index 271cca665..9969700fb 100644
--- a/src/lib/pubkey/ecc_key/ecc_key.h
+++ b/src/lib/pubkey/ecc_key/ecc_key.h
@@ -38,7 +38,7 @@ class BOTAN_PUBLIC_API(2,0) EC_PublicKey : public virtual Public_Key
       * domain parameters of this point are not set
       * @result the public point of this key
       */
-      const EC_Point& public_point() const { return m_public_key; }
+      const PointGFp& public_point() const { return m_public_key; }
 
       AlgorithmIdentifier algorithm_identifier() const override;
 
@@ -65,7 +65,7 @@ class BOTAN_PUBLIC_API(2,0) EC_PublicKey : public virtual Public_Key
       * Set the point encoding method to be used when encoding this key.
       * @param enc the encoding to use
       */
-      void set_point_encoding(EC_Point::Compression_Type enc);
+      void set_point_encoding(PointGFp::Compression_Type enc);
 
       /**
       * Return the DER encoding of this keys domain in whatever format
@@ -85,7 +85,7 @@ class BOTAN_PUBLIC_API(2,0) EC_PublicKey : public virtual Public_Key
       * Get the point encoding method to be used when encoding this key.
       * @result the encoding to use
       */
-      EC_Point::Compression_Type point_encoding() const
+      PointGFp::Compression_Type point_encoding() const
          { return m_point_encoding; }
 
       size_t key_length() const override;
@@ -98,7 +98,7 @@ class BOTAN_PUBLIC_API(2,0) EC_PublicKey : public virtual Public_Key
       * @param pub_point public point on the curve
       */
       EC_PublicKey(const EC_Group& dom_par,
-                   const EC_Point& pub_point);
+                   const PointGFp& pub_point);
 
       /**
       * Load a public key.
@@ -112,9 +112,9 @@ class BOTAN_PUBLIC_API(2,0) EC_PublicKey : public virtual Public_Key
       {}
 
       EC_Group m_domain_params;
-      EC_Point m_public_key;
+      PointGFp m_public_key;
       EC_Group_Encoding m_domain_encoding;
-      EC_Point::Compression_Type m_point_encoding = EC_Point::UNCOMPRESSED;
+      PointGFp::Compression_Type m_point_encoding = PointGFp::UNCOMPRESSED;
    };
 
 /**
diff --git a/src/lib/pubkey/ecdh/ecdh.cpp b/src/lib/pubkey/ecdh/ecdh.cpp
index 0a6474b96..585bc4a87 100644
--- a/src/lib/pubkey/ecdh/ecdh.cpp
+++ b/src/lib/pubkey/ecdh/ecdh.cpp
@@ -39,10 +39,10 @@ class ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
 
       secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) override
          {
-         EC_Point input_point = m_group.get_cofactor() * m_group.OS2ECP(w, w_len);
+         PointGFp input_point = m_group.get_cofactor() * m_group.OS2ECP(w, w_len);
          input_point.randomize_repr(m_rng);
 
-         const EC_Point S = m_group.blinded_var_point_multiply(
+         const PointGFp S = m_group.blinded_var_point_multiply(
             input_point, m_l_times_priv, m_rng, m_ws);
 
          if(S.on_the_curve() == false)
diff --git a/src/lib/pubkey/ecdh/ecdh.h b/src/lib/pubkey/ecdh/ecdh.h
index 328ab884c..4a6061e1a 100644
--- a/src/lib/pubkey/ecdh/ecdh.h
+++ b/src/lib/pubkey/ecdh/ecdh.h
@@ -35,7 +35,7 @@ class BOTAN_PUBLIC_API(2,0) ECDH_PublicKey : public virtual EC_PublicKey
       * @param public_point the public point defining this key
       */
       ECDH_PublicKey(const EC_Group& dom_par,
-                     const EC_Point& public_point) :
+                     const PointGFp& public_point) :
          EC_PublicKey(dom_par, public_point) {}
 
       /**
@@ -48,12 +48,12 @@ class BOTAN_PUBLIC_API(2,0) ECDH_PublicKey : public virtual EC_PublicKey
       * @return public point value
       */
       std::vector<uint8_t> public_value() const
-         { return public_point().encode(EC_Point::UNCOMPRESSED); }
+         { return public_point().encode(PointGFp::UNCOMPRESSED); }
 
       /**
       * @return public point value
       */
-      std::vector<uint8_t> public_value(EC_Point::Compression_Type format) const
+      std::vector<uint8_t> public_value(PointGFp::Compression_Type format) const
          { return public_point().encode(format); }
 
    protected:
@@ -92,9 +92,9 @@ class BOTAN_PUBLIC_API(2,0) ECDH_PrivateKey final : public ECDH_PublicKey,
       std::unique_ptr<Public_Key> public_key() const override;
 
       std::vector<uint8_t> public_value() const override
-         { return ECDH_PublicKey::public_value(EC_Point::UNCOMPRESSED); }
+         { return ECDH_PublicKey::public_value(PointGFp::UNCOMPRESSED); }
 
-      std::vector<uint8_t> public_value(EC_Point::Compression_Type type) const
+      std::vector<uint8_t> public_value(PointGFp::Compression_Type type) const
          { return ECDH_PublicKey::public_value(type); }
 
       std::unique_ptr<PK_Ops::Key_Agreement>
diff --git a/src/lib/pubkey/ecdsa/ecdsa.cpp b/src/lib/pubkey/ecdsa/ecdsa.cpp
index c7b6be6ca..9b17b183e 100644
--- a/src/lib/pubkey/ecdsa/ecdsa.cpp
+++ b/src/lib/pubkey/ecdsa/ecdsa.cpp
@@ -23,7 +23,7 @@ namespace Botan {
 
 namespace {
 
-EC_Point recover_ecdsa_public_key(const EC_Group& group,
+PointGFp recover_ecdsa_public_key(const EC_Group& group,
                                   const std::vector<uint8_t>& msg,
                                   const BigInt& r,
                                   const BigInt& s,
@@ -58,13 +58,13 @@ EC_Point recover_ecdsa_public_key(const EC_Group& group,
       X[0] = 0x02 | y_odd;
       BigInt::encode_1363(&X[1], p_bytes, x);
 
-      const EC_Point R = group.OS2ECP(X);
+      const PointGFp R = group.OS2ECP(X);
 
       if((R*group_order).is_zero() == false)
          throw Decoding_Error("Unable to recover ECDSA public key");
 
       // Compute r_inv * (s*R - eG)
-      EC_Point_Multi_Point_Precompute RG_mul(R, group.get_base_point());
+      PointGFp_Multi_Point_Precompute RG_mul(R, group.get_base_point());
       const BigInt ne = group.mod_order(group_order - e);
       return r_inv * RG_mul.multi_exp(s, ne);
       }
@@ -94,7 +94,7 @@ uint8_t ECDSA_PublicKey::recovery_param(const std::vector<uint8_t>& msg,
       {
       try
          {
-         EC_Point R = recover_ecdsa_public_key(this->domain(), msg, r, s, v);
+         PointGFp R = recover_ecdsa_public_key(this->domain(), msg, r, s, v);
 
          if(R == this->public_point())
             {
@@ -228,7 +228,7 @@ class ECDSA_Verification_Operation final : public PK_Ops::Verification_with_EMSA
                   const uint8_t sig[], size_t sig_len) override;
    private:
       const EC_Group m_group;
-      const EC_Point_Multi_Point_Precompute m_gy_mul;
+      const PointGFp_Multi_Point_Precompute m_gy_mul;
    };
 
 bool ECDSA_Verification_Operation::verify(const uint8_t msg[], size_t msg_len,
@@ -253,7 +253,7 @@ bool ECDSA_Verification_Operation::verify(const uint8_t msg[], size_t msg_len,
 
    const BigInt u1 = m_group.multiply_mod_order(m_group.mod_order(e), w);
    const BigInt u2 = m_group.multiply_mod_order(r, w);
-   const EC_Point R = m_gy_mul.multi_exp(u1, u2);
+   const PointGFp R = m_gy_mul.multi_exp(u1, u2);
 
    if(R.is_zero())
       return false;
diff --git a/src/lib/pubkey/ecdsa/ecdsa.h b/src/lib/pubkey/ecdsa/ecdsa.h
index c5eeb0704..581d024e9 100644
--- a/src/lib/pubkey/ecdsa/ecdsa.h
+++ b/src/lib/pubkey/ecdsa/ecdsa.h
@@ -27,7 +27,7 @@ class BOTAN_PUBLIC_API(2,0) ECDSA_PublicKey : public virtual EC_PublicKey
       * @param public_point the public point defining this key
       */
       ECDSA_PublicKey(const EC_Group& dom_par,
-                      const EC_Point& public_point) :
+                      const PointGFp& public_point) :
          EC_PublicKey(dom_par, public_point) {}
 
       /**
diff --git a/src/lib/pubkey/ecgdsa/ecgdsa.cpp b/src/lib/pubkey/ecgdsa/ecgdsa.cpp
index 68ff9e7fe..073f4e91a 100644
--- a/src/lib/pubkey/ecgdsa/ecgdsa.cpp
+++ b/src/lib/pubkey/ecgdsa/ecgdsa.cpp
@@ -106,7 +106,7 @@ class ECGDSA_Verification_Operation final : public PK_Ops::Verification_with_EMS
                   const uint8_t sig[], size_t sig_len) override;
    private:
       const EC_Group m_group;
-      const EC_Point_Multi_Point_Precompute m_gy_mul;
+      const PointGFp_Multi_Point_Precompute m_gy_mul;
    };
 
 bool ECGDSA_Verification_Operation::verify(const uint8_t msg[], size_t msg_len,
@@ -127,7 +127,7 @@ bool ECGDSA_Verification_Operation::verify(const uint8_t msg[], size_t msg_len,
 
    const BigInt u1 = m_group.multiply_mod_order(e, w);
    const BigInt u2 = m_group.multiply_mod_order(s, w);
-   const EC_Point R = m_gy_mul.multi_exp(u1, u2);
+   const PointGFp R = m_gy_mul.multi_exp(u1, u2);
 
    if(R.is_zero())
       return false;
diff --git a/src/lib/pubkey/ecgdsa/ecgdsa.h b/src/lib/pubkey/ecgdsa/ecgdsa.h
index 98eb80ab9..ea8e912a3 100644
--- a/src/lib/pubkey/ecgdsa/ecgdsa.h
+++ b/src/lib/pubkey/ecgdsa/ecgdsa.h
@@ -25,7 +25,7 @@ class BOTAN_PUBLIC_API(2,0) ECGDSA_PublicKey : public virtual EC_PublicKey
       * @param public_point the public point defining this key
       */
       ECGDSA_PublicKey(const EC_Group& dom_par,
-                      const EC_Point& public_point) :
+                      const PointGFp& public_point) :
          EC_PublicKey(dom_par, public_point) {}
 
       /**
diff --git a/src/lib/pubkey/ecies/ecies.cpp b/src/lib/pubkey/ecies/ecies.cpp
index a1142c369..7a98fbf6e 100644
--- a/src/lib/pubkey/ecies/ecies.cpp
+++ b/src/lib/pubkey/ecies/ecies.cpp
@@ -73,10 +73,10 @@ class ECIES_ECDH_KA_Operation final : public PK_Ops::Key_Agreement_with_KDF
          {
          const EC_Group& group = m_key.domain();
 
-         EC_Point input_point = group.OS2ECP(w, w_len);
+         PointGFp input_point = group.OS2ECP(w, w_len);
          input_point.randomize_repr(m_rng);
 
-         const EC_Point S = group.blinded_var_point_multiply(
+         const PointGFp S = group.blinded_var_point_multiply(
             input_point, m_key.private_value(), m_rng, m_ws);
 
          if(S.on_the_curve() == false)
@@ -147,7 +147,7 @@ ECIES_KA_Operation::ECIES_KA_Operation(const PK_Key_Agreement_Key& private_key,
 * ECIES secret derivation according to ISO 18033-2
 */
 SymmetricKey ECIES_KA_Operation::derive_secret(const std::vector<uint8_t>& eph_public_key_bin,
-      const EC_Point& other_public_key_point) const
+      const PointGFp& other_public_key_point) const
    {
    if(other_public_key_point.is_zero())
       {
@@ -156,7 +156,7 @@ SymmetricKey ECIES_KA_Operation::derive_secret(const std::vector<uint8_t>& eph_p
 
    std::unique_ptr<KDF> kdf = KDF::create_or_throw(m_params.kdf_spec());
 
-   EC_Point other_point = other_public_key_point;
+   PointGFp other_point = other_public_key_point;
 
    // ISO 18033: step b
    if(m_params.old_cofactor_mode())
@@ -185,7 +185,7 @@ SymmetricKey ECIES_KA_Operation::derive_secret(const std::vector<uint8_t>& eph_p
 
 
 ECIES_KA_Params::ECIES_KA_Params(const EC_Group& domain, const std::string& kdf_spec, size_t length,
-                                 EC_Point::Compression_Type compression_type, ECIES_Flags flags) :
+                                 PointGFp::Compression_Type compression_type, ECIES_Flags flags) :
    m_domain(domain),
    m_kdf_spec(kdf_spec),
    m_length(length),
@@ -197,7 +197,7 @@ ECIES_KA_Params::ECIES_KA_Params(const EC_Group& domain, const std::string& kdf_
 ECIES_System_Params::ECIES_System_Params(const EC_Group& domain, const std::string& kdf_spec,
                                          const std::string& dem_algo_spec, size_t dem_key_len,
                                          const std::string& mac_spec, size_t mac_key_len,
-                                         EC_Point::Compression_Type compression_type, ECIES_Flags flags) :
+                                         PointGFp::Compression_Type compression_type, ECIES_Flags flags) :
    ECIES_KA_Params(domain, kdf_spec, dem_key_len + mac_key_len, compression_type, flags),
    m_dem_spec(dem_algo_spec),
    m_dem_keylen(dem_key_len),
@@ -214,7 +214,7 @@ ECIES_System_Params::ECIES_System_Params(const EC_Group& domain, const std::stri
 ECIES_System_Params::ECIES_System_Params(const EC_Group& domain, const std::string& kdf_spec,
                                          const std::string& dem_algo_spec, size_t dem_key_len,
                                          const std::string& mac_spec, size_t mac_key_len) :
-   ECIES_System_Params(domain, kdf_spec, dem_algo_spec, dem_key_len, mac_spec, mac_key_len, EC_Point::UNCOMPRESSED,
+   ECIES_System_Params(domain, kdf_spec, dem_algo_spec, dem_key_len, mac_spec, mac_key_len, PointGFp::UNCOMPRESSED,
                          ECIES_Flags::NONE)
    {
    }
@@ -243,7 +243,7 @@ ECIES_Encryptor::ECIES_Encryptor(const PK_Key_Agreement_Key& private_key,
    m_other_point(),
    m_label()
    {
-   if(ecies_params.compression_type() != EC_Point::UNCOMPRESSED)
+   if(ecies_params.compression_type() != PointGFp::UNCOMPRESSED)
       {
       // ISO 18033: step d
       // convert only if necessary; m_eph_public_key_bin has been initialized with the uncompressed format
@@ -370,7 +370,7 @@ secure_vector<uint8_t> ECIES_Decryptor::do_decrypt(uint8_t& valid_mask, const ui
    const std::vector<uint8_t> mac_data(in + in_len - m_mac->output_length(), in + in_len);
 
    // ISO 18033: step a
-   EC_Point other_public_key = m_params.domain().OS2ECP(other_public_key_bin);
+   PointGFp other_public_key = m_params.domain().OS2ECP(other_public_key_bin);
 
    // ISO 18033: step b
    if(m_params.check_mode() && !other_public_key.on_the_curve())
diff --git a/src/lib/pubkey/ecies/ecies.h b/src/lib/pubkey/ecies/ecies.h
index 8e9f684a5..af2a0c312 100644
--- a/src/lib/pubkey/ecies/ecies.h
+++ b/src/lib/pubkey/ecies/ecies.h
@@ -11,7 +11,7 @@
 #include <botan/ecdh.h>
 #include <botan/ec_group.h>
 #include <botan/cipher_mode.h>
-#include <botan/ec_point.h>
+#include <botan/point_gfp.h>
 #include <botan/pubkey.h>
 #include <botan/secmem.h>
 #include <botan/symkey.h>
@@ -65,7 +65,7 @@ class BOTAN_PUBLIC_API(2,0) ECIES_KA_Params
       * @param flags options, see documentation of ECIES_Flags
       */
       ECIES_KA_Params(const EC_Group& domain, const std::string& kdf_spec, size_t length,
-                      EC_Point::Compression_Type compression_type, ECIES_Flags flags);
+                      PointGFp::Compression_Type compression_type, ECIES_Flags flags);
 
       ECIES_KA_Params(const ECIES_KA_Params&) = default;
       ECIES_KA_Params& operator=(const ECIES_KA_Params&) = delete;
@@ -102,7 +102,7 @@ class BOTAN_PUBLIC_API(2,0) ECIES_KA_Params
          return (m_flags & ECIES_Flags::CHECK_MODE) == ECIES_Flags::CHECK_MODE;
          }
 
-      inline EC_Point::Compression_Type compression_type() const
+      inline PointGFp::Compression_Type compression_type() const
          {
          return m_compression_mode;
          }
@@ -116,7 +116,7 @@ class BOTAN_PUBLIC_API(2,0) ECIES_KA_Params
       const EC_Group m_domain;
       const std::string m_kdf_spec;
       const size_t m_length;
-      const EC_Point::Compression_Type m_compression_mode;
+      const PointGFp::Compression_Type m_compression_mode;
       const ECIES_Flags m_flags;
    };
 
@@ -147,7 +147,7 @@ class BOTAN_PUBLIC_API(2,0) ECIES_System_Params final : public ECIES_KA_Params
       */
       ECIES_System_Params(const EC_Group& domain, const std::string& kdf_spec, const std::string& dem_algo_spec,
                           size_t dem_key_len, const std::string& mac_spec, size_t mac_key_len,
-                          EC_Point::Compression_Type compression_type, ECIES_Flags flags);
+                          PointGFp::Compression_Type compression_type, ECIES_Flags flags);
 
       ECIES_System_Params(const ECIES_System_Params&) = default;
       ECIES_System_Params& operator=(const ECIES_System_Params&) = delete;
@@ -203,7 +203,7 @@ class BOTAN_PUBLIC_API(2,0) ECIES_KA_Operation
       * @param other_public_key_point public key point of the other party
       */
       SymmetricKey derive_secret(const std::vector<uint8_t>& eph_public_key_bin,
-                                 const EC_Point& other_public_key_point) const;
+                                 const PointGFp& other_public_key_point) const;
 
    private:
       const PK_Key_Agreement m_ka;
@@ -234,7 +234,7 @@ class BOTAN_PUBLIC_API(2,0) ECIES_Encryptor final : public PK_Encryptor
       ECIES_Encryptor(RandomNumberGenerator& rng, const ECIES_System_Params& ecies_params);
 
       /// Set the public key of the other party
-      inline void set_other_key(const EC_Point& public_point)
+      inline void set_other_key(const PointGFp& public_point)
          {
          m_other_point = public_point;
          }
@@ -264,7 +264,7 @@ class BOTAN_PUBLIC_API(2,0) ECIES_Encryptor final : public PK_Encryptor
       std::unique_ptr<Cipher_Mode> m_cipher;
       std::vector<uint8_t> m_eph_public_key_bin;
       InitializationVector m_iv;
-      EC_Point m_other_point;
+      PointGFp m_other_point;
       std::vector<uint8_t> m_label;
    };
 
diff --git a/src/lib/pubkey/eckcdsa/eckcdsa.cpp b/src/lib/pubkey/eckcdsa/eckcdsa.cpp
index fa5a86769..2be547545 100644
--- a/src/lib/pubkey/eckcdsa/eckcdsa.cpp
+++ b/src/lib/pubkey/eckcdsa/eckcdsa.cpp
@@ -170,7 +170,7 @@ class ECKCDSA_Verification_Operation final : public PK_Ops::Verification_with_EM
                   const uint8_t sig[], size_t sig_len) override;
    private:
       const EC_Group m_group;
-      const EC_Point_Multi_Point_Precompute m_gy_mul;
+      const PointGFp_Multi_Point_Precompute m_gy_mul;
       secure_vector<uint8_t> m_prefix;
    };
 
@@ -203,7 +203,7 @@ bool ECKCDSA_Verification_Operation::verify(const uint8_t msg[], size_t /*msg_le
    BigInt w(r_xor_e.data(), r_xor_e.size());
    w = m_group.mod_order(w);
 
-   const EC_Point q = m_gy_mul.multi_exp(w, s);
+   const PointGFp q = m_gy_mul.multi_exp(w, s);
    if(q.is_zero())
       {
       return false;
diff --git a/src/lib/pubkey/eckcdsa/eckcdsa.h b/src/lib/pubkey/eckcdsa/eckcdsa.h
index f6af431d0..ebf5ada30 100644
--- a/src/lib/pubkey/eckcdsa/eckcdsa.h
+++ b/src/lib/pubkey/eckcdsa/eckcdsa.h
@@ -25,7 +25,7 @@ class BOTAN_PUBLIC_API(2,0) ECKCDSA_PublicKey : public virtual EC_PublicKey
       * @param public_point the public point defining this key
       */
       ECKCDSA_PublicKey(const EC_Group& dom_par,
-                      const EC_Point& public_point) :
+                      const PointGFp& public_point) :
          EC_PublicKey(dom_par, public_point) {}
 
       /**
diff --git a/src/lib/pubkey/gost_3410/gost_3410.cpp b/src/lib/pubkey/gost_3410/gost_3410.cpp
index 09db1f5a7..8ae2dea90 100644
--- a/src/lib/pubkey/gost_3410/gost_3410.cpp
+++ b/src/lib/pubkey/gost_3410/gost_3410.cpp
@@ -202,7 +202,7 @@ class GOST_3410_Verification_Operation final : public PK_Ops::Verification_with_
                   const uint8_t sig[], size_t sig_len) override;
    private:
       const EC_Group m_group;
-      const EC_Point_Multi_Point_Precompute m_gy_mul;
+      const PointGFp_Multi_Point_Precompute m_gy_mul;
    };
 
 bool GOST_3410_Verification_Operation::verify(const uint8_t msg[], size_t msg_len,
@@ -229,7 +229,7 @@ bool GOST_3410_Verification_Operation::verify(const uint8_t msg[], size_t msg_le
    const BigInt z1 = m_group.multiply_mod_order(s, v);
    const BigInt z2 = m_group.multiply_mod_order(-r, v);
 
-   const EC_Point R = m_gy_mul.multi_exp(z1, z2);
+   const PointGFp R = m_gy_mul.multi_exp(z1, z2);
 
    if(R.is_zero())
      return false;
diff --git a/src/lib/pubkey/gost_3410/gost_3410.h b/src/lib/pubkey/gost_3410/gost_3410.h
index 0e3b8ce47..ecaf0aa36 100644
--- a/src/lib/pubkey/gost_3410/gost_3410.h
+++ b/src/lib/pubkey/gost_3410/gost_3410.h
@@ -27,7 +27,7 @@ class BOTAN_PUBLIC_API(2,0) GOST_3410_PublicKey : public virtual EC_PublicKey
       * @param public_point the public point defining this key
       */
       GOST_3410_PublicKey(const EC_Group& dom_par,
-                          const EC_Point& public_point) :
+                          const PointGFp& public_point) :
          EC_PublicKey(dom_par, public_point) {}
 
       /**
diff --git a/src/lib/pubkey/sm2/sm2.cpp b/src/lib/pubkey/sm2/sm2.cpp
index df8ffb880..a25aa1516 100644
--- a/src/lib/pubkey/sm2/sm2.cpp
+++ b/src/lib/pubkey/sm2/sm2.cpp
@@ -57,7 +57,7 @@ SM2_PrivateKey::SM2_PrivateKey(RandomNumberGenerator& rng,
 std::vector<uint8_t> sm2_compute_za(HashFunction& hash,
                                     const std::string& user_id,
                                     const EC_Group& domain,
-                                    const EC_Point& pubkey)
+                                    const PointGFp& pubkey)
    {
    if(user_id.size() >= 8192)
       throw Invalid_Argument("SM2 user id too long to represent");
@@ -204,7 +204,7 @@ class SM2_Verification_Operation final : public PK_Ops::Verification
       bool is_valid_signature(const uint8_t sig[], size_t sig_len) override;
    private:
       const EC_Group m_group;
-      const EC_Point_Multi_Point_Precompute m_gy_mul;
+      const PointGFp_Multi_Point_Precompute m_gy_mul;
       secure_vector<uint8_t> m_digest;
       std::vector<uint8_t> m_za;
       std::unique_ptr<HashFunction> m_hash;
@@ -239,7 +239,7 @@ bool SM2_Verification_Operation::is_valid_signature(const uint8_t sig[], size_t
    if(t == 0)
       return false;
 
-   const EC_Point R = m_gy_mul.multi_exp(s, t);
+   const PointGFp R = m_gy_mul.multi_exp(s, t);
 
    // ???
    if(R.is_zero())
diff --git a/src/lib/pubkey/sm2/sm2.h b/src/lib/pubkey/sm2/sm2.h
index 937f675e2..d2edf3d6f 100644
--- a/src/lib/pubkey/sm2/sm2.h
+++ b/src/lib/pubkey/sm2/sm2.h
@@ -25,7 +25,7 @@ class BOTAN_PUBLIC_API(2,2) SM2_PublicKey : public virtual EC_PublicKey
       * @param public_point the public point defining this key
       */
       SM2_PublicKey(const EC_Group& dom_par,
-                    const EC_Point& public_point) :
+                    const PointGFp& public_point) :
          EC_PublicKey(dom_par, public_point) {}
 
       /**
@@ -112,7 +112,7 @@ std::vector<uint8_t>
 BOTAN_PUBLIC_API(2,5) sm2_compute_za(HashFunction& hash,
                                      const std::string& user_id,
                                      const EC_Group& domain,
-                                     const EC_Point& pubkey);
+                                     const PointGFp& pubkey);
 
 // For compat with versions 2.2 - 2.7
 typedef SM2_PublicKey SM2_Signature_PublicKey;
diff --git a/src/lib/pubkey/sm2/sm2_enc.cpp b/src/lib/pubkey/sm2/sm2_enc.cpp
index 515f741a7..0a40b6a0a 100644
--- a/src/lib/pubkey/sm2/sm2_enc.cpp
+++ b/src/lib/pubkey/sm2/sm2_enc.cpp
@@ -25,7 +25,7 @@ class SM2_Encryption_Operation final : public PK_Ops::Encryption
                                const std::string& kdf_hash) :
          m_group(key.domain()),
          m_kdf_hash(kdf_hash),
-         m_ws(EC_Point::WORKSPACE_SIZE),
+         m_ws(PointGFp::WORKSPACE_SIZE),
          m_mul_public_point(key.public_point(), rng, m_ws)
          {
          std::unique_ptr<HashFunction> hash = HashFunction::create_or_throw(m_kdf_hash);
@@ -57,7 +57,7 @@ class SM2_Encryption_Operation final : public PK_Ops::Encryption
 
          const BigInt k = m_group.random_scalar(rng);
 
-         const EC_Point C1 = m_group.blinded_base_point_multiply(k, rng, m_ws);
+         const PointGFp C1 = m_group.blinded_base_point_multiply(k, rng, m_ws);
          const BigInt x1 = C1.get_affine_x();
          const BigInt y1 = C1.get_affine_y();
          std::vector<uint8_t> x1_bytes(p_bytes);
@@ -65,7 +65,7 @@ class SM2_Encryption_Operation final : public PK_Ops::Encryption
          BigInt::encode_1363(x1_bytes.data(), x1_bytes.size(), x1);
          BigInt::encode_1363(y1_bytes.data(), y1_bytes.size(), y1);
 
-         const EC_Point kPB = m_mul_public_point.mul(k, rng, m_group.get_order(), m_ws);
+         const PointGFp kPB = m_mul_public_point.mul(k, rng, m_group.get_order(), m_ws);
 
          const BigInt x2 = kPB.get_affine_x();
          const BigInt y2 = kPB.get_affine_y();
@@ -105,7 +105,7 @@ class SM2_Encryption_Operation final : public PK_Ops::Encryption
       const std::string m_kdf_hash;
 
       std::vector<BigInt> m_ws;
-      EC_Point_Var_Point_Precompute m_mul_public_point;
+      PointGFp_Var_Point_Precompute m_mul_public_point;
       size_t m_hash_size;
    };
 
@@ -183,7 +183,7 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption
          if(same_mem(recode_ctext.data(), ciphertext, ciphertext_len) == false)
             return secure_vector<uint8_t>();
 
-         EC_Point C1 = group.point(x1, y1);
+         PointGFp C1 = group.point(x1, y1);
          C1.randomize_repr(m_rng);
 
          // Here C1 is publically invalid, so no problem with early return:
@@ -195,7 +195,7 @@ class SM2_Decryption_Operation final : public PK_Ops::Decryption
             return secure_vector<uint8_t>();
             }
 
-         const EC_Point dbC1 = group.blinded_var_point_multiply(
+         const PointGFp dbC1 = group.blinded_var_point_multiply(
             C1, m_key.private_value(), m_rng, m_ws);
 
          const BigInt x2 = dbC1.get_affine_x();
diff --git a/src/lib/rng/rng.cpp b/src/lib/rng/rng.cpp
index 3619ad8fc..c4a521c88 100644
--- a/src/lib/rng/rng.cpp
+++ b/src/lib/rng/rng.cpp
@@ -9,6 +9,10 @@
 #include <botan/internal/loadstor.h>
 #include <botan/internal/os_utils.h>
 
+#if defined(BOTAN_HAS_AUTO_SEEDING_RNG)
+  #include <botan/auto_rng.h>
+#endif
+
 namespace Botan {
 
 void RandomNumberGenerator::randomize_with_ts_input(uint8_t output[], size_t output_len)
diff --git a/src/lib/rng/rng.h b/src/lib/rng/rng.h
index 2cda22562..811e6368b 100644
--- a/src/lib/rng/rng.h
+++ b/src/lib/rng/rng.h
@@ -242,6 +242,82 @@ class BOTAN_PUBLIC_API(2,0) Null_RNG final : public RandomNumberGenerator
       std::string name() const override { return "Null_RNG"; }
    };
 
+#if defined(BOTAN_TARGET_OS_HAS_THREADS)
+/**
+* Wraps access to a RNG in a mutex
+* Note that most of the time it's much better to use a RNG per thread
+* otherwise the RNG will act as an unnecessary contention point
+*
+* Since 2.16.0 all Stateful_RNG instances have an internal lock, so
+* this class is no longer needed. It will be removed in a future major
+* release.
+*/
+class BOTAN_PUBLIC_API(2,0) Serialized_RNG final : public RandomNumberGenerator
+   {
+   public:
+      void randomize(uint8_t out[], size_t len) override
+         {
+         lock_guard_type<mutex_type> lock(m_mutex);
+         m_rng->randomize(out, len);
+         }
+
+      bool accepts_input() const override
+         {
+         lock_guard_type<mutex_type> lock(m_mutex);
+         return m_rng->accepts_input();
+         }
+
+      bool is_seeded() const override
+         {
+         lock_guard_type<mutex_type> lock(m_mutex);
+         return m_rng->is_seeded();
+         }
+
+      void clear() override
+         {
+         lock_guard_type<mutex_type> lock(m_mutex);
+         m_rng->clear();
+         }
+
+      std::string name() const override
+         {
+         lock_guard_type<mutex_type> lock(m_mutex);
+         return m_rng->name();
+         }
+
+      size_t reseed(Entropy_Sources& src,
+                    size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS,
+                    std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override
+         {
+         lock_guard_type<mutex_type> lock(m_mutex);
+         return m_rng->reseed(src, poll_bits, poll_timeout);
+         }
+
+      void add_entropy(const uint8_t in[], size_t len) override
+         {
+         lock_guard_type<mutex_type> lock(m_mutex);
+         m_rng->add_entropy(in, len);
+         }
+
+      /**
+      * Since 2.16.0 this is no longer needed for any RNG type. This
+      * class will be removed in a future major release.
+      */
+      BOTAN_DEPRECATED("Use version accepting a unique_ptr")
+      explicit Serialized_RNG(RandomNumberGenerator* rng) : m_rng(rng) {}
+
+      /**
+      * Since 2.16.0 this is no longer needed for any RNG type. This
+      * class will be removed in a future major release.
+      */
+      explicit Serialized_RNG(std::unique_ptr<RandomNumberGenerator> rng) : m_rng(std::move(rng)) {}
+
+   private:
+      mutable mutex_type m_mutex;
+      std::unique_ptr<RandomNumberGenerator> m_rng;
+   };
+#endif
+
 }
 
 #endif
diff --git a/src/lib/tls/tls12/msg_server_kex.cpp b/src/lib/tls/tls12/msg_server_kex.cpp
index d7c1a52f8..92fc661c7 100644
--- a/src/lib/tls/tls12/msg_server_kex.cpp
+++ b/src/lib/tls/tls12/msg_server_kex.cpp
@@ -115,7 +115,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
          // follow client's preference for point compression
          ecdh_public_val = ecdh->public_value(
             state.client_hello()->prefers_compressed_ec_points() ?
-            EC_Point::COMPRESSED : EC_Point::UNCOMPRESSED);
+            PointGFp::COMPRESSED : PointGFp::UNCOMPRESSED);
 
          m_kex_key.reset(ecdh.release());
          }
diff --git a/src/lib/tls/tls13/tls_extensions_key_share.cpp b/src/lib/tls/tls13/tls_extensions_key_share.cpp
index d19deaef0..9990e13c8 100644
--- a/src/lib/tls/tls13/tls_extensions_key_share.cpp
+++ b/src/lib/tls/tls13/tls_extensions_key_share.cpp
@@ -82,7 +82,7 @@ class Key_Share_Entry
             //
             // Hence, we neither need to take Policy::use_ecc_point_compression() nor
             // ClientHello::prefers_compressed_ec_points() into account here.
-            m_key_exchange = skey->public_value(EC_Point::UNCOMPRESSED);
+            m_key_exchange = skey->public_value(PointGFp::UNCOMPRESSED);
             m_private_key = std::move(skey);
             }
          else if(is_dh(group))
diff --git a/src/lib/tls/tls_callbacks.cpp b/src/lib/tls/tls_callbacks.cpp
index bef32cc75..f6d08d1a7 100644
--- a/src/lib/tls/tls_callbacks.cpp
+++ b/src/lib/tls/tls_callbacks.cpp
@@ -223,7 +223,7 @@ std::pair<secure_vector<uint8_t>, std::vector<uint8_t>> TLS::Callbacks::tls_ecdh
       ECDH_PrivateKey priv_key(rng, group);
       PK_Key_Agreement ka(priv_key, rng, "Raw");
       ecdh_secret = ka.derive_key(0, peer_key.public_value()).bits_of();
-      our_public_value = priv_key.public_value(compressed ? EC_Point::COMPRESSED : EC_Point::UNCOMPRESSED);
+      our_public_value = priv_key.public_value(compressed ? PointGFp::COMPRESSED : PointGFp::UNCOMPRESSED);
       }
 
    return std::make_pair(ecdh_secret, our_public_value);
diff --git a/src/lib/utils/compiler.h b/src/lib/utils/compiler.h
index 50f65f7b2..2f24e30ad 100644
--- a/src/lib/utils/compiler.h
+++ b/src/lib/utils/compiler.h
@@ -50,19 +50,6 @@
 */
 #define BOTAN_TEST_API BOTAN_DLL
 
-/**
-* Used to annotate API exports which are exported but only for the
-* purposes of fuzzing. They should not be used by applications and
-* may be removed or changed without notice.
-*
-* They are only exported if the fuzzers are being built
-*/
-#if defined(BOTAN_FUZZERS_ARE_BEING_BUILT)
-  #define BOTAN_FUZZER_API BOTAN_DLL
-#else
-  #define BOTAN_FUZZER_API
-#endif
-
 /*
 * Define BOTAN_FUNC_ISA
 */
diff --git a/src/lib/utils/ct_utils.h b/src/lib/utils/ct_utils.h
index eaaa0d5f0..1499bf392 100644
--- a/src/lib/utils/ct_utils.h
+++ b/src/lib/utils/ct_utils.h
@@ -368,17 +368,6 @@ inline Mask<T> conditional_copy_mem(T cnd,
    return mask;
    }
 
-template<typename T>
-inline Mask<T> conditional_assign_mem(T cnd,
-                                      T* sink,
-                                      const T* src,
-                                      size_t elems)
-   {
-   const auto mask = CT::Mask<T>::expand(cnd);
-   mask.select_n(sink, src, sink, elems);
-   return mask;
-   }
-
 template<typename T>
 inline void conditional_swap(bool cnd, T& x, T& y)
    {
diff --git a/src/lib/utils/thread_utils/info.txt b/src/lib/utils/thread_utils/info.txt
index fd583a90f..7aeb364fb 100644
--- a/src/lib/utils/thread_utils/info.txt
+++ b/src/lib/utils/thread_utils/info.txt
@@ -9,7 +9,6 @@ name -> "Thread Utilities"
 <header:internal>
 rwlock.h
 barrier.h
-semaphore.h
 thread_pool.h
 </header:internal>
 
diff --git a/src/lib/utils/thread_utils/semaphore.cpp b/src/lib/utils/thread_utils/semaphore.cpp
deleted file mode 100644
index 0858a013f..000000000
--- a/src/lib/utils/thread_utils/semaphore.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-* Semaphore
-* (C) 2013 Joel Low
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/semaphore.h>
-
-// Based on code by Pierre Gaston (http://p9as.blogspot.com/2012/06/c11-semaphores.html)
-
-namespace Botan {
-
-void Semaphore::release(size_t n)
-   {
-   for(size_t i = 0; i != n; ++i)
-      {
-      std::lock_guard<std::mutex> lock(m_mutex);
-
-      if(m_value++ < 0)
-         {
-         ++m_wakeups;
-         m_cond.notify_one();
-         }
-      }
-   }
-
-void Semaphore::acquire()
-   {
-   std::unique_lock<std::mutex> lock(m_mutex);
-   if(m_value-- <= 0)
-       {
-       m_cond.wait(lock, [this] { return m_wakeups > 0; });
-       --m_wakeups;
-       }
-   }
-
-}
diff --git a/src/lib/utils/thread_utils/semaphore.h b/src/lib/utils/thread_utils/semaphore.h
deleted file mode 100644
index 538d9ecb5..000000000
--- a/src/lib/utils/thread_utils/semaphore.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-* Semaphore
-* (C) 2013 Joel Low
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_SEMAPHORE_H_
-#define BOTAN_SEMAPHORE_H_
-
-#include <condition_variable>
-#include <mutex>
-
-namespace Botan {
-
-class Semaphore final
-   {
-   public:
-      explicit Semaphore(int value = 0) : m_value(value), m_wakeups(0) {}
-
-      void acquire();
-
-      void release(size_t n = 1);
-
-   private:
-      int m_value;
-      int m_wakeups;
-      std::mutex m_mutex;
-      std::condition_variable m_cond;
-   };
-
-}
-
-#endif
diff --git a/src/scripts/monty.py b/src/scripts/monty.py
index 4442d550b..3f4d170c7 100755
--- a/src/scripts/monty.py
+++ b/src/scripts/monty.py
@@ -3,7 +3,7 @@
 import sys
 import datetime
 
-# (C) 2018,2023 Jack Lloyd
+# (C) 2018 Jack Lloyd
 # Botan is released under the Simplified BSD License (see license.txt)
 
 # Used to generate src/lib/math/mp/mp_monty_n.cpp
@@ -29,7 +29,7 @@ def monty_redc_code(n):
         lines.append("word3_muladd(&w2, &w1, &w0, ws[%d], p[0]);" % (i))
         lines.append("w0 = w1; w1 = w2; w2 = 0;")
 
-    for i in range(0, n - 1):
+    for i in range(0, n):
         for j in range(i + 1, n):
             lines.append("word3_muladd(&w2, &w1, &w0, ws[%d], p[%d]);" % (j, n + i-j))
 
@@ -37,15 +37,23 @@ def monty_redc_code(n):
         lines.append("ws[%d] = w0;" % (i))
         lines.append("w0 = w1; w1 = w2; w2 = 0;")
 
-    lines.append("word3_add(&w2, &w1, &w0, z[%d]);" % (2*n-1));
+    lines.append("word3_add(&w2, &w1, &w0, z[%d]);" % (2*(n+1) - 1))
 
-    lines.append("ws[%d] = w0;" % (n - 1))
-    lines.append("ws[%d] = w1;" % (n))
+    lines.append("ws[%d] = w0;" % (n))
+    lines.append("ws[%d] = w1;" % (n+1))
 
-    lines.append("word borrow = bigint_sub3(z, ws, %d + 1, p, %d);" % (n, n))
+    sub3_bound = 0
 
-    lines.append("CT::conditional_assign_mem(borrow, z, ws, %d);" % (n))
-    lines.append("clear_mem(z + %d, %d);" % (n, n))
+    if n >= sub3_bound:
+        lines.append("word borrow = 0;")
+        for i in range(n):
+            lines.append("ws[%d] = word_sub(ws[%d], p[%d], &borrow);" % (n + 1 + i, i, i))
+        lines.append("ws[%d] = word_sub(ws[%d], 0, &borrow);" % (2*n+1, n))
+    else:
+        lines.append("word borrow = bigint_sub3(ws + %d + 1, ws, %d + 1, p, %d);" % (n, n, n))
+
+    lines.append("CT::conditional_copy_mem(borrow, z, ws, ws + %d, %d);" % (n + 1, n + 1))
+    lines.append("clear_mem(z + %d, 2*(%d+1) - %d);" % (n, n, n))
 
     for line in lines:
         print("   %s" % (line))
@@ -73,7 +81,7 @@ namespace Botan {
 """ % (sys.argv[0], datetime.date.today().strftime("%Y-%m-%d")))
 
     for n in sizes:
-        print("void bigint_monty_redc_%d(word z[%d], const word p[%d], word p_dash, word ws[])" % (n, 2*n, n))
+        print("void bigint_monty_redc_%d(word z[], const word p[%d], word p_dash, word ws[])" % (n, n))
         print("   {")
 
         monty_redc_code(n)


Test patch:
diff --git a/src/cli/timing_tests.cpp b/src/cli/timing_tests.cpp
index 1125a6743..8c8c6e6ed 100644
--- a/src/cli/timing_tests.cpp
+++ b/src/cli/timing_tests.cpp
@@ -337,7 +337,7 @@ ticks ECC_Mul_Timing_Test::measure_critical_function(const std::vector<uint8_t>&
 
    ticks start = get_ticks();
 
-   const Botan::EC_Point k_times_P = m_group.blinded_base_point_multiply(k, timing_test_rng(), m_ws);
+   const Botan::PointGFp k_times_P = m_group.blinded_base_point_multiply(k, timing_test_rng(), m_ws);
 
    ticks end = get_ticks();
 
diff --git a/src/scripts/test_fuzzers.py b/src/scripts/test_fuzzers.py
index f911ab195..37a7dff9b 100755
--- a/src/scripts/test_fuzzers.py
+++ b/src/scripts/test_fuzzers.py
@@ -156,7 +156,7 @@ def main(args=None):
         # Generate a random corpus for fuzzers without a corpus
         random_corpus_dir = tempfile.mkdtemp(prefix='fuzzer_corpus_')
 
-        for i in range(1000):
+        for i in range(100):
             random_input = os.urandom(i)
             fd = open(os.path.join(random_corpus_dir, 'input_%d' % (i)), 'wb')
             fd.write(random_input)
diff --git a/src/tests/test_ec_group.cpp b/src/tests/test_ec_group.cpp
index f1c5a51e9..4b01d058c 100644
--- a/src/tests/test_ec_group.cpp
+++ b/src/tests/test_ec_group.cpp
@@ -13,7 +13,7 @@
   #include <botan/numthry.h>
   #include <botan/internal/curve_nistp.h>
   #include <botan/pk_keys.h>
-  #include <botan/ec_point.h>
+  #include <botan/point_gfp.h>
   #include <botan/ec_group.h>
   #include <botan/reducer.h>
   #include <botan/hex.h>
@@ -80,7 +80,7 @@ Botan::BigInt test_integer(Botan::RandomNumberGenerator& rng, size_t bits, const
    return x;
    }
 
-Botan::EC_Point create_random_point(Botan::RandomNumberGenerator& rng,
+Botan::PointGFp create_random_point(Botan::RandomNumberGenerator& rng,
                                     const Botan::EC_Group& group)
    {
    const Botan::BigInt& p = group.get_p();
@@ -119,7 +119,7 @@ std::vector<Test::Result> ECC_Randomized_Tests::run()
 
       Botan::EC_Group group(group_name);
 
-      const Botan::EC_Point pt = create_random_point(Test::rng(), group);
+      const Botan::PointGFp pt = create_random_point(Test::rng(), group);
       const Botan::BigInt& group_order = group.get_order();
 
       std::vector<Botan::BigInt> blind_ws;
@@ -133,16 +133,16 @@ std::vector<Test::Result> ECC_Randomized_Tests::run()
             const Botan::BigInt b = Botan::BigInt::random_integer(Test::rng(), 2, group_order);
             const Botan::BigInt c = a + b;
 
-            const Botan::EC_Point P = pt * a;
-            const Botan::EC_Point Q = pt * b;
-            const Botan::EC_Point R = pt * c;
+            const Botan::PointGFp P = pt * a;
+            const Botan::PointGFp Q = pt * b;
+            const Botan::PointGFp R = pt * c;
 
-            Botan::EC_Point P1 = group.blinded_var_point_multiply(pt, a, Test::rng(), blind_ws);
-            Botan::EC_Point Q1 = group.blinded_var_point_multiply(pt, b, Test::rng(), blind_ws);
-            Botan::EC_Point R1 = group.blinded_var_point_multiply(pt, c, Test::rng(), blind_ws);
+            Botan::PointGFp P1 = group.blinded_var_point_multiply(pt, a, Test::rng(), blind_ws);
+            Botan::PointGFp Q1 = group.blinded_var_point_multiply(pt, b, Test::rng(), blind_ws);
+            Botan::PointGFp R1 = group.blinded_var_point_multiply(pt, c, Test::rng(), blind_ws);
 
-            Botan::EC_Point A1 = P + Q;
-            Botan::EC_Point A2 = Q + P;
+            Botan::PointGFp A1 = P + Q;
+            Botan::PointGFp A2 = Q + P;
 
             result.test_eq("p + q", A1, R);
             result.test_eq("q + p", A2, R);
@@ -310,10 +310,10 @@ class EC_Group_Tests : public Test
                result.test_ne("Group " + group_name + " A does not equal zero", group.get_a(), BigInt(0));
 
             // get a valid point
-            Botan::EC_Point p = group.get_base_point() * Test::rng().next_nonzero_byte();
+            Botan::PointGFp p = group.get_base_point() * Test::rng().next_nonzero_byte();
 
             // get a copy
-            Botan::EC_Point q = p;
+            Botan::PointGFp q = p;
 
             p.randomize_repr(Test::rng());
             q.randomize_repr(Test::rng());
@@ -341,12 +341,12 @@ class EC_Group_Tests : public Test
       static void test_ser_der(Test::Result& result, const Botan::EC_Group& group)
          {
          // generate point
-         const Botan::EC_Point pt = create_random_point(Test::rng(), group);
-         const Botan::EC_Point zero = group.zero_point();
+         const Botan::PointGFp pt = create_random_point(Test::rng(), group);
+         const Botan::PointGFp zero = group.zero_point();
 
-         for(auto scheme : { Botan::EC_Point::UNCOMPRESSED,
-                  Botan::EC_Point::COMPRESSED,
-                  Botan::EC_Point::HYBRID })
+         for(auto scheme : { Botan::PointGFp::UNCOMPRESSED,
+                  Botan::PointGFp::COMPRESSED,
+                  Botan::PointGFp::HYBRID })
             {
             result.test_eq("encoded/decode rt works", group.OS2ECP(pt.encode(scheme)), pt);
             result.test_eq("encoded/decode rt works", group.OS2ECP(zero.encode(scheme)), zero);
@@ -355,9 +355,9 @@ class EC_Group_Tests : public Test
 
       static void test_basic_math(Test::Result& result, const Botan::EC_Group& group)
          {
-         const Botan::EC_Point& G = group.get_base_point();
+         const Botan::PointGFp& G = group.get_base_point();
 
-         Botan::EC_Point p1 = G * 2;
+         Botan::PointGFp p1 = G * 2;
          p1 += G;
 
          result.test_eq("point addition", p1, G * 3);
@@ -367,18 +367,18 @@ class EC_Group_Tests : public Test
          result.test_eq("point subtraction", p1, G);
 
          // The scalar multiplication algorithm relies on this being true:
-         Botan::EC_Point zero_coords = group.point(0, 0);
+         Botan::PointGFp zero_coords = group.point(0, 0);
          result.confirm("point (0,0) is not on the curve", !zero_coords.on_the_curve());
          }
 
       static void test_point_swap(Test::Result& result, const Botan::EC_Group& group)
          {
-         Botan::EC_Point a(create_random_point(Test::rng(), group));
-         Botan::EC_Point b(create_random_point(Test::rng(), group));
+         Botan::PointGFp a(create_random_point(Test::rng(), group));
+         Botan::PointGFp b(create_random_point(Test::rng(), group));
          b *= Botan::BigInt(Test::rng(), 20);
 
-         Botan::EC_Point c(a);
-         Botan::EC_Point d(b);
+         Botan::PointGFp c(a);
+         Botan::PointGFp d(b);
 
          d.swap(c);
          result.test_eq("swap correct", a, d);
@@ -387,26 +387,26 @@ class EC_Group_Tests : public Test
 
       static void test_zeropoint(Test::Result& result, const Botan::EC_Group& group)
          {
-         Botan::EC_Point zero = group.zero_point();
+         Botan::PointGFp zero = group.zero_point();
 
          result.test_throws("Zero point throws", "Cannot convert zero point to affine",
                             [&]() { zero.get_affine_x(); });
          result.test_throws("Zero point throws", "Cannot convert zero point to affine",
                             [&]() { zero.get_affine_y(); });
 
-         const Botan::EC_Point p1 = group.get_base_point() * 2;
+         const Botan::PointGFp p1 = group.get_base_point() * 2;
 
          result.confirm("point is on the curve", p1.on_the_curve());
          result.confirm("point is not zero", !p1.is_zero());
 
-         Botan::EC_Point p2 = p1;
+         Botan::PointGFp p2 = p1;
          p2 -= p1;
 
          result.confirm("p - q with q = p results in zero", p2.is_zero());
 
-         const Botan::EC_Point minus_p1 = -p1;
+         const Botan::PointGFp minus_p1 = -p1;
          result.confirm("point is on the curve", minus_p1.on_the_curve());
-         const Botan::EC_Point shouldBeZero = p1 + minus_p1;
+         const Botan::PointGFp shouldBeZero = p1 + minus_p1;
          result.confirm("point is on the curve", shouldBeZero.on_the_curve());
          result.confirm("point is zero", shouldBeZero.is_zero());
 
@@ -420,9 +420,9 @@ class EC_Group_Tests : public Test
          result.test_eq("addition of zero does nothing", p1, p1 - zero);
          result.confirm("zero times anything is the zero point", (zero * 39193).is_zero());
 
-         for(auto scheme : { Botan::EC_Point::UNCOMPRESSED,
-                  Botan::EC_Point::COMPRESSED,
-                  Botan::EC_Point::HYBRID })
+         for(auto scheme : { Botan::PointGFp::UNCOMPRESSED,
+                  Botan::PointGFp::COMPRESSED,
+                  Botan::PointGFp::HYBRID })
             {
             const std::vector<uint8_t> v = zero.encode(scheme);
             result.test_eq("encoded/decode rt works", group.OS2ECP(v), zero);
@@ -459,12 +459,12 @@ Test::Result test_coordinates()
 
    // precalculation
    const Botan::EC_Group secp160r1("secp160r1");
-   const Botan::EC_Point& p_G = secp160r1.get_base_point();
+   const Botan::PointGFp& p_G = secp160r1.get_base_point();
 
-   const Botan::EC_Point point_exp = secp160r1.point(exp_affine_x, exp_affine_y);
+   const Botan::PointGFp point_exp = secp160r1.point(exp_affine_x, exp_affine_y);
    result.confirm("Point is on the curve", point_exp.on_the_curve());
 
-   const Botan::EC_Point p1 = p_G * 2;
+   const Botan::PointGFp p1 = p_G * 2;
    result.test_eq("Point affine x", p1.get_affine_x(), exp_affine_x);
    result.test_eq("Point affine y", p1.get_affine_y(), exp_affine_y);
    return result;
@@ -487,10 +487,10 @@ Test::Result test_point_mult()
    Test::Result result("ECC Unit");
 
    Botan::EC_Group secp160r1("secp160r1");
-   const Botan::EC_Point& p_G = secp160r1.get_base_point();
+   const Botan::PointGFp& p_G = secp160r1.get_base_point();
 
    Botan::BigInt d_U("0xaa374ffc3ce144e6b073307972cb6d57b2a4e982");
-   Botan::EC_Point Q_U = d_U * p_G;
+   Botan::PointGFp Q_U = d_U * p_G;
 
    result.test_eq("affine x", Q_U.get_affine_x(), Botan::BigInt("466448783855397898016055842232266600516272889280"));
    result.test_eq("affine y", Q_U.get_affine_y(), Botan::BigInt("1110706324081757720403272427311003102474457754220"));
@@ -502,14 +502,14 @@ Test::Result test_point_negative()
    Test::Result result("ECC Unit");
 
    Botan::EC_Group secp160r1("secp160r1");
-   const Botan::EC_Point& p_G = secp160r1.get_base_point();
+   const Botan::PointGFp& p_G = secp160r1.get_base_point();
 
-   const Botan::EC_Point p1 = p_G * 2;
+   const Botan::PointGFp p1 = p_G * 2;
 
    result.test_eq("affine x", p1.get_affine_x(), Botan::BigInt("16984103820118642236896513183038186009872590470"));
    result.test_eq("affine y", p1.get_affine_y(), Botan::BigInt("1373093393927139016463695321221277758035357890939"));
 
-   const Botan::EC_Point p1_neg = -p1;
+   const Botan::PointGFp p1_neg = -p1;
 
    result.test_eq("affine x", p1_neg.get_affine_x(), p1.get_affine_x());
    result.test_eq("affine y", p1_neg.get_affine_y(),  Botan::BigInt("88408243403763901739989511495005261618427168388"));
@@ -521,16 +521,16 @@ Test::Result test_mult_point()
    Test::Result result("ECC Unit");
 
    Botan::EC_Group secp160r1("secp160r1");
-   const Botan::EC_Point& p_G = secp160r1.get_base_point();
+   const Botan::PointGFp& p_G = secp160r1.get_base_point();
 
-   const Botan::EC_Point& p0 = p_G;
-   Botan::EC_Point p1 = p_G * 2;
+   const Botan::PointGFp& p0 = p_G;
+   Botan::PointGFp p1 = p_G * 2;
 
    p1 *= p0.get_affine_x();
 
    const Botan::BigInt exp_mult_x(std::string("967697346845926834906555988570157345422864716250"));
    const Botan::BigInt exp_mult_y(std::string("512319768365374654866290830075237814703869061656"));
-   Botan::EC_Point expected = secp160r1.point(exp_mult_x, exp_mult_y);
+   Botan::PointGFp expected = secp160r1.point(exp_mult_x, exp_mult_y);
 
    result.test_eq("point mult", p1, expected);
    return result;
@@ -543,11 +543,11 @@ Test::Result test_mixed_points()
    Botan::EC_Group secp256r1("secp256r1");
    Botan::EC_Group secp384r1("secp384r1");
 
-   const Botan::EC_Point& G256 = secp256r1.get_base_point();
-   const Botan::EC_Point& G384 = secp384r1.get_base_point();
+   const Botan::PointGFp& G256 = secp256r1.get_base_point();
+   const Botan::PointGFp& G384 = secp384r1.get_base_point();
 
    result.test_throws("Mixing points from different groups",
-                      [&] { Botan::EC_Point p = G256 + G384; });
+                      [&] { Botan::PointGFp p = G256 + G384; });
    return result;
    }
 
@@ -557,24 +557,24 @@ Test::Result test_basic_operations()
 
    // precalculation
    Botan::EC_Group secp160r1("secp160r1");
-   const Botan::EC_Point& p_G = secp160r1.get_base_point();
+   const Botan::PointGFp& p_G = secp160r1.get_base_point();
 
-   const Botan::EC_Point& p0 = p_G;
-   const Botan::EC_Point p1 = p_G * 2;
+   const Botan::PointGFp& p0 = p_G;
+   const Botan::PointGFp p1 = p_G * 2;
 
    result.test_eq("p1 affine x", p1.get_affine_x(), Botan::BigInt("16984103820118642236896513183038186009872590470"));
    result.test_eq("p1 affine y", p1.get_affine_y(), Botan::BigInt("1373093393927139016463695321221277758035357890939"));
 
-   const Botan::EC_Point simplePlus = p1 + p0;
-   const Botan::EC_Point exp_simplePlus = secp160r1.point(Botan::BigInt("704859595002530890444080436569091156047721708633"),
+   const Botan::PointGFp simplePlus = p1 + p0;
+   const Botan::PointGFp exp_simplePlus = secp160r1.point(Botan::BigInt("704859595002530890444080436569091156047721708633"),
                                                           Botan::BigInt("1147993098458695153857594941635310323215433166682"));
 
    result.test_eq("point addition", simplePlus, exp_simplePlus);
 
-   const Botan::EC_Point simpleMinus = p1 - p0;
+   const Botan::PointGFp simpleMinus = p1 - p0;
    result.test_eq("point subtraction", simpleMinus, p_G);
 
-   const Botan::EC_Point simpleMult = p1 * 123456789;
+   const Botan::PointGFp simpleMult = p1 * 123456789;
 
    result.test_eq("point mult affine x", simpleMult.get_affine_x(),
                   Botan::BigInt("43638877777452195295055270548491599621118743290"));
@@ -591,8 +591,8 @@ Test::Result test_enc_dec_compressed_160()
    // Test for compressed conversion (02/03) 160bit
    Botan::EC_Group secp160r1("secp160r1");
    const std::vector<uint8_t> G_comp = Botan::hex_decode("024A96B5688EF573284664698968C38BB913CBFC82");
-   const Botan::EC_Point p = secp160r1.OS2ECP(G_comp);
-   const std::vector<uint8_t> sv_result = p.encode(Botan::EC_Point::COMPRESSED);
+   const Botan::PointGFp p = secp160r1.OS2ECP(G_comp);
+   const std::vector<uint8_t> sv_result = p.encode(Botan::PointGFp::COMPRESSED);
 
    result.test_eq("result", sv_result, G_comp);
    return result;
@@ -607,8 +607,8 @@ Test::Result test_enc_dec_compressed_256()
    const std::string G_secp_comp = "036B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296";
    const std::vector<uint8_t> sv_G_secp_comp = Botan::hex_decode(G_secp_comp);
 
-   Botan::EC_Point p_G = group.OS2ECP(sv_G_secp_comp);
-   std::vector<uint8_t> sv_result = p_G.encode(Botan::EC_Point::COMPRESSED);
+   Botan::PointGFp p_G = group.OS2ECP(sv_G_secp_comp);
+   std::vector<uint8_t> sv_result = p_G.encode(Botan::PointGFp::COMPRESSED);
 
    result.test_eq("compressed_256", sv_result, sv_G_secp_comp);
    return result;
@@ -638,8 +638,8 @@ Test::Result test_enc_dec_uncompressed_112()
    const std::string G_secp_uncomp = "044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97";
    const std::vector<uint8_t> sv_G_secp_uncomp = Botan::hex_decode(G_secp_uncomp);
 
-   Botan::EC_Point p_G = group.OS2ECP(sv_G_secp_uncomp);
-   std::vector<uint8_t> sv_result = p_G.encode(Botan::EC_Point::UNCOMPRESSED);
+   Botan::PointGFp p_G = group.OS2ECP(sv_G_secp_uncomp);
+   std::vector<uint8_t> sv_result = p_G.encode(Botan::PointGFp::UNCOMPRESSED);
 
    result.test_eq("uncompressed_112", sv_result, sv_G_secp_uncomp);
    return result;
@@ -658,9 +658,9 @@ Test::Result test_enc_dec_uncompressed_521()
 
    Botan::EC_Group group("secp521r1");
 
-   Botan::EC_Point p_G = group.OS2ECP(sv_G_secp_uncomp);
+   Botan::PointGFp p_G = group.OS2ECP(sv_G_secp_uncomp);
 
-   std::vector<uint8_t> sv_result = p_G.encode(Botan::EC_Point::UNCOMPRESSED);
+   std::vector<uint8_t> sv_result = p_G.encode(Botan::PointGFp::UNCOMPRESSED);
 
    result.test_eq("expected", sv_result, sv_G_secp_uncomp);
    return result;
diff --git a/src/tests/test_ecc_pointmul.cpp b/src/tests/test_ecc_pointmul.cpp
index 1f297188c..ede4a80fa 100644
--- a/src/tests/test_ecc_pointmul.cpp
+++ b/src/tests/test_ecc_pointmul.cpp
@@ -35,18 +35,18 @@ class ECC_Basepoint_Mul_Tests final : public Text_Based_Test
 
          Botan::EC_Group group(Botan::OID::from_string(group_id));
 
-         const Botan::EC_Point& base_point = group.get_base_point();
+         const Botan::PointGFp& base_point = group.get_base_point();
 
-         const Botan::EC_Point p1 = base_point * m;
+         const Botan::PointGFp p1 = base_point * m;
          result.test_eq("p1 affine X", p1.get_affine_x(), X);
          result.test_eq("p1 affine Y", p1.get_affine_y(), Y);
 
          std::vector<Botan::BigInt> ws;
-         const Botan::EC_Point p2 = group.blinded_base_point_multiply(m, Test::rng(), ws);
+         const Botan::PointGFp p2 = group.blinded_base_point_multiply(m, Test::rng(), ws);
          result.test_eq("p2 affine X", p2.get_affine_x(), X);
          result.test_eq("p2 affine Y", p2.get_affine_y(), Y);
 
-         const Botan::EC_Point p3 = group.blinded_var_point_multiply(base_point, m, Test::rng(), ws);
+         const Botan::PointGFp p3 = group.blinded_var_point_multiply(base_point, m, Test::rng(), ws);
          result.test_eq("p3 affine X", p3.get_affine_x(), X);
          result.test_eq("p3 affine Y", p3.get_affine_y(), Y);
 
@@ -73,18 +73,18 @@ class ECC_Varpoint_Mul_Tests final : public Text_Based_Test
 
          Botan::EC_Group group(Botan::OID::from_string(group_id));
 
-         const Botan::EC_Point pt = group.point(X, Y);
+         const Botan::PointGFp pt = group.point(X, Y);
 
          result.confirm("Input point is on the curve", pt.on_the_curve());
 
-         const Botan::EC_Point p1 = pt * k;
+         const Botan::PointGFp p1 = pt * k;
          result.test_eq("p1 affine X", p1.get_affine_x(), kX);
          result.test_eq("p1 affine Y", p1.get_affine_y(), kY);
 
          result.confirm("Output point is on the curve", p1.on_the_curve());
 
          std::vector<Botan::BigInt> ws;
-         const Botan::EC_Point p2 = group.blinded_var_point_multiply(pt, k, Test::rng(), ws);
+         const Botan::PointGFp p2 = group.blinded_var_point_multiply(pt, k, Test::rng(), ws);
          result.test_eq("p2 affine X", p2.get_affine_x(), kX);
          result.test_eq("p2 affine Y", p2.get_affine_y(), kY);
 
diff --git a/src/tests/test_ecdsa.cpp b/src/tests/test_ecdsa.cpp
index 260dc35d1..42f0a01dc 100644
--- a/src/tests/test_ecdsa.cpp
+++ b/src/tests/test_ecdsa.cpp
@@ -42,7 +42,7 @@ class ECDSA_Verification_Tests final : public PK_Signature_Verification_Test
          const BigInt py = vars.get_req_bn("Py");
          Botan::EC_Group group(Botan::OID::from_string(group_id));
 
-         const Botan::EC_Point public_point = group.point(px, py);
+         const Botan::PointGFp public_point = group.point(px, py);
 
          return std::make_unique<Botan::ECDSA_PublicKey>(group, public_point);
          }
@@ -81,7 +81,7 @@ class ECDSA_Wycheproof_Verification_Tests final : public PK_Signature_Verificati
          const BigInt py = vars.get_req_bn("Py");
          Botan::EC_Group group(Botan::OID::from_string(group_id));
 
-         const Botan::EC_Point public_point = group.point(px, py);
+         const Botan::PointGFp public_point = group.point(px, py);
 
          return std::make_unique<Botan::ECDSA_PublicKey>(group, public_point);
          }
@@ -232,15 +232,15 @@ class ECDSA_Invalid_Key_Tests final : public Text_Based_Test
          const Botan::BigInt x = vars.get_req_bn("InvalidKeyX");
          const Botan::BigInt y = vars.get_req_bn("InvalidKeyY");
 
-         std::unique_ptr<Botan::EC_Point> public_point;
+         std::unique_ptr<Botan::PointGFp> public_point;
 
          try
             {
-            public_point.reset(new Botan::EC_Point(group.point(x, y)));
+            public_point.reset(new Botan::PointGFp(group.point(x, y)));
             }
          catch(Botan::Invalid_Argument&)
             {
-            // EC_Point() performs a range check on x, y in [0, p−1],
+            // PointGFp() performs a range check on x, y in [0, p−1],
             // which is also part of the EC public key checks, e.g.,
             // in NIST SP800-56A rev2, sec. 5.6.2.3.2
             result.test_success("public key fails check");
diff --git a/src/tests/test_ecies.cpp b/src/tests/test_ecies.cpp
index 3f3dacba0..3a89b0550 100644
--- a/src/tests/test_ecies.cpp
+++ b/src/tests/test_ecies.cpp
@@ -20,19 +20,19 @@ namespace {
 
 using Flags = Botan::ECIES_Flags;
 
-Botan::EC_Point::Compression_Type get_compression_type(const std::string& format)
+Botan::PointGFp::Compression_Type get_compression_type(const std::string& format)
    {
    if(format == "uncompressed")
       {
-      return Botan::EC_Point::UNCOMPRESSED;
+      return Botan::PointGFp::UNCOMPRESSED;
       }
    else if(format == "compressed")
       {
-      return Botan::EC_Point::COMPRESSED;
+      return Botan::PointGFp::COMPRESSED;
       }
    else if(format == "hybrid")
       {
-      return Botan::EC_Point::HYBRID;
+      return Botan::PointGFp::HYBRID;
       }
    throw Botan::Invalid_Argument("invalid compression format");
    }
@@ -112,7 +112,7 @@ class ECIES_ISO_Tests final : public Text_Based_Test
          Test::Result result("ECIES-ISO");
 
          // get test vectors defined by ISO 18033
-         const Botan::EC_Point::Compression_Type compression_type = get_compression_type(vars.get_req_str("format"));
+         const Botan::PointGFp::Compression_Type compression_type = get_compression_type(vars.get_req_str("format"));
          const Botan::BigInt p = vars.get_req_bn("p");
          const Botan::BigInt a = vars.get_req_bn("a");
          const Botan::BigInt b = vars.get_req_bn("b");
@@ -131,12 +131,12 @@ class ECIES_ISO_Tests final : public Text_Based_Test
 
          // keys of bob
          const Botan::ECDH_PrivateKey other_private_key(Test::rng(), domain, x);
-         const Botan::EC_Point other_public_key_point = domain.point(hx, hy);
+         const Botan::PointGFp other_public_key_point = domain.point(hx, hy);
          const Botan::ECDH_PublicKey other_public_key(domain, other_public_key_point);
 
          // (ephemeral) keys of alice
          const Botan::ECDH_PrivateKey eph_private_key(Test::rng(), domain, r);
-         const Botan::EC_Point eph_public_key_point = eph_private_key.public_point();
+         const Botan::PointGFp eph_public_key_point = eph_private_key.public_point();
          const std::vector<uint8_t> eph_public_key_bin = eph_public_key_point.encode(compression_type);
          result.test_eq("encoded (ephemeral) public key", eph_public_key_bin, c0);
 
@@ -149,7 +149,7 @@ class ECIES_ISO_Tests final : public Text_Based_Test
 
          // test encryption / decryption
 
-         for(auto comp_type : { Botan::EC_Point::UNCOMPRESSED, Botan::EC_Point::COMPRESSED, Botan::EC_Point::HYBRID })
+         for(auto comp_type : { Botan::PointGFp::UNCOMPRESSED, Botan::PointGFp::COMPRESSED, Botan::PointGFp::HYBRID })
             {
             for(bool cofactor_mode : { true, false })
                {
@@ -213,7 +213,7 @@ class ECIES_Tests final : public Text_Based_Test
          const std::vector<uint8_t> iv = vars.get_opt_bin("Iv");
          const std::string mac = vars.get_req_str("Mac");
          const size_t mac_key_len = vars.get_req_sz("MacKeyLen");
-         const Botan::EC_Point::Compression_Type compression_type = get_compression_type(vars.get_req_str("Format"));
+         const Botan::PointGFp::Compression_Type compression_type = get_compression_type(vars.get_req_str("Format"));
          const bool cofactor_mode = vars.get_req_sz("CofactorMode") != 0;
          const bool old_cofactor_mode = vars.get_req_sz("OldCofactorMode") != 0;
          const bool check_mode = vars.get_req_sz("CheckMode") != 0;
@@ -252,7 +252,7 @@ Test::Result test_other_key_not_set()
 
    const Botan::ECDH_PrivateKey private_key(Test::rng(), domain, private_key_value);
    const Botan::ECIES_System_Params ecies_params(private_key.domain(), "KDF1-18033(SHA-512)", "AES-256/CBC", 32,
-         "HMAC(SHA-512)", 20, Botan::EC_Point::Compression_Type::COMPRESSED,
+         "HMAC(SHA-512)", 20, Botan::PointGFp::Compression_Type::COMPRESSED,
          flags);
 
    Botan::ECIES_Encryptor ecies_enc(private_key, ecies_params, Test::rng());
@@ -277,7 +277,7 @@ Test::Result test_kdf_not_found()
 
    const Botan::ECDH_PrivateKey private_key(Test::rng(), domain, private_key_value);
    const Botan::ECIES_System_Params ecies_params(private_key.domain(), "KDF-XYZ(SHA-512)", "AES-256/CBC", 32,
-         "HMAC(SHA-512)", 20, Botan::EC_Point::Compression_Type::COMPRESSED,
+         "HMAC(SHA-512)", 20, Botan::PointGFp::Compression_Type::COMPRESSED,
          flags);
 
    result.test_throws("kdf not found", [&]()
@@ -301,7 +301,7 @@ Test::Result test_mac_not_found()
 
    const Botan::ECDH_PrivateKey private_key(Test::rng(), domain, private_key_value);
    const Botan::ECIES_System_Params ecies_params(private_key.domain(), "KDF1-18033(SHA-512)", "AES-256/CBC", 32,
-         "XYZMAC(SHA-512)", 20, Botan::EC_Point::Compression_Type::COMPRESSED,
+         "XYZMAC(SHA-512)", 20, Botan::PointGFp::Compression_Type::COMPRESSED,
          flags);
 
    result.test_throws("mac not found", [&]()
@@ -325,7 +325,7 @@ Test::Result test_cipher_not_found()
 
    const Botan::ECDH_PrivateKey private_key(Test::rng(), domain, private_key_value);
    const Botan::ECIES_System_Params ecies_params(private_key.domain(), "KDF1-18033(SHA-512)", "AES-XYZ-256/CBC", 32,
-         "HMAC(SHA-512)", 20, Botan::EC_Point::Compression_Type::COMPRESSED,
+         "HMAC(SHA-512)", 20, Botan::PointGFp::Compression_Type::COMPRESSED,
          flags);
 
    result.test_throws("cipher not found", [&]()
diff --git a/src/tests/test_gost_3410.cpp b/src/tests/test_gost_3410.cpp
index f9d46699a..5fd2726c1 100644
--- a/src/tests/test_gost_3410.cpp
+++ b/src/tests/test_gost_3410.cpp
@@ -41,7 +41,7 @@ class GOST_3410_2001_Verification_Tests final : public PK_Signature_Verification
          const BigInt Px = vars.get_req_bn("Px");
          const BigInt Py = vars.get_req_bn("Py");
 
-         const Botan::EC_Point public_point = group.point(Px, Py);
+         const Botan::PointGFp public_point = group.point(Px, Py);
 
          return std::make_unique<Botan::GOST_3410_PublicKey>(group, public_point);
          }
diff --git a/src/tests/test_pkcs11_high_level.cpp b/src/tests/test_pkcs11_high_level.cpp
index b82f3d3a1..7b8d2d438 100644
--- a/src/tests/test_pkcs11_high_level.cpp
+++ b/src/tests/test_pkcs11_high_level.cpp
@@ -947,10 +947,10 @@ BOTAN_REGISTER_TEST("pkcs11", "pkcs11-rsa", PKCS11_RSA_Tests);
 /***************************** PKCS11 ECDSA *****************************/
 
 #if defined(BOTAN_HAS_ECC_GROUP) && (defined(BOTAN_HAS_ECDSA) || defined(BOTAN_HAS_ECDH))
-std::vector<uint8_t> encode_ec_point_in_octet_str(const Botan::EC_Point& point)
+std::vector<uint8_t> encode_ec_point_in_octet_str(const Botan::PointGFp& point)
    {
    std::vector<uint8_t> enc;
-   DER_Encoder(enc).encode(point.encode(EC_Point::UNCOMPRESSED), ASN1_Type::OctetString);
+   DER_Encoder(enc).encode(point.encode(PointGFp::UNCOMPRESSED), ASN1_Type::OctetString);
    return enc;
    }
 #endif
@@ -1422,8 +1422,8 @@ Test::Result test_ecdh_derive()
    Botan::PK_Key_Agreement ka(keypair.second, Test::rng(), "Raw");
    Botan::PK_Key_Agreement kb(keypair2.second, Test::rng(), "Raw");
 
-   Botan::SymmetricKey alice_key = ka.derive_key(32, keypair2.first.public_point().encode(EC_Point::UNCOMPRESSED));
-   Botan::SymmetricKey bob_key = kb.derive_key(32, keypair.first.public_point().encode(EC_Point::UNCOMPRESSED));
+   Botan::SymmetricKey alice_key = ka.derive_key(32, keypair2.first.public_point().encode(PointGFp::UNCOMPRESSED));
+   Botan::SymmetricKey bob_key = kb.derive_key(32, keypair.first.public_point().encode(PointGFp::UNCOMPRESSED));
 
    bool eq = alice_key == bob_key;
    result.test_eq("same secret key derived", eq, true);
diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp
index 342c9b8a6..4a6c5a634 100644
--- a/src/tests/tests.cpp
+++ b/src/tests/tests.cpp
@@ -20,7 +20,7 @@
 #endif
 
 #if defined(BOTAN_HAS_EC_CURVE_GFP)
-   #include <botan/ec_point.h>
+   #include <botan/point_gfp.h>
 #endif
 
 #if defined(BOTAN_TARGET_OS_HAS_POSIX1)
@@ -376,7 +376,7 @@ bool Test::Result::test_ne(const std::string& what, const BigInt& produced, cons
 
 #if defined(BOTAN_HAS_EC_CURVE_GFP)
 bool Test::Result::test_eq(const std::string& what,
-                           const Botan::EC_Point& a, const Botan::EC_Point& b)
+                           const Botan::PointGFp& a, const Botan::PointGFp& b)
    {
    //return test_is_eq(what, a, b);
    if(a == b)
diff --git a/src/tests/tests.h b/src/tests/tests.h
index bca1def23..220bf0bbf 100644
--- a/src/tests/tests.h
+++ b/src/tests/tests.h
@@ -32,7 +32,7 @@ class BigInt;
 #endif
 
 #if defined(BOTAN_HAS_EC_CURVE_GFP)
-class EC_Point;
+class PointGFp;
 #endif
 
 }
@@ -469,8 +469,8 @@ class Test
 
 #if defined(BOTAN_HAS_EC_CURVE_GFP)
             bool test_eq(const std::string& what,
-                         const Botan::EC_Point& a,
-                         const Botan::EC_Point& b);
+                         const Botan::PointGFp& a,
+                         const Botan::PointGFp& b);
 #endif
 
             bool test_eq(const char* producer, const std::string& what,
diff --git a/src/tests/unit_ecdsa.cpp b/src/tests/unit_ecdsa.cpp
index 63c4f9926..6769b115d 100644
--- a/src/tests/unit_ecdsa.cpp
+++ b/src/tests/unit_ecdsa.cpp
@@ -253,7 +253,7 @@ Test::Result test_unusual_curve()
 
    Botan::EC_Group dom_params(p, a, b, Gx, Gy, order_g, cofactor);
 
-   Botan::EC_Point p_G = dom_params.point(Gx, Gy);
+   Botan::PointGFp p_G = dom_params.point(Gx, Gy);
 
    if(!result.confirm("G is on curve", p_G.on_the_curve()))
       {
@@ -279,14 +279,14 @@ Test::Result test_encoding_options()
    Botan::ECDSA_PrivateKey key(Test::rng(), group);
 
    result.confirm("Default encoding is uncompressed",
-                  key.point_encoding() == Botan::EC_Point::UNCOMPRESSED);
+                  key.point_encoding() == Botan::PointGFp::UNCOMPRESSED);
 
    const std::vector<uint8_t> enc_uncompressed = key.public_key_bits();
 
-   key.set_point_encoding(Botan::EC_Point::COMPRESSED);
+   key.set_point_encoding(Botan::PointGFp::COMPRESSED);
 
    result.confirm("set_point_encoding works",
-                  key.point_encoding() == Botan::EC_Point::COMPRESSED);
+                  key.point_encoding() == Botan::PointGFp::COMPRESSED);
 
    const std::vector<uint8_t> enc_compressed = key.public_key_bits();
 
@@ -298,10 +298,10 @@ Test::Result test_encoding_options()
    result.test_gte("Compressed points smaller by group size",
                    size_diff, 32);
 
-   key.set_point_encoding(Botan::EC_Point::HYBRID);
+   key.set_point_encoding(Botan::PointGFp::HYBRID);
 
    result.confirm("set_point_encoding works",
-                  key.point_encoding() == Botan::EC_Point::HYBRID);
+                  key.point_encoding() == Botan::PointGFp::HYBRID);
 
    const std::vector<uint8_t> enc_hybrid = key.public_key_bits();
 
@@ -309,7 +309,7 @@ Test::Result test_encoding_options()
                   enc_uncompressed.size(), enc_hybrid.size());
 
 #if !defined(BOTAN_HAS_SANITIZER_UNDEFINED)
-   auto invalid_format = static_cast<Botan::EC_Point::Compression_Type>(99);
+   auto invalid_format = static_cast<Botan::PointGFp::Compression_Type>(99);
 
    result.test_throws("Invalid point format throws",
                       "Invalid point encoding for EC_PublicKey",