Auto merge of #976 - ebfull:implement-joinsplit-signatures, r=ebfull

Signing pours with ed25519

This is an alternative to #964 which uses ed25519 instead of secp256k1, and avoids the separate hash for fitting the public key into the `h_sig` block. It's based on @defuse's work in that branch.

Closes #808.
This commit is contained in:
zkbot
2016-05-31 03:46:30 +00:00
11 changed files with 676 additions and 536 deletions

File diff suppressed because one or more lines are too long

View File

@@ -81,6 +81,9 @@ uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, un
txTmp.vin.resize(1);
}
// Blank out the joinsplit signature.
memset(&txTmp.joinSplitSig[0], 0, txTmp.joinSplitSig.size());
// Serialize and hash
CHashWriter ss(SER_GETHASH, 0);
ss << txTmp << nHashType;
@@ -139,6 +142,22 @@ void static RandomTransaction(CMutableTransaction &tx, bool fSingle) {
tx.vpour.push_back(pourtx);
}
unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES];
crypto_sign_keypair(tx.joinSplitPubKey.begin(), joinSplitPrivKey);
// TODO: #966.
static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
// Empty output script.
CScript scriptCode;
CTransaction signTx(tx);
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL);
BOOST_CHECK(dataToBeSigned != one);
assert(crypto_sign_detached(&tx.joinSplitSig[0], NULL,
dataToBeSigned.begin(), 32,
joinSplitPrivKey
) == 0);
}
}

View File

@@ -16,6 +16,8 @@
#include "script/script_error.h"
#include "primitives/transaction.h"
#include "sodium.h"
#include <map>
#include <string>
@@ -379,6 +381,9 @@ BOOST_AUTO_TEST_CASE(test_simple_pour_invalidity)
CMutableTransaction newTx(tx);
CValidationState state;
unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES];
crypto_sign_keypair(newTx.joinSplitPubKey.begin(), joinSplitPrivKey);
state.SetPerformPourVerification(false); // don't verify the snark
// No pours, vin and vout, means it should be invalid.
@@ -396,7 +401,23 @@ BOOST_AUTO_TEST_CASE(test_simple_pour_invalidity)
pourtx->serials[0] = GetRandHash();
pourtx->serials[1] = GetRandHash();
BOOST_CHECK_MESSAGE(CheckTransaction(newTx, state), state.GetRejectReason());
BOOST_CHECK(!CheckTransaction(newTx, state));
BOOST_CHECK(state.GetRejectReason() == "bad-txns-invalid-joinsplit-signature");
// TODO: #966.
static const uint256 one(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
// Empty output script.
CScript scriptCode;
CTransaction signTx(newTx);
uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL);
BOOST_CHECK(dataToBeSigned != one);
assert(crypto_sign_detached(&newTx.joinSplitSig[0], NULL,
dataToBeSigned.begin(), 32,
joinSplitPrivKey
) == 0);
BOOST_CHECK(CheckTransaction(newTx, state));
}
{
// Ensure that values within the pour are well-formed.