Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean out the BigInt interface #4056

Merged
merged 8 commits into from
May 29, 2024
Merged

Conversation

randombit
Copy link
Owner

This class has grown in an unprincipled way out of accretion and it's quite a mess. Many functions are implemented which are just useful for 1 or2 algorithms. Deprecate everything along these lines.

I don't have an immediate plan for how we'll get access to the functionality later from within the library, but sine we can't remove anything until Botan 4 anyway it doesn't really matter right now.

Also add new serialization and deserialization functions based on span. The new serialize_to avoids the bizarre trunction behavior of binary_encode when the output buffer is too small - I'm not sure why or when that was ever useful.

@randombit randombit force-pushed the jack/cleanup-bigint-interface branch 3 times, most recently from c67df9c to ff12476 Compare May 12, 2024 07:34
@coveralls
Copy link

coveralls commented May 12, 2024

Coverage Status

coverage: 91.812% (+0.003%) from 91.809%
when pulling 24da08f on jack/cleanup-bigint-interface
into 100a065 on master.

@randombit randombit force-pushed the jack/cleanup-bigint-interface branch 3 times, most recently from 1a9974e to 79db481 Compare May 12, 2024 14:24
@randombit randombit added this to the Botan 3.5.0 milestone May 22, 2024
@@ -60,17 +64,20 @@ class BOTAN_PUBLIC_API(2, 0) BigInt final {
* Create BigInt from a word (limb)
* @param n initial value of this BigInt
*/
//BOTAN_DEPRECATED("Use BigInt::from_u64 instead")
Copy link
Collaborator

@reneme reneme May 24, 2024

Choose a reason for hiding this comment

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

Commented out on purpose? Same with BigInt(std::string_view).

Copy link
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.

No full review so far. Just a few suggestions.

Comment on lines +712 to +714
// TODO this supports std::vector and secure_vector
// it would be nice if this also could work with std::array as in
// bn.serialize_to<std::array<uint8_t, 32>>(32);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Perhaps just add another overload like so:

template<size_t len>
std::array<uint8_t, len> serialize() const {
   std::array<uint8_t, len> out;
   this->serialize_to(out);
   return out;
}

usage would then look like this:

bn.serialize<32>();

... this style would be similar to the implementation in the BufferSlicer, where one would bs.take<32>().

For call-site readability it might make sense to rename that overload to something like serialize_as_array<len>().

Copy link
Owner Author

Choose a reason for hiding this comment

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

My take at this point is that it's probably quite rare to know at compile time the exact size of the integer being encoded. Can always revisit this issue later, and as always hard to take it back once it is in a release, so I'm going to defer.

Comment on lines 752 to 756
/**
* Read integer value from a byte vector (big endian)
* @param bytes the span of bytes to load
*/
void assign_from_bytes(std::span<const uint8_t> bytes);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we even need that? Or is a simple assignment enough?

BigInt some_existing_bn;
some_existing_bn = BigInt::from_bytes(some_byte_array);

... with an appropriate move-assignment operator that might not even have a performance penalty.

Copy link
Collaborator

Choose a reason for hiding this comment

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

See also: #4056 (comment)

src/lib/math/bigint/bigint.h Show resolved Hide resolved
Most of these are only useful internally to implement specific
algorithms, and should never have been exposed to users.
@randombit randombit force-pushed the jack/cleanup-bigint-interface branch from 79db481 to e152c76 Compare May 24, 2024 22:50
This allows us to deprecate BigInt::data and still use it in
headers/inlines without triggering a warning in user code.
@randombit randombit force-pushed the jack/cleanup-bigint-interface branch from e152c76 to ae49fef Compare May 24, 2024 22:54
Copy link
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.

Looks good to me. Just some nits and a few minor suggestions.

src/lib/math/bigint/big_code.cpp Outdated Show resolved Hide resolved
if(base == Binary) {
return BigInt::from_bytes(buf);
}
return BigInt::decode(buf.data(), buf.size(), base);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Perhaps BigInt::decode(std::span<const uint8_t>, ..)?

Copy link
Owner Author

Choose a reason for hiding this comment

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

For these functions using BigInt::Base I'm inclined to not do anything with span since already the whole set of functions and the enum itself are deprecated. We'd just be introducing new interfaces which begin life deprecated, which seems odd.

src/lib/math/bigint/big_code.cpp Show resolved Hide resolved
src/lib/math/bigint/bigint.cpp Show resolved Hide resolved
src/lib/pubkey/ec_group/ec_point.cpp Outdated Show resolved Hide resolved
src/lib/pubkey/pubkey.cpp Outdated Show resolved Hide resolved
src/lib/pubkey/rfc6979/rfc6979.cpp Outdated Show resolved Hide resolved
Comment on lines 118 to +119
std::array<uint8_t, 56> res_bytes = {0};
res.binary_encode(res_bytes.data(), res_bytes.size());
res.serialize_to(res_bytes);
Copy link
Collaborator

Choose a reason for hiding this comment

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

For reference: If we add a serialization overload that produces an array, this could become:

auto res_bytes = res.serialize_as_array<56>();

doc/api_ref/bigint.rst Outdated Show resolved Hide resolved
out.flip_sign();
} else {
out = BigInt(obj.bits(), obj.length());
out.assign_from_bytes(obj.data());
Copy link
Collaborator

Choose a reason for hiding this comment

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

There's no way to access a BER_Object's data as a span?

Copy link
Owner Author

Choose a reason for hiding this comment

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

BER_Object::data is exactly this?

(This was just recently added in cf82307)

@randombit randombit force-pushed the jack/cleanup-bigint-interface branch from bb10382 to b5498fd Compare May 29, 2024 07:54
randombit and others added 2 commits May 29, 2024 03:54
Co-authored-by: René Meusel <github@renemeusel.de>
@randombit randombit merged commit e101afd into master May 29, 2024
43 checks passed
@randombit randombit deleted the jack/cleanup-bigint-interface branch May 29, 2024 10:03
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.

None yet

3 participants