wallet: add command and RPC to sign/verify data

Signing is done using the spend key, since the view key may
be shared. This could be extended later, to let the user choose
which key (even a per tx key).
simplewallet's sign/verify API uses a file. The RPC uses a
string (simplewallet can't easily do strings since commands
receive a tokenized set of arguments).
This commit is contained in:
moneromooo-monero 2016-04-23 21:46:48 +01:00
parent 18dd507024
commit 89d9f382a0
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
8 changed files with 195 additions and 2 deletions

View file

@ -53,6 +53,7 @@ using namespace epee;
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include "common/json_util.h"
#include "common/base58.h"
extern "C"
{
@ -3106,6 +3107,40 @@ std::string wallet2::get_tx_note(const crypto::hash &txid) const
return std::string();
return i->second;
}
std::string wallet2::sign(const std::string &data) const
{
crypto::hash hash;
crypto::cn_fast_hash(data.data(), data.size(), hash);
const cryptonote::account_keys &keys = m_account.get_keys();
crypto::signature signature;
crypto::generate_signature(hash, keys.m_account_address.m_spend_public_key, keys.m_spend_secret_key, signature);
return std::string("SigV1") + tools::base58::encode(std::string((const char *)&signature, sizeof(signature)));
}
bool wallet2::verify(const std::string &data, const cryptonote::account_public_address &address, const std::string &signature) const
{
const size_t header_len = strlen("SigV1");
if (signature.size() < header_len || signature.substr(0, header_len) != "SigV1") {
LOG_PRINT_L0("Signature header check error");
return false;
}
crypto::hash hash;
crypto::cn_fast_hash(data.data(), data.size(), hash);
std::string decoded;
if (!tools::base58::decode(signature.substr(header_len), decoded)) {
LOG_PRINT_L0("Signature decoding error");
return false;
}
crypto::signature s;
if (sizeof(s) != decoded.size()) {
LOG_PRINT_L0("Signature decoding error");
return false;
}
memcpy(&s, decoded.data(), sizeof(s));
return crypto::check_signature(hash, address.m_spend_public_key, s);
}
//----------------------------------------------------------------------------------------------------
void wallet2::generate_genesis(cryptonote::block& b) {
if (m_testnet)