forked from lthn/blockchain
converted sink to filter
This commit is contained in:
parent
e4aef3f036
commit
79777feda2
5 changed files with 186 additions and 126 deletions
23
src/common/encryption_filter.cpp
Normal file
23
src/common/encryption_filter.cpp
Normal 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()
|
||||
{
|
||||
|
||||
}
|
||||
76
src/common/encryption_filter.h
Normal file
76
src/common/encryption_filter.h
Normal 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;
|
||||
};
|
||||
|
|
@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue