1
0
Fork 0
forked from lthn/blockchain

converted sink to filter

This commit is contained in:
cryptozoidberg 2020-07-07 00:31:20 +02:00
parent e4aef3f036
commit 79777feda2
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
5 changed files with 186 additions and 126 deletions

View file

@ -0,0 +1,23 @@
// Copyright (c) 2014-2019 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "encryption_filter.h"
#include "crypto/chacha8_stream.h"
encrypt_chacha_filter::encrypt_chacha_filter(std::string const &pass, const crypto::chacha8_iv& iv):m_iv(iv), m_ctx(AUTO_VAL_INIT(m_ctx))
{
crypto::generate_chacha8_key(pass, m_key);
ECRYPT_keysetup(&m_ctx, &m_key.data[0], sizeof(m_key.data) * 8, sizeof(m_iv.data)*8);
ECRYPT_ivsetup(&m_ctx, &m_iv.data[0]);
}
//bool encrypt_chacha_filter::flush() const
encrypt_chacha_filter::~encrypt_chacha_filter()
{
}

View file

@ -0,0 +1,76 @@
// Copyright (c) 2014-2018 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#include <iostream>
#include <iosfwd>
#include <type_traits>
#include <boost/iostreams/categories.hpp> // sink_tag
#include "include_base_utils.h"
#include "crypto/chacha8.h"
#include "crypto/chacha8_stream.h"
class encrypt_chacha_filter
{
public:
typedef char char_type;
//typedef boost::iostreams::multichar_output_filter_tag category;
//typedef boost::iostreams::flushable_tag category;
struct category: //public boost::iostreams::seekable_device_tag,
public boost::iostreams::multichar_output_filter_tag,
public boost::iostreams::flushable_tag
{ };
encrypt_chacha_filter(std::string const &pass, const crypto::chacha8_iv& iv);
~encrypt_chacha_filter();
template<typename t_sink>
std::streamsize write(t_sink& snk, char_type const * const buf, std::streamsize const n) const
{
if (n == 0)
return n;
if (n%ECRYPT_BLOCKLENGTH == 0 && m_buff.empty())
{
std::vector<char_type> buff(n);
ECRYPT_encrypt_blocks(&m_ctx, (u8*)buf, (u8*)&buff[0], (u32)(n / ECRYPT_BLOCKLENGTH));
boost::iostreams::write(snk, &buff[0], n);
//m_underlying_stream.write(&buff[0], n);
}
else
{
m_buff.append(buf, n);
size_t encr_count = m_buff.size() - m_buff.size() % ECRYPT_BLOCKLENGTH;
if (!encr_count)
return n;
std::vector<char_type> buff(encr_count);
ECRYPT_encrypt_blocks(&m_ctx, (u8*)m_buff.data(), (u8*)&buff[0], (u32)(m_buff.size() / ECRYPT_BLOCKLENGTH));
//m_underlying_stream.write(&buff[0], encr_count);
boost::iostreams::write(snk, &buff[0], encr_count);
m_buff.erase(0, encr_count);
}
return n;
}
template<typename Sink>
bool flush(Sink& snk)
{
if (m_buff.empty())
return true;
std::vector<char_type> buff(m_buff.size());
ECRYPT_encrypt_bytes(&m_ctx, (u8*)m_buff.data(), (u8*)&buff[0], (u32)m_buff.size());
boost::iostreams::write(snk, &buff[0], m_buff.size());
//m_underlying_stream.write(&buff[0], m_buff.size());
return true;
}
private:
const crypto::chacha8_iv& m_iv;
mutable ECRYPT_ctx m_ctx;
//std::ostream &m_underlying_stream;
crypto::chacha8_key m_key;
mutable std::string m_buff;
};

View file

@ -1,53 +0,0 @@
// Copyright (c) 2014-2019 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "encryption_sink.h"
#include "crypto/chacha8_stream.h"
encrypt_chacha_sink::encrypt_chacha_sink(std::ostream &underlying_stream, std::string const &pass, const crypto::chacha8_iv& iv):m_iv(iv), m_underlying_stream(underlying_stream), m_ctx(AUTO_VAL_INIT(m_ctx))
{
crypto::generate_chacha8_key(pass, m_key);
ECRYPT_keysetup(&m_ctx, &m_key.data[0], sizeof(m_key.data) * 8, sizeof(m_iv.data)*8);
ECRYPT_ivsetup(&m_ctx, &m_iv.data[0]);
}
std::streamsize encrypt_chacha_sink::write(char_type const * const buf, std::streamsize const n) const
{
if (n == 0)
return n;
if (n%ECRYPT_BLOCKLENGTH == 0 && m_buff.empty())
{
std::vector<char_type> buff(n);
ECRYPT_encrypt_blocks(&m_ctx, (u8*)buf, (u8*)&buff[0], n / ECRYPT_BLOCKLENGTH);
m_underlying_stream.write(&buff[0], n);
}else
{
m_buff.append(buf, n);
size_t encr_count = m_buff.size() - m_buff.size() % ECRYPT_BLOCKLENGTH;
if (!encr_count)
return n;
std::vector<char_type> buff(encr_count);
ECRYPT_encrypt_blocks(&m_ctx, (u8*)m_buff.data(), (u8*)&buff[0], m_buff.size() / ECRYPT_BLOCKLENGTH);
m_underlying_stream.write(&buff[0], encr_count);
m_buff.erase(0, encr_count);
}
return n;
}
void encrypt_chacha_sink::flush() const
{
if (m_buff.empty())
return;
std::vector<char_type> buff(m_buff.size());
ECRYPT_encrypt_bytes(&m_ctx, (u8*)m_buff.data(), (u8*)&buff[0], m_buff.size());
m_underlying_stream.write(&buff[0], m_buff.size());
}
encrypt_chacha_sink::~encrypt_chacha_sink()
{
}

