blob: 53f9290b510f97857bb2477d2c55f85606adc8d4 [file] [log] [blame] [edit]
// 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;
}
}