Files
hush3/src/zerocash/utils/util.cpp
2016-03-17 16:38:27 -06:00

347 lines
10 KiB
C++

#include <openssl/rand.h>
#include <openssl/err.h>
#include <string>
#include <iostream>
#include <fstream>
#include <exception>
#include <cstring>
#include <iomanip>
#include <algorithm>
#include <sodium.h>
#include "util.h"
namespace libzerocash {
void printChar(const unsigned char c) {
for(int j = 8; j >= 0; j--) {
std::cout << ((c >> j) & 1);
}
std::cout << std::endl;
}
void printVector(const std::vector<bool>& v) {
std::cout << v.size() << " MSB ";
for(size_t i = 0; i < v.size(); i++) {
std::cout << v.at(i);
}
std::cout << " LSB" << std::endl;
}
void printVector(const std::string str, const std::vector<bool>& v) {
std::cout << str << " " << v.size() << " MSB ";
for(size_t i = 0; i < v.size(); i++) {
std::cout << v.at(i);
}
std::cout << " LSB" << std::endl;
}
void printVectorAsHex(const std::vector<bool>& v) {
unsigned char bytes[int(v.size() / 8)];
convertVectorToBytes(v, bytes);
for(int i = 0; i < int(v.size() / 8); i++) {
std::cout << std::setw(2) << std::setfill('0') << std::hex << (int) bytes[i];
}
std::cout << std::dec << std::endl;
}
void printVectorAsHex(const std::string str, const std::vector<bool>& v) {
unsigned char bytes[int(v.size() / 8)];
convertVectorToBytes(v, bytes);
std::cout << str << " ";
for(int i = 0; i < int(v.size() / 8); i++) {
std::cout << std::setw(2) << std::setfill('0') << std::hex << (int) bytes[i];
}
std::cout << std::dec << std::endl;
}
void printBytesVector(const std::vector<unsigned char>& v) {
std::vector<bool> boolVec(v.size() * 8);
convertBytesVectorToVector(v, boolVec);
printVector(boolVec);
}
void printBytesVector(const std::string str, const std::vector<unsigned char>& v) {
std::vector<bool> boolVec(v.size() * 8);
convertBytesVectorToVector(v, boolVec);
printVector(str, boolVec);
}
void printBytesVectorAsHex(const std::vector<unsigned char>& v) {
std::vector<bool> boolVec(v.size() * 8);
convertBytesVectorToVector(v, boolVec);
printVectorAsHex(boolVec);
}
void printBytesVectorAsHex(const std::string str, const std::vector<unsigned char>& v) {
std::vector<bool> boolVec(v.size() * 8);
convertBytesVectorToVector(v, boolVec);
printVectorAsHex(str, boolVec);
}
void getRandBytes(unsigned char* bytes, int num) {
randombytes_buf(bytes, num);
}
void convertBytesToVector(const unsigned char* bytes, std::vector<bool>& v) {
int numBytes = v.size() / 8;
unsigned char c;
for(int i = 0; i < numBytes; i++) {
c = bytes[i];
for(int j = 0; j < 8; j++) {
v.at((i*8)+j) = ((c >> (7-j)) & 1);
}
}
}
void convertVectorToBytes(const std::vector<bool>& v, unsigned char* bytes) {
int numBytes = v.size() / 8;
unsigned char c = '\0';
for(int i = 0; i < numBytes; i++) {
c = '\0';
for(int j = 0; j < 8; j++) {
if(j == 7)
c = ((c | v.at((i*8)+j)));
else
c = ((c | v.at((i*8)+j)) << 1);
}
bytes[i] = c;
}
}
void convertBytesToBytesVector(const unsigned char* bytes, std::vector<unsigned char>& v) {
for(size_t i = 0; i < v.size(); i++) {
v.at(i) = bytes[i];
}
}
void convertBytesVectorToBytes(const std::vector<unsigned char>& v, unsigned char* bytes) {
for(size_t i = 0; i < v.size(); i++) {
bytes[i] = v.at(i);
}
}
void convertBytesVectorToVector(const std::vector<unsigned char>& bytes, std::vector<bool>& v) {
v.resize(bytes.size() * 8);
unsigned char bytesArr[bytes.size()];
convertBytesVectorToBytes(bytes, bytesArr);
convertBytesToVector(bytesArr, v);
}
void convertVectorToBytesVector(const std::vector<bool>& v, std::vector<unsigned char>& bytes) {
unsigned char bytesArr[int(ceil(v.size() / 8.))];
convertVectorToBytes(v, bytesArr);
convertBytesToBytesVector(bytesArr, bytes);
}
void convertIntToBytesVector(const uint64_t val_int, std::vector<unsigned char>& bytes) {
for(size_t i = 0; i < bytes.size(); i++) {
bytes[bytes.size()-1-i] = (val_int >> (i * 8));
}
}
void convertIntToVector(uint64_t val, std::vector<bool>& v)
{
v.resize(64);
for(unsigned int i = 0; i < 64; ++i, val >>= 1) {
v.at(63 - i) = val & 0x01;
}
}
uint64_t convertVectorToInt(const std::vector<bool>& v) {
if (v.size() > 64) {
throw std::length_error ("boolean vector can't be larger than 64 bits");
}
uint64_t result = 0;
for (size_t i=0; i<v.size();i++) {
if (v.at(i)) {
result |= (uint64_t)1 << ((v.size() - 1) - i);
}
}
return result;
}
uint64_t convertBytesVectorToInt(const std::vector<unsigned char>& bytes) {
uint64_t val_int = 0;
for(size_t i = 0; i < bytes.size(); i++) {
val_int = val_int + (((uint64_t)bytes[i]) << ((bytes.size()-1-i) * 8));
}
return val_int;
}
void concatenateVectors(const std::vector<bool>& A, const std::vector<bool>& B, std::vector<bool>& result) {
result.reserve(A.size() + B.size());
result.insert(result.end(), A.begin(), A.end());
result.insert(result.end(), B.begin(), B.end());
}
void concatenateVectors(const std::vector<unsigned char>& A, const std::vector<unsigned char>& B, std::vector<unsigned char>& result) {
result.reserve(A.size() + B.size());
result.insert(result.end(), A.begin(), A.end());
result.insert(result.end(), B.begin(), B.end());
}
void concatenateVectors(const std::vector<bool>& A, const std::vector<bool>& B, const std::vector<bool>& C, std::vector<bool>& result) {
result.reserve(A.size() + B.size() + C.size());
result.insert(result.end(), A.begin(), A.end());
result.insert(result.end(), B.begin(), B.end());
result.insert(result.end(), C.begin(), C.end());
}
void concatenateVectors(const std::vector<unsigned char>& A, const std::vector<unsigned char>& B, const std::vector<unsigned char>& C, std::vector<unsigned char>& result) {
result.reserve(A.size() + B.size() + C.size());
result.insert(result.end(), A.begin(), A.end());
result.insert(result.end(), B.begin(), B.end());
result.insert(result.end(), C.begin(), C.end());
}
void sha256(const unsigned char* input, unsigned char* hash, int len) {
SHA256_CTX_mod ctx256;
sha256_init(&ctx256);
sha256_update(&ctx256, input, len);
sha256_final_no_padding(&ctx256, hash);
}
void sha256(SHA256_CTX_mod* ctx256, const unsigned char* input, unsigned char* hash, int len) {
sha256_init(ctx256);
sha256_update(ctx256, input, len);
sha256_final_no_padding(ctx256, hash);
}
void hashVector(SHA256_CTX_mod* ctx256, const std::vector<bool> input, std::vector<bool>& output) {
int size = int(input.size() / 8);
unsigned char bytes[size];
convertVectorToBytes(input, bytes);
unsigned char hash[SHA256_BLOCK_SIZE];
sha256(ctx256, bytes, hash, (int)size);
convertBytesToVector(hash, output);
}
void hashVector(SHA256_CTX_mod* ctx256, const std::vector<unsigned char> input, std::vector<unsigned char>& output) {
int size = int(input.size());
unsigned char bytes[size];
convertBytesVectorToBytes(input, bytes);
unsigned char hash[SHA256_BLOCK_SIZE];
sha256(ctx256, bytes, hash, (int)size);
convertBytesToBytesVector(hash, output);
}
void hashVector(const std::vector<bool> input, std::vector<bool>& output) {
SHA256_CTX_mod ctx256;
int size = int(input.size() / 8);
unsigned char bytes[size];
convertVectorToBytes(input, bytes);
unsigned char hash[SHA256_BLOCK_SIZE];
sha256(&ctx256, bytes, hash, (int)size);
convertBytesToVector(hash, output);
}
void hashVector(const std::vector<unsigned char> input, std::vector<unsigned char>& output) {
SHA256_CTX_mod ctx256;
int size = int(input.size());
unsigned char bytes[size];
convertBytesVectorToBytes(input, bytes);
unsigned char hash[SHA256_BLOCK_SIZE];
sha256(&ctx256, bytes, hash, (int)size);
convertBytesToBytesVector(hash, output);
}
void hashVectors(SHA256_CTX_mod* ctx256, const std::vector<bool> left, const std::vector<bool> right, std::vector<bool>& output) {
std::vector<bool> concat;
concatenateVectors(left, right, concat);
int size = int(concat.size() / 8);
unsigned char bytes[size];
convertVectorToBytes(concat, bytes);
unsigned char hash[SHA256_BLOCK_SIZE];
sha256(ctx256, bytes, hash, (int)size);
convertBytesToVector(hash, output);
}
void hashVectors(SHA256_CTX_mod* ctx256, const std::vector<unsigned char> left, const std::vector<unsigned char> right, std::vector<unsigned char>& output) {
std::vector<unsigned char> concat;
concatenateVectors(left, right, concat);
int size = int(concat.size());
unsigned char bytes[size];
convertBytesVectorToBytes(concat, bytes);
unsigned char hash[SHA256_BLOCK_SIZE];
sha256(ctx256, bytes, hash, (int)size);
convertBytesToBytesVector(hash, output);
}
void hashVectors(const std::vector<bool> left, const std::vector<bool> right, std::vector<bool>& output) {
std::cout << std::endl;
std::vector<bool> concat;
concatenateVectors(left, right, concat);
int size = int(concat.size() / 8);
unsigned char bytes[size];
convertVectorToBytes(concat, bytes);
unsigned char hash[SHA256_BLOCK_SIZE];
sha256(bytes, hash, (int)size);
convertBytesToVector(hash, output);
}
void hashVectors(const std::vector<unsigned char> left, const std::vector<unsigned char> right, std::vector<unsigned char>& output) {
std::vector<unsigned char> concat;
concatenateVectors(left, right, concat);
int size = int(concat.size());
unsigned char bytes[size];
convertBytesVectorToBytes(concat, bytes);
unsigned char hash[SHA256_BLOCK_SIZE];
sha256(bytes, hash, (int)size);
convertBytesToBytesVector(hash, output);
}
bool VectorIsZero(const std::vector<bool> test) {
// XXX: not time safe
return (test.end() == std::find(test.begin(), test.end(), true));
}
size_t countOnes(const std::vector<bool>& vec) {
return count(vec.begin(), vec.end(), true);
}
std::vector<unsigned char> vectorSlice(const std::vector<unsigned char>& vec, size_t start, size_t length) {
std::vector<unsigned char> slice(length);
for (size_t i = 0; i < length; i++) {
slice.at(i) = vec.at(start + i);
}
return slice;
}
} /* namespace libzerocash */