twonly-app-dependencies/pointycastle/lib/random/block_ctr_random.dart
2025-12-07 16:10:41 +01:00

69 lines
1.8 KiB
Dart
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// See file LICENSE for more information.
library impl.secure_random.block_ctr_random;
import 'dart:typed_data';
import 'package:pointycastle/api.dart';
import 'package:pointycastle/src/registry/registry.dart';
import 'package:pointycastle/src/ufixnum.dart';
import 'package:pointycastle/src/impl/secure_random_base.dart';
/// An implementation of [SecureRandom] that uses a [BlockCipher] with CTR mode to generate random
/// values.
class BlockCtrRandom extends SecureRandomBase implements SecureRandom {
/// Intended for internal use.
static final FactoryConfig factoryConfig = DynamicFactoryConfig.regex(
SecureRandom,
r'^(.*)/CTR/PRNG$',
(_, final Match match) => () {
var blockCipherName = match.group(1);
var blockCipher = BlockCipher(blockCipherName!);
return BlockCtrRandom(blockCipher);
});
final BlockCipher cipher;
late Uint8List _input;
late Uint8List _output;
late int _used;
BlockCtrRandom(this.cipher) {
_input = Uint8List(cipher.blockSize);
_output = Uint8List(cipher.blockSize);
_used = _output.length;
}
@override
String get algorithmName => '${cipher.algorithmName}/CTR/PRNG';
@override
void seed(CipherParameters params) {
_used = _output.length;
if (params is ParametersWithIV) {
_input.setAll(0, params.iv);
cipher.init(true, params.parameters!);
} else {
cipher.init(true, params);
}
}
@override
int nextUint8() {
if (_used == _output.length) {
cipher.processBlock(_input, 0, _output, 0);
_used = 0;
_incrementInput();
}
return clip8(_output[_used++]);
}
void _incrementInput() {
var offset = _input.length;
do {
offset--;
_input[offset] += 1;
} while (_input[offset] == 0);
}
}