diff --git a/Source/DEC60.dpr b/Source/DEC60.dpr
index 10cdafa5..bca0efc0 100644
--- a/Source/DEC60.dpr
+++ b/Source/DEC60.dpr
@@ -49,7 +49,9 @@ uses
DECZIPHelper in 'DECZIPHelper.pas',
DECCipherPaddings in 'DECCipherPaddings.pas',
DECCipherModesCCM in 'DECCipherModesCCM.pas',
- DECAuthenticatedCipherModesBase in 'DECAuthenticatedCipherModesBase.pas';
+ DECAuthenticatedCipherModesBase in 'DECAuthenticatedCipherModesBase.pas',
+ DECCipherModesPoly1305 in 'DECCipherModesPoly1305.pas',
+ DECCPUSupport in 'DECCPUSupport.pas';
begin
try
diff --git a/Source/DECAuthenticatedCipherModesBase.pas b/Source/DECAuthenticatedCipherModesBase.pas
index 6245f1af..1b392833 100644
--- a/Source/DECAuthenticatedCipherModesBase.pas
+++ b/Source/DECAuthenticatedCipherModesBase.pas
@@ -59,6 +59,16 @@ EDECAuthLengthException = class(EDECException);
/// Base class for authenticated cipher modes
///
TAuthenticatedCipherModesBase = class(TObject)
+ private
+ ///
+ /// Flag that indicates if the method has been initialized
+ ///
+ fAuthMethodInit : boolean;
+
+ ///
+ /// Length of the processed buffer
+ ///
+ fEncDecLen : Int64;
strict protected
///
/// The data which shall be authenticated in parallel to the encryption
@@ -99,6 +109,32 @@ TAuthenticatedCipherModesBase = class(TObject)
/// Length of the calculated authentication value in bit
///
function GetAuthenticationTagBitLength: UInt32; virtual;
+
+
+ ///
+ /// Initialize the authentication procedure. This is a good place to initialize
+ /// the data structures and initialize with the (unencrypted) authenticated buffer
+ ///
+ procedure InitAuth; virtual; abstract;
+
+ ///
+ /// Updates the mac. Can be called multiple times!
+ ///
+ procedure UpdateWithEncDecBuf(buf : PUInt8Array; Size : Integer); virtual; abstract;
+
+ ///
+ /// finalize the MAC - typically the processed buffer lengths are incorporated here.
+ ///
+ procedure FinalizeMAC( authLen, encDecBufSize : Int64 ); virtual; abstract;
+
+ ///
+ /// Encoding/Decoding routine that is called in the Encode/Decode routine.
+ /// This version simply calls the EncryptionMethod givin in the init call
+ ///
+ procedure LocEncodeDecode(Source, Dest: Pointer; Size: Integer); virtual;
+
+ procedure Burn; virtual; abstract;
+
public
///
/// Should be called when starting encryption/decryption in order to
@@ -127,7 +163,7 @@ TAuthenticatedCipherModesBase = class(TObject)
///
procedure Encode(Source,
Dest : PUInt8Array;
- Size : Integer); virtual; abstract;
+ Size : Integer); virtual;
///
/// Decodes a block of data using the supplied cipher
///
@@ -142,7 +178,13 @@ TAuthenticatedCipherModesBase = class(TObject)
///
procedure Decode(Source,
Dest : PUInt8Array;
- Size : Integer); virtual; abstract;
+ Size : Integer); virtual;
+
+ ///
+ /// Call this function to calculate the final MAC - typically one updates the
+ /// remaining buffer with buffer lengths.
+ ///
+ procedure FinalizeAEAD;
///
/// Returns a list of authentication tag lengths explicitely specified by
@@ -192,6 +234,48 @@ implementation
{ TAuthenticatedCipherModesBase }
+procedure TAuthenticatedCipherModesBase.Decode(Source, Dest: PUInt8Array;
+ Size: Integer);
+begin
+ if not fAuthMethodInit then
+ begin
+ InitAuth;
+ fAuthMethodInit := True;
+ end;
+
+ UpdateWithEncDecBuf(Source, size);
+ LocEncodeDecode(Source, Dest, Size);
+ inc(fEncDecLen, Size);
+end;
+
+procedure TAuthenticatedCipherModesBase.Encode(Source, Dest: PUInt8Array;
+ Size: Integer);
+begin
+ if not fAuthMethodInit then
+ begin
+ InitAuth;
+ fAuthMethodInit := True;
+ end;
+
+ LocEncodeDecode(Source, Dest, Size);
+ UpdateWithEncDecBuf(Dest, size);
+ inc(fEncDecLen, Size);
+end;
+
+procedure TAuthenticatedCipherModesBase.FinalizeAEAD;
+begin
+ if not fAuthMethodInit then
+ begin
+ InitAuth;
+ fAuthMethodInit := True;
+ end;
+
+ SetLength(FCalcAuthenticationTag, FCalcAuthenticationTagLength);
+ FinalizeMAC(Length(FDataToAuthenticate), fEncDecLen);
+
+ Burn;
+end;
+
function TAuthenticatedCipherModesBase.GetAuthenticationTagBitLength: UInt32;
begin
Result := FCalcAuthenticationTagLength shl 3;
@@ -210,6 +294,7 @@ procedure TAuthenticatedCipherModesBase.Init(EncryptionMethod : TEncodeDecodeMet
Assert(Assigned(EncryptionMethod), 'No encryption method specified');
// Clear calculated authentication value
+ fAuthMethodInit := False;
CalcAuthLength := Length(FCalcAuthenticationTag);
if (CalcAuthLength > 0) then
begin
@@ -218,9 +303,16 @@ procedure TAuthenticatedCipherModesBase.Init(EncryptionMethod : TEncodeDecodeMet
FillChar(FCalcAuthenticationTag[0], CalcAuthLength, #0);
end;
+ fEncDecLen := 0;
FEncryptionMethod := EncryptionMethod;
end;
+procedure TAuthenticatedCipherModesBase.LocEncodeDecode(Source, Dest: Pointer;
+ Size: Integer);
+begin
+ FEncryptionMethod(Source, Dest, Size);
+end;
+
procedure TAuthenticatedCipherModesBase.SetAuthenticationTagLength(const Value: UInt32);
begin
FCalcAuthenticationTagLength := Value shr 3;
diff --git a/Source/DECCPUSupport.pas b/Source/DECCPUSupport.pas
new file mode 100644
index 00000000..1a81ce18
--- /dev/null
+++ b/Source/DECCPUSupport.pas
@@ -0,0 +1,117 @@
+{*****************************************************************************
+ The DEC team (see file NOTICE.txt) licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. A copy of this licence is found in the root directory
+ of this project in the file LICENCE.txt or alternatively at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*****************************************************************************}
+
+///
+/// x86 and x64 CPU instruction support functions.
+/// this class only works for intel cpus - arm will result.
+/// The functions defined here return true if the feature is availabe
+/// for the cpu
+///
+
+unit DECCPUSupport;
+
+interface
+
+type
+ TDEC_CPUSupport = class(TObject)
+ public
+ // flags are set in initialization
+ class var AES : boolean;
+ class var AVX : boolean;
+ class var AVX2 : boolean;
+
+ class var SSE : boolean;
+ class var SSE2 : boolean;
+ class var SSE3 : boolean;
+ class var SSE41 : boolean;
+ class var SSE42 : boolean;
+
+ class var RDRand : boolean;
+ class var RDSeed : boolean;
+ end;
+
+implementation
+
+{$IFDEF CPUX64}
+{$DEFINE x64}
+{$ENDIF}
+{$IFDEF cpux86_64}
+{$DEFINE x64}
+{$ENDIF}
+
+{$IFDEF CPU86}
+{$DEFINE x86}
+{$ENDIF}
+{$IFDEF CPUX86}
+{$DEFINE x86}
+{$ENDIF}
+
+{$IFDEF CPU386}
+{$DEFINE x86}
+{$ENDIF}
+
+
+{$IF Defined(x64) or Defined(x86)}
+{$WARN SYMBOL_PLATFORM OFF}
+procedure InitFlags;
+var reg : TCPUIDRec;
+ nids : LongWord;
+begin
+ reg := GetCPUID(0, 0);
+ nids := reg.EAX;
+
+
+ if nids >= 1 then
+ begin
+ reg := GetCPUID(1, 0);
+ TDEC_CPUSupport.SSE := (reg.EDX and (1 shl 25)) <> 0;
+ TDEC_CPUSupport.SSE2 := (reg.EDX and (1 shl 26)) <> 0;
+ TDEC_CPUSupport.SSE3 := (reg.ECX and (1 shl 9)) <> 0;
+ TDEC_CPUSupport.SSE41 := (reg.ECX and (1 shl 19)) <> 0;
+ TDEC_CPUSupport.SSE42 := (reg.ECX and (1 shl 20)) <> 0;
+ TDEC_CPUSupport.AES := (reg.ECX and (1 shl 25)) <> 0;
+
+ TDEC_CPUSupport.AVX := (reg.ECX and (1 shl 28)) <> 0;
+ TDEC_CPUSupport.RDRAND := (reg.ECX and (1 shl 30)) <> 0;
+ end;
+
+ if nids >= 7 then
+ begin
+ reg := GetCPUID($7);
+ TDEC_CPUSupport.AVX2 := (reg.EBX and (1 shl 5)) <> 0;
+ TDEC_CPUSupport.RDSEED := (reg.EBX and (1 shl 18)) <> 0;
+ end;
+end;
+{$ENDIF}
+
+initialization
+ TDEC_CPUSupport.AES := False;
+ TDEC_CPUSupport.AVX := False;
+ TDEC_CPUSupport.AVX2 := False;
+
+ TDEC_CPUSupport.SSE := False;
+ TDEC_CPUSupport.SSE2 := False;
+ TDEC_CPUSupport.SSE3 := False;
+ TDEC_CPUSupport.SSE41 := False;
+ TDEC_CPUSupport.SSE42 := False;
+
+ TDEC_CPUSupport.RDRand := False;
+ TDEC_CPUSupport.RDSeed := False;
+{$IF Defined(x64) or Defined(x86)}
+ InitFlags;
+{$IFEND}
+end.
diff --git a/Source/DECCipherBase.pas b/Source/DECCipherBase.pas
index f6cecfae..99e0a4fc 100644
--- a/Source/DECCipherBase.pas
+++ b/Source/DECCipherBase.pas
@@ -183,7 +183,8 @@ interface
cmCFSx, // CFS on Blocksize bytes
cmECBx, // Electronic Code Book
cmGCM, // Galois Counter Mode
- cmCCM // Counter with CBC-MAC Mode
+ cmCCM, // Counter with CBC-MAC Mode
+ cmPoly1305 // Poly1305 for ChaCha
{$IFDEF DEC3_CMCTS}
,cmCTS3 // double CBC, with less secure padding of truncated final block
// for DEC 3.0 compatibility only (see DECOptions.inc)
@@ -1012,7 +1013,7 @@ procedure TDECCipher.Init(const Key; Size: Integer; const IVector;
if (Size > Context.KeySize) and (not (ctNull in Context.CipherType)) then
raise EDECCipherException.CreateRes(@sKeyMaterialTooLarge);
- if (FInitVectorSize > FBufferSize) and (not (FMode = cmGCM)) then
+ if (FInitVectorSize > FBufferSize) and (not (FMode in [cmGCM, cmPoly1305])) then
raise EDECCipherException.CreateRes(@sIVMaterialTooLarge);
DoInit(Key, Size);
diff --git a/Source/DECCipherFormats.pas b/Source/DECCipherFormats.pas
index 20e5c145..42a7da59 100644
--- a/Source/DECCipherFormats.pas
+++ b/Source/DECCipherFormats.pas
@@ -730,10 +730,10 @@ function TDECFormattedCipher.EncodeBytes(const Source: TBytes): TBytes;
begin
SetLength(Result, Length(Source));
if Length(Result) > 0 then
- Encode(Source[0], Result[0], Length(Source))
- else
- if (FMode = cmGCM) then
- EncodeGCM(nil, nil, 0);
+ Encode(Source[0], Result[0], Length(Source));
+ //else
+// if (FMode = cmGCM) then
+// EncodeWithAuthObj(nil, nil, 0);
end;
begin
@@ -745,18 +745,15 @@ function TDECFormattedCipher.EncodeBytes(const Source: TBytes): TBytes;
function TDECFormattedCipher.DecodeBytes(const Source: TBytes): TBytes;
begin
- Result := Source;
+ SetLength(Result, Length(Source));
if Length(Result) > 0 then
begin
- if (FMode = cmGCM) then
- SetLength(Result, Length(Source));
-
Decode(Source[0], Result[0], Length(Source));
- end
- else
- if (FMode = cmGCM) then
- DecodeGCM(nil, nil, 0);
+ end;
+ //else
+ //if (FMode = cmGCM) then
+ // DecodeGCM(nil, nil, 0);
if not (FPaddingClass = nil) then
Result := FPaddingClass.RemovePadding(Result, Context.BlockSize);
diff --git a/Source/DECCipherModes.pas b/Source/DECCipherModes.pas
index e4673bda..e687f63b 100644
--- a/Source/DECCipherModes.pas
+++ b/Source/DECCipherModes.pas
@@ -26,8 +26,8 @@ interface
{$ELSE}
System.SysUtils,
{$ENDIF}
- DECTypes, DECCipherBase, DECCipherModesGCM, DECCipherModesCCM,
- DECCipherInterface;
+ DECTypes, DECCipherBase,
+ DECCipherInterface, DECAuthenticatedCipherModesBase;
type
///
@@ -139,22 +139,12 @@ TDECCipherModes = class(TDECCipher, IDECAuthenticatedCipher)
procedure SetExpectedAuthenticationResult(const Value: TBytes);
strict protected
///
- /// Implementation of the Galois counter mode. Only created when gmGCM is
- /// set as mode.
+ /// Implementation of the Galois counter mode, poly1305 or ccm. Only created if
+ /// such a mode is selected
///
- FGCM : TGCM;
- ///
- /// Implementation of the Counter with CBC-MAC mode. Only created when
- /// gmCCM is set as mode.
- ///
- FCCM : TCCM;
- ///
- /// Raises an EDECCipherException exception and provides the correct value
- /// for block size in that message
- ///
- ///
- /// Exception raised unconditionally.
- ///
+ fAuthObj : TAuthenticatedCipherModesBase;
+
+
procedure ReportInvalidMessageLength(Cipher: TDECCipher);
///
/// Allows to run code after the initialization vector has been initialized
@@ -244,13 +234,8 @@ TDECCipherModes = class(TDECCipher, IDECAuthenticatedCipher)
/// Implemented in its own unit, but needed here to be callable even if
/// source length is 0.
///
- procedure EncodeGCM(Source, Dest: PUInt8Array; Size: Integer); virtual;
- ///
- /// Counter with CBC-MAC Mode: encryption with addtional optional authentication.
- /// Implemented in its own unit, but needed here to be callable even if
- /// source length is 0.
- ///
- procedure EncodeCCM(Source, Dest: PUInt8Array; Size: Integer); virtual;
+ procedure EncodeWithAuthObj(Source, Dest: PUInt8Array; Size: Integer); virtual;
+
{$IFDEF DEC3_CMCTS}
///
/// double CBC, with
@@ -334,14 +319,11 @@ TDECCipherModes = class(TDECCipher, IDECAuthenticatedCipher)
/// inputstream into feedback register.
///
procedure DecodeCTSx(Source, Dest: PUInt8Array; Size: Integer); virtual;
- ///
- /// Galois Counter Mode, details are implemented in DECCipherModesGCM
- ///
- procedure DecodeGCM(Source, Dest: PUInt8Array; Size: Integer); virtual;
- ///
- /// Counter with CBC-MAC Mode, details are implemented in DECCipherModesCCM
+
+ ///
+ /// Decoding for gcm, poly1305 and ccm, details are implemented in special units.
///
- procedure DecodeCCM(Source, Dest: PUInt8Array; Size: Integer); virtual;
+ procedure DecodeWithAuthObj(Source, Dest: PUInt8Array; Size: Integer); virtual;
{$IFDEF DEC3_CMCTS}
///
/// double CBC
@@ -467,7 +449,10 @@ implementation
{$ELSE}
System.TypInfo,
{$ENDIF}
- DECUtil;
+ DECUtil,
+ DECCipherModesGCM,
+ DECCipherModesCCM,
+ DECCipherModesPoly1305;
resourcestring
sInvalidMessageLength = 'Message length for mode %0:s must be a multiple of %1:d bytes';
@@ -491,33 +476,30 @@ procedure TDECCipherModes.ReportInvalidMessageLength(Cipher: TDECCipher);
procedure TDECCipherModes.SetDataToAuthenticate(const Value: TBytes);
begin
- case FMode of
- cmGCM: FGCM.DataToAuthenticate := Value;
- cmCCM: FCCM.DataToAuthenticate := Value;
- else
- raise EDECCipherException.CreateResFmt(@sInvalidModeForMethod, ['cmGCM or cmCCM']);
- end;
+ if Assigned(fAuthObj)
+ then
+ fAuthObj.DataToAuthenticate := Value
+ else
+ raise EDECCipherException.CreateResFmt(@sInvalidModeForMethod, ['cmGCM or cmCCM']);
end;
procedure TDECCipherModes.SetExpectedAuthenticationResult(const Value: TBytes);
begin
- case FMode of
- cmGCM: FGCM.ExpectedAuthenticationTag := Value;
- cmCCM: FCCM.ExpectedAuthenticationTag := Value;
- else
- raise EDECCipherException.CreateResFmt(@sInvalidModeForMethod, ['cmGCM or cmCCM']);
- end;
+ if Assigned(fAuthObj)
+ then
+ fAuthObj.ExpectedAuthenticationTag := Value
+ else
+ raise EDECCipherException.CreateResFmt(@sInvalidModeForMethod, ['cmGCM or cmCCM']);
end;
procedure TDECCipherModes.SetAuthenticationResultBitLength(
const Value: Integer);
begin
- case FMode of
- cmGCM: FGCM.AuthenticationTagBitLength := Value;
- cmCCM: FCCM.AuthenticationTagBitLength := Value;
- else
- raise EDECCipherException.CreateResFmt(@sInvalidModeForMethod, ['cmGCM or cmCCM']);
- end;
+ if Assigned(fAuthObj)
+ then
+ fAuthObj.AuthenticationTagBitLength := Value
+ else
+ raise EDECCipherException.CreateResFmt(@sInvalidModeForMethod, ['cmGCM or cmCCM']);
end;
procedure TDECCipherModes.Encode(const Source; var Dest; DataSize: Integer);
@@ -537,8 +519,9 @@ procedure TDECCipherModes.Encode(const Source; var Dest; DataSize: Integer);
cmOFBx: EncodeOFBx(@Source, @Dest, DataSize);
cmCFS8: EncodeCFS8(@Source, @Dest, DataSize);
cmCFSx: EncodeCFSx(@Source, @Dest, DataSize);
- cmGCM : EncodeGCM(@Source, @Dest, DataSize);
- cmCCM : EncodeCCM(@Source, @Dest, DataSize);
+ cmGCM,
+ cmPoly1305,
+ cmCCM: EncodeWithAuthObj(@Source, @Dest, DataSize);
end;
end;
@@ -710,68 +693,67 @@ procedure TDECCipherModes.EncodeOFBx(Source, Dest: PUInt8Array; Size: Integer);
function TDECCipherModes.GetDataToAuthenticate: TBytes;
begin
- case FMode of
- cmGCM: Result := FGCM.DataToAuthenticate;
- cmCCM: Result := FCCM.DataToAuthenticate;
- else
- raise EDECCipherException.CreateResFmt(@sInvalidModeForMethod, ['cmGCM or cCCM']);
- end;
+ if Assigned(fAuthObj)
+ then
+ Result := fAuthObj.DataToAuthenticate
+ else
+ raise EDECCipherException.CreateResFmt(@sInvalidModeForMethod, ['cmGCM, cmPoly1305 or cCCM']);
end;
function TDECCipherModes.GetExpectedAuthenticationResult: TBytes;
begin
- case FMode of
- cmGCM: Result := FGCM.ExpectedAuthenticationTag;
- cmCCM: Result := FCCM.ExpectedAuthenticationTag;
- else
- raise EDECCipherException.CreateResFmt(@sInvalidModeForMethod, ['cmGCM or cmCCM']);
- end;
+ if Assigned(fAuthObj)
+ then
+ Result := fAuthObj.ExpectedAuthenticationTag
+ else
+ raise EDECCipherException.CreateResFmt(@sInvalidModeForMethod, ['cmGCM, cmPoly1305 or cmCCM']);
end;
function TDECCipherModes.GetStandardAuthenticationTagBitLengths: TStandardBitLengths;
begin
- case FMode of
- cmGCM: Result := FGCM.GetStandardAuthenticationTagBitLengths;
- cmCCM: Result := FCCM.GetStandardAuthenticationTagBitLengths;
- else
- begin
- SetLength(Result, 1);
- Result[0] := 0;
- end;
- end;
+ if Assigned(fAuthObj)
+ then
+ Result := fAuthObj.GetStandardAuthenticationTagBitLengths
+ else
+ begin
+ SetLength(Result, 1);
+ Result[0] := 0;
+ end;
end;
function TDECCipherModes.GetAuthenticationResultBitLength: Integer;
begin
- case FMode of
- cmGCM: Result := FGCM.AuthenticationTagBitLength;
- cmCCM: Result := FCCM.AuthenticationTagBitLength;
- else
- raise EDECCipherException.CreateResFmt(@sInvalidModeForMethod, ['cmGCM or cmCCM']);
- end;
+ if Assigned(fAuthObj)
+ then
+ Result := fAuthObj.AuthenticationTagBitLength
+ else
+ raise EDECCipherException.CreateResFmt(@sInvalidModeForMethod, ['cmGCM, cmPoly1305 or cmCCM']);
end;
function TDECCipherModes.GetCalcAuthenticatonResult: TBytes;
begin
- case FMode of
- cmGCM: Result := FGCM.CalculatedAuthenticationTag;
- cmCCM: Result := FCCM.CalculatedAuthenticationTag;
- else
- raise EDECCipherException.CreateResFmt(@sInvalidModeForMethod, ['cmGCM or cmCCM']);
- end;
+ if Assigned(fAuthObj)
+ then
+ Result := fAuthObj.CalculatedAuthenticationTag
+ else
+ raise EDECCipherException.CreateResFmt(@sInvalidModeForMethod, ['cmGCM, cmPoly1305 or cmCCM']);
end;
procedure TDECCipherModes.InitMode;
begin
- if FMode in [TCipherMode.cmGCM, TCipherMode.cmCCM] then
+ if FMode in [TCipherMode.cmGCM, TCipherMode.cmCCM, TCipherMode.cmPoly1305] then
begin
if (Context.BlockSize = 16) then
begin
- case FMode of
- cmGCM: FGCM := TGCM.Create;
- cmCCM: FCCM := TCCM.Create;
+ case FMode of
+ cmGCM: fAuthObj := TGCM.Create;
+ cmCCM: fAuthObj := TCCM.Create;
+ cmPoly1305: fAuthObj := TPoly1305.Create;
end;
end
+ else if (Context.BlockSize < 16) and (TCipherMode.cmPoly1305 = FMode)
+ then
+ fAuthObj := TPoly1305.Create
else
// GCM and CCM require a cipher with 128 bit block size
raise EDECCipherException.CreateResFmt(@sInvalidBlockSize,
@@ -780,11 +762,8 @@ procedure TDECCipherModes.InitMode;
end
else
begin
- if Assigned(FGCM) then
- FreeAndNil(FGCM);
-
- if Assigned(FCCM) then
- FreeAndNil(FCCM);
+ if Assigned(fAuthObj) then
+ FreeAndNil(fAuthObj);
end;
end;
@@ -878,20 +857,12 @@ procedure TDECCipherModes.EncodeCTSx(Source, Dest: PUInt8Array; Size: Integer);
FState := csEncode;
end;
-procedure TDECCipherModes.EncodeGCM(Source, Dest: PUInt8Array; Size: Integer);
-begin
- if (Size < 0) then
- Size := 0;
-
- FGCM.Encode(Source, Dest, Size);
-end;
-
-procedure TDECCipherModes.EncodeCCM(Source, Dest: PUInt8Array; Size: Integer);
+procedure TDECCipherModes.EncodeWithAuthObj(Source, Dest: PUInt8Array; Size: Integer);
begin
if (Size < 0) then
Size := 0;
- FCCM.Encode(Source, Dest, Size);
+ fAuthObj.Encode(Source, Dest, Size);
end;
{$IFDEF DEC3_CMCTS}
@@ -936,8 +907,9 @@ procedure TDECCipherModes.Decode(const Source; var Dest; DataSize: Integer);
cmOFBx: DecodeOFBx(@Source, @Dest, DataSize);
cmCFS8: DecodeCFS8(@Source, @Dest, DataSize);
cmCFSx: DecodeCFSx(@Source, @Dest, DataSize);
- cmGCM : DecodeGCM(@Source, @Dest, DataSize);
- cmCCM : DecodeCCM(@Source, @Dest, DataSize);
+ cmGCM,
+ cmPoly1305,
+ cmCCM : DecodeWithAuthObj(@Source, @Dest, DataSize);
end;
end;
@@ -976,20 +948,12 @@ procedure TDECCipherModes.DecodeECBx(Source, Dest: PUInt8Array; Size: Integer);
end;
end;
-procedure TDECCipherModes.DecodeGCM(Source, Dest: PUInt8Array; Size: Integer);
-begin
- if (Size < 0) then
- Size := 0;
-
- FGCM.Decode(Source, Dest, Size);
-end;
-
-procedure TDECCipherModes.DecodeCCM(Source, Dest: PUInt8Array; Size: Integer);
+procedure TDECCipherModes.DecodeWithAuthObj(Source, Dest: PUInt8Array; Size: Integer);
begin
if (Size < 0) then
Size := 0;
- FCCM.Decode(Source, Dest, Size);
+ fAuthObj.Decode(Source, Dest, Size);
end;
procedure TDECCipherModes.DecodeCFB8(Source, Dest: PUInt8Array; Size: Integer);
@@ -1137,39 +1101,32 @@ procedure TDECCipherModes.DecodeOFBx(Source, Dest: PUInt8Array; Size: Integer);
destructor TDECCipherModes.Destroy;
begin
- FGCM.Free;
- FCCM.Free;
+ fAuthObj.Free;
- inherited;
+ inherited;
end;
procedure TDECCipherModes.Done;
begin
- inherited;
+ if Assigned(fAuthObj) then
+ begin
+ fAuthObj.FinalizeAEAD;
- case FMode of
- cmGCM : begin
- if (length(FGCM.ExpectedAuthenticationTag) > 0) and
- (not IsEqual(FGCM.ExpectedAuthenticationTag, FGCM.CalculatedAuthenticationTag)) then
- raise EDECCipherAuthenticationException.CreateRes(@sInvalidAuthenticationValue);
- end;
-
- cmCCM : begin
- if (length(FCCM.ExpectedAuthenticationTag) > 0) and
- (not IsEqual(FCCM.ExpectedAuthenticationTag, FCCM.CalculatedAuthenticationTag)) then
- raise EDECCipherAuthenticationException.CreateRes(@sInvalidAuthenticationValue);
- end;
+ if (length(fAuthObj.ExpectedAuthenticationTag) > 0) and
+ (not IsEqual(fAuthObj.ExpectedAuthenticationTag, fAuthObj.CalculatedAuthenticationTag))
+ then
+ raise EDECCipherAuthenticationException.CreateRes(@sInvalidAuthenticationValue);
end;
+
+ inherited;
end;
procedure TDECCipherModes.OnAfterInitVectorInitialization(const OriginalInitVector: TBytes);
begin
inherited;
- case FMode of
- cmGCM: FGCM.Init(self.DoEncode, OriginalInitVector);
- cmCCM: FCCM.Init(self.DoEncode, OriginalInitVector);
- end;
+ if Assigned(fAuthObj) then
+ fAuthObj.Init(self.DoEncode, OriginalInitVector);
end;
procedure TDECCipherModes.DecodeCFSx(Source, Dest: PUInt8Array; Size: Integer);
diff --git a/Source/DECCipherModesCCM.pas b/Source/DECCipherModesCCM.pas
index 3f835f67..966ce7a4 100644
--- a/Source/DECCipherModesCCM.pas
+++ b/Source/DECCipherModesCCM.pas
@@ -78,6 +78,15 @@ TCCM = class(TAuthenticatedCipherModesBase)
/// are: 32, 48, 64, 80, 96, 112, 128
///
procedure SetAuthenticationTagLength(const Value: UInt32); override;
+
+ // ###########################################
+ // #### Empty routines - just to satisfy the interface
+ procedure InitAuth; override;
+ procedure UpdateWithEncDecBuf(buf : PUInt8Array; Size : Integer); override;
+ procedure LocEncodeDecode(Source, Dest: Pointer; Size: Integer); override;
+ procedure FinalizeMAC( authLen, encDecBufSize : Int64 ); override;
+
+ procedure Burn; override;
public
///
/// Savely clear any buffers
@@ -396,4 +405,35 @@ procedure TCCM.Init(EncryptionMethod : TEncodeDecodeMethod;
FOrigInitVector := InitVector;
end;
+
+procedure TCCM.UpdateWithEncDecBuf(buf: PUInt8Array; Size: Integer);
+begin
+ inherited;
+
+end;
+
+procedure TCCM.InitAuth;
+begin
+ inherited;
+
+end;
+
+procedure TCCM.LocEncodeDecode(Source, Dest: Pointer; Size: Integer);
+begin
+ inherited;
+
+end;
+
+procedure TCCM.Burn;
+begin
+ inherited;
+
+end;
+
+procedure TCCM.FinalizeMAC(authLen, encDecBufSize: Int64);
+begin
+ inherited;
+
+end;
+
end.
diff --git a/Source/DECCipherModesGCM.pas b/Source/DECCipherModesGCM.pas
index ed2cde55..c87009b8 100644
--- a/Source/DECCipherModesGCM.pas
+++ b/Source/DECCipherModesGCM.pas
@@ -52,16 +52,37 @@ interface
/// Galois Counter Mode specific methods
///
TGCM = class(TAuthenticatedCipherModesBase)
+ strict private
+ const cGCMBlkSize = 16;
strict private
///
/// Empty value?
///
nullbytes : T128;
+
+ ///
+ /// if flag is set no more encoding is allowed
+ ///
+ fIsLastBlock : boolean;
+
+ ///
+ /// One reserve buffer for the GCM intermediate blocks
+ ///
+ FData : Array[0..cGCMBlkSize-1] of Byte;
+
+ ///
+ /// Current index of non encoded fdata bytes
+ ///
+ FDataIdx : integer;
+
///
/// Table with precalculated values
///
FM : array[0..15,0..255] of T128;
+ ///
+ FGHash : T128;
+
///
/// Required for creating the table and encryption at least
///
@@ -174,6 +195,11 @@ TGCM = class(TAuthenticatedCipherModesBase)
///
procedure INCR(var Y : T128);
+ ///
+ // ###########################################
+ // #### blocked version of GaloisHash functions
+ // ###########################################
+
///
/// Calculates the hash value
///
@@ -193,10 +219,18 @@ TGCM = class(TAuthenticatedCipherModesBase)
///
/// Calculated raw hash value which will later get returned as AuthenticatedTag
///
- function CalcGaloisHash(AuthenticatedData : PUInt8Array;
- AuthLen : Integer;
- Ciphertext : PUInt8Array;
- CiphertextSize : Integer): T128;
+ function CalcGaloisHash(AuthenticatedData: PUInt8Array; AuthLen: integer;
+ Ciphertext: PUInt8Array; CiphertextSize: Integer): T128;
+
+
+
+ ///
+ /// Finalizes the Hash using the Authdata length and accumulated CipherText length.
+ ///
+ ///
+ /// Calculated raw hash value which will later get returned as AuthenticatedTag
+ ///
+
///
/// Encrypts a T128 value using the encryption method specified on init
@@ -207,7 +241,7 @@ TGCM = class(TAuthenticatedCipherModesBase)
///
/// Encrypted value
///
- function EncodeT128(Value: T128): T128;
+ function EncodeT128(Value: T128): T128; inline;
strict protected
///
/// Defines the length of the resulting authentication value in bit.
@@ -219,50 +253,65 @@ TGCM = class(TAuthenticatedCipherModesBase)
/// constrains the length of the input data and the lifetime of the key.
///
procedure SetAuthenticationTagLength(const Value: UInt32); override;
- public
+
+
///
- /// Should be called when starting encryption/decryption in order to
- /// initialize internal tables etc.
+ /// Finalizes the Poly1305 calculation
+ /// The last block is padded and one additional block containing
+ /// the processed length + the legnth processed AuthenticationBytes
+ /// is created and fed into the polynom.
+ /// After this call the MAC is valid.
///
- ///
- /// Encryption method of the cypher used
+ procedure FinalizeMAC( authLen, encDecBufLen : int64); override;
+
+ ///
+ /// Initializes the Galois Hash function internal data and starts
+ /// with the DataToAuthenticate field.
+ ///
+ procedure InitAuth; override;
+
+ ///
+ /// Updates the hash with a given cipher text. Internally the ciphertext length
+ /// field is also updated
+ ///
+ ///
+ /// Pointer the data that updates the hash.
///
- ///
- /// Initialization vector
+ ///
+ /// Length of the buffer
///
- procedure Init(EncryptionMethod : TEncodeDecodeMethod;
- InitVector : TBytes); override;
+ procedure UpdateWithEncDecBuf(buf : PUInt8Array; Size : Integer); override;
+
///
- /// Encodes a block of data using the supplied cipher
+ /// Encoding/Decoding routine - For some methods it is sufficient to just call
+ /// the given encoding routine (poly1305, chacha handles that internally) - some need to update the cipher (e.g. aes gcm)
///
///
- /// Plain text to encrypt
+ /// Pointer the data that updates the hash.
///
///
- /// Ciphertext after encryption
+ /// Pointer the data that updates the hash.
///
- ///
- /// Number of bytes to encrypt
+ ///
+ /// Length of the buffer
///
- procedure Encode(Source,
- Dest : PUInt8Array;
- Size : Integer); override;
+ procedure LocEncodeDecode(Source, Dest: Pointer; Size: Integer); override;
+
+
+ procedure Burn; override;
+ public
///
- /// Decodes a block of data using the supplied cipher
+ /// Should be called when starting encryption/decryption in order to
+ /// initialize internal tables etc.
///
- ///
- /// Encrypted ciphertext to decrypt
- ///
- ///
- /// Plaintext after decryption
+ ///
+ /// Encryption method of the cypher used
///
- ///
- /// Number of bytes to decrypt
+ ///
+ /// Initialization vector
///
- procedure Decode(Source,
- Dest : PUInt8Array;
- Size : Integer); override;
-
+ procedure Init(EncryptionMethod : TEncodeDecodeMethod;
+ InitVector : TBytes); override;
///
/// Returns a list of authentication tag lengths explicitely specified by
/// the official specification of the standard.
@@ -275,6 +324,14 @@ TGCM = class(TAuthenticatedCipherModesBase)
implementation
+uses Math;
+
+function TGCM.EncodeT128(Value: T128): T128;
+begin
+ FEncryptionMethod(@Value[0], @Result[0], 16);
+end;
+
+
function TGCM.XOR_T128(const x, y : T128): T128;
begin
Result[0] := x[0] xor y[0];
@@ -436,11 +493,13 @@ procedure TGCM.Init(EncryptionMethod : TEncodeDecodeMethod;
begin
inherited;
+ FEncryptionMethod := EncryptionMethod;
+
Nullbytes[0] := 0;
Nullbytes[1] := 0;
OldH := FH;
- EncryptionMethod(@Nullbytes[0], @FH[0], 16);
+ FEncryptionMethod(@Nullbytes[0], @FH[0], 16);
// Only generate the table when not already generated
if (OldH[0] <> FH[0]) or (OldH[1] <> FH[1]) then
@@ -460,205 +519,268 @@ procedure TGCM.Init(EncryptionMethod : TEncodeDecodeMethod;
FEncryptionMethod(@FY[0], @FE_K_Y0[0], 16);
end;
-function TGCM.CalcGaloisHash(AuthenticatedData : PUInt8Array; AuthLen : integer; Ciphertext : PUInt8Array;
- CiphertextSize: Integer): T128;
-var
- AuthCipherLength : T128;
- x : T128;
- n : Uint64;
+procedure TGCM.InitAuth;
+var authLen : integer;
+begin
+ inherited;
+
+ FillChar(fData, sizeof(fData), 0);
+ FDataIdx := 0;
+
+ FGHash := nullbytes;
+ if Length(FDataToAuthenticate) > 0 then
+ begin
+ authLen := Length(FDataToAuthenticate);
+ UpdateWithEncDecBuf(@FDataToAuthenticate[0], authLen);
+ // this block needs to be padded if the authentication buffer is not a multiple of 16
+ authLen := 16 - (authLen mod 16);
+ if authLen <> 16 then
+ UpdateWithEncDecBuf(@nullbytes, authLen);
+ end;
+
+ fIsLastBlock := False;
+end;
- procedure encode(data : PUInt8Array; dataSize: Integer);
- var
- i, mod_d, div_d, len_d : UInt64;
- hdata : T128;
- begin
- len_d := dataSize;
- if (len_d > 0) then
- begin
- n := 0;
- div_d := len_d div 16;
- if div_d > 0 then
- begin
- for i := 0 to div_d-1 do
- begin
- x := poly_mult_H(XOR_PointerWithT128(@data^[n], x ));
- inc(n, 16);
- end;
- end;
+procedure TGCM.LocEncodeDecode(Source, Dest: Pointer; Size: Integer);
+var i, j : integer;
+ div_len_plain : integer;
- mod_d := len_d mod 16;
- if mod_d > 0 then
- begin
- hdata := nullbytes;
- Move(data^[n], hdata[0], mod_d);
- x := poly_mult_H(XOR_T128(hdata, x));
- end;
+begin
+ if fIsLastBlock then
+ raise Exception.Create('Already last block processed. Call the encode only with a blocksize of 16 bytes');
+ i := 0;
+ div_len_plain := Size div 16;
+
+ for j := 1 to div_len_plain do
+ begin
+ INCR(FY);
+
+ P128(@PUInt8Array(Dest)^[i])^ := XOR_PointerWithT128(@PUInt8Array(Source)^[i], EncodeT128(FY));
+
+ inc(i,16);
+ end;
+
+ // is it the last block?
+ if i < Size then
+ begin
+ fIsLastBlock := True;
+ INCR(FY);
+ XOR_ArrayWithT128(Source, i, Size - i, EncodeT128(FY), Dest);
end;
- end;
+end;
+procedure TGCM.FinalizeMAC(authLen, encDecBufLen: int64);
+var res : T128;
+ AuthCipherLength : T128;
+ x : T128;
begin
- x := nullbytes;
- if AuthLen > 0 then
- encode(@AuthenticatedData[0], AuthLen);
- //Assert(length(Ciphertext) >= CiphertextSize);
- encode(Ciphertext, CiphertextSize);
- SetAuthenticationCipherLength(AuthCipherLength, AuthLen shl 3, CiphertextSize shl 3);
+ // last block:::
+ if FDataIdx > 0 then
+ begin
+ x := nullbytes;
+ Move(fData[0], x, FDataIdx);
+ FGHash := poly_mult_H(XOR_T128(x, FGHash));
+ fDataIdx := 0;
+ end;
+
+ // update hash with the lengths...
+ SetAuthenticationCipherLength(AuthCipherLength, authLen shl 3, encDecBufLen shl 3);
+ res := XOR_T128(poly_mult_H(XOR_T128(AuthCipherLength, FGHash)), FE_K_Y0);
+
+ // copy and burn
+ if Length(FCalcAuthenticationTag) > 0 then
+ Move(res, FCalcAuthenticationTag[0], Min(sizeof(res), length(FCalcAuthenticationTag)));
+ res := nullbytes;
+ FillChar(FData, sizeof(fData), 0);
+end;
- Result := poly_mult_H(XOR_T128(AuthCipherLength, x));
+procedure TGCM.UpdateWithEncDecBuf(buf: PUInt8Array; Size: Integer);
+var i, div_d, len_d : integer;
+ n : integer;
+begin
+ n := 0;
+ if FDataIdx > 0 then
+ begin
+ if cGCMBlkSize - fDataIdx > Size then
+ begin
+ Move(buf^[0], fData[FDataIdx], size);
+ inc(FDataIdx, size);
+ exit;
+ end
+ else
+ begin
+ // encode one block
+ n := cGCMBlkSize - fDataIdx;
+ Move( buf^[0], fData[fDataIdx], n);
+ FGHash := poly_mult_H(XOR_PointerWithT128(@fData[0], FGHash ));
+ FDataIdx := 0;
+ end;
+
+ end;
+
+ len_d := size - n;
+ if (len_d >= cGCMBlkSize) then
+ begin
+ div_d := len_d div cGCMBlkSize;
+ for i := 0 to div_d - 1 do
+ begin
+ FGHash := poly_mult_H(XOR_PointerWithT128(@buf^[n], FGHash ));
+ inc(n, cGCMBlkSize);
+ end;
+ end;
+
+ if n < size then
+ begin
+ Move(buf^[n], fData[fDataIdx], size - n);
+ inc(FDataIdx, size - n);
+ end;
end;
-procedure TGCM.Decode(Source, Dest: PUInt8Array; Size: Integer);
+(*
+procedure TGCM.Encode(Source, Dest: PUInt8Array; Size: Integer);
var
- i, j, BlockCount : UInt64;
- a_tag : T128;
+ i, j, div_len_plain : UInt64;
+ AuthTag : T128;
pDataToAuth : PUInt8Array;
- pSrc : PUInt8Array;
begin
i := 0;
- BlockCount := Size div 16;
+ div_len_plain := Size div 16;
- for j := 1 to BlockCount do
+ for j := 1 to div_len_plain do
begin
INCR(FY);
+
P128(@Dest^[i])^ := XOR_PointerWithT128(@Source^[i], EncodeT128(FY));
- inc(i, 16);
+
+ inc(i,16);
end;
if i < Size then
begin
INCR(FY);
- XOR_ArrayWithT128(@Source^[0], i, UInt64(Size)-i, EncodeT128(FY), @Dest^[0]);
+ XOR_ArrayWithT128(Source, i, UInt64(Size)-i, EncodeT128(FY), Dest);
end;
pDataToAuth := nil;
if Length(DataToAuthenticate) > 0 then
pDataToAuth := @DataToAuthenticate[0];
- pSrc := nil;
- if Size > 0 then
- pSrc := @source[0];
-
- a_tag := XOR_T128(CalcGaloisHash(pDataToAuth, Length(DataToAuthenticate),
- pSrc, Size), FE_K_Y0);
-
+ AuthTag := XOR_T128(CalcGaloisHash(pDataToAuth, Length(DataToAuthenticate), @Dest[0], Size), FE_K_Y0);
Setlength(FCalcAuthenticationTag, FCalcAuthenticationTagLength);
if (FCalcAuthenticationTagLength > 0) then
- Move(a_tag[0], FCalcAuthenticationTag[0], FCalcAuthenticationTagLength);
-
- // Check for correct authentication result is in Done of DECCipherModes
- // if not IsEqual(FExpectedAuthenticationTag, FCalcAuthenticationTag) then
- // raise EDECCipherAuthenticationException.CreateRes(@sInvalidAuthenticationValue);
-
- // In difference to the NIST recommendation we do not discard plaintext if
- // authentication failed to make data recovery possible. But since we throw
- // an exception the user will get notified that there's something wrong
- // if not IsEqual(authenticaton_tag, ba_tag) then
- // SetLength(plaintext, 0); // NIST FAIL => pt=''
+ Move(AuthTag[0], FCalcAuthenticationTag[0], FCalcAuthenticationTagLength);
end;
-procedure TGCM.Encode(Source, Dest: PUInt8Array; Size: Integer);
+*)
+
+(*
+procedure TGCM.EncodeGCMBlk(Ciphertext, Dest : PUInt8Array;
+ CiphertextSize : Integer;
+ lastBlock: boolean);
var
- i, j, div_len_plain : UInt64;
+ i, j, div_len_plain : integer;
AuthTag : T128;
- pDataToAuth : PUInt8Array;
begin
+ // len = 0 -> first block. Init the hash
+ if FCipherLen = 0 then
+ BeginCalcGaloisHash;
+
+ if not lastBlock and (CiphertextSize mod 16 <> 0) then
+ raise Exception.Create('Only multiple of 16bytes are allowed in block mode');
+
i := 0;
- div_len_plain := Size div 16;
+ div_len_plain := CiphertextSize div 16;
for j := 1 to div_len_plain do
begin
INCR(FY);
- P128(@Dest^[i])^ := XOR_PointerWithT128(@Source^[i], EncodeT128(FY));
+ P128(@Dest^[i])^ := XOR_PointerWithT128(@Ciphertext^[i], EncodeT128(FY));
inc(i,16);
end;
- if i < Size then
+ if lastBlock then
begin
- INCR(FY);
- XOR_ArrayWithT128(Source, i, UInt64(Size)-i, EncodeT128(FY), Dest);
- end;
+ if i < CiphertextSize then
+ begin
+ INCR(FY);
+ XOR_ArrayWithT128(Ciphertext, i, CiphertextSize-i, EncodeT128(FY), Dest);
+ end;
- pDataToAuth := nil;
- if Length(DataToAuthenticate) > 0 then
- pDataToAuth := @DataToAuthenticate[0];
- AuthTag := XOR_T128(CalcGaloisHash(pDataToAuth, Length(DataToAuthenticate), @Dest[0], Size), FE_K_Y0);
- Setlength(FCalcAuthenticationTag, FCalcAuthenticationTagLength);
- if (FCalcAuthenticationTagLength > 0) then
- Move(AuthTag[0], FCalcAuthenticationTag[0], FCalcAuthenticationTagLength);
-end;
+ UpdateGaloisHash(Dest, CiphertextSize);
-function TGCM.EncodeT128(Value: T128): T128;
-begin
- FEncryptionMethod(@Value[0], @Result[0], 16);
+ //AuthTag := XOR_T128(CalcGaloisHash(DataToAuthenticate, Dest, Size), FE_K_Y0);
+ AuthTag := XOR_T128(FinishGaloisHash, FE_K_Y0);
+ Setlength(FCalcAuthenticationTag, FCalcAuthenticationTagLength);
+ if (FCalcAuthenticationTagLength > 0) then
+ Move(AuthTag[0], FCalcAuthenticationTag[0], FCalcAuthenticationTagLength);
+ end
+ else
+ begin
+ UpdateGaloisHash(Dest, CiphertextSize);
+ end;
end;
+*)
+
function TGCM.GetStandardAuthenticationTagBitLengths: TStandardBitLengths;
begin
SetLength(Result, 5);
Result := [96, 104, 112, 120, 128];
end;
-//
-//function decrypt( const key, IV : TBytes; out plaintext : TBytes; const authenticated_data,
-//ciphertext : TBytes; len_auth_tag : integer; const authenticaton_tag : TBytes ) : boolean;
-//var
-// i, j, div_len_ciph, len_ciph : Uint64;
-// a_tag, E_K_Y0, Y, H : T128;
-// bY : array[0..15] of byte absolute Y[0];
-// ba_Tag : TBytes;
-//
-// function equal( const a, b : TBytes ):boolean;
-// begin
-// if length(a) <> length(b) then Result := false
-// else
-// Result := CompareMem( @a[0], @b[0], length(a) );
-// end;
-//
-//begin
-// len_auth_tag := len_auth_tag shr 3;
-//
-// E_Init( key );
-// H := E_Cipher( nullbytes );
-// Table_M_8Bit(H);
-//
-// len_ciph := length( ciphertext );
-// SetLength( plaintext, len_ciph );
-//
-// if length(IV) = 12 then
-// begin
-// Y[1] := 0;
-// Move( IV[0], Y[0], 12 );
-// bY[15] := 1;
-// end
-// else
-// Y := CalcGaloisHash( H, nil, IV );
-//
-// E_K_Y0 := E_Cipher( y );
-//
-// i := 0;
-// div_len_ciph := len_ciph div 16;
-// for j := 1 to div_len_ciph do
-// begin
-// INCR( Y );
-// P128(@plaintext[i])^ := XOR_128_n( @ciphertext[i], E_cipher( Y ) );
-// inc(i,16);
-// end;
-//
-// if i < len_ciph then
-// begin
-// INCR( Y );
-// XOR_128_n_l( ciphertext, i, len_ciph-i, E_cipher( Y ), plaintext );
-// end;
-//
-// a_tag := XOR_128( CalcGaloisHash( H, authenticated_data, ciphertext ), E_K_Y0 );
-//
-// Setlength( ba_tag, len_auth_tag );
-// Move( a_tag[0], ba_tag[0], len_auth_tag );
-//
-// Result := equal( authenticaton_tag, ba_tag );
-// if not Result then SetLength( plaintext, 0 ); // NIST FAIL => pt=''
-//end;
-//
+procedure TGCM.Burn;
+begin
+ inherited;
+
+ FH := nullbytes;
+end;
+
+function TGCM.CalcGaloisHash(AuthenticatedData : PUInt8Array; AuthLen : integer; Ciphertext : PUInt8Array;
+ CiphertextSize: Integer): T128;
+var
+ AuthCipherLength : T128;
+ x : T128;
+ n : Uint64;
+
+ procedure encode(data : PUInt8Array; dataSize: Integer);
+ var
+ i, mod_d, div_d, len_d : UInt64;
+ hdata : T128;
+ begin
+ len_d := dataSize;
+ if (len_d > 0) then
+ begin
+ n := 0;
+ div_d := len_d div 16;
+ if div_d > 0 then
+ begin
+ for i := 0 to div_d-1 do
+ begin
+ x := poly_mult_H(XOR_PointerWithT128(@data^[n], x ));
+ inc(n, 16);
+ end;
+ end;
+
+ mod_d := len_d mod 16;
+ if mod_d > 0 then
+ begin
+ hdata := nullbytes;
+ Move(data^[n], hdata[0], mod_d);
+ x := poly_mult_H(XOR_T128(hdata, x));
+ end;
+ end;
+ end;
+
+begin
+ x := nullbytes;
+ if AuthLen > 0 then
+ encode(@AuthenticatedData[0], AuthLen);
+ //Assert(length(Ciphertext) >= CiphertextSize);
+ encode(Ciphertext, CiphertextSize);
+ SetAuthenticationCipherLength(AuthCipherLength, AuthLen shl 3, CiphertextSize shl 3);
+
+ Result := poly_mult_H(XOR_T128(AuthCipherLength, x));
+end;
end.
diff --git a/Source/DECCipherModesPoly1305.pas b/Source/DECCipherModesPoly1305.pas
new file mode 100644
index 00000000..13a8086d
--- /dev/null
+++ b/Source/DECCipherModesPoly1305.pas
@@ -0,0 +1,1249 @@
+{*****************************************************************************
+ The DEC team (see file NOTICE.txt) licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. A copy of this licence is found in the root directory
+ of this project in the file LICENCE.txt or alternatively at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*****************************************************************************}
+
+unit DECCipherModesPoly1305;
+
+interface
+
+{$INCLUDE DECOptions.inc}
+
+uses
+ {$IFDEF FPC}
+ SysUtils,
+ {$ELSE}
+ System.SysUtils,
+ {$ENDIF}
+ DECTypes, DECAuthenticatedCipherModesBase;
+
+// ###########################################
+// #### The implementation follows the openssl poly1305 one
+// on https://github.com/openssl/openssl/blob/master/crypto/poly1305/poly1305.c
+// the avx optimization is based on https://github.com/Sreyosi/Improved-SIMD-Implementation-of-Poly1305/
+type
+ T32ByteArray = Array[0..31] of Byte; // 0 - 16: key, 17-32 nonce
+ TPoly1305CpuMode = (pmPas, pmAVX);
+type
+ TPoly1305 = class(TAuthenticatedCipherModesBase)
+ private
+ const POLY1305_BLOCK_SIZE = 16;
+ POLY1305_DIGEST_SIZE = 16;
+ POLY1305_KEY_SIZE = 32;
+ type
+ TPoly1305Nonce = Array[0..3] of UInt32;
+ PPoly1305Nonce = ^TPoly1305Nonce;
+ TPoly1305BlockMethod = procedure ( pData : PByteArray; size : integer ) of Object;
+ TPoly1305EmitMethod = procedure( var mac: TBlock16Byte ) of Object;
+ TPoly1305PadAndFinalize = procedure( authLen, encDecBufLen : int64) of Object;
+ THArr = Array[0..4] of UInt32;
+ PHArr = ^THArr;
+ TRArr = Array[0..3] of UInt32;
+ PRArr = ^TRArr;
+
+ TStateAVXArr = Array[0..4] of UInt64;
+ T4UInt64 = Array[0..3] of UInt64;
+ P4UInt64 = ^T4UInt64;
+ T2UInt64 = Array[0..1] of UInt64;
+ P2UInt64 = ^T2UInt64;
+
+ PStateAVXArr = ^TStateAVXArr;
+
+ TPoly1305CTX = packed record
+ r : TStateAVXArr;
+ rr : TStateAVXArr;
+ k0, k1, k2, k3, k4 : T4UInt64; // 4-lane kernels for H0..H3
+ k0_5, k1_5, k2_5, k3_5, k4_5 : UInt64; // scalar 5th term multiplier
+ h : TStateAVXArr;
+ s0, s1 : UInt64; // nonce
+ end;
+ PPoly1305CTX = ^TPoly1305CTX;
+
+ TPoly1305State = Array[0..431] of Byte; // sizeof(TPoly1305Ctx) + 2*xmm register size + 64 alignment bytes
+
+ private
+ ///
+ /// buffer for h and R and other precomputed values. The buffer is shared between
+ /// the pure pascal and the AVX implementation
+ ///
+ fPoly1305State : TPoly1305State;
+
+ ///
+ /// H and R values. These point ot the fPoly1305State buffer
+ ///
+ FH : PHArr;
+ FR : PRArr;
+
+ ///
+ /// AVX2 optimized buffers. These point ot the fPoly1305State buffer
+ ///
+ fAVXCtx : PPoly1305CTX;
+ fXMMMem : PUint64;
+
+ ///
+ /// Initialization vector and nonce - initialized from the 32Byte init vector
+ ///
+ fIV : T32ByteArray;
+ FNonce : TPoly1305Nonce;
+
+ ///
+ /// Internal state variables - number of remaining bytes, block size and intermediate buffer
+ ///
+ fNum : integer;
+ fPolyBlockSize : integer;
+ fData : Array[0..2*POLY1305_BLOCK_SIZE - 1] of Byte; // for both the avx and pas version
+
+ ///
+ /// #bytes of encrypted data
+ ///
+ fPolyInitComplete : boolean;
+
+ ///
+ /// Reference to the actual poly block function. For future SSE, AVX use
+ ///
+ fPolyBlkFunc : TPoly1305BlockMethod;
+ fPadAndFinalizeFunc : TPoly1305PadAndFinalize;
+
+ function U8ToU32( pData : PByteArray ) : UInt32; inline;
+ procedure U32ToU8(pData : PByteArray; value : UInt32); inline;
+
+ ///
+ /// Poly1305 blocks function
+ ///
+ procedure Poly1305Blocks( pData : PByteArray; size : integer; padBit : UInt32 );
+
+ ///
+ /// Finaly MAC creating function
+ ///
+ procedure Poly1305Emit( var mac : TBlock16Byte; const nonce : TPoly1305Nonce );
+ procedure PadAndFinalizePAS( authLen, encDecBufLen : int64);
+ procedure PadAndFinalizeAVX(authLen, encDecBufLen: int64);
+ protected
+ // ###########################################
+ // #### Authentication block functions
+ {$IFNDEF PUREPASCAL}
+ procedure UpdatePolyAVX( pData : PByteArray; size : integer);
+ procedure FinalizeAVX;
+ {$ENDIF}
+ procedure UpdatePoly( pData : PByteArray; size : integer);
+ procedure InitInternal(const InitVector : T32ByteArray);
+ procedure Finalize;
+
+
+ ///
+ /// Finalizes the Poly1305 calculation
+ /// The last block is padded and one additional block containing
+ /// the processed length + the legnth processed AuthenticationBytes
+ /// is created and fed into the polynom.
+ /// After this call the MAC is valid.
+ ///
+ procedure FinalizeMAC( authLen, encDecBufLen : int64); override;
+ procedure InitAuth; override;
+ procedure UpdateWithEncDecBuf(buf : PUInt8Array; Size : Integer); override;
+
+ procedure Burn; override;
+ public
+ ///
+ /// Defines either pure pascal code is used or specialized assembler routines utilizing AVX instructions
+ ///
+ class var CpuMode : TPoly1305CpuMode;
+
+
+ constructor Create;
+
+ ///
+ /// Should be called when starting encryption/decryption in order to
+ /// initialize internal tables etc.
+ ///
+ ///
+ /// Encryption method of the cypher used
+ ///
+ ///
+ /// Initialization vector
+ ///
+ procedure Init(EncryptionMethod : TEncodeDecodeMethod;
+ InitVector : TBytes); override;
+ end;
+
+implementation
+
+{$R-}
+
+uses DECCPUSupport;{$Q-}
+
+const cMask26 : uint64 = $3ffffff;
+ cShl24 : uint64 = $1000000;
+
+//CONSTANT_TIME_CARRY(a,b) ( \
+// (a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(a) * 8 - 1) \
+// )
+function ConstTimeCarray32(a, b : UInt32 ) : UInt32; inline;
+begin
+ Result := (a xor ( (a xor b) or ((a - b) xor b))) shr 31;
+end;
+
+// ###########################################
+// #### AVX Assembler - and associated procedures
+// ###########################################
+
+{$IFNDEF PUREPASCAL}
+
+{$IFDEF FPC} {$ASMMode Intel} {$ENDIF}
+
+procedure Split26( const lo, hi : UInt64; outVal : TPoly1305.PStateAVXArr ); inline;
+var t0, t1, t2, t3, t4 : UInt64;
+begin
+ t0 := lo;
+ t1 := (lo shr 26) or (hi shl 38);
+ t2 := (lo shr 52) or (hi shl 12);
+ t3 := (hi shr 14);
+ t4 := hi shr 40;
+ outval^[0] := t0 and cMask26;
+ outval^[1] := t1 and cMask26;
+ outval^[2] := t2 and cMask26;
+ outval^[3] := t3 and cMask26;
+ outval^[4] := t4 and cMask26;
+end;
+
+procedure clamp_r( r : TPoly1305.PStateAVXArr); inline;
+begin
+ r^[1] := r^[1] and $3ffff03;
+ r^[2] := r^[2] and $3ffc0ff;
+ r^[3] := r^[3] and $3f03fff;
+ r^[4] := r^[4] and $00fffff;
+end;
+
+
+procedure InitPoly1305( ctx : TPoly1305.PPoly1305CTX; key : PByte );
+var i : integer;
+begin
+ FillChar(ctx^, sizeof(ctx^), 0);
+
+ Split26(TPoly1305.P4UInt64(key)^[0], TPoly1305.P4UInt64(key)^[1], @ctx.r[0]);
+ clamp_r(@ctx^.r[0]);
+
+ for i := 0 to High(ctx^.rr) do
+ ctx^.rr[i] := 5*ctx^.r[i];
+
+ // Precompute k0..k4 once (no per-block _mm256_set_epi64x needed)
+ // Note: _mm256_set_epi64x order is [lane3,lane2,lane1,lane0]
+ ctx^.k0[3] := ctx^.rr[2];
+ ctx^.k0[2] := ctx^.rr[3];
+ ctx^.k0[1] := ctx^.rr[4];
+ ctx^.k0[0] := ctx^.r[0];
+ ctx^.k0_5 := ctx^.rr[1];
+
+ ctx^.k1[3] := ctx^.rr[3];
+ ctx^.k1[2] := ctx^.rr[4];
+ ctx^.k1[1] := ctx^.r[0];
+ ctx^.k1[0] := ctx^.r[1];
+ ctx^.k1_5 := ctx^.rr[2];
+
+ ctx^.k2[3] := ctx^.rr[4];
+ ctx^.k2[2] := ctx^.r[0];
+ ctx^.k2[1] := ctx^.r[1];
+ ctx^.k2[0] := ctx^.r[2];
+ ctx^.k2_5 := ctx^.rr[3];
+
+ ctx^.k3[3] := ctx^.r[0];
+ ctx^.k3[2] := ctx^.r[1];
+ ctx^.k3[1] := ctx^.r[2];
+ ctx^.k3[0] := ctx^.r[3];
+ ctx^.k3_5 := ctx^.rr[4];
+
+ ctx^.k4[3] := ctx^.r[1];
+ ctx^.k4[2] := ctx^.r[2];
+ ctx^.k4[1] := ctx^.r[3];
+ ctx^.k4[0] := ctx^.r[4];
+ ctx^.k4_5 := ctx^.r[0];
+
+ // first 16 byte went to R -> the rest is used for the "nonce"
+ ctx^.s0 := TPoly1305.P4UInt64(key)^[2];
+ ctx^.s1 := TPoly1305.P4UInt64(key)^[3];
+end;
+
+procedure FinalizePoly1305( ctx : TPoly1305.PPoly1305CTX; mac : PByte );
+var h : TPoly1305.PStateAVXArr;
+ c : UInt64;
+ g : TPoly1305.TStateAVXArr;
+ mask : UInt64;
+ nmask : UInt64;
+ f0, f1 : UInt64;
+begin
+ h := @(ctx^.h[0]);
+ c := h^[1] shr 26; h^[1] := h^[1] and cMask26; inc(h^[2], c);
+ c := h^[2] shr 26; h^[2] := h^[2] and cMask26; inc(h^[3], c);
+ c := h^[3] shr 26; h^[3] := h^[3] and cMask26; inc(h^[4], c);
+ c := h^[4] shr 26; h^[4] := h^[4] and cMask26; inc(h^[0], 5*c);
+ c := h^[0] shr 26; h^[0] := h^[0] and cMask26; inc(h^[1], c);
+
+ g[0] := h[0] + 5;
+ g[1] := h[1] + (g[0] shr 26); g[0] := g[0] and cMask26;
+ g[2] := h[2] + (g[1] shr 26); g[0] := g[1] and cMask26;
+ g[3] := h[3] + (g[2] shr 26); g[0] := g[2] and cMask26;
+ g[4] := h[4] + (g[3] shr 26); g[0] := g[3] and cMask26;
+
+ dec(g[4], 1 shl 26);
+
+ // mask is either 0 or all ones depending on the last bit
+ // works only for disabled range checking and overflow checking!
+ mask := (g[4] shr 63) - 1;
+ g[4] := g[4] and cMask26;
+ nmask := not mask;
+ h^[0] := (h^[0] and nmask) or (g[0] and mask);
+ h^[1] := (h^[1] and nmask) or (g[1] and mask);
+ h^[2] := (h^[2] and nmask) or (g[2] and mask);
+ h^[3] := (h^[3] and nmask) or (g[3] and mask);
+ h^[4] := (h^[4] and nmask) or (g[4] and mask);
+
+ // pack into 128-bit LE
+ f0 := h^[0] or (h^[1] shl 26) or (h^[2] shl 52);
+ f1 := (h^[2] shr 12) or (h^[3] shl 14) or (h^[4] shl 40);
+
+ // add s
+ TPoly1305.P2UInt64(mac)^[0] := f0 + ctx^.s0;
+ TPoly1305.P2UInt64(mac)^[1] := f1 + ctx^.s1 + UInt64(TPoly1305.P2UInt64(@mac[0])^[0] < f0);
+end;
+
+// central xmm register save and restor (we don't need that in a tight loop)
+
+{$IFDEF X86ASM}
+
+procedure poly1305_block_avx2_ctx(ctx : TPoly1305.PPoly1305CTX; t : TPoly1305.PStateAVXArr); {$IFDEF FPC} assembler; {$ENDIF}
+asm
+ push ebp;
+ mov ecx, edx
+ mov ebp, esp
+ push edi
+ push esi
+ mov esi, eax
+ push ebx
+
+ // reserver mem on the local stack -> aligned 32bytes
+ and esp, -32
+ sub esp, 64
+
+
+ mov eax, DWORD PTR [edx+32]
+ add eax, DWORD PTR [esi+312]
+ {$IFDEF AVXSUP}vmovdqu ymm0, [ecx] {$ELSE}db $C5,$FE,$6F,$01;{$ENDIF}
+ mov edi, DWORD PTR [esi+240]
+ mov ecx, eax
+ mov DWORD PTR [esp+52], 0
+ mov eax, DWORD PTR [esi+244]
+ mov edx, DWORD PTR [edx+36]
+ mov DWORD PTR [esp+56], ecx
+ adc edx, DWORD PTR [esi+316]
+ {$IFDEF AVXSUP}vpaddq ymm0, ymm0, [esi+280] {$ELSE}db $C5,$FD,$D4,$86,$18,$01,$00,$00;{$ENDIF}
+ {$IFDEF AVXSUP}vpmuludq ymm1, ymm0, [esi+80] {$ELSE}db $C5,$FD,$F4,$4E,$50;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm2, xmm1 {$ELSE}db $C5,$F9,$6F,$D1;{$ENDIF}
+ imul eax, ecx
+ {$IFDEF AVXSUP}vextracti128 xmm1, ymm1, $1 {$ELSE}db $C4,$E3,$7D,$39,$C9,$01;{$ENDIF}
+ mov DWORD PTR [esp+60], edx
+ {$IFDEF AVXSUP}vpmuludq ymm3, ymm0, [esi+112] {$ELSE}db $C5,$FD,$F4,$5E,$70;{$ENDIF}
+ imul edi, edx
+ {$IFDEF AVXSUP}vpaddq xmm1, xmm1, xmm2 {$ELSE}db $C5,$F1,$D4,$CA;{$ENDIF}
+ {$IFDEF AVXSUP}vpsrldq xmm2, xmm1, 8 {$ELSE}db $C5,$E9,$73,$D9,$08;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddq xmm1, xmm1, xmm2 {$ELSE}db $C5,$F1,$D4,$CA;{$ENDIF}
+ {$IFDEF AVXSUP}vpmuludq ymm2, ymm0, [esi+144] {$ELSE}db $C5,$FD,$F4,$96,$90,$00,$00,$00;{$ENDIF}
+ add edi, eax
+ mov eax, ecx
+ mul DWORD PTR [esi+240]
+ mov ecx, eax
+ mov ebx, edx
+ {$IFDEF AVXSUP}vmovd eax, xmm1 {$ELSE}db $C5,$F9,$7E,$C8;{$ENDIF}
+ add ebx, edi
+ {$IFDEF AVXSUP}vpextrd edx, xmm1, 1 {$ELSE}db $C4,$E3,$79,$16,$CA,$01;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm1, xmm3 {$ELSE}db $C5,$F9,$6F,$CB;{$ENDIF}
+ add ecx, eax
+ adc ebx, edx
+ mov eax, DWORD PTR [esp+56]
+ mov edx, DWORD PTR [esi+252]
+ mov edi, ecx
+ and edi, 67108863
+ {$IFDEF AVXSUP}vextracti128 xmm3, ymm3, $1 {$ELSE}db $C4,$E3,$7D,$39,$DB,$01;{$ENDIF}
+ imul edx, eax
+ mov DWORD PTR [esp+48], edi
+ mov edi, DWORD PTR [esp+60]
+ {$IFDEF AVXSUP}vpaddq xmm3, xmm3, xmm1 {$ELSE}db $C5,$E1,$D4,$D9;{$ENDIF}
+ imul edi, DWORD PTR [esi+248]
+ mov eax, DWORD PTR [esp+56]
+ {$IFDEF AVXSUP}vpsrldq xmm6, xmm3, 8 {$ELSE}db $C5,$C9,$73,$DB,$08;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm1, xmm2 {$ELSE}db $C5,$F9,$6F,$CA;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddq xmm3, xmm3, xmm6 {$ELSE}db $C5,$E1,$D4,$DE;{$ENDIF}
+ {$IFDEF AVXSUP}vextracti128 xmm2, ymm2, $1 {$ELSE}db $C4,$E3,$7D,$39,$D2,$01;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddq xmm2, xmm2, xmm1 {$ELSE}db $C5,$E9,$D4,$D1;{$ENDIF}
+ {$IFDEF AVXSUP}vmovq QWORD PTR [esp+32], xmm3 {$ELSE}db $C5,$F9,$D6,$5C,$24,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vpmuludq ymm1, ymm0, [esi+176] {$ELSE}db $C5,$FD,$F4,$8E,$B0,$00,$00,$00;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm4, xmm1 {$ELSE}db $C5,$F9,$6F,$E1;{$ENDIF}
+ add edi, edx
+ mul DWORD PTR [esi+248]
+ {$IFDEF AVXSUP}vpmuludq ymm0, ymm0, [esi+208] {$ELSE}db $C5,$FD,$F4,$86,$D0,$00,$00,$00;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm7, xmm0 {$ELSE}db $C5,$F9,$6F,$F8;{$ENDIF}
+ {$IFDEF AVXSUP}vpsrldq xmm5, xmm2, 8 {$ELSE}db $C5,$D1,$73,$DA,$08;{$ENDIF}
+ {$IFDEF AVXSUP}vextracti128 xmm1, ymm1, $1 {$ELSE}db $C4,$E3,$7D,$39,$C9,$01;{$ENDIF}
+ {$IFDEF AVXSUP}vextracti128 xmm0, ymm0, $1 {$ELSE}db $C4,$E3,$7D,$39,$C0,$01;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddq xmm2, xmm2, xmm5 {$ELSE}db $C5,$E9,$D4,$D5;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddq xmm1, xmm1, xmm4 {$ELSE}db $C5,$F1,$D4,$CC;{$ENDIF}
+ add edx, edi
+ {$IFDEF AVXSUP}vpsrldq xmm4, xmm1, 8 {$ELSE}db $C5,$D9,$73,$D9,$08;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddq xmm0, xmm0, xmm7 {$ELSE}db $C5,$F9,$D4,$C7;{$ENDIF}
+ add eax, DWORD PTR [esp+32]
+ adc edx, DWORD PTR [esp+36]
+ shrd ecx, ebx, 26
+ {$IFDEF AVXSUP}vmovq QWORD PTR [esp+32], xmm2 {$ELSE}db $C5,$F9,$D6,$54,$24,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddq xmm1, xmm1, xmm4 {$ELSE}db $C5,$F1,$D4,$CC;{$ENDIF}
+ shr ebx, 26
+ add ecx, eax
+ mov eax, DWORD PTR [esp+56]
+ mov DWORD PTR [esp+44], 0
+ mov edi, ecx
+ {$IFDEF AVXSUP}vpsrldq xmm7, xmm0, 8 {$ELSE}db $C5,$C1,$73,$D8,$08;{$ENDIF}
+ adc ebx, edx
+ and edi, 67108863
+ imul eax, DWORD PTR [esi+260]
+ {$IFDEF AVXSUP}vpaddq xmm0, xmm0, xmm7 {$ELSE}db $C5,$F9,$D4,$C7;{$ENDIF}
+ mov DWORD PTR [esp+40], edi
+ mov edi, DWORD PTR [esp+60]
+ imul edi, DWORD PTR [esi+256]
+ add edi, eax
+ mov eax, DWORD PTR [esp+56]
+ mul DWORD PTR [esi+256]
+ add edx, edi
+ add eax, DWORD PTR [esp+32]
+ adc edx, DWORD PTR [esp+36]
+ shrd ecx, ebx, 26
+ shr ebx, 26
+ add eax, ecx
+ mov ecx, DWORD PTR [esp+56]
+ mov edi, DWORD PTR [esp+60]
+ mov DWORD PTR [esp+32], eax
+ mov eax, DWORD PTR [esi+268]
+ adc edx, ebx
+ imul edi, DWORD PTR [esi+264]
+ mov DWORD PTR [esp+36], edx
+ imul eax, ecx
+ add edi, eax
+ mov eax, ecx
+ mul DWORD PTR [esi+264]
+ mov ecx, eax
+ mov ebx, edx
+ {$IFDEF AVXSUP}vmovd eax, xmm1 {$ELSE}db $C5,$F9,$7E,$C8;{$ENDIF}
+ add ebx, edi
+ {$IFDEF AVXSUP}vpextrd edx, xmm1, 1 {$ELSE}db $C4,$E3,$79,$16,$CA,$01;{$ENDIF}
+ add eax, ecx
+ mov ecx, DWORD PTR [esp+32]
+ adc edx, ebx
+ mov ebx, DWORD PTR [esp+36]
+ mov edi, DWORD PTR [esp+60]
+ shrd ecx, ebx, 26
+ shr ebx, 26
+ add eax, ecx
+ mov ecx, DWORD PTR [esp+56]
+ adc edx, ebx
+ imul edi, DWORD PTR [esi+272]
+ mov DWORD PTR [esp+24], eax
+ mov DWORD PTR [esp+28], edx
+ mov edx, DWORD PTR [esi+276]
+ mov eax, ecx
+ imul edx, ecx
+ add edi, edx
+ mul DWORD PTR [esi+272]
+ mov ecx, eax
+ mov ebx, edx
+ {$IFDEF AVXSUP}vmovd eax, xmm0 {$ELSE}db $C5,$F9,$7E,$C0;{$ENDIF}
+ add ebx, edi
+ {$IFDEF AVXSUP}vpextrd edx, xmm0, 1 {$ELSE}db $C4,$E3,$79,$16,$C2,$01;{$ENDIF}
+ add eax, ecx
+ mov ecx, DWORD PTR [esp+24]
+ adc edx, ebx
+ mov ebx, DWORD PTR [esp+28]
+ mov edi, 5
+ shrd ecx, ebx, 26
+ shr ebx, 26
+ add ecx, eax
+ adc ebx, edx
+ mov eax, ecx
+ mov DWORD PTR [esp+56], ecx
+ mov edx, ebx
+ shrd eax, ebx, 26
+ mov DWORD PTR [esp+60], ebx
+ mov DWORD PTR [esi+284], 0
+ shr edx, 26
+ mov DWORD PTR [esi+300], 0
+ lea ebx, [edx+edx*4]
+ mov DWORD PTR [esi+308], 0
+ mul edi
+ mov DWORD PTR [esi+316], 0
+ add edx, ebx
+ add eax, DWORD PTR [esp+48]
+ adc edx, DWORD PTR [esp+52]
+ mov ebx, eax
+ shrd eax, edx, 26
+ and ebx, 67108863
+ shr edx, 26
+ add eax, DWORD PTR [esp+40]
+ adc edx, DWORD PTR [esp+44]
+ mov DWORD PTR [esi+288], eax
+ mov eax, DWORD PTR [esp+32]
+ mov DWORD PTR [esi+280], ebx
+ and eax, 67108863
+ mov DWORD PTR [esi+292], edx
+ mov DWORD PTR [esi+296], eax
+ mov eax, DWORD PTR [esp+24]
+ and eax, 67108863
+ mov DWORD PTR [esi+304], eax
+ mov eax, DWORD PTR [esp+56]
+ and eax, 67108863
+ mov DWORD PTR [esi+312], eax
+ {$IFDEF AVXSUP}vzeroupper {$ELSE}db $C5,$F8,$77;{$ENDIF}
+ lea esp, [ebp-12]
+ pop ebx
+ pop esi
+ pop edi
+ pop ebp
+end;
+
+
+{$ENDIF}
+
+{$IFDEF X64ASM}
+
+procedure StoreXMM( pXMM : PUInt64 ); register; {$IFDEF FPC} assembler; {$ENDIF}
+asm
+ {$IFDEF AVXSUP}vmovaps [rcx], xmm6; {$ELSE}db $C5,$F8,$29,$31;{$ENDIF}
+ {$IFDEF AVXSUP}vmovaps [rcx + 16], xmm7; {$ELSE}db $C5,$F8,$29,$79,$10;{$ENDIF}
+end;
+
+procedure RestoreXMM( pXMM : PUint64 ); register; {$IFDEF FPC} assembler; {$ENDIF}
+asm
+ {$IFDEF AVXSUP}vmovntdqa xmm6, [rcx]; {$ELSE}db $C4,$E2,$79,$2A,$31;{$ENDIF}
+ {$IFDEF AVXSUP}vmovntdqa xmm7, [rcx + 16]; {$ELSE}db $C4,$E2,$79,$2A,$79,$10;{$ENDIF}
+end;
+
+procedure poly1305_block_avx2_ctx(ctx : TPoly1305.PPoly1305CTX; t : TPoly1305.PStateAVXArr); {$IFDEF FPC} assembler; {$ENDIF}
+asm
+ {$IFDEF UNIX}
+ // Linux uses a diffrent ABI -> copy over the registers so they meet with winABI
+ // (note that the 5th and 6th parameter are are on the stack)
+ // The parameters are passed in the following order:
+ // RDI, RSI, RDX, RCX -> mov to RCX, RDX, R8, R9
+ mov rcx, rdi;
+ mov rdx, rsi;
+ {$ENDIF}
+
+ // H = h + t
+ {$IFDEF AVXSUP}vmovdqu ymm0, [rdx] {$ELSE}db $C5,$FE,$6F,$02;{$ENDIF} // load t[0..3]
+ mov rax, rcx
+ mov rcx, [rdx + 32] // load t[4]
+ {$IFDEF AVXSUP}vpaddq ymm0, ymm0, [rax + 280] {$ELSE}db $C5,$FD,$D4,$80,$18,$01,$00,$00;{$ENDIF} // load h[0..3]
+ mov r8, [rax + 240]
+
+ // calc c0 to c4
+ {$IFDEF AVXSUP}vpmuludq ymm1, ymm0, [rax + 80] {$ELSE}db $C5,$FD,$F4,$48,$50;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm2, xmm1 {$ELSE}db $C5,$F9,$6F,$D1;{$ENDIF}
+ {$IFDEF AVXSUP}vextracti128 xmm1, ymm1, $1 {$ELSE}db $C4,$E3,$7D,$39,$C9,$01;{$ENDIF}
+ add rcx, [rax + 312]
+ {$IFDEF AVXSUP}vpmuludq ymm3, ymm0, [rax + 112] {$ELSE}db $C5,$FD,$F4,$58,$70;{$ENDIF}
+ mov r11, [rax + 256]
+ imul r8, rcx
+ {$IFDEF AVXSUP}vpaddq xmm1, xmm1, xmm2 {$ELSE}db $C5,$F1,$D4,$CA;{$ENDIF}
+ {$IFDEF AVXSUP}vpsrldq xmm2, xmm1, 8 {$ELSE}db $C5,$E9,$73,$D9,$08;{$ENDIF}
+ imul r11, rcx
+ {$IFDEF AVXSUP}vpaddq xmm1, xmm1, xmm2 {$ELSE}db $C5,$F1,$D4,$CA;{$ENDIF}
+ {$IFDEF AVXSUP}vpmuludq ymm2, ymm0, [rax + 144] {$ELSE}db $C5,$FD,$F4,$90,$90,$00,$00,$00;{$ENDIF}
+ {$IFDEF AVXSUP}vmovq rdx, xmm1 {$ELSE}db $C4,$E1,$F9,$7E,$CA;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm1, xmm3 {$ELSE}db $C5,$F9,$6F,$CB;{$ENDIF}
+ {$IFDEF AVXSUP}vextracti128 xmm3, ymm3, $1 {$ELSE}db $C4,$E3,$7D,$39,$DB,$01;{$ENDIF}
+ add rdx, r8
+ mov r8, [rax + 248]
+ {$IFDEF AVXSUP}vpaddq xmm3, xmm3, xmm1 {$ELSE}db $C5,$E1,$D4,$D9;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm1, xmm2 {$ELSE}db $C5,$F9,$6F,$CA;{$ENDIF}
+ {$IFDEF AVXSUP}vpsrldq xmm7, xmm3, 8 {$ELSE}db $C5,$C1,$73,$DB,$08;{$ENDIF}
+ {$IFDEF AVXSUP}vextracti128 xmm2, ymm2, $1 {$ELSE}db $C4,$E3,$7D,$39,$D2,$01;{$ENDIF}
+ mov r9, rdx
+ shr rdx, 26
+ imul r8, rcx
+ {$IFDEF AVXSUP}vpaddq xmm3, xmm3, xmm7 {$ELSE}db $C5,$E1,$D4,$DF;{$ENDIF}
+ and r9d, 67108863
+ {$IFDEF AVXSUP}vpaddq xmm2, xmm2, xmm1 {$ELSE}db $C5,$E9,$D4,$D1;{$ENDIF}
+ {$IFDEF AVXSUP}vmovq r10, xmm3 {$ELSE}db $C4,$C1,$F9,$7E,$DA;{$ENDIF}
+ {$IFDEF AVXSUP}vpmuludq ymm1, ymm0, [rax + 176] {$ELSE}db $C5,$FD,$F4,$88,$B0,$00,$00,$00;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm4, xmm1 {$ELSE}db $C5,$F9,$6F,$E1;{$ENDIF}
+ {$IFDEF AVXSUP}vpsrldq xmm6, xmm2, 8 {$ELSE}db $C5,$C9,$73,$DA,$08;{$ENDIF}
+ {$IFDEF AVXSUP}vextracti128 xmm1, ymm1, $1 {$ELSE}db $C4,$E3,$7D,$39,$C9,$01;{$ENDIF}
+ {$IFDEF AVXSUP}vpmuludq ymm0, ymm0, [rax + 208] {$ELSE}db $C5,$FD,$F4,$80,$D0,$00,$00,$00;{$ENDIF}
+ add r8, r10
+ {$IFDEF AVXSUP}vpaddq xmm2, xmm2, xmm6 {$ELSE}db $C5,$E9,$D4,$D6;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddq xmm1, xmm1, xmm4 {$ELSE}db $C5,$F1,$D4,$CC;{$ENDIF}
+ add r8, rdx
+ {$IFDEF AVXSUP}vmovq rdx, xmm2 {$ELSE}db $C4,$E1,$F9,$7E,$D2;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm4, xmm0 {$ELSE}db $C5,$F9,$6F,$E0;{$ENDIF}
+ add rdx, r11
+ mov r11, [rax + 264]
+ mov r10, r8
+
+ // carry chain 26-bit, reduction mod 2^130-5
+ // + write back to h
+ {$IFDEF AVXSUP}vextracti128 xmm0, ymm0, $1 {$ELSE}db $C4,$E3,$7D,$39,$C0,$01;{$ENDIF}
+ {$IFDEF AVXSUP}vpsrldq xmm5, xmm1, 8 {$ELSE}db $C5,$D1,$73,$D9,$08;{$ENDIF}
+ shr r8, 26
+ {$IFDEF AVXSUP}vpaddq xmm0, xmm0, xmm4 {$ELSE}db $C5,$F9,$D4,$C4;{$ENDIF}
+ and r10d, 67108863
+ imul r11, rcx
+ {$IFDEF AVXSUP}vpaddq xmm1, xmm1, xmm5 {$ELSE}db $C5,$F1,$D4,$CD;{$ENDIF}
+ {$IFDEF AVXSUP}vpsrldq xmm4, xmm0, 8 {$ELSE}db $C5,$D9,$73,$D8,$08;{$ENDIF}
+ add r8, rdx
+ {$IFDEF AVXSUP}vmovq rdx, xmm1 {$ELSE}db $C4,$E1,$F9,$7E,$CA;{$ENDIF}
+ imul rcx, [rax + 272]
+ {$IFDEF AVXSUP}vpaddq xmm0, xmm0, xmm4 {$ELSE}db $C5,$F9,$D4,$C4;{$ENDIF}
+ add rdx, r11
+ mov r11, r8
+ and r8d, 67108863
+ shr r11, 26
+ mov [rax + 296], r8
+ add r11, rdx
+ {$IFDEF AVXSUP}vmovq rdx, xmm0 {$ELSE}db $C4,$E1,$F9,$7E,$C2;{$ENDIF}
+ add rcx, rdx
+ mov rdx, r11
+ shr rdx, 26
+ add rcx, rdx
+ mov rdx, rcx
+ and ecx, 67108863
+ shr rdx, 26
+ mov [rax + 312], rcx
+ lea rdx, [rdx + rdx*4]
+ add rdx, r9
+ mov r9, rdx
+ shr rdx, 26
+ add rdx, r10
+ and r9d, 67108863
+ mov [rax + 288], rdx
+ mov rdx, r11
+ and edx, 67108863
+ mov [rax + 280], r9
+ mov [rax + 304], rdx
+
+ {$IFDEF AVXSUP}vzeroupper {$ELSE}db $C5,$F8,$77;{$ENDIF}
+end;
+
+{$ENDIF}
+
+
+{$ENDIF}
+
+// ###########################################
+// #### Poly1305
+// ###########################################
+
+
+{ TPoly1305 }
+
+procedure TPoly1305.U32ToU8(pData: PByteArray; value: UInt32);
+begin
+ pData^[0] := Byte(value);
+ pData^[1] := Byte(value shr 8);
+ pData^[2] := Byte(value shr 16);
+ pData^[3] := Byte(value shr 24);
+end;
+
+function TPoly1305.U8ToU32(pData: PByteArray): UInt32;
+begin
+ Result := (UInt32(pData^[0]) and $ff) or
+ ((UInt32(pData^[1]) and $ff) shl 8) or
+ ((UInt32(pData^[2]) and $ff) shl 16) or
+ ((UInt32(pData^[3]) and $ff) shl 24);
+end;
+
+
+procedure TPoly1305.InitAuth;
+var aLen : integer;
+ vec : TBytes;
+begin
+ InitInternal(fIV);
+
+ aLen := Length(FDataToAuthenticate);
+ // update the polynom with the unencrypted authentication data
+ if aLen > 0 then
+ begin
+ // pad to blocksize if ncessary
+ if aLen mod POLY1305_BLOCK_SIZE <> 0 then
+ begin
+ aLen := aLen + POLY1305_BLOCK_SIZE - aLen mod POLY1305_BLOCK_SIZE;
+ SetLength(vec, aLen);
+ Move(FDataToAuthenticate[0], vec[0], Length(FDataToAuthenticate));
+ end
+ else
+ vec := FDataToAuthenticate;
+ fPolyBlkFunc( @vec[0], Length(vec));
+ end;
+end;
+
+
+procedure TPoly1305.Burn;
+begin
+ inherited;
+
+ FillChar(fPoly1305State, sizeof(fPoly1305State), 0);
+ FillChar(FNonce, sizeof(FNonce), 0);
+ FillChar(fIV, sizeof(fIV), 0);
+ FillChar(fData, sizeof(fData), 0);
+ fNum := 0;
+end;
+
+function AlignPtr64( A : Pointer ) : Pointer;
+begin
+ Result := A;
+ if (NativeUint(A) and $3F) <> 0 then
+ Result := Pointer( NativeUint(Result) + $40 - NativeUint(Result) and $3F );
+end;
+
+
+constructor TPoly1305.Create;
+begin
+ inherited Create;
+
+ FCalcAuthenticationTagLength := sizeof(TBlock16Byte);
+ fAVXCtx := AlignPtr64(@fPoly1305State[0]);
+ FH := @fAVXCtx^.h[0];
+ FR := @fAVXCtx^.r[0];
+
+ inc(fAVXCtx);
+ fXMMMem := PUInt64(fAVXCtx);
+ dec(fAVXCtx);
+
+ case CpuMode of
+ pmPas: begin
+ fPadAndFinalizeFunc := PadAndFinalizePAS;
+ fPolyBlkFunc := UpdatePoly;
+ end;
+ pmAVX: begin
+ {$IFNDEF PUREPASCAL}
+ fPadAndFinalizeFunc := PadAndFinalizeAVX;
+ fPolyBlkFunc := UpdatePolyAVX;
+ {$ELSE}
+ fPadAndFinalizeFunc := PadAndFinalizePAS;
+ fPolyBlkFunc := UpdatePoly;
+ {$ENDIF}
+ end;
+ end;
+ fPolyBlockSize := POLY1305_BLOCK_SIZE;
+end;
+
+procedure TPoly1305.Finalize;
+var mac : TBlock16Byte;
+begin
+ if fNum > 0 then
+ begin
+ fData[fNum] := 1; // padbit..
+ inc(fNum);
+ while fNum < Length(fData) do
+ begin
+ fData[fNum] := 0;
+ inc(fNum);
+ end;
+
+ Poly1305Blocks(@fData[0], POLY1305_BLOCK_SIZE, 0);
+ fNum := 0;
+ end;
+
+ Poly1305Emit(mac, FNonce);
+
+ SetLength(FCalcAuthenticationTag, sizeof(mac));
+ Move(mac, FCalcAuthenticationTag[0], sizeof(mac));
+
+ FillChar(mac, sizeof(mac), 0);
+end;
+
+{$IFNDEF PUREPASCAL}
+
+procedure TPoly1305.FinalizeAVX;
+var mac : TBlock16Byte;
+ t : TStateAVXArr;
+begin
+ if fNum > 0 then
+ begin
+ fData[fNum] := 1; // padbit..
+ inc(fNum);
+ while fNum < Length(fData) do
+ begin
+ fData[fNum] := 0;
+ inc(fNum);
+ end;
+
+ Split26(PUint64(@fData[0])^, PUint64(@fData[8])^, @t[0]);
+ {$IFDEF x64}
+ StoreXMM(fXMMMem)
+ {$ENDIF}
+ poly1305_block_avx2_ctx(fAVXCtx, @t[0]);
+ {$IFDEF x64}
+ RestoreXMM(fXMMMem);
+ {$ENDIF}
+ fNum := 0;
+ end;
+
+ FinalizePoly1305(fAVXCtx, @mac[0]);
+
+ SetLength(FCalcAuthenticationTag, sizeof(mac));
+ Move(mac, FCalcAuthenticationTag[0], sizeof(mac));
+
+ FillChar(mac, sizeof(mac), 0);
+end;
+{$ENDIF}
+
+
+procedure TPoly1305.Init(EncryptionMethod: TEncodeDecodeMethod;
+ InitVector: TBytes);
+begin
+ inherited;
+
+ // the poly1305 format needs to be initialized correctly from the outside!
+ // for chacha20 one needs to set initialize the chacha block with the key,
+ // 96bit nonce and counter to 0 -> the first 32bytes of that chacha scrambled block
+ // defines the iv
+ if Length(InitVector) <> ( Length(fIV) ) then
+ raise Exception.Create('The initVector must be 32Bytes long!');
+
+ // in this library this only works for chacha since it has an internal counter
+ // don't know how to deal with aes here...
+ // build the poly1305 iv from the first 256 bits
+ FillChar( fIV, sizeof(fIV), 0);
+ Move( initVector[0], fIV, Length(initVector));
+end;
+
+procedure TPoly1305.InitInternal(const InitVector: T32ByteArray);
+begin
+ fPolyInitComplete := True;
+
+ FillChar(fAVXCtx^, sizeof(fAVXCtx^), 0);
+
+ ///* r &= 0xffffffc0ffffffc0ffffffc0fffffff */
+// st->r[0] = U8TOU32(&key[0]) & 0x0fffffff;
+// st->r[1] = U8TOU32(&key[4]) & 0x0ffffffc;
+// st->r[2] = U8TOU32(&key[8]) & 0x0ffffffc;
+// st->r[3] = U8TOU32(&key[12]) & 0x0ffffffc;
+ FR^[0] := U8ToU32(@initVector[0]) and $0fffffff;
+ FR^[1] := U8ToU32(@initVector[4]) and $0ffffffc;
+ FR^[2] := U8ToU32(@initVector[8]) and $0ffffffc;
+ FR^[3] := U8ToU32(@initVector[12]) and $0ffffffc;
+
+
+ FNonce[0] := U8ToU32(@initVector[16]);
+ FNonce[1] := U8ToU32(@initVector[20]);
+ FNonce[2] := U8ToU32(@initVector[24]);
+ FNonce[3] := U8ToU32(@initVector[28]);
+
+ // initialize avx members
+ {$IFNDEF PUREPASCAL}
+ if CpuMode = pmAVX then
+ InitPoly1305(fAVXCtx, @InitVector[0]);
+ {$ENDIF}
+ fNum := 0;
+end;
+
+procedure TPoly1305.FinalizeMAC( authLen, encDecBufLen : int64);
+begin
+ inherited;
+
+ fPadAndFinalizeFunc(authLen, encDecBufLen);
+end;
+
+procedure TPoly1305.PadAndFinalizePAS( authLen, encDecBufLen : int64);
+var lens : Array[0..1] of Int64;
+begin
+ // pad the last block with 0
+ if fNum > 0 then
+ begin
+ fData[fNum] := 0;
+ inc(fNum);
+ while fNum < Length(fData) do
+ begin
+ fData[fNum] := 0;
+ inc(fNum);
+ end;
+
+ Poly1305Blocks(@fData[0], POLY1305_BLOCK_SIZE, 1);
+ fNum := 0;
+ end;
+
+
+ // finalize with the tag with the lengths!
+ lens[0] := authLen;
+ lens[1] := encDecBufLen;
+ Poly1305Blocks(@lens[0], POLY1305_BLOCK_SIZE, 1);
+
+ Finalize;
+end;
+
+{$IFNDEF PUREPASCAL}
+procedure TPoly1305.PadAndFinalizeAVX( authLen, encDecBufLen : int64);
+var lens : Array[0..1] of UInt64;
+ t : TStateAVXArr;
+begin
+ // pad the last block with 0
+ {$IFDEF x64}
+ StoreXMM(fXMMMem);
+ {$ENDIF}
+ if fNum > 0 then
+ begin
+ fData[fNum] := 0;
+ inc(fNum);
+ while fNum < Length(fData) do
+ begin
+ fData[fNum] := 0;
+ inc(fNum);
+ end;
+
+ Split26(PUint64(@fData[0])^, PUint64(@fData[8])^, @t[0]);
+ t[4] := t[4] + cShl24;
+
+ poly1305_block_avx2_ctx(fAVXCtx, @t[0]);
+ fNum := 0;
+ end;
+
+
+ // the last block contains the lenghts
+ lens[0] := authLen;
+ lens[1] := encDecBufLen;
+ Split26(lens[0], lens[1], @t[0]);
+ t[4] := t[4] + cShl24;
+ poly1305_block_avx2_ctx(fAVXCtx, @t[0]);
+ {$IFDEF x64}
+ RestoreXMM(fXMMMem);
+ {$ENDIF}
+
+ FinalizeAVX;
+end;
+{$ENDIF}
+
+
+procedure TPoly1305.Poly1305Blocks(pData: PByteArray; size: integer;
+ padBit: UInt32);
+var r0, r1, r2, r3 : UInt32;
+ s1, s2, s3 : UInt32;
+ h0, h1, h2, h3, h4, c : UInt32;
+ d0, d1, d2, d3 : UInt64;
+begin
+ //r0 = st->r[0];
+// r1 = st->r[1];
+// r2 = st->r[2];
+// r3 = st->r[3];
+ r0 := FR^[0];
+ r1 := FR^[1];
+ r2 := FR^[2];
+ r3 := FR^[3];
+
+ //s1 = r1 + (r1 >> 2);
+// s2 = r2 + (r2 >> 2);
+// s3 = r3 + (r3 >> 2);
+ s1 := r1 + (r1 shr 2);
+ s2 := r2 + (r2 shr 2);
+ s3 := r3 + (r3 shr 2);
+
+ //h0 = st->h[0];
+// h1 = st->h[1];
+// h2 = st->h[2];
+// h3 = st->h[3];
+// h4 = st->h[4];
+ h0 := FH^[0];
+ h1 := FH^[1];
+ h2 := FH^[2];
+ h3 := FH^[3];
+ h4 := FH^[4];
+
+ while size >= POLY1305_BLOCK_SIZE do
+ begin
+ ///* h += m[i] */
+// h0 = (u32)(d0 = (u64)h0 + U8TOU32(inp + 0));
+// h1 = (u32)(d1 = (u64)h1 + (d0 >> 32) + U8TOU32(inp + 4));
+// h2 = (u32)(d2 = (u64)h2 + (d1 >> 32) + U8TOU32(inp + 8));
+// h3 = (u32)(d3 = (u64)h3 + (d2 >> 32) + U8TOU32(inp + 12));
+// h4 += (u32)(d3 >> 32) + padbit;
+ d0 := UInt64(h0) + U8ToU32(pData);
+ h0 := UInt32(d0);
+ d1 := UInt64(h1) + d0 shr 32 + U8ToU32(@pData^[4]); // the delphi compiler seems to be intelligent enough to replace the shift by accessing the high 4 bytes
+ h1 := UInt32(d1);
+ d2 := UInt64(h2) + d1 shr 32 + U8ToU32(@pData^[8]);
+ h2 := UInt32(d2);
+ d3 := UInt64(h3) + d2 shr 32 + U8ToU32(@pData^[12]);
+ h3 := UInt32(d3);
+ h4 := h4 + padbit + UInt32( d3 shr 32);
+
+// /* h *= r "%" p, where "%" stands for "partial remainder" */
+ //d0 = ((u64)h0 * r0) +
+// ((u64)h1 * s3) +
+// ((u64)h2 * s2) +
+// ((u64)h3 * s1);
+ d0 := UInt64(h0)*r0 + UInt64(h1)*s3 + UInt64(h2)*s2 + UInt64(h3)*s1;
+
+// d1 = ((u64)h0 * r1) +
+// ((u64)h1 * r0) +
+// ((u64)h2 * s3) +
+// ((u64)h3 * s2) +
+// (h4 * s1);
+ d1 := UInt64(h0)*r1 + UInt64(h1)*r0 + UInt64(h2)*s3 + UInt64(h3)*s2 + h4*s1;
+
+// d2 = ((u64)h0 * r2) +
+// ((u64)h1 * r1) +
+// ((u64)h2 * r0) +
+// ((u64)h3 * s3) +
+// (h4 * s2);
+ d2 := UInt64(h0)*r2 + UInt64(h1)*r1 + UInt64(h2)*r0 + UInt64(h3)*s3 + h4*s2;
+
+// d3 = ((u64)h0 * r3) +
+// ((u64)h1 * r2) +
+// ((u64)h2 * r1) +
+// ((u64)h3 * r0) +
+// (h4 * s3);
+// h4 = (h4 * r0);
+//
+ d3 := UInt64(h0)*r3 + UInt64(h1)*r2 + UInt64(h2)*r1 + UInt64(h3)*r0 + h4*s3;
+ h4 := h4*r0;
+
+ //* last reduction step: */
+ // /* a) h4:h0 = h4<<128 + d3<<96 + d2<<64 + d1<<32 + d0 */
+// h0 = (u32)d0;
+// h1 = (u32)(d1 += d0 >> 32);
+// h2 = (u32)(d2 += d1 >> 32);
+// h3 = (u32)(d3 += d2 >> 32);
+// h4 += (u32)(d3 >> 32);
+ h0 := UInt32(d0);
+ d1 := d1 + d0 shr 32;
+ h1 := UInt32(d1);
+ d2 := d2 + d1 shr 32;
+ h2 := UInt32(d2);
+ d3 := d3 + d2 shr 32;
+ h3 := UInt32(d3);
+ h4 := h4 + UInt32(d3 shr 32);
+
+ //* b) (h4:h0 += (h4:h0>>130) * 5) %= 2^130 */
+// c = (h4 >> 2) + (h4 & ~3U);
+// h4 &= 3;
+// h0 += c;
+// h1 += (c = CONSTANT_TIME_CARRY(h0,c));
+// h2 += (c = CONSTANT_TIME_CARRY(h1,c));
+// h3 += (c = CONSTANT_TIME_CARRY(h2,c));
+// h4 += CONSTANT_TIME_CARRY(h3,c);
+ c := (h4 shr 2) + (h4 and (not UInt32(3)));
+ h4 := h4 and 3;
+ h0 := h0 + c;
+ c := ConstTimeCarray32(h0, c);
+ h1 := h1 + c;
+ c := ConstTimeCarray32(h1, c);
+ h2 := h2 + c;
+ c := ConstTimeCarray32(h2, c);
+ h3 := h3 + c;
+ h4 := h4 + ConstTimeCarray32(h3, c);
+
+ inc(PByte(pData), POLY1305_BLOCK_SIZE);
+ dec(size, POLY1305_BLOCK_SIZE);
+ end;
+
+ FH^[0] := h0;
+ FH^[1] := h1;
+ FH^[2] := h2;
+ FH^[3] := h3;
+ FH^[4] := h4;
+end;
+
+procedure TPoly1305.Poly1305Emit(var mac: TBlock16Byte;
+ const nonce: TPoly1305Nonce);
+var h0, h1, h2, h3, h4 : UInt32;
+ g0, g1, g2, g3, g4 : UInt32;
+ t: UInt64;
+ mask : UInt32;
+begin
+ // h0 = st->h[0];
+ // h1 = st->h[1];
+ //h2 = st->h[2];
+// h3 = st->h[3];
+// h4 = st->h[4];
+ h0 := FH^[0];
+ h1 := FH^[1];
+ h2 := FH^[2];
+ h3 := FH^[3];
+ h4 := FH^[4];
+
+ // /* compare to modulus by computing h + -p */
+// g0 = (u32)(t = (u64)h0 + 5);
+// g1 = (u32)(t = (u64)h1 + (t >> 32));
+// g2 = (u32)(t = (u64)h2 + (t >> 32));
+// g3 = (u32)(t = (u64)h3 + (t >> 32));
+// g4 = h4 + (u32)(t >> 32);
+ t := UInt64(h0) + 5;
+ g0 := UInt32(t);
+ t := UInt64(h1) + t shr 32;
+ g1 := UInt32(t);
+ t := UInt64(h2) + t shr 32;
+ g2 := UInt32(t);
+ t := UInt64(h3) + t shr 32;
+ g3 := UInt32(t);
+ g4 := h4 + UInt32( t shr 32 );
+
+ //* if there was carry into 131st bit, h3:h0 = g3:g0 */
+ //mask = 0 - (g4 >> 2);
+// g0 &= mask;
+// g1 &= mask;
+// g2 &= mask;
+// g3 &= mask;
+// mask = ~mask;
+// h0 = (h0 & mask) | g0;
+// h1 = (h1 & mask) | g1;
+// h2 = (h2 & mask) | g2;
+// h3 = (h3 & mask) | g3;
+ mask := UInt32( -(g4 shr 2) );
+ g0 := g0 and mask;
+ g1 := g1 and mask;
+ g2 := g2 and mask;
+ g3 := g3 and mask;
+ mask := not mask;
+ h0 := (h0 and mask) or g0;
+ h1 := (h1 and mask) or g1;
+ h2 := (h2 and mask) or g2;
+ h3 := (h3 and mask) or g3;
+
+ // /* mac = (h + nonce) % (2^128) */
+ //h0 = (u32)(t = (u64)h0 + nonce[0]);
+// h1 = (u32)(t = (u64)h1 + (t >> 32) + nonce[1]);
+// h2 = (u32)(t = (u64)h2 + (t >> 32) + nonce[2]);
+// h3 = (u32)(t = (u64)h3 + (t >> 32) + nonce[3]);
+ t := UInt64(h0) + nonce[0];
+ h0 := UInt32(t);
+ t := UInt64(h1) + t shr 32 + nonce[1];
+ h1 := UInt32(t);
+ t := UInt64(h2) + t shr 32 + nonce[2];
+ h2 := UInt32(t);
+ t := UInt64(h3) + t shr 32 + nonce[3];
+ h3 := UInt32(t);
+
+ U32ToU8(@mac[0], h0);
+ U32ToU8(@mac[4], h1);
+ U32ToU8(@mac[8], h2);
+ U32ToU8(@mac[12], h3);
+end;
+
+procedure TPoly1305.UpdatePoly(pData: PByteArray; size: integer);
+var num : integer;
+ rem : integer;
+begin
+ num := fNum;
+
+ if num <> 0 then
+ begin
+ rem := POLY1305_BLOCK_SIZE - num;
+ if size >= rem then
+ begin
+ Move( pData^, fData[num], rem);
+ Poly1305Blocks(@fData[0], POLY1305_BLOCK_SIZE, 1);
+ inc( PByte(pData), rem);
+ dec( size, rem);
+ end
+ else
+ begin
+ //* Still not enough data to process a block. */
+ move( pData^, fData[num], size );
+ inc(fNum, size);
+ exit;
+ end;
+ end;
+
+ rem := size mod POLY1305_BLOCK_SIZE;
+ size := size - rem;
+
+ if size >= POLY1305_BLOCK_SIZE then
+ begin
+ Poly1305Blocks(pData, size, 1);
+ inc(PByte(pData), size);
+ end;
+
+ if rem > 0 then
+ Move( pData^, fData[0], rem );
+
+ fNum := rem;
+end;
+
+{$IFNDEF PUREPASCAL}
+procedure TPoly1305.UpdatePolyAVX(pData: PByteArray; size: integer);
+var num : integer;
+ rem : integer;
+ t : TStateAVXArr;
+begin
+ num := fNum;
+
+ {$IFDEF x64}
+ StoreXMM(fXMMMem);
+ {$ENDIF}
+
+ if num <> 0 then
+ begin
+ rem := POLY1305_BLOCK_SIZE - num;
+ if size >= rem then
+ begin
+ Move( pData^, fData[num], rem);
+ Split26(PUInt64(@fData[0])^, PUInt64(@fData[8])^, @t[0]);
+ t[4] := t[4] + cShl24;
+ poly1305_block_avx2_ctx(fAVXCtx, @t[0]);
+
+ inc( PByte(pData), rem);
+ dec( size, rem);
+ end
+ else
+ begin
+ // Still not enough data to process a block.
+ move( pData^, fData[num], size );
+ inc(fNum, size);
+ {$IFDEF x64}
+ RestoreXMM(fXMMMem);
+ {$endif}
+
+ exit;
+ end;
+ end;
+
+ while size >= POLY1305_BLOCK_SIZE do
+ begin
+ Split26(PUInt64(@pData^[0])^, PUInt64(@pData^[8])^, @t[0]);
+ t[4] := t[4] + cShl24;
+
+ poly1305_block_avx2_ctx(fAVXCtx, @t[0]);
+ inc(PByte(pData), POLY1305_BLOCK_SIZE);
+ dec(size, POLY1305_BLOCK_SIZE);
+ end;
+
+ {$IFDEF x64}
+ RestoreXMM(fXMMMem);
+ {$ENDIF}
+
+ if size > 0 then
+ Move( pData^, fData[0], size );
+
+ fNum := size;
+end;
+{$ENDIF}
+
+
+procedure TPoly1305.UpdateWithEncDecBuf(buf: PUInt8Array; Size: Integer);
+begin
+ fPolyBlkFunc(PByteArray(buf), size);
+end;
+
+initialization
+ if TDEC_CPUSupport.AVX2
+ then
+ TPoly1305.CpuMode := pmAVX
+ else
+ TPoly1305.CpuMode := pmPas;
+
+end.
diff --git a/Source/DECCiphers.pas b/Source/DECCiphers.pas
index d91593ad..481624d6 100644
--- a/Source/DECCiphers.pas
+++ b/Source/DECCiphers.pas
@@ -20,8 +20,13 @@ interface
{$INCLUDE DECOptions.inc}
-uses
- DECCipherBase, DECCipherFormats, DECUtil, DECTypes;
+uses {$IFDEF FPC}
+ SysUtils,
+ {$ELSE}
+ System.SysUtils,
+ {$ENDIF}
+ DECCipherBase, DECCipherFormats, DECUtil, DECTypes, DECCipherMOdesPoly1305,
+ System.Types;
type
// Cipher Classes
@@ -201,6 +206,16 @@ TCipher_TEAN = class;
///
TCipher_XTEA_DEC52 = class;
+ ///
+ /// ChaCha20 cipher.
+ ///
+ TCipher_ChaCha20 = class;
+
+ ///
+ /// XChaCha20 cipher
+ ///
+ TCipher_XChaCha20 = class;
+
// Definitions needed for Skipjack algorithm
PSkipjackTab = ^TSkipjackTab;
TSkipjackTab = array[0..255] of Byte;
@@ -365,8 +380,19 @@ TCipher_RC6 = class(TDECFormattedCipher)
end;
TCipher_Rijndael = class(TDECFormattedCipher)
+ protected
+
+ ///
+ /// Blocksize in LongWords
+ ///
+ const Rijndael_Blocks = 4; // don't change this!
+ ///
+ /// Maximum number of rounds allowed.
+ ///
+ Rijndael_Rounds = 14;
private
FRounds: Integer;
+
///
/// Calculates the key used for encoding. Implemented is the "new AES
/// conform key scheduling".
@@ -394,6 +420,7 @@ TCipher_Rijndael = class(TDECFormattedCipher)
procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
public
+ class var UseAESAsm : boolean;
class function Context: TCipherContext; override;
///
/// Gets the number of rounds/times the algorithm is being applied to the
@@ -477,6 +504,77 @@ TCipher_AES256 = class(TCipher_AES)
class function Context: TCipherContext; override;
end;
+ TChaChaMode = (cmSpeed, cmBalance, cmSecure); // number of rounds... (4, 12, 20) default is 20
+ TChaChaMtx = Array[0..15] of LongWord;
+ PChaChaMtx = ^TChaChaMtx;
+ TChaChaCpuMode = (cmPas, cmSSE, cmAVX);
+ TChaChaAVXMtx = Array[0..31] of LongWord;
+ PChaChaAVXMtx = ^TChaChaAVXMtx;
+
+ TCipher_ChaCha20 = class(TDECFormattedCipher)
+ private
+ type
+ TChaChaKey = Array[0..7] of LongWord; // key - always 256 bit
+ TChaChaNonce = Array[0..1] of LongWord; // nonce - 96 bit, one longword is the counter
+
+ type
+ // double the size -> two blocks at once
+ TChaChaEncodeBlkFunc = procedure(ChaChaMtx : PChaChaAVXMtx; Source, Dest: Pointer); register; {$IFDEF FPC} assembler; {$ENDIF}
+
+ protected
+ fInpChaChaMTX : PChaChaMtx;
+ fOutChaChaMtx : PChaChaAVXMtx;
+
+ fChaChaBlkLen : integer;
+ fChaChaIdx : integer;
+ fChaChaMode : TChaChaMode;
+ fNumChaChaRounds : integer;
+ fFullBlockFunc : TChaChaEncodeBlkFunc;
+
+ procedure ChaChaQuarterRound( var a, b, c, d : LongWord );
+ procedure PasChaChaDoubleQuarterRound(mtx : PChaChaMtx); // one column and row round
+
+ procedure InitChaChaBlk;
+ {$IFNDEF PUREPASCAL}
+ procedure SSEChaChaDoubleQuarterRound(mtx : PChaChaMtx); register; {$IFDEF FPC} assembler; {$ENDIF}
+ {$ENDIF}
+ procedure SetChaChaMode(const Value: TChaChaMode);
+ protected
+ procedure DoInit(const Key; Size: Integer); override;
+ procedure DoEncode(Source, Dest: Pointer; Size: Integer); override;
+ procedure DoDecode(Source, Dest: Pointer; Size: Integer); override;
+ procedure OnAfterInitVectorInitialization(const OriginalInitVector: TBytes); override;
+
+ // some internal test functions
+ function TestChaChaMtx( const expectedMtx : TChaChaMtx ) : boolean;
+ public
+ property ChaChaMode : TChaChaMode read fChaChaMode write SetChaChaMode;
+
+ procedure AfterConstruction; override;
+
+ ///
+ /// Provides meta data about the cipher algorithm used like key size.
+ ///
+ class function Context: TCipherContext; override;
+
+ ///
+ /// Defines either pure pascal code is used or specialized assembler routines for SSE, AVX
+ ///
+ class var CpuMode : TChaChaCpuMode;
+ end;
+
+ // based on the draft: https://datatracker.ietf.org/doc/html/draft-arciszewski-xchacha-03
+ TCipher_XChaCha20 = class(TCipher_ChaCha20)
+ private
+ fHChaCha : Array[0..22] of LongWord;
+ fPHChaCha : PChaChaMtx;
+
+ procedure HChaCha( iv : TBytes );
+ protected
+ procedure OnAfterInitVectorInitialization(const OriginalInitVector: TBytes); override;
+ public
+ end;
+
TCipher_Square = class(TDECFormattedCipher)
protected
///
@@ -1020,12 +1118,7 @@ implementation
{$IFOPT R+}{$DEFINE RESTORE_RANGECHECKS}{$R-}{$ENDIF}
uses
- {$IFDEF FPC}
- SysUtils,
- {$ELSE}
- System.SysUtils,
- {$ENDIF}
- DECData, DECDataCipher;
+ DECData, DECDataCipher, DECCPUSupport;
{ TCipher_Null }
@@ -2748,21 +2841,549 @@ procedure TCipher_RC6.DoDecode(Source, Dest: Pointer; Size: Integer);
{ TCipher_Rijndael }
class function TCipher_Rijndael.Context: TCipherContext;
-const
- // don't change this!
- Rijndael_Blocks = 4;
- Rijndael_Rounds = 14;
begin
Result.KeySize := 32;
Result.BlockSize := Rijndael_Blocks * 4;
Result.BufferSize := Rijndael_Blocks * 4;
- Result.AdditionalBufferSize := (Rijndael_Rounds + 1) * Rijndael_Blocks * SizeOf(UInt32) * 2;
+ Result.AdditionalBufferSize := (Rijndael_Rounds + 1) * Rijndael_Blocks * SizeOf(UInt32) * 2 + $20; // add additional spare memory for alignment
Result.NeedsAdditionalBufferBackup := False;
Result.MinRounds := 1;
Result.MaxRounds := 1;
Result.CipherType := [ctSymmetric, ctBlock];
end;
+{$IF defined(X86ASM) or defined(X64ASM)}
+
+// ###########################################
+// #### AES assembler functions
+// #### Routines are based on the intel whitepaper:
+// #### https://www.intel.com/content/dam/develop/external/us/en/documents/aes-wp-2012-09-22-v01-165683.pdf
+// ###########################################
+
+// assumes registerd preloaded - use only in within BuildASMKey128
+procedure KeyExpand128; register;
+asm
+ pshufd xmm2, xmm2, $ff;
+ movapd xmm3, xmm1;
+ pslldq xmm3, $04;
+ pxor xmm1, xmm3;
+ movapd xmm3, xmm1;
+ pslldq xmm3, $04;
+ pxor xmm1, xmm3;
+ movapd xmm3, xmm1;
+ pslldq xmm3, $04;
+ pxor xmm1, xmm3;
+ pxor xmm1, xmm2;
+ {$IFDEF X64ASM}
+ movdqu [rdx], xmm1;
+ add rdx, $10;
+ {$ELSE}
+ movdqu [edx], xmm1;
+ add edx, $10;
+ {$ENDIF}
+
+end;
+
+procedure BuildAsmKey128( key : PByte; dest : PLongWord ); register;
+// eax : key, edx: dest
+// rcx : key, rdx : dest
+asm
+ xorpd xmm2, xmm2;
+ // key is 128bit
+ // 10 rounds to be filled
+ {$IFDEF X64ASM}
+ movdqu xmm1, [rcx];
+ movdqu [rdx], xmm1;
+ add rdx, 16;
+ {$ELSE}
+ movdqu xmm1, [eax];
+ movdqu [edx], xmm1;
+ add edx, 16;
+ {$ENDIF}
+
+ aeskeygenassist xmm2, xmm1, $1;
+ call KeyExpand128;
+ aeskeygenassist xmm2, xmm1, $2;
+ call KeyExpand128
+ aeskeygenassist xmm2, xmm1, $4
+ call KeyExpand128
+ aeskeygenassist xmm2, xmm1, $8
+ call KeyExpand128
+ aeskeygenassist xmm2, xmm1, $10
+ call KeyExpand128
+ aeskeygenassist xmm2, xmm1, $20
+ call KeyExpand128
+ aeskeygenassist xmm2, xmm1, $40
+ call KeyExpand128
+ aeskeygenassist xmm2, xmm1, $80
+ call KeyExpand128
+ aeskeygenassist xmm2, xmm1, $1b
+ call KeyExpand128
+ aeskeygenassist xmm2, xmm1, $36
+ call KeyExpand128
+end;
+
+
+// only call with BuildasmKey192 - it assumes preloaded registers xmm0, xmm1, xmm2
+// xmm3 is used for intermediate results
+procedure KeyExpand192; register;
+asm
+ pshufd xmm1, xmm1, $55;
+ movapd xmm3, xmm0;
+ pslldq xmm3, $04;
+ pxor xmm0, xmm3;
+
+ pslldq xmm3, $04;
+ pxor xmm0, xmm3;
+
+ pslldq xmm3, $04;
+ pxor xmm0, xmm3;
+
+ pxor xmm0, xmm1;
+ pshufd xmm1, xmm0, $FF;
+
+ movapd xmm3, xmm2;
+ pslldq xmm3, $04;
+
+ pxor xmm2, xmm3;
+ pxor xmm2, xmm1;
+end;
+
+procedure BuildAsmKey196( key : PByte; dest : PLongWord); register;
+// eax: key, edx : dest
+// rcx: key, rdx : dest;
+asm
+ // load key
+ xorpd xmm2, xmm2;
+
+ {$IFDEF X64ASM}
+ movupd xmm0, [rcx];
+ movsd xmm2, [rcx + 16];
+ movupd [rdx], xmm0;
+ {$ELSE}
+ movupd xmm0, [eax];
+ movsd xmm2, [eax + 16];
+ movupd [edx], xmm0;
+ {$ENDIF}
+
+ movapd xmm4, xmm2;
+
+ aeskeygenassist xmm1, xmm2, $01;
+ call KeyExpand192;
+
+ shufpd xmm4, xmm0, 0;
+ {$IFDEF X64ASM}
+ movupd [rdx + 16], xmm4;
+ {$ELSE}
+ movupd [edx + 16], xmm4;
+ {$ENDIF}
+ movapd xmm4, xmm0;
+ shufpd xmm4, xmm2, 1;
+ {$IFDEF X64ASM}
+ movupd [rdx + 32], xmm4;
+ {$ELSE}
+ movupd [edx + 32], xmm4;
+ {$ENDIF}
+
+ aeskeygenassist xmm1, xmm2, $02;
+ call KeyExpand192;
+ {$IFDEF X64ASM}
+ movupd [rdx + 48], xmm0;
+ {$ELSE}
+ movupd [edx + 48], xmm0;
+ {$ENDIF}
+ movapd xmm4, xmm2;
+ aeskeygenassist xmm1, xmm2, $04;
+ call KeyExpand192;
+ shufpd xmm4, xmm0, 0;
+ {$IFDEF X64ASM}
+ movupd [rdx + 64], xmm4;
+ {$ELSE}
+ movupd [edx + 64], xmm4;
+ {$ENDIF}
+
+ movapd xmm4, xmm0;
+ shufpd xmm4, xmm2, 1;
+ {$IFDEF X64ASM}
+ movupd [rdx + 80], xmm4;
+ {$ELSE}
+ movupd [edx + 80], xmm4;
+ {$ENDIF}
+
+ aeskeygenassist xmm1, xmm2, $08;
+ call KeyExpand192;
+ {$IFDEF X64ASM}
+ movupd [rdx + 96], xmm0;
+ {$ELSE}
+ movupd [edx + 96], xmm0;
+ {$ENDIF}
+ movapd xmm4, xmm2;
+
+ aeskeygenassist xmm1, xmm2, $10;
+ call KeyExpand192;
+ shufpd xmm4, xmm0, 0;
+ {$IFDEF X64ASM}
+ movupd [rdx + 112], xmm4;
+ {$ELSE}
+ movupd [edx + 112], xmm4;
+ {$ENDIF}
+
+ movapd xmm4, xmm0;
+ shufpd xmm4, xmm2, 1;
+ {$IFDEF X64ASM}
+ movupd [rdx + 128], xmm4;
+ {$ELSE}
+ movupd [edx + 128], xmm4;
+ {$ENDIF}
+
+ aeskeygenassist xmm1, xmm2, $20;
+ call KeyExpand192;
+ {$IFDEF X64ASM}
+ movupd [rdx + 144], xmm0;
+ {$ELSE}
+ movupd [edx + 144], xmm0;
+ {$ENDIF}
+ movapd xmm4, xmm2;
+
+ aeskeygenassist xmm1, xmm2, $40;
+ call KeyExpand192;
+
+ shufpd xmm4, xmm0, 0;
+ {$IFDEF X64ASM}
+ movupd [rdx + 160], xmm4;
+ {$ELSE}
+ movupd [edx + 160], xmm4;
+ {$ENDIF}
+
+ movapd xmm4, xmm0;
+ shufpd xmm4, xmm2, 1;
+ {$IFDEF X64ASM}
+ movupd [rdx + 176], xmm4;
+ {$ELSE}
+ movupd [edx + 176], xmm4;
+ {$ENDIF}
+
+ aeskeygenassist xmm1, xmm2, $80;
+ call KeyExpand192;
+ {$IFDEF X64ASM}
+ movupd [rdx + 192], xmm0;
+ {$ELSE}
+ movupd [edx + 192], xmm0;
+ {$ENDIF}
+end;
+
+// for the 256 bit key expand functions we assume that xmm0 - xmm2 are
+// prefilled and are used (aka not used as parameters)
+// xmm3 and xmm4 are used as intermediate registers
+procedure KeyExpand256_1; register;
+asm
+ pshufd xmm1, xmm1, $FF;
+ movapd xmm3, xmm0;
+ pslldq xmm3, $04;
+ pxor xmm0, xmm3;
+
+ pslldq xmm3, $04;
+ pxor xmm0, xmm3;
+
+ pslldq xmm3, $04;
+ pxor xmm0, xmm3;
+ pxor xmm0, xmm1;
+end;
+
+// no parameter given here -> xmm01 to xmm3 represent temp1 to temp4
+procedure KeyExpand256_2; register;
+asm
+ aeskeygenassist xmm3, xmm0, $00;
+ pshufd xmm1, xmm3, $AA;
+ movapd xmm3, xmm2;
+ pslldq xmm3, $04;
+ pxor xmm2, xmm3;
+ pslldq xmm3, $04;
+
+ pxor xmm2, xmm3;
+ pslldq xmm3, $04;
+
+ pxor xmm2, xmm3;
+ pxor xmm2, xmm1;
+end;
+
+procedure BuildAsmKey256( key : PByte; dest : PLongWord); register;
+asm
+// eax = key, edx = dest
+// rcx = key, rdx = dest
+
+ // load key
+ {$IFDEF X64ASM}
+ movupd xmm0, [rcx];
+ movupd xmm2, [rcx + 16];
+
+ movupd [rdx], xmm0;
+ movupd [rdx + 16], xmm2;
+
+ {$ELSE}
+ movupd xmm0, [eax];
+ movupd xmm2, [eax + 16];
+
+ movupd [edx], xmm0;
+ movupd [edx + 16], xmm2;
+ {$ENDIF}
+
+ aeskeygenassist xmm1, xmm2, $1;
+ call KeyExpand256_1;
+ {$IFDEF X64ASM}
+ movupd [rdx + 32], xmm0;
+ {$ELSE}
+ movupd [edx + 32], xmm0;
+ {$ENDIF}
+ call KeyExpand256_2;
+ {$IFDEF X64ASM}
+ movupd [rdx + 48], xmm2;
+ {$ELSE}
+ movupd [edx + 48], xmm2;
+ {$ENDIF}
+
+ aeskeygenassist xmm1, xmm2, $2;
+ call KeyExpand256_1;
+ {$IFDEF X64ASM}
+ movupd [rdx + 64], xmm0;
+ {$ELSE}
+ movupd [edx + 64], xmm0;
+ {$ENDIF}
+ call KeyExpand256_2;
+ {$IFDEF X64ASM}
+ movupd [rdx + 80], xmm2;
+ {$ELSE}
+ movupd [edx + 80], xmm2;
+ {$ENDIF}
+
+ aeskeygenassist xmm1, xmm2, $4;
+ call KeyExpand256_1;
+ {$IFDEF X64ASM}
+ movupd [rdx + 96], xmm0;
+ {$ELSE}
+ movupd [edx + 96], xmm0;
+ {$ENDIF}
+ call KeyExpand256_2;
+ {$IFDEF X64ASM}
+ movupd [rdx + 112], xmm2;
+ {$ELSE}
+ movupd [edx + 112], xmm2;
+ {$ENDIF}
+
+ aeskeygenassist xmm1, xmm2, $8;
+ call KeyExpand256_1;
+ {$IFDEF X64ASM}
+ movupd [rdx + 128], xmm0;
+ {$ELSE}
+ movupd [edx + 128], xmm0;
+ {$ENDIF}
+ call KeyExpand256_2;
+ {$IFDEF X64ASM}
+ movupd [rdx + 144], xmm2;
+ {$ELSE}
+ movupd [edx + 144], xmm2;
+ {$ENDIF}
+
+ aeskeygenassist xmm1, xmm2, $10;
+ call KeyExpand256_1;
+ {$IFDEF X64ASM}
+ movupd [rdx + 160], xmm0;
+ {$ELSE}
+ movupd [edx + 160], xmm0;
+ {$ENDIF}
+ call KeyExpand256_2;
+ {$IFDEF X64ASM}
+ movupd [rdx + 176], xmm2;
+ {$ELSE}
+ movupd [edx + 176], xmm2;
+ {$ENDIF}
+
+ aeskeygenassist xmm1, xmm2, $20;
+ call KeyExpand256_1;
+ {$IFDEF X64ASM}
+ movupd [rdx + 192], xmm0;
+ {$ELSE}
+ movupd [edx + 192], xmm0;
+ {$ENDIF}
+ call KeyExpand256_2;
+ {$IFDEF X64ASM}
+ movupd [rdx + 208], xmm2;
+ {$ELSE}
+ movupd [edx + 208], xmm2;
+ {$ENDIF}
+
+ aeskeygenassist xmm1, xmm2, $40;
+ call KeyExpand256_1;
+ {$IFDEF X64ASM}
+ movupd [rdx + 224], xmm0;
+ {$ELSE}
+ movupd [edx + 224], xmm0;
+ {$ENDIF}
+ call KeyExpand256_2;
+ {$IFDEF X64ASM}
+ movupd [rdx + 240], xmm2;
+ {$ELSE}
+ movupd [edx + 240], xmm2;
+ {$ENDIF}
+end;
+
+procedure BuildASMDecodeKey( encodeKey : PLongWord; decodeKey : PLongWord; numRounds : integer); register;
+// eax = encodeKey, edx = decodeKey, ecx = numRounds
+// rcx = encodeKey, rdx = decodeKey, r8 = numRounds
+asm
+// store in reverse order for iterative access in the decode routine!
+ {$IFDEF X64ASM}
+ movdqu xmm0, [rcx];
+ lea rdx, [rdx + 8*r8]; // mult by 16 is not possible -> do it twice
+ lea rdx, [rdx + 8*r8];
+ movdqu [rdx], xmm0;
+
+ add rcx, 16;
+ sub rdx, 16;
+ dec r8d;
+
+ @decLoop:
+ movdqu xmm0, [rcx];
+ aesimc xmm0, xmm0;
+ movdqu [rdx], xmm0;
+
+ add rcx, 16;
+ sub rdx, 16;
+ dec r8d;
+ jg @decLoop;
+
+ movdqu xmm0, [rcx];
+ movdqu [rdx], xmm0;
+ {$ELSE}
+ movdqu xmm0, [eax];
+ lea edx, [edx + 8*ecx]; // mult by 16 is not possible -> do it twice
+ lea edx, [edx + 8*ecx];
+ movdqu [edx], xmm0;
+
+ add eax, 16;
+ sub edx, 16;
+ dec ecx;
+
+ @decLoop:
+ movdqu xmm0, [eax];
+ aesimc xmm0, xmm0;
+ movdqu [edx], xmm0;
+
+ add eax, 16;
+ sub edx, 16;
+
+ // decrement ecx and test
+ loop @decLoop;
+
+ movdqu xmm0, [eax];
+ movdqu [edx], xmm0;
+ {$ENDIF}
+end;
+
+
+// ###########################################
+// #### AES assembler encode/decode
+// ###########################################
+
+{$REGION 'ASM encode/decode'}
+procedure AESEncode( Source, Dest : Pointer; numRounds : integer; key : PLongWord ); register;
+asm
+ {$IFDEF X64ASM}
+ movupd xmm1, [rcx];
+ movdqa xmm2, [r9];
+ pxor xmm1, xmm2;
+ add r9, 16;
+
+ dec r8d;
+
+ @aesloop:
+ movdqa xmm2, [r9];
+ aesenc xmm1, xmm2;
+ add r9, 16;
+
+ dec r8d;
+ jg @aesloop;
+
+ movdqa xmm2, [r9];
+ aesenclast xmm1, xmm2;
+ movupd [rdx], xmm1;
+ {$ELSE}
+ push edi;
+
+ movupd xmm1, [eax];
+ mov edi, key;
+ movdqa xmm2, [edi];
+ pxor xmm1, xmm2;
+ add edi, 16;
+
+ dec ecx;
+
+ @aesloop:
+ movdqa xmm2, [edi];
+ aesenc xmm1, xmm2;
+ add edi, 16;
+
+ dec ecx;
+ jg @aesloop;
+
+ movdqa xmm2, [edi];
+ aesenclast xmm1, xmm2;
+ movupd [edx], xmm1;
+ pop edi;
+ {$ENDIF}
+end;
+
+procedure AESDecode( Source, Dest : Pointer; numRounds : integer; key : PLongWord ); register;
+asm
+ {$IFDEF X64ASM}
+ movupd xmm1, [rcx];
+ movdqa xmm2, [r9];
+ pxor xmm1, xmm2;
+ add r9, 16;
+
+ dec r8d;
+
+ @aesloop:
+ movdqa xmm2, [r9];
+ aesdec xmm1, xmm2;
+ add r9, 16;
+
+ dec r8d;
+ jg @aesloop;
+
+ movdqa xmm2, [r9];
+ aesdeclast xmm1, xmm2;
+ movupd [rdx], xmm1;
+ {$ELSE}
+ push edi;
+
+ movupd xmm1, [eax];
+ mov edi, key;
+ movdqa xmm2, [edi];
+ pxor xmm1, xmm2;
+ add edi, 16;
+
+ dec ecx;
+
+ @aesloop:
+ movdqa xmm2, [edi];
+ aesdec xmm1, xmm2;
+ add edi, 16;
+
+ dec ecx;
+ jg @aesloop;
+
+ movdqa xmm2, [edi];
+ aesdeclast xmm1, xmm2;
+ movupd [edx], xmm1;
+ pop edi;
+ {$ENDIF}
+end;
+
+{$ENDREGION}
+
+{$IFEND}
+
procedure TCipher_Rijndael.DoInit(const Key; Size: Integer);
{$REGION OldKeyShedule}
{
@@ -2853,6 +3474,9 @@ procedure TCipher_Rijndael.DoInit(const Key; Size: Integer);
end; }
{$ENDREGION}
+{$IF defined(X86ASM) or defined(X64ASM)}
+var pBuf : PUInt32Array;
+{$IFEND}
begin
if Size <= 16 then
FRounds := 10
@@ -2861,10 +3485,29 @@ procedure TCipher_Rijndael.DoInit(const Key; Size: Integer);
FRounds := 12
else
FRounds := 14;
- FillChar(FAdditionalBuffer^, 32, 0);
- Move(Key, FAdditionalBuffer^, Size);
- BuildEncodeKey(Size);
- BuildDecodeKey;
+
+ {$IF defined(X86ASM) or defined(X64ASM)}
+ if UseAESAsm and TDEC_CPUSupport.AES then
+ begin
+ pBuf := AlignPtr32( FAdditionalBuffer );
+ case Size of
+ 16: BuildAsmKey128(@key, PLongWord(pBuf));
+ 24: BuildAsmKey196(@key, PLongWord(pBuf));
+ 32: BuildAsmKey256(@key, PLongWord(pBuf));
+ end;
+
+ // build inverse decode key - utilize the aesimc opcode
+ BuildASMDecodeKey( PLongWord(pBuf), @(pBuf^[Rijndael_Rounds*Rijndael_Blocks]), fRounds);
+ end
+ else
+ {$IFEND}
+ begin
+ FillChar(FAdditionalBuffer^, 32, 0);
+ Move(Key, FAdditionalBuffer^, Size);
+
+ BuildEncodeKey(Size);
+ BuildDecodeKey;
+ end;
inherited;
end;
@@ -2965,12 +3608,50 @@ procedure TCipher_Rijndael.DoEncode(Source, Dest: Pointer; Size: Integer);
begin
Assert(Size = Context.BlockSize);
+ {$IF defined(X86ASM) or defined(X64ASM)}
+ if UseAESAsm and (TDEC_CPUSupport.AES) then
+ begin
+ AESEncode(Source, Dest, fRounds, AlignPtr32( FAdditionalBuffer ) );
+ exit;
+ end;
+ {$IFEND}
+
P := FAdditionalBuffer;
A1 := PUInt32Array(Source)[0];
B1 := PUInt32Array(Source)[1];
C1 := PUInt32Array(Source)[2];
D1 := PUInt32Array(Source)[3];
+ //i := frounds;
+// asmP := @fAsmEncKey[0];
+// asm
+// push edx;
+// push ecx;
+// mov ecx, source;
+// movupd xmm1, [ecx];
+// mov ecx, asmP;
+// movupd xmm2, [ecx];
+// pxor xmm1, xmm2;
+// add ecx, 16;
+//
+// mov edx, i;
+// dec edx;
+//
+// aesloop:
+// movupd xmm2, [ecx];
+// aesenc xmm1, xmm2;
+// add ecx, 16;
+//
+// dec edx;
+// jg aesloop;
+//
+// movupd xmm2, [ecx];
+// aesenclast xmm1, xmm2;
+// movupd pp, xmm1;
+// pop ecx;
+// pop edx;
+// end;
+
for I := 2 to FRounds do
begin
A2 := A1 xor P[0];
@@ -3030,6 +3711,14 @@ procedure TCipher_Rijndael.DoDecode(Source, Dest: Pointer; Size: Integer);
begin
Assert(Size = Context.BlockSize);
+ {$IF defined(X86ASM) or defined(X64ASM)}
+ if UseAESAsm and TDEC_CPUSupport.AES then
+ begin
+ AESDecode(Source, Dest, fRounds, @(PUInt32Array(AlignPtr32( FAdditionalBuffer ))^[Rijndael_Rounds*Rijndael_Blocks]) );
+ exit;
+ end;
+ {$IFEND}
+
P := Pointer(PByte(FAdditionalBuffer) + FAdditionalBufferSize shr 1 + FRounds * 16); // for Pointer Math
A1 := PUInt32Array(Source)[0];
B1 := PUInt32Array(Source)[1];
@@ -6786,12 +7475,1058 @@ procedure TCipher_XTEA_DEC52.DoDecode(Source, Dest: Pointer; Size: Integer);
PUInt32Array(Dest)[1] := Y;
end;
+{ TCipher_ChaCha20 }
+
+{$IFDEF PUREPASCAL}
+function rol(value: LongWord; Bits: Byte): LongWord;
+begin
+ Result := (value shl Bits) or (value shr (32 - bits));
+end;
+{$ELSE}
+function rol(value: LongWord; Bits: Byte): LongWord; assembler;
+{$IFDEF FPC}
+begin
+{$ENDIF}
+asm
+ {$IFdef X64ASM}
+ mov eax, ecx;
+ mov cl, dl;
+ rol eax, cl;
+ {$ELSE}
+ xchg cl,dl
+ rol eax, cl
+ {$ENDIF}
+end;
+{$IFDEF FPC}
+end;
+{$ENDIF}
+{$ENDIF}
+
+procedure TCipher_ChaCha20.ChaChaQuarterRound(var a, b, c, d: LongWord);
+begin
+ // ###########################################
+ // ####
+ // a += b; d ^= a; d <<<= 16;
+ // c += d; b ^= c; b <<<= 12;
+ // a += b; d ^= a; d <<<= 8;
+ // c += d; b ^= c; b <<<= 7;
+ a := a + b;
+ d := d xor a;
+ d := rol(d, 16);
+
+ c := c + d;
+ b := b xor c;
+ b := rol(b, 12);
+
+ a := a + b;
+ d := d xor a;
+ d := rol(d, 8);
+
+ c := c + d;
+ b := b xor c;
+ b := rol(b, 7);
+end;
+
+
+class function TCipher_ChaCha20.Context: TCipherContext;
+begin
+ Result.KeySize := 256;
+ Result.BlockSize := 1;
+ Result.BufferSize := 16;
+ Result.AdditionalBufferSize := $40 + 3*sizeof(TChaChaMtx);
+ Result.NeedsAdditionalBufferBackup := False;
+ Result.MinRounds := 1;
+ Result.MaxRounds := 1;
+ Result.CipherType := [ctSymmetric, ctStream];
+end;
+
+
+procedure TCipher_ChaCha20.DoDecode(Source, Dest: Pointer; Size: Integer);
+begin
+ // should be the same
+ DoEncode( Source, Dest, size );
+ FState := csDecode;
+end;
+
+procedure TCipher_ChaCha20.DoEncode(Source, Dest: Pointer; Size: Integer);
+var pChaCha : PByte;
+
+ procedure TryEncodeFullBlocks;
+ begin
+ // ###########################################
+ // #### Full block version ->
+ if fChaChaIdx = 0 then
+ begin
+ while size >= sizeof(TChaChaAVXMtx) do
+ begin
+ fFullBlockFunc(fOutChaChaMtx, Source, Dest);
+
+ inc(PByte(Source), sizeof(TChaChaAVXMtx));
+ inc(PByte(Dest), sizeof(TChaChaAVXMtx));
+ dec(size, sizeof(TChaChaAVXMtx));
+
+ InitChaChaBlk;
+ end;
+ end;
+ end;
+begin
+ FState := csEncode;
+ pChaCha := PByte(fOutChaChaMtx);
+ inc(pChaCha, fChaChaIdx);
+
+ TryEncodeFullBlocks;
+
+ // ###########################################
+ // #### Single byte version
+ while size > 0 do
+ begin
+ if fChaChaIdx = fChaChaBlkLen then
+ begin
+ InitChaChaBlk;
+ pChaCha := PByte(fOutChaChaMtx);
+
+ if size >= sizeof(TChaChaAVXMtx) then
+ begin
+ TryEncodeFullBlocks;
+ if size = 0 then
+ break;
+ end;
+ end;
+
+ PByte(dest)^ := PByte(Source)^ xor pChaCha^;
+
+ inc(pChaCha);
+ inc(PByte(dest));
+ inc(PByte(source));
+ inc(fChaChaIdx);
+
+ dec(size);
+ end;
+end;
+
+procedure TCipher_ChaCha20.OnAfterInitVectorInitialization(
+ const OriginalInitVector: TBytes);
+var iv : TBytes;
+begin
+ if FInitVectorSize <> 12 then
+ raise EDECException.Create('Nonce is not 96 bit.');
+
+ fInpChaChaMTX^[12] := 0; // counter
+ Move( FInitializationVector^, fInpChaChaMTX^[13], 3*sizeof(longword));
+
+ // special care in case of poly1305:
+ if FMode = cmPoly1305 then
+ begin
+ FBufferSize := 0;
+ // according to RFC7539 (chapter 2.6) we create the R and S (the IV vector) value as:
+ // block counter is 0 key and nonce (96 or 64 bits)
+ // build iv by applying the key/nonce pair on the first "block" which results
+ // in an 512bit vector -> use the first 256 bit as IV and discard the remaining one
+ // -> update the counter to 1 and setup the next block
+
+ SetLength(iv, 32);
+ FillChar(iv[0], 32, 0);
+
+ // init with count 0
+ fInpChaChaMTX^[12] := 0;
+ InitChaChaBlk;
+ DoEncode(@iv[0], @iv[0], Length(iv));
+
+ inherited OnAfterInitVectorInitialization( iv );
+
+ // dismiss the remaining block ->
+ // first block was for the polynom... increment block number for the rest
+ fChaChaIdx := sizeof(TChaChaMtx);
+
+ // setup complete -> We are ready to encrypt...
+ end
+ else
+ inherited;
+end;
+
+procedure TCipher_ChaCha20.DoInit(const Key; Size: Integer);
+// from chacha-prng.h
+const cChaChaConst : Array[0..15] of AnsiChar = 'expand 32-byte k';
+begin
+ inherited;
+
+ if size <> 32 then
+ raise EDECException.Create('Given ChaCha key size is not 256 bit');
+
+ // allocate for the AVX case -> 2 cha cha matrices at once
+ fInpChaChaMtx := AlignPtr32(FAdditionalBuffer);
+ fOutChaChaMTX := PChaChaAVXMtx( fInpChaChaMtx );
+ inc(PByte(fOutChaChaMTX), sizeof(TChaChaMtx));
+
+ Move(cChaChaConst[0], fInpChaChaMTX^[0], sizeof(cChaChaConst));
+ Move(key, fInpChaChaMTX^[4], 32);
+
+ fChaChaBlkLen := sizeof(TChaChaAvxMtx);// 2*Length(fInpChaChaMTX^)*sizeof(fInpChaChaMTX^[0]);
+ fChaChaIdx := fChaChaBlkLen;
+end;
+
+procedure FullBlockPas(ChaChaMtx : PChaChaAVXMtx; Source, Dest: Pointer); register;
+var i, j : integer;
+begin
+ // xor the complete block
+ for i := 0 to 7 do
+ begin
+ j := i shl 2;
+ PChaChaAVXMtx(Dest)^[j + 0] := PChaChaAVXMtx(Source)^[j + 0] xor ChaChaMtx^[j + 0];
+ PChaChaAVXMtx(Dest)^[j + 1] := PChaChaAVXMtx(Source)^[j + 1] xor ChaChaMtx^[j + 1];
+ PChaChaAVXMtx(Dest)^[j + 2] := PChaChaAVXMtx(Source)^[j + 2] xor ChaChaMtx^[j + 2];
+ PChaChaAVXMtx(Dest)^[j + 3] := PChaChaAVXMtx(Source)^[j + 3] xor ChaChaMtx^[j + 3];
+ end;
+end;
+
+procedure TCipher_ChaCha20.SetChaChaMode(const Value: TChaChaMode);
+begin
+ fChaChaMode := Value;
+
+ // secure would be 20 rounds
+ case fChaChaMode of
+ cmSpeed: fNumChaChaRounds := 4;
+ cmBalance: fNumChaChaRounds := 6;
+ cmSecure: fNumChaChaRounds := 10;
+ end;
+end;
+
+// ###########################################
+// #### AVX chacha assembler code
+// ###########################################
+
+{$IFNDEF PUREPASCAL}
+
+{$IFDEF X86ASM}
+
+procedure FullBlockSSE(ChaChaMtx : PChaChaAVXMtx; Source, Dest: Pointer); register; {$IFDEF FPC}assembler;{$ENDIF}
+// eax = ChaChaMtx, edx = source, ecx = dest
+asm
+ movapd xmm0, [eax];
+ movupd xmm1, [edx];
+ xorpd xmm0, xmm1;
+ movupd [ecx], xmm0;
+
+ movapd xmm0, [eax + 16];
+ movupd xmm1, [edx + 16];
+ xorpd xmm0, xmm1;
+ movupd [ecx + 16], xmm0;
+
+ movapd xmm0, [eax + 32];
+ movupd xmm1, [edx + 32];
+ xorpd xmm0, xmm1;
+ movupd [ecx + 32], xmm0;
+
+ movapd xmm0, [eax + 48];
+ movupd xmm1, [edx + 48];
+ xorpd xmm0, xmm1;
+ movupd [ecx + 48], xmm0;
+
+ movapd xmm0, [eax + 64];
+ movupd xmm1, [edx + 64];
+ xorpd xmm0, xmm1;
+ movupd [ecx + 64], xmm0;
+
+ movapd xmm0, [eax + 80];
+ movupd xmm1, [edx + 80];
+ xorpd xmm0, xmm1;
+ movupd [ecx + 80], xmm0;
+
+ movapd xmm0, [eax + 96];
+ movupd xmm1, [edx + 96];
+ xorpd xmm0, xmm1;
+ movupd [ecx + 96], xmm0;
+
+ movapd xmm0, [eax + 112];
+ movupd xmm1, [edx + 112];
+ xorpd xmm0, xmm1;
+ movupd [ecx + 112], xmm0;
+end;
+
+procedure FullBlockAVX(ChaChaMtx : PChaChaAVXMtx; Source, Dest: Pointer); register; {$IFDEF FPC}assembler;{$ENDIF}
+// eax = ChaChaMtx, edx = source, ecx = dest
+asm
+ {$IFDEF AVXSUP}vmovapd ymm0, [eax]; {$ELSE}db $C5,$FD,$28,$00;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd ymm1, [edx]; {$ELSE}db $C5,$FD,$10,$0A;{$ENDIF}
+ {$IFDEF AVXSUP}vxorpd ymm0, ymm1, ymm0; {$ELSE}db $C5,$F5,$57,$C0;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd [ecx], ymm0; {$ELSE}db $C5,$FD,$11,$01;{$ENDIF}
+
+ {$IFDEF AVXSUP}vmovapd ymm0, [eax + 32]; {$ELSE}db $C5,$FD,$28,$40,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd ymm1, [edx + 32]; {$ELSE}db $C5,$FD,$10,$4A,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vxorpd ymm0, ymm1, ymm0; {$ELSE}db $C5,$F5,$57,$C0;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd [ecx + 32], ymm0; {$ELSE}db $C5,$FD,$11,$41,$20;{$ENDIF}
+
+ {$IFDEF AVXSUP}vmovapd ymm0, [eax + 64]; {$ELSE}db $C5,$FD,$28,$40,$40;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd ymm1, [edx + 64]; {$ELSE}db $C5,$FD,$10,$4A,$40;{$ENDIF}
+ {$IFDEF AVXSUP}vxorpd ymm0, ymm1, ymm0; {$ELSE}db $C5,$F5,$57,$C0;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd [ecx + 64], ymm0; {$ELSE}db $C5,$FD,$11,$41,$40;{$ENDIF}
+
+ {$IFDEF AVXSUP}vmovapd ymm0, [eax + 96]; {$ELSE}db $C5,$FD,$28,$40,$60;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd ymm1, [edx + 96]; {$ELSE}db $C5,$FD,$10,$4A,$60;{$ENDIF}
+ {$IFDEF AVXSUP}vxorpd ymm0, ymm1, ymm0; {$ELSE}db $C5,$F5,$57,$C0;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd [ecx + 96], ymm0; {$ELSE}db $C5,$FD,$11,$41,$60;{$ENDIF}
+
+ {$IFDEF AVXSUP}vzeroupper; {$ELSE}db $C5,$F8,$77;{$ENDIF}
+end;
+
+
+{$ENDIF}
+{$IFDEF X64ASM}
+procedure FullBlockSSE(ChaChaMtx : PChaChaAVXMtx; Source, Dest: Pointer);
+// rcx = ChaChaMtx, rdx = source, r8 = dest
+asm
+ {$IFDEF UNIX}
+ // Linux uses a diffrent ABI -> copy over the registers so they meet with winABI
+ // The parameters are passed in the following order:
+ // RDI, RSI, RDX, RCX, r8, r9 -> mov to RCX, RDX, R8, R9, width and height
+ mov r8, rdx;
+ mov r9, rcx;
+ mov rcx, rdi;
+ mov rdx, rsi;
+ {$ENDIF}
+
+ movapd xmm0, [rcx];
+ movupd xmm1, [rdx];
+ xorpd xmm0, xmm1;
+ movupd [r8], xmm0;
+
+ movapd xmm0, [rcx + 16];
+ movupd xmm1, [rdx + 16];
+ xorpd xmm0, xmm1;
+ movupd [r8 + 16], xmm0;
+
+ movapd xmm0, [rcx + 32];
+ movupd xmm1, [rdx + 32];
+ xorpd xmm0, xmm1;
+ movupd [r8 + 32], xmm0;
+
+ movapd xmm0, [rcx + 48];
+ movupd xmm1, [rdx + 48];
+ xorpd xmm0, xmm1;
+ movupd [r8 + 48], xmm0;
+
+ movapd xmm0, [rcx + 64];
+ movupd xmm1, [rdx + 64];
+ xorpd xmm0, xmm1;
+ movupd [r8 + 64], xmm0;
+
+ movapd xmm0, [rcx + 80];
+ movupd xmm1, [rdx + 80];
+ xorpd xmm0, xmm1;
+ movupd [r8 + 80], xmm0;
+
+ movapd xmm0, [rcx + 96];
+ movupd xmm1, [rdx + 96];
+ xorpd xmm0, xmm1;
+ movupd [r8 + 96], xmm0;
+
+ movapd xmm0, [rcx + 112];
+ movupd xmm1, [rdx + 112];
+ xorpd xmm0, xmm1;
+ movupd [r8 + 112], xmm0;
+end;
+
+procedure FullBlockAVX(ChaChaMtx : PChaChaAVXMtx; Source, Dest: Pointer);
+// rcx = ChaChaMtx, rdx = source, r8 = dest
+asm
+ {$IFDEF UNIX}
+ // Linux uses a diffrent ABI -> copy over the registers so they meet with winABI
+ // The parameters are passed in the following order:
+ // RDI, RSI, RDX, RCX, r8, r9 -> mov to RCX, RDX, R8, R9, width and height
+ mov r8, rdx;
+ mov r9, rcx;
+ mov rcx, rdi;
+ mov rdx, rsi;
+ {$ENDIF}
+
+ {$IFDEF AVXSUP}vmovapd ymm0, [rcx]; {$ELSE}db $C5,$FD,$28,$01;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd ymm1, [rdx]; {$ELSE}db $C5,$FD,$10,$0A;{$ENDIF}
+ {$IFDEF AVXSUP}vxorpd ymm0, ymm1, ymm0; {$ELSE}db $C5,$F5,$57,$C0;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd [r8], ymm0; {$ELSE}db $C4,$C1,$7D,$11,$00;{$ENDIF}
+
+ {$IFDEF AVXSUP}vmovapd ymm0, [rcx + 32]; {$ELSE}db $C5,$FD,$28,$41,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd ymm1, [rdx + 32]; {$ELSE}db $C5,$FD,$10,$4A,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vxorpd ymm0, ymm1, ymm0; {$ELSE}db $C5,$F5,$57,$C0;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd [r8 + 32], ymm0; {$ELSE}db $C4,$C1,$7D,$11,$40,$20;{$ENDIF}
+
+ {$IFDEF AVXSUP}vmovapd ymm0, [rcx + 64]; {$ELSE}db $C5,$FD,$28,$41,$40;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd ymm1, [rdx + 64]; {$ELSE}db $C5,$FD,$10,$4A,$40;{$ENDIF}
+ {$IFDEF AVXSUP}vxorpd ymm0, ymm1, ymm0; {$ELSE}db $C5,$F5,$57,$C0;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd [r8 + 64], ymm0; {$ELSE}db $C4,$C1,$7D,$11,$40,$40;{$ENDIF}
+
+ {$IFDEF AVXSUP}vmovapd ymm0, [rcx + 96]; {$ELSE}db $C5,$FD,$28,$41,$60;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd ymm1, [rdx + 96]; {$ELSE}db $C5,$FD,$10,$4A,$60;{$ENDIF}
+ {$IFDEF AVXSUP}vxorpd ymm0, ymm1, ymm0; {$ELSE}db $C5,$F5,$57,$C0;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd [r8 + 96], ymm0; {$ELSE}db $C4,$C1,$7D,$11,$40,$60;{$ENDIF}
+
+ {$IFDEF AVXSUP}vzeroupper; {$ELSE}db $C5,$F8,$77;{$ENDIF}
+end;
+{$ENDIF}
+
+const cShuf16 : Array[0..31] of byte = (3, 0, 1, 2,
+ 7, 4, 5, 6,
+ 11, 8, 9, 10,
+ 15, 12, 13, 14,
+ 3, 0, 1, 2,
+ 7, 4, 5, 6,
+ 11, 8, 9, 10,
+ 15, 12, 13, 14);
+
+{$IFDEF X86ASM}
+
+procedure AVXChaChaDoubleQuarterRound( chachaMtx : PChaChaAVXMtx ); {$IFDEF FPC} assembler; {$ELSE} register; {$ENDIF}
+asm
+ lea ecx, cShuf16;
+ {$IFDEF AVXSUP}vmovdqu ymm5, [ecx]; {$ELSE}db $C5,$FE,$6F,$29;{$ENDIF}
+
+ // move the matrix to xmm0 to xmm3
+ {$IFDEF AVXSUP}vmovdqa ymm0, [eax]; {$ELSE}db $C5,$FD,$6F,$00;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa ymm1, [eax + 32]; {$ELSE}db $C5,$FD,$6F,$48,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa ymm2, [eax + 64]; {$ELSE}db $C5,$FD,$6F,$50,$40;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa ymm3, [eax + 96]; {$ELSE}db $C5,$FD,$6F,$58,$60;{$ENDIF}
+
+ // v0 += v1; v3 ^= v0; v3 <<<= 16
+ {$IFDEF AVXSUP}vpaddd ymm0, ymm0, ymm1; {$ELSE}db $C5,$FD,$FE,$C1;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm3, ymm3, ymm0; {$ELSE}db $C5,$E5,$EF,$D8;{$ENDIF}
+ {$IFDEF AVXSUP}vpshufhw ymm3, ymm3, $B1; {$ELSE}db $C5,$FE,$70,$DB,$B1;{$ENDIF} // 10 11 00 01
+ {$IFDEF AVXSUP}vpshuflw ymm3, ymm3, $B1; {$ELSE}db $C5,$FF,$70,$DB,$B1;{$ENDIF}
+
+ // v2 += v3; v1 ^= v2; v1 <<<= (12, 12, 12, 12);
+ {$IFDEF AVXSUP}vpaddd ymm2, ymm2, ymm3; {$ELSE}db $C5,$ED,$FE,$D3;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm1, ymm1, ymm2; {$ELSE}db $C5,$F5,$EF,$CA;{$ENDIF}
+ // rotate is x << n | x >> 32 - n
+ {$IFDEF AVXSUP}vpslld ymm4, ymm1, 12; {$ELSE}db $C5,$DD,$72,$F1,$0C;{$ENDIF}
+ {$IFDEF AVXSUP}vpsrld ymm1, ymm1, 20; {$ELSE}db $C5,$F5,$72,$D1,$14;{$ENDIF} // 32 - 12
+ {$IFDEF AVXSUP}vpor ymm1, ymm1, ymm4; {$ELSE}db $C5,$F5,$EB,$CC;{$ENDIF}
+
+ // v0 += v1; v3 ^= v0; v3 <<<= ( 8, 8, 8, 8);
+ {$IFDEF AVXSUP}vpaddd ymm0, ymm0, ymm1; {$ELSE}db $C5,$FD,$FE,$C1;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm3, ymm3, ymm0; {$ELSE}db $C5,$E5,$EF,$D8;{$ENDIF}
+ {$IFDEF AVXSUP}vpshufb ymm3, ymm3, ymm5; {$ELSE}db $C4,$E2,$65,$00,$DD;{$ENDIF}
+
+ // v2 += v3; v1 ^= v2; v1 <<<= ( 7, 7, 7, 7);
+ {$IFDEF AVXSUP}vpaddd ymm2, ymm2, ymm3; {$ELSE}db $C5,$ED,$FE,$D3;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm1, ymm1, ymm2; {$ELSE}db $C5,$F5,$EF,$CA;{$ENDIF}
+ {$IFDEF AVXSUP}vpslld ymm4, ymm1, 7; {$ELSE}db $C5,$DD,$72,$F1,$07;{$ENDIF}
+ {$IFDEF AVXSUP}vpsrld ymm1, ymm1, 25; {$ELSE}db $C5,$F5,$72,$D1,$19;{$ENDIF} // 32 - 7
+ {$IFDEF AVXSUP}vpor ymm1, ymm1, ymm4; {$ELSE}db $C5,$F5,$EB,$CC;{$ENDIF}
+
+ // v1 >>>= 32; v2 >>>= 64; v3 >>>= 96;
+
+ // palignr is actually a sse3 opcode but ok...
+ {$IFDEF AVXSUP}vmovapd ymm4, ymm1; {$ELSE}db $C5,$FD,$29,$CC;{$ENDIF}
+ {$IFDEF AVXSUP}vpalignr ymm1, ymm1, ymm4, 4; {$ELSE}db $C4,$E3,$75,$0F,$CC,$04;{$ENDIF}
+ {$IFDEF AVXSUP}vmovapd ymm4, ymm2; {$ELSE}db $C5,$FD,$29,$D4;{$ENDIF}
+ {$IFDEF AVXSUP}vpalignr ymm2, ymm2, ymm4, 8; {$ELSE}db $C4,$E3,$6D,$0F,$D4,$08;{$ENDIF}
+ {$IFDEF AVXSUP}vmovapd ymm4, ymm3; {$ELSE}db $C5,$FD,$29,$DC;{$ENDIF}
+ {$IFDEF AVXSUP}vpalignr ymm3, ymm3, ymm4, 12; {$ELSE}db $C4,$E3,$65,$0F,$DC,$0C;{$ENDIF}
+
+ // v0 += v1; v3 ^= v0; v3 <<<= 16
+ {$IFDEF AVXSUP}vpaddd ymm0, ymm0, ymm1; {$ELSE}db $C5,$FD,$FE,$C1;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm3, ymm3, ymm0; {$ELSE}db $C5,$E5,$EF,$D8;{$ENDIF}
+ {$IFDEF AVXSUP}vpshufhw ymm3, ymm3, $B1; {$ELSE}db $C5,$FE,$70,$DB,$B1;{$ENDIF} // 10 11 00 01
+ {$IFDEF AVXSUP}vpshuflw ymm3, ymm3, $B1; {$ELSE}db $C5,$FF,$70,$DB,$B1;{$ENDIF}
+
+ // v2 += v3; v1 ^= v2; v1 <<<= (12, 12, 12, 12);
+ {$IFDEF AVXSUP}vpaddd ymm2, ymm2, ymm3; {$ELSE}db $C5,$ED,$FE,$D3;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm1, ymm1, ymm2; {$ELSE}db $C5,$F5,$EF,$CA;{$ENDIF}
+ // rotate is x << n | x >> 32 - n
+ {$IFDEF AVXSUP}vpslld ymm4, ymm1, 12; {$ELSE}db $C5,$DD,$72,$F1,$0C;{$ENDIF}
+ {$IFDEF AVXSUP}vpsrld ymm1, ymm1, 20; {$ELSE}db $C5,$F5,$72,$D1,$14;{$ENDIF} // 32 - 12
+ {$IFDEF AVXSUP}vpor ymm1, ymm1, ymm4; {$ELSE}db $C5,$F5,$EB,$CC;{$ENDIF}
+
+ // v0 += v1; v3 ^= v0; v3 <<<= ( 8, 8, 8, 8);
+ {$IFDEF AVXSUP}vpaddd ymm0, ymm0, ymm1; {$ELSE}db $C5,$FD,$FE,$C1;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm3, ymm3, ymm0; {$ELSE}db $C5,$E5,$EF,$D8;{$ENDIF}
+ {$IFDEF AVXSUP}vpshufb ymm3, ymm3, ymm5; {$ELSE}db $C4,$E2,$65,$00,$DD;{$ENDIF}
+
+ // v2 += v3; v1 ^= v2; v1 <<<= ( 7, 7, 7, 7);
+ {$IFDEF AVXSUP}vpaddd ymm2, ymm2, ymm3; {$ELSE}db $C5,$ED,$FE,$D3;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm1, ymm1, ymm2; {$ELSE}db $C5,$F5,$EF,$CA;{$ENDIF}
+ {$IFDEF AVXSUP}vpslld ymm4, ymm1, 7; {$ELSE}db $C5,$DD,$72,$F1,$07;{$ENDIF}
+ {$IFDEF AVXSUP}vpsrld ymm1, ymm1, 25; {$ELSE}db $C5,$F5,$72,$D1,$19;{$ENDIF} // 32 - 7
+ {$IFDEF AVXSUP}vpor ymm1, ymm1, ymm4; {$ELSE}db $C5,$F5,$EB,$CC;{$ENDIF}
+
+ // v1 <<<= 32; v2 <<<= 64; v3 <<<= 96; Return
+ {$IFDEF AVXSUP}vmovapd ymm4, ymm1; {$ELSE}db $C5,$FD,$29,$CC;{$ENDIF}
+ {$IFDEF AVXSUP}vpalignr ymm1, ymm1, ymm4, 12; {$ELSE}db $C4,$E3,$75,$0F,$CC,$0C;{$ENDIF}
+ {$IFDEF AVXSUP}vmovapd ymm4, ymm2; {$ELSE}db $C5,$FD,$29,$D4;{$ENDIF}
+ {$IFDEF AVXSUP}vpalignr ymm2, ymm2, ymm4, 8; {$ELSE}db $C4,$E3,$6D,$0F,$D4,$08;{$ENDIF}
+ {$IFDEF AVXSUP}vmovapd ymm4, ymm3; {$ELSE}db $C5,$FD,$29,$DC;{$ENDIF}
+ {$IFDEF AVXSUP}vpalignr ymm3, ymm3, ymm4, 4; {$ELSE}db $C4,$E3,$65,$0F,$DC,$04;{$ENDIF}
+
+ // move back
+ {$IFDEF AVXSUP}vmovdqa [eax], ymm0; {$ELSE}db $C5,$FD,$7F,$00;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [eax + 32], ymm1; {$ELSE}db $C5,$FD,$7F,$48,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [eax + 64], ymm2; {$ELSE}db $C5,$FD,$7F,$50,$40;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [eax + 96], ymm3; {$ELSE}db $C5,$FD,$7F,$58,$60;{$ENDIF}
+ {$IFDEF AVXSUP}vzeroupper; {$ELSE}db $C5,$F8,$77;{$ENDIF}
+end;
+
+// realign the chacha matrix such that further access to it is linear
+procedure AVXRealingAndAddMtx( chaChaMtx : PChaChaAVXMtx; inpChaCha : PChaChaMtx ); {$IFDEF FPC} assembler; {$ELSE} register; {$ENDIF}
+asm
+ // store second matrix
+ {$IFDEF AVXSUP}vmovdqa xmm0, [eax + 16]; {$ELSE}db $C5,$F9,$6F,$40,$10;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm1, [eax + 48]; {$ELSE}db $C5,$F9,$6F,$48,$30;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm2, [eax + 80]; {$ELSE}db $C5,$F9,$6F,$50,$50;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm3, [eax + 112]; {$ELSE}db $C5,$F9,$6F,$58,$70;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddd xmm0, xmm0, [edx]; {$ELSE}db $C5,$F9,$FE,$02;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddd xmm1, xmm1, [edx + 16]; {$ELSE}db $C5,$F1,$FE,$4A,$10;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddd xmm2, xmm2, [edx + 32]; {$ELSE}db $C5,$E9,$FE,$52,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddd xmm3, xmm3, [edx + 48]; {$ELSE}db $C5,$E1,$FE,$5A,$30;{$ENDIF}
+
+ // move positions
+ {$IFDEF AVXSUP}vmovapd xmm5, [eax]; {$ELSE}db $C5,$F9,$28,$28;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddd xmm5, xmm5, [edx]; {$ELSE}db $C5,$D1,$FE,$2A;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [eax], xmm5; {$ELSE}db $C5,$F9,$7F,$28;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm5, [eax + 32]; {$ELSE}db $C5,$F9,$6F,$68,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddd xmm5, xmm5, [edx + 16]; {$ELSE}db $C5,$D1,$FE,$6A,$10;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [eax + 16], xmm5; {$ELSE}db $C5,$F9,$7F,$68,$10;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm5, [eax + 64]; {$ELSE}db $C5,$F9,$6F,$68,$40;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddd xmm5, xmm5, [edx + 32]; {$ELSE}db $C5,$D1,$FE,$6A,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [eax + 32], xmm5; {$ELSE}db $C5,$F9,$7F,$68,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm5, [eax + 96]; {$ELSE}db $C5,$F9,$6F,$68,$60;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddd xmm5, xmm5, [edx + 48]; {$ELSE}db $C5,$D1,$FE,$6A,$30;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [eax + 48], xmm5; {$ELSE}db $C5,$F9,$7F,$68,$30;{$ENDIF}
+
+ // append second matrix
+ {$IFDEF AVXSUP}vmovdqa [eax + 64], xmm0; {$ELSE}db $C5,$F9,$7F,$40,$40;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [eax + 80], xmm1; {$ELSE}db $C5,$F9,$7F,$48,$50;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [eax + 96], xmm2; {$ELSE}db $C5,$F9,$7F,$50,$60;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [eax + 112], xmm3; {$ELSE}db $C5,$F9,$7F,$58,$70;{$ENDIF}
+
+ {$IFDEF AVXSUP}vzeroupper; {$ELSE}db $C5,$F8,$77;{$ENDIF}
+end;
+{$ENDIF}
+
+{$IFDEF X64ASM}
+
+procedure AVXChaChaDoubleQuarterRound( chachaMtx : PChaChaAVXMtx );
+var dYMM4, dYMM5 : Array[0..4] of int64;
+{$IFDEF FPC}
+begin
+{$ENDIF}
+asm
+ {$IFDEF UNIX}
+ // Linux uses a diffrent ABI -> copy over the registers so they meet with winABI
+ // The parameters are passed in the following order:
+ // RDI, RSI, RDX, RCX, r8, r9 -> mov to RCX, RDX, R8, R9, width and height
+ // in our case only rdi to rcx
+ mov rcx, rdi;
+ {$ENDIF}
+ {$IFDEF AVXSUP}vmovupd dYMM4, ymm4; {$ELSE}db $C5,$FD,$11,$65,$D8;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd dYMM5, ymm5; {$ELSE}db $C5,$FD,$11,$6D,$B8;{$ENDIF}
+
+ // 64bit version
+ lea rdx, [rip + cShuf16];
+ {$IFDEF AVXSUP}vmovdqu ymm5, [rdx]; {$ELSE}db $C5,$FE,$6F,$2A;{$ENDIF}
+
+ // move the matrix to xmm0 to xmm3
+ {$IFDEF AVXSUP}vmovdqa ymm0, [rcx]; {$ELSE}db $C5,$FD,$6F,$01;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa ymm1, [rcx + 32]; {$ELSE}db $C5,$FD,$6F,$49,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa ymm2, [rcx + 64]; {$ELSE}db $C5,$FD,$6F,$51,$40;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa ymm3, [rcx + 96]; {$ELSE}db $C5,$FD,$6F,$59,$60;{$ENDIF}
+
+ // v0 += v1; v3 ^= v0; v3 <<<= 16
+ {$IFDEF AVXSUP}vpaddd ymm0, ymm0, ymm1; {$ELSE}db $C5,$FD,$FE,$C1;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm3, ymm3, ymm0; {$ELSE}db $C5,$E5,$EF,$D8;{$ENDIF}
+ {$IFDEF AVXSUP}vpshufhw ymm3, ymm3, $B1; {$ELSE}db $C5,$FE,$70,$DB,$B1;{$ENDIF} // 10 11 00 01
+ {$IFDEF AVXSUP}vpshuflw ymm3, ymm3, $B1; {$ELSE}db $C5,$FF,$70,$DB,$B1;{$ENDIF}
+
+ // v2 += v3; v1 ^= v2; v1 <<<= (12, 12, 12, 12);
+ {$IFDEF AVXSUP}vpaddd ymm2, ymm2, ymm3; {$ELSE}db $C5,$ED,$FE,$D3;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm1, ymm1, ymm2; {$ELSE}db $C5,$F5,$EF,$CA;{$ENDIF}
+ // rotate is x << n | x >> 32 - n
+ {$IFDEF AVXSUP}vpslld ymm4, ymm1, 12; {$ELSE}db $C5,$DD,$72,$F1,$0C;{$ENDIF}
+ {$IFDEF AVXSUP}vpsrld ymm1, ymm1, 20; {$ELSE}db $C5,$F5,$72,$D1,$14;{$ENDIF} // 32 - 12
+ {$IFDEF AVXSUP}vpor ymm1, ymm1, ymm4; {$ELSE}db $C5,$F5,$EB,$CC;{$ENDIF}
+
+ // v0 += v1; v3 ^= v0; v3 <<<= ( 8, 8, 8, 8);
+ {$IFDEF AVXSUP}vpaddd ymm0, ymm0, ymm1; {$ELSE}db $C5,$FD,$FE,$C1;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm3, ymm3, ymm0; {$ELSE}db $C5,$E5,$EF,$D8;{$ENDIF}
+ {$IFDEF AVXSUP}vpshufb ymm3, ymm3, ymm5; {$ELSE}db $C4,$E2,$65,$00,$DD;{$ENDIF}
+
+ // v2 += v3; v1 ^= v2; v1 <<<= ( 7, 7, 7, 7);
+ {$IFDEF AVXSUP}vpaddd ymm2, ymm2, ymm3; {$ELSE}db $C5,$ED,$FE,$D3;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm1, ymm1, ymm2; {$ELSE}db $C5,$F5,$EF,$CA;{$ENDIF}
+ {$IFDEF AVXSUP}vpslld ymm4, ymm1, 7; {$ELSE}db $C5,$DD,$72,$F1,$07;{$ENDIF}
+ {$IFDEF AVXSUP}vpsrld ymm1, ymm1, 25; {$ELSE}db $C5,$F5,$72,$D1,$19;{$ENDIF} // 32 - 7
+ {$IFDEF AVXSUP}vpor ymm1, ymm1, ymm4; {$ELSE}db $C5,$F5,$EB,$CC;{$ENDIF}
+
+ // v1 >>>= 32; v2 >>>= 64; v3 >>>= 96;
+
+ // palignr is actually a sse3 opcode but ok...
+ {$IFDEF AVXSUP}vmovapd ymm4, ymm1; {$ELSE}db $C5,$FD,$29,$CC;{$ENDIF}
+ {$IFDEF AVXSUP}vpalignr ymm1, ymm1, ymm4, 4; {$ELSE}db $C4,$E3,$75,$0F,$CC,$04;{$ENDIF}
+ {$IFDEF AVXSUP}vmovapd ymm4, ymm2; {$ELSE}db $C5,$FD,$29,$D4;{$ENDIF}
+ {$IFDEF AVXSUP}vpalignr ymm2, ymm2, ymm4, 8; {$ELSE}db $C4,$E3,$6D,$0F,$D4,$08;{$ENDIF}
+ {$IFDEF AVXSUP}vmovapd ymm4, ymm3; {$ELSE}db $C5,$FD,$29,$DC;{$ENDIF}
+ {$IFDEF AVXSUP}vpalignr ymm3, ymm3, ymm4, 12; {$ELSE}db $C4,$E3,$65,$0F,$DC,$0C;{$ENDIF}
+
+ // v0 += v1; v3 ^= v0; v3 <<<= 16
+ {$IFDEF AVXSUP}vpaddd ymm0, ymm0, ymm1; {$ELSE}db $C5,$FD,$FE,$C1;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm3, ymm3, ymm0; {$ELSE}db $C5,$E5,$EF,$D8;{$ENDIF}
+ {$IFDEF AVXSUP}vpshufhw ymm3, ymm3, $B1; {$ELSE}db $C5,$FE,$70,$DB,$B1;{$ENDIF} // 10 11 00 01
+ {$IFDEF AVXSUP}vpshuflw ymm3, ymm3, $B1; {$ELSE}db $C5,$FF,$70,$DB,$B1;{$ENDIF}
+
+ // v2 += v3; v1 ^= v2; v1 <<<= (12, 12, 12, 12);
+ {$IFDEF AVXSUP}vpaddd ymm2, ymm2, ymm3; {$ELSE}db $C5,$ED,$FE,$D3;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm1, ymm1, ymm2; {$ELSE}db $C5,$F5,$EF,$CA;{$ENDIF}
+ // rotate is x << n | x >> 32 - n
+ {$IFDEF AVXSUP}vpslld ymm4, ymm1, 12; {$ELSE}db $C5,$DD,$72,$F1,$0C;{$ENDIF}
+ {$IFDEF AVXSUP}vpsrld ymm1, ymm1, 20; {$ELSE}db $C5,$F5,$72,$D1,$14;{$ENDIF} // 32 - 12
+ {$IFDEF AVXSUP}vpor ymm1, ymm1, ymm4; {$ELSE}db $C5,$F5,$EB,$CC;{$ENDIF}
+
+ // v0 += v1; v3 ^= v0; v3 <<<= ( 8, 8, 8, 8);
+ {$IFDEF AVXSUP}vpaddd ymm0, ymm0, ymm1; {$ELSE}db $C5,$FD,$FE,$C1;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm3, ymm3, ymm0; {$ELSE}db $C5,$E5,$EF,$D8;{$ENDIF}
+ {$IFDEF AVXSUP}vpshufb ymm3, ymm3, ymm5; {$ELSE}db $C4,$E2,$65,$00,$DD;{$ENDIF}
+
+ // v2 += v3; v1 ^= v2; v1 <<<= ( 7, 7, 7, 7);
+ {$IFDEF AVXSUP}vpaddd ymm2, ymm2, ymm3; {$ELSE}db $C5,$ED,$FE,$D3;{$ENDIF}
+ {$IFDEF AVXSUP}vpxor ymm1, ymm1, ymm2; {$ELSE}db $C5,$F5,$EF,$CA;{$ENDIF}
+ {$IFDEF AVXSUP}vpslld ymm4, ymm1, 7; {$ELSE}db $C5,$DD,$72,$F1,$07;{$ENDIF}
+ {$IFDEF AVXSUP}vpsrld ymm1, ymm1, 25; {$ELSE}db $C5,$F5,$72,$D1,$19;{$ENDIF} // 32 - 7
+ {$IFDEF AVXSUP}vpor ymm1, ymm1, ymm4; {$ELSE}db $C5,$F5,$EB,$CC;{$ENDIF}
+
+ // v1 <<<= 32; v2 <<<= 64; v3 <<<= 96; Return
+ {$IFDEF AVXSUP}vmovapd ymm4, ymm1; {$ELSE}db $C5,$FD,$29,$CC;{$ENDIF}
+ {$IFDEF AVXSUP}vpalignr ymm1, ymm1, ymm4, 12; {$ELSE}db $C4,$E3,$75,$0F,$CC,$0C;{$ENDIF}
+ {$IFDEF AVXSUP}vmovapd ymm4, ymm2; {$ELSE}db $C5,$FD,$29,$D4;{$ENDIF}
+ {$IFDEF AVXSUP}vpalignr ymm2, ymm2, ymm4, 8; {$ELSE}db $C4,$E3,$6D,$0F,$D4,$08;{$ENDIF}
+ {$IFDEF AVXSUP}vmovapd ymm4, ymm3; {$ELSE}db $C5,$FD,$29,$DC;{$ENDIF}
+ {$IFDEF AVXSUP}vpalignr ymm3, ymm3, ymm4, 4; {$ELSE}db $C4,$E3,$65,$0F,$DC,$04;{$ENDIF}
+
+ // move back
+ {$IFDEF AVXSUP}vmovdqa [rcx], ymm0; {$ELSE}db $C5,$FD,$7F,$01;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [rcx + 32], ymm1; {$ELSE}db $C5,$FD,$7F,$49,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [rcx + 64], ymm2; {$ELSE}db $C5,$FD,$7F,$51,$40;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [rcx + 96], ymm3; {$ELSE}db $C5,$FD,$7F,$59,$60;{$ENDIF}
+
+ // cleanup registers
+ {$IFDEF AVXSUP}vmovupd ymm4, dYMM4; {$ELSE}db $C5,$FD,$10,$65,$D8;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd ymm5, dYMM5; {$ELSE}db $C5,$FD,$10,$6D,$B8;{$ENDIF}
+ {$IFDEF AVXSUP}vzeroupper; {$ELSE}db $C5,$F8,$77;{$ENDIF}
+end;
+{$IFDEF FPC}
+end;
+{$ENDIF}
+
+// realign the chacha matrix such that further access to it is linear
+procedure AVXRealingAndAddMtx( chaChaMtx : PChaChaAVXMtx; inpChaCha : PChaChaMtx );
+var dXMM4, dXMM5 : Array[0..2] of Double;
+{$IFDEF FPC}
+begin
+{$ENDIF}
+asm
+ {$IFDEF UNIX}
+ // Linux uses a diffrent ABI -> copy over the registers so they meet with winABI
+ // The parameters are passed in the following order:
+ // RDI, RSI -> mov to RCX, RDX
+ mov rcx, rdi;
+ mov rdx, rsi;
+ {$ENDIF}
+ {$IFDEF AVXSUP}vmovupd dXMM4, xmm4; {$ELSE}db $C5,$F9,$11,$65,$E0;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd dXMM5, xmm5; {$ELSE}db $C5,$F9,$11,$6D,$D0;{$ENDIF}
+
+ // store second matrix
+ {$IFDEF AVXSUP}vmovdqa xmm0, [rcx + 16]; {$ELSE}db $C5,$F9,$6F,$41,$10;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm1, [rcx + 48]; {$ELSE}db $C5,$F9,$6F,$49,$30;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm2, [rcx + 80]; {$ELSE}db $C5,$F9,$6F,$51,$50;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm3, [rcx + 112]; {$ELSE}db $C5,$F9,$6F,$59,$70;{$ENDIF}
+
+ {$IFDEF AVXSUP}vpaddd xmm0, xmm0, [rdx]; {$ELSE}db $C5,$F9,$FE,$02;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddd xmm1, xmm1, [rdx + 16]; {$ELSE}db $C5,$F1,$FE,$4A,$10;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddd xmm2, xmm2, [rdx + 32]; {$ELSE}db $C5,$E9,$FE,$52,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddd xmm3, xmm3, [rdx + 48]; {$ELSE}db $C5,$E1,$FE,$5A,$30;{$ENDIF}
+
+
+ // move positions
+ {$IFDEF AVXSUP}vmovapd xmm5, [rcx]; {$ELSE}db $C5,$F9,$28,$29;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddd xmm5, xmm5, [rdx]; {$ELSE}db $C5,$D1,$FE,$2A;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [rcx], xmm5; {$ELSE}db $C5,$F9,$7F,$29;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm5, [rcx + 32]; {$ELSE}db $C5,$F9,$6F,$69,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddd xmm5, xmm5, [rdx + 16]; {$ELSE}db $C5,$D1,$FE,$6A,$10;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [rcx + 16], xmm5; {$ELSE}db $C5,$F9,$7F,$69,$10;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm5, [rcx + 64]; {$ELSE}db $C5,$F9,$6F,$69,$40;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddd xmm5, xmm5, [rdx + 32]; {$ELSE}db $C5,$D1,$FE,$6A,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [rcx + 32], xmm5; {$ELSE}db $C5,$F9,$7F,$69,$20;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa xmm5, [rcx + 96]; {$ELSE}db $C5,$F9,$6F,$69,$60;{$ENDIF}
+ {$IFDEF AVXSUP}vpaddd xmm5, xmm5, [rdx + 48]; {$ELSE}db $C5,$D1,$FE,$6A,$30;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [rcx + 48], xmm5; {$ELSE}db $C5,$F9,$7F,$69,$30;{$ENDIF}
+
+ // append second matrix
+ {$IFDEF AVXSUP}vmovdqa [rcx + 64], xmm0; {$ELSE}db $C5,$F9,$7F,$41,$40;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [rcx + 80], xmm1; {$ELSE}db $C5,$F9,$7F,$49,$50;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [rcx + 96], xmm2; {$ELSE}db $C5,$F9,$7F,$51,$60;{$ENDIF}
+ {$IFDEF AVXSUP}vmovdqa [rcx + 112], xmm3; {$ELSE}db $C5,$F9,$7F,$59,$70;{$ENDIF}
+
+ // cleanup registers
+ {$IFDEF AVXSUP}vmovupd xmm4, dXMM4; {$ELSE}db $C5,$F9,$10,$65,$E0;{$ENDIF}
+ {$IFDEF AVXSUP}vmovupd xmm5, dXMM5; {$ELSE}db $C5,$F9,$10,$6D,$D0;{$ENDIF}
+
+ {$IFDEF AVXSUP}vzeroupper; {$ELSE}db $C5,$F8,$77;{$ENDIF}
+end;
+{$IFDEF FPC}
+end;
+{$ENDIF}
+
+{$ENDIF}
+
+{$ENDIF} // PUREPASCAL
+
+procedure TCipher_ChaCha20.AfterConstruction;
+begin
+ inherited;
+
+ // default is poly1305!!
+ Mode := cmPoly1305;
+ SetChaChaMode( cmSecure );
+ {$IFDEF PUREPASCAL}
+ fFullBlockFunc := FullBlockPas;
+ {$ELSE}
+ case CpuMode of
+ cmSSE: if TDEC_CPUSupport.SSE3 then
+ fFullBlockFunc := FullBlockSSE;
+ cmAVX: if TDEC_CPUSupport.AVX2 then
+ fFullBlockFunc := FullBlockAVX;
+ else
+ fFullBlockFunc := FullBlockPas;
+ end;
+ {$ENDIF}
+end;
+
+
+// ###########################################
+// #### ChaChaBlock init
+// ###########################################
+procedure TCipher_ChaCha20.InitChaChaBlk;
+var i : integer;
+ m1, m2 : PChaChaMtx;
+begin
+ if fChaChaIdx >= fChaChaBlkLen then
+ begin
+ {$IFNDEF PUREPASCAL}
+ if CpuMode = cmAVX then
+ begin
+ // move the input matrix so we have nicely aligned memory for the quarter round
+ for i := 0 to 3 do
+ begin
+ Move(fInpChaChaMtx^[4*i], fOutChaChaMtx^[8*i], 4*sizeof(LongWord));
+ Move(fInpChaChaMtx^[4*i], fOutChaChaMtx^[8*i + 4], 4*sizeof(LongWord));
+ end;
+
+ // update index in the "second" matrix - this one is always odd so no further check
+ inc(fOutChaChaMtx^[3*8 + 4]);
+
+ for i := 0 to fNumChaChaRounds - 1 do
+ AVXChaChaDoubleQuarterRound(fOutChaChaMtx);
+ // undo the alignment so both matrices are adjacent again (not intermittent as used for the rounds)
+ AVXRealingAndAddMtx(fOutChaChaMtx, fInpChaChaMTX);
+
+ // increment the one value that is off by one from the input matrix
+ inc(fOutChaChaMtx^[16 + 12]);
+
+ // increment input matrix by 2
+ inc(fInpChaChaMTX^[12], 2);
+ end
+ else
+ {$ENDIF}
+ begin
+ // ###########################################
+ // #### Create two chacha matrices in one go
+ m1 := PChaChaMtx(fOutChaChaMtx);
+ m2 := m1;
+ inc(m2);
+ Move(fInpChaChaMTX^, m1^, sizeof(TChaChaMtx));
+ Move(fInpChaChaMTX^, m2^, sizeof(TChaChaMtx));
+ inc(m2^[12]);
+
+ {$IFNDEF PUREPASCAL}
+ if cpuMode = cmSSE then
+ begin
+ for i := 0 to fNumChaChaRounds - 1 do
+ begin
+ SSEChaChaDoubleQuarterRound(m1);
+ SSEChaChaDoubleQuarterRound(m2);
+ end;
+ end
+ else
+ {$ENDIF}
+ begin
+ for i := 0 to fNumChaChaRounds - 1 do
+ begin
+ PasChaChaDoubleQuarterRound(m1);
+ PasChaChaDoubleQuarterRound(m2);
+ end;
+
+ end;
+ for i := 0 to High(fInpChaChaMTX^) do
+ inc(m1^[i], fInpChaChaMTX^[i]);
+ inc(fInpChaChaMTX^[12]);
+ for i := 0 to High(fInpChaChaMTX^) do
+ inc(m2^[i], fInpChaChaMTX^[i]);
+ inc(fInpChaChaMTX^[12]);
+ end;
+
+ fChaChaIdx := 0;
+
+ // is this here for xchacha?
+ if fInpChaChaMTX^[12] <= 1 then
+ raise EDECException.Create('Counter overflow!');
+// inc(fInpChaChaMTX^[13]);
+ end;
+end;
+
+procedure TCipher_ChaCha20.PasChaChaDoubleQuarterRound(mtx : PChaChaMtx);
+begin
+ ChaChaQuarterRound( mtx^[0], mtx^[4], mtx^[8], mtx^[12]);
+ ChaChaQuarterRound( mtx^[1], mtx^[5], mtx^[9], mtx^[13]);
+ ChaChaQuarterRound( mtx^[2], mtx^[6], mtx^[10], mtx^[14]);
+ ChaChaQuarterRound( mtx^[3], mtx^[7], mtx^[11], mtx^[15]);
+ ChaChaQuarterRound( mtx^[0], mtx^[5], mtx^[10], mtx^[15]);
+ ChaChaQuarterRound( mtx^[1], mtx^[6], mtx^[11], mtx^[12]);
+ ChaChaQuarterRound( mtx^[2], mtx^[7], mtx^[8], mtx^[13]);
+ ChaChaQuarterRound( mtx^[3], mtx^[4], mtx^[9], mtx^[14]);
+end;
+
+{$IFNDEF PUREPASCAL}
+
+(*
+// https://eprint.iacr.org/2013/759.pdf
+Algorithm 5: DOUBLEQUARTERROUND (optimized for 128-bit vectors)
+Input: v0, v1, v2, v3 (state matrix as four 4x32-bit vectors, each vector includes one row)
+Output: v0, v1, v2, v3 (updated state matrix)
+Flow
+ v0 += v1; v3 ^= v0; v3 <<<= (16, 16, 16, 16);
+ v2 += v3; v1 ^= v2; v1 <<<= (12, 12, 12, 12);
+ v0 += v1; v3 ^= v0; v3 <<<= ( 8, 8, 8, 8);
+ v2 += v3; v1 ^= v2; v1 <<<= ( 7, 7, 7, 7);
+ v1 >>>= 32; v2 >>>= 64; v3 >>>= 96;
+ v0 += v1; v3 ^= v0; v3 <<<= (16, 16, 16, 16);
+ v2 += v3; v1 ^= v2; v1 <<<= (12, 12, 12, 12);
+ v0 += v1; v3 ^= v0; v3 <<<= ( 8, 8, 8, 8);
+ v2 += v3; v1 ^= v2; v1 <<<= ( 7, 7, 7, 7);
+ v1 <<<= 32; v2 <<<= 64; v3 <<<= 96; Return
+*)
+const cShuf8 : Array[0..15] of byte = (3, 0, 1, 2,
+ 7, 4, 5, 6,
+ 11, 8, 9, 10,
+ 15, 12, 13, 14 );
+
+procedure TCipher_ChaCha20.SSEChaChaDoubleQuarterRound(mtx : PChaChaMtx);
+// 32Bit: ecx = self, edx = mtx
+// 64bit: rcx = self, rdx = mtx
+{$IFDEF CPUX64}
+var dXMM4, dXMM5 : Array[0..1] of Int64;
+{$ENDIF}
+asm
+ {$IFDEF CPUX64}
+ // rcx seems to have "self" as reference
+ {$IFDEF UNIX}
+ // Linux uses a diffrent ABI -> copy over the registers so they meet with winABI
+ // The parameters are passed in the following order:
+ // RDI, RSI, RDX, RCX, r8, r9 -> mov to RCX, RDX, R8, R9, width and height
+ // in our case only rdi to rcx
+ mov rdx, rsi;
+ {$ENDIF}
+ movupd dXMM4, xmm4;
+ movupd dXMM5, xmm5;
+
+ // 64bit version
+ movdqu xmm5, [rip + cShuf8];
+
+ // move the matrix to xmm0 to xmm3
+ movdqa xmm0, [rdx];
+ movdqa xmm1, [rdx + 16];
+ movdqa xmm2, [rdx + 32];
+ movdqa xmm3, [rdx + 48];
+ {$ELSE}
+ movdqu xmm5, cShuf8;
+
+ // move the matrix to xmm0 to xmm3
+ mov edx, mtx;
+ movdqa xmm0, [edx];
+ movdqa xmm1, [edx + 16];
+ movdqa xmm2, [edx + 32];
+ movdqa xmm3, [edx + 48];
+ {$ENDIF}
+
+ // v0 += v1; v3 ^= v0; v3 <<<= 16
+ paddd xmm0, xmm1;
+ pxor xmm3, xmm0;
+ pshufhw xmm3, xmm3, $B1; // 10 11 00 01
+ pshuflw xmm3, xmm3, $B1;
+
+ // v2 += v3; v1 ^= v2; v1 <<<= (12, 12, 12, 12);
+ paddd xmm2, xmm3;
+ pxor xmm1, xmm2;
+ // rotate is x << n | x >> 32 - n
+ movapd xmm4, xmm1;
+ pslld xmm4, 12;
+ psrld xmm1, 20; // 32 - 12
+ por xmm1, xmm4;
+
+ // v0 += v1; v3 ^= v0; v3 <<<= ( 8, 8, 8, 8);
+ paddd xmm0, xmm1;
+ pxor xmm3, xmm0;
+ pshufb xmm3, xmm5;
+
+ // v2 += v3; v1 ^= v2; v1 <<<= ( 7, 7, 7, 7);
+ paddd xmm2, xmm3;
+ pxor xmm1, xmm2;
+ movapd xmm4, xmm1;
+ pslld xmm4, 7;
+ psrld xmm1, 25; // 32 - 7
+ por xmm1, xmm4;
+
+ // v1 >>>= 32; v2 >>>= 64; v3 >>>= 96;
+
+ // palignr is actually a sse3 opcode but ok...
+ movapd xmm4, xmm1;
+ palignr xmm1, xmm4, 4;
+ movapd xmm4, xmm2;
+ palignr xmm2, xmm4, 8;
+ movapd xmm4, xmm3;
+ palignr xmm3, xmm4, 12;
+
+
+ // v0 += v1; v3 ^= v0; v3 <<<= 16
+ paddd xmm0, xmm1;
+ pxor xmm3, xmm0;
+ pshufhw xmm3, xmm3, $B1; // 10 11 00 01
+ pshuflw xmm3, xmm3, $B1;
+
+ // v2 += v3; v1 ^= v2; v1 <<<= (12, 12, 12, 12);
+ paddd xmm2, xmm3;
+ pxor xmm1, xmm2;
+ // rotate is x << n | x >> 32 - n
+ movapd xmm4, xmm1;
+ pslld xmm4, 12;
+ psrld xmm1, 20; // 32 - 12
+ por xmm1, xmm4;
+
+ // v0 += v1; v3 ^= v0; v3 <<<= ( 8, 8, 8, 8);
+ paddd xmm0, xmm1;
+ pxor xmm3, xmm0;
+ pshufb xmm3, xmm5;
+
+ // v2 += v3; v1 ^= v2; v1 <<<= ( 7, 7, 7, 7);
+ paddd xmm2, xmm3;
+ pxor xmm1, xmm2;
+ movapd xmm4, xmm1;
+ pslld xmm4, 7;
+ psrld xmm1, 25; // 32 - 7
+ por xmm1, xmm4;
+
+ // v1 <<<= 32; v2 <<<= 64; v3 <<<= 96; Return
+ movapd xmm4, xmm1;
+ palignr xmm1, xmm4, 12;
+ movapd xmm4, xmm2;
+ palignr xmm2, xmm4, 8;
+ movapd xmm4, xmm3;
+ palignr xmm3, xmm4, 4;
+
+ // move back
+ {$IFDEF CPUX64}
+ movdqa [rdx], xmm0;
+ movdqa [rdx + 16], xmm1;
+ movdqa [rdx + 32], xmm2;
+ movdqa [rdx + 48], xmm3;
+
+ // cleanup registers
+ movupd xmm4, dXMM4;
+ movupd xmm5, dXMM5;
+ {$ELSE}
+ movdqa [edx], xmm0;
+ movdqa [edx + 16], xmm1;
+ movdqa [edx + 32], xmm2;
+ movdqa [edx + 48], xmm3;
+ {$ENDIF}
+end;
+
+{$ENDIF}
+
{$IFDEF RESTORE_RANGECHECKS}{$R+}{$ENDIF}
{$IFDEF RESTORE_OVERFLOWCHECKS}{$Q+}{$ENDIF}
+function TCipher_ChaCha20.TestChaChaMtx(
+ const expectedMtx: TChaChaMtx): boolean;
+begin
+ Result := CompareMem(fOutChaChaMtx, @expectedMtx, sizeof(TChaChaMtx));
+end;
+
+
+{ TCipher_XChaCha20 }
+
+procedure TCipher_XChaCha20.HChaCha(iv: TBytes);
+var i : integer;
+begin
+ // inpmatrix is initialized with the original key
+ fPHChaCha := AlignPtr32( @fHChaCha[0] );
+ Move( fInpChaChaMTX^, fPHChaCha^, sizeof(fPHChaCha^));
+
+ // copy over the iv -> 128 bit
+ // create the HChaChaMatrix in fPHChaCha
+ Move(iv[0], fPHChaCha^[12], 4*sizeof(LongWord));
+
+ {$IFNDEF PUREPASCAL}
+ if cpuMode = cmSSE then
+ begin
+ for i := 0 to fNumChaChaRounds - 1 do
+ SSEChaChaDoubleQuarterRound(fPHChaCha);
+ end
+ else
+ {$ENDIF}
+ begin
+ for i := 0 to fNumChaChaRounds - 1 do
+ PasChaChaDoubleQuarterRound(fPHChaCha);
+ end;
+end;
+
+
+procedure TCipher_XChaCha20.OnAfterInitVectorInitialization(
+ const OriginalInitVector: TBytes);
+begin
+ // RFC point 2.3 and 2.3.1:
+
+ if length(OriginalInitVector) <> 24 then //192 div 8
+ raise EDECException.Create('IV vector needs to be 192 bits long');
+
+ // update iv -> use the first 16 bytes!
+ HChaCha(OriginalInitVector);
+
+ // extract subkey -> overwrite key
+
+ // subkey is the first row and the last row!!
+ Move(fPHChaCha^[0], fInpChaChaMTX^[4], 4*sizeof(LongWord));
+ Move(fPHChaCha^[12], fInpChaChaMTX^[8], 4*sizeof(LongWord));
+
+ // update IV -> the last 8 bytes
+ Move(OriginalInitVector[16], FInitializationVector[4], 2*sizeof(LongWord));
+ PLongWord(@FInitializationVector[0])^ := 0; // per definition the these bytes are zero
+
+ // truncate iv length
+ FInitVectorSize := 3*sizeof(longword);
+
+ // int chacha with these values
+ // note: the inherted routine may not overwrite the key part and needs
+ // to initialize the nonce with the "tampered" iv
+ inherited;
+
+ // restore the iv vector size
+ FInitVectorSize := 24;
+
+ // burn
+ FillChar(fHChaCha, sizeof(fHChaCha), 0);
+end;
+
initialization
SetDefaultCipherClass(TCipher_Null);
+ TCipher_ChaCha20.CpuMode := cmPas;
+
{$IFNDEF ManualRegisterCipherClasses}
TCipher_Null.RegisterClass(TDECCipher.ClassList);
TCipher_Blowfish.RegisterClass(TDECCipher.ClassList);
@@ -6820,6 +8555,9 @@ initialization
TCipher_3Way.RegisterClass(TDECCipher.ClassList);
TCipher_Cast128.RegisterClass(TDECCipher.ClassList);
TCipher_Gost.RegisterClass(TDECCipher.ClassList);
+ TCipher_ChaCha20.RegisterClass(TDECCipher.ClassList);
+ TCipher_XChaCha20.RegisterClass(TDECCipher.ClassList);
+
// Explicitely not registered, as this is an alias for Gost only
// TCipher_Magma.RegisterClass(TDECCipher.ClassList);
TCipher_Misty.RegisterClass(TDECCipher.ClassList);
@@ -6843,6 +8581,17 @@ initialization
{$ENDIF}
{$ENDIF}
+ if TDEC_CPUSupport.AVX2
+ then
+ TCipher_ChaCha20.CpuMode := cmAVX
+ else if TDEC_CPUSupport.SSE3
+ then
+ TCipher_ChaCha20.CpuMode := cmSSE
+ else
+ TCipher_ChaCha20.CpuMode := cmPas;
+
+ TCipher_Rijndael.UseAESAsm := TDEC_CPUSupport.AES;
+
finalization
end.
diff --git a/Source/DECOptions.inc b/Source/DECOptions.inc
index eceec526..a76838bc 100644
--- a/Source/DECOptions.inc
+++ b/Source/DECOptions.inc
@@ -73,29 +73,39 @@
// Automatically register all hash classes
{.$DEFINE ManualRegisterHashClasses} (* default off *)
+{$DEFINE ASSEMBLER}
+
// if the compiler does not support assembler turn usage off and even if restrict
// it to Windows, as those non Windows platforms which actually do support ASM
// in Delphi do not use Intel x86 ASM
-{$IFDEF FPC }
+{$IFNDEF FPC }
{$IF defined(CPUX86_64) or defined(CPUAMD64) or defined(CPUIA64) }
{$ifndef CPUX64}
{$define CPUX64}
{$endif}
- {$else}{$if defined(CPU386) or defined(CPUI386) }
+ {$IFEND}
+
+ {$if defined(CPU386) or defined(CPUI386) }
{$ifndef CPUX32}
{$define CPUX32}
{$endif}
- {$ELSE}
- {$IFNDEF ASSEMBLER }
- {$DEFINE NO_ASM} (* default ON *)
- {$ELSE}
- {$IFDEF WINDOWS}
- {.$DEFINE NO_ASM} (* default OFF *)
- {$ELSE}
- {$DEFINE NO_ASM} (* default ON *)
- {$ENDIF}
- {$ENDIF}
- {$ENDIF}{$endif}
+ {$IFEND}
+
+ {$IFNDEF ASSEMBLER}
+ {$DEFINE NO_ASM}
+ {$ENDIF}
+ {$IFDEF UNIX}
+ {$DEFINE NO_ASM}
+ {$ENDIF}
+ // {$IFNDEF ASSEMBLER }
+// {$DEFINE NO_ASM} (* default ON *)
+// {$ELSE}
+// {$IFDEF WINDOWS}
+// {.$DEFINE NO_ASM} (* default OFF *)
+// {$ELSE}
+// {$DEFINE NO_ASM} (* default ON *)
+// {$ENDIF}
+// {$ENDIF}
{$ELSE}
// Turn ASM off for FPC as we do not know enough about ASM support on FPC
{$DEFINE NO_ASM}
@@ -119,7 +129,7 @@
///
{$IF DECLARED(FireMonkeyVersion)}
{$DEFINE FMXTranslateableExceptions}
-{$ENDIF}
+{$IFEND} { TODO: convert to $ENDIF when raising minimum supported version to XE4+}
//------------------------------------------------------------------------------
// Do NOT change anything below!
//------------------------------------------------------------------------------
@@ -193,16 +203,16 @@
{$IFNDEF PUREPASCAL}
// ignored by FPC (already in PurePascal mode as defined in FPC block above)
+ {$DEFINE PUREPASCAL}
{$IFDEF CPUX86}
{$DEFINE X86ASM}
- {$ELSE !CPUX86}
- {$IFDEF CPUX64}
- {$DEFINE X64ASM}
- {$ELSE !CPUX64}
- {$DEFINE PUREPASCAL}
- {$ENDIF !CPUX64}
+ {$UNDEF PUREPASCAL}
+ {$ENDIF}
+ {$IFDEF CPUX64}
+ {$DEFINE X64ASM}
+ {$UNDEF PUREPASCAL}
{$ENDIF}
-{$ENDIF !PUREPASCAL}
+{$ENDIF}
//------------------------------------------------------------------------------
// Delphi and C++ Builder
diff --git a/Source/DECUtil.pas b/Source/DECUtil.pas
index a47882c1..14cb71a6 100644
--- a/Source/DECUtil.pas
+++ b/Source/DECUtil.pas
@@ -281,6 +281,17 @@ function StringToBytes(const Str: string): TBytes; inline;
///
function IsEqual(const a, b : TBytes ):Boolean;
+///
+/// Returns the 32Byte aligned address of pointer A
+///
+/// ///
+/// Pointer to input memory block
+///
+/// ///
+/// Returns the fir
+///
+function AlignPtr32( A : Pointer ) : Pointer;
+
implementation
uses
@@ -680,4 +691,12 @@ function IsEqual(const a, b : TBytes):Boolean;
Result := true;
end;
+function AlignPtr32( A : Pointer ) : Pointer;
+begin
+ Result := A;
+ if (NativeUint(A) and $1F) <> 0 then
+ Result := Pointer( NativeUint(Result) + $20 - NativeUint(Result) and $1F );
+end;
+
+
end.
diff --git a/Source/x86_64/DECUtil.inc b/Source/x86_64/DECUtil.inc
index 838a1346..0cbecc72 100644
--- a/Source/x86_64/DECUtil.inc
+++ b/Source/x86_64/DECUtil.inc
@@ -6,9 +6,8 @@
{$define SwapUInt32_asm}
function SwapUInt32(Source: UInt32): UInt32;
asm
- MOV RAX, Source
- BSWAP RAX
- SHR RAX, 32
+ MOV EAX, Source
+ BSWAP EAX
end;
{$endif}
diff --git a/Unit Tests/DECDUnitTestSuite.dpr b/Unit Tests/DECDUnitTestSuite.dpr
index 224f30ca..fdf107d2 100644
--- a/Unit Tests/DECDUnitTestSuite.dpr
+++ b/Unit Tests/DECDUnitTestSuite.dpr
@@ -16,7 +16,6 @@ program DECDUnitTestSuite;
{$ENDIF}
uses
-// FastMM4,
Vcl.Forms,
{$IFDEF TESTINSIGHT}
TestInsight.Client,
@@ -42,8 +41,37 @@ uses
TestDECCipherModesGCM in 'Tests\TestDECCipherModesGCM.pas',
TestDECZIPHelper in 'Tests\TestDECZIPHelper.pas',
TestDECCipherPaddings in 'Tests\TestDECCipherPaddings.pas',
+ DECBaseClass in '..\Source\DECBaseClass.pas',
+ DECCipherBase in '..\Source\DECCipherBase.pas',
+ DECCipherFormats in '..\Source\DECCipherFormats.pas',
+ DECCipherInterface in '..\Source\DECCipherInterface.pas',
TestDECCipherModesCCM in 'Tests\TestDECCipherModesCCM.pas',
- AuthenticatedCiphersCommonTestData in 'Tests\AuthenticatedCiphersCommonTestData.pas';
+ DECCipherModes in '..\Source\DECCipherModes.pas',
+ DECCipherPaddings in '..\Source\DECCipherPaddings.pas',
+ DECCiphers in '..\Source\DECCiphers.pas',
+ DECCRC in '..\Source\DECCRC.pas',
+ DECData in '..\Source\DECData.pas',
+ DECDataCipher in '..\Source\DECDataCipher.pas',
+ DECDataHash in '..\Source\DECDataHash.pas',
+ DECFormat in '..\Source\DECFormat.pas',
+ DECFormatBase in '..\Source\DECFormatBase.pas',
+ DECHash in '..\Source\DECHash.pas',
+ AuthenticatedCiphersCommonTestData in 'Tests\AuthenticatedCiphersCommonTestData.pas',
+ DECAuthenticatedCipherModesBase in '..\Source\DECAuthenticatedCipherModesBase.pas',
+ DECCipherModesCCM in '..\Source\DECCipherModesCCM.pas',
+ DECCipherModesPoly1305 in '..\Source\DECCipherModesPoly1305.pas',
+ DECHashAuthentication in '..\Source\DECHashAuthentication.pas',
+ DECHashBase in '..\Source\DECHashBase.pas',
+ DECHashBitBase in '..\Source\DECHashBitBase.pas',
+ DECHashInterface in '..\Source\DECHashInterface.pas',
+ DECRandom in '..\Source\DECRandom.pas',
+ DECTypes in '..\Source\DECTypes.pas',
+ DECUtil in '..\Source\DECUtil.pas',
+ DECUtilRawByteStringHelper in '..\Source\DECUtilRawByteStringHelper.pas',
+ DECZIPHelper in '..\Source\DECZIPHelper.pas',
+ DECCipherModesGCM in '..\Source\DECCipherModesGCM.pas',
+ TestDECChaChaPoly1305 in 'Tests\TestDECChaChaPoly1305.pas',
+ DECCPUSupport in '..\Source\DECCPUSupport.pas';
{$R *.RES}
diff --git a/Unit Tests/DECDUnitTestSuite.dproj b/Unit Tests/DECDUnitTestSuite.dproj
index 1670f30e..b08d731b 100644
--- a/Unit Tests/DECDUnitTestSuite.dproj
+++ b/Unit Tests/DECDUnitTestSuite.dproj
@@ -112,6 +112,8 @@
.\..\Compiled\DCU_IDE$(ProductVersion)_$(Platform)_$(Config)
3
/L /LL65535
+ ASSEMBLER;$(DCC_Define)
+ none
true
@@ -163,8 +165,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Base
@@ -218,10 +249,8 @@
DECDUnitTestSuite.dpr
- Embarcadero C++Builder-Package für Office 2000-Server
- Embarcadero C++Builder-Package für Office XP-Server
- Microsoft Office 2000 Beispiele für gekapselte Komponenten für Automatisierungsserver
- Microsoft Office XP Beispiele für gekapselte Komponenten für Automation Server
+ Microsoft Office 2000 Beispiele für gekapselte Komponenten für Automatisierungsserver
+ Microsoft Office XP Beispiele für gekapselte Komponenten für Automation Server
@@ -232,6 +261,18 @@
true
+
+
+ DECDUnitTestSuite.exe
+ true
+
+
+
+
+ DECDUnitTestSuite.rsm
+ true
+
+
@@ -239,6 +280,12 @@
true
+
+
+ .\
+ true
+
+
1
diff --git a/Unit Tests/Data/chacha20_poly1305_test.json b/Unit Tests/Data/chacha20_poly1305_test.json
new file mode 100644
index 00000000..e6253fdb
--- /dev/null
+++ b/Unit Tests/Data/chacha20_poly1305_test.json
@@ -0,0 +1,3710 @@
+{
+ "algorithm" : "CHACHA20-POLY1305",
+ "numberOfTests" : 300,
+ "header" : [
+ "Test vectors of type AeadTest test authenticated encryption with",
+ "additional data. The test vectors are intended for testing both",
+ "encryption and decryption."
+ ],
+ "notes" : {
+ },
+ "schema" : "aead_test_schema.json",
+ "testGroups" : [
+ {
+ "ivSize" : 96,
+ "keySize" : 256,
+ "tagSize" : 128,
+ "type" : "AeadTest",
+ "source" : {
+ "name" : "google-wycheproof",
+ "version" : "0.8r12"
+ },
+ "tests" : [
+ {
+ "tcId" : 1,
+ "comment" : "RFC 7539",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "070000004041424344454647",
+ "aad" : "50515253c0c1c2c3c4c5c6c7",
+ "msg" : "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e652074697020666f7220746865206675747572652c2073756e73637265656e20776f756c642062652069742e",
+ "ct" : "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d26586cec64b6116",
+ "tag" : "1ae10b594f09e26a7e902ecbd0600691",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 2,
+ "comment" : "",
+ "key" : "80ba3192c803ce965ea371d5ff073cf0f43b6a2ab576b208426e11409c09b9b0",
+ "iv" : "4da5bf8dfd5852c1ea12379d",
+ "aad" : "",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "76acb342cf3166a5b63c0c0ea1383c8d",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 3,
+ "comment" : "",
+ "key" : "7a4cd759172e02eb204db2c3f5c746227df584fc1345196391dbb9577a250742",
+ "iv" : "a92ef0ac991dd516a3c6f689",
+ "aad" : "bd506764f2d2c410",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "906fa6284b52f87b7359cbaa7563c709",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 4,
+ "comment" : "",
+ "key" : "cc56b680552eb75008f5484b4cb803fa5063ebd6eab91f6ab6aef4916a766273",
+ "iv" : "99e23ec48985bccdeeab60f1",
+ "aad" : "",
+ "msg" : "2a",
+ "ct" : "3a",
+ "tag" : "cac27dec0968801e9f6eded69d807522",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 5,
+ "comment" : "",
+ "key" : "46f0254965f769d52bdb4a70b443199f8ef207520d1220c55e4b70f0fda620ee",
+ "iv" : "ab0dca716ee051d2782f4403",
+ "aad" : "91ca6c592cbcca53",
+ "msg" : "51",
+ "ct" : "c4",
+ "tag" : "168310ca45b1f7c66cad4e99e43f72b9",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 6,
+ "comment" : "",
+ "key" : "2f7f7e4f592bb389194989743507bf3ee9cbde1786b6695fe6c025fd9ba4c100",
+ "iv" : "461af122e9f2e0347e03f2db",
+ "aad" : "",
+ "msg" : "5c60",
+ "ct" : "4d13",
+ "tag" : "91e8b61efb39c122195453077b22e5e2",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 7,
+ "comment" : "",
+ "key" : "c8833dce5ea9f248aa2030eacfe72bffe69a620caf793344e5718fe0d7ab1a58",
+ "iv" : "61546ba5f1720590b6040ac6",
+ "aad" : "88364fc8060518bf",
+ "msg" : "ddf2",
+ "ct" : "b60d",
+ "tag" : "ead0fd4697ec2e5558237719d02437a2",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 8,
+ "comment" : "",
+ "key" : "bd8ed7fb0d607522f04d0b12d42c92570bccc5ba2486953d70ba2e8193f6225a",
+ "iv" : "d2ab0abb50a8e9fba25429e1",
+ "aad" : "",
+ "msg" : "201221",
+ "ct" : "3cf470",
+ "tag" : "a27a69c9d7ee84586f11388c6884e63a",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 9,
+ "comment" : "",
+ "key" : "1c8b59b17a5ceced31bde97d4cefd9aaaa63362e096e863ec1c89580bca79b7a",
+ "iv" : "94f32a6dff588f2b5a2ead45",
+ "aad" : "6c8cf2ab3820b695",
+ "msg" : "453f95",
+ "ct" : "610925",
+ "tag" : "a8a7883eb7e40bc40e2e5922ae95ddc3",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 10,
+ "comment" : "",
+ "key" : "e4912cb75a1174345f1a457366f18885fe8460b06478e04be2f7fb4ec9c113e5",
+ "iv" : "7aa5ad8bf5254762171ec869",
+ "aad" : "",
+ "msg" : "9e4c1d03",
+ "ct" : "fe6849aa",
+ "tag" : "99ad07871b25c27defc31a541bd5c418",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 11,
+ "comment" : "",
+ "key" : "e05777ef3d989ace7d2abfba452bfded54801dbd5c66e91c0c2ef00479d85572",
+ "iv" : "b7f526e3fd71cf5720961aec",
+ "aad" : "15d93a96d0e6c5a9",
+ "msg" : "17bfda03",
+ "ct" : "f4710e51",
+ "tag" : "b957c6a37b6a4c94996c002186d63b2b",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 12,
+ "comment" : "",
+ "key" : "1a4c4f39abe890e62345c947bcf7de7c2e33bd5ceeda0a0abf0e7ef935ddf3ee",
+ "iv" : "9447bf85d5b97d8aee0f8e51",
+ "aad" : "",
+ "msg" : "c15a593bd0",
+ "ct" : "f711647ff1",
+ "tag" : "22b12dc38cb79629f84cdbdc2425c09d",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 13,
+ "comment" : "",
+ "key" : "800e9a24791700c9609736695ba2a8b99b2d57f1c3bfb61ed49db1c6c5219583",
+ "iv" : "3dbe876bd880ec8ea2017043",
+ "aad" : "96224835610b782b",
+ "msg" : "a7bfd041e3",
+ "ct" : "d171f046ea",
+ "tag" : "d179b1b9c4184378df009019dbb8c249",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 14,
+ "comment" : "",
+ "key" : "208c2c376c9430433db20e1a6b7ba817f8ffbfa6827f26759ccede42e591d3ec",
+ "iv" : "27fb58ec6a21e84696cb8830",
+ "aad" : "",
+ "msg" : "af104b5ccd0e",
+ "ct" : "9351b1b1b082",
+ "tag" : "560785509f60f26b681933d9cdbfd29f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 15,
+ "comment" : "",
+ "key" : "2eb168e53b07ab04355ea792fe11a6be2ce9c39cfe15a997076b1e38c17ad620",
+ "iv" : "b5965470c383fd29fe7eaee7",
+ "aad" : "6d52feb2509f7fbf",
+ "msg" : "6fdf2927e169",
+ "ct" : "41abff7b71cc",
+ "tag" : "9b5174297c03cf8902d1f706fd008902",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 16,
+ "comment" : "",
+ "key" : "55568158d3a6483f1f7021eab69b703f614251cadc1af5d34a374fdbfc5adac7",
+ "iv" : "3c4e654d663fa4596dc55bb7",
+ "aad" : "",
+ "msg" : "ab85e9c1571731",
+ "ct" : "5dfe3440dbb3c3",
+ "tag" : "ed7a434e2602d394281e0afa9fb7aa42",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 17,
+ "comment" : "",
+ "key" : "e3c09e7fab1aefb516da6a33022a1dd4eb272c80d540c5da52a730f34d840d7f",
+ "iv" : "58389375c69ee398de948396",
+ "aad" : "84e46be8c0919053",
+ "msg" : "4ee5cda20d4290",
+ "ct" : "4bd47212941ce3",
+ "tag" : "185f1408ee7fbf18f5abad6e2253a1ba",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 18,
+ "comment" : "",
+ "key" : "51e4bf2bad92b7aff1a4bc05550ba81df4b96fabf41c12c7b00e60e48db7e152",
+ "iv" : "4f07afedfdc3b6c2361823d3",
+ "aad" : "",
+ "msg" : "be3308f72a2c6aed",
+ "ct" : "8e9439a56eeec817",
+ "tag" : "fbe8a6ed8fabb1937539dd6c00e90021",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 19,
+ "comment" : "",
+ "key" : "1131c1418577a054de7a4ac551950f1a053f9ae46e5b75fe4abd5608d7cddadd",
+ "iv" : "b4ea666ee119563366484a78",
+ "aad" : "66c0ae70076cb14d",
+ "msg" : "a4c9c2801b71f7df",
+ "ct" : "b9b910433af052b0",
+ "tag" : "4530f51aeee024e0a445a6328fa67a18",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 20,
+ "comment" : "",
+ "key" : "e1094967f86d893cdfe2e2e6d5c7ee4dfef67da3c9c5d64e6ad7c1577dcb38c5",
+ "iv" : "8092fc245b3326cddbd1424c",
+ "aad" : "",
+ "msg" : "c37aa791ddd6accf91",
+ "ct" : "d9d897a9c1c5bb9f01",
+ "tag" : "085a430373058f1a12a0d589fd5be68b",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 21,
+ "comment" : "",
+ "key" : "236f9baee4f9da15beeca40ff4af7c760f254a64bc3a3d7f4fad557e61b68586",
+ "iv" : "f1ca81338629587acf9372bf",
+ "aad" : "8c32f47a386152ec",
+ "msg" : "d7f26d5252e1765f5b",
+ "ct" : "8fdb429d47761cbf8e",
+ "tag" : "8ef647ed334fdebbc2bef80be02884e0",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 22,
+ "comment" : "",
+ "key" : "4de207a3b70c51e5f23048eed5a5da9bb65e917a69aa93e7c8b4a815cd9724de",
+ "iv" : "4c15a71dc6791a8c005ad502",
+ "aad" : "",
+ "msg" : "f2c54b6b5e490da18659",
+ "ct" : "700d35adf5100a22a1de",
+ "tag" : "102d992ffaff599b5bddddeb2dfb399b",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 23,
+ "comment" : "",
+ "key" : "6d667fd79e5fb725f50343dccc4863227c75ee3f7a578476e3e9f32598d81559",
+ "iv" : "6220527aba88e27f766658b2",
+ "aad" : "e1e27ccddb3cb407",
+ "msg" : "0c8c5a252681f2b5b4c0",
+ "ct" : "04aad66c60e0bf8ebba9",
+ "tag" : "c15f69a4d2aef97d7748756ff49d894b",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 24,
+ "comment" : "",
+ "key" : "8f4bd94ef73e75d1e068c30b37ead576c5344e093ece1330e9101c82f793cf05",
+ "iv" : "ec1e2967f0f6979e5f5b07fb",
+ "aad" : "",
+ "msg" : "b89812b34d9bced4a0ba07",
+ "ct" : "1c3d53baaa36eaa1d8ec4d",
+ "tag" : "4d94ebf960f12433bec43aa86d7e6e6d",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 25,
+ "comment" : "",
+ "key" : "2aa3bc7033351cac51364cdaf6ffac2c20f64046e1550a7b1c65f41800599019",
+ "iv" : "28cce57a5db2cd206321e340",
+ "aad" : "a9bc350eaf2e6e3d",
+ "msg" : "83016823123484b56095b0",
+ "ct" : "1c8578f8e75203d0336a52",
+ "tag" : "5910f7a9d5e4df05d7248bd7a8d65e63",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 26,
+ "comment" : "",
+ "key" : "99b62bd5afbe3fb015bde93f0abf483957a1c3eb3ca59cb50b39f7f8a9cc51be",
+ "iv" : "9a59fce26df0005e07538656",
+ "aad" : "",
+ "msg" : "42baae5978feaf5c368d14e0",
+ "ct" : "ff7dc203b26c467a6b50db33",
+ "tag" : "578c0f2758c2e14e36d4fc106dcb29b4",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 27,
+ "comment" : "",
+ "key" : "85f35b6282cff440bc1020c8136ff27031110fa63ec16f1e825118b006b91257",
+ "iv" : "58dbd4ad2c4ad35dd906e9ce",
+ "aad" : "a506e1a5c69093f9",
+ "msg" : "fdc85b94a4b2a6b759b1a0da",
+ "ct" : "9f8816de0994e938d9e53f95",
+ "tag" : "d086fc6c9d8fa915fd8423a7cf05072f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 28,
+ "comment" : "",
+ "key" : "faf4bfe8019a891c74901b17f4f48cee5cd065d55fdea60118aaf6c4319a0ea5",
+ "iv" : "b776c3fddba7c81362ce6e1b",
+ "aad" : "",
+ "msg" : "8dadff8d60c8e88f604f274833",
+ "ct" : "e6b33a74a4ac443bd93f9c1b94",
+ "tag" : "0c115172bdb02bbad3130fff22790d60",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 29,
+ "comment" : "",
+ "key" : "841020d1606edcfc536abfb1a638a7b958e21efc10c386ac45a18493450afd5f",
+ "iv" : "6d62f159731b140eb18ce074",
+ "aad" : "5a8e1c7aa39810d5",
+ "msg" : "d6af138f701b801e60c85ffd5c",
+ "ct" : "b0a7500aca45bb15f01ece4389",
+ "tag" : "0160e83adbec7f6a2ee2ff0215f9ef00",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 30,
+ "comment" : "",
+ "key" : "470f9ce3d2250bd60cbbefdb2e6a1178c012299b5590639c7797b6024fa703d8",
+ "iv" : "a9ea4d619fe405d04cba7d7a",
+ "aad" : "",
+ "msg" : "6ca67dd023fba6507b9f9a1f667e",
+ "ct" : "d3017e0bb1705b380b34cc333450",
+ "tag" : "5708e72ca2bd354f487f82f67fbc3acb",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 31,
+ "comment" : "",
+ "key" : "e4b97e91e4c8e85eb7ce0a7f30bf8a0abf4468251e4c6386c0e7aacb8e879aa8",
+ "iv" : "0e23c942a0c9fb526586eead",
+ "aad" : "eaaaeab26957f9a1",
+ "msg" : "b84b3f74cd23064bb426fe2ced2b",
+ "ct" : "52e9672b416d84d97033796072d0",
+ "tag" : "e83839dc1fd9b8b9d1444c40e488d493",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 32,
+ "comment" : "",
+ "key" : "67119627bd988eda906219e08c0d0d779a07d208ce8a4fe0709af755eeec6dcb",
+ "iv" : "68ab7fdbf61901dad461d23c",
+ "aad" : "",
+ "msg" : "51f8c1f731ea14acdb210a6d973e07",
+ "ct" : "0b29638e1fbdd6df53970be2210042",
+ "tag" : "2a9134087d67a46e79178d0a93f5e1d2",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 33,
+ "comment" : "",
+ "key" : "e6f1118d41e4b43fb58221b7ed79673834e0d8ac5c4fa60bbc8bc4893a58894d",
+ "iv" : "d95b3243afaef714c5035b6a",
+ "aad" : "6453a53384632212",
+ "msg" : "97469da667d6110f9cbda1d1a20673",
+ "ct" : "32db66c4a3819d81557455e5980fed",
+ "tag" : "feae30dec94e6ad3a9eea06a0d703917",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 34,
+ "comment" : "",
+ "key" : "59d4eafb4de0cfc7d3db99a8f54b15d7b39f0acc8da69763b019c1699f87674a",
+ "iv" : "2fcb1b38a99e71b84740ad9b",
+ "aad" : "",
+ "msg" : "549b365af913f3b081131ccb6b825588",
+ "ct" : "e9110e9f56ab3ca483500ceabab67a13",
+ "tag" : "836ccabf15a6a22a51c1071cfa68fa0c",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 35,
+ "comment" : "",
+ "key" : "b907a45075513fe8a8019edee3f2591487b2a030b03c6e1d771c862571d2ea1e",
+ "iv" : "118a6964c2d3e380071f5266",
+ "aad" : "034585621af8d7ff",
+ "msg" : "55a465644f5b650928cbee7c063214d6",
+ "ct" : "e4b113cb775945f3d3a8ae9ec141c00c",
+ "tag" : "7c43f16ce096d0dc27c95849dc383b7d",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 36,
+ "comment" : "",
+ "key" : "3b2458d8176e1621c0cc24c0c0e24c1e80d72f7ee9149a4b166176629616d011",
+ "iv" : "45aaa3e5d16d2d42dc03445d",
+ "aad" : "",
+ "msg" : "3ff1514b1c503915918f0c0c31094a6e1f",
+ "ct" : "02cc3acb5ee1fcdd12a03bb857976474d3",
+ "tag" : "d83b7463a2c3800fe958c28eaa290813",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 37,
+ "comment" : "",
+ "key" : "f60c6a1b625725f76c7037b48fe3577fa7f7b87b1bd5a982176d182306ffb870",
+ "iv" : "f0384fb876121410633d993d",
+ "aad" : "9aaf299eeea78f79",
+ "msg" : "63858ca3e2ce69887b578a3c167b421c9c",
+ "ct" : "35766488d2bc7c2b8d17cbbb9abfad9e6d",
+ "tag" : "1f391e657b2738dda08448cba2811ceb",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 38,
+ "comment" : "",
+ "key" : "37ceb574ccb0b701dd11369388ca27101732339f49d8d908ace4b23af0b7ce89",
+ "iv" : "37270b368f6b1e3e2ca51744",
+ "aad" : "",
+ "msg" : "f26991537257378151f4776aad28ae8bd16b",
+ "ct" : "b621d76a8dacff00b3f840cdf26c894cc5d1",
+ "tag" : "e0a21716ed94c0382fa9b0903d15bb68",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 39,
+ "comment" : "",
+ "key" : "68888361919bc10622f45df168e5f6a03bd8e884c0611bea2f34c1882ed9832b",
+ "iv" : "bfd6ff40f2df8ca7845980cc",
+ "aad" : "b8373438ddb2d6c3",
+ "msg" : "ff97f2eefb3401ac31fc8dc1590d1a92cbc1",
+ "ct" : "e0a745186c1a7b147f74faff2a715df5c19d",
+ "tag" : "917baf703e355d4d950e6c05fe8f349f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 40,
+ "comment" : "",
+ "key" : "1b35b856b5a86d3403d28fc2103a631d42deca5175cdb0669a5e5d90b2caafc5",
+ "iv" : "2343de88be6c7196d33b8694",
+ "aad" : "",
+ "msg" : "21ef185c3ae9a96fa5eb473878f4d0b242781d",
+ "ct" : "d6e0ed54fccef30bd605d72da3320e249a9cb5",
+ "tag" : "c68bc6724ec803c43984ce42f6bd09ff",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 41,
+ "comment" : "",
+ "key" : "d6484e3973f6be8c83ed3208d5be5cfa06fda72fbfdc5b19d09be3f4e4eba29d",
+ "iv" : "1af1d90e877e11a496efa3df",
+ "aad" : "cc4efd8364fb114a",
+ "msg" : "7335ab04b03e706109ec3ee835db9a246ea0ad",
+ "ct" : "29e54d608237c3c3609dba16e6edf43842d72f",
+ "tag" : "d3365fdcd506aaaa5368661e80e9d99b",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 42,
+ "comment" : "",
+ "key" : "422add37849d6e4c3dfd8020dc6a07e8a249788f3d6a83b9cb4d802362c97542",
+ "iv" : "1e7e67be948de7352ffdb727",
+ "aad" : "",
+ "msg" : "d7f5e611dd3a2750fb843fc1b6b93087310dc87d",
+ "ct" : "7fe606652d858f595ec2e706754fa3d933fcc834",
+ "tag" : "78d59235aa5d03a4c32590e590c04d22",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 43,
+ "comment" : "",
+ "key" : "cdccfe3f46d782ef47df4e72f0c02d9c7f774def970d23486f11a57f54247f17",
+ "iv" : "376187894605a8d45e30de51",
+ "aad" : "956846a209e087ed",
+ "msg" : "e28e0e9f9d22463ac0e42639b530f42102fded75",
+ "ct" : "14f707c446988a4903775ec7acec6da114d43112",
+ "tag" : "987d4b147c490d43d376a198cab383f0",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 44,
+ "comment" : "",
+ "key" : "e79dfc6d2fc465b8439e1c5baccb5d8ef2853899fc19753b397e6c25b35e977e",
+ "iv" : "f9d6320d7ce51d8ed0677d3a",
+ "aad" : "",
+ "msg" : "4f543e7938d1b878dacaeec81dce4899974816813b",
+ "ct" : "1003f13ea1329cbb187316f64c3ff3a87cf5b96661",
+ "tag" : "d2323ad625094bec84790d7958d5583f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 45,
+ "comment" : "",
+ "key" : "1d7b8f1d96a1424923aef8a984869d4a777a110990ba465627acf80396c7f376",
+ "iv" : "50ba1962cdc32a5a2d36e640",
+ "aad" : "093053e20261daab",
+ "msg" : "5d3efd5767f3c12efd08af9a44e028ae68c9eff843",
+ "ct" : "2d48b0834e9ffe3046103ef7a214f02e8e4d33360e",
+ "tag" : "d533ad089be229ea606ec0f3fa22eb33",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 46,
+ "comment" : "",
+ "key" : "dd433e28cfbcb5de4ab36a02bf38686d83208771a0e63dcd08b4df1a07ac47a1",
+ "iv" : "c9cc0a1afc38ec6c30c38c68",
+ "aad" : "",
+ "msg" : "8a3e17aba9606dd49e3b1a4d9e5e42f1742373632489",
+ "ct" : "e9917ff3e64bbe1783579375e75ea823976b35539949",
+ "tag" : "074a890669b25105434c75beed3248db",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 47,
+ "comment" : "",
+ "key" : "a60924101b42ac24154a88de42142b2334cf599176caf4d1226f712dd9172930",
+ "iv" : "8ba77644b08d65d5e9f31942",
+ "aad" : "b2a4e12a19a61c75",
+ "msg" : "c949957e66439deee4b2ac1d4a6c98a6c527b90f52ab",
+ "ct" : "db4c700513818972b0dc0e531b1c281ca03e40c60dea",
+ "tag" : "63f4478bba2af469a7a4dc3b4f141360",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 48,
+ "comment" : "",
+ "key" : "1aa42027836965b1e6086fa137f9cf7f1ff48676696829bd281ff81c8ea0a4a9",
+ "iv" : "4b3dca84ecc407f424f281a9",
+ "aad" : "",
+ "msg" : "37252a3eb5c8960f0567e503a9035783b3d0a19a4b9a47",
+ "ct" : "b5f14617491fc923b683e2cc9562d043dd5986b97dbdbd",
+ "tag" : "972ce54713c05c4bb4d088c0a30cacd3",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 49,
+ "comment" : "",
+ "key" : "5d40db0cc18ef2e42815d3b6245a466a0b30a0f93e318ac10edde3bf8ad98160",
+ "iv" : "acad618039b317470d21621b",
+ "aad" : "413036411af75745",
+ "msg" : "959dde1ef3129b27702c558849e466f2baca1a45bdf4b2",
+ "ct" : "b7ca3879f95140bf6a97b3212218b7bf864a51e5bb0b3e",
+ "tag" : "fe558fb570145470ea693eb76eb73171",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 50,
+ "comment" : "",
+ "key" : "0212a8de5007ed87b33f1a7090b6114f9e08cefd9607f2c276bdcfdbc5ce9cd7",
+ "iv" : "e6b1adf2fd58a8762c65f31b",
+ "aad" : "",
+ "msg" : "10f1ecf9c60584665d9ae5efe279e7f7377eea6916d2b111",
+ "ct" : "42f26c56cb4be21d9d8d0c80fc99dde00d75f38074bfe764",
+ "tag" : "54aa7e13d48fff7d7557039457040a3a",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 51,
+ "comment" : "",
+ "key" : "c5bc09565646e7edda954f1f739223dada20b95c44ab033d0fae4b0283d18be3",
+ "iv" : "6b282ebecc541bcd7834ed55",
+ "aad" : "3e8bc5ade182ff08",
+ "msg" : "9222f9018e54fd6de1200806a9ee8e4cc904d29f25cba193",
+ "ct" : "123032437b4bfd6920e8f7e7e0087ae4889ebe7a0ad0e900",
+ "tag" : "3cf68f179550da63d3b96c2d55411865",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 52,
+ "comment" : "",
+ "key" : "9460b3c44ed86e70f3bda66385e1ca10b0c1677ef4f1360532830d17535f996f",
+ "iv" : "abfaf42e0dba884efcf07823",
+ "aad" : "",
+ "msg" : "5c5cce881b93fb7a1b7939af1ffc5f84d3280ada778cca0953",
+ "ct" : "1d218c9f1f9f02f248a6f976a7557057f37d9393d9f213c1f3",
+ "tag" : "bc88344c6fdc898feed394fb28511316",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 53,
+ "comment" : "",
+ "key" : "c111d6d5d78a071b15ab37cc8c3819199387ab7c1933aa97b1489f6584ba8e2a",
+ "iv" : "85f18ad8ff72cafee2452ab8",
+ "aad" : "84cdff939391c022",
+ "msg" : "6989c646a10b7c76f4d9f7d574da40e152013cf0dd78f5aa8a",
+ "ct" : "9715d344e8d3f3a3eaa98a9cea57c0cd717c6ef5076027c9ec",
+ "tag" : "3056ff5ee0aa8636bb639984edb5236b",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 54,
+ "comment" : "",
+ "key" : "8a1b1e699a0c4a3e610b10902daedab1bf1ea0d505c47d7842cbcee0d3b1b6e6",
+ "iv" : "a6f9a8d335fa84c3b27dcd2a",
+ "aad" : "",
+ "msg" : "ee6a15fc183108f0877e7f2b8a9615f4b3fc36e1c83440f66aad",
+ "ct" : "9089bbdb8bcfd124e227bf75c4bfe1cba2004a274fc31aa32358",
+ "tag" : "fd2e21c64a019621c68594826cd7b1cd",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 55,
+ "comment" : "",
+ "key" : "74b384e6e013ec4172ed7a28a10fb9bb79b4be2a24f6999e3d3caa28e64a8656",
+ "iv" : "ebc19fc9ecb2339908ea3836",
+ "aad" : "85073f2edc13d3a1",
+ "msg" : "3aa9f7372f056e5a0729752d9a37132d6dd07c56792e1c7582a9",
+ "ct" : "796ffb70ab43e7fa79f95583e384524727bb3e47fc45b969f714",
+ "tag" : "c3322b4445de5f3c9f18dcc847cc94c3",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 56,
+ "comment" : "",
+ "key" : "77d824795d2029f0eb0e0baab5cfeb32f7e93474913a7f95c737a667a3c33314",
+ "iv" : "f3307430f492d2b8a72d3a81",
+ "aad" : "",
+ "msg" : "0c4179a497d8fdd72796fb725692b805d63b7c718359cf10518aee",
+ "ct" : "49c81d17d67d7ba9954f497d0b0ddc21f3f839c9d2cc198d30bc2c",
+ "tag" : "50009899e5b2a9726c8f3556cadfbe84",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 57,
+ "comment" : "",
+ "key" : "bec5eac68f893951cbd7d1ecd3ee6611130dd9c3f80cddf95111d07d5edd76d1",
+ "iv" : "342ada4f0c115124b222df80",
+ "aad" : "73365f6d80edb1d8",
+ "msg" : "481433d8b1cd38af4a750e13a64b7a4e8507682b3517595938a20e",
+ "ct" : "4c129fc13cbdd9d3fe81ac755bf4fbea2fdd7e0aca0505a6ee9637",
+ "tag" : "9cede1d30a03db5d55265d3648bc40d4",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 58,
+ "comment" : "",
+ "key" : "a59c1e13064df8f2b8df77a492b0ca2eae921b52a84b305a3a9a51408a9ecb69",
+ "iv" : "9544d41ece0c92ef01cfac2d",
+ "aad" : "",
+ "msg" : "1c35b898821ba55c2617c25df9e6df2a8002b384902186cd69dfd20e",
+ "ct" : "a6fa8f57ddc81d6099f667dd62402b6a5d5b7d05a329298029113169",
+ "tag" : "bb24e38b31dbbc3e575b9e3ee076af2a",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 59,
+ "comment" : "",
+ "key" : "084b5d7365f1a8fec6365939ed741e6ea5893e0318d82ab47500a97d77aaa041",
+ "iv" : "829f005e980f0a6e2f983eaa",
+ "aad" : "770f6e6e89a3fe8e",
+ "msg" : "7510016efadc385a71ed689ceb590c8ea9cc1e81b793338bddf5f10c",
+ "ct" : "fd42cb5cf894f879e3cf751662aaa58a2288cc53548802becaf42359",
+ "tag" : "188329438afe1cd7225d0478aa90c773",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 60,
+ "comment" : "",
+ "key" : "5a7f850a1d9aafa77d59ae1b731965e8aaec6352280fc76a7b5e23ef3610cfe4",
+ "iv" : "4946a0d6adea93b82d4332e5",
+ "aad" : "",
+ "msg" : "3c161d791f624fb0388e808f0f69ed790dbe4cbd089ebac46627bcf01d",
+ "ct" : "402302b56140c4dcc39774732c55883de124ce4bf0a0261cfa1569e2cf",
+ "tag" : "e830bfe933a96786cff2dd72b82c4bd5",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 61,
+ "comment" : "",
+ "key" : "e6d5a4246f6f05618b59c8f9ec3ac8068cc0d3f351c571aa52b09cb251f9c2f6",
+ "iv" : "2f90a65e9e48725de6ffc727",
+ "aad" : "f2415377ad283fd8",
+ "msg" : "964fc9e0e8355947aa1c2caadd7b3dbef82a1024e623606fac436ef573",
+ "ct" : "d052932bad6e6c4f835f02019e52d7ff807dc2a5aac2040883c79dd3d5",
+ "tag" : "655f93396b4d755dc4475721665fed91",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 62,
+ "comment" : "",
+ "key" : "09e822123adbb1ed89b79a58619c64853992f8371d46338712f6c91ab11a68bb",
+ "iv" : "a797205a6cacdd7e47a4789d",
+ "aad" : "",
+ "msg" : "80b71bbe833629841bd3aeaeb9db6123e51d367b436fe9d2d3454b62cfad",
+ "ct" : "83f5c77396cabd28dfcc002cba0756d4ea5455e0261d847d5708aac21e8d",
+ "tag" : "705a05820a21f381d244d40e58d2f16b",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 63,
+ "comment" : "",
+ "key" : "625735fe7f8fc81b0c1edc3d08a78b41268f87a3c68488b674222630c1d587a5",
+ "iv" : "9d8cdf289dddd09afdc1b02f",
+ "aad" : "200a9c95946ff05c",
+ "msg" : "67ae1882d0b1c1b2485bec98115ecf53b9b438deb1d0400531705038873a",
+ "ct" : "209b7539385c8b19ecd0fd8b5011b2996e316f1942064e68edfa363acbcd",
+ "tag" : "fa2f454b9fa2608f780f7c6f9b780fe1",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 64,
+ "comment" : "",
+ "key" : "2eb51c469aa8eb9e6c54a8349bae50a20f0e382711bba1152c424f03b6671d71",
+ "iv" : "04a9be03508a5f31371a6fd2",
+ "aad" : "",
+ "msg" : "b053999286a2824f42cc8c203ab24e2c97a685adcc2ad32662558e55a5c729",
+ "ct" : "45c7d6b53acad4abb68876a6e96a48fb59524d2c92c9d8a189c9fd2db91746",
+ "tag" : "566d3ca10e311b695f3eae1551652493",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 65,
+ "comment" : "",
+ "key" : "7f5b74c07ed1b40fd14358fe2ff2a740c116c7706510e6a437f19ea49911cec4",
+ "iv" : "470a339ecb3219b8b81a1f8b",
+ "aad" : "374618a06ea98a48",
+ "msg" : "f45206abc25552b2abc9ab7fa243035fedaaddc3b2293956f1ea6e7156e7eb",
+ "ct" : "46a80c4187024720084627580080dde5a3f4a11093a7076ed6f3d326bc7b70",
+ "tag" : "534d4aa2835a52e72d14df0e4f47f25f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 66,
+ "comment" : "",
+ "key" : "e1731d5854e1b70cb3ffe8b786a2b3ebf0994370954757b9dc8c7bc5354634a3",
+ "iv" : "72cfd90ef3026ca22b7e6e6a",
+ "aad" : "",
+ "msg" : "b9c554cbc36ac18ae897df7beecac1dbeb4eafa156bb60ce2e5d48f05715e678",
+ "ct" : "ea29afa49d36e8760f5fe19723b9811ed5d519934a440f5081ac430b953b0e21",
+ "tag" : "222541af46b86533c6b68d2ff108a7ea",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 67,
+ "comment" : "",
+ "key" : "27d860631b0485a410702fea61bc873f3442260caded4abde25b786a2d97f145",
+ "iv" : "262880d475f3dac5340dd1b8",
+ "aad" : "2333e5ce0f93b059",
+ "msg" : "6b2604996cd30c14a13a5257ed6cffd3bc5e29d6b97eb1799eb335e281ea451e",
+ "ct" : "6dad637897544d8bf6be9507ed4d1bb2e954bc427e5de729daf50762846ff2f4",
+ "tag" : "7b997d93c982189d7095dc794c746232",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 68,
+ "comment" : "",
+ "key" : "5155dee9aade1cc61ee7e3f92660f7590f5e5ba82f1b59b850e3fa453d2fa6b3",
+ "iv" : "c26c4b3bfdb97ee6b0f63ca1",
+ "aad" : "",
+ "msg" : "2734e08eff8f5c4f84fa0c207f49c7fd78af1ad5123ff81f83f500edf4eda09edf",
+ "ct" : "f5982b601c7a18fc72a65b218c44974dc564d8314cbe6f87fcf6c6cfbe618b34b1",
+ "tag" : "c43632f55760b5d1ed37556a94d049b5",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 69,
+ "comment" : "",
+ "key" : "573f08ebbe0cce4ac9618e8c3b224bea0a32f055c6996838a32f527ca3c3b695",
+ "iv" : "ad8050dc6d122dce3e5639ed",
+ "aad" : "e99698241c599b5f",
+ "msg" : "668d5e3f95fe030daf432a5fc5837af3a79c81e94b28d8204c5ee262ab3c9908a7",
+ "ct" : "eaf6810e6ec1cb7a2918856257d1aa3d51a827879146c6337ecf535e9c89b149c5",
+ "tag" : "a2950c2f394a3466c345f796323c1aa7",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 70,
+ "comment" : "",
+ "key" : "cf0d40a4644e5f51815165d5301b22631f4544c49a1878e3a0a5e8e1aae0f264",
+ "iv" : "e74a515e7e2102b90bef55d2",
+ "aad" : "",
+ "msg" : "973d0c753826bae466cf9abb3493152e9de7819e2bd0c71171346b4d2cebf8041aa3cedc0dfd7b467e26228bc86c9a",
+ "ct" : "fba78ae4f9d808a62e3da40be2cb7700c3613d9eb2c529c652e76a432c658d27095f0eb8f940c324981ea935e507f9",
+ "tag" : "8f046956db3a512908bd7afc8f2ab0a9",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 71,
+ "comment" : "",
+ "key" : "6cbfd71c645d184cf5d23c402bdb0d25ec54898c8a0273d42eb5be109fdcb2ac",
+ "iv" : "d4d807341683825b31cd4d95",
+ "aad" : "b3e4064683b02d84",
+ "msg" : "a98995504df16f748bfb7785ff91eeb3b660ea9ed3450c3d5e7b0e79ef653659a9978d75542ef91c456762215640b9",
+ "ct" : "a1ffed80761829ecce242e0e88b138049016bca018da2b6e19986b3e318cae8d806198fb4c527cc39350ebddeac573",
+ "tag" : "c4cbf0befda0b70242c640d7cd02d7a3",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 72,
+ "comment" : "",
+ "key" : "5b1d1035c0b17ee0b0444767f80a25b8c1b741f4b50a4d3052226baa1c6fb701",
+ "iv" : "d61040a313ed492823cc065b",
+ "aad" : "",
+ "msg" : "d096803181beef9e008ff85d5ddc38ddacf0f09ee5f7e07f1e4079cb64d0dc8f5e6711cd4921a7887de76e2678fdc67618f1185586bfea9d4c685d50e4bb9a82",
+ "ct" : "9a4ef22b181677b5755c08f747c0f8d8e8d4c18a9cc2405c12bb51bb1872c8e8b877678bec442cfcbb0ff464a64b74332cf072898c7e0eddf6232ea6e27efe50",
+ "tag" : "9ff3427a0f32fa566d9ca0a78aefc013",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 73,
+ "comment" : "",
+ "key" : "97d635c4f47574d9998a90875da1d3a284b755b2d39297a5725235190e10a97e",
+ "iv" : "d31c21aba175b70de4ebb19c",
+ "aad" : "7193f623663321a2",
+ "msg" : "94ee166d6d6ecf8832437136b4ae805d428864359586d9193a25016293edba443c58e07e7b7195ec5bd84582a9d56c8d4a108c7d7ce34e6c6f8ea1bec0567317",
+ "ct" : "5fbbdecc34be201614f636031eeb42f1cace3c79a12cffd871ee8e73820c829749f1abb4294367849fb6c2aa56bda8a3078f723d7c1c852024b017b58973fb1e",
+ "tag" : "09263da7b4cb921452f97dca40f580ec",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 74,
+ "comment" : "",
+ "key" : "fe6e55bdaed1f7284ca5fc0f8c5f2b8df56dc0f49e8ca66a41995e783351f901",
+ "iv" : "17c86a8abbb7e003acde2799",
+ "aad" : "",
+ "msg" : "b429eb80fb8fe8baeda0c85b9c333458e7c2992e558475069d12d45c22217564121588032297eff56783742a5fc22d7410ffb29d66098661d76f126c3c27689e43b37267cac5a3a6d3ab49e391da29cd3054a5692e2807e4c3ea46c8761d50f592",
+ "ct" : "d0102f6c258bf49742cec34cf2d0fedf23d105fb4c84cf98515e1bc9a64f8ad5be8f0721bde50645d00083c3a263a31053b760245f52ae2866a5ec83b19f61be1d30d5c5d9fecc4cbbe08fd385813a2aa39a00ff9c10f7f23702add1e4b2ffa31c",
+ "tag" : "41865fc71de12b19612127ce49993bb0",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 75,
+ "comment" : "",
+ "key" : "aabc063474e65c4c3e9bdc480dea97b45110c8618846ff6b15bdd2a4a5682c4e",
+ "iv" : "46362f45d6379e63e5229460",
+ "aad" : "a11c40b603767330",
+ "msg" : "ceb534ce50dc23ff638ace3ef63ab2cc2973eeada80785fc165d06c2f5100ff5e8ab2882c475afcd05ccd49f2e7d8f55ef3a72e3dc51d6852b8e6b9e7aece57be6556b0b6d9413e33fc5fc24a9a205ad59574bb39d944a92dc47970d84a6ad3176",
+ "ct" : "7545391b51de01d5c53dfaca777909063e58edee4bb1227e7110ac4d2620c2aec2f848f56deeb037a8dced75afa8a6c890e2dee42f950bb33d9e2424d08a505d899563973ed38870f3de6ee2adc7fe072c366c14e2cf7ca62fb3d36bee11685461",
+ "tag" : "b70d44ef8c66c5c7bbf10dcadd7facf6",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 76,
+ "comment" : "",
+ "key" : "d7addd3889fadf8c893eee14ba2b7ea5bf56b449904869615bd05d5f114cf377",
+ "iv" : "8a3ad26b28cd13ba6504e260",
+ "aad" : "",
+ "msg" : "c877a76bf595560772167c6e3bcc705305db9c6fcbeb90f4fea85116038bc53c3fa5b4b4ea0de5cc534fbe1cf9ae44824c6c2c0a5c885bd8c3cdc906f12675737e434b983e1e231a52a275db5fb1a0cac6a07b3b7dcb19482a5d3b06a9317a54826cea6b36fce452fa9b5475e2aaf25499499d8a8932a19eb987c903bd8502fe",
+ "ct" : "294a764c03353f5f4f6e93cd7e977480d6c343071db0b7c1f0db1e95b85e6053f0423168a9c7533268db9a194e7665359d14489bc47172a9f21370e89b0bd0e5ef9661738de282572bcc3e541247626e57e75dec0f91ac5c530bd1a53271842996dcd04d865321b1ecb6e7630114fe780291b8dc3e5d0abc8e65b1c5493e9af0",
+ "tag" : "f2b974ca0f14fb9f92014bff18573cff",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 77,
+ "comment" : "",
+ "key" : "80be86fb6fc49bc73428cab576f6ad72ff6aca04001b8b1c57a7128be73900aa",
+ "iv" : "903188433c1ce8971aa19b9d",
+ "aad" : "0587af8530ad0547",
+ "msg" : "67ce499cd8ed68bd717dfe61c60f27d260b1c163a72e8cc8597253d3d987c2dbe1bff2e44d9bd4765d3e53d9c3f8eb3b90e751f47c7157bdc1142bc33f5833ac1cd1262cbb239066b334a4ed99ae82c74f2b49540f1a614bc239d8fc5add8c178184e41281f6e66c5c3117fd953547f7c829425b5082aa69686847eaf5784692",
+ "ct" : "2b90b4f3de280c44913d1984bdd5dfa0566c6a14a058659a9b623277b0bb6e82101e79395d12e643f62d9a822bae497907493e4f8213fcf99da8a78fdf867af36bc8b0931c1886b4f0ae5729986494dbd59737e956cd8f226c7c522689d082f023894d54acab0c4d609f3746a67369bb8876008f7fd3dc6681c5fb9d728c5911",
+ "tag" : "f005ebe1c1ada75a9cee8d630881d5b8",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 78,
+ "comment" : "",
+ "key" : "7d00b48095adfa3272050607b264185002ba99957c498be022770f2ce2f3143c",
+ "iv" : "87345f1055fd9e2102d50656",
+ "aad" : "02",
+ "msg" : "e5ccaa441bc814688f8f6e8f28b500b2",
+ "ct" : "7e72f5a185af16a611921b438f749f0b",
+ "tag" : "1242c670732334029adfe1c5001651e4",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 79,
+ "comment" : "",
+ "key" : "6432717f1db85e41ac7836bce25185a080d5762b9e2b18444b6ec72c3bd8e4dc",
+ "iv" : "87a3163ec0598ad95b3aa713",
+ "aad" : "b648",
+ "msg" : "02cde168fba3f544bbd0332f7adeada8",
+ "ct" : "85f29a719557cdd14d1f8fffab6d9e60",
+ "tag" : "732ca32becd515a1ed353f542e999858",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 80,
+ "comment" : "",
+ "key" : "7afa0f59dfcb5ad3a76490c5c804327c8d052be737a60fa8bcbf0a2c36630a43",
+ "iv" : "25b7bdf4a6dcbf7c9a3ec2b3",
+ "aad" : "8b71ac",
+ "msg" : "623e6ba6d3166a338bfcc7af90a230c8",
+ "ct" : "d46e8265a8c6a25393dd956bb44397ad",
+ "tag" : "e28f3ad9e3ef4a3d94ee07bf538eaafb",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 81,
+ "comment" : "",
+ "key" : "2ec25b0ec7ac244224e9c7fc2fa5d3ef17809e19fd6e954158dd0d72738a4cc8",
+ "iv" : "6fb0d1417cdfff4df37db08c",
+ "aad" : "3a5ddf40",
+ "msg" : "a1c933768a6d573ebf68a99e5e18dae8",
+ "ct" : "2d3cb2d9303491e264f2904f0e0753f4",
+ "tag" : "6c1db959362d217b2322b466536bfea0",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 82,
+ "comment" : "",
+ "key" : "0a2cf52371cf9d9f95b10108fc82b4fd6110a8ba9a88a26083685ad29826891a",
+ "iv" : "2538fc67afb9eab333f83290",
+ "aad" : "9eec540bb0",
+ "msg" : "0d8c691d044a3978d790432dc71d69f8",
+ "ct" : "a988c03c71b956ff086d0470d706bd34",
+ "tag" : "b35d7cbf2beb894b0c746e0730429e15",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 83,
+ "comment" : "",
+ "key" : "307e886b38bb18b445f8a2c6d6f8932492a9cea8d041ba72eb5efdfa70d0b8d2",
+ "iv" : "a071be999151e2a1c41c81e9",
+ "aad" : "56e014d97c74",
+ "msg" : "9aba22b495cb7ec887ddaa62019aa14d",
+ "ct" : "32bf95d4c195dbaf58d9af4001c6e57d",
+ "tag" : "4393808703d67a90870578046cd8b525",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 84,
+ "comment" : "",
+ "key" : "dacd51a8a8e4d5905b4cbb947ef4013eb296889353f3c9ee35f5577b26737a51",
+ "iv" : "3fa378a1befdddd61ae68cf4",
+ "aad" : "bb5a3812f0aefd",
+ "msg" : "e148313883a77da121124d06b1c77dca",
+ "ct" : "2a207ca7e9da6b13a229604304d87eb1",
+ "tag" : "8a6b6afec87d93ec6e8dbe13d84c0f8c",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 85,
+ "comment" : "",
+ "key" : "7b5fbbb202c16108fd13066446853a850d8b34e9da40519580da446a922f9162",
+ "iv" : "aa077a5ce9161bde8d8edc40",
+ "aad" : "f94bb92c1c668a695b",
+ "msg" : "da471cd6935a0ca8307ddedc6b959962",
+ "ct" : "548a5ca0ae49211cdf30bbdcb1352d31",
+ "tag" : "204dacb98f8c8908cc5ea22bb23f901f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 86,
+ "comment" : "",
+ "key" : "1ffd101eb97531f6faa821ec4d5c5702725dd033d3b830bb760c4ef27ba983df",
+ "iv" : "598114e8cf7fbdea8ad29683",
+ "aad" : "2155627ec15a978fbcb2",
+ "msg" : "28668ca8db535c7e8eb27491ad0fb7cb",
+ "ct" : "28cedac24f14caa326c7fe401f68a87c",
+ "tag" : "2bf1b2c43d3039f8f5ce359c1102f879",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 87,
+ "comment" : "",
+ "key" : "d2d0a973d5951af352cbee57ac9dab1c284c99af3b992ce015f219506f64888d",
+ "iv" : "9acd213570ce9bb9d886c6ef",
+ "aad" : "37ad668d4d4fe889949763",
+ "msg" : "3f3f0076250352e1b6b5c12cfa12625e",
+ "ct" : "7256e856872ad3a54b34a2a6bdca8838",
+ "tag" : "3b12e4586e45223f78a6eea811efb863",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 88,
+ "comment" : "",
+ "key" : "adcc520b381382237d05a6400a7dfbcd0771b6aa9edb7966131ddef6af21f1be",
+ "iv" : "9183cdf3a8ba7397b6b2d5d5",
+ "aad" : "b334375415f6215c0bf89a9a",
+ "msg" : "958295619cf1b36f0b474663c0bc79eb",
+ "ct" : "852c141b4239a31feeda03550d70a2be",
+ "tag" : "5fc59287b92d3fcf7d66f13defb11b0d",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 89,
+ "comment" : "",
+ "key" : "bd534f7adeca466844fb3ba34658be807f15c5291ed6026860a24f179b712c89",
+ "iv" : "412c3e13ee1f7864bd15ce39",
+ "aad" : "2866afff0bcc6135dc63af88c8",
+ "msg" : "d92f8ce5d8d0ad2eb5f11af02ef63949",
+ "ct" : "89d6d089c4a255952aca11b24a01ff95",
+ "tag" : "f88fa4531204da315e7317970240ce9e",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 90,
+ "comment" : "",
+ "key" : "910ade7d324d2c9688439e1f142e0e5f9d130ff832e507fe1985e5a26452a6d0",
+ "iv" : "9be090dba93deff27adf99ee",
+ "aad" : "ea2575f123268e936c8e4c8c1bb8",
+ "msg" : "6e356094ed9d9a7053c7906c48ba3d9f",
+ "ct" : "01ffb343c757b27843d8a900a36ce39d",
+ "tag" : "a315541b7d6313c6fddf64b303d71d60",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 91,
+ "comment" : "",
+ "key" : "8e34cf73d245a1082a920b86364eb896c4946467bcb3d58929fcb36690e6394f",
+ "iv" : "6f573aa86baa492ba46596df",
+ "aad" : "bd4cd02fc7502bbdbdf6c9a3cbe8f0",
+ "msg" : "16ddd23ff53f3d23c06334487040eb47",
+ "ct" : "c1b295936d56fadac03e5f742bff73a1",
+ "tag" : "39c457dbab66382babb3b55800cda5b8",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 92,
+ "comment" : "",
+ "key" : "cb5575f5c7c45c91cf320b139fb594237560d0a3e6f865a67d4f633f2c08f016",
+ "iv" : "1a6518f02ede1da6809266d9",
+ "aad" : "89cce9fb47441d07e0245a66fe8b778b",
+ "msg" : "623b7850c321e2cf0c6fbcc8dfd1aff2",
+ "ct" : "c84c9bb7c61c1bcb17772a1c500c5095",
+ "tag" : "dbadf7a5138ca03459a2cd65831e092f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 93,
+ "comment" : "",
+ "key" : "a5569e729a69b24ba6e0ff15c4627897436824c941e9d00b2e93fddc4ba77657",
+ "iv" : "564dee49ab00d240fc1068c3",
+ "aad" : "d19f2d989095f7ab03a5fde84416e00c0e",
+ "msg" : "87b3a4d7b26d8d3203a0de1d64ef82e3",
+ "ct" : "94bc80621ed1e71b1fd2b5c3a15e3568",
+ "tag" : "333511861796978401598b963722f5b3",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 94,
+ "comment" : "",
+ "key" : "56207465b4e48e6d04630f4a42f35cfc163ab289c22a2b4784f6f9290330bee0",
+ "iv" : "df8713e87ec3dbcfad14d53e",
+ "aad" : "5e6470facd99c1d81e37cd44015fe19480a2a4d3352a4ff560c0640fdbda",
+ "msg" : "e601b38557797da2f8a4106a089d1da6",
+ "ct" : "299b5d3f3d03c087209a16e285143111",
+ "tag" : "4b454ed198de117e83ec49fa8d8508d6",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 95,
+ "comment" : "",
+ "key" : "077433022ab34d380fc192fc24c2edc6301fec6f24442f572a1087ff2e05b39a",
+ "iv" : "28adcbc74364f26dd4b3108b",
+ "aad" : "e0100eb116cdc5e22a3b9f9b4126c149595e75107f6e237c69e82960052270",
+ "msg" : "03c874eeaaa6fa9f0da62c758fb0ad04",
+ "ct" : "1e9687b35fbc8eaa1825ed3847798f76",
+ "tag" : "0788bf70fd04030ecd1c96d0bc1fcd5d",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 96,
+ "comment" : "",
+ "key" : "3937986af86dafc1ba0c4672d8abc46c207062682d9c264ab06d6c5807205130",
+ "iv" : "8df4b15a888c33286a7b7651",
+ "aad" : "ba446f6f9a0ced22450feb10737d9007fd69abc19b1d4d9049a5551e86ec2b37",
+ "msg" : "dc9e9eaf11e314182df6a4eba17aec9c",
+ "ct" : "605bbf90aeb974f6602bc778056f0dca",
+ "tag" : "38ea23d99054b46b42ffe004129d2204",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 97,
+ "comment" : "",
+ "key" : "36372abcdb78e0279646ac3d176b9674e9154eecf0d5469c651ec7e16b4c1199",
+ "iv" : "be40e5f1a11817a0a8fa8949",
+ "aad" : "d41a828d5e71829247021905402ea257dccbc3b80fcd5675056b68bb59e62e8873",
+ "msg" : "81ce84ede9b35859cc8c49a8f6be7dc6",
+ "ct" : "7b7ce0d824809a70de32562ccf2c2bbd",
+ "tag" : "15d44a00ce0d19b4231f921e22bc0a43",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 98,
+ "comment" : "",
+ "key" : "9f1479ed097d7fe529c11f2f5add9aaff4a1ca0b68997a2cb7f79749bd90aaf4",
+ "iv" : "84c87dae4eee27730ec35d12",
+ "aad" : "3f2dd49bbf09d69a78a3d80ea2566614fc379474196c1aae84583da73d7ff85c6f42ca42056a9792cc1b9fb3c7d261",
+ "msg" : "a66747c89e857af3a18e2c79500087ed",
+ "ct" : "ca82bff3e2f310ccc976672c4415e69b",
+ "tag" : "57638c62a5d85ded774f913c813ea032",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 99,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "00000000000000000000000000000000",
+ "msg" : "65b63bf074b7283992e24b1ac0df0d22b555dbe2254d94a43f1de748d3cc6f0d",
+ "ct" : "0000000000000000000000000000000000000000000000000000000000000000",
+ "tag" : "39f4fce3026d83789ffd1ee6f2cd7c4f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 100,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "00000000000000000000000000000000",
+ "msg" : "65b63bf074b7283992e24b1ac0df0d22b555dbe2254d94a43f1de748d3cc6f0d20c142fe898fbbe668d4324394434c1b18b58ead710aed9c31db1f2a8a1f1bb2",
+ "ct" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "tag" : "f5eaa804605c3a4785f9d7f13b6f67d6",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 101,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "00000000000000000000000000000000",
+ "msg" : "65b63bf074b7283992e24b1ac0df0d22b555dbe2254d94a43f1de748d3cc6f0d20c142fe898fbbe668d4324394434c1b18b58ead710aed9c31db1f2a8a1f1bb24405c183af94ee1ad630cd931158a6213d48c8fff10d0a1f9ef760188e658802aad55e41a1d99069a18db55c56af7c10a6f21ecc8af9b7ce0a7ea0b67426e925",
+ "ct" : "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
+ "tag" : "9b5c43a78d954e8a3c659eebc13d5d55",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 102,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "ffffffffffffffffffffffffffffffff",
+ "msg" : "9a49c40f8b48d7c66d1db4e53f20f2dd4aaa241ddab26b5bc0e218b72c3390f2",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "37e3399d9ca696799f08f4f72bc0cdd8",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 103,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "ffffffffffffffffffffffffffffffff",
+ "msg" : "9a49c40f8b48d7c66d1db4e53f20f2dd4aaa241ddab26b5bc0e218b72c3390f2df3ebd0176704419972bcdbc6bbcb3e4e74a71528ef51263ce24e0d575e0e44d",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "3d52710bec86d4ea9fea2ff269549191",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 104,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "ffffffffffffffffffffffffffffffff",
+ "msg" : "9a49c40f8b48d7c66d1db4e53f20f2dd4aaa241ddab26b5bc0e218b72c3390f2df3ebd0176704419972bcdbc6bbcb3e4e74a71528ef51263ce24e0d575e0e44dbbfa3e7c506b11e529cf326ceea759dec2b737000ef2f5e061089fe7719a77fd552aa1be5e266f965e724aa3a95083ef590de13375064831f5815f498bd916da",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "51356329e280b12d55d3d98f0a580cbe",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 105,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "00000080000000800000008000000080",
+ "msg" : "65b63b7074b728b992e24b9ac0df0da2b555db62254d94243f1de7c8d3cc6f8d",
+ "ct" : "0000008000000080000000800000008000000080000000800000008000000080",
+ "tag" : "c152a4b90c548c71dc479edeaf9211bf",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 106,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "00000080000000800000008000000080",
+ "msg" : "65b63b7074b728b992e24b9ac0df0da2b555db62254d94243f1de7c8d3cc6f8d20c1427e898fbb6668d432c394434c9b18b58e2d710aed1c31db1faa8a1f1b32",
+ "ct" : "00000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080",
+ "tag" : "40ef6383052d91c2e4b4611b0e32c5ff",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 107,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "00000080000000800000008000000080",
+ "msg" : "65b63b7074b728b992e24b9ac0df0da2b555db62254d94243f1de7c8d3cc6f8d20c1427e898fbb6668d432c394434c9b18b58e2d710aed1c31db1faa8a1f1b324405c103af94ee9ad630cd131158a6a13d48c87ff10d0a9f9ef760988e658882aad55ec1a1d990e9a18db5dc56af7c90a6f21e4c8af9b74e0a7ea0367426e9a5",
+ "ct" : "0000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080",
+ "tag" : "ae9b542541e84fc74542eed6be638fee",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 108,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "80000000800000008000000080000000",
+ "msg" : "e5b63bf0f4b7283912e24b1a40df0d223555dbe2a54d94a4bf1de74853cc6f0d",
+ "ct" : "8000000080000000800000008000000080000000800000008000000080000000",
+ "tag" : "10fee3ecfba9cdf797bae37a626ec83b",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 109,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "80000000800000008000000080000000",
+ "msg" : "e5b63bf0f4b7283912e24b1a40df0d223555dbe2a54d94a4bf1de74853cc6f0da0c142fe098fbbe6e8d4324314434c1b98b58eadf10aed9cb1db1f2a0a1f1bb2",
+ "ct" : "80000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000",
+ "tag" : "7490795bdbbbf5d0aecb9a4f65aa379f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 110,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "80000000800000008000000080000000",
+ "msg" : "e5b63bf0f4b7283912e24b1a40df0d223555dbe2a54d94a4bf1de74853cc6f0da0c142fe098fbbe6e8d4324314434c1b98b58eadf10aed9cb1db1f2a0a1f1bb2c405c1832f94ee1a5630cd939158a621bd48c8ff710d0a1f1ef760180e6588022ad55e4121d99069218db55cd6af7c1026f21ecc0af9b7ce8a7ea0b6f426e925",
+ "ct" : "8000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000800000008000000080000000",
+ "tag" : "1d1096a8ca9e2bda2762c41d5b16f62f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 111,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "ffffff7fffffff7fffffff7fffffff7f",
+ "msg" : "9a49c48f8b48d7466d1db4653f20f25d4aaa249ddab26bdbc0e218372c339072",
+ "ct" : "ffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7f",
+ "tag" : "af8492c792bf8d8062be74ff6efb3869",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 112,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "ffffff7fffffff7fffffff7fffffff7f",
+ "msg" : "9a49c48f8b48d7466d1db4653f20f25d4aaa249ddab26bdbc0e218372c339072df3ebd8176704499972bcd3c6bbcb364e74a71d28ef512e3ce24e05575e0e4cd",
+ "ct" : "ffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7f",
+ "tag" : "f24db68c46b67d6f402fa6c897913368",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 113,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "ffffff7fffffff7fffffff7fffffff7f",
+ "msg" : "9a49c48f8b48d7466d1db4653f20f25d4aaa249ddab26bdbc0e218372c339072df3ebd8176704499972bcd3c6bbcb364e74a71d28ef512e3ce24e05575e0e4cdbbfa3efc506b116529cf32eceea7595ec2b737800ef2f56061089f67719a777d552aa13e5e266f165e724a23a950836f590de1b3750648b1f5815fc98bd9165a",
+ "ct" : "ffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7f",
+ "tag" : "43f651ab2e2eb0f04bf689a40d32da24",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 114,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "7fffffff7fffffff7fffffff7fffffff",
+ "msg" : "1a49c40f0b48d7c6ed1db4e5bf20f2ddcaaa241d5ab26b5b40e218b7ac3390f2",
+ "ct" : "7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff",
+ "tag" : "60d95294a3694cfaa64b2f63bc1f82ec",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 115,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "7fffffff7fffffff7fffffff7fffffff",
+ "msg" : "1a49c40f0b48d7c6ed1db4e5bf20f2ddcaaa241d5ab26b5b40e218b7ac3390f25f3ebd01f6704419172bcdbcebbcb3e4674a71520ef512634e24e0d5f5e0e44d",
+ "ct" : "7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff",
+ "tag" : "beaca0b47027196176186d944019c1c8",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 116,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "7fffffff7fffffff7fffffff7fffffff",
+ "msg" : "1a49c40f0b48d7c6ed1db4e5bf20f2ddcaaa241d5ab26b5b40e218b7ac3390f25f3ebd01f6704419172bcdbcebbcb3e4674a71520ef512634e24e0d5f5e0e44d3bfa3e7cd06b11e5a9cf326c6ea759de42b737008ef2f5e0e1089fe7f19a77fdd52aa1bede266f96de724aa3295083efd90de133f506483175815f490bd916da",
+ "ct" : "7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff",
+ "tag" : "d4811028a577d4dd69d6b35d717f73e3",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 117,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "00000000ffffffff00000000ffffffff",
+ "msg" : "65b63bf08b48d7c692e24b1a3f20f2ddb555dbe2dab26b5b3f1de7482c3390f2",
+ "ct" : "00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff",
+ "tag" : "10fb61272b555bee104f5a71818716d6",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 118,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "00000000ffffffff00000000ffffffff",
+ "msg" : "65b63bf08b48d7c692e24b1a3f20f2ddb555dbe2dab26b5b3f1de7482c3390f220c142fe7670441968d432436bbcb3e418b58ead8ef5126331db1f2a75e0e44d",
+ "ct" : "00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff",
+ "tag" : "4756764e59583504182877d8c33120f0",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 119,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "00000000ffffffff00000000ffffffff",
+ "msg" : "65b63bf08b48d7c692e24b1a3f20f2ddb555dbe2dab26b5b3f1de7482c3390f220c142fe7670441968d432436bbcb3e418b58ead8ef5126331db1f2a75e0e44d4405c183506b11e5d630cd93eea759de3d48c8ff0ef2f5e09ef76018719a77fdaad55e415e266f96a18db55ca95083efa6f21ecc750648310a7ea0b68bd916da",
+ "ct" : "00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff",
+ "tag" : "95a2b12a4a280089d4bd4f904253e754",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 120,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "ffffffff00000000ffffffff00000000",
+ "msg" : "9a49c40f74b728396d1db4e5c0df0d224aaa241d254d94a4c0e218b7d3cc6f0d",
+ "ct" : "ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000",
+ "tag" : "60dcd45974bebe032eb7b86c9d063452",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 121,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "ffffffff00000000ffffffff00000000",
+ "msg" : "9a49c40f74b728396d1db4e5c0df0d224aaa241d254d94a4c0e218b7d3cc6f0ddf3ebd01898fbbe6972bcdbc94434c1be74a7152710aed9cce24e0d58a1f1bb2",
+ "ct" : "ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000",
+ "tag" : "f0e6a3c1f28ad92d0dbc900be291d877",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 122,
+ "comment" : "",
+ "key" : "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "ffffffff00000000ffffffff00000000",
+ "msg" : "9a49c40f74b728396d1db4e5c0df0d224aaa241d254d94a4c0e218b7d3cc6f0ddf3ebd01898fbbe6972bcdbc94434c1be74a7152710aed9cce24e0d58a1f1bb2bbfa3e7caf94ee1a29cf326c1158a621c2b73700f10d0a1f61089fe78e658802552aa1bea1d990695e724aa356af7c10590de1338af9b7cef5815f497426e925",
+ "ct" : "ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000",
+ "tag" : "57eff4a525eeff2ebd7a28eb894282be",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 123,
+ "comment" : "Flipped bit 0 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f5409bb729039d0814ac514054323f44",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 124,
+ "comment" : "Flipped bit 1 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f6409bb729039d0814ac514054323f44",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 125,
+ "comment" : "Flipped bit 7 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "74409bb729039d0814ac514054323f44",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 126,
+ "comment" : "Flipped bit 8 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f4419bb729039d0814ac514054323f44",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 127,
+ "comment" : "Flipped bit 31 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f4409b3729039d0814ac514054323f44",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 128,
+ "comment" : "Flipped bit 32 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f4409bb728039d0814ac514054323f44",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 129,
+ "comment" : "Flipped bit 33 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f4409bb72b039d0814ac514054323f44",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 130,
+ "comment" : "Flipped bit 63 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f4409bb729039d8814ac514054323f44",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 131,
+ "comment" : "Flipped bit 64 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f4409bb729039d0815ac514054323f44",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 132,
+ "comment" : "Flipped bit 77 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f4409bb729039d08148c514054323f44",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 133,
+ "comment" : "Flipped bit 80 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f4409bb729039d0814ac504054323f44",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 134,
+ "comment" : "Flipped bit 96 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f4409bb729039d0814ac514055323f44",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 135,
+ "comment" : "Flipped bit 97 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f4409bb729039d0814ac514056323f44",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 136,
+ "comment" : "Flipped bit 120 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f4409bb729039d0814ac514054323f45",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 137,
+ "comment" : "Flipped bit 121 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f4409bb729039d0814ac514054323f46",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 138,
+ "comment" : "Flipped bit 126 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f4409bb729039d0814ac514054323f04",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 139,
+ "comment" : "Flipped bit 127 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f4409bb729039d0814ac514054323fc4",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 140,
+ "comment" : "Flipped bit 63 and 127 in tag expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "f4409bb729039d8814ac514054323fc4",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 141,
+ "comment" : "Tag changed to all zero expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "00000000000000000000000000000000",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 142,
+ "comment" : "tag change to all 1 expected tag:f4409bb729039d0814ac514054323f44",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "ffffffffffffffffffffffffffffffff",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 143,
+ "comment" : "Flipped bit 0 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "28914007a6119dd3f109bba21ce9a7d6",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 144,
+ "comment" : "Flipped bit 1 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "2b914007a6119dd3f109bba21ce9a7d6",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 145,
+ "comment" : "Flipped bit 7 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "a9914007a6119dd3f109bba21ce9a7d6",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 146,
+ "comment" : "Flipped bit 8 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "29904007a6119dd3f109bba21ce9a7d6",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 147,
+ "comment" : "Flipped bit 31 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "29914087a6119dd3f109bba21ce9a7d6",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 148,
+ "comment" : "Flipped bit 32 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "29914007a7119dd3f109bba21ce9a7d6",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 149,
+ "comment" : "Flipped bit 33 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "29914007a4119dd3f109bba21ce9a7d6",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 150,
+ "comment" : "Flipped bit 63 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "29914007a6119d53f109bba21ce9a7d6",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 151,
+ "comment" : "Flipped bit 64 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "29914007a6119dd3f009bba21ce9a7d6",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 152,
+ "comment" : "Flipped bit 77 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "29914007a6119dd3f129bba21ce9a7d6",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 153,
+ "comment" : "Flipped bit 80 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "29914007a6119dd3f109baa21ce9a7d6",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 154,
+ "comment" : "Flipped bit 96 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "29914007a6119dd3f109bba21de9a7d6",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 155,
+ "comment" : "Flipped bit 97 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "29914007a6119dd3f109bba21ee9a7d6",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 156,
+ "comment" : "Flipped bit 120 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "29914007a6119dd3f109bba21ce9a7d7",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 157,
+ "comment" : "Flipped bit 121 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "29914007a6119dd3f109bba21ce9a7d4",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 158,
+ "comment" : "Flipped bit 126 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "29914007a6119dd3f109bba21ce9a796",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 159,
+ "comment" : "Flipped bit 127 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "29914007a6119dd3f109bba21ce9a756",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 160,
+ "comment" : "Flipped bit 63 and 127 in tag expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "29914007a6119d53f109bba21ce9a756",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 161,
+ "comment" : "Tag changed to all zero expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "00000000000000000000000000000000",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 162,
+ "comment" : "tag change to all 1 expected tag:29914007a6119dd3f109bba21ce9a7d6",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995a",
+ "tag" : "ffffffffffffffffffffffffffffffff",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 163,
+ "comment" : "Flipped bit 0 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "67405a16e8b44eba92aa47f5cea52b7a",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 164,
+ "comment" : "Flipped bit 1 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "64405a16e8b44eba92aa47f5cea52b7a",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 165,
+ "comment" : "Flipped bit 7 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "e6405a16e8b44eba92aa47f5cea52b7a",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 166,
+ "comment" : "Flipped bit 8 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "66415a16e8b44eba92aa47f5cea52b7a",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 167,
+ "comment" : "Flipped bit 31 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "66405a96e8b44eba92aa47f5cea52b7a",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 168,
+ "comment" : "Flipped bit 32 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "66405a16e9b44eba92aa47f5cea52b7a",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 169,
+ "comment" : "Flipped bit 33 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "66405a16eab44eba92aa47f5cea52b7a",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 170,
+ "comment" : "Flipped bit 63 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "66405a16e8b44e3a92aa47f5cea52b7a",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 171,
+ "comment" : "Flipped bit 64 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "66405a16e8b44eba93aa47f5cea52b7a",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 172,
+ "comment" : "Flipped bit 77 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "66405a16e8b44eba928a47f5cea52b7a",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 173,
+ "comment" : "Flipped bit 80 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "66405a16e8b44eba92aa46f5cea52b7a",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 174,
+ "comment" : "Flipped bit 96 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "66405a16e8b44eba92aa47f5cfa52b7a",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 175,
+ "comment" : "Flipped bit 97 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "66405a16e8b44eba92aa47f5cca52b7a",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 176,
+ "comment" : "Flipped bit 120 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "66405a16e8b44eba92aa47f5cea52b7b",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 177,
+ "comment" : "Flipped bit 121 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "66405a16e8b44eba92aa47f5cea52b78",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 178,
+ "comment" : "Flipped bit 126 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "66405a16e8b44eba92aa47f5cea52b3a",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 179,
+ "comment" : "Flipped bit 127 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "66405a16e8b44eba92aa47f5cea52bfa",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 180,
+ "comment" : "Flipped bit 63 and 127 in tag expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "66405a16e8b44e3a92aa47f5cea52bfa",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 181,
+ "comment" : "Tag changed to all zero expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "00000000000000000000000000000000",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 182,
+ "comment" : "tag change to all 1 expected tag:66405a16e8b44eba92aa47f5cea52b7a",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "000102",
+ "msg" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20",
+ "ct" : "d03bcb3ca52d48d1d203b1e7b1a5995af1a0466a61bb386a2e12d189a2c4ea15e9",
+ "tag" : "ffffffffffffffffffffffffffffffff",
+ "result" : "invalid",
+ "flags" : []
+ },
+ {
+ "tcId" : 183,
+ "comment" : "edge case for poly1305 key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "dc8ce708bf26aab862d97e1b42f31ef38c382cf07174142ea564920612997b1c2e38aca2438b588d5459493e97e7fa330ff9bc3b9458297ba0967d86ed090b435103478f2869b93ee29c837e95fb6b9903f3b735b7345428eb93b3db1d9b5187cebb889aa177d83e4f63fc9a5c0596eed939883d06aacdfdea44fdecdf5cb7fc",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "c296436246c3a7c4b3ba09ab2a6a0889",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 184,
+ "comment" : "edge case for poly1305 key:278de313ffffffdfffe9acbf3ea59357c4e16a5bc120d346af4a8cf694a84374",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "0001020304050607051e9373",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "931227274a89d0b3aade7fac62c96262c1e77b8dafd248f10ad37c6ccb69cb7131b041593c8bb8c3db38f39dd8a124c424fce4389dede1d3cb9d46cf95970aea9856b6e313d756197baf4fcb58df275bca8a2188f9e8a1ad04354ede542ddc30e8b735b2f5905f5811799282be94ae842ec126c55d2e667235e9acf1d48798f0",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "99a3b0fff6fdcbcce9dc5820f2a64861",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 185,
+ "comment" : "edge case for poly1305 key:0050799fe9e74fcffcffffcfd21aa8b5cb5aa2c6ab347b6886eedaca4bfff3c0",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "0001020304050607048c3c5f",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "0df91f31230e8941e700a752fef08c897c511ed618fdf8a378a1f439013b40a48d4634c27d9ada7c0bb6f3fa92e341425903d7ecd0c49bee4c77e84b11f1c721922308642885b813fae364da32eaf120d6a43a74fb1632443667bfea6eef1be73eb1c3c0b5a57cee8dc4feed4a1fb9ae02f7b1695588c3c878451cb6ee0cb3dc",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "eaff8f47ef9268fd0d94e8a9c4b78d24",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 186,
+ "comment" : "edge case for poly1305 key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "1fde9b9ec8b247d42bbee2016d6715ba428a85431430eada56a2c5dc944b6aa6cef0b056a2eecc51d30838e640615e1458e0943e30f91ba41b4362fa9ed6037b21d14da7b4f76f9f68fa8903138d563ce2590af1201c7cfec2290cfce98a822ebb8d1ed9dc4e20d241755aff91cdfd10fdb69efa0d5c8082692601cbfbb955c7",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "86ed21fda080a7d13981078d86b3e3cd",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 187,
+ "comment" : "edge case for poly1305 key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "66115e67ecd3d4178c4c60e713ab4e5e66f8d1f971da17437a2b5e04fbca1671e847139a5f4e3f8e92d7a3b71eb4ff0e50354c0c1580af3662d5f8151e3f7e8264a0085c32ddfcbeb01a8be4c34d53319800ac4ef9d4e4014524bc7cd3387242e774f4d1a7a0521e42ec44844d0bd8b9d73fec959212fd7e8eacf4d984996d9b",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "34f9e0faa515eee0e784e6ef2678befa",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 188,
+ "comment" : "edge case for poly1305 key:0000003059ffce96438a246ff9536787d92bc40eafa0241a2972780ef6ca1ef8",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060726c6961b",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "e97244259af5a379238da0cad2a5f493655ec0e5024fd553bbb3deb66a94036d106c3d513407b2dd1cc5936c4c9c1e4f4b37b54dec261c601dc99e90680e23e2dc5c9a8d503d8bea49a8cdca3706bfd2a3daa0afb19a70fd3d355fc37c13f3f9e5c8d0864a5f80a780b36d4698ec2ce9ccc27b97ecbe672e41628ebd773acb81",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "3c94b9fe60bdb35c6b7b73b765083492",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 189,
+ "comment" : "edge case for poly1305 key:3fa0ea9c030000a036217d42e775ad189b96e24ee591952e2922ff151334b9ec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "0001020304050607013da060",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "9453aa159c3d87f17e21e88adabc37e553b904d00eefc66b8e0905e23576fbdc9c7bea9777f3b8368481932534b3344d309e6307cddfe7b3549300dd9cda7efe9d43c8a115912a392904079ee92bcd33099f7022ea94c1e7353b89bfc54de3ceb56f529a1a608bb5a970e1359609d1f56806b37f8605f4c27451da6066fc557a",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "2b11cf9f8db8490d409fc62afd7379f3",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 190,
+ "comment" : "edge case for poly1305 key:a556cb502baf395b020000f03c5108fb1cf76df1b8a8f724e877bd3c588d3285",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060707db33de",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "2e1836640d810c2709fb83ccf1aef3a971085d1bbfb58a425abf75ccec70b3abde0e80539e83a82546e7372a19481547053308dd7842675e9c4f61302426da0d71c1da3102031030ed928152be009b15b52f71b5911991d39f68a8658d99729df2bbef31c8989f9604558df9f2aba4b3766c58aaef3548de545ec1f080225a88",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "c9c8366920f88381407712cec61e6607",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 191,
+ "comment" : "edge case for poly1305 key:0c327fbcc564555545d4fe75020000d0a65799f363ec51b1c5c427b4a04af190",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060702a11942",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "0ecb4d85c956b5268c9b35a8c63b4e9d3e5cb72b64ef98773841b947bd7d59ef7d0eb0e1c050d49a5424ce7deb527d76087e4746674c958965df32d9e5fb03b46501706128d481217aaeae2f78f9259273358a2954cac0bc2fbfe77447d1d387b9314c6541b69f1270b3438b1042b2b4663e62ba4d49c07ac6f163034afa80af",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "2373cfa2ab24446ad5a236167b8027fe",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 192,
+ "comment" : "edge case for poly1305 key:415f08302f210340240d0e903e2b01205ba43e106aebd7e2481016b31118b1ae",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506073c0df637",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "2e8e45e903bfab32f2f0d49d9a3e449bef6f4093e2722cdab2cf935c1822b830fb5a4056516d560dfc8638c9a57d2927200a56f0b67153271d498e8f08dc888c61ef634f7ae40f4608f96f92fea5a1e5bd45131120098dc5de0378e58f2ddb46fa4aa5adb38fe006bb19b69146382f77a79e06214def547cfb5ce37a7008b9b6",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "5f93946478d8081e7247f414ad39a515",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 193,
+ "comment" : "edge case for poly1305 key:feffff1ff6b87403fd6435b09775bc92491a0ae62c5842a30e3b82710cc2dad1",
+ "key" : "9de836aa579585081f330a7c4036e20e38ef15eff3945184d231867f505fffdf",
+ "iv" : "00000000101112130bc672c3",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "3619cb470af86dceceb6940f2d9abb34c9a9131476053387445ffebbe240d4f9818377855652f46a8219c7f71c3554f8acef8258de4b7d17c0f3d353ac981cc6a13287be1e6b41dc6d133df4ababebdf43d665ce7a4a5c982a0b139cb8202eebc74173e3224a440e4c37d2b595f384290e939ba016df0d49b36cdb4bd91c39",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "133fe62391744d11ce44594b96c53baf",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 194,
+ "comment" : "edge case for poly1305 key:bf358f18ffffffbf4b62ed6e1f53790785c4dabdfc72e2a219d377a682c85f38",
+ "key" : "9de836aa579585081f330a7c4036e20e38ef15eff3945184d231867f505fffdf",
+ "iv" : "000000001011121303e9b9a4",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "af205bda819f7451be0f28667d4b01b59ff2daa8173cab52046c3c9e0d989889c5e021ef7afd06e9ce6cc30e3a6ebab509134ba10d10e570c55587c13eee53e73be54804c8539ffbf23b35922b1ca37b9e9bc24ee204837ca5a294ce05d12600c7eff6aee32270db2feff47dc5a04176169e15850628e6035f78994f9f5603",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "e3451adb9d23a7710a1aafba26f56387",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 195,
+ "comment" : "edge case for poly1305 key:d0b7b3a352a4010ffeffffbfe8cc66dc6e5e7451dc61762c5753174fed88e746",
+ "key" : "9de836aa579585081f330a7c4036e20e38ef15eff3945184d231867f505fffdf",
+ "iv" : "00000000101112130700b982",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "68c67272036fb652a0182eeb4781358e4704a4a702fd731bf3b3ea994717989e7d9104e0ae81732a8c7e9a82b3d31d541761a366b67c3396f1a6c67e293ddb65a59e42541dda144dc6c78388cfca982e23350958ac5b3d54a1722fd64733577862e1879c9e9445ebdec5315d1706db7ebbedd4c779935e72057e5b0ecde081",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "b0bb8a55ff5f52a5043c6e7795847557",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 196,
+ "comment" : "edge case for poly1305 key:7bee33931a4157a8cb701becfeffff4fbe7e69f19cd065313bb49a252628dd3d",
+ "key" : "9de836aa579585081f330a7c4036e20e38ef15eff3945184d231867f505fffdf",
+ "iv" : "0000000010111213019836bb",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "c483b7334ebe2e879b0c3f9db4fcd9f5219062360d6ce44cdae0f94e04c8345ea7e3ae33855118741dcafe0de4ae98c4e43af7b12b04ee8ab175625823ac040e5abac4403f1d45238adcb8c0cf44bd56917f9f5d93974c82b56951986a9c0450bd9047b5a616e814526ad0580e3ecd8189c9fef2cdb979a22ad3a01930fbd1",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "f4fc25f4c5543a9afee9819e2904fb68",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 197,
+ "comment" : "edge case for poly1305 key:7cb5fbdffb40ff5f3c7de74f655ffc1fac03013a7fe468440b861ebe0ab1650a",
+ "key" : "9de836aa579585081f330a7c4036e20e38ef15eff3945184d231867f505fffdf",
+ "iv" : "00000000101112131d59f288",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "bc7f4f15fd1e4c1399740836670abe39a05707be19956ce169b32321759e0f213ae19ad34aa612b3a29f02c4bbac9f785a55a3adfe419ab891bbe0acee9921322ea21002c9dd3dcdd13a7f8554dddc10f9b529ce94be7050937dab76557b7eb17c685aad8f0797e39d62553988989aab1d9764fe431cc1d4c595062ce93ce9",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "5e67a7b8733e0e4b01ac2178a205ae7e",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 198,
+ "comment" : "edge case for poly1305 key:00000090e6e328c242cde5c83e3d8262d467f2bcd53d3755c781f3c6a2cb0648",
+ "key" : "9de836aa579585081f330a7c4036e20e38ef15eff3945184d231867f505fffdf",
+ "iv" : "00000000101112130552a411",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "eaccaa778935ef249e0900149dd889462d2a061486ba102b8caebe465f3959fb3119ebb5689676ffdd6d851a26739e772b54a2f5f473ea9c7e58ccbc4cfc953e8c420b2175d9dd519265630bb79bd87a601b113231a8b16ce54c331347ec04c2b1c9160f38207aa46e96feb06dee883eb422fa14908df300bb1a1ef758c408",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "177a77fce114a4349c4f8d5ec825d06f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 199,
+ "comment" : "edge case for poly1305 key:9e98d64e000000505a07183c5c68c63c14c9266dd37ff86aafc22ddbdb355617",
+ "key" : "9de836aa579585081f330a7c4036e20e38ef15eff3945184d231867f505fffdf",
+ "iv" : "00000000101112130c807a72",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "a76c330e015060a17e64cb7b6d753f201f75be8759fd7539fb92b22aef54c9d3029dba0c15cbf7c95135888319c6b2e6276da21e0c351fd522b29aabb5883a3291d6f427de773b124390ef6fd96621ffbc42dfbf7a34da272cbc9ccb1a498d078033d1ac3bf7e92715948b06d69d5c5039e9164ba9c3a02219ec5908206b3b",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "623c7d4424f5497aedfd1339cf8cecce",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 200,
+ "comment" : "edge case for poly1305 key:1048a92e65f5e63102000080d9ae08de4319a7c45fdbe707b9ec1b7e0d635161",
+ "key" : "9de836aa579585081f330a7c4036e20e38ef15eff3945184d231867f505fffdf",
+ "iv" : "00000000101112130397a143",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "228a7e15bcce13051de9145f77f7f4ff7921828b4f99efc4ff55ee0d9344955b69ec2d4798b0517f0273c4456ae5ffc5929cbe74ddb0da51d4f2b4df7578a31240c88ae922c3c5eca7b97d72d497062050a587447c562b343d5c71921944872f9fd06b8f34b3eb5d4341f5ff8a907dd7c2e1676b81252726ba54814da51eab",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "1c18b69354b189731a1a83fe8f0d57c9",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 201,
+ "comment" : "edge case for poly1305 key:01517a2ceb89bbfb5741f7d9000000401a65b132ad661072a00ffe7defbb18a5",
+ "key" : "9de836aa579585081f330a7c4036e20e38ef15eff3945184d231867f505fffdf",
+ "iv" : "000000001011121308cb0f3f",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "c7d843188ab193dfef5c4daf583f952cd4b195f240fa2e704d021723023c123371a41e87dfc6e6c3874a42f331cf035988a38c72ba2da854b1208f98bf8cc29948169481ab3a402d5fcc7ff78f9e31925576dc3938074b8c5b27960e3afc750ad686563688b7441787288d5256c1301d563b7744843bd1ab4eff5be6f1653d",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "2045815b8211b9a2995effe0b8ed9868",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 202,
+ "comment" : "edge case for poly1305 key:bc90156087e0125006d90c30babd0590427bff19de1f2e7d0757a79528731138",
+ "key" : "9de836aa579585081f330a7c4036e20e38ef15eff3945184d231867f505fffdf",
+ "iv" : "00000000101112130d8fcf4e",
+ "aad" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "msg" : "cfc3db8631c81c69023a3c8a9ad66c35053685144c4fa2a9510add72e211dad9ca5b982e4c194591fdb74116280311d1299ad81227258cb52f079bbcb12aff161d278dec33a326d71276b3de01a8327ee7f45f94179dff18a3fe643e56c30cfd03871c8110ab00f6612b9e17a4647360d7847bb63a3122613c2e7cdddd08ae",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "1ae2ed84ea9774d78d782bf8d972a8b8",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 203,
+ "comment" : "edge case for tag",
+ "key" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "ffffffffffffffffffffffffffffffff415771fda4fbcc55c377f73203e60226",
+ "msg" : "e48caf8a76183327c9561a4651c07c822ccd1642c06607d0d4bc0afb4de15915dbfa3b0b422e77e15c64bf6247031f15fdb643117809821870000adf83834da5",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "000102030405060708090a0b0c0d0e0f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 204,
+ "comment" : "edge case for tag",
+ "key" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "f1ffffffffffffffffffffffffffffff615af39eddb5fcd2519190d5507d3b06",
+ "msg" : "e48caf8a76183327c9561a4651c07c822ccd1642c06607d0d4bc0afb4de15915dbfa3b0b422e77e15c64bf6247031f15fdb643117809821870000adf83834da5",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "00000000000000000000000000000000",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 205,
+ "comment" : "edge case for tag",
+ "key" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "b5ffffffffffffffffffffffffffffff764e5d82ce7da0d44148484fd96a6107",
+ "msg" : "e48caf8a76183327c9561a4651c07c822ccd1642c06607d0d4bc0afb4de15915dbfa3b0b422e77e15c64bf6247031f15fdb643117809821870000adf83834da5",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "ffffffffffffffffffffffffffffffff",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 206,
+ "comment" : "edge case for tag",
+ "key" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "fdffffffffffffffffffffffffffffff2bdbf16d8ea4d39dab8dcb3d4bc4e104",
+ "msg" : "e48caf8a76183327c9561a4651c07c822ccd1642c06607d0d4bc0afb4de15915dbfa3b0b422e77e15c64bf6247031f15fdb643117809821870000adf83834da5",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "00000080000000800000008000000080",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 207,
+ "comment" : "edge case for tag",
+ "key" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "a9ffffffffffffffffffffffffffffffaccd5eb31d8fc909e84b0de7de23bb08",
+ "msg" : "e48caf8a76183327c9561a4651c07c822ccd1642c06607d0d4bc0afb4de15915dbfa3b0b422e77e15c64bf6247031f15fdb643117809821870000adf83834da5",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "ffffff7fffffff7fffffff7fffffff7f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 208,
+ "comment" : "edge case for tag",
+ "key" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "d2ffffffffffffffffffffffffffffffdd4b933e7b1a7ed93cc7c050db71dc03",
+ "msg" : "e48caf8a76183327c9561a4651c07c822ccd1642c06607d0d4bc0afb4de15915dbfa3b0b422e77e15c64bf6247031f15fdb643117809821870000adf83834da5",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "01000000010000000100000001000000",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 209,
+ "comment" : "edge case for tag",
+ "key" : "404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f",
+ "iv" : "000102030405060708090a0b",
+ "aad" : "ffffffffffffffffffffffffffffffffa08164425d7642e9e90fc8d5c32d2cf6",
+ "msg" : "e48caf8a76183327c9561a4651c07c822ccd1642c06607d0d4bc0afb4de15915dbfa3b0b422e77e15c64bf6247031f15fdb643117809821870000adf83834da5",
+ "ct" : "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+ "tag" : "ffffffff000000000000000000000000",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 210,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "c68ce708bf26aab862d97e1b42f31ef37bb66f8090c149e452ec7f20327eb2ea2e38aca2438b588d5459493e97e7fa330ff9bc23c897df6b00af86931d6c81555103478f2869b93ee29c837e95fb6b9903f3b72debfba2384baa48ceedfedb91",
+ "ct" : "e5ffffffffffffffffffffffffffffff0871bc8f1e4aa235087712d9df183609ffffffffffffffffffffffffffffffffffffffe7a33009ef5fc604ea0f9a75e9ffffffffffffffffffffffffffffffffffffffe7a33009ef5fc604ea0f9a75e9",
+ "tag" : "3572162777262c518eef573b720e8e64",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 211,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "c78ce708bf26aab862d97e1b42f31ef376209eef141691fba5d10eaf581affe62e38aca2438b588d5459493e97e7fa330e73d2dc3bbd954989cb8433b7d6597b5103478f2869b93ee29c837e95fb6b990279d9d218d1e81ac2ce4a6e474403bf",
+ "ct" : "e4ffffffffffffffffffffffffffffff05e74de09a9d7a2aff4a6356b57c7b05fffffffffffffffffffffffffffffffffe759118501a43cdd6a2064aa520adc7fffffffffffffffffffffffffffffffffe759118501a43cdd6a2064aa520adc7",
+ "tag" : "347216375f5b7b5c4e6bff4912fd9473",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 212,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "fc8ce708bf26aab862d97e1b42f31ef38b79403dfaabc0d8c18d23a3469c13e62e38aca2438b588d5459493e97e7fa330a4b941e6b66fcc2ed7d8cb3e8cc7ffc5103478f2869b93ee29c837e95fb6b9906419f10480a8191a67842ee185e2538",
+ "ct" : "dffffffffffffffffffffffffffffffff8be933274202b099b164e5aabfa9705fffffffffffffffffffffffffffffffffa4dd7da00c12a46b2140ecafa3a8b40fffffffffffffffffffffffffffffffffa4dd7da00c12a46b2140ecafa3a8b40",
+ "tag" : "30721677ff2eb8894e5a9d8492b7b0af",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 213,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "fa8ce708bf26aab862d97e1b42f31ef39bcbb8da477d580d772de4229bba7de22938aca2438b588d5459493e97e7fa331e9dedf9dd64a0681bac2969549425bc5603478f2869b93ee29c837e95fb6b991297e6f7fe08dd3b50a9e734a4067f78",
+ "ct" : "d9ffffffffffffffffffffffffffffffe80c6bd5c9f6b3dc2db689db76dcf901f8ffffffffffffffffffffffffffffffee9bae3db6c376ec44c5ab104662d100f8ffffffffffffffffffffffffffffffee9bae3db6c376ec44c5ab104662d100",
+ "tag" : "2b7216c7873744c20ec5e2cdb260d3fa",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 214,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "ee8ce708bf26aab862d97e1b42f31ef3b9f55bd56e0fd74b46063a96354cfbee3238aca2438b588d5459493e97e7fa3320c78886a6f6292d6cc5fbddb546a2b04d03478f2869b93ee29c837e95fb6b992ccd8388859a547e27c0358045d4f874",
+ "ct" : "cdffffffffffffffffffffffffffffffca3288dae0843c9a1c9d576fd82a7f0de3ffffffffffffffffffffffffffffffd0c1cb42cd51ffa933ac79a4a7b0560ce3ffffffffffffffffffffffffffffffd0c1cb42cd51ffa933ac79a4a7b0560c",
+ "tag" : "22721657b0130d28cf1ec65153c41182",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 215,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "ef8ce708bf26aab862d97e1b42f31ef3b46fca24d353ff5e49eac51540e840ea3038aca2438b588d5459493e97e7fa333d311e572202011a75e948586fe268b44f03478f2869b93ee29c837e95fb6b99313b1559016e7c493eec86059f703270",
+ "ct" : "ccffffffffffffffffffffffffffffffc7a8192b5dd8148f1371a8ecad8ec409e1ffffffffffffffffffffffffffffffcd375d9349a5d79e2a80ca217d149c08e1ffffffffffffffffffffffffffffffcd375d9349a5d79e2a80ca217d149c08",
+ "tag" : "2172166798485c338f9a6d60f3b21891",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 216,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "f59d56151de28bef83505f6d89c0b0f7f75b2fa8e6dce386075db283ec85ee62555baffad423af25f66069bb69fb6f4d",
+ "ct" : "d6ee4ee25d3bdea81e76de8934cc51fb849cfca7685708575dc6df7a01e36a81849cfca7685708575dc6df7a01e36a81",
+ "tag" : "831312cbb0f165dc3e8ff52125f48640",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 217,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "f717f8d5b28032d5c8e8061cd44d71e4f2d55de772fe7a91ce85e410db3e2d8d50d5ddb5400136323fb83f285e40aca2",
+ "ct" : "d464e022f259679255ce87f8694190e881128ee8fc759140941e89e93658a96e81128ee8fc759140941e89e93658a96e",
+ "tag" : "821312db9826b5e7fe0a9d30c5e28d4f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 218,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "f28ce708bf26aab862d97e1b42f31ef3e68a922c9219d30f07554d7d99f2bde92c38aca2438b588d5459493e97e7fa33e24c07dd98f9b253ab0c318d9b14f6b15303478f2869b93ee29c837e95fb6b99ee460cd3bb95cf00e009ffd06b86ac75",
+ "ct" : "d1ffffffffffffffffffffffffffffff954d41231c9238de5dce20847494390afdffffffffffffffffffffffffffffff124a4419f35e64d7f465b3f489e2020dfdffffffffffffffffffffffffffffff124a4419f35e64d7f465b3f489e2020d",
+ "tag" : "c1045769d487d545cef3f0d34b7a8733",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 219,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "dc8ce708bf26aab862d97e1b42f31ef32e6784d857df07543d0dc72f179935fbede8c8baf01ee2044b162cbb343b355acc29d82327cd93f2bfd918034ed5c42a",
+ "ct" : "ffffffffffffffffffffffffffffffff5da057d7d954ec856796aad6faffb1183c2f9be74c6a4576e0b09a7a5c2330963c2f9be74c6a4576e0b09a7a5c233096",
+ "tag" : "64e7efd24516a83e2c87e06a76e2dea3",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 220,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "f78ce708bf26aab862d97e1b42f31ef34c6ead26f84a0225d557745d32fc72e72c38aca2438b588d5459493e97e7fa3364db334b69bee579383e61ae742c71bb5303478f2869b93ee29c837e95fb6b9968d138454ad2982a733baff384be2b7f",
+ "ct" : "d4ffffffffffffffffffffffffffffff3fa97e2976c1e9f48fcc19a4df9af604fdffffffffffffffffffffffffffffff94dd708f021933fd6757e3d766da8507fdffffffffffffffffffffffffffffff94dd708f021933fd6757e3d766da8507",
+ "tag" : "e6cc6729d79ba558cd73b03cba54d660",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 221,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "f08ce708bf26aab862d97e1b42f31ef34fd8c3757c9f2938dc3b07d85898bfe22a38aca2438b588d5459493e97e7fa336155412415cbdd760142b62c2ec83fbf5503478f2869b93ee29c837e95fb6b996d5f4a2a36a7a0254a477871de5a657b",
+ "ct" : "d3ffffffffffffffffffffffffffffff3c1f107af214c2e986a06a21b5fe3b01fbffffffffffffffffffffffffffffff915302e07e6c0bf25e2b34553c3ecb03fbffffffffffffffffffffffffffffff915302e07e6c0bf25e2b34553c3ecb03",
+ "tag" : "e5cc6739bfd0f4638def574b5a43dd6f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 222,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "f28ce708bf26aab862d97e1b42f31ef3df03ca84082f7f70ad8e4004cabd2ce42b38aca2438b588d5459493e97e7fa3328fd413caab1d02bf1c65753aa2ad3b95403478f2869b93ee29c837e95fb6b9924f74a3289ddad78bac3990e5ab8897d",
+ "ct" : "d1ffffffffffffffffffffffffffffffacc4198b86a494a1f7152dfd27dba807faffffffffffffffffffffffffffffffd8fb02f8c11606afaeafd52ab8dc2705faffffffffffffffffffffffffffffffd8fb02f8c11606afaeafd52ab8dc2705",
+ "tag" : "0fca702228817d53ee64d142b192e665",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 223,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "f38ce708bf26aab862d97e1b42f31ef31ffc31ae69399394b8c338674c3dfde92938aca2438b588d5459493e97e7fa33477ec8cf3ea3d4d5d76d85ad2b7f0bb85603478f2869b93ee29c837e95fb6b994b74c3c11dcfa9869c684bf0dbed517c",
+ "ct" : "d0ffffffffffffffffffffffffffffff6c3be2a1e7b27845e258559ea15b790af8ffffffffffffffffffffffffffffffb7788b0b55040251880407d43989ff04f8ffffffffffffffffffffffffffffffb7788b0b55040251880407d43989ff04",
+ "tag" : "efc3b035ded6b460bfce6f494955e677",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 224,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "2bfd0d56ece98771756d60d9d9106cd0c6fc106936c7ef347c078fd71c54228164fc903b0438a3978d3a54ef992aa3ae",
+ "ct" : "088e15a1ac30d236e84be13d641c8ddcb53bc366b84c04e5269ce22ef132a662b53bc366b84c04e5269ce22ef132a662",
+ "tag" : "345fc9fe573c136c1be83730500ce662",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 225,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "f68ce708bf26aab862d97e1b42f31ef37cc2255decdf8e0fe1373591da0e28e42838aca2438b588d5459493e97e7fa33e291fb4838019c51dfb7141515bb53b15703478f2869b93ee29c837e95fb6b99ee9bf0461b6de10294b2da48e5290975",
+ "ct" : "d5ffffffffffffffffffffffffffffff0f05f652625465debbac58683768ac07f9ffffffffffffffffffffffffffffff1297b88c53a64ad580de966c074da70df9ffffffffffffffffffffffffffffff1297b88c53a64ad580de966c074da70d",
+ "tag" : "336f97a5faa995a2a03781b591588da8",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 226,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "c68ce708bf26aab862d97e1b42f31ef37ab66f8090c149e452ec7f20327eb2ea0438aca2438b588d5459493e97e7fa338d2613ea0ef8b656b247373ecec015bc7b03478f2869b93ee29c837e95fb6b99812c18e42d94cb05f942f9633e524f78",
+ "ct" : "e5ffffffffffffffffffffffffffffff0971bc8f1e4aa235087712d9df183609d5ffffffffffffffffffffffffffffff7d20502e655f60d2ed2eb547dc36e100d5ffffffffffffffffffffffffffffff7d20502e655f60d2ed2eb547dc36e100",
+ "tag" : "9351c680c8a5d34882d42145e89745c4",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 227,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "c68ce708bf26aab862d97e1b42f31ef374b66f8090c149e452ec7f20327eb2ea2e38aca2438b588d5459493e97e7fa33acd9ec859e0866620cc24c8a97d5d9f55103478f2869b93ee29c837e95fb6b99a0d3e78bbd641b3147c782d767478331",
+ "ct" : "e5ffffffffffffffffffffffffffffff0771bc8f1e4aa235087712d9df183609ffffffffffffffffffffffffffffffff5cdfaf41f5afb0e653abcef385232d49ffffffffffffffffffffffffffffffff5cdfaf41f5afb0e653abcef385232d49",
+ "tag" : "d79266cd25a784599a0a8e31fc84d604",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 228,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "f78ce708bf26aab862d97e1b42f31ef34251cd29b0aaa960557c9ea2828334e4e4e231db0a27fac9ec9e744886eb0133c5232142ddf48b3f185140f0fc05f043",
+ "ct" : "d4ffffffffffffffffffffffffffffff31961e263e2142b10fe7f35b6fe5b00735256286b6535dbb4738c289eef304ff35256286b6535dbb4738c289eef304ff",
+ "tag" : "9d671d407d7660459d5d582d83915efe",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 229,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "f58ce708bf26aab862d97e1b42f31ef373bd9f01bf3331b12e31dd14cf11feee1d38aca2438b588d5459493e97e7fa33625c6965f61a1c36118c747076d5b7b76203478f2869b93ee29c837e95fb6b996e56626bd57661655a89ba2d8647ed73",
+ "ct" : "d6ffffffffffffffffffffffffffffff007a4c0e31b8da6074aab0ed22777a0dccffffffffffffffffffffffffffffff925a2aa19dbdcab24ee5f6096423430bccffffffffffffffffffffffffffffff925a2aa19dbdcab24ee5f6096423430b",
+ "tag" : "7b207c2c3278c64f0d6b913fe371fe63",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 230,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "dc8ce708bf26aab862d97e1b42f31ef3ec0933f0bfb91218cea0d74e061f559e2d38aca2438b588d5459493e97e7fa338d5b67e0acee534ce2d9791487b1ecb25203478f2869b93ee29c837e95fb6b9981516cee8f822e1fa9dcb7497723b676",
+ "ct" : "ffffffffffffffffffffffffffffffff9fcee0ff3132f9c9943bbab7eb79d17dfcffffffffffffffffffffffffffffff7d5d2424c74985c8bdb0fb6d9547180efcffffffffffffffffffffffffffffff7d5d2424c74985c8bdb0fb6d9547180e",
+ "tag" : "3672162bb1f3ff537ece013f1aca4f68",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 231,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "dc8ce708bf26aab862d97e1b42f31ef3ee83a14f48db696291080edfcc898b882b38aca2438b588d5459493e97e7fa338ad5f6b0283a8b39ebedce92785da9b65403478f2869b93ee29c837e95fb6b9986dffdbe0b56f66aa0e800cf88cff372",
+ "ct" : "ffffffffffffffffffffffffffffffff9d447240c65082b3cb93632621ef0f6bfaffffffffffffffffffffffffffffff7ad3b574439d5dbdb4844ceb6aab5d0afaffffffffffffffffffffffffffffff7ad3b574439d5dbdb4844ceb6aab5d0a",
+ "tag" : "3572163b99284f5f3e4aa94dbab85677",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 232,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "dc8ce708bf26aab862d97e1b42f31ef3e87dd08ed4e4e04c5877616cbb02cabb2938aca2438b588d5459493e97e7fa33874f0401d457e336f4311f1152f957ba5603478f2869b93ee29c837e95fb6b998b450f0ff73b9e65bf34d14ca26b0d7e",
+ "ct" : "ffffffffffffffffffffffffffffffff9bba03815a6f0b9d02ec0c9556644e58f8ffffffffffffffffffffffffffffff774947c5bff035b2ab589d68400fa306f8ffffffffffffffffffffffffffffff774947c5bff035b2ab589d68400fa306",
+ "tag" : "3472164b815d9e6afec5505c5aa75d86",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 233,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "c88ce708bf26aab862d97e1b42f31ef36be436e346f8f2b32f4cbbaef95150ef0438aca2438b588d5459493e97e7fa332fb76b5132e930f6d0acf70875e977b57b03478f2869b93ee29c837e95fb6b9923bd605f11854da59ba93955857b2d71",
+ "ct" : "ebffffffffffffffffffffffffffffff1823e5ecc873196275d7d6571437d40cd5ffffffffffffffffffffffffffffffdfb12895594ee6728fc57571671f8309d5ffffffffffffffffffffffffffffffdfb12895594ee6728fc57571671f8309",
+ "tag" : "3a7216d7ee1da018ce8412f251656b19",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 234,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "c58ce708bf26aab862d97e1b42f31ef3783cf9302c7d22914b38aca2e7d374ef1d38aca2438b588d5459493e97e7fa33228f2d23597640d574f8e20c4f6b6bb56203478f2869b93ee29c837e95fb6b992e85262d7a1a3d863ffd2c51bff93171",
+ "ct" : "e6ffffffffffffffffffffffffffffff0bfb2a3fa2f6c94011a3c15b0ab5f00cccffffffffffffffffffffffffffffffd2896ee732d196512b9160755d9d9f09ccffffffffffffffffffffffffffffffd2896ee732d196512b9160755d9d9f09",
+ "tag" : "367216178ff1dc45ce73b02cd21f8755",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 235,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "dc8ce708bf26aab862d97e1b42f31ef35db72f89d1402b1a0373ff0a9c5cd44b6d67af40798f5455501792953248ec234ca6bfd9ae5c25a3a4d8a62d48a61d53",
+ "ct" : "ffffffffffffffffffffffffffffffff2e70fc865fcbc0cb59e892f3713a50a8bca0fc1dc5fbf327fbb124545a50e9efbca0fc1dc5fbf327fbb124545a50e9ef",
+ "tag" : "0b4961c9525ea2f2cdad6273e1c7824c",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 236,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "dc8ce708bf26aab862d97e1b42f31ef35f215ec87d62a264cadb519b4ac90a7668d1dd03e56eda6399ac7803e7dd22114910cd9a32bdab956d634cbb9d33d361",
+ "ct" : "ffffffffffffffffffffffffffffffff2ce68dc7f3e949b590403c62a7af8e95b9168e5e591a7d11320acec28fc527ddb9168e5e591a7d11320acec28fc527dd",
+ "tag" : "0a4961d93a93f1fd8d290a8281b6895b",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 237,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:ffffffefeb344f6bc37ba77ea2ee06dfe8c7f4ae10810422124fc5e1bd7fe301",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060710abb165",
+ "aad" : "ffffffff",
+ "msg" : "dc8ce708bf26aab862d97e1b42f31ef3d15ad590dd0f40ba18acd168f6ac777a0f38aca2438b588d5459493e97e7fa33932a097f1d39a04ad30f1b6c650260bf7003478f2869b93ee29c837e95fb6b999f2002713e55dd19980ad53195903a7b",
+ "ct" : "ffffffffffffffffffffffffffffffffa29d069f5384ab6b4237bc911bcaf399deffffffffffffffffffffffffffffff632c4abb769e76ce8c66991577f49403deffffffffffffffffffffffffffffff632c4abb769e76ce8c66991577f49403",
+ "tag" : "3572161355240943de9406292a64c551",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 238,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "40115e67ecd3d4178c4c60e713ab4e5e390ef93aeb61aa307f141323c38e0685fa47139a5f4e3f8e92d7a3b71eb4ff0e259445f4ffc31bce540190edd6ad207876a0085c32ddfcbeb01a8be4c34d5331eda1a5b6139750f973f0d4841baa2cb8",
+ "ct" : "d9ffffffffffffffffffffffffffffffa009d73c6544428cfac0b2d8c7bbef0bedffffffffffffffffffffffffffffff8a5ef60715bc4b07c92b9707376da105edffffffffffffffffffffffffffffff8a5ef60715bc4b07c92b9707376da105",
+ "tag" : "19532d9fa0b5fbd582aaeda830602f1d",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 239,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "49115e67ecd3d4178c4c60e713ab4e5ee02b87aeae8c3da8895f8cb0f6b9cc80f447139a5f4e3f8e92d7a3b71eb4ff0ecc4b7b803a5f8f4647df169080fe567a78a0085c32ddfcbeb01a8be4c34d5331047e9bc2d60bc471602e52f94df95aba",
+ "ct" : "d0ffffffffffffffffffffffffffffff792ca9a820a9d5140c8b2d4bf28c250ee3ffffffffffffffffffffffffffffff6381c873d020df8fdaf5117a613ed707e3ffffffffffffffffffffffffffffff6381c873d020df8fdaf5117a613ed707",
+ "tag" : "adbd2cafc8c8f0e51250e7b81c9d0a2d",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 240,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "43eadae036f733ea9b5b7eb22aee395db6f51a4d10bc2460810c229651556acf384ad82e3e280cad69f0df25b42b83b0",
+ "ct" : "da047b7825db1802e8e8e1aac6ba88fc2ff2344b9e99ccdc04d8836d556083412ff2344b9e99ccdc04d8836d55608341",
+ "tag" : "973e270a7afcab75348e14dbe19c5156",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 241,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "66115e67ecd3d4178c4c60e713ab4e5e891b797521ba925b24090aaf6c4482bae847139a5f4e3f8e92d7a3b71eb4ff0e6d50c32d05a946cb8cea57c9f1442cb164a0085c32ddfcbeb01a8be4c34d5331a565236fe9fd0dfcab1b13a03c432071",
+ "ct" : "ffffffffffffffffffffffffffffffff101c5773af9f7ae7a1ddab5468716b34ffffffffffffffffffffffffffffffffc29a70deefd6160211c050231084adccffffffffffffffffffffffffffffffffc29a70deefd6160211c050231084adcc",
+ "tag" : "e17c273f31758e752322ae4869c1bfbb",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 242,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "6a115e67ecd3d4178c4c60e713ab4e5e519cccebf72573dbee8c12f74255d18c0add1035861ffc0b7f40079b969f8c63b2af4fa3ccd16cb38f425c3996140def",
+ "ct" : "f3ffffffffffffffffffffffffffffffc89be2ed79009b676b58b30c466038021d65fc5026ae3c7a12685bd377d48c921d65fc5026ae3c7a12685bd377d48c92",
+ "tag" : "a22390224c5db0f01696743d870725c5",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 243,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "e235b8c21384557085c3f2eb2a8fa36058cffd2af743dacf96b4ae4d51b4e488d6703f49d9d7f2027e4853feb4ca0df7",
+ "ct" : "7bdb195a00a87e98f6706df3c6db12c1c1c8d32c7966327313600fb655810d06c1c8d32c7966327313600fb655810d06",
+ "tag" : "437d1efad21b0865a541b5cab62e2a44",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 244,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "66115e67ecd3d4178c4c60e713ab4e5e8fab58574a322bac6f394474e4ce7eaec347139a5f4e3f8e92d7a3b71eb4ff0e71532dfb0e9141b00983394722829e7c4fa0085c32ddfcbeb01a8be4c34d5331b966cdb9e2c50a872e727d2eef8592bc",
+ "ct" : "ffffffffffffffffffffffffffffffff16ac7651c417c310eaede58fe0fb9720d4ffffffffffffffffffffffffffffffde999e08e4ee117994a93eadc3421f01d4ffffffffffffffffffffffffffffffde999e08e4ee117994a93eadc3421f01",
+ "tag" : "acf4ffa20c0d06d61a18e9a8d4c84d1d",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 245,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "61115e67ecd3d4178c4c60e713ab4e5e5efe679ba17384c55eb8cc193666fe8d04608c3503d217aa3f90a9b0e1b3b313bc12d3a3491c8712cf92f212e138329f",
+ "ct" : "f8ffffffffffffffffffffffffffffffc7f9499d2f566c79db6c6de23253170313d86050a363d7db52b8f5f800f8b3e213d86050a363d7db52b8f5f800f8b3e2",
+ "tag" : "cd466d06e75b7fd18d5fe21d9227d9a7",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 246,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "9064b88a282052a1ee44df05ad213da679f8d1f971da17437a2b5e04fbca167151b2650ec945fec70588bc65a616a5f24f354c0c1580af3662d5f8151e3f7e82dd557ec8a4d63df7274594367bef09cd",
+ "ct" : "098a19123b0c79499df7401d41758c07e0ffffffffffffffffffffffffffffff460a896b69f43eb668a0e02d475da503e0ffffffffffffffffffffffffffffff460a896b69f43eb668a0e02d475da503",
+ "tag" : "ce8a3d4d887d95613d829b538ed01196",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 247,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "43115e67ecd3d4178c4c60e713ab4e5eeef67bd4795b74015a3493905d544a86e847139a5f4e3f8e92d7a3b71eb4ff0e3197be28eff843592bd8fc8d578421d664a0085c32ddfcbeb01a8be4c34d5331f9a25e6a03ac086e0c29b8e49a832d16",
+ "ct" : "daffffffffffffffffffffffffffffff77f155d2f77e9cbddfe0326b5961a308ffffffffffffffffffffffffffffffff9e5d0ddb05871390b6f2fb67b644a0abffffffffffffffffffffffffffffffff9e5d0ddb05871390b6f2fb67b644a0ab",
+ "tag" : "08289f5199df476fe90475cb95225566",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 248,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "6b115e67ecd3d4178c4c60e713ab4e5e1e34412ab0a056e809d5d4b92be1128a4b2a651a62aeab26cf437fb195407574f3583a8c28603b9e3f41241395cbf4f8",
+ "ct" : "f2ffffffffffffffffffffffffffffff87336f2c3e85be548c0175422fd4fb045c92897fc21f6b57a26b23f9740b75855c92897fc21f6b57a26b23f9740b7585",
+ "tag" : "06df93f651ea5cc56911f30d3e58f997",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 249,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "3fe606108f35869df4c7aa0128464a1265f8d1f971da17437a2b5e04fbca1671fdbe843a0ad9be25055992ab6dcbc9f153354c0c1580af3662d5f8151e3f7e8271599ffc674a7d152794baf8b03265ce",
+ "ct" : "a608a7889c19ad7587743519c412fbb3fcffffffffffffffffffffffffffffffea06685faa687e546871cee38c80c900fcffffffffffffffffffffffffffffffea06685faa687e546871cee38c80c900",
+ "tag" : "9264fc0f47febb30661254daf9a06189",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 250,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "6e8eb98cf7fffe4cd683568cf892991564f8d1f971da17437a2b5e04fbca1671c70f5d8b30c64bf2e6d1d613f40e0bf052354c0c1580af3662d5f8151e3f7e824be8464d5d5588c2c41cfe4029f7a7cf",
+ "ct" : "f7601814e4d3d5a4a530c99414c628b4fdffffffffffffffffffffffffffffffd0b7b1ee90778b838bf98a5b15450b01fdffffffffffffffffffffffffffffffd0b7b1ee90778b838bf98a5b15450b01",
+ "tag" : "69a124fc7f96e220d1a031ced5527279",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 251,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "4f115e67ecd3d4178c4c60e713ab4e5e4156269fe3da101eeb0abf8dda20fe8fff47139a5f4e3f8e92d7a3b71eb4ff0e6aece983e64f97e43ff5295bc884fa7773a0085c32ddfcbeb01a8be4c34d5331a2d909c10a1bdcd318046d320583f6b7",
+ "ct" : "d6ffffffffffffffffffffffffffffffd85108996dfff8a26ede1e76de151701e8ffffffffffffffffffffffffffffffc5265a700c30c72da2df2eb129447b0ae8ffffffffffffffffffffffffffffffc5265a700c30c72da2df2eb129447b0a",
+ "tag" : "3ea8f9b2012321e63d5fb5bc2c5d332d",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 252,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "66115e67ecd3d4178c4c60e713ab4e5e18f125ef374c1454b680e23427e7dc69e447139a5f4e3f8e92d7a3b71eb4ff0e858b08eb1d581570a7cd1e48593b757568a0085c32ddfcbeb01a8be4c34d53314dbee8a9f10c5e47803c5a21943c79b5",
+ "ct" : "ffffffffffffffffffffffffffffffff81f60be9b969fce8335443cf23d235e7f3ffffffffffffffffffffffffffffff2a41bb18f72745b93ae719a2b8fbf408f3ffffffffffffffffffffffffffffff2a41bb18f72745b93ae719a2b8fbf408",
+ "tag" : "dfaf8a3a15d45e7f4c3430048d8589f0",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 253,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "b02ab747a310d6a3bbdb97018a3be8b341f8d1f971da17437a2b5e04fbca1671b7a338bc3423895f0fd96cdb27a787f277354c0c1580af3662d5f8151e3f7e823b44237a59b04a6f2d144488fa5e2bcd",
+ "ct" : "29c416dfb03cfd4bc8680819666f5912d8ffffffffffffffffffffffffffffffa01bd4d99492492e62f13093c6ec8703d8ffffffffffffffffffffffffffffffa01bd4d99492492e62f13093c6ec8703",
+ "tag" : "3408eb2b13a9b76befcedf699422d61f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 254,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "40115e67ecd3d4178c4c60e713ab4e5e380ef93aeb61aa307f141323c38e0685f647139a5f4e3f8e92d7a3b71eb4ff0e3f769a30e8951ff2fb365fa780fdde7e7aa0085c32ddfcbeb01a8be4c34d5331f7437a7204c154c5dcc71bce4dfad2be",
+ "ct" : "d9ffffffffffffffffffffffffffffffa109d73c6544428cfac0b2d8c7bbef0be1ffffffffffffffffffffffffffffff90bc29c302ea4f3b661c584d613d5f03e1ffffffffffffffffffffffffffffff90bc29c302ea4f3b661c584d613d5f03",
+ "tag" : "09f4f2a3936d7461a67ce022176bb8dd",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 255,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "40115e67ecd3d4178c4c60e713ab4e5e060ef93aeb61aa307f141323c38e0685ee47139a5f4e3f8e92d7a3b71eb4ff0e2bca70bfcdf1171ab611d12bed5d627a62a0085c32ddfcbeb01a8be4c34d5331e3ff90fd21a55c2d91e09542205a6eba",
+ "ct" : "d9ffffffffffffffffffffffffffffff9f09d73c6544428cfac0b2d8c7bbef0bf9ffffffffffffffffffffffffffffff8400c34c278e47d32b3bd6c10c9de307f9ffffffffffffffffffffffffffffff8400c34c278e47d32b3bd6c10c9de307",
+ "tag" : "2eb2679aadfd824a5fd8fa2e4a55a65c",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 256,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "56115e67ecd3d4178c4c60e713ab4e5e6c7e1312c6774fae7d1e5d0cc609028ff547139a5f4e3f8e92d7a3b71eb4ff0e81c9e61cbeeed5546b1ce5d8fef21a7a79a0085c32ddfcbeb01a8be4c34d533149fc065e52ba9e634ceda1b133f516ba",
+ "ct" : "cffffffffffffffffffffffffffffffff5793d144852a712f8cafcf7c23ceb01e2ffffffffffffffffffffffffffffff2e0355ef5491859df636e2321f329b07e2ffffffffffffffffffffffffffffff2e0355ef5491859df636e2321f329b07",
+ "tag" : "5e89349f6b011cd6e24ee6ac2f590c21",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 257,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "2ea8410b4dca8c9d5369a033d8db61e46cf8d1f971da17437a2b5e04fbca1671f0f58e8bba6cf1a52146273d8fe0c4fc5a354c0c1580af3662d5f8151e3f7e827c12954dd7ff3295038b0f6e521968c3",
+ "ct" : "b746e0935ee6a77520da3f2b348fd045f5ffffffffffffffffffffffffffffffe74d62ee1add31d44c6e7b756eabc40df5ffffffffffffffffffffffffffffffe74d62ee1add31d44c6e7b756eabc40d",
+ "tag" : "b24537fcb0dcb6200b0285cafc9c3a7d",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 258,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "17059a7c8883a28b90bd94ae44d1543662f8d1f971da17437a2b5e04fbca1671a23018bf8e68e413e99ac2d4ab3f8df154354c0c1580af3662d5f8151e3f7e822ed70379e3fb2723cb57ea8776c621ce",
+ "ct" : "8eeb3be49baf8963e30e0bb6a885e597fbffffffffffffffffffffffffffffffb588f4da2ed9246284b29e9c4a748d00fbffffffffffffffffffffffffffffffb588f4da2ed9246284b29e9c4a748d00",
+ "tag" : "43300400ea36e720361153ce0c5d637d",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 259,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "aaa1b258fd4b54b497b520806a66d7aa68f8d1f971da17437a2b5e04fbca167199132a234a8c789bf8544547940ec3f35e354c0c1580af3662d5f8151e3f7e8215f431e5271fbbabda996d1449f76fcc",
+ "ct" : "334f13c0ee677f5ce406bf988632660bf1ffffffffffffffffffffffffffffff8eabc646ea3db8ea957c190f7545c302f1ffffffffffffffffffffffffffffff8eabc646ea3db8ea957c190f7545c302",
+ "tag" : "d79a0310124adc30c6b64cdef8993e8d",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 260,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "4c115e67ecd3d4178c4c60e713ab4e5ebb5357ed314ad740b9910fad6f01d781f047139a5f4e3f8e92d7a3b71eb4ff0ec8042b414fdd1bba3a6c936b7ed678797ca0085c32ddfcbeb01a8be4c34d53310031cb03a389508d1d9dd702b3d174b9",
+ "ct" : "d5ffffffffffffffffffffffffffffff225479ebbf6f3ffc3c45ae566b343e0fe7ffffffffffffffffffffffffffffff67ce98b2a5a24b73a74694819f16f904e7ffffffffffffffffffffffffffffff67ce98b2a5a24b73a74694819f16f904",
+ "tag" : "e6022cc3ba20e3f9065fdfcc43a9dc40",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 261,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "66115e67ecd3d4178c4c60e713ab4e5ef64296975af7fced168181f76c6508e1c947139a5f4e3f8e92d7a3b71eb4ff0e4975060f7ddef4a098699333b30fbf7c45a0085c32ddfcbeb01a8be4c34d53318140e64d918abf97bf98d75a7e08b3bc",
+ "ct" : "ffffffffffffffffffffffffffffffff6f45b891d4d214519355200c6850e16fdeffffffffffffffffffffffffffffffe6bfb5fc97a1a469054394d952cf3e01deffffffffffffffffffffffffffffffe6bfb5fc97a1a469054394d952cf3e01",
+ "tag" : "353e304fd8553286b26e0d59942fe7cd",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 262,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "9841cfc927a57dc491ab35427ff935e66ef8d1f971da17437a2b5e04fbca1671a683c8f9f9e6780fda4940ddedd76bf258354c0c1580af3662d5f8151e3f7e822a64d33f9475bb3ff884688e302ec7cd",
+ "ct" : "01af6e513489562ce218aa5a93ad8447f7ffffffffffffffffffffffffffffffb13b249c5957b87eb7611c950c9c6b03f7ffffffffffffffffffffffffffffffb13b249c5957b87eb7611c950c9c6b03",
+ "tag" : "0aeb04ecf7def40c42025bbae5509169",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 263,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "42115e67ecd3d4178c4c60e713ab4e5e0b61bf9b7caf83cc34da625593514289e847139a5f4e3f8e92d7a3b71eb4ff0e696a5c7fb9da9cd4a39c8591086db42d64a0085c32ddfcbeb01a8be4c34d5331a15fbc3d558ed7e3846dc1f8c56ab8ed",
+ "ct" : "dbffffffffffffffffffffffffffffff9266919df28a6b70b10ec3ae9764ab07ffffffffffffffffffffffffffffffffc6a0ef8c53a5cc1d3eb6827be9ad3550ffffffffffffffffffffffffffffffffc6a0ef8c53a5cc1d3eb6827be9ad3550",
+ "tag" : "8fc4f77a6ee052a4c314780b8df9a2d0",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 264,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "4b115e67ecd3d4178c4c60e713ab4e5ef28e4d0f20ca1644470c9cdac6000887ed47139a5f4e3f8e92d7a3b71eb4ff0e1464775bacd5c69fe26e1a74968ea27e61a0085c32ddfcbeb01a8be4c34d5331dc51971940818da8c59f5e1d5b89aebe",
+ "ct" : "d2ffffffffffffffffffffffffffffff6b896309aeeffef8c2d83d21c235e109faffffffffffffffffffffffffffffffbbaec4a846aa96567f441d9e774e2303faffffffffffffffffffffffffffffffbbaec4a846aa96567f441d9e774e2303",
+ "tag" : "232ff78a96f347b453ba711b79367ee0",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 265,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:946aff9f2a13f56f92a5f9cfee3cdb1fef6d98d5a55ab563cb28620cd57f19d2",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "00010203040506072dd4cd40",
+ "aad" : "ffffffff",
+ "msg" : "4d115e67ecd3d4178c4c60e713ab4e5e6ee628fc4b5830184cd293364a213e84fe47139a5f4e3f8e92d7a3b71eb4ff0e29db953ad5458fea61f013ea1854fe7572a0085c32ddfcbeb01a8be4c34d5331e1ee75783911c4dd46015783d553f2b5",
+ "ct" : "d4fffffffffffffffffffffffffffffff7e106fac57dd8a4c90632cd4e14d70ae9ffffffffffffffffffffffffffffff861126c93f3adf23fcda1400f9947f08e9ffffffffffffffffffffffffffffff861126c93f3adf23fcda1400f9947f08",
+ "tag" : "e00d2e8bae5d09c28e9bf59409545d09",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 266,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "19de9b9ec8b247d42bbee2016d6715babc286fd979807951b183a188930ad15edcf0b056a2eecc51d30838e640615e14890e659fd3028c904e65018fdfd6038333d14da7b4f76f9f68fa8903138d563c33b7fb50c3e7ebca970f6f89a88a82d6",
+ "ct" : "f9ffffffffffffffffffffffffffffff015d1565924f6c7418de9babf8be4407edffffffffffffffffffffffffffffff2e110e5e1c0468cbaad99c8abeffff07edffffffffffffffffffffffffffffff2e110e5e1c0468cbaad99c8abeffff07",
+ "tag" : "47e5d4294239db73b836c04070ff5b2d",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 267,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "1fde9b9ec8b247d42bbee2016d6715ba839f811ad0310c77052f45320b0d9560c4f0b056a2eecc51d30838e640615e1470d6b14fd209fedf261fd1d250d3478d2bd14da7b4f76f9f68fa8903138d563cca6f2f80c2ec9985ff75bfd4278fc6d8",
+ "ct" : "ffffffffffffffffffffffffffffffff3eeafba63bfe1952ac727f1160b90039f5ffffffffffffffffffffffffffffffd7c9da8e1d0f1a84c2a34cd731fabb09f5ffffffffffffffffffffffffffffffd7c9da8e1d0f1a84c2a34cd731fabb09",
+ "tag" : "232c882f7a1a2f808ccf26496cff5b3d",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 268,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "97311cd6e2d25a7b4eaa16f0a61ca6246b8a85431430eada56a2c5dc944b6aa695136310b6b6b5c17c9f8c02ba7d0aeb71e0943e30f91ba41b4362fa9ed6037b7a329ee1a0af160fc76d3de7e99102c3",
+ "ct" : "771078b7d59fe2509aeb0b0e34844c61d6ffffffffffffffffffffffffffffffa41c2cb9eba7866f50684b1b05e3ab00d6ffffffffffffffffffffffffffffffa41c2cb9eba7866f50684b1b05e3ab00",
+ "tag" : "d71bc70d5adc74e7dfd89406fc15f044",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 269,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "34de9b9ec8b247d42bbee2016d6715ba74cf7e9d82b7e8ed9ec965f6ea310951dc104940e08a4222556828eba459f65a4a006d28729d95d79d2372f77aeeab35",
+ "ct" : "d4ffffffffffffffffffffffffffffffc9ba04216978fdc837945fd581859c08ed1f06e9bd9b718c799feff21bc757b1ed1f06e9bd9b718c799feff21bc757b1",
+ "tag" : "21e63987d494673f3040ae9de2bc0da0",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 270,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "e72b83514e5e50509070359c1cac7e1c428a85431430eada56a2c5dc944b6aa6dad35950d8a9b55a472f9bb8860a526358e0943e30f91ba41b4362fa9ed6037b35f2a4a1ceb01694fcdd2a5dd5e65a4b",
+ "ct" : "070ae7307913e87b443128628e349459ffffffffffffffffffffffffffffffffebdc16f985b886f46bd85ca13994f388ffffffffffffffffffffffffffffffffebdc16f985b886f46bd85ca13994f388",
+ "tag" : "e4fb945d6a2d0b947834317cc415f024",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 271,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "8c6165f445443588041b6e044fb6baae728a85431430eada56a2c5dc944b6aa6881a54c09516a1f1cae7b9dd71130ee168e0943e30f91ba41b4362fa9ed6037b673ba931830f023f7115083822ff06c9",
+ "ct" : "6c40019572098da3d05a73fadd2e50ebcfffffffffffffffffffffffffffffffb9151b69c807925fe6107ec4ce8daf0acfffffffffffffffffffffffffffffffb9151b69c807925fe6107ec4ce8daf0a",
+ "tag" : "c0424863a20e5fa04ccd9784c015f034",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 272,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "18e36174545fa7ec9ea9f05d7057c5ca638a85431430eada56a2c5dc944b6aa6434e1c5e71005b690ca5cb8d580b89ed79e0943e30f91ba41b4362fa9ed6037bac6fe1af6719f8a7b7577a680be781c5",
+ "ct" : "f8c2051563121fc74ae8eda3e2cf2f8fdeffffffffffffffffffffffffffffff724153f72c1168c720520c94e7952806deffffffffffffffffffffffffffffff724153f72c1168c720520c94e7952806",
+ "tag" : "aa7293ffe5db30a31f2581e0e7ae56ed",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 273,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "12de9b9ec8b247d42bbee2016d6715ba54305dff6b61c40b775c352d025c1a56d7f0b056a2eecc51d30838e640615e14bce574e9e11afedbdca021e53bb9188338d14da7b4f76f9f68fa8903138d563c065cea26f1ff998105ca4fe34ce599d6",
+ "ct" : "f2ffffffffffffffffffffffffffffffe945274380aed12ede010f0e69e88f0fe6ffffffffffffffffffffffffffffff1bfa1f282e1c1a80381cbce05a90e407e6ffffffffffffffffffffffffffffff1bfa1f282e1c1a80381cbce05a90e407",
+ "tag" : "42e5d43d1e808e79f017144d4498c235",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 274,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "1fde9b9ec8b247d42bbee2016d6715badf0599194b0ce890cc1d8eb383b57f38dcf0b056a2eecc51d30838e640615e1435df81077d068077ce805ea592f6f88833d14da7b4f76f9f68fa8903138d563c8f661fc86de3e72d17ea30a3e5aa79dd",
+ "ct" : "ffffffffffffffffffffffffffffffff6270e3a5a0c3fdb56540b490e801ea61edffffffffffffffffffffffffffffff92c0eac6b200642c2a3cc3a0f3df040cedffffffffffffffffffffffffffffff92c0eac6b200642c2a3cc3a0f3df040c",
+ "tag" : "6cf2f9230af8679e7ecb19421362fce3",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 275,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "39de9b9ec8b247d42bbee2016d6715ba4092e1f9a22c8b18184d805c128ade57c7f0b056a2eecc51d30838e640615e1464fe8b9bdd215a620973affefe93398528d14da7b4f76f9f68fa8903138d563cde471554cdc43d38d019c1f889cfb8d0",
+ "ct" : "d9fffffffffffffffffffffffffffffffde79b4549e39e3db110ba7f793e4b0ef6ffffffffffffffffffffffffffffffc3e1e05a1227be39edcf32fb9fbac501f6ffffffffffffffffffffffffffffffc3e1e05a1227be39edcf32fb9fbac501",
+ "tag" : "6d46d2230a9848d518f9d94bb2c49caa",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 276,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "12de9b9ec8b247d42bbee2016d6715ba327f3a1befb4287c17450391ed0eb854d6f0b056a2eecc51d30838e640615e141460d3545c29ddc790711b8e7533698539d14da7b4f76f9f68fa8903138d563caed94d9b4cccba9d491b7588026fe8d0",
+ "ct" : "f2ffffffffffffffffffffffffffffff8f0a40a7047b3d59be1839b286ba2d0de7ffffffffffffffffffffffffffffffb37fb895932f399c74cd868b141a9501e7ffffffffffffffffffffffffffffffb37fb895932f399c74cd868b141a9501",
+ "tag" : "74dda12e0558877bc0e40c3eace0af29",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 277,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "1bde9b9ec8b247d42bbee2016d6715ba85b67664ee49fa347fbfd2dd92007c57def0b056a2eecc51d30838e640615e14fb27ee075b3c0f0f682babdde63dad8731d14da7b4f76f9f68fa8903138d563c419e70c84bd96855b141c5db91612cd2",
+ "ct" : "fbffffffffffffffffffffffffffffff38c30cd80586ef11d6e2e8fef9b4e90eefffffffffffffffffffffffffffffff5c3885c6943aeb548c9736d887145103efffffffffffffffffffffffffffffff5c3885c6943aeb548c9736d887145103",
+ "tag" : "502455343d39db87947d7346a8e0af39",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 278,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "36de9b9ec8b247d42bbee2016d6715ba1132811b2f18321ba99b12432c7f865aa3352cd2d7ac70b4c6f5419767926e20352508ba45bba7410ebe1b8bb925334f",
+ "ct" : "d6ffffffffffffffffffffffffffffffac47fba7c4d7273e00c6286047cb1303923a637b8abd431aea02868ed80ccfcb923a637b8abd431aea02868ed80ccfcb",
+ "tag" : "14fba149d1c0edc8aa665851126b5afd",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 279,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "1fde9b9ec8b247d42bbee2016d6715baf999461058f6d7733e5cd0d1639d9025cbf0b056a2eecc51d30838e640615e14520a0da50439db00e289e1791342068e24d14da7b4f76f9f68fa8903138d563ce8b3936a14dcbc5a3be38f7f641e87db",
+ "ct" : "ffffffffffffffffffffffffffffffff44ec3cacb339c2569701eaf20829057cfafffffffffffffffffffffffffffffff5156664cb3f3f5b06357c7c726bfa0afafffffffffffffffffffffffffffffff5156664cb3f3f5b06357c7c726bfa0a",
+ "tag" : "bf7fbd422cbf0e700fd1605be8fd212f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 280,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "15de9b9ec8b247d42bbee2016d6715bacc1629a40cd11eafdf04138b45afe458eff0b056a2eecc51d30838e640615e14340ac9b45a5896a418a8cee8032e078f00d14da7b4f76f9f68fa8903138d563c8eb3577b4abdf1fec1c2a0ee747286da",
+ "ct" : "f5ffffffffffffffffffffffffffffff71635318e71e0b8a765929a82e1b7101deffffffffffffffffffffffffffffff9315a275955e72fffc1453ed6207fb0bdeffffffffffffffffffffffffffffff9315a275955e72fffc1453ed6207fb0b",
+ "tag" : "c6f23204865b0adde0070037d6538dd3",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 281,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "31de9b9ec8b247d42bbee2016d6715baff746ef53ec3357cbc3c3ce4ab1d2d51ed9eb456dc9d9b59f656a5d2d974d26a7b8e903e4e8a4cac3e1dffce07c38f05",
+ "ct" : "d1ffffffffffffffffffffffffffffff42011449d50c2059156106c7c0a9b808dc91fbff818ca8f7daa162cb66ea7381dc91fbff818ca8f7daa162cb66ea7381",
+ "tag" : "8cff61b7b3919ed6bde72b36e0d31326",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 282,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "19de9b9ec8b247d42bbee2016d6715babf286fd979807951b183a188930ad15ecef0b056a2eecc51d30838e640615e1464413d71939b9cb0a4d32ef115da9e1021d14da7b4f76f9f68fa8903138d563cdef8a3be837efbea7db940f762861f45",
+ "ct" : "f9ffffffffffffffffffffffffffffff025d1565924f6c7418de9babf8be4407ffffffffffffffffffffffffffffffffc35e56b05c9d78eb406fb3f474f36294ffffffffffffffffffffffffffffffffc35e56b05c9d78eb406fb3f474f36294",
+ "tag" : "369cf17011cae47539e2723f010cf980",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 283,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "19de9b9ec8b247d42bbee2016d6715babd286fd979807951b183a188930ad15ee3f0b056a2eecc51d30838e640615e14f25e78fe1b53ae416d1fbc698522618f0cd14da7b4f76f9f68fa8903138d563c48e7e6310bb6c91bb475d26ff27ee0da",
+ "ct" : "f9ffffffffffffffffffffffffffffff005d1565924f6c7418de9babf8be4407d2ffffffffffffffffffffffffffffff5541133fd4554a1a89a3216ce40b9d0bd2ffffffffffffffffffffffffffffff5541133fd4554a1a89a3216ce40b9d0b",
+ "tag" : "532eb8e272a8d171378b0d42dff2bed9",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 284,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "32de9b9ec8b247d42bbee2016d6715ba258d5d3e441683f546beba2e23755f5ccef0b056a2eecc51d30838e640615e149d13fdf8fa899836fa5c410d4ccd25ea21d14da7b4f76f9f68fa8903138d563c27aa6337ea6cff6c23362f0b3b91a4bf",
+ "ct" : "d2ffffffffffffffffffffffffffffff98f82782afd996d0efe3800d48c1ca05ffffffffffffffffffffffffffffffff3a0c9639358f7c6d1ee0dc082de4d96effffffffffffffffffffffffffffffff3a0c9639358f7c6d1ee0dc082de4d96e",
+ "tag" : "d1be7426cd12446fe52e8d45331e0835",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 285,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "1fde9b9ec8b247d42bbee2016d6715bad64add2aa3c5a30a31d9e65e90f93ad1cbf0b056a2eecc51d30838e640615e14de9aeab86144d5464811b2373ba4cc8324d14da7b4f76f9f68fa8903138d563c6423747771a1b21c917bdc314cf84dd6",
+ "ct" : "ffffffffffffffffffffffffffffffff6b3fa796480ab62f9884dc7dfb4daf88faffffffffffffffffffffffffffffff79858179ae42311dacad2f325a8d3007faffffffffffffffffffffffffffffff79858179ae42311dacad2f325a8d3007",
+ "tag" : "62630c18de8c10876adb9f30f300963f",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 286,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "1fde9b9ec8b247d42bbee2016d6715bacc3492272b8a4b112a4e7d7ccf092692cef0b056a2eecc51d30838e640615e1430ce678e9375b2af0b82c2d2fbd7928c21d14da7b4f76f9f68fa8903138d563c8a77f9418390d5f5d2e8acd48c8b13d9",
+ "ct" : "ffffffffffffffffffffffffffffffff7141e89bc0455e348313475fa4bdb3cbffffffffffffffffffffffffffffffff97d10c4f5c7356f4ef3e5fd79afe6e08ffffffffffffffffffffffffffffffff97d10c4f5c7356f4ef3e5fd79afe6e08",
+ "tag" : "feb6412b9031f076eddcd9426fff5b31",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 287,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "34de9b9ec8b247d42bbee2016d6715ba722b6549c9df0f4b04b5f7432203fa54cef0b056a2eecc51d30838e640615e1487de186cd28e43544c73de628fd1d60e21d14da7b4f76f9f68fa8903138d563c3d6786a3c26b240e9519b064f88d575b",
+ "ct" : "d4ffffffffffffffffffffffffffffffcf5e1ff522101a6eade8cd6049b76f0dffffffffffffffffffffffffffffffff20c173ad1d88a70fa8cf4367eef82a8affffffffffffffffffffffffffffffff20c173ad1d88a70fa8cf4367eef82a8a",
+ "tag" : "dafdf430c8124483c175404b6bff5b41",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 288,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "3dde9b9ec8b247d42bbee2016d6715bac5629699cfd4d9036cef478ed705be5650f575882c3800f757ea6e0f8c6d47acc6e551e0be2fd7029fa1341352da1ac3",
+ "ct" : "ddffffffffffffffffffffffffffffff7817ec25241bcc26c5b27dadbcb12b0f61fa3a21712933597b1da91633f3e64761fa3a21712933597b1da91633f3e647",
+ "tag" : "f8800c5b6283dddfc41f935c01bd0d24",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 289,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "1fde9b9ec8b247d42bbee2016d6715ba66d624f288f52941ca24865ce96f0d9736ff33a27c23f4976fc74f1fcd82f5cca0ef17caee342362a78c15031335a8a3",
+ "ct" : "ffffffffffffffffffffffffffffffffdba35e4e633a3c646379bc7f82db98ce07f07c0b2132c73943308806721c542707f07c0b2132c73943308806721c5427",
+ "tag" : "38bfb8318c627d86c34bab1f1ebd0db0",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 290,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "f4ebbe3fca96bc4885b35582c43e0eb3588a85431430eada56a2c5dc944b6aa6b4570e8446e886bcbff82a24f49be5ed42e0943e30f91ba41b4362fa9ed6037b5b76f37550f12572040a9bc1a777edc5",
+ "ct" : "14cada5efddb046351f2487c56a6e4f6e5ffffffffffffffffffffffffffffff8558412d1bf9b512930fed3d4b054406e5ffffffffffffffffffffffffffffff8558412d1bf9b512930fed3d4b054406",
+ "tag" : "af7293eb09957d9de7432dd41316f0e4",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 291,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "1ade9b9ec8b247d42bbee2016d6715ba571a3fca3cda7def4c93d4a382ca3a57eaf0b056a2eecc51d30838e640615e1476cddbee2f185776174f6df3bbe5b38105d14da7b4f76f9f68fa8903138d563ccc7445213ffd302cce2503f5ccb932d4",
+ "ct" : "faffffffffffffffffffffffffffffffea6f4576d71568cae5ceee80e97eaf0edbffffffffffffffffffffffffffffffd1d2b02fe01eb32df3f3f0f6dacc4f05dbffffffffffffffffffffffffffffffd1d2b02fe01eb32df3f3f0f6dacc4f05",
+ "tag" : "e178b0d5eb9bc551fa645c49f9f17667",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 292,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "1fde9b9ec8b247d42bbee2016d6715babe31a501536a7c91e4a102cc27cdfe09d2f0b056a2eecc51d30838e640615e14dd9416a12e2f81bdee023d462feef7833dd14da7b4f76f9f68fa8903138d563c672d886e3ecae6e73768534058b276d6",
+ "ct" : "ffffffffffffffffffffffffffffffff0344dfbdb8a569b44dfc38ef4c796b50e3ffffffffffffffffffffffffffffff7a8b7d60e12965e60abea0434ec70b07e3ffffffffffffffffffffffffffffff7a8b7d60e12965e60abea0434ec70b07",
+ "tag" : "bdbf63db237d195ecefdc251f5f17677",
+ "result" : "valid",
+ "flags" : []
+ },
+ {
+ "tcId" : 293,
+ "comment" : "edge case intermediate sums in poly1305. poly_key:dc46b3c53be153ccd4986678ffffffafe484c316c93f64195da65a2742fd3fec",
+ "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f",
+ "iv" : "000102030405060703e76f6f",
+ "aad" : "ffffffff",
+ "msg" : "3ede9b9ec8b247d42bbee2016d6715ba8567a7fde812a3aa2f552a33c1718c58e2f0b056a2eecc51d30838e640615e14bb8729fd148f23b2a916b7f40f2f29810dd14da7b4f76f9f68fa8903138d563c013eb732046a44e8707cd9f27873a8d4",
+ "ct" : "deffffffffffffffffffffffffffffff3812dd4103ddb68f86081010aac51901d3ffffffffffffffffffffffffffffff1c98423cdb89c7e94daa2af16e06d505d3ffffffffffffffffffffffffffffff1c98423cdb89c7e94daa2af16e06d505",
+ "tag" : "b4ccb422bc5f7264aff73f3675ff5b19",
+ "result" : "valid",
+ "flags" : []
+ }
+ ]
+ },
+ {
+ "ivSize" : 0,
+ "keySize" : 256,
+ "tagSize" : 128,
+ "type" : "AeadTest",
+ "source" : {
+ "name" : "google-wycheproof",
+ "version" : "0.8r12"
+ },
+ "tests" : [
+ {
+ "tcId" : 294,
+ "comment" : "invalid nonce size",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "",
+ "aad" : "",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "",
+ "result" : "invalid",
+ "flags" : []
+ }
+ ]
+ },
+ {
+ "ivSize" : 64,
+ "keySize" : 256,
+ "tagSize" : 128,
+ "type" : "AeadTest",
+ "source" : {
+ "name" : "google-wycheproof",
+ "version" : "0.8r12"
+ },
+ "tests" : [
+ {
+ "tcId" : 295,
+ "comment" : "invalid nonce size",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "0001020304050607",
+ "aad" : "",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "",
+ "result" : "invalid",
+ "flags" : []
+ }
+ ]
+ },
+ {
+ "ivSize" : 88,
+ "keySize" : 256,
+ "tagSize" : 128,
+ "type" : "AeadTest",
+ "source" : {
+ "name" : "google-wycheproof",
+ "version" : "0.8r12"
+ },
+ "tests" : [
+ {
+ "tcId" : 296,
+ "comment" : "invalid nonce size",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a",
+ "aad" : "",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "",
+ "result" : "invalid",
+ "flags" : []
+ }
+ ]
+ },
+ {
+ "ivSize" : 104,
+ "keySize" : 256,
+ "tagSize" : 128,
+ "type" : "AeadTest",
+ "source" : {
+ "name" : "google-wycheproof",
+ "version" : "0.8r12"
+ },
+ "tests" : [
+ {
+ "tcId" : 297,
+ "comment" : "invalid nonce size",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b0c",
+ "aad" : "",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "",
+ "result" : "invalid",
+ "flags" : []
+ }
+ ]
+ },
+ {
+ "ivSize" : 112,
+ "keySize" : 256,
+ "tagSize" : 128,
+ "type" : "AeadTest",
+ "source" : {
+ "name" : "google-wycheproof",
+ "version" : "0.8r12"
+ },
+ "tests" : [
+ {
+ "tcId" : 298,
+ "comment" : "invalid nonce size",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b0c0d",
+ "aad" : "",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "",
+ "result" : "invalid",
+ "flags" : []
+ }
+ ]
+ },
+ {
+ "ivSize" : 128,
+ "keySize" : 256,
+ "tagSize" : 128,
+ "type" : "AeadTest",
+ "source" : {
+ "name" : "google-wycheproof",
+ "version" : "0.8r12"
+ },
+ "tests" : [
+ {
+ "tcId" : 299,
+ "comment" : "invalid nonce size",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b0c0d0e0f",
+ "aad" : "",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "",
+ "result" : "invalid",
+ "flags" : []
+ }
+ ]
+ },
+ {
+ "ivSize" : 160,
+ "keySize" : 256,
+ "tagSize" : 128,
+ "type" : "AeadTest",
+ "source" : {
+ "name" : "google-wycheproof",
+ "version" : "0.8r12"
+ },
+ "tests" : [
+ {
+ "tcId" : 300,
+ "comment" : "invalid nonce size",
+ "key" : "202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f",
+ "iv" : "000102030405060708090a0b0c0d0e0f10111213",
+ "aad" : "",
+ "msg" : "",
+ "ct" : "",
+ "tag" : "",
+ "result" : "invalid",
+ "flags" : []
+ }
+ ]
+ }
+ ]
+}
diff --git a/Unit Tests/Tests/TestDECChaChaPoly1305.pas b/Unit Tests/Tests/TestDECChaChaPoly1305.pas
new file mode 100644
index 00000000..27d6c985
--- /dev/null
+++ b/Unit Tests/Tests/TestDECChaChaPoly1305.pas
@@ -0,0 +1,754 @@
+unit TestDECChaChaPoly1305;
+
+interface
+
+uses {$IFDEF DUnitX}
+ DUnitX.TestFramework,DUnitX.DUnitCompatibility,
+ {$ELSE}
+ TestFramework,
+ {$ENDIF}
+ System.SysUtils, Generics.Collections, System.Math,
+ DECBaseClass, System.JSON,
+ DECCipherBase, DECCipherModes, DECCipherFormats, DECCiphers;
+
+
+type
+// Testmethods for class TDECCipher
+ {$IFDEF DUnitX} [TestFixture] {$ENDIF}
+ TestChaCha20Poly1305 = class(TTestCase)
+ private
+ type
+ TJsonTestCase = record
+ key : TBytes;
+ iv : TBytes;
+ msg : TBytes;
+ aad : TBytes;
+ tag : TBytes;
+ enc : TBytes;
+ isValid : boolean;
+ end;
+ TTestEnumerator = class(TEnumerable)
+ private
+ fTests : TList;
+ protected
+ function DoGetEnumerator: TEnumerator; override;
+ public
+ constructor Create(const aTestFile : string);
+ destructor Destroy; override;
+ end;
+ private
+ fTests : TTestEnumerator;
+
+ function IterTests : TTestEnumerator;
+ public
+ destructor Destroy; override;
+ published
+ procedure TestPoly1305;
+ procedure TestChaCha20_Poly1305_KeySetup;
+ procedure TestChaCha20_Poly1305_AEAD;
+ procedure TestChaChaEncodeDecodeSpeed;
+ procedure TestChaChaPoly1305EncodeDecodeSpeed;
+
+ procedure TestXChaCha_Poly1305_AEAD;
+
+ // test suite code
+ procedure TestEncode;
+ procedure TestDecode;
+ end;
+implementation
+
+uses DECCipherModesPoly1305, System.Diagnostics, classes, DECFormat, DECTypes,
+ System.JSON.Readers;
+
+
+// ###########################################
+// ####
+// ###########################################
+
+{ TestTDECGCM }
+type
+ THackChaChaCipher = class(TCipher_chacha20);
+
+
+procedure TestChaCha20Poly1305.TestChaCha20_Poly1305_KeySetup;
+// test vector of chapter 2.6.2 in RFC 7538
+const cKey : TBytes = [$80, $81, $82, $83, $84, $85, $86, $87, $88, $89, $8a, $8b, $8c, $8d, $8e, $8f,
+ $90, $91, $92, $93, $94, $95, $96, $97, $98, $99, $9a, $9b, $9c, $9d, $9e, $9f];
+ cNonce : TBytes = [$00, $00, $00, $00, $00, $01, $02, $03, $04, $05, $06, $07];
+
+ cChaChaMtx : TChaChaMtx = ($8ba0d58a, $cc815f90, $27405081, $7194b24a,
+ $37b633a8, $a50dfde3, $e2b8db08, $46a6d1fd,
+ $7da03782, $9183a233, $148ad271, $b46773d1,
+ $3cc1875a, $8607def1, $ca5c3086, $7085eb87);
+
+
+var chaCha : TCipher_ChaCha20;
+ cpuMode : TChaChaCpuMode;
+begin
+ for cpuMode in [cmPas, cmSSE, cmAVX] do
+ begin
+ TCipher_ChaCha20.CpuMode := cpuMode;
+ chaCha := TCipher_ChaCha20.Create;
+ try
+ chaCha.Mode := cmPoly1305;
+ chaCha.Init( cKey, cNonce );
+ Check( THackChaChaCipher(chaCha).TestChaChaMtx(cChaChaMtx), 'Initialization failed');
+ finally
+ chaCha.Free;
+ end;
+ end;
+end;
+
+procedure TestChaCha20Poly1305.TestChaChaEncodeDecodeSpeed;
+var startStop : TStopWatch;
+ encBuf : TBytes;
+ decBuf_pas, decBuf_SSe, decBuf_AVX, testDecode : TBytes;
+ i : Integer;
+ chaCha : TCipher_ChaCha20;
+ cpuMode : TChaChaCpuMode;
+
+const cKey : TBytes = [$80, $81, $82, $83, $84, $85, $86, $87, $88, $89, $8a, $8b, $8c, $8d, $8e, $8f,
+ $90, $91, $92, $93, $94, $95, $96, $97, $98, $99, $9a, $9b, $9c, $9d, $9e, $9f];
+
+ cNonce : TBytes = [$07, $00, $00, $00, $40, $43, $41, $43, $44, $45, $46, $47];
+
+procedure EncodeBuf( var dest : TBytes );
+var i : integer;
+begin
+ for i := 0 to 3 do
+ begin
+ chaCha := TCipher_ChaCha20.Create;
+ try
+ chaCha.Mode := cmECBx;
+ chaCha.Init(cKey, cNonce);
+
+ dest := chaCha.EncodeBytes(encBuf);
+ finally
+ chaCha.Free;
+ end;
+ end;
+
+end;
+
+begin
+ SetLength(encBuf, 10000000);
+
+ for i := 0 to Length(encBuf) - 1 do
+ encBuf[i] := Byte(Random(255));
+
+
+ SetLength(decBuf_pas, Length(encBuf));
+ SetLength(decBuf_sse, Length(encBuf));
+ SetLength(decBuf_avx, Length(encBuf));
+ SetLength(testDecode, Length(encBuf));
+
+ // ###########################################
+ // #### Perform encryption of all 3 types
+ //
+ TCipher_ChaCha20.CpuMode := cmPas;
+ startStop.Reset;
+ startStop.Start;
+ EncodeBuf( decbuf_pas );
+ startStop.Stop;
+ Status( Format( 'Pas Encoding took %dms', [startStop.ElapsedMilliseconds]));
+
+ TCipher_ChaCha20.CpuMode := cmSSE;
+ startStop.Reset;
+ startStop.Start;
+ EncodeBuf( decbuf_sse );
+ startStop.Stop;
+ Status( Format( 'SSE Encoding took %dms', [startStop.ElapsedMilliseconds]));
+
+ TCipher_ChaCha20.CpuMode := cmAVX;
+ startStop.Reset;
+ startStop.Start;
+ EncodeBuf( decbuf_avx );
+ startStop.Stop;
+ Status( Format( 'AVX Encoding took %dms', [startStop.ElapsedMilliseconds]));
+
+
+ Check( CompareMem( @decbuf_pas[0], @decBuf_sse[0], Length(decBuf_sse)), 'SSE encoding failed');
+ Check( CompareMem( @decbuf_pas[0], @decBuf_sse[0], Length(decBuf_sse)), 'avx encoding failed');
+
+
+ // test decode
+ for cpuMode in [cmPas, cmSSE, cmAVX] do
+ begin
+ TCipher_ChaCha20.CpuMode := cpuMode;
+ chaCha := TCipher_ChaCha20.Create;
+ try
+ chaCha.Mode := cmECBx;
+ chaCha.Init(cKey, cNonce);
+
+ testDecode := chaCha.DecodeBytes(decbuf_sse);
+ finally
+ chaCha.Free;
+ end;
+
+ Check( CompareMem( @encBuf[0], @testDecode[0], Length(testDecode)), 'Dencoding failed');
+ end;
+end;
+
+procedure TestChaCha20Poly1305.TestChaChaPoly1305EncodeDecodeSpeed;
+var startStop : TStopWatch;
+ encBuf : TBytes;
+ decBuf_pas, decBuf_SSe, decBuf_AVX, testDecode : TBytes;
+ i : Integer;
+ chaCha : TCipher_ChaCha20;
+ cpuMode : TChaChaCpuMode;
+ polyCPUMode : TPoly1305CpuMode;
+ tags : Array[pmPas..pmAVX] of TBytes;
+
+const cKey : TBytes = [$80, $81, $82, $83, $84, $85, $86, $87, $88, $89, $8a, $8b, $8c, $8d, $8e, $8f,
+ $90, $91, $92, $93, $94, $95, $96, $97, $98, $99, $9a, $9b, $9c, $9d, $9e, $9f];
+
+ cNonce : TBytes = [$07, $00, $00, $00, $40, $43, $41, $43, $44, $45, $46, $47];
+
+function EncodeBuf( var dest : TBytes ) : TBytes;
+var i : integer;
+begin
+ for i := 0 to 3 do
+ begin
+ chaCha := TCipher_ChaCha20.Create;
+ try
+ chaCha.Mode := cmPoly1305;
+ chaCha.Init(cKey, cNonce);
+
+ dest := chaCha.EncodeBytes(encBuf);
+ chaCha.Done;
+
+ Result := chaCha.CalculatedAuthenticationResult;
+ finally
+ chaCha.Free;
+ end;
+ end;
+
+end;
+
+var tag : TBytes;
+
+begin
+ SetLength(encBuf, 10000000);
+
+ for i := 0 to Length(encBuf) - 1 do
+ encBuf[i] := Byte(Random(255));
+
+
+ SetLength(decBuf_pas, Length(encBuf));
+ SetLength(decBuf_sse, Length(encBuf));
+ SetLength(decBuf_avx, Length(encBuf));
+ SetLength(testDecode, Length(encBuf));
+
+ // ###########################################
+ // #### Perform encryption of all 3 types
+ for polyCPUMode in [pmPas, pmAVX] do
+ begin
+ TPoly1305.CpuMode := polyCPUMode;
+
+ case polyCPUMode of
+ pmPas: Status('POLY1305 Pascal mode');
+ pmAVX: Status('POLY1305 AVX mode');
+ end;
+
+ //
+ TCipher_ChaCha20.CpuMode := cmPas;
+ startStop.Reset;
+ startStop.Start;
+ tags[polyCPUMode] := EncodeBuf( decbuf_pas );
+ startStop.Stop;
+ Status( Format( 'Pas Encoding took %dms', [startStop.ElapsedMilliseconds]));
+
+ TCipher_ChaCha20.CpuMode := cmSSE;
+ startStop.Reset;
+ startStop.Start;
+ tag := EncodeBuf( decbuf_sse );
+ startStop.Stop;
+ Status( Format( 'SSE Encoding took %dms', [startStop.ElapsedMilliseconds]));
+
+ Check(CompareMem( @tag[0], @tags[polyCPUMode][0], Length(tag)), 'Tag calculation failed');
+
+ TCipher_ChaCha20.CpuMode := cmAVX;
+ startStop.Reset;
+ startStop.Start;
+ tag := EncodeBuf( decbuf_avx );
+ startStop.Stop;
+ Status( Format( 'AVX Encoding took %dms', [startStop.ElapsedMilliseconds]));
+ Check(CompareMem( @tag[0], @tags[polyCPUMode][0], Length(tag)), 'Tag calculation failed');
+
+ Check( CompareMem( @decbuf_pas[0], @decBuf_sse[0], Length(decBuf_sse)), 'SSE encoding failed');
+ Check( CompareMem( @decbuf_pas[0], @decBuf_sse[0], Length(decBuf_sse)), 'avx encoding failed');
+ end;
+
+ Check(CompareMem( @tags[pmAVX][0], @tags[pmPas][0], Length(tags[pmPas])), 'AVX, PAS Tag calculation failed');
+
+ // test decode
+ for cpuMode in [cmPas, cmSSE, cmAVX] do
+ begin
+ TCipher_ChaCha20.CpuMode := cpuMode;
+ chaCha := TCipher_ChaCha20.Create;
+ try
+ chaCha.Mode := cmPoly1305;
+ chaCha.Init(cKey, cNonce);
+
+ testDecode := chaCha.DecodeBytes(decbuf_sse);
+ chaCha.Done;
+ finally
+ chaCha.Free;
+ end;
+
+ Check( CompareMem( @encBuf[0], @testDecode[0], Length(testDecode)), 'Decoding failed');
+ end;
+end;
+
+procedure TestChaCha20Poly1305.TestDecode;
+var aTest : TJsonTestCase;
+ chacha : TCipher_ChaCha20;
+ decode : TBytes;
+ isValid : boolean;
+begin
+ isValid := False; // satisfy compiler
+ for aTest in IterTests do
+ begin
+ try
+ chacha := TCipher_ChaCha20.Create;
+ try
+ chacha.DataToAuthenticate := aTest.aad;
+ chacha.ExpectedAuthenticationResult := aTest.tag;
+ chaCha.Init( aTest.key, aTest.iv );
+
+ decode := chaCha.DecodeBytes(aTest.enc);
+ chaCha.Done;
+ isValid := True;
+ finally
+ chacha.Free;
+ end;
+
+ Check( Length(decode) = Length(aTest.msg), 'Decoding length test failed');
+ if Length(decode) <> 0 then
+ Check( Comparemem(@decode[0], @aTest.msg[0], Length(decode) ), 'Decoding failed' );
+ except
+ // tests marked as "invalid" (or not "valid") raise an exception
+ // -> the test does not fail if the result is different to "valid"
+ on E : EDECException do
+ begin
+ isValid := False;
+ end;
+ else
+ raise;
+ end;
+
+ Check( not (isValid xor aTest.isValid), 'Test failed');
+ end;
+end;
+
+procedure TestChaCha20Poly1305.TestEncode;
+var aTest : TJsonTestCase;
+ chacha : TCipher_ChaCha20;
+ encode : TBytes;
+ isValid : boolean;
+begin
+ isValid := False; // satisfy compiler
+ for aTest in IterTests do
+ begin
+ try
+ chacha := TCipher_ChaCha20.Create;
+ try
+ chacha.DataToAuthenticate := aTest.aad;
+ chacha.ExpectedAuthenticationResult := aTest.tag;
+ chaCha.Init( aTest.key, aTest.iv );
+
+ encode := chaCha.EncodeBytes(aTest.msg);
+ chaCha.Done;
+ isValid := True;
+ finally
+ chacha.Free;
+ end;
+
+ Check( Length(encode) = Length(aTest.enc), 'Decoding length test failed');
+ if Length(encode) <> 0 then
+ Check( Comparemem(@encode[0], @aTest.enc[0], Length(encode) ), 'Encoding failed' );
+ except
+ // tests marked as "invalid" (or not "valid") raise an exception
+ // -> the test does not fail if the result is different to "valid"
+ on E : EDECException do
+ begin
+ isValid := False;
+ end;
+ else
+ raise;
+ end;
+
+ Check( not (isValid xor aTest.isValid), 'Test failed');
+ end;
+end;
+
+type
+ THackPly1305 = class(TPoly1305);
+
+procedure TestChaCha20Poly1305.TestPoly1305;
+const// cKey : Array of Byte = [$85, $d6, $be, $78, $57, $55, $6d, $33, $7f, $44, $52, $fe, $42, $d5, $06, $a8, $01, $0,
+// $3, $80, $8a, $fb, $0d, $b2, $fd, $4a, $bf, $f6, $af, $41, $49, $f5, $1b ];
+
+ // original test vector from rfc7539
+ cMsg : AnsiString = 'Cryptographic Forum Research Group'; // without trailing #0!
+ cS : Array of BYte = [$01, $03, $80, $8a, $fb, $0d, $b2, $fd, $4a, $bf, $f6, $af, $41, $49, $f5, $1b];
+ cR : Array of Byte = [$85, $d6, $be, $78, $57, $55, $6d, $33, $7f, $44, $52, $fe, $42, $d5, $06, $a8];
+ cTag : Array of Byte = [$a8, $06, $1d, $c1, $30, $51, $36, $c6, $c2, $2b, $8b, $af, $0c, $01, $27, $a9];
+
+// cKey1 : Array of Byte = [$ec, $07, $4c, $83, $55, $80, $74, $17, $01, $42, $5b, $62, $32, $35, $ad, $d6];
+ cR1 : Array of BYte = [$85, $1f, $c4, $0c, $34, $67, $ac, $0b, $e0, $5c, $c2, $04, $04, $f3, $f7, $00];
+ cS1 : Array of BYte = [$ec, $07, $4c, $83, $55, $80, $74, $17, $01, $42, $5b, $62, $32, $35, $ad, $d6];
+ cMsg1 : Array of Byte = [$f3, $f6];
+ cTag1 : Array of BYte = [$88, $C3, $44, $37, $C6, $87, $7A, $3E, $90, $C1, $F8, $08, $58, $C3, $92, $F8];
+
+var poly : TPoly1305;
+ iv : T32ByteArray;
+ msg : TBytes;
+ calcTag : TBytes;
+ // ctx : PPoly1305Ctx;
+procedure InvData( data : PByte; len : integer );
+var tmp : byte;
+ pEnd : PByte;
+begin
+ pEnd := data;
+ inc(pEnd, len - 1);
+ while pEnd > data do
+ begin
+ tmp := pEnd^;
+ pEnd^ := data^;
+ data^ := tmp;
+
+ inc(data);
+ dec(pEnd);
+ end;
+end;
+begin
+ // test vector from https://datatracker.ietf.org/doc/html/rfc7539.html#page-15
+ // RFC 7538
+ FillChar(iv[0], Length(iv), 0);
+ Move( cR1[0], iv[0], Length(cr));
+ Move( cS1[0], iv[16], Length(cS1));
+
+ //InvData( @iv[0], 16);
+ //invData( @iv[16], 16);
+ SetLength(msg, length(cMsg1));
+ Move(cMsg1[0], msg[0], Length(msg));
+ //InvData( @msg[0], Length(msg));
+
+ TPOly1305.CpuMode := pmPas;
+ poly := TPoly1305.Create;
+ try
+ THackPly1305(poly).InitInternal(iv);
+ THackPly1305(poly).UpdatePoly(@msg[0], Length(msg));
+ THackPly1305(poly).Finalize;
+
+ calcTag := poly.CalculatedAuthenticationTag;
+ finally
+ poly.Free;
+ end;
+
+ Check(Length(cTag) = Length(calcTag), 'MAC length is wrong');
+ Check( CompareMem(@cTag1[0], @calcTag[0], Length(calcTag)), 'Polynom calculated tag does not match');
+
+ // ###########################################
+ // #### second test
+ FillChar(iv[0], Length(iv), 0);
+ Move( cR[0], iv[0], Length(cr));
+ Move( cS[0], iv[16], Length(cS1));
+
+ SetLength(msg, length(cMsg));
+ Move(cMsg[1], msg[0], Length(msg));
+
+ poly := TPoly1305.Create;
+ try
+ THackPly1305(poly).InitInternal(iv);
+ THackPly1305(poly).UpdatePoly(@msg[0], Length(msg));
+ THackPly1305(poly).Finalize;
+
+ calcTag := poly.CalculatedAuthenticationTag;
+ finally
+ poly.Free;
+ end;
+
+ Check(Length(cTag) = Length(calcTag), 'MAC length is wrong');
+ Check( CompareMem(@cTag[0], @calcTag[0], Length(calcTag)), 'Polynom calculated tag does not match');
+
+ // ###########################################
+ // #### third test
+ FillChar(iv[0], Length(iv), 0);
+ Move( cR[0], iv[0], Length(cr));
+ Move( cS[0], iv[16], Length(cS1));
+
+ SetLength(msg, length(cMsg));
+ Move(cMsg[1], msg[0], Length(msg));
+
+ TPoly1305.CpuMode := pmAVX;
+ poly := TPoly1305.Create;
+ try
+ THackPly1305(poly).InitInternal(iv);
+ THackPly1305(poly).UpdatePolyAVX(@msg[0], Length(msg));
+ THackPly1305(poly).FinalizeAVX;
+
+ calcTag := poly.CalculatedAuthenticationTag;
+ finally
+ poly.Free;
+ TPoly1305.CpuMode := pmPas;
+ end;
+
+ Check(Length(cTag) = Length(calcTag), 'MAC length is wrong');
+ Check( CompareMem(@cTag[0], @calcTag[0], Length(calcTag)), 'Polynom calculated tag does not match');
+end;
+
+
+function TestChaCha20Poly1305.IterTests: TTestEnumerator;
+begin
+ if not Assigned(fTests) then
+ fTests := TTestEnumerator.Create('..\..\Unit Tests\Data\chacha20_poly1305_test.json');
+
+ Result := fTests;
+end;
+
+procedure TestChaCha20Poly1305.TestXChaCha_Poly1305_AEAD;
+// is actually the same test vector as for chacha20_poly1305
+const cMsg : AnsiString = 'Ladies and Gentlemen of the class of ''99: If I could offer you only one tip for the future, sunscreen would be it.';
+ cAAD : TBytes = [$50, $51, $52, $53, $c0, $c1, $c2, $c3, $c4, $c5, $c6, $c7];
+
+ cKey : TBytes = [$80, $81, $82, $83, $84, $85, $86, $87, $88, $89, $8a, $8b, $8c, $8d, $8e, $8f,
+ $90, $91, $92, $93, $94, $95, $96, $97, $98, $99, $9a, $9b, $9c, $9d, $9e, $9f];
+
+ cNonce : TBytes = [$40, $41, $42, $43, $44, $45, $46, $47, $48, $49, $4a, $4b, $4c, $4d, $4e, $4f, $50, $51, $52, $53, $54, $55, $56, $57];
+
+ cTag : TBytes = [$c0, $87, $59, $24, $c1, $c7, $98, $79, $47, $de, $af, $d8, $78, $0a, $cf, $49];
+
+ cCipherText : TBytes = [$bd, $6d, $17, $9d, $3e, $83, $d4, $3b, $95, $76, $57, $94, $93, $c0, $e9, $39,
+ $57, $2a, $17, $00, $25, $2b, $fa, $cc, $be, $d2, $90, $2c, $21, $39, $6c, $bb,
+ $73, $1c, $7f, $1b, $0b, $4a, $a6, $44, $0b, $f3, $a8, $2f, $4e, $da, $7e, $39,
+ $ae, $64, $c6, $70, $8c, $54, $c2, $16, $cb, $96, $b7, $2e, $12, $13, $b4, $52,
+ $2f, $8c, $9b, $a4, $0d, $b5, $d9, $45, $b1, $1b, $69, $b9, $82, $c1, $bb, $9e,
+ $3f, $3f, $ac, $2b, $c3, $69, $48, $8f, $76, $b2, $38, $35, $65, $d3, $ff, $f9,
+ $21, $f9, $66, $4c, $97, $63, $7d, $a9, $76, $88, $12, $f6, $15, $c6, $8b, $13,
+ $b5, $2e ];
+var chaCha : TCipher_XChaCha20;
+ msg : TBytes;
+ encr : TBytes;
+ encrTag : TBytes;
+ decr : TBytes;
+ decodeTag : TBytes;
+ cpuMode : TChaChaCpuMode;
+begin
+ for cpuMode in [cmPas, cmSSE, cmAVX] do
+ begin
+ TCipher_XChaCha20.CpuMode := cpuMode;
+
+ if cpuMode = cmPas
+ then
+ TPoly1305.CpuMode := pmPas
+ else
+ TPoly1305.CpuMode := pmAVX;
+
+ SetLength(msg, Length(cMsg));
+ Move( cMsg[1], msg[0], Length(msg));
+
+
+ chaCha := TCipher_XChaCha20.Create;
+ try
+ chaCha.Mode := cmPoly1305;
+ chaCha.DataToAuthenticate := cAAD;
+ chaCha.Init(cKey, cNonce);
+ encr := chaCha.EncodeBytes(msg);
+ chaCha.Done;
+
+ encrTag := chaCha.CalculatedAuthenticationResult;
+ finally
+ chaCha.Free;
+ end;
+
+ Check( Length(cCipherText) = Length(encr), 'Encryption length is wrong');
+ Check( CompareMem( @cCipherText[0], @encr[0], Length(encr) ), 'Encryption failed');
+
+
+ Check( Length(cTag) = Length(encrTag), 'Tag length is wrong');
+ Check( CompareMem( @encrTag[0], @cTag[0], Length(cTag)), 'Calculated Tag is wrong');
+
+ // ###########################################
+ // #### Test decode
+ chaCha := TCipher_XChaCha20.Create;
+ try
+ chaCha.Mode := cmPoly1305;
+ chaCha.ExpectedAuthenticationResult := encrTag;
+ chaCha.DataToAuthenticate := cAAD;
+
+ chaCha.Init(cKey, cNonce);
+ decr := chaCha.DecodeBytes(encr);
+ chaCha.Done;
+
+ decodeTag := chaCha.CalculatedAuthenticationResult
+ finally
+ chaCha.Free;
+ end;
+
+ Check( Length(cTag) = Length(decodeTag), 'Tag length is wrong');
+ Check( CompareMem( @decodeTag[0], @cTag[0], Length(cTag)), 'Calculated Tag is wrong');
+ end;
+
+ TPoly1305.CpuMode := pmPas
+end;
+
+
+destructor TestChaCha20Poly1305.Destroy;
+begin
+ fTests.Free;
+
+ inherited;
+end;
+
+procedure TestChaCha20Poly1305.TestChaCha20_Poly1305_AEAD;
+const cMsg : AnsiString = 'Ladies and Gentlemen of the class of ''99: If I could offer you only one tip for the future, sunscreen would be it.';
+ cAAD : TBytes = [$50, $51, $52, $53, $c0, $c1, $c2, $c3, $c4, $c5, $c6, $c7];
+
+ cKey : TBytes = [$80, $81, $82, $83, $84, $85, $86, $87, $88, $89, $8a, $8b, $8c, $8d, $8e, $8f,
+ $90, $91, $92, $93, $94, $95, $96, $97, $98, $99, $9a, $9b, $9c, $9d, $9e, $9f];
+
+ cNonce : TBytes = [$07, $00, $00, $00, $40, $41, $42, $43, $44, $45, $46, $47];
+
+ cTag : TBytes = [$1a, $e1, $0b, $59, $4f, $09, $e2, $6a, $7e, $90, $2e, $cb, $d0, $60, $06, $91];
+
+ cCipherText : TBytes = [$d3, $1a, $8d, $34, $64, $8e, $60, $db, $7b, $86, $af, $bc, $53, $ef, $7e, $c2,
+ $a4, $ad, $ed, $51, $29, $6e, $08, $fe, $a9, $e2, $b5, $a7, $36, $ee, $62, $d6,
+ $3d, $be, $a4, $5e, $8c, $a9, $67, $12, $82, $fa, $fb, $69, $da, $92, $72, $8b,
+ $1a, $71, $de, $0a, $9e, $06, $0b, $29, $05, $d6, $a5, $b6, $7e, $cd, $3b, $36,
+ $92, $dd, $bd, $7f, $2d, $77, $8b, $8c, $98, $03, $ae, $e3, $28, $09, $1b, $58,
+ $fa, $b3, $24, $e4, $fa, $d6, $75, $94, $55, $85, $80, $8b, $48, $31, $d7, $bc,
+ $3f, $f4, $de, $f0, $8e, $4b, $7a, $9d, $e5, $76, $d2, $65, $86, $ce, $c6, $4b,
+ $61, $16 ];
+
+var chaCha : TCipher_ChaCha20;
+ msg : TBytes;
+ encr : TBytes;
+ encrTag : TBytes;
+ decr : TBytes;
+ decodeTag : TBytes;
+ cpuMode : TChaChaCpuMode;
+begin
+ for cpuMode in [cmPas, cmSSE, cmAVX] do
+ begin
+ TCipher_ChaCha20.CpuMode := cpuMode;
+ if cpuMode = cmPas
+ then
+ TPoly1305.CpuMode := pmPas
+ else
+ TPoly1305.CpuMode := pmAVX;
+
+ SetLength(msg, Length(cMsg));
+ Move( cMsg[1], msg[0], Length(msg));
+
+
+ chaCha := TCipher_ChaCha20.Create;
+ try
+ chaCha.Mode := cmPoly1305;
+ chaCha.DataToAuthenticate := cAAD;
+ chaCha.Init(cKey, cNonce);
+ encr := chaCha.EncodeBytes(msg);
+ chaCha.Done;
+
+ encrTag := chaCha.CalculatedAuthenticationResult;
+ finally
+ chaCha.Free;
+ end;
+
+ Check( Length(cCipherText) = Length(encr), 'Encryption length is wrong');
+ Check( CompareMem( @cCipherText[0], @encr[0], Length(encr) ), 'Encryption failed');
+
+
+ Check( Length(cTag) = Length(encrTag), 'Tag length is wrong');
+ Check( CompareMem( @encrTag[0], @cTag[0], Length(cTag)), 'Calculated Tag is wrong');
+
+ // ###########################################
+ // #### Test decode
+ chaCha := TCipher_ChaCha20.Create;
+ try
+ chaCha.Mode := cmPoly1305;
+ chaCha.ExpectedAuthenticationResult := encrTag;
+ chaCha.DataToAuthenticate := cAAD;
+
+ chaCha.Init(cKey, cNonce);
+ decr := chaCha.DecodeBytes(encr);
+ chaCha.Done;
+
+ decodeTag := chaCha.CalculatedAuthenticationResult
+ finally
+ chaCha.Free;
+ end;
+
+ Check( Length(cTag) = Length(decodeTag), 'Tag length is wrong');
+ Check( CompareMem( @decodeTag[0], @cTag[0], Length(cTag)), 'Calculated Tag is wrong');
+ end;
+end;
+
+
+{ TestChaCha20Poly1305.TTestEnumerator }
+
+constructor TestChaCha20Poly1305.TTestEnumerator.Create(
+ const aTestFile: string);
+var groups : TJSONArray;
+ tests : TJsonValue;
+ aTest : TJsonValue;
+ testFile : TJSonObject;
+ testRec : TJsonTestCase;
+begin
+ inherited Create;
+
+ fTests := TList.Create;
+ with TSTringList.create do
+ try
+ Loadfromfile('..\..\Unit Tests\Data\chacha20_poly1305_test.json');
+ testFile := TJSONObject.ParseJSONValue(Text) as TJSONObject;
+ finally
+ Free;
+ end;
+
+ // ###########################################
+ // #### Build list of tests
+ try
+ groups := testFile.GetValue('testGroups') as TJsonArray;
+
+ for tests in groups do
+ begin
+ for aTest in ((tests as TJsonObject).GetValue('tests') as TJsonArray) do
+ begin
+ testRec.aad := BytesOf(TFormat_HexL.Decode(RawByteString(aTest.GetValue('aad'))));
+ testRec.iv := BytesOf(TFormat_HexL.Decode(RawByteString(aTest.GetValue('iv'))));
+ testRec.key := BytesOf(TFormat_HexL.Decode(RawByteString(aTest.GetValue('key'))));
+ testRec.msg := BytesOf(TFormat_HexL.Decode(RawByteString(aTest.GetValue('msg'))));
+ testRec.tag := BytesOf(TFormat_HexL.Decode(RawByteString(aTest.GetValue('tag'))));
+ testRec.Enc := BytesOf(TFormat_HexL.Decode(RawByteString(aTest.GetValue('ct'))));
+ testRec.isValid := SameText( aTest.GetValue('result'), 'Valid');
+ fTests.Add(testRec);
+ end;
+ end;
+ finally
+ testFile.Free;
+ end;
+end;
+
+destructor TestChaCha20Poly1305.TTestEnumerator.Destroy;
+begin
+ fTests.Free;
+
+ inherited;
+end;
+
+function TestChaCha20Poly1305.TTestEnumerator.DoGetEnumerator: TEnumerator;
+begin
+ Result := fTests.GetEnumerator;
+end;
+
+initialization
+ // Register all test cases to be run
+ {$IFDEF DUnitX}
+ TDUnitX.RegisterTestFixture(TPoly1305);
+ {$ELSE}
+ RegisterTest(TestChaCha20Poly1305.Suite);
+ {$ENDIF}
+
+end.
diff --git a/Unit Tests/Tests/TestDECCipher.pas b/Unit Tests/Tests/TestDECCipher.pas
index d72456f2..b8550f0a 100644
--- a/Unit Tests/Tests/TestDECCipher.pas
+++ b/Unit Tests/Tests/TestDECCipher.pas
@@ -4587,7 +4587,7 @@ procedure TestTCipher_AES.TestContext;
CheckEquals( 32, ReturnValue.KeySize);
CheckEquals( 16, ReturnValue.BlockSize);
CheckEquals( 16, ReturnValue.BufferSize);
- CheckEquals( 480, ReturnValue.AdditionalBufferSize);
+ CheckEquals( 512, ReturnValue.AdditionalBufferSize);
CheckEquals( 1, ReturnValue.MinRounds);
CheckEquals( 1, ReturnValue.MaxRounds);
CheckEquals(false, ReturnValue.NeedsAdditionalBufferBackup);
@@ -4675,7 +4675,7 @@ procedure TestTCipher_Rijndael.TestContext;
CheckEquals( 32, ReturnValue.KeySize);
CheckEquals( 16, ReturnValue.BlockSize);
CheckEquals( 16, ReturnValue.BufferSize);
- CheckEquals( 480, ReturnValue.AdditionalBufferSize);
+ CheckEquals( 512, ReturnValue.AdditionalBufferSize);
CheckEquals( 1, ReturnValue.MinRounds);
CheckEquals( 1, ReturnValue.MaxRounds);
CheckEquals(false, ReturnValue.NeedsAdditionalBufferBackup);
diff --git a/Unit Tests/Tests/TestDECCipherModesGCM.pas b/Unit Tests/Tests/TestDECCipherModesGCM.pas
index b7f5f6cc..0d6c0727 100644
--- a/Unit Tests/Tests/TestDECCipherModesGCM.pas
+++ b/Unit Tests/Tests/TestDECCipherModesGCM.pas
@@ -163,6 +163,7 @@ TestTDECGCM = class(TTestCase)
/// Test for GitHub issue #86
///
procedure TestEncodeConstData_86;
+ procedure TestStreamGCM_87;
end;
@@ -584,6 +585,7 @@ procedure TestTDECGCM.TestEncodeConstData_86;
cipher.DataToAuthenticate := hea;
cipher.Encode(refPlainText, ciphText, sizeof(refPlainText));
+ cipher.Done;
tag := cipher.CalculatedAuthenticationResult;
finally
cipher.Free;
@@ -897,6 +899,109 @@ procedure TestTDECGCM.TestSetGetDataToAuthenticate;
RawByteString(StringOf(FCipherAES.DataToAuthenticate)));
end;
+procedure TestTDECGCM.TestStreamGCM_87;
+// testing of https://github.com/MHumm/DelphiEncryptionCompendium/issues/87
+const cKey : Array[0..3] of LongWord = ( $55A46905, $AA23072B, $1309087f, $A5020869 );
+ cIV : Array[0..2] of LongWord = ($1, $2, $3 );
+
+var inp : TBytes;
+ inpStream : TMemoryStream;
+
+ cipher : TCipher_AES128;
+ outStream : TMemoryStream;
+ decodeStream : TMemoryStream;
+ out1, out2 : TBytes;
+ i : integer;
+ hea : TBytes;
+ tag2, tag1, tag3 : TBytes;
+begin
+ // needs to be larger than the default block size of 8192 (in EncodeStream)
+ SetLength(inp, 32768);
+
+ for i := 0 to Length(inp) - 1 do
+ inp[i] := i mod 255;
+
+ inpStream := TMemoryStream.Create;
+ inpStream.WriteBuffer(inp, Length(inp));
+
+ // ###########################################
+ // #### First run -> direct encoding
+ cipher := TCipher_AES128.Create;
+ try
+ cipher.Mode := cmGCM;
+ cipher.Init( cKey, sizeof(cKey), civ, sizeof(civ) );
+
+ cipher.AuthenticationResultBitLength := 128;
+ // some authenticatino data
+ hea := [1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+ cipher.DataToAuthenticate := hea;
+
+ out1 := cipher.EncodeBytes(inp);
+
+ cipher.Done;
+ tag1 := cipher.CalculatedAuthenticationResult;
+ finally
+ cipher.Free;
+ end;
+
+
+ // ###########################################
+ // #### Second run -> stream
+ outStream := TMemoryStream.Create;
+ inpStream.Position := 0;
+ cipher := TCipher_AES128.Create;
+ try
+ cipher.Mode := cmGCM;
+ cipher.Init( cKey, sizeof(cKey), civ, sizeof(civ) );
+
+ cipher.AuthenticationResultBitLength := 128;
+ hea := [1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+ cipher.DataToAuthenticate := hea;
+
+ cipher.EncodeStream(inpStream, outStream, inpStream.Size, nil);
+ cipher.Done;
+ tag2 := cipher.CalculatedAuthenticationResult;
+ finally
+ cipher.Free;
+ end;
+
+ outStream.Position := 0;
+ SetLength(out2, outStream.Size);
+ outStream.ReadBuffer(out2, outStream.Size);
+
+ Check( CompareMem(@out1[0], @out2[0], Length(out1) ), 'AES128 Encryption failed');
+ Check( CompareMem(@tag1[0], @tag2[0], Length(tag1) ), 'Authentication Result do not match');
+
+
+ // ###########################################
+ // #### Decode
+ decodeStream := TMemoryStream.Create;
+ inpStream.Position := 0;
+ outStream.Position := 0;
+ cipher := TCipher_AES128.Create;
+ try
+ cipher.Mode := cmGCM;
+ cipher.Init( cKey, sizeof(cKey), civ, sizeof(civ) );
+
+ cipher.AuthenticationResultBitLength := 128;
+ hea := [1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
+ cipher.DataToAuthenticate := hea;
+
+ cipher.DecodeStream(outStream, decodeStream, outStream.Size, nil);
+ cipher.Done;
+ tag3 := cipher.CalculatedAuthenticationResult;
+ finally
+ cipher.Free;
+ end;
+
+ Check( CompareMem(@tag3[0], @tag2[0], Length(tag1) ), 'Authentication Result do not match');
+ Check( CompareMem( inpStream.Memory, decodeStream.Memory, inpStream.Size ), 'Decoding failed');
+
+ decodeStream.Free;
+ outStream.Free;
+ inpStream.Free;
+end;
+
initialization
// Register all test cases to be run
{$IFDEF DUnitX}