1#ifndef CRYPTOPP_MISC_H
2#define CRYPTOPP_MISC_H
3
4#include "cryptlib.h"
5#include "smartptr.h"
6#include <string.h>		// for memcpy and memmove
7
8#ifdef _MSC_VER
9	#include <stdlib.h>
10	#if _MSC_VER >= 1400
11		// VC2005 workaround: disable declarations that conflict with winnt.h
12		#define _interlockedbittestandset CRYPTOPP_DISABLED_INTRINSIC_1
13		#define _interlockedbittestandreset CRYPTOPP_DISABLED_INTRINSIC_2
14		#define _interlockedbittestandset64 CRYPTOPP_DISABLED_INTRINSIC_3
15		#define _interlockedbittestandreset64 CRYPTOPP_DISABLED_INTRINSIC_4
16		#include <intrin.h>
17		#undef _interlockedbittestandset
18		#undef _interlockedbittestandreset
19		#undef _interlockedbittestandset64
20		#undef _interlockedbittestandreset64
21		#define CRYPTOPP_FAST_ROTATE(x) 1
22	#elif _MSC_VER >= 1300
23		#define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64)
24	#else
25		#define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
26	#endif
27#elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \
28	(defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM)))
29	#define CRYPTOPP_FAST_ROTATE(x) ((x) == 32)
30#elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86)	// depend on GCC's peephole optimization to generate rotate instructions
31	#define CRYPTOPP_FAST_ROTATE(x) 1
32#else
33	#define CRYPTOPP_FAST_ROTATE(x) 0
34#endif
35
36#ifdef __BORLANDC__
37#include <mem.h>
38#endif
39
40#if defined(__GNUC__) && defined(__linux__)
41#define CRYPTOPP_BYTESWAP_AVAILABLE
42#include <byteswap.h>
43#endif
44
45NAMESPACE_BEGIN(CryptoPP)
46
47// ************** compile-time assertion ***************
48
49template <bool b>
50struct CompileAssert
51{
52	static char dummy[2*b-1];
53};
54
55#define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__)
56#if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS)
57#define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance)
58#else
59#define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) static CompileAssert<(assertion)> CRYPTOPP_ASSERT_JOIN(cryptopp_assert_, instance)
60#endif
61#define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y)
62#define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y
63
64// ************** misc classes ***************
65
66class CRYPTOPP_DLL Empty
67{
68};
69
70//! _
71template <class BASE1, class BASE2>
72class CRYPTOPP_NO_VTABLE TwoBases : public BASE1, public BASE2
73{
74};
75
76//! _
77template <class BASE1, class BASE2, class BASE3>
78class CRYPTOPP_NO_VTABLE ThreeBases : public BASE1, public BASE2, public BASE3
79{
80};
81
82template <class T>
83class ObjectHolder
84{
85protected:
86	T m_object;
87};
88
89class NotCopyable
90{
91public:
92	NotCopyable() {}
93private:
94    NotCopyable(const NotCopyable &);
95    void operator=(const NotCopyable &);
96};
97
98template <class T>
99struct NewObject
100{
101	T* operator()() const {return new T;}
102};
103
104/*! This function safely initializes a static object in a multithreaded environment without using locks.
105	It may leak memory when two threads try to initialize the static object at the same time
106	but this should be acceptable since each static object is only initialized once per session.
107*/
108template <class T, class F = NewObject<T>, int instance=0>
109class Singleton
110{
111public:
112	Singleton(F objectFactory = F()) : m_objectFactory(objectFactory) {}
113
114	// prevent this function from being inlined
115	CRYPTOPP_NOINLINE const T & Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const;
116
117private:
118	F m_objectFactory;
119};
120
121template <class T, class F, int instance>
122const T & Singleton<T, F, instance>::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const
123{
124	static simple_ptr<T> s_pObject;
125	static char s_objectState = 0;
126
127retry:
128	switch (s_objectState)
129	{
130	case 0:
131		s_objectState = 1;
132		try
133		{
134			s_pObject.m_p = m_objectFactory();
135		}
136		catch(...)
137		{
138			s_objectState = 0;
139			throw;
140		}
141		s_objectState = 2;
142		break;
143	case 1:
144		goto retry;
145	default:
146		break;
147	}
148	return *s_pObject.m_p;
149}
150
151// ************** misc functions ***************
152
153#if (!__STDC_WANT_SECURE_LIB__)
154inline void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
155{
156	if (count > sizeInBytes)
157		throw InvalidArgument("memcpy_s: buffer overflow");
158	memcpy(dest, src, count);
159}
160
161inline void memmove_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
162{
163	if (count > sizeInBytes)
164		throw InvalidArgument("memmove_s: buffer overflow");
165	memmove(dest, src, count);
166}
167#endif
168
169inline void * memset_z(void *ptr, int value, size_t num)
170{
171// avoid extranous warning on GCC 4.3.2 Ubuntu 8.10
172#if CRYPTOPP_GCC_VERSION >= 30001
173	if (__builtin_constant_p(num) && num==0)
174		return ptr;
175#endif
176	return memset(ptr, value, num);
177}
178
179// can't use std::min or std::max in MSVC60 or Cygwin 1.1.0
180template <class T> inline const T& STDMIN(const T& a, const T& b)
181{
182	return b < a ? b : a;
183}
184
185template <class T1, class T2> inline const T1 UnsignedMin(const T1& a, const T2& b)
186{
187	CRYPTOPP_COMPILE_ASSERT((sizeof(T1)<=sizeof(T2) && T2(-1)>0) || (sizeof(T1)>sizeof(T2) && T1(-1)>0));
188	assert(a==0 || a>0);	// GCC workaround: get rid of the warning "comparison is always true due to limited range of data type"
189	assert(b>=0);
190
191	if (sizeof(T1)<=sizeof(T2))
192		return b < (T2)a ? (T1)b : a;
193	else
194		return (T1)b < a ? (T1)b : a;
195}
196
197template <class T> inline const T& STDMAX(const T& a, const T& b)
198{
199	return a < b ? b : a;
200}
201
202#define RETURN_IF_NONZERO(x) size_t returnedValue = x; if (returnedValue) return returnedValue
203
204// this version of the macro is fastest on Pentium 3 and Pentium 4 with MSVC 6 SP5 w/ Processor Pack
205#define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y)))
206// these may be faster on other CPUs/compilers
207// #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255)
208// #define GETBYTE(x, y) (((byte *)&(x))[y])
209
210#define CRYPTOPP_GET_BYTE_AS_BYTE(x, y) byte((x)>>(8*(y)))
211
212template <class T>
213unsigned int Parity(T value)
214{
215	for (unsigned int i=8*sizeof(value)/2; i>0; i/=2)
216		value ^= value >> i;
217	return (unsigned int)value&1;
218}
219
220template <class T>
221unsigned int BytePrecision(const T &value)
222{
223	if (!value)
224		return 0;
225
226	unsigned int l=0, h=8*sizeof(value);
227
228	while (h-l > 8)
229	{
230		unsigned int t = (l+h)/2;
231		if (value >> t)
232			l = t;
233		else
234			h = t;
235	}
236
237	return h/8;
238}
239
240template <class T>
241unsigned int BitPrecision(const T &value)
242{
243	if (!value)
244		return 0;
245
246	unsigned int l=0, h=8*sizeof(value);
247
248	while (h-l > 1)
249	{
250		unsigned int t = (l+h)/2;
251		if (value >> t)
252			l = t;
253		else
254			h = t;
255	}
256
257	return h;
258}
259
260template <class T>
261inline T Crop(T value, size_t size)
262{
263	if (size < 8*sizeof(value))
264    	return T(value & ((T(1) << size) - 1));
265	else
266		return value;
267}
268
269template <class T1, class T2>
270inline bool SafeConvert(T1 from, T2 &to)
271{
272	to = (T2)from;
273	if (from != to || (from > 0) != (to > 0))
274		return false;
275	return true;
276}
277
278inline size_t BitsToBytes(size_t bitCount)
279{
280	return ((bitCount+7)/(8));
281}
282
283inline size_t BytesToWords(size_t byteCount)
284{
285	return ((byteCount+WORD_SIZE-1)/WORD_SIZE);
286}
287
288inline size_t BitsToWords(size_t bitCount)
289{
290	return ((bitCount+WORD_BITS-1)/(WORD_BITS));
291}
292
293inline size_t BitsToDwords(size_t bitCount)
294{
295	return ((bitCount+2*WORD_BITS-1)/(2*WORD_BITS));
296}
297
298CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *buf, const byte *mask, size_t count);
299CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *output, const byte *input, const byte *mask, size_t count);
300
301CRYPTOPP_DLL bool CRYPTOPP_API VerifyBufsEqual(const byte *buf1, const byte *buf2, size_t count);
302
303template <class T>
304inline bool IsPowerOf2(const T &n)
305{
306	return n > 0 && (n & (n-1)) == 0;
307}
308
309template <class T1, class T2>
310inline T2 ModPowerOf2(const T1 &a, const T2 &b)
311{
312	assert(IsPowerOf2(b));
313	return T2(a) & (b-1);
314}
315
316template <class T1, class T2>
317inline T1 RoundDownToMultipleOf(const T1 &n, const T2 &m)
318{
319	if (IsPowerOf2(m))
320		return n - ModPowerOf2(n, m);
321	else
322		return n - n%m;
323}
324
325template <class T1, class T2>
326inline T1 RoundUpToMultipleOf(const T1 &n, const T2 &m)
327{
328	if (n+m-1 < n)
329		throw InvalidArgument("RoundUpToMultipleOf: integer overflow");
330	return RoundDownToMultipleOf(n+m-1, m);
331}
332
333template <class T>
334inline unsigned int GetAlignmentOf(T *dummy=NULL)	// VC60 workaround
335{
336#ifdef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
337	if (sizeof(T) < 16)
338		return 1;
339#endif
340
341#if (_MSC_VER >= 1300)
342	return __alignof(T);
343#elif defined(__GNUC__)
344	return __alignof__(T);
345#elif CRYPTOPP_BOOL_SLOW_WORD64
346	return UnsignedMin(4U, sizeof(T));
347#else
348	return sizeof(T);
349#endif
350}
351
352inline bool IsAlignedOn(const void *p, unsigned int alignment)
353{
354	return alignment==1 || (IsPowerOf2(alignment) ? ModPowerOf2((size_t)p, alignment) == 0 : (size_t)p % alignment == 0);
355}
356
357template <class T>
358inline bool IsAligned(const void *p, T *dummy=NULL)	// VC60 workaround
359{
360	return IsAlignedOn(p, GetAlignmentOf<T>());
361}
362
363#ifdef IS_LITTLE_ENDIAN
364	typedef LittleEndian NativeByteOrder;
365#else
366	typedef BigEndian NativeByteOrder;
367#endif
368
369inline ByteOrder GetNativeByteOrder()
370{
371	return NativeByteOrder::ToEnum();
372}
373
374inline bool NativeByteOrderIs(ByteOrder order)
375{
376	return order == GetNativeByteOrder();
377}
378
379template <class T>
380std::string IntToString(T a, unsigned int base = 10)
381{
382	if (a == 0)
383		return "0";
384	bool negate = false;
385	if (a < 0)
386	{
387		negate = true;
388		a = 0-a;	// VC .NET does not like -a
389	}
390	std::string result;
391	while (a > 0)
392	{
393		T digit = a % base;
394		result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result;
395		a /= base;
396	}
397	if (negate)
398		result = "-" + result;
399	return result;
400}
401
402template <class T1, class T2>
403inline T1 SaturatingSubtract(const T1 &a, const T2 &b)
404{
405	return T1((a > b) ? (a - b) : 0);
406}
407
408template <class T>
409inline CipherDir GetCipherDir(const T &obj)
410{
411	return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION;
412}
413
414CRYPTOPP_DLL void CRYPTOPP_API CallNewHandler();
415
416inline void IncrementCounterByOne(byte *inout, unsigned int s)
417{
418	for (int i=s-1, carry=1; i>=0 && carry; i--)
419		carry = !++inout[i];
420}
421
422inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s)
423{
424	int i, carry;
425	for (i=s-1, carry=1; i>=0 && carry; i--)
426		carry = ((output[i] = input[i]+1) == 0);
427	memcpy_s(output, s, input, i+1);
428}
429
430// ************** rotate functions ***************
431
432template <class T> inline T rotlFixed(T x, unsigned int y)
433{
434	assert(y < sizeof(T)*8);
435	return T((x<<y) | (x>>(sizeof(T)*8-y)));
436}
437
438template <class T> inline T rotrFixed(T x, unsigned int y)
439{
440	assert(y < sizeof(T)*8);
441	return T((x>>y) | (x<<(sizeof(T)*8-y)));
442}
443
444template <class T> inline T rotlVariable(T x, unsigned int y)
445{
446	assert(y < sizeof(T)*8);
447	return T((x<<y) | (x>>(sizeof(T)*8-y)));
448}
449
450template <class T> inline T rotrVariable(T x, unsigned int y)
451{
452	assert(y < sizeof(T)*8);
453	return T((x>>y) | (x<<(sizeof(T)*8-y)));
454}
455
456template <class T> inline T rotlMod(T x, unsigned int y)
457{
458	y %= sizeof(T)*8;
459	return T((x<<y) | (x>>(sizeof(T)*8-y)));
460}
461
462template <class T> inline T rotrMod(T x, unsigned int y)
463{
464	y %= sizeof(T)*8;
465	return T((x>>y) | (x<<(sizeof(T)*8-y)));
466}
467
468#ifdef _MSC_VER
469
470template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
471{
472	assert(y < 8*sizeof(x));
473	return y ? _lrotl(x, y) : x;
474}
475
476template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
477{
478	assert(y < 8*sizeof(x));
479	return y ? _lrotr(x, y) : x;
480}
481
482template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
483{
484	assert(y < 8*sizeof(x));
485	return _lrotl(x, y);
486}
487
488template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
489{
490	assert(y < 8*sizeof(x));
491	return _lrotr(x, y);
492}
493
494template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
495{
496	return _lrotl(x, y);
497}
498
499template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
500{
501	return _lrotr(x, y);
502}
503
504#endif // #ifdef _MSC_VER
505
506#if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER)
507// Intel C++ Compiler 10.0 calls a function instead of using the rotate instruction when using these instructions
508
509template<> inline word64 rotlFixed<word64>(word64 x, unsigned int y)
510{
511	assert(y < 8*sizeof(x));
512	return y ? _rotl64(x, y) : x;
513}
514
515template<> inline word64 rotrFixed<word64>(word64 x, unsigned int y)
516{
517	assert(y < 8*sizeof(x));
518	return y ? _rotr64(x, y) : x;
519}
520
521template<> inline word64 rotlVariable<word64>(word64 x, unsigned int y)
522{
523	assert(y < 8*sizeof(x));
524	return _rotl64(x, y);
525}
526
527template<> inline word64 rotrVariable<word64>(word64 x, unsigned int y)
528{
529	assert(y < 8*sizeof(x));
530	return _rotr64(x, y);
531}
532
533template<> inline word64 rotlMod<word64>(word64 x, unsigned int y)
534{
535	return _rotl64(x, y);
536}
537
538template<> inline word64 rotrMod<word64>(word64 x, unsigned int y)
539{
540	return _rotr64(x, y);
541}
542
543#endif // #if _MSC_VER >= 1310
544
545#if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER)
546// Intel C++ Compiler 10.0 gives undefined externals with these
547
548template<> inline word16 rotlFixed<word16>(word16 x, unsigned int y)
549{
550	assert(y < 8*sizeof(x));
551	return y ? _rotl16(x, y) : x;
552}
553
554template<> inline word16 rotrFixed<word16>(word16 x, unsigned int y)
555{
556	assert(y < 8*sizeof(x));
557	return y ? _rotr16(x, y) : x;
558}
559
560template<> inline word16 rotlVariable<word16>(word16 x, unsigned int y)
561{
562	assert(y < 8*sizeof(x));
563	return _rotl16(x, y);
564}
565
566template<> inline word16 rotrVariable<word16>(word16 x, unsigned int y)
567{
568	assert(y < 8*sizeof(x));
569	return _rotr16(x, y);
570}
571
572template<> inline word16 rotlMod<word16>(word16 x, unsigned int y)
573{
574	return _rotl16(x, y);
575}
576
577template<> inline word16 rotrMod<word16>(word16 x, unsigned int y)
578{
579	return _rotr16(x, y);
580}
581
582template<> inline byte rotlFixed<byte>(byte x, unsigned int y)
583{
584	assert(y < 8*sizeof(x));
585	return y ? _rotl8(x, y) : x;
586}
587
588template<> inline byte rotrFixed<byte>(byte x, unsigned int y)
589{
590	assert(y < 8*sizeof(x));
591	return y ? _rotr8(x, y) : x;
592}
593
594template<> inline byte rotlVariable<byte>(byte x, unsigned int y)
595{
596	assert(y < 8*sizeof(x));
597	return _rotl8(x, y);
598}
599
600template<> inline byte rotrVariable<byte>(byte x, unsigned int y)
601{
602	assert(y < 8*sizeof(x));
603	return _rotr8(x, y);
604}
605
606template<> inline byte rotlMod<byte>(byte x, unsigned int y)
607{
608	return _rotl8(x, y);
609}
610
611template<> inline byte rotrMod<byte>(byte x, unsigned int y)
612{
613	return _rotr8(x, y);
614}
615
616#endif // #if _MSC_VER >= 1400
617
618#if (defined(__MWERKS__) && TARGET_CPU_PPC)
619
620template<> inline word32 rotlFixed<word32>(word32 x, unsigned int y)
621{
622	assert(y < 32);
623	return y ? __rlwinm(x,y,0,31) : x;
624}
625
626template<> inline word32 rotrFixed<word32>(word32 x, unsigned int y)
627{
628	assert(y < 32);
629	return y ? __rlwinm(x,32-y,0,31) : x;
630}
631
632template<> inline word32 rotlVariable<word32>(word32 x, unsigned int y)
633{
634	assert(y < 32);
635	return (__rlwnm(x,y,0,31));
636}
637
638template<> inline word32 rotrVariable<word32>(word32 x, unsigned int y)
639{
640	assert(y < 32);
641	return (__rlwnm(x,32-y,0,31));
642}
643
644template<> inline word32 rotlMod<word32>(word32 x, unsigned int y)
645{
646	return (__rlwnm(x,y,0,31));
647}
648
649template<> inline word32 rotrMod<word32>(word32 x, unsigned int y)
650{
651	return (__rlwnm(x,32-y,0,31));
652}
653
654#endif // #if (defined(__MWERKS__) && TARGET_CPU_PPC)
655
656// ************** endian reversal ***************
657
658template <class T>
659inline unsigned int GetByte(ByteOrder order, T value, unsigned int index)
660{
661	if (order == LITTLE_ENDIAN_ORDER)
662		return GETBYTE(value, index);
663	else
664		return GETBYTE(value, sizeof(T)-index-1);
665}
666
667inline byte ByteReverse(byte value)
668{
669	return value;
670}
671
672inline word16 ByteReverse(word16 value)
673{
674#ifdef CRYPTOPP_BYTESWAP_AVAILABLE
675	return bswap_16(value);
676#elif defined(_MSC_VER) && _MSC_VER >= 1300
677	return _byteswap_ushort(value);
678#else
679	return rotlFixed(value, 8U);
680#endif
681}
682
683inline word32 ByteReverse(word32 value)
684{
685#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE)
686	__asm__ ("bswap %0" : "=r" (value) : "0" (value));
687	return value;
688#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
689	return bswap_32(value);
690#elif defined(__MWERKS__) && TARGET_CPU_PPC
691	return (word32)__lwbrx(&value,0);
692#elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL))
693	return _byteswap_ulong(value);
694#elif CRYPTOPP_FAST_ROTATE(32)
695	// 5 instructions with rotate instruction, 9 without
696	return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
697#else
698	// 6 instructions with rotate instruction, 8 without
699	value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
700	return rotlFixed(value, 16U);
701#endif
702}
703
704inline word64 ByteReverse(word64 value)
705{
706#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__x86_64__)
707	__asm__ ("bswap %0" : "=r" (value) : "0" (value));
708	return value;
709#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE)
710	return bswap_64(value);
711#elif defined(_MSC_VER) && _MSC_VER >= 1300
712	return _byteswap_uint64(value);
713#elif CRYPTOPP_BOOL_SLOW_WORD64
714	return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32));
715#else
716	value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8);
717	value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16);
718	return rotlFixed(value, 32U);
719#endif
720}
721
722inline byte BitReverse(byte value)
723{
724	value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1);
725	value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2);
726	return rotlFixed(value, 4U);
727}
728
729inline word16 BitReverse(word16 value)
730{
731	value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1);
732	value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2);
733	value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4);
734	return ByteReverse(value);
735}
736
737inline word32 BitReverse(word32 value)
738{
739	value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1);
740	value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2);
741	value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4);
742	return ByteReverse(value);
743}
744
745inline word64 BitReverse(word64 value)
746{
747#if CRYPTOPP_BOOL_SLOW_WORD64
748	return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32));
749#else
750	value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1);
751	value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2);
752	value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4);
753	return ByteReverse(value);
754#endif
755}
756
757template <class T>
758inline T BitReverse(T value)
759{
760	if (sizeof(T) == 1)
761		return (T)BitReverse((byte)value);
762	else if (sizeof(T) == 2)
763		return (T)BitReverse((word16)value);
764	else if (sizeof(T) == 4)
765		return (T)BitReverse((word32)value);
766	else
767	{
768		assert(sizeof(T) == 8);
769		return (T)BitReverse((word64)value);
770	}
771}
772
773template <class T>
774inline T ConditionalByteReverse(ByteOrder order, T value)
775{
776	return NativeByteOrderIs(order) ? value : ByteReverse(value);
777}
778
779template <class T>
780void ByteReverse(T *out, const T *in, size_t byteCount)
781{
782	assert(byteCount % sizeof(T) == 0);
783	size_t count = byteCount/sizeof(T);
784	for (size_t i=0; i<count; i++)
785		out[i] = ByteReverse(in[i]);
786}
787
788template <class T>
789inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, size_t byteCount)
790{
791	if (!NativeByteOrderIs(order))
792		ByteReverse(out, in, byteCount);
793	else if (in != out)
794		memcpy_s(out, byteCount, in, byteCount);
795}
796
797template <class T>
798inline void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen)
799{
800	const size_t U = sizeof(T);
801	assert(inlen <= outlen*U);
802	memcpy_s(out, outlen*U, in, inlen);
803	memset_z((byte *)out+inlen, 0, outlen*U-inlen);
804	ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U));
805}
806
807#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
808inline byte UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const byte *)
809{
810	return block[0];
811}
812
813inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word16 *)
814{
815	return (order == BIG_ENDIAN_ORDER)
816		? block[1] | (block[0] << 8)
817		: block[0] | (block[1] << 8);
818}
819
820inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word32 *)
821{
822	return (order == BIG_ENDIAN_ORDER)
823		? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24)
824		: word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24);
825}
826
827inline word64 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word64 *)
828{
829	return (order == BIG_ENDIAN_ORDER)
830		?
831		(word64(block[7]) |
832		(word64(block[6]) <<  8) |
833		(word64(block[5]) << 16) |
834		(word64(block[4]) << 24) |
835		(word64(block[3]) << 32) |
836		(word64(block[2]) << 40) |
837		(word64(block[1]) << 48) |
838		(word64(block[0]) << 56))
839		:
840		(word64(block[0]) |
841		(word64(block[1]) <<  8) |
842		(word64(block[2]) << 16) |
843		(word64(block[3]) << 24) |
844		(word64(block[4]) << 32) |
845		(word64(block[5]) << 40) |
846		(word64(block[6]) << 48) |
847		(word64(block[7]) << 56));
848}
849
850inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, byte value, const byte *xorBlock)
851{
852	block[0] = xorBlock ? (value ^ xorBlock[0]) : value;
853}
854
855inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word16 value, const byte *xorBlock)
856{
857	if (order == BIG_ENDIAN_ORDER)
858	{
859		if (xorBlock)
860		{
861			block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
862			block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
863		}
864		else
865		{
866			block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
867			block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
868		}
869	}
870	else
871	{
872		if (xorBlock)
873		{
874			block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
875			block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
876		}
877		else
878		{
879			block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
880			block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
881		}
882	}
883}
884
885inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word32 value, const byte *xorBlock)
886{
887	if (order == BIG_ENDIAN_ORDER)
888	{
889		if (xorBlock)
890		{
891			block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
892			block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
893			block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
894			block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
895		}
896		else
897		{
898			block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
899			block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
900			block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
901			block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
902		}
903	}
904	else
905	{
906		if (xorBlock)
907		{
908			block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
909			block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
910			block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
911			block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
912		}
913		else
914		{
915			block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
916			block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
917			block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
918			block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
919		}
920	}
921}
922
923inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word64 value, const byte *xorBlock)
924{
925	if (order == BIG_ENDIAN_ORDER)
926	{
927		if (xorBlock)
928		{
929			block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
930			block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
931			block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
932			block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
933			block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
934			block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
935			block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
936			block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
937		}
938		else
939		{
940			block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
941			block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
942			block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
943			block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
944			block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
945			block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
946			block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
947			block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
948		}
949	}
950	else
951	{
952		if (xorBlock)
953		{
954			block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
955			block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
956			block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
957			block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
958			block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
959			block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
960			block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
961			block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
962		}
963		else
964		{
965			block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0);
966			block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1);
967			block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2);
968			block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3);
969			block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4);
970			block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5);
971			block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6);
972			block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7);
973		}
974	}
975}
976#endif	// #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
977
978template <class T>
979inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block)
980{
981#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
982	if (!assumeAligned)
983		return UnalignedGetWordNonTemplate(order, block, (T*)NULL);
984	assert(IsAligned<T>(block));
985#endif
986	return ConditionalByteReverse(order, *reinterpret_cast<const T *>(block));
987}
988
989template <class T>
990inline void GetWord(bool assumeAligned, ByteOrder order, T &result, const byte *block)
991{
992	result = GetWord<T>(assumeAligned, order, block);
993}
994
995template <class T>
996inline void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock = NULL)
997{
998#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS
999	if (!assumeAligned)
1000		return UnalignedPutWordNonTemplate(order, block, value, xorBlock);
1001	assert(IsAligned<T>(block));
1002	assert(IsAligned<T>(xorBlock));
1003#endif
1004	*reinterpret_cast<T *>(block) = ConditionalByteReverse(order, value) ^ (xorBlock ? *reinterpret_cast<const T *>(xorBlock) : 0);
1005}
1006
1007template <class T, class B, bool A=false>
1008class GetBlock
1009{
1010public:
1011	GetBlock(const void *block)
1012		: m_block((const byte *)block) {}
1013
1014	template <class U>
1015	inline GetBlock<T, B, A> & operator()(U &x)
1016	{
1017		CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T));
1018		x = GetWord<T>(A, B::ToEnum(), m_block);
1019		m_block += sizeof(T);
1020		return *this;
1021	}
1022
1023private:
1024	const byte *m_block;
1025};
1026
1027template <class T, class B, bool A=false>
1028class PutBlock
1029{
1030public:
1031	PutBlock(const void *xorBlock, void *block)
1032		: m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {}
1033
1034	template <class U>
1035	inline PutBlock<T, B, A> & operator()(U x)
1036	{
1037		PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock);
1038		m_block += sizeof(T);
1039		if (m_xorBlock)
1040			m_xorBlock += sizeof(T);
1041		return *this;
1042	}
1043
1044private:
1045	const byte *m_xorBlock;
1046	byte *m_block;
1047};
1048
1049template <class T, class B, bool GA=false, bool PA=false>
1050struct BlockGetAndPut
1051{
1052	// function needed because of C++ grammatical ambiguity between expression-statements and declarations
1053	static inline GetBlock<T, B, GA> Get(const void *block) {return GetBlock<T, B, GA>(block);}
1054	typedef PutBlock<T, B, PA> Put;
1055};
1056
1057template <class T>
1058std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER)
1059{
1060	if (!NativeByteOrderIs(order))
1061		value = ByteReverse(value);
1062
1063	return std::string((char *)&value, sizeof(value));
1064}
1065
1066template <class T>
1067T StringToWord(const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER)
1068{
1069	T value = 0;
1070	memcpy_s(&value, sizeof(value), str.data(), UnsignedMin(str.size(), sizeof(value)));
1071	return NativeByteOrderIs(order) ? value : ByteReverse(value);
1072}
1073
1074// ************** help remove warning on g++ ***************
1075
1076template <bool overflow> struct SafeShifter;
1077
1078template<> struct SafeShifter<true>
1079{
1080	template <class T>
1081	static inline T RightShift(T value, unsigned int bits)
1082	{
1083		return 0;
1084	}
1085
1086	template <class T>
1087	static inline T LeftShift(T value, unsigned int bits)
1088	{
1089		return 0;
1090	}
1091};
1092
1093template<> struct SafeShifter<false>
1094{
1095	template <class T>
1096	static inline T RightShift(T value, unsigned int bits)
1097	{
1098		return value >> bits;
1099	}
1100
1101	template <class T>
1102	static inline T LeftShift(T value, unsigned int bits)
1103	{
1104		return value << bits;
1105	}
1106};
1107
1108template <unsigned int bits, class T>
1109inline T SafeRightShift(T value)
1110{
1111	return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits);
1112}
1113
1114template <unsigned int bits, class T>
1115inline T SafeLeftShift(T value)
1116{
1117	return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits);
1118}
1119
1120// ************** use one buffer for multiple data members ***************
1121
1122#define CRYPTOPP_BLOCK_1(n, t, s) t* m_##n() {return (t *)(m_aggregate+0);}     size_t SS1() {return       sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
1123#define CRYPTOPP_BLOCK_2(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS1());} size_t SS2() {return SS1()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
1124#define CRYPTOPP_BLOCK_3(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS2());} size_t SS3() {return SS2()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
1125#define CRYPTOPP_BLOCK_4(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS3());} size_t SS4() {return SS3()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
1126#define CRYPTOPP_BLOCK_5(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS4());} size_t SS5() {return SS4()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
1127#define CRYPTOPP_BLOCK_6(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS5());} size_t SS6() {return SS5()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
1128#define CRYPTOPP_BLOCK_7(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS6());} size_t SS7() {return SS6()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
1129#define CRYPTOPP_BLOCK_8(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS7());} size_t SS8() {return SS7()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);}
1130#define CRYPTOPP_BLOCKS_END(i) size_t SST() {return SS##i();} void AllocateBlocks() {m_aggregate.New(SST());} AlignedSecByteBlock m_aggregate;
1131
1132NAMESPACE_END
1133
1134#endif
1135