92 lines
2.2 KiB
Dart
92 lines
2.2 KiB
Dart
// This file has been migrated.
|
|
|
|
library impl.digest.shake;
|
|
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:pointycastle/api.dart';
|
|
import 'package:pointycastle/src/impl/keccak_engine.dart';
|
|
import 'package:pointycastle/src/registry/registry.dart';
|
|
|
|
///
|
|
/// implementation of SHAKE based on following KeccakNISTInterface.c from http://keccak.noekeon.org/
|
|
///
|
|
/// Following the naming conventions used in the C source code to enable easy review of the implementation.
|
|
///
|
|
class SHAKEDigest extends KeccakEngine implements Xof {
|
|
static final RegExp _shakeREGEX = RegExp(r'^SHAKE-([0-9]+)$');
|
|
|
|
/// Intended for internal use.
|
|
static final FactoryConfig factoryConfig = DynamicFactoryConfig(
|
|
Digest,
|
|
_shakeREGEX,
|
|
(_, final Match match) => () {
|
|
var bitLength = int.parse(match.group(1)!);
|
|
return SHAKEDigest(bitLength);
|
|
});
|
|
|
|
SHAKEDigest([int bitLength = 256]) {
|
|
switch (bitLength) {
|
|
case 128:
|
|
case 256:
|
|
init(bitLength);
|
|
break;
|
|
default:
|
|
throw StateError(
|
|
'invalid bitLength ($bitLength) for SHAKE must only be 128 or 256');
|
|
}
|
|
}
|
|
|
|
@override
|
|
String get algorithmName => 'SHAKE-$fixedOutputLength';
|
|
|
|
@override
|
|
int doFinal(Uint8List out, int outOff) {
|
|
return doFinalRange(out, digestSize, digestSize);
|
|
}
|
|
|
|
@override
|
|
int doFinalRange(Uint8List out, int outOff, int outLen) {
|
|
var length = doOutput(out, outOff, outLen);
|
|
reset();
|
|
return length;
|
|
}
|
|
|
|
int doFinalPartial(
|
|
Uint8List out, int outOff, int outLen, int partialByte, int partialBits) {
|
|
if (partialBits < 0 || partialBits > 7) {
|
|
throw ArgumentError('partialBits must be in the range [0,7]');
|
|
}
|
|
|
|
var finalInput =
|
|
(partialByte & ((1 << partialBits) - 1)) | (0x0F << partialBits);
|
|
var finalBits = partialBits + 4;
|
|
|
|
if (finalBits >= 8) {
|
|
absorb(finalInput);
|
|
finalBits -= 8;
|
|
finalInput >>= 8;
|
|
}
|
|
|
|
if (finalBits > 0) {
|
|
absorbBits(finalInput, finalBits);
|
|
}
|
|
|
|
squeeze(out, outOff, outLen * 8);
|
|
|
|
reset();
|
|
|
|
return outLen;
|
|
}
|
|
|
|
@override
|
|
int doOutput(Uint8List out, int outOff, int outLen) {
|
|
if (!squeezing) {
|
|
absorbBits(0x0F, 4);
|
|
}
|
|
|
|
squeeze(out, outOff, outLen * 8);
|
|
|
|
return outLen;
|
|
}
|
|
}
|