| // 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; |
| } |
| } |