Merge branch 'master' of https://github.com/monero-project/bitmonero
commit
8fc42a21fc
@ -1,3 +1,7 @@
|
||||
.DS_Store
|
||||
/build
|
||||
/tags
|
||||
/tags
|
||||
|
||||
# vim swap files
|
||||
*.swp
|
||||
*.swo
|
||||
|
@ -0,0 +1,167 @@
|
||||
#ifndef JSONRPC_PROTOCOL_HANDLER_H
|
||||
#define JSONRPC_PROTOCOL_HANDLER_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "net/net_utils_base.h"
|
||||
#include "jsonrpc_structs.h"
|
||||
#include "storages/portable_storage.h"
|
||||
#include "storages/portable_storage_template_helper.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
namespace jsonrpc2
|
||||
{
|
||||
inline
|
||||
std::string& make_error_resp_json(int64_t code, const std::string& message,
|
||||
std::string& response_data,
|
||||
const epee::serialization::storage_entry& id = nullptr)
|
||||
{
|
||||
epee::json_rpc::error_response rsp;
|
||||
rsp.id = id;
|
||||
rsp.jsonrpc = "2.0";
|
||||
rsp.error.code = code;
|
||||
rsp.error.message = message;
|
||||
epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(rsp), response_data, 0, false);
|
||||
response_data += "\n";
|
||||
return response_data;
|
||||
}
|
||||
|
||||
template<class t_connection_context>
|
||||
struct i_jsonrpc2_server_handler
|
||||
{
|
||||
virtual ~i_jsonrpc2_server_handler()
|
||||
{}
|
||||
virtual bool handle_rpc_request(const std::string& req_data,
|
||||
std::string& resp_data,
|
||||
t_connection_context& conn_context) = 0;
|
||||
virtual bool init_server_thread()
|
||||
{ return true; }
|
||||
virtual bool deinit_server_thread()
|
||||
{ return true; }
|
||||
};
|
||||
|
||||
template<class t_connection_context>
|
||||
struct jsonrpc2_server_config
|
||||
{
|
||||
i_jsonrpc2_server_handler<t_connection_context>* m_phandler;
|
||||
critical_section m_lock;
|
||||
};
|
||||
|
||||
template<class t_connection_context = net_utils::connection_context_base>
|
||||
class jsonrpc2_connection_handler
|
||||
{
|
||||
public:
|
||||
typedef t_connection_context connection_context;
|
||||
typedef jsonrpc2_server_config<t_connection_context> config_type;
|
||||
|
||||
jsonrpc2_connection_handler(i_service_endpoint* psnd_hndlr,
|
||||
config_type& config,
|
||||
t_connection_context& conn_context)
|
||||
: m_psnd_hndlr(psnd_hndlr),
|
||||
m_config(config),
|
||||
m_conn_context(conn_context),
|
||||
m_is_stop_handling(false)
|
||||
{}
|
||||
virtual ~jsonrpc2_connection_handler()
|
||||
{}
|
||||
|
||||
bool release_protocol()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual bool thread_init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual bool thread_deinit()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
void handle_qued_callback()
|
||||
{}
|
||||
bool after_init_connection()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual bool handle_recv(const void* ptr, size_t cb)
|
||||
{
|
||||
std::string buf((const char*)ptr, cb);
|
||||
LOG_PRINT_L0("JSONRPC2_RECV: " << ptr << "\r\n" << buf);
|
||||
|
||||
bool res = handle_buff_in(buf);
|
||||
return res;
|
||||
}
|
||||
private:
|
||||
bool handle_buff_in(std::string& buf)
|
||||
{
|
||||
if(m_cache.size())
|
||||
m_cache += buf;
|
||||
else
|
||||
m_cache.swap(buf);
|
||||
|
||||
m_is_stop_handling = false;
|
||||
while (!m_is_stop_handling) {
|
||||
std::string::size_type pos = match_end_of_request(m_cache);
|
||||
if (std::string::npos == pos) {
|
||||
m_is_stop_handling = true;
|
||||
if (m_cache.size() > 4096) {
|
||||
LOG_ERROR("jsonrpc2_connection_handler::handle_buff_in: Too long request");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
extract_cached_request_and_handle(pos);
|
||||
}
|
||||
|
||||
if (!m_cache.size()) {
|
||||
m_is_stop_handling = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
bool extract_cached_request_and_handle(std::string::size_type pos)
|
||||
{
|
||||
std::string request_data(m_cache.begin(), m_cache.begin() + pos);
|
||||
m_cache.erase(0, pos);
|
||||
return handle_request_and_send_response(request_data);
|
||||
}
|
||||
bool handle_request_and_send_response(const std::string& request_data)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(m_config.m_phandler, false, "m_config.m_phandler is NULL!!!!");
|
||||
std::string response_data;
|
||||
|
||||
LOG_PRINT_L3("JSONRPC2_REQUEST: >> \r\n" << request_data);
|
||||
bool rpc_result = m_config.m_phandler->handle_rpc_request(request_data, response_data, m_conn_context);
|
||||
LOG_PRINT_L3("JSONRPC2_RESPONSE: << \r\n" << response_data);
|
||||
|
||||
m_psnd_hndlr->do_send((void*)response_data.data(), response_data.size());
|
||||
return rpc_result;
|
||||
}
|
||||
std::string::size_type match_end_of_request(const std::string& buf)
|
||||
{
|
||||
std::string::size_type res = buf.find("\n");
|
||||
if(std::string::npos != res) {
|
||||
return res + 2;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
protected:
|
||||
i_service_endpoint* m_psnd_hndlr;
|
||||
|
||||
private:
|
||||
config_type& m_config;
|
||||
t_connection_context& m_conn_context;
|
||||
std::string m_cache;
|
||||
bool m_is_stop_handling;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* JSONRPC_PROTOCOL_HANDLER_H */
|
@ -0,0 +1,86 @@
|
||||
#ifndef JSONRPC_SERVER_HANDLERS_MAP_H
|
||||
#define JSONRPC_SERVER_HANDLERS_MAP_H
|
||||
|
||||
#include <string>
|
||||
#include "serialization/keyvalue_serialization.h"
|
||||
#include "storages/portable_storage_template_helper.h"
|
||||
#include "storages/portable_storage_base.h"
|
||||
#include "jsonrpc_structs.h"
|
||||
#include "jsonrpc_protocol_handler.h"
|
||||
|
||||
#define BEGIN_JSONRPC2_MAP(t_connection_context) \
|
||||
bool handle_rpc_request(const std::string& req_data, \
|
||||
std::string& resp_data, \
|
||||
t_connection_context& m_conn_context) \
|
||||
{ \
|
||||
bool handled = false; \
|
||||
uint64_t ticks = epee::misc_utils::get_tick_count(); \
|
||||
epee::serialization::portable_storage ps; \
|
||||
if (!ps.load_from_json(req_data)) \
|
||||
{ \
|
||||
epee::net_utils::jsonrpc2::make_error_resp_json(-32700, "Parse error", resp_data); \
|
||||
return true; \
|
||||
} \
|
||||
epee::serialization::storage_entry id_; \
|
||||
id_ = epee::serialization::storage_entry(std::string()); \
|
||||
if (!ps.get_value("id", id_, nullptr)) \
|
||||
{ \
|
||||
epee::net_utils::jsonrpc2::make_error_resp_json(-32600, "Invalid Request", resp_data); \
|
||||
return true; \
|
||||
} \
|
||||
std::string callback_name; \
|
||||
if (!ps.get_value("method", callback_name, nullptr)) \
|
||||
{ \
|
||||
epee::net_utils::jsonrpc2::make_error_resp_json(-32600, "Invalid Request", resp_data, id_); \
|
||||
return true; \
|
||||
} \
|
||||
if (false) return true; //just a stub to have "else if"
|
||||
|
||||
|
||||
|
||||
#define PREPARE_JSONRPC2_OBJECTS_FROM_JSON(command_type) \
|
||||
handled = true; \
|
||||
boost::value_initialized<epee::json_rpc::request<command_type::request> > req_; \
|
||||
epee::json_rpc::request<command_type::request>& req = static_cast<epee::json_rpc::request<command_type::request>&>(req_);\
|
||||
if(!req.load(ps)) \
|
||||
{ \
|
||||
epee::net_utils::jsonrpc2::make_error_resp_json(-32602, "Invalid params", resp_data, req.id); \
|
||||
return true; \
|
||||
} \
|
||||
uint64_t ticks1 = epee::misc_utils::get_tick_count(); \
|
||||
boost::value_initialized<epee::json_rpc::response<command_type::response, epee::json_rpc::dummy_error> > resp_; \
|
||||
epee::json_rpc::response<command_type::response, epee::json_rpc::dummy_error>& resp = static_cast<epee::json_rpc::response<command_type::response, epee::json_rpc::dummy_error> &>(resp_); \
|
||||
resp.jsonrpc = "2.0"; \
|
||||
resp.id = req.id;
|
||||
|
||||
#define FINALIZE_JSONRPC2_OBJECTS_TO_JSON(method_name) \
|
||||
uint64_t ticks2 = epee::misc_utils::get_tick_count(); \
|
||||
epee::serialization::store_t_to_json(resp, resp_data, 0, false); \
|
||||
resp_data += "\n"; \
|
||||
uint64_t ticks3 = epee::misc_utils::get_tick_count(); \
|
||||
LOG_PRINT("[" << method_name << "] processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms", LOG_LEVEL_2);
|
||||
|
||||
|
||||
#define MAP_JSONRPC2_WE(method_name, callback_f, command_type) \
|
||||
else if (callback_name == method_name) \
|
||||
{ \
|
||||
PREPARE_JSONRPC2_OBJECTS_FROM_JSON(command_type) \
|
||||
epee::json_rpc::error_response fail_resp = AUTO_VAL_INIT(fail_resp); \
|
||||
fail_resp.jsonrpc = "2.0"; \
|
||||
fail_resp.id = req.id; \
|
||||
if(!callback_f(req.params, resp.result, fail_resp.error, m_conn_context)) \
|
||||
{ \
|
||||
epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), resp_data, 0, false); \
|
||||
resp_data += "\n"; \
|
||||
return true; \
|
||||
} \
|
||||
FINALIZE_JSONRPC2_OBJECTS_TO_JSON(method_name) \
|
||||
return true; \
|
||||
}
|
||||
|
||||
#define END_JSONRPC2_MAP() \
|
||||
epee::net_utils::jsonrpc2::make_error_resp_json(-32601, "Method not found", resp_data, id_); \
|
||||
return true; \
|
||||
}
|
||||
|
||||
#endif /* JSONRPC_SERVER_HANDLERS_MAP_H */
|
@ -0,0 +1,84 @@
|
||||
#ifndef JSONRPC_SERVER_IMPL_BASE_H
|
||||
#define JSONRPC_SERVER_IMPL_BASE_H
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include "net/jsonrpc_protocol_handler.h"
|
||||
#include "net/jsonrpc_server_handlers_map.h"
|
||||
#include "net/abstract_tcp_server2.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
|
||||
template<class t_child_class, class t_connection_context = epee::net_utils::connection_context_base>
|
||||
class jsonrpc_server_impl_base: public net_utils::jsonrpc2::i_jsonrpc2_server_handler<t_connection_context>
|
||||
{
|
||||
|
||||
public:
|
||||
jsonrpc_server_impl_base()
|
||||
: m_net_server()
|
||||
{}
|
||||
|
||||
explicit jsonrpc_server_impl_base(boost::asio::io_service& external_io_service)
|
||||
: m_net_server(external_io_service)
|
||||
{}
|
||||
|
||||
bool init(const std::string& bind_port = "0", const std::string& bind_ip = "0.0.0.0")
|
||||
{
|
||||
//set self as callback handler
|
||||
m_net_server.get_config_object().m_phandler = static_cast<t_child_class*>(this);
|
||||
|
||||
LOG_PRINT_L0("Binding on " << bind_ip << ":" << bind_port);
|
||||
bool res = m_net_server.init_server(bind_port, bind_ip);
|
||||
if (!res)
|
||||
{
|
||||
LOG_ERROR("Failed to bind server");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool run(size_t threads_count, bool wait = true)
|
||||
{
|
||||
//go to loop
|
||||
LOG_PRINT("Run net_service loop( " << threads_count << " threads)...", LOG_LEVEL_0);
|
||||
if(!m_net_server.run_server(threads_count, wait))
|
||||
{
|
||||
LOG_ERROR("Failed to run net tcp server!");
|
||||
}
|
||||
|
||||
if(wait)
|
||||
LOG_PRINT("net_service loop stopped.", LOG_LEVEL_0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool deinit()
|
||||
{
|
||||
return m_net_server.deinit_server();
|
||||
}
|
||||
|
||||
bool timed_wait_server_stop(uint64_t ms)
|
||||
{
|
||||
return m_net_server.timed_wait_server_stop(ms);
|
||||
}
|
||||
|
||||
bool send_stop_signal()
|
||||
{
|
||||
m_net_server.send_stop_signal();
|
||||
return true;
|
||||
}
|
||||
|
||||
int get_binded_port()
|
||||
{
|
||||
return m_net_server.get_binded_port();
|
||||
}
|
||||
|
||||
protected:
|
||||
net_utils::boosted_tcp_server<net_utils::jsonrpc2::jsonrpc2_connection_handler<t_connection_context> > m_net_server;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* JSONRPC_SERVER_IMPL_BASE_H */
|
||||
|
@ -0,0 +1,96 @@
|
||||
#ifndef JSONRPC_STRUCTS_H
|
||||
#define JSONRPC_STRUCTS_H
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
#include "serialization/keyvalue_serialization.h"
|
||||
#include "storages/portable_storage_base.h"
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace json_rpc
|
||||
{
|
||||
template<typename t_param>
|
||||
struct request
|
||||
{
|
||||
std::string jsonrpc;
|
||||
std::string method;
|
||||
epee::serialization::storage_entry id;
|
||||
t_param params;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(jsonrpc)
|
||||
KV_SERIALIZE(id)
|
||||
KV_SERIALIZE(method)
|
||||
KV_SERIALIZE(params)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct error
|
||||
{
|
||||
int64_t code;
|
||||
std::string message;
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(code)
|
||||
KV_SERIALIZE(message)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct dummy_error
|
||||
{
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct dummy_result
|
||||
{
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
template<typename t_param, typename t_error>
|
||||
struct response
|
||||
{
|
||||
std::string jsonrpc;
|
||||
t_param result;
|
||||
epee::serialization::storage_entry id;
|
||||
t_error error;
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(jsonrpc)
|
||||
KV_SERIALIZE(id)
|
||||
KV_SERIALIZE(result)
|
||||
KV_SERIALIZE(error)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
template<typename t_param>
|
||||
struct response<t_param, dummy_error>
|
||||
{
|
||||
std::string jsonrpc;
|
||||
t_param result;
|
||||
epee::serialization::storage_entry id;
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(jsonrpc)
|
||||
KV_SERIALIZE(id)
|
||||
KV_SERIALIZE(result)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
template<typename t_error>
|
||||
struct response<dummy_result, t_error>
|
||||
{
|
||||
std::string jsonrpc;
|
||||
t_error error;
|
||||
epee::serialization::storage_entry id;
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(jsonrpc)
|
||||
KV_SERIALIZE(id)
|
||||
KV_SERIALIZE(error)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
typedef response<dummy_result, error> error_response;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* JSONRPC_STRUCTS_H */
|
@ -0,0 +1,177 @@
|
||||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
|
||||
|
||||
The redistribution and use of this software (with or without changes)
|
||||
is allowed without the payment of fees or royalties provided that:
|
||||
|
||||
source code distributions include the above copyright notice, this
|
||||
list of conditions and the following disclaimer;
|
||||
|
||||
binary distributions include the above copyright notice, this list
|
||||
of conditions and the following disclaimer in their documentation.
|
||||
|
||||
This software is provided 'as is' with no explicit or implied warranties
|
||||
in respect of its operation, including, but not limited to, correctness
|
||||
and fitness for purpose.
|
||||
---------------------------------------------------------------------------
|
||||
Issue Date: 20/12/2007
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define TABLE_ALIGN 32
|
||||
#define WPOLY 0x011b
|
||||
#define N_COLS 4
|
||||
#define AES_BLOCK_SIZE 16
|
||||
#define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2))
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define ALIGN __declspec(align(TABLE_ALIGN))
|
||||
#elif defined(__GNUC__)
|
||||
#define ALIGN __attribute__ ((aligned(16)))
|
||||
#else
|
||||
#define ALIGN
|
||||
#endif
|
||||
|
||||
#define rf1(r,c) (r)
|
||||
#define word_in(x,c) (*((uint32_t*)(x)+(c)))
|
||||
#define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = (v))
|
||||
|
||||
#define s(x,c) x[c]
|
||||
#define si(y,x,c) (s(y,c) = word_in(x, c))
|
||||
#define so(y,x,c) word_out(y, c, s(x,c))
|
||||
#define state_in(y,x) si(y,x,0); si(y,x,1); si(y,x,2); si(y,x,3)
|
||||
#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
|
||||
#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
|
||||
#define to_byte(x) ((x) & 0xff)
|
||||
#define bval(x,n) to_byte((x) >> (8 * (n)))
|
||||
|
||||
#define fwd_var(x,r,c)\
|
||||
( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
|
||||
: r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
|
||||
: r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
|
||||
: ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
|
||||
|
||||
#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
|
||||
|
||||
#define sb_data(w) {\
|
||||
w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
|
||||
w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
|
||||
w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
|
||||
w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
|
||||
w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
|
||||
w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
|
||||
w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
|
||||
w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
|
||||
w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
|
||||
w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
|
||||
w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
|
||||
w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
|
||||
w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
|
||||
w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
|
||||
w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
|
||||
w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
|
||||
w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
|
||||
w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
|
||||
w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
|
||||
w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
|
||||
w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
|
||||
w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
|
||||
w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
|
||||
w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
|
||||
w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
|
||||
w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
|
||||
w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
|
||||
w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
|
||||
w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
|
||||
w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
|
||||
w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
|
||||
w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }
|
||||
|
||||
#define rc_data(w) {\
|
||||
w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\
|
||||
w(0x1b), w(0x36) }
|
||||
|
||||
#define bytes2word(b0, b1, b2, b3) (((uint32_t)(b3) << 24) | \
|
||||
((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0))
|
||||
|
||||
#define h0(x) (x)
|
||||
#define w0(p) bytes2word(p, 0, 0, 0)
|
||||
#define w1(p) bytes2word(0, p, 0, 0)
|
||||
#define w2(p) bytes2word(0, 0, p, 0)
|
||||
#define w3(p) bytes2word(0, 0, 0, p)
|
||||
|
||||
#define u0(p) bytes2word(f2(p), p, p, f3(p))
|
||||
#define u1(p) bytes2word(f3(p), f2(p), p, p)
|
||||
#define u2(p) bytes2word(p, f3(p), f2(p), p)
|
||||
#define u3(p) bytes2word(p, p, f3(p), f2(p))
|
||||
|
||||
#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p))
|
||||
#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p))
|
||||
#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p))
|
||||
#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p))
|
||||
|
||||
#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY))
|
||||
#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
|
||||
#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) ^ (((x>>5) & 4) * WPOLY))
|
||||
#define f3(x) (f2(x) ^ x)
|
||||
#define f9(x) (f8(x) ^ x)
|
||||
#define fb(x) (f8(x) ^ f2(x) ^ x)
|
||||
#define fd(x) (f8(x) ^ f4(x) ^ x)
|
||||
#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
|
||||
|
||||
#define t_dec(m,n) t_##m##n
|
||||
#define t_set(m,n) t_##m##n
|
||||
#define t_use(m,n) t_##m##n
|
||||
|
||||
#define d_4(t,n,b,e,f,g,h) ALIGN const t n[4][256] = { b(e), b(f), b(g), b(h) }
|
||||
|
||||
#define four_tables(x,tab,vf,rf,c) \
|
||||
(tab[0][bval(vf(x,0,c),rf(0,c))] \
|
||||
^ tab[1][bval(vf(x,1,c),rf(1,c))] \
|
||||
^ tab[2][bval(vf(x,2,c),rf(2,c))] \
|
||||
^ tab[3][bval(vf(x,3,c),rf(3,c))])
|
||||
|
||||
d_4(uint32_t, t_dec(f,n), sb_data, u0, u1, u2, u3);
|
||||
|
||||
void aesb_single_round(const uint8_t *in, uint8_t *out, uint8_t *expandedKey)
|
||||
{
|
||||
uint32_t b0[4], b1[4];
|
||||
const uint32_t *kp = (uint32_t *) expandedKey;
|
||||
state_in(b0, in);
|
||||
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
|
||||
state_out(out, b1);
|
||||
}
|
||||
|
||||
void aesb_pseudo_round(const uint8_t *in, uint8_t *out, uint8_t *expandedKey)
|
||||
{
|
||||
uint32_t b0[4], b1[4];
|
||||
const uint32_t *kp = (uint32_t *) expandedKey;
|
||||
state_in(b0, in);
|
||||
|
||||
round(fwd_rnd, b1, b0, kp);
|
||||
round(fwd_rnd, b0, b1, kp + 1 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 2 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 3 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 4 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 5 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 6 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 7 * N_COLS);
|
||||
round(fwd_rnd, b1, b0, kp + 8 * N_COLS);
|
||||
round(fwd_rnd, b0, b1, kp + 9 * N_COLS);
|
||||
|
||||
state_out(out, b0);
|
||||
}
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* This file and its header file are for translating Electrum-style word lists
|
||||
* into their equivalent byte representations for cross-compatibility with
|
||||
* that method of "backing up" one's wallet keys.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include "crypto/crypto.h" // for declaration of crypto::secret_key
|
||||
|
||||
#include "crypto/electrum-words.h"
|
||||
|
||||
namespace crypto
|
||||
{
|
||||
namespace ElectrumWords
|
||||
{
|
||||
|
||||
/* convert words to bytes, 3 words -> 4 bytes
|
||||
* returns:
|
||||
* false if not a multiple of 3 words, or if a words is not in the
|
||||
* words list
|
||||
*
|
||||
* true otherwise
|
||||
*/
|
||||
bool words_to_bytes(const std::string& words, crypto::secret_key& dst)
|
||||
{
|
||||
int n = NUMWORDS; // hardcoded because this is what electrum uses
|
||||
|
||||
std::vector<std::string> wlist;
|
||||
|
||||
boost::split(wlist, words, boost::is_any_of(" "));
|
||||
|
||||
// error on non-compliant word list
|
||||
if (wlist.size() != 12 && wlist.size() != 24) return false;
|
||||
|
||||
for (unsigned int i=0; i < wlist.size() / 3; i++)
|
||||
{
|
||||
uint32_t val;
|
||||
uint32_t w1, w2, w3;
|
||||
|
||||
// verify all three words exist in the word list
|
||||
if (wordsMap.count(wlist[i*3]) == 0 ||
|
||||
wordsMap.count(wlist[i*3 + 1]) == 0 ||
|
||||
wordsMap.count(wlist[i*3 + 2]) == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
w1 = wordsMap.at(wlist[i*3]);
|
||||
w2 = wordsMap.at(wlist[i*3 + 1]);
|
||||
w3 = wordsMap.at(wlist[i*3 + 2]);
|
||||
|
||||
val = w1 + n * (((n - w1) + w2) % n) + n * n * (((n - w2) + w3) % n);
|
||||
|
||||
if (!(val % n == w1)) return false;
|
||||
|
||||
memcpy(dst.data + i * 4, &val, 4); // copy 4 bytes to position
|
||||
}
|
||||
|
||||
std::string wlist_copy = words;
|
||||
if (wlist.size() == 12)
|
||||
{
|
||||
memcpy(dst.data, dst.data + 16, 16); // if electrum 12-word seed, duplicate
|
||||
wlist_copy += ' ';
|
||||
wlist_copy += words;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* convert bytes to words, 4 bytes-> 3 words
|
||||
* returns:
|
||||
* false if wrong number of bytes (shouldn't be possible)
|
||||
* true otherwise
|
||||
*/
|
||||
bool bytes_to_words(const crypto::secret_key& src, std::string& words)
|
||||
{
|
||||
int n = NUMWORDS; // hardcoded because this is what electrum uses
|
||||
|
||||
if (sizeof(src.data) % 4 != 0) return false;
|
||||
|
||||
// 8 bytes -> 3 words. 8 digits base 16 -> 3 digits base 1626
|
||||
for (unsigned int i=0; i < sizeof(src.data)/4; i++, words += ' ')
|
||||
{
|
||||
uint32_t w1, w2, w3;
|
||||
|
||||
uint32_t val;
|
||||
|
||||
memcpy(&val, (src.data) + (i * 4), 4);
|
||||
|
||||
w1 = val % n;
|
||||
w2 = ((val / n) + w1) % n;
|
||||
w3 = (((val / n) / n) + w2) % n;
|
||||
|
||||
words += wordsArray[w1];
|
||||
words += ' ';
|
||||
words += wordsArray[w2];
|
||||
words += ' ';
|
||||
words += wordsArray[w3];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace ElectrumWords
|
||||
|
||||
} // namespace crypto
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
#define BUILD_COMMIT_ID "@VERSION@"
|
||||
#define PROJECT_VERSION "0.8.6"
|
||||
#define PROJECT_VERSION_BUILD_NO "295"
|
||||
#define PROJECT_VERSION "0.8.8"
|
||||
#define PROJECT_VERSION_BUILD_NO "1"
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO "(" BUILD_COMMIT_ID ")"
|
||||
|
@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "crypto/crypto.h"
|
||||
#include "cryptonote_core/cryptonote_basic.h"
|
||||
|
||||
class test_cn_slow_hash
|
||||
{
|
||||
public:
|
||||
static const size_t loop_count = 10;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct data_t
|
||||
{
|
||||
char data[13];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
static_assert(13 == sizeof(data_t), "Invalid structure size");
|
||||
|
||||
bool init()
|
||||
{
|
||||
if (!epee::string_tools::hex_to_pod("63617665617420656d70746f72", m_data))
|
||||
return false;
|
||||
|
||||
if (!epee::string_tools::hex_to_pod("bbec2cacf69866a8e740380fe7b818fc78f8571221742d729d9d02d7f8989b87", m_expected_hash))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test()
|
||||
{
|
||||
crypto::hash hash;
|
||||
crypto::cn_slow_hash(&m_data, sizeof(m_data), hash);
|
||||
return hash == m_expected_hash;
|
||||
}
|
||||
|
||||
private:
|
||||
data_t m_data;
|
||||
crypto::hash m_expected_hash;
|
||||
};
|
@ -0,0 +1,140 @@
|
||||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "cryptonote_core/checkpoints.cpp"
|
||||
|
||||
using namespace cryptonote;
|
||||
|
||||
|
||||
TEST(checkpoints_is_alternative_block_allowed, handles_empty_checkpoins)
|
||||
{
|
||||
checkpoints cp;
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(0, 0));
|
||||
|
||||
ASSERT_TRUE(cp.is_alternative_block_allowed(1, 1));
|
||||
ASSERT_TRUE(cp.is_alternative_block_allowed(1, 9));
|
||||
ASSERT_TRUE(cp.is_alternative_block_allowed(9, 1));
|
||||
}
|
||||
|
||||
TEST(checkpoints_is_alternative_block_allowed, handles_one_checkpoint)
|
||||
{
|
||||
checkpoints cp;
|
||||
cp.add_checkpoint(5, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(0, 0));
|
||||
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 1));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 4));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 9));
|
||||
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 1));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 4));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 9));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(5, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(5, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(5, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(5, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(5, 9));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(6, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(6, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(6, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(6, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(6, 9));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(9, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(9, 9));
|
||||
}
|
||||
|
||||
TEST(checkpoints_is_alternative_block_allowed, handles_two_and_more_checkpoints)
|
||||
{
|
||||
checkpoints cp;
|
||||
cp.add_checkpoint(5, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
cp.add_checkpoint(9, "0000000000000000000000000000000000000000000000000000000000000000");
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(0, 0));
|
||||
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 1));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 4));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 8));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(1, 11));
|
||||
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 1));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 4));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 8));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(4, 11));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(5, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(5, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(5, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(5, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(5, 8));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(5, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(5, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(5, 11));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(6, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(6, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(6, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(6, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(6, 8));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(6, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(6, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(6, 11));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(8, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(8, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(8, 5));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(8, 6));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(8, 8));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(8, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(8, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(8, 11));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 5));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 6));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 8));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(9, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(9, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(9, 11));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(10, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(10, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(10, 5));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(10, 6));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(10, 8));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(10, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(10, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(10, 11));
|
||||
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(11, 1));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(11, 4));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(11, 5));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(11, 6));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(11, 8));
|
||||
ASSERT_FALSE(cp.is_alternative_block_allowed(11, 9));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(11, 10));
|
||||
ASSERT_TRUE (cp.is_alternative_block_allowed(11, 11));
|
||||
}
|
Loading…
Reference in new issue