From 3a016ea0b41c67eeeabf7ae0d20ceb378f13f24a Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 10 Nov 2014 13:13:40 +0100 Subject: [PATCH 01/16] Replace function selector jump table by more resilient linear time check. --- solidityCompiler.cpp | 14 +++++++------- solidityEndToEndTest.cpp | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/solidityCompiler.cpp b/solidityCompiler.cpp index ba2db67e6..054ad3297 100644 --- a/solidityCompiler.cpp +++ b/solidityCompiler.cpp @@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE(smoke_test) "}\n"; bytes code = compileContract(sourceCode); - unsigned boilerplateSize = 51; + unsigned boilerplateSize = 42; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x0, // initialize local variable x byte(Instruction::PUSH1), 0x2, @@ -100,8 +100,8 @@ BOOST_AUTO_TEST_CASE(different_argument_numbers) "}\n"; bytes code = compileContract(sourceCode); - unsigned shift = 75; - unsigned boilerplateSize = 88; + unsigned shift = 70; + unsigned boilerplateSize = 83; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x0, // initialize return variable d byte(Instruction::DUP3), @@ -153,8 +153,8 @@ BOOST_AUTO_TEST_CASE(ifStatement) "}\n"; bytes code = compileContract(sourceCode); - unsigned shift = 38; - unsigned boilerplateSize = 51; + unsigned shift = 29; + unsigned boilerplateSize = 42; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x0, byte(Instruction::DUP1), @@ -195,8 +195,8 @@ BOOST_AUTO_TEST_CASE(loops) "}\n"; bytes code = compileContract(sourceCode); - unsigned shift = 38; - unsigned boilerplateSize = 51; + unsigned shift = 29; + unsigned boilerplateSize = 42; bytes expectation({byte(Instruction::JUMPDEST), byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x1, diff --git a/solidityEndToEndTest.cpp b/solidityEndToEndTest.cpp index 796adcb15..788c388e4 100644 --- a/solidityEndToEndTest.cpp +++ b/solidityEndToEndTest.cpp @@ -148,6 +148,22 @@ BOOST_AUTO_TEST_CASE(recursive_calls) BOOST_CHECK(testSolidityAgainstCpp(0, recursive_calls_cpp, u256(4))); } +BOOST_AUTO_TEST_CASE(multiple_functions) +{ + char const* sourceCode = "contract test {\n" + " function a() returns(uint n) { return 0; }\n" + " function b() returns(uint n) { return 1; }\n" + " function c() returns(uint n) { return 2; }\n" + " function f() returns(uint n) { return 3; }\n" + "}\n"; + compileAndRun(sourceCode); + BOOST_CHECK(callFunction(0, bytes()) == toBigEndian(u256(0))); + BOOST_CHECK(callFunction(1, bytes()) == toBigEndian(u256(1))); + BOOST_CHECK(callFunction(2, bytes()) == toBigEndian(u256(2))); + BOOST_CHECK(callFunction(3, bytes()) == toBigEndian(u256(3))); + BOOST_CHECK(callFunction(4, bytes()) == bytes()); +} + BOOST_AUTO_TEST_CASE(while_loop) { char const* sourceCode = "contract test {\n" From 315223fc41b61f1027aab88f19bdbfc40b89f576 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 10 Nov 2014 15:36:21 +0100 Subject: [PATCH 02/16] Tests on ranges of input data. --- solidityEndToEndTest.cpp | 114 +++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/solidityEndToEndTest.cpp b/solidityEndToEndTest.cpp index 796adcb15..cca9b7db2 100644 --- a/solidityEndToEndTest.cpp +++ b/solidityEndToEndTest.cpp @@ -41,7 +41,7 @@ class ExecutionFramework public: ExecutionFramework() { g_logVerbosity = 0; } - bytes const& compileAndRun(std::string const& _sourceCode) + bytes const& compileAndRun(string const& _sourceCode) { bytes code = dev::solidity::CompilerStack::compile(_sourceCode); sendMessage(code, true); @@ -49,28 +49,50 @@ public: return m_output; } - bytes const& callFunction(byte _index, bytes const& _data) + bytes const& callFunction(byte _index, bytes const& _data = bytes()) { sendMessage(bytes(1, _index) + _data, false); return m_output; } - bytes const& callFunction(byte _index, u256 const& _argument1) + template + bytes const& callFunction(byte _index, Args const&... _arguments) { - return callFunction(_index, toBigEndian(_argument1)); + return callFunction(_index, argsToBigEndian(_arguments...)); } - bool testSolidityAgainstCpp(byte _index, std::function const& _cppfun, u256 const& _argument1) + template + void testSolidityAgainstCpp(byte _index, CppFunction const& _cppFunctions, Args const&... _arguments) { - return toBigEndian(_cppfun(_argument1)) == callFunction(_index, toBigEndian(_argument1)); + bytes solidityResult = callFunction(_index, _arguments...); + bytes cppResult = toBigEndian(_cppFunctions(_arguments...)); + BOOST_CHECK_MESSAGE(solidityResult == cppResult, "Computed values do not match." + "\nSolidity: " + toHex(solidityResult) + "\nC++: " + toHex(cppResult)); } - bool testSolidityAgainstCpp(byte _index, std::function const& _cppfun) + template + void testSolidityAgainstCppOnRange(byte _index, CppFunction const& _cppFunction, + u256 const& _rangeStart, u256 const& _rangeEnd) { - return toBigEndian(_cppfun()) == callFunction(_index, bytes()); + for (u256 argument = _rangeStart; argument < _rangeEnd; ++argument) + { + bytes solidityResult = callFunction(_index, argument); + bytes cppResult = toBigEndian(_cppFunction(argument)); + BOOST_CHECK_MESSAGE(solidityResult == cppResult, "Computed values do not match." + "\nSolidity: " + toHex(solidityResult) + "\nC++: " + toHex(cppResult) + + "\nArgument: " + toHex(toBigEndian(argument))); + } } private: + template + bytes argsToBigEndian(FirstArg const& _firstArg, Args const&... _followingArgs) const + { + return toBigEndian(_firstArg) + argsToBigEndian(_followingArgs...); + } + + bytes argsToBigEndian() const { return bytes(); } + void sendMessage(bytes const& _data, bool _isCreation) { eth::Executive executive(m_state); @@ -91,7 +113,10 @@ private: BOOST_REQUIRE(m_state.addressHasCode(m_contractAddress)); } else + { + BOOST_REQUIRE(m_state.addressHasCode(m_contractAddress)); BOOST_REQUIRE(!executive.call(m_contractAddress, Address(), 0, m_gasPrice, &_data, m_gas, Address())); + } BOOST_REQUIRE(executive.go()); executive.finalize(); m_output = executive.out().toVector(); @@ -112,8 +137,7 @@ BOOST_AUTO_TEST_CASE(smoke_test) " function f(uint a) returns(uint d) { return a * 7; }\n" "}\n"; compileAndRun(sourceCode); - u256 a = 0x200030004; - BOOST_CHECK(callFunction(0, a) == toBigEndian(a * 7)); + testSolidityAgainstCppOnRange(0, [](u256 const& a) -> u256 { return a * 7; }, 0, 100); } BOOST_AUTO_TEST_CASE(empty_contract) @@ -133,7 +157,7 @@ BOOST_AUTO_TEST_CASE(recursive_calls) " }\n" "}\n"; compileAndRun(sourceCode); - std::function recursive_calls_cpp = [&recursive_calls_cpp](u256 const& n) -> u256 + function recursive_calls_cpp = [&recursive_calls_cpp](u256 const& n) -> u256 { if (n <= 1) return 1; @@ -141,11 +165,7 @@ BOOST_AUTO_TEST_CASE(recursive_calls) return n * recursive_calls_cpp(n - 1); }; - BOOST_CHECK(testSolidityAgainstCpp(0, recursive_calls_cpp, u256(0))); - BOOST_CHECK(testSolidityAgainstCpp(0, recursive_calls_cpp, u256(1))); - BOOST_CHECK(testSolidityAgainstCpp(0, recursive_calls_cpp, u256(2))); - BOOST_CHECK(testSolidityAgainstCpp(0, recursive_calls_cpp, u256(3))); - BOOST_CHECK(testSolidityAgainstCpp(0, recursive_calls_cpp, u256(4))); + testSolidityAgainstCppOnRange(0, recursive_calls_cpp, 0, 5); } BOOST_AUTO_TEST_CASE(while_loop) @@ -169,11 +189,7 @@ BOOST_AUTO_TEST_CASE(while_loop) return nfac; }; - BOOST_CHECK(testSolidityAgainstCpp(0, while_loop_cpp, u256(0))); - BOOST_CHECK(testSolidityAgainstCpp(0, while_loop_cpp, u256(1))); - BOOST_CHECK(testSolidityAgainstCpp(0, while_loop_cpp, u256(2))); - BOOST_CHECK(testSolidityAgainstCpp(0, while_loop_cpp, u256(3))); - BOOST_CHECK(testSolidityAgainstCpp(0, while_loop_cpp, u256(4))); + testSolidityAgainstCppOnRange(0, while_loop_cpp, 0, 5); } BOOST_AUTO_TEST_CASE(break_outside_loop) @@ -184,9 +200,8 @@ BOOST_AUTO_TEST_CASE(break_outside_loop) " break; continue; return 2;\n" " }\n" "}\n"; - ExecutionFramework framework; - framework.compileAndRun(sourceCode); - BOOST_CHECK(framework.callFunction(0, u256(0)) == toBigEndian(u256(2))); + compileAndRun(sourceCode); + testSolidityAgainstCpp(0, [](u256 const& _a) -> u256 { return 2; }, u256(0)); } BOOST_AUTO_TEST_CASE(nested_loops) @@ -209,8 +224,7 @@ BOOST_AUTO_TEST_CASE(nested_loops) " return x;\n" " }\n" "}\n"; - ExecutionFramework framework; - framework.compileAndRun(sourceCode); + compileAndRun(sourceCode); auto nested_loops_cpp = [](u256 n) -> u256 { @@ -236,18 +250,7 @@ BOOST_AUTO_TEST_CASE(nested_loops) return n; }; - BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(0))); - BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(1))); - BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(2))); - BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(3))); - BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(4))); - BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(5))); - BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(6))); - BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(7))); - BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(8))); - BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(9))); - BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(10))); - BOOST_CHECK(framework.testSolidityAgainstCpp(0, nested_loops_cpp, u256(11))); + testSolidityAgainstCppOnRange(0, nested_loops_cpp, 0, 12); } BOOST_AUTO_TEST_CASE(calling_other_functions) @@ -279,7 +282,8 @@ BOOST_AUTO_TEST_CASE(calling_other_functions) return 3 * n + 1; }; - auto collatz_cpp = [&evenStep_cpp, &oddStep_cpp] (u256 n) -> u256 { + auto collatz_cpp = [&evenStep_cpp, &oddStep_cpp](u256 n) -> u256 + { u256 y; while ((y = n) > 1) { @@ -291,11 +295,11 @@ BOOST_AUTO_TEST_CASE(calling_other_functions) return y; }; - BOOST_CHECK(testSolidityAgainstCpp(2, collatz_cpp, u256(0))); - BOOST_CHECK(testSolidityAgainstCpp(2, collatz_cpp, u256(1))); - BOOST_CHECK(testSolidityAgainstCpp(2, collatz_cpp, u256(2))); - BOOST_CHECK(testSolidityAgainstCpp(2, collatz_cpp, u256(8))); - BOOST_CHECK(testSolidityAgainstCpp(2, collatz_cpp, u256(127))); + testSolidityAgainstCpp(2, collatz_cpp, u256(0)); + testSolidityAgainstCpp(2, collatz_cpp, u256(1)); + testSolidityAgainstCpp(2, collatz_cpp, u256(2)); + testSolidityAgainstCpp(2, collatz_cpp, u256(8)); + testSolidityAgainstCpp(2, collatz_cpp, u256(127)); } BOOST_AUTO_TEST_CASE(many_local_variables) @@ -308,8 +312,15 @@ BOOST_AUTO_TEST_CASE(many_local_variables) " }\n" "}\n"; compileAndRun(sourceCode); - BOOST_CHECK(callFunction(0, toBigEndian(u256(0x1000)) + toBigEndian(u256(0x10000)) + toBigEndian(u256(0x100000))) - == toBigEndian(u256(0x121121))); + auto f = [](u256 const& x1, u256 const& x2, u256 const& x3) -> u256 + { + u256 a = 0x1; + u256 b = 0x10; + u256 c = 0x100; + u256 y = a + b + c + x1 + x2 + x3; + return y + b + x2; + }; + testSolidityAgainstCpp(0, f, u256(0x1000), u256(0x10000), u256(0x100000)); } BOOST_AUTO_TEST_CASE(packing_unpacking_types) @@ -354,8 +365,7 @@ BOOST_AUTO_TEST_CASE(short_circuiting) return n; }; - BOOST_CHECK(testSolidityAgainstCpp(0, short_circuiting_cpp, u256(0))); - BOOST_CHECK(testSolidityAgainstCpp(0, short_circuiting_cpp, u256(1))); + testSolidityAgainstCppOnRange(0, short_circuiting_cpp, 0, 2); } BOOST_AUTO_TEST_CASE(high_bits_cleaning) @@ -375,7 +385,7 @@ BOOST_AUTO_TEST_CASE(high_bits_cleaning) return 0; return x; }; - BOOST_CHECK(testSolidityAgainstCpp(0, high_bits_cleaning_cpp)); + testSolidityAgainstCpp(0, high_bits_cleaning_cpp); } BOOST_AUTO_TEST_CASE(sign_extension) @@ -395,7 +405,7 @@ BOOST_AUTO_TEST_CASE(sign_extension) return 0; return u256(x) * -1; }; - BOOST_CHECK(testSolidityAgainstCpp(0, sign_extension_cpp)); + testSolidityAgainstCpp(0, sign_extension_cpp); } BOOST_AUTO_TEST_CASE(small_unsigned_types) @@ -412,7 +422,7 @@ BOOST_AUTO_TEST_CASE(small_unsigned_types) uint32_t x = uint32_t(0xffffff) * 0xffffff; return x / 0x100; }; - BOOST_CHECK(testSolidityAgainstCpp(0, small_unsigned_types_cpp)); + testSolidityAgainstCpp(0, small_unsigned_types_cpp); } BOOST_AUTO_TEST_CASE(small_signed_types) @@ -427,7 +437,7 @@ BOOST_AUTO_TEST_CASE(small_signed_types) { return -int32_t(10) * -int64_t(20); }; - BOOST_CHECK(testSolidityAgainstCpp(0, small_signed_types_cpp)); + testSolidityAgainstCpp(0, small_signed_types_cpp); } BOOST_AUTO_TEST_CASE(state_smoke_test) From f0dd0d797e5cff8ba4e864ea8963266dd2ecd719 Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 10 Nov 2014 18:07:56 +0100 Subject: [PATCH 03/16] Allow void return type. --- solidityEndToEndTest.cpp | 58 ++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/solidityEndToEndTest.cpp b/solidityEndToEndTest.cpp index cca9b7db2..123d67988 100644 --- a/solidityEndToEndTest.cpp +++ b/solidityEndToEndTest.cpp @@ -22,6 +22,7 @@ */ #include +#include #include #include #include @@ -49,25 +50,24 @@ public: return m_output; } - bytes const& callFunction(byte _index, bytes const& _data = bytes()) + bytes const& callContractFunction(byte _index, bytes const& _data = bytes()) { sendMessage(bytes(1, _index) + _data, false); return m_output; } template - bytes const& callFunction(byte _index, Args const&... _arguments) + bytes const& callContractFunction(byte _index, Args const&... _arguments) { - return callFunction(_index, argsToBigEndian(_arguments...)); + return callContractFunction(_index, argsToBigEndian(_arguments...)); } template - void testSolidityAgainstCpp(byte _index, CppFunction const& _cppFunctions, Args const&... _arguments) + void testSolidityAgainstCpp(byte _index, CppFunction const& _cppFunction, Args const&... _arguments) { - bytes solidityResult = callFunction(_index, _arguments...); - bytes cppResult = toBigEndian(_cppFunctions(_arguments...)); - BOOST_CHECK_MESSAGE(solidityResult == cppResult, "Computed values do not match." - "\nSolidity: " + toHex(solidityResult) + "\nC++: " + toHex(cppResult)); + pair result = callImplementations(_index, _cppFunction, _arguments...); + BOOST_CHECK_MESSAGE(result.first == result.second, "Computed values do not match." + "\nSolidity: " + toHex(result.first) + "\nC++: " + toHex(result.second)); } template @@ -76,15 +76,27 @@ public: { for (u256 argument = _rangeStart; argument < _rangeEnd; ++argument) { - bytes solidityResult = callFunction(_index, argument); - bytes cppResult = toBigEndian(_cppFunction(argument)); - BOOST_CHECK_MESSAGE(solidityResult == cppResult, "Computed values do not match." - "\nSolidity: " + toHex(solidityResult) + "\nC++: " + toHex(cppResult) + + pair result = callImplementations(_index, _cppFunction, argument); + BOOST_CHECK_MESSAGE(result.first == result.second, "Computed values do not match." + "\nSolidity: " + toHex(result.first) + "\nC++: " + toHex(result.second) + "\nArgument: " + toHex(toBigEndian(argument))); } } private: + template + pair callImplementations(byte _solidityIndex, CppFunction const& _cppFunction, + Args const&... _arguments) + { + bytes solidityResult = callContractFunction(_solidityIndex, _arguments...); + bytes cppResult; + if (is_void::value) + _cppFunction(_arguments...); + else + cppResult = toBigEndian(_cppFunction(_arguments...)); + return make_pair(solidityResult, cppResult); + } + template bytes argsToBigEndian(FirstArg const& _firstArg, Args const&... _followingArgs) const { @@ -145,7 +157,7 @@ BOOST_AUTO_TEST_CASE(empty_contract) char const* sourceCode = "contract test {\n" "}\n"; compileAndRun(sourceCode); - BOOST_CHECK(callFunction(0, bytes()).empty()); + BOOST_CHECK(callContractFunction(0, bytes()).empty()); } BOOST_AUTO_TEST_CASE(recursive_calls) @@ -333,7 +345,7 @@ BOOST_AUTO_TEST_CASE(packing_unpacking_types) " }\n" "}\n"; compileAndRun(sourceCode); - BOOST_CHECK(callFunction(0, fromHex("01""0f0f0f0f""f0f0f0f0f0f0f0f0")) + BOOST_CHECK(callContractFunction(0, fromHex("01""0f0f0f0f""f0f0f0f0f0f0f0f0")) == fromHex("00000000000000000000000000000000000000""01""f0f0f0f0""0f0f0f0f0f0f0f0f")); } @@ -345,7 +357,7 @@ BOOST_AUTO_TEST_CASE(multiple_return_values) " }\n" "}\n"; compileAndRun(sourceCode); - BOOST_CHECK(callFunction(0, bytes(1, 1) + toBigEndian(u256(0xcd))) + BOOST_CHECK(callContractFunction(0, bytes(1, 1) + toBigEndian(u256(0xcd))) == toBigEndian(u256(0xcd)) + bytes(1, 1) + toBigEndian(u256(0))); } @@ -455,14 +467,14 @@ BOOST_AUTO_TEST_CASE(state_smoke_test) " }\n" "}\n"; compileAndRun(sourceCode); - BOOST_CHECK(callFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0))); - BOOST_CHECK(callFunction(0, bytes(1, 0x01)) == toBigEndian(u256(0))); - BOOST_CHECK(callFunction(1, bytes(1, 0x00) + toBigEndian(u256(0x1234))) == bytes()); - BOOST_CHECK(callFunction(1, bytes(1, 0x01) + toBigEndian(u256(0x8765))) == bytes()); - BOOST_CHECK(callFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0x1234))); - BOOST_CHECK(callFunction(0, bytes(1, 0x01)) == toBigEndian(u256(0x8765))); - BOOST_CHECK(callFunction(1, bytes(1, 0x00) + toBigEndian(u256(0x3))) == bytes()); - BOOST_CHECK(callFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0x3))); + BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0))); + BOOST_CHECK(callContractFunction(0, bytes(1, 0x01)) == toBigEndian(u256(0))); + BOOST_CHECK(callContractFunction(1, bytes(1, 0x00) + toBigEndian(u256(0x1234))) == bytes()); + BOOST_CHECK(callContractFunction(1, bytes(1, 0x01) + toBigEndian(u256(0x8765))) == bytes()); + BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0x1234))); + BOOST_CHECK(callContractFunction(0, bytes(1, 0x01)) == toBigEndian(u256(0x8765))); + BOOST_CHECK(callContractFunction(1, bytes(1, 0x00) + toBigEndian(u256(0x3))) == bytes()); + BOOST_CHECK(callContractFunction(0, bytes(1, 0x00)) == toBigEndian(u256(0x3))); } BOOST_AUTO_TEST_SUITE_END() From 381bec82848ced1bf906f8f8c324f9ce13ba354b Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 11 Nov 2014 11:41:23 +0100 Subject: [PATCH 04/16] Working template magic for void function. --- solidityEndToEndTest.cpp | 41 +++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/solidityEndToEndTest.cpp b/solidityEndToEndTest.cpp index 123d67988..85fd707c3 100644 --- a/solidityEndToEndTest.cpp +++ b/solidityEndToEndTest.cpp @@ -65,9 +65,10 @@ public: template void testSolidityAgainstCpp(byte _index, CppFunction const& _cppFunction, Args const&... _arguments) { - pair result = callImplementations(_index, _cppFunction, _arguments...); - BOOST_CHECK_MESSAGE(result.first == result.second, "Computed values do not match." - "\nSolidity: " + toHex(result.first) + "\nC++: " + toHex(result.second)); + bytes solidityResult = callContractFunction(_index, _arguments...); + bytes cppResult = callCppAndEncodeResult(_cppFunction, _arguments...); + BOOST_CHECK_MESSAGE(solidityResult == cppResult, "Computed values do not match." + "\nSolidity: " + toHex(solidityResult) + "\nC++: " + toHex(cppResult)); } template @@ -76,27 +77,15 @@ public: { for (u256 argument = _rangeStart; argument < _rangeEnd; ++argument) { - pair result = callImplementations(_index, _cppFunction, argument); - BOOST_CHECK_MESSAGE(result.first == result.second, "Computed values do not match." - "\nSolidity: " + toHex(result.first) + "\nC++: " + toHex(result.second) + + bytes solidityResult = callContractFunction(_index, argument); + bytes cppResult = callCppAndEncodeResult(_cppFunction, argument); + BOOST_CHECK_MESSAGE(solidityResult == cppResult, "Computed values do not match." + "\nSolidity: " + toHex(solidityResult) + "\nC++: " + toHex(cppResult) + "\nArgument: " + toHex(toBigEndian(argument))); } } private: - template - pair callImplementations(byte _solidityIndex, CppFunction const& _cppFunction, - Args const&... _arguments) - { - bytes solidityResult = callContractFunction(_solidityIndex, _arguments...); - bytes cppResult; - if (is_void::value) - _cppFunction(_arguments...); - else - cppResult = toBigEndian(_cppFunction(_arguments...)); - return make_pair(solidityResult, cppResult); - } - template bytes argsToBigEndian(FirstArg const& _firstArg, Args const&... _followingArgs) const { @@ -105,6 +94,20 @@ private: bytes argsToBigEndian() const { return bytes(); } + template + auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments) + -> typename enable_if::value, bytes>::type + { + _cppFunction(_arguments...); + return bytes(); + } + template + auto callCppAndEncodeResult(CppFunction const& _cppFunction, Args const&... _arguments) + -> typename enable_if::value, bytes>::type + { + return toBigEndian(_cppFunction(_arguments...)); + } + void sendMessage(bytes const& _data, bool _isCreation) { eth::Executive executive(m_state); From 1b405a6957e8860f4d4db78df5d92dbb69c301dc Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 11 Nov 2014 17:41:48 +0100 Subject: [PATCH 05/16] Provide interface for calls in JSON and some other formatting changes. --- solidityEndToEndTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solidityEndToEndTest.cpp b/solidityEndToEndTest.cpp index 796adcb15..ffeab0a76 100644 --- a/solidityEndToEndTest.cpp +++ b/solidityEndToEndTest.cpp @@ -43,7 +43,7 @@ public: bytes const& compileAndRun(std::string const& _sourceCode) { - bytes code = dev::solidity::CompilerStack::compile(_sourceCode); + bytes code = dev::solidity::CompilerStack::staticCompile(_sourceCode); sendMessage(code, true); BOOST_REQUIRE(!m_output.empty()); return m_output; From 3842c3c9bd4e349ad2bce0efa5672473f80d7ace Mon Sep 17 00:00:00 2001 From: subtly Date: Tue, 11 Nov 2014 18:31:23 +0100 Subject: [PATCH 06/16] ecdh, ecdhe, initial aes classes --- TestHelperCrypto.h | 51 --------------- crypto.cpp | 151 ++++++++++++++++++++++++++++----------------- 2 files changed, 93 insertions(+), 109 deletions(-) delete mode 100644 TestHelperCrypto.h diff --git a/TestHelperCrypto.h b/TestHelperCrypto.h deleted file mode 100644 index 01e97c21f..000000000 --- a/TestHelperCrypto.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - 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. - - cpp-ethereum 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 cpp-ethereum. If not, see . - */ -/** @file TestHelperCrypto.h - * @author Alex Leverington - * @date 2014 - */ - -#pragma once - -#include - -using namespace std; -using namespace CryptoPP; - -void SavePrivateKey(const PrivateKey& key, const string& file = "ecies.private.key") -{ - FileSink sink(file.c_str()); - key.Save(sink); -} - -void SavePublicKey(const PublicKey& key, const string& file = "ecies.public.key") -{ - FileSink sink(file.c_str()); - key.Save(sink); -} - -void LoadPrivateKey(PrivateKey& key, const string& file = "ecies.private.key") -{ - FileSource source(file.c_str(), true); - key.Load(source); -} - -void LoadPublicKey(PublicKey& key, const string& file = "ecies.public.key") -{ - FileSource source(file.c_str(), true); - key.Load(source); -} diff --git a/crypto.cpp b/crypto.cpp index 06e55658a..a84c1fbb5 100644 --- a/crypto.cpp +++ b/crypto.cpp @@ -27,9 +27,10 @@ #include #include #include -#include #include -#include "TestHelperCrypto.h" +#include +#include +#include using namespace std; using namespace dev; @@ -40,7 +41,7 @@ BOOST_AUTO_TEST_SUITE(devcrypto) BOOST_AUTO_TEST_CASE(common_encrypt_decrypt) { - string message("Now is the time for all good persons to come to the aide of humanity."); + string message("Now is the time for all good persons to come to the aid of humanity."); bytes m = asBytes(message); bytesConstRef bcr(&m); @@ -267,7 +268,7 @@ BOOST_AUTO_TEST_CASE(ecies_eckeypair) { KeyPair k = KeyPair::create(); - string message("Now is the time for all good persons to come to the aide of humanity."); + string message("Now is the time for all good persons to come to the aid of humanity."); string original = message; bytes b = asBytes(message); @@ -278,6 +279,79 @@ BOOST_AUTO_TEST_CASE(ecies_eckeypair) BOOST_REQUIRE(b == asBytes(original)); } +BOOST_AUTO_TEST_CASE(ecdh) +{ + cnote << "Testing ecdh..."; + + ECDH::Domain dhLocal(pp::secp256k1Curve); + SecByteBlock privLocal(dhLocal.PrivateKeyLength()); + SecByteBlock pubLocal(dhLocal.PublicKeyLength()); + dhLocal.GenerateKeyPair(pp::PRNG, privLocal, pubLocal); + + ECDH::Domain dhRemote(pp::secp256k1Curve); + SecByteBlock privRemote(dhRemote.PrivateKeyLength()); + SecByteBlock pubRemote(dhRemote.PublicKeyLength()); + dhRemote.GenerateKeyPair(pp::PRNG, privRemote, pubRemote); + + assert(dhLocal.AgreedValueLength() == dhRemote.AgreedValueLength()); + + // local: send public to remote; remote: send public to local + + // Local + SecByteBlock sharedLocal(dhLocal.AgreedValueLength()); + assert(dhLocal.Agree(sharedLocal, privLocal, pubRemote)); + + // Remote + SecByteBlock sharedRemote(dhRemote.AgreedValueLength()); + assert(dhRemote.Agree(sharedRemote, privRemote, pubLocal)); + + // Test + Integer ssLocal, ssRemote; + ssLocal.Decode(sharedLocal.BytePtr(), sharedLocal.SizeInBytes()); + ssRemote.Decode(sharedRemote.BytePtr(), sharedRemote.SizeInBytes()); + + assert(ssLocal != 0); + assert(ssLocal == ssRemote); + + + // Now use our keys + KeyPair a = KeyPair::create(); + byte puba[65] = {0x04}; + memcpy(&puba[1], a.pub().data(), 64); + + KeyPair b = KeyPair::create(); + byte pubb[65] = {0x04}; + memcpy(&pubb[1], b.pub().data(), 64); + + ECDH::Domain dhA(pp::secp256k1Curve); + Secret shared; + BOOST_REQUIRE(dhA.Agree(shared.data(), a.sec().data(), pubb)); + BOOST_REQUIRE(shared); +} + +BOOST_AUTO_TEST_CASE(ecdhe) +{ + cnote << "Testing ecdhe..."; + + ECDHE a, b; + BOOST_CHECK_NE(a.pubkey(), b.pubkey()); + + ECDHE local; + ECDHE remote; + + // local tx pubkey -> remote + Secret sremote; + remote.agree(local.pubkey(), sremote); + + // remote tx pbukey -> local + Secret slocal; + local.agree(remote.pubkey(), slocal); + + BOOST_REQUIRE(sremote); + BOOST_REQUIRE(slocal); + BOOST_REQUIRE_EQUAL(sremote, slocal); +} + BOOST_AUTO_TEST_CASE(ecdhe_aes128_ctr_sha3mac) { // New connections require new ECDH keypairs @@ -288,53 +362,6 @@ BOOST_AUTO_TEST_CASE(ecdhe_aes128_ctr_sha3mac) } -BOOST_AUTO_TEST_CASE(cryptopp_ecies_message) -{ - cnote << "Testing cryptopp_ecies_message..."; - - string const message("Now is the time for all good persons to come to the aide of humanity."); - - ECIES::Decryptor localDecryptor(pp::PRNG, pp::secp256k1Curve); - SavePrivateKey(localDecryptor.GetPrivateKey()); - - ECIES::Encryptor localEncryptor(localDecryptor); - SavePublicKey(localEncryptor.GetPublicKey()); - - ECIES::Decryptor futureDecryptor; - LoadPrivateKey(futureDecryptor.AccessPrivateKey()); - futureDecryptor.GetPrivateKey().ThrowIfInvalid(pp::PRNG, 3); - - ECIES::Encryptor futureEncryptor; - LoadPublicKey(futureEncryptor.AccessPublicKey()); - futureEncryptor.GetPublicKey().ThrowIfInvalid(pp::PRNG, 3); - - // encrypt/decrypt with local - string cipherLocal; - StringSource ss1 (message, true, new PK_EncryptorFilter(pp::PRNG, localEncryptor, new StringSink(cipherLocal) ) ); - string plainLocal; - StringSource ss2 (cipherLocal, true, new PK_DecryptorFilter(pp::PRNG, localDecryptor, new StringSink(plainLocal) ) ); - - // encrypt/decrypt with future - string cipherFuture; - StringSource ss3 (message, true, new PK_EncryptorFilter(pp::PRNG, futureEncryptor, new StringSink(cipherFuture) ) ); - string plainFuture; - StringSource ss4 (cipherFuture, true, new PK_DecryptorFilter(pp::PRNG, futureDecryptor, new StringSink(plainFuture) ) ); - - // decrypt local w/future - string plainFutureFromLocal; - StringSource ss5 (cipherLocal, true, new PK_DecryptorFilter(pp::PRNG, futureDecryptor, new StringSink(plainFutureFromLocal) ) ); - - // decrypt future w/local - string plainLocalFromFuture; - StringSource ss6 (cipherFuture, true, new PK_DecryptorFilter(pp::PRNG, localDecryptor, new StringSink(plainLocalFromFuture) ) ); - - - BOOST_REQUIRE(plainLocal == message); - BOOST_REQUIRE(plainFuture == plainLocal); - BOOST_REQUIRE(plainFutureFromLocal == plainLocal); - BOOST_REQUIRE(plainLocalFromFuture == plainLocal); -} - BOOST_AUTO_TEST_CASE(cryptopp_aes128_ctr) { const int aesKeyLen = 16; @@ -346,21 +373,29 @@ BOOST_AUTO_TEST_CASE(cryptopp_aes128_ctr) rng.GenerateBlock(key, key.size()); // cryptopp uses IV as nonce/counter which is same as using nonce w/0 ctr - byte ctr[AES::BLOCKSIZE]; - rng.GenerateBlock(ctr, sizeof(ctr)); + FixedHash ctr; + rng.GenerateBlock(ctr.data(), sizeof(ctr)); + + // used for decrypt + FixedHash ctrcopy(ctr); - string text = "Now is the time for all good persons to come to the aide of humanity."; - // c++11 ftw + string text = "Now is the time for all good persons to come to the aid of humanity."; unsigned char const* in = (unsigned char*)&text[0]; unsigned char* out = (unsigned char*)&text[0]; string original = text; + string doublespeak = text + text; string cipherCopy; try { CTR_Mode::Encryption e; - e.SetKeyWithIV(key, key.size(), ctr); + e.SetKeyWithIV(key, key.size(), ctr.data()); + + // 68 % 255 should be difference of counter e.ProcessData(out, in, text.size()); + + (u128)ctr += (u128)(text.size() % 16); + BOOST_REQUIRE(text != original); cipherCopy = text; } @@ -372,7 +407,7 @@ BOOST_AUTO_TEST_CASE(cryptopp_aes128_ctr) try { CTR_Mode< AES >::Decryption d; - d.SetKeyWithIV(key, key.size(), ctr); + d.SetKeyWithIV(key, key.size(), ctrcopy.data()); d.ProcessData(out, in, text.size()); BOOST_REQUIRE(text == original); } @@ -390,7 +425,7 @@ BOOST_AUTO_TEST_CASE(cryptopp_aes128_ctr) out = (unsigned char*)&cipherCopy[0]; CTR_Mode::Encryption e; - e.SetKeyWithIV(key, key.size(), ctr); + e.SetKeyWithIV(key, key.size(), ctrcopy.data()); e.ProcessData(out, in, text.size()); // yep, ctr mode. From d010b15523d0c59d4152ebb1b63ef2b5452abf17 Mon Sep 17 00:00:00 2001 From: Christoph Jentzsch Date: Tue, 11 Nov 2014 21:56:17 +0100 Subject: [PATCH 07/16] Store return value of call to precompiled contract in test --- stPreCompiledContractsFiller.json | 38 +++++++++++++++---------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/stPreCompiledContractsFiller.json b/stPreCompiledContractsFiller.json index 8975f1aea..bb2b35756 100644 --- a/stPreCompiledContractsFiller.json +++ b/stPreCompiledContractsFiller.json @@ -12,7 +12,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -46,7 +46,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) (CALL 500 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 500 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -80,7 +80,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) (CALL 499 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 499 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -114,7 +114,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code": "{ (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) }", + "code": "{ [[ 2 ]] (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -148,7 +148,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 1) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 1) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -182,7 +182,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 33 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 65 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) (CALL 1000 1 0 0 97 97 32) [[ 0 ]] (MOD (MLOAD 97) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 33 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 65 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 1000 1 0 0 97 97 32) [[ 0 ]] (MOD (MLOAD 97) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -216,7 +216,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code": "{ (MSTORE 0 0x2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9) (MSTORE 32 27) (MSTORE 64 0x6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a) (MSTORE 96 0x37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d4) (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "code": "{ (MSTORE 0 0x2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9) (MSTORE 32 27) (MSTORE 64 0x6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a) (MSTORE 96 0x37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d4) [[ 2 ]] (CALL 1000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -284,7 +284,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code" : "{ (CALL 500 2 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ [[ 2 ]] (CALL 500 2 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -318,7 +318,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code" : "{ (MSTORE 5 0xf34578907f) (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -352,7 +352,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code" : "{ (MSTORE 0 0xf34578907f) (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -386,7 +386,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (CALL 100 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 100 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -420,7 +420,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (CALL 99 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 99 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -454,7 +454,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (CALL 500 2 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 500 2 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -522,7 +522,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code" : "{ (CALL 500 3 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ [[ 2 ]] (CALL 500 3 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -556,7 +556,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code" : "{ (MSTORE 5 0xf34578907f) (CALL 500 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALL 500 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -590,7 +590,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code" : "{ (MSTORE 0 0xf34578907f) (CALL 500 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 500 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -624,7 +624,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (CALL 100 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 100 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -658,7 +658,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (CALL 99 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 99 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -692,7 +692,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : 0, - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (CALL 500 3 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 500 3 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { From 508b7f14d8639ccf650fc1717c37eefce5d14f09 Mon Sep 17 00:00:00 2001 From: Christoph Jentzsch Date: Tue, 11 Nov 2014 22:25:21 +0100 Subject: [PATCH 08/16] Create state test with commandline flag --- TestHelper.cpp | 47 +++++++++++++++++++++++++---------------------- state.cpp | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 22 deletions(-) diff --git a/TestHelper.cpp b/TestHelper.cpp index c1a141abb..80482399a 100644 --- a/TestHelper.cpp +++ b/TestHelper.cpp @@ -27,8 +27,6 @@ #include #include -//#define FILL_TESTS - using namespace std; using namespace dev::eth; @@ -351,28 +349,33 @@ void executeTests(const string& _name, const string& _testPathAppendix, std::fun string testPath = getTestPath(); testPath += _testPathAppendix; -#ifdef FILL_TESTS - try + for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) { - cnote << "Populating tests..."; - json_spirit::mValue v; - boost::filesystem::path p(__FILE__); - boost::filesystem::path dir = p.parent_path(); - string s = asString(dev::contents(dir.string() + "/" + _name + "Filler.json")); - BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + dir.string() + "/" + _name + "Filler.json is empty."); - json_spirit::read_string(s, v); - doTests(v, true); - writeFile(testPath + "/" + _name + ".json", asBytes(json_spirit::write_string(v, true))); + string arg = boost::unit_test::framework::master_test_suite().argv[i]; + if (arg == "--createtest") + { + try + { + cnote << "Populating tests..."; + json_spirit::mValue v; + boost::filesystem::path p(__FILE__); + boost::filesystem::path dir = p.parent_path(); + string s = asString(dev::contents(dir.string() + "/" + _name + "Filler.json")); + BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + dir.string() + "/" + _name + "Filler.json is empty."); + json_spirit::read_string(s, v); + doTests(v, true); + writeFile(testPath + "/" + _name + ".json", asBytes(json_spirit::write_string(v, true))); + } + catch (Exception const& _e) + { + BOOST_ERROR("Failed test with Exception: " << diagnostic_information(_e)); + } + catch (std::exception const& _e) + { + BOOST_ERROR("Failed test with Exception: " << _e.what()); + } + } } - catch (Exception const& _e) - { - BOOST_ERROR("Failed test with Exception: " << diagnostic_information(_e)); - } - catch (std::exception const& _e) - { - BOOST_ERROR("Failed test with Exception: " << _e.what()); - } -#endif try { diff --git a/state.cpp b/state.cpp index 91d9f3e51..b5b238299 100644 --- a/state.cpp +++ b/state.cpp @@ -122,6 +122,40 @@ BOOST_AUTO_TEST_CASE(stPreCompiledContracts) dev::test::executeTests("stPreCompiledContracts", "/StateTests", dev::test::doStateTests); } +BOOST_AUTO_TEST_CASE(stCreateTest) +{ + for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) + { + string arg = boost::unit_test::framework::master_test_suite().argv[i]; + if (arg == "--createtest") + { + if (boost::unit_test::framework::master_test_suite().argc <= i + 2) + { + cnote << "usage: ./testeth --createtest \n"; + return; + } + try + { + cnote << "Populating tests..."; + json_spirit::mValue v; + string s = asString(dev::contents(boost::unit_test::framework::master_test_suite().argv[i + 1])); + BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + (string)boost::unit_test::framework::master_test_suite().argv[i + 1] + " is empty."); + json_spirit::read_string(s, v); + dev::test::doStateTests(v, true); + writeFile(boost::unit_test::framework::master_test_suite().argv[i + 2], asBytes(json_spirit::write_string(v, true))); + } + catch (Exception const& _e) + { + BOOST_ERROR("Failed state test with Exception: " << diagnostic_information(_e)); + } + catch (std::exception const& _e) + { + BOOST_ERROR("Failed state test with Exception: " << _e.what()); + } + } + } +} + BOOST_AUTO_TEST_CASE(userDefinedFileState) { dev::test::userDefinedTest("--statetest", dev::test::doStateTests); From 4f589053a028ee95fecdb0e6db523444bb875224 Mon Sep 17 00:00:00 2001 From: Christoph Jentzsch Date: Tue, 11 Nov 2014 22:28:43 +0100 Subject: [PATCH 09/16] changed name of command line option to filltests --- TestHelper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TestHelper.cpp b/TestHelper.cpp index 80482399a..1b13f9e82 100644 --- a/TestHelper.cpp +++ b/TestHelper.cpp @@ -352,7 +352,7 @@ void executeTests(const string& _name, const string& _testPathAppendix, std::fun for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) { string arg = boost::unit_test::framework::master_test_suite().argv[i]; - if (arg == "--createtest") + if (arg == "--filltests") { try { From e4fd61382184cf974c17f50df0e3d6c6f87ab6d2 Mon Sep 17 00:00:00 2001 From: subtly Date: Wed, 12 Nov 2014 02:01:27 +0100 Subject: [PATCH 10/16] cryptopp recover public key --- crypto.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crypto.cpp b/crypto.cpp index a84c1fbb5..4e752fd1a 100644 --- a/crypto.cpp +++ b/crypto.cpp @@ -172,19 +172,19 @@ BOOST_AUTO_TEST_CASE(cryptopp_ecdsa_sipaseckp256k1) Integer nB(fromHex("f2ee15ea639b73fa3db9b34a245bdfa015c260c598b211bf05a1ecc4b3e3b4f2").data(), 32); BOOST_REQUIRE(nHex == nB); - bytes sbytes(fromHex("0x01")); + bytes sbytes(fromHex("0xFFFF")); Secret secret(sha3(sbytes)); // 5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2 KeyPair key(secret); - bytes m(fromHex("0x01")); - int tests = 2; + bytes m(fromHex("0xFF")); + int tests = 3; while (m[0]++, tests--) { h256 hm(sha3(m)); Integer hInt(hm.asBytes().data(), 32); h256 k(hm ^ key.sec()); Integer kInt(k.asBytes().data(), 32); - + // raw sign w/cryptopp (doesn't pass through cryptopp hash filter) ECDSA::Signer signer; pp::initializeDLScheme(key.sec(), signer); From 9ae6dcc5d14a87492158f030c88414138009c28d Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 12 Nov 2014 11:39:42 +0100 Subject: [PATCH 11/16] solidity JSON interface tests --- solidityJSONInterfaceTest.cpp | 213 ++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 solidityJSONInterfaceTest.cpp diff --git a/solidityJSONInterfaceTest.cpp b/solidityJSONInterfaceTest.cpp new file mode 100644 index 000000000..fec9f7db2 --- /dev/null +++ b/solidityJSONInterfaceTest.cpp @@ -0,0 +1,213 @@ +/* + 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. + + cpp-ethereum 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 cpp-ethereum. If not, see . + */ +/** + * @author Marek Kotewicz + * @date 2014 + * Unit tests for the solidity compiler JSON Interface output. + */ + +#include +#include +#include + +namespace dev +{ +namespace solidity +{ +namespace test +{ + +class InterfaceChecker { +public: + bool checkInterface(std::string const& _code, std::string const& _expectedInterfaceString) + { + m_compilerStack.compile(_code); + std::string generatedInterfaceString = m_compilerStack.getInterface(); + Json::Value generatedInterface; + m_reader.parse(generatedInterfaceString, generatedInterface); + Json::Value expectedInterface; + m_reader.parse(_expectedInterfaceString, expectedInterface); + return expectedInterface == generatedInterface; + } + +private: + CompilerStack m_compilerStack; + Json::Reader m_reader; +}; + +BOOST_FIXTURE_TEST_SUITE(SolidityCompilerJSONInterfaceOutput, InterfaceChecker) + +BOOST_AUTO_TEST_CASE(basic_test) +{ + char const* sourceCode = "contract test {\n" + " function f(uint a) returns(uint d) { return a * 7; }\n" + "}\n"; + + char const* interface = R"([ + { + "name": "f", + "inputs": [ + { + "name": "a", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "d", + "type": "uint256" + } + ] + } + ])"; + + BOOST_CHECK(checkInterface(sourceCode, interface)); +} + +BOOST_AUTO_TEST_CASE(empty_contract) +{ + char const* sourceCode = "contract test {\n" + "}\n"; + + char const* interface = "[]"; + + BOOST_CHECK(checkInterface(sourceCode, interface)); +} + +BOOST_AUTO_TEST_CASE(multiple_methods) +{ + char const* sourceCode = "contract test {\n" + " function f(uint a) returns(uint d) { return a * 7; }\n" + " function g(uint b) returns(uint e) { return b * 8; }\n" + "}\n"; + + char const* interface = R"([ + { + "name": "f", + "inputs": [ + { + "name": "a", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "d", + "type": "uint256" + } + ] + }, + { + "name": "g", + "inputs": [ + { + "name": "b", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "e", + "type": "uint256" + } + ] + } + ])"; + + BOOST_CHECK(checkInterface(sourceCode, interface)); +} + +BOOST_AUTO_TEST_CASE(multiple_params) +{ + char const* sourceCode = "contract test {\n" + " function f(uint a, uint b) returns(uint d) { return a + b; }\n" + "}\n"; + + char const* interface = R"([ + { + "name": "f", + "inputs": [ + { + "name": "a", + "type": "uint256" + }, + { + "name": "b", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "d", + "type": "uint256" + } + ] + } + ])"; + + BOOST_CHECK(checkInterface(sourceCode, interface)); +} + +BOOST_AUTO_TEST_CASE(multiple_methods_order) +{ + // methods are expected to be in alpabetical order + char const* sourceCode = "contract test {\n" + " function f(uint a) returns(uint d) { return a * 7; }\n" + " function c(uint b) returns(uint e) { return b * 8; }\n" + "}\n"; + + char const* interface = R"([ + { + "name": "c", + "inputs": [ + { + "name": "b", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "e", + "type": "uint256" + } + ] + }, + { + "name": "f", + "inputs": [ + { + "name": "a", + "type": "uint256" + } + ], + "outputs": [ + { + "name": "d", + "type": "uint256" + } + ] + } + ])"; + + BOOST_CHECK(checkInterface(sourceCode, interface)); +} + +BOOST_AUTO_TEST_SUITE_END() + +} +} +} From a519e8350408582ef83207b4ff97056a4a7f79d7 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 12 Nov 2014 13:00:11 +0100 Subject: [PATCH 12/16] solidity json interface tests fixes --- solidityJSONInterfaceTest.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/solidityJSONInterfaceTest.cpp b/solidityJSONInterfaceTest.cpp index fec9f7db2..1a443087f 100644 --- a/solidityJSONInterfaceTest.cpp +++ b/solidityJSONInterfaceTest.cpp @@ -20,9 +20,9 @@ * Unit tests for the solidity compiler JSON Interface output. */ +#include #include #include -#include namespace dev { @@ -31,11 +31,12 @@ namespace solidity namespace test { -class InterfaceChecker { +class InterfaceChecker +{ public: bool checkInterface(std::string const& _code, std::string const& _expectedInterfaceString) { - m_compilerStack.compile(_code); + m_compilerStack.parse(_code); std::string generatedInterfaceString = m_compilerStack.getInterface(); Json::Value generatedInterface; m_reader.parse(generatedInterfaceString, generatedInterface); From 84b3fb6168a5deb1e40801407c5aaedd6801e313 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 13 Nov 2014 02:00:19 +0100 Subject: [PATCH 13/16] refactor and thread-safe cryptopp. for now, remove secp256klib calls. ecdh and tests. move sha3mac into sha3. --- crypto.cpp | 143 +++++++++++++++++------------------------------------ 1 file changed, 45 insertions(+), 98 deletions(-) diff --git a/crypto.cpp b/crypto.cpp index 4e752fd1a..2a206bdd7 100644 --- a/crypto.cpp +++ b/crypto.cpp @@ -27,8 +27,7 @@ #include #include #include -#include -#include +#include #include #include @@ -39,6 +38,21 @@ using namespace CryptoPP; BOOST_AUTO_TEST_SUITE(devcrypto) +static Secp256k1 s_secp256k1; +static CryptoPP::AutoSeededRandomPool s_rng; +static CryptoPP::OID s_curveOID(CryptoPP::ASN1::secp256k1()); +static CryptoPP::DL_GroupParameters_EC s_params(s_curveOID); +static CryptoPP::DL_GroupParameters_EC::EllipticCurve s_curve(s_params.GetCurve()); + +BOOST_AUTO_TEST_CASE(verify_secert) +{ + h256 empty; + KeyPair kNot(empty); + BOOST_REQUIRE(!kNot.address()); + KeyPair k(sha3(empty)); + BOOST_REQUIRE(k.address()); +} + BOOST_AUTO_TEST_CASE(common_encrypt_decrypt) { string message("Now is the time for all good persons to come to the aid of humanity."); @@ -57,103 +71,50 @@ BOOST_AUTO_TEST_CASE(common_encrypt_decrypt) BOOST_REQUIRE(plain == asBytes(message)); } -BOOST_AUTO_TEST_CASE(cryptopp_vs_secp256k1) -{ - ECIES::Decryptor d(pp::PRNG, pp::secp256k1Curve); - ECIES::Encryptor e(d.GetKey()); - - Secret s; - pp::exportPrivateKey(d.GetKey(), s); - - Public p; - pp::exportPublicKey(e.GetKey(), p); - - BOOST_REQUIRE(dev::toAddress(s) == right160(dev::sha3(p.ref()))); - - Secret previous = s; - for (auto i = 0; i < 2; i++) - { - ECIES::Decryptor d(pp::PRNG, pp::secp256k1Curve); - ECIES::Encryptor e(d.GetKey()); - - Secret s; - pp::exportPrivateKey(d.GetKey(), s); - BOOST_REQUIRE(s != previous); - - Public p; - pp::exportPublicKey(e.GetKey(), p); - - h160 secp256k1Addr = dev::toAddress(s); - h160 cryptoppAddr = right160(dev::sha3(p.ref())); - if (secp256k1Addr != cryptoppAddr) - { - BOOST_REQUIRE(secp256k1Addr == cryptoppAddr); - break; - } - } -} - BOOST_AUTO_TEST_CASE(cryptopp_cryptopp_secp256k1libport) { - // cryptopp implementation of secp256k1lib sign_compact w/recid parameter and recovery of public key from signature - + secp256k1_start(); + // base secret Secret secret(sha3("privacy")); // we get ec params from signer - const CryptoPP::DL_GroupParameters_EC params = pp::secp256k1Params; ECDSA::Signer signer; // e := sha3(msg) bytes e(fromHex("0x01")); e.resize(32); - int tests = 2; // Oct 29: successful @ 1500 + int tests = 2; while (sha3(&e, &e), secret = sha3(secret.asBytes()), tests--) { KeyPair key(secret); Public pkey = key.pub(); - pp::initializeDLScheme(secret, signer); + signer.AccessKey().Initialize(s_params, secretToExponent(secret)); h256 he(sha3(e)); Integer heInt(he.asBytes().data(), 32); h256 k(crypto::kdf(secret, he)); Integer kInt(k.asBytes().data(), 32); - kInt %= params.GetSubgroupOrder()-1; + kInt %= s_params.GetSubgroupOrder()-1; - ECP::Point rp = params.ExponentiateBase(kInt); - Integer const& q = params.GetGroupOrder(); - Integer r = params.ConvertElementToInteger(rp); - int recid = ((r >= q) ? 2 : 0) | (rp.y.IsOdd() ? 1 : 0); + ECP::Point rp = s_params.ExponentiateBase(kInt); + Integer const& q = s_params.GetGroupOrder(); + Integer r = s_params.ConvertElementToInteger(rp); Integer kInv = kInt.InverseMod(q); Integer s = (kInv * (Integer(secret.asBytes().data(), 32)*r + heInt)) % q; BOOST_REQUIRE(!!r && !!s); - -/* - // For future reference: - // According to maths, this codepath can't be reached, however, it's in secp256k1. - // Commenting this out diverges from codebase implementation. - // To be removed after upstream PR and proof are evaulated. - - if (s > params.GetSubgroupOrder()) - { - // note: this rarely happens - s = params.GetGroupOrder() - s; - if (recid) - recid ^= 1; - } - */ Signature sig; + sig[64] = rp.y.IsOdd() ? 1 : 0; r.Encode(sig.data(), 32); s.Encode(sig.data() + 32, 32); - sig[64] = recid; Public p = dev::recover(sig, he); BOOST_REQUIRE(p == pkey); // verify w/cryptopp - BOOST_REQUIRE(crypto::verify(pkey, sig, bytesConstRef(&e))); + BOOST_REQUIRE(s_secp256k1.verify(pkey, sig, bytesConstRef(&e))); // verify with secp256k1lib byte encpub[65] = {0x04}; @@ -167,17 +128,19 @@ BOOST_AUTO_TEST_CASE(cryptopp_cryptopp_secp256k1libport) BOOST_AUTO_TEST_CASE(cryptopp_ecdsa_sipaseckp256k1) { + secp256k1_start(); + // cryptopp integer encoding Integer nHex("f2ee15ea639b73fa3db9b34a245bdfa015c260c598b211bf05a1ecc4b3e3b4f2H"); Integer nB(fromHex("f2ee15ea639b73fa3db9b34a245bdfa015c260c598b211bf05a1ecc4b3e3b4f2").data(), 32); BOOST_REQUIRE(nHex == nB); bytes sbytes(fromHex("0xFFFF")); - Secret secret(sha3(sbytes)); // 5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2 + Secret secret(sha3(sbytes)); KeyPair key(secret); bytes m(fromHex("0xFF")); - int tests = 3; + int tests = 2; while (m[0]++, tests--) { h256 hm(sha3(m)); @@ -187,42 +150,42 @@ BOOST_AUTO_TEST_CASE(cryptopp_ecdsa_sipaseckp256k1) // raw sign w/cryptopp (doesn't pass through cryptopp hash filter) ECDSA::Signer signer; - pp::initializeDLScheme(key.sec(), signer); + signer.AccessKey().Initialize(s_params, secretToExponent(key.sec())); Integer r, s; signer.RawSign(kInt, hInt, r, s); // verify cryptopp raw-signature w/cryptopp ECDSA::Verifier verifier; - pp::initializeDLScheme(key.pub(), verifier); + verifier.AccessKey().Initialize(s_params, publicToPoint(key.pub())); Signature sigppraw; r.Encode(sigppraw.data(), 32); s.Encode(sigppraw.data() + 32, 32); BOOST_REQUIRE(verifier.VerifyMessage(m.data(), m.size(), sigppraw.data(), 64)); - BOOST_REQUIRE(crypto::verify(key.pub(), sigppraw, bytesConstRef(&m))); +// BOOST_REQUIRE(crypto::verify(key.pub(), sigppraw, bytesConstRef(&m))); BOOST_REQUIRE(dev::verify(key.pub(), sigppraw, hm)); // sign with cryptopp, verify, recover w/sec256lib Signature seclibsig(dev::sign(key.sec(), hm)); BOOST_REQUIRE(verifier.VerifyMessage(m.data(), m.size(), seclibsig.data(), 64)); - BOOST_REQUIRE(crypto::verify(key.pub(), seclibsig, bytesConstRef(&m))); +// BOOST_REQUIRE(crypto::verify(key.pub(), seclibsig, bytesConstRef(&m))); BOOST_REQUIRE(dev::verify(key.pub(), seclibsig, hm)); BOOST_REQUIRE(dev::recover(seclibsig, hm) == key.pub()); // sign with cryptopp (w/hash filter?), verify with cryptopp bytes sigppb(signer.MaxSignatureLength()); - size_t ssz = signer.SignMessage(pp::PRNG, m.data(), m.size(), sigppb.data()); + size_t ssz = signer.SignMessage(s_rng, m.data(), m.size(), sigppb.data()); Signature sigpp; memcpy(sigpp.data(), sigppb.data(), 64); BOOST_REQUIRE(verifier.VerifyMessage(m.data(), m.size(), sigppb.data(), ssz)); - BOOST_REQUIRE(crypto::verify(key.pub(), sigpp, bytesConstRef(&m))); +// BOOST_REQUIRE(crypto::verify(key.pub(), sigpp, bytesConstRef(&m))); BOOST_REQUIRE(dev::verify(key.pub(), sigpp, hm)); // sign with cryptopp and stringsource hash filter string sigstr; - StringSource ssrc(asString(m), true, new SignerFilter(pp::PRNG, signer, new StringSink(sigstr))); + StringSource ssrc(asString(m), true, new SignerFilter(s_rng, signer, new StringSink(sigstr))); FixedHash retsig((byte const*)sigstr.data(), Signature::ConstructFromPointer); BOOST_REQUIRE(verifier.VerifyMessage(m.data(), m.size(), retsig.data(), 64)); - BOOST_REQUIRE(crypto::verify(key.pub(), retsig, bytesConstRef(&m))); +// BOOST_REQUIRE(crypto::verify(key.pub(), retsig, bytesConstRef(&m))); BOOST_REQUIRE(dev::verify(key.pub(), retsig, hm)); /// verification w/sec256lib @@ -248,22 +211,6 @@ BOOST_AUTO_TEST_CASE(cryptopp_ecdsa_sipaseckp256k1) } } -BOOST_AUTO_TEST_CASE(cryptopp_public_export_import) -{ - ECIES::Decryptor d(pp::PRNG, pp::secp256k1Curve); - ECIES::Encryptor e(d.GetKey()); - - Secret s; - pp::exportPrivateKey(d.GetKey(), s); - Public p; - pp::exportPublicKey(e.GetKey(), p); - Address addr = right160(dev::sha3(p.ref())); - BOOST_REQUIRE(toAddress(s) == addr); - - KeyPair l(s); - BOOST_REQUIRE(l.address() == addr); -} - BOOST_AUTO_TEST_CASE(ecies_eckeypair) { KeyPair k = KeyPair::create(); @@ -272,10 +219,10 @@ BOOST_AUTO_TEST_CASE(ecies_eckeypair) string original = message; bytes b = asBytes(message); - encrypt(k.pub(), b); + s_secp256k1.encrypt(k.pub(), b); BOOST_REQUIRE(b != asBytes(original)); - decrypt(k.sec(), b); + s_secp256k1.decrypt(k.sec(), b); BOOST_REQUIRE(b == asBytes(original)); } @@ -283,15 +230,15 @@ BOOST_AUTO_TEST_CASE(ecdh) { cnote << "Testing ecdh..."; - ECDH::Domain dhLocal(pp::secp256k1Curve); + ECDH::Domain dhLocal(s_curveOID); SecByteBlock privLocal(dhLocal.PrivateKeyLength()); SecByteBlock pubLocal(dhLocal.PublicKeyLength()); - dhLocal.GenerateKeyPair(pp::PRNG, privLocal, pubLocal); + dhLocal.GenerateKeyPair(s_rng, privLocal, pubLocal); - ECDH::Domain dhRemote(pp::secp256k1Curve); + ECDH::Domain dhRemote(s_curveOID); SecByteBlock privRemote(dhRemote.PrivateKeyLength()); SecByteBlock pubRemote(dhRemote.PublicKeyLength()); - dhRemote.GenerateKeyPair(pp::PRNG, privRemote, pubRemote); + dhRemote.GenerateKeyPair(s_rng, privRemote, pubRemote); assert(dhLocal.AgreedValueLength() == dhRemote.AgreedValueLength()); @@ -323,7 +270,7 @@ BOOST_AUTO_TEST_CASE(ecdh) byte pubb[65] = {0x04}; memcpy(&pubb[1], b.pub().data(), 64); - ECDH::Domain dhA(pp::secp256k1Curve); + ECDH::Domain dhA(s_curveOID); Secret shared; BOOST_REQUIRE(dhA.Agree(shared.data(), a.sec().data(), pubb)); BOOST_REQUIRE(shared); From 4294fb9cbdb34eafad2d589b3a4ab168d0874403 Mon Sep 17 00:00:00 2001 From: subtly Date: Thu, 13 Nov 2014 17:40:44 +0100 Subject: [PATCH 14/16] changes for code review --- crypto.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto.cpp b/crypto.cpp index 2a206bdd7..cd7d8e984 100644 --- a/crypto.cpp +++ b/crypto.cpp @@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE(cryptopp_ecdsa_sipaseckp256k1) Secret secret(sha3(sbytes)); KeyPair key(secret); - bytes m(fromHex("0xFF")); + bytes m({0xFF}); int tests = 2; while (m[0]++, tests--) { From 7e7204ec18bdeb0c6cf3f550cfb6d33b3c2ba45e Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 14 Nov 2014 12:45:20 +0100 Subject: [PATCH 15/16] Compile fixes. Version bump. --- solidityEndToEndTest.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/solidityEndToEndTest.cpp b/solidityEndToEndTest.cpp index 1d09c114f..d905646cb 100644 --- a/solidityEndToEndTest.cpp +++ b/solidityEndToEndTest.cpp @@ -192,11 +192,11 @@ BOOST_AUTO_TEST_CASE(multiple_functions) " function f() returns(uint n) { return 3; }\n" "}\n"; compileAndRun(sourceCode); - BOOST_CHECK(callFunction(0, bytes()) == toBigEndian(u256(0))); - BOOST_CHECK(callFunction(1, bytes()) == toBigEndian(u256(1))); - BOOST_CHECK(callFunction(2, bytes()) == toBigEndian(u256(2))); - BOOST_CHECK(callFunction(3, bytes()) == toBigEndian(u256(3))); - BOOST_CHECK(callFunction(4, bytes()) == bytes()); + BOOST_CHECK(callContractFunction(0, bytes()) == toBigEndian(u256(0))); + BOOST_CHECK(callContractFunction(1, bytes()) == toBigEndian(u256(1))); + BOOST_CHECK(callContractFunction(2, bytes()) == toBigEndian(u256(2))); + BOOST_CHECK(callContractFunction(3, bytes()) == toBigEndian(u256(3))); + BOOST_CHECK(callContractFunction(4, bytes()) == bytes()); } BOOST_AUTO_TEST_CASE(while_loop) @@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(break_outside_loop) " }\n" "}\n"; compileAndRun(sourceCode); - testSolidityAgainstCpp(0, [](u256 const& _a) -> u256 { return 2; }, u256(0)); + testSolidityAgainstCpp(0, [](u256 const&) -> u256 { return 2; }, u256(0)); } BOOST_AUTO_TEST_CASE(nested_loops) From cdfeb725d469e686cbd024dcf4366d778e223930 Mon Sep 17 00:00:00 2001 From: subtly Date: Fri, 14 Nov 2014 13:14:22 +0100 Subject: [PATCH 16/16] pr fix --- crypto.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/crypto.cpp b/crypto.cpp index cd7d8e984..d8bd25035 100644 --- a/crypto.cpp +++ b/crypto.cpp @@ -340,8 +340,7 @@ BOOST_AUTO_TEST_CASE(cryptopp_aes128_ctr) // 68 % 255 should be difference of counter e.ProcessData(out, in, text.size()); - - (u128)ctr += (u128)(text.size() % 16); + ctr = h128(u128(ctr) + text.size() % 16); BOOST_REQUIRE(text != original); cipherCopy = text;