View file

@ -1,31 +0,0 @@
// Copyright (c) 2014-2018 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#include <iostream>
#include <iosfwd>
#include <type_traits>
#include <boost/iostreams/categories.hpp> // sink_tag
#include "include_base_utils.h"
#include "crypto/chacha8.h"
#include "crypto/chacha8_stream.h"
class encrypt_chacha_sink
{
public:
typedef char char_type;
typedef boost::iostreams::sink_tag category;
encrypt_chacha_sink(std::ostream &underlyingStream, std::string const &pass, const crypto::chacha8_iv& iv);
std::streamsize write(char_type const * const buf, std::streamsize const n) const;
void flush() const;
~encrypt_chacha_sink();
private:
const crypto::chacha8_iv& m_iv;
mutable ECRYPT_ctx m_ctx;
std::ostream &m_underlying_stream;
crypto::chacha8_key m_key;
mutable std::string m_buff;
};

View file

@ -6,10 +6,14 @@
#include <cstdint>
#include <vector>
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/invert.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include "common/encryption_sink.h"
#include "common/encryption_filter.h"
#include "crypto/crypto.h"
TEST(chacha_stream_test, chacha_stream_test)
{
LOG_PRINT_L0("chacha_stream_test");
@ -19,53 +23,94 @@ TEST(chacha_stream_test, chacha_stream_test)
{
buff[i] = i % 255;
}
for (size_t i = 0; i!= 100; i++)
{
std::cout << "Encrypting..." << std::endl;
std::stringstream encrypted;
crypto::chacha8_iv iv = crypto::rand<crypto::chacha8_iv>();
// for (size_t i = 0; i!= 100; i++)
// {
// std::cout << "Encrypting..." << std::endl;
// std::stringstream encrypted;
// crypto::chacha8_iv iv = crypto::rand<crypto::chacha8_iv>();
//
// encrypt_chacha_sink sink(encrypted, "pass", iv);
//
// size_t offset = 0;
// while (offset < buff_size)
// {
// std::streamsize count = std::rand() % 1000;
// if (count + offset > buff_size)
// {
// count = buff_size - offset;
// }
// sink.write(&buff[offset], count);
//
// offset += count;
// }
// sink.flush();
// std::string buff_encrypted = encrypted.str();
//
// std::cout << "Decrypting...";
// std::stringstream decrypted;
// encrypt_chacha_sink sink2(decrypted, "pass", iv);
// offset = 0;
// while (offset < buff_size)
// {
// std::streamsize count = std::rand() % 1000;
// if (count + offset > buff_size)
// {
// count = buff_size - offset;
// }
// sink2.write(&buff_encrypted[offset], count);
//
// offset += count;
// }
// sink2.flush();
// std::string buff_decrypted = decrypted.str();
//
// if (buff_decrypted != buff)
// {
// std::cout << "Failed" << std::endl;
// ASSERT_TRUE(false);
// }
// std::cout << "OK" << std::endl;
// }
encrypt_chacha_sink sink(encrypted, "pass", iv);
size_t offset = 0;
while (offset < buff_size)
{
std::streamsize count = std::rand() % 1000;
if (count + offset > buff_size)
{
count = buff_size - offset;
}
sink.write(&buff[offset], count);
crypto::chacha8_iv iv = crypto::rand<crypto::chacha8_iv>();
boost::filesystem::ofstream store_data_file;
store_data_file.open("./test.bin", std::ios_base::binary | std::ios_base::out | std::ios::trunc);
encrypt_chacha_filter encrypt_filter("pass", iv);
//boost::iostreams::stream<encrypt_chacha_sink> outputStream(sink_encrypt);
boost::iostreams::filtering_ostream out;
out.push(encrypt_filter);
out.push(store_data_file);
out << buff;
out.flush();
store_data_file.close();
offset += count;
}
sink.flush();
std::string buff_encrypted = encrypted.str();
std::cout << "Decrypting...";
std::stringstream decrypted;
encrypt_chacha_sink sink2(decrypted, "pass", iv);
offset = 0;
while (offset < buff_size)
{
std::streamsize count = std::rand() % 1000;
if (count + offset > buff_size)
{
count = buff_size - offset;
}
sink2.write(&buff_encrypted[offset], count);
boost::filesystem::ifstream data_file;
data_file.open("./test.bin", std::ios_base::binary | std::ios_base::in);
encrypt_chacha_filter decrypt_filter("pass", iv);
offset += count;
}
sink2.flush();
std::string buff_decrypted = decrypted.str();
boost::iostreams::filtering_istream in;
in.push(boost::iostreams::invert(decrypt_filter));
in.push(data_file);
//todo: read from stream
auto size = buff_size;
std::string str(size, '\0'); // construct string to stream size
try {
in.read(&str[0], size+1);
std::cout << "ddd";
if (buff_decrypted != buff)
{
std::cout << "Failed" << std::endl;
ASSERT_TRUE(false);
}
std::cout << "OK" << std::endl;
}
catch (std::exception& err)
{
std::cout << err.what();
std::cout << err.what();
}
}