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