Botan
1.11.15
|
00001 /* 00002 * XOR operations 00003 * (C) 1999-2008 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #ifndef BOTAN_XOR_BUF_H__ 00009 #define BOTAN_XOR_BUF_H__ 00010 00011 #include <botan/types.h> 00012 #include <vector> 00013 00014 namespace Botan { 00015 00016 /** 00017 * XOR arrays. Postcondition out[i] = in[i] ^ out[i] forall i = 0...length 00018 * @param out the input/output buffer 00019 * @param in the read-only input buffer 00020 * @param length the length of the buffers 00021 */ 00022 template<typename T> 00023 void xor_buf(T out[], const T in[], size_t length) 00024 { 00025 while(length >= 8) 00026 { 00027 out[0] ^= in[0]; out[1] ^= in[1]; 00028 out[2] ^= in[2]; out[3] ^= in[3]; 00029 out[4] ^= in[4]; out[5] ^= in[5]; 00030 out[6] ^= in[6]; out[7] ^= in[7]; 00031 00032 out += 8; in += 8; length -= 8; 00033 } 00034 00035 for(size_t i = 0; i != length; ++i) 00036 out[i] ^= in[i]; 00037 } 00038 00039 /** 00040 * XOR arrays. Postcondition out[i] = in[i] ^ in2[i] forall i = 0...length 00041 * @param out the output buffer 00042 * @param in the first input buffer 00043 * @param in2 the second output buffer 00044 * @param length the length of the three buffers 00045 */ 00046 template<typename T> void xor_buf(T out[], 00047 const T in[], 00048 const T in2[], 00049 size_t length) 00050 { 00051 while(length >= 8) 00052 { 00053 out[0] = in[0] ^ in2[0]; 00054 out[1] = in[1] ^ in2[1]; 00055 out[2] = in[2] ^ in2[2]; 00056 out[3] = in[3] ^ in2[3]; 00057 out[4] = in[4] ^ in2[4]; 00058 out[5] = in[5] ^ in2[5]; 00059 out[6] = in[6] ^ in2[6]; 00060 out[7] = in[7] ^ in2[7]; 00061 00062 in += 8; in2 += 8; out += 8; length -= 8; 00063 } 00064 00065 for(size_t i = 0; i != length; ++i) 00066 out[i] = in[i] ^ in2[i]; 00067 } 00068 00069 #if BOTAN_TARGET_UNALIGNED_MEMORY_ACCESS_OK 00070 00071 template<> 00072 inline void xor_buf<byte>(byte out[], const byte in[], size_t length) 00073 { 00074 while(length >= 8) 00075 { 00076 *reinterpret_cast<u64bit*>(out) ^= *reinterpret_cast<const u64bit*>(in); 00077 out += 8; in += 8; length -= 8; 00078 } 00079 00080 for(size_t i = 0; i != length; ++i) 00081 out[i] ^= in[i]; 00082 } 00083 00084 template<> 00085 inline void xor_buf<byte>(byte out[], 00086 const byte in[], 00087 const byte in2[], 00088 size_t length) 00089 { 00090 while(length >= 8) 00091 { 00092 *reinterpret_cast<u64bit*>(out) = 00093 *reinterpret_cast<const u64bit*>(in) ^ 00094 *reinterpret_cast<const u64bit*>(in2); 00095 00096 in += 8; in2 += 8; out += 8; length -= 8; 00097 } 00098 00099 for(size_t i = 0; i != length; ++i) 00100 out[i] = in[i] ^ in2[i]; 00101 } 00102 00103 #endif 00104 00105 template<typename Alloc, typename Alloc2> 00106 void xor_buf(std::vector<byte, Alloc>& out, 00107 const std::vector<byte, Alloc2>& in, 00108 size_t n) 00109 { 00110 xor_buf(&out[0], &in[0], n); 00111 } 00112 00113 template<typename Alloc> 00114 void xor_buf(std::vector<byte, Alloc>& out, 00115 const byte* in, 00116 size_t n) 00117 { 00118 xor_buf(&out[0], in, n); 00119 } 00120 00121 template<typename Alloc, typename Alloc2> 00122 void xor_buf(std::vector<byte, Alloc>& out, 00123 const byte* in, 00124 const std::vector<byte, Alloc2>& in2, 00125 size_t n) 00126 { 00127 xor_buf(&out[0], &in[0], &in2[0], n); 00128 } 00129 00130 template<typename T, typename Alloc, typename Alloc2> 00131 std::vector<T, Alloc>& 00132 operator^=(std::vector<T, Alloc>& out, 00133 const std::vector<T, Alloc2>& in) 00134 { 00135 if(out.size() < in.size()) 00136 out.resize(in.size()); 00137 00138 xor_buf(&out[0], &in[0], in.size()); 00139 return out; 00140 } 00141 00142 } 00143 00144 #endif