HomePhabricator

[electrum] fix int to bytes conversion for curve points when gmpy is installed

Description

[electrum] fix int to bytes conversion for curve points when gmpy is installed

Summary:
ecdsa returns gmpy2.mpz objects rather than regular python integers when gmpy2 is installed, and these objects don't have a to_bytes method, so D14462 broke the application for systems that have gmpy installed.

Convert curve points to int before converting to bytes, to be sure it works.
This reduces the performance, but it is still better than the situation before D14462.

big_int = 0xdeadbeefc0ffeef0deadbeefc0ffeef0deadbeefc0ffeef0deadbeefc0ffeef0
big_mpz = mpz(big_int)
%timeit big_int.to_bytes(32, "big")
61.5 ns ± 0.375 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)
%timeit int(big_mpz).to_bytes(32, "big")
138 ns ± 0.434 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)
%timeit gmpy2.to_binary(big_mpz)
108 ns ± 0.273 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)
%timeit int(big_int).to_bytes(32, "big")
93.1 ns ± 0.646 ns per loop (mean ± std. dev. of 7 runs, 10,000,000 loops each)

Note that other modules in the codebase already do that (ecc_fast.py, schnorr.py, fusion.py), so it was probably a known issue for a long time.

This should be fixed in gmpy in the next release (can be tested in a couple of days with an alpha release), and then this explicit int conversion can be reverted if gmpy2 can be added with a pinpointed version to the dependencies.

Test Plan: python test_runner.py

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D14490

Event Timeline