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

Feature request: xmpz's bit range feature, byte arrays #1

Closed
danwallach opened this issue Nov 22, 2021 · 3 comments
Closed

Feature request: xmpz's bit range feature, byte arrays #1

danwallach opened this issue Nov 22, 2021 · 3 comments

Comments

@danwallach
Copy link

First, thank you for this library. It's exactly what I need.

GnuMP has a very useful feature for selecting bit ranges from an xmpz. For my particular application, this allows for an optimization worth about 9x (precompute to optimize modular exponentiation for known bases).

Python binding: https://gmpy2.readthedocs.io/en/latest/advmpz.html

I'd love something analogous to the "bit slice" read feature. I don't actually need anything else, but I imagine others might want the full suite of xmpz mutability features.

Also, in terms of general purpose features, it would be handy to have input and output as byte arrays. Java BigInteger defines this to be big endian, twos complement, which seems as good as anything else you might do.

@Daninet
Copy link
Owner

Daninet commented Nov 22, 2021

Thank you for sharing your ideas!

I started with a mutable wrapper, but I dropped it. It turned out that immutable wrappers have comparable performance, while providing a more JavaScript-friendly API. All of the low-level GMP / MPFR functions are also exposed so those can be used when somebody wants to do advanced optimizations. https://github.com/Daninet/gmp-wasm#advanced-usage. You can even mix the high level wrapper with low level code, by accessing the mpz_t pointer from the wrapper.

"Bit slice" read feature wouldn't be a same as doing a shiftRight() + bitwise and() with a bitmask? I see that GMP has functions for manipulating individual bits, maybe those could be exposed in the wrapper.

I like the idea of byte array I/O. I will try to add it to the next version.

@danwallach
Copy link
Author

You could definitely implement bit slicing with shifting and masking. I suppose it might be faster to do all that on the inside and just let me ask for a specific range of bits.

For byte arrays, gmpy gives you a "portable" output with a two byte header. You probably want to be interoperable with that as well as the Java version (no header).

@Daninet
Copy link
Owner

Daninet commented Nov 24, 2021

I added some new Integer functions to version 0.8.2:

setBit(index)
setBits(indices)
clearBit(index)
clearBits(indices)
flipBit(index)
flipBits(indices)
getBit(index)
msbPosition()
sliceBits(start, end) => Works similarly to JS Array.slice(), but on bits. It supports negative offsets.
writeTo(num, offset, bitCount) => Can be used to put an another integer somewhere in the middle of the binary representation
toBuffer(littleEndian = false) => Exports Uint8Array without any extra headers. Sign is not included
toString(radix = 10) has now an optional radix parameter

Uint8Array buffers are also supported by the constructor:
ctx.Integer(ctx.Integer('1234567').toBuffer())

Now it also possible to use create and read strings in arbitrary bases:
ctx.Integer(6).toString(7)
ctx.Integer('110', 2)

@Daninet Daninet closed this as completed Nov 25, 2021
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

No branches or pull requests

2 participants