12 #if CRYPTOPP_MSC_VERSION 13 # pragma warning(disable: 4731) 18 #if defined(_MSC_VER) && !CRYPTOPP_BOOL_SLOW_WORD64 22 #define VMAC_BOOL_WORD128 (defined(CRYPTOPP_WORD128_AVAILABLE) && !defined(CRYPTOPP_X64_ASM_AVAILABLE)) 24 #define const // Turbo C++ 2006 workaround 26 static const word64 p64 = W64LIT(0xfffffffffffffeff);
27 static const word64 m62 = W64LIT(0x3fffffffffffffff);
28 static const word64 m63 = W64LIT(0x7fffffffffffffff);
29 static const word64 m64 = W64LIT(0xffffffffffffffff);
30 static const word64 mpoly = W64LIT(0x1fffffff1fffffff);
37 #define m126 ((word128(m62)<<64)|m64) 39 static const word128 m126 = (word128(m62)<<64)|m64;
46 if (digestLength != 8 && digestLength != 16)
48 m_is128 = digestLength == 16;
51 if (m_L1KeyLength <= 0 || m_L1KeyLength % 128 != 0)
52 throw InvalidArgument(
"VMAC: L1KeyLength must be a positive multiple of 128");
57 cipher.
SetKey(userKey, keylength, params);
58 const unsigned int blockSize = cipher.
BlockSize();
59 const unsigned int blockSizeInWords = blockSize /
sizeof(word64);
68 ConditionalByteReverse<word64>(BIG_ENDIAN_ORDER, m_nhKey(), m_nhKey(), m_nhKeySize()*
sizeof(word64));
73 for (i = 0; i <= (size_t)m_is128; i++)
76 m_polyState()[i*4+2] = GetWord<word64>(
true, BIG_ENDIAN_ORDER, out.
BytePtr()) & mpoly;
77 m_polyState()[i*4+3] = GetWord<word64>(
true, BIG_ENDIAN_ORDER, out.
BytePtr()+8) & mpoly;
84 word64 *l3Key = m_l3Key();
85 for (i = 0; i <= (size_t)m_is128; i++)
89 l3Key[i*2+0] = GetWord<word64>(
true, BIG_ENDIAN_ORDER, out.
BytePtr());
90 l3Key[i*2+1] = GetWord<word64>(
true, BIG_ENDIAN_ORDER, out.
BytePtr()+8);
92 }
while ((l3Key[i*2+0] >= p64) || (l3Key[i*2+1] >= p64));
96 const byte *nonce = GetIVAndThrowIfInvalid(params, nonceLength);
108 size_t length = ThrowIfInvalidIVLength(len);
110 byte *storedNonce = m_nonce();
114 memset(storedNonce, 0, s-length);
115 memcpy(storedNonce+s-length, nonce, length);
120 if (m_padCached && (storedNonce[s-1] | 1) == (nonce[length-1] | 1))
123 for (
size_t i=0; m_padCached && i<s-length; i++)
124 m_padCached = (storedNonce[i] == 0);
128 memset(storedNonce, 0, s-length);
129 memcpy(storedNonce+s-length, nonce, length-1);
130 storedNonce[s-1] = nonce[length-1] & 0xfe;
134 storedNonce[s-1] = nonce[length-1];
136 m_isFirstBlock =
true;
140 void VMAC_Base::HashEndianCorrectedBlock(
const word64 *data)
142 CRYPTOPP_UNUSED(data);
144 throw NotImplemented(
"VMAC: HashEndianCorrectedBlock is not implemented");
150 #if (CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE)) && !defined(CRYPTOPP_DISABLE_VMAC_ASM) 156 #if (CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86 || (CRYPTOPP_BOOL_X32 && !defined(CRYPTOPP_DISABLE_VMAC_ASM)))) 157 #if CRYPTOPP_MSC_VERSION 158 # pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code 162 __attribute__ ((noinline))
164 VMAC_Base::VHASH_Update_SSE2(
const word64 *data,
size_t blocksRemainingInWord64,
int tagPart)
166 const word64 *nhK = m_nhKey();
167 word64 *polyS = m_polyState();
170 CRYPTOPP_UNUSED(data); CRYPTOPP_UNUSED(tagPart); CRYPTOPP_UNUSED(L1KeyLength);
171 CRYPTOPP_UNUSED(blocksRemainingInWord64);
181 #
if _MSC_VER < 1300 || defined(__INTEL_COMPILER)
182 char isFirstBlock = m_isFirstBlock;
183 AS2( mov ebx, [L1KeyLength])
184 AS2( mov dl, [isFirstBlock])
187 AS2( mov ebx, [ecx+m_L1KeyLength])
188 AS2( mov dl, [ecx+m_isFirstBlock])
190 AS2( mov eax, tagPart)
198 AS2( mov ecx, blocksRemainingInWord64)
202 #if CRYPTOPP_BOOL_X32 214 AS2( lea ebp, [edi+8*ebp])
215 AS2( movq mm6, [esi])
216 AS2( paddq mm6, [edi])
217 AS2( movq mm5, [esi+8])
218 AS2( paddq mm5, [edi+8])
222 ASS( pshufw mm2, mm6, 1, 0, 3, 2)
223 AS2( pmuludq mm6, mm5)
224 ASS( pshufw mm3, mm5, 1, 0, 3, 2)
225 AS2( pmuludq mm5, mm2)
226 AS2( pmuludq mm2, mm3)
227 AS2( pmuludq mm3, mm4)
229 AS2( movd [esp], mm6)
231 #if CRYPTOPP_BOOL_X32 232 AS2( movd [esp+8], mm5)
234 AS2( movd [esp+4], mm5)
240 AS2( movq mm0, [esi])
241 AS2( paddq mm0, [edi])
242 AS2( movq mm1, [esi+8])
243 AS2( paddq mm1, [edi+8])
248 ASS( pshufw mm2, mm0, 1, 0, 3, 2)
249 AS2( pmuludq mm0, mm1)
250 #if CRYPTOPP_BOOL_X32 251 AS2( movd [esp+16], mm3)
253 AS2( movd [esp+8], mm3)
257 ASS( pshufw mm3, mm1, 1, 0, 3, 2)
258 AS2( pmuludq mm1, mm2)
259 AS2( pmuludq mm2, mm3)
260 AS2( pmuludq mm3, mm4)
261 AS2( movd mm4, [esp])
263 #if CRYPTOPP_BOOL_X32 264 AS2( movd mm4, [esp+8])
266 AS2( movd mm4, [esp+16])
268 AS2( movd mm4, [esp+4])
270 AS2( movd mm4, [esp+8])
273 AS2( movd [esp], mm0)
276 #if CRYPTOPP_BOOL_X32 277 AS2( movd [esp+8], mm1)
279 AS2( movd [esp+4], mm1)
287 #if CRYPTOPP_BOOL_X32 288 AS2( movd [esp+16], mm3)
290 AS2( movd [esp+8], mm3)
294 AS2( movd mm4, [esp])
296 #if CRYPTOPP_BOOL_X32 297 AS2( movd mm4, [esp+8])
299 AS2( movd mm4, [esp+16])
301 AS2( movd mm4, [esp+4])
303 AS2( movd mm4, [esp+8])
306 AS2( lea ebp, [8*ebx])
309 AS2( movd [esp], mm7)
312 #if CRYPTOPP_BOOL_X32 313 AS2( movd [esp+8], mm6)
315 AS2( movd [esp+4], mm6)
326 #define k0 [eax+2*8+2*4] 327 #define k1 [eax+2*8+3*4] 328 #define k2 [eax+2*8+0*4] 329 #define k3 [eax+2*8+1*4] 333 AS2( movd mm0, [esp])
338 #if CRYPTOPP_BOOL_X32 339 AS2( movd mm2, [esp+8])
341 AS2( movd mm2, [esp+4])
355 AS2( pmuludq mm0, k3)
357 AS2( pmuludq mm1, k2)
360 AS2( pmuludq mm2, mm6)
366 AS2( pmuludq mm3, mm7)
367 AS2( pmuludq mm4, mm7)
368 AS2( pmuludq mm5, mm6)
373 AS2( pmuludq mm1, k2)
378 AS2( pmuludq mm2, k3)
379 AS2( pmuludq mm3, mm7)
380 #if CRYPTOPP_BOOL_X32 381 AS2( movd [esp+16], mm0)
383 AS2( movd [esp+8], mm0)
386 AS2( pmuludq mm7, mm5)
387 AS2( pmuludq mm5, k3)
390 AS2( pmuludq mm1, k2)
395 AS2( pmuludq mm2, mm6)
396 AS2( pmuludq mm6, a0)
399 AS2( movd mm3, [esp])
402 AS2( pmuludq mm3, k3)
405 AS2( pmuludq mm1, k2)
407 #if CRYPTOPP_BOOL_X32 408 AS2( movd mm2, [esp+8])
410 AS2( movd mm2, [esp+4])
418 #if CRYPTOPP_BOOL_X32 419 AS2( movd mm7, [esp+16])
421 AS2( movd mm7, [esp+8])
446 #if CRYPTOPP_BOOL_X32 457 :
"m" (L1KeyLength),
"c" (blocksRemainingInWord64),
"S" (data),
"D" (nhK+tagPart*2),
"d" (m_isFirstBlock),
"a" (polyS+tagPart*4)
464 #if VMAC_BOOL_WORD128 465 #define DeclareNH(a) word128 a=0 466 #define MUL64(rh,rl,i1,i2) {word128 p = word128(i1)*(i2); rh = word64(p>>64); rl = word64(p);} 467 #define AccumulateNH(a, b, c) a += word128(b)*(c) 468 #define Multiply128(r, i1, i2) r = word128(word64(i1)) * word64(i2) 470 #if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER) 471 #define MUL32(a, b) __emulu(word32(a), word32(b)) 473 #define MUL32(a, b) ((word64)((word32)(a)) * (word32)(b)) 475 #if defined(CRYPTOPP_X64_ASM_AVAILABLE) 476 #define DeclareNH(a) word64 a##0=0, a##1=0 477 #define MUL64(rh,rl,i1,i2) asm ("mulq %3" : "=a"(rl), "=d"(rh) : "a"(i1), "g"(i2) : "cc"); 478 #define AccumulateNH(a, b, c) asm ("mulq %3; addq %%rax, %0; adcq %%rdx, %1" : "+r"(a##0), "+r"(a##1) : "a"(b), "g"(c) : "%rdx", "cc"); 479 #define ADD128(rh,rl,ih,il) asm ("addq %3, %1; adcq %2, %0" : "+r"(rh),"+r"(rl) : "r"(ih),"r"(il) : "cc"); 480 #elif defined(_MSC_VER) && !CRYPTOPP_BOOL_SLOW_WORD64 481 #define DeclareNH(a) word64 a##0=0, a##1=0 482 #define MUL64(rh,rl,i1,i2) (rl) = _umul128(i1,i2,&(rh)); 483 #define AccumulateNH(a, b, c) {\ 485 pl = _umul128(b,c,&ph);\ 487 a##1 += ph + (a##0 < pl);} 489 #define VMAC_BOOL_32BIT 1 490 #define DeclareNH(a) word64 a##0=0, a##1=0, a##2=0 491 #define MUL64(rh,rl,i1,i2) \ 492 { word64 _i1 = (i1), _i2 = (i2); \ 493 word64 m1= MUL32(_i1,_i2>>32); \ 494 word64 m2= MUL32(_i1>>32,_i2); \ 495 rh = MUL32(_i1>>32,_i2>>32); \ 496 rl = MUL32(_i1,_i2); \ 497 ADD128(rh,rl,(m1 >> 32),(m1 << 32)); \ 498 ADD128(rh,rl,(m2 >> 32),(m2 << 32)); \ 500 #define AccumulateNH(a, b, c) {\ 501 word64 p = MUL32(b, c);\ 502 a##1 += word32((p)>>32);\ 504 p = MUL32((b)>>32, c);\ 505 a##2 += word32((p)>>32);\ 507 p = MUL32((b)>>32, (c)>>32);\ 509 p = MUL32(b, (c)>>32);\ 511 a##2 += word32(p>>32);} 514 #ifndef VMAC_BOOL_32BIT 515 #define VMAC_BOOL_32BIT 0 518 #define ADD128(rh,rl,ih,il) \ 519 { word64 _il = (il); \ 521 (rh) += (ih) + ((rl) < (_il)); \ 525 #if !(defined(_MSC_VER) && _MSC_VER < 1300) 526 template <
bool T_128BitTag>
528 void VMAC_Base::VHASH_Update_Template(
const word64 *data,
size_t blocksRemainingInWord64)
530 #define INNER_LOOP_ITERATION(j) {\ 531 word64 d0 = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, data[i+2*j+0]);\ 532 word64 d1 = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, data[i+2*j+1]);\ 533 AccumulateNH(nhA, d0+nhK[i+2*j+0], d1+nhK[i+2*j+1]);\ 535 AccumulateNH(nhB, d0+nhK[i+2*j+2], d1+nhK[i+2*j+3]);\ 538 #if (defined(_MSC_VER) && _MSC_VER < 1300) 539 bool T_128BitTag = m_is128;
541 size_t L1KeyLengthInWord64 = m_L1KeyLength / 8;
542 size_t innerLoopEnd = L1KeyLengthInWord64;
543 const word64 *nhK = m_nhKey();
544 word64 *polyS = m_polyState();
545 bool isFirstBlock =
true;
549 #if VMAC_BOOL_WORD128 552 word64 ah1=0, al1=0, ah2=0, al2=0;
554 word64 kh1, kl1, kh2, kl2;
555 kh1=(polyS+0*4+2)[0]; kl1=(polyS+0*4+2)[1];
558 kh2=(polyS+1*4+2)[0]; kl2=(polyS+1*4+2)[1];
568 if (blocksRemainingInWord64 < L1KeyLengthInWord64)
570 if (blocksRemainingInWord64 % 8)
572 innerLoopEnd = blocksRemainingInWord64 % 8;
573 for (; i<innerLoopEnd; i+=2)
574 INNER_LOOP_ITERATION(0);
576 innerLoopEnd = blocksRemainingInWord64;
578 for (; i<innerLoopEnd; i+=8)
580 INNER_LOOP_ITERATION(0);
581 INNER_LOOP_ITERATION(1);
582 INNER_LOOP_ITERATION(2);
583 INNER_LOOP_ITERATION(3);
585 blocksRemainingInWord64 -= innerLoopEnd;
586 data += innerLoopEnd;
589 word32 nh0[2], nh1[2];
592 nh0[0] = word32(nhA0);
593 nhA1 += (nhA0 >> 32);
594 nh1[0] = word32(nhA1);
595 nh2[0] = (nhA2 + (nhA1 >> 32)) & m62;
599 nh0[1] = word32(nhB0);
600 nhB1 += (nhB0 >> 32);
601 nh1[1] = word32(nhB1);
602 nh2[1] = (nhB2 + (nhB1 >> 32)) & m62;
605 #define a0 (((word32 *)(polyS+i*4))[2+NativeByteOrder::ToEnum()]) 606 #define a1 (*(((word32 *)(polyS+i*4))+3-NativeByteOrder::ToEnum())) // workaround for GCC 3.2 607 #define a2 (((word32 *)(polyS+i*4))[0+NativeByteOrder::ToEnum()]) 608 #define a3 (*(((word32 *)(polyS+i*4))+1-NativeByteOrder::ToEnum())) 609 #define aHi ((polyS+i*4)[0]) 610 #define k0 (((word32 *)(polyS+i*4+2))[2+NativeByteOrder::ToEnum()]) 611 #define k1 (*(((word32 *)(polyS+i*4+2))+3-NativeByteOrder::ToEnum())) 612 #define k2 (((word32 *)(polyS+i*4+2))[0+NativeByteOrder::ToEnum()]) 613 #define k3 (*(((word32 *)(polyS+i*4+2))+1-NativeByteOrder::ToEnum())) 614 #define kHi ((polyS+i*4+2)[0]) 618 isFirstBlock =
false;
621 m_isFirstBlock =
false;
622 for (i=0; i<=(size_t)T_128BitTag; i++)
624 word64 t = (word64)nh0[i] + k0;
626 t = (t >> 32) + nh1[i] + k1;
628 aHi = (t >> 32) + nh2[i] + kHi;
633 for (i=0; i<=(size_t)T_128BitTag; i++)
649 t = (word64(word32(p) & 0x7fffffff) << 32) | t2;
653 p += MUL32(a1, 2*k3);
654 p += MUL32(a2, 2*k2);
655 p += MUL32(a3, 2*k1);
661 p += MUL32(a2, 2*k3);
662 p += MUL32(a3, 2*k2);
678 #else // #if VMAC_BOOL_32BIT 681 isFirstBlock =
false;
684 m_isFirstBlock =
false;
685 #if VMAC_BOOL_WORD128 686 #define first_poly_step(a, kh, kl, m) a = (m & m126) + ((word128(kh) << 64) | kl) 688 first_poly_step(a1, kh1, kl1, nhA);
690 first_poly_step(a2, kh2, kl2, nhB);
692 #define first_poly_step(ah, al, kh, kl, mh, ml) {\ 694 ADD128(mh, ml, kh, kl); \ 697 first_poly_step(ah1, al1, kh1, kl1, nhA1, nhA0);
699 first_poly_step(ah2, al2, kh2, kl2, nhB1, nhB0);
705 #if VMAC_BOOL_WORD128 706 a1 = (word128((polyS+0*4)[0]) << 64) | (polyS+0*4)[1];
708 ah1=(polyS+0*4)[0]; al1=(polyS+0*4)[1];
712 #if VMAC_BOOL_WORD128 713 a2 = (word128((polyS+1*4)[0]) << 64) | (polyS+1*4)[1];
715 ah2=(polyS+1*4)[0]; al2=(polyS+1*4)[1];
721 #if VMAC_BOOL_WORD128 722 #define poly_step(a, kh, kl, m) \ 723 { word128 t1, t2, t3, t4;\ 724 Multiply128(t2, a>>64, kl);\ 725 Multiply128(t3, a, kh);\ 726 Multiply128(t1, a, kl);\ 727 Multiply128(t4, a>>64, 2*kh);\ 731 a = (word128(word64(t2)&m63) << 64) | word64(t4);\ 736 poly_step(a1, kh1, kl1, nhA);
738 poly_step(a2, kh2, kl2, nhB);
740 #define poly_step(ah, al, kh, kl, mh, ml) \ 741 { word64 t1h, t1l, t2h, t2l, t3h, t3l, z=0; \ 743 MUL64(t2h,t2l,ah,kl); \ 744 MUL64(t3h,t3l,al,kh); \ 745 MUL64(t1h,t1l,ah,2*kh); \ 746 MUL64(ah,al,al,kl); \ 748 ADD128(t2h,t2l,t3h,t3l); \ 750 ADD128(ah,al,t1h,t1l); \ 753 ADD128(t2h,ah,z,t2l); \ 755 t2h += t2h + (ah >> 63); \ 759 ADD128(ah,al,mh,ml); \ 760 ADD128(ah,al,z,t2h); \ 763 poly_step(ah1, al1, kh1, kl1, nhA1, nhA0);
765 poly_step(ah2, al2, kh2, kl2, nhB1, nhB0);
767 #endif // #if VMAC_BOOL_32BIT 768 }
while (blocksRemainingInWord64);
770 #if VMAC_BOOL_WORD128 771 (polyS+0*4)[0]=word64(a1>>64); (polyS+0*4)[1]=word64(a1);
774 (polyS+1*4)[0]=word64(a2>>64); (polyS+1*4)[1]=word64(a2);
776 #elif !VMAC_BOOL_32BIT 777 (polyS+0*4)[0]=ah1; (polyS+0*4)[1]=al1;
780 (polyS+1*4)[0]=ah2; (polyS+1*4)[1]=al2;
785 inline void VMAC_Base::VHASH_Update(
const word64 *data,
size_t blocksRemainingInWord64)
787 #if (CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && (CRYPTOPP_BOOL_X86 || (CRYPTOPP_BOOL_X32 && !defined(CRYPTOPP_DISABLE_VMAC_ASM)))) 790 VHASH_Update_SSE2(data, blocksRemainingInWord64, 0);
792 VHASH_Update_SSE2(data, blocksRemainingInWord64, 1);
793 m_isFirstBlock =
false;
798 #if defined(_MSC_VER) && _MSC_VER < 1300 799 VHASH_Update_Template(data, blocksRemainingInWord64);
802 VHASH_Update_Template<true>(data, blocksRemainingInWord64);
804 VHASH_Update_Template<false>(data, blocksRemainingInWord64);
809 size_t VMAC_Base::HashMultipleBlocks(
const word64 *data,
size_t length)
811 size_t remaining =
ModPowerOf2(length, m_L1KeyLength);
812 VHASH_Update(data, (length-remaining)/8);
816 static word64 L3Hash(
const word64 *input,
const word64 *l3Key,
size_t len)
818 word64 rh, rl, t, z=0;
819 word64 p1 = input[0], p2 = input[1];
820 word64 k1 = l3Key[0], k2 = l3Key[1];
825 ADD128(p1, p2, len, t);
827 t = (p1 > m63) + ((p1 == m63) & (p2 == m64));
828 ADD128(p1, p2, z, t);
834 t += (word32)t > 0xfffffffeU;
840 p1 += (0 - (p1 < k1)) & 257;
842 p2 += (0 - (p2 < k2)) & 257;
845 MUL64(rh, rl, p1, p2);
847 ADD128(t, rl, z, rh);
849 ADD128(t, rl, z, rh);
852 rl += (0 - (rl < t)) & 257;
853 rl += (0 - (rl > p64-1)) & 257;
859 size_t len =
ModPowerOf2(GetBitCountLo()/8, m_L1KeyLength);
863 memset(m_data()+len, 0, (0-len)%16);
864 VHASH_Update(DataBuf(), ((len+15)/16)*2);
867 else if (m_isFirstBlock)
870 m_polyState()[0] = m_polyState()[2];
871 m_polyState()[1] = m_polyState()[3];
874 m_polyState()[4] = m_polyState()[6];
875 m_polyState()[5] = m_polyState()[7];
882 t[0] = L3Hash(m_polyState(), m_l3Key(), len) + GetWord<word64>(
true, BIG_ENDIAN_ORDER, m_pad());
883 t[1] = L3Hash(m_polyState()+4, m_l3Key()+2, len) + GetWord<word64>(
true, BIG_ENDIAN_ORDER, m_pad()+8);
886 PutWord(
false, BIG_ENDIAN_ORDER, mac, t[0]);
887 PutWord(
false, BIG_ENDIAN_ORDER, mac+8, t[1]);
893 memcpy(mac, t, size);
898 word64 t = L3Hash(m_polyState(), m_l3Key(), len);
899 t += GetWord<word64>(
true, BIG_ENDIAN_ORDER, m_pad() + (m_nonce()[
IVSize()-1]&1) * 8);
901 PutWord(
false, BIG_ENDIAN_ORDER, mac, t);
905 memcpy(mac, &t, size);
Standard names for retrieving values by name when working with NameValuePairs.
const char * DigestSize()
int, in bytes
An invalid argument was detected.
virtual void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms=g_nullNameValuePairs)
Sets or reset the key of this object.
T2 ModPowerOf2(const T1 &a, const T2 &b)
Tests whether the residue of a value is a power of 2.
void CleanNew(size_type newSize)
Change size without preserving contents.
Library configuration file.
Interface for random number generators.
SecByteBlock is a SecBlock<byte> typedef.
Interface for one direction (encryption or decryption) of a block cipher.
Classes and functions for secure memory allocations.
int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
A method was called which was not implemented.
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianess.
void UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs ¶ms)
Sets the key for this object without performing parameter validation.
Classes, functions, intrinsics and features for X86, X32 nd X64 assembly.
void TruncatedFinal(byte *mac, size_t size)
Computes the hash of the current message.
const char * IV()
ConstByteArrayParameter, also accepts const byte * for backwards compatibility.
unsigned int IVSize() const
Returns length of the IV accepted by this object.
bool VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count)
Performs a near constant-time comparison of two equally sized buffers.
unsigned int OptimalDataAlignment() const
Provides input and output data alignment for optimal performance.
const char * L1KeyLength()
int, in bytes
Crypto++ library namespace.
void Resynchronize(const byte *nonce, int length=-1)
resynchronize with an IV. ivLength=-1 means use IVSize()
virtual void GetNextIV(RandomNumberGenerator &rng, byte *iv)
Gets a secure IV for the next message.
void GetNextIV(RandomNumberGenerator &rng, byte *IV)
Gets a secure IV for the next message.
Interface for retrieving values given their names.
byte * BytePtr()
Provides a byte pointer to the first element in the memory block.