Search code examples
flutterdartencryptioncryptographylargenumber

How do I get a random BigInt in a specific range (Dart)


I'm sorry if this question has been asked before but I cannot find any solution that helps me.

Basically, I have a huge number n where n is a 4000 bit number. Obviously, it won't fit in the 64 bits allowed by the primitive type int in Dart.

I need to find a random number g such that 2 ≤ g ≤ (n - 1). Is there a way I can generate such a random number?

My current solution:

void _generatePrivateKey() {
  const numbers = '0123456789';
  final halfOfNLength = N.toString().length ~/ 2; // Where `N` is `BigInt`
  final length = _rand.nextInt(halfOfNLength) + halfOfNLength;
  final buffer = StringBuffer();
  for (var _ = 0; _ < length; _++) {
    buffer.write(numbers[_rand.nextInt(numbers.length)]);
  }
  _privateKey = BigInt.parse(buffer.toString());
}

I know it's not a good solution but that's all I have for now


Solution

  • package:pointycastle contains a utility file with a decodeBigInt function that converts a list of bytes into a BigInt.

    Here's how you can use it to generate a 4000 bit value:

    import 'dart:math';
    import 'dart:typed_data';
    
    BigInt randomBigInt() {
      const size = 4000;
      final random = Random.secure();
      final builder = BytesBuilder();
      for (var i = 0; i < size; ++i) {
        builder.addByte(random.nextInt(256));
      }
      final bytes = builder.toBytes();
      return decodeBigInt(bytes);
    }
    

    Alternatively, decodeBigIntWithSign can be used to enforce a negative or positive result.