lokinet/include/llarp/aligned.hpp

240 lines
4.1 KiB
C++
Raw Normal View History

2018-06-01 14:08:54 +00:00
#ifndef LLARP_ALIGNED_HPP
#define LLARP_ALIGNED_HPP
#include <llarp/bencode.h>
2018-06-01 14:08:54 +00:00
#include <llarp/crypto.h>
2018-06-01 14:24:58 +00:00
#include <iomanip>
2018-06-01 14:08:54 +00:00
#include <iostream>
2018-06-13 13:18:18 +00:00
#include <llarp/encode.hpp>
#include <llarp/logger.hpp>
2018-06-01 14:08:54 +00:00
2018-10-23 12:40:34 +00:00
extern "C"
{
extern void
randombytes(unsigned char* const ptr, unsigned long long sz);
extern void
sodium_memzero(void* const ptr, const size_t sz);
extern int
sodium_is_zero(const unsigned char* ptr, size_t sz);
}
2018-06-01 14:08:54 +00:00
namespace llarp
{
/// aligned buffer, aligns to the nears Long_t
template < size_t sz, bool randomize = false, typename Long_t = uint64_t >
2018-06-01 14:08:54 +00:00
struct AlignedBuffer
{
2018-07-26 21:08:56 +00:00
AlignedBuffer()
{
if(randomize)
Randomize();
2018-08-10 21:34:11 +00:00
else
Zero();
2018-06-22 00:25:30 +00:00
}
AlignedBuffer(const byte_t* data)
2018-06-01 14:08:54 +00:00
{
for(size_t idx = 0; idx < sz; ++idx)
2018-07-17 04:37:50 +00:00
b[idx] = data[idx];
2018-06-01 14:08:54 +00:00
}
AlignedBuffer&
operator=(const byte_t* data)
2018-06-01 14:08:54 +00:00
{
for(size_t idx = 0; idx < sz; ++idx)
2018-07-17 04:37:50 +00:00
b[idx] = data[idx];
2018-06-01 14:08:54 +00:00
return *this;
}
friend std::ostream&
operator<<(std::ostream& out, const AlignedBuffer& self)
2018-06-01 14:08:54 +00:00
{
2018-06-13 13:18:18 +00:00
char tmp[(1 + sz) * 2] = {0};
return out << HexEncode(self, tmp);
2018-06-01 14:08:54 +00:00
}
2018-09-24 14:31:58 +00:00
/// bitwise NOT
AlignedBuffer< sz >
operator~() const
{
AlignedBuffer< sz > ret;
size_t idx = 0;
while(idx < sz / sizeof(Long_t))
{
ret.data_l()[idx] = ~data_l()[idx];
++idx;
}
return ret;
}
2018-06-01 14:08:54 +00:00
bool
operator==(const AlignedBuffer& other) const
{
2018-11-15 18:10:09 +00:00
return memcmp(b, other.b, sz) == 0;
2018-06-01 14:08:54 +00:00
}
bool
operator!=(const AlignedBuffer& other) const
{
return !(*this == other);
}
bool
operator<(const AlignedBuffer& other) const
{
return memcmp(l, other.l, sz) < 0;
}
2018-08-10 21:34:11 +00:00
bool
operator>(const AlignedBuffer& other) const
{
return memcmp(l, other.l, sz) > 0;
}
bool
operator<=(const AlignedBuffer& other) const
{
return memcmp(l, other.l, sz) <= 0;
}
bool
operator>=(const AlignedBuffer& other) const
{
return memcmp(l, other.l, sz) >= 0;
}
AlignedBuffer
operator^(const AlignedBuffer& other) const
{
AlignedBuffer< sz > ret;
for(size_t idx = 0; idx < sz / sizeof(Long_t); ++idx)
ret.l[idx] = l[idx] ^ other.l[idx];
return ret;
}
AlignedBuffer&
operator^=(const AlignedBuffer& other)
{
for(size_t idx = 0; idx < sz / sizeof(Long_t); ++idx)
l[idx] ^= other.l[idx];
return *this;
}
2018-06-01 14:08:54 +00:00
size_t
size() const
{
return sz;
}
size_t
size()
{
return sz;
}
2018-06-14 14:04:42 +00:00
void
Fill(byte_t f)
{
for(size_t idx = 0; idx < sz; ++idx)
2018-07-17 04:37:50 +00:00
b[idx] = f;
2018-06-14 14:04:42 +00:00
}
bool
IsZero() const
{
2018-08-14 21:17:18 +00:00
return sodium_is_zero(b, sz) != 0;
}
2018-06-14 14:04:42 +00:00
2018-06-01 14:08:54 +00:00
void
Zero()
{
2018-08-14 21:17:18 +00:00
sodium_memzero(l, sz);
2018-06-01 14:08:54 +00:00
}
void
Randomize()
{
2018-06-12 16:45:12 +00:00
randombytes(b, sz);
2018-06-01 14:08:54 +00:00
}
byte_t*
data()
{
2018-11-14 21:31:21 +00:00
return b;
2018-06-01 14:08:54 +00:00
}
const byte_t*
data() const
{
2018-11-14 21:31:21 +00:00
return b;
}
Long_t*
data_l()
{
2018-11-14 21:31:21 +00:00
return l;
2018-06-01 14:08:54 +00:00
}
const Long_t*
2018-06-01 14:08:54 +00:00
data_l() const
{
2018-11-14 21:31:21 +00:00
return l;
2018-06-01 14:08:54 +00:00
}
operator const byte_t*() const
2018-06-01 14:08:54 +00:00
{
2018-11-14 21:31:21 +00:00
return b;
2018-06-01 14:08:54 +00:00
}
operator byte_t*()
2018-06-01 14:08:54 +00:00
{
2018-11-14 21:31:21 +00:00
return b;
2018-06-01 14:08:54 +00:00
}
bool
BEncode(llarp_buffer_t* buf) const
{
return bencode_write_bytestring(buf, b, sz);
}
bool
BDecode(llarp_buffer_t* buf)
{
llarp_buffer_t strbuf;
if(!bencode_read_string(buf, &strbuf))
return false;
if(strbuf.sz != sz)
{
2018-09-04 19:15:06 +00:00
llarp::LogError("bdecode buffer size missmatch ", strbuf.sz, "!=", sz);
return false;
}
memcpy(b, strbuf.base, sz);
return true;
}
std::string
ToHex() const
{
char strbuf[(1 + sz) * 2] = {0};
2018-10-25 19:06:16 +00:00
return std::string(HexEncode(*this, strbuf));
}
2018-07-19 04:58:39 +00:00
struct Hash
{
size_t
2018-11-15 18:10:09 +00:00
operator()(const AlignedBuffer< sz, randomize, Long_t >& buf) const
2018-07-19 04:58:39 +00:00
{
2018-11-15 14:19:50 +00:00
return buf.l[0];
2018-07-19 04:58:39 +00:00
}
};
2018-06-14 14:04:42 +00:00
protected:
2018-06-01 14:08:54 +00:00
union {
byte_t b[sz];
Long_t l[(sz / sizeof(Long_t)) + (sz % sizeof(Long_t))];
2018-06-06 12:46:26 +00:00
};
2018-06-01 14:08:54 +00:00
};
2018-07-26 21:08:56 +00:00
2018-06-18 22:03:50 +00:00
} // namespace llarp
2018-06-01 14:08:54 +00:00
#endif