Skip to content

Avoid validation of known EC groups when decoding an explicit curve block#5268

Merged
randombit merged 1 commit intomasterfrom
jack/ecc-params-setup
Jan 30, 2026
Merged

Avoid validation of known EC groups when decoding an explicit curve block#5268
randombit merged 1 commit intomasterfrom
jack/ecc-params-setup

Conversation

@randombit
Copy link
Copy Markdown
Owner

Instead first check if the group is a known group, either a group known at compile time or something that the application registered. Only if that fails, perform the usual validation.

This skips various expensive primality checks for the common case when the explicit curve is just an explicit encoding of a standard group. It also sets up for easily removing support for non-standard explicit groups; if lookup_from_params fails, instead of trying to validate the group just throw an exception.

@randombit randombit requested review from Copilot and reneme January 27, 2026 13:35
@randombit randombit force-pushed the jack/ecc-params-setup branch 2 times, most recently from e995fc8 to dd3337d Compare January 27, 2026 13:51
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves performance of decoding explicitly-encoded EC domain parameters by first attempting to recognize them as a known/registered group (skipping expensive primality checks in the common case), and adds regression tests for explicit-curve decoding behavior.

Changes:

  • Add a parameter-based lookup path (lookup_from_params) to map explicit curve parameters to known EC groups before doing heavyweight validation.
  • Add an EC group parameter matcher that accepts the encoded base point.
  • Add new text-based tests and vectors for explicit EC curve decoding/validation.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/tests/test_ecc_explicit_params.cpp Adds a text-based test that loads explicit-curve public keys and checks acceptance/rejection behavior.
src/tests/data/pubkey/ecc_explicit_curve.vec Adds test vectors for valid and invalid explicit curve encodings across multiple groups.
src/lib/pubkey/ec_group/ec_inner_data.h Declares a new params_match overload that matches the encoded base point.
src/lib/pubkey/ec_group/ec_inner_data.cpp Implements the new encoded-base-point matcher and refactors existing matcher.
src/lib/pubkey/ec_group/ec_group.cpp Adds lookup_from_params and uses it early in explicit group decoding to avoid expensive validation for known groups.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coveralls
Copy link
Copy Markdown

coveralls commented Jan 27, 2026

Coverage Status

coverage: 90.07% (-0.007%) from 90.077%
when pulling b325234 on jack/ecc-params-setup
into 0d718b1 on master.

Copy link
Copy Markdown
Collaborator

@reneme reneme left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea! Changes look good to me. We could reorder the parameter lookup a little to avoid unnecessary point serializations in unlikely failure cases. But given that the benefit of that would be reaped only in fail cases, I don't see that as more than a nit.

Some SEC1 encoder/decoder helper classes would probably be nice at this point, though.

Comment on lines +182 to +183
if(base_pt.size() == 1 + field_len && (base_pt[0] == 0x02 || base_pt[0] == 0x03)) {
// compressed
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the number of times we jotted down the encoding/decoding of this SEC1 encoding across the code base now, I think we should introduce a small helper along those lines:

class SEC1_Decoder {
  public:
    enum Label {
      Identity = 0x00;
      Compressed_Even = 0x02;
      Compressed_Odd = 0x03;
      Full = 0x04;
      // Hybrid?
    };

  public:
    static SEC1_Decoder from_bytes(const EC_Group& group, std::span<const uint8_t> bytes);
    static SEC1_Decoder from_bytes(size_t field_len, std::span<const uint8_t> bytes);
    
    Label label() const { /* ... */ }
    std::span<const uint8_t> x_bytes() const { /* ... */ }
    std::optional<std::span<const uint8_t>> y_bytes() cosnt { /* ... */ }

    EC_AffinePoint affine_point() const;

  private:
    std::span<const uint8_t> m_bytes;
};

... certainly a follow-up, though.

@reneme
Copy link
Copy Markdown
Collaborator

reneme commented Jan 28, 2026

Oh, and the CI failure is relevant. I guess it tries to instantiate a standard curve in a build where there's no backend for them. Perhaps try deserializing in a Text_Based_Test::skip_this_test() first and return true iff it catches Not_Implemented.

Failure 1: ECC explicit curve validation Rejected valid explicit curve parameters with error Not implemented EC_Group this group is not supported in this build configuration (at /home/runner/work/botan/botan/source/src/tests/test_ecc_explicit_params.cpp:62)
  Failure 2: ECC explicit curve validation Rejected valid explicit curve parameters with error Not implemented EC_Group the group 1.3.36.3.3.2.8.1.1.7 is not supported in this build configuration (at /home/runner/work/botan/botan/source/src/tests/test_ecc_explicit_params.cpp:62)
  Failure 3: ECC explicit curve validation Rejection failure other than what was expected with error Not implemented EC_Group the group 1.3.36.3.3.2.8.1.1.7 is not supported in this build configuration (at /home/runner/work/botan/botan/source/src/tests/test_ecc_explicit_params.cpp:62)
  Note 1: ECC explicit curve validation Test # 2 failed Pubkey=308201B53082014D06072A8648CE3D020130820140020101303C06072A8648CE3D0101023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC330640430FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC00430FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77BB0461040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000023C9F82CB4B87B4DC71E763E0663E5DBD8034ED422F04F82673330DC58D15FFA2B4A3D0BAD5D30F865BCBBF503EA66F43023100FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD61EAF1EEB5D6881BEDA9D3D4C37E27A604D81F67B0E61B902010103620004C23D4E83CD9988055C1DC816F7881C14B1C915C756FE189885F67B82CF38CE69756B30FD35FB651BEC58DD8FF66018F7B5A7B269877B43FB2D5991C48059055BC6E4012C928E6D4A0761638F6A28C7157F562BF173DB9F365276291F1D5DBA78 Result=OK 
  Note 2: ECC explicit curve validation Test # 3 failed Pubkey=308201333081EC06072A8648CE3D02013081E0020101302C06072A8648CE3D0101022100A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E537730440420A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E53740420662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04044104A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F42D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE022100A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7020101034200043398E38269601DBADCC70F2B3EE6D77ACC16A31EA0B4CF80A073587551A1D08729C849FF3E6D6C67435D67F9495BFB27EB172C495D61002369BBE8D0A59D4726 Result=OK 
  Note 3: ECC explicit curve validation Test # 4 failed Pubkey=308201333081EC06072A8648CE3D02013081E0020101302C06072A8648CE3D0101022100A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E537930440420A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E53740420662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04044104A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F42D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE022100A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7020101034200043DE15A95F34445551D72A71D079EC862E5B6C6DDF6735E89C1AAA4FE41E6086B29E7BBA60FE13B86189FA92BA16BEEE1B6C9910A3861F67AAAA1046FFEC0C2DB Result=p parameter is not a prime 

@randombit randombit force-pushed the jack/ecc-params-setup branch from dd3337d to 53ec20d Compare January 29, 2026 10:51
…lock

Instead first check if the group is a known group, either a group known at compile time or
something that the application registered. Only if that fails, perform the usual validation.

This skips various expensive primality checks for the common case when the explicit curve
is just an explicit encoding of a standard group. It also sets up for easily removing
support for non-standard explicit groups; if lookup_from_params fails, instead of trying to
validate the group just throw an exception.
@randombit randombit force-pushed the jack/ecc-params-setup branch from 53ec20d to b325234 Compare January 29, 2026 11:31
@randombit randombit merged commit f859c22 into master Jan 30, 2026
46 checks passed
@randombit randombit deleted the jack/ecc-params-setup branch January 30, 2026 10:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants