/* This file is part of cpp-ethereum. cpp-ethereum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Foobar is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Foobar. If not, see . */ /** @file crypto.cpp * @author Gav Wood * @date 2014 * Crypto test functions. */ #include #include #include #include #include using namespace std; using namespace eth; int cryptoTest() { secp256k1_start(); KeyPair p(Secret(fromUserHex("3ecb44df2159c26e0f995712d4f39b6f6e499b40749b1cf1246c37f9516cb6a4"))); assert(p.pub() == Public(fromUserHex("97466f2b32bc3bb76d4741ae51cd1d8578b48d3f1e68da206d47321aec267ce78549b514e4453d74ef11b0cd5e4e4c364effddac8b51bcfc8de80682f952896f"))); assert(p.address() == Address(fromUserHex("8a40bfaa73256b60764c1bf40675a99083efb075"))); { Transaction t; t.nonce = 0; t.receiveAddress = h160(fromUserHex("944400f4b88ac9589a0f17ed4671da26bddb668b")); t.value = 1000; t.data = u256s(); cnote << RLP(t.rlp(false)); cnote << asHex(t.rlp(false)); cnote << t.sha3(false); t.sign(p.secret()); cnote << RLP(t.rlp(true)); cnote << asHex(t.rlp(true)); cnote << t.sha3(true); assert(t.sender() == p.address()); } #if 0 // Test transaction. bytes tx = fromUserHex("88005401010101010101010101010101010101010101011f0de0b6b3a76400001ce8d4a5100080181c373130a009ba1f10285d4e659568bfcfec85067855c5a3c150100815dad4ef98fd37cf0593828c89db94bd6c64e210a32ef8956eaa81ea9307194996a3b879441f5d"); cout << "TX: " << RLP(tx) << endl; Transaction t2(tx); cout << "SENDER: " << hex << t2.sender() << dec << endl; secp256k1_start(); Transaction t; t.nonce = 0; t.value = 1; // 1 wei. t.receiveAddress = toAddress(sha3("123")); bytes sig64 = toBigEndian(t.vrs.r) + toBigEndian(t.vrs.s); cout << "SIG: " << sig64.size() << " " << asHex(sig64) << " " << t.vrs.v << endl; auto msg = t.rlp(false); cout << "TX w/o SIG: " << RLP(msg) << endl; cout << "RLP(TX w/o SIG): " << asHex(t.rlpString(false)) << endl; std::string hmsg = sha3(t.rlpString(false), false); cout << "SHA256(RLP(TX w/o SIG)): 0x" << asHex(hmsg) << endl; bytes privkey = sha3Bytes("123"); { bytes pubkey(65); int pubkeylen = 65; int ret = secp256k1_ecdsa_seckey_verify(privkey.data()); cout << "SEC: " << dec << ret << " " << asHex(privkey) << endl; ret = secp256k1_ecdsa_pubkey_create(pubkey.data(), &pubkeylen, privkey.data(), 1); pubkey.resize(pubkeylen); int good = secp256k1_ecdsa_pubkey_verify(pubkey.data(), pubkey.size()); cout << "PUB: " << dec << ret << " " << pubkeylen << " " << asHex(pubkey) << (good ? " GOOD" : " BAD") << endl; } // Test roundtrip... { bytes sig(64); u256 nonce = 0; int v = 0; cout << asHex(hmsg) << endl; cout << asHex(privkey) << endl; cout << hex << nonce << dec << endl; int ret = secp256k1_ecdsa_sign_compact((byte const*)hmsg.data(), hmsg.size(), sig.data(), privkey.data(), (byte const*)&nonce, &v); cout << "MYSIG: " << dec << ret << " " << sig.size() << " " << asHex(sig) << " " << v << endl; bytes pubkey(65); int pubkeylen = 65; ret = secp256k1_ecdsa_recover_compact((byte const*)hmsg.data(), hmsg.size(), (byte const*)sig.data(), pubkey.data(), &pubkeylen, 0, v); pubkey.resize(pubkeylen); cout << "MYREC: " << dec << ret << " " << pubkeylen << " " << asHex(pubkey) << endl; } { bytes pubkey(65); int pubkeylen = 65; int ret = secp256k1_ecdsa_recover_compact((byte const*)hmsg.data(), hmsg.size(), (byte const*)sig64.data(), pubkey.data(), &pubkeylen, 0, (int)t.vrs.v - 27); pubkey.resize(pubkeylen); cout << "RECPUB: " << dec << ret << " " << pubkeylen << " " << asHex(pubkey) << endl; cout << "SENDER: " << hex << low160(eth::sha3(bytesConstRef(&pubkey).cropped(1))) << dec << endl; } #endif return 0; }