pc-dart icon indicating copy to clipboard operation
pc-dart copied to clipboard

Provide an abstract ByteBasedSecureRandom

Open EP-u-NW opened this issue 3 years ago • 1 comments

We could implement an abstract class ByteBasedSecureRandom that extends SecureRandom and implements all of it functions based on nextBytes. Then, it is easy to extend this ByteBasedSecureRandom with a custom algorithm that puts out bytes.

I'm thinking about something like

import 'dart:typed_data';
import 'package:pointycastle/api.dart';

abstract class ByteBasedSecureRandom implements SecureRandom {
  @override
  BigInt nextBigInteger(int bitLength) {
    int byteCount = (bitLength + 7) ~/ 8;
    Uint8List bytes = nextBytes(byteCount);
    String s = '';
    for (int i = 0; i < byteCount; i++) {
      s = s + (bytes[i].toRadixString(2).padLeft(8, '0'));
    }
    return BigInt.parse(s, radix: 2).toUnsigned(bitLength);
  }

  @override
  int nextUint16() {
    return nextBytes(2).buffer.asByteData().getUint16(0);
  }

  @override
  int nextUint32() {
    return nextBytes(4).buffer.asByteData().getUint32(0);
  }

  @override
  int nextUint8() {
    return nextBytes(1).buffer.asByteData().getUint8(0);
  }

  @override
  void seed(CipherParameters params) {}
}

While this might be slow (especially the nextBigInteger part), it was pointed out in #87 that

This package is pure Dart, completely software implementation, so it is slow.

so I see no problem with speed.

The idea behind this byte based approach is to then implement a Random on top of dart's own Random.secure, like

import 'dart:typed_data';
import 'dart:math';
import 'package:pointycastle/api.dart';
import 'byte_based_secure_random.dart';

class DartSecureRandom extends ByteBasedSecureRandom {
  final Random _random;
  DartSecureRandom({bool secure: true})
      : this._random = secure ? new Random.secure() : new Random();
  @override
  String get algorithmName => "DartSecure";

  @override
  Uint8List nextBytes(int count) {
    Uint8List bytes = new Uint8List(count);
    for (int i = 0; i < count; i++) {
      bytes[i] = _random.nextInt(256);
    }
    return bytes;
  }
}

EP-u-NW avatar May 23 '21 21:05 EP-u-NW

We should have something like this for sure. I'll take a look.

By the way, just a note: that first snippet can be sped up using direct array access and bitwise operators.

AKushWarrior avatar May 23 '21 22:05 AKushWarrior