/* Demonstration of private keys. */ #include <iostream> #include <sstream> #include <bitcoin/bitcoin.hpp> using namespace bc; void display_help() { puts("Usage: priv [COMMAND] [ARGS]..."); puts(""); puts("The priv commands are:"); puts(" new\t\tGenerate a new private key and output to STDOUT"); puts(" sign\t\tSign the next argument using the private key in STDIN"); puts(" verify\tVerify the next argument using the private key in STDIN"); puts(" address\tshow the associated bitcoin address"); } void error_exit(const char* message, int status=1) { std::cerr << "priv: " << message << std::endl; exit(status); } int new_keypair() { elliptic_curve_key ec; ec.new_key_pair(); private_data raw_private_key = ec.private_key(); std::cout << std::string(raw_private_key.begin(), raw_private_key.end()); return 0; } int sign(const std::string input_data, const std::string raw_private_key) { hash_digest digest = decode_hex_digest<hash_digest>(input_data); elliptic_curve_key ec; if (!ec.set_private_key( private_data(raw_private_key.begin(), raw_private_key.end()))) error_exit("bad private key"); log_info() << encode_hex(ec.sign(digest)); return 0; } int verify(const std::string input_data, const std::string& signature_data, const std::string raw_private_key) { hash_digest digest = decode_hex_digest<hash_digest>(input_data); data_chunk signature = decode_hex(signature_data); elliptic_curve_key ec; if (!ec.set_private_key( private_data(raw_private_key.begin(), raw_private_key.end()))) error_exit("bad private key"); log_info() << (ec.verify(digest, signature) ? '1' : '0'); return 0; } int address(const std::string raw_private_key) { elliptic_curve_key ec; if (!ec.set_private_key( private_data(raw_private_key.begin(), raw_private_key.end()))) error_exit("bad private key"); payment_address address; if (!set_public_key(address, ec.public_key())) error_exit("set public key on address"); log_info() << address.encoded(); return 0; } std::string read_private_key() { std::istreambuf_iterator<char> it(std::cin); std::istreambuf_iterator<char> end; return std::string(it, end); } int main(int argc, char** argv) { if (argc < 2) { display_help(); return 0; } std::string command = argv[1]; size_t number_args = argc - 2, arg_index = 2; if (command == "new") return new_keypair(); else if (command == "sign") { if (number_args != 1) error_exit("sign requires argument data"); std::string input_data = argv[arg_index]; return sign(input_data, read_private_key()); } else if (command == "verify") { if (number_args != 2) error_exit("verify requires argument data and signature"); std::string input_data = argv[arg_index], signature = argv[arg_index + 1]; return verify(input_data, signature, read_private_key()); } else if (command == "address") return address(read_private_key()); else error_exit("not a valid command. See priv help text."); // Should never happen! return 1; }