#ifndef UTIL_H
#define UTIL_H
#include "vdf_new.h"
#if defined(_WIN32)
#include <cstdlib>
#define bswap_16(x) _byteswap_ushort(x)
#define bswap_32(x) _byteswap_ulong(x)
#define bswap_64(x) _byteswap_uint64(x)
#elif defined(__APPLE__)
#include <libkern/OSByteOrder.h>
#define bswap_16(x) OSSwapInt16(x)
#define bswap_32(x) OSSwapInt32(x)
#define bswap_64(x) OSSwapInt64(x)
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
# if defined(__OpenBSD__)
# include <endian.h>
# define bswap_16(x) swap16(x)
# define bswap_32(x) swap32(x)
# define bswap_64(x) swap64(x)
# else
# include <sys/endian.h>
# define bswap_16(x) bswap16(x)
# define bswap_32(x) bswap32(x)
# define bswap_64(x) bswap64(x)
# endif
#else
#include <byteswap.h>
#endif
struct Segment {
uint64_t start;
uint64_t length;
form x;
form y;
form proof;
bool is_empty;
Segment() {
is_empty = true;
}
Segment(uint64_t start, uint64_t length, form& x, form& y) {
this->start = start;
this->length = length;
this->x = x;
this->y = y;
is_empty = false;
}
bool IsWorseThan(Segment& other) {
if (is_empty) {
if (!other.is_empty)
return true;
return false;
}
if (length > other.length)
return true;
if (length < other.length)
return false;
return start > other.start;
}
int GetSegmentBucket() {
uint64_t c_length = length;
length >>= 16;
int index = 0;
while (length > 1) {
index++;
if (length == 2 || length == 3) {
std::cout << "Warning: Invalid segment length.\n";
}
length >>= 2;
}
length = c_length;
return index;
}
};
void Int64ToBytes(uint8_t *result, uint64_t input)
{
uint64_t r = bswap_64(input);
memcpy(result, &r, sizeof(r));
}
void Int32ToBytes(uint8_t *result, uint32_t input)
{
uint32_t r = bswap_32(input);
memcpy(result, &r, sizeof(r));
}
uint64_t BytesToInt64(const uint8_t *bytes)
{
uint64_t i;
memcpy(&i, bytes, sizeof(i));
return bswap_64(i);
}
template<typename T>
void VectorAppend(std::vector<T> &dst, const std::vector<T> &src)
{
dst.insert(dst.end(), src.begin(), src.end());
}
template<typename T>
void VectorAppendArray(std::vector<T> &dst, const T *src, size_t len)
{
dst.insert(dst.end(), src, src + len);
}
std::string BytesToStr(const std::vector<unsigned char> &in)
{
std::vector<unsigned char>::const_iterator from = in.cbegin();
std::vector<unsigned char>::const_iterator to = in.cend();
std::ostringstream oss;
for (; from != to; ++from)
oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(*from);
return oss.str();
}
void ApproximateParameters(uint64_t T, uint32_t& L, uint32_t& K) {
double log_memory = 23.25349666;
double log_T = log2(T);
L = 1;
if (log_T - log_memory > 0.000001) {
L = ceil(pow(2, log_memory - 20));
}
double intermediate = T * (double)0.6931471 / (2.0 * L);
K = std::max(std::round(log(intermediate) - log(log(intermediate)) + 0.25), 1.0);
}
struct Proof {
Proof() {
}
Proof(std::vector<unsigned char> y, std::vector<unsigned char> proof) {
this->y = y;
this->proof = proof;
}
string hex() {
std::vector<unsigned char> bytes(y);
bytes.insert(bytes.end(), proof.begin(), proof.end());
return BytesToStr(bytes);
}
std::vector<unsigned char> y;
std::vector<unsigned char> proof;
uint8_t witness_type;
};
#endif