64 bit arithmetic soft fork

I think there’s a few choices here:

  • what happens with “overflows” ?
    • they’re not possible, everything happens modulo 2^n
    • if the inputs are “too large”, the script aborts
    • you get an overflow indicator in every result
  • what is 2^n or what constitutes “too large” ?
    • BTC’s max supply is about 2^{51} satoshis, so 64bit is a fine minimum
    • 2^{256} would let you manipulate scalars for secp256k1 which might be useful
    • 2^{4160} would let you do numbers of to 520 bytes which matches current stack entry limits
  • unsigned only, or signed
    • if we’re doing modular arithmetic, unsigned seems easier
    • signed maths probably makes some contracts a bunch easier though
  • what serialization format?
    • if signed, use a sign-bit or 2’s complement?
    • fixed length or variable length – if fixed length, that constrains the precision we could use
    • if variable length, does every integer have a unique serialization, or can you have “0000” and “0” and “-0” all as different representations of 0?

I guess 64-bit unsigned modular arithmetic would be easiest (uint64_t already works), but 4160-bit signed numbers (or some similarly large value that benchmarks fast enough) with abort-on-overflow behaviour and stored/serialized like CScriptNum format might be more appropriate?

Abort-on-overflow seems kind of appealing as far as writing contracts goes: we’ve already had an “overflow allows printing money” bug in bitcoin proper, so immediately aborting if that happens in script seems like a wise protection. If people want to do modular arithmetic, they could perhaps manually calculate ((x % k) * (y % k)) % k provided they pick k \le \sqrt{2^{n}} or similar.